src/Pure/Tools/nbe_codegen.ML
author haftmann
Fri, 10 Aug 2007 17:04:34 +0200
changeset 24219 e558fe311376
parent 23397 2cc3352f6c3c
permissions -rwxr-xr-x
new structure for code generator modules
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
20856
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
     1
(*  Title:      Pure/nbe_codegen.ML
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
     2
    ID:         $Id$
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
     3
    Author:     Klaus Aehlig, LMU Muenchen; Tobias Nipkow, TU Muenchen
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
     4
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
     5
Code generator for "normalization by evaluation".
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
     6
*)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
     7
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
     8
(* Global asssumptions:
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
     9
   For each function: there is at least one defining eqns and
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    10
   all defining equations have same number of arguments.
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    11
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    12
FIXME
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
    13
fun MLname
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    14
val quote = quote;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    15
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    16
*)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    17
19118
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    18
signature NBE_CODEGEN =
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    19
sig
20846
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
    20
  val generate: theory -> (string -> bool) -> (string * thm list) list -> string option;
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    21
  val nterm_to_term: theory -> NBE_Eval.nterm -> term;
19118
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    22
end
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    23
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    24
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    25
structure NBE_Codegen: NBE_CODEGEN =
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    26
struct
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
    27
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    28
val Eval = "NBE_Eval";
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
    29
val Eval_mk_Fun  = Eval ^ ".mk_Fun";
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    30
val Eval_apply   = Eval ^ ".apply";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    31
val Eval_Constr  = Eval ^ ".Constr";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    32
val Eval_C       = Eval ^ ".C";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    33
val Eval_AbsN    = Eval ^ ".AbsN";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    34
val Eval_Fun     = Eval ^ ".Fun";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    35
val Eval_BVar    = Eval ^ ".BVar";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    36
val Eval_new_name = Eval ^ ".new_name";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    37
val Eval_to_term = Eval ^ ".to_term";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    38
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
    39
fun MLname s = "nbe_" ^ translate_string (fn "." => "_" | c => c) s;
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    40
fun MLvname s  = "v_" ^ MLname s;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    41
fun MLparam n  = "p_" ^ string_of_int n;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    42
fun MLintern s = "i_" ^ MLname s;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    43
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    44
fun MLparams n = map MLparam (1 upto n);
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    45
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    46
structure S =
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    47
struct
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    48
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    49
val quote = quote; (* FIXME *)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    50
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    51
fun app e1 e2 = "(" ^ e1 ^ " " ^ e2 ^ ")";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    52
fun abs v e = "(fn" ^ v ^ " => " ^ e ^ ")";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    53
fun tup es = "(" ^ commas es ^ ")";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    54
fun list es = "[" ^ commas es ^ "]";
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    55
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    56
fun apps s ss = Library.foldl (uncurry app) (s, ss);
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    57
fun nbe_apps s ss =
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    58
  Library.foldr (fn (s,e) => app (app Eval_apply e) s) (ss,s);
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    59
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    60
fun eqns name ees =
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    61
  let fun eqn (es,e) = name ^ " " ^ space_implode " " es ^ " = " ^ e
20846
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
    62
  in space_implode "\n  | " (map eqn ees) end;
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    63
20846
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
    64
fun eqnss (es :: ess) = prefix "fun " es :: map (prefix "and ") ess
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
    65
  |> space_implode "\n"
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
    66
  |> suffix "\n";
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    67
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    68
fun Val v s = "val " ^ v ^ " = " ^ s;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    69
fun Let ds e = "let\n" ^ (space_implode "\n" ds) ^ " in " ^ e ^ " end"
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    70
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    71
end
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    72
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    73
val tab_lookup = S.app "NBE.lookup";
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    74
val tab_update = S.app "NBE.update";
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
    75
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    76
fun mk_nbeFUN(nm,e) =
23397
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 22554
diff changeset
    77
  S.app Eval_Fun (S.tup [S.abs(S.list [MLvname nm])e,S.list [],"1" (*,
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    78
      S.abs(S.tup [])(S.Let 
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    79
        [S.Val (MLintern "var") (S.app Eval_new_name (S.tup [])),
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    80
         S.Val (MLvname nm) (S.app Eval_BVar (S.tup [(MLintern "var"), S.list []]))]
23397
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 22554
diff changeset
    81
	(S.app Eval_AbsN(S.tup[MLintern "var",(S.app Eval_to_term e)])))*)]);
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    82
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    83
fun take_last n xs = rev (Library.take(n, rev xs));
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    84
fun drop_last n xs = rev (Library.drop(n, rev xs));
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    85
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    86
fun selfcall nm ar args =
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    87
	if (ar <= length args) then 
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    88
	  S.nbe_apps (S.app (MLname nm) (S.list (take_last ar args)))
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    89
	             (drop_last ar args)
23397
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 22554
diff changeset
    90
        else S.app Eval_Fun (S.tup [MLname nm,S.list args(*,
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    91
	           string_of_int(ar - (length args)),
23397
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 22554
diff changeset
    92
		   S.abs (S.tup []) (S.app Eval_C (S.quote nm))*)]);
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    93
20846
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
    94
