(* This file is copied from RamifyCoq project. *)
Require Coq.Setoids.Setoid.
Require Export Coq.Classes.Equivalence.
Require Export Coq.Sets.Ensembles.
intros.
split; intros [].
Qed.
Arguments Included {U} B C.
Arguments Same_set {U} B C.
Instance Included_proper (V: Type): Proper (Same_set ==> Same_set ==> iff) (@Included V).
Instance Intersection_proper {A}: Proper (Same_set ==> Same_set ==> Same_set) (Intersection A).
Definition app_same_set {A: Type} {P Q: Ensemble A} (H: Same_set P Q) (x: A): P x <-> Q x := proj1 (Same_set_spec A P Q) H x.
Coercion app_same_set : Same_set >-> Funclass.
(* TODO: rename it into preimage set *)
Definition respectful_set {A B: Type} (X: Ensemble B) (f: A -> B): Ensemble A := fun x => X (f x).
Inductive image_set {A B: Type}: Ensemble A -> (A -> B) -> Ensemble B :=
| image_set_intro: forall (X: Ensemble A) (f: A -> B) (x: A), X x -> image_set X f (f x).
Instance respectful_set_proper {A B: Type}: Proper (Same_set ==> pointwise_relation A (@eq B) ==> Same_set) respectful_set.
Instance image_set_proper2 {A B: Type}: Proper (Same_set ==> eq ==> Same_set) (@image_set A B).

Lemma image_Union: forall {A B: Type} (X Y: Ensemble A) (f: A -> B),
Same_set
(image_set (Union _ X Y) f)
(Union _ (image_set X f) (image_set Y f)).