def testApplyInduction(self): thy = basic.load_theory('nat') n = Var("n", nat.natT) state = ProofState.init_state(thy, [n], [], Term.mk_equals(nat.plus(n, nat.zero), n)) state.apply_induction(0, "nat_induct", "n") self.assertEqual(state.check_proof(), Thm([], Term.mk_equals(nat.plus(n, nat.zero), n))) self.assertEqual(len(state.prf.items), 3)
def testInferPrintedType(self): t = Const("nil", listT(Ta)) infer_printed_type(thy, t) self.assertTrue(hasattr(t, "print_type")) t = list.cons(Ta)(Var("a", Ta)) infer_printed_type(thy, t) self.assertFalse(hasattr(t.fun, "print_type")) t = Term.mk_equals(Const("nil", listT(Ta)), Const("nil", listT(Ta))) infer_printed_type(thy, t) self.assertFalse(hasattr(t.fun.fun, "print_type")) self.assertTrue(hasattr(t.arg1, "print_type")) self.assertFalse(hasattr(t.arg, "print_type")) t = Term.mk_equals(list.mk_append(list.nil(Ta), list.nil(Ta)), list.nil(Ta)) infer_printed_type(thy, t) self.assertTrue(hasattr(t.arg1.arg1, "print_type")) self.assertFalse(hasattr(t.arg1.arg, "print_type")) self.assertFalse(hasattr(t.arg, "print_type")) t = Term.mk_abs(Var("x", Ta), Term.mk_equals(Var("x", Ta), Var("x", Ta))) infer_printed_type(thy, t)
def testSubstitution(self): x_eq_y = Term.mk_equals(x, y) th = Thm([x_eq_y], x_eq_y) y_eq_x = Term.mk_equals(y, x) self.assertEqual(Thm.substitution({ "x": y, "y": x }, th), Thm([y_eq_x], y_eq_x))
def testExport(self): """Basic case.""" pt1 = ProofTerm.assume(Term.mk_equals(x, y)) pt2 = ProofTerm.assume(Term.mk_equals(y, z)) pt3 = ProofTerm.transitive(pt1, pt2) prf = pt3.export() self.assertEqual(len(prf.items), 3) self.assertEqual(thy.check_proof(prf), pt3.th)
def testRewriteGoalWithAssum(self): Ta = TVar("a") a = Var("a", Ta) b = Var("b", Ta) eq_a = Term.mk_equals(a, a) if_t = logic.mk_if(eq_a, b, a) state = ProofState.init_state(thy, [a, b], [], Term.mk_equals(if_t, b)) state.rewrite_goal(0, "if_P") state.set_line(0, "reflexive", args=a) self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_equals(if_t, b))
def testCheckTerm(self): test_data = [ x, Term.mk_equals(x, y), Term.mk_equals(f, f), Term.mk_implies(A, B), Abs("x", Ta, Term.mk_equals(x, y)), ] for t in test_data: self.assertEqual(thy.check_term(t), None)
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 testCheckProof3(self): """Proof of [x = y, y = z] |- f z = f x.""" x_eq_y = Term.mk_equals(x,y) y_eq_z = Term.mk_equals(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], Term.mk_equals(f(z),f(x))) self.assertEqual(thy.check_proof(prf, rpt), th) self.assertEqual(rpt.steps, 6)
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 testInduct(self): n = Var('n', natT) goal = Thm([], Term.mk_equals(plus(n, zero), n)) induct_tac = tactic.var_induct() pt = induct_tac.get_proof_term(thy, ProofTerm.sorry(goal), args=('nat_induct', n)) prf = pt.export() self.assertEqual(thy.check_proof(prf), goal)
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 testRule4(self): n = Var('n', natT) goal = Thm([], Term.mk_equals(plus(n, zero), n)) inst = {'P': Term.mk_abs(n, goal.prop), 'x': n} pt = tactic.rule().get_proof_term(thy, ProofTerm.sorry(goal), args=('nat_induct', ({}, inst))) prf = pt.export() self.assertEqual(thy.check_proof(prf), goal)
def testInferType(self): test_data = [ # A1 --> A2 (Const("implies", None)(Var("A1", None), Var("A2", None)), Term.mk_implies(Var("A1", boolT), Var("A2", boolT))), # A1 = A2 (Const("equals", None)(Var("A1", boolT), Var("A2", None)), Term.mk_equals(Var("A1", boolT), Var("A2", boolT))), # a = b (Const("equals", None)(Var("a", None), Var("b", None)), Const("equals", TFun(Ta, Ta, boolT))(Var("a", Ta), Var("b", Ta))), # %x. P x (Abs("x", None, Var("P", None)(Bound(0))), Abs("x", Ta, Var("P", TFun(Ta, boolT))(Bound(0)))), # %x y. x = y (Abs("x", Ta, Abs("y", None, Const("equals", None)(Bound(1), Bound(0)))), Abs( "x", Ta, Abs("y", Ta, Const("equals", TFun(Ta, Ta, boolT))(Bound(1), Bound(0))))), # [a] (Const("cons", None)(Var("a", None), Const("nil", None)), list.cons(Ta)(Var("a", Ta), Const("nil", listT(Ta)))), ] for t, res in test_data: self.assertEqual(type_infer(thy, ctxt, t), res)
def testExport2(self): """Repeated theorems.""" pt1 = ProofTerm.assume(Term.mk_equals(x, y)) pt2 = ProofTerm.reflexive(f) pt3 = ProofTerm.combination(pt2, pt1) # f x = f y pt4 = ProofTerm.combination(pt3, pt1) # f x x = f y y prf = pt4.export() self.assertEqual(len(prf.items), 4) self.assertEqual(thy.check_proof(prf), pt4.th)
def testFunUpdTriv(self): thy = basic.load_theory('function') Ta = TVar("a") Tb = TVar("b") f = Var("f", TFun(Ta, Tb)) a = Var("a", Ta) x = Var("x", Ta) prop = Term.mk_equals(function.mk_fun_upd(f, a, f(a)), f) state = ProofState.init_state(thy, [f, a], [], prop) state.apply_backward_step(0, "extension") state.introduction(0, names=["x"]) state.rewrite_goal((0, 1), "fun_upd_eval") state.apply_cases((0, 1), Term.mk_equals(x, a)) state.introduction((0, 1)) state.rewrite_goal((0, 1, 1), "if_P") state.rewrite_goal_with_prev((0, 1, 1), (0, 1, 0)) state.introduction((0, 2)) state.rewrite_goal((0, 2, 1), "if_not_P") self.assertEqual(state.check_proof(no_gaps=True), Thm([], prop))
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 testPrintExtensionReport(self): ext_report = ExtensionReport() id_const = Const("id", TFun(Ta, Ta)) id_simps = Term.mk_equals(id_const(x), x) ext_report.add_axiom("id.simps", Thm([], id_simps)) str_ext_report = "\n".join( ["Axiom added: 1", "id.simps: |- equals (id x) x"]) self.assertEqual(str(ext_report), str_ext_report)
def testCheckedExtend(self): """Checked extension: adding an axiom.""" thy = Theory.EmptyTheory() thy_ext = TheoryExtension() id_simps = Term.mk_equals(Comb(Const("id", TFun(Ta,Ta)),x), x) thy_ext.add_extension(Theorem("id.simps", Thm([], id_simps))) ext_report = thy.checked_extend(thy_ext) self.assertEqual(thy.get_theorem("id.simps"), Thm([], id_simps)) self.assertEqual(ext_report.get_axioms(), [("id.simps", Thm([], id_simps))])
def testRewrite2(self): Ta = TVar("a") a = Var("a", Ta) b = Var("b", Ta) eq_a = Term.mk_equals(a, a) goal = Thm.mk_equals(mk_if(eq_a, b, a), b) rewrite_tac = tactic.rewrite() pt = rewrite_tac.get_proof_term(thy, ProofTerm.sorry(goal), args='if_P') prf = pt.export() self.assertEqual(prf.items[0], ProofItem(0, 'sorry', th=Thm.mk_equals(a, a))) self.assertEqual(thy.check_proof(prf), goal)
def testMultZeroRight(self): """Proof of n * 0 = 0 by induction.""" thy = basic.load_theory('nat') n = Var("n", nat.natT) state = ProofState.init_state(thy, [n], [], Term.mk_equals(nat.times(n, nat.zero), nat.zero)) state.apply_induction(0, "nat_induct", "n") state.rewrite_goal(0, "times_def_1") state.introduction(1, names=["n"]) state.rewrite_goal((1, 2), "times_def_2") state.rewrite_goal((1, 2), "plus_def_1") self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_equals(nat.times(n, nat.zero), nat.zero))
def testAVal(self): thy = basic.load_theory('expr') th = thy.get_theorem('aval_test2') state = ProofState.init_state(thy, [], [], th.prop) state.rewrite_goal(0, "aval_def_3") state.rewrite_goal(0, "aval_def_2") state.rewrite_goal(0, "aval_def_1") state.rewrite_goal(0, "fun_upd_def") state.rewrite_goal(0, "if_not_P") state.set_line(0, "nat_norm", args=Term.mk_equals(nat.plus(nat.zero, nat.to_binary(5)), nat.to_binary(5))) state.apply_backward_step(1, "nat_zero_Suc_neq") self.assertEqual(state.check_proof(no_gaps=True), th)
def symmetric(th): """Derivation rule SYMMETRIC: |- x = y ------------ |- y = x """ if th.prop.is_equals(): x, y = th.prop.args return Thm(th.hyps, Term.mk_equals(y, x)) else: raise InvalidDerivationException("symmetric")
def testNatEqConv(self): test_data = [ ((zero, zero), logic.true), ((one, one), logic.true), ((zero, one), logic.false), ] cv = nat.nat_eq_conv() for (a, b), res in test_data: t = Term.mk_equals(a, b) prf = cv.get_proof_term(thy, t).export() res_th = Thm.mk_equals(t, res) self.assertEqual(thy.check_proof(prf), res_th)
def add_invariant(self): """Add the invariant for the system in GCL.""" s = Var("s", gcl.stateT) invC = Const("inv", TFun(gcl.stateT, boolT)) inv_rhs = logic.mk_conj( *[gcl.convert_term(self.var_map, s, t) for _, t in self.invs]) prop = Term.mk_equals(invC(s), inv_rhs) exts = extension.TheoryExtension() exts.add_extension(extension.AxConstant("inv", TFun(gcl.stateT, boolT))) exts.add_extension(extension.Theorem("inv_def", Thm([], prop))) self.thy.unchecked_extend(exts)
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 testAppendNil(self): """Proof of xs @ [] = xs by induction.""" thy = basic.load_theory('list') Ta = TVar("a") xs = Var("xs", list.listT(Ta)) nil = list.nil(Ta) state = ProofState.init_state(thy, [xs], [], Term.mk_equals(list.mk_append(xs, nil), xs)) state.apply_induction(0, "list_induct", "xs") state.apply_backward_step(0, "append_def_1") state.introduction(1, names=["x", "xs"]) state.rewrite_goal((1, 3), "append_def_2") self.assertEqual(state.get_ctxt((1, 3)), {'x': Ta, 'xs': list.listT(Ta)}) state.rewrite_goal_with_prev((1, 3), (1, 2)) self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_equals(list.mk_append(xs, nil), xs))
def testPrintTheoryExtension(self): 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) thy_ext.add_extension(Constant("id", id_def)) thy_ext.add_extension(Theorem("id.simps", Thm([], id_simps))) str_thy_ext = "\n".join( ["Constant id = %x. x", "Theorem id.simps: |- equals (id x) x"]) self.assertEqual(str(thy_ext), str_thy_ext)
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 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 testNatIneqMacro(self): test_data = [ (0, 1), (1, 0), (0, 2), (2, 0), (1, 2), (2, 1), (1, 3), (3, 1), (2, 3), (3, 2), (10, 13), (17, 19), (22, 24), ] macro = nat.nat_const_ineq_macro() for m, n in test_data: goal = logic.neg(Term.mk_equals(nat.to_binary(m), nat.to_binary(n))) prf = macro.get_proof_term(thy, goal, []).export() self.assertEqual(thy.check_proof(prf), Thm([], goal))