fun mk_rexpr defined names ar =
19202
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
    95
  let
20846
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
    96
    fun mk args (Const (c, _)) = 
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
    97
          if member (op =) names c then selfcall c ar args
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
    98
            else if defined c then S.nbe_apps (MLname c) args
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
    99
            else S.app Eval_Constr (S.tup [S.quote c, S.list args])
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   100
      | mk args (Free (v, _)) = S.nbe_apps (MLvname v) args
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   101
      | mk args (t1 $ t2) = mk (args @ [mk [] t2]) t1
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   102
      | mk args (Abs (v, _, t)) = S.nbe_apps (mk_nbeFUN (v, mk [] t)) 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
20846
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   107
    fun mk args (Const (c, _)) =
19202
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   108
          S.app Eval_Constr (S.tup [S.quote c, S.list args])
20846
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   109
      | mk args (Free (v, _)) = if null args then MLvname v else 
19202
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   110
          sys_error "NBE mk_lexpr illegal higher order pattern"
20846
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   111
      | mk args (t1 $ t2) = mk (args @ [mk [] t2]) t1
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   112
      | mk args (Abs _) =
19202
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   113
          sys_error "NBE mk_lexpr illegal pattern";
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   114
  in mk [] end;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   115
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19118
diff changeset
   116
fun lookup nm = S.Val (MLname nm) (tab_lookup (S.quote nm));
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   117
20846
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   118
fun generate thy defined [(_, [])] = NONE
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   119
  | generate thy defined raw_eqnss =
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   120
      let
20846
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   121
        val eqnss0 = map (fn (name, thms as thm :: _) =>
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   122
          (name, ((length o snd o strip_comb o fst o Logic.dest_equals o prop_of) thm,
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   123
            map (apfst (snd o strip_comb) o Logic.dest_equals o Logic.unvarify
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   124
              o prop_of) thms)))
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   125
          raw_eqnss;
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   126
        val eqnss = (map o apsnd o apsnd o map) (fn (args, t) =>
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   127
          (map (NBE_Eval.prep_term thy) args, NBE_Eval.prep_term thy t)) eqnss0
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   128
        val names = map fst eqnss;
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   129
        val used_funs =
19202
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19178
diff changeset
   130
          []
20846
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   131
          |> fold (fold (fold_aterms (fn Const (c, _) => insert (op =) c
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   132
                                      | _ => I)) o map snd o snd o snd) eqnss
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   133
          |> subtract (op =) names;
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   134
        fun mk_def (name, (ar, eqns)) =
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   135
          let
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   136
            fun mk_eqn (args, t) = ([S.list (map mk_lexpr (rev args))],
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   137
              mk_rexpr defined names ar t);
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   138
            val default_params = (S.list o rev o MLparams) ar;
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   139
            val default_eqn = ([default_params], S.app Eval_Constr (S.tup [S.quote name, default_params]));
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   140
          in S.eqns (MLname name) (map mk_eqn eqns @ [default_eqn]) end;
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   141
        val globals = map lookup (filter defined used_funs);
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   142
        fun register (name, (ar, _)) = tab_update
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   143
            (S.app Eval_mk_Fun (S.tup [S.quote name, MLname name, string_of_int ar]))
5fde744176d7 various code refinements
haftmann
parents: 20706
diff changeset
   144
      in SOME (S.Let (globals @ [S.eqnss (map mk_def eqnss)]) (space_implode "; " (map register eqnss))) end;
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   145
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   146
open NBE_Eval;
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   147
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   148
fun nterm_to_term thy t =
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   149
  let
20856
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   150
    fun to_term bounds (C s) tcount =
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   151
          let
24219
e558fe311376 new structure for code generator modules
haftmann
parents: 23397
diff changeset
   152
            val SOME (const as (c, _)) = CodeNames.const_rev thy s;
22554
d1499fff65d8 simplified constant representation in code generator
haftmann
parents: 21883
diff changeset
   153
            val ty = CodegenData.default_typ thy const;
20856
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   154
            val ty' = map_type_tvar (fn ((s,i),S) => TypeInfer.param (tcount + i) (s,S)) ty;
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   155
            val tcount' = tcount + maxidx_of_typ ty + 1;
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   156
          in (Const (c, ty'), tcount') end
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   157
      | to_term bounds (V s) tcount = (Free (s, dummyT), tcount)
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   158
      | to_term bounds (B i) tcount = (Bound (find_index (fn j => i = j) bounds), tcount)
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   159
      | to_term bounds (A (t1, t2)) tcount =
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   160
          tcount
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   161
          |> to_term bounds t1
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   162
          ||>> to_term bounds t2
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   163
          |-> (fn (t1', t2') => pair (t1' $ t2'))
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   164
      | to_term bounds (AbsN (i, t)) tcount =
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   165
          tcount
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   166
          |> to_term (i :: bounds) t
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   167
          |-> (fn t' => pair (Abs ("u", dummyT, t')));
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   168
  in fst (to_term [] t 0) end;
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   169
19118
52f751b50716 added Tools/nbe, fixes
nipkow
parents: 19116
diff changeset
   170
end;