src/HOL/simpdata.ML
changeset 15423 761a4f8e6ad6
parent 15184 d2c19aea17bc
child 15531 08c8dad8e399
--- a/src/HOL/simpdata.ML	Sat Dec 18 17:12:45 2004 +0100
+++ b/src/HOL/simpdata.ML	Sat Dec 18 17:14:33 2004 +0100
@@ -131,6 +131,55 @@
   Simplifier.simproc (Theory.sign_of (the_context ()))
     "defined ALL" ["ALL x. P x"] Quantifier1.rearrange_all;
 
+(*** Simproc for Let ***)
+
+val use_let_simproc = ref true;
+
+local
+val Let_folded = thm "Let_folded";
+val Let_unfold = thm "Let_unfold";
+
+val f_Let_unfold = 
+      let val [(_$(f$_)$_)] = prems_of Let_unfold in cterm_of (sign_of (the_context ())) f end
+val f_Let_folded = 
+      let val [(_$(f$_)$_)] = prems_of Let_folded in cterm_of (sign_of (the_context ())) f end;
+val g_Let_folded = 
+      let val [(_$_$(g$_))] = prems_of Let_folded in cterm_of (sign_of (the_context ())) g end;
+in
+val let_simproc =
+  Simplifier.simproc (Theory.sign_of (the_context ())) "let_simp" ["Let x f"] 
+   (fn sg => fn ss => fn t =>
+      (case t of (Const ("Let",_)$x$f) => (* x and f are already in normal form *)
+         if not (!use_let_simproc) then None
+         else if is_Free x orelse is_Bound x orelse is_Const x 
+         then Some Let_def  
+         else
+          let
+             val n = case f of (Abs (x,_,_)) => x | _ => "x";
+             val cx = cterm_of sg x;
+             val {T=xT,...} = rep_cterm cx;
+             val cf = cterm_of sg f;
+             val fx_g = Simplifier.rewrite ss (Thm.capply cf cx);
+             val (_$_$g) = prop_of fx_g;
+             val g' = abstract_over (x,g);
+           in (if (g aconv g') 
+               then
+                  let
+                    val rl = cterm_instantiate [(f_Let_unfold,cf)] Let_unfold;
+                  in Some (rl OF [fx_g]) end 
+               else if betapply (f,x) aconv g then None (* avoid identity conversion *)
+               else let 
+                     val abs_g'= Abs (n,xT,g');
+                     val g'x = abs_g'$x;
+                     val g_g'x = symmetric (beta_conversion false (cterm_of sg g'x));
+                     val rl = cterm_instantiate
+                               [(f_Let_folded,cterm_of sg f),
+                                (g_Let_folded,cterm_of sg abs_g')]
+                               Let_folded; 
+                   in Some (rl OF [transitive fx_g g_g'x]) end)
+           end
+        | _ => None))
+end
 
 (*** Case splitting ***)
 
@@ -248,7 +297,7 @@
        disj_not1, not_all, not_ex, cases_simp,
        thm "the_eq_trivial", the_sym_eq_trivial]
      @ ex_simps @ all_simps @ simp_thms)
-     addsimprocs [defALL_regroup,defEX_regroup]
+     addsimprocs [defALL_regroup,defEX_regroup,let_simproc]
      addcongs [imp_cong]
      addsplits [split_if];