Example #1
0
def test_delta():
    parser = LDLfParser()
    i_ = {}
    i_a = {"A": True}
    i_b = {"B": True}
    i_ab = {"A": True, "B": True}

    true = PLTrue()
    false = PLFalse()
    tt = PLAtomic(LDLfLogicalTrue())
    ff = PLAtomic(LDLfLogicalFalse())

    assert parser("<A>tt").delta(i_) == false
    assert parser("<A>tt").delta(i_a) == tt
    assert parser("<A>tt").delta(i_b) == false
    assert parser("<A>tt").delta(i_ab) == tt

    assert parser("[B]ff").delta(i_) == true
    assert parser("[B]ff").delta(i_a) == true
    assert parser("[B]ff").delta(i_b) == ff
    assert parser("[B]ff").delta(i_ab) == ff

    f = parser("!(<?(!last)>end)")
    assert f.delta(i_) == f.to_nnf().delta(i_)
    assert f.delta(i_ab) == f.to_nnf().delta(i_ab)

    assert f.delta(i_, epsilon=True) == f.to_nnf().delta(i_, epsilon=True)
    assert f.delta(i_ab, epsilon=True) == f.to_nnf().delta(i_ab, epsilon=True)
    # with epsilon=True, the result is either PLTrue or PLFalse
    assert f.delta(i_, epsilon=True) in [PLTrue(), PLFalse()]
Example #2
0
 def _delta(self, i: PLInterpretation, epsilon=False):
     if epsilon:
         return PLFalse()
     else:
         return PLAnd(
             [PLAtomic(self.f),
              PLAtomic(LTLfNot(LTLfEnd()).to_nnf())])
Example #3
0
def test_nnf():
    parser = PLParser()
    sa, sb = "A", "B"
    a, b = PLAtomic(sa), PLAtomic(sb)
    i_ = PLInterpretation(set())
    i_a = PLInterpretation({sa})
    i_b = PLInterpretation({sb})
    i_ab = PLInterpretation({sa, sb})

    not_a_and_b = parser("!(A&B)")
    nnf_not_a_and_b = parser("!A | !B")
    assert not_a_and_b.to_nnf() == nnf_not_a_and_b
    assert nnf_not_a_and_b == nnf_not_a_and_b.to_nnf()

    dup = parser("!(A | A)")
    nnf_dup = dup.to_nnf()
    assert nnf_dup == PLNot(a)

    material_implication = parser("!A | B <-> !(A & !B) <-> A->B")
    nnf_material_implication = parser(
        "((!A | B) & (!A | B) & (!A | B)) | ((A & !B) & (A & !B) & (A & !B))")
    nnf_m = material_implication.to_nnf()
    assert nnf_m == nnf_material_implication.to_nnf()

    assert nnf_m.truth(i_) == material_implication.truth(
        i_) == nnf_material_implication.truth(i_) == True
    assert nnf_m.truth(i_a) == material_implication.truth(
        i_a) == nnf_material_implication.truth(i_a) == True
    assert nnf_m.truth(i_b) == material_implication.truth(
        i_b) == nnf_material_implication.truth(i_b) == True
    assert nnf_m.truth(i_ab) == material_implication.truth(
        i_ab) == nnf_material_implication.truth(i_ab) == True
Example #4
0
    def test_always(self):
        parser = self.parser
        i_, i_a, i_b, i_ab = self.i_, self.i_a, self.i_b, self.i_ab
        true = self.true
        false = self.false

        assert parser("G a").delta(i_a) == PLAnd([
            true,
            PLOr([
                false,
                PLOr([
                    PLAtomic(LTLfRelease([LTLfFalse(),
                                          LTLfAtomic("a")])),
                    PLAtomic(LTLfRelease([LTLfFalse(),
                                          LTLfFalse()])),
                ]),
            ]),
        ])
        assert parser("G a").delta(i_a) == PLAnd([
            true,
            PLOr([
                false,
                PLOr([
                    PLAtomic(LTLfRelease([LTLfFalse(),
                                          LTLfAtomic("a")])),
                    PLAtomic(LTLfRelease([LTLfFalse(),
                                          LTLfFalse()])),
                ]),
            ]),
        ])
        assert parser("G a").delta(i_a, epsilon=True) == true
        assert parser("G a").delta(i_, epsilon=True) == true
