def _build_automata(self): rows = self.row_symbols atoms = [AtomicFormula(r) for r in rows] alphabet = Alphabet(set(rows)) ldlf = LDLf_EmptyTraces(alphabet) f = PathExpressionEventually( PathExpressionSequence.chain([ PathExpressionStar( And.chain([Not(atoms[0]), Not(atoms[1]), Not(atoms[2])])), PathExpressionStar( And.chain([atoms[0], Not(atoms[1]), Not(atoms[2])])), # Not(atoms[3]), Not(atoms[4]), Not(atoms[5])]), PathExpressionStar( And.chain([atoms[0], atoms[1], Not(atoms[2])])), # Not(atoms[3]), Not(atoms[4]), Not(atoms[5])]), # And.chain([atoms[0], atoms[1], atoms[2]]), # Not(atoms[3]), Not(atoms[4]), Not(atoms[5])]), # And.chain([atoms[0], atoms[1], atoms[2], atoms[3], Not(atoms[4]), Not(atoms[5])]), # And.chain([atoms[0], atoms[1], atoms[2], atoms[3], atoms[4], Not(atoms[5])]), # And.chain([atoms[0], atoms[1], atoms[2], atoms[3], atoms[4], atoms[5] ]) ]), And.chain([atoms[0], atoms[1], atoms[2]])) nfa = ldlf.to_nfa(f) dfa = _to_pythomata_dfa(nfa) return dfa
def test_minimal_models(self): a = Symbol("a") b = Symbol("b") c = Symbol("c") alphabet = Alphabet({a, b, c}) pl = PL(alphabet) atomic_a = AtomicFormula(a) atomic_b = AtomicFormula(b) atomic_c = AtomicFormula(c) self.assertEqual( pl.minimal_models(TrueFormula()), {PLInterpretation(alphabet, { a: False, b: False, c: False })}) self.assertEqual(pl.minimal_models(FalseFormula()), set()) self.assertEqual( pl.minimal_models(atomic_a), {PLInterpretation(alphabet, { a: True, b: False, c: False })}) self.assertEqual( pl.minimal_models(Not(atomic_a)), {PLInterpretation(alphabet, { a: False, b: False, c: False })}) self.assertEqual( pl.minimal_models(And(atomic_a, atomic_b)), {PLInterpretation(alphabet, { a: True, b: True, c: False })}) self.assertEqual(pl.minimal_models(And(atomic_a, Not(atomic_a))), set()) self.assertEqual( pl.minimal_models(Or(atomic_a, atomic_b)), { PLInterpretation(alphabet, { a: False, b: True, c: False }), PLInterpretation(alphabet, { a: True, b: False, c: False }) }) self.assertEqual( pl.minimal_models(And.chain([atomic_a, atomic_b, atomic_c])), {PLInterpretation(alphabet, { a: True, b: True, c: True })})
def to_nfa(self, f: Formula): # TODO: optimize!!! assert self.is_formula(f) nnf_f = self.to_nnf(f) alphabet = powerset(self.alphabet.symbols) initial_states = {frozenset([nnf_f])} final_states = {frozenset()} delta = set() pl, I = PL._from_set_of_propositionals(set(), Alphabet(set())) d = self.delta(nnf_f, frozenset(), epsilon=True) if pl.truth(d, I): final_states.add(frozenset([nnf_f])) states = {frozenset(), frozenset([nnf_f])} states_changed, delta_changed = True, True while states_changed or delta_changed: states_changed, delta_changed = False, False for actions_set in alphabet: states_list = list(states) for q in states_list: delta_formulas = [ self.delta(subf, actions_set) for subf in q ] atomics = [ s for subf in delta_formulas for s in PL.find_atomics(subf) ] symbol2formula = { Symbol(str(f)): f for f in atomics if f != TrueFormula() and f != FalseFormula() } formula2atomic_formulas = { f: AtomicFormula.fromName(str(f)) if f != TrueFormula() and f != FalseFormula() else f for f in atomics } transformed_delta_formulas = [ self._tranform_delta(f, formula2atomic_formulas) for f in delta_formulas ] conjunctions = And.chain(transformed_delta_formulas) models = frozenset( PL(Alphabet( set(symbol2formula))).minimal_models(conjunctions)) if len(models) == 0: continue for min_model in models: q_prime = frozenset({ symbol2formula[s] for s in min_model.symbol2truth if min_model.symbol2truth[s] }) len_before = len(states) states.add(q_prime) if len(states) == len_before + 1: states_list.append(q_prime) states_changed = True len_before = len(delta) delta.add((q, actions_set, q_prime)) if len(delta) == len_before + 1: delta_changed = True # check if q_prime should be added as final state if len(q_prime) == 0: final_states.add(q_prime) else: q_prime_delta_conjunction = And.chain([ self.delta(subf, frozenset(), epsilon=True) for subf in q_prime ]) pl, I = PL._from_set_of_propositionals( set(), Alphabet(set())) if pl.truth(q_prime_delta_conjunction, I): final_states.add(q_prime) return { "alphabet": alphabet, "states": frozenset(states), "initial_states": frozenset(initial_states), "transitions": delta, "accepting_states": frozenset(final_states) }
def test_chain(self): a_sym, b_sym, c_sym = [Symbol(s) for s in ["a", "b", "c"]] a, b, c = [AtomicFormula(s) for s in [a_sym,b_sym,c_sym]] and_chain = And.chain([a, b, c]) self.assertEqual(and_chain, And(a, And(b, And(c, TrueFormula()))))