def get_proof(self): invC = Const("inv", TFun(gcl.stateT, boolT)) transC = Const("trans", TFun(gcl.stateT, gcl.stateT, boolT)) s1 = Var("s1", gcl.stateT) s2 = Var("s2", gcl.stateT) prop = Thm.mk_implies(invC(s1), transC(s1, s2), invC(s2)) # print(printer.print_thm(self.thy, prop)) trans_pt = ProofTerm.assume(transC(s1, s2)) # print(printer.print_thm(self.thy, trans_pt.th)) P = Term.mk_implies(invC(s1), invC(s2)) ind_pt = apply_theorem(self.thy, "trans_cases", inst={ "a1": s1, "a2": s2, "P": P }) # print(printer.print_thm(self.thy, ind_pt.th)) ind_As, ind_C = ind_pt.prop.strip_implies() for ind_A in ind_As[1:-1]: # print("ind_A: ", printer.print_term(self.thy, ind_A)) vars, As, C = logic.strip_all_implies(ind_A, ["s", "k"]) # for A in As: # print("A: ", printer.print_term(self.thy, A)) # print("C: ", printer.print_term(self.thy, C)) eq1 = ProofTerm.assume(As[0]) eq2 = ProofTerm.assume(As[1]) guard = ProofTerm.assume(As[2]) inv_pre = ProofTerm.assume(As[3]).on_arg(self.thy, rewr_conv(eq1)) \ .on_prop(self.thy, rewr_conv("inv_def")) C_goal = ProofTerm.assume(C).on_arg(self.thy, rewr_conv(eq2)) \ .on_prop(self.thy, rewr_conv("inv_def"))
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 testInferTypeFail3(self): test_data = [ Var('s', None)(Var('s', None)), ] for t in test_data: self.assertRaisesRegex(TypeInferenceException, "Infinite loop", type_infer, t)
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 testRule(self): A = Var('A', boolT) B = Var('B', boolT) goal = Thm([], conj(B, A)) pt = tactic.rule().get_proof_term(thy, ProofTerm.sorry(goal), args='conjI') prf = pt.export() self.assertEqual(thy.check_proof(prf), goal)
def get_proof(self): invC = Const("inv", TFun(gcl.stateT, BoolType)) transC = Const("trans", TFun(gcl.stateT, gcl.stateT, BoolType)) s1 = Var("s1", gcl.stateT) s2 = Var("s2", gcl.stateT) prop = Thm([], Implies(invC(s1), transC(s1, s2), invC(s2))) # print(printer.print_thm(prop)) trans_pt = ProofTerm.assume(transC(s1, s2)) # print(printer.print_thm(trans_pt.th)) P = Implies(invC(s1), invC(s2)) ind_pt = apply_theorem("trans_cases", inst=Inst(a1=s1, a2=s2, P=P)) # print(printer.print_thm(ind_pt.th)) ind_As, ind_C = ind_pt.prop.strip_implies() for ind_A in ind_As[1:-1]: # print("ind_A: ", ind_A) vars, As, C = logic.strip_all_implies(ind_A, ["s", "k"]) # for A in As: # print("A: ", A) # print("C: ", C) eq1 = ProofTerm.assume(As[0]) eq2 = ProofTerm.assume(As[1]) guard = ProofTerm.assume(As[2]) inv_pre = ProofTerm.assume(As[3]).on_arg(rewr_conv(eq1)).on_prop( rewr_conv("inv_def")) C_goal = ProofTerm.assume(C).on_arg(rewr_conv(eq2)).on_prop( rewr_conv("inv_def"))
def rec(t): if t.is_exists(): # Obtain the list of variables that t depends on, not # counting functions (including skolem functions). xs = [v for v in t.arg.body.get_vars() if not v.T.is_fun()] # Obtain the new skolem variable. nm = "c_" + t.arg.var_name if len( xs) == 0 else "f_" + t.arg.var_name nm = name.get_variant_name(nm, var_names) var_names.append(nm) # Obtain the concrete instantiation of the skolem variable. T = TFun(*([x.T for x in xs] + [t.arg.var_T])) f = Var(nm, T)(*xs) return rec(t.arg.subst_bound(f)) elif t.is_forall(): nm = name.get_variant_name(t.arg.var_name, var_names) var_names.append(nm) v = Var(nm, t.arg.var_T) body = t.arg.subst_bound(v) return Forall(v, rec(body)) elif t.is_conj() or t.is_disj(): return t.head(rec(t.arg1), rec(t.arg)) else: return t
def testAllConj(self): """Proof of (!x. A x & B x) --> (!x. A x) & (!x. B x).""" thy = basic.load_theory('logic_base') Ta = TVar("a") A = Var("A", TFun(Ta, boolT)) B = Var("B", TFun(Ta, boolT)) x = Var("x", Ta) all_conj = Term.mk_all(x, logic.mk_conj(A(x), B(x))) all_A = Term.mk_all(x, A(x)) all_B = Term.mk_all(x, B(x)) conj_all = logic.mk_conj(all_A, all_B) prf = Proof(all_conj) prf.add_item(1, "forall_elim", args=x, prevs=[0]) prf.add_item(2, "theorem", args="conjD1") prf.add_item(3, "substitution", args={"A": A(x), "B": B(x)}, prevs=[2]) prf.add_item(4, "implies_elim", prevs=[3, 1]) prf.add_item(5, "forall_intr", args=x, prevs=[4]) prf.add_item(6, "theorem", args="conjD2") prf.add_item(7, "substitution", args={"A": A(x), "B": B(x)}, prevs=[6]) prf.add_item(8, "implies_elim", prevs=[7, 1]) prf.add_item(9, "forall_intr", args=x, prevs=[8]) prf.add_item(10, "theorem", args="conjI") prf.add_item(11, "substitution", args={ "A": all_A, "B": all_B }, prevs=[10]) prf.add_item(12, "implies_elim", prevs=[11, 5]) prf.add_item(13, "implies_elim", prevs=[12, 9]) prf.add_item(14, "implies_intr", args=all_conj, prevs=[13]) th = Thm.mk_implies(all_conj, conj_all) self.assertEqual(thy.check_proof(prf), th)
def testDisjCommWithMacro(self): """Proof of commutativity of disjunction, with macros.""" thy = basic.load_theory('logic_base') A = Var("A", boolT) B = Var("B", boolT) disjAB = logic.mk_disj(A, B) disjBA = logic.mk_disj(B, A) prf = Proof(disjAB) prf.add_item(1, "assume", args=A) prf.add_item(2, "apply_theorem_for", args=("disjI2", {}, { "A": B, "B": A }), prevs=[1]) prf.add_item(3, "implies_intr", args=A, prevs=[2]) prf.add_item(4, "assume", args=B) prf.add_item(5, "apply_theorem_for", args=("disjI1", {}, { "A": B, "B": A }), prevs=[4]) prf.add_item(6, "implies_intr", args=B, prevs=[5]) prf.add_item(7, "apply_theorem", args="disjE", prevs=[0, 3, 6]) prf.add_item(8, "implies_intr", args=disjAB, prevs=[7]) th = Thm.mk_implies(disjAB, disjBA) self.assertEqual(thy.check_proof(prf), th)
def testFirstOrderMatchFun(self): """First-order matching of variables in function position.""" P = Var("P", TFun(Ta, boolT)) Q = Var("Q", TFun(Ta, boolT)) C = Const("C", TFun(boolT, boolT, boolT)) test_data = [ (abs(x, P(x)), abs(x, C(P(x), Q(x))), { "P": abs(x, C(P(x), Q(x))) }), (abs(x, C(P(x), Q(x))), abs(x, C(Q(x), P(x))), { "P": Q, "Q": P }), (abs(x, C(P(x), P(x))), abs(x, C(C(P(x), Q(x)), C(P(x), Q(x)))), { "P": abs(x, C(P(x), Q(x))) }), (exists(x, P(x)), exists(x, conj(P(x), Q(x))), { "P": abs(x, conj(P(x), Q(x))) }), ] for pat, t, inst in test_data: if inst is not None: self.assertEqual(matcher.first_order_match(pat, t)[1], inst) else: self.assertRaises(matcher.MatchException, matcher.first_order_match, pat, t)
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 testInferTypeFail2(self): test_data = [ Abs("x", None, Abs("y", None, Const("equals", None)(Var("x", None), Var("y", None)))), Const("nil", None), ] for t in test_data: self.assertRaisesRegex(TypeInferenceException, "Unspecified type", type_infer, t)
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 testInferTypeFail(self): test_data = [(Const("implies", None)(Var("A1", nat.natT), Var("A2", None))), (Const("equals", None)(Var("A", None), Var("a", None)))] for t in test_data: self.assertRaisesRegex(TypeInferenceException, "Unable to unify", type_infer, thy, ctxt, t)
def testIsPattern(self): test_data = [ (Var('a', Ta), True), (Var('f', TFun(Ta, Tb))(Var('a', Ta)), False), (Const('f', TFun(Ta, Tb))(Var('a', Ta)), True), ] for t, res in test_data: self.assertEqual(matcher.is_pattern(t, []), res)
def testParseNamedThm(self): A = Var('A', BoolType) B = Var('B', BoolType) test_data = [("conjI: A = B", ('conjI', Eq(A, B))), ("A = B", (None, Eq(A, B)))] context.set_context('logic_base', vars={'A': 'bool', 'B': 'bool'}) for s, res in test_data: self.assertEqual(parser.parse_named_thm(s), res)
def testPrintThmHighlight(self): """Test printing of theorems with highlight.""" # 0, 1, 2, 3 = NORMAL, BOUND, VAR, TVAR A = Var('A', boolT) B = Var('B', boolT) A_to_B = Term.mk_implies(A, B) th = Thm([A, A_to_B], B) res = printer.print_thm(thy, th, highlight=True) self.assertEqual(res, [('A',2),(', ',0),('A',2),(' --> ',0),('B',2),(' ',0),('|-',0),(' ',0),('B',2)])
def testIntros(self): Ta = TVar('a') x = Var('x', Ta) P = Var('P', TFun(Ta, boolT)) Q = Var('Q', TFun(Ta, boolT)) goal = Thm([], Term.mk_all(x, Term.mk_implies(P(x), Q(x)))) intros_tac = tactic.intros() pt = intros_tac.get_proof_term(thy, ProofTerm.sorry(goal), args=['x']) prf = pt.export() self.assertEqual(thy.check_proof(prf), goal)
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 testIntroduction3(self): Ta = TVar("a") A = Var("A", TFun(Ta, boolT)) B = Var("B", TFun(Ta, boolT)) x = Var("x", Ta) state = ProofState.init_state(thy, [A, B], [], Term.mk_all(x, imp(A(x), B(x)))) state.introduction(0, ["x"]) self.assertEqual(state.check_proof(), Thm([], Term.mk_all(x, imp(A(x), B(x))))) self.assertEqual(len(state.prf.items), 1) self.assertEqual(len(state.prf.items[0].subproof.items), 4)
def testVCGWhile(self): A = Var("A", natT) B = Var("B", natT) ctxt = {"A": natT, "B": natT} c = parser.parse_term(thy, ctxt, \ "While (%s. ~s 0 = A) (%s. s 1 = s 0 * B) (Seq (Assign 1 (%s. s 1 + B)) (Assign 0 (%s. s 0 + 1)))") P = parser.parse_term(thy, ctxt, "%s. s 0 = 0 & s 1 = 0") Q = parser.parse_term(thy, ctxt, "%s. s 1 = A * B") goal = Valid(P, c, Q) prf = hoare.vcg_solve(thy, goal).export() self.assertEqual(thy.check_proof(prf), Thm([], goal))
def testBetaNorm(self): x = Var('x', Ta) y = Var('y', Ta) test_data = [ (Lambda(x, x)(x), x), (Lambda(x, Lambda(y, y))(x, y), y), (Lambda(x, Lambda(y, x))(x, y), x), ] for t, res in test_data: self.assertEqual(t.beta_norm(), res)
def testPrintInterval(self): m = Var("m", NatType) n = Var("n", NatType) test_data = [ (interval.mk_interval(m, n), "{m..n}"), (interval.mk_interval(nat.one, m), "{1..m}"), ] basic.load_theory('iterate') for t, s in test_data: self.assertEqual(printer.print_term(t), s)
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 testIsLiteralSet(self): Ta = TVar('a') x = Var('x', Ta) y = Var('x', Ta) test_data = [ (set.empty_set(Ta), True), (set.mk_insert(x, set.empty_set(Ta)), True), (x, False), ] for t, res in test_data: self.assertEqual(set.is_literal_set(t), res)
def testBetaNorm(self): x = Var('x', Ta) y = Var('y', Ta) abs = term.Term.mk_abs test_data = [ (abs(x, x)(x), x), (abs(x, abs(y, y))(x, y), y), (abs(x, abs(y, x))(x, y), x), ] for t, res in test_data: self.assertEqual(t.beta_norm(), res)
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 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 convert_cnf_to_HOL(cnf_file): disjs = read_cnf_file(cnf_file) tms = [] for disj in disjs: lits = [] for var, stat in disj: if stat: lits.append(Var(var, BoolType)) else: lits.append(Not(Var(var, BoolType))) tms.append(Or(*lits)) return And(*tms)