291 (resolve_tac ctxt [@{thm refl}, split_trans, |
291 (resolve_tac ctxt [@{thm refl}, split_trans, |
292 Su.case_inl RS @{thm trans}, Su.case_inr RS @{thm trans}] 1)]); |
292 Su.case_inl RS @{thm trans}, Su.case_inr RS @{thm trans}] 1)]); |
293 |
293 |
294 val free_iffs = map Drule.export_without_context (con_defs RL [@{thm def_swap_iff}]); |
294 val free_iffs = map Drule.export_without_context (con_defs RL [@{thm def_swap_iff}]); |
295 |
295 |
296 val case_eqns = map prove_case_eqn (flat con_ty_lists ~~ case_args ~~ tl con_defs); |
296 val ([case_eqns], thy2) = thy1 |
|
297 |> Sign.add_path big_rec_base_name |
|
298 |> Global_Theory.add_thmss |
|
299 [((Binding.name "case_eqns", |
|
300 map prove_case_eqn (flat con_ty_lists ~~ case_args ~~ tl con_defs)), [])] |
|
301 ||> Sign.parent_path; |
|
302 |
297 |
303 |
298 (*** Prove the recursor theorems ***) |
304 (*** Prove the recursor theorems ***) |
299 |
305 |
300 val recursor_eqns = case try (Misc_Legacy.get_def thy1) recursor_base_name of |
306 val (recursor_eqns, thy3) = |
|
307 case try (Misc_Legacy.get_def thy2) recursor_base_name of |
301 NONE => (writeln " [ No recursion operator ]"; |
308 NONE => (writeln " [ No recursion operator ]"; |
302 []) |
309 ([], thy2)) |
303 | SOME recursor_def => |
310 | SOME recursor_def => |
304 let |
311 let |
305 (*Replace subterms rec`x (where rec is a Free var) by recursor_tm(x) *) |
312 (*Replace subterms rec`x (where rec is a Free var) by recursor_tm(x) *) |
306 fun subst_rec (Const(\<^const_name>\<open>apply\<close>,_) $ Free _ $ arg) = recursor_tm $ arg |
313 fun subst_rec (Const(\<^const_name>\<open>apply\<close>,_) $ Free _ $ arg) = recursor_tm $ arg |
307 | subst_rec tm = |
314 | subst_rec tm = |
314 constructor argument.*) |
321 constructor argument.*) |
315 fun mk_recursor_eqn (((_,T,_), name, args, _), recursor_case) = |
322 fun mk_recursor_eqn (((_,T,_), name, args, _), recursor_case) = |
316 FOLogic.mk_Trueprop |
323 FOLogic.mk_Trueprop |
317 (FOLogic.mk_eq |
324 (FOLogic.mk_eq |
318 (recursor_tm $ |
325 (recursor_tm $ |
319 (list_comb (Const (Sign.intern_const thy1 name,T), |
326 (list_comb (Const (Sign.intern_const thy2 name,T), |
320 args)), |
327 args)), |
321 subst_rec (Term.betapplys (recursor_case, args)))); |
328 subst_rec (Term.betapplys (recursor_case, args)))); |
322 |
329 |
323 val recursor_trans = recursor_def RS @{thm def_Vrecursor} RS @{thm trans}; |
330 val recursor_trans = recursor_def RS @{thm def_Vrecursor} RS @{thm trans}; |
324 |
331 |
325 fun prove_recursor_eqn arg = |
332 fun prove_recursor_eqn arg = |
326 Goal.prove_global thy1 [] [] |
333 Goal.prove_global thy2 [] [] |
327 (Ind_Syntax.traceIt "next recursor equation = " thy1 (mk_recursor_eqn arg)) |
334 (Ind_Syntax.traceIt "next recursor equation = " thy2 (mk_recursor_eqn arg)) |
328 (*Proves a single recursor equation.*) |
335 (*Proves a single recursor equation.*) |
329 (fn {context = ctxt, ...} => EVERY |
336 (fn {context = ctxt, ...} => EVERY |
330 [resolve_tac ctxt [recursor_trans] 1, |
337 [resolve_tac ctxt [recursor_trans] 1, |
331 simp_tac (put_simpset rank_ss ctxt addsimps case_eqns) 1, |
338 simp_tac (put_simpset rank_ss ctxt addsimps case_eqns) 1, |
332 IF_UNSOLVED (simp_tac (put_simpset rank_ss ctxt addsimps tl con_defs) 1)]); |
339 IF_UNSOLVED (simp_tac (put_simpset rank_ss ctxt addsimps tl con_defs) 1)]); |
333 in |
340 in |
334 map prove_recursor_eqn (flat con_ty_lists ~~ recursor_cases) |
341 thy2 |
|
342 |> Sign.add_path big_rec_base_name |
|
343 |> Global_Theory.add_thmss |
|
344 [((Binding.name "recursor_eqns", |
|
345 map prove_recursor_eqn (flat con_ty_lists ~~ recursor_cases)), [])] |
|
346 ||> Sign.parent_path |
|
347 |>> the_single |
335 end |
348 end |
336 |
349 |
337 val constructors = |
350 val constructors = |
338 map (head_of o #1 o Logic.dest_equals o Thm.prop_of) (tl con_defs); |
351 map (head_of o #1 o Logic.dest_equals o Thm.prop_of) (tl con_defs); |
339 |
352 |
373 (*associate with each constructor the datatype name and rewrites*) |
386 (*associate with each constructor the datatype name and rewrites*) |
374 val con_pairs = map (fn c => (#1 (dest_Const c), con_info)) constructors |
387 val con_pairs = map (fn c => (#1 (dest_Const c), con_info)) constructors |
375 |
388 |
376 in |
389 in |
377 (*Updating theory components: simprules and datatype info*) |
390 (*Updating theory components: simprules and datatype info*) |
378 (thy1 |> Sign.add_path big_rec_base_name |
391 (thy3 |> Sign.add_path big_rec_base_name |
379 |> Global_Theory.add_thmss |
392 |> Global_Theory.add_thmss |
380 [((Binding.name "case_eqns", case_eqns), []), |
393 [((Binding.name "simps", case_eqns @ recursor_eqns), [Simplifier.simp_add]), |
381 ((Binding.name "recursor_eqns", recursor_eqns), []), |
|
382 ((Binding.empty, intrs), [Cla.safe_intro NONE]), |
394 ((Binding.empty, intrs), [Cla.safe_intro NONE]), |
383 ((Binding.name "con_defs", con_defs), []), |
395 ((Binding.name "con_defs", con_defs), []), |
384 ((Binding.name "free_iffs", free_iffs), []), |
396 ((Binding.name "free_iffs", free_iffs), []), |
385 ((Binding.name "free_elims", free_SEs), [])] |
397 ((Binding.name "free_elims", free_SEs), [])] |> #2 |
386 |-> (fn simps1 :: simps2 :: _ => |
|
387 Global_Theory.add_thmss |
|
388 [((Binding.name "simps", simps1 @ simps2), [Simplifier.simp_add])]) |> #2 |
|
389 |> DatatypesData.map (Symtab.update (big_rec_name, dt_info)) |
398 |> DatatypesData.map (Symtab.update (big_rec_name, dt_info)) |
390 |> ConstructorsData.map (fold Symtab.update con_pairs) |
399 |> ConstructorsData.map (fold Symtab.update con_pairs) |
391 |> Sign.parent_path, |
400 |> Sign.parent_path, |
392 ind_result, |
401 ind_result, |
393 {con_defs = con_defs, |
402 {con_defs = con_defs, |