src/Pure/Tools/codegen_package.ML
changeset 22554 d1499fff65d8
parent 22507 3572bc633d9a
child 22570 f166a5416b3f
equal deleted inserted replaced
22553:b860975e47b4 22554:d1499fff65d8
   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;