src/Pure/Tools/nbe_codegen.ML
author nipkow
Fri, 09 Jun 2006 12:17:58 +0200
changeset 19830 b81d803dfaa4
parent 19795 746274ca400b
child 20706 f77bd47a70df
permissions -rwxr-xr-x
renamed command
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
     1
(*  ID:         $Id$
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
     2
    Author:     Klaus Aehlig, LMU Muenchen; Tobias Nipkow, TU Muenchen
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
     3
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
     4
Code generator for "normalization by evaluation".
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
     5
*)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
     6
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
     7
(* Global asssumptions:
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
     8
   For each function: there is at least one defining eqns and
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
     9
   all defining equations have same number of arguments.
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    10
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    11
FIXME
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
    12
fun MLname
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    13
val quote = quote;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    14
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    15
*)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    16
19118
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    17
signature NBE_CODEGEN =
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    18
sig
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    19
  val generate: (string -> bool) -> string * CodegenThingol.def -> string;
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    20
  val nterm_to_term: theory -> NBE_Eval.nterm -> term;
19118
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    21
end
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    22
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    23
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    24
structure NBE_Codegen: NBE_CODEGEN =
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    25
struct
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    26
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    27
val Eval = "NBE_Eval";
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
    28
val Eval_mk_Fun  = Eval ^ ".mk_Fun";
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    29
val Eval_apply   = Eval ^ ".apply";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    30
val Eval_Constr  = Eval ^ ".Constr";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    31
val Eval_C       = Eval ^ ".C";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    32
val Eval_AbsN    = Eval ^ ".AbsN";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    33
val Eval_Fun     = Eval ^ ".Fun";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    34
val Eval_BVar    = Eval ^ ".BVar";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    35
val Eval_new_name = Eval ^ ".new_name";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    36
val Eval_to_term = Eval ^ ".to_term";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    37
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
    38
fun MLname s = "nbe_" ^ translate_string (fn "." => "_" | c => c) s;
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    39
fun MLvname s  = "v_" ^ MLname s;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    40
fun MLparam n  = "p_" ^ string_of_int n;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    41
fun MLintern s = "i_" ^ MLname s;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    42
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    43
fun MLparams n = map MLparam (1 upto n);
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    44
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    45
structure S =
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    46
struct
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    47
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    48
val quote = quote; (* FIXME *)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    49
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    50
fun app e1 e2 = "(" ^ e1 ^ " " ^ e2 ^ ")";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    51
fun abs v e = "(fn" ^ v ^ " => " ^ e ^ ")";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    52
fun tup es = "(" ^ commas es ^ ")";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    53
fun list es = "[" ^ commas es ^ "]";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    54
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    55
fun apps s ss = Library.foldl (uncurry app) (s, ss);
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    56
fun nbe_apps s ss =
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    57
  Library.foldr (fn (s,e) => app (app Eval_apply e) s) (ss,s);
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    58
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    59
fun eqns name ees =
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    60
  let fun eqn (es,e) = name ^ " " ^ space_implode " " es ^ " = " ^ e
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    61
  in "fun " ^ space_implode "\n  | " (map eqn ees) ^ ";\n" end;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    62
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    63
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    64
fun Val v s = "val " ^ v ^ " = " ^ s;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    65
fun Let ds e = "let\n" ^ (space_implode "\n" ds) ^ " in " ^ e ^ " end"
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    66
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    67
end
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    68
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    69
val tab_lookup = S.app "NBE.lookup";
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    70
val tab_update = S.app "NBE.update";
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
    71
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    72
fun mk_nbeFUN(nm,e) =
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    73
  S.app Eval_Fun (S.tup [S.abs(S.list [MLvname nm])e,S.list [],"1",
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    74
      S.abs(S.tup [])(S.Let 
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    75
        [S.Val (MLintern "var") (S.app Eval_new_name (S.tup [])),
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    76
         S.Val (MLvname nm) (S.app Eval_BVar (S.tup [(MLintern "var"), S.list []]))]
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    77
	(S.app Eval_AbsN(S.tup[MLintern "var",(S.app Eval_to_term e)])))]);
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    78
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    79
fun take_last n xs = rev (Library.take(n, rev xs));
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    80
fun drop_last n xs = rev (Library.drop(n, rev xs));
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    81
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    82
fun selfcall nm ar args =
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    83
	if (ar <= length args) then 
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    84
	  S.nbe_apps (S.app (MLname nm) (S.list (take_last ar args)))
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    85
	             (drop_last ar args)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    86
        else S.app Eval_Fun (S.tup [MLname nm,S.list args,
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    87
	           string_of_int(ar - (length args)),
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    88
		   S.abs (S.tup []) (S.app Eval_C
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    89
	(S.quote nm))]);
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    90
19167
f237c0cb3882 refined representation of codegen intermediate language
haftmann
parents: 19147
diff changeset
    91
open BasicCodegenThingol;
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    92
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
    93
