(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *         Copyright INRIA, CNRS and contributors             *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)
Require Export RelationClasses.
Set Implicit Arguments.
Unset Strict Implicit.
(** Structure with nothing inside. Used to force a module type T into a module via Nop <+ T. (HACK!) *)
Module Type Nop.
End Nop.
(** * Structure with just a base type [t] *)
Module Type Typ.
Parameter Inline(10) t : Type.
End Typ.
(** * Structure with an equality relation [eq] *)
Module Type HasEq (Import T:Typ).
Parameter Inline(30) eq : t -> t -> Prop.
End HasEq.
Module Type Eq := Typ <+ HasEq.
Module Type EqNotation (Import E:Eq).
Infix "==" := eq (at level 70, no associativity).
Notation "x ~= y" := (~eq x y) (at level 70, no associativity).
End EqNotation.
Module Type Eq' := Eq <+ EqNotation.
(** * Specification of the equality via the [Equivalence] type class *)
Module Type IsEq (Import E:Eq).
#[global]
Declare Instance eq_equiv : Equivalence eq.
End IsEq.
(** * Earlier specification of equality by three separate lemmas. *)
Module Type IsEqOrig (Import E:Eq').

(* Specifications: *)
Axiom eq_refl : forall x : t, x==x.
Axiom eq_sym : forall x y : t, x==y -> y==x.
Axiom eq_trans : forall x y z : t, x==y -> y==z -> x==z.
#[global]
Hint Immediate eq_sym : core.