예제 #1
0
    def test_to_nnf_derived_formulas(self):
        fol = self.fol
        john = ConstantTerm.fromString("john")
        x = Variable.fromString("x")
        right_equal = Equal(x, john)
        true_ = TrueFormula()
        false_ = FalseFormula()
        or_ = Or(true_, Not(right_equal))
        implies_ = Implies(or_, false_)
        equivalence_ = Equivalence(implies_, false_)
        forall_true_ = ForAll(x, true_)
        forall_not_or_ = ForAll(x, Not(or_))
        forall_equivalence_ = ForAll(x, equivalence_)

        to_nnf_true_ = Equal(DUMMY_TERM, DUMMY_TERM)
        to_nnf_false_ = Not(Equal(DUMMY_TERM, DUMMY_TERM))
        to_nnf_or_ = Or(to_nnf_true_, Not(right_equal))
        to_nnf_not_or_ = And(Not(to_nnf_true_), right_equal)
        to_nnf_implies_ = Or(to_nnf_not_or_, to_nnf_false_)

        not_to_nnf_implies_ = And(to_nnf_or_, to_nnf_true_)
        positive_equivalence = And(to_nnf_implies_, to_nnf_false_)
        negative_equivalence = And(not_to_nnf_implies_, to_nnf_true_)
        to_nnf_equivalence_ = Or(positive_equivalence, negative_equivalence)

        self.assertEqual(fol.to_nnf(true_), to_nnf_true_)
        self.assertEqual(fol.to_nnf(false_), to_nnf_false_)
        self.assertEqual(fol.to_nnf(or_), to_nnf_or_)
        self.assertEqual(fol.to_nnf(implies_), to_nnf_implies_)
        self.assertEqual(fol.to_nnf(equivalence_), to_nnf_equivalence_)
        self.assertEqual(fol.to_nnf(forall_true_), ForAll(x, to_nnf_true_))
        self.assertEqual(fol.to_nnf(forall_not_or_), ForAll(x, to_nnf_not_or_))
        self.assertEqual(fol.to_nnf(forall_equivalence_),
                         ForAll(x, to_nnf_equivalence_))
예제 #2
0
 def test_truth_star(self):
     ref = self.ref
     a = self.a
     b = self.b
     c = self.c
     self.assertTrue(ref.truth(PathExpressionStar(a), self.trace_1, 0, 4))
     self.assertFalse(ref.truth(PathExpressionStar(a), self.trace_1, 0, 5))
     self.assertTrue(
         ref.truth(PathExpressionStar(Or(a, Or(b, c))), self.trace_1, 0, 5))
     self.assertTrue(ref.truth(TrueFormula(), self.trace_1, 0, 1))
예제 #3
0
    def test_to_nnf(self):
        f1 = Not(
            PathExpressionEventually(
                PathExpressionSequence(PathExpressionTest(Not(self.a_and_b)),
                                       PathExpressionStar(TrueFormula())),
                self.abc))
        nnf_f1 = PathExpressionAlways(
            PathExpressionSequence(
                PathExpressionTest(Or(Not(self.a), Not(self.b))),
                # PathExpressionStar(Or(DUMMY_ATOMIC, Not(DUMMY_ATOMIC)))
                PathExpressionStar(TrueFormula())),
            Or(Not(self.a), Or(Not(self.b), Not(self.c))))

        self.assertEqual(self.ldlf.to_nnf(f1), nnf_f1)
예제 #4
0
 def test_find_atomics(self):
     a = Symbol("a")
     b = Symbol("b")
     c = Symbol("c")
     atomic_a = AtomicFormula(a)
     atomic_b = AtomicFormula(b)
     atomic_c = AtomicFormula(c)
     self.assertEqual(
         PL.find_atomics(And(atomic_a, And(atomic_b, atomic_c))),
         {atomic_a, atomic_b, atomic_c})
     self.assertEqual(PL.find_atomics(Or(atomic_a, Or(atomic_b, atomic_c))),
                      {atomic_a, atomic_b, atomic_c})
     self.assertEqual(
         PL.find_atomics(Equivalence(atomic_a, Or(atomic_b, atomic_c))),
         {atomic_a, atomic_b, atomic_c})
