Zulip Chat Archive
Stream: new members
Topic: Question about List.getElem_idxOf
Yongxi Lin (Aaron) (Nov 23 2025 at 07:26):
I want to prove that if r is a list (of some subtype) and a is an element of r, then r[List.idxOf a r] = a. I failed because of a type class instance problem. May someone help me understand what I did wrong?
import Mathlib
open Set
variable {ι : Type*} {t : ι} [LinearOrder ι] {r : List (Iic t)} {a : Iic t} {mar : a ∈ r}
#check List.idxOf_lt_length_of_mem mar
#check List.getElem_idxOf (List.idxOf_lt_length_of_mem mar)
Snir Broshi (Nov 23 2025 at 14:24):
I believe the problem is that docs#List.getElem_idxOf requires [DecidableEq α] while docs#List.idxOf_lt_length_of_mem requires [BEq α].
There's a "diamond" in the typeclasses because Subtype is involved, which causes there to be two different instances of BEq:
Apart from changing both theorems to use DecidableEq, or deleting docs#Subtype.instBEq, I don't know how to fix it.
Snir Broshi (Nov 23 2025 at 14:24):
But you can do Option.some_injective _ <| getElem?_pos .. |>.symm.trans <| List.getElem?_idxOf mar instead, it only uses DecidableEq
Snir Broshi (Nov 23 2025 at 14:31):
Also if you don't need to know the underlying type Iic t of the list for what you need from idxOf, you can prove lemmas with {α : Type*} [DecidableEq α] and use them from the part of the code that does know about Iic t.
E.g.:
import Mathlib
lemma List.getElem_idxOf_of_mem {α : Type*} [DecidableEq α] {l : List α} {a : α} (h : a ∈ l) :
l[l.idxOf a]'(List.idxOf_lt_length_of_mem h) = a :=
List.getElem_idxOf ..
open Set
variable {ι : Type*} {t : ι} [LinearOrder ι] {r : List (Iic t)} {a : Iic t} {mar : a ∈ r}
#check List.getElem_idxOf_of_mem mar
Robin Arnez (Nov 23 2025 at 15:37):
Snir Broshi schrieb:
Apart from changing both theorems to use
DecidableEq, or deleting docs#Subtype.instBEq, I don't know how to fix it.
The real fix would be to make both theorems use [BEq α] [LawfulBEq α]
Ruben Van de Velde (Nov 23 2025 at 15:42):
I thought https://github.com/leanprover/lean4/pull/8309 was the real fix
Robin Arnez (Nov 23 2025 at 15:54):
Also that :-) But until then, you should use BEq + LawfulBEq when talking about functions that use BEq (and maybe even after then to help unification)
Snir Broshi (Nov 24 2025 at 18:19):
Robin Arnez said:
Also that :-) But until then, you should use
BEq+LawfulBEqwhen talking about functions that useBEq(and maybe even after then to help unification)
So how should docs#List.getElem_idxOf / docs#List.idxOf_lt_length_of_mem be changed?
Robin Arnez (Nov 24 2025 at 21:28):
docs#List.idxOf_lt_length_of_mem is perfectly fine,
docs#List.getElem_idxOf, docs#List.idxOf_get, docs#List.getElem?_idxOf and docs#List.idxOf_inj should all take [BEq α] [LawfulBEq α] instead of [DecidableEq α]
Snir Broshi (Nov 24 2025 at 21:50):
Robin Arnez said:
docs#List.idxOf_lt_length_of_mem is perfectly fine,
docs#List.getElem_idxOf, docs#List.idxOf_get, docs#List.getElem?_idxOf and docs#List.idxOf_inj should all take[BEq α] [LawfulBEq α]instead of[DecidableEq α]
Is the eventual goal to deprecate DecidableEq?
Robin Arnez (Nov 24 2025 at 22:03):
No, DecidableEq is good and all but docs#List.idxOf has a BEq assumption, not a DecidableEq one
Last updated: Dec 20 2025 at 21:32 UTC