Пример #1
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
Пример #2
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
Пример #3
0
    def test_and(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 & b").delta(i_) == PLAnd([false, false])
        assert parser("a & b").delta(i_a) == PLAnd([true, false])
        assert parser("a & b").delta(i_b) == PLAnd([false, true])
        assert parser("a & b").delta(i_ab) == PLAnd([true, true])
        assert parser("a & b").delta(i_, epsilon=True) == false
Пример #4
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
Пример #5
0
    def test_and(self):
        a, b = self.a, self.b
        i_, i_a, i_b, i_ab = self.i_, self.i_a, self.i_b, self.i_ab

        a_and_b = PLAnd([a, b])
        assert not a_and_b.truth(i_)
        assert not a_and_b.truth(i_a)
        assert not a_and_b.truth(i_b)
        assert a_and_b.truth(i_ab)

        not_a_and_not_b = PLAnd([PLNot(a), PLNot(b)])
        assert not_a_and_not_b.truth(i_)
        assert not not_a_and_not_b.truth(i_a)
        assert not not_a_and_not_b.truth(i_b)
        assert not not_a_and_not_b.truth(i_ab)
Пример #6
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
Пример #7
0
 def _delta(self, i: PLInterpretation, epsilon=False):
     if epsilon:
         return PLFalse()
     else:
         return PLAnd(
             [PLAtomic(self.f),
              PLAtomic(LTLfNot(LTLfEnd()).to_nnf())])
Пример #8
0
 def delta_diamond(self,
                   f: LDLfFormula,
                   i: PropositionalInterpretation,
                   epsilon=False) -> PLFormula:
     """Apply delta function for regular expressions in the diamond operator."""
     return PLAnd([self.f._delta(i, epsilon),
                   f._delta(i, epsilon)])  # type: ignore
Пример #9
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())])
Пример #10
0
 def prop_and(self, args):
     if len(args) == 1:
         return args[0]
     elif (len(args) - 1) % 2 == 0:
         subformulas = args[::2]
         return PLAnd(subformulas)
     else:
         raise ParsingError
Пример #11
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)
Пример #12
0
 def delta_box(self,
               f: LDLfFormula,
               i: PropositionalInterpretation,
               epsilon=False):
     """Apply delta function for regular expressions in the box operator."""
     return PLAnd([
         f._delta(i, epsilon),
         LDLfBox(self.f, _FreezedTrue(LDLfBox(self, f)))._delta(i, epsilon),
     ])
Пример #13
0
 def delta_box(self, f: LDLfFormula, i: PLInterpretation, epsilon=False):
     # subf = LDLfBox(self.f, T(LDLfBox(self, f)))
     # k = subf._delta(i, epsilon)
     # l = [f._delta(i, epsilon), subf]
     # ff = PLAnd(l)
     return PLAnd([
         f._delta(i, epsilon),
         LDLfBox(self.f, T(LDLfBox(self, f)))._delta(i, epsilon)
     ])
Пример #14
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
Пример #15
0
 def _delta(self, i: PLInterpretation, epsilon: bool = False):
     if epsilon:
         return PLFalse()
     f1 = self.formulas[0]
     f2 = LTLfUntil(
         self.formulas[1:]) if len(self.formulas) > 2 else self.formulas[1]
     return PLOr([
         f2._delta(i, epsilon),
         PLAnd([f1._delta(i, epsilon),
                LTLfNext(self)._delta(i, epsilon)])
     ])
Пример #16
0
 def _delta(self, i: PLInterpretation, epsilon=False):
     if epsilon:
         return PLTrue()
     f1 = self.formulas[0]
     f2 = LTLfRelease(
         self.formulas[1:]) if len(self.formulas) > 2 else self.formulas[1]
     return PLAnd([
         f2._delta(i, epsilon),
         PLOr(
             [f1._delta(i, epsilon),
              LTLfWeakNext(self)._delta(i, epsilon)])
     ])
Пример #17
0
 def _delta(self, i: PropositionalInterpretation, epsilon: bool = False):
     """Apply the delta function."""
     if epsilon:
         return PLFalse()
     f1 = self.formulas[0]
     f2 = (LTLfUntil(self.formulas[1:])
           if len(self.formulas) > 2 else self.formulas[1])
     return PLOr([
         f2._delta(i, epsilon),
         PLAnd([f1._delta(i, epsilon),
                LTLfNext(self)._delta(i, epsilon)]),
     ])
