Zulip Chat Archive
Stream: new members
Topic: Can't unify seemingly identical terms
Daniel Weber (Mar 24 2024 at 06:26):
I'm trying to prove a theorem in additive combinatorics, but there's a weird bug - when I'm trying to do exact
to something which looks like the goal, it fails to unify. A #mwe:
import Mathlib
open Classical Pointwise
lemma card_of_inv {α : Type*} [Field α] [Fintype α] (A : Finset α) (a : α) (h : a ≠ 0) : (a • A).card = A.card := by
sorry
theorem GUS (p : ℕ) [Fact (p.Prime)] (A : Finset (ZMod p)) : (3 • A^2 - 3 • A^2).card ≥
((min (A.card^2) p) / 2 : ℚ) := by
rw [ge_iff_le]
have a : ZMod p := sorry
have b : ZMod p := sorry
have c : ZMod p := sorry
have d : ZMod p := sorry
calc ((min (A.card^2) p) / 2 : ℚ)
_ ≤ (A + ((a - b) / (c - d) + 1) • A).card := by
sorry
_ = ((c - d) • (A + ((a - b) / (c - d) + 1) • A)).card := by
norm_cast
apply Eq.symm
have : c - d ≠ 0 := sorry
have := card_of_inv (α := ZMod p) (a := c - d) (h := this) (A := (A + ((a - b) / (c - d) + 1) • A))
exact this
-- type mismatch
-- this
-- has type
-- ((c - d) • (A + ((a - b) / (c - d) + 1) • A)).card = (A + ((a - b) / (c - d) + 1) • A).card : Prop
-- but is expected to have type
-- ((c - d) • (A + ((a - b) / (c - d) + 1) • A)).card = (A + ((a - b) / (c - d) + 1) • A).card : Prop
sorry
_ ≤ _ := sorry
Additionally, if I try to end the calc
with (3 • A^2 - 3 • A^2).card
it fails, with:
'calc' tactic failed, has type
↑(min (A.card ^ 2) p) / 2 ≤ ?m.24439
but it is expected to have type
↑(min (A.card ^ 2) p) / 2 ≤ ↑(3 • A ^ 2 - 3 • A ^ 2).card
I don't know if this is related. Regardless, what's going on there, and are there general ways to debug something like this?
Daniel Weber (Mar 24 2024 at 06:40):
In fact
import Mathlib
open Classical Pointwise
lemma card_of_inv {α : Type*} [Field α] [Fintype α] (A : Finset α) (a : α) (h : a ≠ 0) : (a • A).card = A.card := by
sorry
lemma card_of_inv_zmod (p : ℕ) [Fact (p.Prime)] (A : Finset (ZMod p)) (a : ZMod p) (h : a ≠ 0) : (a • A).card = A.card := by
have := card_of_inv A a h
exact this
already fails, so it shouldn't be related to the calc
. I'm suspecting there might be a diamond or something, but I don't know what to do about that
Daniel Weber (Mar 24 2024 at 06:58):
Oh, I figured it out, there's a diamond with DecidableEq α
. Removing Classical
and adding DecidableEq
works, although calc
still fails. I realized I should try and remove Classical
for my whole project, but I have another problem: is DecidableEq
and DecidableMem
for submodules over a DecidableEq
Fintype
defined somewhere?
Notification Bot (Mar 24 2024 at 07:27):
This topic was moved here from #general > Can't unify seemingly identical terms by Riccardo Brasca.
Riccardo Brasca (Mar 24 2024 at 07:31):
Can you write precisely what you are looking for? A #mwe would be great
Daniel Weber (Mar 24 2024 at 07:33):
Sure:
import Mathlib
variable {α : Type*} [Field α] [Fintype α] [DecidableEq α]
def Line (α : Type*) [Ring α] := {x : Submodule α (α × α × α) // FiniteDimensional.finrank α x = 2}
instance instSetLike : SetLike (Line α) (α × α × α) where
coe x := x.val
coe_injective' x1 x2 h := by
apply Subtype.ext
simp_all
instance mem2 : Membership (α × α) (Line α) where
mem x l := ⟨x.1, x.2, 1⟩ ∈ l
instance instDecidableMem2 (x : α × α) (y : Line α) : Decidable (x ∈ y) := inferInstance -- fails
instance instDecidableEqLine : DecidableEq (Line α) := inferInstance -- fails
Riccardo Brasca (Mar 24 2024 at 07:45):
Are you really interested in these instances or you want them just because Lean is complaining? It Lean wants them is a proof you can just start the proof with classical
and the problem will disappear.
Daniel Weber (Mar 24 2024 at 08:16):
Riccardo Brasca said:
Are you really interested in these instances or you want them just because Lean is complaining? It Lean wants them is a proof you can just start the proof with
classical
and the problem will disappear.
But wouldn't that potentially cause a diamond?
Kyle Miller (Mar 24 2024 at 08:20):
You're not going to be able to create these two instances. These are additional assumptions you'll have to add to theorems if you don't want to go with classical
.
Kyle Miller (Mar 24 2024 at 08:21):
For your original problem, do you know about convert
? It's like exact
, but it tries to handle dealing with small differences between terms automatically, and for whatever it can't handle you get new subgoals.
Kyle Miller (Mar 24 2024 at 08:22):
If you replace exact this
with convert this
, it works.
Riccardo Brasca (Mar 24 2024 at 08:28):
Daniel Weber said:
Riccardo Brasca said:
Are you really interested in these instances or you want them just because Lean is complaining? It Lean wants them is a proof you can just start the proof with
classical
and the problem will disappear.But wouldn't that potentially cause a diamond?
Using classical
in a proof is fine. In your previous example you used it in the statement, and that can indeed create diamond.
Kevin Buzzard (Mar 24 2024 at 08:41):
In your initial example all those have a : ZMod p :=
should be let a : ZMod p :=
btw
Kevin Buzzard (Mar 24 2024 at 08:43):
The basic rule for classical/decidable is that if you can state the theorems without decidability then do this and use the classical
tactic in the proof and you'll be fine.
Daniel Weber (Mar 24 2024 at 08:51):
Kyle Miller said:
For your original problem, do you know about
convert
? It's likeexact
, but it tries to handle dealing with small differences between terms automatically, and for whatever it can't handle you get new subgoals.
Interesting, I didn't know of it, thanks
Bolton Bailey (Apr 03 2024 at 22:45):
Concerning to me that this is giving the unhelpful error message where it reports a distinction between terms that are visually identical. I thought we fixed this issue. Isn't the error message supposed to automatically show the more elaborate terms when the pretty-printings are equal?
Bolton Bailey (Apr 03 2024 at 22:45):
@Joachim Breitner
Bolton Bailey (Apr 03 2024 at 22:47):
lean4#3234 was the relevant PR. Maybe that only fixed apply
and not exact
?
Joachim Breitner (Apr 05 2024 at 11:21):
My PR wasn’t good and I ran out of cycles for this feature; it needs more refactoring to make the error message “lazy enough“ so that you don’t run an expensive algorithm when the users never sees the message (e.g. when backtracking tactics.)
Last updated: May 02 2025 at 03:31 UTC