src/HOL/BNF/Tools/bnf_gfp_rec_sugar.ML
changeset 54842 a020f7d74fed
parent 54835 431133d07192
child 54844 630ba4d8a206
equal deleted inserted replaced
54841:af71b753c459 54842:a020f7d74fed
    33 
    33 
    34 val codeN = "code"
    34 val codeN = "code"
    35 val ctrN = "ctr"
    35 val ctrN = "ctr"
    36 val discN = "disc"
    36 val discN = "disc"
    37 val excludeN = "exclude"
    37 val excludeN = "exclude"
       
    38 val nchotomyN = "nchotomy"
    38 val selN = "sel"
    39 val selN = "sel"
    39 
    40 
    40 val nitpicksimp_attrs = @{attributes [nitpick_simp]};
    41 val nitpicksimp_attrs = @{attributes [nitpick_simp]};
    41 val simp_attrs = @{attributes [simp]};
    42 val simp_attrs = @{attributes [simp]};
    42 val code_nitpicksimp_attrs = Code.add_default_eqn_attrib :: nitpicksimp_attrs;
    43 val code_nitpicksimp_attrs = Code.add_default_eqn_attrib :: nitpicksimp_attrs;
   915     val taut_thmss = map (map (apsnd (the o fst)) o filter (is_some o fst o snd)) excludess'';
   916     val taut_thmss = map (map (apsnd (the o fst)) o filter (is_some o fst o snd)) excludess'';
   916     val (goal_idxss, goalss') = excludess''
   917     val (goal_idxss, goalss') = excludess''
   917       |> map (map (apsnd (rpair [] o snd)) o filter (is_none o fst o snd))
   918       |> map (map (apsnd (rpair [] o snd)) o filter (is_none o fst o snd))
   918       |> split_list o map split_list;
   919       |> split_list o map split_list;
   919 
   920 
   920     val exhaust_props = if not exhaustive then [] else
   921     val nchotomy_props = if not exhaustive then [] else
   921       map (HOLogic.mk_Trueprop o mk_disjs o map (mk_conjs o #prems)) disc_eqnss
   922       map (HOLogic.mk_Trueprop o mk_disjs o map (mk_conjs o #prems)) disc_eqnss
   922       |> map2 ((fn {fun_args, ...} =>
   923       |> map2 ((fn {fun_args, ...} =>
   923         curry Logic.list_all (map dest_Free fun_args)) o hd) disc_eqnss;
   924         curry Logic.list_all (map dest_Free fun_args)) o hd) disc_eqnss;
   924     val exhaust_taut_thms = if exhaustive andalso is_some maybe_tac then
   925     val nchotomy_taut_thms = if exhaustive andalso is_some maybe_tac then
   925         map (fn t => Goal.prove lthy [] [] t (the maybe_tac) |> Thm.close_derivation) exhaust_props
   926         map (fn t => Goal.prove lthy [] [] t (the maybe_tac) |> Thm.close_derivation) nchotomy_props
   926       else [];
   927       else [];
   927     val goalss = if exhaustive andalso is_none maybe_tac then
   928     val goalss = if exhaustive andalso is_none maybe_tac then
   928       map (rpair []) exhaust_props :: goalss' else goalss';
   929       map (rpair []) nchotomy_props :: goalss' else goalss';
   929 
   930 
   930     fun prove thmss'' def_thms' lthy =
   931     fun prove thmss'' def_thms' lthy =
   931       let
   932       let
   932         val def_thms = map (snd o snd) def_thms';
   933         val def_thms = map (snd o snd) def_thms';
   933 
   934 
   934         val maybe_exhaust_thms = if not exhaustive then map (K NONE) def_thms else
   935         val maybe_nchotomy_thms = if not exhaustive then map (K NONE) def_thms else
   935           map SOME (if is_none maybe_tac then hd thmss'' else exhaust_taut_thms);
   936           map SOME (if is_none maybe_tac then hd thmss'' else nchotomy_taut_thms);
   936         val exclude_thmss = if exhaustive andalso is_none maybe_tac then tl thmss'' else thmss'';
   937         val exclude_thmss = if exhaustive andalso is_none maybe_tac then tl thmss'' else thmss'';
   937 
   938 
   938         val excludess' = map (op ~~) (goal_idxss ~~ exclude_thmss);
   939         val excludess' = map (op ~~) (goal_idxss ~~ exclude_thmss);
   939         fun mk_excludesss excludes n =
   940         fun mk_excludesss excludes n =
   940           (excludes, map (fn k => replicate k [TrueI] @ replicate (n - k) []) (0 upto n - 1))
   941           (excludes, map (fn k => replicate k [TrueI] @ replicate (n - k) []) (0 upto n - 1))
  1032                 |> Thm.close_derivation
  1033                 |> Thm.close_derivation
  1033                 |> pair ctr
  1034                 |> pair ctr
  1034                 |> single
  1035                 |> single
  1035             end;
  1036             end;
  1036 
  1037 
  1037         fun prove_code disc_eqns sel_eqns maybe_exhaust ctr_alist ctr_specs =
  1038         fun prove_code disc_eqns sel_eqns maybe_nchotomy ctr_alist ctr_specs =
  1038           let
  1039           let
  1039             val maybe_fun_data =
  1040             val maybe_fun_data =
  1040               (find_first (member (op =) (map #ctr ctr_specs) o #ctr) disc_eqns,
  1041               (find_first (member (op =) (map #ctr ctr_specs) o #ctr) disc_eqns,
  1041                find_first (member (op =) (map #ctr ctr_specs) o #ctr) sel_eqns)
  1042                find_first (member (op =) (map #ctr ctr_specs) o #ctr) sel_eqns)
  1042               |>> Option.map (fn x => (#fun_name x, #fun_T x, #fun_args x, #maybe_code_rhs x))
  1043               |>> Option.map (fn x => (#fun_name x, #fun_T x, #fun_args x, #maybe_code_rhs x))
  1108                         #> curry Logic.list_all (map dest_Free fun_args));
  1109                         #> curry Logic.list_all (map dest_Free fun_args));
  1109                     val (distincts, discIs, sel_splits, sel_split_asms) =
  1110                     val (distincts, discIs, sel_splits, sel_split_asms) =
  1110                       case_thms_of_term lthy bound_Ts raw_rhs;
  1111                       case_thms_of_term lthy bound_Ts raw_rhs;
  1111 
  1112 
  1112                     val raw_code_thm = mk_primcorec_raw_code_of_ctr_tac lthy distincts discIs
  1113                     val raw_code_thm = mk_primcorec_raw_code_of_ctr_tac lthy distincts discIs
  1113                         sel_splits sel_split_asms ms ctr_thms maybe_exhaust
  1114                         sel_splits sel_split_asms ms ctr_thms maybe_nchotomy
  1114                       |> K |> Goal.prove lthy [] [] raw_t
  1115                       |> K |> Goal.prove lthy [] [] raw_t
  1115                       |> Thm.close_derivation;
  1116                       |> Thm.close_derivation;
  1116                   in
  1117                   in
  1117                     mk_primcorec_code_of_raw_code_tac lthy distincts sel_splits raw_code_thm
  1118                     mk_primcorec_code_of_raw_code_tac lthy distincts sel_splits raw_code_thm
  1118                     |> K |> Goal.prove lthy [] [] t
  1119                     |> K |> Goal.prove lthy [] [] t
  1129 
  1130 
  1130         val ctr_alists = map5 (maps oooo prove_ctr) disc_alists sel_alists disc_eqnss sel_eqnss
  1131         val ctr_alists = map5 (maps oooo prove_ctr) disc_alists sel_alists disc_eqnss sel_eqnss
  1131           ctr_specss;
  1132           ctr_specss;
  1132         val ctr_thmss = map (map snd) ctr_alists;
  1133         val ctr_thmss = map (map snd) ctr_alists;
  1133 
  1134 
  1134         val code_thmss = map5 prove_code disc_eqnss sel_eqnss maybe_exhaust_thms ctr_alists
  1135         val code_thmss = map5 prove_code disc_eqnss sel_eqnss maybe_nchotomy_thms ctr_alists
  1135           ctr_specss;
  1136           ctr_specss;
  1136 
  1137 
  1137         val simp_thmss = map2 append disc_thmss sel_thmss
  1138         val simp_thmss = map2 append disc_thmss sel_thmss
  1138 
  1139 
  1139         val common_name = mk_common_name fun_names;
  1140         val common_name = mk_common_name fun_names;
  1142           [(coinductN, map (if n2m then single else K []) coinduct_thms, []),
  1143           [(coinductN, map (if n2m then single else K []) coinduct_thms, []),
  1143            (codeN, code_thmss, code_nitpicksimp_attrs),
  1144            (codeN, code_thmss, code_nitpicksimp_attrs),
  1144            (ctrN, ctr_thmss, []),
  1145            (ctrN, ctr_thmss, []),
  1145            (discN, disc_thmss, simp_attrs),
  1146            (discN, disc_thmss, simp_attrs),
  1146            (excludeN, exclude_thmss, []),
  1147            (excludeN, exclude_thmss, []),
  1147            (exhaustN, map the_list maybe_exhaust_thms, []),
  1148            (nchotomyN, map the_list maybe_nchotomy_thms, []),
  1148            (selN, sel_thmss, simp_attrs),
  1149            (selN, sel_thmss, simp_attrs),
  1149            (simpsN, simp_thmss, []),
  1150            (simpsN, simp_thmss, []),
  1150            (strong_coinductN, map (if n2m then single else K []) strong_coinduct_thms, [])]
  1151            (strong_coinductN, map (if n2m then single else K []) strong_coinduct_thms, [])]
  1151           |> maps (fn (thmN, thmss, attrs) =>
  1152           |> maps (fn (thmN, thmss, attrs) =>
  1152             map2 (fn fun_name => fn thms =>
  1153             map2 (fn fun_name => fn thms =>