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 |