| author | wenzelm | 
| Fri, 07 Nov 2014 22:15:51 +0100 | |
| changeset 58936 | 7fbe4436952d | 
| parent 58825 | 2065f49da190 | 
| child 59859 | f9d1442c70f3 | 
| permissions | -rw-r--r-- | 
| 
31723
 
f5cafe803b55
discontinued ancient tradition to suffix certain ML module names with "_package"
 
haftmann 
parents: 
31243 
diff
changeset
 | 
1  | 
(* Title: HOL/Tools/recdef.ML  | 
| 6429 | 2  | 
Author: Markus Wenzel, TU Muenchen  | 
3  | 
||
4  | 
Wrapper module for Konrad Slind's TFL package.  | 
|
5  | 
*)  | 
|
6  | 
||
| 
31723
 
f5cafe803b55
discontinued ancient tradition to suffix certain ML module names with "_package"
 
haftmann 
parents: 
31243 
diff
changeset
 | 
7  | 
signature RECDEF =  | 
| 6429 | 8  | 
sig  | 
| 8657 | 9  | 
val get_recdef: theory -> string  | 
| 
35756
 
cfde251d03a5
refining and adding Spec_Rules to definitional packages old_primrec, primrec, recdef, size and function
 
bulwahn 
parents: 
35690 
diff
changeset
 | 
10  | 
    -> {lhs: term, simps: thm list, rules: thm list list, induct: thm, tcs: term list} option
 | 
| 21505 | 11  | 
  val get_hints: Proof.context -> {simps: thm list, congs: (string * thm) list, wfs: thm list}
 | 
| 18728 | 12  | 
val simp_add: attribute  | 
13  | 
val simp_del: attribute  | 
|
14  | 
val cong_add: attribute  | 
|
15  | 
val cong_del: attribute  | 
|
16  | 
val wf_add: attribute  | 
|
17  | 
val wf_del: attribute  | 
|
| 
58011
 
bc6bced136e5
tuned signature -- moved type src to Token, without aliases;
 
wenzelm 
parents: 
57964 
diff
changeset
 | 
18  | 
val add_recdef: bool -> xstring -> string -> ((binding * string) * Token.src list) list ->  | 
| 
 
bc6bced136e5
tuned signature -- moved type src to Token, without aliases;
 
wenzelm 
parents: 
57964 
diff
changeset
 | 
19  | 
Token.src option -> theory -> theory  | 
| 
35756
 
cfde251d03a5
refining and adding Spec_Rules to definitional packages old_primrec, primrec, recdef, size and function
 
bulwahn 
parents: 
35690 
diff
changeset
 | 
20  | 
      * {lhs: term, simps: thm list, rules: thm list list, induct: thm, tcs: term list}
 | 
| 29579 | 21  | 
val add_recdef_i: bool -> xstring -> term -> ((binding * term) * attribute list) list ->  | 
| 
35756
 
cfde251d03a5
refining and adding Spec_Rules to definitional packages old_primrec, primrec, recdef, size and function
 
bulwahn 
parents: 
35690 
diff
changeset
 | 
22  | 
    theory -> theory * {lhs: term, simps: thm list, rules: thm list list, induct: thm, tcs: term list}
 | 
| 
58011
 
bc6bced136e5
tuned signature -- moved type src to Token, without aliases;
 
wenzelm 
parents: 
57964 
diff
changeset
 | 
23  | 
val defer_recdef: xstring -> string list -> (Facts.ref * Token.src list) list  | 
| 6557 | 24  | 
    -> theory -> theory * {induct_rules: thm}
 | 
| 
27727
 
2397e310b2cc
simplified defer_recdef(_i): plain facts via Attrib.eval_thms;
 
wenzelm 
parents: 
27353 
diff
changeset
 | 
25  | 
  val defer_recdef_i: xstring -> term list -> thm list -> theory -> theory * {induct_rules: thm}
 | 
| 
58011
 
bc6bced136e5
tuned signature -- moved type src to Token, without aliases;
 
wenzelm 
parents: 
57964 
diff
changeset
 | 
26  | 
val recdef_tc: bstring * Token.src list -> xstring -> int option -> bool ->  | 
| 
27727
 
2397e310b2cc
simplified defer_recdef(_i): plain facts via Attrib.eval_thms;
 
wenzelm 
parents: 
27353 
diff
changeset
 | 
27  | 
local_theory -> Proof.state  | 
| 
58011
 
bc6bced136e5
tuned signature -- moved type src to Token, without aliases;
 
wenzelm 
parents: 
57964 
diff
changeset
 | 
28  | 
val recdef_tc_i: bstring * Token.src list -> string -> int option -> bool ->  | 
| 
27727
 
2397e310b2cc
simplified defer_recdef(_i): plain facts via Attrib.eval_thms;
 
