Module E.
#[universes(polymorphic=yes)]
Definition t@{u} (A : Type@{u}) : Type@{u} := A -> Prop.
#[universes(polymorphic=yes)]
Definition In@{u} {A : Type@{u}} (x : A) (X : t@{u} A) : Prop := X x.
#[universes(polymorphic=yes)]
Definition isSubsetOf@{u} {A : Type@{u}} (X1 : t@{u} A) (X2 : t@{u} A) : Prop :=
forall x, In@{u} x X1 -> In@{u} x X2.
#[local] Infix "\in" := In : type_scope.
#[local] Infix "\subseteq" := isSubsetOf : type_scope.
#[global]
Instance ensemble_isProset {A : Type} : isProset (E.t A) :=
let PROSET : isProset (E.t A) := pi_isProset (fun _ : A => Prop_isProset) in
{|
leProp := isSubsetOf;
Proset_isSetoid := {| eqProp lhs rhs := forall x, x \in lhs <-> x \in rhs; eqProp_Equivalence := PROSET.(Proset_isSetoid).(eqProp_Equivalence) |};
leProp_PreOrder := PROSET.(leProp_PreOrder);
leProp_PartialOrder := PROSET.(leProp_PartialOrder);
|}.
#[global]
Add Parametric Morphism {A : Type}
: (@In A) with signature (eq ==> eqProp ==> iff)
as In_compatWith_eqProp.

Lemma liftM2_spec {A : Type} {B : Type} {C : Type} (f : A -> B -> C) (X : E.t A) (Y : E.t B)
: forall z, z \in liftM2 f X Y <-> exists x, x \in X /\ exists y, y \in Y /\ z = f x y.