Zulip Chat Archive
Stream: general
Topic: How to resolve `HEq u (e ▸ u)`?
Andrej Bauer (Apr 13 2024 at 08:51):
I must not be the first one who used congr
and was left with HEq u (e ▸ u)
. How do I get rid of this? I am happy to assume UIP or whatever it takes. (Currently I am not using mathlib, if that matters, and would prefer not to.)
Mario Carneiro (Apr 13 2024 at 08:54):
cases e; rfl
seems likely to work
Mario Carneiro (Apr 13 2024 at 08:54):
there is probably a lemma you can apply as well
Mario Carneiro (Apr 13 2024 at 08:55):
eqRec_heq.symm
, give or take
Andrej Bauer (Apr 13 2024 at 08:58):
Here's an example:
theorem chicken {α β}
(P : α → Type)
(f : ∀ (x : α), P x → β)
{x y : α}
(e : x = y) {u : P x} :
f x u = f y (e ▸ u)
:= by congr ; sorry --left with HEq u (e ▸ u)
Andrej Bauer (Apr 13 2024 at 09:00):
Indeed, cases e ; rfl
(instead of congr
) worked. Thanks.
Notification Bot (Apr 13 2024 at 09:00):
Andrej Bauer has marked this topic as resolved.
Andrej Bauer (Apr 13 2024 at 09:01):
More generally, is there a way to say "Just get rid of all the ▸
, even if you assume UIP"?
Notification Bot (Apr 13 2024 at 09:02):
Andrej Bauer has marked this topic as unresolved.
Andrej Bauer (Apr 13 2024 at 09:03):
The problem is that in many other cases I have goals like step p (⋯ ▸ ps) = ⋯ ▸ step p ps
and I really don't want to look what's inside ⋯
. Any advice on how to deal with these is most welcome.
Mario Carneiro (Apr 13 2024 at 09:03):
I believe this is what we affectionately refer to as DTT hell
Andrej Bauer (Apr 13 2024 at 09:04):
Yes, I know, I helped advertise it under the slogan "homotopy type theory" a while ago.
Mario Carneiro (Apr 13 2024 at 09:04):
unfortunately there are a lot of non-theorems in this space so it's not that easy to just ignore all the casts
Andrej Bauer (Apr 13 2024 at 09:04):
But since Lean 4 has choice, excluded middle, and nuclear bombs, perhaps the hell is more enjoyable.
Andrej Bauer (Apr 13 2024 at 09:05):
In that case, how do I look inside ⋯
?
Mario Carneiro (Apr 13 2024 at 09:06):
as long as enough things are variables you can pretty much just cases e1; cases e2; rfl
your way to success, but when the equalities are between nontrivial things you first have to generalize various things, and I don't know a general way of doing this correctly
Andrej Bauer (Apr 13 2024 at 09:06):
Or even better, is there UIP somewhere in the Lean standard library? I think that would solve my problems.
Andrej Bauer (Apr 13 2024 at 09:06):
(Of course they are not variables.)
Mario Carneiro (Apr 13 2024 at 09:06):
you can mouse over the ... to see it, or use set_option pp.proofs true
Mario Carneiro (Apr 13 2024 at 09:06):
UIP is assumed by everything, and it's a definitional equality. That's not the problem
Mario Carneiro (Apr 13 2024 at 09:07):
I suppose in this example you can kind of just rewrite the cast away because HEq is transitive and casts are HEq to their main argument
Mario Carneiro (Apr 13 2024 at 09:08):
but rewrite doesn't understand HEq
Mario Carneiro (Apr 13 2024 at 09:09):
One tool which may help you here is generalize_proofs
, which will pull all the ...
proofs into variables so you can induct on them or revert them or something
Mario Carneiro (Apr 13 2024 at 09:10):
but it's in mathlib, you'll have to copy it into your project if you don't want to depend on mathlib
Andrej Bauer (Apr 13 2024 at 09:11):
I think I'll just have to put on my HoTT hat and deal with the matter. Thanks.
Sina Hazratpour 𓃵 (Apr 16 2024 at 12:11):
Mario Carneiro said:
One tool which may help you here is
generalize_proofs
, which will pull all the...
proofs into variables so you can induct on them or revert them or something
Interesting! Do you have a mwe or a link to somewhere on Mathlib for a use case of generalize_proofs
?
Mario Carneiro (Apr 16 2024 at 12:50):
basic example:
import Mathlib.Tactic.GeneralizeProofs
example {n} (v : BitVec (n + 5)) (a : BitVec 5) (b : BitVec n) : a ++ b = v.cast (by omega) := by
-- ⊢ a ++ b = BitVec.cast ⋯ v
generalize_proofs h
-- h : n + 5 = 5 + n
-- ⊢ a ++ b = BitVec.cast h v
Mario Carneiro (Apr 16 2024 at 12:52):
the next step can vary depending on what you want to do, but what generalize_proofs
saves you is the trouble of having to write down whatever nasty proof term was generated by omega
in this example in order to use it with generalize
Last updated: May 02 2025 at 03:31 UTC