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; |