open import Realizability.ApplicativeStructure
open import Realizability.CombinatoryAlgebra
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.HLevels
open import Cubical.Foundations.Structure using (⟨_⟩; str)
open import Cubical.Foundations.Isomorphism
open import Cubical.Foundations.Equiv
open import Cubical.Foundations.Univalence
open import Cubical.Foundations.Powerset
open import Cubical.Functions.FunExtEquiv
open import Cubical.Relation.Binary
open import Cubical.Data.Sigma
open import Cubical.Data.FinData
open import Cubical.Data.Vec
open import Cubical.Reflection.RecordEquiv
open import Cubical.HITs.PropositionalTruncation as PT hiding (map)
open import Cubical.HITs.PropositionalTruncation.Monad
open import Cubical.HITs.SetQuotients as SQ
open import Cubical.Categories.Category
open import Cubical.Categories.Functor hiding (Id)
module Realizability.PERs.PER
{ℓ} {A : Type ℓ} (ca : CombinatoryAlgebra A) where
open import Realizability.Assembly.Base ca
open import Realizability.Assembly.Morphism ca
open CombinatoryAlgebra ca
open Combinators ca renaming (i to Id; ia≡a to Ida≡a)
module BR = BinaryRelation
isPartialEquivalenceRelation : (A → A → Type ℓ) → Type _
isPartialEquivalenceRelation rel = BR.isSym rel × BR.isTrans rel
isPropIsPartialEquivalenceRelation : ∀ r → (∀ a b → isProp (r a b)) → isProp (isPartialEquivalenceRelation r)
isPropIsPartialEquivalenceRelation rel isPropValuedRel =
isProp×
(isPropΠ (λ x → isPropΠ λ y → isProp→ (isPropValuedRel y x)))
(isPropΠ λ x → isPropΠ λ y → isPropΠ λ z → isProp→ (isProp→ (isPropValuedRel x z)))
record PER : Type (ℓ-suc ℓ) where
no-eta-equality
constructor makePER
field
relation : A → A → Type ℓ
isPropValued : ∀ a b → isProp (relation a b)
isPER : isPartialEquivalenceRelation relation
isSymmetric = isPER .fst
isTransitive = isPER .snd
open PER
PERΣ : Type (ℓ-suc ℓ)
PERΣ = Σ[ relation ∈ (A → A → hProp ℓ) ] isPartialEquivalenceRelation λ a b → ⟨ relation a b ⟩
isSetPERΣ : isSet PERΣ
isSetPERΣ =
isSetΣ
(isSet→ (isSet→ isSetHProp))
(λ relation →
isProp→isSet
(isPropIsPartialEquivalenceRelation
(λ a b → ⟨ relation a b ⟩)
(λ a b → str (relation a b))))
PER≡ : ∀ (R S : PER) → (R .relation ≡ S .relation) → R ≡ S
relation (PER≡ R S rel≡ i) = rel≡ i
isPropValued (PER≡ R S rel≡ i) a b =
isProp→PathP
{B = λ j → isProp (rel≡ j a b)}
(λ j → isPropIsProp)
(R .isPropValued a b)
(S .isPropValued a b) i
isPER (PER≡ R S rel≡ i) =
isProp→PathP
{B = λ j → isPartialEquivalenceRelation (rel≡ j)}
(λ j → isPropIsPartialEquivalenceRelation (rel≡ j) λ a b → isPropRelJ a b j)
(R .isPER)
(S .isPER) i where
isPropRelJ : ∀ a b j → isProp (rel≡ j a b)
isPropRelJ a b j = isProp→PathP {B = λ k → isProp (rel≡ k a b)} (λ k → isPropIsProp) (R .isPropValued a b) (S .isPropValued a b) j
PERIsoΣ : Iso PER PERΣ
Iso.fun PERIsoΣ per = (λ a b → per .relation a b , per .isPropValued a b) , per .isPER
relation (Iso.inv PERIsoΣ perΣ) a b = ⟨ perΣ .fst a b ⟩
isPropValued (Iso.inv PERIsoΣ perΣ) a b = str (perΣ .fst a b)
isPER (Iso.inv PERIsoΣ perΣ) = perΣ .snd
Iso.rightInv PERIsoΣ perΣ = refl
Iso.leftInv PERIsoΣ per = PER≡ _ _ refl
isSetPER : isSet PER
isSetPER = isOfHLevelRetractFromIso 2 PERIsoΣ isSetPERΣ
PER≡Iso : ∀ (R S : PER) → Iso (R ≡ S) (R .relation ≡ S .relation)
Iso.fun (PER≡Iso R S) R≡S i = R≡S i .relation
Iso.inv (PER≡Iso R S) rel≡ = PER≡ R S rel≡
Iso.rightInv (PER≡Iso R S) rel≡ = refl
Iso.leftInv (PER≡Iso R S) R≡S = isSetPER R S _ _
_~[_]_ : A → PER → A → Type ℓ
a ~[ R ] b = R .relation a b
isProp~ : ∀ a R b → isProp (a ~[ R ] b)
isProp~ a R b = R .isPropValued a b
isTracker : (R S : PER) → A → Type ℓ
isTracker R S a = ∀ r r' → r ~[ R ] r' → (a ⨾ r) ~[ S ] (a ⨾ r')
perTracker : (R S : PER) → Type ℓ
perTracker R S = Σ[ a ∈ A ] isTracker R S a
isEquivTracker : (R S : PER) → perTracker R S → perTracker R S → Type ℓ
isEquivTracker R S (a , _) (b , _) = (∀ r → r ~[ R ] r → (a ⨾ r) ~[ S ] (b ⨾ r))
isEquivRelIsEquivTracker : (R S : PER) → BR.isEquivRel (isEquivTracker R S)
BinaryRelation.isEquivRel.reflexive (isEquivRelIsEquivTracker R S) (a , isTrackerA) r r~r = isTrackerA r r r~r
BinaryRelation.isEquivRel.symmetric (isEquivRelIsEquivTracker R S) (a , isTrackerA) (b , isTrackerB) a~b r r~r =
isSymmetric S (a ⨾ r) (b ⨾ r) (a~b r r~r)
BinaryRelation.isEquivRel.transitive (isEquivRelIsEquivTracker R S) (a , isTrackerA) (b , isTrackerB) (c , isTrackerC) a~b b~c r r~r =
isTransitive S (a ⨾ r) (b ⨾ r) (c ⨾ r) (a~b r r~r) (b~c r r~r)
isPropIsEquivTracker : ∀ R S a b → isProp (isEquivTracker R S a b)
isPropIsEquivTracker R S (a , isTrackerA) (b , isTrackerB) = isPropΠ2 λ r r~r → isPropValued S (a ⨾ r) (b ⨾ r)
isEffectiveIsEquivTracker : ∀ R S → BR.isEffective (isEquivTracker R S)
isEffectiveIsEquivTracker R S = isEquivRel→isEffective (isPropIsEquivTracker R S) (isEquivRelIsEquivTracker R S)
perMorphism : (R S : PER) → Type ℓ
perMorphism R S = perTracker R S / (isEquivTracker R S)
effectiveIsEquivTracker : ∀ R S a b → [ a ] ≡ [ b ] → isEquivTracker R S a b
effectiveIsEquivTracker R S a b eq' = effective (isPropIsEquivTracker R S) (isEquivRelIsEquivTracker R S) a b eq'
isSetPerMorphism : ∀ R S → isSet (perMorphism R S)
isSetPerMorphism R S = squash/
idPerMorphism : (R : PER) → perMorphism R R
idPerMorphism R = [ Id , (λ r r' r~r' → subst2 (λ r r' → r ~[ R ] r') (sym (Ida≡a r)) (sym (Ida≡a r')) r~r') ]
composePerTracker : (R S T : PER) → perTracker R S → perTracker S T → perTracker R T
composePerTracker R S T (a , a⊩f) (b , b⊩g) =
let
realizer : Term as 1
realizer = ` b ̇ (` a ̇ # zero)
in
λ* realizer ,
λ r r' r~r' →
subst2
_~[ T ]_
(sym (λ*ComputationRule realizer r))
(sym (λ*ComputationRule realizer r'))
(b⊩g (a ⨾ r) (a ⨾ r') (a⊩f r r' r~r'))
composePerMorphism : (R S T : PER) → perMorphism R S → perMorphism S T → perMorphism R T
composePerMorphism R S T f g =
SQ.rec2
squash/
(λ { (a , a⊩f) (b , b⊩g) →
[ composePerTracker R S T (a , a⊩f) (b , b⊩g) ] })
(λ { (a , a⊩f) (b , b⊩f) (c , c⊩g) a~b →
eq/ _ _
λ r r~r →
subst2
(λ car cbr → car ~[ T ] cbr)
(sym (λ*ComputationRule (` c ̇ (` a ̇ # zero)) r))
(sym (λ*ComputationRule (` c ̇ (` b ̇ # zero)) r))
(c⊩g (a ⨾ r) (b ⨾ r) (a~b r r~r)) })
(λ { (a , a⊩f) (b , b⊩g) (c , c⊩g) b~c →
eq/ _ _
λ r r~r →
subst2
(λ bar car → bar ~[ T ] car)
(sym (λ*ComputationRule (` b ̇ (` a ̇ # zero)) r))
(sym (λ*ComputationRule (` c ̇ (` a ̇ # zero)) r))
(b~c (a ⨾ r) (a⊩f r r r~r)) })
f g
idLPerMorphism : ∀ R S f → composePerMorphism R R S (idPerMorphism R) f ≡ f
idLPerMorphism R S f =
SQ.elimProp
(λ f → squash/ (composePerMorphism R R S (idPerMorphism R) f) f)
(λ { (a , a⊩f) →
eq/ _ _
λ r r~r →
subst
(λ ar → ar ~[ S ] (a ⨾ r))
(sym (λ*ComputationRule (` a ̇ (` Id ̇ # zero)) r ∙ cong (λ x → a ⨾ x) (Ida≡a r)))
(a⊩f r r r~r) })
f
idRPerMorphism : ∀ R S f → composePerMorphism R S S f (idPerMorphism S) ≡ f
idRPerMorphism R S f =
SQ.elimProp
(λ f → squash/ (composePerMorphism R S S f (idPerMorphism S)) f)
(λ { (a , a⊩f) →
eq/ _ _
λ r r~r →
subst (λ ar → ar ~[ S ] (a ⨾ r)) (sym (λ*ComputationRule (` Id ̇ (` a ̇ # zero)) r ∙ Ida≡a (a ⨾ r))) (a⊩f r r r~r) })
f
assocPerMorphism : ∀ R S T U f g h → composePerMorphism R T U (composePerMorphism R S T f g) h ≡ composePerMorphism R S U f (composePerMorphism S T U g h)
assocPerMorphism R S T U f g h =
SQ.elimProp3
(λ f g h → squash/ (composePerMorphism R T U (composePerMorphism R S T f g) h) (composePerMorphism R S U f (composePerMorphism S T U g h)))
(λ { (a , a⊩f) (b , b⊩g) (c , c⊩h) →
eq/ _ _
λ r r~r →
subst2
(λ cba cba' → cba ~[ U ] cba')
(sym (λ*ComputationRule (` c ̇ (` ⟦ as ⟧ (λ*abst (` b ̇ (` a ̇ # zero))) [] ̇ # zero)) r ∙ cong (λ bar → c ⨾ bar) (λ*ComputationRule (` b ̇ (` a ̇ # zero)) r)))
(sym (λ*ComputationRule (` ⟦ as ⟧ (λ*abst (` c ̇ (` b ̇ # zero))) [] ̇ (` a ̇ # zero)) r ∙ λ*ComputationRule (` c ̇ (` b ̇ # zero)) (a ⨾ r)))
(c⊩h (b ⨾ (a ⨾ r)) (b ⨾ (a ⨾ r)) (b⊩g (a ⨾ r) (a ⨾ r) (a⊩f r r r~r)) ) })
f g h
PERCat : Category (ℓ-suc ℓ) ℓ
Category.ob PERCat = PER
Category.Hom[_,_] PERCat R S = perMorphism R S
Category.id PERCat {R} = idPerMorphism R
Category._⋆_ PERCat {R} {S} {T} f g = composePerMorphism R S T f g
Category.⋆IdL PERCat {R} {S} f = idLPerMorphism R S f
Category.⋆IdR PERCat {R} {S} f = idRPerMorphism R S f
Category.⋆Assoc PERCat {R} {S} {T} {U} f g h = assocPerMorphism R S T U f g h
Category.isSetHom PERCat {R} {S} = isSetPerMorphism R S