src/Pure/Tools/nbe_eval.ML
author wenzelm
Mon, 09 Jul 2007 23:12:31 +0200
changeset 23670 681ffad36776
parent 23397 2cc3352f6c3c
child 24219 e558fe311376
permissions -rwxr-xr-x
use position.ML after pretty.ML;
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_eval.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
Evaluator infrastructure 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
(* Optimizations:
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
     9
 int instead of string in Constr
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    10
 treat int via ML ints
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    11
*)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    12
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    13
signature NBE_EVAL =
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    14
sig
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    15
  (*named terms used for output only*)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    16
  datatype nterm =
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    17
      C of string         (*named constants*)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    18
    | V of string         (*free variable*)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    19
    | B of int            (*named(!!) bound variables*)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    20
    | A of nterm * nterm  (*application*)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    21
    | AbsN of int * nterm (*binding of named variables*);
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    22
  datatype Univ = 
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    23
      Constr of string*(Univ list)       (*named constructors*)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    24
    | Var of string*(Univ list)          (*free variables*)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    25
    | BVar of int*(Univ list)            (*bound named variables*)
23397
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
    26
    | Fun of (Univ list -> Univ) * (Univ list) * int
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    27
                                         (*functions*);
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    28
20856
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
    29
  val eval: theory -> Univ Symtab.table -> term -> nterm
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    30
  val apply: Univ -> Univ -> Univ
20846
5fde744176d7 various code refinements
haftmann
parents: 20596
diff changeset
    31
  val prep_term: theory -> term -> term
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    32
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    33
  val to_term: Univ -> nterm
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19116
diff changeset
    34
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    35
  val mk_Fun: string * (Univ list -> Univ) * int -> string * Univ
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    36
  val new_name: unit -> int
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    37
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    38
  val string_of_nterm: nterm -> string
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    39
end;
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    40
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    41
structure NBE_Eval: NBE_EVAL =
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    42
struct
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    43
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    44
datatype nterm =
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    45
    C of string
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    46
  | V of string
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    47
  | B of int
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    48
  | A of nterm * nterm
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    49
  | AbsN of int * nterm;
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    50
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    51
fun string_of_nterm(C s) = "(C \"" ^ s ^ "\")"
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    52
  | string_of_nterm(V s) = "(V \"" ^ s ^ "\")"
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    53
  | string_of_nterm(B n) = "(B " ^ string_of_int n ^ ")"
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    54
  | string_of_nterm(A(s,t)) =
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    55
       "(A " ^ string_of_nterm s ^ string_of_nterm t ^ ")"
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    56
  | string_of_nterm(AbsN(n,t)) =
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    57
      "(Abs " ^ string_of_int n ^ " " ^ string_of_nterm t ^ ")";
746274ca400b added type inference at the end of normalization
nipkow
parents: 19202
diff changeset
    58
23178
07ba6b58b3d2 simplified/unified list fold;
wenzelm
parents: 22554
diff changeset
    59
fun apps t args = fold_rev (fn y => fn x => A(x,y)) args t;
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    60
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    61
(* ------------------------------ The semantical universe --------------------- *)
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
   Functions are given by their semantical function value. To avoid
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    65
   trouble with the ML-type system, these functions have the most
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    66
   generic type, that is "Univ list -> Univ". The calling convention is
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    67
   that the arguments come as a list, the last argument first. In
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    68
   other words, a function call that usually would look like
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    69
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    70
   f x_1 x_2 ... x_n   or   f(x_1,x_2, ..., x_n)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    71
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    72
   would be in our convention called as
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    73
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    74
              f [x_n,..,x_2,x_1]
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    75
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    76
   Moreover, to handle functions that are still waiting for some
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    77
   arguments we have additionally a list of arguments collected to far
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    78
   and the number of arguments we're still waiting for.
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    79
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    80
   Finally, it might happen, that a function does not get all the
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    81
   arguments it needs. In this case the function must provide means to
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    82
   present itself as a string. As this might be a heavy-wight
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    83
   operation, we delay it.
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    84
*)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    85
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    86
datatype Univ = 
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    87
    Constr of string*(Univ list)       (* Named Constructors *)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    88
  | Var of string*(Univ list)          (* Free variables *)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    89
  | BVar of int*(Univ list)         (* Bound named variables *)