예제 #5
0
    def setUp(self):
        """Set up test fixtures, if any."""
        self.a_sym = Symbol("a")
        self.b_sym = Symbol("b")
        self.c_sym = Symbol("c")
        self.alphabet = Alphabet({self.a_sym, self.b_sym, self.c_sym})

        # Propositions
        self.a = AtomicFormula(self.a_sym)
        self.b = AtomicFormula(self.b_sym)
        self.c = AtomicFormula(self.c_sym)

        self.not_a = Not(self.a)
        self.not_a_and_b = And(self.not_a, self.b)
        self.not_a_or_c = Or(self.not_a, self.c)
        self.true = TrueFormula()
        self.false = FalseFormula()

        self.symbol2truth = {
            self.a_sym: True,
            self.b_sym: False,
            self.c_sym: True
        }
        self.I = PLInterpretation(self.alphabet, self.symbol2truth)
        self.PL = PL(self.alphabet)
예제 #6
0
    def test_expand_formula_derived_formulas(self):
        fol = self.fol
        john = ConstantTerm.fromString("john")
        x = Variable.fromString("x")
        right_equal = Equal(x, john)
        true_ = TrueFormula()
        false_ = FalseFormula()
        or_ = Or(true_, Not(right_equal))
        implies_ = Implies(or_, false_)
        equivalence_ = Equivalence(implies_, false_)
        forall_ = ForAll(x, equivalence_)

        expanded_true = Equal(DUMMY_TERM, DUMMY_TERM)
        expanded_false = Not(Equal(DUMMY_TERM, DUMMY_TERM))
        expanded_or_ = Not(And(Not(expanded_true), Not(Not(right_equal))))
        expanded_implies_ = Not(And(expanded_or_, Not(expanded_false)))

        positive_equivalence = And(expanded_implies_, expanded_false)
        negative_equivalence = And(Not(expanded_implies_), Not(expanded_false))
        expanded_equivalence_ = Not(
            And(Not(positive_equivalence), Not(negative_equivalence)))

        self.assertEqual(fol.expand_formula(true_), expanded_true)
        self.assertEqual(fol.expand_formula(false_), expanded_false)
        self.assertEqual(fol.expand_formula(or_), expanded_or_)
        self.assertEqual(fol.expand_formula(implies_), expanded_implies_)
        self.assertEqual(fol.expand_formula(equivalence_),
                         expanded_equivalence_)
        self.assertEqual(fol.expand_formula(forall_),
                         Not(Exists(x, Not(expanded_equivalence_))))
예제 #7
0
 def to_nnf(self, f: Formula):
     # assert self.is_formula(f)
     # formula = self.expand_formula(f)
     formula = f
     if isinstance(formula, AtomicFormula) or isinstance(
             formula, TrueFormula) or isinstance(formula, FalseFormula):
         return formula
     elif isinstance(formula, And) or isinstance(formula, Or):
         return type(formula)(self.to_nnf(formula.f1),
                              self.to_nnf(formula.f2))
     elif type(formula) in self.derived_formulas:
         return self.to_nnf(self.derived_formulas[type(formula)](formula))
     elif isinstance(formula, Not):
         subformula = formula.f
         if isinstance(subformula, Not):
             return self.to_nnf(subformula.f)
         elif isinstance(subformula, And):
             return Or(self.to_nnf(Not(subformula.f1)),
                       self.to_nnf((Not(subformula.f2))))
         elif isinstance(subformula, Or):
             return And(self.to_nnf(Not(subformula.f1)),
                        self.to_nnf((Not(subformula.f2))))
         elif isinstance(subformula, AtomicFormula) or isinstance(
                 formula, TrueFormula) or isinstance(formula, FalseFormula):
             return formula
         elif type(subformula) in self.derived_formulas:
             return self.to_nnf(
                 Not(self.derived_formulas[type(subformula)](subformula)))
         else:
             raise ValueError
     else:
         raise ValueError
