92 val ((goal_state, cont), lthy') = |
92 val ((goal_state, cont), lthy') = |
93 Function_Mutual.prepare_function_mutual config defname fixes eqs lthy |
93 Function_Mutual.prepare_function_mutual config defname fixes eqs lthy |
94 |
94 |
95 fun afterqed [[proof]] lthy = |
95 fun afterqed [[proof]] lthy = |
96 let |
96 let |
|
97 val result = cont (Thm.close_derivation proof) |
97 val FunctionResult {fs, R, dom, psimps, simple_pinducts, |
98 val FunctionResult {fs, R, dom, psimps, simple_pinducts, |
98 termination, domintros, cases, ...} = |
99 termination, domintros, cases, ...} = result |
99 cont (Thm.close_derivation proof) |
100 |
|
101 val pelims = Function_Elims.mk_partial_elim_rules lthy result |
100 |
102 |
101 val fnames = map (fst o fst) fixes |
103 val fnames = map (fst o fst) fixes |
102 fun qualify n = Binding.name n |
104 fun qualify n = Binding.name n |
103 |> Binding.qualify true defname |
105 |> Binding.qualify true defname |
104 val conceal_partial = if partials then I else Binding.conceal |
106 val conceal_partial = if partials then I else Binding.conceal |
105 |
107 |
106 val addsmps = add_simps fnames post sort_cont |
108 val addsmps = add_simps fnames post sort_cont |
107 |
109 |
108 val ((((psimps', [pinducts']), [termination']), [cases']), lthy) = |
110 (* TODO: case names *) |
|
111 fun addcases lthy = |
|
112 let fun go name thm (thms_acc, lthy) = |
|
113 case Local_Theory.note ((Binding.name "cases" |> Binding.qualify true name, |
|
114 [Attrib.internal (K (Rule_Cases.case_names cnames))]), [thm]) lthy |
|
115 of ((_,thms), lthy') => (thms :: thms_acc, lthy') |
|
116 val (thms, lthy') = fold2 go fnames cases ([], lthy); |
|
117 in |
|
118 (rev thms, lthy') |
|
119 end; |
|
120 |
|
121 fun addpelims lthy = |
|
122 let fun go name thm (thms_acc, lthy) = |
|
123 case Local_Theory.note ((Binding.name "pelims" |> Binding.qualify true name, |
|
124 [Attrib.internal (K (Rule_Cases.consumes 1)), |
|
125 Attrib.internal (K (Rule_Cases.constraints 1))]), thm) lthy |
|
126 of ((_,thms), lthy') => (thms :: thms_acc, lthy') |
|
127 val (thms, lthy') = fold2 go fnames pelims ([], lthy); |
|
128 in |
|
129 (rev thms, lthy') |
|
130 end; |
|
131 |
|
132 val (((((psimps', [pinducts']), [termination']), cases'), pelims'), lthy) = |
109 lthy |
133 lthy |
110 |> addsmps (conceal_partial o Binding.qualify false "partial") |
134 |> addsmps (conceal_partial o Binding.qualify false "partial") |
111 "psimps" conceal_partial psimp_attribs psimps |
135 "psimps" conceal_partial psimp_attribs psimps |
112 ||>> Local_Theory.notes [((conceal_partial (qualify "pinduct"), []), |
136 ||>> Local_Theory.notes [((conceal_partial (qualify "pinduct"), []), |
113 simple_pinducts |> map (fn th => ([th], |
137 simple_pinducts |> map (fn th => ([th], |
114 [Attrib.internal (K (Rule_Cases.case_names cnames)), |
138 [Attrib.internal (K (Rule_Cases.case_names cnames)), |
115 Attrib.internal (K (Rule_Cases.consumes (1 - Thm.nprems_of th))), |
139 Attrib.internal (K (Rule_Cases.consumes (1 - Thm.nprems_of th))), |
116 Attrib.internal (K (Induct.induct_pred ""))])))] |
140 Attrib.internal (K (Induct.induct_pred ""))])))] |
117 ||>> (apfst snd o Local_Theory.note ((Binding.conceal (qualify "termination"), []), [termination])) |
141 ||>> (apfst snd o Local_Theory.note ((Binding.conceal (qualify "termination"), []), [termination])) |
118 ||>> (apfst snd o Local_Theory.note ((qualify "cases", |
142 ||>> addcases |
119 [Attrib.internal (K (Rule_Cases.case_names cnames))]), [cases])) |
143 ||>> addpelims |
120 ||> (case domintros of NONE => I | SOME thms => |
144 ||> (case domintros of NONE => I | SOME thms => |
121 Local_Theory.note ((qualify "domintros", []), thms) #> snd) |
145 Local_Theory.note ((qualify "domintros", []), thms) #> snd) |
122 |
146 |
123 val info = { add_simps=addsmps, case_names=cnames, psimps=psimps', |
147 val info = { add_simps=addsmps, fnames=fnames, case_names=cnames, psimps=psimps', |
124 pinducts=snd pinducts', simps=NONE, inducts=NONE, termination=termination', |
148 pinducts=snd pinducts', simps=NONE, inducts=NONE, termination=termination', |
125 fs=fs, R=R, dom=dom, defname=defname, is_partial=true, cases=cases'} |
149 fs=fs, R=R, dom=dom, defname=defname, is_partial=true, cases=flat cases', |
|
150 pelims=pelims',elims=NONE} |
126 |
151 |
127 val _ = Proof_Display.print_consts do_print lthy (K false) (map fst fixes) |
152 val _ = Proof_Display.print_consts do_print lthy (K false) (map fst fixes) |
128 in |
153 in |
129 (info, |
154 (info, |
130 lthy |> Local_Theory.declaration {syntax = false, pervasive = false} |
155 lthy |> Local_Theory.declaration {syntax = false, pervasive = false} |
178 (case import_last_function lthy of |
203 (case import_last_function lthy of |
179 SOME info => info |
204 SOME info => info |
180 | NONE => error "Not a function")) |
205 | NONE => error "Not a function")) |
181 |
206 |
182 val { termination, fs, R, add_simps, case_names, psimps, |
207 val { termination, fs, R, add_simps, case_names, psimps, |
183 pinducts, defname, cases, dom, ...} = info |
208 pinducts, defname, fnames, cases, dom, pelims, ...} = info |
184 val domT = domain_type (fastype_of R) |
209 val domT = domain_type (fastype_of R) |
185 val goal = HOLogic.mk_Trueprop (HOLogic.mk_all ("x", domT, mk_acc domT R $ Free ("x", domT))) |
210 val goal = HOLogic.mk_Trueprop (HOLogic.mk_all ("x", domT, mk_acc domT R $ Free ("x", domT))) |
186 fun afterqed [[totality]] lthy = |
211 fun afterqed [[totality]] lthy = |
187 let |
212 let |
188 val totality = Thm.close_derivation totality |
213 val totality = Thm.close_derivation totality |
189 val remove_domain_condition = |
214 val remove_domain_condition = |
190 full_simplify (put_simpset HOL_basic_ss lthy |
215 full_simplify (put_simpset HOL_basic_ss lthy |
191 addsimps [totality, @{thm True_implies_equals}]) |
216 addsimps [totality, @{thm True_implies_equals}]) |
192 val tsimps = map remove_domain_condition psimps |
217 val tsimps = map remove_domain_condition psimps |
193 val tinduct = map remove_domain_condition pinducts |
218 val tinduct = map remove_domain_condition pinducts |
|
219 val telims = map (map remove_domain_condition) pelims |
194 |
220 |
195 fun qualify n = Binding.name n |
221 fun qualify n = Binding.name n |
196 |> Binding.qualify true defname |
222 |> Binding.qualify true defname |
|
223 |
|
224 fun addtelims lthy = |
|
225 let fun go name thm (thms_acc, lthy) = |
|
226 case Local_Theory.note ((Binding.name "elims" |> Binding.qualify true name, |
|
227 [Attrib.internal (K (Rule_Cases.consumes 1)), |
|
228 Attrib.internal (K (Rule_Cases.constraints 1)), |
|
229 Attrib.internal (K (Induct.cases_pred defname))]), thm) lthy |
|
230 of ((_,thms), lthy') => (thms :: thms_acc, lthy') |
|
231 val (thms, lthy') = fold2 go fnames telims ([], lthy); |
|
232 in |
|
233 (rev thms, lthy') |
|
234 end; |
|
235 |
197 in |
236 in |
198 lthy |
237 lthy |
199 |> add_simps I "simps" I simp_attribs tsimps |
238 |> add_simps I "simps" I simp_attribs tsimps |
200 ||>> Local_Theory.note |
239 ||>> Local_Theory.note |
201 ((qualify "induct", |
240 ((qualify "induct", |
202 [Attrib.internal (K (Rule_Cases.case_names case_names))]), |
241 [Attrib.internal (K (Rule_Cases.case_names case_names))]), |
203 tinduct) |
242 tinduct) |
204 |-> (fn (simps, (_, inducts)) => fn lthy => |
243 ||>> addtelims |
205 let val info' = { is_partial=false, defname=defname, add_simps=add_simps, |
244 |-> (fn ((simps,(_,inducts)), elims) => fn lthy => |
|
245 let val info' = { is_partial=false, defname=defname, fnames=fnames, add_simps=add_simps, |
206 case_names=case_names, fs=fs, R=R, dom=dom, psimps=psimps, pinducts=pinducts, |
246 case_names=case_names, fs=fs, R=R, dom=dom, psimps=psimps, pinducts=pinducts, |
207 simps=SOME simps, inducts=SOME inducts, termination=termination, cases=cases } |
247 simps=SOME simps, inducts=SOME inducts, termination=termination, cases=cases, pelims=pelims, elims=SOME elims} |
208 in |
248 in |
209 (info', |
249 (info', |
210 lthy |
250 lthy |
211 |> Local_Theory.declaration {syntax = false, pervasive = false} |
251 |> Local_Theory.declaration {syntax = false, pervasive = false} |
212 (add_function_data o transform_function_data info') |
252 (add_function_data o transform_function_data info') |
213 |> Spec_Rules.add Spec_Rules.Equational (fs, tsimps)) |
253 |> Spec_Rules.add Spec_Rules.Equational (fs, tsimps)) |
214 end) |
254 end) |
215 end |
255 end |