Section Normalize.
Context (A : Type).
Class Normalizes (m : relation A) (m' : relation A) : Prop :=
normalizes : relation_equivalence m m'.
(** Current strategy: add [flip] everywhere and reduce using [subrelation] afterwards. *)
End Normalize.
Ltac normalizes :=
match goal with
| [ |- Normalizes _ (respectful _ _) _ ] => class_apply @flip_arrow
| _ => class_apply @flip_atom
end.
Ltac proper_normalization :=
match goal with
| [ _ : normalization_done |- _ ] => fail 1
| [ _ : apply_subrelation |- @Proper _ ?R _ ] =>
let H := fresh "H" in
set(H:=did_normalization) ; class_apply @proper_normalizes_proper
end.
Hint Extern 1 (Normalizes _ _ _) => normalizes : typeclass_instances.
Hint Extern 6 (@Proper _ _ _) => proper_normalization
: typeclass_instances.
(** When the relation on the domain is symmetric, we can flip the relation on the codomain. Same for binary functions. *)
(** When the relation on the domain is symmetric, a predicate is compatible with [iff] as soon as it is compatible with [impl]. Same with a binary relation. *)
(** A [PartialOrder] is compatible with its underlying equivalence. *)
Instance PartialOrder_proper `(PartialOrder A eqA R) :
Proper (eqA==>eqA==>iff) R.
(** From a [PartialOrder] to the corresponding [StrictOrder]: [lt = le /\ ~eq]. If the order is total, we could also say [gt = ~le]. *)
(** From a [StrictOrder] to the corresponding [PartialOrder]: [le = lt \/ eq]. If the order is total, we could also say [ge = ~lt]. *)

Lemma StrictOrder_PreOrder
`(Equivalence A eqA, StrictOrder A R, Proper _ (eqA==>eqA==>iff) R) :
PreOrder (relation_disjunction R eqA).