Пример #18
0
    def test_misc(self):
        a, b = self.a, self.b
        i_, i_a, i_b, i_ab = self.i_, self.i_a, self.i_b, self.i_ab

        material_implication = PLEquivalence(
            [PLOr([PLNot(a), b]), PLNot(PLAnd([a, PLNot(b)])), PLImplies([a, b])]
        )

        # the equivalence is valid (i.e. satisfied for every interpretation)
        assert material_implication.truth(i_)
        assert material_implication.truth(i_a)
        assert material_implication.truth(i_b)
        assert material_implication.truth(i_ab)

        a_and_false_and_true = PLAnd([a, PLFalse(), PLTrue()])
        assert not a_and_false_and_true.truth(i_)
        assert not a_and_false_and_true.truth(i_a)
        assert not a_and_false_and_true.truth(i_b)
        assert not a_and_false_and_true.truth(i_ab)

        a_or_false_or_true = PLOr([a, PLFalse(), PLTrue()])
        assert a_or_false_or_true.truth(i_)
        assert a_or_false_or_true.truth(i_a)
        assert a_or_false_or_true.truth(i_b)
        assert a_or_false_or_true.truth(i_ab)
Пример #19
0
def _is_true(Q: FrozenSet[FrozenSet]):
    if frozenset() in Q:
        return True
    conj = [
        PLAnd([subf.s.delta(None, epsilon=True)
               for subf in q]) if len(q) >= 2 else next(iter(q)).s.delta(
                   None, epsilon=True) if len(q) == 1 else PLFalse() for q in Q
    ]
    if len(conj) == 0:
        return False
    else:
        pl_conj = PLOr(conj) if len(conj) >= 2 else conj[0]
        result = pl_conj.truth({})
        return result
Пример #20
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
    )
Пример #21
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
Пример #22
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
Пример #23
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)
Пример #24
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)
Пример #25
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)
Пример #26
0
 def delta_diamond(self,
                   f: LDLfFormula,
                   i: PLInterpretation,
                   epsilon=False):
     return PLAnd([self.f._delta(i, epsilon), f._delta(i, epsilon)])
Пример #27
0
 def delta_box(self, f: LDLfFormula, i: PLInterpretation, epsilon=False):
     return PLAnd(
         [LDLfBox(r, f)._delta(i, epsilon) for r in self.formulas_set])
Пример #28
0
def test_parser():
    parser = LDLfParser()
    a, b = PLAtomic("A"), PLAtomic("B")

    tt = LDLfLogicalTrue()
    ff = LDLfLogicalFalse()
    true = PLTrue()
    false = PLFalse()
    r_true = RegExpPropositional(true)
    r_false = RegExpPropositional(false)

    assert tt == parser("tt")
    assert ff == parser("ff")
    assert LDLfDiamond(r_true, tt) == parser("<true>tt")
    assert LDLfDiamond(r_false, tt) == parser("<false>tt")
    assert parser("!tt & <!A&B>tt") == LDLfAnd([
        LDLfNot(tt),
        LDLfDiamond(RegExpPropositional(PLAnd([PLNot(a), b])), tt)
    ])
    assert parser("[true*]([true]ff | <!A>tt | <(true)*><B>tt)") == LDLfBox(
        RegExpStar(r_true),
        LDLfOr([
            LDLfBox(r_true, ff),
            LDLfDiamond(RegExpPropositional(PLNot(a)), tt),
            LDLfDiamond(RegExpStar(r_true),
                        (LDLfDiamond(RegExpPropositional(b), tt))),
        ]),
    )

    assert parser("[A&B&A]ff <-> <A&B&A>tt") == LDLfEquivalence([
        LDLfBox(RegExpPropositional(PLAnd([a, b, a])), ff),
        LDLfDiamond(RegExpPropositional(PLAnd([a, b, a])), tt),
    ])

    assert parser("<A+B>tt") == LDLfDiamond(
        RegExpUnion([RegExpPropositional(a),
                     RegExpPropositional(b)]), tt)
    assert parser("<A;B>tt") == LDLfDiamond(
        RegExpSequence([RegExpPropositional(a),
                        RegExpPropositional(b)]), tt)
    assert parser("<A+(B;A)>end") == LDLfDiamond(
        RegExpUnion([
            RegExpPropositional(a),
            RegExpSequence([RegExpPropositional(b),
                            RegExpPropositional(a)]),
        ]),
        LDLfEnd(),
    )

    assert parser("!(<(!(A<->D))+((B;C)*)+(?!last)>[(true)*]end)") == LDLfNot(
        LDLfDiamond(
            RegExpUnion([
                RegExpPropositional(PLNot(PLEquivalence([a, PLAtomic("D")]))),
                RegExpStar(
                    RegExpSequence([
                        RegExpPropositional(PLAtomic("B")),
                        RegExpPropositional(PLAtomic("C")),
                    ])),
                RegExpTest(LDLfNot(LDLfLast())),
            ]),
            LDLfBox(RegExpStar(RegExpPropositional(PLTrue())), LDLfEnd()),
        ))
Пример #29
0
 def _delta(self, i: PLInterpretation, epsilon=False):
     return PLAnd([f._delta(i, epsilon) for f in self.formulas])
Пример #30
0
 def _delta(self, i: PropositionalInterpretation, epsilon=False):
     """Apply the delta function."""
     return PLAnd([f._delta(i, epsilon) for f in self.formulas])