wenzelm 
parents: 
27353 
diff
changeset
 | 
29  | 
local_theory -> Proof.state  | 
| 6429 | 30  | 
end;  | 
31  | 
||
| 
31723
 
f5cafe803b55
discontinued ancient tradition to suffix certain ML module names with "_package"
 
haftmann 
parents: 
31243 
diff
changeset
 | 
32  | 
structure Recdef: RECDEF =  | 
| 6429 | 33  | 
struct  | 
34  | 
||
35  | 
||
| 9859 | 36  | 
(** recdef hints **)  | 
| 6439 | 37  | 
|
| 9859 | 38  | 
(* type hints *)  | 
39  | 
||
40  | 
type hints = {simps: thm list, congs: (string * thm) list, wfs: thm list};
 | 
|
41  | 
||
42  | 
fun mk_hints (simps, congs, wfs) = {simps = simps, congs = congs, wfs = wfs}: hints;
 | 
|
43  | 
fun map_hints f ({simps, congs, wfs}: hints) = mk_hints (f (simps, congs, wfs));
 | 
|
44  | 
||
45  | 
fun map_simps f = map_hints (fn (simps, congs, wfs) => (f simps, congs, wfs));  | 
|
46  | 
fun map_congs f = map_hints (fn (simps, congs, wfs) => (simps, f congs, wfs));  | 
|
47  | 
fun map_wfs f = map_hints (fn (simps, congs, wfs) => (simps, congs, f wfs));  | 
|
48  | 
||
49  | 
||
50  | 
(* congruence rules *)  | 
|
51  | 
||
52  | 
local  | 
|
53  | 
||
54  | 
val cong_head =  | 
|
55  | 
fst o Term.dest_Const o Term.head_of o fst o Logic.dest_equals o Thm.concl_of;  | 
|
| 6439 | 56  | 
|
| 9859 | 57  | 
fun prep_cong raw_thm =  | 
58  | 
let val thm = safe_mk_meta_eq raw_thm in (cong_head thm, thm) end;  | 
|
59  | 
||
60  | 
in  | 
|
61  | 
||
62  | 
fun add_cong raw_thm congs =  | 
|
| 
21098
 
d0d8a48ae4e6
switched merge_alists'' to AList.merge'' whenever appropriate
 
haftmann 
parents: 
21078 
diff
changeset
 | 
63  | 
let  | 
| 
 
d0d8a48ae4e6
switched merge_alists'' to AList.merge'' whenever appropriate
 
haftmann 
parents: 
21078 
diff
changeset
 | 
64  | 
val (c, thm) = prep_cong raw_thm;  | 
| 
 
d0d8a48ae4e6
switched merge_alists'' to AList.merge'' whenever appropriate
 
haftmann 
parents: 
21078 
diff
changeset
 | 
65  | 
val _ = if AList.defined (op =) congs c  | 
| 
 
d0d8a48ae4e6
switched merge_alists'' to AList.merge'' whenever appropriate
 
haftmann 
parents: 
21078 
diff
changeset
 | 
66  | 
      then warning ("Overwriting recdef congruence rule for " ^ quote c)
 | 
| 
 
d0d8a48ae4e6
switched merge_alists'' to AList.merge'' whenever appropriate
 
haftmann 
parents: 
21078 
diff
changeset
 | 
67  | 
else ();  | 
| 
 
d0d8a48ae4e6
switched merge_alists'' to AList.merge'' whenever appropriate
 
haftmann 
parents: 
21078 
diff
changeset
 | 
68  | 
in AList.update (op =) (c, thm) congs end;  | 
| 9859 | 69  | 
|
70  | 
fun del_cong raw_thm congs =  | 
|
71  | 
let  | 
|
72  | 
val (c, thm) = prep_cong raw_thm;  | 
|
| 
21098
 
d0d8a48ae4e6
switched merge_alists'' to AList.merge'' whenever appropriate
 
haftmann 
parents: 
21078 
diff
changeset
 | 
73  | 
val _ = if AList.defined (op =) congs c  | 
| 
 
d0d8a48ae4e6
switched merge_alists'' to AList.merge'' whenever appropriate
 
haftmann 
parents: 
21078 
diff
changeset
 | 
74  | 
then ()  | 
| 
 
d0d8a48ae4e6
switched merge_alists'' to AList.merge'' whenever appropriate
 
haftmann 
parents: 
21078 
diff
changeset
 | 
75  | 
      else warning ("No recdef congruence rule for " ^ quote c);
 | 
| 
 
d0d8a48ae4e6
switched merge_alists'' to AList.merge'' whenever appropriate
 
haftmann 
parents: 
21078 
diff
changeset
 | 
76  | 
in AList.delete (op =) c congs end;  | 
| 9859 | 77  | 
|
78  | 
end;  | 
|
79  | 
||
80  | 
||
81  | 
||
82  | 
(** global and local recdef data **)  | 
|
83  | 
||
| 17920 | 84  | 
(* theory data *)  | 
| 6439 | 85  | 
|
| 
35756
 
