Zulip Chat Archive
Stream: lean4
Topic: Eq.subst
Dan Velleman (Oct 20 2022 at 13:38):
In this example:
example (a b c m n : Int) (h1 : b = a * m) (h2 : c = b * n) : c = a * m * n :=
Eq.subst h1 h2
I get the error message application type mismatch Eq.subst h1 argument h1 has type b = a * m : Prop but is expected to have type b = a * m * n : Prop
. If I use @Eq.subst
and supply the motive explicitly, it works. So I guess Lean isn't able to figure out the motive, but I'm surprised at that. Isn't inferring the motive pretty straightforward in this case?
François G. Dorais (Oct 20 2022 at 18:29):
elab_as_eliminator
isn't much used in Lean 4. (It was added at some point to help porting mathlib but it isn't acutally used.)
In term mode, you need to supply the motive for pretty much all recursors. Instead of @Eq.subst
, you can use Eq.subst (motive:=_)
so the other implicit arguments are filled in.
That said, in the case of Eq.subst
, you can simply use ▸
:
example (a b c m n : Int) (h1 : b = a * m) (h2 : c = b * n) : c = a * m * n := h1 ▸ h2
Mario Carneiro (Oct 20 2022 at 18:36):
See also lean4#1679
Dan Velleman (Oct 20 2022 at 18:49):
I was assuming h1 ▸ h2
was just shorthand for Eq.subst h1 h2
--that's what it said in TPIL 3. But I see that TPIL 4 says something slightly different--it says that ▸
is "a macro built on top of Eq.subst and Eq.symm." So I guess it has changed.
Actually, when I hover over h1 ▸ h2
in Lean it tells me that ▸
is a macro built on top of Eq.rec and Eq.symm.
Mario Carneiro (Oct 20 2022 at 18:51):
It was changed, because \t
in lean 3 was very often useless / didn't do the obvious thing even when by rw h; exact e
would work - which has exactly the same amount of information as h \t e
François G. Dorais (Oct 20 2022 at 19:21):
Eq.subst
is limited to propositions; Eq.ndrec
is the same but applies to any sort. Eq.rec
is the natural eliminator for equality but it has a more complex signature that is rarely of much use.
Richard Copley (Feb 15 2023 at 10:52):
With this setup:
import Lean.Meta.Tactic.Rewrite
example (a b : Prop) (ha : a) : b → b :=
by
have h₁ : (a → b) → b := fun f => f ha
have h₂ : (a → b) = b := propext ⟨(fun f => f ha), (fun hb _ha => hb)⟩
have h₃ := h₂ ▸ h₁
-- h₁ : (a → b) → b
-- h₂ : (a → b) = b
-- h₃ : b → b
exact h₃
closes the goal, but exact h₂ ▸ h₁
gives the following error
type mismatch
h₁
has type
(a → b) → b : Prop
but is expected to have type
(a → b) → a → b : Prop
Same error if I specify the expected type of h₃
,
have h₃ : b → b := h₂ ▸ h₁
Is there a bug here?
Kevin Buzzard (Feb 15 2023 at 13:52):
Higher order unification is undecidable so it's just different algorithms giving different answers I guess
Kevin Buzzard (Feb 15 2023 at 13:54):
My guess is that having access to the type of the term eq.subst is supposed to be producing changes how elaboration works.
Richard Copley (Feb 15 2023 at 17:29):
Must be! But we know it's possible to find a motive that does what is wanted, because we need only ignore the expected type :smiling_face_with_tear:
Kevin Buzzard (Feb 15 2023 at 21:07):
Right, and we also know that no computer program can reliably find these motives, because there's no algorithm, so it's not clear that failure of a computer program to do so is a bug.
Last updated: Dec 20 2023 at 11:08 UTC