Zulip Chat Archive
Stream: new members
Topic: Simplify `let ... in ...` in hypothesis
Henning Dieterichs (Dec 04 2020 at 10:28):
How can I deconstruct an hypothesis of the form h: a = let x = y in z x
into x: ...
, h1: x = y
and h2: a = z[x]
? I tried cases
and simp
, both inlined x
into y
which I want to avoid, as it becomes an unreadable mess.
Henning Dieterichs (Dec 04 2020 at 10:52):
It seems like this works:
set x = y,
have h1: a = z x := h,
It is a little bit magic though, as have h1 := h
does nothing.
Eric Wieser (Dec 04 2020 at 10:53):
I assume in your real example z
depends on x
?
Henning Dieterichs (Dec 04 2020 at 10:53):
yes
Reid Barton (Dec 04 2020 at 10:55):
I think there's a version of set
which doesn't introduce a let
binding
Mario Carneiro (Dec 04 2020 at 11:52):
generalize
Eric Wieser (Dec 04 2020 at 11:54):
Does generalize
avoid the need to write x = y
a second time?
Mario Carneiro (Dec 04 2020 at 11:55):
no
Mario Carneiro (Dec 04 2020 at 11:55):
it's a first time though
Henning Dieterichs (Dec 04 2020 at 12:03):
This does not work anymore though:
generalize x_def: y = x,
have h1: a = z x := h,
I.e. I don't know how to get rid of the let in
in h
with this.
Lean gets rid of it automatically when using set
.
Kevin Buzzard (Dec 04 2020 at 12:05):
#mwe ?
Reid Barton (Dec 04 2020 at 12:08):
oh right that makes sense
Reid Barton (Dec 04 2020 at 12:09):
There's also a tactic to clear the let binding part of a hypothesis
Mario Carneiro (Dec 04 2020 at 12:16):
I wonder if rcases
can be modified to capture let bindings. It's a bit tricky because whnf will go right past a let binding
Henning Dieterichs (Dec 04 2020 at 12:17):
def f (x: nat) := (x, x)
def g (x: nat × nat) := x.fst + x.snd
lemma mwe (x: nat) (h: x = let y := f x in g y): x = 0 :=
begin
set y := f x,
have y_def: y = f x, { simp [y] },
replace h: x = g y := h,
sorry,
end
Somewhat artificial though. How can I get to the sorry with the same state more elegantly?
Mario Carneiro (Dec 04 2020 at 12:20):
Actually, perhaps a better interface is some kind of split_lets
that will extract let
statements in the targeted hyp(s) and introduce new variables like set
Kevin Buzzard (Dec 04 2020 at 12:21):
import tactic
def f (x: nat) := (x, x)
def g (x: nat × nat) := x.fst + x.snd
lemma mwe (x: nat) (h: x = let y := f x in g y): x = 0 :=
begin
set y := f x with y_def,
simp at h,
sorry,
end
is one less line and also less painful
Mario Carneiro (Dec 04 2020 at 12:21):
this still doesn't solve the problem of a let under a lambda though
Eric Wieser (Dec 04 2020 at 12:22):
While not what this thread is about, note that intro
will slice off a let
from the goal
Reid Barton (Dec 04 2020 at 12:22):
maybe in Lean 4 we can just reuse the lambda lifting pass
Mario Carneiro (Dec 04 2020 at 12:22):
actually maybe there is a dsimp option for doing beta reduction but not zeta (let reduction)
Eric Wieser (Dec 04 2020 at 12:22):
Of course intro at
would be silly for the other meanings of intro
Henning Dieterichs (Dec 04 2020 at 12:24):
Kevin Buzzard said:
import tactic def f (x: nat) := (x, x) def g (x: nat × nat) := x.fst + x.snd lemma mwe (x: nat) (h: x = let y := f x in g y): x = 0 := begin set y := f x with y_def, simp at h, sorry, end
is one less line and also less painful
Thanks! Didn't know about with
in set
. I thought I should avoid non-goal closing simps though?
Kevin Buzzard (Dec 04 2020 at 12:47):
For me the whole point of set
is the with
. You're right -- simp only [y_def] at h,
is better for the second line.
Kevin Buzzard (Dec 04 2020 at 12:49):
change _ = g _ at h,
also works
Last updated: Dec 20 2023 at 11:08 UTC