src/HOL/BNF/Tools/bnf_gfp_rec_sugar.ML
changeset 54613 985f8b49c050
parent 54591 c822230fd22b
child 54628 ce80d7cd7277
equal deleted inserted replaced
54612:7e291ae244ea 54613:985f8b49c050
   902 *)
   902 *)
   903 
   903 
   904     val exclss'' = exclss' |> map (map (fn (idx, t) =>
   904     val exclss'' = exclss' |> map (map (fn (idx, t) =>
   905       (idx, (Option.map (Goal.prove lthy [] [] t #> Thm.close_derivation) (excl_tac idx), t))));
   905       (idx, (Option.map (Goal.prove lthy [] [] t #> Thm.close_derivation) (excl_tac idx), t))));
   906     val taut_thmss = map (map (apsnd (the o fst)) o filter (is_some o fst o snd)) exclss'';
   906     val taut_thmss = map (map (apsnd (the o fst)) o filter (is_some o fst o snd)) exclss'';
   907     val (goal_idxss, goalss) = exclss''
   907     val (goal_idxss, goalss') = exclss''
   908       |> map (map (apsnd (rpair [] o snd)) o filter (is_none o fst o snd))
   908       |> map (map (apsnd (rpair [] o snd)) o filter (is_none o fst o snd))
   909       |> split_list o map split_list;
   909       |> split_list o map split_list;
   910 
   910 
   911     val exhaustive_props = map (mk_disjs o map (mk_conjs o #prems)) disc_eqnss;
   911     val exh_props = if not exhaustive then [] else
   912 
   912       map (HOLogic.mk_Trueprop o mk_disjs o map (mk_conjs o #prems)) disc_eqnss
   913     fun prove thmss' def_thms' lthy =
   913       |> map2 ((fn {fun_args, ...} =>
       
   914         curry Logic.list_all (map dest_Free fun_args)) o hd) disc_eqnss;
       
   915     val exh_taut_thms = if exhaustive andalso is_some maybe_tac then
       
   916         map (fn t => Goal.prove lthy [] [] t (the maybe_tac) |> Thm.close_derivation) exh_props
       
   917       else [];
       
   918     val goalss = if exhaustive andalso is_none maybe_tac then
       
   919       map (rpair []) exh_props :: goalss' else goalss';
       
   920 
       
   921     fun prove thmss'' def_thms' lthy =
   914       let
   922       let
   915         val def_thms = map (snd o snd) def_thms';
   923         val def_thms = map (snd o snd) def_thms';
       
   924 
       
   925         val maybe_exh_thms = if exhaustive andalso is_none maybe_tac then
       
   926           map SOME (hd thmss'') else map (K NONE) def_thms;
       
   927         val thmss' = if exhaustive andalso is_none maybe_tac then tl thmss'' else thmss'';
   916 
   928 
   917         val exclss' = map (op ~~) (goal_idxss ~~ thmss');
   929         val exclss' = map (op ~~) (goal_idxss ~~ thmss');
   918         fun mk_exclsss excls n =
   930         fun mk_exclsss excls n =
   919           (excls, map (fn k => replicate k [TrueI] @ replicate (n - k) []) (0 upto n - 1))
   931           (excls, map (fn k => replicate k [TrueI] @ replicate (n - k) []) (0 upto n - 1))
   920           |-> fold (fn ((c, c', _), thm) => nth_map c (nth_map c' (K [thm])));
   932           |-> fold (fn ((c, c', _), thm) => nth_map c (nth_map c' (K [thm])));
  1010                 |> Thm.close_derivation
  1022                 |> Thm.close_derivation
  1011                 |> pair ctr
  1023                 |> pair ctr
  1012                 |> single
  1024                 |> single
  1013             end;
  1025             end;
  1014 
  1026 
  1015         fun prove_code disc_eqns sel_eqns ctr_alist ctr_specs =
  1027         fun prove_code disc_eqns sel_eqns maybe_exh ctr_alist ctr_specs =
  1016           let
  1028           let
  1017             val fun_data =
  1029             val fun_data =
  1018               (find_first (member (op =) (map #ctr ctr_specs) o #ctr) disc_eqns,
  1030               (find_first (member (op =) (map #ctr ctr_specs) o #ctr) disc_eqns,
  1019                find_first (member (op =) (map #ctr ctr_specs) o #ctr) sel_eqns)
  1031                find_first (member (op =) (map #ctr ctr_specs) o #ctr) sel_eqns)
  1020               |>> Option.map (fn x => (#fun_name x, #fun_T x, #fun_args x, #maybe_code_rhs x))
  1032               |>> Option.map (fn x => (#fun_name x, #fun_T x, #fun_args x, #maybe_code_rhs x))
  1055                           end;
  1067                           end;
  1056                       val maybe_ctr_conds_argss = map prove_code_ctr ctr_specs;
  1068                       val maybe_ctr_conds_argss = map prove_code_ctr ctr_specs;
  1057                     in
  1069                     in
  1058                       if exists is_none maybe_ctr_conds_argss then NONE else
  1070                       if exists is_none maybe_ctr_conds_argss then NONE else
  1059                         let
  1071                         let
  1060                           val rhs = fold_rev (fn SOME (prems, u) => fn t => mk_If (s_conjs prems) u t)
  1072                           val rhs = (if exhaustive then
  1061                             maybe_ctr_conds_argss
  1073                               split_last maybe_ctr_conds_argss ||> snd o the
  1062                             (Const (@{const_name Code.abort}, @{typ String.literal} -->
  1074                             else
  1063                                 (@{typ unit} --> body_type fun_T) --> body_type fun_T) $
  1075                               Const (@{const_name Code.abort}, @{typ String.literal} -->
  1064                               HOLogic.mk_literal fun_name $
  1076                                   (@{typ unit} --> body_type fun_T) --> body_type fun_T) $
  1065                               absdummy @{typ unit} (incr_boundvars 1 lhs));
  1077                                 HOLogic.mk_literal fun_name $
       
  1078                                 absdummy @{typ unit} (incr_boundvars 1 lhs)
       
  1079                               |> pair maybe_ctr_conds_argss)
       
  1080                             |-> fold_rev (fn SOME (prems, u) => fn t => mk_If (s_conjs prems) u t)
  1066                         in SOME (rhs, rhs, map snd ctr_alist) end
  1081                         in SOME (rhs, rhs, map snd ctr_alist) end
  1067                     end);
  1082                     end);
  1068               in
  1083               in
  1069                 (case maybe_rhs_info of
  1084                 (case maybe_rhs_info of
  1070                   NONE => []
  1085                   NONE => []
  1078                         #> HOLogic.mk_Trueprop
  1093                         #> HOLogic.mk_Trueprop
  1079                         #> curry Logic.list_all (map dest_Free fun_args));
  1094                         #> curry Logic.list_all (map dest_Free fun_args));
  1080                     val (distincts, discIs, sel_splits, sel_split_asms) =
  1095                     val (distincts, discIs, sel_splits, sel_split_asms) =
  1081                       case_thms_of_term lthy bound_Ts raw_rhs;
  1096                       case_thms_of_term lthy bound_Ts raw_rhs;
  1082 
  1097 
  1083                     val raw_code_thm = mk_primcorec_raw_code_of_ctr_tac lthy distincts discIs sel_splits
  1098                     val raw_code_thm = mk_primcorec_raw_code_of_ctr_tac lthy distincts discIs
  1084                         sel_split_asms ms ctr_thms
  1099                         sel_splits sel_split_asms ms ctr_thms maybe_exh
  1085                       |> K |> Goal.prove lthy [] [] raw_t
  1100                       |> K |> Goal.prove lthy [] [] raw_t
  1086                       |> Thm.close_derivation;
  1101                       |> Thm.close_derivation;
  1087                   in
  1102                   in
  1088                     mk_primcorec_code_of_raw_code_tac lthy distincts sel_splits raw_code_thm
  1103                     mk_primcorec_code_of_raw_code_tac lthy distincts sel_splits raw_code_thm
  1089                     |> K |> Goal.prove lthy [] [] t
  1104                     |> K |> Goal.prove lthy [] [] t
  1100 
  1115 
  1101         val ctr_alists = map5 (maps oooo prove_ctr) disc_alists sel_alists disc_eqnss sel_eqnss
  1116         val ctr_alists = map5 (maps oooo prove_ctr) disc_alists sel_alists disc_eqnss sel_eqnss
  1102           ctr_specss;
  1117           ctr_specss;
  1103         val ctr_thmss = map (map snd) ctr_alists;
  1118         val ctr_thmss = map (map snd) ctr_alists;
  1104 
  1119 
  1105         val code_thmss = map4 prove_code disc_eqnss sel_eqnss ctr_alists ctr_specss;
  1120         val code_thmss = map5 prove_code disc_eqnss sel_eqnss maybe_exh_thms ctr_alists ctr_specss;
  1106 
  1121 
  1107         val simp_thmss = map2 append disc_thmss sel_thmss
  1122         val simp_thmss = map2 append disc_thmss sel_thmss
  1108 
  1123 
  1109         val common_name = mk_common_name fun_names;
  1124         val common_name = mk_common_name fun_names;
  1110 
  1125