23397
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
    90
  | Fun of (Univ list -> Univ) * (Univ list) * int;
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    91
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    92
(*
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    93
   A typical operation, why functions might be good for, is
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    94
   application. Moreover, functions are the only values that can
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    95
   reasonably we applied in a semantical way.
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    96
*)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
    97
23397
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
    98
fun apply (Fun(f,xs,1))  x = f (x::xs)
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
    99
  | apply (Fun(f,xs,n))  x = Fun(f,x::xs,n-1)
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   100
  | apply (Constr(name,args)) x = Constr(name,x::args)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   101
  | apply (Var(name,args))    x = Var(name,x::args)
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   102
  | apply (BVar(name,args))   x = BVar(name,x::args);
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   103
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19116
diff changeset
   104
fun mk_Fun(name,v,0) = (name,v [])
23397
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
   105
  | mk_Fun(name,v,n) = (name,Fun(v,[],n));
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents: 19116
diff changeset
   106
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   107
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   108
(* ------------------ evaluation with greetings to Tarski ------------------ *)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   109
22554
d1499fff65d8 simplified constant representation in code generator
haftmann
parents: 22038
diff changeset
   110
fun prep_term thy (Const c) = Const (CodegenNames.const thy
d1499fff65d8 simplified constant representation in code generator
haftmann
parents: 22038
diff changeset
   111
      (CodegenConsts.const_of_cexpr thy c), dummyT)
20846
5fde744176d7 various code refinements
haftmann
parents: 20596
diff changeset
   112
  | prep_term thy (Free v_ty) = Free v_ty
5fde744176d7 various code refinements
haftmann
parents: 20596
diff changeset
   113
  | prep_term thy (s $ t) = prep_term thy s $ prep_term thy t
5fde744176d7 various code refinements
haftmann
parents: 20596
diff changeset
   114
  | prep_term thy (Abs (raw_v, ty, raw_t)) =
23397
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
   115
      let val (v,t) = Syntax.variant_abs (raw_v, ty, raw_t);
20846
5fde744176d7 various code refinements
haftmann
parents: 20596
diff changeset
   116
      in Abs (v, ty, prep_term thy t) end;
5fde744176d7 various code refinements
haftmann
parents: 20596
diff changeset
   117
5fde744176d7 various code refinements
haftmann
parents: 20596
diff changeset
   118
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   119
(* generation of fresh names *)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   120
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   121
val counter = ref 0;
20856
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   122
fun new_name () = (counter := !counter +1; !counter);
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   123
23397
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
   124
fun to_term (Constr(name, args))    = apps (C name) (map to_term args)
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
   125
  | to_term (Var   (name, args))    = apps (V name) (map to_term args)
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
   126
  | to_term (BVar  (name, args))    = apps (B name) (map to_term args)
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
   127
  | to_term (F as Fun _) =
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
   128
      let val var = new_name()
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
   129
      in AbsN(var, to_term (apply F (BVar(var,[])))) end;
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
   130
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   131
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   132
(* greetings to Tarski *)
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   133
20856
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   134
fun eval thy tab t =
19202
0b9eb4b0ad98 substantial improvement in codegen iml
haftmann
parents: 19177
diff changeset
   135
  let
20856
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   136
    fun evl vars (Const (s, _)) =
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   137
          the_default (Constr (s, [])) (Symtab.lookup tab s)
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   138
      | evl vars (Free (v, _)) =
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   139
          the_default (Var (v, [])) (AList.lookup (op =) vars v)
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   140
      | evl vars (s $ t) =
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   141
          apply (evl vars s) (evl vars t)
20846
5fde744176d7 various code refinements
haftmann
parents: 20596
diff changeset
   142
      | evl vars (Abs (v, _, t)) =
23397
2cc3352f6c3c Removed thunk from Fun
nipkow
parents: 23178
diff changeset
   143
          Fun (fn [x] => evl (AList.update (op =) (v, x) vars) t, [], 1)
20856
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
   144
  in (counter := 0; to_term (evl [] (prep_term thy t))) end;
19116
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   145
d065ec558092 New normalization-by-evaluation package
nipkow
parents:
diff changeset
   146
end;