src/Pure/Tools/codegen_package.ML
changeset 24166 7b28dc69bdbb
parent 23955 f1ba12c117ec
equal deleted inserted replaced
24165:605f664d5115 24166:7b28dc69bdbb
     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);
   509 
   524 
   510 (* generic generation combinators *)
   525 (* generic generation combinators *)
   511 
   526 
   512 fun generate thy funcgr gen it =
   527 fun generate thy funcgr gen it =
   513   let
   528   let
       
   529     (*FIXME*)
       
   530     val _ = Funcgr.intervene thy funcgr;
   514     val cs = map_filter (Consttab.lookup ((snd o snd o Translation.get) thy))
   531     val cs = map_filter (Consttab.lookup ((snd o snd o Translation.get) thy))
   515       (CodegenFuncgr.all funcgr);
   532       (CodegenFuncgr.all funcgr);
   516     val funcgr' = Funcgr.make thy cs;
   533     val funcgr' = Funcgr.make thy cs;
   517     val naming = NameSpace.qualified_names NameSpace.default_naming;
   534     val naming = NameSpace.qualified_names NameSpace.default_naming;
   518     val consttab = Consts.empty
   535     val consttab = Consts.empty
   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"))