Example #5
0
    def test_eventually(self):
        parser = self.parser
        i_, i_a, i_b, i_ab = self.i_, self.i_a, self.i_b, self.i_ab
        true = self.true
        false = self.false

        assert parser("F a").delta(i_a) == PLOr([
            true,
            PLAnd([
                true,
                PLAnd([
                    PLAtomic(LTLfUntil([LTLfTrue(),
                                        LTLfAtomic("a")])),
                    PLAtomic(LTLfUntil([LTLfTrue(), LTLfTrue()])),
                ]),
            ]),
        ])
        assert parser("F a").delta(i_) == PLOr([
            false,
            PLAnd([
                true,
                PLAnd([
                    PLAtomic(LTLfUntil([LTLfTrue(),
                                        LTLfAtomic("a")])),
                    PLAtomic(LTLfUntil([LTLfTrue(), LTLfTrue()])),
                ]),
            ]),
        ])
        assert parser("F a").delta(i_a, epsilon=True) == false
        assert parser("F a").delta(i_, epsilon=True) == false
Example #6
0
 def _delta(self, i: PropositionalInterpretation, epsilon=False):
     """Apply the delta function."""
     if epsilon:
         return PLFalse()
     else:
         return PLAnd(
             [PLAtomic(self.f),
              PLAtomic(LTLfNot(LTLfEnd()).to_nnf())])
Example #7
0
    def setup_class(cls):
        cls.sa, cls.sb = "a", "b"

        cls.i_ = PLInterpretation(set())
        cls.i_a = PLInterpretation({cls.sa})
        cls.i_b = PLInterpretation({cls.sb})
        cls.i_ab = PLInterpretation({cls.sa, cls.sb})

        cls.a, cls.b = PLAtomic(cls.sa), PLAtomic(cls.sb)
Example #8
0
    def setup_class(cls):
        cls.sa, cls.sb = "a", "b"

        cls.i_ = {}
        cls.i_a = {cls.sa: True}
        cls.i_b = {cls.sb: True}
        cls.i_ab = {cls.sa: True, cls.sb: True}

        cls.a, cls.b = PLAtomic(cls.sa), PLAtomic(cls.sb)
Example #9
0
def test_nnf():
    parser = PLParser()
    sa, sb = "A", "B"
    a, b = PLAtomic(sa), PLAtomic(sb)
    i_ = {}
    i_a = {sa: True}
    i_b = {sb: True}
    i_ab = {sa: True, sb: True}

    not_a_and_b = parser("!(A&B)")
    nnf_not_a_and_b = parser("!A | !B")
    assert not_a_and_b.to_nnf() == nnf_not_a_and_b
    assert nnf_not_a_and_b == nnf_not_a_and_b.to_nnf()

    dup = parser("!(A | A)")
    nnf_dup = dup.to_nnf()
    assert nnf_dup == PLAnd([PLNot(a), PLNot(a)])

    material_implication = parser("!A | B <-> !(A & !B) <-> A->B")
    nnf_material_implication = parser(
        "((!A | B) & (!A | B) & (!A | B)) | ((A & !B) & (A & !B) & (A & !B))"
    )
    nnf_m = material_implication.to_nnf()
    assert nnf_m == nnf_material_implication.to_nnf()

    assert (
        nnf_m.truth(i_)
        == material_implication.truth(i_)
        == nnf_material_implication.truth(i_)
        == True
    )
    assert (
        nnf_m.truth(i_a)
        == material_implication.truth(i_a)
        == nnf_material_implication.truth(i_a)
        == True
    )
    assert (
        nnf_m.truth(i_b)
        == material_implication.truth(i_b)
        == nnf_material_implication.truth(i_b)
        == True
    )
    assert (
        nnf_m.truth(i_ab)
        == material_implication.truth(i_ab)
        == nnf_material_implication.truth(i_ab)
        == True
    )
