Zulip Chat Archive
Stream: mathlib4
Topic: Bug(?) in `congrm` and `refine`
Yury G. Kudryashov (Mar 01 2025 at 02:18):
Here is a #mwe:
import Mathlib.Tactic.CongrM
-- works
example (a b : ℤ) : (a - b + b) + a + b = a + (a - b + b) + (b - a + a) := by
congrm ?h1 + ?h2
· congrm ?h3 + ?h4 <;> rw [Int.sub_add_cancel]
· rw [Int.sub_add_cancel]
-- fails
example (a b : ℤ) : (a - b + b) + a + b = a + (a - b + b) + (b - a + a) := by
congrm ?h1 + ?h2
· congrm ?h1 + ?h2 <;> rw [Int.sub_add_cancel]
· rw [Int.sub_add_cancel]
Yury G. Kudryashov (Mar 01 2025 at 02:20):
In the second example, the second call to congrm
tries to reuse ?h1
and ?h2
from the first call to congrm
.
Yury G. Kudryashov (Mar 01 2025 at 02:20):
CC: @Moritz Doll , @Damiano Testa
Damiano Testa (Mar 01 2025 at 04:08):
That's interesting: thanks for the report!
Damiano Testa (Mar 01 2025 at 04:37):
This could be fixed by replacing the given metavar names with "fresh" ones, although I am not completely sure that the current behaviour is undesirable.
Yury G. Kudryashov (Mar 01 2025 at 04:40):
refine
does the same:
import Mathlib.Tactic.CongrM
example (a b : ℤ) : (a - b + b) + a + b = a + (a - b + b) + (b - a + a) := by
refine congrArg₂ (· + ·) ?h1 ?h2
· refine congrArg₂ (· + ·) ?h1 ?h2 -- fail
Yury G. Kudryashov (Mar 01 2025 at 04:40):
I think that it should be either documented or changed.
Yury G. Kudryashov (Mar 01 2025 at 04:41):
Generally, I wouldn't expect tactic calls in different branches of the proof interact in any way.
Damiano Testa (Mar 01 2025 at 04:42):
The congrm
tactic is implemented via refine (congr(pattern))
, so the two are correlated. :smile:
Damiano Testa (Mar 01 2025 at 04:42):
Let me try to see if my proposed "fix" builds mathlib.
Yury G. Kudryashov (Mar 01 2025 at 04:46):
Here is a Mathlib-free example:
theorem congrArg₂ (f : α → β → γ) {x x' : α} {y y' : β}
(hx : x = x') (hy : y = y') : f x y = f x' y' := by subst hx hy; rfl
example (a b : Int) : (a + b) + (b + a) = (a + b) + (b + a) := by
refine congrArg₂ (· + ·) ?_ ?_
· have : ∀ a b : Int, a + b = a + b := by
refine fun a b => congrArg₂ (· + ·) ?h1 ?_
rfl
rfl
· refine congrArg₂ (· + ·) ?h1 ?_ <;> rfl
Damiano Testa (Mar 01 2025 at 04:47):
#22422 has the "downstream" fix, but, if this is something that should be fixed, it should be in refine
or further upstream.
Yury G. Kudryashov (Mar 01 2025 at 04:48):
@Kim Morrison Is it a bug or an underdocumented feature?
Kyle Miller (Mar 01 2025 at 05:05):
This is a problem with how metavariable names work. There's a single namespace for metavariables, and when they're re-used, they refer to the same metavariable. This is used by some people, for better or for worse, to be able to use values across multiple tactic branches.
It's not a bug with refine
itself, but with how ?m
syntax is elaborated.
The thing is, congrm
really is wanting metavariables here, since they stand for the equality proof.
It makes sense that refine
and congrm
might want to elaborate ?m
as a guaranteed new metavariable. I think we should think about how to get that done in a consistent way, rather than add a workaround in congrm
itself.
Right now, the safest thing to do is use ?_
instead, like congrm ?_ + ?_
.
Damiano Testa (Mar 01 2025 at 05:09):
I will close the PR: it was fun to work out what the issue was, but I agree that this feature/bug is upstream! :smile:
Kyle Miller (Mar 01 2025 at 05:14):
With your solution @Damiano Testa, did using case
work , like case h1 =>
, to select one of the goals after congrm
?
Damiano Testa (Mar 01 2025 at 05:18):
Yes, I had tried that.
Damiano Testa (Mar 01 2025 at 05:18):
I was worried that the hygienic names would get in the way, but they didn't.
Damiano Testa (Mar 01 2025 at 05:20):
I suspect that the matching in case
is by "username", rather than by actual name.
Kyle Miller (Mar 01 2025 at 05:42):
I think the only two names a metavariable has are its mvarid and its username
Damiano Testa (Mar 01 2025 at 05:48):
Ok, I updated the test to use case h1
and it seems to have passed (I'm no longer at a computer, though).
Damiano Testa (Mar 01 2025 at 05:49):
In a previous iteration, my phone's autocorrection had case H1 =>
and the error message seemed to talk about the hygienic names.
Last updated: May 02 2025 at 03:31 UTC