open import Realizability.ApplicativeStructure renaming (Term to ApplStrTerm)
open import Realizability.CombinatoryAlgebra
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.HLevels
open import Cubical.Data.Unit
open import Cubical.Data.Empty
open import Cubical.Data.FinData
open import Cubical.Data.Vec
open import Cubical.HITs.PropositionalTruncation
open import Cubical.HITs.PropositionalTruncation.Monad
open import Cubical.HITs.SetQuotients as SQ
open import Cubical.Categories.Category
open import Cubical.Categories.Limits.Terminal
module Realizability.Topos.TerminalObject
{ℓ ℓ' ℓ''}
{A : Type ℓ}
(ca : CombinatoryAlgebra A)
(isNonTrivial : CombinatoryAlgebra.s ca ≡ CombinatoryAlgebra.k ca → ⊥) where
open CombinatoryAlgebra ca
open import Realizability.Tripos.Prealgebra.Predicate {ℓ' = ℓ'} {ℓ'' = ℓ''} ca
open import Realizability.Topos.Object {ℓ' = ℓ'} {ℓ'' = ℓ''} ca isNonTrivial
open import Realizability.Topos.FunctionalRelation {ℓ' = ℓ'} {ℓ'' = ℓ''} ca isNonTrivial
open Combinators ca renaming (i to Id; ia≡a to Ida≡a)
open PartialEquivalenceRelation
open Predicate renaming (isSetX to isSetPredicateBase)
opaque
terminalPer : PartialEquivalenceRelation Unit*
isSetPredicateBase (equality terminalPer) = isSet× isSetUnit* isSetUnit*
∣ equality terminalPer ∣ (tt* , tt*) _ = Unit*
isPropValued (equality terminalPer) _ _ = isPropUnit*
isPartialEquivalenceRelation.isSetX (isPerEquality terminalPer) = isSetUnit*
isPartialEquivalenceRelation.isSymmetric (isPerEquality terminalPer) =
return (k , (λ { tt* tt* r tt* → tt* }))
isPartialEquivalenceRelation.isTransitive (isPerEquality terminalPer) =
return (k , (λ { tt* tt* tt* _ _ tt* tt* → tt* }))
open FunctionalRelation
opaque
unfolding terminalPer
terminalFuncRel : ∀ {Y : Type ℓ'} → (perY : PartialEquivalenceRelation Y) → FunctionalRelation perY terminalPer
terminalFuncRel {Y} perY =
record
{ relation =
record
{ isSetX = isSet× (perY .isSetX) isSetUnit*
; ∣_∣ = λ { (y , tt*) r → r ⊩ ∣ perY .equality ∣ (y , y) }
; isPropValued = λ { (y , tt*) r → perY .equality .isPropValued _ _ } }
; isFuncRel =
record
{ isStrictDomain = return (Id , (λ { y tt* r r⊩y~y → subst (λ r' → r' ⊩ ∣ perY .equality ∣ (y , y)) (sym (Ida≡a _)) r⊩y~y }))
; isStrictCodomain = return (k , (λ { y tt* r r⊩y~y → tt* }))
; isRelational =
(do
(t , t⊩isTransitive) ← perY .isTransitive
(s , s⊩isSymmetric) ← perY .isSymmetric
let
prover : ApplStrTerm as 3
prover = ` t ̇ (` s ̇ # two) ̇ # two
return
(λ*3 prover ,
(λ { y y' tt* tt* a b c a⊩y~y' b⊩y~y tt* →
subst
(λ r' → r' ⊩ ∣ perY .equality ∣ (y' , y'))
(sym (λ*3ComputationRule prover a b c))
(t⊩isTransitive y' y y' (s ⨾ a) a (s⊩isSymmetric y y' a a⊩y~y') a⊩y~y') })))
; isSingleValued = (return (k , (λ { y tt* tt* r₁ r₂ r₁⊩y~y r₂⊩y~y → tt* })))
; isTotal = return
(Id ,
(λ y r r⊩y~y →
return (tt* , (subst (λ r' → r' ⊩ ∣ perY .equality ∣ (y , y)) (sym (Ida≡a _)) r⊩y~y))))
} }
opaque
unfolding terminalPer
isTerminalTerminalPer : ∀ {Y : Type ℓ'} → (perY : PartialEquivalenceRelation Y) → isContr (RTMorphism perY terminalPer)
isTerminalTerminalPer {Y} perY =
inhProp→isContr
[ terminalFuncRel perY ]
λ f g →
SQ.elimProp2
(λ f g → squash/ f g)
(λ F G →
let
answer : pointwiseEntailment perY terminalPer F G
answer =
do
(tlG , tlG⊩isTotalG) ← G .isTotal
(stFD , stFD⊩isStrictDomainF) ← F .isStrictDomain
let
prover : ApplStrTerm as 1
prover = ` tlG ̇ (` stFD ̇ # zero)
return
(λ* prover ,
(λ { y tt* r r⊩Fy →
transport
(propTruncIdempotent (G .relation .isPropValued _ _))
(do
(tt* , tlGstFD⊩Gy) ← tlG⊩isTotalG y (stFD ⨾ r) (stFD⊩isStrictDomainF y tt* r r⊩Fy)
return (subst (λ r' → r' ⊩ ∣ G .relation ∣ (y , tt*)) (sym (λ*ComputationRule prover r)) tlGstFD⊩Gy)) }))
in
eq/ _ _ (answer , F≤G→G≤F perY terminalPer F G answer))
f g
TerminalRT : Terminal RT
TerminalRT =
(Unit* , terminalPer) , (λ { (Y , perY) → isTerminalTerminalPer perY})