Example #10
0
    def test_until(self):
        parser = self.parser
        i_, i_a, i_b, i_ab = self.i_, self.i_a, self.i_b, self.i_ab
        true = self.true
        false = self.false

        assert parser("A U B").delta(i_a) == PLOr([
            false,
            PLAnd([
                true,
                PLAtomic(LTLfUntil([LTLfAtomic("A"), LTLfAtomic("B")])),
                PLAtomic(LTLfEventually(LTLfTrue()).to_nnf())
            ])
        ])
        assert parser("A U B").delta(i_ab, epsilon=True) == false
Example #11
0
    def test_release(self):
        parser = self.parser
        i_, i_a, i_b, i_ab = self.i_, self.i_a, self.i_b, self.i_ab
        true = self.true
        false = self.false

        assert parser("A R B").delta(i_a) == PLAnd([
            false,
            PLOr([
                true,
                PLAtomic(LTLfRelease([LTLfAtomic("A"), LTLfAtomic("B")])),
                PLAtomic(LTLfAlways(LTLfFalse()).to_nnf())
            ])
        ])
        assert parser("A R B").delta(i_ab, epsilon=True) == true
Example #12
0
 def p_propositional(self, p):
     """propositional : propositional EQUIVALENCE propositional
                      | propositional IMPLIES propositional
                      | propositional OR propositional
                      | propositional AND propositional
                      | NOT propositional
                      | FALSE
                      | TRUE
                      | ATOM"""
     if len(p)==4:
         if p[2] == Symbols.EQUIVALENCE.value:
             p[0] = PLEquivalence([p[1], p[3]])
         elif p[2] == Symbols.IMPLIES.value:
             p[0] = PLImplies([p[1], p[3]])
         elif p[2] == Symbols.OR.value:
             p[0] = PLOr([p[1], p[3]])
         elif p[2] == Symbols.AND.value:
             p[0] = PLAnd([p[1], p[3]])
         else:
             raise ValueError
         # else:
         #     p[0] = p[2]
     elif len(p)==3:
         p[0] = PLNot(p[2])
     elif len(p)==2:
         if p[1]==Symbols.TRUE.value:
             p[0] = PLTrue()
         elif p[1]==Symbols.FALSE.value:
             p[0] = PLFalse()
         else:
             p[0] = PLAtomic(p[1])
     else:
         raise ValueError
Example #13
0
 def delta_box(self, f: LDLfFormula, i: PLInterpretation, epsilon=False):
     if epsilon:
         return PLTrue()
     if self.pl_formula.truth(i):
         return PLAtomic(_expand(f))
     else:
         return PLTrue()
Example #14
0
def to_automaton(f) -> SymbolicDFA:  # noqa: C901
    """Translate to automaton."""
    f = f.to_nnf()
    initial_state = frozenset({frozenset({PLAtomic(f)})})
    states = {initial_state}
    final_states = set()
    transition_function = {}  # type: Dict

    all_labels = f.find_labels()
    alphabet = powerset(all_labels)

    if f.delta({}, epsilon=True) == PLTrue():
        final_states.add(initial_state)

    visited = set()  # type: Set
    to_be_visited = {initial_state}

    while len(to_be_visited) != 0:

        for q in list(to_be_visited):
            to_be_visited.remove(q)
            for actions_set in alphabet:
                new_state = _make_transition(
                    q, {label: True
                        for label in actions_set})
                if new_state not in states:
                    states.add(new_state)
                    to_be_visited.add(new_state)

                transition_function.setdefault(q, {})[actions_set] = new_state

                if new_state not in visited:
                    visited.add(new_state)
                    if _is_true(new_state):
                        final_states.add(new_state)

    automaton = SymbolicAutomaton()
    state2idx = {}
    for state in states:
        state_idx = automaton.create_state()
        state2idx[state] = state_idx
        if state == initial_state:
            automaton.set_initial_state(state_idx)
        if state in final_states:
            automaton.set_accepting_state(state_idx, True)

    for source in transition_function:
        for symbol, destination in transition_function[source].items():
            source_idx = state2idx[source]
            dest_idx = state2idx[destination]
            pos_expr = sympy.And(*map(sympy.Symbol, symbol))
            neg_expr = sympy.And(*map(lambda x: sympy.Not(sympy.Symbol(x)),
                                      all_labels.difference(symbol)))
            automaton.add_transition(
                (source_idx, sympy.And(pos_expr, neg_expr), dest_idx))

    determinized = automaton.determinize()
    minimized = determinized.minimize()
    return minimized
