---
title:          Properties of compactness
author:         Ayberk Tosun
date-started:   2024-07-19
date-completed: 2024-07-31
dates-updated:  [2024-09-05]
---

We collect properties related to compactness in locale theory in this module.
This includes the equivalences to two alternative definitions of the notion of
compactness, which we denote `is-compact-open'` and `is-compact-open''`.

\begin{code}[hide]

{-# OPTIONS --safe --without-K #-}

open import MLTT.Spartan hiding (J)
open import UF.Base
open import UF.Classifiers
open import UF.FunExt
open import UF.PropTrunc
open import UF.Sets
open import UF.Subsingletons
open import UF.Subsingletons-FunExt
open import UF.Subsingletons-Properties
open import UF.SubtypeClassifier

module Locales.Compactness.Properties
        (pt : propositional-truncations-exist)
        (fe : Fun-Ext)
        (pe : Prop-Ext)
       where

open import Fin.Kuratowski pt
open import Fin.Type
open import Locales.Compactness.Definition pt fe
open import Locales.Frame pt fe renaming (⟨_⟩ to ⟨_⟩∙) hiding (∅)
open import Locales.WayBelowRelation.Definition  pt fe
open import MLTT.List using (member; []; _∷_; List; in-head; in-tail; length)
open import MLTT.List-Properties
open import Slice.Family
open import Taboos.FiniteSubsetTaboo pt fe
open import UF.Equiv hiding (_■)
open import UF.EquivalenceExamples
open import UF.ImageAndSurjection pt
open import UF.Logic
open import UF.Powerset-Fin pt
open import UF.Powerset-MultiUniverse
open import UF.Sets-Properties
open import Notation.UnderlyingType

open AllCombinators pt fe
open Locale
open PropositionalTruncation pt

\end{code}

\section{Preliminaries}

We define a frame instance of the `Underlying-Type` typeclass to avoid name
clashes.

\begin{code}

instance
 underlying-type-of-frame : Underlying-Type (Frame 𝓤 𝓥 𝓦) (𝓤  ̇)
 ⟨_⟩ {{underlying-type-of-frame}} (A , _) = A

\end{code}

Given a family `S`, we denote the type of its subfamilies by `SubFam S`.

\begin{code}

SubFam : {A : 𝓤  ̇} {𝓦 : Universe} → Fam 𝓦 A → 𝓦 ⁺  ̇
SubFam {_} {A} {𝓦} (I , α) = Σ J ꞉ 𝓦  ̇ , (J → I)

\end{code}

Given any list, the type of elements that fall in the list is a
Kuratowski-finite type.

\begin{code}

list-members-is-Kuratowski-finite : {X : 𝓤  ̇}
                                  → (xs : List X)
                                  → is-Kuratowski-finite
                                     (Σ x ꞉ X , ∥ member x xs ∥)
list-members-is-Kuratowski-finite {𝓤} {A} xs =
 ∣ length xs , nth xs , nth-is-surjection xs ∣
  where
   open list-indexing pt

\end{code}

TODO: The function `nth` above should be placed in a more appropriate module.

\section{Alternative definition of compactness}

Compactness could have been alternatively defined as:

\begin{code}

is-compact-open' : (X : Locale 𝓤 𝓥 𝓦) → ⟨ 𝒪 X ⟩ → Ω (𝓤 ⊔ 𝓥 ⊔ 𝓦 ⁺)
is-compact-open' {𝓤} {𝓥} {𝓦} X U =
 Ɐ S ꞉ Fam 𝓦 ⟨ 𝒪 X ⟩ ,
  U ≤ (⋁[ 𝒪 X ] S) ⇒
   (Ǝ (J , h) ꞉ SubFam S , is-Kuratowski-finite J
                         × (U ≤ (⋁[ 𝒪 X ] ⁅  S [ h j ] ∣ j ∶ J ⁆)) holds)
   where
    open PosetNotation (poset-of (𝒪 X))

\end{code}

This is much closer to the “every cover has a finite subcover” definition from
point-set topology.

It is easy to show that this implies the standard definition of compactness, but
we need a bit of preparation first.

Given a family `S`, we denote by `family-of-lists S` the family of families
of lists of `S`.

\begin{code}

module some-lemmas-on-directification (F : Frame 𝓤 𝓥 𝓦) where

 family-of-lists : Fam 𝓦 ⟨ F ⟩ → Fam 𝓦 (Fam 𝓦 ⟨ F ⟩)
 family-of-lists S = List (index S) , h
  where
   h : List (index S) → Fam 𝓦 ⟨ F ⟩
   h is = (Σ i ꞉ index S , ∥ member i is ∥) , S [_] ∘ pr₁

\end{code}

Using this, we can give an alternative definition of the directification of
a family:

\begin{code}

 directify₂ : Fam 𝓦 ⟨ F ⟩ → Fam 𝓦 ⟨ F ⟩
 directify₂ S = ⁅ ⋁[ F ] T ∣ T ε family-of-lists S ⁆

\end{code}

The function `directify₂` is equal to `directify` as expected.

\begin{code}

 directify₂-is-equal-to-directify
  : (S : Fam 𝓦 ⟨ F ⟩)
  → directify₂ S [_] ∼ directify F S [_]

 directify₂-is-equal-to-directify S [] =
  directify₂ S [ [] ]   ＝⟨ Ⅰ    ⟩
  𝟎[ F ]                ＝⟨ refl ⟩
  directify F S [ [] ]   ∎
   where

    † : (directify₂ S [ [] ] ≤[ poset-of F ] 𝟎[ F ]) holds
    † = ⋁[ F ]-least
         (family-of-lists S [ [] ])
         (𝟎[ F ] , λ { (_ , μ) → 𝟘-elim (∥∥-rec 𝟘-is-prop not-in-empty-list μ) })

    Ⅰ = only-𝟎-is-below-𝟎 F (directify₂ S [ [] ]) †

 directify₂-is-equal-to-directify S (i ∷ is) =
  directify₂ S [ i ∷ is ]                ＝⟨ Ⅰ    ⟩
  S [ i ] ∨[ F ] directify₂ S [ is ]     ＝⟨ Ⅱ    ⟩
  S [ i ] ∨[ F ] directify  F S [ is ]   ＝⟨ refl ⟩
  directify F S [ i ∷ is ]               ∎
   where
    open PosetNotation (poset-of F)
    open PosetReasoning (poset-of F)
    open Joins (λ x y → x ≤[ poset-of F ] y)

    IH = directify₂-is-equal-to-directify S is

    β : ((S [ i ] ∨[ F ] directify₂ S [ is ])
          is-an-upper-bound-of
         (family-of-lists S [ i ∷ is ]))
         holds
    β (j , ∣μ∣) =
     ∥∥-rec (holds-is-prop (S [ j ] ≤ (S [ i ] ∨[ F ] directify₂ S [ is ]))) † ∣μ∣
      where
       † : member j (i ∷ is)
         → (S [ j ] ≤ (S [ i ] ∨[ F ] directify₂ S [ is ]))
            holds
       † in-head     = ∨[ F ]-upper₁ (S [ j ]) (directify₂ S [ is ])
       † (in-tail μ) =
        family-of-lists S [ i ∷ is ] [ j , μ′ ]  ＝⟨ refl ⟩ₚ
        S [ j ]                                  ≤⟨ Ⅰ     ⟩
        directify₂ S [ is ]                      ≤⟨ Ⅱ     ⟩
        S [ i ] ∨[ F ] directify₂ S [ is ]       ■
         where
          μ′ : ∥ member j (i ∷ is) ∥
          μ′ = ∣ in-tail μ ∣

          Ⅰ = ⋁[ F ]-upper (family-of-lists S [ is ]) (j , ∣ μ ∣)
          Ⅱ = ∨[ F ]-upper₂ (S [ i ]) (directify₂ S [ is ])

    γ : ((directify₂ S [ i ∷ is ])
          is-an-upper-bound-of
         (family-of-lists S [ is ]))
        holds
    γ (k , μ) = ∥∥-rec (holds-is-prop (S [ k ] ≤ directify₂ S [ i ∷ is ])) ♢ μ
     where
      ♢ : member k is → (S [ k ] ≤ directify₂ S [ i ∷ is ]) holds
      ♢ μ = ⋁[ F ]-upper (family-of-lists S [ i ∷ is ]) (k , ∣ in-tail μ ∣)

    † : (directify₂ S [ i ∷ is ] ≤ (S [ i ] ∨[ F ] directify₂ S [ is ]))
         holds
    † = ⋁[ F ]-least
         (family-of-lists S [ i ∷ is ])
         ((S [ i ] ∨[ F ] directify₂ S [ is ]) , β)

    ‡ : ((S [ i ] ∨[ F ] directify₂ S [ is ]) ≤ directify₂ S [ i ∷ is ])
         holds
    ‡ = ∨[ F ]-least ‡₁ ‡₂
     where
      ‡₁ : (S [ i ] ≤ directify₂ S [ i ∷ is ]) holds
      ‡₁ = ⋁[ F ]-upper (family-of-lists S [ i ∷ is ]) (i , ∣ in-head ∣)

      ‡₂ : (directify₂ S [ is ] ≤ directify₂ S [ i ∷ is ]) holds
      ‡₂ = ⋁[ F ]-least
            (family-of-lists S [ is ])
            (directify₂ S [ i ∷ is ] , γ)

    Ⅰ  = ≤-is-antisymmetric (poset-of F) † ‡
    Ⅱ  = ap (λ - → S [ i ] ∨[ F ] -) IH

\end{code}

Using the equality between `directify` and `directify₂`, we can now easily show
how to obtain a subcover, from which it follows that `is-compact` implies
`is-compact'`.

\begin{code}

module characterization-of-compactness₁ (X : Locale 𝓤 𝓥 𝓦) where

 open PosetNotation (poset-of (𝒪 X))
 open PosetReasoning (poset-of (𝒪 X))
 open some-lemmas-on-directification (𝒪 X)

 finite-subcover-through-directification
  : (U : ⟨ 𝒪 X ⟩)
  → (S : Fam 𝓦 ⟨ 𝒪 X ⟩)
  → (is : List (index S))
  → (U ≤ directify (𝒪 X) S [ is ]) holds
  → Σ (J , β) ꞉ SubFam S ,
     is-Kuratowski-finite J × (U ≤ (⋁[ 𝒪 X ] ⁅  S [ β j ] ∣ j ∶ J ⁆)) holds
 finite-subcover-through-directification U S is p = T , 𝕗 , q
  where
   T : SubFam S
   T = (Σ i ꞉ index S , ∥ member i is ∥) , pr₁

   𝕗 : is-Kuratowski-finite (index T)
   𝕗 = list-members-is-Kuratowski-finite is

   † = directify₂-is-equal-to-directify S is ⁻¹

   q : (U ≤ (⋁[ 𝒪 X ] ⁅ S [ T [ x ] ] ∣ x ∶ index T ⁆)) holds
   q = U                                          ≤⟨ p     ⟩
       directify (𝒪 X) S [ is ]                   ＝⟨ †    ⟩ₚ
       directify₂ S [ is ]                        ＝⟨ refl ⟩ₚ
       ⋁[ 𝒪 X ] ⁅ S [ T [ x ] ] ∣ x ∶ index T ⁆   ■

\end{code}

It follows from this that `is-compact-open` implies `is-compact-open'`.

\begin{code}

 compact-open-implies-compact-open' : (U : ⟨ 𝒪 X ⟩)
                                    → is-compact-open  X U holds
                                    → is-compact-open' X U holds
 compact-open-implies-compact-open' U κ S q = ∥∥-functor † (κ S↑ δ p)
  where
   open JoinNotation (join-of (𝒪 X))

   Xₚ = poset-of (𝒪 X)

   S↑ : Fam 𝓦 ⟨ 𝒪 X ⟩
   S↑ = directify (𝒪 X) S

   δ : is-directed (𝒪 X) (directify (𝒪 X) S) holds
   δ = directify-is-directed (𝒪 X) S

   p : (U ≤[ Xₚ ] (⋁[ 𝒪 X ] S↑)) holds
   p = U             ≤⟨ Ⅰ ⟩
       ⋁[ 𝒪 X ] S    ＝⟨ Ⅱ ⟩ₚ
       ⋁[ 𝒪 X ] S↑   ■
        where
         Ⅰ = q
         Ⅱ = directify-preserves-joins (𝒪 X) S

   † : Σ is ꞉ index S↑ , (U ≤[ Xₚ ] S↑ [ is ]) holds
     → Σ (J , β) ꞉ SubFam S , is-Kuratowski-finite J
                            × (U ≤[ Xₚ ] (⋁⟨ j ∶ J ⟩ S [ β j ])) holds
   † = uncurry (finite-subcover-through-directification U S)

\end{code}

We now prove the converse which is a bit more difficult. We start with some
preparation.

Given a subset `P : ⟨ 𝒪 X ⟩ → Ω` and a family `S : Fam 𝓤 ⟨ 𝒪 X ⟩`, the type
`Upper-Bound-Data P S` is the type of indices `i` of `S` such that `S [ i ]` is
an upper bound of the subset `P`.

\begin{code}

module characterization-of-compactness₂ (X : Locale (𝓤 ⁺) 𝓤 𝓤) where

 open some-lemmas-on-directification (𝒪 X)
 open PosetNotation (poset-of (𝒪 X))
 open PosetReasoning (poset-of (𝒪 X))
 open Joins (λ x y → x ≤ y)

 Upper-Bound-Data : 𝓟 {𝓣} ⟨ 𝒪 X ⟩ → Fam 𝓤 ⟨ 𝒪 X ⟩ → 𝓤 ⁺ ⊔ 𝓣  ̇
 Upper-Bound-Data P S =
  Σ i ꞉ index S , (Ɐ x ꞉ ⟨ 𝒪 X ⟩ , P x ⇒ x ≤ S [ i ]) holds

\end{code}

We now define the truncated version of this which we denote `has-upper-bound-in`:

\begin{code}

 has-upper-bound-in :  𝓟 {𝓣} ⟨ 𝒪 X ⟩ → Fam 𝓤 ⟨ 𝒪 X ⟩ → Ω (𝓤 ⁺ ⊔ 𝓣)
 has-upper-bound-in P S = ∥ Upper-Bound-Data P S ∥Ω

\end{code}

Given a family `S`, we denote by `χ∙ S` the subset corresponding to the image of
the family.

\begin{code}

 χ∙ : Fam 𝓤 ⟨ 𝒪 X ⟩ → ⟨ 𝒪 X ⟩ → Ω (𝓤 ⁺)
 χ∙ S U = U ∈image (S [_]) , being-in-the-image-is-prop U (S [_])
  where
   open Equality carrier-of-[ poset-of (𝒪 X) ]-is-set

\end{code}

Given a Kuratowski-finite family `S`, the subset `χ∙ S` is a Kuratowski-finite
subset.

\begin{code}

 χ∙-of-Kuratowski-finite-subset-is-Kuratowski-finite
  : (S : Fam 𝓤 ⟨ 𝒪 X ⟩)
  → is-Kuratowski-finite (index S)
  → is-Kuratowski-finite-subset (χ∙ S)
 χ∙-of-Kuratowski-finite-subset-is-Kuratowski-finite S = ∥∥-functor †
  where
   † : Σ n ꞉ ℕ , Fin n ↠ index S → Σ n ꞉ ℕ , Fin n ↠ image (S [_])
   † (n , h , σ) = n , h′ , φ
    where
     h′ : Fin n → image (S [_])
     h′ = corestriction (S [_]) ∘ h

     φ : is-surjection h′
     φ = ∘-is-surjection σ (corestrictions-are-surjections (S [_]))

\end{code}

We are now ready to prove our main lemma stating that every directed family `S`
contains at least one upper bound of every Kuratowski-finite subset.

\begin{code}

 open binary-unions-of-subsets pt

 directed-families-have-upper-bounds-of-Kuratowski-finite-subsets
  : (S : Fam 𝓤 ⟨ 𝒪 X ⟩)
  → is-directed (𝒪 X) S holds
  → (P : 𝓚 ⟨ 𝒪 X ⟩)
  → (⟨ P ⟩ ⊆ χ∙ S)
  → has-upper-bound-in ⟨ P ⟩ S holds
 directed-families-have-upper-bounds-of-Kuratowski-finite-subsets S 𝒹 (P , 𝕗) φ =
  Kuratowski-finite-subset-induction pe fe ⟨ 𝒪 X ⟩ σ R i β γ δ (P , 𝕗) φ
   where
    R : 𝓚 ⟨ 𝒪 X ⟩ → 𝓤 ⁺  ̇
    R Q = ⟨ Q ⟩ ⊆ χ∙ S → has-upper-bound-in ⟨ Q ⟩ S holds

    i : (Q : 𝓚 ⟨ 𝒪 X ⟩) → is-prop (R Q)
    i Q = Π-is-prop fe λ _ → holds-is-prop (has-upper-bound-in ⟨ Q ⟩ S)

    σ : is-set ⟨ 𝒪 X ⟩
    σ = carrier-of-[ poset-of (𝒪 X) ]-is-set

    open singleton-Kuratowski-finite-subsets σ

    β : R ∅[𝓚]
    β _ = ∥∥-functor
           (λ i → i , λ _ → 𝟘-elim)
           (directedness-entails-inhabitation (𝒪 X) S 𝒹)

    γ : (U : ⟨ 𝒪 X ⟩) → R ❴ U ❵[𝓚]
    γ U μ = ∥∥-functor † (μ U refl)
     where
      † : Σ i ꞉ index S , S [ i ] ＝ U
        → Upper-Bound-Data ⟨ ❴ U ❵[𝓚] ⟩ S
      † (i , q) = i , ϑ
       where
        ϑ : (V : ⟨ 𝒪 X ⟩ ) → U ＝ V → (V ≤ S [ i ]) holds
        ϑ V p = V          ＝⟨ p ⁻¹ ⟩ₚ
                U          ＝⟨ q ⁻¹ ⟩ₚ
                S [ i ]    ■

    δ : (𝒜 ℬ : 𝓚 ⟨ 𝒪 X ⟩) → R 𝒜 → R ℬ → R (𝒜 ∪[𝓚] ℬ)
    δ 𝒜@(A , _) ℬ@(B , _) ψ ϑ ι =
     ∥∥-rec₂ (holds-is-prop (has-upper-bound-in (A ∪ B) S)) † (ψ ι₁) (ϑ ι₂)
      where
       ι₁ : A ⊆ χ∙ S
       ι₁ V μ = ι V ∣ inl μ ∣

       ι₂ : B ⊆ χ∙ S
       ι₂ V μ = ι V ∣ inr μ ∣

       † : Upper-Bound-Data A S
         → Upper-Bound-Data B S
         → has-upper-bound-in (A ∪ B) S holds
       † (i , ξ) (j , ζ) = ∥∥-functor ‡ (pr₂ 𝒹 i j)
        where
         ‡ : (Σ k ꞉ index S , (S [ i ] ≤[ poset-of (𝒪 X) ] S [ k ]) holds
                            × (S [ j ] ≤[ poset-of (𝒪 X) ] S [ k ]) holds)
           → Upper-Bound-Data (A ∪ B) S
         ‡ (k , p , q) = k , ♢
          where
           ♢ : (U : ⟨ 𝒪 X ⟩) → U ∈ (A ∪ B) → (U ≤ S [ k ]) holds
           ♢ U = ∥∥-rec (holds-is-prop (U ≤ S [ k ])) ♠
            where
             ♠ : A U holds + B U holds → (U ≤ S [ k ]) holds
             ♠ (inl μ) = U           ≤⟨ ξ U μ ⟩
                         S [ i ]     ≤⟨ p     ⟩
                         S [ k ]     ■
             ♠ (inr μ) = U           ≤⟨ ζ U μ ⟩
                         S [ j ]     ≤⟨ q     ⟩
                         S [ k ]     ■

\end{code}

From this, we get that directed families contain at least one upper bound of
their Kuratowski-finite subfamilies.

\begin{code}

 directed-families-have-upper-bounds-of-Kuratowski-finite-subfamilies
  : (S : Fam 𝓤 ⟨ 𝒪 X ⟩)
  → is-directed (𝒪 X) S holds
  → (𝒥 : SubFam S)
  → is-Kuratowski-finite (index 𝒥)
  → has-upper-bound-in (χ∙ ⁅ S [ 𝒥 [ j ] ] ∣ j ∶ index 𝒥 ⁆) S holds
 directed-families-have-upper-bounds-of-Kuratowski-finite-subfamilies S 𝒹 𝒥 𝕗 =
  directed-families-have-upper-bounds-of-Kuratowski-finite-subsets
   S
   𝒹
   (χ∙ ⁅ S [ 𝒥 [ j ] ] ∣ j ∶ index 𝒥 ⁆ , 𝕗′)
   †
    where
     𝕗′ : is-Kuratowski-finite-subset (χ∙ ⁅ S [ 𝒥 [ j ] ] ∣ j ∶ index 𝒥 ⁆)
     𝕗′ = χ∙-of-Kuratowski-finite-subset-is-Kuratowski-finite
           ⁅ S [ 𝒥 [ j ] ] ∣ j ∶ index 𝒥 ⁆
           𝕗

     † : χ∙ ⁅ S [ 𝒥 [ j ] ] ∣ j ∶ index 𝒥 ⁆ ⊆ χ∙ S
     † U = ∥∥-functor ‡
      where
       ‡ : Σ j ꞉ index 𝒥 , S [ 𝒥 [ j ] ] ＝ U → Σ i ꞉ index S , S [ i ] ＝ U
       ‡ (i , p) = 𝒥 [ i ] , p

\end{code}

It easily follows from this that `is-compact-open'` implies `is-compact-open`.

\begin{code}

 compact-open'-implies-compact-open : (U : ⟨ 𝒪 X ⟩)
                                    → is-compact-open' X U holds
                                    → is-compact-open  X U holds
 compact-open'-implies-compact-open U κ S δ p = ∥∥-rec ∃-is-prop † (κ S p)
  where
   † : Σ (J , h) ꞉ SubFam S , is-Kuratowski-finite J
                            × (U ≤ (⋁[ 𝒪 X ] ⁅  S [ h j ] ∣ j ∶ J ⁆)) holds
     → ∃ i ꞉ index S , (U ≤ S [ i ]) holds
   † ((J , h) , 𝕗 , c) = ∥∥-functor ‡ γ
    where
     S′ : Fam 𝓤 ⟨ 𝒪 X ⟩
     S′ = ⁅  S [ h j ] ∣ j ∶ J ⁆

     ‡ : Upper-Bound-Data (χ∙ S′) S → Σ (λ i → (U ≤ S [ i ]) holds)
     ‡ (i , q) = i , ♢
      where
       φ : ((S [ i ]) is-an-upper-bound-of S′) holds
       φ j = q (S′ [ j ]) ∣ j , refl ∣

       Ⅰ = c
       Ⅱ = ⋁[ 𝒪 X ]-least ⁅ S [ h j ] ∣ j ∶ J ⁆ (S [ i ] , φ)

       ♢ : (U ≤ S [ i ]) holds
       ♢ = U                                 ≤⟨ Ⅰ ⟩
           ⋁[ 𝒪 X ] ⁅ S [ h j ] ∣ j ∶ J ⁆    ≤⟨ Ⅱ ⟩
           S [ i ]                           ■

     γ : has-upper-bound-in (χ∙ S′) S holds
     γ = directed-families-have-upper-bounds-of-Kuratowski-finite-subfamilies
          S
          δ
          (J , h)
          𝕗

\end{code}

\section{Another alternative definition}

We now provide another variant of the definition `is-compact-open'`, which we
show to be equivalent. This one says exactly that every cover has a
Kuratowski-finite subcover.

\begin{code}

is-compact-open'' : (X : Locale 𝓤 𝓥 𝓦) → ⟨ 𝒪 X ⟩ → Ω (𝓤 ⊔ 𝓦 ⁺)
is-compact-open'' {𝓤} {𝓥} {𝓦} X U =
 Ɐ S ꞉ Fam 𝓦 ⟨ 𝒪 X ⟩ ,
  (U ＝ₚ ⋁[ 𝒪 X ] S) ⇒
   (Ǝ (J , h) ꞉ SubFam S , is-Kuratowski-finite J
                         × (U ＝ ⋁[ 𝒪 X ] ⁅  S [ h j ] ∣ j ∶ J ⁆))
    where
     open PosetNotation (poset-of (𝒪 X))
     open Equality carrier-of-[ poset-of (𝒪 X) ]-is-set

module characterization-of-compactness₃ (X : Locale 𝓤 𝓥 𝓦) where

 open PosetNotation (poset-of (𝒪 X))
 open PosetReasoning (poset-of (𝒪 X))
 open some-lemmas-on-directification (𝒪 X)

\end{code}

To see that `is-compact-open'` implies `is-compact-open''`, notice first that
for every open `U : ⟨ 𝒪 X ⟩` and family `S`, we have that `U ≤ ⋁ S` if and
only if `U ＝ ⋁ { U ∧ Sᵢ ∣ i : index S }`.

\begin{code}

 distribute-inside-cover₁ : (U : ⟨ 𝒪 X ⟩) (S : Fam 𝓦 ⟨ 𝒪 X ⟩)
                          → U ＝ ⋁[ 𝒪 X ] ⁅ U ∧[ 𝒪 X ] (S [ i ]) ∣ i ∶ index S ⁆
                          → (U ≤ (⋁[ 𝒪 X ] S)) holds
 distribute-inside-cover₁ U S p = connecting-lemma₂ (𝒪 X) †
  where
   Ⅰ = p

   Ⅱ : ⋁[ 𝒪 X ] ⁅ U ∧[ 𝒪 X ] S [ i ] ∣ i ∶ index S ⁆ ＝ U ∧[ 𝒪 X ] (⋁[ 𝒪 X ] S)
   Ⅱ = distributivity (𝒪 X) U S ⁻¹

   † : U ＝ U ∧[ 𝒪 X ] (⋁[ 𝒪 X ] S)
   † = U                                               ＝⟨ Ⅰ ⟩
       ⋁[ 𝒪 X ] ⁅ U ∧[ 𝒪 X ] S [ i ] ∣ i ∶ index S ⁆   ＝⟨ Ⅱ ⟩
       U ∧[ 𝒪 X ] (⋁[ 𝒪 X ] S)                         ∎

 distribute-inside-cover₂
  : (U : ⟨ 𝒪 X ⟩) (S : Fam 𝓦 ⟨ 𝒪 X ⟩)
  → (U ≤ (⋁[ 𝒪 X ] S)) holds
  → U ＝ ⋁[ 𝒪 X ] ⁅ U ∧[ 𝒪 X ] (S [ i ]) ∣ i ∶ index S ⁆
 distribute-inside-cover₂ U S p =
  U                                                 ＝⟨ Ⅰ ⟩
  U ∧[ 𝒪 X ] (⋁[ 𝒪 X ] S)                           ＝⟨ Ⅱ ⟩
  ⋁[ 𝒪 X ] ⁅ U ∧[ 𝒪 X ] (S [ i ]) ∣ i ∶ index S ⁆   ∎
  where
   Ⅰ = connecting-lemma₁ (𝒪 X) p
   Ⅱ = distributivity (𝒪 X) U S

\end{code}

The backward implication follows easily from these two lemmas.

\begin{code}

 compact-open''-implies-compact-open' : (U : ⟨ 𝒪 X ⟩)
                                      → is-compact-open'' X U holds
                                      → is-compact-open'  X U holds
 compact-open''-implies-compact-open' U κ S p = ∥∥-functor † ♢
  where
   q : U ＝ ⋁[ 𝒪 X ] ⁅ U ∧[ 𝒪 X ] (S [ i ]) ∣ i ∶ index S ⁆
   q = distribute-inside-cover₂ U S p

   ♢ : ∃ (J , h) ꞉ SubFam S , is-Kuratowski-finite J
                            × (U ＝ ⋁[ 𝒪 X ] ⁅ U ∧[ 𝒪 X ] S [ h j ] ∣ j ∶ J ⁆)
   ♢ = κ ⁅ U ∧[ 𝒪 X ] (S [ i ]) ∣ i ∶ index S ⁆ q

   † : Σ (J , h) ꞉ SubFam S , is-Kuratowski-finite J
                            × (U ＝ ⋁[ 𝒪 X ] ⁅ U ∧[ 𝒪 X ] S [ h j ] ∣ j ∶ J ⁆)
     → Σ (J , h) ꞉ SubFam S , is-Kuratowski-finite J
                            × (U ≤ (⋁[ 𝒪 X ] ⁅ S [ h j ] ∣ j ∶ J ⁆)) holds
   † (𝒥@(J , h) , 𝕗 , p) =
    𝒥 , 𝕗 , distribute-inside-cover₁ U ⁅ S [ h j ] ∣ j ∶ J ⁆ p

\end{code}

Now, the forward implication:

\begin{code}

 compact-open'-implies-compact-open'' : (U : ⟨ 𝒪 X ⟩)
                                      → is-compact-open'  X U holds
                                      → is-compact-open'' X U holds
 compact-open'-implies-compact-open'' U κ S p = ∥∥-functor † (κ S c)
  where
   open Joins (λ x y → x ≤ y)
   open PosetNotation (poset-of (𝒪 X)) renaming (_≤_ to _≤∙_)

   c : (U ≤∙ (⋁[ 𝒪 X ] S)) holds
   c = reflexivity+ (poset-of (𝒪 X)) p

   † : (Σ F ꞉ SubFam S ,
         is-Kuratowski-finite (index F)
         × (U ≤∙ (⋁[ 𝒪 X ] ⁅ S [ F [ j ] ] ∣ j ∶ index F ⁆)) holds)
     → Σ F ꞉ SubFam S ,
        is-Kuratowski-finite (index F)
        × (U ＝ ⋁[ 𝒪 X ] ⁅ S [ F [ j ] ] ∣ j ∶ index F ⁆)
   † (F , 𝕗 , q) = F , 𝕗 , r
    where
     ψ : cofinal-in (𝒪 X) ⁅ S [ F [ j ] ] ∣ j ∶ index F ⁆ S holds
     ψ j = ∣ F [ j ] , ≤-is-reflexive (poset-of (𝒪 X)) (S [ F [ j ] ]) ∣

     ♢ : ((⋁[ 𝒪 X ] ⁅ S [ F [ j ] ] ∣ j ∶ index F ⁆) ≤∙ U) holds
     ♢ = ⋁[ 𝒪 X ] ⁅ S [ F [ j ] ] ∣ j ∶ index F ⁆   ≤⟨  Ⅰ ⟩
         ⋁[ 𝒪 X ] S                                 ＝⟨ Ⅱ ⟩ₚ
         U                                          ■
          where
           Ⅰ = cofinal-implies-join-covered (𝒪 X) _ _ ψ
           Ⅱ = p ⁻¹

     r : U ＝ ⋁[ 𝒪 X ] ⁅ S [ F [ j ] ] ∣ j ∶ index F ⁆
     r = ≤-is-antisymmetric (poset-of (𝒪 X)) q ♢

\end{code}

In the above proof, I have implemented a simplification that Tom de Jong
suggested in a code review.
