195 val yctrs = map2 (curry Term.list_comb) ctrs yss; |
195 val yctrs = map2 (curry Term.list_comb) ctrs yss; |
196 |
196 |
197 val xfs = map2 (curry Term.list_comb) fs xss; |
197 val xfs = map2 (curry Term.list_comb) fs xss; |
198 val xgs = map2 (curry Term.list_comb) gs xss; |
198 val xgs = map2 (curry Term.list_comb) gs xss; |
199 |
199 |
|
200 val fcase = Term.list_comb (casex, fs); |
|
201 val gcase = Term.list_comb (casex, gs); |
|
202 |
|
203 val ufcase = fcase $ u; |
|
204 val vfcase = fcase $ v; |
|
205 |
|
206 (* TODO: Eta-expension is for compatibility with the old datatype package (but it also provides |
|
207 nicer names). Consider removing. *) |
200 val eta_fs = map2 eta_expand_arg xss xfs; |
208 val eta_fs = map2 eta_expand_arg xss xfs; |
201 val eta_gs = map2 eta_expand_arg xss xgs; |
209 val eta_gs = map2 eta_expand_arg xss xgs; |
202 |
210 |
203 val fcase = Term.list_comb (casex, eta_fs); |
211 val eta_fcase = Term.list_comb (casex, eta_fs); |
204 val gcase = Term.list_comb (casex, eta_gs); |
212 val eta_gcase = Term.list_comb (casex, eta_gs); |
205 |
213 |
206 val ufcase = fcase $ u; |
214 val eta_ufcase = eta_fcase $ u; |
207 val vfcase = fcase $ v; |
215 val eta_vfcase = eta_fcase $ v; |
208 val vgcase = gcase $ v; |
216 val eta_vgcase = eta_gcase $ v; |
209 |
217 |
210 fun mk_uu_eq () = HOLogic.mk_eq (u, u); |
218 fun mk_uu_eq () = HOLogic.mk_eq (u, u); |
211 |
219 |
212 val uv_eq = mk_Trueprop_eq (u, v); |
220 val uv_eq = mk_Trueprop_eq (u, v); |
213 |
221 |
344 map (map mk_goal) (mk_half_pairss (`I (xss ~~ xctrs))) |
352 map (map mk_goal) (mk_half_pairss (`I (xss ~~ xctrs))) |
345 end; |
353 end; |
346 |
354 |
347 val cases_goal = |
355 val cases_goal = |
348 map3 (fn xs => fn xctr => fn xf => |
356 map3 (fn xs => fn xctr => fn xf => |
349 fold_rev Logic.all (fs @ xs) (mk_Trueprop_eq (fcase $ xctr, xf))) xss xctrs xfs; |
357 fold_rev Logic.all (fs @ xs) (mk_Trueprop_eq (eta_fcase $ xctr, xf))) xss xctrs xfs; |
350 |
358 |
351 val goalss = [exhaust_goal] :: inject_goalss @ half_distinct_goalss @ [cases_goal]; |
359 val goalss = [exhaust_goal] :: inject_goalss @ half_distinct_goalss @ [cases_goal]; |
352 |
360 |
353 fun after_qed thmss lthy = |
361 fun after_qed thmss lthy = |
354 let |
362 let |
546 end; |
554 end; |
547 |
555 |
548 val case_conv_thms = |
556 val case_conv_thms = |
549 let |
557 let |
550 fun mk_body f usels = Term.list_comb (f, usels); |
558 fun mk_body f usels = Term.list_comb (f, usels); |
551 val goal = mk_Trueprop_eq (ufcase, mk_IfN B udiscs (map2 mk_body fs uselss)); |
559 val goal = mk_Trueprop_eq (eta_ufcase, mk_IfN B udiscs (map2 mk_body fs uselss)); |
552 in |
560 in |
553 [Goal.prove_sorry lthy [] [] goal (fn {context = ctxt, ...} => |
561 [Goal.prove_sorry lthy [] [] goal (fn {context = ctxt, ...} => |
554 mk_case_conv_tac ctxt n uexhaust_thm case_thms disc_thmss' sel_thmss)] |
562 mk_case_conv_tac ctxt n uexhaust_thm case_thms disc_thmss' sel_thmss)] |
555 |> map Thm.close_derivation |
563 |> map Thm.close_derivation |
556 |> Proof_Context.export names_lthy lthy |
564 |> Proof_Context.export names_lthy lthy |
566 fold_rev Logic.all xs (Logic.mk_implies (mk_Trueprop_eq (v, xctr), |
574 fold_rev Logic.all xs (Logic.mk_implies (mk_Trueprop_eq (v, xctr), |
567 mk_Trueprop_eq (f, g))); |
575 mk_Trueprop_eq (f, g))); |
568 |
576 |
569 val goal = |
577 val goal = |
570 Logic.list_implies (uv_eq :: map4 mk_prem xctrs xss fs gs, |
578 Logic.list_implies (uv_eq :: map4 mk_prem xctrs xss fs gs, |
571 mk_Trueprop_eq (ufcase, vgcase)); |
579 mk_Trueprop_eq (eta_ufcase, eta_vgcase)); |
572 val weak_goal = Logic.mk_implies (uv_eq, mk_Trueprop_eq (ufcase, vfcase)); |
580 val weak_goal = Logic.mk_implies (uv_eq, mk_Trueprop_eq (ufcase, vfcase)); |
573 in |
581 in |
574 (Goal.prove_sorry lthy [] [] goal (fn _ => mk_case_cong_tac lthy uexhaust_thm case_thms), |
582 (Goal.prove_sorry lthy [] [] goal (fn _ => mk_case_cong_tac lthy uexhaust_thm case_thms), |
575 Goal.prove_sorry lthy [] [] weak_goal (K (etac arg_cong 1))) |
583 Goal.prove_sorry lthy [] [] weak_goal (K (etac arg_cong 1))) |
576 |> pairself (Thm.close_derivation #> singleton (Proof_Context.export names_lthy lthy)) |
584 |> pairself (Thm.close_derivation #> singleton (Proof_Context.export names_lthy lthy)) |
582 list_all_free xs (HOLogic.mk_imp (HOLogic.mk_eq (u, xctr), q $ f_xs)); |
590 list_all_free xs (HOLogic.mk_imp (HOLogic.mk_eq (u, xctr), q $ f_xs)); |
583 fun mk_disjunct xctr xs f_xs = |
591 fun mk_disjunct xctr xs f_xs = |
584 list_exists_free xs (HOLogic.mk_conj (HOLogic.mk_eq (u, xctr), |
592 list_exists_free xs (HOLogic.mk_conj (HOLogic.mk_eq (u, xctr), |
585 HOLogic.mk_not (q $ f_xs))); |
593 HOLogic.mk_not (q $ f_xs))); |
586 |
594 |
587 val lhs = q $ ufcase; |
595 val lhs = q $ eta_ufcase; |
588 |
596 |
589 val goal = |
597 val goal = |
590 mk_Trueprop_eq (lhs, Library.foldr1 HOLogic.mk_conj (map3 mk_conjunct xctrs xss xfs)); |
598 mk_Trueprop_eq (lhs, Library.foldr1 HOLogic.mk_conj (map3 mk_conjunct xctrs xss xfs)); |
591 val asm_goal = |
599 val asm_goal = |
592 mk_Trueprop_eq (lhs, HOLogic.mk_not (Library.foldr1 HOLogic.mk_disj |
600 mk_Trueprop_eq (lhs, HOLogic.mk_not (Library.foldr1 HOLogic.mk_disj |