Example #15
0
def find_atomics(formula: Formula) -> Set[PLAtomic]:
    """Finds all the atomic formulas"""
    res = set()
    if isinstance(formula, PLFormula):
        res = formula.find_atomics()
    else:
        res.add(PLAtomic(formula))
    return res
Example #16
0
    def test_1(self):
        sa, sb = "A", "B"
        a, b = PLAtomic(sa), PLAtomic(sb)

        i_ = {}
        i_a = {"A": True}
        i_b = {"B": True}
        i_ab = {"A": True, "B": True}

        tr_false_a_b_ab = [i_, i_a, i_b, i_ab, i_]

        tt = LDLfLogicalTrue()
        ff = LDLfLogicalFalse()

        assert tt.truth(tr_false_a_b_ab, 0)
        assert not ff.truth(tr_false_a_b_ab, 0)
        assert not LDLfNot(tt).truth(tr_false_a_b_ab, 0)
        assert LDLfNot(ff).truth(tr_false_a_b_ab, 0)
        # assert LDLfAnd([LDLfPropositional(a), LDLfPropositional(b)]).truth(
        #     tr_false_a_b_ab, 3
        # )
        assert not LDLfDiamond(RegExpPropositional(PLAnd([a, b])), tt).truth(
            tr_false_a_b_ab, 0)

        trace = self.trace
        parser = self.parser

        formula = "<true*;A&B>tt"
        parsed_formula = parser(formula)
        assert parsed_formula.truth(trace, 0)

        formula = "[(A+!B)*]<C>tt"
        parsed_formula = parser(formula)
        assert not parsed_formula.truth(trace, 1)

        formula = "<?(<!C>tt)><A>tt"
        parsed_formula = parser(formula)
        assert parsed_formula.truth(trace, 1)

        formula = "<!C+A>tt"
        parsed_formula = parser(formula)
        assert parsed_formula.truth(trace, 1)

        formula = "<!C+A>tt"
        parsed_formula = parser(formula)
        assert parsed_formula.truth(trace, 1)
Example #17
0
def test_delta():
    parser = LDLfParser()
    sa, sb, sc = "A", "B", "C"
    a, b, c = PLAtomic(sa), PLAtomic(sb), PLAtomic(sc)

    i_ = PLFalseInterpretation()
    i_a = PLInterpretation({sa})
    i_b = PLInterpretation({sb})
    i_ab = PLInterpretation({sa, sb})

    true = PLTrue()
    false = PLFalse()
    tt = LDLfLogicalTrue()
    ff = LDLfLogicalFalse()

    assert parser("<A>tt").delta(i_) == false
    assert parser("<A>tt").delta(i_a) == PLAtomic(tt)
    assert parser("<A>tt").delta(i_b) == false
    assert parser("<A>tt").delta(i_ab) == PLAtomic(tt)

    assert parser("[B]ff").delta(i_) == true
    assert parser("[B]ff").delta(i_a) == true
    assert parser("[B]ff").delta(i_b) == PLAtomic(ff)
    assert parser("[B]ff").delta(i_ab) == PLAtomic(ff)

    f = parser("!(<!(A<->B)+(B;A)*+(!last)?>[(true)*]end)")
    assert f.delta(i_) == f.to_nnf().delta(i_)
    assert f.delta(i_ab) == f.to_nnf().delta(i_ab)

    assert f.delta(i_, epsilon=True) == f.to_nnf().delta(i_, epsilon=True)
    assert f.delta(i_ab, epsilon=True) == f.to_nnf().delta(i_ab, epsilon=True)
    # with epsilon=True, the result is either PLTrue or PLFalse
    assert f.delta(i_, epsilon=True) in [PLTrue(), PLFalse()]