예제 #8
0
    def to_nnf(self, f: Formula):
        assert self.is_formula(f)
        formula = self.expand_formula(f)

        if isinstance(formula, PredicateFormula) or isinstance(formula, Equal):
            return formula
        elif isinstance(formula, And):
            return And(self.to_nnf(formula.f1), self.to_nnf(formula.f2))
        if isinstance(formula, Exists):
            return Exists(formula.v, self.to_nnf(formula.f))
        if isinstance(formula, Not):
            subformula = formula.f
            if isinstance(subformula, Not):
                return self.to_nnf(subformula.f)
            elif isinstance(subformula, And):
                return Or(self.to_nnf(Not(subformula.f1)),
                          self.to_nnf((Not(subformula.f2))))
            elif isinstance(subformula, Exists):
                return ForAll(subformula.v, self.to_nnf(Not(subformula.f)))
            elif isinstance(subformula, PredicateFormula) or isinstance(
                    subformula, Equal):
                return formula
            else:
                raise ValueError
        else:
            raise ValueError
예제 #9
0
 def test_to_nnf_allowed_formulas_not_normalized(self):
     a_sym = Symbol("a")
     b_sym = Symbol("b")
     alphabet = Alphabet({a_sym, b_sym})
     a = AtomicFormula(a_sym)
     b = AtomicFormula(b_sym)
     pl = PL(alphabet)
     self.assertEqual(pl.to_nnf(Not(Not(b))), b)
     self.assertEqual(pl.to_nnf(Not(And(a, Not(b)))), Or(Not(a), b))
예제 #10
0
 def test_to_nnf_derived_formula(self):
     a_sym = Symbol("a")
     b_sym = Symbol("b")
     alphabet = Alphabet({a_sym, b_sym})
     a = AtomicFormula(a_sym)
     b = AtomicFormula(b_sym)
     pl = PL(alphabet)
     self.assertEqual(pl.to_nnf(Not(Or(b, Not(a)))), And(Not(b), a))
     self.assertEqual(pl.to_nnf(Not(Implies(b, Not(a)))), And(b, a))
예제 #11
0
    def test_is_formula_derived(self):
        fol = self.fol
        john = ConstantTerm.fromString("john")
        not_a_term = ConstantTerm.fromString("NotATerm")
        x = Variable.fromString("x")
        y = Variable.fromString("y")
        right_equal = Equal(x, john)
        wrong_equal = Equal(x, not_a_term)

        self.assertTrue(fol.is_formula(TrueFormula()))
        self.assertTrue(fol.is_formula(FalseFormula()))

        self.assertTrue(fol.is_formula(Or(right_equal, right_equal)))
        self.assertFalse(fol.is_formula(Or(right_equal, wrong_equal)))

        self.assertTrue(fol.is_formula(Or(right_equal, right_equal)))
        self.assertFalse(fol.is_formula(Or(right_equal, wrong_equal)))

        self.assertTrue(fol.is_formula(Implies(right_equal, right_equal)))
        self.assertFalse(fol.is_formula(Implies(right_equal, wrong_equal)))

        self.assertTrue(fol.is_formula(Equivalence(right_equal, right_equal)))
        self.assertFalse(fol.is_formula(Equivalence(right_equal, wrong_equal)))

        self.assertTrue(
            fol.is_formula(
                ForAll(x,
                       PredicateFormula(PredicateSymbol("Person", 2), john,
                                        x))))
        self.assertFalse(
            fol.is_formula(
                ForAll(
                    x,
                    PredicateFormula(PredicateSymbol("Person", 3), john, x,
                                     john))))
        self.assertFalse(
            fol.is_formula(
                ForAll(
                    x,
                    PredicateFormula(PredicateSymbol("Person_fake", 2), john,
                                     x))))
