src/HOL/HOL.thy
changeset 59582 0fbed69ff081
parent 59507 b468e0f8da2a
child 59586 ddf6deaadfe8
equal deleted inserted replaced
59580:cbc38731d42f 59582:0fbed69ff081
  1191 *}
  1191 *}
  1192 
  1192 
  1193 simproc_setup let_simp ("Let x f") = {*
  1193 simproc_setup let_simp ("Let x f") = {*
  1194 let
  1194 let
  1195   val (f_Let_unfold, x_Let_unfold) =
  1195   val (f_Let_unfold, x_Let_unfold) =
  1196     let val [(_ $ (f $ x) $ _)] = prems_of @{thm Let_unfold}
  1196     let val [(_ $ (f $ x) $ _)] = Thm.prems_of @{thm Let_unfold}
  1197     in (cterm_of @{theory} f, cterm_of @{theory} x) end
  1197     in (Thm.cterm_of @{theory} f, Thm.cterm_of @{theory} x) end
  1198   val (f_Let_folded, x_Let_folded) =
  1198   val (f_Let_folded, x_Let_folded) =
  1199     let val [(_ $ (f $ x) $ _)] = prems_of @{thm Let_folded}
  1199     let val [(_ $ (f $ x) $ _)] = Thm.prems_of @{thm Let_folded}
  1200     in (cterm_of @{theory} f, cterm_of @{theory} x) end;
  1200     in (Thm.cterm_of @{theory} f, Thm.cterm_of @{theory} x) end;
  1201   val g_Let_folded =
  1201   val g_Let_folded =
  1202     let val [(_ $ _ $ (g $ _))] = prems_of @{thm Let_folded}
  1202     let val [(_ $ _ $ (g $ _))] = Thm.prems_of @{thm Let_folded}
  1203     in cterm_of @{theory} g end;
  1203     in Thm.cterm_of @{theory} g end;
  1204   fun count_loose (Bound i) k = if i >= k then 1 else 0
  1204   fun count_loose (Bound i) k = if i >= k then 1 else 0
  1205     | count_loose (s $ t) k = count_loose s k + count_loose t k
  1205     | count_loose (s $ t) k = count_loose s k + count_loose t k
  1206     | count_loose (Abs (_, _, t)) k = count_loose  t (k + 1)
  1206     | count_loose (Abs (_, _, t)) k = count_loose  t (k + 1)
  1207     | count_loose _ _ = 0;
  1207     | count_loose _ _ = 0;
  1208   fun is_trivial_let (Const (@{const_name Let}, _) $ x $ t) =
  1208   fun is_trivial_let (Const (@{const_name Let}, _) $ x $ t) =
  1220       if is_Free x orelse is_Bound x orelse is_Const x
  1220       if is_Free x orelse is_Bound x orelse is_Const x
  1221       then SOME @{thm Let_def}
  1221       then SOME @{thm Let_def}
  1222       else
  1222       else
  1223         let
  1223         let
  1224           val n = case f of (Abs (x, _, _)) => x | _ => "x";
  1224           val n = case f of (Abs (x, _, _)) => x | _ => "x";
  1225           val cx = cterm_of thy x;
  1225           val cx = Thm.cterm_of thy x;
  1226           val {T = xT, ...} = rep_cterm cx;
  1226           val {T = xT, ...} = Thm.rep_cterm cx;
  1227           val cf = cterm_of thy f;
  1227           val cf = Thm.cterm_of thy f;
  1228           val fx_g = Simplifier.rewrite ctxt (Thm.apply cf cx);
  1228           val fx_g = Simplifier.rewrite ctxt (Thm.apply cf cx);
  1229           val (_ $ _ $ g) = prop_of fx_g;
  1229           val (_ $ _ $ g) = Thm.prop_of fx_g;
  1230           val g' = abstract_over (x,g);
  1230           val g' = abstract_over (x,g);
  1231           val abs_g'= Abs (n,xT,g');
  1231           val abs_g'= Abs (n,xT,g');
  1232         in (if (g aconv g')
  1232         in (if (g aconv g')
  1233              then
  1233              then
  1234                 let
  1234                 let
  1236                     cterm_instantiate [(f_Let_unfold, cf), (x_Let_unfold, cx)] @{thm Let_unfold};
  1236                     cterm_instantiate [(f_Let_unfold, cf), (x_Let_unfold, cx)] @{thm Let_unfold};
  1237                 in SOME (rl OF [fx_g]) end
  1237                 in SOME (rl OF [fx_g]) end
  1238              else if (Envir.beta_eta_contract f) aconv (Envir.beta_eta_contract abs_g') then NONE (*avoid identity conversion*)
  1238              else if (Envir.beta_eta_contract f) aconv (Envir.beta_eta_contract abs_g') then NONE (*avoid identity conversion*)
  1239              else let
  1239              else let
  1240                    val g'x = abs_g'$x;
  1240                    val g'x = abs_g'$x;
  1241                    val g_g'x = Thm.symmetric (Thm.beta_conversion false (cterm_of thy g'x));
  1241                    val g_g'x = Thm.symmetric (Thm.beta_conversion false (Thm.cterm_of thy g'x));
  1242                    val rl = cterm_instantiate
  1242                    val rl = cterm_instantiate
  1243                              [(f_Let_folded, cterm_of thy f), (x_Let_folded, cx),
  1243                              [(f_Let_folded, Thm.cterm_of thy f), (x_Let_folded, cx),
  1244                               (g_Let_folded, cterm_of thy abs_g')]
  1244                               (g_Let_folded, Thm.cterm_of thy abs_g')]
  1245                              @{thm Let_folded};
  1245                              @{thm Let_folded};
  1246                  in SOME (rl OF [Thm.transitive fx_g g_g'x])
  1246                  in SOME (rl OF [Thm.transitive fx_g g_g'x])
  1247                  end)
  1247                  end)
  1248         end
  1248         end
  1249     | _ => NONE)
  1249     | _ => NONE)