src/Pure/Tools/codegen_package.ML
changeset 18385 d0071d93978e
parent 18380 9668764224a7
child 18454 6720b5010a57
equal deleted inserted replaced
18384:fa38cca42913 18385:d0071d93978e
    63   val defgen_datatype: (theory -> string -> ((string * sort) list * string list) option)
    63   val defgen_datatype: (theory -> string -> ((string * sort) list * string list) option)
    64     -> (theory -> string * string -> typ list option)
    64     -> (theory -> string * string -> typ list option)
    65     -> defgen;
    65     -> defgen;
    66   val defgen_datacons: (theory -> string * string -> typ list option)
    66   val defgen_datacons: (theory -> string * string -> typ list option)
    67     -> defgen;
    67     -> defgen;
    68   val defgen_datatype_eq: (theory -> string -> ((string * sort) list * string list) option)
       
    69     -> defgen;
       
    70   val defgen_datatype_eqinst: (theory -> string -> ((string * sort) list * string list) option)
       
    71     -> defgen;
       
    72   val defgen_recfun: (theory -> string * typ -> (term list * term) list * typ)
    68   val defgen_recfun: (theory -> string * typ -> (term list * term) list * typ)
    73     -> defgen;
    69     -> defgen;
    74 
    70 
    75   val print_codegen_generated: theory -> unit;
    71   val print_codegen_generated: theory -> unit;
    76   val mk_deftab: theory -> deftab;
    72   val mk_deftab: theory -> deftab;
    79 end;
    75 end;
    80 
    76 
    81 structure CodegenPackage : CODEGEN_PACKAGE =
    77 structure CodegenPackage : CODEGEN_PACKAGE =
    82 struct
    78 struct
    83 
    79 
    84 open CodegenThingol;
    80 open CodegenThingolOp;
       
    81 infix 8 `%%;
       
    82 infixr 6 `->;
       
    83 infixr 6 `-->;
       
    84 infix 4 `$;
       
    85 infix 4 `$$;
       
    86 infixr 5 `|->;
       
    87 infixr 5 `|-->;
    85 
    88 
    86 (* auxiliary *)
    89 (* auxiliary *)
    87 
    90 
    88 fun devarify_term t = (fst o Type.freeze_thaw) t;
    91 fun devarify_term t = (fst o Type.freeze_thaw) t;
    89 fun devarify_type ty = (fst o Type.freeze_thaw_type) ty;
    92 fun devarify_type ty = (fst o Type.freeze_thaw_type) ty;
   123 val nsp_type = "type";
   126 val nsp_type = "type";
   124 val nsp_const = "const";
   127 val nsp_const = "const";
   125 val nsp_dtcon = "dtcon"; (*NOT OPERATIONAL YET*)
   128 val nsp_dtcon = "dtcon"; (*NOT OPERATIONAL YET*)
   126 val nsp_mem = "mem";
   129 val nsp_mem = "mem";
   127 val nsp_inst = "inst";
   130 val nsp_inst = "inst";
   128 val nsp_eq_class = "eq_class";
   131 val nsp_eq_inst = "eq_inst";
   129 val nsp_eq = "eq";
   132 val nsp_eq_pred = "eq";
   130 
   133 
   131 
   134 
   132 (* serializer *)
   135 (* serializer *)
   133 
   136 
   134 val serializer_ml =
   137 val serializer_ml =
   135   let
   138   let
   136     val name_root = "Generated";
   139     val name_root = "Generated";
   137     val nsp_conn = [
   140     val nsp_conn = [
   138       [nsp_class, nsp_type, nsp_eq_class], [nsp_const, nsp_dtcon, nsp_inst, nsp_mem, nsp_eq]
   141       [nsp_class, nsp_type], [nsp_const, nsp_dtcon, nsp_inst, nsp_mem, nsp_eq_inst, nsp_eq_pred]
   139     ];
   142     ];
   140   in CodegenSerializer.ml_from_thingol nsp_conn name_root end;
   143   in CodegenSerializer.ml_from_thingol nsp_conn name_root end;
   141 
   144 
   142 val serializer_hs =
   145 val serializer_hs =
   143   let
   146   let
   144     val name_root = "Generated";
   147     val name_root = "Generated";
   145     val nsp_conn = [
   148     val nsp_conn = [
   146       [nsp_class, nsp_eq_class], [nsp_type], [nsp_const, nsp_mem, nsp_eq], [nsp_dtcon], [nsp_inst]
   149       [nsp_class], [nsp_type], [nsp_const, nsp_mem, nsp_eq_pred], [nsp_dtcon], [nsp_inst, nsp_eq_inst]
   147     ];
   150     ];
   148   in CodegenSerializer.haskell_from_thingol nsp_conn name_root end;
   151   in CodegenSerializer.haskell_from_thingol nsp_conn name_root end;
   149 
   152 
   150 
   153 
   151 (* theory data for codegen *)
   154 (* theory data for codegen *)
   270       Symtab.empty
   273       Symtab.empty
   271       |> Symtab.update ("ml",
   274       |> Symtab.update ("ml",
   272           { serializer = serializer_ml : CodegenSerializer.serializer,
   275           { serializer = serializer_ml : CodegenSerializer.serializer,
   273             primitives =
   276             primitives =
   274               CodegenSerializer.empty_prims
   277               CodegenSerializer.empty_prims
       
   278               |> CodegenSerializer.add_prim ("Eq", ("type 'a Eq = {eq: 'a -> 'a -> bool};", []))
   275               |> CodegenSerializer.add_prim ("fst", ("fun fst (x, _) = x;", []))
   279               |> CodegenSerializer.add_prim ("fst", ("fun fst (x, _) = x;", []))
   276               |> CodegenSerializer.add_prim ("snd", ("fun snd (_, y) = y;", []))
   280               |> CodegenSerializer.add_prim ("snd", ("fun snd (_, y) = y;", []))
   277               |> CodegenSerializer.add_prim ("wfrec", ("fun wfrec f x = f (wfrec f) x;", [])),
   281               |> CodegenSerializer.add_prim ("wfrec", ("fun wfrec f x = f (wfrec f) x;", [])),
   278             syntax_tyco = Symtab.empty, syntax_const = Symtab.empty })
   282             syntax_tyco = Symtab.empty, syntax_const = Symtab.empty })
   279       |> Symtab.update ("haskell",
   283       |> Symtab.update ("haskell",
   569     |-> (fn ((eqs, ty), sortctxt) => pair (Fun (eqs, (sortctxt, ty))))
   573     |-> (fn ((eqs, ty), sortctxt) => pair (Fun (eqs, (sortctxt, ty))))
   570   end;
   574   end;
   571 
   575 
   572 fun fix_nargs thy defs gen (imin, imax) (t, ts) trns =
   576 fun fix_nargs thy defs gen (imin, imax) (t, ts) trns =
   573   if length ts < imin then
   577   if length ts < imin then
   574     trns
   578     let
   575     |> debug 10 (fn _ => "eta-expanding")
   579       val d = imin - length ts;
   576     |> gen (strip_comb (Codegen.eta_expand t ts imin))
   580       val vs = Term.invent_names (add_term_names (t, [])) "x" d;
   577     |-> succeed
   581       val tys = Library.take (d, ((fst o strip_type o fastype_of) t));
       
   582     in
       
   583       trns
       
   584       |> debug 10 (fn _ => "eta-expanding")
       
   585       |> fold_map (invoke_cg_type thy defs) tys
       
   586       ||>> gen (t, ts @ map2 (curry Free) vs tys)
       
   587       |-> (fn (tys, e) => succeed ((vs ~~ tys) `|--> e))
       
   588     end
   578   else if length ts > imax then
   589   else if length ts > imax then
   579     trns
   590     trns
   580     |> debug 10 (fn _ => "splitting arguments (" ^ string_of_int imax ^ ", " ^ string_of_int (length ts) ^ ")")
   591     |> debug 10 (fn _ => "splitting arguments (" ^ string_of_int imax ^ ", " ^ string_of_int (length ts) ^ ")")
   581     |> gen (t, Library.take (imax, ts))
   592     |> gen (t, Library.take (imax, ts))
   582     ||>> fold_map (invoke_cg_expr thy defs) (Library.drop (imax, ts))
   593     ||>> fold_map (invoke_cg_expr thy defs) (Library.drop (imax, ts))
   585     trns
   596     trns
   586     |> debug 10 (fn _ => "keeping arguments")
   597     |> debug 10 (fn _ => "keeping arguments")
   587     |> gen (t, ts)
   598     |> gen (t, ts)
   588     |-> succeed;
   599     |-> succeed;
   589 
   600 
   590 local
       
   591   open CodegenThingolOp;
       
   592   infix 8 `%%;
       
   593   infixr 6 `->;
       
   594   infixr 6 `-->;
       
   595   infix 4 `$;
       
   596   infix 4 `$$;
       
   597   infixr 5 `|->;
       
   598   infixr 5 `|-->;
       
   599 in
       
   600 
   601 
   601 (* code generators *)
   602 (* code generators *)
   602 
   603 
   603 fun exprgen_sort_default thy defs sort trns =
   604 fun exprgen_sort_default thy defs sort trns =
   604   trns
   605   trns
   699       end
   700       end
   700   | appgen_neg thy defs ((f, _), _) trns =
   701   | appgen_neg thy defs ((f, _), _) trns =
   701       trns
   702       trns
   702       |> fail ("not a negation: " ^ quote f);
   703       |> fail ("not a negation: " ^ quote f);
   703 
   704 
   704 fun exprgen_term_eq thy defs (Const ("op =", Type ("fun", [ty, _]))) trns =
   705 fun appgen_eq thy defs (f as ("op =", Type ("fun", [ty, _])), ts) trns =
   705   trns
   706       let
   706 
   707         fun mk_eq_pred_inst (dtco, (eqpred, arity)) trns =
   707 (*fun codegen_eq thy defs t trns =
   708           let
   708  let
   709             val name_dtco = (the oo tname_of_idf) thy dtco;
   709    fun cg_eq (Const ("op =", _), [t, u]) =
   710             val idf_eqinst = idf_of_name thy nsp_eq_inst name_dtco;
   710          trns
   711             val idf_eqpred = idf_of_name thy nsp_eq_pred name_dtco;
   711          |> invoke_cg_type thy defs (type_of t)
   712             fun mk_eq_pred _ trns =
   712          |-> (fn ty => invoke_ensure_eqinst nsp_eq_class nsp_eq ty #> pair ty)
   713               trns
   713          ||>> invoke_cg_expr thy defs t
   714               |> succeed (eqpred, [])
   714          ||>> invoke_cg_expr thy defs u
   715             fun mk_eq_inst _ trns =
   715          |-> (fn ((ty, t'), u') => succeed (
   716               trns
   716                IConst (fun_eq, ty `-> ty `-> Type_bool)
   717               |> gen_ensure_def [("eqpred", mk_eq_pred)] ("generating equality predicate for " ^ quote dtco) idf_eqpred
   717                  `$ t' `$ u'))
   718               |> succeed (Classinst (class_eq, (dtco, arity), [(fun_eq, idf_eqpred)]), [])
   718      | cg_eq _ =
   719           in
   719          trns
   720             trns
   720          |> fail ("no equality: " ^ Sign.string_of_term thy t)
   721             |> gen_ensure_def [("eqinst", mk_eq_inst)] ("generating equality instance for " ^ quote dtco) idf_eqinst
   721   in cg_eq (strip_comb t) end;*)
   722           end;
   722 
   723         fun mk_eq_expr (_, [t1, t2]) trns =
       
   724           trns
       
   725           |> invoke_eq (invoke_cg_type thy defs) mk_eq_pred_inst ty
       
   726           |-> (fn false => error ("could not derive equality for " ^ Sign.string_of_typ thy ty)
       
   727                 | true => fn trns => trns
       
   728           |> invoke_cg_expr thy defs t1
       
   729           ||>> invoke_cg_expr thy defs t2
       
   730           |-> (fn (e1, e2) => pair (Fun_eq `$ e1 `$ e2)))
       
   731       in
       
   732         trns
       
   733         |> fix_nargs thy defs mk_eq_expr (2, 2) (Const f, ts)
       
   734       end
       
   735   | appgen_eq thy defs ((f, _), _) trns =
       
   736       trns
       
   737       |> fail ("not an equality: " ^ quote f);
       
   738 
       
   739 
       
   740 (* invoke_eq: ((string * def) -> transact -> transact) -> itype -> transact -> bool * transact;  *)
   723 
   741 
   724 (* definition generators *)
   742 (* definition generators *)
   725 
   743 
   726 fun defgen_tyco_fallback thy defs tyco trns =
   744 fun defgen_tyco_fallback thy defs tyco trns =
   727   if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco)
   745   if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco)
   944             |> fix_nargs thy defs (cg_case dty (cs ~~ tys))
   962             |> fix_nargs thy defs (cg_case dty (cs ~~ tys))
   945                  (length cs + 1, length cs + 1) (Const (f, ty), ts)
   963                  (length cs + 1, length cs + 1) (Const (f, ty), ts)
   946           end
   964           end
   947   end;
   965   end;
   948 
   966 
   949 local
       
   950 
       
   951 fun add_eqinst get_datacons thy modl dtname cnames =
       
   952   if forall (is_eqtype modl)
       
   953     (Library.flat (map (fn cname => get_datacons thy (cname, dtname)) cnames))
       
   954   then append [idf_of_name thy nsp_eq_class dtname]
       
   955   else I
       
   956 
       
   957 in
       
   958 
       
   959 fun defgen_datatype get_datatype get_datacons thy defs idf trns =
   967 fun defgen_datatype get_datatype get_datacons thy defs idf trns =
   960   case tname_of_idf thy idf
   968   case tname_of_idf thy idf
   961    of SOME dtco =>
   969    of SOME dtco =>
   962         (case get_datatype thy dtco
   970         (case get_datatype thy dtco
   963          of SOME (vars, cos) =>
   971          of SOME (vars, cos) =>
   981               trns
   989               trns
   982               |> fail ("no datatype found for " ^ quote dtco))
   990               |> fail ("no datatype found for " ^ quote dtco))
   983     | NONE =>
   991     | NONE =>
   984         trns
   992         trns
   985         |> fail ("not a type constructor: " ^ quote idf)
   993         |> fail ("not a type constructor: " ^ quote idf)
   986   end;
       
   987 
       
   988 end; (* local *)
       
   989 
   994 
   990 fun defgen_datacons get_datacons thy defs f trns =
   995 fun defgen_datacons get_datacons thy defs f trns =
   991   let
   996   let
   992     fun the_type "0" = SOME "nat"
   997     fun the_type "0" = SOME "nat"
   993       | the_type c =
   998       | the_type c =
  1013                 |> fail ("no datatype constructor found for " ^ quote f))
  1018                 |> fail ("no datatype constructor found for " ^ quote f))
  1014       | _ =>
  1019       | _ =>
  1015           trns
  1020           trns
  1016           |> fail ("not a constant: " ^ quote f)
  1021           |> fail ("not a constant: " ^ quote f)
  1017   end;
  1022   end;
  1018 
       
  1019 fun defgen_datatype_eq get_datatype thy defs f trns =
       
  1020   case name_of_idf thy nsp_eq f
       
  1021    of SOME dtname =>
       
  1022         (case get_datatype thy dtname
       
  1023          of SOME (_, cnames) =>
       
  1024               trns
       
  1025               |> debug 5 (fn _ => "trying defgen datatype_eq for " ^ quote dtname)
       
  1026               |> ensure_def_tyco thy defs (idf_of_tname thy dtname)
       
  1027               ||>> fold_map (ensure_def_const thy defs) (cnames
       
  1028                    |> map (idf_of_name thy nsp_const)
       
  1029                    |> map (fn "0" => "const.Zero" | c => c))
       
  1030               ||>> `(fn (_, modl) => build_eqpred modl dtname)
       
  1031               |-> (fn (_, eqpred) => succeed (eqpred, []))
       
  1032           | NONE =>
       
  1033               trns
       
  1034               |> fail ("no datatype found for " ^ quote dtname))
       
  1035     | NONE =>
       
  1036         trns
       
  1037         |> fail ("not an equality predicate: " ^ quote f)
       
  1038 
       
  1039 fun defgen_datatype_eqinst get_datatype thy defs f trns =
       
  1040   case name_of_idf thy nsp_eq_class f
       
  1041    of SOME dtname =>
       
  1042         (case get_datatype thy dtname
       
  1043          of SOME (vars, _) =>
       
  1044               trns
       
  1045               |> debug 5 (fn _ => "trying defgen datatype_eqinst for " ^ quote dtname)
       
  1046               |> ensure_def_const thy defs (idf_of_name thy nsp_eq dtname)
       
  1047               |-> (fn pred_eq => succeed (Classinst (class_eq, (dtname,
       
  1048                     map (fn (v, _) => (v, [class_eq])) vars), [(fun_eq, pred_eq)]), []))
       
  1049           | NONE =>
       
  1050               trns
       
  1051               |> fail ("no datatype found for " ^ quote dtname))
       
  1052     | NONE =>
       
  1053         trns
       
  1054         |> fail ("not an equality instance: " ^ quote f)
       
  1055 
  1023 
  1056 fun defgen_recfun get_equations thy defs f trns =
  1024 fun defgen_recfun get_equations thy defs f trns =
  1057   case cname_of_idf thy defs f
  1025   case cname_of_idf thy defs f
  1058    of SOME (f, ty) =>
  1026    of SOME (f, ty) =>
  1059         let
  1027         let
  1453     CodegenData.init,
  1421     CodegenData.init,
  1454     add_codegen_sort ("default", exprgen_sort_default),
  1422     add_codegen_sort ("default", exprgen_sort_default),
  1455     add_codegen_type ("default", exprgen_type_default),
  1423     add_codegen_type ("default", exprgen_type_default),
  1456     add_codegen_expr ("default", exprgen_term_default),
  1424     add_codegen_expr ("default", exprgen_term_default),
  1457     add_appgen ("default", appgen_default),
  1425     add_appgen ("default", appgen_default),
  1458 (*     add_codegen_expr ("eq", codegen_eq),  *)
  1426     add_appgen ("eq", appgen_eq),
  1459     add_appgen ("neg", appgen_neg),
  1427     add_appgen ("neg", appgen_neg),
  1460     add_defgen ("clsdecl", defgen_clsdecl),
  1428     add_defgen ("clsdecl", defgen_clsdecl),
  1461     add_defgen ("tyco_fallback", defgen_tyco_fallback),
  1429     add_defgen ("tyco_fallback", defgen_tyco_fallback),
  1462     add_defgen ("const_fallback", defgen_const_fallback),
  1430     add_defgen ("const_fallback", defgen_const_fallback),
  1463     add_defgen ("defs", defgen_defs),
  1431     add_defgen ("defs", defgen_defs),