5 Code generator translation kernel. Code generator Isar setup. |
5 Code generator translation kernel. Code generator Isar setup. |
6 *) |
6 *) |
7 |
7 |
8 signature CODEGEN_PACKAGE = |
8 signature CODEGEN_PACKAGE = |
9 sig |
9 sig |
10 val compile_term: theory -> term -> CodegenThingol.code * CodegenThingol.iterm; |
10 (* interfaces *) |
|
11 val eval_conv: theory |
|
12 -> (CodegenThingol.code -> CodegenThingol.iterm -> cterm -> thm) -> cterm -> thm; |
|
13 val codegen_command: theory -> string -> unit; |
|
14 |
|
15 (* primitive interfaces *) |
11 val eval_term: theory -> (string (*reference name!*) * 'a option ref) * term -> 'a; |
16 val eval_term: theory -> (string (*reference name!*) * 'a option ref) * term -> 'a; |
12 val satisfies_ref: bool option ref; |
17 val satisfies_ref: bool option ref; |
13 val satisfies: theory -> term -> string list -> bool; |
18 val satisfies: theory -> term -> string list -> bool; |
14 val codegen_command: theory -> string -> unit; |
19 |
15 |
20 (* axiomatic interfaces *) |
16 (*axiomatic interfaces*) |
|
17 type appgen; |
21 type appgen; |
18 val add_appconst: string * appgen -> theory -> theory; |
22 val add_appconst: string * appgen -> theory -> theory; |
19 val appgen_let: appgen; |
23 val appgen_let: appgen; |
|
24 val appgen_if: appgen; |
20 val appgen_case: (theory -> term |
25 val appgen_case: (theory -> term |
21 -> ((string * typ) list * ((term * typ) * (term * term) list)) option) |
26 -> ((string * typ) list * ((term * typ) * (term * term) list)) option) |
22 -> appgen; |
27 -> appgen; |
23 |
28 |
24 val timing: bool ref; |
29 val timing: bool ref; |
123 val class' = CodegenNames.class thy class; |
128 val class' = CodegenNames.class thy class; |
124 val classrels' = map (curry (CodegenNames.classrel thy) class) superclasses; |
129 val classrels' = map (curry (CodegenNames.classrel thy) class) superclasses; |
125 val classops' = map (CodegenNames.const thy o CodegenConsts.const_of_cexpr thy) cs; |
130 val classops' = map (CodegenNames.const thy o CodegenConsts.const_of_cexpr thy) cs; |
126 val defgen_class = |
131 val defgen_class = |
127 fold_map (ensure_def_class thy algbr funcgr) superclasses |
132 fold_map (ensure_def_class thy algbr funcgr) superclasses |
128 ##>> (fold_map (exprgen_type thy algbr funcgr) o map snd) cs |
133 ##>> (fold_map (exprgen_typ thy algbr funcgr) o map snd) cs |
129 #-> (fn (superclasses, classoptyps) => succeed |
134 #-> (fn (superclasses, classoptyps) => succeed |
130 (CodegenThingol.Class (superclasses ~~ classrels', (unprefix "'" v, classops' ~~ classoptyps)))) |
135 (CodegenThingol.Class (superclasses ~~ classrels', (unprefix "'" v, classops' ~~ classoptyps)))) |
131 in |
136 in |
132 tracing (fn _ => "generating class " ^ quote class) |
137 tracing (fn _ => "generating class " ^ quote class) |
133 #> ensure_def thy defgen_class ("generating class " ^ quote class) class' |
138 #> ensure_def thy defgen_class ("generating class " ^ quote class) class' |
146 val (vs, cos) = CodegenData.get_datatype thy tyco; |
151 val (vs, cos) = CodegenData.get_datatype thy tyco; |
147 in |
152 in |
148 trns |
153 trns |
149 |> fold_map (exprgen_tyvar_sort thy algbr funcgr) vs |
154 |> fold_map (exprgen_tyvar_sort thy algbr funcgr) vs |
150 ||>> fold_map (fn (c, tys) => |
155 ||>> fold_map (fn (c, tys) => |
151 fold_map (exprgen_type thy algbr funcgr) tys |
156 fold_map (exprgen_typ thy algbr funcgr) tys |
152 #-> (fn tys' => |
157 #-> (fn tys' => |
153 pair ((CodegenNames.const thy o CodegenConsts.const_of_cexpr thy) |
158 pair ((CodegenNames.const thy o CodegenConsts.const_of_cexpr thy) |
154 (c, tys ---> Type (tyco, map TFree vs)), tys'))) cos |
159 (c, tys ---> Type (tyco, map TFree vs)), tys'))) cos |
155 |-> (fn (vs, cos) => succeed (CodegenThingol.Datatype (vs, cos))) |
160 |-> (fn (vs, cos) => succeed (CodegenThingol.Datatype (vs, cos))) |
156 end; |
161 end; |
163 end |
168 end |
164 and exprgen_tyvar_sort thy (algbr as ((proj_sort, _), _)) funcgr (v, sort) trns = |
169 and exprgen_tyvar_sort thy (algbr as ((proj_sort, _), _)) funcgr (v, sort) trns = |
165 trns |
170 trns |
166 |> fold_map (ensure_def_class thy algbr funcgr) (proj_sort sort) |
171 |> fold_map (ensure_def_class thy algbr funcgr) (proj_sort sort) |
167 |>> (fn sort => (unprefix "'" v, sort)) |
172 |>> (fn sort => (unprefix "'" v, sort)) |
168 and exprgen_type thy algbr funcgr (TFree vs) trns = |
173 and exprgen_typ thy algbr funcgr (TFree vs) trns = |
169 trns |
174 trns |
170 |> exprgen_tyvar_sort thy algbr funcgr vs |
175 |> exprgen_tyvar_sort thy algbr funcgr vs |
171 |>> (fn (v, sort) => ITyVar v) |
176 |>> (fn (v, sort) => ITyVar v) |
172 | exprgen_type thy algbr funcgr (Type (tyco, tys)) trns = |
177 | exprgen_typ thy algbr funcgr (Type (tyco, tys)) trns = |
173 case get_abstype thy (tyco, tys) |
178 case get_abstype thy (tyco, tys) |
174 of SOME ty => |
179 of SOME ty => |
175 trns |
180 trns |
176 |> exprgen_type thy algbr funcgr ty |
181 |> exprgen_typ thy algbr funcgr ty |
177 | NONE => |
182 | NONE => |
178 trns |
183 trns |
179 |> ensure_def_tyco thy algbr funcgr tyco |
184 |> ensure_def_tyco thy algbr funcgr tyco |
180 ||>> fold_map (exprgen_type thy algbr funcgr) tys |
185 ||>> fold_map (exprgen_typ thy algbr funcgr) tys |
181 |>> (fn (tyco, tys) => tyco `%% tys); |
186 |>> (fn (tyco, tys) => tyco `%% tys); |
182 |
187 |
183 exception CONSTRAIN of (string * typ) * typ; |
188 exception CONSTRAIN of (string * typ) * typ; |
184 val timing = ref false; |
189 val timing = ref false; |
185 |
190 |
289 in |
294 in |
290 trns |
295 trns |
291 |> CodegenThingol.message msg (fn trns => trns |
296 |> CodegenThingol.message msg (fn trns => trns |
292 |> timeap (fold_map (exprgen_eq o dest_eqthm) thms) |
297 |> timeap (fold_map (exprgen_eq o dest_eqthm) thms) |
293 ||>> fold_map (exprgen_tyvar_sort thy algbr funcgr) vs |
298 ||>> fold_map (exprgen_tyvar_sort thy algbr funcgr) vs |
294 ||>> exprgen_type thy algbr funcgr ty |
299 ||>> exprgen_typ thy algbr funcgr ty |
295 |-> (fn ((eqs, vs), ty) => succeed (CodegenThingol.Fun (eqs, (vs, ty))))) |
300 |-> (fn ((eqs, vs), ty) => succeed (CodegenThingol.Fun (eqs, (vs, ty))))) |
296 end; |
301 end; |
297 val defgen = if (is_some o CodegenData.get_datatype_of_constr thy) const |
302 val defgen = if (is_some o CodegenData.get_datatype_of_constr thy) const |
298 then defgen_datatypecons |
303 then defgen_datatypecons |
299 else if is_some opt_tyco |
304 else if is_some opt_tyco |
310 and exprgen_term thy algbr funcgr (Const (c, ty)) trns = |
315 and exprgen_term thy algbr funcgr (Const (c, ty)) trns = |
311 trns |
316 trns |
312 |> select_appgen thy algbr funcgr ((c, ty), []) |
317 |> select_appgen thy algbr funcgr ((c, ty), []) |
313 | exprgen_term thy algbr funcgr (Free (v, ty)) trns = |
318 | exprgen_term thy algbr funcgr (Free (v, ty)) trns = |
314 trns |
319 trns |
315 |> exprgen_type thy algbr funcgr ty |
320 |> exprgen_typ thy algbr funcgr ty |
316 |>> (fn _ => IVar v) |
321 |>> (fn _ => IVar v) |
317 | exprgen_term thy algbr funcgr (Abs (raw_v, ty, raw_t)) trns = |
322 | exprgen_term thy algbr funcgr (Abs (raw_v, ty, raw_t)) trns = |
318 let |
323 let |
319 val (v, t) = Syntax.variant_abs (raw_v, ty, raw_t); |
324 val (v, t) = Syntax.variant_abs (raw_v, ty, raw_t); |
320 in |
325 in |
321 trns |
326 trns |
322 |> exprgen_type thy algbr funcgr ty |
327 |> exprgen_typ thy algbr funcgr ty |
323 ||>> exprgen_term thy algbr funcgr t |
328 ||>> exprgen_term thy algbr funcgr t |
324 |>> (fn (ty, t) => (v, ty) `|-> t) |
329 |>> (fn (ty, t) => (v, ty) `|-> t) |
325 end |
330 end |
326 | exprgen_term thy algbr funcgr (t as _ $ _) trns = |
331 | exprgen_term thy algbr funcgr (t as _ $ _) trns = |
327 case strip_comb t |
332 case strip_comb t |
334 ||>> fold_map (exprgen_term thy algbr funcgr) ts |
339 ||>> fold_map (exprgen_term thy algbr funcgr) ts |
335 |>> (fn (t, ts) => t `$$ ts) |
340 |>> (fn (t, ts) => t `$$ ts) |
336 and appgen_default thy algbr funcgr ((c, ty), ts) trns = |
341 and appgen_default thy algbr funcgr ((c, ty), ts) trns = |
337 trns |
342 trns |
338 |> ensure_def_const thy algbr funcgr (CodegenConsts.const_of_cexpr thy (c, ty)) |
343 |> ensure_def_const thy algbr funcgr (CodegenConsts.const_of_cexpr thy (c, ty)) |
339 ||>> fold_map (exprgen_type thy algbr funcgr) ((fst o Term.strip_type) ty) |
344 ||>> fold_map (exprgen_typ thy algbr funcgr) ((fst o Term.strip_type) ty) |
340 ||>> exprgen_type thy algbr funcgr ((snd o Term.strip_type) ty) |
345 ||>> exprgen_typ thy algbr funcgr ((snd o Term.strip_type) ty) |
341 ||>> exprgen_dict_parms thy algbr funcgr (c, ty) |
346 ||>> exprgen_dict_parms thy algbr funcgr (c, ty) |
342 ||>> fold_map (exprgen_term thy algbr funcgr) ts |
347 ||>> fold_map (exprgen_term thy algbr funcgr) ts |
343 |>> (fn ((((c, tys), ty), iss), ts) => IConst (c, (iss, tys)) `$$ ts) |
348 |>> (fn ((((c, tys), ty), iss), ts) => IConst (c, (iss, tys)) `$$ ts) |
344 and select_appgen thy algbr funcgr ((c, ty), ts) trns = |
349 and select_appgen thy algbr funcgr ((c, ty), ts) trns = |
345 case Symtab.lookup (fst (Translation.get thy)) c |
350 case Symtab.lookup (fst (Translation.get thy)) c |
351 val ctxt = (fold o fold_aterms) |
356 val ctxt = (fold o fold_aterms) |
352 (fn Free (v, _) => Name.declare v | _ => I) ts Name.context; |
357 (fn Free (v, _) => Name.declare v | _ => I) ts Name.context; |
353 val vs = Name.names ctxt "a" tys; |
358 val vs = Name.names ctxt "a" tys; |
354 in |
359 in |
355 trns |
360 trns |
356 |> fold_map (exprgen_type thy algbr funcgr) tys |
361 |> fold_map (exprgen_typ thy algbr funcgr) tys |
357 ||>> appgen thy algbr funcgr ((c, ty), ts @ map Free vs) |
362 ||>> appgen thy algbr funcgr ((c, ty), ts @ map Free vs) |
358 |>> (fn (tys, t) => map2 (fn (v, _) => pair v) vs tys `|--> t) |
363 |>> (fn (tys, t) => map2 (fn (v, _) => pair v) vs tys `|--> t) |
359 end |
364 end |
360 else if length ts > i then |
365 else if length ts > i then |
361 trns |
366 trns |
395 |
400 |
396 |
401 |
397 (* parametrized application generators, for instantiation in object logic *) |
402 (* parametrized application generators, for instantiation in object logic *) |
398 (* (axiomatic extensions of translation kernel) *) |
403 (* (axiomatic extensions of translation kernel) *) |
399 |
404 |
400 fun appgen_case dest_case_expr thy algbr funcgr (app as (c_ty, ts)) trns = |
405 fun appgen_case dest_case_expr thy algbr funcgr (app as (c_ty, ts)) = |
401 let |
406 let |
402 val SOME ([], ((st, sty), ds)) = dest_case_expr thy (list_comb (Const c_ty, ts)); |
407 val SOME ([], ((st, sty), ds)) = dest_case_expr thy (list_comb (Const c_ty, ts)); |
403 fun clausegen (dt, bt) trns = |
408 fun clause_gen (dt, bt) = |
404 trns |
409 exprgen_term thy algbr funcgr dt |
405 |> exprgen_term thy algbr funcgr dt |
410 ##>> exprgen_term thy algbr funcgr bt; |
406 ||>> exprgen_term thy algbr funcgr bt; |
411 in |
407 in |
412 exprgen_term thy algbr funcgr st |
408 trns |
413 ##>> exprgen_typ thy algbr funcgr sty |
409 |> exprgen_term thy algbr funcgr st |
414 ##>> fold_map clause_gen ds |
410 ||>> exprgen_type thy algbr funcgr sty |
415 ##>> appgen_default thy algbr funcgr app |
411 ||>> fold_map clausegen ds |
416 #>> (fn (((se, sty), ds), t0) => ICase (((se, sty), ds), t0)) |
412 |>> (fn ((se, sty), ds) => ICase ((se, sty), ds)) |
|
413 end; |
417 end; |
414 |
418 |
415 fun appgen_let thy algbr funcgr (app as (_, [st, ct])) trns = |
419 fun appgen_let thy algbr funcgr (app as (_, [st, ct])) = |
416 trns |
420 exprgen_term thy algbr funcgr ct |
417 |> exprgen_term thy algbr funcgr ct |
421 ##>> exprgen_term thy algbr funcgr st |
418 ||>> exprgen_term thy algbr funcgr st |
422 ##>> appgen_default thy algbr funcgr app |
419 |-> (fn ((v, ty) `|-> be, se) => pair (CodegenThingol.collapse_let (((v, ty), se), be)) |
423 #>> (fn (((v, ty) `|-> be, se), t0) => |
420 | _ => appgen_default thy algbr funcgr app); |
424 ICase (CodegenThingol.collapse_let (((v, ty), se), be), t0) |
|
425 | (_, t0) => t0); |
|
426 |
|
427 fun appgen_if thy algbr funcgr (app as (_, [tb, tt, tf])) = |
|
428 exprgen_term thy algbr funcgr tb |
|
429 ##>> exprgen_typ thy algbr funcgr (Type ("bool", [])) |
|
430 ##>> exprgen_term thy algbr funcgr (Const ("True", Type ("bool", []))) |
|
431 ##>> exprgen_term thy algbr funcgr tt |
|
432 ##>> exprgen_term thy algbr funcgr (Const ("False", Type ("bool", []))) |
|
433 ##>> exprgen_term thy algbr funcgr tf |
|
434 ##>> appgen_default thy algbr funcgr app |
|
435 #>> (fn ((((((tb, B), T), tt), F), tf), t0) => ICase (((tb, B), [(T, tt), (F, tf)]), t0)); |
421 |
436 |
422 fun add_appconst (c, appgen) thy = |
437 fun add_appconst (c, appgen) thy = |
423 let |
438 let |
424 val i = (length o fst o strip_type o Sign.the_const_type thy) c; |
439 val i = (length o fst o strip_type o Sign.the_const_type thy) c; |
425 val _ = Code.change thy (K CodegenThingol.empty_code); |
440 val _ = Code.change thy (K CodegenThingol.empty_code); |
524 Code.change_yield thy |
541 Code.change_yield thy |
525 (CodegenThingol.start_transact (gen thy algbr funcgr' it)) |
542 (CodegenThingol.start_transact (gen thy algbr funcgr' it)) |
526 |> fst |
543 |> fst |
527 end; |
544 end; |
528 |
545 |
|
546 fun eval_conv thy conv = |
|
547 let |
|
548 fun conv' funcgr ct = |
|
549 let |
|
550 val t = generate thy funcgr exprgen_term' (Thm.term_of ct); |
|
551 val consts = CodegenThingol.fold_constnames (insert (op =)) t []; |
|
552 val code = Code.get thy |
|
553 |> CodegenThingol.project_code true [] (SOME consts) |
|
554 in conv code t ct end; |
|
555 in Funcgr.eval_conv thy conv' end; |
|
556 |
529 fun codegen_term thy t = |
557 fun codegen_term thy t = |
530 let |
558 let |
531 val ct = Thm.cterm_of thy t; |
559 val ct = Thm.cterm_of thy t; |
532 val (ct', funcgr) = Funcgr.make_term thy (K (K K)) ct; |
560 val (ct', funcgr) = Funcgr.make_term thy (K (K K)) ct; |
533 val t' = Thm.term_of ct'; |
561 val t' = Thm.term_of ct'; |
534 in generate thy funcgr exprgen_term' t' end; |
562 in generate thy funcgr exprgen_term' t' end; |
535 |
|
536 fun compile_term thy t = |
|
537 let |
|
538 val ct = Thm.cterm_of thy t; |
|
539 val (ct', funcgr) = Funcgr.make_term thy (K (K K)) ct; |
|
540 val t' = Thm.term_of ct'; |
|
541 val t'' = generate thy funcgr exprgen_term' t'; |
|
542 val consts = CodegenThingol.fold_constnames (insert (op =)) t'' []; |
|
543 val code = Code.get thy |
|
544 |> CodegenThingol.project_code true [] (SOME consts) |
|
545 in (code, t'') end; |
|
546 |
563 |
547 fun raw_eval_term thy (ref_spec, t) args = |
564 fun raw_eval_term thy (ref_spec, t) args = |
548 let |
565 let |
549 val _ = (Term.map_types o Term.map_atyps) (fn _ => |
566 val _ = (Term.map_types o Term.map_atyps) (fn _ => |
550 error ("Term " ^ Sign.string_of_term thy t ^ " contains polymorphic type")) |
567 error ("Term " ^ Sign.string_of_term thy t ^ " contains polymorphic type")) |