Module Exports.
Coercion sort : type >-> Sortclass.
Notation eqType := type.
Notation EqMixin := Mixin.
Notation EqType T m := (@Pack T m).
Notation "[ 'eqMixin' 'of' T ]" := (class _ : mixin_of T)
(at level 0, format "[ 'eqMixin'  'of'  T ]") : form_scope.
Notation "[ 'eqType' 'of' T 'for' C ]" := (@clone T C _ idfun id)
(at level 0, format "[ 'eqType'  'of'  T  'for'  C ]") : form_scope.
Notation "[ 'eqType' 'of' T ]" := (@clone T _ _ id id)
(at level 0, format "[ 'eqType'  'of'  T ]") : form_scope.
End Exports.
End Equality.
Export Equality.Exports.
Definition eq_op T := Equality.op (Equality.class T).

(* eqE is a generic lemma that can be used to fold back recursive comparisons *)
(* after using partial evaluation to simplify comparisons on concrete         *)
(* instances. The eqE lemma can be used e.g. like so: rewrite !eqE /= -!eqE.  *)
(* For instance, with the above rewrite, n.+1 == n.+1 gets simplified to      *)
(* n == n. For this to work, we need to declare equality _mixins_             *)
(* as canonical. Canonical declarations remove the need for specific          *)
(* inverses to eqE (like eqbE, eqnE, eqseqE, etc.) for new recursive          *)
(* comparisons, but can only be used for manifest mixing with a bespoke       *)
(* comparison function, and so is incompatible with PcanEqMixin and the like  *)
(* - this is why the tree_eqMixin for GenTree.tree in library choice is not   *)
(* declared Canonical.                                                        *)
Lemma eqE T x : eq_op x = Equality.op (Equality.class T) x.