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.
(** Section SET_CONSTRUCTIONS. *)
Inductive unions {A : Type} (Xs : E.t (E.t A)) (x : A) : Prop :=
| In_unions X
(H_in : x \in X)
(H_IN : X \in Xs)
: x \in unions Xs.
#[local] Hint Constructors unions : core.
#[global] Hint Rewrite in_unions_iff : simplication_hints.
#[global]
Instance unions_eqPropCompatible1 (A : Type)
: eqPropCompatible1 (@unions A).
Inductive union {A : Type} (X1 : E.t A) (X2 : E.t A) (x : A) : Prop :=
| In_union_l
(H_inl : x \in X1)
: x \in union X1 X2
| In_union_r
(H_inr : x \in X2)
: x \in union X1 X2.
#[local] Hint Constructors union : core.
#[global] Hint Rewrite in_union_iff : simplication_hints.
#[global]
Instance union_eqPropCompatible2 (A : Type)
: eqPropCompatible2 (@union A).
Inductive empty {A : Type} : E.t A :=.
#[local] Hint Constructors empty : core.
#[global] Hint Rewrite in_empty_iff : simplication_hints.
Inductive intersection {A : Type} (X1 : E.t A) (X2 : E.t A) (x : A) : Prop :=
| In_intersection
(H_IN1 : x \in X1)
(H_IN2 : x \in X2)
: x \in intersection X1 X2.
#[local] Hint Constructors intersection : core.
#[global] Hint Rewrite in_intersection_iff : simplication_hints.
#[global]
Instance intersection_eqPropCompatible2 (A : Type)
: eqPropCompatible2 (@intersection A).
Inductive singleton {A : Type} (x : A) : E.t A :=
| In_singleton
: x \in singleton x.
#[local] Hint Constructors singleton : core.
#[global] Hint Rewrite in_singleton_iff : simplication_hints.
Inductive image {A : Type} {B : Type} (f : A -> B) (X : E.t A) (y : B) : Prop :=
| In_image x
(IMAGE : y = f x)
(H_IN : x \in X)
: y \in image f X.
#[local] Hint Constructors image : core.
#[global] Hint Rewrite in_image_iff : simplication_hints.
#[global]
Add Parametric Morphism {A : Type} {B : Type}
: (@image A B) with signature (eqProp (isSetoid := pi_isSetoid (fun _ => mkSetoid_from_eq)) ==> eqProp ==> eqProp)
as image_compatWith_eqProp.
Inductive preimage {A : Type} {B : Type} (f : A -> B) (Y : E.t B) (x : A) : Prop :=
| In_preimage y
(IMAGE : y = f x)
(H_IN : y \in Y)
: x \in preimage f Y.
#[local] Hint Constructors preimage : core.
#[global] Hint Rewrite in_preimage_iff : simplication_hints.
#[global]
Add Parametric Morphism {A : Type} {B : Type}
: (@preimage A B) with signature (eqProp (isSetoid := pi_isSetoid (fun _ => mkSetoid_from_eq)) ==> eqProp ==> eqProp)
as preimage_compatWith_eqProp.
#[universes(polymorphic=yes)]
Definition fromList@{u} {A : Type@{u}} (xs : list A) : E.t@{u} A :=
fun x => List.In x xs.
#[global] Hint Unfold fromList : simplication_hints.
#[universes(polymorphic=yes)]
Definition full@{u} {A : Type@{u}} : E.t@{u} A :=
fun x => True.
#[global] Hint Unfold full : simplication_hints.
#[universes(polymorphic=yes)]
Definition insert@{u} {A : Type@{u}} (x1 : A) (X2 : E.t@{u} A) : E.t@{u} A :=
fun x => x = x1 \/ x \in X2.
#[global] Hint Unfold insert : simplication_hints.
#[global] Hint Rewrite in_insert_iff : simplication_hints.
#[global]
Add Parametric Morphism {A : Type}
: (@insert A) with signature (eq ==> eqProp ==> eqProp)
as insert_compatWith_eqProp.
#[universes(polymorphic=yes)]
Definition complement@{u} {A : Type@{u}} (X : E.t@{u} A) : E.t@{u} A :=
fun x => ~ x \in X.
#[global] Hint Unfold complement : simplication_hints.
#[global] Hint Rewrite in_complement_iff : simplication_hints.
#[global]
Add Parametric Morphism {A : Type}
: (@complement A) with signature (eqProp ==> eqProp)
as complement_compatWith_eqProp.
#[universes(polymorphic=yes)]
Definition delete@{u} {A : Type@{u}} (x1 : A) (X2 : E.t@{u} A) : E.t@{u} A :=
fun x => x <> x1 /\ x \in X2.
#[global] Hint Unfold delete : simplication_hints.
#[global] Hint Rewrite in_delete_iff : simplication_hints.
#[global]
Add Parametric Morphism {A : Type}
: (@delete A) with signature (eq ==> eqProp ==> eqProp)
as delete_compatWith_eqProp.
#[universes(polymorphic=yes)]
Definition intersections@{u} {A : Type@{u}} (Xs : E.t@{u} (E.t@{u} A)) : E.t@{u} A :=
fun x => forall X, X \in Xs -> x \in X.
#[global] Hint Unfold intersections : simplication_hints.
#[global] Hint Rewrite in_intersections_iff : simplication_hints.
#[global]
Add Parametric Morphism {A : Type}
: (@intersections A) with signature (eqProp ==> eqProp)
as intersections_compatWith_eqProp.
(** End SET_CONSTRUCTIONS. *)
Ltac unfold_E := repeat
match goal with
| [ H : context[ E.In _ (fun _ => _) ] |- _ ] => unfold E.In in H
| [ |- context[ E.In _ (fun _ => _) ] ] => unfold E.In
| [ H : context[ E.isSubsetOf _ (fun _ => _) ] |- _ ] => unfold E.isSubsetOf in H
| [ |- context[ E.isSubsetOf _ (fun _ => _) ] ] => unfold E.isSubsetOf
end.
#[global]
Instance subseteq_PreOrder {A : Type}
: PreOrder (@E.isSubsetOf A).
End E.
Notation ensemble := E.t.
#[local] Infix "\in" := E.In : type_scope.
#[local] Infix "\subseteq" := E.isSubsetOf : type_scope.

Lemma unfold_ensemble_eqProp (A : Type) (X1 : ensemble A) (X2 : ensemble A)
: X1 == X2 <-> (X1 \subseteq X2 /\ X2 \subseteq X1).