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) |