Example #18
0
def _make_transition(Q: FrozenSet[FrozenSet[PLAtomic]], i: PLInterpretation):
    actions_set = i.true_propositions
    new_macrostate = set()

    for q in Q:
        # delta function applied to every formula in the macro state Q
        delta_formulas = [f.s.delta(actions_set) for f in q]

        # find the list of atoms, which are "true" atoms (i.e. propositional atoms) or LDLf formulas
        atomics = [s for subf in delta_formulas for s in find_atomics(subf)]

        atom2id = {v: k
                   for k, v in enumerate(atomics)}  # type: Dict[int, PLAtomic]
        id2atom = {v: k
                   for k, v in atom2id.items()}  # type: Dict[PLAtomic, int]

        # "freeze" the found atoms as symbols and build a mapping from symbols to formulas
        symbol2formula = {
            atom2id[f]
            for f in atomics if f != PLTrue() and f != PLFalse()
        }

        # build a map from formula to a "freezed" propositional Atomic Formula
        formula2atomic_formulas = {
            f: PLAtomic(atom2id[f]) if f != PLTrue()
            and f != PLFalse()  # and not isinstance(f, PLAtomic)
            else f
            for f in atomics
        }

        # the final list of Propositional Atomic Formulas, one for each formula in the original macro state Q
        transformed_delta_formulas = [
            _transform_delta(f, formula2atomic_formulas)
            for f in delta_formulas
        ]

        # the empty conjunction stands for true
        if len(transformed_delta_formulas) == 0:
            conjunctions = PLTrue()
        elif len(transformed_delta_formulas) == 1:
            conjunctions = transformed_delta_formulas[0]
        else:
            conjunctions = PLAnd(transformed_delta_formulas)

        # the model in this case is the smallest set of symbols s.t. the conjunction of "freezed" atomic formula
        # is true.
        alphabet = frozenset(symbol2formula)
        models = frozenset(conjunctions.minimal_models(alphabet))

        for min_model in models:
            q_prime = frozenset(
                {id2atom[s]
                 for s in min_model.true_propositions})

            new_macrostate.add(q_prime)

    return frozenset(new_macrostate)
Example #19
0
def test_names():

    good = [
        "A",
        "b",
        "Hello",
        "PropZero",
        "Prop0",
        "this_is_fine_2",
        '"This is also allowed!"',
        PLParser()("A -> B"),
    ]
    bad = ["!", "&", "Invalid:", "", '"', "="]

    for name in good:
        PLAtomic(name)
    for name in bad:
        with pytest.raises(ValueError):
            PLAtomic(name)
Example #20
0
 def p_formula_atom(self, p):
     """formula : ATOM
                | TRUE
                | FALSE"""
     if p[1] == Symbols.TRUE.value:
         p[0] = PLTrue()
     elif p[1] == Symbols.FALSE.value:
         p[0] = PLFalse()
     else:
         p[0] = PLAtomic(p[1])
Example #21
0
def test_parser():
    parser = PLParser()
    sa, sb = "A", "B"
    a, b = PLAtomic(sa), PLAtomic(sb)

    a_and_b = parser("A & B")
    true_a_and_b = PLAnd([a, b])
    assert a_and_b == true_a_and_b

    material_implication = parser("!A | B <-> !(A & !B) <-> A->B")
    true_material_implication = PLEquivalence(
        [PLOr([PLNot(a), b]), PLNot(PLAnd([a, PLNot(b)])), PLImplies([a, b])]
    )

    assert material_implication == true_material_implication

    true_a_and_false_and_true = PLAnd([a, PLFalse(), PLTrue()])
    a_and_false_and_true = parser("A & false & true")

    assert a_and_false_and_true == true_a_and_false_and_true
