def testPrintExtension(self): exts = [TConst("nat", 0), Constant("id", TFun(TVar("a"), TVar("a")))] str_exts = ["Type nat 0", "Constant id :: 'a => 'a"] for ext, str_ext in zip(exts, str_exts): with global_setting(unicode=False): self.assertEqual(str(ext), str_ext)
def testParseTypeInd(self): test_data = [ ("cons (x ::'a) (xs ::'a list)", { 'name': 'cons', 'type': [TVar('a'), TConst('list', TVar('a'))], 'args': ['x', 'xs'] }), ] basic.load_theory('list') for s, res in test_data: self.assertEqual(parser.parse_ind_constr(s), res)
def testFromInternalInstsp(self): test_data = [ (({ "_a": TVar("a") }, { "_x": Var("x", TVar("a")) }), ({ "a": TVar("a") }, { "x": Var("x", TVar("a")) })), ] for instsp, res in test_data: self.assertEqual(matcher.from_internal_instsp(instsp), res)
def testPrintType(self): test_data = [ (Ta, "'a"), (TVar("ab"), "'ab"), (TConst("bool"), "bool"), (TConst("list", Ta), "'a list"), (TConst("list", TConst("list", Ta)), "'a list list"), (TConst("tree", Ta, Tb), "('a, 'b) tree"), (TFun(Ta, Tb), "'a => 'b"), (TFun(Ta, Tb, Tc), "'a => 'b => 'c"), (TFun(TFun(Ta, Tb), Tc), "('a => 'b) => 'c"), (TFun(TConst("list", Ta), Tb), "'a list => 'b"), (TFun(Ta, TConst("list", Tb)), "'a => 'b list"), (TConst("list", TFun(Ta, Tb)), "('a => 'b) list"), (TConst("list", TConst("list", TFun(Ta, Tb))), "('a => 'b) list list"), (TFun(TConst("list", Ta), TConst("list", Tb)), "'a list => 'b list"), (TConst("list", TFun(TConst("list", Ta), Tb)), "('a list => 'b) list"), ] for T, str_T in test_data: with global_setting(unicode=False): self.assertEqual(str(T), str_T)
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 to_internal_tvars(pat_T): """Add underscore to each type variable in the pattern.""" if pat_T.ty == HOLType.TVAR: return TVar("_" + pat_T.name) elif pat_T.ty == HOLType.TYPE: return Type(pat_T.name, *[to_internal_tvars(arg) for arg in pat_T.args])
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 testPrintFunction(self): f = Var("f", TFun(Ta, Ta)) Tb = TVar('b') Tc = TVar('c') g = Var('g', TFun(Tb, Tc)) h = Var('h', TFun(Ta, Tb)) test_data = [ (function.mk_fun_upd(f, a, b), "(f)(a := b)"), (function.mk_fun_upd(f, a, b, b, a), "(f)(a := b, b := a)"), (function.mk_comp(g, h), "g O h"), (function.mk_comp(g, h)(a), "(g O h) a"), (function.mk_const_fun(NatType, nat.zero), "%x::nat. (0::nat)"), ] basic.load_theory('function') with global_setting(unicode=False): for t, s in test_data: self.assertEqual(printer.print_term(t), s)
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 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 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 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 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 testToInternalVars(self): test_data = [ (Var("x", TVar("a")), Var("_x", TVar("_a"))), (Var("x", natT), Var("_x", natT)), (Const("x", TVar("a")), Const("x", TVar("_a"))), (Const("x", natT), Const("x", natT)), (Abs("x", TVar("a"), Var("y", TVar("b"))), Abs("x", TVar("_a"), Var("_y", TVar("_b")))), ] for t, res in test_data: self.assertEqual(matcher.to_internal_vars(t), res)
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 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 EmptyTheory(): """Empty theory, with the absolute minimum setup.""" thy = Theory() # Fundamental data structures, needed for proof checking. thy.add_data_type("type_sig") thy.add_data_type("term_sig") thy.add_data_type("theorems") thy.add_data_type("proof_macro") thy.add_data_type("method") thy.add_data_type("attributes") # Fundamental types. thy.add_type_sig("bool", 0) thy.add_type_sig("fun", 2) # Fundamental terms. thy.add_term_sig("equals", TFun(TVar("a"), TVar("a"), boolT)) thy.add_term_sig("implies", TFun(boolT, boolT, boolT)) thy.add_term_sig("all", TFun(TFun(TVar("a"), boolT), boolT)) return thy
def EmptyTheory(): """Empty theory, with the absolute minimum setup.""" thy = Theory() # Fundamental data structures, needed for proof checking. thy.add_data_type("type_sig") thy.add_data_type("term_sig") thy.add_data_type("theorems") thy.add_data_type( "theorems_svar") # cache of version of theorem with SVar. thy.add_data_type("attributes") thy.add_data_type("overload") # Fundamental types. thy.add_type_sig("bool", 0) thy.add_type_sig("fun", 2) # Fundamental terms. thy.add_term_sig("equals", TFun(TVar("a"), TVar("a"), BoolType)) thy.add_term_sig("implies", TFun(BoolType, BoolType, BoolType)) thy.add_term_sig("all", TFun(TFun(TVar("a"), BoolType), BoolType)) return thy
def testInductProd(self): Ta = TVar("a") Tb = TVar("b") Tab = Type("prod", Ta, Tb) prod_ext = induct.add_induct_type( "prod", ["a", "b"], [("Pair", TFun(Ta, Tb, Tab), ["a", "b"])]) a = Var("a", Ta) b = Var("b", Tb) a2 = Var("a'", Ta) b2 = Var("b'", Tb) pair = Const("Pair", TFun(Ta, Tb, Tab)) P = Var("P", TFun(Tab, boolT)) x = Var("x", Tab) res = [ AxType("prod", 2), AxConstant("Pair", TFun(Ta, Tb, Tab)), Theorem("prod_Pair_inject", Thm([], imp(eq(pair(a, b), pair(a2, b2)), conj(eq(a, a2), eq(b, b2))))), Theorem("prod_induct", Thm([], imp(all(a, all(b, P(pair(a, b)))), P(x)))), Attribute("prod_induct", "var_induct") ] self.assertEqual(prod_ext.data, res)
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 check_modify(): """Check a modified item for validity.""" data = json.loads(request.get_data().decode("utf-8")) error = {} item = data['content'] thy = basic.load_theory('list') if item['ty'] == 'thm' or item['ty'] == 'thm.ax': vars = {} for v in item['vars'].split('\n'): (nm, T) = parser.parse_thm_vars(thy, v) if nm: vars[nm.strip()] = T.strip() item['vars'] = vars if item['ty'] == 'type.ind': constrs, temp_list = [], [] if len(item['data_name'].split(' ')) > 1: temp_list.append(item['data_name'].split(' ')[0][1:]) item['name'] = item['data_name'].split(' ')[1] else: item['name'] = item['data_name'] item['args'] = temp_list apd = Type(item['name'], *(TVar(nm) for nm in item['args'])) for c in item['data_content'].split('\n'): constr = parser.parse_type_ind(thy, c) type_list = constr['type'] + [apd] constr['type'] = str(TFun(type_list)) constrs.append(constr) item['constrs'] = constrs # if item['ty'] == 'def.ind' or item['ty'] == 'def' or item['ty'] == 'def.pred': # item['name'] = parser.parse_thm_vars(thy, item['data_name'])[0] # item['type'] = parser.parse_thm_vars(thy, item['data_name'])[1] with open_file(data['file_name'], 'r') as f: f_data = json.load(f) try: thy = basic.load_imported_theory(f_data['imports'], user_info['username']) for d in data['prev_list']: parser.parse_extension(thy, d) file_data_to_output(thy, item) except Exception as e: exc_detailed = traceback2.format_exc() return jsonify({ "failed": e.__class__.__name__, "message": str(e), "detail_content": exc_detailed }) return jsonify({'content': item, 'error': error})
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 get_display(self): Targs = [TVar(arg) for arg in self.args] T = TConst(self.name, *Targs) constrs = [] for constr in self.constrs: argsT, _ = constr['type'].strip_type() res = pprint.N(constr['name']) for i, arg in enumerate(constr['args']): res += pprint.N(' (' + arg + ' :: ') + printer.print_type( argsT[i]) + pprint.N(')') constrs.append(res) return { 'ty': 'type.ind', 'type': printer.print_type(T), 'constrs': constrs if settings.highlight else '\n'.join(constrs) }
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 testPrintType(self): test_data = [ (Ta, "'a"), (TVar("ab"), "'ab"), (Type("bool"), "bool"), (Type("list", Ta), "'a list"), (Type("list", Type("list", Ta)), "'a list list"), (Type("tree", Ta, Tb), "('a, 'b) tree"), (TFun(Ta, Tb), "'a => 'b"), (TFun(Ta, Tb, Tc), "'a => 'b => 'c"), (TFun(TFun(Ta, Tb), Tc), "('a => 'b) => 'c"), (TFun(Type("list", Ta), Tb), "'a list => 'b"), (TFun(Ta, Type("list", Tb)), "'a => 'b list"), (Type("list", TFun(Ta, Tb)), "('a => 'b) list"), (Type("list", Type("list", TFun(Ta, Tb))), "('a => 'b) list list"), (TFun(Type("list", Ta), Type("list", Tb)), "'a list => 'b list"), (Type("list", TFun(Type("list", Ta), Tb)), "('a list => 'b) list"), ] for T, str_T in test_data: self.assertEqual(str(T), str_T)
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 testCheckedExtend2(self): """Checked extension: proved theorem.""" id_const = Const("id", TFun(Ta,Ta)) id_def = Abs("x", Ta, Bound(0)) id_simps = Eq(id_const(x), x) # Proof of |- id x = x from |- id = (%x. x) prf = Proof() prf.add_item(0, "theorem", args="id_def") # id = (%x. x) prf.add_item(1, "subst_type", args=TyInst(a=TVar('a')), prevs=[0]) # id = (%x. x) prf.add_item(2, "reflexive", args=x) # x = x prf.add_item(3, "combination", prevs=[1, 2]) # id x = (%x. x) x prf.add_item(4, "beta_conv", args=id_def(x)) # (%x. x) x = x prf.add_item(5, "transitive", prevs=[3, 4]) # id x = x exts = [ extension.Constant("id", TFun(Ta, Ta)), extension.Theorem("id_def", Thm([], Eq(id_const, id_def))), extension.Theorem("id.simps", Thm([], id_simps), prf) ] 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_def', Thm([], Eq(id_const, id_def)))])
from data import nat from data import real from data import list from data import set from data import string from data import function from data import interval from syntax import printer from syntax.settings import settings, global_setting basic.load_theory('list') A = Var("A", BoolType) B = Var("B", BoolType) C = Var("C", BoolType) Ta = TVar("a") a = Var("a", Ta) b = Var("b", Ta) P = Var("P", TFun(Ta, BoolType)) Q = Var("Q", TFun(Ta, BoolType)) R = Var("R", TFun(Ta, Ta, BoolType)) nn = Var("n", TFun(BoolType, BoolType)) m = Var("m", NatType) n = Var("n", NatType) p = Var("p", NatType) xs = Var("xs", TConst("list", Ta)) ys = Var("ys", TConst("list", Ta)) zs = Var("zs", TConst("list", Ta)) mk_if = logic.mk_if
# Author: Bohua Zhan import unittest from kernel.type import TVar, TFun, NatType from kernel.term import Var, Eq, Nat from kernel.thm import Thm from kernel import theory from logic import basic from data import nat from data import function from data.function import mk_fun_upd, strip_fun_upd Ta = TVar("a") Tb = TVar("b") f = Var("f", TFun(Ta, Tb)) a1 = Var("a1", Ta) a2 = Var("a2", Ta) b1 = Var("b1", Ta) b2 = Var("b2", Ta) zero = nat.zero one = nat.one def fun_upd_of_seq(*ns): return mk_fun_upd(function.mk_const_fun(NatType, zero), *[Nat(n) for n in ns]) class FunctionTest(unittest.TestCase):