def testParseType(self): test_data = [ "'b", "nat", "'a list", "nat list", "('a, 'b) prod", "nat list list", "(nat, 'a) prod", "'a => 'b", "'a => 'b => 'c", "('a => 'b) => 'c", "('a => 'b) => 'c => 'd", "(('a => 'b) => 'c) => 'd", "'a => 'b list", "('a => 'b) list", "'a list list", "'a list => 'b list", "('a list => 'b) list", "('a => 'b, 'c) prod", "('a list, 'b => 'c) prod", ] for s in test_data: T = parser.parse_type(thy, s) self.assertIsInstance(T, HOLType) self.assertEqual(str(T), s)
def testParseUnicodeType(self): test_data = ["'a ⇒ 'b"] for s in test_data: T = parser.parse_type(thy, s) self.assertIsInstance(T, HOLType) self.assertEqual(print_type(thy, T, unicode=True), s)
def parse(self, data): self.name = data['name'] try: self.type = parser.parse_type(data['type']) self.cname = theory.thy.get_overload_const_name( self.name, self.type) for rule in data['rules']: with context.fresh_context(defs={self.name: self.type}): prop = parser.parse_term(rule['prop']) # Test conclusion of the prop _, concl = prop.strip_implies() f, _ = concl.strip_comb() if f != Const(self.name, self.type): raise ItemException( "Inductive %s: wrong head of conclusion" % self.name) self.rules.append({'name': rule['name'], 'prop': prop}) except Exception as error: self.type = data['type'] self.rules = data['rules'] self.error = error self.trace = traceback2.format_exc()
def parse(self, data): self.name = data['name'] try: self.type = parser.parse_type(data['type']) self.cname = theory.thy.get_overload_const_name( self.name, self.type) for rule in data['rules']: with context.fresh_context(defs={self.name: self.type}): prop = parser.parse_term(rule['prop']) # prop should be an equality if not prop.is_equals(): raise ItemException("Fun %s: rule is not an equality" % self.name) f, args = prop.lhs.strip_comb() if f != Const(self.name, self.type): raise ItemException("Fun %s: wrong head of lhs" % self.name) lhs_vars = set(v.name for v in prop.lhs.get_vars()) rhs_vars = set(v.name for v in prop.rhs.get_vars()) if not rhs_vars.issubset(lhs_vars): raise ItemException( "Fun %s: extra variables in rhs: %s" % (self.name, ", ".join(v for v in rhs_vars - lhs_vars))) self.rules.append({'prop': prop}) except Exception as error: self.type = data['type'] self.rules = data['rules'] self.error = error self.trace = traceback2.format_exc()
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 testParseSet(self): ctxt = { "x": Ta, "A": set.setT(Ta), "B": set.setT(Ta), } test_data = [ ("({}::'a set)", "(∅::'a set)", "'a set"), ("x MEM A", "x ∈ A", "bool"), ("A SUB B", "A ⊆ B", "bool"), ("A INTER B", "A ∩ B", "'a set"), ("A UNION B", "A ∪ B", "'a set"), ] for s1, s2, Ts in test_data: T = parser.parse_type(thy, Ts) t1 = parser.parse_term(thy, ctxt, s1) self.assertIsInstance(t1, Term) self.assertEqual(t1.checked_get_type(), T) self.assertEqual(print_term(thy, t1), s1) t2 = parser.parse_term(thy, ctxt, s2) self.assertIsInstance(t2, Term) self.assertEqual(t2.checked_get_type(), T) self.assertEqual(print_term(thy, t2, unicode=True), s2)
def parse_edit(self, edit_data): T = parser.parse_type(edit_data['type'], check_type=False) data = { 'ty': 'type.ax', 'name': T.name, 'args': [argT.name for argT in T.args] } self.parse(data)
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 run_test(self, thy_name, *, vars=None, svars=None, s, Ts): context.set_context(thy_name, vars=vars, svars=svars) t = parser.parse_term(s) T = parser.parse_type(Ts) self.assertIsInstance(t, Term) self.assertEqual(t.checked_get_type(), T) # with global_setting(unicode=False): self.assertEqual(print_term(t), s)
def parse_proof(thy, data): """Obtain proof from json format.""" ctxt = {} state = ProofState(thy) for name, str_T in data['vars'].items(): T = parser.parse_type(thy, str_T) state.vars.append(Var(name, T)) ctxt[name] = T state.prf = Proof() for line in data['proof']: if line['rule'] == "variable": nm, str_T = line['args'].split(',', 1) ctxt[nm] = parser.parse_type(thy, str_T.strip()) item = parser.parse_proof_rule(thy, ctxt, line) state.prf.insert_item(item) state.check_proof(compute_only=True) return state
def testInferType2(self): thy = basic.load_theory('function') test_data = [("(%x. 0)(1 := 7)", "nat => nat")] for s, Ts in test_data: t = parser.parse_term(thy, ctxt, s) T = parser.parse_type(thy, Ts) self.assertIsInstance(t, Term) self.assertEqual(t.checked_get_type(), T) self.assertEqual(print_term(thy, t), s)
def __init__(self, *, svars=None, vars=None, defs=None): self.svars = dict() if svars is not None: for nm, T in svars.items(): if isinstance(T, str): T = parser.parse_type(T) self.svars[nm] = T self.vars = dict() if vars is not None: for nm, T in vars.items(): if isinstance(T, str): T = parser.parse_type(T) self.vars[nm] = T self.defs = dict() if defs is not None: for nm, T in defs.items(): if isinstance(T, str): T = parser.parse_type(T) self.defs[nm] = T
def testParseFunction(self): thy = basic.load_theory('function') test_data = [ ("(f)(a := b)", "'a => 'a"), ("(f)(a := b, b := a)", "'a => 'a"), ] for s, Ts in test_data: t = parser.parse_term(thy, ctxt, s) T = parser.parse_type(thy, Ts) self.assertIsInstance(t, Term) self.assertEqual(t.checked_get_type(), T) self.assertEqual(print_term(thy, t), s)
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 testParseTypedTerm(self): test_data = [ ("([]::'a list)", "'a list"), ("([]::nat list)", "nat list"), ("([]::'a list) = []", "bool"), ("!a::'a. a = a", "bool"), ] for s, Ts in test_data: t = parser.parse_term(thy, ctxt, s) T = parser.parse_type(thy, Ts) self.assertIsInstance(t, Term) self.assertEqual(t.checked_get_type(), T) self.assertEqual(print_term(thy, t), s)
def parse_proof(proof): """Obtain proof from json format.""" state = ProofState() for nm, T in context.ctxt.vars.items(): state.vars.append(Var(nm, T)) state.prf = Proof() for line in proof: if line['rule'] == "variable": nm, str_T = line['args'].split(',', 1) context.ctxt.vars[nm] = parser.parse_type(str_T.strip()) item = parser.parse_proof_rule(line) state.prf.insert_item(item) state.check_proof() return state
def parse_edit(self, edit_data): T = parser.parse_type(edit_data['type']) constrs = [] for constr_decl in edit_data['constrs'].split('\n'): constr = parser.parse_ind_constr(constr_decl) constr['type'] = str(TFun(*(constr['type'] + [T]))) constrs.append(constr) data = { 'ty': 'type.ind', 'name': T.name, 'args': [argT.name for argT in T.args], 'constrs': constrs } self.parse(data)
def parse(self, data): self.name = data['name'] if 'overloaded' in data and data['overloaded']: self.overloaded = True try: self.type = parser.parse_type(data['type']) if self.overloaded: self.cname = self.name else: self.cname = theory.thy.get_overload_const_name( self.name, self.type) except Exception as error: self.type = data['type'] self.error = error self.trace = traceback2.format_exc()
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 parse_init_state(thy, data): """Given data for a theorem statement, construct the initial partial proof. data['vars']: list of variables. data['prop']: proposition to be proved. In the form A1 --> ... --> An --> C. """ ctxt = {} vars = [] for name, str_T in data['vars'].items(): T = parser.parse_type(thy, str_T) vars.append(Var(name, T)) ctxt[name] = T prop = parser.parse_term(thy, ctxt, data['prop']) assums, concl = prop.strip_implies() return ProofState.init_state(thy, vars, assums, concl)
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) thy = basic.load_theory('gcl') name = data['name'] vars = [] for nm, str_T in data['vars'].items(): T = parser.parse_type(thy, str_T) vars.append(Var(nm, T)) for i, nm in enumerate(data['states']): thy.add_term_sig(nm, natT) thy.add_theorem(nm + "_def", Thm.mk_equals(Const(nm, natT), to_binary(i))) states = [Const(nm, natT) for nm in data['states']] rules = [] for rule in data['rules']: if isinstance(rule['var'], str): rule_var = Var(rule['var'], natT) ctxt = dict((v.name, v.T) for v in vars + [rule_var]) else: assert isinstance(rule['var'], list) rule_var = [Var(nm, natT) for nm in rule['var']] ctxt = dict((v.name, v.T) for v in vars + rule_var) guard = parser.parse_term(thy, ctxt, rule['guard']) assign = dict() for k, v in rule['assign'].items(): assign[parser.parse_term(thy, ctxt, k)] = parser.parse_term(thy, ctxt, v) rules.append((rule_var, guard, assign)) invs = [] for inv in data['invs']: inv_vars = [Var(nm, natT) for nm in inv['vars']] ctxt = dict((v.name, v.T) for v in vars + inv_vars) prop = parser.parse_term(thy, ctxt, inv['prop']) invs.append((inv_vars, prop)) return ParaSystem(thy, name, vars, states, rules, invs)
def testParseTermNoAbs(self): test_data = [ ("!x. P x", "bool"), ("!x. !y. R x y", "bool"), ("!x. P x & Q x", "bool"), ("(!x. P x) & Q a", "bool"), ("!x. P x --> Q x", "bool"), ("(!x. P x) --> Q a", "bool"), ("A = (!x. P x)", "bool"), ("?x. P x", "bool"), ("?x. !y. R x y", "bool"), ("!x. ?y. R x y", "bool"), ("!a. P a", "bool"), ] for s, Ts in test_data: t = parser.parse_term(thy, ctxt, s) T = parser.parse_type(thy, Ts) self.assertIsInstance(t, Term) self.assertEqual(t.checked_get_type(), T) self.assertEqual(print_term(thy, t), s)
def parse(self, data): self.name = data['name'] try: self.type = parser.parse_type(data['type']) self.cname = theory.thy.get_overload_const_name( self.name, self.type) with context.fresh_context(defs={self.name: self.type}): self.prop = parser.parse_term(data['prop']) # prop should be an equality if not self.prop.is_equals(): raise ItemException("Definition %s: prop is not an equality" % self.name) f, args = self.prop.lhs.strip_comb() if f != Const(self.name, self.type): raise ItemException("Definition %s: wrong head of lhs" % self.name) lhs_vars = set(v.name for v in args) rhs_vars = set(v.name for v in self.prop.rhs.get_vars()) if len(lhs_vars) != len(args): raise ItemException( "Definition %s: variables on lhs must be distinct" % self.name) if not rhs_vars.issubset(lhs_vars): raise ItemException( "Definition %s: extra variables in rhs: %s" % (self.name, ", ".join(v for v in rhs_vars - lhs_vars))) except Exception as error: self.type = data['type'] self.prop = data['prop'] self.error = error self.trace = traceback2.format_exc() if 'attributes' in data: self.attributes = data['attributes']
def parse(self, data): self.name = data['name'] self.args = data['args'] theory.thy.add_type_sig(self.name, len(self.args)) try: for constr in data['constrs']: constr_type = parser.parse_type(constr['type']) self.constrs.append({ 'name': constr['name'], 'type': constr_type, 'cname': theory.thy.get_overload_const_name(constr['name'], constr_type), 'args': constr['args'] }) except Exception as error: self.constrs = data['constrs'] self.error = error self.trace = traceback2.format_exc()
def apply(self, state, id, data, prevs): state.add_line_before(id, 1) T = parser.parse_type(state.thy, data['type']) state.set_line(id, 'variable', args=(data['name'], T), prevs=[])
def display_step(self, state, data): T = parser.parse_type(data['type']) return pprint.N("Variable " + data['name'] + " :: ") + printer.print_type(T)
def testParseTypeIsString(self): basic.load_theory('logic_base') a = parser.parse_type('bool') self.assertEqual(type(a.name), str)
def testParseTerm(self): test_data = [ # Atoms ("A", "bool"), ("P", "'a => bool"), ("a", "'a"), # Function application ("P a", "bool"), ("R a", "'a => bool"), ("R a b", "bool"), ("f a", "'a"), ("P (f a)", "bool"), ("P (f (f a))", "bool"), ("R (f a) b", "bool"), ("R a (f b)", "bool"), # Abstraction ("%x::'a. x", "'a => 'a"), ("%x. P x", "'a => bool"), ("%x. %y. R x y", "'a => 'a => bool"), # Equality and implies ("a = b", "bool"), ("A --> B", "bool"), ("f a = b", "bool"), ("A --> B --> C", "bool"), ("(A --> B) --> C", "bool"), ("a = b --> C", "bool"), ("A = (B --> C)", "bool"), ("P a --> Q b", "bool"), ("A = B = C", "bool"), ("A = (B = C)", "bool"), # Conjunction and disjunction ("A & B", "bool"), ("A & B & C", "bool"), ("(A & B) & C", "bool"), ("A | B", "bool"), ("A | B | C", "bool"), ("(A | B) | C", "bool"), ("A & B | B & C", "bool"), ("(A | B) & (B | C)", "bool"), # Negation ("~A", "bool"), ("~~A", "bool"), # Constants ("true", "bool"), ("false", "bool"), # Mixed ("A --> B & C", "bool"), ("A | B --> C", "bool"), ("(A --> B) & C", "bool"), ("A | (B --> C)", "bool"), ("~A & B", "bool"), ("~(A & B)", "bool"), ("~A = B", "bool"), ("(~A) = B", "bool"), ("(~A) = (~B)", "bool"), ("nn (A & B)", "bool"), ("nn A & B", "bool"), # Quantifiers ("!x. P x", "bool"), ("!x. !y. R x y", "bool"), ("!x. P x & Q x", "bool"), ("(!x. P x) & Q a", "bool"), ("!x. P x --> Q x", "bool"), ("(!x. P x) --> Q a", "bool"), ("A = (!x. P x)", "bool"), ("?x. P x", "bool"), ("?x. !y. R x y", "bool"), ("!x. ?y. R x y", "bool"), ("!a. P a", "bool"), # If expression ("if A then a else b", "'a"), ("(if A then a else b) = a", "bool"), # Arithmetic ("m + n", "nat"), ("m * n", "nat"), ("m + n + p", "nat"), ("m + (n + p)", "nat"), ("m + n * p", "nat"), ("m * (n + p)", "nat"), ("0", "nat"), ("0 + 0", "nat"), ("m * 0", "nat"), # Binary numbers ("1", "nat"), ("2", "nat"), ("3", "nat"), ("4", "nat"), ("5", "nat"), ("101", "nat"), ("101 + 102", "nat"), ("bit0", "nat => nat"), ("bit1", "nat => nat"), # Lists ("xs @ ys", "'a list"), ("(xs @ ys) @ zs", "'a list"), ("xs @ ys @ zs", "'a list"), ("[a]", "'a list"), ("[a, b]", "'a list"), ("[a] @ [b]", "'a list"), ("a # xs", "'a list"), ("a # xs @ ys", "'a list"), ("(a # xs) @ ys", "'a list"), ("[[], [a]]", "'a list list"), ] for s, Ts in test_data: t = parser.parse_term(thy, ctxt, s) T = parser.parse_type(thy, Ts) self.assertIsInstance(t, Term) self.assertEqual(t.checked_get_type(), T) self.assertEqual(print_term(thy, t), s)
def testParseTypeIsString(self): a = parser.parse_type(thy, 'bool') self.assertEqual(type(a.name), str)
def file_data_to_output(thy, data): """Convert items in the theory from json format for the file to json format for the web client. Modifies data in-place. Also modifies argument thy in parsing the item. """ parser.parse_extension(thy, data) if data['ty'] == 'def.ax': T = parser.parse_type(thy, data['type']) data['type_hl'] = printer.print_type(thy, T, unicode=True, highlight=True) elif data['ty'] == 'thm' or data['ty'] == 'thm.ax': temp_list = [] for k, v in data['vars'].items(): temp_list.append(k + ' :: ' + v) ctxt = parser.parse_vars(thy, data['vars']) prop = parser.parse_term(thy, ctxt, data['prop']) data['prop_hl'] = printer.print_term(thy, prop, unicode=True, highlight=True) data['vars_lines'] = temp_list elif data['ty'] == 'type.ind': constrs = [] data_content = '' for constr in data['constrs']: T = parser.parse_type(thy, constr['type']) constrs.append((constr['name'], T, constr['args'])) exts = induct.add_induct_type(data['name'], data['args'], constrs) # Obtain items added by the extension ext_output = [] for ext in exts.data: s = print_extension(thy, ext) if s: ext_output.append(s) data['ext'] = ext_output # Obtain type to be defined T = Type(data['name'], *(TVar(nm) for nm in data['args'])) data['type_hl'] = printer.print_type(thy, T, unicode=True, highlight=True) # Obtain types of arguments for each constructor data['argsT'] = dict() for i, constr in enumerate(data['constrs']): str_temp_var = '' T = parser.parse_type(thy, constr['type']) argsT, _ = HOLType.strip_type(T) argsT = [ printer.print_type(thy, argT, unicode=True, highlight=True) for argT in argsT ] data['argsT'][str(i)] = argsT for j, a in enumerate(constr['args']): str_temp_term = '' for m, t in enumerate(data['argsT'][str(i)][j]): str_temp_term += t[0] str_temp_var += ' (' + a + ' :: ' + str_temp_term + ')' data_content += '\n' + constr['name'] + str_temp_var data['type_content'] = data_content elif data['ty'] == 'def.ind' or data['ty'] == 'def.pred': container = [[], [], [], '', '', ''] data_content_list, data_rule_names, data_vars_list, data_new_content, data_rule_name, data_vars_str = container T = parser.parse_type(thy, data['type']) data['type_hl'] = printer.print_type(thy, T, unicode=True, highlight=True) rules = [] for rule in data['rules']: ctxt = parser.parse_vars(thy, rule['vars']) prop = parser.parse_term(thy, ctxt, rule['prop']) rule['prop_hl'] = printer.print_term(thy, prop, unicode=True, highlight=True) rules.append(prop) exts = induct.add_induct_def(data['name'], T, rules) # Obtain items added by the extension ext_output = [] for ext in exts.data: s = print_extension(thy, ext) if s: ext_output.append(s) data['ext'] = ext_output if data['ty'] == 'def.ind': type_name = 'fun' if data['ty'] == 'def.pred': type_name = 'inductive' data['ext_output'] = '\n'.join(ext_output) data['type_name'] = type_name for k, r in enumerate(data['rules']): vars_str = '' data_con = '' for m, v in enumerate(r['vars']): vars_str += str(m) + '::' + v + ' ' data_vars_list.append(vars_str) for p in r['prop_hl']: data_con += p[0] data_content_list.append(data_con) if 'name' in r: data_rule_names.append(r['name']) for n, dv in enumerate(data_vars_list): data_vars_str += str(n) + ': ' + dv + '\n' for j, dc in enumerate(data_content_list): data_new_content += str(j) + ': ' + dc + '\n' data_rule_name += str(j) + ': ' + dc + '\n' data['data_new_content'] = data_new_content data['data_rule_name'] = data_rule_name data['data_vars_str'] = data_vars_str elif data['ty'] == 'def': i = 0 vars = '' data_new_content = '' data_content_list = [] data_content_list.append(data['prop']) for j, dc in enumerate(data_content_list): data_new_content += str(j) + ': ' + dc + '\n' for j, v in enumerate(data['vars']): vars += str(i) + ': ' + str(j) + '::' + v + '\n' i += 1 data['item_vars'] = vars T = parser.parse_type(thy, data['type']) data['type_name'] = 'definition' data['data_new_content'] = data_new_content data['type_hl'] = printer.print_type(thy, T, unicode=True, highlight=True) ctxt = parser.parse_vars(thy, data['vars']) prop = parser.parse_term(thy, ctxt, data['prop']) data['prop_hl'] = printer.print_term(thy, prop, unicode=True, highlight=True) # Ignore other types of information. else: pass