fun mk_rexpr defined nm ar =
19202
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
    94
  let
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
    95
    fun mk args = CodegenThingol.map_pure (mk' args)
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
    96
    and mk' args (IConst (c, _)) =
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
    97
          if c = nm then selfcall nm ar args
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
    98
          else if defined c then S.nbe_apps (MLname c) args
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
    99
          else S.app Eval_Constr (S.tup [S.quote c, S.list args])
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   100
      | mk' args (IVar s) = S.nbe_apps (MLvname s) args
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   101
      | mk' args (e1 `$ e2) = mk (args @ [mk [] e2]) e1
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   102
      | mk' args ((nm, _) `|-> e) = S.nbe_apps (mk_nbeFUN (nm, mk [] e)) args;
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   103
  in mk [] end;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   104
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   105
val mk_lexpr =
19202
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   106
  let
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   107
    fun mk args = CodegenThingol.map_pure (mk' args)
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   108
    and mk' args (IConst (c, _)) =
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   109
          S.app Eval_Constr (S.tup [S.quote c, S.list args])
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   110
      | mk' args (IVar s) = if args = [] then MLvname s else 
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   111
          sys_error "NBE mk_lexpr illegal higher order pattern"
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   112
      | mk' args (e1 `$ e2) = mk (args @ [mk [] e2]) e1
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   113
      | mk' args (_ `|-> _) =
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   114
          sys_error "NBE mk_lexpr illegal pattern";
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   115
  in mk [] end;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   116
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
   117
fun mk_eqn defined nm ar (lhs,e) =
19202
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   118
  if has_duplicates (op =) (fold CodegenThingol.add_varnames lhs []) then [] else
19178
9b295c37854f ignore repeated vars on lhs, cleanup
nipkow
parents: 19177
diff changeset
   119
  [([S.list(map mk_lexpr (rev lhs))], mk_rexpr defined nm ar e)];
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   120
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
   121
fun lookup nm = S.Val (MLname nm) (tab_lookup (S.quote nm));
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   122
19167
f237c0cb3882 refined representation of codegen intermediate language
haftmann
parents: 19147
diff changeset
   123
fun generate defined (nm, CodegenThingol.Fun (eqns, _)) =
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   124
      let
19202
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   125
        val ar = (length o fst o hd) eqns;
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   126
        val params = (S.list o rev o MLparams) ar;
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   127
        val funs =
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   128
          []
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   129
          |> fold (fn (_, e) => CodegenThingol.add_constnames e) eqns
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   130
          |> remove (op =) nm;
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   131
        val globals = map lookup (filter defined funs);
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   132
        val default_eqn = ([params], S.app Eval_Constr (S.tup[S.quote nm,params]));
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   133
        val code = S.eqns (MLname nm)
19482
9f11af8f7ef9 tuned basic list operators (flat, maps, map_filter);
wenzelm
parents: 19341
diff changeset
   134
                          (maps (mk_eqn defined nm ar) eqns @ [default_eqn])
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   135
        val register = tab_update
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   136
            (S.app Eval_mk_Fun (S.tup[S.quote nm, MLname nm, string_of_int ar]))
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   137
      in
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   138
        S.Let (globals @ [code]) register
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   139
      end
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   140
  | generate _ _ = "";
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   141
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   142
open NBE_Eval;
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   143
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19482
diff changeset
   144
val tcount = ref 0;
746274ca400b added type inference at the end of normalization
nipkow
parents: 19482
diff changeset
   145
19830
b81d803dfaa4 renamed command
nipkow
parents: 19795
diff changeset
   146
(* FIXME get rid of TFree case!!! *)
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19482
diff changeset
   147
fun varifyT ty =
746274ca400b added type inference at the end of normalization
nipkow
parents: 19482
diff changeset
   148
  let val ty' = map_type_tvar (fn ((s,i),S) => TypeInfer.param (!tcount + i) (s,S)) ty;
746274ca400b added type inference at the end of normalization
nipkow
parents: 19482
diff changeset
   149
      val _ = (tcount := !tcount + maxidx_of_typ ty + 1);
746274ca400b added type inference at the end of normalization
nipkow
parents: 19482
diff changeset
   150
      val ty'' = map_type_tfree (TypeInfer.param (!tcount)) ty'
746274ca400b added type inference at the end of normalization
nipkow
parents: 19482
diff changeset
   151
  in tcount := !tcount+1; ty'' end;
746274ca400b added type inference at the end of normalization
nipkow
parents: 19482
diff changeset
   152
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   153
fun nterm_to_term thy t =
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   154
  let
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   155
    fun consts_of (C s) = insert (op =) s
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   156
      | consts_of (V _) = I
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   157
      | consts_of (B _) = I
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   158
      | consts_of (A (t1, t2)) = consts_of t1 #> consts_of t2
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   159
      | consts_of (AbsN (_, t)) = consts_of t;
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   160
    val consts = consts_of t [];
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19482
diff changeset
   161
    val ctab = consts ~~ CodegenPackage.consts_of_idfs thy consts;
746274ca400b added type inference at the end of normalization
nipkow
parents: 19482
diff changeset
   162
    val the_const = apsnd varifyT o the o AList.lookup (op =) ctab;
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   163
    fun to_term bounds (C s) = Const (the_const s)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   164
      | to_term bounds (V s) = Free (s, dummyT)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   165
      | to_term bounds (B i) = Bound (find_index (fn j => i = j) bounds)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   166
      | to_term bounds (A (t1, t2)) = to_term bounds t1 $ to_term bounds t2
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   167
      | to_term bounds (AbsN (i, t)) =
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   168
          Abs("u", dummyT, to_term (i::bounds) t);
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19482
diff changeset
   169
  in tcount := 0; to_term [] t end;
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   170
19118
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
   171
end;