139 let |
139 let |
140 val superclasses = (Sorts.certify_sort algebra o Sorts.super_classes algebra) class; |
140 val superclasses = (Sorts.certify_sort algebra o Sorts.super_classes algebra) class; |
141 val (v, cs) = AxClass.params_of_class thy class; |
141 val (v, cs) = AxClass.params_of_class thy class; |
142 val class' = CodegenNames.class thy class; |
142 val class' = CodegenNames.class thy class; |
143 val classrels' = map (curry (CodegenNames.classrel thy) class) superclasses; |
143 val classrels' = map (curry (CodegenNames.classrel thy) class) superclasses; |
144 val classops' = map (CodegenNames.const thy o CodegenConsts.norm_of_typ thy) cs; |
144 val classops' = map (CodegenNames.const thy o CodegenConsts.const_of_cexpr thy) cs; |
145 val defgen_class = |
145 val defgen_class = |
146 fold_map (ensure_def_class thy algbr funcgr strct) superclasses |
146 fold_map (ensure_def_class thy algbr funcgr strct) superclasses |
147 ##>> (fold_map (exprgen_type thy algbr funcgr strct) o map snd) cs |
147 ##>> (fold_map (exprgen_type thy algbr funcgr strct) o map snd) cs |
148 #-> (fn (superclasses, classoptyps) => succeed |
148 #-> (fn (superclasses, classoptyps) => succeed |
149 (CodegenThingol.Class (superclasses ~~ classrels', (unprefix "'" v, classops' ~~ classoptyps)))) |
149 (CodegenThingol.Class (superclasses ~~ classrels', (unprefix "'" v, classops' ~~ classoptyps)))) |
168 trns |
168 trns |
169 |> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs |
169 |> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs |
170 ||>> fold_map (fn (c, tys) => |
170 ||>> fold_map (fn (c, tys) => |
171 fold_map (exprgen_type thy algbr funcgr strct) tys |
171 fold_map (exprgen_type thy algbr funcgr strct) tys |
172 #-> (fn tys' => |
172 #-> (fn tys' => |
173 pair ((CodegenNames.const thy o CodegenConsts.norm_of_typ thy) |
173 pair ((CodegenNames.const thy o CodegenConsts.const_of_cexpr thy) |
174 (c, tys ---> Type (tyco, map TFree vs)), tys'))) cos |
174 (c, tys ---> Type (tyco, map TFree vs)), tys'))) cos |
175 |-> (fn (vs, cos) => succeed (CodegenThingol.Datatype (vs, cos))) |
175 |-> (fn (vs, cos) => succeed (CodegenThingol.Datatype (vs, cos))) |
176 end; |
176 end; |
177 val tyco' = CodegenNames.tyco thy tyco; |
177 val tyco' = CodegenNames.tyco thy tyco; |
178 in |
178 in |
233 in |
233 in |
234 fold_map mk_dict typargs |
234 fold_map mk_dict typargs |
235 end |
235 end |
236 and exprgen_dict_parms thy (algbr as (_, consts)) funcgr strct (c, ty_ctxt) = |
236 and exprgen_dict_parms thy (algbr as (_, consts)) funcgr strct (c, ty_ctxt) = |
237 let |
237 let |
238 val c' = CodegenConsts.norm_of_typ thy (c, ty_ctxt) |
238 val c' = CodegenConsts.const_of_cexpr thy (c, ty_ctxt) |
239 val idf = CodegenNames.const thy c'; |
239 val idf = CodegenNames.const thy c'; |
240 val ty_decl = Consts.the_declaration consts idf; |
240 val ty_decl = Consts.the_declaration consts idf; |
241 val (tys, tys_decl) = pairself (curry (Consts.typargs consts) idf) (ty_ctxt, ty_decl); |
241 val (tys, tys_decl) = pairself (curry (Consts.typargs consts) idf) (ty_ctxt, ty_decl); |
242 val sorts = map (snd o dest_TVar) tys_decl; |
242 val sorts = map (snd o dest_TVar) tys_decl; |
243 in |
243 in |
256 ||>> exprgen_dicts thy algbr funcgr strct (arity_typ, [superclass]) |
256 ||>> exprgen_dicts thy algbr funcgr strct (arity_typ, [superclass]) |
257 |>> (fn ((superclass, classrel), [DictConst (inst, dss)]) => |
257 |>> (fn ((superclass, classrel), [DictConst (inst, dss)]) => |
258 (superclass, (classrel, (inst, dss)))); |
258 (superclass, (classrel, (inst, dss)))); |
259 fun gen_classop_def (classop as (c, ty)) trns = |
259 fun gen_classop_def (classop as (c, ty)) trns = |
260 trns |
260 trns |
261 |> ensure_def_const thy algbr funcgr strct (CodegenConsts.norm_of_typ thy classop) |
261 |> ensure_def_const thy algbr funcgr strct (CodegenConsts.const_of_cexpr thy classop) |
262 ||>> exprgen_term thy algbr funcgr strct (Const (c, map_type_tfree (K arity_typ) ty)); |
262 ||>> exprgen_term thy algbr funcgr strct (Const (c, map_type_tfree (K arity_typ) ty)); |
263 fun defgen_inst trns = |
263 fun defgen_inst trns = |
264 trns |
264 trns |
265 |> ensure_def_class thy algbr funcgr strct class |
265 |> ensure_def_class thy algbr funcgr strct class |
266 ||>> ensure_def_tyco thy algbr funcgr strct tyco |
266 ||>> ensure_def_tyco thy algbr funcgr strct tyco |
274 trns |
274 trns |
275 |> tracing (fn _ => "generating instance " ^ quote class ^ " / " ^ quote tyco) |
275 |> tracing (fn _ => "generating instance " ^ quote class ^ " / " ^ quote tyco) |
276 |> ensure_def thy defgen_inst true ("generating instance " ^ quote class ^ " / " ^ quote tyco) inst |
276 |> ensure_def thy defgen_inst true ("generating instance " ^ quote class ^ " / " ^ quote tyco) inst |
277 |> pair inst |
277 |> pair inst |
278 end |
278 end |
279 and ensure_def_const thy (algbr as (_, consts)) funcgr strct (c_tys as (c, tys)) trns = |
279 and ensure_def_const thy (algbr as (_, consts)) funcgr strct (const as (c, opt_tyco)) trns = |
280 let |
280 let |
281 val c' = CodegenNames.const thy c_tys; |
281 val c' = CodegenNames.const thy const; |
282 fun defgen_datatypecons trns = |
282 fun defgen_datatypecons trns = |
283 trns |
283 trns |
284 |> ensure_def_tyco thy algbr funcgr strct |
284 |> ensure_def_tyco thy algbr funcgr strct |
285 ((the o CodegenData.get_datatype_of_constr thy) c_tys) |
285 ((the o CodegenData.get_datatype_of_constr thy) const) |
286 |-> (fn _ => succeed CodegenThingol.Bot); |
286 |-> (fn _ => succeed CodegenThingol.Bot); |
287 fun defgen_classop trns = |
287 fun defgen_classop trns = |
288 trns |
288 trns |
289 |> ensure_def_class thy algbr funcgr strct ((the o AxClass.class_of_param thy) c) |
289 |> ensure_def_class thy algbr funcgr strct ((the o AxClass.class_of_param thy) c) |
290 |-> (fn _ => succeed CodegenThingol.Bot); |
290 |-> (fn _ => succeed CodegenThingol.Bot); |
291 fun defgen_fun trns = |
291 fun defgen_fun trns = |
292 case CodegenFuncgr.funcs funcgr |
292 case CodegenFuncgr.funcs funcgr |
293 (perhaps (Consttab.lookup ((snd o snd o CodegenPackageData.get) thy)) c_tys) |
293 (perhaps (Consttab.lookup ((snd o snd o CodegenPackageData.get) thy)) const) |
294 of thms as _ :: _ => |
294 of thms as _ :: _ => |
295 let |
295 let |
296 val (ty, eq_thms) = prep_eqs thy thms; |
296 val (ty, eq_thms) = prep_eqs thy thms; |
297 val timeap = if !timing then Output.timeap_msg ("time for " ^ c') |
297 val timeap = if !timing then Output.timeap_msg ("time for " ^ c') |
298 else I; |
298 else I; |
313 |-> (fn ((eqs, vs), ty) => succeed (CodegenThingol.Fun (eqs, (vs, ty))))) |
313 |-> (fn ((eqs, vs), ty) => succeed (CodegenThingol.Fun (eqs, (vs, ty))))) |
314 end |
314 end |
315 | [] => |
315 | [] => |
316 trns |
316 trns |
317 |> fail ("No defining equations found for " |
317 |> fail ("No defining equations found for " |
318 ^ (quote o CodegenConsts.string_of_const thy) c_tys); |
318 ^ (quote o CodegenConsts.string_of_const thy) const); |
319 val defgen = if (is_some o CodegenData.get_datatype_of_constr thy) c_tys |
319 val defgen = if (is_some o CodegenData.get_datatype_of_constr thy) const |
320 then defgen_datatypecons |
320 then defgen_datatypecons |
321 else if (is_some o AxClass.class_of_param thy) c andalso |
321 else if is_some opt_tyco |
322 case tys of [TFree _] => true | [TVar _] => true | _ => false |
322 orelse (not o is_some o AxClass.class_of_param thy) c |
323 then defgen_classop |
323 then defgen_fun |
324 else defgen_fun |
324 else defgen_classop |
325 val strict = check_strict strct (CodegenSerializer.const_has_serialization thy) c'; |
325 val strict = check_strict strct (CodegenSerializer.const_has_serialization thy) c'; |
326 in |
326 in |
327 trns |
327 trns |
328 |> tracing (fn _ => "generating constant " |
328 |> tracing (fn _ => "generating constant " |
329 ^ (quote o CodegenConsts.string_of_const thy) c_tys) |
329 ^ (quote o CodegenConsts.string_of_const thy) const) |
330 |> ensure_def thy defgen strict ("generating constant " |
330 |> ensure_def thy defgen strict ("generating constant " |
331 ^ CodegenConsts.string_of_const thy c_tys) c' |
331 ^ CodegenConsts.string_of_const thy const) c' |
332 |> pair c' |
332 |> pair c' |
333 end |
333 end |
334 and exprgen_term thy algbr funcgr strct (Const (c, ty)) trns = |
334 and exprgen_term thy algbr funcgr strct (Const (c, ty)) trns = |
335 trns |
335 trns |
336 |> select_appgen thy algbr funcgr strct ((c, ty), []) |
336 |> select_appgen thy algbr funcgr strct ((c, ty), []) |
357 |> exprgen_term thy algbr funcgr strct t' |
357 |> exprgen_term thy algbr funcgr strct t' |
358 ||>> fold_map (exprgen_term thy algbr funcgr strct) ts |
358 ||>> fold_map (exprgen_term thy algbr funcgr strct) ts |
359 |>> (fn (t, ts) => t `$$ ts) |
359 |>> (fn (t, ts) => t `$$ ts) |
360 and appgen_default thy algbr funcgr strct ((c, ty), ts) trns = |
360 and appgen_default thy algbr funcgr strct ((c, ty), ts) trns = |
361 trns |
361 trns |
362 |> ensure_def_const thy algbr funcgr strct (CodegenConsts.norm_of_typ thy (c, ty)) |
362 |> ensure_def_const thy algbr funcgr strct (CodegenConsts.const_of_cexpr thy (c, ty)) |
363 ||>> fold_map (exprgen_type thy algbr funcgr strct) ((fst o Term.strip_type) ty) |
363 ||>> fold_map (exprgen_type thy algbr funcgr strct) ((fst o Term.strip_type) ty) |
364 ||>> exprgen_type thy algbr funcgr strct ((snd o Term.strip_type) ty) |
364 ||>> exprgen_type thy algbr funcgr strct ((snd o Term.strip_type) ty) |
365 ||>> exprgen_dict_parms thy algbr funcgr strct (c, ty) |
365 ||>> exprgen_dict_parms thy algbr funcgr strct (c, ty) |
366 ||>> fold_map (exprgen_term thy algbr funcgr strct) ts |
366 ||>> fold_map (exprgen_term thy algbr funcgr strct) ts |
367 |>> (fn ((((c, tys), ty), iss), ts) => IConst (c, (iss, tys)) `$$ ts) |
367 |>> (fn ((((c, tys), ty), iss), ts) => IConst (c, (iss, tys)) `$$ ts) |
481 |
481 |
482 (** abstype and constsubst interface **) |
482 (** abstype and constsubst interface **) |
483 |
483 |
484 local |
484 local |
485 |
485 |
486 fun add_consts thy f (c1, c2 as (c, tys)) = |
486 fun add_consts thy f (c1, c2 as (c, opt_tyco)) = |
487 let |
487 let |
488 val _ = case tys |
488 val _ = if |
489 of [TVar _] => if is_some (AxClass.class_of_param thy c) |
489 is_some (AxClass.class_of_param thy c) andalso is_none opt_tyco |
490 then error ("Not a function: " ^ CodegenConsts.string_of_const thy c2) |
490 orelse is_some (CodegenData.get_datatype_of_constr thy c2) |
491 else () |
|
492 | _ => (); |
|
493 val _ = if is_some (CodegenData.get_datatype_of_constr thy c2) |
|
494 then error ("Not a function: " ^ CodegenConsts.string_of_const thy c2) |
491 then error ("Not a function: " ^ CodegenConsts.string_of_const thy c2) |
495 else (); |
492 else (); |
496 val funcgr = Funcgr.make thy [c1, c2]; |
493 val funcgr = Funcgr.make thy [c1, c2]; |
497 val ty1 = (f o CodegenFuncgr.typ funcgr) c1; |
494 val ty1 = (f o CodegenFuncgr.typ funcgr) c1; |
498 val ty2 = CodegenFuncgr.typ funcgr c2; |
495 val ty2 = CodegenFuncgr.typ funcgr c2; |
546 |> (CodegenPackageData.map o apsnd o apsnd) (fold (add_consts thy I) constsubsts) |
543 |> (CodegenPackageData.map o apsnd o apsnd) (fold (add_consts thy I) constsubsts) |
547 end; |
544 end; |
548 |
545 |
549 in |
546 in |
550 |
547 |
551 val abstyp = gen_abstyp CodegenConsts.norm Sign.certify_typ; |
548 val abstyp = gen_abstyp (K I) Sign.certify_typ; |
552 val abstyp_e = gen_abstyp CodegenConsts.read_const (fn thy => Sign.read_typ (thy, K NONE)); |
549 val abstyp_e = gen_abstyp CodegenConsts.read_const (fn thy => Sign.read_typ (thy, K NONE)); |
553 |
550 |
554 val constsubst = gen_constsubst CodegenConsts.norm; |
551 val constsubst = gen_constsubst (K I); |
555 val constsubst_e = gen_constsubst CodegenConsts.read_const; |
552 val constsubst_e = gen_constsubst CodegenConsts.read_const; |
556 |
553 |
557 end; (*local*) |
554 end; (*local*) |
558 |
555 |
559 |
556 |
606 (* constant specifications with wildcards *) |
603 (* constant specifications with wildcards *) |
607 |
604 |
608 fun consts_of thy thyname = |
605 fun consts_of thy thyname = |
609 let |
606 let |
610 val this_thy = Option.map theory thyname |> the_default thy; |
607 val this_thy = Option.map theory thyname |> the_default thy; |
611 val defs = (#defs o rep_theory) this_thy; |
608 val defs = (#defs o rep_theory) thy; |
612 val cs_names = (Symtab.keys o snd o #constants o Consts.dest o #consts o Sign.rep_sg) this_thy; |
609 val cs = Symtab.fold (fn (c, (_, NONE)) => cons c | _ => I) |
613 val consts = maps (fn c => (map (fn tys => CodegenConsts.norm thy (c, tys)) |
610 ((snd o #constants o Consts.dest o #consts o Sign.rep_sg) this_thy) []; |
614 o map #lhs o filter #is_def o map snd o Defs.specifications_of defs) c) cs_names; |
611 fun classop c = case AxClass.class_of_param thy c |
615 fun is_const thyname (c, _) = |
612 of NONE => [(c, NONE)] |
616 (*this is an approximation*) |
613 | SOME class => Symtab.fold |
617 not (exists (fn thy => Sign.declared_const thy c) (Theory.parents_of this_thy)) |
614 (fn (tyco, classes) => if AList.defined (op =) classes class |
|
615 then cons (c, SOME tyco) else I) |
|
616 ((#arities o Sorts.rep_algebra o Sign.classes_of) this_thy) |
|
617 [(c, NONE)]; |
|
618 val consts = maps classop cs; |
|
619 fun test_instance thy (class, tyco) = |
|
620 can (Sorts.mg_domain (Sign.classes_of thy) tyco) [class] |
|
621 fun belongs_here thyname (c, NONE) = |
|
622 not (exists (fn thy => Sign.declared_const thy c) (Theory.parents_of this_thy)) |
|
623 | belongs_here thyname (c, SOME tyco) = |
|
624 not (exists (fn thy => test_instance thy ((the o AxClass.class_of_param thy) c, tyco)) |
|
625 (Theory.parents_of this_thy)) |
618 in case thyname |
626 in case thyname |
619 of NONE => consts |
627 of NONE => consts |
620 | SOME thyname => filter (is_const thyname) consts |
628 | SOME thyname => filter (belongs_here thyname) consts |
621 end; |
629 end; |
622 |
630 |
623 fun filter_generatable thy targets consts = |
631 fun filter_generatable thy targets consts = |
624 let |
632 let |
625 val (consts', funcgr) = Funcgr.make_consts thy consts; |
633 val (consts', funcgr) = Funcgr.make_consts thy consts; |