src/HOL/HOL.thy
changeset 28741 1b257449f804
parent 28699 32b6a8f12c1c
child 28856 5e009a80fe6d
     1.1 --- a/src/HOL/HOL.thy	Thu Nov 13 15:58:37 2008 +0100
     1.2 +++ b/src/HOL/HOL.thy	Thu Nov 13 15:58:38 2008 +0100
     1.3 @@ -1322,55 +1322,63 @@
     1.4  simproc_setup let_simp ("Let x f") = {*
     1.5  let
     1.6    val (f_Let_unfold, x_Let_unfold) =
     1.7 -    let val [(_$(f$x)$_)] = prems_of @{thm Let_unfold}
     1.8 +    let val [(_ $ (f $ x) $ _)] = prems_of @{thm Let_unfold}
     1.9      in (cterm_of @{theory} f, cterm_of @{theory} x) end
    1.10    val (f_Let_folded, x_Let_folded) =
    1.11 -    let val [(_$(f$x)$_)] = prems_of @{thm Let_folded}
    1.12 +    let val [(_ $ (f $ x) $ _)] = prems_of @{thm Let_folded}
    1.13      in (cterm_of @{theory} f, cterm_of @{theory} x) end;
    1.14    val g_Let_folded =
    1.15 -    let val [(_$_$(g$_))] = prems_of @{thm Let_folded} in cterm_of @{theory} g end;
    1.16 -
    1.17 -  fun proc _ ss ct =
    1.18 -    let
    1.19 -      val ctxt = Simplifier.the_context ss;
    1.20 -      val thy = ProofContext.theory_of ctxt;
    1.21 -      val t = Thm.term_of ct;
    1.22 -      val ([t'], ctxt') = Variable.import_terms false [t] ctxt;
    1.23 -    in Option.map (hd o Variable.export ctxt' ctxt o single)
    1.24 -      (case t' of Const ("Let",_) $ x $ f => (* x and f are already in normal form *)
    1.25 -        if is_Free x orelse is_Bound x orelse is_Const x
    1.26 -        then SOME @{thm Let_def}
    1.27 -        else
    1.28 -          let
    1.29 -            val n = case f of (Abs (x,_,_)) => x | _ => "x";
    1.30 -            val cx = cterm_of thy x;
    1.31 -            val {T=xT,...} = rep_cterm cx;
    1.32 -            val cf = cterm_of thy f;
    1.33 -            val fx_g = Simplifier.rewrite ss (Thm.capply cf cx);
    1.34 -            val (_$_$g) = prop_of fx_g;
    1.35 -            val g' = abstract_over (x,g);
    1.36 -          in (if (g aconv g')
    1.37 -               then
    1.38 -                  let
    1.39 -                    val rl =
    1.40 -                      cterm_instantiate [(f_Let_unfold,cf),(x_Let_unfold,cx)] @{thm Let_unfold};
    1.41 -                  in SOME (rl OF [fx_g]) end
    1.42 -               else if Term.betapply (f,x) aconv g then NONE (*avoid identity conversion*)
    1.43 -               else let
    1.44 -                     val abs_g'= Abs (n,xT,g');
    1.45 -                     val g'x = abs_g'$x;
    1.46 -                     val g_g'x = symmetric (beta_conversion false (cterm_of thy g'x));
    1.47 -                     val rl = cterm_instantiate
    1.48 -                               [(f_Let_folded,cterm_of thy f),(x_Let_folded,cx),
    1.49 -                                (g_Let_folded,cterm_of thy abs_g')]
    1.50 -                               @{thm Let_folded};
    1.51 -                   in SOME (rl OF [transitive fx_g g_g'x])
    1.52 -                   end)
    1.53 -          end
    1.54 -      | _ => NONE)
    1.55 -    end
    1.56 -in proc end *}
    1.57 -
    1.58 +    let val [(_ $ _ $ (g $ _))] = prems_of @{thm Let_folded}
    1.59 +    in cterm_of @{theory} g end;
    1.60 +  fun count_loose (Bound i) k = if i >= k then 1 else 0
    1.61 +    | count_loose (s $ t) k = count_loose s k + count_loose t k
    1.62 +    | count_loose (Abs (_, _, t)) k = count_loose  t (k + 1)
    1.63 +    | count_loose _ _ = 0;
    1.64 +  fun is_trivial_let (Const (@{const_name Let}, _) $ x $ t) =
    1.65 +   case t
    1.66 +    of Abs (_, _, t') => count_loose t' 0 <= 1
    1.67 +     | _ => true;
    1.68 +in fn _ => fn ss => fn ct => if is_trivial_let (Thm.term_of ct)
    1.69 +  then SOME @{thm Let_def} (*no or one ocurrenc of bound variable*)
    1.70 +  else let (*Norbert Schirmer's case*)
    1.71 +    val ctxt = Simplifier.the_context ss;
    1.72 +    val thy = ProofContext.theory_of ctxt;
    1.73 +    val t = Thm.term_of ct;
    1.74 +    val ([t'], ctxt') = Variable.import_terms false [t] ctxt;
    1.75 +  in Option.map (hd o Variable.export ctxt' ctxt o single)
    1.76 +    (case t' of Const (@{const_name Let},_) $ x $ f => (* x and f are already in normal form *)
    1.77 +      if is_Free x orelse is_Bound x orelse is_Const x
    1.78 +      then SOME @{thm Let_def}
    1.79 +      else
    1.80 +        let
    1.81 +          val n = case f of (Abs (x, _, _)) => x | _ => "x";
    1.82 +          val cx = cterm_of thy x;
    1.83 +          val {T = xT, ...} = rep_cterm cx;
    1.84 +          val cf = cterm_of thy f;
    1.85 +          val fx_g = Simplifier.rewrite ss (Thm.capply cf cx);
    1.86 +          val (_ $ _ $ g) = prop_of fx_g;
    1.87 +          val g' = abstract_over (x,g);
    1.88 +        in (if (g aconv g')
    1.89 +             then
    1.90 +                let
    1.91 +                  val rl =
    1.92 +                    cterm_instantiate [(f_Let_unfold, cf), (x_Let_unfold, cx)] @{thm Let_unfold};
    1.93 +                in SOME (rl OF [fx_g]) end
    1.94 +             else if Term.betapply (f, x) aconv g then NONE (*avoid identity conversion*)
    1.95 +             else let
    1.96 +                   val abs_g'= Abs (n,xT,g');
    1.97 +                   val g'x = abs_g'$x;
    1.98 +                   val g_g'x = symmetric (beta_conversion false (cterm_of thy g'x));
    1.99 +                   val rl = cterm_instantiate
   1.100 +                             [(f_Let_folded, cterm_of thy f), (x_Let_folded, cx),
   1.101 +                              (g_Let_folded, cterm_of thy abs_g')]
   1.102 +                             @{thm Let_folded};
   1.103 +                 in SOME (rl OF [transitive fx_g g_g'x])
   1.104 +                 end)
   1.105 +        end
   1.106 +    | _ => NONE)
   1.107 +  end
   1.108 +end *}
   1.109  
   1.110  lemma True_implies_equals: "(True \<Longrightarrow> PROP P) \<equiv> PROP P"
   1.111  proof