예제 #12
0
 def to_nnf(self, formula: Formula) -> Formula:
     if isinstance(formula, AtomicFormula):
         return formula
     elif isinstance(formula, And):
         return And(self.to_nnf(formula.f1), self.to_nnf(formula.f2))
     elif isinstance(formula, Or):
         return Or(self.to_nnf(formula.f1), self.to_nnf(formula.f2))
     elif isinstance(formula, PathExpressionFormula):
         return type(formula)(self.to_nnf_path(formula.p), self.to_nnf(formula.f))
     elif isinstance(formula, Not):
         return self._not_to_nnf(formula)
     else:
         raise ValueError
예제 #13
0
 def _not_to_nnf(self, not_formula: Not):
     subformula = not_formula.f
     if isinstance(subformula, AtomicFormula):
         return not_formula
     if isinstance(subformula, Not):
         # skip two consecutive Not
         new_formula = subformula.f
         return self.to_nnf(new_formula)
     elif isinstance(subformula, And):
         return Or(self.to_nnf(Not(subformula.f1)), self.to_nnf(Not(subformula.f2)))
     elif isinstance(subformula, Or):
         return And(self.to_nnf(Not(subformula.f1)), self.to_nnf(Not(subformula.f2)))
     elif isinstance(subformula, PathExpressionEventually):
         return PathExpressionAlways(self.to_nnf_path(subformula.p), self.to_nnf(Not(subformula.f)))
     elif isinstance(subformula, PathExpressionAlways):
         return PathExpressionEventually(self.to_nnf_path(subformula.p), self.to_nnf(Not(subformula.f)))
     else:
         raise ValueError
예제 #14
0
 def test_expand_formula_composed(self):
     a_sym = Symbol("a")
     alphabet = Alphabet({a_sym})
     a = AtomicFormula(a_sym)
     # T = Not(And(Not(DUMMY_ATOMIC), DUMMY_ATOMIC))
     # F = And(Not(DUMMY_ATOMIC), DUMMY_ATOMIC)
     T = TrueFormula()
     F = FalseFormula()
     pl = PL(alphabet)
     self.assertEqual(pl.expand_formula(And(TrueFormula(), FalseFormula())),
                      And(T, F))
     self.assertEqual(pl.expand_formula(Or(TrueFormula(), FalseFormula())),
                      Not(And(Not(T), Not(F))))
     self.assertEqual(
         pl.expand_formula(Implies(TrueFormula(), FalseFormula())),
         Not(And(Not(Not(T)), Not(F))))
     self.assertEqual(
         pl.expand_formula(Equivalence(TrueFormula(), FalseFormula())),
         Not(And(Not(And(T, F)), Not(And(Not(T), Not(F))))))
예제 #15
0
 def test_expand_formula_derived_formulas(self):
     a_sym = Symbol("a")
     b_sym = Symbol("b")
     alphabet = Alphabet({a_sym, b_sym})
     a = AtomicFormula(a_sym)
     b = AtomicFormula(b_sym)
     # T = Not(And(Not(DUMMY_ATOMIC), DUMMY_ATOMIC))
     # F = And(Not(DUMMY_ATOMIC), DUMMY_ATOMIC)
     T = TrueFormula()
     F = FalseFormula()
     pl = PL(alphabet)
     self.assertEqual(pl.expand_formula(TrueFormula()), T)
     self.assertEqual(pl.expand_formula(FalseFormula()), F)
     self.assertEqual(pl.expand_formula(Or(a, b)), Not(And(Not(a), Not(b))))
     self.assertEqual(pl.expand_formula(Implies(a, b)),
                      Not(And(Not(Not(a)), Not(b))))
     self.assertEqual(pl.expand_formula(Implies(b, a)),
                      Not(And(Not(Not(b)), Not(a))))
     # A === B = (A AND B) OR (NOT A AND NOT B) = NOT( NOT(A AND B) AND NOT(NOT A AND NOT B) )
     self.assertEqual(pl.expand_formula(Equivalence(a, b)),
                      Not(And(Not(And(a, b)), Not(And(Not(a), Not(b))))))
예제 #16
0
    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
            })})