cfde251d03a5
refining and adding Spec_Rules to definitional packages old_primrec, primrec, recdef, size and function
 
bulwahn 
parents: 
35690 
diff
changeset
 | 
86  | 
type recdef_info = {lhs: term, simps: thm list, rules: thm list list, induct: thm, tcs: term list};
 | 
| 6439 | 87  | 
|
| 33522 | 88  | 
structure GlobalRecdefData = Theory_Data  | 
| 22846 | 89  | 
(  | 
| 9859 | 90  | 
type T = recdef_info Symtab.table * hints;  | 
| 9879 | 91  | 
val empty = (Symtab.empty, mk_hints ([], [], [])): T;  | 
| 16458 | 92  | 
val extend = I;  | 
| 33522 | 93  | 
fun merge  | 
| 9859 | 94  | 
   ((tab1, {simps = simps1, congs = congs1, wfs = wfs1}),
 | 
| 16458 | 95  | 
    (tab2, {simps = simps2, congs = congs2, wfs = wfs2})) : T =
 | 
| 9859 | 96  | 
(Symtab.merge (K true) (tab1, tab2),  | 
| 
24039
 
273698405054
renamed Drule.add/del/merge_rules to Thm.add/del/merge_thms;
 
wenzelm 
parents: 
22846 
diff
changeset
 | 
97  | 
mk_hints (Thm.merge_thms (simps1, simps2),  | 
| 
33699
 
f33b036ef318
permissive AList.merge -- most likely setup for theory data (beware of spurious AList.DUP);
 
wenzelm 
parents: 
33643 
diff
changeset
 | 
98  | 
AList.merge (op =) (K true) (congs1, congs2),  | 
| 
24039
 
273698405054
renamed Drule.add/del/merge_rules to Thm.add/del/merge_thms;
 
wenzelm 
parents: 
22846 
diff
changeset
 | 
99  | 
Thm.merge_thms (wfs1, wfs2)));  | 
| 22846 | 100  | 
);  | 
| 6439 | 101  | 
|
| 17412 | 102  | 
val get_recdef = Symtab.lookup o #1 o GlobalRecdefData.get;  | 
| 6439 | 103  | 
|
104  | 
fun put_recdef name info thy =  | 
|
| 6429 | 105  | 
let  | 
| 9859 | 106  | 
val (tab, hints) = GlobalRecdefData.get thy;  | 
| 17412 | 107  | 
val tab' = Symtab.update_new (name, info) tab  | 
| 6439 | 108  | 
      handle Symtab.DUP _ => error ("Duplicate recursive function definition " ^ quote name);
 | 
