(** * Declarations of morphisms with respects to [E.eq] and [Equal] *)

#[global]
Instance In_m : Proper (E.eq==>Equal==>iff) In.#[global]
Instance Empty_m : Proper (Equal==>iff) Empty.#[global]
Instance is_empty_m : Proper (Equal==>Logic.eq) is_empty.#[global]
Instance mem_m : Proper (E.eq==>Equal==>Logic.eq) mem.#[global]
Instance singleton_m : Proper (E.eq==>Equal) singleton.#[global]
Instance add_m : Proper (E.eq==>Equal==>Equal) add.#[global]
Instance remove_m : Proper (E.eq==>Equal==>Equal) remove.#[global]
Instance union_m : Proper (Equal==>Equal==>Equal) union.#[global]
Instance inter_m : Proper (Equal==>Equal==>Equal) inter.#[global]
Instance diff_m : Proper (Equal==>Equal==>Equal) diff.#[global]
Instance Subset_m : Proper (Equal==>Equal==>iff) Subset.#[global]
Instance subset_m : Proper (Equal==>Equal==>Logic.eq) subset.#[global]
Instance equal_m : Proper (Equal==>Equal==>Logic.eq) equal.#[global]
Instance SubsetSetoid : PreOrder Subset.Definition Subset_refl := @PreOrder_Reflexive _ _ SubsetSetoid.Definition Subset_trans := @PreOrder_Transitive _ _ SubsetSetoid.#[global]
Instance In_s_m : Morphisms.Proper (E.eq ==> Subset ++> impl) In | 1.#[global]
Instance Empty_s_m : Proper (Subset-->impl) Empty.#[global]
Instance add_s_m : Proper (E.eq==>Subset++>Subset) add.#[global]
Instance remove_s_m : Proper (E.eq==>Subset++>Subset) remove.#[global]
Instance union_s_m : Proper (Subset++>Subset++>Subset) union.#[global]
Instance inter_s_m : Proper (Subset++>Subset++>Subset) inter.#[global]
Instance diff_s_m : Proper (Subset++>Subset-->Subset) diff.(* [fold], [filter], [for_all], [exists_] and [partition] requires
  some knowledge on [f] in order to be known as morphisms. *)

Generalizable Variables f.#[global]
Instance filter_equal : forall `(Proper _ (E.eq==>Logic.eq) f),
 Proper (Equal==>Equal) (filter f).#[global]
Instance filter_subset : forall `(Proper _ (E.eq==>Logic.eq) f),
 Proper (Subset==>Subset) (filter f).

(* Specifications: *)
Lemma filter_ext : forall f f', Proper (E.eq==>Logic.eq) f -> (forall x, f x = f' x) -> forall s s', s[=]s' -> filter f s [=] filter f' s'.