예제 #17
0
    def setUp(self):
        """Set up test fixtures, if any."""
        # Symbols
        self.a_sym = Symbol("a")
        self.b_sym = Symbol("b")
        self.c_sym = Symbol("c")

        # Propositions
        self.a = AtomicFormula(self.a_sym)
        self.b = AtomicFormula(self.b_sym)
        self.c = AtomicFormula(self.c_sym)

        # Propositionals
        self.not_a = Not(self.a)
        self.not_b = Not(self.b)
        self.not_c = Not(self.c)
        self.a_and_b = And(self.a, self.b)
        self.a_and_c = And(self.a, self.c)
        self.b_and_c = And(self.b, self.c)
        self.abc = And(self.a, And(self.b, self.c))
        self.b_or_c = Or(self.b, self.c)
        self.a_or_b = Or(self.a, self.b)
        self.not_abc = Not(And(self.a, And(self.b, self.c)))

        ### Path expression
        # Tests
        self.test_a = PathExpressionTest(self.a)
        self.test_b = PathExpressionTest(self.b)
        self.test_not_a = PathExpressionTest(self.not_a)
        self.test_not_b = PathExpressionTest(self.not_b)
        # Union
        self.path_a_or_b = PathExpressionUnion(self.a, self.b)
        self.path_b_or_c = PathExpressionUnion(self.b, self.c)
        # Sequence
        self.path_seq_a_and_b__a_and_c = PathExpressionSequence(
            self.a_and_b, self.a_and_c)
        self.path_a_or_b__b_or_c = PathExpressionSequence(
            self.path_a_or_b, self.path_b_or_c)
        # Stars
        self.path_b_or_c_star = PathExpressionStar(self.path_b_or_c)
        self.path_not_abc = PathExpressionStar(self.not_abc)

        # Modal connective
        self.eventually_propositional_a_and_b__a_and_c = PathExpressionEventually(
            self.a_and_b, self.a_and_c)
        self.eventually_test_a__c = PathExpressionEventually(
            self.test_a, self.c)
        self.eventually_test_a__b = PathExpressionEventually(
            self.test_a, self.b)
        self.eventually_seq_a_and_b__a_and_c__not_c = PathExpressionEventually(
            self.path_seq_a_and_b__a_and_c, self.not_c)
        self.eventually_seq_a_and_b__a_and_c__c = PathExpressionEventually(
            self.path_seq_a_and_b__a_and_c, self.c)
        self.eventually_b_or_c_star__b_and_c = PathExpressionEventually(
            self.path_b_or_c_star, self.b_and_c)

        self.next_a_and_c = PathExpressionEventually(TrueFormula(),
                                                     self.a_and_c)
        self.liveness_b_and_c = PathExpressionEventually(
            PathExpressionStar(TrueFormula()), self.b_and_c)
        self.liveness_abc = PathExpressionEventually(
            PathExpressionStar(TrueFormula()), self.abc)

        self.always_true__a = PathExpressionAlways(
            PathExpressionStar(TrueFormula()), self.a)
        self.always_true__b_or_c = PathExpressionAlways(
            PathExpressionStar(TrueFormula()), self.b_or_c)

        self.alphabet = Alphabet({self.a_sym, self.b_sym, self.c_sym})
        # Traces
        self.ldlf = LDLf(self.alphabet)
        self.trace_1_list = [
            {self.a_sym, self.b_sym},
            {self.a_sym, self.c_sym},
            {self.a_sym, self.b_sym},
            {self.a_sym, self.c_sym},
            {self.b_sym, self.c_sym},
        ]
        self.trace_1 = FiniteTrace(self.trace_1_list, self.alphabet)
