author | haftmann |
Thu, 19 Jul 2007 21:47:42 +0200 | |
changeset 23855 | b1a754e544b6 |
parent 23691 | cedf9610b71d |
permissions | -rw-r--r-- |
20387 | 1 |
(* Title: Pure/Tools/codegen_consts.ML |
2 |
ID: $Id$ |
|
3 |
Author: Florian Haftmann, TU Muenchen |
|
4 |
||
20855 | 5 |
Identifying constants by name plus normalized type instantantiation schemes. |
22197 | 6 |
Convenient data structures for constants. Auxiliary. |
20387 | 7 |
*) |
8 |
||
9 |
signature CODEGEN_CONSTS = |
|
10 |
sig |
|
22921
475ff421a6a3
consts in consts_code Isar commands are now referred to by usual term syntax
haftmann
parents:
22737
diff
changeset
|
11 |
type const = string * string option (*constant name, possibly instance*) |
20387 | 12 |
val const_ord: const * const -> order |
13 |
val eq_const: const * const -> bool |
|
14 |
structure Consttab: TABLE |
|
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
15 |
val const_of_cexpr: theory -> string * typ -> const |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
16 |
val string_of_typ: theory -> typ -> string |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
17 |
val string_of_const: theory -> const -> string |
22921
475ff421a6a3
consts in consts_code Isar commands are now referred to by usual term syntax
haftmann
parents:
22737
diff
changeset
|
18 |
val read_bare_const: theory -> string -> string * typ |
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
19 |
val read_const: theory -> string -> const |
22737 | 20 |
val read_const_exprs: theory -> (const list -> const list) |
23691 | 21 |
-> string list -> bool * const list |
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
22 |
|
22508 | 23 |
val co_of_const: theory -> const |
24 |
-> string * ((string * sort) list * (string * typ list)) |
|
25 |
val co_of_const': theory -> const |
|
26 |
-> (string * ((string * sort) list * (string * typ list))) option |
|
27 |
val cos_of_consts: theory -> const list |
|
28 |
-> string * ((string * sort) list * (string * typ list) list) |
|
29 |
val const_of_co: theory -> string -> (string * sort) list |
|
30 |
-> string * typ list -> const |
|
31 |
val consts_of_cos: theory -> string -> (string * sort) list |
|
32 |
-> (string * typ list) list -> const list |
|
23855 | 33 |
val no_args: theory -> const -> int |
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
34 |
|
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
35 |
val typargs: theory -> string * typ -> typ list |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
36 |
val typ_sort_inst: Sorts.algebra -> typ * sort |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
37 |
-> sort Vartab.table -> sort Vartab.table |
20387 | 38 |
end; |
39 |
||
40 |
structure CodegenConsts: CODEGEN_CONSTS = |
|
41 |
struct |
|
42 |
||
43 |
||
44 |
(* basic data structures *) |
|
45 |
||
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
46 |
type const = string * string option; |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
47 |
val const_ord = prod_ord fast_string_ord (option_ord string_ord); |
20387 | 48 |
val eq_const = is_equal o const_ord; |
49 |
||
50 |
structure Consttab = |
|
51 |
TableFun( |
|
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
52 |
type key = const; |
20387 | 53 |
val ord = const_ord; |
54 |
); |
|
55 |
||
22197 | 56 |
fun string_of_typ thy = setmp show_sorts true (Sign.string_of_typ thy); |
57 |
||
20387 | 58 |
|
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
59 |
(* conversion between constant expressions and constants *) |
20387 | 60 |
|
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
61 |
fun const_of_cexpr thy (c_ty as (c, _)) = |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
62 |
case AxClass.class_of_param thy c |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
63 |
of SOME class => (case Sign.const_typargs thy c_ty |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
64 |
of [Type (tyco, _)] => if can (Sorts.mg_domain (Sign.classes_of thy) tyco) [class] |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
65 |
then (c, SOME tyco) |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
66 |
else (c, NONE) |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
67 |
| [_] => (c, NONE)) |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
68 |
| NONE => (c, NONE); |
20387 | 69 |
|
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
70 |
fun string_of_const thy (c, NONE) = Sign.extern_const thy c |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
71 |
| string_of_const thy (c, SOME tyco) = Sign.extern_const thy c |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
72 |
^ " " ^ enclose "[" "]" (Sign.extern_type thy tyco); |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
73 |
|
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
74 |
|
22737 | 75 |
(* reading constants as terms and wildcards pattern *) |
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
76 |
|
22921
475ff421a6a3
consts in consts_code Isar commands are now referred to by usual term syntax
haftmann
parents:
22737
diff
changeset
|
77 |
fun read_bare_const thy raw_t = |
20387 | 78 |
let |
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
79 |
val t = Sign.read_term thy raw_t; |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
80 |
in case try dest_Const t |
22921
475ff421a6a3
consts in consts_code Isar commands are now referred to by usual term syntax
haftmann
parents:
22737
diff
changeset
|
81 |
of SOME c_ty => c_ty |
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
82 |
| NONE => error ("Not a constant: " ^ Sign.string_of_term thy t) |
22197 | 83 |
end; |
84 |
||
22921
475ff421a6a3
consts in consts_code Isar commands are now referred to by usual term syntax
haftmann
parents:
22737
diff
changeset
|
85 |
fun read_const thy = const_of_cexpr thy o read_bare_const thy; |
475ff421a6a3
consts in consts_code Isar commands are now referred to by usual term syntax
haftmann
parents:
22737
diff
changeset
|
86 |
|
22737 | 87 |
local |
88 |
||
89 |
fun consts_of thy some_thyname = |
|
90 |
let |
|
91 |
val this_thy = Option.map theory some_thyname |> the_default thy; |
|
92 |
val cs = Symtab.fold (fn (c, (_, NONE)) => cons c | _ => I) |
|
93 |
((snd o #constants o Consts.dest o #consts o Sign.rep_sg) this_thy) []; |
|
94 |
fun classop c = case AxClass.class_of_param thy c |
|
95 |
of NONE => [(c, NONE)] |
|
96 |
| SOME class => Symtab.fold |
|
97 |
(fn (tyco, classes) => if AList.defined (op =) classes class |
|
98 |
then cons (c, SOME tyco) else I) |
|
99 |
((#arities o Sorts.rep_algebra o Sign.classes_of) this_thy) |
|
100 |
[(c, NONE)]; |
|
101 |
val consts = maps classop cs; |
|
102 |
fun test_instance thy (class, tyco) = |
|
103 |
can (Sorts.mg_domain (Sign.classes_of thy) tyco) [class] |
|
104 |
fun belongs_here thyname (c, NONE) = |
|
105 |
not (exists (fn thy' => Sign.declared_const thy' c) (Theory.parents_of this_thy)) |
|
106 |
| belongs_here thyname (c, SOME tyco) = |
|
107 |
let |
|
108 |
val SOME class = AxClass.class_of_param thy c |
|
109 |
in not (exists (fn thy' => test_instance thy' (class, tyco)) |
|
110 |
(Theory.parents_of this_thy)) |
|
111 |
end; |
|
112 |
in case some_thyname |
|
113 |
of NONE => consts |
|
114 |
| SOME thyname => filter (belongs_here thyname) consts |
|
115 |
end; |
|
116 |
||
117 |
fun read_const_expr thy "*" = ([], consts_of thy NONE) |
|
118 |
| read_const_expr thy s = if String.isSuffix ".*" s |
|
119 |
then ([], consts_of thy (SOME (unsuffix ".*" s))) |
|
120 |
else ([read_const thy s], []); |
|
121 |
||
122 |
in |
|
123 |
||
23691 | 124 |
fun read_const_exprs thy select exprs = |
125 |
case (pairself flat o split_list o map (read_const_expr thy)) exprs |
|
126 |
of (consts, []) => (false, consts) |
|
127 |
| (consts, consts') => (true, consts @ select consts'); |
|
22737 | 128 |
|
129 |
end; (*local*) |
|
20387 | 130 |
|
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
131 |
(* conversion between constants, constant expressions and datatype constructors *) |
22508 | 132 |
|
133 |
fun const_of_co thy tyco vs (co, tys) = |
|
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
134 |
const_of_cexpr thy (co, tys ---> Type (tyco, map TFree vs)); |
22508 | 135 |
|
136 |
fun consts_of_cos thy tyco vs cos = |
|
137 |
let |
|
138 |
val dty = Type (tyco, map TFree vs); |
|
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
139 |
fun mk_co (co, tys) = const_of_cexpr thy (co, tys ---> dty); |
22508 | 140 |
in map mk_co cos end; |
141 |
||
142 |
local |
|
143 |
||
144 |
exception BAD of string; |
|
145 |
||
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
146 |
fun mg_typ_of_const thy (c, NONE) = Sign.the_const_type thy c |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
147 |
| mg_typ_of_const thy (c, SOME tyco) = |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
148 |
let |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
149 |
val SOME class = AxClass.class_of_param thy c; |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
150 |
val ty = Sign.the_const_type thy c; |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
151 |
(*an approximation*) |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
152 |
val sorts = Sorts.mg_domain (Sign.classes_of thy) tyco [class] |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
153 |
handle CLASS_ERROR => raise BAD ("No such instance: " ^ tyco ^ " :: " ^ class |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
154 |
^ ",\nrequired for overloaded constant " ^ c); |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
155 |
val vs = Name.invents Name.context "'a" (length sorts); |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
156 |
in map_atyps (K (Type (tyco, map (fn v => TVar ((v, 0), [])) vs))) ty end; |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
157 |
|
22508 | 158 |
fun gen_co_of_const thy const = |
159 |
let |
|
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
160 |
val (c, _) = const; |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
161 |
val ty = (Logic.unvarifyT o mg_typ_of_const thy) const; |
22508 | 162 |
fun err () = raise BAD |
23855 | 163 |
("Illegal type for datatype constructor: " ^ string_of_typ thy ty); |
22508 | 164 |
val (tys, ty') = strip_type ty; |
165 |
val (tyco, vs) = ((apsnd o map) dest_TFree o dest_Type) ty' |
|
166 |
handle TYPE _ => err (); |
|
167 |
val sorts = if has_duplicates (eq_fst op =) vs then err () |
|
168 |
else map snd vs; |
|
169 |
val vs_names = Name.invent_list [] "'a" (length vs); |
|
170 |
val vs_map = map fst vs ~~ vs_names; |
|
171 |
val vs' = vs_names ~~ sorts; |
|
172 |
val tys' = (map o map_type_tfree) (fn (v, sort) => |
|
173 |
(TFree ((the o AList.lookup (op =) vs_map) v, sort))) tys |
|
174 |
handle Option => err (); |
|
175 |
in (tyco, (vs', (c, tys'))) end; |
|
176 |
||
177 |
in |
|
178 |
||
179 |
fun co_of_const thy const = gen_co_of_const thy const handle BAD msg => error msg; |
|
180 |
fun co_of_const' thy const = SOME (gen_co_of_const thy const) handle BAD msg => NONE; |
|
181 |
||
23855 | 182 |
fun no_args thy = length o fst o strip_type o mg_typ_of_const thy; |
183 |
||
22508 | 184 |
end; |
185 |
||
186 |
fun cos_of_consts thy consts = |
|
187 |
let |
|
188 |
val raw_cos = map (co_of_const thy) consts; |
|
189 |
val (tyco, (vs_names, sorts_cos)) = if (length o distinct (eq_fst op =)) raw_cos = 1 |
|
190 |
then ((fst o hd) raw_cos, ((map fst o fst o snd o hd) raw_cos, |
|
191 |
map ((apfst o map) snd o snd) raw_cos)) |
|
192 |
else error ("Term constructors not referring to the same type: " |
|
193 |
^ commas (map (string_of_const thy) consts)); |
|
194 |
val sorts = foldr1 ((uncurry o map2 o curry o Sorts.inter_sort) (Sign.classes_of thy)) |
|
195 |
(map fst sorts_cos); |
|
196 |
val cos = map snd sorts_cos; |
|
197 |
val vs = vs_names ~~ sorts; |
|
198 |
in (tyco, (vs, cos)) end; |
|
199 |
||
200 |
||
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
201 |
(* dictionary values *) |
20387 | 202 |
|
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
203 |
fun typargs thy (c_ty as (c, ty)) = |
20387 | 204 |
let |
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
205 |
val opt_class = AxClass.class_of_param thy c; |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
206 |
val tys = Sign.const_typargs thy (c, ty); |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
207 |
in case (opt_class, tys) |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
208 |
of (SOME class, ty as [Type (tyco, tys')]) => |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
209 |
if can (Sorts.mg_domain (Sign.classes_of thy) tyco) [class] |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
210 |
then tys' else ty |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
211 |
| _ => tys |
20387 | 212 |
end; |
213 |
||
22554
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
214 |
fun typ_sort_inst algebra = |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
215 |
let |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
216 |
val inters = Sorts.inter_sort algebra; |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
217 |
fun match _ [] = I |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
218 |
| match (TVar (v, S)) S' = Vartab.map_default (v, []) (fn S'' => inters (S, inters (S', S''))) |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
219 |
| match (Type (a, Ts)) S = |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
220 |
fold2 match Ts (Sorts.mg_domain algebra a S) |
d1499fff65d8
simplified constant representation in code generator
haftmann
parents:
22508
diff
changeset
|
221 |
in uncurry match end; |
20387 | 222 |
|
223 |
end; |