Continuing the discussion from Why `sort()` need `T` to be `Ord`?:
There has been some confusion about how the traits in std::cmp
relate to the mathematical terms
- partial order
- partial equivalence
- equivalence
- partial equality (whatever that is, if it exists)
- equality
- strict weak order or total preorder
- total order
Firstly, let me summarize what the std
documentation states:
PartialEq
: "Trait for equality comparisons which are partial equivalence relations."Eq
: "Trait for equality comparisons which are equivalence relations."PartialOrd
: "Trait for values that can be compared for a sort-order."Ord
: "Trait for types that form a total order."
Moreover in std::cmp
's overview:
- "
Eq
andPartialEq
are traits that allow you to define total and partial equality between values, respectively. Implementing them overloads the==
and!=
operators." - "
Ord
andPartialOrd
are traits that allow you to define total and partial orderings between values, respectively. Implementing them overloads the<
,<=
,>
, and>=
operators."
Consequently, the documentation sets these terms equal (pun not intended ):
PartialEq
โ partial equivalence or "partial equality"Eq
โ equivalence or "total equality"PartialOrd
โ partial orderOrd
โ total order
I'll try to summarize the discussion in the original thread in a short manner, so everyone who's interested in this topic (not sure if there's anyone) can catch up. If I make a mistake with citing, please correct me. I'm just trying to do it as good as I can.
I claimed that there would be no trait for weak orderings in (std
) Rust,
because
@steffahn said that in his opinion Ord
describes a "weak order" or "total preorder", except if we "(mis-)interpret" an Eq
implementation as "equality":
This led to the argument whether Eq
means some "equivalence relation" or "equality".
@tczajka stated that there are two levels of description: the representation level and the higher, semantic level:
Moreover:
@tczajka also questioned why PartialOrd
isn't a partial order. After some back-and-forth discussion (and some confused posts by me ), I think I could prove that PartialOrd
indeed describes a partial order:
While @steffahn agreed that "technically <
is a strict partial order" in case of PartialOrd
, he also pointed out that the corresponding non-strict partial order requires that ==
is defined according to "mathematical equality, which is โ in particular โ an equivalence relation".
Thus, the operators ==
, !=
, <
, <=
, >
, >=
would only resemble a strict partial order with the corresponding non-strict partial order if Eq
was implemented in addition to PartialOrd
.
This, however, comes with practical problems, because of how https://en.wikipedia.org/wiki/IEEE_754 defines "equality" (not in the mathematical sense, I guess) for NaN values:
I hope that I gave a good summary of our discussion (and would like to apologize if I didn't get some things right or missed important points).
I'd like to follow up with my personal conclusion(s) in that matter:
PartialEq
describes a "partial equality relation".Eq
describes an "equivalence relation", which most often is sementically identical to "equality" (in practice, and maybe also according to the docs).PartialOrd
kinda describes a (strict) partial order, but the corresponding non-strict partial order isn't reflected by Rust's comparison operators (except<
and>
).Ord
could either be interpreted as a total order or as weak order (e.g. as strict weak order or total preorder). This depends on whether we sayEq
reflects "equality" in particular or an arbitrary "equivalence relation", respectively.