예제 #18
0
    def setUp(self):
        """Set up symbols, terms and formulas. Both legal and illegal, according to some FOL system"""

        # Symbols
        self.a_sym = Symbol('a')
        self.b_sym = Symbol('b')
        self.const_sym = ConstantSymbol("Const")
        self.fun_sym = FunctionSymbol("Fun", 3)
        self.predicate_sym = PredicateSymbol("Predicate", 2)
        self.A = PredicateSymbol("A", 1)

        # Terms
        self.a = Variable(self.a_sym)
        self.b = Variable(self.b_sym)
        self.c = Variable.fromString("c")
        self.const = ConstantTerm(self.const_sym)
        self.fun_abc = FunctionTerm(self.fun_sym, self.a, self.b, self.c)

        # Formulas
        self.predicate_ab = PredicateFormula(self.predicate_sym, self.a,
                                             self.b)
        self.predicate_ac = PredicateFormula(self.predicate_sym, self.a,
                                             self.c)
        self.A_a = PredicateFormula(self.A, self.a)
        self.a_equal_a = Equal(self.a, self.a)
        self.b_equal_c = Equal(self.b, self.c)
        self.neg_a_equal_a = Not(self.a_equal_a)
        self.neg_Aa = Not(self.A_a)
        self.Aa_and_b_equal_c = And(self.A_a, self.b_equal_c)
        self.Aa_or_b_equal_c = Or(self.A_a, self.b_equal_c)
        self.Aa_implies_b_equal_c = Implies(self.A_a, self.b_equal_c)
        self.exists_a_predicate_ab = Exists(self.a, self.predicate_ab)
        self.forall_b_exists_a_predicate_ab = ForAll(
            self.b, self.exists_a_predicate_ab)

        # FOL
        self.vars = {self.a, self.b, self.c}
        self.functions = {self.const_sym, self.fun_sym}
        self.predicates = {self.predicate_sym, self.A}

        self.alphabet = FOLAlphabet(self.functions, self.predicates)
        self.myFOL = FOL(self.alphabet)

        # define dummy stuff
        # does not belong to myFOL. They are used for test membership to myFOL
        self.dummy_variable = Variable.fromString(
            "ThisVariableDoesNotBelongToFOLSystem")
        self.dummy_fun_sym = FunctionSymbol(
            "ThisFunctionDoesNotBelongToFOLSystem", 3)
        self.dummy_constant_sym = ConstantSymbol(
            "ThisConstDoesNotBelongToFOLSystem")
        self.dummy_predicate_sym = PredicateSymbol(
            "ThisPredicateDoesNotBelongToFOLSystem", 2)

        self.dummy_fun = FunctionTerm(self.dummy_fun_sym, self.a, self.b,
                                      self.dummy_variable)
        self.dummy_constant = ConstantTerm(self.dummy_constant_sym)

        self.dummy_predicate = PredicateFormula(self.dummy_predicate_sym,
                                                self.a, self.b)
        self.dummy_predicate_only_one_symbol_false = PredicateFormula(
            self.predicate_sym, self.dummy_variable, self.dummy_constant)
        self.dummy_equal = Equal(self.c, self.dummy_constant)
        self.dummy_neg = Not(self.dummy_predicate_only_one_symbol_false)
        self.dummy_and = And(self.dummy_predicate, self.predicate_ab)
        self.dummy_or = Or(self.dummy_predicate_only_one_symbol_false,
                           self.predicate_ac)

        self.dummy_exists = Exists(self.dummy_variable,
                                   self.dummy_predicate_only_one_symbol_false)
        self.dummy_forall = ForAll(self.b, self.dummy_predicate)
