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