def testCheckProofMacro(self): """Proof checking with simple macro.""" thy = Theory.EmptyTheory() thy.add_proof_macro("beta_conv_rhs", beta_conv_rhs_macro()) t = Comb(Abs("x", Ta, Bound(0)), x) prf = Proof() prf.add_item(0, "reflexive", args=t) prf.add_item(1, "beta_conv_rhs", prevs=[0]) th = Thm.mk_equals(t,x) # Check obtaining signature self.assertEqual(thy.get_proof_rule_sig("beta_conv_rhs"), Term) # Check proof without trusting beta_conv_rhs rpt = ProofReport() self.assertEqual(thy.check_proof(prf, rpt), th) self.assertEqual(rpt.steps_stat(), (0, 3, 0)) self.assertEqual(rpt.macros_expand, {"beta_conv_rhs"}) # Check proof while trusting beta_conv_rhs rpt = ProofReport() self.assertEqual(thy.check_proof(prf, rpt, check_level=1), th) self.assertEqual(rpt.steps_stat(), (0, 1, 1)) self.assertEqual(rpt.macros_eval, {"beta_conv_rhs"})
def testCheckProof2(self): """Proof of |- A --> A.""" prf = Proof(A) prf.add_item(1, "implies_intr", args=A, prevs=[0]) rpt = ProofReport() self.assertEqual(theory.check_proof(prf, rpt), Thm([], Implies(A,A))) self.assertEqual(rpt.steps, 2)
def expand(self, prefix, thy, args, prevs): id, th = prevs[0] assert Term.is_equals(th.prop), "beta_conv_rhs" rhs = th.prop.rhs prf = Proof() prf.add_item(prefix + (0,), "beta_conv", args=rhs) prf.add_item(prefix + (1,), "transitive", prevs=[id, prefix + (0,)]) return prf
def testCheckProof(self): """Proof of [A, A --> B] |- B.""" A_to_B = Implies(A, B) prf = Proof(A_to_B, A) prf.add_item(2, "implies_elim", prevs=[0, 1]) rpt = ProofReport() self.assertEqual(theory.check_proof(prf, rpt), Thm([A_to_B, A], B)) self.assertEqual(rpt.steps, 3)
def testTopSweepConv(self): f = Const("f", TFun(natT, natT)) x = Var("x", natT) th0 = eq(x, f(x)) cv = top_sweep_conv(rewr_conv(ProofTerm.atom(0, th0), match_vars=False)) prf = Proof() prf.add_item(0, "sorry", th=th0) cv.get_proof_term(thy, f(x)).export(prf=prf) self.assertEqual(thy.check_proof(prf), eq(f(x), f(f(x))))
def testExport3(self): """Case with atoms.""" pt1 = ProofTerm.atom(0, Thm([], Eq(x, y))) pt2 = ProofTerm.atom(1, Thm([], Eq(y, z))) pt3 = pt1.transitive(pt2) prf = Proof() prf.add_item(0, rule="sorry", th=Thm([], Eq(x, y))) prf.add_item(1, rule="sorry", th=Thm([], Eq(y, z))) pt3.export(prf=prf) self.assertEqual(theory.check_proof(prf), Thm([], Eq(x, z)))
def testRewrConvWithAssum(self): x = Const("x", natT) y = Const("y", natT) x_eq_y = Term.mk_equals(x, y) th = Thm([], Term.mk_implies(x_eq_y, x_eq_y)) cv = arg_conv(rewr_conv(ProofTerm.atom(0, th))) f = Const("f", TFun(natT, natT)) res = Thm([x_eq_y], Term.mk_equals(f(x), f(y))) self.assertEqual(cv.eval(thy, f(x)), res) prf = Proof() prf.add_item(0, "sorry", th=th) cv.get_proof_term(thy, f(x)).export(prf=prf) self.assertEqual(thy.check_proof(prf), res)
def testCheckProof4(self): """Proof of |- x = y --> x = y by instantiating an existing theorem.""" theory.thy.add_theorem("trivial", Thm([], Implies(A,A))) x_eq_y = Eq(x,y) prf = Proof() prf.add_item(0, "theorem", args="trivial") prf.add_item(1, "substitution", args=Inst(A=x_eq_y), prevs=[0]) rpt = ProofReport() th = Thm([], Implies(x_eq_y,x_eq_y)) self.assertEqual(theory.check_proof(prf, rpt), th) self.assertEqual(rpt.steps, 2)
def testCheckProof4(self): """Proof of |- x = y --> x = y by instantiating an existing theorem.""" thy = Theory.EmptyTheory() thy.add_theorem("trivial", Thm.mk_implies(A,A)) x_eq_y = Term.mk_equals(x,y) prf = Proof() prf.add_item(0, "theorem", args="trivial") prf.add_item(1, "substitution", args={"A" : x_eq_y}, prevs=[0]) rpt = ProofReport() th = Thm.mk_implies(x_eq_y,x_eq_y) self.assertEqual(thy.check_proof(prf, rpt), th) self.assertEqual(rpt.steps, 2)
def testCheckProof5(self): """Empty instantiation.""" theory.thy.add_theorem("trivial", Thm([], Implies(A,A))) x_eq_y = Eq(x,y) prf = Proof() prf.add_item(0, "theorem", args="trivial") prf.add_item(1, "substitution", args=Inst(), prevs=[0]) rpt = ProofReport() th = Thm([], Implies(SVar('A', BoolType), SVar('A', BoolType))) self.assertEqual(theory.check_proof(prf, rpt), th) self.assertEqual(rpt.steps_stat(), (1, 1, 0)) self.assertEqual(rpt.th_names, {"trivial"})
def testCheckProof5(self): """Empty instantiation.""" thy = Theory.EmptyTheory() thy.add_theorem("trivial", Thm.mk_implies(A,A)) x_eq_y = Term.mk_equals(x,y) prf = Proof() prf.add_item(0, "theorem", args="trivial") prf.add_item(1, "substitution", args={}, prevs=[0]) rpt = ProofReport() th = Thm.mk_implies(A,A) self.assertEqual(thy.check_proof(prf, rpt), th) self.assertEqual(rpt.steps_stat(), (1, 1, 0)) self.assertEqual(rpt.th_names, {"trivial"})
def testProof(self): prf = Proof(A_to_B, A) prf.vars = [A, B] th = Thm([A, A_to_B], B) prf.add_item(2, "implies_elim", prevs=[0, 1], th=th) self.assertEqual(len(prf.items), 3) self.assertEqual(prf.items[-1].th, th) str_prf = "\n".join([ "0: assume implies A B", "1: assume A", "2: A, implies A B |- B by implies_elim from 0, 1" ]) self.assertEqual(str(prf), str_prf)
def testFunCombination(self): thy = basic.load_theory('logic_base') macro = logic_macro.fun_combination_macro() f_eq_g = Term.mk_equals(f, g) fx_eq_gx = Term.mk_equals(f(x), g(x)) th = Thm.assume(f_eq_g) res = Thm([f_eq_g], fx_eq_gx) self.assertEqual(macro.eval(thy, x, [th]), res) prf = Proof(f_eq_g) prf.add_item(1, "fun_combination", args=x, prevs=[0]) rpt = ProofReport() self.assertEqual(thy.check_proof(prf, rpt), res) self.assertEqual(rpt.macros_expand, {"fun_combination"}) self.assertEqual(rpt.prim_steps, 3)
def testArgCombination(self): thy = basic.load_theory('logic_base') macro = logic_macro.arg_combination_macro() x_eq_y = Term.mk_equals(x, y) fx_eq_fy = Term.mk_equals(f(x), f(y)) th = Thm.assume(x_eq_y) res = Thm([x_eq_y], fx_eq_fy) self.assertEqual(macro.eval(thy, f, [th]), res) prf = Proof(x_eq_y) prf.add_item(1, "arg_combination", args=f, prevs=[0]) rpt = ProofReport() self.assertEqual(thy.check_proof(prf, rpt), res) self.assertEqual(rpt.macros_expand, {"arg_combination"}) self.assertEqual(rpt.prim_steps, 3)
def testBetaNorm(self): thy = basic.load_theory('logic_base') t = Term.mk_abs(x, f(x)) prf = Proof(Term.mk_equals(t(x), y)) prf.add_item(1, "beta_norm", prevs=[0]) prf.add_item(2, "implies_intr", args=Term.mk_equals(t(x), y), prevs=[1]) th = Thm.mk_implies(Term.mk_equals(t(x), y), Term.mk_equals(f(x), y)) rpt = ProofReport() self.assertEqual(thy.check_proof(prf, rpt), th) self.assertEqual(rpt.prim_steps, 8) rpt2 = ProofReport() self.assertEqual(thy.check_proof(prf, rpt2, check_level=1), th) self.assertEqual(rpt2.prim_steps, 2) self.assertEqual(rpt2.macro_steps, 1)
def testApplyTheorem(self): thy = basic.load_theory('logic_base') A = Var("A", boolT) B = Var("B", boolT) th = Thm([logic.mk_conj(A, B)], A) prf = Proof(logic.mk_conj(A, B)) prf.add_item(1, "apply_theorem", args="conjD1", prevs=[0]) rpt = ProofReport() self.assertEqual(thy.check_proof(prf, rpt), th) self.assertEqual(rpt.prim_steps, 4) # Reset data for the next check prf = Proof(logic.mk_conj(A, B)) prf.add_item(1, "apply_theorem", args="conjD1", prevs=[0]) rpt = ProofReport() self.assertEqual(thy.check_proof(prf, rpt, check_level=1), th) self.assertEqual(rpt.prim_steps, 1) self.assertEqual(rpt.macro_steps, 1)
def testLargeSum(self): f = Const("f", TFun(natT, natT)) g = Const("g", TFun(natT, natT)) x = Var("x", natT) th0, th1 = eq(one, zero), eq(f(x), g(x)) cv = top_conv( else_conv(rewr_conv(ProofTerm.atom(0, th0)), rewr_conv(ProofTerm.atom(1, th1)))) f1 = f(one) g0 = g(zero) t = plus(*([f1] * 50)) res = plus(*([g0] * 50)) self.assertEqual(cv.eval(thy, t), eq(t, res)) prf = Proof() prf.add_item(0, "sorry", th=th0) prf.add_item(1, "sorry", th=th1) cv.get_proof_term(thy, t).export(prf=prf) self.assertEqual(thy.check_proof(prf, check_level=1), eq(t, res))
def testRewriteGoal(self): thy = basic.load_theory('nat') n = Var("n", nat.natT) eq = Term.mk_equals zero = nat.zero plus = nat.mk_plus prf = Proof() prf.add_item(0, "rewrite_goal", args=("plus_def_1", eq(plus(zero, zero), zero))) th = Thm([], eq(plus(zero, zero), zero)) rpt = ProofReport() self.assertEqual(thy.check_proof(prf, rpt), th) self.assertEqual(rpt.prim_steps, 9) rpt2 = ProofReport() self.assertEqual(thy.check_proof(prf, rpt2, check_level=1), th) self.assertEqual(rpt2.prim_steps, 0) self.assertEqual(rpt2.macro_steps, 1)
def testCheckProof3(self): """Proof of [x = y, y = z] |- f z = f x.""" x_eq_y = Eq(x,y) y_eq_z = Eq(y,z) prf = Proof(x_eq_y, y_eq_z) prf.add_item(2, "transitive", prevs=[0, 1]) prf.add_item(3, "symmetric", prevs=[2]) prf.add_item(4, "reflexive", args=f) prf.add_item(5, "combination", prevs=[4, 3]) rpt = ProofReport() th = Thm([x_eq_y, y_eq_z], Eq(f(z),f(x))) self.assertEqual(theory.check_proof(prf, rpt), th) self.assertEqual(rpt.steps, 6)
def testCheckedExtend2(self): """Checked extension: proved theorem.""" id_const = Const("id", TFun(Ta,Ta)) id_def = Abs("x", Ta, Bound(0)) id_simps = Eq(id_const(x), x) # Proof of |- id x = x from |- id = (%x. x) prf = Proof() prf.add_item(0, "theorem", args="id_def") # id = (%x. x) prf.add_item(1, "subst_type", args=TyInst(a=TVar('a')), prevs=[0]) # id = (%x. x) prf.add_item(2, "reflexive", args=x) # x = x prf.add_item(3, "combination", prevs=[1, 2]) # id x = (%x. x) x prf.add_item(4, "beta_conv", args=id_def(x)) # (%x. x) x = x prf.add_item(5, "transitive", prevs=[3, 4]) # id x = x exts = [ extension.Constant("id", TFun(Ta, Ta)), extension.Theorem("id_def", Thm([], Eq(id_const, id_def))), extension.Theorem("id.simps", Thm([], id_simps), prf) ] ext_report = theory.thy.checked_extend(exts) self.assertEqual(theory.get_theorem("id.simps", svar=False), Thm([], id_simps)) self.assertEqual(ext_report.get_axioms(), [('id_def', Thm([], Eq(id_const, id_def)))])
def testCheckProofGap(self): """Check proof with gap.""" prf = Proof() prf.add_item(0, "sorry", th = Thm([], Implies(A,B))) prf.add_item(1, "sorry", th = Thm([], A)) prf.add_item(2, "implies_elim", prevs=[0, 1]) rpt = ProofReport() self.assertEqual(theory.check_proof(prf, rpt), Thm([], B)) self.assertEqual(rpt.gaps, [Thm([], Implies(A, B)), Thm([], A)])
def testConjCommWithMacro(self): """Proof of commutativity of conjunction, with macros.""" thy = basic.load_theory('logic_base') A = Var("A", boolT) B = Var("B", boolT) prf = Proof(logic.mk_conj(A, B)) prf.add_item(1, "apply_theorem", args="conjD1", prevs=[0]) prf.add_item(2, "apply_theorem", args="conjD2", prevs=[0]) prf.add_item(3, "apply_theorem", args="conjI", prevs=[2, 1]) prf.add_item(4, "implies_intr", args=logic.mk_conj(A, B), prevs=[3]) th = Thm.mk_implies(logic.mk_conj(A, B), logic.mk_conj(B, A)) self.assertEqual(thy.check_proof(prf), th)
def testTrueAbsorb(self): """Proof of A --> true & A.""" thy = basic.load_theory('logic_base') A = Var("A", boolT) prf = Proof(A) prf.add_item(1, "theorem", args="trueI") prf.add_item(2, "theorem", args="conjI") prf.add_item(3, "substitution", args={ "A": logic.true, "B": A }, prevs=[2]) prf.add_item(4, "implies_elim", prevs=[3, 1]) prf.add_item(5, "implies_elim", prevs=[4, 0]) prf.add_item(6, "implies_intr", args=A, prevs=[5]) th = Thm.mk_implies(A, logic.mk_conj(logic.true, A)) self.assertEqual(thy.check_proof(prf), th)
def testIntersection(self): """Proof of x : A INTER B --> x : A.""" thy = basic.load_theory('set') x = Var('x', Ta) A = Var('A', set.setT(Ta)) B = Var('B', set.setT(Ta)) x_in_AB = set.mk_mem(x, set.mk_inter(A, B)) x_in_A = set.mk_mem(x, A) prf = Proof(x_in_AB) prf.add_item(1, "rewrite_fact", args="member_inter_iff", prevs=[0]) prf.add_item(2, "apply_theorem", args="conjD1", prevs=[1]) prf.add_item(3, "implies_intr", args=x_in_AB, prevs=[2]) self.assertEqual(thy.check_proof(prf), Thm.mk_implies(x_in_AB, x_in_A))
def testCombination(self): """Test arg and fun combination together using proofs.""" thy = basic.load_theory('logic_base') prf = Proof(Term.mk_equals(f, g), Term.mk_equals(x, y)) prf.add_item(2, "arg_combination", args=f, prevs=[1]) prf.add_item(3, "fun_combination", args=y, prevs=[0]) prf.add_item(4, "transitive", prevs=[2, 3]) prf.add_item(5, "implies_intr", args=Term.mk_equals(x, y), prevs=[4]) prf.add_item(6, "implies_intr", args=Term.mk_equals(f, g), prevs=[5]) th = Thm.mk_implies(Term.mk_equals(f, g), Term.mk_equals(x, y), Term.mk_equals(f(x), g(y))) self.assertEqual(thy.check_proof(prf), th)
def testCheckedExtend2(self): """Checked extension: proved theorem.""" thy = Theory.EmptyTheory() thy_ext = TheoryExtension() id_const = Const("id", TFun(Ta,Ta)) id_def = Abs("x", Ta, Bound(0)) id_simps = Term.mk_equals(id_const(x), x) # Proof of |- id x = x from |- id = (%x. x) prf = Proof() prf.add_item(0, "theorem", args="id_def") # id = (%x. x) prf.add_item(1, "reflexive", args=x) # x = x prf.add_item(2, "combination", prevs=[0, 1]) # id x = (%x. x) x prf.add_item(3, "beta_conv", args=id_def(x)) # (%x. x) x = x prf.add_item(4, "transitive", prevs=[2, 3]) # id x = x thy_ext.add_extension(Constant("id", id_def)) thy_ext.add_extension(Theorem("id.simps", Thm([], id_simps), prf)) ext_report = thy.checked_extend(thy_ext) self.assertEqual(thy.get_theorem("id.simps"), Thm([], id_simps)) self.assertEqual(ext_report.get_axioms(), [])
def testRewrConv(self): f = Const("f", TFun(natT, natT)) g = Const("g", TFun(natT, natT)) x = Var("x", natT) assum0 = eq(one, zero) assum1 = eq(f(x), g(x)) # Test conversion using 1 = 0 cv1 = rewr_conv(ProofTerm.atom(0, assum0)) prf = Proof() prf.add_item(0, "sorry", th=assum0) eq_th = eq(one, zero) cv1.get_proof_term(thy, one).export(prf=prf) self.assertEqual(cv1.eval(thy, one), eq_th) self.assertEqual(thy.check_proof(prf), eq_th) self.assertRaises(ConvException, cv1.eval, thy, zero) self.assertRaises(ConvException, cv1.get_proof_term, thy, zero) # Test conversion using f x = g x cv2 = rewr_conv(ProofTerm.atom(0, assum1)) eq0 = eq(f(zero), g(zero)) eq1 = eq(f(one), g(one)) self.assertEqual(cv2.eval(thy, f(zero)), eq0) self.assertEqual(cv2.eval(thy, f(one)), eq1) prf0 = Proof() prf0.add_item(0, "sorry", th=assum1) cv2.get_proof_term(thy, f(zero)).export(prf=prf0) self.assertEqual(thy.check_proof(prf0), eq0) self.assertRaises(ConvException, cv1.eval, thy, zero) prf1 = Proof() prf1.add_item(0, "sorry", th=assum1) cv2.get_proof_term(thy, f(one)).export(prf=prf1) self.assertEqual(thy.check_proof(prf1), eq1) self.assertRaises(ConvException, cv1.get_proof_term, thy, zero)
def testAssumsSubsetFail(self): """res_th is not OK if assumptions is not a subset of that of seq.th.""" prf = Proof() prf.add_item(0, "assume", args=A, th=Thm([], A)) self.assertRaisesRegex(CheckProofException, "output does not match", theory.check_proof, prf)
def testAssumsSubset(self): """res_th is OK if assumptions is a subset of that of seq.th.""" prf = Proof() prf.add_item(0, "assume", args=A, th=Thm([A, B], A)) self.assertEqual(theory.check_proof(prf), Thm([A, B], A))
def testCheckProofFail8(self): """Proof method not found.""" prf = Proof() prf.add_item(0, "random") self.assertRaisesRegex(CheckProofException, "proof method not found", theory.check_proof, prf)