Section BASIC1.
#[local] Close Scope nat_scope.
#[local] Notation "x >= y" := (y =< x) (only parsing) : type_scope.
Definition fixedpointsOf {D : Type} `{SETOID : isSetoid D} (f : D -> D) : ensemble D :=
fun x => x == f x.
#[global]
Instance fixedpointsOf_eqPropCompatible1 {D : Type} `{SETOID : isSetoid D}
: eqPropCompatible1 (@fixedpointsOf D SETOID).
Definition prefixedpointsOf {D : Type} `{PROSET : isProset D} (f : D -> D) : ensemble D :=
fun x => x >= f x.
Definition postfixedpointsOf {D : Type} `{PROSET : isProset D} (f : D -> D) : ensemble D :=
fun x => x =< f x.
Definition upperboundsOf {D : Type} `{PROSET : isProset D} (X : ensemble D) : ensemble D :=
fun u => forall x : D, forall IN : x \in X, x =< u.
Definition lowerboundsOf {D : Type} `{PROSET : isProset D} (X: ensemble D) : ensemble D :=
fun l => forall x : D, forall IN : x \in X, x >= l.
Definition is_supremum_of {D : Type} `{PROSET : isProset D} (sup_X : D) (X : ensemble D) : Prop :=
forall u : D, sup_X =< u <-> u \in upperboundsOf X.
Definition is_infimum_of {D : Type} `{PROSET : isProset D} (inf_X : D) (X : ensemble D) : Prop :=
forall l : D, inf_X >= l <-> l \in lowerboundsOf X.
#[global]
Add Parametric Morphism {D : Type} `{SETOID : isSetoid D}
: fixedpointsOf with signature (eqProp ==> eqProp)
as fixedpointsOf_compatWith_eqProp.
#[local] Hint Unfold fixedpointsOf prefixedpointsOf postfixedpointsOf upperboundsOf lowerboundsOf is_supremum_of is_infimum_of : simplication_hints.
Context {D : Type} `{PROSET : isProset D}.
#[local] Existing Instance pi_isProset.
#[global]
Instance prefixecpointsOf_eqPropCompatible1
: eqPropCompatible1 (@prefixedpointsOf D PROSET).
#[global]
Instance postfixedpointsOf_eqPropCompatible1
: eqPropCompatible1 (@postfixedpointsOf D PROSET).
#[global]
Add Parametric Morphism
: (@upperboundsOf D PROSET) with signature (eqProp ==> eqProp)
as upperboundsOf_compatWith_eqProp.
#[global]
Add Parametric Morphism
: (@lowerboundsOf D PROSET) with signature (eqProp ==> eqProp)
as lowerboundsOf_compatWith_eqProp.
#[global]
Add Parametric Morphism
: (@is_supremum_of D PROSET) with signature (eqProp ==> eqProp ==> iff)
as is_supremum_of_compatWith_eqProp.
#[global]
Add Parametric Morphism
: (@is_infimum_of D PROSET) with signature (eqProp ==> eqProp ==> iff)
as is_infimum_of_compatWith_eqProp.
#[local] Hint Resolve supremum_monotonic : poset_hints.
#[local] Hint Resolve supremum_unique : poset_hints.
#[local] Hint Resolve supremum_congruence : poset_hints.
Definition map_suprema (Xs : ensemble (ensemble D)) : ensemble D :=
Xs >>= fun X_i => fun sup_X_i => is_supremum_of sup_X_i X_i.
Proof with eauto with *.
eapply SUPREMUM... rewrite in_map_suprema_iff...
Qed.
#[local] Hint Resolve supremum_of_map_suprema_ge_suprema : poset_hints.
Proof with eauto with *.
split; intros H_supremum z; split; ii.
- rewrite E.in_unions_iff in IN. destruct IN as [X_i [x_in_X_i X_i_in_Xs]].
pose proof (SUPS_EXIST X_i X_i_in_Xs) as [sup_X_i sup_X_i_isSupremumOf_X_i].
transitivity sup_X_i.
+ eapply sup_X_i_isSupremumOf_X_i...
+ transitivity sup...
- eapply H_supremum. intros sup_X_i sup_X_i_in_MapSuprema.
rewrite in_map_suprema_iff in sup_X_i_in_MapSuprema.
destruct sup_X_i_in_MapSuprema as [X_i [X_i_in_Xs sup_X_i_isSupremumOf_X_i]].
eapply sup_X_i_isSupremumOf_X_i. ii. eapply H. rewrite E.in_unions_iff...
- rewrite in_map_suprema_iff in IN. destruct IN as [X [X_in_Xs sup_X_isSupremumOf_X]].
rename x into sup_X. enough (to_show : sup_X =< sup) by now transitivity sup.
eapply sup_X_isSupremumOf_X. ii. eapply H_supremum... rewrite E.in_unions_iff...
- eapply H_supremum. ii. rewrite E.in_unions_iff in IN.
destruct IN as [X [x_in_X X_in_Xs]]. pose proof (SUPS_EXIST X X_in_Xs) as [sup_X sup_X_isSupremumOf_X].
transitivity sup_X.
+ eapply sup_X_isSupremumOf_X...
+ eapply H; rewrite in_map_suprema_iff...
Qed.

Theorem infimum_of_upperbounds_is_supremum (sup_X : D) (X : ensemble D)
: is_supremum_of sup_X X <-> is_infimum_of sup_X (upperboundsOf X).