(* Copied from RamifyCoq project *)
Require Export Coq.Relations.Relations.
Require Export Coq.Classes.Equivalence.
Require Coq.Setoids.Setoid.
Definition full_relation {A} : relation A := fun _ _ => True.
Instance same_relation_Equivalence {A}: Equivalence (same_relation A).
Instance inclusion_proper {A}: Proper (same_relation A ==> same_relation A ==> iff) (inclusion A).
Inductive compond_relation {A: Type} (R1 R2: relation A) : relation A :=
| compond_intro: forall x y z, R1 x y -> R2 y z -> compond_relation R1 R2 x z.
Instance compond_relation_proper {A: Type}: Proper (same_relation A ==> same_relation A ==> same_relation A) compond_relation.
Instance relation_conjunction_proper {A: Type}: Proper (same_relation A ==> same_relation A ==> same_relation A) relation_conjunction.
Definition respectful_relation {A B} (f: A -> B) (R: relation B): relation A := fun x y => R (f x) (f y).
Definition fst_relation {A B}: relation A -> relation (A * B) := respectful_relation (@fst A B).
Definition snd_relation {A B}: relation B -> relation (A * B) := respectful_relation (@snd A B).
Instance respectful_relation_proper {A B} (f: A -> B): Proper (same_relation _ ==> same_relation _) (respectful_relation f).
Definition partial_functional {A: Type} (R: relation A): Prop :=
forall m n n', R m n -> R m n' -> n = n'.
Class PartialFunctional {A: Type} (R: relation A): Prop :=
partial_functionality: forall m n n', R m n -> R m n' -> n = n'.
Definition functional {A: Type} (R: relation A): Prop :=
forall m, exists n, forall n', R m n' <-> n' = n.
Class Functional {A: Type} (R: relation A): Prop :=
functionality: forall m, exists n, forall n', R m n' <-> n' = n.
Definition serial {A: Type} (R: relation A): Prop :=
forall m, exists n, R m n.
Class Serial {A: Type} (R: relation A): Prop :=
seriality: forall m, exists n, R m n.

Lemma function_Functional {A: Type} {f: A -> A}: Functional (fun a => eq (f a)).