src/HOL/BNF/Tools/bnf_fp_rec_sugar.ML
changeset 54177 acea8033beaa
parent 54176 8039bd7e98b1
child 54178 d6dc359426b7
equal deleted inserted replaced
54176:8039bd7e98b1 54177:acea8033beaa
   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;