src/HOL/Tools/Old_Datatype/old_primrec.ML
changeset 64674 ef0a5fd30f3b
parent 63239 d562c9948dee
child 66251 cd935b7cb3fb
equal deleted inserted replaced
64673:b5965890e54d 64674:ef0a5fd30f3b
     6 Primitive recursive functions on datatypes.
     6 Primitive recursive functions on datatypes.
     7 *)
     7 *)
     8 
     8 
     9 signature OLD_PRIMREC =
     9 signature OLD_PRIMREC =
    10 sig
    10 sig
    11   val primrec: (binding * typ option * mixfix) list ->
    11   val primrec: bool -> (binding * typ option * mixfix) list ->
    12     Specification.multi_specs -> local_theory -> (term list * thm list) * local_theory
    12     Specification.multi_specs -> local_theory -> (term list * thm list) * local_theory
    13   val primrec_cmd: (binding * string option * mixfix) list ->
    13   val primrec_cmd: bool -> (binding * string option * mixfix) list ->
    14     Specification.multi_specs_cmd -> local_theory -> (term list * thm list) * local_theory
    14     Specification.multi_specs_cmd -> local_theory -> (term list * thm list) * local_theory
    15   val primrec_global: (binding * typ option * mixfix) list ->
    15   val primrec_global: bool -> (binding * typ option * mixfix) list ->
    16     Specification.multi_specs -> theory -> (term list * thm list) * theory
    16     Specification.multi_specs -> theory -> (term list * thm list) * theory
    17   val primrec_overloaded: (string * (string * typ) * bool) list ->
    17   val primrec_overloaded: bool -> (string * (string * typ) * bool) list ->
    18     (binding * typ option * mixfix) list ->
    18     (binding * typ option * mixfix) list ->
    19     Specification.multi_specs -> theory -> (term list * thm list) * theory
    19     Specification.multi_specs -> theory -> (term list * thm list) * theory
    20   val primrec_simple: ((binding * typ) * mixfix) list -> term list ->
    20   val primrec_simple: bool -> ((binding * typ) * mixfix) list -> term list ->
    21     local_theory -> (string * (term list * thm list)) * local_theory
    21     local_theory -> (string * (term list * thm list)) * local_theory
    22 end;
    22 end;
    23 
    23 
    24 structure Old_Primrec : OLD_PRIMREC =
    24 structure Old_Primrec : OLD_PRIMREC =
    25 struct
    25 struct
   186             dummyT ---> HOLogic.unitT)) constrs;
   186             dummyT ---> HOLogic.unitT)) constrs;
   187         val _ = warning ("No function definition for datatype " ^ quote tname)
   187         val _ = warning ("No function definition for datatype " ^ quote tname)
   188       in
   188       in
   189         (dummy_fns @ fs, defs)
   189         (dummy_fns @ fs, defs)
   190       end
   190       end
   191   | SOME (fname, ls, fs') => (fs' @ fs, (fname, ls, rec_name, tname) :: defs));
   191   | SOME (fname, ls, fs') => (fs' @ fs, (fname, ls, rec_name) :: defs));
   192 
   192 
   193 
   193 
   194 (* make definition *)
   194 (* make definition *)
   195 
   195 
   196 fun make_def ctxt fixes fs (fname, ls, rec_name, tname) =
   196 fun make_def ctxt fixes fs (fname, ls, rec_name) =
   197   let
   197   let
   198     val SOME (var, varT) = get_first (fn ((b, T), mx) =>
   198     val SOME (var, varT) = get_first (fn ((b, T), mx) =>
   199       if Binding.name_of b = fname then SOME ((b, mx), T) else NONE) fixes;
   199       if Binding.name_of b = fname then SOME ((b, mx), T) else NONE) fixes;
   200     val def_name = Thm.def_name (Long_Name.base_name fname);
   200     val def_name = Thm.def_name (Long_Name.base_name fname);
   201     val raw_rhs = fold_rev (fn T => fn t => Abs ("", T, t)) (map snd ls @ [dummyT])
   201     val raw_rhs = fold_rev (fn T => fn t => Abs ("", T, t)) (map snd ls @ [dummyT])
   258       | NONE => ""));
   258       | NONE => ""));
   259 
   259 
   260 
   260 
   261 (* primrec definition *)
   261 (* primrec definition *)
   262 
   262 
   263 fun primrec_simple fixes ts lthy =
   263 fun primrec_simple int fixes ts lthy =
   264   let
   264   let
   265     val ((prefix, (_, defs)), prove) = distill lthy fixes ts;
   265     val ((prefix, (_, defs)), prove) = distill lthy fixes ts;
   266   in
   266   in
   267     lthy
   267     lthy
   268     |> fold_map Local_Theory.define defs
   268     |> fold_map Local_Theory.define defs
       
   269     |> tap (uncurry (BNF_FP_Rec_Sugar_Util.print_def_consts int))
   269     |-> (fn defs => `(fn lthy => (prefix, (map fst defs, prove lthy defs))))
   270     |-> (fn defs => `(fn lthy => (prefix, (map fst defs, prove lthy defs))))
   270   end;
   271   end;
   271 
   272 
   272 local
   273 local
   273 
   274 
   274 fun gen_primrec prep_spec raw_fixes raw_spec lthy =
   275 fun gen_primrec prep_spec int raw_fixes raw_spec lthy =
   275   let
   276   let
   276     val (fixes, spec) = fst (prep_spec raw_fixes raw_spec lthy);
   277     val (fixes, spec) = fst (prep_spec raw_fixes raw_spec lthy);
   277     fun attr_bindings prefix = map (fn ((b, attrs), _) =>
   278     fun attr_bindings prefix = map (fn ((b, attrs), _) =>
   278       (Binding.qualify false prefix b, Code.add_default_eqn_attrib Code.Equation :: attrs)) spec;
   279       (Binding.qualify false prefix b, Code.add_default_eqn_attrib Code.Equation :: attrs)) spec;
   279     fun simp_attr_binding prefix =
   280     fun simp_attr_binding prefix =
   280       (Binding.qualify true prefix (Binding.name "simps"), @{attributes [simp, nitpick_simp]});
   281       (Binding.qualify true prefix (Binding.name "simps"), @{attributes [simp, nitpick_simp]});
   281   in
   282   in
   282     lthy
   283     lthy
   283     |> primrec_simple fixes (map snd spec)
   284     |> primrec_simple int fixes (map snd spec)
   284     |-> (fn (prefix, (ts, simps)) =>
   285     |-> (fn (prefix, (ts, simps)) =>
   285       Spec_Rules.add Spec_Rules.Equational (ts, simps)
   286       Spec_Rules.add Spec_Rules.Equational (ts, simps)
   286       #> fold_map Local_Theory.note (attr_bindings prefix ~~ map single simps)
   287       #> fold_map Local_Theory.note (attr_bindings prefix ~~ map single simps)
   287       #-> (fn simps' => Local_Theory.note (simp_attr_binding prefix, maps snd simps')
   288       #-> (fn simps' => Local_Theory.note (simp_attr_binding prefix, maps snd simps')
   288       #>> (fn (_, simps'') => (ts, simps''))))
   289       #>> (fn (_, simps'') => (ts, simps''))))
   293 val primrec = gen_primrec Specification.check_multi_specs;
   294 val primrec = gen_primrec Specification.check_multi_specs;
   294 val primrec_cmd = gen_primrec Specification.read_multi_specs;
   295 val primrec_cmd = gen_primrec Specification.read_multi_specs;
   295 
   296 
   296 end;
   297 end;
   297 
   298 
   298 fun primrec_global fixes specs thy =
   299 fun primrec_global int fixes specs thy =
   299   let
   300   let
   300     val lthy = Named_Target.theory_init thy;
   301     val lthy = Named_Target.theory_init thy;
   301     val ((ts, simps), lthy') = primrec fixes specs lthy;
   302     val ((ts, simps), lthy') = primrec int fixes specs lthy;
   302     val simps' = Proof_Context.export lthy' lthy simps;
   303     val simps' = Proof_Context.export lthy' lthy simps;
   303   in ((ts, simps'), Local_Theory.exit_global lthy') end;
   304   in ((ts, simps'), Local_Theory.exit_global lthy') end;
   304 
   305 
   305 fun primrec_overloaded ops fixes specs thy =
   306 fun primrec_overloaded int ops fixes specs thy =
   306   let
   307   let
   307     val lthy = Overloading.overloading ops thy;
   308     val lthy = Overloading.overloading ops thy;
   308     val ((ts, simps), lthy') = primrec fixes specs lthy;
   309     val ((ts, simps), lthy') = primrec int fixes specs lthy;
   309     val simps' = Proof_Context.export lthy' lthy simps;
   310     val simps' = Proof_Context.export lthy' lthy simps;
   310   in ((ts, simps'), Local_Theory.exit_global lthy') end;
   311   in ((ts, simps'), Local_Theory.exit_global lthy') end;
   311 
   312 
   312 end;
   313 end;