Zulip Chat Archive
Stream: lean4
Topic: DecidableEq, LT, GT
André Luiz Feijó dos Santos (Sep 26 2025 at 20:19):
I've been struggling to define DecidableEq, LT, and LE instances for "non-direct" notions of equality — that is, equality different from the default, where, for example, in this post, monday = monday and wednesday = wednesday.
Suppose I want to define NumQ, which is rational -- like:
inductive NumQ where
| rat : Int -> Nat -> NumQ -- "rat num den"
where I want DecidableEq, LT and LE to consider the comparison by cross multiplication to say that, e.g.:
(rat 3 4 = rat 30 40) = true.
How should I define DecidableEq, LT, and LE for NumQ in this way?
Aaron Liu (Sep 26 2025 at 20:21):
for decidableeq you need to take a quotient
André Luiz Feijó dos Santos (Sep 26 2025 at 20:23):
Thanks for answering. Could you give me an example of how to implement it?
Aaron Liu (Sep 26 2025 at 20:24):
inductive NumQ : Type where
| rat : Int -> Nat -> NumQ -- "rat num den"
open NumQ
-- actually it doesn't work like that
example : rat 3 4 ≠ rat 30 40 := by simp
Aaron Liu (Sep 26 2025 at 20:26):
André Luiz Feijó dos Santos said:
Thanks for answering. Could you give me an example of how to implement it?
well Batteries does docs#Rat differently (it reduces the fractions) and usually we don't like to use Quotient if there's a way to efficiently pick a representative from each equivalence class
Aaron Liu (Sep 26 2025 at 20:26):
since it breaks canonicity
Robin Arnez (Sep 26 2025 at 22:07):
If you want to still know how quotients work:
inductive PreNumQ : Type where
| rat : Int → Nat → PreNumQ -- "rat num den"
def PreNumQ.Eqv (x y : PreNumQ) : Prop :=
match x, y with
| .rat a b, .rat c d =>
sorry -- what you want rat a b = rat c d to mean
instance PreNumQ.setoid : Setoid PreNumQ where
r := PreNumQ.Eqv
iseqv := { -- proof that it is an equivalence relation
refl x := sorry
symm {x y} h := sorry
trans {x y z} h h' := sorry
}
def NumQ := Quotient PreNumQ.setoid
def NumQ.rat (a : Int) (b : Nat) : NumQ := Quotient.mk _ (.rat a b)
theorem NumQ.rat_eq_rat_iff {a b c d} : rat a b = rat c d ↔ PreNumQ.Eqv (.rat a b) (.rat c d) :=
⟨Quotient.exact, Quotient.sound (s := PreNumQ.setoid)⟩
Kenny Lau (Sep 26 2025 at 22:59):
@André Luiz Feijó dos Santos the key concept here is that while < and <= are relations that can be defined arbitrarily, = is actually a core notion of Lean that cannot be changed
François G. Dorais (Sep 27 2025 at 05:15):
In addition to the previous responses, note that == (aka BEq) can be defined arbitrarily. It is, however, required to be decidable since its value is in Bool instead of Prop.
Robert Maxton (Sep 27 2025 at 08:56):
higher inductives when :(
David Thrane Christiansen (Sep 28 2025 at 00:22):
The reference manual explains quotient types and gives some related examples, in case that's useful.
Last updated: Dec 20 2025 at 21:32 UTC