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