Library Waterproof.Notations.Sets
Require Import Sets.Ensembles.
Require Import Notations.Common.
Set Auto Template Polymorphism.
Definition subset (X : Type) := X -> Prop.
Definition as_subset (X : Type) (Q : X -> Prop) := Q.
Definition subset_type {X : Type} (A : subset X) := X.
Definition subset_in {X : Type} (A : subset X) (x : X) := A x.
Declare Scope ensemble_scope.
Notation "'set_of_subsets' U" :=
(Ensemble (Ensemble U)) (at level 50).
Definition empty {U} := Empty_set U.
Definition full {U} := Full_set U.
Notation "∅" :=
(empty).
Notation "'Ω'" :=
(full) (at level 0).
Notation "A ∩ B" :=
(Intersection _ A B) (at level 45).
Notation "A ∪ B" :=
(Union _ A B) (at level 45).
Notation "A \ B" :=
(Setminus _ A B) (at level 45).
Notation "x ∉ A" :=
(~ In _ A x) (at level 50).
Notation "A ⊂ B" :=
(Included _ A B) (at level 45).
Notation "A 'and' B 'are' 'disjoint'" :=
(Disjoint _ A B) (at level 50).
Notation "{ x : T | P }" :=
(fun (x : T) ↦ P) (x at level 99) : ensemble_scope.
Declare Scope subset_scope.
Definition conv (T : Type) : T -> Prop := (fun x : T => True).
Coercion conv : Sortclass >-> Funclass.
Definition seal {T : Type} (Q : T -> Prop) (y : T) := Q y.
Require Import Coq.Reals.Reals.
Class ge_type (carrier : Type) := {
ge_op : carrier -> carrier -> Prop
}.
#[export] Instance nat_ge_type : ge_type nat :=
{ge_op := fun y z => ge z y}.
#[export] Instance R_ge_type : ge_type R :=
{ge_op := fun y z => Rge z y}.
Class gt_type (carrier : Type) := {
gt_op : carrier -> carrier -> Prop
}.
#[export] Instance nat_gt_type : gt_type nat :=
{gt_op := fun y z => gt z y}.
#[export] Instance R_gt_type : gt_type R :=
{gt_op := fun y z => Rgt z y}.
Class le_type (carrier : Type) := {
le_op : carrier -> carrier -> Prop
}.
#[export] Instance nat_le_type : le_type nat :=
{le_op := fun y z => le z y}.
#[export] Instance R_le_type : le_type R :=
{le_op := fun y z => Rle z y}.
Class lt_type (carrier : Type) := {
lt_op : carrier -> carrier -> Prop
}.
#[export] Instance nat_lt_type : lt_type nat :=
{lt_op := fun y z => lt z y}.
#[export] Instance R_lt_type : lt_type R :=
{lt_op := fun y z => Rlt z y}.
Declare Scope pred_for_subset_scope.
Delimit Scope pred_for_subset_scope with pfs.
Notation "∈ A" := (subset_in A) (at level 69, A at next level) : pred_for_subset_scope.
Notation "< y" := (lt_op y) (at level 69, y at next level) : pred_for_subset_scope.
Notation "≤ y" := (le_op y) (at level 69, y at next level) : pred_for_subset_scope.
Notation "> y" := (gt_op y) (at level 69, y at next level) : pred_for_subset_scope.
Notation "≥ y" := (ge_op y) (at level 69, y at next level) : pred_for_subset_scope.
Notation "x ∈ A" := (subset_in A x) (at level 70, no associativity) : type_scope.
Notation "x ≥ y" := (ge_op y x) (at level 70, no associativity, only printing) : subset_scope.
Notation "x > y" := (gt_op y x) (at level 70, no associativity, only printing) : subset_scope.
Notation "x ≤ y" := (le_op y x) (at level 70, no associativity, only printing) : subset_scope.
Notation "x < y" := (lt_op y x) (at level 70, no associativity, only printing) : subset_scope.
Notation "∃ x , P" := (exists x, P)
(at level 200, x binder, right associativity) : type_scope.
Notation "'there' 'exists' x , P" := (exists x, P)
(at level 200, x binder, right associativity, only parsing) : type_scope.
Notation "∀ x , P" := (forall x, P)
(at level 200, x binder, right associativity) : type_scope.
Notation "'for' 'all' x , P" := (forall x, P)
(at level 200, x binder, right associativity, only parsing) : type_scope.
Notation "'∃' x Q , P" :=
(seal (fun z : subset_type (Q)%pfs -> Prop => exists x : (subset_type (Q)%pfs), z x /\ P) Q%pfs)
(at level 200, x binder, right associativity) : subset_scope.
Notation "'there' 'exists' x Q , P" :=
(seal (fun z : subset_type (Q)%pfs -> Prop => exists x : (subset_type (Q)%pfs), z x /\ P) Q%pfs)
(at level 200, x binder, right associativity, only parsing) : subset_scope.
Notation "'∀' x Q , P" :=
(seal (fun z : subset_type (Q)%pfs -> Prop => forall x : (subset_type (Q)%pfs), z x -> P) Q%pfs)
(at level 200, x binder, right associativity) : subset_scope.
Notation "'for' 'all' x Q , P" :=
(seal (fun z : subset_type (Q)%pfs -> Prop => forall x : (subset_type (Q)%pfs), z x -> P) Q%pfs)
(at level 200, x binder, right associativity, only parsing) : subset_scope.
Lemma mem_subset_full_set {T : Type} (x : T) : (x ∈ T).
Proof.
unfold subset_in, conv, as_subset; exact I.
Qed.
Open Scope subset_scope.
Lemma forall_forall_in_iff (T : Type) (Q : T -> Prop) :
(∀ x ∈ T, Q x) <-> ∀ x, Q x.
Proof.
unfold seal, subset_in, conv, as_subset.
split; auto.
Qed.
Lemma exists_exists_in_iff (T : Type) (Q : T -> Prop) :
(∃ x ∈ T, Q x) <-> ∃ x, Q x.
Proof.
unfold seal, subset_in, conv, as_subset.
split.
* intro H. destruct H as [x [wx1 wx2]].
exists x. exact wx2.
* intro H. destruct H as [x wx].
exists x. auto.
Qed.
Close Scope subset_scope.
Close Scope R_scope.