src/Pure/Tools/nbe.ML
author haftmann
Wed, 04 Oct 2006 14:17:47 +0200
changeset 20856 9f7f0bf89e7d
parent 20846 5fde744176d7
child 20920 07f279940664
permissions -rw-r--r--
cleaned up some mess
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.ML
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
     2
    ID:         $Id$
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
     3
    Author:     Tobias Nipkow, Florian Haftmann, TU Muenchen
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
     4
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
     5
Toplevel theory interface for "normalization by evaluation"
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
     6
*)
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
     7
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
     8
signature NBE =
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
     9
sig
20856
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
    10
  (*preconditions: no Vars/TVars in term*)
19962
016ba2d907a7 new function norm_term
nipkow
parents: 19830
diff changeset
    11
  val norm_term: theory -> term -> term
20602
96fa2cf465f5 moved part of normalization oracle here
haftmann
parents: 20191
diff changeset
    12
  val normalization_conv: cterm -> thm
19962
016ba2d907a7 new function norm_term
nipkow
parents: 19830
diff changeset
    13
  val lookup: string -> NBE_Eval.Univ
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19341
diff changeset
    14
  val update: string * NBE_Eval.Univ -> unit
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    15
  val trace: bool ref
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
    16
end;
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
    17
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    18
structure NBE: NBE =
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
    19
struct
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
    20
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    21
val trace = ref false;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    22
fun tracing f = if !trace then Output.tracing (f ()) else ();
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    23
19968
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
    24
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
    25
(* theory data setup *)
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
    26
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    27
structure NBE_Data = CodeDataFun
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
    28
(struct
19962
016ba2d907a7 new function norm_term
nipkow
parents: 19830
diff changeset
    29
  val name = "Pure/NBE"
016ba2d907a7 new function norm_term
nipkow
parents: 19830
diff changeset
    30
  type T = NBE_Eval.Univ Symtab.table
016ba2d907a7 new function norm_term
nipkow
parents: 19830
diff changeset
    31
  val empty = Symtab.empty
016ba2d907a7 new function norm_term
nipkow
parents: 19830
diff changeset
    32
  fun merge _ = Symtab.merge (K true)
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    33
  fun purge _ _ = Symtab.empty
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
    34
end);
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
    35
19968
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
    36
val _ = Context.add_setup NBE_Data.init;
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19341
diff changeset
    37
746274ca400b added type inference at the end of normalization
nipkow
parents: 19341
diff changeset
    38
19968
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
    39
