199 |
199 |
200 (* complex goal statements *) |
200 (* complex goal statements *) |
201 |
201 |
202 local |
202 local |
203 |
203 |
|
204 fun subtract_prems ctxt1 ctxt2 = |
|
205 Library.drop (length (Assumption.prems_of ctxt1), Assumption.prems_of ctxt2); |
|
206 |
204 fun prep_statement prep_att prep_stmt elems concl ctxt = |
207 fun prep_statement prep_att prep_stmt elems concl ctxt = |
205 (case concl of |
208 (case concl of |
206 Element.Shows shows => |
209 Element.Shows shows => |
207 let |
210 let |
208 val (_, _, elems_ctxt, propp) = prep_stmt elems (map snd shows) ctxt; |
211 val (_, loc_ctxt, elems_ctxt, propp) = prep_stmt elems (map snd shows) ctxt; |
|
212 val prems = subtract_prems loc_ctxt elems_ctxt; |
|
213 val stmt = Attrib.map_specs prep_att (map fst shows ~~ propp); |
209 val goal_ctxt = fold (fold (Variable.auto_fixes o fst)) propp elems_ctxt; |
214 val goal_ctxt = fold (fold (Variable.auto_fixes o fst)) propp elems_ctxt; |
210 val stmt = Attrib.map_specs prep_att (map fst shows ~~ propp); |
215 in ((prems, stmt, []), goal_ctxt) end |
211 in ((stmt, []), goal_ctxt) end |
|
212 | Element.Obtains obtains => |
216 | Element.Obtains obtains => |
213 let |
217 let |
214 val case_names = obtains |> map_index |
218 val case_names = obtains |> map_index |
215 (fn (i, ("", _)) => string_of_int (i + 1) | (_, (name, _)) => name); |
219 (fn (i, ("", _)) => string_of_int (i + 1) | (_, (name, _)) => name); |
216 val constraints = obtains |> map (fn (_, (vars, _)) => |
220 val constraints = obtains |> map (fn (_, (vars, _)) => |
217 Locale.Elem (Element.Constrains |
221 Locale.Elem (Element.Constrains |
218 (vars |> map_filter (fn (x, SOME T) => SOME (x, T) | _ => NONE)))); |
222 (vars |> map_filter (fn (x, SOME T) => SOME (x, T) | _ => NONE)))); |
219 |
223 |
220 val raw_propp = obtains |> map (fn (_, (_, props)) => map (rpair []) props); |
224 val raw_propp = obtains |> map (fn (_, (_, props)) => map (rpair []) props); |
221 val (_, _, elems_ctxt, propp) = prep_stmt (elems @ constraints) raw_propp ctxt; |
225 val (_, loc_ctxt, elems_ctxt, propp) = prep_stmt (elems @ constraints) raw_propp ctxt; |
222 |
226 |
223 val thesis = ObjectLogic.fixed_judgment (ProofContext.theory_of ctxt) AutoBind.thesisN; |
227 val thesis = ObjectLogic.fixed_judgment (ProofContext.theory_of ctxt) AutoBind.thesisN; |
224 |
228 |
225 fun assume_case ((name, (vars, _)), asms) ctxt' = |
229 fun assume_case ((name, (vars, _)), asms) ctxt' = |
226 let |
230 let |
238 |>> (fn [(_, [th])] => th) |
242 |>> (fn [(_, [th])] => th) |
239 end; |
243 end; |
240 |
244 |
241 val atts = map Attrib.internal |
245 val atts = map Attrib.internal |
242 [RuleCases.consumes (~ (length obtains)), RuleCases.case_names case_names]; |
246 [RuleCases.consumes (~ (length obtains)), RuleCases.case_names case_names]; |
|
247 val prems = subtract_prems loc_ctxt elems_ctxt; |
243 val stmt = [(("", atts), [(thesis, [])])]; |
248 val stmt = [(("", atts), [(thesis, [])])]; |
244 |
249 |
245 val (facts, goal_ctxt) = elems_ctxt |
250 val (facts, goal_ctxt) = elems_ctxt |
246 |> (snd o ProofContext.add_fixes_i [(AutoBind.thesisN, NONE, NoSyn)]) |
251 |> (snd o ProofContext.add_fixes_i [(AutoBind.thesisN, NONE, NoSyn)]) |
247 |> fold_map assume_case (obtains ~~ propp) |
252 |> fold_map assume_case (obtains ~~ propp) |
248 |-> (fn ths => ProofContext.note_thmss_i Thm.assumptionK |
253 |-> (fn ths => ProofContext.note_thmss_i Thm.assumptionK |
249 [((Obtain.thatN, []), [(ths, [])])] #> #2 #> pair ths); |
254 [((Obtain.thatN, []), [(ths, [])])] #> #2 #> pair ths); |
250 in ((stmt, facts), goal_ctxt) end); |
255 in ((prems, stmt, facts), goal_ctxt) end); |
251 |
256 |
252 fun gen_theorem prep_att prep_stmt |
257 fun gen_theorem prep_att prep_stmt |
253 kind before_qed after_qed (name, raw_atts) raw_elems raw_concl lthy0 = |
258 kind before_qed after_qed (name, raw_atts) raw_elems raw_concl lthy0 = |
254 let |
259 let |
255 val _ = LocalTheory.assert lthy0; |
260 val _ = LocalTheory.assert lthy0; |
264 val attrib = prep_att thy; |
269 val attrib = prep_att thy; |
265 val atts = map attrib raw_atts; |
270 val atts = map attrib raw_atts; |
266 |
271 |
267 val elems = raw_elems |> (map o Locale.map_elem) |
272 val elems = raw_elems |> (map o Locale.map_elem) |
268 (Element.map_ctxt {name = I, var = I, typ = I, term = I, fact = I, attrib = attrib}); |
273 (Element.map_ctxt {name = I, var = I, typ = I, term = I, fact = I, attrib = attrib}); |
269 val ((stmt, facts), goal_ctxt) = prep_statement attrib (prep_stmt loc) elems raw_concl ctxt; |
274 val ((prems, stmt, facts), goal_ctxt) = |
|
275 prep_statement attrib (prep_stmt loc) elems raw_concl ctxt; |
270 |
276 |
271 fun after_qed' results goal_ctxt' = |
277 fun after_qed' results goal_ctxt' = |
272 let val results' = burrow (ProofContext.export_standard goal_ctxt' lthy) results in |
278 let val results' = burrow (ProofContext.export_standard goal_ctxt' lthy) results in |
273 lthy |
279 lthy |
274 |> LocalTheory.notes kind (map2 (fn (a, _) => fn ths => (a, [(ths, [])])) stmt results') |
280 |> LocalTheory.notes kind (map2 (fn (a, _) => fn ths => (a, [(ths, [])])) stmt results') |
278 else #2 (LocalTheory.notes kind [((name, atts), [(maps #2 res, [])])] lthy'))) |
284 else #2 (LocalTheory.notes kind [((name, atts), [(maps #2 res, [])])] lthy'))) |
279 |> after_qed results' |
285 |> after_qed results' |
280 end; |
286 end; |
281 in |
287 in |
282 goal_ctxt |
288 goal_ctxt |
|
289 |> ProofContext.note_thmss_i Thm.assumptionK [((AutoBind.assmsN, []), [(prems, [])])] |
|
290 |> snd |
283 |> Proof.theorem_i before_qed after_qed' (map snd stmt) |
291 |> Proof.theorem_i before_qed after_qed' (map snd stmt) |
284 |> Proof.refine_insert facts |
292 |> Proof.refine_insert facts |
285 end; |
293 end; |
286 |
294 |
287 in |
295 in |