示例#1
0
    def test_expand_formula_error(self):
        a_sym = Symbol("a")
        alphabet = Alphabet({a_sym})
        a = Next(AtomicFormula(a_sym))
        pl = PL(alphabet)

        with self.assertRaises(ValueError) as ve:
            pl.expand_formula(a)
示例#2
0
 def test_expand_formula_allowed_formulas(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.expand_formula(a), a)
     self.assertEqual(pl.expand_formula(Not(b)), Not(b))
     self.assertEqual(pl.expand_formula(And(a, b)), And(a, b))
示例#3
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))))))
示例#4
0
 def _expand_path(self, p: PathExpression) -> PathExpression:
     if isinstance(p, PathExpressionUnion) or isinstance(
             p, PathExpressionSequence):
         return type(p)(self._expand_path(p.p1), self._expand_path(p.p2))
     elif isinstance(p, PathExpressionTest):
         return PathExpressionTest(self.expand_formula(p.f))
     elif isinstance(p, PathExpressionStar):
         return PathExpressionStar(self._expand_path(p.p))
     elif isinstance(p, Formula):
         pl = PL(self.alphabet)
         return pl.expand_formula(p)
     else:
         raise ValueError
示例#5
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))))))
示例#6
0
class REf(FormalSystem):
    def __init__(self, alphabet: Alphabet):
        super().__init__(alphabet)
        self.pl = PL(self.alphabet)

    allowed_formulas = {
        PathExpressionUnion, PathExpressionSequence, PathExpressionStar,
        AtomicFormula, And, Not
    }
    derived_formulas = {Or, Implies, Equivalence, TrueFormula, FalseFormula}

    def _is_formula(self, f: Formula):
        """Check if a formula is legal in the current formal system"""
        if isinstance(f, PathExpressionUnion):
            return self.is_formula(f.p1) and self.is_formula(f.p2)
        elif isinstance(f, PathExpressionSequence):
            return self._is_formula(f.p1) and self._is_formula(f.p2)
        elif isinstance(f, PathExpressionStar):
            return self._is_formula(f.p)
        else:
            pl = PL(self.alphabet)
            return pl.is_formula(f)

    def _truth(self, f: Formula, trace: FiniteTrace, start: int, end: int):
        assert self._is_formula(f)
        assert trace.alphabet == self.alphabet
        truth = self.truth
        if isinstance(f, PathExpressionUnion):
            return truth(f.p1, trace, start, end) or truth(
                f.p2, trace, start, end)
        if isinstance(f, PathExpressionSequence):
            return any(
                truth(f.p1, trace, start, k) and truth(f.p2, trace, k, end)
                for k in range(start, end + 1))
        if isinstance(f, PathExpressionStar):
            return end == start or any(
                truth(f.p, trace, start, k) and truth(f, trace, k, end)
                for k in range(start, end + 1))
        else:
            pl, I = PL._from_set_of_propositionals(trace.get(start),
                                                   self.alphabet)
            assert pl.is_formula(f)
            return end == start + 1 and end <= trace.length() and pl.truth(
                f, I)

    def to_nnf(self, f: Formula):
        if isinstance(f, PathExpressionUnion):
            return PathExpressionUnion(self.to_nnf(f.p1), self.to_nnf(f.p2))
        elif isinstance(f, PathExpressionSequence):
            return PathExpressionSequence(self.to_nnf(f.p1), self.to_nnf(f.p2))
        elif isinstance(f, PathExpressionStar):
            return PathExpressionStar(self.to_nnf(f.p))
        elif isinstance(f, Formula):
            pl = PL(self.alphabet)
            assert pl.is_formula(f)
            return f
        else:
            raise ValueError

    def to_equivalent_formula(self, derived_formula: Formula):
        return self.pl.to_equivalent_formula(derived_formula)

    def _expand_formula(self, f: Formula):
        if self.pl.is_formula(f):
            return self.pl.expand_formula(f)
        else:
            return f