(* sandbox communication *)
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
    40
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    41
val tab : NBE_Eval.Univ Symtab.table ref = ref Symtab.empty;
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    42
fun lookup s = (the o Symtab.lookup (!tab)) s;
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    43
fun update sx = (tab := Symtab.update sx (!tab));
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
    44
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
    45
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    46
(* norm by eval *)
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    47
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    48
local
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    49
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    50
(* FIXME better turn this into a function
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    51
    NBE_Eval.Univ Symtab.table -> NBE_Eval.Univ Symtab.table
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    52
    with implicit side effect *)
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    53
fun use_code NONE = ()
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    54
  | use_code (SOME s) =
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    55
      (tracing (fn () => "\n---generated code:\n" ^ s);
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    56
       use_text (Output.tracing o enclose "\n---compiler echo:\n" "\n---\n",
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    57
            Output.tracing o enclose "\n--- compiler echo (with error!):\n" "\n---\n")
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    58
        (!trace) s);
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    59
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    60
fun generate thy funs =
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    61
  let
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    62
    val _ = tab := NBE_Data.get thy;;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    63
    val _ = Library.seq (use_code o NBE_Codegen.generate thy
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    64
      (fn s => Symtab.defined (!tab) s)) funs;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    65
  in NBE_Data.change thy (K (!tab)) end;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    66
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    67
fun compile_term thy t =
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    68
  let
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    69
    (*FIXME: proper interfaces in codegen_*)
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    70
    val (consts, cs) = CodegenConsts.consts_of thy t;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    71
    val funcgr = CodegenFuncgr.mk_funcgr thy consts cs;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    72
    (*FIXME: proper interfaces in codegen_*)
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    73
    fun const_typ (c, ty) =
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19341
diff changeset
    74
      let
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    75
        val const = CodegenConsts.norm_of_typ thy (c, ty);
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    76
      in case CodegenFuncgr.get_funcs funcgr const
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    77
       of (thm :: _) => CodegenData.typ_func thy thm
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    78
        | [] => Sign.the_const_type thy c
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    79
      end;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    80
    val (_, ct) = CodegenData.preprocess_cterm thy const_typ (Thm.cterm_of thy t)
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    81
    val t' = Thm.term_of ct;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    82
    val (consts, cs) = CodegenConsts.consts_of thy t';
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    83
    val funcgr = CodegenFuncgr.mk_funcgr thy consts cs;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    84
    val nbe_tab = NBE_Data.get thy;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    85
    val all_consts =
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    86
      CodegenFuncgr.all_deps_of funcgr consts
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    87
      |> (map o filter_out) (Symtab.defined nbe_tab o CodegenNames.const thy)
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    88
      |> filter_out null;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    89
    val funs = (map o map)
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    90
      (fn c => (CodegenNames.const thy c, CodegenFuncgr.get_funcs funcgr c)) all_consts;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    91
    val _ = tracing (fn () => "new definitions: " ^ (commas o maps (map fst)) funs);
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    92
    val _ = generate thy funs;
20856
9f7f0bf89e7d cleaned up some mess
haftmann
parents: 20846
diff changeset
    93
    val nt = NBE_Eval.eval thy (!tab) t';
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    94
  in nt end;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    95
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    96
fun subst_Frees [] = I
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    97
  | subst_Frees inst =
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    98
      Term.map_aterms (fn (t as Free(s, _)) => the_default t (AList.lookup (op =) inst s)
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
    99
                  | t => t);
19795
746274ca400b added type inference at the end of normalization
nipkow
parents: 19341
diff changeset
   100
746274ca400b added type inference at the end of normalization
nipkow
parents: 19341
diff changeset
   101
fun var_tab t = (Term.add_frees t [], Term.add_vars t []);
746274ca400b added type inference at the end of normalization
nipkow
parents: 19341
diff changeset
   102
