Zulip Chat Archive
Stream: lean4
Topic: A question regarding the eta rule for the product type
Gordon Hsu (Feb 08 2025 at 14:37):
Why is there an error for rfl
in the code below?
example (m : Nat × Nat) : Nat :=
let ⟨a, b⟩ := m
have : m.2 = b := rfl /-
type mismatch
rfl
has type
?m.36775 = ?m.36775 : Prop
but is expected to have type
b = m.snd : Prop
-/
a
Besides using a match
and congrArg Prod.snd
as shown below, can definitional equality be applied somehow?
example (m : Nat × Nat) : Nat :=
match e : m with
| ⟨a, b⟩ =>
have : m.2 = b := congrArg Prod.snd e
a
Kyle Miller (Feb 08 2025 at 16:38):
Destructuring let
notation doesn't keep track of the relationship between the value being destructed and the new variables unfortunately.
The match e : m with
is one way to do it, and the other is to simply not destruct m
in the first place.
Gordon Hsu (Feb 08 2025 at 16:58):
Thanks for the clarification. One other question, how is the let
binder different from Prod.eta (p : α × β) : (p.1, p.2) = p := rfl
? Why is one definitionally equal, yet the other isn't? I think I am missing something very basic.
Aaron Liu (Feb 08 2025 at 17:31):
The let
binder throws away the relationship between a
, b
, and m
.
Kyle Miller (Feb 08 2025 at 17:33):
The let
destructuring bind is sugar for match
, so just like match
there's no relationship between the original value and the pattern variables.
Kyle Miller (Feb 08 2025 at 17:36):
Underneath all this is that match
uses recursors to break apart values, and there's no defeq relationship between the value broken apart and the components given by the recursor.
It seems like a reasonable feature request for match
for structure-likes to be special cased, to use projections instead of the recursor. So for example let ⟨a, b⟩ := m; ...
would be short for let a := m.1; let b := m.2; ...
.
Kyle Miller (Feb 08 2025 at 17:39):
One small complexity here is that in case the structure-like has dependent fields, successive fields refer to the new let
variables rather than m
.
This is a reasonably large project though.
Kevin Buzzard (Feb 08 2025 at 17:44):
Note that in tactic mode obtain \<a,b\> := m
will simply remove m
and replace it with Prod.mk a b
so you won't have this problem
Aaron Liu (Feb 08 2025 at 17:45):
It also leaves some ugly recursors in the term generated.
Kyle Miller (Feb 08 2025 at 17:47):
That's not something people usually care about for proofs though. (But in the context of the original question, yes that could be an issue, and it's consistent with the 'don't use tactics for data' advice.)
Gordon Hsu (Feb 09 2025 at 04:45):
Thanks for all your help :big_smile:
Since let
boils down to match
that uses recursors, there is no definitional equality with propositional equality being the only thing available. The obtain
tactic is indeed helpful in tactic mode.
Eric Wieser (Feb 10 2025 at 11:28):
There is an open feature request on GitHub for changing the let
behavior here
Gordon Hsu (Feb 10 2025 at 11:56):
Eric Wieser said:
There is an open feature request on GitHub for changing the
let
behavior here
That's awesome, but I couldn't find the GitHub issue.
Kyle Miller (Feb 10 2025 at 17:21):
I wasn't able to find it either.
Eric Wieser (Feb 10 2025 at 17:28):
lean4#5216 is what I was thinking of
Last updated: May 02 2025 at 03:31 UTC