(* Aliases *)

Notation sym_eq := eq_sym (only parsing).Notation trans_eq := eq_trans (only parsing).Notation sym_not_eq := not_eq_sym (only parsing).Notation refl_equal := eq_refl (only parsing).Notation sym_equal := eq_sym (only parsing).Notation trans_equal := eq_trans (only parsing).Notation sym_not_equal := not_eq_sym (only parsing).(** Basic definitions about relations and properties *)

Definition subrelation (A B : Type) (R R' : A->B->Prop) :=
  forall x y, R x y -> R' x y.Definition unique (A : Type) (P : A->Prop) (x:A) :=
  P x /\ forall (x':A), P x' -> x=x'.Definition uniqueness (A:Type) (P:A->Prop) := forall x y, P x -> P y -> x = y.(** Unique existence *)

Notation "'exists' ! x .. y , p" :=
  (ex (unique (fun x => .. (ex (unique (fun y => p))) ..)))
  (at level 200, x binder, right associativity,
   format "'[' 'exists'  !  '/  ' x  ..  y ,  '/  ' p ']'")
  : type_scope.

(* Specifications: *)
Lemma unique_existence : forall (A:Type) (P:A->Prop), ((exists x, P x) /\ uniqueness P) <-> (exists! x, P x).
Lemma forall_exists_unique_domain_coincide : forall A (P:A->Prop), (exists! x, P x) -> forall Q:A->Prop, (forall x, P x -> Q x) <-> (exists x, P x /\ Q x).
Lemma forall_exists_coincide_unique_domain : forall A (P:A->Prop), (forall Q:A->Prop, (forall x, P x -> Q x) <-> (exists x, P x /\ Q x)) -> (exists! x, P x).