14 val const_of_idf: theory -> string -> string * typ; |
14 val const_of_idf: theory -> string -> string * typ; |
15 val get_root_module: theory -> CodegenThingol.module; |
15 val get_root_module: theory -> CodegenThingol.module; |
16 |
16 |
17 type appgen; |
17 type appgen; |
18 val add_appconst: string * appgen -> theory -> theory; |
18 val add_appconst: string * appgen -> theory -> theory; |
19 val appgen_default: appgen; |
|
20 val appgen_numeral: (theory -> term -> IntInf.int) -> appgen; |
19 val appgen_numeral: (theory -> term -> IntInf.int) -> appgen; |
21 val appgen_char: (term -> int option) -> appgen; |
20 val appgen_char: (term -> int option) -> appgen; |
22 val appgen_case: (theory -> term |
21 val appgen_case: (theory -> term |
23 -> ((string * typ) list * ((term * typ) * (term * term) list)) option) |
22 -> ((string * typ) list * ((term * typ) * (term * term) list)) option) |
24 -> appgen; |
23 -> appgen; |
99 | check_strict has_seri x (_, SOME targets) = |
98 | check_strict has_seri x (_, SOME targets) = |
100 not (has_seri targets x) |
99 not (has_seri targets x) |
101 | check_strict has_seri x (true, _) = |
100 | check_strict has_seri x (true, _) = |
102 true; |
101 true; |
103 |
102 |
104 fun no_strict (_, targets) = (false, targets); |
|
105 |
|
106 fun ensure_def_class thy algbr funcgr strct cls trns = |
103 fun ensure_def_class thy algbr funcgr strct cls trns = |
107 let |
104 let |
108 fun defgen_class thy (algbr as ((proj_sort, _), _)) funcgr strct cls trns = |
105 fun defgen_class thy (algbr as ((proj_sort, _), _)) funcgr strct cls trns = |
109 case CodegenNames.class_rev thy cls |
106 case CodegenNames.class_rev thy cls |
110 of SOME cls => |
107 of SOME cls => |
112 val (v, cs) = (ClassPackage.the_consts_sign thy) cls; |
109 val (v, cs) = (ClassPackage.the_consts_sign thy) cls; |
113 val superclasses = (proj_sort o Sign.super_classes thy) cls |
110 val superclasses = (proj_sort o Sign.super_classes thy) cls |
114 val idfs = map (CodegenNames.const thy o CodegenConsts.norm_of_typ thy) cs; |
111 val idfs = map (CodegenNames.const thy o CodegenConsts.norm_of_typ thy) cs; |
115 in |
112 in |
116 trns |
113 trns |
117 |> debug_msg (fn _ => "trying defgen class declaration for " ^ quote cls) |
114 |> tracing (fn _ => "trying defgen class declaration for " ^ quote cls) |
118 |> fold_map (ensure_def_class thy algbr funcgr strct) superclasses |
115 |> fold_map (ensure_def_class thy algbr funcgr strct) superclasses |
119 ||>> (fold_map (exprgen_type thy algbr funcgr strct) o map snd) cs |
116 ||>> (fold_map (exprgen_type thy algbr funcgr strct) o map snd) cs |
120 |-> (fn (supcls, memtypes) => succeed |
117 |-> (fn (supcls, memtypes) => succeed |
121 (Class (supcls, (unprefix "'" v, idfs ~~ memtypes)))) |
118 (Class (supcls, (unprefix "'" v, idfs ~~ memtypes)))) |
122 end |
119 end |
138 case CodegenNames.tyco_rev thy dtco |
135 case CodegenNames.tyco_rev thy dtco |
139 of SOME dtco => |
136 of SOME dtco => |
140 (case CodegenData.get_datatype thy dtco |
137 (case CodegenData.get_datatype thy dtco |
141 of SOME (vs, cos) => |
138 of SOME (vs, cos) => |
142 trns |
139 trns |
143 |> debug_msg (fn _ => "trying defgen datatype for " ^ quote dtco) |
140 |> tracing (fn _ => "trying defgen datatype for " ^ quote dtco) |
144 |> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs |
141 |> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs |
145 ||>> fold_map (fn (c, tys) => |
142 ||>> fold_map (fn (c, tys) => |
146 fold_map (exprgen_type thy algbr funcgr strct) tys |
143 fold_map (exprgen_type thy algbr funcgr strct) tys |
147 #-> (fn tys' => |
144 #-> (fn tys' => |
148 pair ((CodegenNames.const thy o CodegenConsts.norm_of_typ thy) |
145 pair ((CodegenNames.const thy o CodegenConsts.norm_of_typ thy) |
180 trns |
177 trns |
181 |> ensure_def_tyco thy algbr funcgr strct tyco |
178 |> ensure_def_tyco thy algbr funcgr strct tyco |
182 ||>> fold_map (exprgen_type thy algbr funcgr strct) tys |
179 ||>> fold_map (exprgen_type thy algbr funcgr strct) tys |
183 |-> (fn (tyco, tys) => pair (tyco `%% tys)); |
180 |-> (fn (tyco, tys) => pair (tyco `%% tys)); |
184 |
181 |
185 exception CONSTRAIN of ((string * typ) * typ) * term option; |
182 exception CONSTRAIN of (string * typ) * typ; |
186 |
183 |
187 fun exprgen_typinst thy (algbr as ((proj_sort, algebra), consts)) funcgr strct (ty_ctxt, sort_decl) trns = |
184 fun exprgen_typinst thy (algbr as ((proj_sort, algebra), consts)) funcgr strct (ty_ctxt, sort_decl) trns = |
188 let |
185 let |
189 val pp = Sign.pp thy; |
186 val pp = Sign.pp thy; |
190 datatype inst = |
187 datatype inst = |
223 val idf = CodegenNames.const thy c'; |
220 val idf = CodegenNames.const thy c'; |
224 val ty_decl = Consts.declaration consts idf; |
221 val ty_decl = Consts.declaration consts idf; |
225 val insts = (op ~~ o apsnd (map (snd o dest_TVar)) oo pairself) |
222 val insts = (op ~~ o apsnd (map (snd o dest_TVar)) oo pairself) |
226 (curry (Consts.typargs consts) idf) (ty_ctxt, ty_decl); |
223 (curry (Consts.typargs consts) idf) (ty_ctxt, ty_decl); |
227 val _ = if exists not (map (Sign.of_sort thy) insts) |
224 val _ = if exists not (map (Sign.of_sort thy) insts) |
228 then raise CONSTRAIN (((c, ty_decl), ty_ctxt), NONE) else (); |
225 then raise CONSTRAIN ((c, ty_decl), ty_ctxt) else (); |
229 in |
226 in |
230 trns |
227 trns |
231 |> fold_map (exprgen_typinst thy algbr funcgr strct) insts |
228 |> fold_map (exprgen_typinst thy algbr funcgr strct) insts |
232 end |
229 end |
233 and ensure_def_inst thy algbr funcgr strct (cls, tyco) trns = |
230 and ensure_def_inst thy algbr funcgr strct (cls, tyco) trns = |
249 trns |
246 trns |
250 |> ensure_def_const thy algbr funcgr strct (CodegenConsts.norm_of_typ thy (m0, ty0)) |
247 |> ensure_def_const thy algbr funcgr strct (CodegenConsts.norm_of_typ thy (m0, ty0)) |
251 ||>> exprgen_term thy algbr funcgr strct (Const (m, ty)); |
248 ||>> exprgen_term thy algbr funcgr strct (Const (m, ty)); |
252 in |
249 in |
253 trns |
250 trns |
254 |> debug_msg (fn _ => "trying defgen class instance for (" ^ quote cls |
251 |> tracing (fn _ => "trying defgen class instance for (" ^ quote cls |
255 ^ ", " ^ quote tyco ^ ")") |
252 ^ ", " ^ quote tyco ^ ")") |
256 |> ensure_def_class thy algbr funcgr strct class |
253 |> ensure_def_class thy algbr funcgr strct class |
257 ||>> ensure_def_tyco thy algbr funcgr strct tyco |
254 ||>> ensure_def_tyco thy algbr funcgr strct tyco |
258 ||>> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs |
255 ||>> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs |
259 ||>> fold_map gen_suparity superclasses |
256 ||>> fold_map gen_suparity superclasses |
264 | _ => |
261 | _ => |
265 trns |> fail ("No class instance found for " ^ quote inst); |
262 trns |> fail ("No class instance found for " ^ quote inst); |
266 val inst = CodegenNames.instance thy (cls, tyco); |
263 val inst = CodegenNames.instance thy (cls, tyco); |
267 in |
264 in |
268 trns |
265 trns |
269 |> debug_msg (fn _ => "generating instance " ^ quote cls ^ " / " ^ quote tyco) |
266 |> tracing (fn _ => "generating instance " ^ quote cls ^ " / " ^ quote tyco) |
270 |> ensure_def (defgen_inst thy algbr funcgr strct) true |
267 |> ensure_def (defgen_inst thy algbr funcgr strct) true |
271 ("generating instance " ^ quote cls ^ " / " ^ quote tyco) inst |
268 ("generating instance " ^ quote cls ^ " / " ^ quote tyco) inst |
272 |> pair inst |
269 |> pair inst |
273 end |
270 end |
274 and ensure_def_const thy algbr funcgr strct (c, tys) trns = |
271 and ensure_def_const thy algbr funcgr strct (c, tys) trns = |
275 let |
272 let |
276 fun defgen_datatypecons thy algbr funcgr strct co trns = |
273 fun defgen_datatypecons thy algbr funcgr strct co trns = |
277 case CodegenData.get_datatype_of_constr thy ((the o CodegenNames.const_rev thy) co) |
274 case CodegenData.get_datatype_of_constr thy ((the o CodegenNames.const_rev thy) co) |
278 of SOME tyco => |
275 of SOME tyco => |
279 trns |
276 trns |
280 |> debug_msg (fn _ => "trying defgen datatype constructor for " ^ quote co) |
277 |> tracing (fn _ => "trying defgen datatype constructor for " ^ quote co) |
281 |> ensure_def_tyco thy algbr funcgr strct tyco |
278 |> ensure_def_tyco thy algbr funcgr strct tyco |
282 |-> (fn _ => succeed Bot) |
279 |-> (fn _ => succeed Bot) |
283 | _ => |
280 | _ => |
284 trns |
281 trns |
285 |> fail ("Not a datatype constructor: " |
282 |> fail ("Not a datatype constructor: " |
286 ^ (quote o CodegenConsts.string_of_const thy) (c, tys)); |
283 ^ (quote o CodegenConsts.string_of_const thy) (c, tys)); |
287 fun defgen_clsmem thy algbr funcgr strct m trns = |
284 fun defgen_clsmem thy algbr funcgr strct m trns = |
288 case AxClass.class_of_param thy ((fst o the o CodegenNames.const_rev thy) m) |
285 case AxClass.class_of_param thy ((fst o the o CodegenNames.const_rev thy) m) |
289 of SOME class => |
286 of SOME class => |
290 trns |
287 trns |
291 |> debug_msg (fn _ => "trying defgen class operation for " ^ quote m) |
288 |> tracing (fn _ => "trying defgen class operation for " ^ quote m) |
292 |> ensure_def_class thy algbr funcgr strct class |
289 |> ensure_def_class thy algbr funcgr strct class |
293 |-> (fn _ => succeed Bot) |
290 |-> (fn _ => succeed Bot) |
294 | _ => |
291 | _ => |
295 trns |> fail ("No class found for " ^ (quote o CodegenConsts.string_of_const thy) (c, tys)) |
292 trns |> fail ("No class found for " ^ (quote o CodegenConsts.string_of_const thy) (c, tys)) |
296 fun defgen_funs thy (algbr as (_, consts)) funcgr strct c' trns = |
293 fun defgen_funs thy (algbr as (_, consts)) funcgr strct c' trns = |
298 of eq_thms as eq_thm :: _ => |
295 of eq_thms as eq_thm :: _ => |
299 let |
296 let |
300 val msg = cat_lines ("generating code for theorems " :: map string_of_thm eq_thms); |
297 val msg = cat_lines ("generating code for theorems " :: map string_of_thm eq_thms); |
301 val ty = (Logic.unvarifyT o CodegenData.typ_func thy) eq_thm; |
298 val ty = (Logic.unvarifyT o CodegenData.typ_func thy) eq_thm; |
302 val vs = (map dest_TFree o Consts.typargs consts) (c', ty); |
299 val vs = (map dest_TFree o Consts.typargs consts) (c', ty); |
303 fun dest_eqthm eq_thm = |
300 val dest_eqthm = |
304 let |
301 apfst (snd o strip_comb) o Logic.dest_equals o Logic.unvarify o prop_of; |
305 val ((t, args), rhs) = |
|
306 (apfst strip_comb o Logic.dest_equals o Logic.unvarify o prop_of) eq_thm; |
|
307 in case t |
|
308 of Const (c', _) => if c' = c then (args, rhs) |
|
309 else error ("Illegal function equation for " ^ quote c |
|
310 ^ ", actually defining " ^ quote c') |
|
311 | _ => error ("Illegal function equation for " ^ quote c) |
|
312 end; |
|
313 fun exprgen_eq (args, rhs) trns = |
302 fun exprgen_eq (args, rhs) trns = |
314 trns |
303 trns |
315 |> fold_map (exprgen_term thy algbr funcgr strct) args |
304 |> fold_map (exprgen_term thy algbr funcgr strct) args |
316 ||>> exprgen_term thy algbr funcgr strct rhs; |
305 ||>> exprgen_term thy algbr funcgr strct rhs; |
317 fun checkvars (args, rhs) = |
|
318 if CodegenThingol.vars_distinct args then (args, rhs) |
|
319 else error ("Repeated variables on left hand side of function") |
|
320 in |
306 in |
321 trns |
307 trns |
322 |> message msg (fn trns => trns |
308 |> message msg (fn trns => trns |
323 |> fold_map (exprgen_eq o dest_eqthm) eq_thms |
309 |> fold_map (exprgen_eq o dest_eqthm) eq_thms |
324 |-> (fn eqs => pair (map checkvars eqs)) |
|
325 ||>> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs |
310 ||>> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs |
326 ||>> exprgen_type thy algbr funcgr strct ty |
311 ||>> exprgen_type thy algbr funcgr strct ty |
327 |-> (fn ((eqs, vs), ty) => succeed (Fun (eqs, (vs, ty))))) |
312 |-> (fn ((eqs, vs), ty) => succeed (Fun (eqs, (vs, ty))))) |
328 end |
313 end |
329 | [] => |
314 | [] => |
340 else error ("Illegal shallow name space for constant: " ^ quote idf); |
325 else error ("Illegal shallow name space for constant: " ^ quote idf); |
341 val idf = CodegenNames.const thy (c, tys); |
326 val idf = CodegenNames.const thy (c, tys); |
342 val strict = check_strict (CodegenSerializer.const_has_serialization thy) idf strct; |
327 val strict = check_strict (CodegenSerializer.const_has_serialization thy) idf strct; |
343 in |
328 in |
344 trns |
329 trns |
345 |> debug_msg (fn _ => "generating constant " |
330 |> tracing (fn _ => "generating constant " |
346 ^ (quote o CodegenConsts.string_of_const thy) (c, tys)) |
331 ^ (quote o CodegenConsts.string_of_const thy) (c, tys)) |
347 |> ensure_def (get_defgen funcgr strct idf) strict ("generating constant " |
332 |> ensure_def (get_defgen funcgr strct idf) strict ("generating constant " |
348 ^ CodegenConsts.string_of_const thy (c, tys)) idf |
333 ^ CodegenConsts.string_of_const thy (c, tys)) idf |
349 |> pair idf |
334 |> pair idf |
350 end |
335 end |
413 | NONE => |
398 | NONE => |
414 trns |
399 trns |
415 |> appgen_default thy algbr funcgr strct ((f, ty), ts); |
400 |> appgen_default thy algbr funcgr strct ((f, ty), ts); |
416 |
401 |
417 |
402 |
418 (* entry points into extraction kernel *) |
403 (* entrance points into extraction kernel *) |
419 |
404 |
420 fun ensure_def_const' thy algbr funcgr strct c trns = |
405 fun ensure_def_const' thy algbr funcgr strct c trns = |
421 ensure_def_const thy algbr funcgr strct c trns |
406 ensure_def_const thy algbr funcgr strct c trns |
422 handle CONSTRAIN (((c, ty), ty_decl), NONE) => error ( |
407 handle CONSTRAIN ((c, ty), ty_decl) => error ( |
423 "Constant " ^ c ^ " with most general type\n" |
408 "Constant " ^ c ^ " with most general type\n" |
424 ^ Sign.string_of_typ thy ty |
409 ^ Sign.string_of_typ thy ty |
425 ^ "\noccurs with type\n" |
410 ^ "\noccurs with type\n" |
426 ^ Sign.string_of_typ thy ty_decl) |
411 ^ Sign.string_of_typ thy ty_decl); |
427 handle CONSTRAIN (((c, ty), ty_decl), SOME t) => error ("In term " ^ (quote o Sign.string_of_term thy) t |
412 fun exprgen_term' thy algbr funcgr strct t trns = |
|
413 exprgen_term thy algbr funcgr strct t trns |
|
414 handle CONSTRAIN ((c, ty), ty_decl) => error ("In term " ^ (quote o Sign.string_of_term thy) t |
428 ^ ",\nconstant " ^ c ^ " with most general type\n" |
415 ^ ",\nconstant " ^ c ^ " with most general type\n" |
429 ^ Sign.string_of_typ thy ty |
416 ^ Sign.string_of_typ thy ty |
430 ^ "\noccurs with type\n" |
417 ^ "\noccurs with type\n" |
431 ^ Sign.string_of_typ thy ty_decl); |
418 ^ Sign.string_of_typ thy ty_decl); |
432 |
419 |
433 fun exprgen_term' thy algbr funcgr strct t trns = |
|
434 exprgen_term thy algbr funcgr strct t trns |
|
435 handle CONSTRAIN (((c, ty), ty_decl), _) => error ("In term " ^ (quote o Sign.string_of_term thy) t |
|
436 ^ ",\nconstant " ^ c ^ " with most general type\n" |
|
437 ^ Sign.string_of_typ thy ty |
|
438 ^ "\noccurs with type\n" |
|
439 ^ Sign.string_of_typ thy ty_decl); |
|
440 |
|
441 |
420 |
442 (* parametrized application generators, for instantiation in object logic *) |
421 (* parametrized application generators, for instantiation in object logic *) |
443 (* (axiomatic extensions of extraction kernel *) |
422 (* (axiomatic extensions of extraction kernel *) |
444 |
423 |
445 fun appgen_numeral int_of_numeral thy algbr funcgr strct (app as (c, ts)) trns = |
424 fun appgen_numeral int_of_numeral thy algbr funcgr strct (app as (c, ts)) trns = |
446 case try (int_of_numeral thy) (list_comb (Const c, ts)) |
425 case try (int_of_numeral thy) (list_comb (Const c, ts)) |
447 of SOME i => (*if i < 0 then (*preprocessor eliminates negative numerals*) |
426 of SOME i => |
448 trns |
427 trns |
449 |> appgen_default thy algbr funcgr (no_strict strct) app |
428 |> appgen_default thy algbr funcgr strct app |
450 else*) |
|
451 trns |
|
452 |> appgen_default thy algbr funcgr (no_strict strct) app |
|
453 |-> (fn e => pair (CodegenThingol.INum (i, e))) |
429 |-> (fn e => pair (CodegenThingol.INum (i, e))) |
454 | NONE => |
430 | NONE => |
455 trns |
431 trns |
456 |> appgen_default thy algbr funcgr (no_strict strct) app; |
432 |> appgen_default thy algbr funcgr strct app; |
457 |
433 |
458 fun appgen_char char_to_index thy algbr funcgr strct (app as ((_, ty), _)) trns = |
434 fun appgen_char char_to_index thy algbr funcgr strct (app as ((_, ty), _)) trns = |
459 case (char_to_index o list_comb o apfst Const) app |
435 case (char_to_index o list_comb o apfst Const) app |
460 of SOME i => |
436 of SOME i => |
461 trns |
437 trns |
519 |> (fn (x, modl) => x) |
495 |> (fn (x, modl) => x) |
520 end; |
496 end; |
521 |
497 |
522 fun codegen_term thy t = |
498 fun codegen_term thy t = |
523 let |
499 let |
|
500 fun const_typ (c, ty) = |
|
501 let |
|
502 val const = CodegenConsts.norm_of_typ thy (c, ty); |
|
503 val funcgr = CodegenFuncgr.mk_funcgr thy [const] []; |
|
504 in case CodegenFuncgr.get_funcs funcgr const |
|
505 of (thm :: _) => CodegenData.typ_func thy thm |
|
506 | [] => Sign.the_const_type thy c |
|
507 end; |
524 val ct = Thm.cterm_of thy t; |
508 val ct = Thm.cterm_of thy t; |
525 val thm = CodegenData.preprocess_cterm thy ct; |
509 val (thm, ct') = CodegenData.preprocess_cterm thy |
526 val t' = (snd o Logic.dest_equals o Drule.plain_prop_of) thm; |
510 (const_typ) ct; |
|
511 val t' = Thm.term_of ct'; |
527 val cs_rhss = CodegenConsts.consts_of thy t'; |
512 val cs_rhss = CodegenConsts.consts_of thy t'; |
528 in |
513 in |
529 (thm, generate thy cs_rhss (SOME []) NONE exprgen_term' t') |
514 (thm, generate thy cs_rhss (SOME []) NONE exprgen_term' t') |
530 end; |
515 end; |
531 |
516 |
538 fun eval_term thy (ref_spec, t) = |
523 fun eval_term thy (ref_spec, t) = |
539 let |
524 let |
540 val _ = Term.fold_atyps (fn _ => |
525 val _ = Term.fold_atyps (fn _ => |
541 error ("Term" ^ Sign.string_of_term thy t ^ "is polymorhpic")) |
526 error ("Term" ^ Sign.string_of_term thy t ^ "is polymorhpic")) |
542 (Term.fastype_of t); |
527 (Term.fastype_of t); |
543 fun preprocess_term t = |
528 val (_, t') = codegen_term thy t; |
544 let |
|
545 val x = Free (Name.variant (add_term_names (t, [])) "x", fastype_of t); |
|
546 (* fake definition *) |
|
547 val eq = setmp quick_and_dirty true (SkipProof.make_thm thy) |
|
548 (Logic.mk_equals (x, t)); |
|
549 fun err () = error "preprocess_term: bad preprocessor" |
|
550 in case map prop_of (CodegenFuncgr.preprocess thy [eq]) |
|
551 of [Const ("==", _) $ x' $ t'] => if x = x' then t' else err () |
|
552 | _ => err () |
|
553 end; |
|
554 val (_, t') = codegen_term thy (preprocess_term t); |
|
555 in |
529 in |
556 CodegenSerializer.eval_term thy (ref_spec, t') (Code.get thy) |
530 CodegenSerializer.eval_term thy (ref_spec, t') (Code.get thy) |
557 end; |
531 end; |
558 |
532 |
559 |
533 |
611 syntax_classK, syntax_instK, syntax_tycoK, syntax_constK) = |
585 syntax_classK, syntax_instK, syntax_tycoK, syntax_constK) = |
612 ("code_gen", |
586 ("code_gen", |
613 "code_class", "code_instance", "code_type", "code_const"); |
587 "code_class", "code_instance", "code_type", "code_const"); |
614 |
588 |
615 val codeP = |
589 val codeP = |
616 OuterSyntax.command codeK "generate and serialize executable code for constants" K.diag ( |
590 OuterSyntax.improper_command codeK "generate and serialize executable code for constants" K.diag ( |
617 Scan.repeat P.term |
591 Scan.repeat P.term |
618 -- Scan.repeat (P.$$$ "(" |-- |
592 -- Scan.repeat (P.$$$ "(" |-- |
619 P.name :-- (fn target => (CodegenSerializer.parse_serializer target >> SOME) || pair NONE) |
593 P.name :-- (fn target => (CodegenSerializer.parse_serializer target >> SOME) || pair NONE) |
620 --| P.$$$ ")") |
594 --| P.$$$ ")") |
621 >> (fn (raw_cs, seris) => Toplevel.keep (code raw_cs seris o Toplevel.theory_of)) |
595 >> (fn (raw_cs, seris) => Toplevel.keep (code raw_cs seris o Toplevel.theory_of)) |