1 (* Title: Pure/Isar/code_unit.ML |
1 (* Title: Pure/Isar/code_unit.ML |
2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Florian Haftmann, TU Muenchen |
3 Author: Florian Haftmann, TU Muenchen |
4 |
4 |
5 Basic units of code generation: Identifying (possibly overloaded) constants |
5 Basic units of code generation. Auxiliary. |
6 by name plus optional type constructor. Convenient data structures for constants. |
|
7 Defining equations ("func"s). Auxiliary. |
|
8 *) |
6 *) |
9 |
7 |
10 signature CODE_UNIT = |
8 signature CODE_UNIT = |
11 sig |
9 sig |
12 type const = string * string option (*constant name, possibly instance*) |
|
13 val const_ord: const * const -> order |
|
14 val eq_const: const * const -> bool |
|
15 structure Consttab: TABLE |
|
16 val const_of_cexpr: theory -> string * typ -> const |
|
17 val string_of_typ: theory -> typ -> string |
10 val string_of_typ: theory -> typ -> string |
18 val string_of_const: theory -> const -> string |
11 val string_of_const: theory -> string -> string |
|
12 val no_args: theory -> string -> int |
19 val read_bare_const: theory -> string -> string * typ |
13 val read_bare_const: theory -> string -> string * typ |
20 val read_const: theory -> string -> const |
14 val read_const: theory -> string -> string |
21 val read_const_exprs: theory -> (const list -> const list) |
15 val read_const_exprs: theory -> (string list -> string list) |
22 -> string list -> bool * const list |
16 -> string list -> bool * string list |
23 |
17 |
24 val co_of_const: theory -> const |
18 val constrset_of_consts: theory -> (string * typ) list |
25 -> string * ((string * sort) list * (string * typ list)) |
|
26 val co_of_const': theory -> const |
|
27 -> (string * ((string * sort) list * (string * typ list))) option |
|
28 val cos_of_consts: theory -> const list |
|
29 -> string * ((string * sort) list * (string * typ list) list) |
19 -> string * ((string * sort) list * (string * typ list) list) |
30 val const_of_co: theory -> string -> (string * sort) list |
|
31 -> string * typ list -> const |
|
32 val consts_of_cos: theory -> string -> (string * sort) list |
|
33 -> (string * typ list) list -> const list |
|
34 val no_args: theory -> const -> int |
|
35 |
|
36 val typargs: theory -> string * typ -> typ list |
|
37 val typ_sort_inst: Sorts.algebra -> typ * sort |
20 val typ_sort_inst: Sorts.algebra -> typ * sort |
38 -> sort Vartab.table -> sort Vartab.table |
21 -> sort Vartab.table -> sort Vartab.table |
39 |
22 |
40 val assert_rew: thm -> thm |
23 val assert_rew: thm -> thm |
41 val mk_rew: thm -> thm |
24 val mk_rew: thm -> thm |
42 val mk_func: thm -> thm |
25 val mk_func: thm -> thm |
43 val head_func: thm -> const * typ |
26 val head_func: thm -> string * typ |
44 val bad_thm: string -> 'a |
27 val bad_thm: string -> 'a |
45 val error_thm: (thm -> thm) -> thm -> thm |
28 val error_thm: (thm -> thm) -> thm -> thm |
46 val warning_thm: (thm -> thm) -> thm -> thm option |
29 val warning_thm: (thm -> thm) -> thm -> thm option |
47 |
30 |
48 val inst_thm: sort Vartab.table -> thm -> thm |
31 val inst_thm: sort Vartab.table -> thm -> thm |
62 fun bad_thm msg = raise BAD_THM msg; |
45 fun bad_thm msg = raise BAD_THM msg; |
63 fun error_thm f thm = f thm handle BAD_THM msg => error msg; |
46 fun error_thm f thm = f thm handle BAD_THM msg => error msg; |
64 fun warning_thm f thm = SOME (f thm) handle BAD_THM msg |
47 fun warning_thm f thm = SOME (f thm) handle BAD_THM msg |
65 => (warning ("code generator: " ^ msg); NONE); |
48 => (warning ("code generator: " ^ msg); NONE); |
66 |
49 |
67 |
|
68 (* basic data structures *) |
|
69 |
|
70 type const = string * string option; |
|
71 val const_ord = prod_ord fast_string_ord (option_ord string_ord); |
|
72 val eq_const = is_equal o const_ord; |
|
73 |
|
74 structure Consttab = |
|
75 TableFun( |
|
76 type key = const; |
|
77 val ord = const_ord; |
|
78 ); |
|
79 |
|
80 fun string_of_typ thy = setmp show_sorts true (Sign.string_of_typ thy); |
50 fun string_of_typ thy = setmp show_sorts true (Sign.string_of_typ thy); |
81 |
51 fun string_of_const thy c = case Class.param_const thy c |
82 |
52 of SOME (c, tyco) => Sign.extern_const thy c ^ " " ^ enclose "[" "]" (Sign.extern_type thy tyco) |
83 (* conversion between constant expressions and constants *) |
53 | NONE => Sign.extern_const thy c; |
84 |
54 |
85 fun const_of_cexpr thy (c_ty as (c, _)) = |
55 fun no_args thy = length o fst o strip_type o Sign.the_const_type thy; |
86 case AxClass.class_of_param thy c |
|
87 of SOME class => (case Sign.const_typargs thy c_ty |
|
88 of [Type (tyco, _)] => if can (Sorts.mg_domain (Sign.classes_of thy) tyco) [class] |
|
89 then (c, SOME tyco) |
|
90 else (c, NONE) |
|
91 | [_] => (c, NONE)) |
|
92 | NONE => (c, NONE); |
|
93 |
|
94 fun string_of_const thy (c, NONE) = Sign.extern_const thy c |
|
95 | string_of_const thy (c, SOME tyco) = Sign.extern_const thy c |
|
96 ^ " " ^ enclose "[" "]" (Sign.extern_type thy tyco); |
|
97 |
|
98 |
56 |
99 (* reading constants as terms and wildcards pattern *) |
57 (* reading constants as terms and wildcards pattern *) |
100 |
58 |
101 fun read_bare_const thy raw_t = |
59 fun read_bare_const thy raw_t = |
102 let |
60 let |
104 in case try dest_Const t |
62 in case try dest_Const t |
105 of SOME c_ty => c_ty |
63 of SOME c_ty => c_ty |
106 | NONE => error ("Not a constant: " ^ Sign.string_of_term thy t) |
64 | NONE => error ("Not a constant: " ^ Sign.string_of_term thy t) |
107 end; |
65 end; |
108 |
66 |
109 fun read_const thy = const_of_cexpr thy o read_bare_const thy; |
67 fun read_const thy = Class.unoverload_const thy o read_bare_const thy; |
110 |
68 |
111 local |
69 local |
112 |
70 |
113 fun consts_of thy some_thyname = |
71 fun consts_of thy some_thyname = |
114 let |
72 let |
115 val this_thy = Option.map theory some_thyname |> the_default thy; |
73 val this_thy = Option.map theory some_thyname |> the_default thy; |
116 val cs = Symtab.fold (fn (c, (_, NONE)) => cons c | _ => I) |
74 val cs = Symtab.fold (fn (c, (_, NONE)) => cons c | _ => I) |
117 ((snd o #constants o Consts.dest o #consts o Sign.rep_sg) this_thy) []; |
75 ((snd o #constants o Consts.dest o #consts o Sign.rep_sg) this_thy) []; |
118 fun classop c = case AxClass.class_of_param thy c |
76 fun belongs_here thyname c = |
119 of NONE => [(c, NONE)] |
|
120 | SOME class => Symtab.fold |
|
121 (fn (tyco, classes) => if AList.defined (op =) classes class |
|
122 then cons (c, SOME tyco) else I) |
|
123 ((#arities o Sorts.rep_algebra o Sign.classes_of) this_thy) |
|
124 [(c, NONE)]; |
|
125 val consts = maps classop cs; |
|
126 fun test_instance thy (class, tyco) = |
|
127 can (Sorts.mg_domain (Sign.classes_of thy) tyco) [class] |
|
128 fun belongs_here thyname (c, NONE) = |
|
129 not (exists (fn thy' => Sign.declared_const thy' c) (Theory.parents_of this_thy)) |
77 not (exists (fn thy' => Sign.declared_const thy' c) (Theory.parents_of this_thy)) |
130 | belongs_here thyname (c, SOME tyco) = |
|
131 let |
|
132 val SOME class = AxClass.class_of_param thy c |
|
133 in not (exists (fn thy' => test_instance thy' (class, tyco)) |
|
134 (Theory.parents_of this_thy)) |
|
135 end; |
|
136 in case some_thyname |
78 in case some_thyname |
137 of NONE => consts |
79 of NONE => cs |
138 | SOME thyname => filter (belongs_here thyname) consts |
80 | SOME thyname => filter (belongs_here thyname) cs |
139 end; |
81 end; |
140 |
82 |
141 fun read_const_expr thy "*" = ([], consts_of thy NONE) |
83 fun read_const_expr thy "*" = ([], consts_of thy NONE) |
142 | read_const_expr thy s = if String.isSuffix ".*" s |
84 | read_const_expr thy s = if String.isSuffix ".*" s |
143 then ([], consts_of thy (SOME (unsuffix ".*" s))) |
85 then ([], consts_of thy (SOME (unsuffix ".*" s))) |
150 of (consts, []) => (false, consts) |
92 of (consts, []) => (false, consts) |
151 | (consts, consts') => (true, consts @ select consts'); |
93 | (consts, consts') => (true, consts @ select consts'); |
152 |
94 |
153 end; (*local*) |
95 end; (*local*) |
154 |
96 |
155 (* conversion between constants, constant expressions and datatype constructors *) |
97 |
156 |
98 (* constructor sets *) |
157 fun const_of_co thy tyco vs (co, tys) = |
99 |
158 const_of_cexpr thy (co, tys ---> Type (tyco, map TFree vs)); |
100 fun constrset_of_consts thy cs = |
159 |
101 let |
160 fun consts_of_cos thy tyco vs cos = |
102 fun no_constr (c, ty) = error ("Not a datatype constructor: " ^ string_of_const thy c |
161 let |
103 ^ " :: " ^ string_of_typ thy ty); |
162 val dty = Type (tyco, map TFree vs); |
104 fun last_typ c_ty ty = |
163 fun mk_co (co, tys) = const_of_cexpr thy (co, tys ---> dty); |
105 let |
164 in map mk_co cos end; |
106 val frees = typ_tfrees ty; |
165 |
107 val (tyco, vs) = ((apsnd o map) (dest_TFree) o dest_Type o snd o strip_type) ty |
166 local |
108 handle TYPE _ => no_constr c_ty |
167 |
109 val _ = if has_duplicates (eq_fst (op =)) vs then no_constr c_ty else (); |
168 exception BAD of string; |
110 val _ = if length frees <> length vs then no_constr c_ty else (); |
169 |
111 in (tyco, vs) end; |
170 fun mg_typ_of_const thy (c, NONE) = Sign.the_const_type thy c |
112 fun ty_sorts (c, ty) = |
171 | mg_typ_of_const thy (c, SOME tyco) = |
113 let |
172 let |
114 val ty_decl = (Logic.unvarifyT o Sign.the_const_type thy) c; |
173 val SOME class = AxClass.class_of_param thy c; |
115 val (tyco, vs_decl) = last_typ (c, ty) ty_decl; |
174 val ty = Sign.the_const_type thy c; |
116 val (_, vs) = last_typ (c, ty) ty; |
175 (*an approximation*) |
117 in ((tyco, map snd vs), (c, (map fst vs, ty_decl))) end; |
176 val sorts = Sorts.mg_domain (Sign.classes_of thy) tyco [class] |
118 fun add ((tyco', sorts'), c) ((tyco, sorts), cs) = |
177 handle CLASS_ERROR => raise BAD ("No such instance: " ^ tyco ^ " :: " ^ class |
119 let |
178 ^ ",\nrequired for overloaded constant " ^ c); |
120 val _ = if tyco' <> tyco |
179 val vs = Name.invents Name.context "'a" (length sorts); |
121 then error "Different type constructors in constructor set" |
180 in map_atyps (K (Type (tyco, map (fn v => TVar ((v, 0), [])) vs))) ty end; |
122 else (); |
181 |
123 val sorts'' = map2 (curry (Sorts.inter_sort (Sign.classes_of thy))) sorts' sorts |
182 fun gen_co_of_const thy const = |
124 in ((tyco, sorts), c :: cs) end; |
183 let |
125 fun inst vs' (c, (vs, ty)) = |
184 val (c, _) = const; |
126 let |
185 val ty = (Logic.unvarifyT o mg_typ_of_const thy) const; |
127 val the_v = the o AList.lookup (op =) (vs ~~ vs'); |
186 fun err () = raise BAD |
128 val ty' = map_atyps (fn TFree (v, _) => TFree (the_v v)) ty; |
187 ("Illegal type for datatype constructor: " ^ string_of_typ thy ty); |
129 in (c, (fst o strip_type) ty') end; |
188 val (tys, ty') = strip_type ty; |
130 val c' :: cs' = map ty_sorts cs; |
189 val (tyco, vs) = ((apsnd o map) dest_TFree o dest_Type) ty' |
131 val ((tyco, sorts), cs'') = fold add cs' (apsnd single c'); |
190 handle TYPE _ => err (); |
132 val vs = Name.names Name.context "'a" sorts; |
191 val sorts = if has_duplicates (eq_fst op =) vs then err () |
133 val cs''' = map (inst vs) cs''; |
192 else map snd vs; |
134 in (tyco, (vs, cs''')) end; |
193 val vs_names = Name.invent_list [] "'a" (length vs); |
|
194 val vs_map = map fst vs ~~ vs_names; |
|
195 val vs' = vs_names ~~ sorts; |
|
196 val tys' = (map o map_type_tfree) (fn (v, sort) => |
|
197 (TFree ((the o AList.lookup (op =) vs_map) v, sort))) tys |
|
198 handle Option => err (); |
|
199 in (tyco, (vs', (c, tys'))) end; |
|
200 |
|
201 in |
|
202 |
|
203 fun co_of_const thy const = gen_co_of_const thy const handle BAD msg => error msg; |
|
204 fun co_of_const' thy const = SOME (gen_co_of_const thy const) handle BAD msg => NONE; |
|
205 |
|
206 fun no_args thy = length o fst o strip_type o mg_typ_of_const thy; |
|
207 |
|
208 end; |
|
209 |
|
210 fun cos_of_consts thy consts = |
|
211 let |
|
212 val raw_cos = map (co_of_const thy) consts; |
|
213 val (tyco, (vs_names, sorts_cos)) = if (length o distinct (eq_fst op =)) raw_cos = 1 |
|
214 then ((fst o hd) raw_cos, ((map fst o fst o snd o hd) raw_cos, |
|
215 map ((apfst o map) snd o snd) raw_cos)) |
|
216 else error ("Term constructors not referring to the same type: " |
|
217 ^ commas (map (string_of_const thy) consts)); |
|
218 val sorts = foldr1 ((uncurry o map2 o curry o Sorts.inter_sort) (Sign.classes_of thy)) |
|
219 (map fst sorts_cos); |
|
220 val cos = map snd sorts_cos; |
|
221 val vs = vs_names ~~ sorts; |
|
222 in (tyco, (vs, cos)) end; |
|
223 |
135 |
224 |
136 |
225 (* dictionary values *) |
137 (* dictionary values *) |
226 |
|
227 fun typargs thy (c_ty as (c, ty)) = |
|
228 let |
|
229 val opt_class = AxClass.class_of_param thy c; |
|
230 val tys = Sign.const_typargs thy (c, ty); |
|
231 in case (opt_class, tys) |
|
232 of (SOME class, ty as [Type (tyco, tys')]) => |
|
233 if can (Sorts.mg_domain (Sign.classes_of thy) tyco) [class] |
|
234 then tys' else ty |
|
235 | _ => tys |
|
236 end; |
|
237 |
138 |
238 fun typ_sort_inst algebra = |
139 fun typ_sort_inst algebra = |
239 let |
140 let |
240 val inters = Sorts.inter_sort algebra; |
141 val inters = Sorts.inter_sort algebra; |
241 fun match _ [] = I |
142 fun match _ [] = I |