| 9859 | 109  | 
in GlobalRecdefData.put (tab', hints) thy end;  | 
110  | 
||
111  | 
val get_global_hints = #2 o GlobalRecdefData.get;  | 
|
112  | 
||
113  | 
||
| 17920 | 114  | 
(* proof data *)  | 
| 9859 | 115  | 
|
| 33519 | 116  | 
structure LocalRecdefData = Proof_Data  | 
| 22846 | 117  | 
(  | 
| 9859 | 118  | 
type T = hints;  | 
119  | 
val init = get_global_hints;  | 
|
| 22846 | 120  | 
);  | 
| 9859 | 121  | 
|
| 21505 | 122  | 
val get_hints = LocalRecdefData.get;  | 
123  | 
fun map_hints f = Context.mapping (GlobalRecdefData.map (apsnd f)) (LocalRecdefData.map f);  | 
|
| 9859 | 124  | 
|
| 20291 | 125  | 
|
126  | 
(* attributes *)  | 
|
127  | 
||
| 18728 | 128  | 
fun attrib f = Thm.declaration_attribute (map_hints o f);  | 
| 9859 | 129  | 
|
| 
24039
 
273698405054
renamed Drule.add/del/merge_rules to Thm.add/del/merge_thms;
 
wenzelm 
parents: 
22846 
diff
changeset
 | 
130  | 
val simp_add = attrib (map_simps o Thm.add_thm);  | 
| 
 
273698405054
renamed Drule.add/del/merge_rules to Thm.add/del/merge_thms;
 
wenzelm 
parents: 
22846 
diff
changeset
 | 
131  | 
val simp_del = attrib (map_simps o Thm.del_thm);  | 
| 18688 | 132  | 
val cong_add = attrib (map_congs o add_cong);  | 
133  | 
val cong_del = attrib (map_congs o del_cong);  | 
|
| 
24039
 
273698405054
renamed Drule.add/del/merge_rules to Thm.add/del/merge_thms;
 
wenzelm 
parents: 
22846 
diff
changeset
 | 
134  | 
val wf_add = attrib (map_wfs o Thm.add_thm);  | 
| 
 
273698405054
renamed Drule.add/del/merge_rules to Thm.add/del/merge_thms;
 
wenzelm 
parents: 
22846 
diff
changeset
 | 
135  | 
val wf_del = attrib (map_wfs o Thm.del_thm);  | 
| 9859 | 136  | 
|
137  | 
||
| 9949 | 138  | 
(* modifiers *)  | 
| 9859 | 139  | 
|
| 9949 | 140  | 
val recdef_simpN = "recdef_simp";  | 
141  | 
val recdef_congN = "recdef_cong";  | 
|
142  | 
val recdef_wfN = "recdef_wf";  | 
|
| 9859 | 143  | 
|
144  | 
val recdef_modifiers =  | 
|
| 
58048
 
aa6296d09e0e
more explicit Method.modifier with reported position;
 
wenzelm 
parents: 
58028 
diff
changeset
 | 
145  | 
 [Args.$$$ recdef_simpN -- Args.colon >> K (Method.modifier simp_add @{here}),
 | 
| 
 
aa6296d09e0e
more explicit Method.modifier with reported position;
 
wenzelm 
parents: 
58028 
diff
changeset
 | 
146  | 
  Args.$$$ recdef_simpN -- Args.add -- Args.colon >> K (Method.modifier simp_add @{here}),
 | 
| 
 
aa6296d09e0e
more explicit Method.modifier with reported position;
 
wenzelm 
parents: 
58028 
diff
changeset
 | 
147  | 
  Args.$$$ recdef_simpN -- Args.del -- Args.colon >> K (Method.modifier simp_del @{here}),
 | 
| 
 
aa6296d09e0e
more explicit Method.modifier with reported position;
 
wenzelm 
parents: 
58028 
diff
changeset
 | 
148  | 
  Args.$$$ recdef_congN -- Args.colon >> K (Method.modifier cong_add @{here}),
 | 
| 
 
aa6296d09e0e
more explicit Method.modifier with reported position;
 
wenzelm 
parents: 
58028 
diff
changeset
 | 
149  | 
  Args.$$$ recdef_congN -- Args.add -- Args.colon >> K (Method.modifier cong_add @{here}),
 | 
| 
 
aa6296d09e0e
more explicit Method.modifier with reported position;
 
wenzelm 
parents: 
58028 
diff
changeset
 | 
150  | 
  Args.$$$ recdef_congN -- Args.del -- Args.colon >> K (Method.modifier cong_del @{here}),
 | 
| 
 
aa6296d09e0e
more explicit Method.modifier with reported position;
 
wenzelm 
parents: 
58028 
diff
changeset
 | 
151  | 
  Args.$$$ recdef_wfN -- Args.colon >> K (Method.modifier wf_add @{here}),
 | 
| 
 
aa6296d09e0e
more explicit Method.modifier with reported position;
 
wenzelm 
parents: 
58028 
diff
changeset
 | 
152  | 
  Args.$$$ recdef_wfN -- Args.add -- Args.colon >> K (Method.modifier wf_add @{here}),
 | 
| 
 
aa6296d09e0e
more explicit Method.modifier with reported position;
 
wenzelm 
parents: 
58028 
diff
changeset
 | 
153  | 
  Args.$$$ recdef_wfN -- Args.del -- Args.colon >> K (Method.modifier wf_del @{here})] @
 | 
| 9949 | 154  | 
Clasimp.clasimp_modifiers;  | 
| 9859 | 155  | 
|
| 9949 | 156  | 
|
| 9859 | 157  | 
|
| 9949 | 158  | 
(** prepare_hints(_i) **)  | 
| 9859 | 159  | 
|
160  | 
fun prepare_hints thy opt_src =  | 
|
161  | 
let  | 
|
| 42361 | 162  | 
val ctxt0 = Proof_Context.init_global thy;  | 
| 9859 | 163  | 
val ctxt =  | 
164  | 
(case opt_src of  | 
|
| 15531 | 165  | 
NONE => ctxt0  | 
| 
58011
 
bc6bced136e5
tuned signature -- moved type src to Token, without aliases;
 
wenzelm 
parents: 
57964 
diff
changeset
 | 
166  | 
| SOME src => #2 (Token.syntax (Method.sections recdef_modifiers) src ctxt0));  | 
| 21505 | 167  | 
    val {simps, congs, wfs} = get_hints ctxt;
 | 
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
50214 
diff
changeset
 | 
168  | 
    val ctxt' = ctxt addsimps simps |> Simplifier.del_cong @{thm imp_cong};
 | 
| 
42775
 
a973f82fc885
prefer Proof.context over old-style claset/simpset;
 
wenzelm 
parents: 
42361 
diff
changeset
 | 
169  | 
in (ctxt', rev (map snd congs), wfs) end;  | 
| 9859 | 170  | 
|
171  | 
fun prepare_hints_i thy () =  | 
|
| 15032 | 172  | 
let  | 
| 
42775
 
a973f82fc885
prefer Proof.context over old-style claset/simpset;
 
wenzelm 
parents: 
42361 
diff
changeset
 | 
173  | 
val ctxt = Proof_Context.init_global thy;  | 
| 15032 | 174  | 
    val {simps, congs, wfs} = get_global_hints thy;
 | 
| 
51717
 
9e7d1c139569
simplifier uses proper Proof.context instead of historic type simpset;
 
wenzelm 
parents: 
50214 
diff
changeset
 | 
175  | 
    val ctxt' = ctxt addsimps simps |> Simplifier.del_cong @{thm imp_cong};
 | 
| 
42775
 
a973f82fc885
prefer Proof.context over old-style claset/simpset;
 
wenzelm 
parents: 
42361 
diff
changeset
 | 
176  | 
in (ctxt', rev (map snd congs), wfs) end;  | 
| 9859 | 177  | 
|
| 6439 | 178  | 
|
179  | 
||
180  | 
(** add_recdef(_i) **)  | 
|
181  | 
||
| 17920 | 182  | 
fun gen_add_recdef tfl_fn prep_att prep_hints not_permissive raw_name R eq_srcs hints thy =  | 
| 6439 | 183  | 
let  | 
| 36865 | 184  | 
val _ = legacy_feature "Old 'recdef' command -- use 'fun' or 'function' instead";  | 
| 9859 | 185  | 
|
| 16458 | 186  | 
val name = Sign.intern_const thy raw_name;  | 
| 
30364
 
577edc39b501
moved basic algebra of long names from structure NameSpace to Long_Name;
 
wenzelm 
parents: 
30280 
diff
changeset
 | 
187  | 
val bname = Long_Name.base_name name;  | 
| 26478 | 188  | 
    val _ = writeln ("Defining recursive function " ^ quote name ^ " ...");
 | 
| 6429 | 189  | 
|
| 8657 | 190  | 
val ((eq_names, eqs), raw_eq_atts) = apfst split_list (split_list eq_srcs);  | 
191  | 
val eq_atts = map (map (prep_att thy)) raw_eq_atts;  | 
|
192  | 
||
| 
42775
 
a973f82fc885
prefer Proof.context over old-style claset/simpset;
 
wenzelm 
parents: 
42361 
diff
changeset
 | 
193  | 
val (ctxt, congs, wfs) = prep_hints thy hints;  | 
| 
14241
 
dfae7eb2830c
Prevent recdef from looping when the inductio rule is simplified
 
paulson 
parents: 
12876 
diff
changeset
 | 
194  | 
(*We must remove imp_cong to prevent looping when the induction rule  | 
| 
 
dfae7eb2830c
Prevent recdef from looping when the inductio rule is simplified
 
paulson 
parents: 
12876 
diff
changeset
 | 
195  | 
is simplified. Many induction rules have nested implications that would  | 
| 
 
dfae7eb2830c
Prevent recdef from looping when the inductio rule is simplified
 
paulson 
parents: 
12876 
diff
changeset
 | 
196  | 
give rise to looping conditional rewriting.*)  | 
| 
42775
 
a973f82fc885
prefer Proof.context over old-style claset/simpset;
 
wenzelm 
parents: 
42361 
diff
changeset
 | 
197  | 
    val ({lhs, rules = rules_idx, induct, tcs}, thy) =
 | 
| 
 
a973f82fc885
prefer Proof.context over old-style claset/simpset;
 
wenzelm 
parents: 
42361 
diff
changeset
 | 
198  | 
tfl_fn not_permissive ctxt congs wfs name R eqs thy;  | 
| 
21098
 
d0d8a48ae4e6
switched merge_alists'' to AList.merge'' whenever appropriate
 
haftmann 
parents: 
21078 
diff
changeset
 | 
199  | 
val rules = (map o map) fst (partition_eq (eq_snd (op = : int * int -> bool)) rules_idx);  | 
| 33552 | 200  | 
val simp_att =  | 
| 57964 | 201  | 
if null tcs then [Simplifier.simp_add,  | 
202  | 
        Named_Theorems.add @{named_theorems nitpick_simp}, Code.add_default_eqn_attribute]
 | 
|
| 33552 | 203  | 
else [];  | 
| 18377 | 204  | 
val ((simps' :: rules', [induct']), thy) =  | 
| 
7798
 
42e94b618f34
return stored thms with proper naming in derivation;
 
wenzelm 
parents: 
7262 
diff
changeset
 | 
205  | 
thy  | 
| 
24712
 
64ed05609568
proper Sign operations instead of Theory aliases;
 
wenzelm 
parents: 
24624 
diff
changeset
 | 
206  | 
|> Sign.add_path bname  | 
| 
39557
 
fe5722fce758
renamed structure PureThy to Pure_Thy and moved most content to Global_Theory, to emphasize that this is global-only;
 
wenzelm 
parents: 
36960 
diff
changeset
 | 
207  | 
|> Global_Theory.add_thmss  | 
| 32952 | 208  | 
(((Binding.name "simps", flat rules), simp_att) :: ((eq_names ~~ rules) ~~ eq_atts))  | 
| 
39557
 
fe5722fce758
renamed structure PureThy to Pure_Thy and moved most content to Global_Theory, to emphasize that this is global-only;
 
wenzelm 
parents: 
36960 
diff
changeset
 | 
209  | 
||>> Global_Theory.add_thms [((Binding.name "induct", induct), [])]  | 
| 
35756
 
cfde251d03a5
refining and adding Spec_Rules to definitional packages old_primrec, primrec, recdef, size and function
 
bulwahn 
parents: 
35690 
diff
changeset
 | 
210  | 
||> Spec_Rules.add_global Spec_Rules.Equational ([lhs], flat rules);  | 
| 
 
cfde251d03a5
refining and adding Spec_Rules to definitional packages old_primrec, primrec, recdef, size and function
 
bulwahn 
parents: 
35690 
diff
changeset
 | 
211  | 
    val result = {lhs = lhs, simps = simps', rules = rules', induct = induct', tcs = tcs};
 | 
| 
7798
 
42e94b618f34
return stored thms with proper naming in derivation;
 
wenzelm 
parents: 
7262 
diff
changeset
 | 
212  | 
val thy =  | 
| 
 
42e94b618f34
return stored thms with proper naming in derivation;
 
wenzelm 
parents: 
7262 
diff
changeset
 | 
213  | 
thy  | 
| 6439 | 214  | 
|> put_recdef name result  | 
| 
24712
 
64ed05609568
proper Sign operations instead of Theory aliases;
 
wenzelm 
parents: 
24624 
diff
changeset
 | 
215  | 
|> Sign.parent_path;  | 
| 
7798
 
42e94b618f34
return stored thms with proper naming in derivation;
 
wenzelm 
parents: 
7262 
diff
changeset
 | 
216  | 
in (thy, result) end;  | 
| 6429 | 217  | 
|
| 47815 | 218  | 
val add_recdef = gen_add_recdef Tfl.define Attrib.attribute_cmd_global prepare_hints;  | 
| 11629 | 219  | 
fun add_recdef_i x y z w = gen_add_recdef Tfl.define_i (K I) prepare_hints_i x y z w ();  | 
| 9859 | 220  | 
|
221  | 
||
| 6557 | 222  | 
|
223  | 
(** defer_recdef(_i) **)  | 
|
224  | 
||
| 
27727
 
2397e310b2cc
simplified defer_recdef(_i): plain facts via Attrib.eval_thms;
 
wenzelm 
parents: 
27353 
diff
changeset
 | 
225  | 
fun gen_defer_recdef tfl_fn eval_thms raw_name eqs raw_congs thy =  | 
| 6557 | 226  | 
let  | 
| 16458 | 227  | 
val name = Sign.intern_const thy raw_name;  | 
| 
30364
 
577edc39b501
moved basic algebra of long names from structure NameSpace to Long_Name;
 
wenzelm 
parents: 
30280 
diff
changeset
 | 
228  | 
val bname = Long_Name.base_name name;  | 
| 6557 | 229  | 
|
| 26478 | 230  | 
    val _ = writeln ("Deferred recursive function " ^ quote name ^ " ...");
 | 
| 6557 | 231  | 
|
| 42361 | 232  | 
val congs = eval_thms (Proof_Context.init_global thy) raw_congs;  | 
| 
42775
 
a973f82fc885
prefer Proof.context over old-style claset/simpset;
 
wenzelm 
parents: 
42361 
diff
changeset
 | 
233  | 
val (induct_rules, thy2) = tfl_fn congs name eqs thy;  | 
| 18377 | 234  | 
val ([induct_rules'], thy3) =  | 
| 6557 | 235  | 
thy2  | 
| 
24712
 
64ed05609568
proper Sign operations instead of Theory aliases;
 
wenzelm 
parents: 
24624 
diff
changeset
 | 
236  | 
|> Sign.add_path bname  | 
| 
39557
 
fe5722fce758
renamed structure PureThy to Pure_Thy and moved most content to Global_Theory, to emphasize that this is global-only;
 
wenzelm 
parents: 
36960 
diff
changeset
 | 
237  | 
|> Global_Theory.add_thms [((Binding.name "induct_rules", induct_rules), [])]  | 
| 
24712
 
64ed05609568
proper Sign operations instead of Theory aliases;
 
wenzelm 
parents: 
24624 
diff
changeset
 | 
238  | 
||> Sign.parent_path;  | 
| 8430 | 239  | 
  in (thy3, {induct_rules = induct_rules'}) end;
 | 
| 6557 | 240  | 
|
| 
27727
 
2397e310b2cc
simplified defer_recdef(_i): plain facts via Attrib.eval_thms;
 
wenzelm 
parents: 
27353 
diff
changeset
 | 
241  | 
val defer_recdef = gen_defer_recdef Tfl.defer Attrib.eval_thms;  | 
| 
 
2397e310b2cc
simplified defer_recdef(_i): plain facts via Attrib.eval_thms;
 
wenzelm 
parents: 
27353 
diff
changeset
 | 
242  | 
val defer_recdef_i = gen_defer_recdef Tfl.defer_i (K I);  | 
| 6557 | 243  | 
|
244  | 
||
245  | 
||
| 10775 | 246  | 
(** recdef_tc(_i) **)  | 
247  | 
||
| 
24457
 
a33258c78ed2
Adapted to changes in interface of Specification.theorem_i
 
berghofe 
parents: 
24039 
diff
changeset
 | 
248  | 
fun gen_recdef_tc prep_att prep_name (bname, raw_atts) raw_name opt_i int lthy =  | 
| 10775 | 249  | 
let  | 
| 42361 | 250  | 
val thy = Proof_Context.theory_of lthy;  | 
| 16458 | 251  | 
val name = prep_name thy raw_name;  | 
| 
55997
 
9dc5ce83202c
modernized Attrib.check_name/check_src similar to methods (see also a989bdaf8121);
 
wenzelm 
parents: 
51717 
diff
changeset
 | 
252  | 
val atts = map (prep_att lthy) raw_atts;  | 
| 10775 | 253  | 
val tcs =  | 
254  | 
(case get_recdef thy name of  | 
|
| 15531 | 255  | 
        NONE => error ("No recdef definition of constant: " ^ quote name)
 | 
256  | 
      | SOME {tcs, ...} => tcs);
 | 
|
| 
21351
 
1fb804b96d7c
recdef_tc(_i): local_theory interface via Specification.theorem_i;
 
wenzelm 
parents: 
21098 
diff
changeset
 | 
257  | 
val i = the_default 1 opt_i;  | 
| 43278 | 258  | 
val tc = nth tcs (i - 1) handle General.Subscript =>  | 
| 10775 | 259  | 
      error ("No termination condition #" ^ string_of_int i ^
 | 
260  | 
" in recdef definition of " ^ quote name);  | 
|
| 
21351
 
1fb804b96d7c
recdef_tc(_i): local_theory interface via Specification.theorem_i;
 
wenzelm 
parents: 
21098 
diff
changeset
 | 
261  | 
in  | 
| 
33643
 
b275f26a638b
eliminated obsolete "internal" kind -- collapsed to unspecific "";
 
wenzelm 
parents: 
33552 
diff
changeset
 | 
262  | 
Specification.theorem "" NONE (K I)  | 
| 
47067
 
4ef29b0c568f
optional 'includes' element for long theorem statements;
 
wenzelm 
parents: 
46961 
diff
changeset
 | 
263  | 
(Binding.conceal (Binding.name bname), atts) [] []  | 
| 33278 | 264  | 
(Element.Shows [(Attrib.empty_binding, [(HOLogic.mk_Trueprop tc, [])])]) int lthy  | 
| 
21351
 
1fb804b96d7c
recdef_tc(_i): local_theory interface via Specification.theorem_i;
 
wenzelm 
parents: 
21098 
diff
changeset
 | 
265  | 
end;  | 
| 10775 | 266  | 
|
| 
55997
 
9dc5ce83202c
modernized Attrib.check_name/check_src similar to methods (see also a989bdaf8121);
 
wenzelm 
parents: 
51717 
diff
changeset
 | 
267  | 
val recdef_tc = gen_recdef_tc Attrib.check_src Sign.intern_const;  | 
| 10775 | 268  | 
val recdef_tc_i = gen_recdef_tc (K I) (K I);  | 
269  | 
||
270  | 
||
271  | 
||
| 6439 | 272  | 
(** package setup **)  | 
273  | 
||
274  | 
(* setup theory *)  | 
|
275  | 
||
| 58825 | 276  | 
val _ =  | 
277  | 
Theory.setup  | 
|
278  | 
   (Attrib.setup @{binding recdef_simp} (Attrib.add_del simp_add simp_del)
 | 
|
279  | 
"declaration of recdef simp rule" #>  | 
|
280  | 
    Attrib.setup @{binding recdef_cong} (Attrib.add_del cong_add cong_del)
 | 
|
281  | 
"declaration of recdef cong rule" #>  | 
|
282  | 
    Attrib.setup @{binding recdef_wf} (Attrib.add_del wf_add wf_del)
 | 
|
283  | 
"declaration of recdef wf rule");  | 
|
| 6439 | 284  | 
|
285  | 
||
| 6429 | 286  | 
(* outer syntax *)  | 
287  | 
||
| 9859 | 288  | 
val hints =  | 
| 46949 | 289  | 
  @{keyword "("} |--
 | 
| 56201 | 290  | 
    Parse.!!! (Parse.position @{keyword "hints"} -- Parse.args --| @{keyword ")"})
 | 
| 
58011
 
bc6bced136e5
tuned signature -- moved type src to Token, without aliases;
 
wenzelm 
parents: 
57964 
diff
changeset
 | 
291  | 
>> uncurry Token.src;  | 
| 9859 | 292  | 
|
| 6429 | 293  | 
val recdef_decl =  | 
| 
36960
 
01594f816e3a
prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
 
wenzelm 
parents: 
36954 
diff
changeset
 | 
294  | 
Scan.optional  | 
| 46949 | 295  | 
    (@{keyword "("} -- Parse.!!! (@{keyword "permissive"} -- @{keyword ")"}) >> K false) true --
 | 
| 
36960
 
01594f816e3a
prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
 
wenzelm 
parents: 
36954 
diff
changeset
 | 
296  | 
Parse.name -- Parse.term -- Scan.repeat1 (Parse_Spec.opt_thm_name ":" -- Parse.prop)  | 
| 
28083
 
103d9282a946
explicit type Name.binding for higher-specification elements;
 
wenzelm 
parents: 
27809 
diff
changeset
 | 
297  | 
-- Scan.option hints  | 
| 
36960
 
01594f816e3a
prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
 
wenzelm 
parents: 
36954 
diff
changeset
 | 
298  | 
>> (fn ((((p, f), R), eqs), src) => #1 o add_recdef p f R (map Parse.triple_swap eqs) src);  | 
| 6429 | 299  | 
|
| 24867 | 300  | 
val _ =  | 
| 50214 | 301  | 
  Outer_Syntax.command @{command_spec "recdef"} "define general recursive functions (obsolete TFL)"
 | 
| 6429 | 302  | 
(recdef_decl >> Toplevel.theory);  | 
303  | 
||
| 6557 | 304  | 
|
305  | 
val defer_recdef_decl =  | 
|
| 
36960
 
01594f816e3a
prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
 
wenzelm 
parents: 
36954 
diff
changeset
 | 
306  | 
Parse.name -- Scan.repeat1 Parse.prop --  | 
| 
 
01594f816e3a
prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
 
wenzelm 
parents: 
36954 
diff
changeset
 | 
307  | 
Scan.optional  | 
| 
58028
 
e4250d370657
tuned signature -- define some elementary operations earlier;
 
wenzelm 
parents: 
58011 
diff
changeset
 | 
308  | 
    (@{keyword "("} |-- @{keyword "congs"} |-- Parse.!!! (Parse.xthms1 --| @{keyword ")"})) []
 | 
| 6557 | 309  | 
>> (fn ((f, eqs), congs) => #1 o defer_recdef f eqs congs);  | 
310  | 
||
| 24867 | 311  | 
val _ =  | 
| 
46961
 
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
 
wenzelm 
parents: 
46949 
diff
changeset
 | 
312  | 
  Outer_Syntax.command @{command_spec "defer_recdef"}
 | 
| 50214 | 313  | 
"defer general recursive functions (obsolete TFL)"  | 
| 6557 | 314  | 
(defer_recdef_decl >> Toplevel.theory);  | 
315  | 
||
| 24867 | 316  | 
val _ =  | 
| 
46961
 
5c6955f487e5
outer syntax command definitions based on formal command_spec derived from theory header declarations;
 
wenzelm 
parents: 
46949 
diff
changeset
 | 
317  | 
  Outer_Syntax.local_theory_to_proof' @{command_spec "recdef_tc"}
 | 
| 50214 | 318  | 
"recommence proof of termination condition (obsolete TFL)"  | 
| 
36960
 
01594f816e3a
prefer structure Keyword, Parse, Parse_Spec, Outer_Syntax;
 
wenzelm 
parents: 
36954 
diff
changeset
 | 
319  | 
((Parse_Spec.opt_thm_name ":" >> apfst Binding.name_of) -- Parse.xname --  | 
| 46949 | 320  | 
        Scan.option (@{keyword "("} |-- Parse.nat --| @{keyword ")"})
 | 
| 
26988
 
742e26213212
more uniform treatment of OuterSyntax.local_theory commands;
 
wenzelm 
parents: 
26478 
diff
changeset
 | 
321  | 
>> (fn ((thm_name, name), i) => recdef_tc thm_name name i));  | 
| 10775 | 322  | 
|
| 6429 | 323  | 
end;  |