src/Pure/Tools/codegen_thingol.ML
changeset 18335 99baddf6b0d0
parent 18330 444f16d232a2
child 18360 a2c9506b62a7
equal deleted inserted replaced
18334:a41ce9c10b73 18335:99baddf6b0d0
     1 (*  Title:      Pure/Tools/codegen_thingol.ML
     1  (*  Title:      Pure/Tools/codegen_thingol.ML
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Florian Haftmann, TU Muenchen
     3     Author:     Florian Haftmann, TU Muenchen
     4 
     4 
     5 Intermediate language ("Thin-gol") for code extraction.
     5 Intermediate language ("Thin-gol") for code extraction.
     6 *)
     6 *)
    46 
    46 
    47   datatype def =
    47   datatype def =
    48       Nop
    48       Nop
    49     | Fun of (ipat list * iexpr) list * (ClassPackage.sortcontext * itype)
    49     | Fun of (ipat list * iexpr) list * (ClassPackage.sortcontext * itype)
    50     | Typesyn of (vname * string list) list * itype
    50     | Typesyn of (vname * string list) list * itype
    51     | Datatype of (vname * string list) list * string list * class list
    51     | Datatype of (vname * string list) list * string list * string list
    52     | Datatypecons of string * itype list
    52     | Datatypecons of string * itype list
    53     | Class of class list * vname * string list * string list
    53     | Class of class list * vname * string list * string list
    54     | Classmember of class * vname * itype
    54     | Classmember of class * vname * itype
    55     | Classinst of class * (string * (vname * string list) list) * (string * string) list;
    55     | Classinst of class * (string * (vname * string list) list) * (string * string) list;
    56   type module;
    56   type module;
    76   val type_bool: string;
    76   val type_bool: string;
    77   val type_pair: string;
    77   val type_pair: string;
    78   val type_list: string;
    78   val type_list: string;
    79   val type_integer: string;
    79   val type_integer: string;
    80   val cons_pair: string;
    80   val cons_pair: string;
       
    81   val fun_eq: string;
    81   val fun_fst: string;
    82   val fun_fst: string;
    82   val fun_snd: string;
    83   val fun_snd: string;
    83   val Type_integer: itype;
    84   val Type_integer: itype;
    84   val Cons_true: iexpr;
    85   val Cons_true: iexpr;
    85   val Cons_false: iexpr;
    86   val Cons_false: iexpr;
   101   val Fun_lt: iexpr;
   102   val Fun_lt: iexpr;
   102   val Fun_le: iexpr;
   103   val Fun_le: iexpr;
   103   val Fun_wfrec: iexpr;
   104   val Fun_wfrec: iexpr;
   104 
   105 
   105   val prims: string list;
   106   val prims: string list;
       
   107   val get_eqpred: module -> string -> string option;
   106   val is_eqtype: module -> itype -> bool;
   108   val is_eqtype: module -> itype -> bool;
       
   109   val build_eqpred: module -> string -> def;
   107   val extract_defs: iexpr -> string list;
   110   val extract_defs: iexpr -> string list;
   108   val eta_expand: (string -> int) -> module -> module;
   111   val eta_expand: (string -> int) -> module -> module;
   109   val eta_expand_poly: module -> module;
   112   val eta_expand_poly: module -> module;
   110   val connect_datatypes_clsdecls: module -> module;
   113   val connect_datatypes_clsdecls: module -> module;
   111   val tupelize_cons: module -> module;
   114   val tupelize_cons: module -> module;
   482       Pretty.block [
   485       Pretty.block [
   483         Pretty.list "(" ")" (map (pretty_itype o IVarT) vs),
   486         Pretty.list "(" ")" (map (pretty_itype o IVarT) vs),
   484         Pretty.str " |=> ",
   487         Pretty.str " |=> ",
   485         pretty_itype ty
   488         pretty_itype ty
   486       ]
   489       ]
   487   | pretty_def (Datatype (vs, cs, clss)) =
   490   | pretty_def (Datatype (vs, cs, insts)) =
   488       Pretty.block [
   491       Pretty.block [
   489         Pretty.list "(" ")" (map (pretty_itype o IVarT) vs),
   492         Pretty.list "(" ")" (map (pretty_itype o IVarT) vs),
   490         Pretty.str " |=> ",
   493         Pretty.str " |=> ",
   491         Pretty.gen_list " |" "" "" (map Pretty.str cs),
   494         Pretty.gen_list " |" "" "" (map Pretty.str cs),
   492         Pretty.str ", instance of ",
   495         Pretty.str ", instances ",
   493         Pretty.gen_list "," "[" "]" (map Pretty.str clss)
   496         Pretty.gen_list "," "[" "]" (map Pretty.str insts)
   494       ]
   497       ]
   495   | pretty_def (Datatypecons (dtname, tys)) =
   498   | pretty_def (Datatypecons (dtname, tys)) =
   496       Pretty.block [
   499       Pretty.block [
   497         Pretty.str "cons ",
   500         Pretty.str "cons ",
   498         Pretty.gen_list " ->" "" "" (map pretty_itype tys @ [Pretty.str dtname])
   501         Pretty.gen_list " ->" "" "" (map pretty_itype tys @ [Pretty.str dtname])
   653       | join_module _ =
   656       | join_module _ =
   654           NONE
   657           NONE
   655   in Graph.join (K join_module) modl12 end;
   658   in Graph.join (K join_module) modl12 end;
   656 
   659 
   657 fun partof names modl =
   660 fun partof names modl =
   658       let
   661   let
   659         datatype pathnode = PN of (string list * (string * pathnode) list);
   662     datatype pathnode = PN of (string list * (string * pathnode) list);
   660         fun mk_ipath ([], base) (PN (defs, modls)) =
   663     fun mk_ipath ([], base) (PN (defs, modls)) =
   661               PN (base :: defs, modls)
   664           PN (base :: defs, modls)
   662           | mk_ipath (n::ns, base) (PN (defs, modls)) =
   665       | mk_ipath (n::ns, base) (PN (defs, modls)) =
   663               modls
   666           modls
   664               |> AList.default (op =) (n, PN ([], []))
   667           |> AList.default (op =) (n, PN ([], []))
   665               |> AList.map_entry (op =) n (mk_ipath (ns, base))
   668           |> AList.map_entry (op =) n (mk_ipath (ns, base))
   666               |> (pair defs #> PN);
   669           |> (pair defs #> PN);
   667         fun select (PN (defs, modls)) (Module module) =
   670     fun select (PN (defs, modls)) (Module module) =
   668           module
   671       module
   669           |> Graph.subgraph (Graph.all_succs module (defs @ map fst modls))
   672       |> Graph.subgraph (Graph.all_succs module (defs @ map fst modls))
   670           |> fold (fn (name, modls) => Graph.map_node name (select modls)) modls
   673       |> fold (fn (name, modls) => Graph.map_node name (select modls)) modls
   671           |> Module;
   674       |> Module;
   672       in
   675   in
   673         Module modl
   676     Module modl
   674         |> select (fold (mk_ipath o dest_name) (filter NameSpace.is_qualified names) (PN ([], [])))
   677     |> select (fold (mk_ipath o dest_name) (filter NameSpace.is_qualified names) (PN ([], [])))
   675         |> dest_modl
   678     |> dest_modl
   676       end;
   679   end;
   677 
   680 
   678 fun add_check_transform (name, (Datatypecons (dtname, _))) =
   681 fun add_check_transform (name, (Datatypecons (dtname, _))) =
   679       (debug 7 (fn _ => "transformation for datatype constructor " ^ quote name
   682       (debug 7 (fn _ => "transformation for datatype constructor " ^ quote name
   680         ^ " of datatype " ^ quote dtname) ();
   683         ^ " of datatype " ^ quote dtname) ();
   681       ([([dtname],
   684       ([([dtname],
   682           fn [Datatype (_, _, [])] => NONE
   685           fn [Datatype (_, _, [])] => NONE
   683             | _ => "attempted to add constructor to already instantiating datatype" |> SOME)],
   686             | _ => "attempted to add constructor to already instantiating datatype" |> SOME)],
   684        [(dtname,
   687        [(dtname,
   685           fn Datatype (vs, cs, clss) => Datatype (vs, name::cs, clss)
   688           fn Datatype (vs, cs, insts) => Datatype (vs, name::cs, insts)
   686            | def => "attempted to add datatype constructor to non-datatype: "
   689            | def => "attempted to add datatype constructor to non-datatype: "
   687               ^ (Pretty.output o pretty_def) def |> error)])
   690               ^ (Pretty.output o pretty_def) def |> error)])
   688       )
   691       )
   689   | add_check_transform (name, Classmember (clsname, v, ty)) =
   692   | add_check_transform (name, Classmember (clsname, v, ty)) =
   690       let
   693       let
   732           [(clsname,
   735           [(clsname,
   733               fn Class (supcs, v, mems, insts) => Class (supcs, v, mems, name::insts)
   736               fn Class (supcs, v, mems, insts) => Class (supcs, v, mems, name::insts)
   734                | def => "attempted to add class instance to non-class"
   737                | def => "attempted to add class instance to non-class"
   735                   ^ (Pretty.output o pretty_def) def |> error),
   738                   ^ (Pretty.output o pretty_def) def |> error),
   736            (tyco,
   739            (tyco,
   737               fn Datatype (vs, cs, clss) => Datatype (vs, cs, clsname::clss)
   740               fn Datatype (vs, cs, insts) => Datatype (vs, cs, name::insts)
   738                | Nop => Nop
   741                | Nop => Nop
   739                | def => "attempted to instantiate non-type to class instance"
   742                | def => "attempted to instantiate non-type to class instance"
   740                   ^ (Pretty.output o pretty_def) def |> error)])
   743                   ^ (Pretty.output o pretty_def) def |> error)])
   741       end
   744       end
   742   | add_check_transform _ = ([], []);
   745   | add_check_transform _ = ([], []);
   943 
   946 
   944 val prims = [class_eq, type_bool, type_integer, type_float, type_pair, type_list,
   947 val prims = [class_eq, type_bool, type_integer, type_float, type_pair, type_list,
   945   cons_true, cons_false, cons_pair, cons_nil, cons_cons, fun_primeq, fun_eq, fun_not, fun_and,
   948   cons_true, cons_false, cons_pair, cons_nil, cons_cons, fun_primeq, fun_eq, fun_not, fun_and,
   946   fun_or, fun_if, fun_fst, fun_snd, fun_add, fun_mult, fun_minus, fun_lt, fun_le, fun_wfrec];
   949   fun_or, fun_if, fun_fst, fun_snd, fun_add, fun_mult, fun_minus, fun_lt, fun_le, fun_wfrec];
   947 
   950 
   948 fun is_superclass_of modl class_sub class_sup =
   951 
   949   if class_sub = class_sup
   952 (** equality handling **)
   950   then true
   953 
   951   else
   954 fun get_eqpred modl tyco =
   952     if NameSpace.is_qualified class_sub
   955   if NameSpace.is_qualified tyco
   953     then
   956   then
   954       case get_def modl class_sub
   957     case get_def modl tyco
   955        of Class (supclsnames, _, _, _)
   958      of Datatype (_, _, insts) =>
   956             => exists (fn class => is_superclass_of modl class class_sup) supclsnames
   959           get_first (fn inst =>
   957     else
   960             case get_def modl inst
   958       false;
   961              of Classinst (cls, _, memdefs) =>
       
   962                 if cls = class_eq
       
   963                 then (SOME o snd o hd) memdefs
       
   964                 else NONE) insts
       
   965   else SOME fun_primeq;
   959 
   966 
   960 fun is_eqtype modl (IType (tyco, tys)) =
   967 fun is_eqtype modl (IType (tyco, tys)) =
   961       forall (is_eqtype modl) tys
   968       forall (is_eqtype modl) tys
   962       andalso
   969       andalso (
   963         if NameSpace.is_qualified tyco
   970         NameSpace.is_qualified tyco
   964         then
   971         orelse
   965           case get_def modl tyco
   972           case get_def modl tyco
   966            of Typesyn (vs, ty) => is_eqtype modl ty
   973            of Typesyn (vs, ty) => is_eqtype modl ty
   967             | Datatype (_, _, classes) => exists (is_superclass_of modl class_eq) classes
   974             | Datatype (_, _, insts) =>
   968         else
   975                 exists (fn inst => case get_def modl inst of Classinst (cls, _, _) => cls = class_eq) insts
   969           true
   976       )
   970   | is_eqtype modl (IFun _) =
   977   | is_eqtype modl (IFun _) =
   971       false
   978       false
   972   | is_eqtype modl (IVarT (_, sort)) =
   979   | is_eqtype modl (IVarT (_, sort)) =
   973       exists (is_superclass_of modl class_eq) sort
   980       member (op =) sort class_eq;
       
   981 
       
   982 fun build_eqpred modl dtname =
       
   983   let
       
   984     val cons =
       
   985       map ((fn Datatypecons c => c) o get_def modl)
       
   986         (case get_def modl dtname of Datatype (_, cs, _) => cs);
       
   987     val sortctxt =
       
   988       map (rpair [class_eq])
       
   989         (case get_def modl dtname of Datatype (_, vs, _) => vs);
       
   990     val ty = IType (dtname, map IVarT sortctxt);
       
   991     fun mk_eq (c, []) =
       
   992           ([ICons ((c, []), ty), ICons ((c, []), ty)], Cons_true)
       
   993       | mk_eq (c, tys) =
       
   994           let
       
   995             val vars1 = Term.invent_names [] "a" (length tys);
       
   996             val vars2 = Term.invent_names vars1 "b" (length tys);
       
   997             fun mk_eq_cons ty' (v1, v2) =
       
   998               IConst (fun_eq, ty' `-> ty' `-> Type_bool) `$ IVarE (v1, ty) `$ IVarE (v2, ty)
       
   999             fun mk_conj (e1, e2) =
       
  1000               Fun_and `$ e1 `$ e2;
       
  1001           in
       
  1002             ([ICons ((c, map2 (curry IVarP) vars1 tys), ty),
       
  1003               ICons ((c, map2 (curry IVarP) vars2 tys), ty)],
       
  1004               foldr1 mk_conj (map2 mk_eq_cons tys (vars1 ~~ vars2)))
       
  1005           end;
       
  1006     val eqs = map mk_eq cons @ [([IVarP ("_", ty), IVarP ("_", ty)], Cons_false)];
       
  1007   in
       
  1008     Fun (eqs, (sortctxt, ty `-> ty `-> Type_bool))
       
  1009   end;
       
  1010 
       
  1011 
       
  1012 (** generic transformation **)
   974 
  1013 
   975 fun extract_defs e =
  1014 fun extract_defs e =
   976   let
  1015   let
   977     fun extr_itype (ty as IType (tyco, _)) =
  1016     fun extr_itype (ty as IType (tyco, _)) =
   978           cons tyco #> fold_itype extr_itype ty
  1017           cons tyco #> fold_itype extr_itype ty
   985     fun extr_iexpr (e as IConst (f, _)) =
  1024     fun extr_iexpr (e as IConst (f, _)) =
   986           cons f #> fold_iexpr extr_itype extr_ipat extr_iexpr e
  1025           cons f #> fold_iexpr extr_itype extr_ipat extr_iexpr e
   987       | extr_iexpr e =
  1026       | extr_iexpr e =
   988           fold_iexpr extr_itype extr_ipat extr_iexpr e
  1027           fold_iexpr extr_itype extr_ipat extr_iexpr e
   989   in extr_iexpr e [] end;
  1028   in extr_iexpr e [] end;
   990 
       
   991 
       
   992 
       
   993 (** generic transformation **)
       
   994 
  1029 
   995 fun eta_expand query =
  1030 fun eta_expand query =
   996   let
  1031   let
   997     fun eta_app ((f, ty), es) =
  1032     fun eta_app ((f, ty), es) =
   998       let
  1033       let