src/HOL/Tools/primrec.ML
changeset 35166 a57ef2cd2236
parent 34952 bd7e347eb768
child 35756 cfde251d03a5
equal deleted inserted replaced
35165:58b9503a7f9a 35166:a57ef2cd2236
     6 *)
     6 *)
     7 
     7 
     8 signature PRIMREC =
     8 signature PRIMREC =
     9 sig
     9 sig
    10   val add_primrec: (binding * typ option * mixfix) list ->
    10   val add_primrec: (binding * typ option * mixfix) list ->
    11     (Attrib.binding * term) list -> local_theory -> thm list * local_theory
    11     (Attrib.binding * term) list -> local_theory -> (term list * thm list) * local_theory
    12   val add_primrec_cmd: (binding * string option * mixfix) list ->
    12   val add_primrec_cmd: (binding * string option * mixfix) list ->
    13     (Attrib.binding * string) list -> local_theory -> thm list * local_theory
    13     (Attrib.binding * string) list -> local_theory -> (term list * thm list) * local_theory
    14   val add_primrec_global: (binding * typ option * mixfix) list ->
    14   val add_primrec_global: (binding * typ option * mixfix) list ->
    15     (Attrib.binding * term) list -> theory -> thm list * theory
    15     (Attrib.binding * term) list -> theory -> (term list * thm list) * theory
    16   val add_primrec_overloaded: (string * (string * typ) * bool) list ->
    16   val add_primrec_overloaded: (string * (string * typ) * bool) list ->
    17     (binding * typ option * mixfix) list ->
    17     (binding * typ option * mixfix) list ->
    18     (Attrib.binding * term) list -> theory -> thm list * theory
    18     (Attrib.binding * term) list -> theory -> (term list * thm list) * theory
    19   val add_primrec_simple: ((binding * typ) * mixfix) list -> term list ->
    19   val add_primrec_simple: ((binding * typ) * mixfix) list -> term list ->
    20     local_theory -> (string * thm list list) * local_theory
    20     local_theory -> (string * (term list * thm list)) * local_theory
    21 end;
    21 end;
    22 
    22 
    23 structure Primrec : PRIMREC =
    23 structure Primrec : PRIMREC =
    24 struct
    24 struct
    25 
    25 
   242         val frees = (fold o Term.fold_aterms) (fn Free (x, _) =>
   242         val frees = (fold o Term.fold_aterms) (fn Free (x, _) =>
   243           if Variable.is_fixed lthy x then I else insert (op =) x | _ => I) eqs [];
   243           if Variable.is_fixed lthy x then I else insert (op =) x | _ => I) eqs [];
   244         val rewrites = rec_rewrites' @ map (snd o snd) defs;
   244         val rewrites = rec_rewrites' @ map (snd o snd) defs;
   245         fun tac _ = EVERY [rewrite_goals_tac rewrites, rtac refl 1];
   245         fun tac _ = EVERY [rewrite_goals_tac rewrites, rtac refl 1];
   246         val _ = message ("Proving equations for primrec function(s) " ^ commas_quote names);
   246         val _ = message ("Proving equations for primrec function(s) " ^ commas_quote names);
   247       in map (fn eq => [Goal.prove lthy frees [] eq tac]) eqs end;
   247       in map (fn eq => Goal.prove lthy frees [] eq tac) eqs end;
   248   in ((prefix, (fs, defs)), prove) end
   248   in ((prefix, (fs, defs)), prove) end
   249   handle PrimrecError (msg, some_eqn) =>
   249   handle PrimrecError (msg, some_eqn) =>
   250     error ("Primrec definition error:\n" ^ msg ^ (case some_eqn
   250     error ("Primrec definition error:\n" ^ msg ^ (case some_eqn
   251      of SOME eqn => "\nin\n" ^ quote (Syntax.string_of_term lthy eqn)
   251      of SOME eqn => "\nin\n" ^ quote (Syntax.string_of_term lthy eqn)
   252       | NONE => ""));
   252       | NONE => ""));
   258   let
   258   let
   259     val ((prefix, (fs, defs)), prove) = distill lthy fixes ts;
   259     val ((prefix, (fs, defs)), prove) = distill lthy fixes ts;
   260   in
   260   in
   261     lthy
   261     lthy
   262     |> fold_map Local_Theory.define defs
   262     |> fold_map Local_Theory.define defs
   263     |-> (fn defs => `(fn lthy => (prefix, prove lthy defs)))
   263     |-> (fn defs => `(fn lthy => (prefix, (map fst defs, prove lthy defs))))
   264   end;
   264   end;
   265 
   265 
   266 local
   266 local
   267 
   267 
   268 fun specs_of simps =
   268 fun specs_of simps =
   283       (Binding.qualify true prefix (Binding.name "simps"),
   283       (Binding.qualify true prefix (Binding.name "simps"),
   284         map (Attrib.internal o K) [Simplifier.simp_add, Nitpick_Simps.add]);
   284         map (Attrib.internal o K) [Simplifier.simp_add, Nitpick_Simps.add]);
   285   in
   285   in
   286     lthy
   286     lthy
   287     |> add_primrec_simple fixes (map snd spec)
   287     |> add_primrec_simple fixes (map snd spec)
   288     |-> (fn (prefix, simps) => fold_map Local_Theory.note (attr_bindings prefix ~~ simps)
   288     |-> (fn (prefix, (ts, simps)) => fold_map Local_Theory.note (attr_bindings prefix ~~ map single simps)
   289       #-> (fn simps' => Local_Theory.note (simp_attr_binding prefix, maps snd simps')
   289       #-> (fn simps' => Local_Theory.note (simp_attr_binding prefix, maps snd simps')
       
   290       #>> (fn (_, simps'') => (ts, simps''))
   290       ##> (Spec_Rules.add Spec_Rules.Equational (specs_of simps'))))
   291       ##> (Spec_Rules.add Spec_Rules.Equational (specs_of simps'))))
   291     |>> snd
       
   292   end;
   292   end;
   293 
   293 
   294 in
   294 in
   295 
   295 
   296 val add_primrec = gen_primrec Specification.check_spec;
   296 val add_primrec = gen_primrec Specification.check_spec;
   299 end;
   299 end;
   300 
   300 
   301 fun add_primrec_global fixes specs thy =
   301 fun add_primrec_global fixes specs thy =
   302   let
   302   let
   303     val lthy = Theory_Target.init NONE thy;
   303     val lthy = Theory_Target.init NONE thy;
   304     val (simps, lthy') = add_primrec fixes specs lthy;
   304     val ((ts, simps), lthy') = add_primrec fixes specs lthy;
   305     val simps' = ProofContext.export lthy' lthy simps;
   305     val simps' = ProofContext.export lthy' lthy simps;
   306   in (simps', Local_Theory.exit_global lthy') end;
   306   in ((ts, simps'), Local_Theory.exit_global lthy') end;
   307 
   307 
   308 fun add_primrec_overloaded ops fixes specs thy =
   308 fun add_primrec_overloaded ops fixes specs thy =
   309   let
   309   let
   310     val lthy = Theory_Target.overloading ops thy;
   310     val lthy = Theory_Target.overloading ops thy;
   311     val (simps, lthy') = add_primrec fixes specs lthy;
   311     val ((ts, simps), lthy') = add_primrec fixes specs lthy;
   312     val simps' = ProofContext.export lthy' lthy simps;
   312     val simps' = ProofContext.export lthy' lthy simps;
   313   in (simps', Local_Theory.exit_global lthy') end;
   313   in ((ts, simps'), Local_Theory.exit_global lthy') end;
   314 
   314 
   315 
   315 
   316 (* outer syntax *)
   316 (* outer syntax *)
   317 
   317 
   318 local structure P = OuterParse and K = OuterKeyword in
   318 local structure P = OuterParse and K = OuterKeyword in