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 testCheckProofGap(self): """Check proof with gap.""" prf = Proof() prf.add_item(0, "sorry", th = Thm.mk_implies(A,B)) prf.add_item(1, "sorry", th = Thm([], A)) prf.add_item(2, "implies_elim", prevs=[0, 1]) rpt = ProofReport() self.assertEqual(thy.check_proof(prf, rpt), Thm([], B)) self.assertEqual(rpt.gaps, [Thm.mk_implies(A, B), Thm([], A)])
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.""" 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 testDoubleNegInv(self): """Proof of ~~A --> A, requires classical axiom.""" thy = basic.load_theory('logic_base') A = Var("A", boolT) neg = logic.neg prf = Proof(neg(neg(A))) prf.add_item(1, "theorem", args="classical") prf.add_item(2, "assume", args=A) prf.add_item(3, "assume", args=neg(A)) prf.add_item(4, "theorem", args="negE") prf.add_item(5, "substitution", args={"A": neg(A)}, prevs=[4]) prf.add_item(6, "implies_elim", prevs=[5, 0]) prf.add_item(7, "implies_elim", prevs=[6, 3]) prf.add_item(8, "theorem", args="falseE") prf.add_item(9, "implies_elim", prevs=[8, 7]) prf.add_item(10, "implies_intr", args=A, prevs=[2]) prf.add_item(11, "implies_intr", args=neg(A), prevs=[9]) prf.add_item(12, "theorem", args="disjE") prf.add_item(13, "substitution", args={ "B": neg(A), "C": A }, prevs=[12]) prf.add_item(14, "implies_elim", prevs=[13, 1]) prf.add_item(15, "implies_elim", prevs=[14, 10]) prf.add_item(16, "implies_elim", prevs=[15, 11]) prf.add_item(17, "implies_intr", args=neg(neg(A)), prevs=[16]) th = Thm.mk_implies(neg(neg(A)), A) self.assertEqual(thy.check_proof(prf), th)
def testAddLineAfter(self): state = ProofState.init_state(thy, [A, B], [conj(A, B)], conj(B, A)) state.add_line_after(0) self.assertEqual(len(state.prf.items), 4) self.assertEqual(state.check_proof(), Thm.mk_implies(conj(A, B), conj(B, A))) self.assertEqual(state.prf.items[1].rule, "")
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 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 testConjComm(self): """Proof of A & B --> B & A.""" state = ProofState.init_state(thy, [A, B], [conj(A, B)], conj(B, A)) state.apply_backward_step(1, "conjI") state.apply_backward_step(1, "conjD2", prevs=[0]) state.apply_backward_step(2, "conjD1", prevs=[0]) self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_implies(conj(A, B), conj(B, A)))
def testDoubleNegInv(self): """Proof of ~~A --> A.""" state = ProofState.init_state(thy, [A], [neg(neg(A))], A) state.apply_cases(1, A) state.introduction(1) state.introduction(2) state.apply_backward_step((2, 1), "negE_gen", prevs=[0]) self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_implies(neg(neg(A)), A))
def testCheckProof2(self): """Proof of |- A --> A.""" prf = Proof(A) prf.add_item(1, "implies_intr", args=A, prevs=[0]) rpt = ProofReport() self.assertEqual(thy.check_proof(prf, rpt), Thm.mk_implies(A,A)) self.assertEqual(rpt.steps, 2)
def testDisjComm(self): """Proof of A | B --> B | A.""" state = ProofState.init_state(thy, [A, B], [disj(A, B)], disj(B, A)) state.apply_backward_step(1, "disjE", prevs=[0]) state.introduction(1) state.apply_backward_step((1, 1), "disjI2", prevs=[(1, 0)]) state.introduction(2) state.apply_backward_step((2, 1), "disjI1", prevs=[(2, 0)]) self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_implies(disj(A, B), disj(B, 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 testInductPredicate(self): nat = Type("nat") even = Const("even", TFun(nat, boolT)) zero = Const("zero", nat) Suc = Const("Suc", TFun(nat, nat)) n = Var("n", nat) prop_zero = even(zero) prop_Suc = Term.mk_implies(even(n), even(Suc(Suc(n)))) data = [("even_zero", prop_zero), ("even_Suc", prop_Suc)] even_ext = induct.add_induct_predicate("even", TFun(nat, boolT), data) a1 = Var("_a1", nat) P = Var("P", boolT) res = [ AxConstant("even", TFun(nat, boolT)), Theorem("even_zero", Thm([], even(zero))), Attribute("even_zero", "hint_backward"), Theorem("even_Suc", Thm.mk_implies(even(n), even(Suc(Suc(n))))), Attribute("even_Suc", "hint_backward"), Theorem("even_cases", Thm.mk_implies(even(a1), imp(eq(a1,zero), P), all(n, imp(eq(a1,Suc(Suc(n))), even(n), P)), P)) ] self.assertEqual(even_ext.data, res)
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 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 testExistsConj(self): """Proof of (?x. A x & B x) --> (?x. A x) & (?x. B x).""" Ta = TVar("a") A = Var("A", TFun(Ta, boolT)) B = Var("B", TFun(Ta, boolT)) x = Var("x", Ta) ex_conj = exists(x, conj(A(x), B(x))) conj_ex = conj(exists(x, A(x)), exists(x, B(x))) state = ProofState.init_state(thy, [A, B], [ex_conj], conj_ex) state.apply_backward_step(1, "exE", prevs=[0]) state.introduction(1, "x") state.apply_backward_step((1, 2), "conjI") state.apply_forward_step((1, 2), "conjD1", prevs=[(1, 1)]) state.apply_backward_step((1, 3), "exI", prevs=[(1, 2)]) state.apply_forward_step((1, 4), "conjD2", prevs=[(1, 1)]) state.apply_backward_step((1, 5), "exI", prevs=[(1, 4)]) self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_implies(ex_conj, conj_ex))
def testDoubleNeg(self): """Proof of A --> ~~A.""" thy = basic.load_theory('logic_base') A = Var("A", boolT) neg = logic.neg prf = Proof(A) prf.add_item(1, "assume", args=neg(A)) prf.add_item(2, "theorem", args="negE") prf.add_item(3, "implies_elim", prevs=[2, 1]) prf.add_item(4, "implies_elim", prevs=[3, 0]) prf.add_item(5, "implies_intr", args=neg(A), prevs=[4]) prf.add_item(6, "theorem", args="negI") prf.add_item(7, "substitution", args={"A": neg(A)}, prevs=[6]) prf.add_item(8, "implies_elim", prevs=[7, 5]) prf.add_item(9, "implies_intr", args=A, prevs=[8]) th = Thm.mk_implies(A, neg(neg(A))) self.assertEqual(thy.check_proof(prf), th)
def testDoubleNegInvWithMacro(self): """Proof of ~~A --> A, using macros.""" thy = basic.load_theory('logic_base') A = Var("A", boolT) neg = logic.neg prf = Proof(neg(neg(A))) prf.add_item(1, "theorem", args="classical") prf.add_item(2, "assume", args=A) prf.add_item(3, "assume", args=neg(A)) prf.add_item(4, "apply_theorem", args="negE", prevs=[0, 3]) prf.add_item(5, "apply_theorem", args="falseE", prevs=[4]) prf.add_item(6, "implies_intr", args=A, prevs=[2]) prf.add_item(7, "implies_intr", args=neg(A), prevs=[5]) prf.add_item(8, "apply_theorem", args="disjE", prevs=[1, 6, 7]) prf.add_item(9, "implies_intr", args=neg(neg(A)), prevs=[8]) th = Thm.mk_implies(neg(neg(A)), A) self.assertEqual(thy.check_proof(prf), th)
def testConjComm(self): """Proof of commutativity of conjunction.""" 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, "theorem", args="conjD1") prf.add_item(2, "implies_elim", prevs=[1, 0]) prf.add_item(3, "theorem", args="conjD2") prf.add_item(4, "implies_elim", prevs=[3, 0]) prf.add_item(5, "theorem", args="conjI") prf.add_item(6, "substitution", args={"A": B, "B": A}, prevs=[5]) prf.add_item(7, "implies_elim", prevs=[6, 4]) prf.add_item(8, "implies_elim", prevs=[7, 2]) prf.add_item(9, "implies_intr", args=logic.mk_conj(A, B), prevs=[8]) 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 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 testDisjComm(self): """Proof of commutativity of disjunction.""" 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, "theorem", args="disjI2") prf.add_item(2, "substitution", args={"A": B, "B": A}, prevs=[1]) prf.add_item(3, "theorem", args="disjI1") prf.add_item(4, "substitution", args={"A": B, "B": A}, prevs=[3]) prf.add_item(5, "theorem", args="disjE") prf.add_item(6, "substitution", args={"C": disjBA}, prevs=[5]) prf.add_item(7, "implies_elim", prevs=[6, 0]) prf.add_item(8, "implies_elim", prevs=[7, 2]) prf.add_item(9, "implies_elim", prevs=[8, 4]) prf.add_item(10, "implies_intr", args=disjAB, prevs=[9]) th = Thm.mk_implies(disjAB, disjBA) self.assertEqual(thy.check_proof(prf), th)
def testAllConjWithMacro(self): """Proof of (!x. A x & B x) --> (!x. A x) & (!x. B x), using macros.""" 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, "apply_theorem", args="conjD1", prevs=[1]) prf.add_item(3, "forall_intr", args=x, prevs=[2]) prf.add_item(4, "apply_theorem", args="conjD2", prevs=[1]) prf.add_item(5, "forall_intr", args=x, prevs=[4]) prf.add_item(6, "apply_theorem", args="conjI", prevs=[3, 5]) prf.add_item(7, "implies_intr", args=all_conj, prevs=[6]) th = Thm.mk_implies(all_conj, conj_all) self.assertEqual(thy.check_proof(prf), th)
def testExistsConjWithMacro(self): """Proof of (?x. A x & B x) --> (?x. A x) & (?x. B x), using macros.""" 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) conjAB = logic.mk_conj(A(x), B(x)) exists_conj = logic.mk_exists(x, conjAB) exists_A = logic.mk_exists(x, A(x)) exists_B = logic.mk_exists(x, B(x)) conj_exists = logic.mk_conj(exists_A, exists_B) prf = Proof(exists_conj) prf.add_item(1, "assume", args=conjAB) prf.add_item(2, "apply_theorem", args="conjD1", prevs=[1]) prf.add_item(3, "apply_theorem", args="conjD2", prevs=[1]) prf.add_item(4, "apply_theorem_for", args=("exI", {}, { 'P': A, 'a': x }), prevs=[2]) prf.add_item(5, "apply_theorem_for", args=("exI", {}, { 'P': B, 'a': x }), prevs=[3]) prf.add_item(6, "apply_theorem", args="conjI", prevs=[4, 5]) prf.add_item(7, "implies_intr", args=conjAB, prevs=[6]) prf.add_item(8, "forall_intr", args=x, prevs=[7]) prf.add_item(9, "apply_theorem", args="exE", prevs=[0, 8]) prf.add_item(10, "implies_intr", args=exists_conj, prevs=[9]) th = Thm.mk_implies(exists_conj, conj_exists) self.assertEqual(thy.check_proof(prf), th)
def add_induct_type(name, targs, constrs): """Add the given inductive type to the theory. The inductive type is specified by name, arity (as list of default names of type arguments), and a list of constructors (triple consisting of name of the constant, type of the constant, and a list of suggested names of the arguments). For example, the natural numbers is specified by: (nat, [], [(0, nat, []), (Suc, nat => nat, ["n"])]). List type is specified by: (list, ["a"], [(nil, 'a list, []), (cons, 'a => 'a list => 'a list, ["x", "xs"])]). """ exts = TheoryExtension() # Add to type and term signature. exts.add_extension(AxType(name, len(targs))) for cname, cT, _ in constrs: exts.add_extension(AxConstant(cname, cT)) # Add non-equality theorems. for (cname1, cT1, vars1), (cname2, cT2, vars2) in itertools.combinations(constrs, 2): # For each A x_1 ... x_m and B y_1 ... y_n, get the theorem # ~ A x_1 ... x_m = B y_1 ... y_n. argT1, _ = cT1.strip_type() argT2, _ = cT2.strip_type() lhs_vars = [Var(nm, T) for nm, T in zip(vars1, argT1)] rhs_vars = [Var(nm, T) for nm, T in zip(vars2, argT2)] A = Const(cname1, cT1) B = Const(cname2, cT2) lhs = A(*lhs_vars) rhs = B(*rhs_vars) neq = logic.neg(Term.mk_equals(lhs, rhs)) th_name = name + "_" + cname1 + "_" + cname2 + "_neq" exts.add_extension(Theorem(th_name, Thm([], neq))) # Add injectivity theorems. for cname, cT, vars in constrs: # For each A x_1 ... x_m with m > 0, get the theorem # A x_1 ... x_m = A x_1' ... x_m' --> x_1 = x_1' & ... & x_m = x_m' if vars: argT, _ = cT.strip_type() lhs_vars = [Var(nm, T) for nm, T in zip(vars, argT)] rhs_vars = [Var(nm + "'", T) for nm, T in zip(vars, argT)] A = Const(cname, cT) assum = Term.mk_equals(A(*lhs_vars), A(*rhs_vars)) concls = [ Term.mk_equals(var1, var2) for var1, var2 in zip(lhs_vars, rhs_vars) ] concl = logic.mk_conj(*concls) if len(concls) > 1 else concls[0] th_name = name + "_" + cname + "_inject" exts.add_extension(Theorem(th_name, Thm.mk_implies(assum, concl))) # Add the inductive theorem. tvars = [TVar(targ) for targ in targs] T = Type(name, *tvars) var_P = Var("P", TFun(T, boolT)) ind_assums = [] for cname, cT, vars in constrs: A = Const(cname, cT) argT, _ = cT.strip_type() args = [Var(nm, T2) for nm, T2 in zip(vars, argT)] C = var_P(A(*args)) As = [var_P(Var(nm, T2)) for nm, T2 in zip(vars, argT) if T2 == T] ind_assum = Term.mk_implies(*(As + [C])) for arg in reversed(args): ind_assum = Term.mk_all(arg, ind_assum) ind_assums.append(ind_assum) ind_concl = var_P(Var("x", T)) th_name = name + "_induct" exts.add_extension( Theorem(th_name, Thm.mk_implies(*(ind_assums + [ind_concl])))) exts.add_extension(Attribute(th_name, "var_induct")) return exts
def testParseInitState(self): state = ProofState.parse_init_state( thy, {'vars': {'A': 'bool', 'B': 'bool'}, 'prop': "A & B --> B & A"}) self.assertEqual(len(state.prf.items), 3) self.assertEqual(state.check_proof(), Thm.mk_implies(conj(A, B), conj(B, A)))
def testInitProof2(self): state = ProofState.init_state(thy, [A, B], [A, B], conj(A, B)) self.assertEqual(len(state.prf.items), 4) self.assertEqual(state.check_proof(), Thm.mk_implies(A, B, conj(A, B)))
def testIntroduction2(self): state = ProofState.init_state(thy, [A, B], [], imp(A, B, conj(A, B))) state.introduction(0) self.assertEqual(state.check_proof(), Thm.mk_implies(A, B, conj(A, B)))