added codegen_func.ML
authorhaftmann
Fri, 05 Jan 2007 14:32:07 +0100
changeset 22023 487b79b95a20
parent 22022 93f842eb51a8
child 22024 adf64b316f07
added codegen_func.ML
src/Pure/IsaMakefile
src/Pure/Tools/ROOT.ML
src/Pure/Tools/codegen_func.ML
--- a/src/Pure/IsaMakefile	Fri Jan 05 14:31:51 2007 +0100
+++ b/src/Pure/IsaMakefile	Fri Jan 05 14:32:07 2007 +0100
@@ -58,8 +58,8 @@
   Thy/latex.ML Thy/present.ML Thy/thm_database.ML Thy/thm_deps.ML		\
   Thy/thy_info.ML Thy/thy_load.ML Tools/ROOT.ML Tools/am_compiler.ML		\
   Tools/am_interpreter.ML Tools/am_util.ML Tools/class_package.ML		\
-  Tools/codegen_consts.ML Tools/codegen_data.ML Tools/codegen_funcgr.ML		\
-  Tools/codegen_names.ML Tools/codegen_package.ML				\
+  Tools/codegen_consts.ML Tools/codegen_data.ML Tools/codegen_func.ML		\
+  Tools/codegen_funcgr.ML Tools/codegen_names.ML Tools/codegen_package.ML	\
   Tools/codegen_serializer.ML Tools/codegen_thingol.ML Tools/compute.ML		\
   Tools/invoke.ML Tools/nbe.ML Tools/nbe_codegen.ML Tools/nbe_eval.ML		\
   Tools/xml_syntax.ML assumption.ML axclass.ML codegen.ML compress.ML		\
--- a/src/Pure/Tools/ROOT.ML	Fri Jan 05 14:31:51 2007 +0100
+++ b/src/Pure/Tools/ROOT.ML	Fri Jan 05 14:32:07 2007 +0100
@@ -14,6 +14,7 @@
 
 (*code generator, 2nd generation*)
 use "codegen_consts.ML";
+use "codegen_func.ML";
 use "codegen_data.ML";
 use "codegen_names.ML";
 use "codegen_funcgr.ML";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Pure/Tools/codegen_func.ML	Fri Jan 05 14:32:07 2007 +0100
@@ -0,0 +1,71 @@
+(*  Title:      Pure/Tools/codegen_func.ML
+    ID:         $Id$
+    Author:     Florian Haftmann, TU Muenchen
+
+Handling defining equations ("func"s) for code generator framework
+*)
+
+(* FIXME move various stuff here *)
+
+signature CODEGEN_FUNC =
+sig
+  val expand_eta: theory -> int -> thm -> thm
+end;
+
+structure CodegenFunc : CODEGEN_FUNC =
+struct
+
+(* FIXME get rid of this code duplication *)
+val purify_name =
+  let
+    fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s orelse s = "'";
+    val is_junk = not o is_valid andf Symbol.not_eof;
+    val junk = Scan.many is_junk;
+    val scan_valids = Symbol.scanner "Malformed input"
+      ((junk |--
+        (Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.many is_valid >> implode)
+        --| junk))
+      -- Scan.repeat ((Scan.many1 is_valid >> implode) --| junk) >> op ::);
+  in explode #> scan_valids #> space_implode "_" end;
+
+val purify_lower =
+  explode
+  #> (fn cs => (if forall Symbol.is_ascii_upper cs
+        then map else nth_map 0) Symbol.to_ascii_lower cs)
+  #> implode;
+
+fun purify_var "" = "x"
+  | purify_var v = (purify_name #> purify_lower) v;
+
+fun expand_eta thy k thm =
+  let
+    val (lhs, rhs) = (Logic.dest_equals o Drule.plain_prop_of) thm;
+    val (head, args) = strip_comb lhs;
+    val l = if k = ~1
+      then (length o fst o strip_abs) rhs
+      else Int.max (0, k - length args);
+    val used = Name.make_context (map (fst o fst) (Term.add_vars lhs []));
+    fun get_name _ 0 used = ([], used)
+      | get_name (Abs (v, ty, t)) k used =
+          used
+          |> Name.variants [purify_var v]
+          ||>> get_name t (k - 1)
+          |>> (fn ([v'], vs') => (v', ty) :: vs')
+      | get_name t k used = 
+          let
+            val (tys, _) = (strip_type o fastype_of) t
+          in case tys
+           of [] => raise TERM ("expand_eta", [t])
+            | ty :: _ =>
+                used
+                |> Name.variants [""]
+                |-> (fn [v] => get_name (t $ Var ((v, 0), ty)) (k - 1)
+                #>> (fn vs' => (v, ty) :: vs'))
+          end;
+    val (vs, _) = get_name rhs l used;
+    val vs_refl = map (fn (v, ty) => Thm.reflexive (Thm.cterm_of thy (Var ((v, 0), ty)))) vs;
+  in
+    fold (fn refl => fn thm => Thm.combination thm refl) vs_refl thm
+  end;
+
+end;