830 in |
830 in |
831 find rhs_term |
831 find rhs_term |
832 |> K |> nth_map sel_no |> AList.map_entry (op =) ctr |
832 |> K |> nth_map sel_no |> AList.map_entry (op =) ctr |
833 end; |
833 end; |
834 |
834 |
835 fun add_primcorec simple seq fixes specs of_specs lthy = |
835 fun add_primcorec_ursive maybe_tac seq fixes specs of_specs lthy = |
836 let |
836 let |
837 val (bs, mxs) = map_split (apfst fst) fixes; |
837 val (bs, mxs) = map_split (apfst fst) fixes; |
838 val (arg_Ts, res_Ts) = map (strip_type o snd o fst #>> HOLogic.mk_tupleT) fixes |> split_list; |
838 val (arg_Ts, res_Ts) = map (strip_type o snd o fst #>> HOLogic.mk_tupleT) fixes |> split_list; |
839 |
839 |
840 val fun_names = map Binding.name_of bs; |
840 val fun_names = map Binding.name_of bs; |
882 val disc_eqnss = map5 mk_real_disc_eqns bs arg_Tss corec_specs sel_eqnss disc_eqnss'; |
882 val disc_eqnss = map5 mk_real_disc_eqns bs arg_Tss corec_specs sel_eqnss disc_eqnss'; |
883 val (defs, exclss') = |
883 val (defs, exclss') = |
884 build_codefs lthy' bs mxs has_call arg_Tss corec_specs disc_eqnss sel_eqnss; |
884 build_codefs lthy' bs mxs has_call arg_Tss corec_specs disc_eqnss sel_eqnss; |
885 |
885 |
886 fun excl_tac (c, c', a) = |
886 fun excl_tac (c, c', a) = |
887 if a orelse c = c' orelse seq then |
887 if a orelse c = c' orelse seq then SOME (K (HEADGOAL (mk_primcorec_assumption_tac lthy []))) |
888 SOME (K (HEADGOAL (mk_primcorec_assumption_tac lthy []))) |
888 else maybe_tac; |
889 else if simple then |
|
890 SOME (K (auto_tac lthy)) |
|
891 else |
|
892 NONE; |
|
893 |
889 |
894 (* |
890 (* |
895 val _ = tracing ("exclusiveness properties:\n \<cdot> " ^ |
891 val _ = tracing ("exclusiveness properties:\n \<cdot> " ^ |
896 space_implode "\n \<cdot> " (maps (map (Syntax.string_of_term lthy o snd)) exclss')); |
892 space_implode "\n \<cdot> " (maps (map (Syntax.string_of_term lthy o snd)) exclss')); |
897 *) |
893 *) |
898 |
894 |
899 val exclss'' = exclss' |> map (map (fn (idx, t) => |
895 val exclss'' = exclss' |> map (map (fn (idx, t) => |
900 (idx, (Option.map (Goal.prove lthy [] [] t |> Thm.close_derivation) (excl_tac idx), t)))); |
896 (idx, (Option.map (Goal.prove lthy [] [] t #> Thm.close_derivation) (excl_tac idx), t)))); |
901 val taut_thmss = map (map (apsnd (the o fst)) o filter (is_some o fst o snd)) exclss''; |
897 val taut_thmss = map (map (apsnd (the o fst)) o filter (is_some o fst o snd)) exclss''; |
902 val (obligation_idxss, obligationss) = exclss'' |
898 val (obligation_idxss, goalss) = exclss'' |
903 |> map (map (apsnd (rpair [] o snd)) o filter (is_none o fst o snd)) |
899 |> map (map (apsnd (rpair [] o snd)) o filter (is_none o fst o snd)) |
904 |> split_list o map split_list; |
900 |> split_list o map split_list; |
905 |
901 |
906 fun prove thmss' def_thms' lthy = |
902 fun prove thmss' def_thms' lthy = |
907 let |
903 let |
1117 in |
1113 in |
1118 lthy |> Local_Theory.notes (notes @ common_notes) |> snd |
1114 lthy |> Local_Theory.notes (notes @ common_notes) |> snd |
1119 end; |
1115 end; |
1120 |
1116 |
1121 fun after_qed thmss' = fold_map Local_Theory.define defs #-> prove thmss'; |
1117 fun after_qed thmss' = fold_map Local_Theory.define defs #-> prove thmss'; |
1122 |
1118 in |
1123 val _ = if not simple orelse forall null obligationss then () else |
1119 (goalss, after_qed, lthy') |
1124 primrec_error "need exclusiveness proofs - use primcorecursive instead of primcorec"; |
1120 end; |
1125 in |
1121 |
1126 if simple then |
1122 fun add_primcorec_ursive_cmd maybe_tac seq (raw_fixes, raw_specs') lthy = |
1127 lthy' |
|
1128 |> after_qed (map (fn [] => []) obligationss) |
|
1129 |> pair NONE o SOME |
|
1130 else |
|
1131 lthy' |
|
1132 |> Proof.theorem NONE after_qed obligationss |
|
1133 |> Proof.refine (Method.primitive_text I) |
|
1134 |> Seq.hd |
|
1135 |> rpair NONE o SOME |
|
1136 end; |
|
1137 |
|
1138 fun add_primcorec_ursive_cmd simple seq (raw_fixes, raw_specs') lthy = |
|
1139 let |
1123 let |
1140 val (raw_specs, of_specs) = split_list raw_specs' ||> map (Option.map (Syntax.read_term lthy)); |
1124 val (raw_specs, of_specs) = split_list raw_specs' ||> map (Option.map (Syntax.read_term lthy)); |
1141 val ((fixes, specs), _) = Specification.read_spec raw_fixes raw_specs lthy; |
1125 val ((fixes, specs), _) = Specification.read_spec raw_fixes raw_specs lthy; |
1142 in |
1126 in |
1143 add_primcorec simple seq fixes specs of_specs lthy |
1127 add_primcorec_ursive maybe_tac seq fixes specs of_specs lthy |
1144 handle ERROR str => primrec_error str |
1128 handle ERROR str => primrec_error str |
1145 end |
1129 end |
1146 handle Primrec_Error (str, eqns) => |
1130 handle Primrec_Error (str, eqns) => |
1147 if null eqns |
1131 if null eqns |
1148 then error ("primcorec error:\n " ^ str) |
1132 then error ("primcorec error:\n " ^ str) |
1149 else error ("primcorec error:\n " ^ str ^ "\nin\n " ^ |
1133 else error ("primcorec error:\n " ^ str ^ "\nin\n " ^ |
1150 space_implode "\n " (map (quote o Syntax.string_of_term lthy) eqns)); |
1134 space_implode "\n " (map (quote o Syntax.string_of_term lthy) eqns)); |
1151 |
1135 |
1152 val add_primcorecursive_cmd = (the o fst) ooo add_primcorec_ursive_cmd false; |
1136 val add_primcorecursive_cmd = (fn (goalss, after_qed, lthy) => |
1153 val add_primcorec_cmd = (the o snd) ooo add_primcorec_ursive_cmd true; |
1137 lthy |
|
1138 |> Proof.theorem NONE after_qed goalss |
|
1139 |> Proof.refine (Method.primitive_text I) |
|
1140 |> Seq.hd) ooo add_primcorec_ursive_cmd NONE; |
|
1141 |
|
1142 val add_primcorec_cmd = (fn (goalss, after_qed, lthy) => |
|
1143 lthy |
|
1144 |> after_qed (map (fn [] => [] |
|
1145 | _ => primrec_error "need exclusiveness proofs - use primcorecursive instead of primcorec") |
|
1146 goalss)) ooo add_primcorec_ursive_cmd (SOME (fn {context = ctxt, ...} => auto_tac ctxt)); |
1154 |
1147 |
1155 end; |
1148 end; |