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 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 testEvalSem2(self): com = Seq(incr_one, incr_one) st = mk_const_fun(NatType, zero) st2 = fun_upd_of_seq(0, 2) goal = Sem(com, st, st2) prf = imp.eval_Sem_macro().get_proof_term(goal, []).export() self.assertEqual(theory.check_proof(prf), Thm([], goal))
def testEvalSem(self): com = Seq(Assign(zero, Lambda(s, one)), Assign(one, Lambda(s, Nat(2)))) st = mk_const_fun(NatType, zero) st2 = fun_upd_of_seq(0, 1, 1, 2) goal = Sem(com, st, st2) prf = imp.eval_Sem_macro().get_proof_term(goal, []).export() self.assertEqual(theory.check_proof(prf), Thm([], goal))
def testVCG(self): P = Var("P", TFun(natFunT, BoolType)) Q = Var("Q", TFun(natFunT, BoolType)) test_data = [ Assign(zero, Lambda(s, one)), Seq(Assign(zero, Lambda(s, one)), Assign(one, Lambda(s, Nat(2)))), ] for c in test_data: goal = Valid(P, c, Q) prf = imp.vcg(natFunT, goal).export() self.assertEqual(theory.check_proof(prf).concl, goal) prf = imp.vcg_tactic().get_proof_term(Thm([], goal), None, []).export() self.assertEqual(theory.check_proof(prf).prop, goal)
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 check_proof(self, *, no_gaps=False, compute_only=False): """Check the given proof. Report is stored in rpt.""" self.rpt = report.ProofReport() return theory.check_proof(self.prf, rpt=self.rpt, no_gaps=no_gaps, compute_only=compute_only)
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 testEvalSem5(self): com = While(Lambda(s, Not(Eq(s(zero), Nat(3)))), assn_true, incr_one) st = mk_const_fun(NatType, zero) st2 = fun_upd_of_seq(0, 3) goal = Sem(com, st, st2) prf = imp.eval_Sem_macro().get_proof_term(goal, []).export() rpt = ProofReport() self.assertEqual(theory.check_proof(prf, rpt), Thm([], goal))
def testVCGIf(self): context.set_context(None, vars={'A': 'nat'}) c = parser.parse_term("Cond (%s. s (0::nat) = A) Skip (Assign 0 (%s. A))") P = parser.parse_term("%s::nat=>nat. true") Q = parser.parse_term("%s. s (0::nat) = A") goal = Valid(P, c, Q) prf = imp.vcg_solve(goal).export() self.assertEqual(theory.check_proof(prf), Thm([], goal))
def testVCGWhile(self): context.set_context(None, vars={"A": 'nat', "B": 'nat'}) c = parser.parse_term( "While (%s. ~s (0::nat) = A) (%s. s 1 = s 0 * B) (Seq (Assign 1 (%s. s 1 + B)) (Assign 0 (%s. s 0 + 1)))") P = parser.parse_term("%s. s (0::nat) = (0::nat) & s 1 = 0") Q = parser.parse_term("%s. s (1::nat) = A * B") goal = Valid(P, c, Q) prf = imp.vcg_solve(goal).export() self.assertEqual(theory.check_proof(prf), Thm([], goal))
def testExport(self): """Basic case.""" pt1 = ProofTerm.assume(Eq(x, y)) pt2 = ProofTerm.assume(Eq(y, z)) pt3 = pt1.transitive(pt2) prf = pt3.export() self.assertEqual(len(prf.items), 3) self.assertEqual(theory.check_proof(prf), pt3.th)
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 process_file(input, output): basic.load_theory('hoare') dn = os.path.dirname(os.path.realpath(__file__)) with open(os.path.join(dn, 'examples/' + input + '.json'), encoding='utf-8') as a: data = json.load(a) output = json_output.JSONTheory(output, ["hoare"], "Generated from " + input) content = data['content'] eval_count = 0 vcg_count = 0 for run in content[:5]: if run['ty'] == 'eval': com = parse_com(run['com']) st1 = mk_const_fun(NatType, nat.zero) for k, v in sorted(run['init'].items()): st1 = mk_fun_upd(st1, Nat(str_to_nat(k)), Nat(v)) st2 = mk_const_fun(NatType, nat.zero) for k, v in sorted(run['final'].items()): st2 = mk_fun_upd(st2, Nat(str_to_nat(k)), Nat(v)) Sem = imp.Sem(natFunT) goal = Sem(com, st1, st2) prf = ProofTerm("eval_Sem", goal, []).export() rpt = ProofReport() th = theory.check_proof(prf, rpt) output.add_theorem("eval" + str(eval_count), th, prf) eval_count += 1 elif run['ty'] == 'vcg': com = parse_com(run['com']) pre = Lambda(st, parse_cond(run['pre'])) post = Lambda(st, parse_cond(run['post'])) Valid = imp.Valid(natFunT) goal = Valid(pre, com, post) prf = imp.vcg_solve(goal).export() rpt = ProofReport() th = theory.check_proof(prf, rpt) output.add_theorem("vcg" + str(vcg_count), th, prf) vcg_count += 1 else: raise TypeError output.export_json()
def testExport2(self): """Repeated theorems.""" pt1 = ProofTerm.assume(Eq(x, y)) pt2 = ProofTerm.reflexive(f) pt3 = pt2.combination(pt1) # f x = f y pt4 = pt3.combination(pt1) # f x x = f y y prf = pt4.export() self.assertEqual(len(prf.items), 4) self.assertEqual(theory.check_proof(prf), pt4.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 run_test(self, data, verbose=False): Ta = TVar('a') context.set_context('nat', vars={ 'a': Ta, 'b': Ta, 'c': Ta, 'd': Ta, 'f': TFun(Ta, Ta), 'g': TFun(Ta, Ta), 'R': TFun(Ta, Ta, Ta), 'm': NatType, 'n': NatType, 'p': NatType, 'q': NatType, 'x': NatType, 'y': NatType, 'z': NatType }) closure = congc.CongClosureHOL() for item in data: if item[0] == MERGE: _, s, t = item s = parser.parse_term(s) t = parser.parse_term(t) closure.merge(s, t) if verbose: print("Merge %s, %s\nAfter\n%s" % (s, t, closure)) elif item[0] == CHECK: _, s, t, b = item s = parser.parse_term(s) t = parser.parse_term(t) self.assertEqual(closure.test(s, t), b) elif item[0] == EXPLAIN: _, s, t = item s = parser.parse_term(s) t = parser.parse_term(t) prf = closure.explain(s, t).export() self.assertEqual(theory.check_proof(prf), Thm([], Eq(s, t))) if verbose: print("Proof of %s" % Eq(s, t)) print(prf) elif item[0] == MATCH: _, pat, t, res = item pat = parser.parse_term(pat) t = parser.parse_term(t) for res_inst in res: for k in res_inst: res_inst[k] = parser.parse_term(res_inst[k]) inst = closure.ematch(pat, t) self.assertEqual(inst, res) else: raise NotImplementedError
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 testTseitin(self): t = Or(Implies(a,And(c,d)),Implies(b,And(c,e))) pt = tseitin.encode(t) self.assertEqual(len(pt.hyps), 11) self.assertEqual(len(pt.prop.strip_conj()), 16) rpt = report.ProofReport() self.assertEqual(theory.check_proof(pt.export(), rpt, check_level=1), pt.th) self.assertEqual(len(rpt.gaps), 0) cnf = tseitin.convert_cnf(pt.prop) self.assertEqual(len(cnf), 16)
def testComputeWP(self): Q = Var("Q", TFun(natFunT, BoolType)) test_data = [ (Assign(zero, Lambda(s, one)), Lambda(s, Q(mk_fun_upd(s, zero, one)))), (Seq(Assign(zero, Lambda(s, one)), Assign(one, Lambda(s, Nat(2)))), Lambda(s, Q(mk_fun_upd(s, zero, one, one, Nat(2))))), ] for c, P in test_data: prf = imp.compute_wp(natFunT, c, Q).export() self.assertEqual(theory.check_proof(prf), Thm([], Valid(P, c, Q)))
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 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 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 testIntro(self): basic.load_theory('logic_base') macro = logic.intros_macro() Ta = TVar('a') x = Var('x', Ta) P = Var('P', TFun(Ta, BoolType)) C = Var('C', BoolType) ex_P = Exists(x, P(x)) pt1 = ProofTerm.assume(ex_P) pt2 = ProofTerm.variable('x', Ta) pt3 = ProofTerm.assume(P(x)) pt4 = ProofTerm.sorry(Thm([P(x)], C)) pt4 = ProofTerm('intros', args=[ex_P], prevs=[pt1, pt2, pt3, pt4]) prf = pt4.export() self.assertEqual(theory.check_proof(prf), Thm([ex_P], C))
def testNormFunUpd(self): test_data = [ ((0, 1), (0, 1)), ((1, 0, 0, 5), (0, 5, 1, 0)), ((0, 1, 1, 5), (0, 1, 1, 5)), ((2, 0, 1, 1), (1, 1, 2, 0)), ((2, 0, 1, 1, 0, 2), (0, 2, 1, 1, 2, 0)), ((0, 1, 0, 2), (0, 2)), ((2, 0, 1, 1, 2, 1, 1, 2), (1, 2, 2, 1)), ] for n_f, n_res in test_data: f = fun_upd_of_seq(*n_f) res = fun_upd_of_seq(*n_res) cv = function.fun_upd_norm_conv() prf = cv.get_proof_term(f).export() self.assertEqual(theory.check_proof(prf), Thm([], Eq(f, res)))
def run_test(self, thy_name, tactic, *, vars=None, prevs=None, goal, args=None, new_goals=None, failed=None): """Test a single invocation of a tactic.""" context.set_context(thy_name, vars=vars) assms = [parser.parse_term(prev) for prev in prevs] if prevs is not None else [] prf = Proof(*assms) prevs = [ ProofTerm.atom(i, Thm.assume(assm)) for i, assm in enumerate(assms) ] goal = parser.parse_term(goal) goal_pt = ProofTerm.sorry(Thm(assms, goal)) # Invoke the tactic to get the proof term if failed is not None: self.assertRaises(failed, tactic.get_proof_term, goal_pt, prevs=prevs, args=args) return pt = tactic.get_proof_term(goal_pt, prevs=prevs, args=args) # Export and check proof prefix = ItemID(len(prevs) - 1) if len(prevs) > 0 else ItemID(len(prevs)) prf = pt.export(prefix=prefix, prf=prf, subproof=False) self.assertEqual(theory.check_proof(prf), Thm(assms, goal)) # Test agreement of new goals new_goals = [parser.parse_term(new_goal) for new_goal in new_goals ] if new_goals is not None else [] concls = [goal.prop for goal in prf.get_sorrys()] self.assertEqual(new_goals, concls)
def test_macro(self, thy_name, macro, *, vars=None, assms=None, res=None, args="", failed=None, limit=None, eval_only=False): context.set_context(thy_name, vars=vars, limit=limit) macro = theory.global_macros[macro] assms = [parser.parse_term(assm) for assm in assms] if assms is not None else [] prev_ths = [Thm([assm], assm) for assm in assms] prevs = [ProofTerm.assume(assm) for assm in assms] args = parser.parse_args(macro.sig, args) if failed is not None: self.assertRaises(failed, macro.eval, args, prev_ths) if not eval_only: self.assertRaises(failed, macro.get_proof_term, args, prevs) return res = parser.parse_term(res) # Check the eval function self.assertEqual(macro.eval(args, prev_ths), Thm(assms, res)) # Check the proof term if not eval_only: pt = macro.get_proof_term(args, prevs) prf = pt.export() self.assertEqual(theory.check_proof(prf), Thm(assms, res))
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))