diff --git a/Cubical/Data/Cardinal.agda b/Cubical/Data/Cardinal.agda new file mode 100644 index 0000000000..380e953f10 --- /dev/null +++ b/Cubical/Data/Cardinal.agda @@ -0,0 +1,5 @@ +{-# OPTIONS --safe #-} +module Cubical.Data.Cardinal where + +open import Cubical.Data.Cardinal.Base public +open import Cubical.Data.Cardinal.Properties public diff --git a/Cubical/Data/Cardinality/Base.agda b/Cubical/Data/Cardinal/Base.agda similarity index 83% rename from Cubical/Data/Cardinality/Base.agda rename to Cubical/Data/Cardinal/Base.agda index 56f161145f..72b8ebd6db 100644 --- a/Cubical/Data/Cardinality/Base.agda +++ b/Cubical/Data/Cardinal/Base.agda @@ -7,7 +7,7 @@ This file contains: -} {-# OPTIONS --safe #-} -module Cubical.Data.Cardinality.Base where +module Cubical.Data.Cardinal.Base where open import Cubical.HITs.SetTruncation as ∥₂ open import Cubical.Foundations.Prelude @@ -19,7 +19,7 @@ open import Cubical.Data.Unit private variable - ℓ : Level + ℓ ℓ' : Level -- First, we define a cardinal as the set truncation of Set Card : Type (ℓ-suc ℓ) @@ -41,14 +41,14 @@ card = ∣_∣₂ 𝟙 = card (Unit* , isSetUnit*) -- Now we define some arithmetic -_+_ : Card {ℓ} → Card {ℓ} → Card {ℓ} +_+_ : Card {ℓ} → Card {ℓ'} → Card {ℓ-max ℓ ℓ'} _+_ = ∥₂.rec2 isSetCard λ (A , isSetA) (B , isSetB) → card ((A ⊎ B) , isSet⊎ isSetA isSetB) -_·_ : Card {ℓ} → Card {ℓ} → Card {ℓ} +_·_ : Card {ℓ} → Card {ℓ'} → Card {ℓ-max ℓ ℓ'} _·_ = ∥₂.rec2 isSetCard λ (A , isSetA) (B , isSetB) → card ((A × B) , isSet× isSetA isSetB) -_^_ : Card {ℓ} → Card {ℓ} → Card {ℓ} +_^_ : Card {ℓ} → Card {ℓ'} → Card {ℓ-max ℓ ℓ'} _^_ = ∥₂.rec2 isSetCard λ (A , isSetA) (B , _) → card ((B → A) , isSet→ isSetA) diff --git a/Cubical/Data/Cardinality/Properties.agda b/Cubical/Data/Cardinal/Properties.agda similarity index 72% rename from Cubical/Data/Cardinality/Properties.agda rename to Cubical/Data/Cardinal/Properties.agda index 77a6dba379..1c7371cf0c 100644 --- a/Cubical/Data/Cardinality/Properties.agda +++ b/Cubical/Data/Cardinal/Properties.agda @@ -7,10 +7,10 @@ This file contains: -} {-# OPTIONS --safe #-} -module Cubical.Data.Cardinality.Properties where +module Cubical.Data.Cardinal.Properties where open import Cubical.HITs.SetTruncation as ∥₂ -open import Cubical.Data.Cardinality.Base +open import Cubical.Data.Cardinal.Base open import Cubical.Algebra.CommSemiring @@ -30,55 +30,60 @@ open import Cubical.Relation.Binary.Order.Properties private variable - ℓ : Level + ℓ ℓ' ℓ'' ℓa ℓb ℓc ℓd : Level -- Cardinality is a commutative semiring module _ where private - +Assoc : (A B C : Card {ℓ}) → A + (B + C) ≡ (A + B) + C + +Assoc : (A : Card {ℓa}) (B : Card {ℓb}) (C : Card {ℓc}) + → A + (B + C) ≡ (A + B) + C +Assoc = ∥₂.elim3 (λ _ _ _ → isProp→isSet (isSetCard _ _)) λ _ _ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (sym (isoToPath ⊎-assoc-Iso))) - ·Assoc : (A B C : Card {ℓ}) → A · (B · C) ≡ (A · B) · C + ·Assoc : (A : Card {ℓa}) (B : Card {ℓb}) (C : Card {ℓc}) + → A · (B · C) ≡ (A · B) · C ·Assoc = ∥₂.elim3 (λ _ _ _ → isProp→isSet (isSetCard _ _)) λ _ _ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (sym (isoToPath Σ-assoc-Iso))) - +IdR𝟘 : (A : Card {ℓ}) → A + 𝟘 ≡ A + +IdR𝟘 : (A : Card {ℓ}) → A + 𝟘 {ℓ} ≡ A +IdR𝟘 = ∥₂.elim (λ _ → isProp→isSet (isSetCard _ _)) λ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath ⊎-IdR-⊥*-Iso)) - +IdL𝟘 : (A : Card {ℓ}) → 𝟘 + A ≡ A + +IdL𝟘 : (A : Card {ℓ}) → 𝟘 {ℓ} + A ≡ A +IdL𝟘 = ∥₂.elim (λ _ → isProp→isSet (isSetCard _ _)) λ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath ⊎-IdL-⊥*-Iso)) - ·IdR𝟙 : (A : Card {ℓ}) → A · 𝟙 ≡ A + ·IdR𝟙 : (A : Card {ℓ}) → A · 𝟙 {ℓ} ≡ A ·IdR𝟙 = ∥₂.elim (λ _ → isProp→isSet (isSetCard _ _)) λ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath rUnit*×Iso)) - ·IdL𝟙 : (A : Card {ℓ}) → 𝟙 · A ≡ A + ·IdL𝟙 : (A : Card {ℓ}) → 𝟙 {ℓ} · A ≡ A ·IdL𝟙 = ∥₂.elim (λ _ → isProp→isSet (isSetCard _ _)) λ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath lUnit*×Iso)) - +Comm : (A B : Card {ℓ}) → (A + B) ≡ (B + A) + +Comm : (A : Card {ℓa}) (B : Card {ℓb}) + → (A + B) ≡ (B + A) +Comm = ∥₂.elim2 (λ _ _ → isProp→isSet (isSetCard _ _)) λ _ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath ⊎-swap-Iso)) - ·Comm : (A B : Card {ℓ}) → (A · B) ≡ (B · A) + ·Comm : (A : Card {ℓa}) (B : Card {ℓb}) + → (A · B) ≡ (B · A) ·Comm = ∥₂.elim2 (λ _ _ → isProp→isSet (isSetCard _ _)) λ _ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath Σ-swap-Iso)) - ·LDist+ : (A B C : Card {ℓ}) → A · (B + C) ≡ (A · B) + (A · C) + ·LDist+ : (A : Card {ℓa}) (B : Card {ℓb}) (C : Card {ℓc}) + → A · (B + C) ≡ (A · B) + (A · C) ·LDist+ = ∥₂.elim3 (λ _ _ _ → isProp→isSet (isSetCard _ _)) λ _ _ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) - (isoToPath ×DistL⊎Iso)) + (isoToPath ×DistR⊎Iso)) AnnihilL : (A : Card {ℓ}) → 𝟘 · A ≡ 𝟘 AnnihilL = ∥₂.elim (λ _ → isProp→isSet (isSetCard _ _)) @@ -90,7 +95,7 @@ module _ where -- Exponentiation is also well-behaved -^AnnihilR𝟘 : (A : Card {ℓ}) → A ^ 𝟘 ≡ 𝟙 +^AnnihilR𝟘 : (A : Card {ℓ}) → A ^ 𝟘 {ℓ} ≡ 𝟙 {ℓ} ^AnnihilR𝟘 = ∥₂.elim (λ _ → isProp→isSet (isSetCard _ _)) λ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath (iso⊥ _))) @@ -100,7 +105,7 @@ module _ where Iso.rightInv (iso⊥ A) _ = refl Iso.leftInv (iso⊥ A) _ i () -^IdR𝟙 : (A : Card {ℓ}) → A ^ 𝟙 ≡ A +^IdR𝟙 : (A : Card {ℓ}) → A ^ 𝟙 {ℓ} ≡ A ^IdR𝟙 = ∥₂.elim (λ _ → isProp→isSet (isSetCard _ _)) λ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath (iso⊤ _))) @@ -110,7 +115,7 @@ module _ where Iso.rightInv (iso⊤ _) _ = refl Iso.leftInv (iso⊤ _) _ = refl -^AnnihilL𝟙 : (A : Card {ℓ}) → 𝟙 ^ A ≡ 𝟙 +^AnnihilL𝟙 : (A : Card {ℓ}) → 𝟙 {ℓ} ^ A ≡ 𝟙 {ℓ} ^AnnihilL𝟙 = ∥₂.elim (λ _ → isProp→isSet (isSetCard _ _)) λ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath (iso⊤ _))) @@ -120,12 +125,14 @@ module _ where Iso.rightInv (iso⊤ _) _ = refl Iso.leftInv (iso⊤ _) _ = refl -^LDist+ : (A B C : Card {ℓ}) → A ^ (B + C) ≡ (A ^ B) · (A ^ C) +^LDist+ : (A : Card {ℓa}) (B : Card {ℓb}) (C : Card {ℓc}) + → A ^ (B + C) ≡ (A ^ B) · (A ^ C) ^LDist+ = ∥₂.elim3 (λ _ _ _ → isProp→isSet (isSetCard _ _)) λ _ _ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath Π⊎Iso)) -^Assoc· : (A B C : Card {ℓ}) → A ^ (B · C) ≡ (A ^ B) ^ C +^Assoc· : (A : Card {ℓa}) (B : Card {ℓb}) (C : Card {ℓc}) + → A ^ (B · C) ≡ (A ^ B) ^ C ^Assoc· = ∥₂.elim3 (λ _ _ _ → isProp→isSet (isSetCard _ _)) λ _ _ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath (is _ _ _))) @@ -134,7 +141,8 @@ module _ where (C × B → A) Iso⟨ curryIso ⟩ (C → B → A) ∎Iso -^RDist· : (A B C : Card {ℓ}) → (A · B) ^ C ≡ (A ^ C) · (B ^ C) +^RDist· : (A : Card {ℓa}) (B : Card {ℓb}) (C : Card {ℓc}) + → (A · B) ^ C ≡ (A ^ C) · (B ^ C) ^RDist· = ∥₂.elim3 (λ _ _ _ → isProp→isSet (isSetCard _ _)) λ _ _ _ → cong ∣_∣₂ (Σ≡Prop (λ _ → isPropIsSet) (isoToPath Σ-Π-Iso)) @@ -143,51 +151,48 @@ module _ where -- With basic arithmetic done, we can now define an ordering over cardinals module _ where private - _≲'_ : Card {ℓ} → Card {ℓ} → hProp ℓ + _≲'_ : Card {ℓ} → Card {ℓ'} → hProp (ℓ-max ℓ ℓ') _≲'_ = ∥₂.rec2 isSetHProp λ (A , _) (B , _) → ∥ A ↪ B ∥₁ , isPropPropTrunc - _≲_ : Rel (Card {ℓ}) (Card {ℓ}) ℓ + _≲_ : Rel (Card {ℓ}) (Card {ℓ'}) (ℓ-max ℓ ℓ') A ≲ B = ⟨ A ≲' B ⟩ + isPropValued≲ : (A : Card {ℓ}) (B : Card {ℓ'}) → isProp (A ≲ B) + isPropValued≲ a b = str (a ≲' b) + + isRefl≲ : BinaryRelation.isRefl {A = Card {ℓ}} _≲_ + isRefl≲ = ∥₂.elim (λ A → isProp→isSet (isPropValued≲ A A)) + λ (A , _) → ∣ id↪ A ∣₁ + + isTrans≲ : (A : Card {ℓ}) (B : Card {ℓ'}) (C : Card {ℓ''}) + → A ≲ B → B ≲ C → A ≲ C + isTrans≲ = ∥₂.elim3 + (λ x _ z → isSetΠ2 λ _ _ → isProp→isSet (isPropValued≲ x z)) + λ (A , _) (B , _) (C , _) + → ∥₁.map2 λ A↪B B↪C → compEmbedding B↪C A↪B + isPreorder≲ : IsPreorder {ℓ-suc ℓ} _≲_ isPreorder≲ - = ispreorder isSetCard prop reflexive transitive - where prop : BinaryRelation.isPropValued _≲_ - prop a b = str (a ≲' b) - - reflexive : BinaryRelation.isRefl _≲_ - reflexive = ∥₂.elim (λ A → isProp→isSet (prop A A)) - (λ (A , _) → ∣ id↪ A ∣₁) - - transitive : BinaryRelation.isTrans _≲_ - transitive = ∥₂.elim3 (λ x _ z → isSetΠ2 - λ _ _ → isProp→isSet - (prop x z)) - (λ (A , _) (B , _) (C , _) - → ∥₁.map2 λ A↪B B↪C - → compEmbedding - B↪C - A↪B) + = ispreorder isSetCard isPropValued≲ isRefl≲ isTrans≲ isLeast𝟘 : ∀{ℓ} → isLeast isPreorder≲ (Card {ℓ} , id↪ (Card {ℓ})) (𝟘 {ℓ}) -isLeast𝟘 = ∥₂.elim (λ x → isProp→isSet (IsPreorder.is-prop-valued - isPreorder≲ 𝟘 x)) +isLeast𝟘 = ∥₂.elim (λ x → isProp→isSet (isPropValued≲ 𝟘 x)) (λ _ → ∣ ⊥.rec* , (λ ()) ∣₁) -- Our arithmetic behaves as expected over our preordering -+Monotone≲ : (A B C D : Card {ℓ}) → A ≲ C → B ≲ D → (A + B) ≲ (C + D) ++Monotone≲ : (A : Card {ℓa}) (B : Card {ℓb}) (C : Card {ℓc}) (D : Card {ℓd}) + → A ≲ C → B ≲ D → (A + B) ≲ (C + D) +Monotone≲ - = ∥₂.elim4 (λ w x y z → isSetΠ2 λ _ _ → isProp→isSet (IsPreorder.is-prop-valued - isPreorder≲ + = ∥₂.elim4 (λ w x y z → isSetΠ2 λ _ _ → isProp→isSet (isPropValued≲ (w + x) (y + z))) λ (A , _) (B , _) (C , _) (D , _) → ∥₁.map2 λ A↪C B↪D → ⊎Monotone↪ A↪C B↪D -·Monotone≲ : (A B C D : Card {ℓ}) → A ≲ C → B ≲ D → (A · B) ≲ (C · D) +·Monotone≲ : (A : Card {ℓa}) (B : Card {ℓb}) (C : Card {ℓc}) (D : Card {ℓd}) + → A ≲ C → B ≲ D → (A · B) ≲ (C · D) ·Monotone≲ - = ∥₂.elim4 (λ w x y z → isSetΠ2 λ _ _ → isProp→isSet (IsPreorder.is-prop-valued - isPreorder≲ + = ∥₂.elim4 (λ w x y z → isSetΠ2 λ _ _ → isProp→isSet (isPropValued≲ (w · x) (y · z))) λ (A , _) (B , _) (C , _) (D , _) diff --git a/Cubical/Data/Cardinality.agda b/Cubical/Data/Cardinality.agda deleted file mode 100644 index 2c992fe9c8..0000000000 --- a/Cubical/Data/Cardinality.agda +++ /dev/null @@ -1,5 +0,0 @@ -{-# OPTIONS --safe #-} -module Cubical.Data.Cardinality where - -open import Cubical.Data.Cardinality.Base public -open import Cubical.Data.Cardinality.Properties public diff --git a/Cubical/Data/Empty/Base.agda b/Cubical/Data/Empty/Base.agda index b126a028f1..2ed93831b5 100644 --- a/Cubical/Data/Empty/Base.agda +++ b/Cubical/Data/Empty/Base.agda @@ -20,3 +20,6 @@ rec* () elim : {A : ⊥ → Type ℓ} → (x : ⊥) → A x elim () + +elim* : {A : ⊥* {ℓ'} → Type ℓ} → (x : ⊥* {ℓ'}) → A x +elim* () diff --git a/Cubical/Data/Ordinal.agda b/Cubical/Data/Ordinal.agda new file mode 100644 index 0000000000..54a05cdc3f --- /dev/null +++ b/Cubical/Data/Ordinal.agda @@ -0,0 +1,5 @@ +{-# OPTIONS --safe #-} +module Cubical.Data.Ordinal where + +open import Cubical.Data.Ordinal.Base public +open import Cubical.Data.Ordinal.Properties public diff --git a/Cubical/Data/Ordinal/Base.agda b/Cubical/Data/Ordinal/Base.agda new file mode 100644 index 0000000000..116fb8c4f9 --- /dev/null +++ b/Cubical/Data/Ordinal/Base.agda @@ -0,0 +1,257 @@ +{- + +This file contains: + +- Ordinals as well-ordered sets + +-} +{-# OPTIONS --safe #-} +module Cubical.Data.Ordinal.Base where + +open import Cubical.Foundations.Prelude +open import Cubical.Foundations.HLevels +open import Cubical.Foundations.Equiv +open import Cubical.Foundations.Function +open import Cubical.Foundations.Structure + +open import Cubical.Data.Empty as ⊥ +open import Cubical.Data.Sigma +open import Cubical.Data.Sum as ⊎ +open import Cubical.Data.Unit + +open import Cubical.Induction.WellFounded + +open import Cubical.Relation.Binary.Base +open import Cubical.Relation.Binary.Extensionality +open import Cubical.Relation.Binary.Order.Woset + +private + variable + ℓ : Level + +infix 7 _·_ +infix 6 _+_ + +-- Ordinals are simply well-ordered sets +Ord : ∀ {ℓ} → Type _ +Ord {ℓ} = Woset ℓ ℓ + +isSetOrd : isSet (Ord {ℓ}) +isSetOrd = isSetWoset + +-- The successor ordinal is simply the union with unit +suc : Ord {ℓ} → Ord {ℓ} +suc {ℓ} (A , ordStr) = (A ⊎ Unit* {ℓ}) , wosetstr _≺_ iswos + where _≺ₐ_ = WosetStr._≺_ ordStr + wosA = WosetStr.isWoset ordStr + setA = IsWoset.is-set wosA + propA = IsWoset.is-prop-valued wosA + wellA = IsWoset.is-well-founded wosA + weakA = IsWoset.is-weakly-extensional wosA + transA = IsWoset.is-trans wosA + + + _≺_ : Rel (A ⊎ Unit* {ℓ}) (A ⊎ Unit* {ℓ}) ℓ + inl a ≺ inl b = a ≺ₐ b + inl _ ≺ inr * = Unit* {ℓ} + inr * ≺ _ = ⊥* {ℓ} + + open BinaryRelation + + set : isSet (A ⊎ Unit*) + set = isSet⊎ setA isSetUnit* + + prop : isPropValued _≺_ + prop (inl a) (inl b) = propA a b + prop (inl _) (inr *) = isPropUnit* + prop (inr *) _ = isProp⊥* + + well : WellFounded _≺_ + well (inl x) = WFI.induction wellA {P = λ x → Acc _≺_ (inl x)} + (λ _ ind → acc (λ { (inl y) → ind y + ; (inr *) () })) x + well (inr *) = acc (λ { (inl y) _ → well (inl y) + ; (inr *) () }) + + weak : isWeaklyExtensional _≺_ + weak = ≺×→≡→isWeaklyExtensional _≺_ set prop + λ { (inl x) (inl y) ex → cong inl + (isWeaklyExtensional→≺Equiv→≡ _≺ₐ_ weakA x y λ z + → propBiimpl→Equiv (propA z x) (propA z y) + (ex (inl z) .fst) + (ex (inl z) .snd)) + ; (inl x) (inr *) ex → ⊥.rec + (WellFounded→isIrrefl _≺ₐ_ wellA x (ex (inl x) .snd tt*)) + ; (inr *) (inl x) ex → ⊥.rec + (WellFounded→isIrrefl _≺ₐ_ wellA x (ex (inl x) .fst tt*)) + ; (inr *) (inr _) _ → refl + } + + trans : isTrans _≺_ + trans (inl a) (inl b) (inl c) = transA a b c + trans (inl _) (inl _) (inr *) _ _ = tt* + trans (inl a) (inr *) _ _ () + trans (inr *) _ _ () + + iswos : IsWoset _≺_ + iswos = iswoset set prop well weak trans + +-- Ordinal addition is handled similarly +_+_ : Ord {ℓ} → Ord {ℓ} → Ord {ℓ} +A + B = (⟨ A ⟩ ⊎ ⟨ B ⟩) , wosetstr _≺_ wos + where _≺ᵣ_ = WosetStr._≺_ (str A) + _≺ₛ_ = WosetStr._≺_ (str B) + + wosA = WosetStr.isWoset (str A) + setA = IsWoset.is-set wosA + propA = IsWoset.is-prop-valued wosA + wellA = IsWoset.is-well-founded wosA + weakA = IsWoset.is-weakly-extensional wosA + transA = IsWoset.is-trans wosA + + wosB = WosetStr.isWoset (str B) + setB = IsWoset.is-set wosB + propB = IsWoset.is-prop-valued wosB + wellB = IsWoset.is-well-founded wosB + weakB = IsWoset.is-weakly-extensional wosB + transB = IsWoset.is-trans wosB + + _≺_ : Rel (⟨ A ⟩ ⊎ ⟨ B ⟩) (⟨ A ⟩ ⊎ ⟨ B ⟩) _ + inl a₀ ≺ inl a₁ = a₀ ≺ᵣ a₁ + inl a₀ ≺ inr b₁ = Unit* + inr b₀ ≺ inl a₁ = ⊥* + inr b₀ ≺ inr b₁ = b₀ ≺ₛ b₁ + + open BinaryRelation + + set : isSet (⟨ A ⟩ ⊎ ⟨ B ⟩) + set = isSet⊎ setA setB + + prop : isPropValued _≺_ + prop (inl a₀) (inl a₁) = propA a₀ a₁ + prop (inl a₀) (inr b₁) = isPropUnit* + prop (inr b₀) (inl a₁) = isProp⊥* + prop (inr b₀) (inr b₁) = propB b₀ b₁ + + well : WellFounded _≺_ + well (inl a₀) = WFI.induction wellA {P = λ a → Acc _≺_ (inl a)} + (λ _ ind → acc λ { (inl a₁) → ind a₁ + ; (inr b₁) () }) a₀ + well (inr b₀) = WFI.induction wellB {P = λ b → Acc _≺_ (inr b)} + (λ _ ind → acc λ { (inl a₁) _ → well (inl a₁) + ; (inr b₁) → ind b₁ }) b₀ + + weak : isWeaklyExtensional _≺_ + weak = ≺×→≡→isWeaklyExtensional _≺_ set prop + λ { (inl a₀) (inl a₁) ex → cong inl + (isWeaklyExtensional→≺Equiv→≡ _≺ᵣ_ weakA a₀ a₁ λ c → + propBiimpl→Equiv (propA c a₀) (propA c a₁) + (ex (inl c) .fst) + (ex (inl c) .snd)) + ; (inl a₀) (inr _) ex → + ⊥.rec (WellFounded→isIrrefl _≺ᵣ_ wellA a₀ (ex (inl a₀) .snd tt*)) + ; (inr _) (inl a₁) ex → + ⊥.rec (WellFounded→isIrrefl _≺ᵣ_ wellA a₁ (ex (inl a₁) .fst tt*)) + ; (inr b₀) (inr b₁) ex → cong inr + (isWeaklyExtensional→≺Equiv→≡ _≺ₛ_ weakB b₀ b₁ λ c → + propBiimpl→Equiv (propB c b₀) (propB c b₁) + (ex (inr c) .fst) + (ex (inr c) .snd)) + } + + trans : isTrans _≺_ + trans (inl a) (inl b) (inl c) = transA a b c + trans (inl _) _ (inr _) _ _ = tt* + trans _ (inr _) (inl _) _ () + trans (inr _) (inl _) _ () + trans (inr a) (inr b) (inr c) = transB a b c + + wos : IsWoset _≺_ + wos = iswoset set prop well weak trans + +-- Ordinal multiplication is handled lexicographically +_·_ : Ord {ℓ} → Ord {ℓ} → Ord {ℓ} +A · B = ⟨ A ⟩ × ⟨ B ⟩ , wosetstr _≺_ wos + where _≺ᵣ_ = WosetStr._≺_ (str A) + _≺ₛ_ = WosetStr._≺_ (str B) + + wosA = WosetStr.isWoset (str A) + setA = IsWoset.is-set wosA + propA = IsWoset.is-prop-valued wosA + wellA = IsWoset.is-well-founded wosA + weakA = IsWoset.is-weakly-extensional wosA + transA = IsWoset.is-trans wosA + + wosB = WosetStr.isWoset (str B) + setB = IsWoset.is-set wosB + propB = IsWoset.is-prop-valued wosB + wellB = IsWoset.is-well-founded wosB + weakB = IsWoset.is-weakly-extensional wosB + transB = IsWoset.is-trans wosB + + _≺_ : Rel (⟨ A ⟩ × ⟨ B ⟩) (⟨ A ⟩ × ⟨ B ⟩) _ + (a₀ , b₀) ≺ (a₁ , b₁) = (b₀ ≺ₛ b₁) ⊎ ((b₀ ≡ b₁) × (a₀ ≺ᵣ a₁)) + + open BinaryRelation + + set : isSet (⟨ A ⟩ × ⟨ B ⟩) + set = isSet× setA setB + + prop : isPropValued _≺_ + prop (a₀ , b₀) (a₁ , b₁) + = isProp⊎ (propB _ _) (isProp× (setB _ _) (propA _ _)) + λ b₀≺b₁ (b₀≡b₁ , _) + → WellFounded→isIrrefl _≺ₛ_ wellB b₁ (subst (_≺ₛ b₁) b₀≡b₁ b₀≺b₁) + + well : WellFounded _≺_ + well (a₀ , b₀) = WFI.induction wellB {P = λ b → ∀ a → Acc _≺_ (a , b)} + (λ b₁ indB → WFI.induction wellA {P = λ a → Acc _≺_ (a , b₁)} + λ a₂ indA → acc λ { (a , b) (inl b≺b₁) → indB b b≺b₁ a + ; (a , b) (inr (b≡b₁ , a≺a₁)) + → subst (λ x → Acc _≺_ (a , x)) + (sym b≡b₁) + (indA a a≺a₁) }) b₀ a₀ + + weak : isWeaklyExtensional _≺_ + weak = ≺×→≡→isWeaklyExtensional _≺_ set prop λ (a₀ , b₀) (a₁ , b₁) ex → + ΣPathP ((isWeaklyExtensional→≺Equiv→≡ _≺ᵣ_ weakA a₀ a₁ + (λ a₂ → propBiimpl→Equiv (propA a₂ a₀) (propA a₂ a₁) + (λ a₂≺a₀ → ⊎.rec (λ b₀≺b₁ → ⊥.rec + (WellFounded→isIrrefl _≺ₛ_ wellB b₁ + (subst (_≺ₛ b₁) (lemma a₀ a₁ b₀ b₁ ex) b₀≺b₁))) snd + (ex (a₂ , b₀) .fst (inr (refl , a₂≺a₀)))) + λ a₂≺a₁ → ⊎.rec (λ b₁≺b₀ → ⊥.rec + (WellFounded→isIrrefl _≺ₛ_ wellB b₁ + (subst (b₁ ≺ₛ_) (lemma a₀ a₁ b₀ b₁ ex) b₁≺b₀))) snd + (ex (a₂ , b₁) .snd (inr (refl , a₂≺a₁))))) + , lemma a₀ a₁ b₀ b₁ ex) + where lemma : ∀ a₀ a₁ b₀ b₁ + → (∀ c → (c ≺ (a₀ , b₀) → c ≺ (a₁ , b₁)) + × (c ≺ (a₁ , b₁) → c ≺ (a₀ , b₀))) + → b₀ ≡ b₁ + lemma a₀ a₁ b₀ b₁ ex + = isWeaklyExtensional→≺Equiv→≡ _≺ₛ_ weakB b₀ b₁ + λ b₂ → propBiimpl→Equiv (propB b₂ b₀) (propB b₂ b₁) + (λ b₂≺b₀ → ⊎.rec (λ b₂≺b₁ → b₂≺b₁) + (λ (_ , a₁≺a₁) + → ⊥.rec (WellFounded→isIrrefl _≺ᵣ_ wellA a₁ a₁≺a₁)) + (ex (a₁ , b₂) .fst (inl b₂≺b₀))) + λ b₂≺b₁ → ⊎.rec (λ b₂≺b₀ → b₂≺b₀) + (λ (_ , a₀≺a₀) + → ⊥.rec (WellFounded→isIrrefl _≺ᵣ_ wellA a₀ a₀≺a₀)) + (ex (a₀ , b₂) .snd (inl b₂≺b₁)) + + trans : isTrans _≺_ + trans (_ , b₀) (_ , b₁) (_ , b₂) (inl b₀≺b₁) (inl b₁≺b₂) + = inl (transB b₀ b₁ b₂ b₀≺b₁ b₁≺b₂) + trans (_ , b₀) _ _ (inl b₀≺b₁) (inr (b₁≡b₂ , _)) + = inl (subst (b₀ ≺ₛ_) b₁≡b₂ b₀≺b₁) + trans _ _ (_ , b₂) (inr (b₀≡b₁ , _)) (inl b₁≺b₂) + = inl (subst (_≺ₛ b₂) (sym b₀≡b₁) b₁≺b₂) + trans (a₀ , _) (a₁ , _) (a₂ , _) + (inr (b₀≡b₁ , a₀≺a₁)) + (inr (b₁≡b₂ , a₁≺a₂)) + = inr ((b₀≡b₁ ∙ b₁≡b₂) , (transA a₀ a₁ a₂ a₀≺a₁ a₁≺a₂)) + + wos : IsWoset _≺_ + wos = iswoset set prop well weak trans diff --git a/Cubical/Data/Ordinal/Properties.agda b/Cubical/Data/Ordinal/Properties.agda new file mode 100644 index 0000000000..0cfbd9d98c --- /dev/null +++ b/Cubical/Data/Ordinal/Properties.agda @@ -0,0 +1,299 @@ +{- + +This file contains: + +- Properties of ordinals + +-} +{-# OPTIONS --safe #-} +module Cubical.Data.Ordinal.Properties where + +open import Cubical.Foundations.Prelude +open import Cubical.Foundations.Structure +open import Cubical.Foundations.Equiv +open import Cubical.Foundations.Function +open import Cubical.Foundations.Isomorphism + +open import Cubical.Functions.Embedding + +open import Cubical.Data.Ordinal.Base +open import Cubical.Data.Empty as ⊥ using (⊥ ; ⊥* ; isProp⊥*) +open import Cubical.Data.Sigma +open import Cubical.Data.Sum as ⊎ hiding (rec ; elim ; map) +open import Cubical.Data.Unit + +open import Cubical.Induction.WellFounded + +open import Cubical.Relation.Binary.Base +open import Cubical.Relation.Binary.Extensionality +open import Cubical.Relation.Binary.Order.Woset +open import Cubical.Relation.Binary.Order.Woset.Simulation +open import Cubical.Relation.Binary.Order + +private + variable + ℓ : Level + +propOrd : (P : Type ℓ) → isProp P → Ord {ℓ} +propOrd {ℓ} P prop = P , (wosetstr _<_ (iswoset set prp well weak trans)) + where + open BinaryRelation + _<_ : P → P → Type ℓ + a < b = ⊥*{ℓ} + + set : isSet P + set = isProp→isSet prop + + prp : isPropValued _<_ + prp _ _ = isProp⊥* + + well : WellFounded _<_ + well _ = acc (λ _ → ⊥.elim*) + + weak : isWeaklyExtensional _<_ + weak = ≺×→≡→isWeaklyExtensional _<_ set prp λ x y _ → prop x y + + trans : isTrans _<_ + trans _ _ _ = ⊥.elim* + +𝟘 𝟙 : Ord {ℓ} +𝟘 {ℓ} = propOrd (⊥* {ℓ}) (isProp⊥*) +𝟙 {ℓ} = propOrd (Unit* {ℓ}) (isPropUnit*) + +isLeast𝟘 : ∀{ℓ} → isLeast (isPoset→isPreorder isPoset≼) ((Ord {ℓ}) , (id↪ (Ord {ℓ}))) (𝟘 {ℓ}) +isLeast𝟘 _ = ⊥.elim* , (⊥.elim* , ⊥.elim*) + +-- The successor of 𝟘 is 𝟙 +suc𝟘 : suc (𝟘 {ℓ}) ≡ 𝟙 {ℓ} +suc𝟘 = equivFun (WosetPath _ _) (eq , makeIsWosetEquiv eq eqsuc λ _ _ → ⊥.elim*) + where + eq : ⟨ 𝟘 ⟩ ⊎ Unit* ≃ ⟨ 𝟙 ⟩ + eq = ⊎-IdL-⊥*-≃ + + eqsuc : _ + eqsuc (inr x) (inr y) = ⊥.elim* + ++IdR : (α : Ord {ℓ}) → α + 𝟘 {ℓ} ≡ α ++IdR α = equivFun (WosetPath _ _) (eq , (makeIsWosetEquiv eq eqα λ _ _ x≺y → x≺y)) + where + eq : ⟨ α ⟩ ⊎ ⟨ 𝟘 ⟩ ≃ ⟨ α ⟩ + eq = ⊎-IdR-⊥*-≃ + + eqα : _ + eqα (inl x) (inl y) x≺y = x≺y + ++IdL : (α : Ord {ℓ}) → 𝟘 {ℓ} + α ≡ α ++IdL α = equivFun (WosetPath _ _) (eq , (makeIsWosetEquiv eq eqα λ _ _ x≺y → x≺y)) + where + eq : ⟨ 𝟘 ⟩ ⊎ ⟨ α ⟩ ≃ ⟨ α ⟩ + eq = ⊎-IdL-⊥*-≃ + + eqα : (x y : ⟨ 𝟘 ⟩ ⊎ ⟨ α ⟩) + → ((𝟘 + α) .snd WosetStr.≺ x) y + → (α .snd WosetStr.≺ equivFun eq x) (equivFun eq y) + eqα (inr x) (inr y) x≺y = x≺y + +-- The successor is just addition by 𝟙 +suc≡+𝟙 : (α : Ord {ℓ}) → suc α ≡ α + 𝟙 {ℓ} +suc≡+𝟙 α = equivFun (WosetPath _ _) (eq , (makeIsWosetEquiv eq eqsucα eqα+𝟙)) + where + eq : ⟨ suc α ⟩ ≃ ⟨ α ⟩ ⊎ ⟨ 𝟙 ⟩ + eq = idEquiv ⟨ suc α ⟩ + + eqsucα : _ + eqsucα (inl x) (inl y) x≺y = x≺y + eqsucα (inl x) (inr y) _ = tt* + eqsucα (inr x) (inl y) = ⊥.elim* + eqsucα (inr x) (inr y) = ⊥.elim* + + eqα+𝟙 : _ + eqα+𝟙 (inl x) (inl y) x≺y = x≺y + eqα+𝟙 (inl x) (inr y) _ = tt* + eqα+𝟙 (inr x) (inl y) = ⊥.elim* + eqα+𝟙 (inr x) (inr y) = ⊥.elim* + +-- Successor is strictly increasing, though we can't prove it's the smallest ordinal greater than its predecessor +suc≺ : (α : Ord {ℓ}) → α ≺ suc α +suc≺ α = (inr tt*) , (eq , makeIsWosetEquiv eq eqsucα eqαsuc) + where + fun : ⟨ suc α ↓ inr tt* ⟩ → ⟨ α ⟩ + fun (inl a , _) = a + + iseq : isEquiv fun + fst (fst (equiv-proof iseq a)) = (inl a) , tt* + snd (fst (equiv-proof iseq a)) = refl + snd (equiv-proof iseq a) ((inl x , _) , x≡a) + = Σ≡Prop (λ _ → IsWoset.is-set (WosetStr.isWoset (str α)) _ _) + (Σ≡Prop lem (cong inl (sym x≡a))) + where lem : (y : ⟨ suc α ⟩) → isProp _ + lem (inl y) = isPropUnit* + lem (inr _) = ⊥.elim* + eq : ⟨ suc α ↓ inr tt* ⟩ ≃ ⟨ α ⟩ + eq = fun , iseq + + eqsucα : _ + eqsucα (inl x , _) (inl y , _) x