def testEvalFunUpd(self): f = fun_upd_of_seq(1, 5) cv = function.fun_upd_eval_conv() prf = cv.get_proof_term(thy, f(one)).export() self.assertEqual(thy.check_proof(prf), Thm.mk_equals(f(one), five)) prf = cv.get_proof_term(thy, f(zero)).export() self.assertEqual(thy.check_proof(prf), Thm.mk_equals(f(zero), zero))
def eval(self, goal, prevs=None): if len(goal.get_vars()) != 0: raise ConvException try: if goal.is_equals(): if real_eval(goal.lhs) == real_eval(goal.rhs): return Thm([], Eq(goal, true)) else: return Thm([], Eq(goal, false)) else: # inequations lhs, rhs = real_eval(goal.arg1), real_eval(goal.arg) if goal.is_less(): return Thm([], Eq(goal, true)) if lhs < rhs else Thm( [], Eq(goal, false)) elif goal.is_less_eq(): return Thm([], Eq(goal, true)) if lhs <= rhs else Thm( [], Eq(goal, false)) elif goal.is_greater(): return Thm([], Eq(goal, true)) if lhs > rhs else Thm( [], Eq(goal, false)) elif goal.is_greater_eq(): return Thm([], Eq(goal, true)) if lhs >= rhs else Thm( [], Eq(goal, false)) else: raise NotImplementedError except: raise ConvException
def testProveAvalI(self): s = fun_upd_of_seq(1, 7) test_data = [ (Plus(V(one), N(Nat(5))), Nat(12)), (Plus(V(zero), N(Nat(5))), Nat(5)), (Times(V(one), N(Nat(5))), Nat(35)), ] macro = expr.prove_avalI_macro() for t, n in test_data: goal = expr.avalI(s, t, n) # Test get_avalI self.assertEqual(Nat(macro.get_avalI(s, t)), n) # Test can_eval self.assertTrue(macro.can_eval(goal)) # Test eval self.assertEqual(macro.eval(goal, []), Thm([], goal)) # Test get_proof_term prf = macro.get_proof_term(goal, []).export() self.assertEqual(theory.check_proof(prf), Thm([], goal))
def get_proof_term(self, thy, goal, *, args=None, prevs=None): assert isinstance(prevs, list) and len(prevs) == 1, "rewrite_goal_with_prev" pt = prevs[0] init_As = goal.hyps C = goal.prop cv = then_conv(top_sweep_conv(rewr_conv(pt, match_vars=False)), top_conv(beta_conv())) eq_th = cv.eval(thy, C) new_goal = eq_th.prop.rhs new_As = list(set(eq_th.hyps) - set(init_As)) new_As_pts = [ProofTerm.sorry(Thm(init_As, A)) for A in new_As] if Term.is_equals(new_goal) and new_goal.lhs == new_goal.rhs: return ProofTermDeriv('rewrite_goal_with_prev', thy, args=C, prevs=[pt] + new_As_pts) else: new_goal_pts = ProofTerm.sorry(Thm(init_As, new_goal)) return ProofTermDeriv('rewrite_goal_with_prev', thy, args=C, prevs=[pt, new_goal_pts] + new_As_pts)
def eval(self, args, prevs): if self.with_inst: name, inst = args else: name = args inst = Inst() th = theory.get_theorem(name) As, C = th.prop.strip_implies() assert len(prevs) <= len(As), "apply_theorem: too many prevs." # First attempt to match type variables svars = th.prop.get_svars() for v in svars: if v.name in inst: v.T.match_incr(inst[v.name].get_type(), inst.tyinst) pats = As[:len(prevs)] ts = [prev_th.prop for prev_th in prevs] inst = matcher.first_order_match_list(pats, ts, inst) As, C = th.prop.subst_norm(inst).strip_implies() new_prop = Implies(*(As[len(prevs):] + [C])) prev_hyps = sum([prev.hyps for prev in prevs], ()) th = Thm(th.hyps + prev_hyps, new_prop) assert len(new_prop.get_stvars()) == 0, "apply_theorem: unmatched type variables." vars = new_prop.get_svars() for v in reversed(vars): th = Thm.forall_intr(v, th) return th
def get_extension(self): assert self.error is None, "get_extension" res = [] res.append( extension.Constant(self.name, self.type, ref_name=self.cname)) for rule in self.rules: res.append(extension.Theorem(rule['name'], Thm([], rule['prop']))) res.append(extension.Attribute(rule['name'], 'hint_backward')) # Case rule Targs, _ = self.type.strip_type() vars = [] for i, Targ in enumerate(Targs): vars.append(Var("_a" + str(i + 1), Targ)) P = Var("P", BoolType) pred = Const(self.name, self.type) assum0 = pred(*vars) assums = [] for rule in self.rules: prop = rule['prop'] As, C = prop.strip_implies() eq_assums = [Eq(var, arg) for var, arg in zip(vars, C.args)] assum = Implies(*(eq_assums + As), P) for var in reversed(prop.get_vars()): assum = Forall(var, assum) assums.append(assum) prop = Implies(*([assum0] + assums + [P])) res.append(extension.Theorem(self.cname + "_cases", Thm([], prop))) return res
def testEvalFunUpd(self): f = fun_upd_of_seq(1, 5) cv = function.fun_upd_eval_conv() prf = cv.get_proof_term(f(one)).export() self.assertEqual(theory.check_proof(prf), Thm([], Eq(f(one), Nat(5)))) prf = cv.get_proof_term(f(zero)).export() self.assertEqual(theory.check_proof(prf), Thm([], Eq(f(zero), zero)))
def testInductList(self): Ta = TVar("a") Tlista = Type("list", Ta) list_ext = induct.add_induct_type( "list", ["a"], [("nil", Tlista, []), ("cons", TFun(Ta, Tlista, Tlista), ["x", "xs"])]) nil = Const("nil", Tlista) cons = Const("cons", TFun(Ta, Tlista, Tlista)) x = Var("x", Ta) xs = Var("xs", Tlista) x2 = Var("x'", Ta) xs2 = Var("xs'", Tlista) P = Var("P", TFun(Tlista, boolT)) xlist = Var("x", Tlista) res = [ AxType("list", 1), AxConstant("nil", Tlista), AxConstant("cons", TFun(Ta, Tlista, Tlista)), Theorem("list_nil_cons_neq", Thm([], logic.neg(eq(nil, cons(x, xs))))), Theorem("list_cons_inject", Thm([], imp(eq(cons(x, xs), cons(x2, xs2)), conj(eq(x, x2), eq(xs, xs2))))), Theorem("list_induct", Thm([], imp(P(nil), all(x, all(xs, imp(P(xs), P(cons(x, xs))))), P(xlist)))), Attribute("list_induct", "var_induct") ] self.assertEqual(list_ext.data, res)
def get_proof_term(self, goal, *, args=None, prevs=None): assert isinstance(args, Term), "cases" As = goal.hyps C = goal.prop goal1 = ProofTerm.sorry(Thm(goal.hyps, Implies(args, C))) goal2 = ProofTerm.sorry(Thm(goal.hyps, Implies(Not(args), C))) return apply_theorem('classical_cases', goal1, goal2)
def testCheckedExtend(self): """Checked extension: adding an axiom.""" id_simps = Eq(Comb(Const("id", TFun(Ta,Ta)), x), x) exts = [extension.Theorem("id.simps", Thm([], id_simps))] 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.simps", Thm([], id_simps))])
def testRule2(self): A = Var('A', boolT) B = Var('B', boolT) goal = Thm([], disj(B, A)) prev = ProofTermAtom(0, Thm.assume(disj(A, B))) pt = tactic.rule().get_proof_term(thy, ProofTerm.sorry(goal), args='disjE', prevs=[prev]) prf = pt.export(prefix=(1,), subproof=False) self.assertEqual(prf.items[2], ProofItem(3, 'apply_theorem', args='disjE', prevs=[0, 1, 2]))
def testRule3(self): A = Var('A', boolT) B = Var('B', boolT) goal = Thm([], disj(B, A)) prev = ProofTermAtom(0, Thm.assume(B)) pt = tactic.rule().get_proof_term(thy, ProofTerm.sorry(goal), args='disjI1', prevs=[prev]) prf = pt.export(prefix=(1,), subproof=False) self.assertEqual(prf.items[0], ProofItem(1, 'apply_theorem_for', args=('disjI1', {}, {'A': B, 'B': A}), prevs=[0]))
def testCases(self): A = Var('A', boolT) B = Var('B', boolT) C = Var('C', boolT) cases_tac = tactic.cases() pt = cases_tac.get_proof_term(thy, ProofTerm.sorry(Thm([B], C)), args=A) prf = pt.export() self.assertEqual(thy.check_proof(prf), Thm([B], C))
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 testPrintThm(self): test_data = [ (Thm([], A), "|- A"), (Thm([A], A), "A |- A"), (Thm([A, B], A), "A, B |- A"), ] for th, str_th in test_data: self.assertEqual(str(th), str_th)
def testPrintThm(self): test_data = [ (Thm([], A), "|- A"), (Thm([A], A), "A |- A"), (Thm([A,B], A), "A, B |- A"), ] for th, str_th in test_data: with global_setting(unicode=False): self.assertEqual(str(th), str_th)
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 testAddLineBefore(self): state = ProofState.init_state(thy, [A, B], [conj(A, B)], conj(B, A)) state.add_line_before(2, 1) self.assertEqual(len(state.prf.items), 4) self.assertEqual(state.check_proof(), Thm.mk_implies(conj(A, B), conj(B, A))) state.add_line_before(2, 3) self.assertEqual(len(state.prf.items), 7) self.assertEqual(state.check_proof(), Thm.mk_implies(conj(A, B), conj(B, A)))
def testParseThm(self): test_data = [ ("|- A", Thm([], A)), ("|- A & B", Thm([], logic.mk_conj(A, B))), ("A |- B", Thm([A], B)), ("A, B |- C", Thm([A, B], C)), ] for s, th in test_data: self.assertEqual(parser.parse_thm(thy, ctxt, s), th)
def testEvalSem4(self): com = Cond(abs(s, logic.neg(eq(s(zero), one))), incr_one, Skip) st = mk_const_fun(natT, zero) st2 = fun_upd_of_seq(0, 1) goal = Sem(com, st, st2) prf = hoare.eval_Sem_macro().get_proof_term(thy, goal, []).export() self.assertEqual(thy.check_proof(prf), Thm([], goal)) goal = Sem(com, st2, st2) prf = hoare.eval_Sem_macro().get_proof_term(thy, goal, []).export() self.assertEqual(thy.check_proof(prf), Thm([], goal))
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 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 testEvalSem4(self): com = Cond(Lambda(s, Not(Eq(s(zero), one))), incr_one, Skip) st = mk_const_fun(NatType, zero) st2 = fun_upd_of_seq(0, 1) goal = Sem(com, st, st2) prf = imp.eval_Sem_macro().get_proof_term(goal, []).export() self.assertEqual(theory.check_proof(prf), Thm([], goal)) goal = Sem(com, st2, st2) prf = imp.eval_Sem_macro().get_proof_term(goal, []).export() self.assertEqual(theory.check_proof(prf), Thm([], goal))
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 testUncheckedExtend(self): """Unchecked extension.""" id_const = Const("id", TFun(Ta,Ta)) id_def = Abs("x", Ta, Bound(0)) exts = [ extension.Constant("id", TFun(Ta, Ta)), extension.Theorem("id_def", Thm([], Eq(id_const, id_def))), extension.Theorem("id.simps", Thm([], Eq(id_const, x))) ] self.assertEqual(theory.thy.unchecked_extend(exts), None) self.assertEqual(theory.thy.get_term_sig("id"), TFun(Ta, Ta)) self.assertEqual(theory.get_theorem("id_def", svar=False), Thm([], Eq(id_const, id_def))) self.assertEqual(theory.get_theorem("id.simps", svar=False), Thm([], Eq(id_const, x)))