author | haftmann |
Tue, 09 Jan 2007 08:32:50 +0100 | |
changeset 22039 | 9bc8058250a7 |
parent 22021 | 6466a24dee5b |
child 22185 | 24bf0e403526 |
permissions | -rw-r--r-- |
20600 | 1 |
(* Title: Pure/Tools/codegen_funcgr.ML |
2 |
ID: $Id$ |
|
3 |
Author: Florian Haftmann, TU Muenchen |
|
4 |
||
20855 | 5 |
Retrieving, normalizing and structuring code function theorems |
6 |
in graph with explicit dependencies. |
|
20600 | 7 |
*) |
8 |
||
9 |
signature CODEGEN_FUNCGR = |
|
10 |
sig |
|
11 |
type T; |
|
21120 | 12 |
val make: theory -> CodegenConsts.const list -> T |
21129 | 13 |
val make_term: theory -> ((thm -> thm) -> cterm -> thm -> 'a) -> cterm -> 'a * T |
21120 | 14 |
val funcs: T -> CodegenConsts.const -> thm list |
15 |
val typ: T -> CodegenConsts.const -> typ |
|
16 |
val deps: T -> CodegenConsts.const list -> CodegenConsts.const list list |
|
17 |
val all: T -> CodegenConsts.const list |
|
21989
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
18 |
val norm_varnames: theory -> thm list -> thm list |
20600 | 19 |
val print_codethms: theory -> CodegenConsts.const list -> unit |
20938 | 20 |
structure Constgraph : GRAPH |
20600 | 21 |
end; |
22 |
||
23 |
structure CodegenFuncgr: CODEGEN_FUNCGR = |
|
24 |
struct |
|
25 |
||
26 |
(** code data **) |
|
27 |
||
28 |
structure Consttab = CodegenConsts.Consttab; |
|
29 |
structure Constgraph = GraphFun ( |
|
30 |
type key = CodegenConsts.const; |
|
31 |
val ord = CodegenConsts.const_ord; |
|
32 |
); |
|
33 |
||
34 |
type T = (typ * thm list) Constgraph.T; |
|
35 |
||
36 |
structure Funcgr = CodeDataFun |
|
37 |
(struct |
|
38 |
val name = "Pure/codegen_funcgr"; |
|
39 |
type T = T; |
|
40 |
val empty = Constgraph.empty; |
|
41 |
fun merge _ _ = Constgraph.empty; |
|
20938 | 42 |
fun purge _ NONE _ = Constgraph.empty |
43 |
| purge _ (SOME cs) funcgr = |
|
21463
42dd50268c8b
completed class parameter handling in axclass.ML
haftmann
parents:
21387
diff
changeset
|
44 |
Constgraph.del_nodes ((Constgraph.all_preds funcgr |
20938 | 45 |
o filter (can (Constgraph.get_node funcgr))) cs) funcgr; |
20600 | 46 |
end); |
47 |
||
48 |
val _ = Context.add_setup Funcgr.init; |
|
49 |
||
50 |
||
51 |
(** theorem purification **) |
|
52 |
||
22039 | 53 |
fun norm_args thms = |
21989
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
54 |
let |
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
55 |
val num_args_of = length o snd o strip_comb o fst o Logic.dest_equals; |
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
56 |
val k = fold (curry Int.max o num_args_of o Drule.plain_prop_of) thms 0; |
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
57 |
in |
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
58 |
thms |
22039 | 59 |
|> map (CodegenFunc.expand_eta k) |
21989
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
60 |
|> map (Drule.fconv_rule Drule.beta_eta_conversion) |
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
61 |
end; |
21120 | 62 |
|
22039 | 63 |
fun canonical_tvars thm = |
20600 | 64 |
let |
22039 | 65 |
val ctyp = Thm.ctyp_of (Thm.theory_of_thm thm); |
21159 | 66 |
fun tvars_subst_for thm = (fold_types o fold_atyps) |
67 |
(fn TVar (v_i as (v, _), sort) => let |
|
21915 | 68 |
val v' = CodegenNames.purify_tvar v |
21159 | 69 |
in if v = v' then I |
70 |
else insert (op =) (v_i, (v', sort)) end |
|
20600 | 71 |
| _ => I) (prop_of thm) []; |
21159 | 72 |
fun mk_inst (v_i, (v', sort)) (maxidx, acc) = |
73 |
let |
|
74 |
val ty = TVar (v_i, sort) |
|
75 |
in |
|
22039 | 76 |
(maxidx + 1, (ctyp ty, ctyp (TVar ((v', maxidx), sort))) :: acc) |
21159 | 77 |
end; |
20600 | 78 |
val maxidx = Thm.maxidx_of thm + 1; |
21159 | 79 |
val (_, inst) = fold mk_inst (tvars_subst_for thm) (maxidx + 1, []); |
20600 | 80 |
in Thm.instantiate (inst, []) thm end; |
81 |
||
22039 | 82 |
fun canonical_vars thm = |
20600 | 83 |
let |
22039 | 84 |
val cterm = Thm.cterm_of (Thm.theory_of_thm thm); |
21159 | 85 |
fun vars_subst_for thm = fold_aterms |
86 |
(fn Var (v_i as (v, _), ty) => let |
|
87 |
val v' = CodegenNames.purify_var v |
|
88 |
in if v = v' then I |
|
89 |
else insert (op =) (v_i, (v', ty)) end |
|
20600 | 90 |
| _ => I) (prop_of thm) []; |
21159 | 91 |
fun mk_inst (v_i as (v, i), (v', ty)) (maxidx, acc) = |
92 |
let |
|
93 |
val t = Var (v_i, ty) |
|
94 |
in |
|
22039 | 95 |
(maxidx + 1, (cterm t, cterm (Var ((v', maxidx), ty))) :: acc) |
21159 | 96 |
end; |
20600 | 97 |
val maxidx = Thm.maxidx_of thm + 1; |
21159 | 98 |
val (_, inst) = fold mk_inst (vars_subst_for thm) (maxidx + 1, []); |
20600 | 99 |
in Thm.instantiate ([], inst) thm end; |
100 |
||
22039 | 101 |
fun canonical_absvars thm = |
102 |
let |
|
103 |
val t = Thm.prop_of thm; |
|
104 |
val t' = Term.map_abs_vars CodegenNames.purify_var t; |
|
105 |
in Thm.rename_boundvars t t' thm end; |
|
106 |
||
21989
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
107 |
fun norm_varnames thy thms = |
20600 | 108 |
let |
109 |
fun burrow_thms f [] = [] |
|
110 |
| burrow_thms f thms = |
|
111 |
thms |
|
112 |
|> Conjunction.intr_list |
|
113 |
|> f |
|
114 |
|> Conjunction.elim_list; |
|
115 |
in |
|
116 |
thms |
|
22039 | 117 |
|> norm_args |
118 |
|> burrow_thms canonical_tvars |
|
119 |
|> map canonical_vars |
|
120 |
|> map canonical_absvars |
|
21159 | 121 |
|> map Drule.zero_var_indexes |
20600 | 122 |
end; |
123 |
||
124 |
||
125 |
||
126 |
(** retrieval **) |
|
127 |
||
21120 | 128 |
fun funcs funcgr = |
129 |
these o Option.map snd o try (Constgraph.get_node funcgr); |
|
20600 | 130 |
|
21120 | 131 |
fun typ funcgr = |
132 |
fst o Constgraph.get_node funcgr; |
|
20600 | 133 |
|
21120 | 134 |
fun deps funcgr cs = |
20835 | 135 |
let |
136 |
val conn = Constgraph.strong_conn funcgr; |
|
137 |
val order = rev conn; |
|
138 |
in |
|
139 |
(map o filter) (member (op =) (Constgraph.all_succs funcgr cs)) order |
|
140 |
|> filter_out null |
|
141 |
end; |
|
142 |
||
21120 | 143 |
fun all funcgr = Constgraph.keys funcgr; |
144 |
||
20600 | 145 |
local |
146 |
||
147 |
fun add_things_of thy f (c, thms) = |
|
148 |
(fold o fold_aterms) |
|
149 |
(fn Const c_ty => let |
|
150 |
val c' = CodegenConsts.norm_of_typ thy c_ty |
|
21120 | 151 |
in if is_some c andalso CodegenConsts.eq_const (the c, c') then I |
20600 | 152 |
else f (c', c_ty) end |
153 |
| _ => I) (maps (op :: o swap o apfst (snd o strip_comb) |
|
154 |
o Logic.dest_equals o Drule.plain_prop_of) thms) |
|
155 |
||
156 |
fun rhs_of thy (c, thms) = |
|
157 |
Consttab.empty |
|
22039 | 158 |
|> add_things_of thy (Consttab.update o rpair () o fst) (c, thms) |
20600 | 159 |
|> Consttab.keys; |
160 |
||
22039 | 161 |
fun rhs_of' thy (c, thms) = |
162 |
add_things_of thy (cons o snd) (c, thms) []; |
|
163 |
||
20600 | 164 |
fun insts_of thy funcgr (c, ty) = |
165 |
let |
|
166 |
val tys = Sign.const_typargs thy (c, ty); |
|
167 |
val c' = CodegenConsts.norm thy (c, tys); |
|
20705 | 168 |
val ty_decl = CodegenConsts.disc_typ_of_const thy |
169 |
(fst o Constgraph.get_node funcgr o CodegenConsts.norm thy) (c, tys); |
|
20600 | 170 |
val tys_decl = Sign.const_typargs thy (c, ty_decl); |
171 |
fun constructor tyco xs class = |
|
172 |
(tyco, class) :: maps (maps fst) xs; |
|
173 |
fun variable (TVar (_, sort)) = map (pair []) sort |
|
174 |
| variable (TFree (_, sort)) = map (pair []) sort; |
|
175 |
fun mk_inst ty (TVar (_, sort)) = cons (ty, sort) |
|
176 |
| mk_inst ty (TFree (_, sort)) = cons (ty, sort) |
|
177 |
| mk_inst (Type (tyco1, tys1)) (Type (tyco2, tys2)) = |
|
178 |
if tyco1 <> tyco2 then error "bad instance" |
|
179 |
else fold2 mk_inst tys1 tys2; |
|
21120 | 180 |
val pp = Sign.pp thy; |
181 |
val algebra = Sign.classes_of thy; |
|
182 |
fun classrel (x, _) _ = x; |
|
183 |
fun of_sort_deriv (ty, sort) = |
|
184 |
Sorts.of_sort_derivation pp algebra |
|
185 |
{ classrel = classrel, constructor = constructor, variable = variable } |
|
186 |
(ty, sort) |
|
20600 | 187 |
in |
21120 | 188 |
flat (maps of_sort_deriv (fold2 mk_inst tys tys_decl [])) |
20600 | 189 |
end; |
190 |
||
22039 | 191 |
exception MISSING_INSTANCE of string * string; (*FIXME provide reasonable error tracking*) |
192 |
||
20600 | 193 |
fun all_classops thy tyco class = |
22039 | 194 |
if can (Sign.arity_sorts thy tyco) [class] |
195 |
then |
|
196 |
try (AxClass.params_of_class thy) class |
|
197 |
|> Option.map snd |
|
198 |
|> these |
|
199 |
|> map (fn (c, _) => (c, CodegenConsts.disc_typ_of_classop thy (c, [Type (tyco, [])]))) |
|
200 |
|> map (CodegenConsts.norm_of_typ thy) |
|
201 |
else raise MISSING_INSTANCE (tyco, class); |
|
20600 | 202 |
|
203 |
fun instdefs_of thy insts = |
|
204 |
let |
|
205 |
val thy_classes = (#classes o Sorts.rep_algebra o Sign.classes_of) thy; |
|
206 |
in |
|
207 |
Symtab.empty |
|
208 |
|> fold (fn (tyco, class) => |
|
209 |
Symtab.map_default (tyco, []) (insert (op =) class)) insts |
|
210 |
|> (fn tab => Symtab.fold (fn (tyco, classes) => append (maps (all_classops thy tyco) |
|
211 |
(Graph.all_succs thy_classes classes))) tab []) |
|
212 |
end; |
|
213 |
||
21120 | 214 |
fun insts_of_thms thy funcgr (c, thms) = |
20600 | 215 |
let |
216 |
val insts = add_things_of thy (fn (_, c_ty) => fold (insert (op =)) |
|
21120 | 217 |
(insts_of thy funcgr c_ty)) (SOME c, thms) []; |
22039 | 218 |
in |
219 |
instdefs_of thy insts handle MISSING_INSTANCE (tyco, class) => |
|
220 |
error ("No such instance: " ^ quote tyco ^ ", " ^ quote class |
|
221 |
^ "\nin function theorems\n" |
|
222 |
^ (cat_lines o map string_of_thm) thms) |
|
223 |
end; |
|
20600 | 224 |
|
225 |
fun ensure_const thy funcgr c auxgr = |
|
226 |
if can (Constgraph.get_node funcgr) c |
|
227 |
then (NONE, auxgr) |
|
228 |
else if can (Constgraph.get_node auxgr) c |
|
229 |
then (SOME c, auxgr) |
|
230 |
else if is_some (CodegenData.get_datatype_of_constr thy c) then |
|
231 |
auxgr |
|
232 |
|> Constgraph.new_node (c, []) |
|
233 |
|> pair (SOME c) |
|
234 |
else let |
|
21989
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
235 |
val thms = norm_varnames thy (CodegenData.these_funcs thy c); |
22039 | 236 |
val rhs = rhs_of thy (SOME c, thms); |
20600 | 237 |
in |
238 |
auxgr |
|
239 |
|> Constgraph.new_node (c, thms) |
|
240 |
|> fold_map (ensure_const thy funcgr) rhs |
|
241 |
|-> (fn rhs' => fold (fn SOME c' => Constgraph.add_edge (c, c') |
|
242 |
| NONE => I) rhs') |
|
243 |
|> pair (SOME c) |
|
244 |
end; |
|
245 |
||
22039 | 246 |
exception INVALID of CodegenConsts.const list * string; (*FIXME provide reasonable error tracking*) |
21387
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
247 |
|
22039 | 248 |
(*FIXME: clarify algorithm*) |
249 |
fun specialize_typs' thy funcgr eqss = |
|
20600 | 250 |
let |
22039 | 251 |
fun max xs = fold (curry Int.max) xs 0; |
21387
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
252 |
fun incr_indices (c, thms) maxidx = |
20600 | 253 |
let |
21387
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
254 |
val thms' = map (Thm.incr_indexes (maxidx + 1)) thms; |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
255 |
val maxidx' = max (maxidx :: map Thm.maxidx_of thms'); |
20600 | 256 |
in ((c, thms'), maxidx') end; |
21387
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
257 |
val (eqss', maxidx) = |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
258 |
fold_map incr_indices eqss 0; |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
259 |
fun unify_const (c, ty) (env, maxidx) = |
22039 | 260 |
case try (Constgraph.get_node funcgr) (CodegenConsts.norm_of_typ thy (c, ty)) |
261 |
of SOME (ty_decl, _) => let |
|
21387
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
262 |
val ty_decl' = Logic.incr_tvar (maxidx + 1) ty_decl; |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
263 |
val maxidx' = max [maxidx, Term.maxidx_of_typ ty_decl']; |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
264 |
in Type.unify (Sign.tsig_of thy) (ty_decl', ty) (env, maxidx') |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
265 |
handle TUNIFY => raise INVALID ([], setmp show_sorts true (setmp show_types true (fn f => f ())) (fn _ => ("Failed to instantiate\n" |
20600 | 266 |
^ (Sign.string_of_typ thy o Envir.norm_type env) ty_decl' ^ "\nto\n" |
21387
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
267 |
^ (Sign.string_of_typ thy o Envir.norm_type env) ty |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
268 |
^ ",\nfor constant " ^ quote c |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
269 |
^ "\nin function theorems\n" |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
270 |
^ (cat_lines o maps (map (Sign.string_of_term thy o map_types (Envir.norm_type env) o Thm.prop_of) o snd)) eqss'))) |
20600 | 271 |
end |
272 |
| NONE => (env, maxidx); |
|
273 |
fun apply_unifier unif (c, []) = (c, []) |
|
274 |
| apply_unifier unif (c, thms as thm :: _) = |
|
275 |
let |
|
21120 | 276 |
val tvars = Term.add_tvars (Thm.prop_of thm) []; |
277 |
fun mk_inst (v_i_sort as (v, _)) = |
|
278 |
let |
|
279 |
val ty = TVar v_i_sort; |
|
280 |
in |
|
281 |
pairself (Thm.ctyp_of thy) (ty, |
|
282 |
TVar (v, (snd o dest_TVar o Envir.norm_type unif) ty)) |
|
283 |
end; |
|
284 |
val instmap = map mk_inst tvars; |
|
21387
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
285 |
val (thms' as thm' :: _) = map (Drule.zero_var_indexes o Thm.instantiate (instmap, [])) thms; |
22039 | 286 |
val _ = case c of NONE => () |
287 |
| SOME c => (case pairself CodegenFunc.typ_func (thm, thm') |
|
21989
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
288 |
of (ty, ty') => if (is_none o AxClass.class_of_param thy o fst) c |
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
289 |
andalso Sign.typ_equiv thy (Type.strip_sorts ty, Type.strip_sorts ty') |
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
290 |
orelse Sign.typ_equiv thy (ty, ty') |
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
291 |
then () |
22039 | 292 |
else raise INVALID ([], "illegal function type instantiation:\n" ^ Sign.string_of_typ thy (CodegenFunc.typ_func thm) |
293 |
^ "\nto " ^ Sign.string_of_typ thy (CodegenFunc.typ_func thm') |
|
21989
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
294 |
^ ",\nfor constant " ^ CodegenConsts.string_of_const thy c |
0315ecfd3d5d
eta-expansion now only to common maximum number of arguments
haftmann
parents:
21915
diff
changeset
|
295 |
^ "\nin function theorems\n" |
22039 | 296 |
^ (cat_lines o map string_of_thm) thms)) |
21120 | 297 |
in (c, thms') end; |
20600 | 298 |
val (unif, _) = |
21387
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
299 |
fold (fn (c, thms) => fold unify_const (rhs_of' thy (c, thms))) |
20600 | 300 |
eqss' (Vartab.empty, maxidx); |
22039 | 301 |
val eqss'' = map (apply_unifier unif) eqss'; |
20600 | 302 |
in eqss'' end; |
303 |
||
22039 | 304 |
fun specialize_typs thy funcgr = |
305 |
(map o apfst) SOME |
|
306 |
#> specialize_typs' thy funcgr |
|
307 |
#> (map o apfst) the; |
|
308 |
||
20600 | 309 |
fun merge_eqsyss thy raw_eqss funcgr = |
310 |
let |
|
311 |
val eqss = specialize_typs thy funcgr raw_eqss; |
|
20938 | 312 |
val tys = map (CodegenData.typ_funcs thy) eqss; |
22039 | 313 |
val rhss = map (rhs_of thy o apfst SOME) eqss; |
20600 | 314 |
in |
315 |
funcgr |
|
316 |
|> fold2 (fn (c, thms) => fn ty => Constgraph.new_node (c, (ty, thms))) eqss tys |
|
317 |
|> `(fn funcgr => map (insts_of_thms thy funcgr) eqss) |
|
318 |
|-> (fn rhs_insts => fold2 (fn (c, _) => fn rhs_inst => |
|
319 |
ensure_consts thy rhs_inst #> fold (curry Constgraph.add_edge c) rhs_inst) eqss rhs_insts) |
|
320 |
|> fold2 (fn (c, _) => fn rhs => fold (curry Constgraph.add_edge c) rhs) eqss rhss |
|
321 |
end |
|
20705 | 322 |
and merge_new_eqsyss thy raw_eqss funcgr = |
323 |
if exists (member CodegenConsts.eq_const (Constgraph.keys funcgr)) (map fst raw_eqss) |
|
324 |
then funcgr |
|
325 |
else merge_eqsyss thy raw_eqss funcgr |
|
20600 | 326 |
and ensure_consts thy cs funcgr = |
327 |
fold (snd oo ensure_const thy funcgr) cs Constgraph.empty |
|
20705 | 328 |
|> (fn auxgr => fold (merge_new_eqsyss thy) |
20600 | 329 |
(map (AList.make (Constgraph.get_node auxgr)) |
21387
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
330 |
(rev (Constgraph.strong_conn auxgr))) funcgr) |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
331 |
handle INVALID (cs', msg) => raise INVALID (cs @ cs', msg); |
20600 | 332 |
|
21120 | 333 |
fun drop_classes thy tfrees thm = |
334 |
let |
|
335 |
val (_, thm') = Thm.varifyT' [] thm; |
|
336 |
val tvars = Term.add_tvars (Thm.prop_of thm') []; |
|
337 |
val unconstr = map (Thm.ctyp_of thy o TVar) tvars; |
|
338 |
val instmap = map2 (fn (v_i, _) => fn (v, sort) => pairself (Thm.ctyp_of thy) |
|
339 |
(TVar (v_i, []), TFree (v, sort))) tvars tfrees; |
|
340 |
in |
|
341 |
thm' |
|
342 |
|> fold Thm.unconstrainT unconstr |
|
343 |
|> Thm.instantiate (instmap, []) |
|
344 |
|> Tactic.rule_by_tactic ((REPEAT o CHANGED o ALLGOALS o Tactic.resolve_tac) (AxClass.class_intros thy)) |
|
345 |
end; |
|
346 |
||
20600 | 347 |
in |
348 |
||
21387
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
349 |
val ensure_consts = (fn thy => fn cs => fn funcgr => ensure_consts thy |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
350 |
cs funcgr handle INVALID (cs', msg) => error (msg ^ ",\nwhile preprocessing equations for constant(s) " |
5d3d340cb783
clarified code for building function equation system; explicit check of type discipline
haftmann
parents:
21196
diff
changeset
|
351 |
^ commas (map (CodegenConsts.string_of_const thy) cs'))); |
20600 | 352 |
|
21120 | 353 |
fun make thy consts = |
354 |
Funcgr.change thy (ensure_consts thy consts); |
|
355 |
||
21129 | 356 |
fun make_term thy f ct = |
21120 | 357 |
let |
358 |
val _ = Sign.no_vars (Sign.pp thy) (Thm.term_of ct); |
|
359 |
val _ = Term.fold_types (Type.no_tvars #> K I) (Thm.term_of ct) (); |
|
22039 | 360 |
val thm1 = CodegenData.preprocess_cterm ct; |
21120 | 361 |
val ct' = Drule.dest_equals_rhs (Thm.cprop_of thm1); |
362 |
val consts = CodegenConsts.consts_of thy (Thm.term_of ct'); |
|
363 |
val funcgr = make thy consts; |
|
364 |
val (_, thm2) = Thm.varifyT' [] thm1; |
|
365 |
val thm3 = Thm.reflexive (Drule.dest_equals_rhs (Thm.cprop_of thm2)); |
|
22039 | 366 |
val [(_, [thm4])] = specialize_typs' thy funcgr [(NONE, [thm3])]; |
21120 | 367 |
val tfrees = Term.add_tfrees (Thm.prop_of thm1) []; |
368 |
fun inst thm = |
|
369 |
let |
|
370 |
val tvars = Term.add_tvars (Thm.prop_of thm) []; |
|
371 |
val instmap = map2 (fn (v_i, sort) => fn (v, _) => pairself (Thm.ctyp_of thy) |
|
372 |
(TVar (v_i, sort), TFree (v, sort))) tvars tfrees; |
|
373 |
in Thm.instantiate (instmap, []) thm end; |
|
374 |
val thm5 = inst thm2; |
|
375 |
val thm6 = inst thm4; |
|
376 |
val ct'' = Drule.dest_equals_rhs (Thm.cprop_of thm6); |
|
377 |
val cs = fold_aterms (fn Const c => cons c | _ => I) (Thm.term_of ct'') []; |
|
378 |
val drop = drop_classes thy tfrees; |
|
22039 | 379 |
val instdefs = instdefs_of thy (fold (fold (insert (op =)) o insts_of thy funcgr) cs []) |
380 |
handle MISSING_INSTANCE (tyco, class) => |
|
381 |
error ("No such instance: " ^ quote tyco ^ ", " ^ quote class |
|
382 |
^ "\nwhile prcoessing term\n" |
|
383 |
^ string_of_cterm ct) |
|
384 |
val funcgr' = ensure_consts thy instdefs funcgr; |
|
21129 | 385 |
in (f drop ct'' thm5, Funcgr.change thy (K funcgr')) end; |
20600 | 386 |
|
387 |
end; (*local*) |
|
388 |
||
389 |
fun print_funcgr thy funcgr = |
|
390 |
AList.make (snd o Constgraph.get_node funcgr) (Constgraph.keys funcgr) |
|
391 |
|> (map o apfst) (CodegenConsts.string_of_const thy) |
|
392 |
|> sort (string_ord o pairself fst) |
|
393 |
|> map (fn (s, thms) => |
|
394 |
(Pretty.block o Pretty.fbreaks) ( |
|
395 |
Pretty.str s |
|
396 |
:: map Display.pretty_thm thms |
|
397 |
)) |
|
398 |
|> Pretty.chunks |
|
399 |
|> Pretty.writeln; |
|
400 |
||
401 |
fun print_codethms thy consts = |
|
21120 | 402 |
make thy consts |> print_funcgr thy; |
20600 | 403 |
|
404 |
fun print_codethms_e thy cs = |
|
405 |
print_codethms thy (map (CodegenConsts.read_const thy) cs); |
|
406 |
||
407 |
||
408 |
(** Isar **) |
|
409 |
||
410 |
structure P = OuterParse; |
|
411 |
||
412 |
val print_codethmsK = "print_codethms"; |
|
413 |
||
414 |
val print_codethmsP = |
|
415 |
OuterSyntax.improper_command print_codethmsK "print code theorems of this theory" OuterKeyword.diag |
|
416 |
(Scan.option (P.$$$ "(" |-- Scan.repeat P.term --| P.$$$ ")") |
|
417 |
>> (fn NONE => CodegenData.print_thms |
|
418 |
| SOME cs => fn thy => print_codethms_e thy cs) |
|
419 |
>> (fn f => Toplevel.no_timing o Toplevel.unknown_theory |
|
420 |
o Toplevel.keep (f o Toplevel.theory_of))); |
|
421 |
||
422 |
val _ = OuterSyntax.add_parsers [print_codethmsP]; |
|
423 |
||
424 |
end; (*struct*) |