Zulip Chat Archive
Stream: lean4
Topic: Option.decidableEqNone
Aaron Liu (Jul 04 2025 at 19:34):
Could we make docs#Option.decidableEqNone an instance? I know it makes a diamond with the current implementations, but
universe u
variable {α : Type u} (o : Option α)
example [DecidableEq α] : Option.instDecidableEq o none = @Option.decidableEqNone α o := by
with_unfolding_all rfl -- fails :(
-- these are better
abbrev instDecidableEq [DecidableEq α] : DecidableEq (Option α) := fun a b =>
match a with
| none => match b with
| none => .isTrue rfl
| some _ => .isFalse Option.noConfusion
| some a => match b with
| none => .isFalse Option.noConfusion
| some b => decidable_of_decidable_of_eq (Option.some.injEq a b).symm
abbrev instDecidableEqNone : Decidable (o = none) :=
match o with
| none => .isTrue rfl
| some _ => .isFalse Option.noConfusion
abbrev instDecidableNoneEq : Decidable (none = o) :=
match o with
| none => .isTrue rfl
| some _ => .isFalse Option.noConfusion
example [DecidableEq α] : instDecidableEq o none = instDecidableEqNone o := by
with_reducible rfl
example [DecidableEq α] : instDecidableEq none o = instDecidableNoneEq o := by
with_reducible rfl
that can be avoided.
Eric Wieser (Jul 04 2025 at 19:42):
I was not expecting
match a, b with
| none, none => .isTrue rfl
| none, some _ => .isFalse Option.noConfusion
| some _, none => .isFalse Option.noConfusion
| some a, some b => decidable_of_decidable_of_eq (Option.some.injEq a b).symm
to have a different defeq
Aaron Liu (Jul 04 2025 at 19:42):
I was thinking about doing that but then I realized I don't know how the matches are compiled and better be safe than sorry
Aaron Liu (Jul 04 2025 at 19:44):
It turns out it is still defeq if you turn off smartUnfolding
Eric Wieser (Jul 04 2025 at 19:45):
Which I guess is something that forbids partially unfolding a match
Eric Wieser (Jul 04 2025 at 19:45):
How did you find smartUnfolding so fast?
Aaron Liu (Jul 04 2025 at 19:45):
prior experience
Eric Wieser (Jul 04 2025 at 19:46):
For reference, the docstring of that option is
when computing weak head normal form, use auxiliary definition created for functions defined by structural recursion
Aaron Liu (Jul 04 2025 at 19:46):
specifically, docs#Nat.repeatTR and docs#Nat.iterate are defeq but only if you turn off smartUnfolding
Eric Wieser (Jul 04 2025 at 19:46):
I guess there's an implicit "instead of actually unfolding"
Aaron Liu (Jul 04 2025 at 19:47):
I think Kyle said something about it before and I remembered
Aaron Liu (Jul 10 2025 at 16:49):
No one objected so I made a PR: lean4#9302
Rob Simmons (Nov 20 2025 at 02:38):
Just merged! Thanks for your patience everyone, I'm also working on a follow-up to get the same thing working for lists and maybe arrays.
Aaron Liu (Nov 20 2025 at 02:48):
I tried implementing it naively for lists (copy what I did for Option) but it didn't work because of the structural recursion
Aaron Liu (Nov 20 2025 at 02:48):
I think if it make it into two mutual definitions it might still be possible
Rob Simmons (Nov 20 2025 at 03:20):
@Aaron Liu I think the List instances in that PR works fine with defeq, you can check my work though! I basically just unfolded the definition by one step. It's only the array one that doesn't respect definitional equality right now.
Rob Simmons (Nov 20 2025 at 03:21):
(I'm still wrapping my head around lean-specific defeq nuances tbh)
Last updated: Dec 20 2025 at 21:32 UTC