56 |
56 |
57 val app = curry (list_comb o swap); |
57 val app = curry (list_comb o swap); |
58 |
58 |
59 fun prove_size_thms (info : info) new_type_names thy = |
59 fun prove_size_thms (info : info) new_type_names thy = |
60 let |
60 let |
61 val {descr, alt_names, sorts, rec_names, rec_rewrites, induct, ...} = info; |
61 val {descr, sorts, rec_names, rec_rewrites, induct, ...} = info; |
62 val l = length new_type_names; |
62 val l = length new_type_names; |
63 val alt_names' = (case alt_names of |
|
64 NONE => replicate l NONE | SOME names => map SOME names); |
|
65 val descr' = List.take (descr, l); |
63 val descr' = List.take (descr, l); |
66 val (rec_names1, rec_names2) = chop l rec_names; |
64 val (rec_names1, rec_names2) = chop l rec_names; |
67 val recTs = get_rec_types descr sorts; |
65 val recTs = get_rec_types descr sorts; |
68 val (recTs1, recTs2) = chop l recTs; |
66 val (recTs1, recTs2) = chop l recTs; |
69 val (_, (_, paramdts, _)) :: _ = descr; |
67 val (_, (_, paramdts, _)) :: _ = descr; |
81 val extra_rewrites = descr |> map (#1 o snd) |> distinct op = |> |
79 val extra_rewrites = descr |> map (#1 o snd) |> distinct op = |> |
82 map_filter (Option.map snd o lookup_size thy) |> flat; |
80 map_filter (Option.map snd o lookup_size thy) |> flat; |
83 val extra_size = Option.map fst o lookup_size thy; |
81 val extra_size = Option.map fst o lookup_size thy; |
84 |
82 |
85 val (((size_names, size_fns), def_names), def_names') = |
83 val (((size_names, size_fns), def_names), def_names') = |
86 recTs1 ~~ alt_names' |> |
84 recTs1 |> map (fn T as Type (s, _) => |
87 map (fn (T as Type (s, _), optname) => |
|
88 let |
85 let |
89 val s' = the_default (Long_Name.base_name s) optname ^ "_size"; |
86 val s' = Long_Name.base_name s ^ "_size"; |
90 val s'' = Sign.full_bname thy s' |
87 val s'' = Sign.full_bname thy s'; |
91 in |
88 in |
92 (s'', |
89 (s'', |
93 (list_comb (Const (s'', param_size_fTs @ [T] ---> HOLogic.natT), |
90 (list_comb (Const (s'', param_size_fTs @ [T] ---> HOLogic.natT), |
94 map snd param_size_fs), |
91 map snd param_size_fs), |
95 (s' ^ "_def", s' ^ "_overloaded_def"))) |
92 (s' ^ "_def", s' ^ "_overloaded_def"))) |
219 (new_type_names ~~ size_names)) thy'' |
216 (new_type_names ~~ size_names)) thy'' |
220 end; |
217 end; |
221 |
218 |
222 fun add_size_thms config (new_type_names as name :: _) thy = |
219 fun add_size_thms config (new_type_names as name :: _) thy = |
223 let |
220 let |
224 val info as {descr, alt_names, ...} = Datatype.the_info thy name; |
221 val info as {descr, ...} = Datatype.the_info thy name; |
225 val prefix = Long_Name.map_base_name (K (space_implode "_" |
222 val prefix = |
226 (the_default (map Long_Name.base_name new_type_names) alt_names))) name; |
223 Long_Name.map_base_name (K (space_implode "_" (map Long_Name.base_name new_type_names))) name; |
227 val no_size = exists (fn (_, (_, _, constrs)) => exists (fn (_, cargs) => exists (fn dt => |
224 val no_size = exists (fn (_, (_, _, constrs)) => exists (fn (_, cargs) => exists (fn dt => |
228 is_rec_type dt andalso not (null (fst (strip_dtyp dt)))) cargs) constrs) descr |
225 is_rec_type dt andalso not (null (fst (strip_dtyp dt)))) cargs) constrs) descr |
229 in if no_size then thy |
226 in |
|
227 if no_size then thy |
230 else |
228 else |
231 thy |
229 thy |
232 |> Sign.root_path |
230 |> Sign.root_path |
233 |> Sign.add_path prefix |
231 |> Sign.add_path prefix |
234 |> Theory.checkpoint |
232 |> Theory.checkpoint |