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 => |