def testDatatypeNat(self): basic.load_theory('logic_base') nat_item = items.parse_item({ "args": [], "constrs": [{ "args": [], "name": "zero", "type": "nat" }, { "args": ["n"], "name": "Suc", "type": "nat => nat" }], "name": "nat", "ty": "type.ind" }) self.assertIsNone(nat_item.error) ext = nat_item.get_extension() theory.thy.unchecked_extend(ext) ext_output = [ "Type nat 0", "Constant zero :: nat", "Constant Suc :: nat => nat", "Theorem nat_zero_Suc_neq: ~(0 = Suc n)", "Theorem nat_Suc_inject: Suc n = Suc n1 --> n = n1", "Theorem nat_induct: P 0 --> (!n. P n --> P (Suc n)) --> P x", "Attribute nat_induct [var_induct]" ] with global_setting(unicode=False): self.assertEqual(printer.print_extensions(ext), '\n'.join(ext_output))
def testDatatypeList(self): basic.load_theory('logic_base') list_item = items.parse_item({ "args": ["a"], "constrs": [{ "args": [], "name": "nil", "type": "'a list" }, { "args": ["x", "xs"], "name": "cons", "type": "'a => 'a list => 'a list" }], "name": "list", "ty": "type.ind" }) self.assertIsNone(list_item.error) ext = list_item.get_extension() theory.thy.unchecked_extend(ext) ext_output = [ "Type list 1", "Constant nil :: 'a list", "Constant cons :: 'a => 'a list => 'a list", "Theorem list_nil_cons_neq: ~([] = x # xs)", "Theorem list_cons_inject: x # xs = x1 # xs1 --> x = x1 & xs = xs1", "Theorem list_induct: P [] --> (!x1. !xs. P xs --> P (x1 # xs)) --> P x", "Attribute list_induct [var_induct]" ] with global_setting(unicode=False): self.assertEqual(printer.print_extensions(ext), '\n'.join(ext_output))
def testPredEven(self): basic.load_theory('nat', limit=('def', 'one')) even_item = items.parse_item({ "name": "even", "rules": [{ "name": "even_zero", "prop": "even 0" }, { "name": "even_Suc", "prop": "even n --> even (Suc (Suc n))" }], "ty": "def.pred", "type": "nat => bool" }) self.assertIsNone(even_item.error) ext = even_item.get_extension() theory.thy.unchecked_extend(ext) ext_output = [ "Constant even :: nat => bool", "Theorem even_zero: even 0", "Attribute even_zero [hint_backward]", "Theorem even_Suc: even n --> even (Suc (Suc n))", "Attribute even_Suc [hint_backward]", "Theorem even_cases: even _a1 --> (_a1 = 0 --> P) --> (!n. _a1 = Suc (Suc n) --> even n --> P) --> P" ] with global_setting(unicode=False): self.assertEqual(printer.print_extensions(ext), '\n'.join(ext_output))
def testParseType(self): test_data = [ "'b", "?'b", "nat", "'a list", "nat list", "nat list list", "'a => 'b", "'a => 'b => 'c", "('a => 'b) => 'c", "('a => 'b) => 'c => 'd", "(('a => 'b) => 'c) => 'd", "?'a => ?'b", "'a => 'b list", "('a => 'b) list", "'a list list", "'a list => 'b list", "('a list => 'b) list", ] basic.load_theory('list') for s in test_data: T = parser.parse_type(s) self.assertIsInstance(T, Type) with global_setting(unicode=False): self.assertEqual(str(T), s)
def check_modify(): """Check a modified item for validity. Input: * username: username. * filename: name of the file. * line_length: maximum length of printed line. * item: item to be checked. Returns: * checked item. """ data = json.loads(request.get_data().decode("utf-8")) username = data['username'] edit_item = data['item'] line_length = data.get('line_length') if 'limit_ty' in data: limit = (data['limit_ty'], data['limit_name']) else: limit = None basic.load_theory(data['filename'], limit=limit, username=username) item = items.parse_edit(edit_item) if item.error is None: theory.thy.unchecked_extend(item.get_extension()) with settings.global_setting(line_length=line_length): output_item = item.export_web() return jsonify({'item': output_item})
def testDatatypeProd(self): basic.load_theory('logic_base') prod_item = items.parse_item({ "args": ["a", "b"], "constrs": [{ "args": ["a", "b"], "name": "Pair", "type": "'a => 'b => ('a, 'b) prod" }], "name": "prod", "ty": "type.ind" }) self.assertIsNone(prod_item.error) ext = prod_item.get_extension() theory.thy.unchecked_extend(ext) ext_output = [ "Type prod 2", "Constant Pair :: 'a => 'b => ('a, 'b) prod", "Theorem prod_Pair_inject: Pair a b = Pair a1 b1 --> a = a1 & b = b1", "Theorem prod_induct: (!a. !b. P (Pair a b)) --> P x", "Attribute prod_induct [var_induct]" ] with global_setting(unicode=False): self.assertEqual(printer.print_extensions(ext), '\n'.join(ext_output))
def testOpenEmpty(self): basic.load_theory('topology') st = auto.init_proof_theorem('open_empty') st.step_for(20, debug=False) self.assertEqual(st.step_count, 7) self.assertEqual(len(st.updates), 6)
def testLoadTheory(self): thy1 = basic.load_theory('logic_base') thy2 = basic.load_theory('logic') self.assertEqual(thy1.get_theorem('conjI'), thy2.get_theorem('conjI')) self.assertRaises(TheoryException, thy1.get_theorem, 'conj_comm') self.assertIsInstance(thy2.get_theorem('conj_comm'), Thm)
def testFunPlus(self): basic.load_theory('nat', limit=('def', 'one')) plus_item = items.parse_item({ "name": "plus", "rules": [{ "prop": "0 + n = n" }, { "prop": "Suc m + n = Suc (m + n)" }], "ty": "def.ind", "type": "nat ⇒ nat ⇒ nat" }) self.assertIsNone(plus_item.error) ext = plus_item.get_extension() theory.thy.unchecked_extend(ext) ext_output = [ "Constant plus :: nat => nat => nat", "Theorem plus_def_1: 0 + n = n", "Attribute plus_def_1 [hint_rewrite]", "Theorem plus_def_2: Suc m + n = Suc (m + n)", "Attribute plus_def_2 [hint_rewrite]" ] with global_setting(unicode=False): self.assertEqual(printer.print_extensions(ext), '\n'.join(ext_output))
def testSteps(self, thy_name, thm_name, *, no_gaps=True, print_proof=False, \ print_stat=False, print_search=False, print_steps=False): """Test list of steps for the given theorem.""" def test_val(val): context.set_context(None, vars=val['vars']) state = server.parse_init_state(val['prop']) goal = state.prf.items[-1].th num_found = 0 if print_stat and 'steps' not in val: print("%20s %s" % (val['name'], "No steps found")) return for i, step in enumerate(val['steps']): if print_search or print_stat: if 'fact_ids' not in step: step['fact_ids'] = [] if print_steps: print(method.output_step(state, step)) if print_search: select_ids = "goal " + step['goal_id'] if step['fact_ids']: select_ids += ", fact " + ", ".join(step['fact_ids']) print('Step ' + str(i) + " (" + select_ids + ")") search_res = state.search_method(step['goal_id'], step['fact_ids']) found = 0 for res in search_res: m = method.global_methods[res['method_name']] if res['method_name'] == step['method_name'] and \ all(sig not in res or sig not in step or res[sig] == step[sig] for sig in m.sig): if print_search: print('* ' + m.display_step(state, res)) found += 1 else: if print_search: print(' ' + m.display_step(state, res)) assert found <= 1, "test_val: multiple found" if found == 0: if print_search: m = method.global_methods[step['method_name']] print('- ' + m.display_step(state, step)) else: num_found += 1 method.apply_method(state, step) self.assertEqual(state.check_proof(no_gaps=no_gaps), goal) if print_proof: print("Final state:") print(state.prf) if print_stat: total = len(val['steps']) print("%20s %5d %5d %5d" % (val['name'], total, num_found, total - num_found)) basic.load_theory(thy_name, limit=('thm', thm_name)) with open('./library/' + thy_name + '.json', 'r', encoding='utf-8') as f: f_data = json.load(f) for val in f_data['content']: if val['ty'] == 'thm' and val['name'] == thm_name: test_val(val)
def setUp(self): basic.load_theory('list') context.ctxt = context.Context(vars={ "A" : BoolType, "P" : TFun(Ta, BoolType), "a" : Ta, "b" : Ta, })
def testParseUnicodeType(self): test_data = ["'a ⇒ 'b"] basic.load_theory('list') for s in test_data: T = parser.parse_type(s) self.assertIsInstance(T, Type) with global_setting(unicode=True): self.assertEqual(print_type(T), s)
def search_method(): """Match for applicable methods and their arguments. Input: * username: username. * theory_name: name of the theory. * thm_name: name of the theorem. Returns: * search_res: list of search results. * ctxt: current proof context. """ data = json.loads(request.get_data().decode("utf-8")) if data['profile']: pr = cProfile.Profile() pr.enable() if not proof_cache.check_cache(data): start_time = time.perf_counter() proof_cache.create_cache(data) print("Load: %f" % (time.perf_counter() - start_time)) if data['thm_name'] != '': limit = ('thm', data['thm_name']) else: limit = None basic.load_theory(data['theory_name'], limit=limit, username=data['username']) start_time = time.perf_counter() state = proof_cache.states[data['index']] fact_ids = data['step']['fact_ids'] goal_id = data['step']['goal_id'] search_res = state.search_method(goal_id, fact_ids) with settings.global_setting(unicode=True): for res in search_res: if '_goal' in res: res['_goal'] = [printer.print_term(t) for t in res['_goal']] if '_fact' in res: res['_fact'] = [printer.print_term(t) for t in res['_fact']] vars = state.get_vars(goal_id) with settings.global_setting(unicode=True, highlight=True): print_vars = dict((k, printer.print_type(v)) for k, v in vars.items()) print("Response:", time.perf_counter() - start_time) if data['profile']: p = Stats(pr) p.strip_dirs() p.sort_stats('cumtime') p.print_stats() return jsonify({'search_res': search_res, 'ctxt': print_vars})
def testLoadTheoryWithLimit(self): thy = basic.load_theory('logic_base') thy1 = basic.load_theory('logic_base', limit=('thm.ax', 'conjD1')) self.assertEqual(thy.get_theorem('conjI'), thy1.get_theorem('conjI')) self.assertRaises(TheoryException, thy1.get_theorem, 'conjD1') self.assertRaises(AssertionError, basic.load_theory, 'logic_base', limit=('thm.ax', 'conj'))
def testPrintString(self): test_data = [ (string.mk_char('c'), "'c'"), (string.mk_string("ab"), '"ab"'), ] basic.load_theory('string') for t, s in test_data: self.assertEqual(printer.print_term(t), s)
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 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 testInduct2(self): basic.load_theory('list') xs = Var("xs", parser.parse_type("'a list")) self.run_test( 'list', tactic.var_induct(), vars={"xs": "'a list"}, goal="xs @ [] = xs", args=("list_induct", xs), new_goals=[ "([]::'a list) @ [] = []", "!x::'a. !xs. xs @ [] = xs --> (x # xs) @ [] = x # xs" ])
def testPrintReal(self): basic.load_theory('real') m = Var("m", RealType) test_data = [ (real.zero, "(0::real)"), (real.one, "(1::real)"), (Real(2), "(2::real)"), (Real(3), "(3::real)"), (real.plus(m, real.one), "m + 1"), (real.plus(real.one, Real(2)), "(1::real) + 2"), ] for t, s in test_data: self.assertEqual(printer.print_term(t), s)
def testPrintInt(self): basic.load_theory('int') m = Var("m", IntType) test_data = [ (Int(0), "(0::int)"), (Int(1), "(1::int)"), (Int(2), "(2::int)"), (Int(3), "(3::int)"), (m + 1, "m + 1"), (Int(1) + 2, "(1::int) + 2"), ] for t, s in test_data: self.assertEqual(printer.print_term(t), s)
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 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 testApplyInduction(self): thy = basic.load_theory('nat') n = Var("n", nat.natT) state = ProofState.init_state(thy, [n], [], Term.mk_equals(nat.plus(n, nat.zero), n)) state.apply_induction(0, "nat_induct", "n") self.assertEqual(state.check_proof(), Thm([], Term.mk_equals(nat.plus(n, nat.zero), n))) self.assertEqual(len(state.prf.items), 3)
def testAddZeroRightWithMacro(self): """Proof of n + 0 = n by induction, using macros.""" thy = basic.load_theory('nat') n = Var("n", nat.natT) eq = Term.mk_equals plus = nat.plus zero = nat.zero S = nat.Suc prf = Proof() prf.add_item(0, "reflexive", args=zero) prf.add_item(1, "rewrite_goal", args=("plus_def_1", eq(plus(zero, zero), zero)), prevs=[0]) prf.add_item(2, "assume", args=eq(plus(n, zero), n)) prf.add_item(3, "arg_combination", args=S, prevs=[2]) prf.add_item(4, "rewrite_goal", args=("plus_def_2", eq(plus(S(n), zero), S(n))), prevs=[3]) prf.add_item(5, "implies_intr", args=eq(plus(n, zero), n), prevs=[4]) prf.add_item(6, "forall_intr", args=n, prevs=[5]) prf.add_item(7, "apply_theorem_for", args=("nat_induct", {}, { "P": Term.mk_abs(n, eq(plus(n, zero), n)), "x": n }), prevs=[1, 6]) th = Thm.mk_equals(plus(n, zero), n) self.assertEqual(thy.check_proof(prf), th)
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 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 load_system(filename): dn = os.path.dirname(os.path.realpath(__file__)) with open(os.path.join(dn, 'examples/' + filename + '.json'), encoding='utf-8') as a: data = json.load(a) basic.load_theory('gcl') name = data['name'] vars = [] for nm, str_T in data['vars'].items(): T = parser.parse_type(str_T) vars.append(Var(nm, T)) for i, nm in enumerate(data['states']): theory.thy.add_term_sig(nm, NatType) theory.thy.add_theorem(nm + "_def", Thm([], Eq(Const(nm, NatType), Nat(i)))) states = [Const(nm, NatType) for nm in data['states']] rules = [] for rule in data['rules']: if isinstance(rule['var'], str): rule_var = Var(rule['var'], NatType) cur_vars = {v.name: v.T for v in vars + [rule_var]} else: assert isinstance(rule['var'], list) rule_var = [Var(nm, NatType) for nm in rule['var']] cur_vars = {v.name: v.T for v in vars + rule_var} with context.fresh_context(vars=cur_vars): guard = parser.parse_term(rule['guard']) assign = dict() for k, v in rule['assign'].items(): assign[parser.parse_term(k)] = parser.parse_term(v) rules.append((rule_var, guard, assign)) invs = [] for inv in data['invs']: inv_vars = [Var(nm, NatType) for nm in inv['vars']] with context.fresh_context(vars={v.name: v.T for v in vars + inv_vars}): prop = parser.parse_term(inv['prop']) invs.append((inv_vars, prop)) return ParaSystem(name, vars, states, rules, invs)
def process_file(input): 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) content = data['content'] for run in content: if run['ty'] == 'vcg': c = com_parser.parse(run['com']) pre = cond_parser.parse(run['pre']) post = cond_parser.parse(run['post']) c.pre = [pre] c.compute_wp(post)
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 testPrintFunction(self): 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)"), ] thy = basic.load_theory('function') for t, s in test_data: self.assertEqual(printer.print_term(thy, t), s)