src/HOL/Codatatype/Tools/bnf_wrap.ML
changeset 49458 9321a9465021
parent 49438 5bc80d96241e
child 49463 83ac281bcdc2
equal deleted inserted replaced
49457:1d2825673cec 49458:9321a9465021
   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;