14 struct |
14 struct |
15 |
15 |
16 |
16 |
17 (* type induct_kind *) |
17 (* type induct_kind *) |
18 |
18 |
19 datatype induct_kind = Type | Set | Function; |
19 datatype induct_kind = Type | Set | Function | Rule; |
20 |
20 |
21 val typeN = "type"; |
21 val kind_name = |
22 val setN = "set"; |
22 Args.$$$ "type" >> K Type || |
23 val functionN = "function"; |
23 Args.$$$ "set" >> K Set || |
|
24 Args.$$$ "function" >> K Function || |
|
25 Args.$$$ "rule" >> K Rule; |
24 |
26 |
25 val kind = |
27 val kind = kind_name --| Args.$$$ ":"; |
26 (Args.$$$ typeN >> K Type || Args.$$$ setN >> K Set || Args.$$$ functionN >> K Function) |
|
27 --| Args.$$$ ":"; |
|
28 |
28 |
29 |
29 |
30 (* induct_rule *) |
30 (* induct_rule *) |
31 |
31 |
32 fun kind_rule Type = (#induction oo DatatypePackage.datatype_info_err, Sign.intern_tycon) |
32 fun kind_rule Type = (#induction oo DatatypePackage.datatype_info_err, Sign.intern_tycon) |
33 | kind_rule Set = ((#induct o #2) oo InductivePackage.get_inductive, Sign.intern_const) |
33 | kind_rule Set = ((#induct o #2) oo InductivePackage.get_inductive, Sign.intern_const) |
34 | kind_rule Function = (#induct oo RecdefPackage.get_recdef, Sign.intern_const); |
34 | kind_rule Function = (#induct oo RecdefPackage.get_recdef, Sign.intern_const) |
|
35 | kind_rule Rule = (PureThy.get_thm, K I); |
35 |
36 |
36 fun induct_rule thy kind name = |
37 fun induct_rule thy kind name = |
37 let val (ind_rule, intern) = kind_rule kind |
38 let val (ind_rule, intern) = kind_rule kind |
38 in ind_rule thy (intern (Theory.sign_of thy) name) end; |
39 in ind_rule thy (intern (Theory.sign_of thy) name) end; |
39 |
40 |
46 (case opt_kind_name of Some kind_name => kind_name | None => |
47 (case opt_kind_name of Some kind_name => kind_name | None => |
47 (case try (#1 o Term.dest_Type o Term.type_of o #2 o hd) insts of |
48 (case try (#1 o Term.dest_Type o Term.type_of o #2 o hd) insts of |
48 Some name => (Type, name) |
49 Some name => (Type, name) |
49 | None => error "Unable to figure out induction rule")); |
50 | None => error "Unable to figure out induction rule")); |
50 val rule = Drule.incr_indexes_wrt [] [] [] [state] (induct_rule thy kind name); |
51 val rule = Drule.incr_indexes_wrt [] [] [] [state] (induct_rule thy kind name); |
51 |
|
52 |
52 |
53 val cert = Thm.cterm_of (Sign.merge (pairself Thm.sign_of_thm (state, rule))); |
53 val cert = Thm.cterm_of (Sign.merge (pairself Thm.sign_of_thm (state, rule))); |
54 |
54 |
55 fun prep_inst ((P $ x), (Some Q, y)) = [(cert P, cert Q), (cert x, cert y)] |
55 fun prep_inst ((P $ x), (Some Q, y)) = [(cert P, cert Q), (cert x, cert y)] |
56 | prep_inst ((_ $ x), (None, y)) = [(cert x, cert y)] |
56 | prep_inst ((_ $ x), (None, y)) = [(cert x, cert y)] |
73 fun induct ctxt = |
73 fun induct ctxt = |
74 Args.and_list inst -- Scan.option (Scan.lift (kind -- Args.name)) |
74 Args.and_list inst -- Scan.option (Scan.lift (kind -- Args.name)) |
75 >> (fn (is, k) => Method.METHOD (FIRSTGOAL o induct_tac (ProofContext.theory_of ctxt) is k)); |
75 >> (fn (is, k) => Method.METHOD (FIRSTGOAL o induct_tac (ProofContext.theory_of ctxt) is k)); |
76 |
76 |
77 fun induct_meth src ctxt = #2 (Method.syntax (induct ctxt) ctxt src); |
77 fun induct_meth src ctxt = #2 (Method.syntax (induct ctxt) ctxt src); |
78 val induct_method = ("induct", induct_meth, "induction on types / sets / functions"); |
78 val induct_method = ("induct", induct_meth, "induction on types, sets, functions etc."); |
79 |
79 |
80 |
80 |
81 (* theory setup *) |
81 (* theory setup *) |
82 |
82 |
83 val setup = [Method.add_methods [induct_method]]; |
83 val setup = [Method.add_methods [induct_method]]; |