Example #22
0
 def delta_box(self,
               f: LDLfFormula,
               i: PropositionalInterpretation,
               epsilon=False):
     """Apply delta function for regular expressions in the box operator."""
     if epsilon:
         return PLTrue()
     if self.pl_formula.truth(i):
         return PLAtomic(_expand(f))
     else:
         return PLTrue()
Example #23
0
def test_truth():
    sa, sb = "a", "b"
    a, b = PLAtomic(sa), PLAtomic(sb)

    i_ = PLFalseInterpretation()
    i_a = PLInterpretation({sa})
    i_b = PLInterpretation({sb})
    i_ab = PLInterpretation({sa, sb})

    tr_false_a_b_ab = FiniteTrace([i_, i_a, i_b, i_ab, i_])

    tt = LDLfLogicalTrue()
    ff = LDLfLogicalFalse()

    assert tt.truth(tr_false_a_b_ab, 0)
    assert not ff.truth(tr_false_a_b_ab, 0)
    assert not LDLfNot(tt).truth(tr_false_a_b_ab, 0)
    assert LDLfNot(ff).truth(tr_false_a_b_ab, 0)
    assert LDLfAnd([LDLfPropositional(a),
                    LDLfPropositional(b)]).truth(tr_false_a_b_ab, 3)
    assert not LDLfDiamond(RegExpPropositional(PLAnd([a, b])), tt).truth(
        tr_false_a_b_ab, 0)

    parser = LDLfParser()
    trace = FiniteTrace.from_symbol_sets([{}, {"A"}, {"A"}, {"A", "B"}, {}])

    formula = "<true*;A&B>tt"
    parsed_formula = parser(formula)
    assert parsed_formula.truth(trace, 0)

    formula = "[(A+!B)*]<C>tt"
    parsed_formula = parser(formula)
    assert not parsed_formula.truth(trace, 1)

    formula = "<(<!C>tt)?><A>tt"
    parsed_formula = parser(formula)
    assert parsed_formula.truth(trace, 1)

    formula = "<!C+A>tt"
    parsed_formula = parser(formula)
    assert parsed_formula.truth(trace, 1)
Example #24
0
    def test_next(self):
        parser = self.parser
        i_, i_a, i_b, i_ab = self.i_, self.i_a, self.i_b, self.i_ab
        true = self.true
        false = self.false

        assert parser("X A").delta(i_) == PLAnd(
            [PLAtomic(LTLfAtomic("A")), PLAtomic(LTLfEventually(LTLfTrue()).to_nnf())])
        assert parser("X A").delta(i_a) == PLAnd(
            [PLAtomic(LTLfAtomic("A")), PLAtomic(LTLfEventually(LTLfTrue()).to_nnf())])
        assert parser("X A").delta(i_b) == PLAnd(
            [PLAtomic(LTLfAtomic("A")), PLAtomic(LTLfEventually(LTLfTrue()).to_nnf())])
        assert parser("X A").delta(i_ab) == PLAnd(
            [PLAtomic(LTLfAtomic("A")), PLAtomic(LTLfEventually(LTLfTrue()).to_nnf())])
        assert parser("X A").delta(i_, epsilon=True) == false