예제 #19
0
    def test_truth(self):
        w = Variable.fromString("w")
        Person_x_20 = PredicateFormula(self.Person_pred_sym, self.x,
                                       ConstantTerm.fromString("20"))
        Person_x_y = PredicateFormula(self.Person_pred_sym, self.x, self.y)
        not_Person_x_21 = Not(
            PredicateFormula(self.Person_pred_sym, self.x,
                             ConstantTerm.fromString("21")))
        y_equal_20 = Equal(self.y, ConstantTerm.fromString("20"))
        x_equal_john = Equal(self.x, ConstantTerm.fromString("john"))
        x_equal_x = Equal(self.x, self.x)
        x_equal_y = Equal(self.x, self.y)
        x_equal_z = Equal(self.x, self.z)

        x_lives_w = PredicateFormula(self.Lives_pred_sym, self.x, w)
        x_lives_y = PredicateFormula(self.Lives_pred_sym, self.x, self.y)
        x_lives_ny = PredicateFormula(self.Lives_pred_sym, self.x,
                                      ConstantTerm.fromString("ny"))
        x_lives_paris = PredicateFormula(self.Lives_pred_sym, self.x,
                                         ConstantTerm.fromString("paris"))
        w_lives_z = PredicateFormula(self.Lives_pred_sym, w, self.z)

        exists_w__x_lives_w = Exists(w, x_lives_w)
        exists_y__x_lives_y = Exists(self.y, x_lives_y)
        exists_z_exists_w__w_lives_z = Exists(self.z, Exists(w, w_lives_z))
        exists_x__x_equal_x = Exists(self.x, x_equal_x)
        exists_x__x_equal_y = Exists(self.x, x_equal_y)
        exists_x__x_equal_john_and_Lives_x_paris = Exists(
            self.x, And(x_equal_john, x_lives_paris))
        exists_x__x_equal_john_and_exists_x__Lives_x_ny = And(
            Exists(self.x, x_equal_john), Exists(self.x, x_lives_ny))
        exists_x__x_equal_x_and_exists_x__Lives_x_ny = And(
            exists_x__x_equal_x, Exists(self.x, x_lives_ny))

        forall_x__x_equal_x = ForAll(self.x, x_equal_x)
        forall_x__x_equal_y = ForAll(self.x, x_equal_y)
        not_forall_x__x_equal_x = Not(forall_x__x_equal_x)

        # Person(x, 20)
        # x = "john"
        self.assertTrue(self.FOL.truth(Person_x_20, self.assignment))

        # ~Person(x, 21)
        # x = "john"
        self.assertTrue(self.FOL.truth(not_Person_x_21, self.assignment))

        # Equals
        self.assertTrue(self.FOL.truth(y_equal_20, self.assignment))
        self.assertTrue(self.FOL.truth(x_equal_x, self.assignment))
        self.assertFalse(self.FOL.truth(x_equal_y, self.assignment))
        self.assertFalse(self.FOL.truth(x_equal_z, self.assignment))

        # y == 20 and x == "john" and Person(x, y)
        self.assertTrue(
            self.FOL.truth(And(y_equal_20, And(x_equal_john, Person_x_y)),
                           self.assignment))

        self.assertTrue(
            self.FOL.truth(Or(Person_x_20, x_equal_john), self.assignment))
        # De Morgan on previous formula
        # Not (Not y == 20 or Not x == "john" ot Not Person(x, y)
        self.assertTrue(
            self.FOL.truth(
                Not(Or(Not(y_equal_20), Or(Not(x_equal_john),
                                           Not(Person_x_y)))),
                self.assignment))

        # Or with the last formula true
        self.assertTrue(
            self.FOL.truth(
                Or(Equal(self.x, self.y),
                   Or(Equal(self.x, self.y), Equal(self.z, self.z))),
                self.assignment))

        # (y==20 and x=="john") => Person(x,y)
        self.assertTrue(
            self.FOL.truth(Implies(And(y_equal_20, x_equal_john), Person_x_y),
                           self.assignment))

        self.assertTrue(
            self.FOL.truth(Implies(Not(x_equal_x), Person_x_y),
                           self.assignment))

        # Exists
        self.assertTrue(self.FOL.truth(exists_w__x_lives_w, self.assignment))
        self.assertTrue(self.FOL.truth(exists_x__x_equal_x, self.assignment))
        self.assertTrue(self.FOL.truth(exists_x__x_equal_y, self.assignment))
        # quantified variable not present in the formula
        self.assertTrue(self.FOL.truth(exists_y__x_lives_y, self.assignment))
        # 2 quantified variables
        self.assertTrue(
            self.FOL.truth(exists_z_exists_w__w_lives_z, self.assignment))
        # annidate exists
        self.assertTrue(
            self.FOL.truth(exists_x__x_equal_john_and_exists_x__Lives_x_ny,
                           self.assignment))
        self.assertTrue(
            self.FOL.truth(exists_x__x_equal_x_and_exists_x__Lives_x_ny,
                           self.assignment))
        self.assertFalse(
            self.FOL.truth(exists_x__x_equal_john_and_Lives_x_paris,
                           self.assignment))

        # ForAll
        self.assertTrue(self.FOL.truth(forall_x__x_equal_x, self.assignment))
        self.assertFalse(self.FOL.truth(forall_x__x_equal_y, self.assignment))
        self.assertFalse(
            self.FOL.truth(not_forall_x__x_equal_x, self.assignment))