19968
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   103
fun anno_vars (Ftab, Vtab) =
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   104
  subst_Vars  (map (fn (ixn, T) => (ixn, Var(ixn,T))) Vtab) o
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   105
  subst_Frees (map (fn (s, T) =>   (s,   Free(s,T)))  Ftab)
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   106
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   107
in
19968
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   108
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   109
fun norm_term thy t =
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   110
  let
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   111
    val _ = tracing (fn () => "Input:\n" ^ Display.raw_string_of_term t);
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   112
    val nt = compile_term thy t;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   113
    val vtab = var_tab t;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   114
    val ty = type_of t;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   115
    fun constrain ty t = Sign.infer_types (Sign.pp thy) thy (Sign.consts_of thy)
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   116
        (K NONE) (K NONE) Name.context false ([t], ty) |> fst;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   117
    val _ = tracing (fn () => "Normalized:\n" ^ NBE_Eval.string_of_nterm nt);
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   118
    val t' = NBE_Codegen.nterm_to_term thy nt;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   119
    val _ = tracing (fn () =>"Converted back:\n" ^ Display.raw_string_of_term t');
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   120
    val t'' = anno_vars vtab t';
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   121
    val _ = tracing (fn () =>"Vars typed:\n" ^ Display.raw_string_of_term t'');
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   122
    val t''' = constrain ty t'';
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   123
    val _ = if null (Term.term_tvars t''') then () else
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   124
      error ("Illegal schematic type variables in normalized term: "
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   125
        ^ setmp show_types true (Sign.string_of_term thy) t''');
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   126
  in t''' end;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   127
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   128
fun norm_print_term ctxt modes t =
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   129
  let
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   130
    val thy = ProofContext.theory_of ctxt;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   131
    val t' = norm_term thy t;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   132
    val ty = Term.type_of t';
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   133
    val p = Library.setmp print_mode (modes @ ! print_mode) (fn () =>
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   134
      Pretty.block [Pretty.quote (ProofContext.pretty_term ctxt t'), Pretty.fbrk,
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   135
        Pretty.str "::", Pretty.brk 1, Pretty.quote (ProofContext.pretty_typ ctxt ty)]) ();
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   136
  in Pretty.writeln p end;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   137
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   138
fun norm_print_term_e (modes, raw_t) state =
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   139
  let
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   140
    val ctxt = (Proof.context_of o Toplevel.enter_forward_proof) state;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   141
  in norm_print_term ctxt modes (ProofContext.read_term ctxt raw_t) end;
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   142
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   143
end; (*local*)
19968
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   144
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   145
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   146
(* normalization oracle *)
19962
016ba2d907a7 new function norm_term
nipkow
parents: 19830
diff changeset
   147
20602
96fa2cf465f5 moved part of normalization oracle here
haftmann
parents: 20191
diff changeset
   148
exception Normalization of term;
96fa2cf465f5 moved part of normalization oracle here
haftmann
parents: 20191
diff changeset
   149
96fa2cf465f5 moved part of normalization oracle here
haftmann
parents: 20191
diff changeset
   150
fun normalization_oracle (thy, Normalization t) =
96fa2cf465f5 moved part of normalization oracle here
haftmann
parents: 20191
diff changeset
   151
  Logic.mk_equals (t, norm_term thy t);
96fa2cf465f5 moved part of normalization oracle here
haftmann
parents: 20191
diff changeset
   152
96fa2cf465f5 moved part of normalization oracle here
haftmann
parents: 20191
diff changeset
   153
fun normalization_conv ct =
96fa2cf465f5 moved part of normalization oracle here
haftmann
parents: 20191
diff changeset
   154
  let val {sign, t, ...} = rep_cterm ct
20677
5ce43b38a175 tuned oracle name;
wenzelm
parents: 20602
diff changeset
   155
  in Thm.invoke_oracle_i sign "Pure.normalization" (sign, Normalization t) end;
20602
96fa2cf465f5 moved part of normalization oracle here
haftmann
parents: 20191
diff changeset
   156
96fa2cf465f5 moved part of normalization oracle here
haftmann
parents: 20191
diff changeset
   157
val _ = Context.add_setup
20677
5ce43b38a175 tuned oracle name;
wenzelm
parents: 20602
diff changeset
   158
  (Theory.add_oracle ("normalization", normalization_oracle));
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   159
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   160
19968
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   161
(* Isar setup *)
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   162
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   163
local structure P = OuterParse and K = OuterKeyword in
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
   164
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   165
val opt_modes = Scan.optional (P.$$$ "(" |-- P.!!! (Scan.repeat1 P.xname --| P.$$$ ")")) [];
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   166
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
   167
val nbeP =
20846
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   168
  OuterSyntax.improper_command "normal_form" "normalize term by evaluation" K.diag
5fde744176d7 various code refinements
haftmann
parents: 20677
diff changeset
   169
    (opt_modes -- P.typ >> (Toplevel.keep o norm_print_term_e));
19968
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   170
2180f0f443af fixed stale theory bug
haftmann
parents: 19962
diff changeset
   171
end;
19147
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
   172
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
   173
val _ = OuterSyntax.add_parsers [nbeP];
0f584853b6a4 added nbe, updated neb_*
nipkow
parents:
diff changeset
   174
19177
68c6824d8bb6 improvements for nbe
haftmann
parents: 19167
diff changeset
   175
end;