Zulip Chat Archive
Stream: mathlib4
Topic: Finset / Multiset / Set issue
John Talbot (May 15 2025 at 10:41):
Could anyone give some advice about why the following proof fails?
import Mathlib.Data.Finset.Basic
variable {α : Type*} {a : α}
def null (f : Set α → ℕ) (s : Set α) [NeZero (f s)] : ℕ := 0
lemma null_set (f : Set α → ℕ) (s : Set α) (_h : a ∈ s) [NeZero (f s)] :
null f s = 0 := rfl
lemma null_finset (f : Set α → ℕ) (s : Finset α) (h : a ∈ s) [NeZero (f s)] :
null f s = 0 := by
exact null_set f _ h -- failed to synthesize NeZero (f (Membership.mem s.val))
-- exact null_set f s h -- Goals accomplished!
-- exact null_set f _ (by exact h) -- Goals accomplished!
-- exact @null_set _ _ _ _ h ‹_› -- Goals accomplished!
-- rfl -- Goals accomplished!
John Talbot (May 15 2025 at 10:44):
Sorry posted prematurely!
In particular how do we arrive at the Membership.mem s.val in the typeclass resolution?
Riccardo Brasca (May 15 2025 at 10:44):
Because Lean has no way of guessing what you mean by _. This is because s is a Finset, not a Set.
Riccardo Brasca (May 15 2025 at 10:45):
In particular, it cannot guess it from h, since h is not of type "a belongs to a set"
Riccardo Brasca (May 15 2025 at 10:48):
OK, maybe not exactly this, but the issue due to s : Finset α
John Talbot (May 15 2025 at 10:50):
Thanks! But I don't see a coercion from Finset to Multiset so I was surprised to see s.val appear?
Riccardo Brasca (May 15 2025 at 10:52):
To understand that you have to look at the trace
Riccardo Brasca (May 15 2025 at 10:52):
Give my 10 minutes
John Talbot (May 15 2025 at 10:52):
Thanks!
Aaron Liu (May 15 2025 at 11:00):
Aaron Liu (May 15 2025 at 11:00):
wait you were looking for the multiset
John Talbot (May 15 2025 at 11:01):
No - I was just naively expecting the Finset to be coerced to a Set
Aaron Liu (May 15 2025 at 11:02):
The reason s.val appears is because it's unfolding the membership instance
docs#Finset.instMembership
John Talbot (May 15 2025 at 11:04):
So it looks for a Set α and finds Membership.mem s.val?
Aaron Liu (May 15 2025 at 11:06):
I think so
Riccardo Brasca (May 15 2025 at 11:11):
The underscore in null_set f _ h means "Lean, please figure out what the _ is looking at the other variables". Lean knows that the underscore has type Set α and looks at h to guess it. Since h hasn't type x ∈ X for a set X it unfold h, hoping to get to something of the form x ∈ X, so it gets to a ∈ s.val. Now it goes back to check the required NeZero instance, and it complains.
Riccardo Brasca (May 15 2025 at 11:11):
There must be a trace to see off all of this, but I am not 100% sure which option is required.
Aaron Liu (May 15 2025 at 11:13):
I tried trace.Meta.isDefEq, trace.Elab.app.propagateExpectedType, trace.Elab.step, trace.Elab.step.result, trace.Elab.app.args, which told me a lot but didn't tell me enough
John Talbot (May 15 2025 at 11:14):
Thanks both! I will investigate those trace options.
Last updated: Dec 20 2025 at 21:32 UTC