Example #25
0
def to_automaton(f, labels: Optional[Set[Symbol]] = None):

    initial_state = frozenset({frozenset({PLAtomic(f)})})
    states = {initial_state}
    final_states = set()
    transition_function = {}

    # the alphabet is the powerset of the set of fluents
    alphabet = powerset(labels if labels is not None else f.find_labels())

    if f.delta(PLFalseInterpretation(), epsilon=True) == PLTrue():
        final_states.add(initial_state)

    visited = set()
    to_be_visited = {initial_state}

    while len(to_be_visited) != 0:

        for q in list(to_be_visited):
            to_be_visited.remove(q)
            for actions_set in alphabet:
                new_state = _make_transition(q, PLInterpretation(actions_set))
                if new_state not in states:
                    states.add(new_state)
                    to_be_visited.add(new_state)

                transition_function.setdefault(
                    q, {})[PLInterpretation(actions_set)] = new_state

                if new_state not in visited:
                    visited.add(new_state)
                    if _is_true(new_state):
                        final_states.add(new_state)

    new_alphabet = {PLInterpretation(set(sym)) for sym in alphabet}
    dfa = DFA(states, new_alphabet, initial_state, final_states,
              transition_function)
    dfa = dfa.minimize()
    dfa = dfa.trim()

    return dfa
Example #26
0
def _make_transition(marco_q: FrozenSet[FrozenSet[PLAtomic]],
                     i: PropositionalInterpretation):
    new_macrostate = set()

    for q in marco_q:
        # delta function applied to every formula in the macro state Q
        delta_formulas = [cast(Delta, f.s).delta(i) for f in q]

        # find atomics -> so also ldlf formulas
        # replace atomic with custom object
        # convert to sympy

        # find the list of atoms, which are "true" atoms
        # (i.e. propositional atoms) or LDLf formulas
        atomics = [s for subf in delta_formulas for s in find_atomics(subf)]

        atom2id = {v: str(k)
                   for k, v in enumerate(atomics)}  # type: Dict[PLAtomic, str]
        id2atom = {v: k
                   for k, v in atom2id.items()}  # type: Dict[str, PLAtomic]

        # build a map from formula to a "freezed" propositional Atomic Formula
        formula2atomic_formulas = {
            f: PLAtomic(atom2id[f]) if f != PLTrue()
            and f != PLFalse()  # and not isinstance(f, PLAtomic)
            else f
            for f in atomics
        }

        # the final list of Propositional Atomic Formulas,
        # one for each formula in the original macro state Q
        transformed_delta_formulas = [
            _transform_delta(f, formula2atomic_formulas)
            for f in delta_formulas
        ]

        # the empty conjunction stands for true
        if len(transformed_delta_formulas) == 0:
            conjunctions = PLTrue()
        elif len(transformed_delta_formulas) == 1:
            conjunctions = transformed_delta_formulas[0]
        else:
            conjunctions = PLAnd(transformed_delta_formulas)  # type: ignore

        # the model in this case is the smallest set of symbols
        # s.t. the conjunction of "freezed" atomic formula is true.
        # alphabet = frozenset(symbol2formula)
        # models = frozenset(conjunctions.minimal_models(alphabet))

        formula = to_sympy(conjunctions, replace=atom2id)  # type: ignore
        all_models = list(sympy.satisfiable(formula, all_models=True))
        if len(all_models) == 1 and all_models[0] == BooleanFalse():
            models = []  # type: List[Set[str]]
        elif len(all_models) == 1 and all_models[0] == {True: True}:
            models = [set()]
        else:
            models = list(
                map(lambda x: {k
                               for k, v in x.items()
                               if v is True}, all_models))

        for min_model in models:
            q_prime = frozenset({id2atom[s] for s in map(str, min_model)})
            new_macrostate.add(q_prime)

    return frozenset(new_macrostate)
Example #27
0
 def to_LDLf(self):
     return LDLfPropositional(PLAtomic(self.s)).convert()
Example #28
0
 def find_labels(self):
     return PLAtomic(self.s).find_labels()
Example #29
0
 def truth(self, i: FiniteTrace, pos: int = 0):
     return PLAtomic(self.s).truth(i.get(pos))
Example #30
0
 def _delta(self, i: PLInterpretation, epsilon: bool = False):
     if epsilon:
         return PLFalse()
     return PLTrue() if PLAtomic(self.s).truth(i) else PLFalse()