# Least upper bounds in posets
```agda
module order-theory.least-upper-bounds-posets where
```
<details><summary>Imports</summary>
```agda
open import foundation.action-on-identifications-functions
open import foundation.dependent-pair-types
open import foundation.identity-types
open import foundation.logical-equivalences
open import foundation.propositions
open import foundation.subtypes
open import foundation.universe-levels
open import order-theory.posets
open import order-theory.upper-bounds-posets
```
</details>
## Idea
A **least upper bound** of `a` and `b` in a poset `P` is an element `x` such
that the logical equivalence
```text
((a ≤ y) ∧ (b ≤ y)) ⇔ (x ≤ y)
```
holds for every element `y` in `P`. Similarly, a **least upper bound** of a
family `a : I → P` of elements of `P` is an element `x` of `P` such that the
logical equivalence
```text
(∀ᵢ (aᵢ ≤ y)) ⇔ (x ≤ y)
```
holds for every element `y` in `P`.
## Definitions
### The predicate of being a least binary upper bound of two elements in a poset
```agda
module _
{l1 l2 : Level} (P : Poset l1 l2) (a b : type-Poset P)
where
is-least-binary-upper-bound-Poset-Prop : type-Poset P → Prop (l1 ⊔ l2)
is-least-binary-upper-bound-Poset-Prop x =
Π-Prop
( type-Poset P)
( λ y →
iff-Prop
( is-binary-upper-bound-Poset-Prop P a b y)
( leq-Poset-Prop P x y))
is-least-binary-upper-bound-Poset : type-Poset P → UU (l1 ⊔ l2)
is-least-binary-upper-bound-Poset x =
type-Prop (is-least-binary-upper-bound-Poset-Prop x)
is-prop-is-least-binary-upper-bound-Poset :
(x : type-Poset P) →
is-prop (is-least-binary-upper-bound-Poset x)
is-prop-is-least-binary-upper-bound-Poset x =
is-prop-type-Prop (is-least-binary-upper-bound-Poset-Prop x)
module _
{l1 l2 : Level} (P : Poset l1 l2) {a b : type-Poset P}
where
forward-implication-is-least-binary-upper-bound-Poset :
{x y : type-Poset P} →
is-least-binary-upper-bound-Poset P a b x →
is-binary-upper-bound-Poset P a b y → leq-Poset P x y
forward-implication-is-least-binary-upper-bound-Poset {x} {y} H =
forward-implication (H y)
backward-implication-is-least-binary-upper-bound-Poset :
{x y : type-Poset P} →
is-least-binary-upper-bound-Poset P a b x →
leq-Poset P x y → is-binary-upper-bound-Poset P a b y
backward-implication-is-least-binary-upper-bound-Poset {x} {y} H =
backward-implication (H y)
prove-is-least-binary-upper-bound-Poset :
{x : type-Poset P} →
is-binary-upper-bound-Poset P a b x →
( (y : type-Poset P) →
is-binary-upper-bound-Poset P a b y → leq-Poset P x y) →
is-least-binary-upper-bound-Poset P a b x
pr1 (prove-is-least-binary-upper-bound-Poset H K y) L = K y L
pr2 (prove-is-least-binary-upper-bound-Poset H K y) L =
is-binary-upper-bound-leq-Poset P H L
is-binary-upper-bound-is-least-binary-upper-bound-Poset :
{x : type-Poset P} →
is-least-binary-upper-bound-Poset P a b x →
is-binary-upper-bound-Poset P a b x
is-binary-upper-bound-is-least-binary-upper-bound-Poset {x} H =
backward-implication-is-least-binary-upper-bound-Poset H
( refl-leq-Poset P x)
leq-left-is-least-binary-upper-bound-Poset :
{x : type-Poset P} →
is-least-binary-upper-bound-Poset P a b x →
leq-Poset P a x
leq-left-is-least-binary-upper-bound-Poset H =
leq-left-is-binary-upper-bound-Poset P
( is-binary-upper-bound-is-least-binary-upper-bound-Poset H)
leq-right-is-least-binary-upper-bound-Poset :
{x : type-Poset P} →
is-least-binary-upper-bound-Poset P a b x →
leq-Poset P b x
leq-right-is-least-binary-upper-bound-Poset H =
leq-right-is-binary-upper-bound-Poset P
( is-binary-upper-bound-is-least-binary-upper-bound-Poset H)
```
### The proposition that two elements have a least upper bound
```agda
module _
{l1 l2 : Level} (P : Poset l1 l2) (a b : type-Poset P)
where
has-least-binary-upper-bound-Poset : UU (l1 ⊔ l2)
has-least-binary-upper-bound-Poset =
Σ (type-Poset P) (is-least-binary-upper-bound-Poset P a b)
all-elements-equal-has-least-binary-upper-bound-Poset :
all-elements-equal has-least-binary-upper-bound-Poset
all-elements-equal-has-least-binary-upper-bound-Poset
(pair u H) (pair v K) =
eq-type-subtype
( is-least-binary-upper-bound-Poset-Prop P a b)
( antisymmetric-leq-Poset P u v
( forward-implication-is-least-binary-upper-bound-Poset P H
( is-binary-upper-bound-is-least-binary-upper-bound-Poset P K))
( forward-implication-is-least-binary-upper-bound-Poset P K
( is-binary-upper-bound-is-least-binary-upper-bound-Poset P H)))
is-prop-has-least-binary-upper-bound-Poset :
is-prop has-least-binary-upper-bound-Poset
is-prop-has-least-binary-upper-bound-Poset =
is-prop-all-elements-equal
all-elements-equal-has-least-binary-upper-bound-Poset
has-least-binary-upper-bound-Poset-Prop : Prop (l1 ⊔ l2)
pr1 has-least-binary-upper-bound-Poset-Prop =
has-least-binary-upper-bound-Poset
pr2 has-least-binary-upper-bound-Poset-Prop =
is-prop-has-least-binary-upper-bound-Poset
module _
{l1 l2 : Level} (P : Poset l1 l2) {a b : type-Poset P}
where
eq-is-least-binary-upper-bound-Poset :
{x y : type-Poset P} →
is-least-binary-upper-bound-Poset P a b x →
is-least-binary-upper-bound-Poset P a b y →
x = y
eq-is-least-binary-upper-bound-Poset {x} {y} H K =
ap
( pr1)
( all-elements-equal-has-least-binary-upper-bound-Poset P a b
( x , H)
( y , K))
```
### Least upper bounds of families of elements
```agda
module _
{l1 l2 l3 : Level} (P : Poset l1 l2) {I : UU l3} (a : I → type-Poset P)
where
is-least-upper-bound-family-of-elements-Poset-Prop :
type-Poset P → Prop (l1 ⊔ l2 ⊔ l3)
is-least-upper-bound-family-of-elements-Poset-Prop x =
Π-Prop
( type-Poset P)
( λ y →
iff-Prop
( Π-Prop I (λ i → leq-Poset-Prop P (a i) y))
( leq-Poset-Prop P x y))
is-least-upper-bound-family-of-elements-Poset :
type-Poset P → UU (l1 ⊔ l2 ⊔ l3)
is-least-upper-bound-family-of-elements-Poset z =
type-Prop (is-least-upper-bound-family-of-elements-Poset-Prop z)
is-prop-is-least-upper-bound-family-of-elements-Poset :
(z : type-Poset P) →
is-prop (is-least-upper-bound-family-of-elements-Poset z)
is-prop-is-least-upper-bound-family-of-elements-Poset z =
is-prop-type-Prop (is-least-upper-bound-family-of-elements-Poset-Prop z)
module _
{l1 l2 l3 : Level} (P : Poset l1 l2) {I : UU l3} {a : I → type-Poset P}
where
forward-implication-is-least-upper-bound-family-of-elements-Poset :
{x y : type-Poset P} →
is-least-upper-bound-family-of-elements-Poset P a x →
is-upper-bound-family-of-elements-Poset P a y → leq-Poset P x y
forward-implication-is-least-upper-bound-family-of-elements-Poset {x} {y} H =
forward-implication (H y)
backward-implication-is-least-upper-bound-family-of-elements-Poset :
{x y : type-Poset P} →
is-least-upper-bound-family-of-elements-Poset P a x →
leq-Poset P x y → is-upper-bound-family-of-elements-Poset P a y
backward-implication-is-least-upper-bound-family-of-elements-Poset {x} {y} H =
backward-implication (H y)
is-upper-bound-is-least-upper-bound-family-of-elements-Poset :
{x : type-Poset P} →
is-least-upper-bound-family-of-elements-Poset P a x →
is-upper-bound-family-of-elements-Poset P a x
is-upper-bound-is-least-upper-bound-family-of-elements-Poset {x} H =
backward-implication-is-least-upper-bound-family-of-elements-Poset H
( refl-leq-Poset P x)
```
### The proposition that a family of elements has a least upper bound
```agda
module _
{l1 l2 l3 : Level} (P : Poset l1 l2) {I : UU l3} (a : I → type-Poset P)
where
has-least-upper-bound-family-of-elements-Poset : UU (l1 ⊔ l2 ⊔ l3)
has-least-upper-bound-family-of-elements-Poset =
Σ (type-Poset P) (is-least-upper-bound-family-of-elements-Poset P a)
all-elements-equal-has-least-upper-bound-family-of-elements-Poset :
all-elements-equal has-least-upper-bound-family-of-elements-Poset
all-elements-equal-has-least-upper-bound-family-of-elements-Poset
( x , H) (y , K) =
eq-type-subtype
( is-least-upper-bound-family-of-elements-Poset-Prop P a)
( antisymmetric-leq-Poset P x y
( forward-implication-is-least-upper-bound-family-of-elements-Poset
( P)
( H)
( is-upper-bound-is-least-upper-bound-family-of-elements-Poset
( P)
( K)))
( forward-implication-is-least-upper-bound-family-of-elements-Poset
( P)
( K)
( is-upper-bound-is-least-upper-bound-family-of-elements-Poset
( P)
( H))))
is-prop-has-least-upper-bound-family-of-elements-Poset :
is-prop has-least-upper-bound-family-of-elements-Poset
is-prop-has-least-upper-bound-family-of-elements-Poset =
is-prop-all-elements-equal
all-elements-equal-has-least-upper-bound-family-of-elements-Poset
has-least-upper-bound-family-of-elements-Poset-Prop : Prop (l1 ⊔ l2 ⊔ l3)
pr1 has-least-upper-bound-family-of-elements-Poset-Prop =
has-least-upper-bound-family-of-elements-Poset
pr2 has-least-upper-bound-family-of-elements-Poset-Prop =
is-prop-has-least-upper-bound-family-of-elements-Poset
module _
{l1 l2 l3 : Level} (P : Poset l1 l2) {I : UU l3} {a : I → type-Poset P}
where
eq-is-least-upper-bound-family-of-elements-Poset :
{x y : type-Poset P} →
is-least-upper-bound-family-of-elements-Poset P a x →
is-least-upper-bound-family-of-elements-Poset P a y →
x = y
eq-is-least-upper-bound-family-of-elements-Poset {x} {y} H K =
ap
( pr1)
( all-elements-equal-has-least-upper-bound-family-of-elements-Poset
( P)
( a)
( x , H)
( y , K))
```