src/Pure/Tools/codegen_package.ML
changeset 20466 7c20ddbd911b
parent 20456 42be3a46dcd8
child 20485 3078fd2eec7b
equal deleted inserted replaced
20465:95f6d354b0ed 20466:7c20ddbd911b
   104 );
   104 );
   105 
   105 
   106 
   106 
   107 (* theory data  *)
   107 (* theory data  *)
   108 
   108 
   109 type appgen = theory -> Sorts.algebra * (sort -> sort) -> CodegenTheorems.thmtab
   109 type appgen = theory -> ((sort -> sort) * Sorts.algebra) * Consts.T -> CodegenTheorems.thmtab
   110   -> bool * string list option -> (string * typ) * term list -> transact -> iterm * transact;
   110   -> bool * string list option -> (string * typ) * term list -> transact -> iterm * transact;
   111 
   111 
   112 type appgens = (int * (appgen * stamp)) Symtab.table;
   112 type appgens = (int * (appgen * stamp)) Symtab.table;
   113 
   113 
   114 fun merge_appgens (x : appgens * appgens) =
   114 fun merge_appgens (x : appgens * appgens) =
   300 
   300 
   301 fun no_strict (_, targets) = (false, targets);
   301 fun no_strict (_, targets) = (false, targets);
   302 
   302 
   303 fun ensure_def_class thy algbr thmtab strct cls trns =
   303 fun ensure_def_class thy algbr thmtab strct cls trns =
   304   let
   304   let
   305     fun defgen_class thy (algbr as (_, proj_sort)) thmtab strct cls trns =
   305     fun defgen_class thy (algbr as ((proj_sort, _), _)) thmtab strct cls trns =
   306       case class_of_idf thy cls
   306       case class_of_idf thy cls
   307        of SOME cls =>
   307        of SOME cls =>
   308             let
   308             let
   309               val (v, cs) = (ClassPackage.the_consts_sign thy) cls;
   309               val (v, cs) = (ClassPackage.the_consts_sign thy) cls;
   310               val superclasses = (proj_sort o Sign.super_classes thy) cls
   310               val superclasses = (proj_sort o Sign.super_classes thy) cls
   354     |> debug_msg (fn _ => "generating type constructor " ^ quote tyco)
   354     |> debug_msg (fn _ => "generating type constructor " ^ quote tyco)
   355     |> ensure_def (defgen_datatype thy algbr thmtab strct) strict
   355     |> ensure_def (defgen_datatype thy algbr thmtab strct) strict
   356         ("generating type constructor " ^ quote tyco) tyco'
   356         ("generating type constructor " ^ quote tyco) tyco'
   357     |> pair tyco'
   357     |> pair tyco'
   358   end
   358   end
   359 and exprgen_tyvar_sort thy (algbr as (_, proj_sort)) thmtab strct (v, sort) trns =
   359 and exprgen_tyvar_sort thy (algbr as ((proj_sort, _), _)) thmtab strct (v, sort) trns =
   360   trns
   360   trns
   361   |> fold_map (ensure_def_class thy algbr thmtab strct) (proj_sort sort)
   361   |> fold_map (ensure_def_class thy algbr thmtab strct) (proj_sort sort)
   362   |-> (fn sort => pair (unprefix "'" v, sort))
   362   |-> (fn sort => pair (unprefix "'" v, sort))
   363 and exprgen_type thy algbr thmtab strct (TVar _) trns =
   363 and exprgen_type thy algbr thmtab strct (TVar _) trns =
   364       error "TVar encountered in typ during code generation"
   364       error "TVar encountered in typ during code generation"
   375       trns
   375       trns
   376       |> ensure_def_tyco thy algbr thmtab strct tyco
   376       |> ensure_def_tyco thy algbr thmtab strct tyco
   377       ||>> fold_map (exprgen_type thy algbr thmtab strct) tys
   377       ||>> fold_map (exprgen_type thy algbr thmtab strct) tys
   378       |-> (fn (tyco, tys) => pair (tyco `%% tys));
   378       |-> (fn (tyco, tys) => pair (tyco `%% tys));
   379 
   379 
   380 fun exprgen_typinst thy (algbr as (algebra, proj_sort)) thmtab strct (ty_ctxt, sort_decl) trns =
   380 fun exprgen_typinst thy (algbr as ((proj_sort, algebra), consts)) thmtab strct (ty_ctxt, sort_decl) trns =
   381   let
   381   let
   382     val pp = Sign.pp thy;
   382     val pp = Sign.pp thy;
   383     datatype inst =
   383     datatype inst =
   384         Inst of (class * string) * inst list list
   384         Inst of (class * string) * inst list list
   385       | Contxt of (string * sort) * (class list * int);
   385       | Contxt of (string * sort) * (class list * int);
   408                 if length sort = 1 then ~1 else k))))
   408                 if length sort = 1 then ~1 else k))))
   409   in
   409   in
   410     trns
   410     trns
   411     |> fold_map mk_dict insts
   411     |> fold_map mk_dict insts
   412   end
   412   end
   413 and exprgen_typinst_const thy algbr thmtab strct (c, ty_ctxt) trns =
   413 and exprgen_typinst_const thy (algbr as (_, consts)) thmtab strct (c, ty_ctxt) trns =
   414   let
   414   let 
   415     val ty_decl = case CodegenTheorems.get_fun_thms thmtab (c, ty_ctxt)
   415     val idf = idf_of_const thy thmtab (c, ty_ctxt)
   416      of thms as thm :: _ => CodegenTheorems.extr_typ thy thm
   416     val ty_decl = Consts.declaration consts idf;
   417       | [] => (case AxClass.class_of_param thy c
   417     val insts = (op ~~ o apsnd (map (snd o dest_TVar)) oo pairself)
   418          of SOME class => (case ClassPackage.the_consts_sign thy class of (v, cs) =>
   418       (curry (Consts.typargs consts) idf) (ty_ctxt, ty_decl);
   419               (Logic.varifyT o map_type_tfree (fn u as (w, _) =>
       
   420                 if w = v then TFree (v, [class]) else TFree u))
       
   421               ((the o AList.lookup (op =) cs) c))
       
   422           | NONE => Sign.the_const_type thy c);
       
   423     val insts =
       
   424       Vartab.empty
       
   425       |> Sign.typ_match thy (ty_decl, ty_ctxt)
       
   426       |> Vartab.dest
       
   427       |> map (fn (_, (sort, ty)) => (ty, sort))
       
   428   in
   419   in
   429     trns
   420     trns
   430     |> fold_map (exprgen_typinst thy algbr thmtab strct) insts
   421     |> fold_map (exprgen_typinst thy algbr thmtab strct) insts
   431   end
   422   end
   432 and ensure_def_inst thy algbr thmtab strct (cls, tyco) trns =
   423 and ensure_def_inst thy algbr thmtab strct (cls, tyco) trns =
   433   let
   424   let
   434     fun defgen_inst thy (algbr as (_, proj_sort)) thmtab strct inst trns =
   425     fun defgen_inst thy (algbr as ((proj_sort, _), _)) thmtab strct inst trns =
   435       case inst_of_idf thy inst
   426       case inst_of_idf thy inst
   436        of SOME (class, tyco) =>
   427        of SOME (class, tyco) =>
   437             let
   428             let
   438               val (vs, memdefs) = ClassPackage.the_inst_sign thy (class, tyco);
   429               val (vs, memdefs) = ClassPackage.the_inst_sign thy (class, tyco);
   439               val (_, members) = ClassPackage.the_consts_sign thy class;
   430               val (_, members) = ClassPackage.the_consts_sign thy class;
   440               val arity_typ = Type (tyco, (map TFree vs));
   431               val arity_typ = Type (tyco, (map TFree vs));
   441               val superclasses = (proj_sort o Sign.super_classes thy) class
   432               val superclasses = (proj_sort o Sign.super_classes thy) class
   442               fun gen_suparity supclass trns =
   433               fun gen_suparity supclass trns =
   443                 trns
   434                 trns
   444                 |> ensure_def_class thy algbr thmtab strct supclass
   435                 |> ensure_def_class thy algbr thmtab strct supclass
   445                 ||>> exprgen_typinst thy algbr thmtab strct (arity_typ, [supclass]);
   436                 ||>> exprgen_typinst thy algbr thmtab strct (arity_typ, [supclass])
       
   437                 |-> (fn (supclass, [Instance (supints, lss)]) => pair (supclass, (supints, lss)));
   446               fun gen_membr ((m0, ty0), (m, ty)) trns =
   438               fun gen_membr ((m0, ty0), (m, ty)) trns =
   447                 trns
   439                 trns
   448                 |> ensure_def_const thy algbr thmtab strct (m0, ty0)
   440                 |> ensure_def_const thy algbr thmtab strct (m0, ty0)
   449                 ||>> exprgen_term thy algbr thmtab strct (Const (m, ty));
   441                 ||>> exprgen_term thy algbr thmtab strct (Const (m, ty));
   450             in
   442             in
   490             |> debug_msg (fn _ => "trying defgen class member for " ^ quote m)
   482             |> debug_msg (fn _ => "trying defgen class member for " ^ quote m)
   491             |> ensure_def_class thy algbr thmtab strct class
   483             |> ensure_def_class thy algbr thmtab strct class
   492             |-> (fn _ => succeed Bot)
   484             |-> (fn _ => succeed Bot)
   493         | _ =>
   485         | _ =>
   494             trns |> fail ("No class found for " ^ (quote o CodegenConsts.string_of_const_typ thy) (c, ty))
   486             trns |> fail ("No class found for " ^ (quote o CodegenConsts.string_of_const_typ thy) (c, ty))
   495     fun defgen_funs thy algbr thmtab strct c' trns =
   487     fun defgen_funs thy (algbr as (_, consts)) thmtab strct c' trns =
   496       case CodegenTheorems.get_fun_thms thmtab ((the o const_of_idf thy) c')
   488       case CodegenTheorems.get_fun_thms thmtab ((the o const_of_idf thy) c')
   497        of eq_thms as eq_thm :: _ =>
   489        of eq_thms as eq_thm :: _ =>
   498             let
   490             let
   499               val msg = cat_lines ("generating code for theorems " :: map string_of_thm eq_thms);
   491               val msg = cat_lines ("generating code for theorems " :: map string_of_thm eq_thms);
   500               val ty = (Logic.unvarifyT o CodegenTheorems.extr_typ thy) eq_thm;
   492               val ty = (Logic.unvarifyT o CodegenTheorems.extr_typ thy) eq_thm;
   501               val vs = (rev ooo fold_atyps)
   493               val vs = (map dest_TFree o Consts.typargs consts) (c', ty);
   502                 (fn TFree v_sort => insert (op =) v_sort | _ => I) ty [];
       
   503               fun dest_eqthm eq_thm =
   494               fun dest_eqthm eq_thm =
   504                 let
   495                 let
   505                   val ((t, args), rhs) =
   496                   val ((t, args), rhs) =
   506                     (apfst strip_comb o Logic.dest_equals o Logic.legacy_unvarify o prop_of) eq_thm;
   497                     (apfst strip_comb o Logic.dest_equals o Logic.unvarify o prop_of) eq_thm;
   507                 in case t
   498                 in case t
   508                  of Const (c', _) => if c' = c then (args, rhs)
   499                  of Const (c', _) => if c' = c then (args, rhs)
   509                      else error ("Illegal function equation for " ^ quote c
   500                      else error ("Illegal function equation for " ^ quote c
   510                        ^ ", actually defining " ^ quote c')
   501                        ^ ", actually defining " ^ quote c')
   511                   | _ => error ("Illegal function equation for " ^ quote c)
   502                   | _ => error ("Illegal function equation for " ^ quote c)
   698 
   689 
   699 
   690 
   700 (** code generation interfaces **)
   691 (** code generation interfaces **)
   701 
   692 
   702 fun generate cs targets init gen it thy =
   693 fun generate cs targets init gen it thy =
   703   thy
   694   let
   704   |> CodegenTheorems.notify_dirty
   695     val thmtab = CodegenTheorems.mk_thmtab thy cs;
   705   |> `Code.get
   696     val qnaming = NameSpace.qualified_names NameSpace.default_naming
   706   |> (fn (modl, thy) =>
   697     val algebr = ClassPackage.operational_algebra thy;
   707         (start_transact init (gen thy (ClassPackage.operational_algebra thy) (CodegenTheorems.mk_thmtab thy cs)
   698     fun ops_of_class class =
   708           (true, targets) it) modl, thy))
   699       let
   709   |-> (fn (x, modl) => Code.map (K modl) #> pair x);
   700         val (v, ops) = ClassPackage.the_consts_sign thy class;
       
   701         val ops_tys = map (fn (c, ty) =>
       
   702           (c, (Logic.varifyT o map_type_tfree (fn u as (w, _) =>
       
   703             if w = v then TFree (v, [class]) else TFree u)) ty)) ops;
       
   704       in
       
   705         map (fn (c, ty) => (idf_of_const thy thmtab (c, ty), ty)) ops_tys
       
   706       end;
       
   707     val classops = maps ops_of_class (Sorts.classes (snd algebr));
       
   708     val consttab = Consts.empty
       
   709       |> fold (fn (c, ty) => Consts.declare qnaming
       
   710            (((idf_of_const thy thmtab o CodegenConsts.typ_of_typinst thy) c, ty), true))
       
   711            (CodegenTheorems.get_fun_typs thmtab)
       
   712       |> fold (Consts.declare qnaming o rpair true) classops;
       
   713     val algbr = (algebr, consttab);
       
   714   in   
       
   715     thy
       
   716     |> CodegenTheorems.notify_dirty
       
   717     |> `Code.get
       
   718     |> (fn (modl, thy) =>
       
   719           (start_transact init (gen thy algbr thmtab
       
   720             (true, targets) it) modl, thy))
       
   721     |-> (fn (x, modl) => Code.map (K modl) #> pair x)
       
   722   end;
   710 
   723 
   711 fun consts_of t =
   724 fun consts_of t =
   712   fold_aterms (fn Const c => cons c | _ => I) t [];
   725   fold_aterms (fn Const c => cons c | _ => I) t [];
   713 
   726 
   714 fun codegen_term t thy =
   727 fun codegen_term t thy =