tuned
authorhaftmann
Fri, 13 Oct 2006 16:52:47 +0200
changeset 21012 f08574148b7a
parent 21011 19d7f07b0fa3
child 21013 b9321724c2cc
tuned
src/HOL/Tools/datatype_codegen.ML
src/Pure/Tools/codegen_package.ML
src/Pure/Tools/codegen_thingol.ML
--- a/src/HOL/Tools/datatype_codegen.ML	Fri Oct 13 16:52:46 2006 +0200
+++ b/src/HOL/Tools/datatype_codegen.ML	Fri Oct 13 16:52:47 2006 +0200
@@ -336,8 +336,6 @@
     val abs = Name.names Name.context "a" (Library.drop (length ts, tys));
     val (ts', t) = split_last (ts @ map Free abs);
     val (tys', sty) = split_last tys;
-    fun freenames_of t = fold_aterms
-      (fn Free (v, _) => insert (op =) v | _ => I) t [];
     fun dest_case ((c, tys_decl), ty) t =
       let
         val (vs, t') = Term.strip_abs_eta (length tys_decl) t;
--- a/src/Pure/Tools/codegen_package.ML	Fri Oct 13 16:52:46 2006 +0200
+++ b/src/Pure/Tools/codegen_package.ML	Fri Oct 13 16:52:47 2006 +0200
@@ -21,6 +21,8 @@
     -> ((string * typ) list * ((term * typ) * (term * term) list)) option)
     -> appgen;
   val appgen_let: appgen;
+
+  val timing: bool ref;
 end;
 
 structure CodegenPackage : CODEGEN_PACKAGE =
@@ -173,6 +175,7 @@
             |-> (fn (tyco, tys) => pair (tyco `%% tys));
 
 exception CONSTRAIN of (string * typ) * typ;
+val timing = ref false;
 
 fun exprgen_typinst thy (algbr as ((proj_sort, algebra), consts)) funcgr strct (ty_ctxt, sort_decl) trns =
   let
@@ -271,6 +274,8 @@
         (perhaps (Consttab.lookup ((snd o snd o CodegenPackageData.get) thy)) (c, tys))
        of eq_thms as eq_thm :: _ =>
             let
+              val timeap = if !timing then Output.timeap_msg ("time for " ^ c')
+                else I;
               val msg = cat_lines ("generating code for theorems " :: map string_of_thm eq_thms);
               val ty = (Logic.unvarifyT o CodegenData.typ_func thy) eq_thm;
               val vs = (map dest_TFree o Consts.typargs consts) (c', ty);
@@ -283,7 +288,7 @@
             in
               trns
               |> CodegenThingol.message msg (fn trns => trns
-              |> fold_map (exprgen_eq o dest_eqthm) eq_thms
+              |> timeap (fold_map (exprgen_eq o dest_eqthm) eq_thms)
               ||>> fold_map (exprgen_tyvar_sort thy algbr funcgr strct) vs
               ||>> exprgen_type thy algbr funcgr strct ty
               |-> (fn ((eqs, vs), ty) => succeed (CodegenThingol.Fun (eqs, (vs, ty)))))
@@ -397,8 +402,7 @@
   case try (int_of_numeral thy) (list_comb (Const c, ts))
    of SOME i =>
         trns
-        |> appgen_default thy algbr funcgr strct app
-        |-> (fn t => pair (CodegenThingol.INum (i, t)))
+        |> pair (CodegenThingol.INum i)
     | NONE =>
         trns
         |> appgen_default thy algbr funcgr strct app;
@@ -408,14 +412,16 @@
    of SOME i =>
         trns
         |> exprgen_type thy algbr funcgr strct ty
-        ||>> appgen_default thy algbr funcgr strct app
-        |-> (fn (_, t0) => pair (IChar (chr i, t0)))
+        |-> (fn _ => pair (IChar (chr i)))
     | NONE =>
         trns
         |> appgen_default thy algbr funcgr strct app;
 
+val debug_term = ref (Bound 0);
+
 fun appgen_case dest_case_expr thy algbr funcgr strct (app as (c_ty, ts)) trns =
   let
+    val _ = debug_term := list_comb (Const c_ty, ts);
     val SOME ([], ((st, sty), ds)) = dest_case_expr thy (list_comb (Const c_ty, ts));
     fun fold_map_aterms f (t $ u) s =
           s
@@ -427,16 +433,23 @@
           |> fold_map_aterms f t
           |-> (fn t' => pair (Abs (v, ty, t')))
       | fold_map_aterms f a s = f a s;
-    fun purify_term_frees (Free (v, ty)) ctxt = 
+    fun purify_term_frees (Free (v, ty)) (renaming, ctxt) = 
           let
             val ([v'], ctxt') = Name.variants [CodegenNames.purify_var v] ctxt;
-          in (Free (v, ty), ctxt') end
+            val renaming' = if v <> v' then Symtab.update (v, v') renaming else renaming;
+          in (Free (v', ty), (renaming', ctxt')) end
       | purify_term_frees t ctxt = (t, ctxt);
     fun clausegen (raw_dt, raw_bt) trns =
       let
-        val ((dt, bt), _) = Name.context
-          |> fold_map_aterms purify_term_frees raw_dt
-          ||>> fold_map_aterms purify_term_frees raw_bt;
+        val d_vs = map fst (Term.add_frees raw_dt []);
+        val b_vs = map fst (Term.add_frees raw_bt []);
+        val (dt, (renaming, ctxt)) =
+          Name.context
+          |> fold Name.declare (subtract (op =) d_vs b_vs)
+          |> pair Symtab.empty
+          |> fold_map_aterms purify_term_frees raw_dt;
+        val bt = map_aterms (fn t as Free (v, ty) => Free (perhaps (Symtab.lookup renaming) v, ty)
+                              | t => t) raw_bt;
       in
         trns
         |> exprgen_term thy algbr funcgr strct dt
@@ -447,21 +460,19 @@
     |> exprgen_term thy algbr funcgr strct st
     ||>> exprgen_type thy algbr funcgr strct sty
     ||>> fold_map clausegen ds
-    ||>> appgen_default thy algbr funcgr strct app
-    |-> (fn (((se, sty), ds), e0) => pair (ICase (((se, sty), ds), e0)))
+    |-> (fn ((se, sty), ds) => pair (ICase ((se, sty), ds)))
   end;
 
 fun appgen_let thy algbr funcgr strct (app as (_, [st, ct])) trns =
   trns
   |> exprgen_term thy algbr funcgr strct ct
   ||>> exprgen_term thy algbr funcgr strct st
-  ||>> appgen_default thy algbr funcgr strct app
-  |-> (fn (((v, ty) `|-> be, se), e0) =>
-            pair (ICase (((se, ty), case be
-              of ICase (((IVar w, _), ds), _) => if v = w then ds else [(IVar v, be)]
+  |-> (fn ((v, ty) `|-> be, se) =>
+            pair (ICase ((se, ty), case be
+              of ICase ((IVar w, _), ds) => if v = w then ds else [(IVar v, be)]
                | _ => [(IVar v, be)]
-            ), e0))
-        | (_, e0) => pair e0);
+            ))
+        | _ => appgen_default thy algbr funcgr strct app);
 
 fun add_appconst (c, appgen) thy =
   let
@@ -630,7 +641,7 @@
      of [] => NONE
       | xs => SOME xs;
     val seris' = map_filter (fn (target, args as _ :: _) =>
-      SOME (CodegenSerializer.get_serializer thy (target, args)) | _ => NONE) seris;
+      SOME (CodegenSerializer.get_serializer thy target args) | _ => NONE) seris;
     fun generate' thy = case cs
      of [] => []
       | _ =>
--- a/src/Pure/Tools/codegen_thingol.ML	Fri Oct 13 16:52:46 2006 +0200
+++ b/src/Pure/Tools/codegen_thingol.ML	Fri Oct 13 16:52:47 2006 +0200
@@ -28,12 +28,11 @@
     | IVar of vname
     | `$ of iterm * iterm
     | `|-> of (vname * itype) * iterm
-    | INum of IntInf.int * iterm
-    | IChar of string (*length one!*) * iterm
-    | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm;
-        (*((discriminendum term (td), discriminendum type (ty)),
-                [(selector pattern (p), body term (t))] (bs)),
-                pure term (t0))*)
+    | INum of IntInf.int
+    | IChar of string (*length one!*)
+    | ICase of (iterm * itype) * (iterm * iterm) list;
+        (*(discriminendum term (td), discriminendum type (ty)),
+                [(selector pattern (p), body term (t))] (bs))*)
   val `--> : itype list * itype -> itype;
   val `$$ : iterm * iterm list -> iterm;
   val `|--> : (vname * itype) list * iterm -> iterm;
@@ -47,11 +46,10 @@
   val unfoldr: ('a -> ('b * 'a) option) -> 'a -> 'b list * 'a;
   val unfold_fun: itype -> itype list * itype;
   val unfold_app: iterm -> iterm * iterm list;
-  val unfold_abs: iterm -> (iterm * itype) list * iterm;
+  val unfold_abs: iterm -> ((vname * iterm option) * itype) list * iterm;
   val unfold_let: iterm -> ((iterm * itype) * iterm) list * iterm;
   val unfold_const_app: iterm ->
     ((string * (inst list list * itype)) * iterm list) option;
-  val map_pure: (iterm -> 'a) -> iterm -> 'a;
   val eta_expand: (string * (inst list list * itype)) * iterm list -> int -> iterm;
   val fold_constnames: (string -> 'a -> 'a) -> iterm -> 'a -> 'a;
   val fold_varnames: (string -> 'a -> 'a) -> iterm -> 'a -> 'a;
@@ -72,9 +70,10 @@
   val empty_code: code;
   val get_def: code -> string -> def;
   val merge_code: code * code -> code;
-  val project_code: string list -> code -> code;
+  val project_code: string list (*hidden*) -> string list option (*selected*)
+    -> code -> code;
   val add_eval_def: string (*shallow name space*) * iterm -> code -> string * code;
-  val delete_garbage: string list (*hidden definitions*) -> code -> code;
+
 
   val ensure_def: (transact -> def * code) -> bool -> string
     -> string -> transact -> transact;
@@ -85,7 +84,6 @@
 
   val trace: bool ref;
   val tracing: ('a -> string) -> 'a -> 'a;
-  val soft_exc: bool ref;
 end;
 
 structure CodegenThingol: CODEGEN_THINGOL =
@@ -95,7 +93,6 @@
 
 val trace = ref false;
 fun tracing f x = (if !trace then Output.tracing (f x) else (); x);
-val soft_exc = ref true;
 
 fun unfoldl dest x =
   case dest x
@@ -131,9 +128,9 @@
   | IVar of vname
   | `$ of iterm * iterm
   | `|-> of (vname * itype) * iterm
-  | INum of IntInf.int * iterm
-  | IChar of string * iterm
-  | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm;
+  | INum of IntInf.int
+  | IChar of string
+  | ICase of (iterm * itype) * (iterm * iterm) list;
     (*see also signature*)
 
 (*
@@ -174,13 +171,13 @@
     | _ => NONE);
 
 val unfold_abs = unfoldr
-  (fn (v, ty) `|-> (t as ICase (((IVar w, _), [(p, t')]), _)) =>
-        if v = w then SOME ((p, ty), t') else SOME ((IVar v, ty), t)
-    | (v, ty) `|-> t => SOME ((IVar v, ty), t)
+  (fn (v, ty) `|-> (t as ICase ((IVar w, _), [(p, t')])) =>
+        if v = w then SOME (((v, SOME p), ty), t') else SOME (((v, NONE), ty), t)
+    | (v, ty) `|-> t => SOME (((v, NONE), ty), t)
     | _ => NONE)
 
 val unfold_let = unfoldr
-  (fn ICase (((td, ty), [(p, t)]), _) => SOME (((p, ty), td), t)
+  (fn ICase ((td, ty), [(p, t)]) => SOME (((p, ty), td), t)
     | _ => NONE);
 
 fun unfold_const_app t =
@@ -188,21 +185,6 @@
   of (IConst c, ts) => SOME (c, ts)
    | _ => NONE;
 
-fun map_pure f (t as IConst _) =
-      f t
-  | map_pure f (t as IVar _) =
-      f t
-  | map_pure f (t as _ `$ _) =
-      f t
-  | map_pure f (t as _ `|-> _) =
-      f t
-  | map_pure f (INum (_, t0)) =
-      f t0
-  | map_pure f (IChar (_, t0)) =
-      f t0
-  | map_pure f (ICase (_, t0)) =
-      f t0;
-
 fun fold_aiterms f (t as IConst _) =
       f t
   | fold_aiterms f (t as IVar _) =
@@ -211,12 +193,12 @@
       fold_aiterms f t1 #> fold_aiterms f t2
   | fold_aiterms f (t as _ `|-> t') =
       f t #> fold_aiterms f t'
-  | fold_aiterms f (INum (_, t0)) =
-      fold_aiterms f t0
-  | fold_aiterms f (IChar (_, t0)) =
-      fold_aiterms f t0
-  | fold_aiterms f (ICase (_, t0)) =
-      fold_aiterms f t0;
+  | fold_aiterms f (t as INum _) =
+      f t
+  | fold_aiterms f (t as IChar _) =
+      f t
+  | fold_aiterms f (ICase ((td, _), bs)) =
+      fold_aiterms f td #> fold (fn (p, t) => fold_aiterms f p #> fold_aiterms f t) bs;
 
 fun fold_constnames f =
   let
@@ -241,12 +223,12 @@
           add vs t1 #> add vs t2
       | add vs ((v, _) `|-> t) =
           add (insert (op =) v vs) t
-      | add vs (INum (_, t)) =
-          add vs t
-      | add vs (IChar (_, t)) =
-          add vs t
-      | add vs (ICase (_, t0)) =
-          add vs t0
+      | add vs (INum _) =
+          I
+      | add vs (IChar _) =
+          I
+      | add vs (ICase ((td, _), bs)) =
+          add vs td #> fold (fn (p, t) => add vs p #> add vs t) bs;
   in add [] end;
 
 fun eta_expand (c as (_, (_, ty)), ts) k =
@@ -278,7 +260,7 @@
 
 type code = def Graph.T;
 type transact = Graph.key option * code;
-exception FAIL of string list * exn option;
+exception FAIL of string list;
 
 
 (* abstract code *)
@@ -307,19 +289,24 @@
 
 val merge_code = Graph.join (fn _ => fn def12 => if eq_def def12 then fst def12 else Bot);
 
-fun project_code names code =
-  Graph.project (member (op =) (Graph.all_succs code names)) code;
-
-fun delete_garbage hidden code =
+fun project_code hidden raw_selected code =
   let
     fun is_bot name = case get_def code name
      of Bot => true
       | _ => false;
     val names = subtract (op =) hidden (Graph.keys code);
-    val names' = subtract (op =)
-      (Graph.all_preds code (filter is_bot names)) names;
+    val deleted = Graph.all_preds code (filter is_bot names);
+    val selected = case raw_selected
+     of NONE => names |> subtract (op =) deleted 
+      | SOME sel => sel
+          |> subtract (op =) deleted
+          |> subtract (op =) hidden
+          |> Graph.all_succs code
+          |> subtract (op =) deleted
+          |> subtract (op =) hidden;
   in
-    Graph.project (member (op =) names') code
+    code
+    |> Graph.project (member (op =) selected)
   end;
 
 fun check_samemodule names =
@@ -406,17 +393,10 @@
     fun prep_def def modl =
       (check_prep_def modl def, modl);
     fun invoke_generator name defgen modl =
-      if ! soft_exc (*that "!" isn't a "not"...*)
-      then defgen (SOME name, modl)
-        handle FAIL (msgs, exc) =>
-                if strict then raise FAIL (msg' :: msgs, exc)
-                else (Bot, modl)
-             | e => raise
-                FAIL (["definition generator for " ^ quote name, msg'], SOME e)
-      else defgen (SOME name, modl)
-        handle FAIL (msgs, exc) =>
-              if strict then raise FAIL (msg' :: msgs, exc)
-              else (Bot, modl);
+      defgen (SOME name, modl)
+        handle FAIL msgs =>
+          if strict then raise FAIL (msg' :: msgs)
+          else (Bot, modl);
   in
     modl
     |> (if can (get_def modl) name
@@ -442,20 +422,18 @@
 
 fun succeed some (_, modl) = (some, modl);
 
-fun fail msg (_, modl) = raise FAIL ([msg], NONE);
+fun fail msg (_, modl) = raise FAIL [msg];
 
 fun message msg f trns =
-  f trns handle FAIL (msgs, exc) =>
-    raise FAIL (msg :: msgs, exc);
+  f trns handle FAIL msgs =>
+    raise FAIL (msg :: msgs);
 
 fun start_transact init f modl =
   let
     fun handle_fail f x =
       (f x
-      handle FAIL (msgs, NONE) =>
+      handle FAIL msgs =>
         (error o cat_lines) ("Code generation failed, while:" :: msgs))
-      handle FAIL (msgs, SOME e) =>
-        ((Output.error_msg o cat_lines) ("Code generation failed, while:" :: msgs); raise e);
   in
     modl
     |> (if is_some init then ensure_bot (the init) else I)