```------------------------------------------------------------------------
-- Strict ω-continuous functions
------------------------------------------------------------------------

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

module Partiality-algebra.Strict-omega-continuous where

open import Equality.Propositional
open import Interval using (ext)
open import Prelude hiding (⊥)

open import Bijection equality-with-J using (_↔_)
import Equivalence equality-with-J as Eq
open import Function-universe equality-with-J hiding (_∘_)
open import H-level.Closure equality-with-J

open import Partiality-algebra as PA
open import Partiality-algebra.Monotone
open import Partiality-algebra.Omega-continuous

-- Definition of strict ω-continuous functions.

record [_⟶_]⊥
{a₁ p₁ q₁} {A₁ : Set a₁} (P₁ : Partiality-algebra p₁ q₁ A₁)
{a₂ p₂ q₂} {A₂ : Set a₂} (P₂ : Partiality-algebra p₂ q₂ A₂) :
Set (p₁ ⊔ p₂ ⊔ q₁ ⊔ q₂) where
private
module P₁ = Partiality-algebra P₁
module P₂ = Partiality-algebra P₂

field
ω-continuous-function : [ P₁ ⟶ P₂ ]

open [_⟶_] ω-continuous-function public

field
strict : function P₁.never ≡ P₂.never

open [_⟶_]⊥

-- Identity.

id⊥ : ∀ {a p q} {A : Set a} {P : Partiality-algebra p q A} →
[ P ⟶ P ]⊥
ω-continuous-function id⊥ = idω
strict                id⊥ = refl

-- Composition.

infixr 40 _∘⊥_

_∘⊥_ :
∀ {a₁ p₁ q₁} {A₁ : Set a₁} {P₁ : Partiality-algebra p₁ q₁ A₁}
{a₂ p₂ q₂} {A₂ : Set a₂} {P₂ : Partiality-algebra p₂ q₂ A₂}
{a₃ p₃ q₃} {A₃ : Set a₃} {P₃ : Partiality-algebra p₃ q₃ A₃} →
[ P₂ ⟶ P₃ ]⊥ → [ P₁ ⟶ P₂ ]⊥ → [ P₁ ⟶ P₃ ]⊥
ω-continuous-function (f ∘⊥ g) =
ω-continuous-function f ∘ω ω-continuous-function g

strict (_∘⊥_ {P₁ = P₁} {P₂ = P₂} {P₃ = P₃} f g) =
function f (function g P₁.never)  ≡⟨ cong (function f) (strict g) ⟩
function f P₂.never               ≡⟨ strict f ⟩∎
P₃.never                          ∎
where
module P₁ = Partiality-algebra P₁
module P₂ = Partiality-algebra P₂
module P₃ = Partiality-algebra P₃

-- Equality characterisation lemma for strict ω-continuous functions.

equality-characterisation-strict :
∀ {a₁ p₁ q₁} {A₁ : Set a₁} {P₁ : Partiality-algebra p₁ q₁ A₁}
{a₂ p₂ q₂} {A₂ : Set a₂} {P₂ : Partiality-algebra p₂ q₂ A₂}
{f g : [ P₁ ⟶ P₂ ]⊥} →
(∀ x → function f x ≡ function g x) ↔ f ≡ g
equality-characterisation-strict {P₁ = P₁} {P₂ = P₂} {f} {g} =
(∀ x → function f x ≡ function g x)                ↝⟨ equality-characterisation-continuous ⟩
ω-continuous-function f ≡ ω-continuous-function g  ↝⟨ ignore-propositional-component
(P₂.Type-is-set _ _) ⟩
_↔_.to rearrange f ≡ _↔_.to rearrange g            ↔⟨ Eq.≃-≡ (Eq.↔⇒≃ rearrange) ⟩□
f ≡ g                                              □
where
module P₁ = Partiality-algebra P₁
module P₂ = Partiality-algebra P₂

rearrange :
[ P₁ ⟶ P₂ ]⊥
↔
∃ λ (h : [ P₁ ⟶ P₂ ]) → [_⟶_].function h P₁.never ≡ P₂.never
rearrange = record
{ surjection = record
{ logical-equivalence = record
{ to   = λ f → ω-continuous-function f , strict f
; from = uncurry λ f c → record { ω-continuous-function = f
; strict                = c
}
}
; right-inverse-of = λ _ → refl
}
; left-inverse-of = λ _ → refl
}
where
open Partiality-algebra

-- Composition is associative.

∘⊥-assoc :
∀ {a₁ p₁ q₁} {A₁ : Set a₁} {P₁ : Partiality-algebra p₁ q₁ A₁}
{a₂ p₂ q₂} {A₂ : Set a₂} {P₂ : Partiality-algebra p₂ q₂ A₂}
{a₃ p₃ q₃} {A₃ : Set a₃} {P₃ : Partiality-algebra p₃ q₃ A₃}
{a₄ p₄ q₄} {A₄ : Set a₄} {P₄ : Partiality-algebra p₄ q₄ A₄}
(f : [ P₃ ⟶ P₄ ]⊥) (g : [ P₂ ⟶ P₃ ]⊥) (h : [ P₁ ⟶ P₂ ]⊥) →
f ∘⊥ (g ∘⊥ h) ≡ (f ∘⊥ g) ∘⊥ h
∘⊥-assoc _ _ _ =
_↔_.to equality-characterisation-strict λ _ → refl
```