290 (all_sels_distinct, discs, selss, disc_defs, sel_defs, sel_defss, lthy') |
290 (all_sels_distinct, discs, selss, disc_defs, sel_defs, sel_defss, lthy') |
291 end; |
291 end; |
292 |
292 |
293 fun mk_imp_p Qs = Logic.list_implies (Qs, HOLogic.mk_Trueprop p); |
293 fun mk_imp_p Qs = Logic.list_implies (Qs, HOLogic.mk_Trueprop p); |
294 |
294 |
295 val goal_exhaust = |
295 val exhaust_goal = |
296 let fun mk_prem xctr xs = fold_rev Logic.all xs (mk_imp_p [mk_Trueprop_eq (v, xctr)]) in |
296 let fun mk_prem xctr xs = fold_rev Logic.all xs (mk_imp_p [mk_Trueprop_eq (v, xctr)]) in |
297 fold_rev Logic.all [p, v] (mk_imp_p (map2 mk_prem xctrs xss)) |
297 fold_rev Logic.all [p, v] (mk_imp_p (map2 mk_prem xctrs xss)) |
298 end; |
298 end; |
299 |
299 |
300 val goal_injectss = |
300 val injectss_goal = |
301 let |
301 let |
302 fun mk_goal _ _ [] [] = [] |
302 fun mk_goal _ _ [] [] = [] |
303 | mk_goal xctr yctr xs ys = |
303 | mk_goal xctr yctr xs ys = |
304 [fold_rev Logic.all (xs @ ys) (mk_Trueprop_eq (HOLogic.mk_eq (xctr, yctr), |
304 [fold_rev Logic.all (xs @ ys) (mk_Trueprop_eq (HOLogic.mk_eq (xctr, yctr), |
305 Library.foldr1 HOLogic.mk_conj (map2 (curry HOLogic.mk_eq) xs ys)))]; |
305 Library.foldr1 HOLogic.mk_conj (map2 (curry HOLogic.mk_eq) xs ys)))]; |
306 in |
306 in |
307 map4 mk_goal xctrs yctrs xss yss |
307 map4 mk_goal xctrs yctrs xss yss |
308 end; |
308 end; |
309 |
309 |
310 val goal_half_distinctss = |
310 val half_distinctss_goal = |
311 let |
311 let |
312 fun mk_goal ((xs, xc), (xs', xc')) = |
312 fun mk_goal ((xs, xc), (xs', xc')) = |
313 fold_rev Logic.all (xs @ xs') |
313 fold_rev Logic.all (xs @ xs') |
314 (HOLogic.mk_Trueprop (HOLogic.mk_not (HOLogic.mk_eq (xc, xc')))); |
314 (HOLogic.mk_Trueprop (HOLogic.mk_not (HOLogic.mk_eq (xc, xc')))); |
315 in |
315 in |
316 map (map mk_goal) (mk_half_pairss (xss ~~ xctrs)) |
316 map (map mk_goal) (mk_half_pairss (xss ~~ xctrs)) |
317 end; |
317 end; |
318 |
318 |
319 val goal_cases = |
319 val cases_goal = |
320 map3 (fn xs => fn xctr => fn xf => |
320 map3 (fn xs => fn xctr => fn xf => |
321 fold_rev Logic.all (fs @ xs) (mk_Trueprop_eq (fcase $ xctr, xf))) xss xctrs xfs; |
321 fold_rev Logic.all (fs @ xs) (mk_Trueprop_eq (fcase $ xctr, xf))) xss xctrs xfs; |
322 |
322 |
323 val goalss = [goal_exhaust] :: goal_injectss @ goal_half_distinctss @ [goal_cases]; |
323 val goalss = [exhaust_goal] :: injectss_goal @ half_distinctss_goal @ [cases_goal]; |
324 |
324 |
325 fun after_qed thmss lthy = |
325 fun after_qed thmss lthy = |
326 let |
326 let |
327 val ([exhaust_thm], (inject_thmss, (half_distinct_thmss, [case_thms]))) = |
327 val ([exhaust_thm], (inject_thmss, (half_distinct_thmss, [case_thms]))) = |
328 (hd thmss, apsnd (chop (n * n)) (chop n (tl thmss))); |
328 (hd thmss, apsnd (chop (n * n)) (chop n (tl thmss))); |
444 fun prove tac goal = Skip_Proof.prove lthy [] [] goal (K tac); |
444 fun prove tac goal = Skip_Proof.prove lthy [] [] goal (K tac); |
445 |
445 |
446 val infos = ms ~~ discD_thms ~~ discs ~~ no_discs; |
446 val infos = ms ~~ discD_thms ~~ discs ~~ no_discs; |
447 val half_pairss = mk_half_pairss infos; |
447 val half_pairss = mk_half_pairss infos; |
448 |
448 |
449 val goal_halvess = map mk_goal half_pairss; |
449 val halvess_goal = map mk_goal half_pairss; |
450 val half_thmss = |
450 val half_thmss = |
451 map3 (fn [] => K (K []) | [goal] => fn [((((m, discD), _), _), _)] => |
451 map3 (fn [] => K (K []) | [goal] => fn [((((m, discD), _), _), _)] => |
452 fn disc_thm => [prove (mk_half_disc_exclude_tac m discD disc_thm) goal]) |
452 fn disc_thm => [prove (mk_half_disc_exclude_tac m discD disc_thm) goal]) |
453 goal_halvess half_pairss (flat disc_thmss'); |
453 halvess_goal half_pairss (flat disc_thmss'); |
454 |
454 |
455 val goal_other_halvess = map (mk_goal o map swap) half_pairss; |
455 val other_halvess_goal = map (mk_goal o map swap) half_pairss; |
456 val other_half_thmss = |
456 val other_half_thmss = |
457 map2 (map2 (prove o mk_other_half_disc_exclude_tac)) half_thmss |
457 map2 (map2 (prove o mk_other_half_disc_exclude_tac)) half_thmss |
458 goal_other_halvess; |
458 other_halvess_goal; |
459 in |
459 in |
460 interleave (flat half_thmss) (flat other_half_thmss) |
460 interleave (flat half_thmss) (flat other_half_thmss) |
461 end; |
461 end; |
462 |
462 |
463 val disc_exhaust_thms = |
463 val disc_exhaust_thms = |
523 val v_eq_w = mk_Trueprop_eq (v, w); |
523 val v_eq_w = mk_Trueprop_eq (v, w); |
524 |
524 |
525 val goal = |
525 val goal = |
526 Logic.list_implies (v_eq_w :: map4 mk_prem xctrs xss fs gs, |
526 Logic.list_implies (v_eq_w :: map4 mk_prem xctrs xss fs gs, |
527 mk_Trueprop_eq (fcase $ v, gcase $ w)); |
527 mk_Trueprop_eq (fcase $ v, gcase $ w)); |
528 val goal_weak = Logic.mk_implies (v_eq_w, mk_Trueprop_eq (fcase $ v, fcase $ w)); |
528 val weak_goal = Logic.mk_implies (v_eq_w, mk_Trueprop_eq (fcase $ v, fcase $ w)); |
529 in |
529 in |
530 (Skip_Proof.prove lthy [] [] goal (fn _ => mk_case_cong_tac exhaust_thm' case_thms), |
530 (Skip_Proof.prove lthy [] [] goal (fn _ => mk_case_cong_tac exhaust_thm' case_thms), |
531 Skip_Proof.prove lthy [] [] goal_weak (K (etac arg_cong 1))) |
531 Skip_Proof.prove lthy [] [] weak_goal (K (etac arg_cong 1))) |
532 |> pairself (singleton (Proof_Context.export names_lthy lthy)) |
532 |> pairself (singleton (Proof_Context.export names_lthy lthy)) |
533 end; |
533 end; |
534 |
534 |
535 val (split_thm, split_asm_thm) = |
535 val (split_thm, split_asm_thm) = |
536 let |
536 let |
542 |
542 |
543 val lhs = q $ (fcase $ v); |
543 val lhs = q $ (fcase $ v); |
544 |
544 |
545 val goal = |
545 val goal = |
546 mk_Trueprop_eq (lhs, Library.foldr1 HOLogic.mk_conj (map3 mk_conjunct xctrs xss xfs)); |
546 mk_Trueprop_eq (lhs, Library.foldr1 HOLogic.mk_conj (map3 mk_conjunct xctrs xss xfs)); |
547 val goal_asm = |
547 val asm_goal = |
548 mk_Trueprop_eq (lhs, HOLogic.mk_not (Library.foldr1 HOLogic.mk_disj |
548 mk_Trueprop_eq (lhs, HOLogic.mk_not (Library.foldr1 HOLogic.mk_disj |
549 (map3 mk_disjunct xctrs xss xfs))); |
549 (map3 mk_disjunct xctrs xss xfs))); |
550 |
550 |
551 val split_thm = |
551 val split_thm = |
552 Skip_Proof.prove lthy [] [] goal |
552 Skip_Proof.prove lthy [] [] goal |
553 (fn _ => mk_split_tac exhaust_thm' case_thms inject_thmss distinct_thmsss) |
553 (fn _ => mk_split_tac exhaust_thm' case_thms inject_thmss distinct_thmsss) |
554 |> singleton (Proof_Context.export names_lthy lthy) |
554 |> singleton (Proof_Context.export names_lthy lthy) |
555 val split_asm_thm = |
555 val split_asm_thm = |
556 Skip_Proof.prove lthy [] [] goal_asm (fn {context = ctxt, ...} => |
556 Skip_Proof.prove lthy [] [] asm_goal (fn {context = ctxt, ...} => |
557 mk_split_asm_tac ctxt split_thm) |
557 mk_split_asm_tac ctxt split_thm) |
558 |> singleton (Proof_Context.export names_lthy lthy) |
558 |> singleton (Proof_Context.export names_lthy lthy) |
559 in |
559 in |
560 (split_thm, split_asm_thm) |
560 (split_thm, split_asm_thm) |
561 end; |
561 end; |