274 |
274 |
275 (* code generators for terms and types *) |
275 (* code generators for terms and types *) |
276 |
276 |
277 fun datatype_codegen thy defs dep module brack t gr = (case strip_comb t of |
277 fun datatype_codegen thy defs dep module brack t gr = (case strip_comb t of |
278 (c as Const (s, T), ts) => |
278 (c as Const (s, T), ts) => |
279 (case Datatype.datatype_of_case thy s of |
279 (case Datatype.info_of_case thy s of |
280 SOME {index, descr, ...} => |
280 SOME {index, descr, ...} => |
281 if is_some (get_assoc_code thy (s, T)) then NONE else |
281 if is_some (get_assoc_code thy (s, T)) then NONE else |
282 SOME (pretty_case thy defs dep module brack |
282 SOME (pretty_case thy defs dep module brack |
283 (#3 (the (AList.lookup op = descr index))) c ts gr ) |
283 (#3 (the (AList.lookup op = descr index))) c ts gr ) |
284 | NONE => case (Datatype.datatype_of_constr thy s, strip_type T) of |
284 | NONE => case (Datatype.info_of_constr thy s, strip_type T) of |
285 (SOME {index, descr, ...}, (_, U as Type (tyname, _))) => |
285 (SOME {index, descr, ...}, (_, U as Type (tyname, _))) => |
286 if is_some (get_assoc_code thy (s, T)) then NONE else |
286 if is_some (get_assoc_code thy (s, T)) then NONE else |
287 let |
287 let |
288 val SOME (tyname', _, constrs) = AList.lookup op = descr index; |
288 val SOME (tyname', _, constrs) = AList.lookup op = descr index; |
289 val SOME args = AList.lookup op = constrs s |
289 val SOME args = AList.lookup op = constrs s |
294 end |
294 end |
295 | _ => NONE) |
295 | _ => NONE) |
296 | _ => NONE); |
296 | _ => NONE); |
297 |
297 |
298 fun datatype_tycodegen thy defs dep module brack (Type (s, Ts)) gr = |
298 fun datatype_tycodegen thy defs dep module brack (Type (s, Ts)) gr = |
299 (case Datatype.get_datatype thy s of |
299 (case Datatype.get_info thy s of |
300 NONE => NONE |
300 NONE => NONE |
301 | SOME {descr, sorts, ...} => |
301 | SOME {descr, sorts, ...} => |
302 if is_some (get_assoc_type thy s) then NONE else |
302 if is_some (get_assoc_type thy s) then NONE else |
303 let |
303 let |
304 val (ps, gr') = fold_map |
304 val (ps, gr') = fold_map |
329 (* case certificates *) |
329 (* case certificates *) |
330 |
330 |
331 fun mk_case_cert thy tyco = |
331 fun mk_case_cert thy tyco = |
332 let |
332 let |
333 val raw_thms = |
333 val raw_thms = |
334 (#case_rewrites o Datatype.the_datatype thy) tyco; |
334 (#case_rewrites o Datatype.the_info thy) tyco; |
335 val thms as hd_thm :: _ = raw_thms |
335 val thms as hd_thm :: _ = raw_thms |
336 |> Conjunction.intr_balanced |
336 |> Conjunction.intr_balanced |
337 |> Thm.unvarify |
337 |> Thm.unvarify |
338 |> Conjunction.elim_balanced (length raw_thms) |
338 |> Conjunction.elim_balanced (length raw_thms) |
339 |> map Simpdata.mk_meta_eq |
339 |> map Simpdata.mk_meta_eq |
362 |
362 |
363 (* equality *) |
363 (* equality *) |
364 |
364 |
365 fun mk_eq_eqns thy dtco = |
365 fun mk_eq_eqns thy dtco = |
366 let |
366 let |
367 val (vs, cos) = Datatype.the_datatype_spec thy dtco; |
367 val (vs, cos) = Datatype.the_spec thy dtco; |
368 val { descr, index, inject = inject_thms, ... } = Datatype.the_datatype thy dtco; |
368 val { descr, index, inject = inject_thms, ... } = Datatype.the_info thy dtco; |
369 val ty = Type (dtco, map TFree vs); |
369 val ty = Type (dtco, map TFree vs); |
370 fun mk_eq (t1, t2) = Const (@{const_name eq_class.eq}, ty --> ty --> HOLogic.boolT) |
370 fun mk_eq (t1, t2) = Const (@{const_name eq_class.eq}, ty --> ty --> HOLogic.boolT) |
371 $ t1 $ t2; |
371 $ t1 $ t2; |
372 fun true_eq t12 = HOLogic.mk_eq (mk_eq t12, HOLogic.true_const); |
372 fun true_eq t12 = HOLogic.mk_eq (mk_eq t12, HOLogic.true_const); |
373 fun false_eq t12 = HOLogic.mk_eq (mk_eq t12, HOLogic.false_const); |
373 fun false_eq t12 = HOLogic.mk_eq (mk_eq t12, HOLogic.false_const); |
426 |
426 |
427 (* register a datatype etc. *) |
427 (* register a datatype etc. *) |
428 |
428 |
429 fun add_all_code config dtcos thy = |
429 fun add_all_code config dtcos thy = |
430 let |
430 let |
431 val (vs :: _, coss) = (split_list o map (Datatype.the_datatype_spec thy)) dtcos; |
431 val (vs :: _, coss) = (split_list o map (Datatype.the_spec thy)) dtcos; |
432 val any_css = map2 (mk_constr_consts thy vs) dtcos coss; |
432 val any_css = map2 (mk_constr_consts thy vs) dtcos coss; |
433 val css = if exists is_none any_css then [] |
433 val css = if exists is_none any_css then [] |
434 else map_filter I any_css; |
434 else map_filter I any_css; |
435 val case_rewrites = maps (#case_rewrites o Datatype.the_datatype thy) dtcos; |
435 val case_rewrites = maps (#case_rewrites o Datatype.the_info thy) dtcos; |
436 val certs = map (mk_case_cert thy) dtcos; |
436 val certs = map (mk_case_cert thy) dtcos; |
437 in |
437 in |
438 if null css then thy |
438 if null css then thy |
439 else thy |
439 else thy |
440 |> tap (fn _ => DatatypeAux.message config "Registering datatype for code generator ...") |
440 |> tap (fn _ => DatatypeAux.message config "Registering datatype for code generator ...") |