def test_miniscope(self): """ miniscoped normal form """ f = expr("forall z: exists x: P(z) ==> Q(z) | ~Q(x)") e = expr("forall z: ~P(z) | Q(z) | ~forall x: Q(x)") self.assertEqual(e, miniscope(f)) self.assertTrue(prover.test_equivalent(e, f, [])) f = expr("exists x: forall z: P(z) ==> Q(z) | ~Q(x)") # e = expr("forall z: ~P(z) | Q(z) | ~forall x: Q(x)") # do not swap the quantifiers e = expr("exists x: forall z: ~P(z) | Q(z) | ~Q(x)") self.assertTrue(prover.test_equivalent(e, f, [])) self.assertEqual(e, miniscope(f))
def bfs(f, h, operators, max=0): """Return the best formula given a heuristic `h`. """ get_log().debug('running search for shortest formula using ops {}' .format(operators)) if max == 0: max = h.formula_cost(f) closed = set() atoms = sorted(collect_propositions(f), key=lambda x: str(x)) queue = atoms[:] best = None best_cost = max if max > 0 else 1000 while queue: current = queue.pop(0) get_log().debug('...current: {}'.format(str(current))) if h.formula_cost(current) < best_cost: if prover.test_equivalent(f, current, []): best = current best_cost = h.formula_cost(best) if (max == -1): return best new = [n for n in create_combinations(current, atoms, operators) if h.formula_cost(n) < best_cost and n not in closed] queue.extend(new) closed.update(new) return best or f
def test_pushquants(self): # easy forall cases f = expr('forall x: P(x) & Q') e = expr('(forall x: P(x)) & Q') self.assertEqual(e, push_quants(f)) self.assertTrue(prover.test_equivalent(e, f, [])) f = expr('forall x: P & Q(x)') e = expr('P & (forall x: Q(x))') self.assertEqual(e, push_quants(f)) self.assertTrue(prover.test_equivalent(e, f, [])) f = expr('forall x: P(x) | Q') e = expr('(forall x: P(x)) | Q') self.assertEqual(e, push_quants(f)) self.assertTrue(prover.test_equivalent(e, f, [])) f = expr('forall x: P | Q(x)') e = expr('P | forall x: Q(x)') self.assertEqual(e, push_quants(f)) self.assertTrue(prover.test_equivalent(e, f, [])) # easy exists cases f = expr('exists x: P(x) & Q') e = expr('(exists x: P(x)) & Q') self.assertEqual(e, push_quants(f)) self.assertTrue(prover.test_equivalent(e, f, [])) f = expr('exists x: P & Q(x)') e = expr('P & (exists x: Q(x))') self.assertEqual(e, push_quants(f)) self.assertTrue(prover.test_equivalent(e, f, [])) f = expr('exists x: P(x) | Q') e = expr('(exists x: P(x)) | Q') self.assertEqual(e, push_quants(f)) self.assertTrue(prover.test_equivalent(e, f, [])) f = expr('exists x: P | Q(x)') e = expr('P | (exists x: Q(x))') self.assertEqual(e, push_quants(f)) self.assertTrue(prover.test_equivalent(e, f, [])) # variable reduction f = expr('(forall x: P(x) & Q(x))') e = expr('(forall x: P(x)) & (forall x: Q(x))') self.assertEqual(e, push_quants(f)) self.assertTrue(prover.test_equivalent(e, f, [])) # catch f = expr("(forall x: forall x': P(x) | Q(x'))") e = expr("(forall x: P(x)) | (forall x': Q(x'))") self.assertEqual(e, push_quants(f)) # variable reduction f = expr('(exists x: P(x) | Q(x))') e = expr('(exists x: P(x)) | (exists x: Q(x))') self.assertEqual(e, push_quants(f)) # catch f = expr("(exists x: exists x': P(x) & Q(x'))") e = expr("(exists x: P(x)) & (exists x': Q(x'))") self.assertEqual(e, push_quants(f)) # no rename f = expr('(forall y: P(x) & Q(y))') e = expr('P(x) & (forall y: Q(y))') self.assertEqual(e, push_quants(f)) # rename required f = expr("(forall x': P(x) & Q(x'))") e = expr("P(x) & (forall x': Q(x'))") self.assertEqual(e, push_quants(f)) # rename required f = expr("(exists x': P(x) & Q(x'))") e = expr("P(x) & (exists x': Q(x'))") self.assertEqual(e, push_quants(f)) f = expr("forall x: forall z: ( ( Q or P(x)) ==> R(z) )") e = expr("(Q | exists x: P(x)) ==> forall z: R(z)") self.assertEqual(e, push_quants(f)) f = expr('(forall x: exists y: P(x) & Q(y))') e = expr('(forall x: P(x)) & (exists y: Q(y))') self.assertEqual(e, push_quants(f)) f = expr('(forall x: exists y: P(x) | Q(y))') e = expr('(forall x: P(x)) | (exists y: Q(y))') self.assertEqual(e, push_quants(f)) f = expr('(forall x: exists y: P(x) ==> Q(y))') e = expr('(exists x: P(x)) ==> (exists y: Q(y))') self.assertEqual(e, push_quants(f)) f = expr('(forall x: exists y: P(x) ==> Q(y, x))') e = expr('(forall x: P(x) ==> (exists y: Q(y, x)))') self.assertEqual(e, push_quants(f)) f = expr('(forall x: exists y: P(x) <== Q(y))') e = expr('(forall x: P(x)) <== (forall y: Q(y))') self.assertEqual(e, push_quants(f))
def test_simplification_complex(self): f = expr('forall x: P(x)') expected = expr('forall x: P(x)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('forall x: P(x) & true') expected = expr('forall x: P(x)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('forall x: P(x) & Q(x) ==> false') expected = expr('forall x: ~(P(x) & Q(x))') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('forall x, y: P(x) & true') expected = expr('forall x: P(x)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('forall x: forall y: P(x) & Q(x) ==> false') expected = expr('forall x: ~(P(x) & Q(x))') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('forall x: exists y: P(x) & Q(x) ==> false') expected = expr('forall x: ~(P(x) & Q(x))') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('forall x, y: exists z: x =/= y ==> x < z & z < y') expected = expr('forall x, y: exists z: x =/= y ==> x < z & z < y') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('forall x, y: (P(x1) & true) | (Q(y1) & false)') expected = expr('P(x1)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('forall x, y: exists z: (P(x1) & true) ==> (Q(y1) & false)') expected = expr('~P(x1)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('forall x, y: exists z: ' \ '(P(x1) & true) | (Q(y1) & false) ==> Z(xy) ') expected = expr('P(x1) ==> Z(xy)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('forall x, y: exists z: ' \ '(P(x1) & true) | (Q(y1) & false) <=> true ') expected = expr('P(x1)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('forall x, y: exists z: ' \ '(P(x1) & true) | (Q(y1) & false) <== Z(xy) | true ') expected = expr('true') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('true ==> (P <=> (P <=> false))') expected = expr('P <=> ~P') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('exists x, y, z: P(x) ==> Q(z) ==> false') expected = expr('exists x, z: P(x) ==> ~Q(z)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('(forall x, y: P(x) | (P(y) & false)) ==> exists z: Q') expected = expr('(forall x: P(x)) ==> Q') self.assertTrue(prover.test_equivalent(expected, kleene(f), []))
def test_simplification_basic(self): f = expr('~true') expected = expr('false') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('~false') expected = expr('true') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('~~true') expected = expr('true') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('~~~true') expected = expr('false') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P | true') expected = expr(OP_TRUE) self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P | false') expected = expr('P') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P & false') expected = expr(OP_FALSE) self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P & true') expected = expr('P') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P ==> false') expected = expr('~P') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('true ==> P') expected = expr('P') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P <=> true') expected = expr('P') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P <=> false') expected = expr('~P') self.assertTrue(prover.test_equivalent(expected, kleene(f), []))
def test_simplification_none(self): f = expr('1') expected = expr('1') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P') expected = expr('P') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('true') expected = expr('true') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('false') expected = expr('false') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P(x)') expected = expr('P(x)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P(x) | Q(x)') expected = expr('P(x) | Q(x)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P(x) & Q(x)') expected = expr('P(x) & Q(x)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P(x) ==> Q(x)') expected = expr('P(x) ==> Q(x)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P(x) <== Q(x)') expected = expr('P(x) <== Q(x)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P(x) <=> Q(x)') expected = expr('P(x) <=> Q(x)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('P(x, y) ==> Q(x)') expected = expr('P(x, y) ==> Q(x)') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('x > 0') expected = expr('x > 0') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('x = y') expected = expr('x = y') self.assertTrue(prover.test_equivalent(expected, kleene(f), [])) f = expr('x =/= 0') expected = expr('x =/= 0') self.assertTrue(prover.test_equivalent(expected, kleene(f), []))