|
1 (* Title: HOL/Tools/function_package/fundef_package.ML |
|
2 ID: $Id$ |
|
3 Author: Alexander Krauss, TU Muenchen |
|
4 |
|
5 A package for general recursive function definitions. |
|
6 Isar commands. |
|
7 |
|
8 *) |
|
9 |
|
10 signature FUNDEF_PACKAGE = |
|
11 sig |
|
12 val add_fundef : ((bstring * Attrib.src list) * string) list -> theory -> Proof.state (* Need an _i variant *) |
|
13 |
|
14 val cong_add: attribute |
|
15 val cong_del: attribute |
|
16 |
|
17 val setup : theory -> theory |
|
18 end |
|
19 |
|
20 |
|
21 structure FundefPackage : FUNDEF_PACKAGE = |
|
22 struct |
|
23 |
|
24 open FundefCommon |
|
25 |
|
26 val True_implies = thm "True_implies" |
|
27 |
|
28 |
|
29 (*#> FundefTermination.setup #> FundefDatatype.setup*) |
|
30 |
|
31 fun fundef_afterqed congs curry_info name data natts thmss thy = |
|
32 let |
|
33 val (complete_thm :: compat_thms) = map hd thmss |
|
34 val fundef_data = FundefProof.mk_partial_rules_curried thy congs curry_info data (freezeT complete_thm) (map freezeT compat_thms) |
|
35 val {psimps, subset_pinduct, simple_pinduct, total_intro, dom_intros, ...} = fundef_data |
|
36 |
|
37 val (names, attsrcs) = split_list natts |
|
38 val atts = map (map (Attrib.attribute thy)) attsrcs |
|
39 |
|
40 val accR = (#acc_R(#names(data))) |
|
41 val dom_abbrev = Logic.mk_equals (Free ("dom", fastype_of accR), accR) |
|
42 |
|
43 val thy = thy |> Theory.add_path name |
|
44 |
|
45 val thy = thy |> Theory.add_path "psimps" |
|
46 val (_, thy) = PureThy.add_thms ((names ~~ psimps) ~~ atts) thy; |
|
47 val thy = thy |> Theory.parent_path |
|
48 |
|
49 val (_, thy) = LocalTheory.mapping NONE (Specification.abbreviation_i ("", false) [(NONE, dom_abbrev)]) thy |
|
50 val (_, thy) = PureThy.add_thms [(("cases", complete_thm), [RuleCases.case_names names])] thy |
|
51 val (_, thy) = PureThy.add_thmss [(("domintros", dom_intros), [])] thy |
|
52 val (_, thy) = PureThy.add_thms [(("termination", total_intro), [])] thy |
|
53 val (_,thy) = PureThy.add_thms [(("pinduct", simple_pinduct), [RuleCases.case_names names, InductAttrib.induct_set ""])] thy |
|
54 val (_, thy) = PureThy.add_thmss [(("psimps", psimps), [Simplifier.simp_add])] thy |
|
55 val thy = thy |> Theory.parent_path |
|
56 in |
|
57 add_fundef_data name fundef_data thy |
|
58 end |
|
59 |
|
60 fun add_fundef eqns_atts thy = |
|
61 let |
|
62 val (natts, eqns) = split_list eqns_atts |
|
63 |
|
64 val congs = get_fundef_congs (Context.Theory thy) |
|
65 |
|
66 val (curry_info, name, (data, thy)) = FundefPrep.prepare_fundef_curried congs (map (Sign.read_prop thy) eqns) thy |
|
67 val {complete, compat, ...} = data |
|
68 |
|
69 val props = (complete :: compat) (*(complete :: fst (chop 110 compat))*) |
|
70 in |
|
71 thy |> ProofContext.init |
|
72 |> Proof.theorem_i PureThy.internalK NONE (fundef_afterqed congs curry_info name data natts) NONE ("", []) |
|
73 (map (fn t => (("", []), [(t, ([], []))])) props) |
|
74 end |
|
75 |
|
76 |
|
77 fun total_termination_afterqed name thmss thy = |
|
78 let |
|
79 val totality = hd (hd thmss) |
|
80 |
|
81 val {psimps, simple_pinduct, ... } |
|
82 = the (get_fundef_data name thy) |
|
83 |
|
84 val remove_domain_condition = full_simplify (HOL_basic_ss addsimps [totality, True_implies]) |
|
85 |
|
86 val tsimps = map remove_domain_condition psimps |
|
87 val tinduct = remove_domain_condition simple_pinduct |
|
88 |
|
89 val thy = Theory.add_path name thy |
|
90 |
|
91 (* Need the names and attributes. Apply the attributes again? *) |
|
92 (* val thy = thy |> Theory.add_path "simps" |
|
93 val (_, thy) = PureThy.add_thms ((names ~~ tsimps) ~~ atts) thy; |
|
94 val thy = thy |> Theory.parent_path*) |
|
95 |
|
96 val (_, thy) = PureThy.add_thms [(("induct", tinduct), [])] thy |
|
97 val (_, thy) = PureThy.add_thmss [(("simps", tsimps), [Simplifier.simp_add, RecfunCodegen.add NONE])] thy |
|
98 val thy = Theory.parent_path thy |
|
99 in |
|
100 thy |
|
101 end |
|
102 |
|
103 (* |
|
104 fun mk_partial_rules name D_name D domT idomT thmss thy = |
|
105 let |
|
106 val [subs, dcl] = (hd thmss) |
|
107 |
|
108 val {f_const, f_curried_const, G_const, R_const, G_elims, completeness, f_simps, names_attrs, subset_induct, ... } |
|
109 = the (Symtab.lookup (FundefData.get thy) name) |
|
110 |
|
111 val D_implies_dom = subs COMP (instantiate' [SOME (ctyp_of thy idomT)] |
|
112 [SOME (cterm_of thy D)] |
|
113 subsetD) |
|
114 |
|
115 val D_simps = map (curry op RS D_implies_dom) f_simps |
|
116 |
|
117 val D_induct = subset_induct |
|
118 |> cterm_instantiate [(cterm_of thy (Var (("D",0), fastype_of D)) ,cterm_of thy D)] |
|
119 |> curry op COMP subs |
|
120 |> curry op COMP (dcl |> forall_intr (cterm_of thy (Var (("z",0), idomT))) |
|
121 |> forall_intr (cterm_of thy (Var (("x",0), idomT)))) |
|
122 |
|
123 val ([tinduct'], thy2) = PureThy.add_thms [((name ^ "_" ^ D_name ^ "_induct", D_induct), [])] thy |
|
124 val ([tsimps'], thy3) = PureThy.add_thmss [((name ^ "_" ^ D_name ^ "_simps", D_simps), [])] thy2 |
|
125 in |
|
126 thy3 |
|
127 end |
|
128 *) |
|
129 |
|
130 |
|
131 fun fundef_setup_termination_proof name NONE thy = |
|
132 let |
|
133 val name = if name = "" then get_last_fundef thy else name |
|
134 val data = the (get_fundef_data name thy) |
|
135 |
|
136 val {total_intro, ...} = data |
|
137 val goal = FundefTermination.mk_total_termination_goal data |
|
138 in |
|
139 thy |> ProofContext.init |
|
140 |> ProofContext.note_thmss_i [(("termination_intro", |
|
141 [ContextRules.intro_query NONE]), [([total_intro], [])])] |> snd |
|
142 |> Proof.theorem_i PureThy.internalK NONE (total_termination_afterqed name) NONE ("", []) |
|
143 [(("", []), [(goal, ([], []))])] |
|
144 end |
|
145 | fundef_setup_termination_proof name (SOME (dom_name, dom)) thy = |
|
146 let |
|
147 val name = if name = "" then get_last_fundef thy else name |
|
148 val data = the (get_fundef_data name thy) |
|
149 val (subs, dcl) = FundefTermination.mk_partial_termination_goal thy data dom |
|
150 in |
|
151 thy |> ProofContext.init |
|
152 |> Proof.theorem_i PureThy.internalK NONE (K I) NONE ("", []) |
|
153 [(("", []), [(subs, ([], [])), (dcl, ([], []))])] |
|
154 end |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 (* congruence rules *) |
|
160 |
|
161 val cong_add = Thm.declaration_attribute (map_fundef_congs o cons o safe_mk_meta_eq); |
|
162 val cong_del = Thm.declaration_attribute (map_fundef_congs o remove (op =) o safe_mk_meta_eq); |
|
163 |
|
164 |
|
165 (* setup *) |
|
166 |
|
167 val setup = FundefData.init #> FundefCongs.init |
|
168 #> Attrib.add_attributes |
|
169 [("fundef_cong", Attrib.add_del_args cong_add cong_del, "declaration of congruence rule for function definitions")] |
|
170 |
|
171 |
|
172 (* outer syntax *) |
|
173 |
|
174 local structure P = OuterParse and K = OuterKeyword in |
|
175 |
|
176 val function_decl = |
|
177 Scan.repeat1 (P.opt_thm_name ":" -- P.prop); |
|
178 |
|
179 val functionP = |
|
180 OuterSyntax.command "function" "define general recursive functions" K.thy_goal |
|
181 (function_decl >> (fn eqns => |
|
182 Toplevel.print o Toplevel.theory_to_proof (add_fundef eqns))); |
|
183 |
|
184 val terminationP = |
|
185 OuterSyntax.command "termination" "prove termination of a recursive function" K.thy_goal |
|
186 ((Scan.optional P.name "" -- Scan.option (P.$$$ "(" |-- Scan.optional (P.name --| P.$$$ ":") "dom" -- P.term --| P.$$$ ")")) |
|
187 >> (fn (name,dom) => |
|
188 Toplevel.print o Toplevel.theory_to_proof (fundef_setup_termination_proof name dom))); |
|
189 |
|
190 val _ = OuterSyntax.add_parsers [functionP]; |
|
191 val _ = OuterSyntax.add_parsers [terminationP]; |
|
192 |
|
193 |
|
194 end; |
|
195 |
|
196 |
|
197 end |