예제 #20
0
 def delta(self, f: Formula, action: FrozenSet[Symbol], epsilon=False):
     # TODO: should return [True|False]Formula or simply True/False?
     pl, I = PL._from_set_of_propositionals(action, self.alphabet)
     if pl.is_formula(f):
         return self.delta(PathExpressionEventually(f, LogicalTrue()),
                           action, epsilon)
     elif isinstance(f, LogicalTrue):
         return TrueFormula()
     elif isinstance(f, LogicalFalse):
         return FalseFormula()
     elif isinstance(f, And):
         return And(self.delta(f.f1, action),
                    self.delta(f.f2, action, epsilon))
     elif isinstance(f, Or):
         return Or(self.delta(f.f1, action),
                   self.delta(f.f2, action, epsilon))
     elif isinstance(f, PathExpressionEventually):
         if pl.is_formula(f.p):
             if not epsilon and pl.truth(f.p, I):
                 return self._expand(f.f)
             else:
                 return FalseFormula()
         elif isinstance(f.p, PathExpressionTest):
             return And(self.delta(f.p.f, action, epsilon),
                        self.delta(f.f, action, epsilon))
         elif isinstance(f.p, PathExpressionUnion):
             return Or(
                 self.delta(PathExpressionEventually(f.p.p1, f.f), action,
                            epsilon),
                 self.delta(PathExpressionEventually(f.p.p2, f.f), action,
                            epsilon))
         elif isinstance(f.p, PathExpressionSequence):
             e2 = PathExpressionEventually(f.p.p2, f.f)
             e1 = PathExpressionEventually(f.p.p1, e2)
             return self.delta(e1, action, epsilon)
         elif isinstance(f.p, PathExpressionStar):
             o1 = self.delta(f.f, action, epsilon)
             o2 = self.delta(PathExpressionEventually(f.p.p, F(f)), action,
                             epsilon)
             return Or(o1, o2)
     elif isinstance(f, PathExpressionAlways):
         if pl.is_formula(f.p):
             if not epsilon and pl.truth(f.p, I):
                 return self._expand(f.f)
             else:
                 return TrueFormula()
         elif isinstance(f.p, PathExpressionTest):
             o1 = self.delta(self.to_nnf(Not(f.p.f)), action, epsilon)
             o2 = self.delta(f.f, action, epsilon)
             return Or(o1, o2)
         elif isinstance(f.p, PathExpressionUnion):
             return And(
                 self.delta(PathExpressionAlways(f.p.p1, f.f), action,
                            epsilon),
                 self.delta(PathExpressionAlways(f.p.p2, f.f), action,
                            epsilon))
         elif isinstance(f.p, PathExpressionSequence):
             return self.delta(
                 PathExpressionAlways(f.p.p1,
                                      PathExpressionAlways(f.p.p2, f.f)),
                 action, epsilon)
         elif isinstance(f.p, PathExpressionStar):
             a1 = self.delta(f.f, action, epsilon)
             a2 = self.delta(PathExpressionAlways(f.p.p, T(f)), action,
                             epsilon)
             return And(a1, a2)
     elif isinstance(f, F):
         return FalseFormula()
     elif isinstance(f, T):
         return TrueFormula()
     else:
         raise ValueError
예제 #21
0
def _implies_to_or(f: Implies) -> Formula:
    equivalent_formula = Or(Not(f.f1), f.f2)
    return _or_to_and(equivalent_formula)