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 |