diff --git a/#foo.agda# b/#foo.agda# new file mode 100644 index 0000000..eb6e959 --- /dev/null +++ b/#foo.agda# @@ -0,0 +1,2 @@ +A → A ⇀ A +♯ A → ♯ A → ♯ A \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0b1e34b --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +check: + cd src + agda --html --html-dir=docs ./index.agda + +commit_message = Commit [Automated by Make] +commit: + git add . && git commit -m '${commit_message}' + +push : commit + git push origin master diff --git a/Makefile~ b/Makefile~ new file mode 100644 index 0000000..336d80e --- /dev/null +++ b/Makefile~ @@ -0,0 +1,10 @@ +check: + cd src + agda --html --html-dir=docs ./index.agda + +commit_message = Commit [Automated by Make] +commit: check + git add . && git commit -m '${commit_message}' + +push : commit + git push origin master diff --git a/docs/Cubical.Data.Fin.Base.html b/docs/Cubical.Data.Fin.Base.html new file mode 100644 index 0000000..f65df59 --- /dev/null +++ b/docs/Cubical.Data.Fin.Base.html @@ -0,0 +1,113 @@ + +Cubical.Data.Fin.Base
{-# OPTIONS --safe #-}
+
+module Cubical.Data.Fin.Base where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.HLevels
+
+import Cubical.Data.Empty as 
+open import Cubical.Data.Nat using ( ; zero ; suc ; _+_ ; znots)
+open import Cubical.Data.Nat.Order
+open import Cubical.Data.Nat.Order.Recursive using () renaming (_≤_ to _≤′_)
+open import Cubical.Data.Sigma
+open import Cubical.Data.Sum using (_⊎_; _⊎?_; inl; inr)
+
+open import Cubical.Relation.Nullary
+
+-- Finite types.
+--
+-- Currently it is most convenient to define these as a subtype of the
+-- natural numbers, because indexed inductive definitions don't behave
+-- well with cubical Agda. This definition also has some more general
+-- attractive properties, of course, such as easy conversion back to
+-- ℕ.
+Fin :   Type₀
+Fin n = Σ[ k   ] k < n
+
+private
+  variable
+     : Level
+    k : 
+
+fzero : Fin (suc k)
+fzero = (0 , suc-≤-suc zero-≤)
+
+fone : Fin (suc (suc k))
+fone = (1 , suc-≤-suc (suc-≤-suc zero-≤))
+
+fzero≠fone : ¬ fzero {k = suc k}  fone
+fzero≠fone p = znots (cong fst p)
+
+-- It is easy, using this representation, to take the successor of a
+-- number as a number in the next largest finite type.
+fsuc : Fin k  Fin (suc k)
+fsuc (k , l) = (suc k , suc-≤-suc l)
+
+-- Conversion back to ℕ is trivial...
+toℕ : Fin k  
+toℕ = fst
+
+-- ... and injective.
+toℕ-injective : ∀{fj fk : Fin k}  toℕ fj  toℕ fk  fj  fk
+toℕ-injective {fj = fj} {fk} = Σ≡Prop  _  isProp≤)
+
+-- Conversion from ℕ with a recursive definition of ≤
+
+fromℕ≤ : (m n : )  m ≤′ n  Fin (suc n)
+fromℕ≤ zero    _       _    = fzero
+fromℕ≤ (suc m) (suc n) m≤n = fsuc (fromℕ≤ m n m≤n)
+
+-- A case analysis helper for induction.
+fsplit
+  : ∀(fj : Fin (suc k))
+   (fzero  fj)  (Σ[ fk  Fin k ] fsuc fk  fj)
+fsplit (0 , k<sn) = inl (toℕ-injective refl)
+fsplit (suc k , k<sn) = inr ((k , pred-≤-pred k<sn) , toℕ-injective refl)
+
+inject< :  {m n} (m<n : m < n)  Fin m  Fin n
+inject< m<n (k , k<m) = k , <-trans k<m m<n
+
+flast : Fin (suc k)
+flast {k = k} = k , suc-≤-suc ≤-refl
+
+-- Fin 0 is empty
+¬Fin0 : ¬ Fin 0
+¬Fin0 (k , k<0) = ¬-<-zero k<0
+
+-- The full inductive family eliminator for finite types.
+elim
+  : ∀(P : ∀{k}  Fin k  Type )
+   (∀{k}  P {suc k} fzero)
+   (∀{k} {fn : Fin k}  P fn  P (fsuc fn))
+   {k : }  (fn : Fin k)  P fn
+elim P fz fs {zero} = ⊥.rec  ¬Fin0
+elim P fz fs {suc k} fj
+  = case fsplit fj return  _  P fj) of λ
+  { (inl p)  subst P p fz
+  ; (inr (fk , p))  subst P p (fs (elim P fz fs fk))
+  }
+
+any? :  {n} {P : Fin n  Type }  (∀ i  Dec (P i))  Dec (Σ (Fin n) P)
+any? {n = zero}  {P = _} P? = no  (x , _)  ¬Fin0 x)
+any? {n = suc n} {P = P} P? =
+  mapDec
+    
+      { (inl P0)  fzero , P0
+      ; (inr (x , Px))  fsuc x , Px
+      }
+    )
+     n h  n (helper h))
+    (P? fzero ⊎? any? (P?  fsuc))
+  where
+    helper : Σ (Fin (suc n)) P  P fzero  Σ (Fin n) λ z  P (fsuc z)
+    helper (x , Px) with fsplit x
+    ... | inl x≡0 = inl (subst P (sym x≡0) Px)
+    ... | inr (k , x≡sk) = inr (k , subst P (sym x≡sk) Px)
+
+FinPathℕ : {n : } (x : Fin n) (y : )  fst x  y  Σ[ p  _ ] (x  (y , p))
+FinPathℕ {n = n} x y p =
+    ((fst (snd x)) , (cong  y  fst (snd x) + y) (cong suc (sym p))  snd (snd x)))
+  , (Σ≡Prop  _  isProp≤) p)
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Fin.Literals.html b/docs/Cubical.Data.Fin.Literals.html new file mode 100644 index 0000000..d86ae7b --- /dev/null +++ b/docs/Cubical.Data.Fin.Literals.html @@ -0,0 +1,20 @@ + +Cubical.Data.Fin.Literals
{-# OPTIONS --no-exact-split --safe #-}
+module Cubical.Data.Fin.Literals where
+
+open import Agda.Builtin.Nat
+  using (suc)
+open import Agda.Builtin.FromNat
+  renaming (Number to HasFromNat)
+open import Cubical.Data.Fin.Base
+  using (Fin; fromℕ≤)
+open import Cubical.Data.Nat.Order.Recursive
+  using (_≤_)
+
+instance
+  fromNatFin : {n : _}  HasFromNat (Fin (suc n))
+  fromNatFin {n} = record
+    { Constraint = λ m  m  n
+    ; fromNat    = λ m  m≤n   fromℕ≤ m n m≤n
+    }
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Fin.Properties.html b/docs/Cubical.Data.Fin.Properties.html new file mode 100644 index 0000000..54d3716 --- /dev/null +++ b/docs/Cubical.Data.Fin.Properties.html @@ -0,0 +1,684 @@ + +Cubical.Data.Fin.Properties
{-# OPTIONS --safe #-}
+
+module Cubical.Data.Fin.Properties where
+
+open import Cubical.Core.Everything
+
+open import Cubical.Functions.Embedding
+open import Cubical.Functions.Surjection
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.HLevels
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Univalence
+open import Cubical.Foundations.Transport
+
+open import Cubical.HITs.PropositionalTruncation renaming (rec to ∥∥rec)
+
+open import Cubical.Data.Fin.Base as Fin
+open import Cubical.Data.Nat
+open import Cubical.Data.Nat.Order
+open import Cubical.Data.Empty as Empty
+open import Cubical.Data.Unit
+open import Cubical.Data.Sum
+open import Cubical.Data.Sigma
+open import Cubical.Data.FinData.Base renaming (Fin to FinData) hiding (¬Fin0 ; toℕ)
+
+open import Cubical.Relation.Nullary
+
+open import Cubical.Induction.WellFounded
+
+open import Cubical.Relation.Nullary
+
+private
+ variable
+   a b  : Level
+   n : 
+   A : Type a
+
+-- Fin 0 is empty, and thus a proposition.
+isPropFin0 : isProp (Fin 0)
+isPropFin0 = Empty.rec  ¬Fin0
+
+-- Fin 1 has only one value.
+isContrFin1 : isContr (Fin 1)
+isContrFin1
+  = fzero , λ
+  { (zero , _)  toℕ-injective refl
+  ; (suc k , sk<1)  Empty.rec (¬-<-zero (pred-≤-pred sk<1))
+  }
+
+Unit≃Fin1 : Unit  Fin 1
+Unit≃Fin1 =
+  isoToEquiv
+    (iso
+      (const fzero)
+      (const tt)
+      (isContrFin1 .snd)
+      (isContrUnit .snd)
+    )
+
+-- Regardless of k, Fin k is a set.
+isSetFin : ∀{k}  isSet (Fin k)
+isSetFin {k} = isSetΣ isSetℕ  _  isProp→isSet isProp≤)
+
+discreteFin :  {n}  Discrete (Fin n)
+discreteFin {n} (x , hx) (y , hy) with discreteℕ x y
+... | yes prf = yes (Σ≡Prop  _  isProp≤) prf)
+... | no prf = no λ h  prf (cong fst h)
+
+inject<-ne :  {n} (i : Fin n)  ¬ inject< ≤-refl i  (n , ≤-refl)
+inject<-ne {n} (k , k<n) p = <→≢ k<n (cong fst p)
+
+Fin-fst-≡ :  {n} {i j : Fin n}  fst i  fst j  i  j
+Fin-fst-≡ = Σ≡Prop  _  isProp≤)
+
+private
+  subst-app : (B : A  Type b) (f : (x : A)  B x) {x y : A} (x≡y : x  y) 
+              subst B x≡y (f x)  f y
+  subst-app B f {x = x} =
+    J  y e  subst B e (f x)  f y) (substRefl {B = B} (f x))
+
+-- Computation rules for the eliminator.
+module _ (P :  {k}  Fin k  Type )
+         (fz :  {k}  P {suc k} fzero)
+         (fs :  {k} {fn : Fin k}  P fn  P (fsuc fn))
+         {k : } where
+  elim-fzero : Fin.elim P fz fs {k = suc k} fzero  fz
+  elim-fzero =
+    subst P (toℕ-injective _) fz ≡⟨ cong  p  subst P p fz) (isSetFin _ _ _ _) 
+    subst P refl fz              ≡⟨ substRefl {B = P} fz 
+    fz                           
+
+  elim-fsuc : (fk : Fin k)  Fin.elim P fz fs (fsuc fk)  fs (Fin.elim P fz fs fk)
+  elim-fsuc fk =
+    subst P (toℕ-injective  _  toℕ (fsuc fk′))) (fs (Fin.elim P fz fs fk′))
+      ≡⟨ cong  p  subst P p (fs (Fin.elim P fz fs fk′)) ) (isSetFin _ _ _ _) 
+    subst P (cong fsuc fk′≡fk) (fs (Fin.elim P fz fs fk′))
+      ≡⟨ subst-app _  fj  fs (Fin.elim P fz fs fj)) fk′≡fk 
+    fs (Fin.elim P fz fs fk)
+      
+    where
+    fk′ = fst fk , pred-≤-pred (snd (fsuc fk))
+    fk′≡fk : fk′  fk
+    fk′≡fk = toℕ-injective refl
+
+-- Helper function for the reduction procedure below.
+--
+-- If n = expand o k m, then n is congruent to m modulo k.
+expand :       
+expand 0 k m = m
+expand (suc o) k m = k + expand o k m
+
+expand≡ :  k m o  expand o k m  o · k + m
+expand≡ k m zero = refl
+expand≡ k m (suc o)
+  = cong (k +_) (expand≡ k m o)  +-assoc k (o · k) m
+
+-- Expand a pair. This is useful because the whole function is
+-- injective.
+expand× : ∀{k}  (Fin k × )  
+expand× {k} (f , o) = expand o k (toℕ f)
+
+private
+  lemma₀ : ∀{k m n r}  r  n  k + m  n  k  r
+  lemma₀ {k = k} {m} p q = m , +-comm m k  q  sym p
+
+  expand×Inj :  k  {t1 t2 : Fin (suc k) × }  expand× t1  expand× t2  t1  t2
+  expand×Inj k {f1 , zero} {f2 , zero} p i
+    = toℕ-injective {fj = f1} {f2} p i , zero
+  expand×Inj k {f1 , suc o1} {(r , r<sk) , zero} p
+    = Empty.rec (<-asym r<sk (lemma₀ refl p))
+  expand×Inj k {(r , r<sk) , zero} {f2 , suc o2} p
+    = Empty.rec (<-asym r<sk (lemma₀ refl (sym p)))
+  expand×Inj k {f1 , suc o1} {f2 , suc o2}
+    = cong  { (f , o)  (f , suc o) })
+     expand×Inj k {f1 , o1} {f2 , o2}
+     inj-m+ {suc k}
+
+  expand×Emb :  k  isEmbedding (expand× {k})
+  expand×Emb 0 = Empty.rec  ¬Fin0  fst
+  expand×Emb (suc k)
+    = injEmbedding isSetℕ (expand×Inj k)
+
+-- A Residue is a family of types representing evidence that a
+-- natural is congruent to a value of a finite type.
+Residue :     Type₀
+Residue k n = Σ[ tup  Fin k ×  ] expand× tup  n
+
+-- There is at most one canonical finite value congruent to each
+-- natural.
+isPropResidue :  k n  isProp (Residue k n)
+isPropResidue k = isEmbedding→hasPropFibers (expand×Emb k)
+
+-- A value of a finite type is its own residue.
+Fin→Residue : ∀{k}  (f : Fin k)  Residue k (toℕ f)
+Fin→Residue f = (f , 0) , refl
+
+-- Fibers of numbers that differ by k are equivalent in a more obvious
+-- way than via the fact that they are propositions.
+Residue+k : (k n : )  Residue k n  Residue k (k + n)
+Residue+k k n ((f , o) , p) = (f , suc o) , cong (k +_) p
+
+Residue-k : (k n : )  Residue k (k + n)  Residue k n
+Residue-k k n (((r , r<k) , zero) , p) = Empty.rec (<-asym r<k (lemma₀ p refl))
+Residue-k k n ((f , suc o) , p) = ((f , o) , inj-m+ p)
+
+Residue+k-k
+  : (k n : )
+   (R : Residue k (k + n))
+   Residue+k k n (Residue-k k n R)  R
+Residue+k-k k n (((r , r<k) , zero) , p) = Empty.rec (<-asym r<k (lemma₀ p refl))
+Residue+k-k k n ((f , suc o) , p)
+  = Σ≡Prop  tup  isSetℕ (expand× tup) (k + n)) refl
+
+Residue-k+k
+  : (k n : )
+   (R : Residue k n)
+   Residue-k k n (Residue+k k n R)  R
+Residue-k+k k n ((f , o) , p)
+  = Σ≡Prop  tup  isSetℕ (expand× tup) n) refl
+
+private
+  Residue≃ :  k n  Residue k n  Residue k (k + n)
+  Residue≃ k n
+    = Residue+k k n
+    , isoToIsEquiv (iso (Residue+k k n) (Residue-k k n)
+                        (Residue+k-k k n) (Residue-k+k k n))
+
+Residue≡ :  k n  Residue k n  Residue k (k + n)
+Residue≡ k n = ua (Residue≃ k n)
+
+-- For positive `k`, all `n` have a canonical residue mod `k`.
+module Reduce (k₀ : ) where
+  k : 
+  k = suc k₀
+
+  base :  n (n<k : n < k)  Residue k n
+  base n n<k = Fin→Residue (n , n<k)
+
+  step :  n  Residue k n  Residue k (k + n)
+  step n = transport (Residue≡ k n)
+
+  reduce :  n  Residue k n
+  reduce = +induction k₀ (Residue k) base step
+
+  reduce≡
+    :  n  transport (Residue≡ k n) (reduce n)  reduce (k + n)
+  reduce≡ n
+    = sym (+inductionStep k₀ _ base step n)
+
+  reduceP
+    :  n  PathP  i  Residue≡ k n i) (reduce n) (reduce (k + n))
+  reduceP n = toPathP (reduce≡ n)
+
+open Reduce using (reduce; reduce≡) public
+
+extract : ∀{k n}  Residue k n  Fin k
+extract = fst  fst
+
+private
+  lemma₅
+    :  k n (R : Residue k n)
+      extract R  extract (transport (Residue≡ k n) R)
+  lemma₅ k n = sym  cong extract  uaβ (Residue≃ k n)
+
+-- The residue of n modulo k is the same as the residue of k + n.
+extract≡ :  k n  extract (reduce k n)  extract (reduce k (suc k + n))
+extract≡ k n
+  = lemma₅ (suc k) n (reduce k n)  cong extract (Reduce.reduce≡ k n)
+
+isContrResidue : ∀{k n}  isContr (Residue (suc k) n)
+isContrResidue {k} {n} = inhProp→isContr (reduce k n) (isPropResidue (suc k) n)
+
+-- the modulo operator on ℕ
+
+_%_ :     
+n % zero = n
+n % (suc k) = toℕ (extract (reduce k n))
+
+_/_ :     
+n / zero = zero
+n / (suc k) = reduce k n .fst .snd
+
+moddiv :  n k  (n / k) · k + n % k  n
+moddiv n zero = refl
+moddiv n (suc k) = sym (expand≡ _ _ (n / suc k))  reduce k n .snd
+
+n%k≡n[modk] :  n k  Σ[ o   ] o · k + n % k  n
+n%k≡n[modk] n k = (n / k) , moddiv n k
+
+n%sk<sk : (n k : )  (n % suc k) < suc k
+n%sk<sk n k = extract (reduce k n) .snd
+
+fznotfs :  {m : } {k : Fin m}  ¬ fzero  fsuc k
+fznotfs {m} p = subst F p tt
+  where
+    F : Fin (suc m)  Type₀
+    F (zero , _) = Unit
+    F (suc _ , _) = 
+
+fsuc-inj : {fj fk : Fin n}  fsuc fj  fsuc fk  fj  fk
+fsuc-inj = toℕ-injective  injSuc  cong toℕ
+
+punchOut :  {m} {i j : Fin (suc m)}  (¬ i  j)  Fin m
+punchOut {_} {i} {j} p with fsplit i | fsplit j
+punchOut {_} {i} {j} p | inl prfi | inl prfj =
+  Empty.elim (p (i ≡⟨ sym prfi  fzero ≡⟨ prfj  j ))
+punchOut {_} {i} {j} p | inl prfi | inr (kj , prfj) =
+  kj
+punchOut {zero} {i} {j} p  | inr (ki , prfi) | inl prfj =
+  Empty.elim (p (
+    i ≡⟨ sym (isContrFin1 .snd i) 
+    c ≡⟨ isContrFin1 .snd j 
+    j 
+  ))
+  where c = isContrFin1 .fst
+punchOut {suc _} {i} {j} p | inr (ki , prfi) | inl prfj =
+  fzero
+punchOut {zero} {i} {j} p | inr (ki , prfi) | inr (kj , prfj) =
+  Empty.elim ((p (
+    i ≡⟨ sym (isContrFin1 .snd i) 
+    c ≡⟨ isContrFin1 .snd j 
+    j )
+  ))
+  where c = isContrFin1 .fst
+punchOut {suc _} {i} {j} p | inr (ki , prfi) | inr (kj , prfj) =
+  fsuc (punchOut {i = ki} {j = kj}
+     q  p (i ≡⟨ sym prfi  fsuc ki ≡⟨ cong fsuc q  fsuc kj ≡⟨ prfj  j ))
+  )
+
+punchOut-inj
+  :  {m} {i j k : Fin (suc m)} (i≢j : ¬ i  j) (i≢k : ¬ i  k)
+   punchOut i≢j  punchOut i≢k  j  k
+punchOut-inj {_} {i} {j} {k} i≢j i≢k p with fsplit i | fsplit j | fsplit k
+punchOut-inj {zero} {i} {j} {k} i≢j i≢k p | _ | _ | _ =
+  Empty.elim (i≢j (i ≡⟨ sym (isContrFin1 .snd i)  c ≡⟨ isContrFin1 .snd j  j ))
+    where c = isContrFin1 .fst
+punchOut-inj {suc _} {i} {j} {k} i≢j i≢k p | inl prfi | inl prfj | _ =
+  Empty.elim (i≢j (i ≡⟨ sym prfi  fzero ≡⟨ prfj  j ))
+punchOut-inj {suc _} {i} {j} {k} i≢j i≢k p | inl prfi | _ | inl prfk =
+  Empty.elim (i≢k (i ≡⟨ sym prfi  fzero ≡⟨ prfk  k ))
+punchOut-inj {suc _} {i} {j} {k} i≢j i≢k p | inl prfi | inr (kj , prfj) | inr (kk , prfk) =
+  j       ≡⟨ sym prfj 
+  fsuc kj ≡⟨ cong fsuc p 
+  fsuc kk ≡⟨ prfk 
+  k       
+punchOut-inj {suc _} {i} {j} {k} i≢j i≢k p | inr (ki , prfi) | inl prfj | inl prfk =
+  j     ≡⟨ sym prfj 
+  fzero ≡⟨ prfk 
+  k     
+punchOut-inj {suc _} {i} {j} {k} i≢j i≢k p | inr (ki , prfi) | inr (kj , prfj) | inr (kk , prfk) =
+  j ≡⟨ sym prfj 
+  fsuc kj ≡⟨ cong fsuc lemma4 
+  fsuc kk ≡⟨ prfk 
+  k 
+  where
+    lemma1 = λ q  i≢j (i ≡⟨ sym prfi  fsuc ki ≡⟨ cong fsuc q  fsuc kj ≡⟨ prfj  j )
+    lemma2 = λ q  i≢k (i ≡⟨ sym prfi  fsuc ki ≡⟨ cong fsuc q  fsuc kk ≡⟨ prfk  k )
+    lemma3 = fsuc-inj p
+    lemma4 = punchOut-inj lemma1 lemma2 lemma3
+punchOut-inj {suc m} {i} {j} {k} i≢j i≢k p | inr (ki , prfi) | inl prfj | inr (kk , prfk) =
+  Empty.rec (fznotfs p)
+punchOut-inj {suc _} {i} {j} {k} i≢j i≢k p | inr (ki , prfi) | inr (kj , prfj) | inl prfk =
+  Empty.rec (fznotfs (sym p))
+
+pigeonhole-special
+  :  {n}
+   (f : Fin (suc n)  Fin n)
+   Σ[ i  Fin (suc n) ] Σ[ j  Fin (suc n) ] (¬ i  j) × (f i  f j)
+pigeonhole-special {zero} f = Empty.rec (¬Fin0 (f fzero))
+pigeonhole-special {suc n} f =
+  proof (any?
+     (i : Fin (suc n)) 
+      discreteFin (f (inject< ≤-refl i)) (f (suc n , ≤-refl))
+    ))
+  where
+    proof
+      : Dec (Σ (Fin (suc n))  z  f (inject< ≤-refl z)  f (suc n , ≤-refl)))
+       Σ[ i  Fin (suc (suc n)) ] Σ[ j  Fin (suc (suc n)) ] (¬ i  j) × (f i  f j)
+    proof (yes (i , prf)) = inject< ≤-refl i , (suc n , ≤-refl) , inject<-ne i , prf
+    proof (no h) =
+      let
+        g : Fin (suc n)  Fin n
+        g k = punchOut
+          {i = f (suc n , ≤-refl)}
+          {j = f (inject< ≤-refl k)}
+           p  h (k , Fin-fst-≡ (sym (cong fst p))))
+        i , j , i≢j , p = pigeonhole-special g
+      in
+        inject< ≤-refl i
+      , inject< ≤-refl j
+      ,  q  i≢j (Fin-fst-≡ (cong fst q)))
+      , punchOut-inj
+          {i = f (suc n , ≤-refl)}
+          {j = f (inject< ≤-refl i)}
+          {k = f (inject< ≤-refl j)}
+           q  h (i , Fin-fst-≡ (sym (cong fst q))))
+           q  h (j , Fin-fst-≡ (sym (cong fst q))))
+          (Fin-fst-≡ (cong fst p))
+
+pigeonhole
+  :  {m n}
+   m < n
+   (f : Fin n  Fin m)
+   Σ[ i  Fin n ] Σ[ j  Fin n ] (¬ i  j) × (f i  f j)
+pigeonhole {m} {n} (zero , sm≡n) f =
+  transport transport-prf (pigeonhole-special f′)
+  where
+    f′ : Fin (suc m)  Fin m
+    f′ = subst  h  Fin h  Fin m) (sym sm≡n) f
+
+    f′≡f : PathP  i  Fin (sm≡n i)  Fin m) f′ f
+    f′≡f i = transport-fillerExt (cong  h  Fin h  Fin m) (sym sm≡n)) (~ i) f
+
+    transport-prf
+      : (Σ[ i  Fin (suc m) ] Σ[ j  Fin (suc m) ] (¬ i  j) × (f′ i  f′ j))
+       (Σ[ i  Fin n ] Σ[ j  Fin n ] (¬ i  j) × (f i  f j))
+    transport-prf φ =
+      Σ[ i  Fin (sm≡n φ) ] Σ[ j  Fin (sm≡n φ) ]
+        (¬ i  j) × (f′≡f φ i  f′≡f φ j)
+pigeonhole {m} {n} (suc k , prf) f =
+  let
+    g : Fin (suc n′)  Fin n′
+    g k = fst (f′ k) , <-trans (snd (f′ k)) m<n′
+    i , j , ¬q , r = pigeonhole-special g
+  in transport transport-prf (i , j , ¬q , Σ≡Prop  _  isProp≤) (cong fst r))
+  where
+    n′ : 
+    n′ = k + suc m
+
+    n≡sn′ : n  suc n′
+    n≡sn′ =
+      n ≡⟨ sym prf 
+      suc (k + suc m) ≡⟨ refl 
+      suc n′ 
+
+    m<n′ : m < n′
+    m<n′ = k , injSuc (suc (k + suc m) ≡⟨ prf  n ≡⟨ n≡sn′  suc n′ )
+
+    f′ : Fin (suc n′)  Fin m
+    f′ = subst  h  Fin h  Fin m) n≡sn′ f
+
+    f′≡f : PathP  i  Fin (n≡sn′ (~ i))  Fin m) f′ f
+    f′≡f i = transport-fillerExt (cong  h  Fin h  Fin m) n≡sn′) (~ i) f
+
+    transport-prf
+      : (Σ[ i  Fin (suc n′) ] Σ[ j  Fin (suc n′) ] (¬ i  j) × (f′ i  f′ j))
+       (Σ[ i  Fin n ] Σ[ j  Fin n ] (¬ i  j) × (f i  f j))
+    transport-prf φ =
+      Σ[ i  Fin (n≡sn′ (~ φ)) ] Σ[ j  Fin (n≡sn′ (~ φ)) ]
+        (¬ i  j) × (f′≡f φ i  f′≡f φ j)
+
+Fin-inj′ : {n m : }  n < m  ¬ Fin m  Fin n
+Fin-inj′ n<m p =
+  let
+    i , j , i≢j , q = pigeonhole n<m (transport p)
+  in i≢j (
+    i ≡⟨ refl 
+    fst (pigeonhole n<m (transport p)) ≡⟨ transport-p-inj {p = p} q 
+    fst (snd (pigeonhole n<m (transport p))) ≡⟨ refl 
+    j 
+  )
+  where
+    transport-p-inj
+      :  {A B : Type } {x y : A} {p : A  B}
+       transport p x  transport p y
+       x  y
+    transport-p-inj {x = x} {y = y} {p = p} q =
+      x ≡⟨ sym (transport⁻Transport p x) 
+      transport (sym p) (transport p x) ≡⟨ cong (transport (sym p)) q 
+      transport (sym p) (transport p y) ≡⟨ transport⁻Transport p y 
+      y 
+
+Fin-inj : (n m : )  Fin n  Fin m  n  m
+Fin-inj n m p with n  m
+... | eq prf = prf
+... | lt n<m = Empty.rec (Fin-inj′ n<m (sym p))
+... | gt n>m = Empty.rec (Fin-inj′ n>m p)
+
+≤-·sk-cancel :  {m} {k} {n}  m · suc k  n · suc k  m  n
+≤-·sk-cancel {m} {k} {n} (d , p) = o , inj-·sm {m = k} goal where
+  r = d % suc k
+  o = d / suc k
+  resn·k : Residue (suc k) (n · suc k)
+  resn·k = ((r , n%sk<sk d k) , (o + m)) , reason where
+   reason = expand× ((r , n%sk<sk d k) , o + m) ≡⟨ expand≡ (suc k) r (o + m) 
+            (o + m) · suc k + r                 ≡[ i ]⟨ +-comm (·-distribʳ o m (suc k) (~ i)) r i 
+            r + (o · suc k + m · suc k)         ≡⟨ +-assoc r (o · suc k) (m · suc k) 
+            (r + o · suc k) + m · suc k         ≡⟨ cong (_+ m · suc k) (+-comm r (o · suc k)  moddiv d (suc k)) 
+            d + m · suc k                       ≡⟨ p 
+            n · suc k 
+
+  residuek·n :  k n  (r : Residue (suc k) (n · suc k))  ((fzero , n) , expand≡ (suc k) 0 n  +-zero _)  r
+  residuek·n _ _ = isContr→isProp isContrResidue _
+
+  r≡0 : r  0
+  r≡0 = cong (toℕ  extract) (sym (residuek·n k n resn·k))
+  d≡o·sk : d  o · suc k
+  d≡o·sk = sym (moddiv d (suc k)) ∙∙ cong (o · suc k +_) r≡0 ∙∙ +-zero _
+  goal : (o + m) · suc k  n · suc k
+  goal = sym (·-distribʳ o m (suc k)) ∙∙ cong (_+ m · suc k) (sym d≡o·sk) ∙∙ p
+
+<-·sk-cancel :  {m} {k} {n}  m · suc k < n · suc k  m < n
+<-·sk-cancel {m} {k} {n} p = goal where
+  ≤-helper : m  n
+  ≤-helper = ≤-·sk-cancel (pred-≤-pred (<≤-trans p (≤-suc ≤-refl)))
+  goal : m < n
+  goal = case <-split (suc-≤-suc ≤-helper) of λ
+    { (inl g)  g
+    ; (inr e)  Empty.rec (¬m<m (subst  m  m · suc k < n · suc k) e p))
+    }
+
+factorEquiv :  {n} {m}  Fin n × Fin m  Fin (n · m)
+factorEquiv {zero} {m} = uninhabEquiv (¬Fin0  fst) ¬Fin0
+factorEquiv {suc n} {m} = intro , isEmbedding×isSurjection→isEquiv (isEmbeddingIntro , isSurjectionIntro) where
+  intro : Fin (suc n) × Fin m  Fin (suc n · m)
+  intro (nn , mm) = nm , subst  nm₁  nm₁ < suc n · m) (sym (expand≡ _ (toℕ nn) (toℕ mm))) nm<n·m where
+    nm : 
+    nm = expand× (nn , toℕ mm)
+    nm<n·m : toℕ mm · suc n + toℕ nn < suc n · m
+    nm<n·m =
+      toℕ mm · suc n + toℕ nn <≤⟨ <-k+ (snd nn) 
+      toℕ mm · suc n + suc n  ≡≤⟨ +-comm _ (suc n) 
+      suc (toℕ mm) · suc n    ≤≡⟨ ≤-·k (snd mm) 
+      m · suc n               ≡⟨ ·-comm _ (suc n) 
+      suc n · m                where open <-Reasoning
+
+  intro-injective :  {o} {p}  intro o  intro p  o  p
+  intro-injective {o} {p} io≡ip = λ i  io′≡ip′ i .fst , toℕ-injective {fj = snd o} {fk = snd p} (cong snd io′≡ip′) i where
+    io′≡ip′ : (fst o , toℕ (snd o))  (fst p , toℕ (snd p))
+    io′≡ip′ = expand×Inj _ (cong fst io≡ip)
+  isEmbeddingIntro : isEmbedding intro
+  isEmbeddingIntro = injEmbedding isSetFin intro-injective
+
+  elimF :  nm  fiber intro nm
+  elimF nm = ((nn , nn<n) , (mm , mm<m)) , toℕ-injective (reduce n (toℕ nm) .snd) where
+    mm = toℕ nm / suc n
+    nn = toℕ nm % suc n
+
+    nmmoddiv : mm · suc n + nn  toℕ nm
+    nmmoddiv = moddiv _ (suc n)
+    nn<n : nn < suc n
+    nn<n = n%sk<sk (toℕ nm) _
+
+    nmsnd : mm · suc n + nn < suc n · m
+    nmsnd = subst  l  l < suc n · m) (sym nmmoddiv) (snd nm)
+    mm·sn<m·sn : mm · suc n < m · suc n
+    mm·sn<m·sn =
+      mm · suc n      ≤<⟨ nn , +-comm nn (mm · suc n) 
+      mm · suc n + nn <≡⟨ nmsnd 
+      suc n · m       ≡⟨ ·-comm (suc n) m 
+      m · suc n        where open <-Reasoning
+    mm<m : mm < m
+    mm<m = <-·sk-cancel mm·sn<m·sn
+
+  isSurjectionIntro : isSurjection intro
+  isSurjectionIntro = ∣_∣₁  elimF
+
+-- Fin (m + n) ≡ Fin m ⊎ Fin n
+-- ===========================
+
+o<m→o<m+n : (m n o : )  o < m  o < (m + n)
+o<m→o<m+n m n o (k , p) = (n + k) , (n + k + suc o    ≡⟨ sym (+-assoc n k _)  
+                                     n + (k + suc o)  ≡⟨ cong  -  n + -) p 
+                                     n + m            ≡⟨ +-comm n m           
+                                     m + n            )
+
+∸-<-lemma : (m n o : )  o < m + n  m  o  o  m < n
+∸-<-lemma zero    n o       o<m+n m<o = o<m+n
+∸-<-lemma (suc m) n zero    o<m+n m<o = Empty.rec (¬-<-zero m<o)
+∸-<-lemma (suc m) n (suc o) o<m+n m<o =
+  ∸-<-lemma m n o (pred-≤-pred o<m+n) (pred-≤-pred m<o)
+
+-- A convenient wrapper on top of trichotomy, as we will be interested in
+-- whether `m < n` or `n ≤ m`.
+_≤?_ : (m n : )  (m < n)  (n  m)
+_≤?_ m n with m  n
+_≤?_ m n | lt m<n = inl m<n
+_≤?_ m n | eq m=n = inr (subst  -  -  m) m=n ≤-refl)
+_≤?_ m n | gt n<m = inr (<-weaken n<m)
+
+¬-<-and-≥ : {m n : }  m < n  ¬ n  m
+¬-<-and-≥ {m}     {zero}  m<n n≤m = ¬-<-zero m<n
+¬-<-and-≥ {zero}  {suc n} m<n n≤m = ¬-<-zero n≤m
+¬-<-and-≥ {suc m} {suc n} m<n n≤m = ¬-<-and-≥ (pred-≤-pred m<n) (pred-≤-pred n≤m)
+
+m+n∸n=m : (n m : )  (m + n)  n  m
+m+n∸n=m zero    k = +-zero k
+m+n∸n=m (suc m) k = (k + suc m)  suc m   ≡⟨ cong  -  -  suc m) (+-suc k m) 
+                    suc (k + m)  (suc m) ≡⟨ refl                               
+                    (k + m)  m           ≡⟨ m+n∸n=m m k                        
+                    k                     
+
+∸-lemma : {m n : }  m  n  m + (n  m)  n
+∸-lemma {zero}  {k}     _   = refl {x = k}
+∸-lemma {suc m} {zero}  m≤k = Empty.rec (¬-<-and-≥ (suc-≤-suc zero-≤) m≤k)
+∸-lemma {suc m} {suc k} m≤k =
+  suc m + (suc k  suc m)   ≡⟨ refl                                 
+  suc (m + (suc k  suc m)) ≡⟨ refl                                 
+  suc (m + (k  m))         ≡⟨ cong suc (∸-lemma (pred-≤-pred m≤k)) 
+  suc k                     
+
+Fin+≅Fin⊎Fin : (m n : )  Iso (Fin (m + n)) (Fin m  Fin n)
+Iso.fun (Fin+≅Fin⊎Fin m n) = f
+  where
+    f : Fin (m + n)  Fin m  Fin n
+    f (k , k<m+n) with k ≤? m
+    f (k , k<m+n) | inl k<m = inl (k , k<m)
+    f (k , k<m+n) | inr k≥m = inr (k  m , ∸-<-lemma m n k k<m+n k≥m)
+Iso.inv (Fin+≅Fin⊎Fin m n) = g
+  where
+    g :  Fin m    Fin n    Fin (m + n)
+    g (inl (k , k<m)) = k     , o<m→o<m+n m n k k<m
+    g (inr (k , k<n)) = m + k , <-k+ k<n
+Iso.rightInv (Fin+≅Fin⊎Fin m n) = sec-f-g
+  where
+    sec-f-g : _
+    sec-f-g (inl (k , k<m)) with k ≤? m
+    sec-f-g (inl (k , k<m)) | inl _   = cong inl (Σ≡Prop  _  isProp≤) refl)
+    sec-f-g (inl (k , k<m)) | inr m≤k = Empty.rec (¬-<-and-≥ k<m m≤k)
+    sec-f-g (inr (k , k<n)) with (m + k) ≤? m
+    sec-f-g (inr (k , k<n)) | inl p   = Empty.rec (¬m+n<m {m} {k} p)
+    sec-f-g (inr (k , k<n)) | inr k≥m = cong inr (Σ≡Prop  _  isProp≤) rem)
+      where
+        rem : (m + k)  m  k
+        rem = subst  -  -  m  k) (+-comm k m) (m+n∸n=m m k)
+Iso.leftInv  (Fin+≅Fin⊎Fin m n) = ret-f-g
+  where
+    ret-f-g : _
+    ret-f-g (k , k<m+n) with k ≤? m
+    ret-f-g (k , k<m+n) | inl _   = Σ≡Prop  _  isProp≤) refl
+    ret-f-g (k , k<m+n) | inr m≥k = Σ≡Prop  _  isProp≤) (∸-lemma m≥k)
+
+Fin+≡Fin⊎Fin : (m n : )  Fin (m + n)  Fin m  Fin n
+Fin+≡Fin⊎Fin m n = isoToPath (Fin+≅Fin⊎Fin m n)
+
+-- Equivalence between FinData and Fin
+
+sucFin : {N : }  Fin N  Fin (suc N)
+sucFin (k , n , p) = suc k , n , (+-suc _ _  cong suc p)
+
+FinData→Fin : (N : )  FinData N  Fin N
+FinData→Fin zero ()
+FinData→Fin (suc N) zero = 0 , suc-≤-suc zero-≤
+FinData→Fin (suc N) (suc k) = sucFin (FinData→Fin N k)
+
+Fin→FinData : (N : )  Fin N  FinData N
+Fin→FinData zero (k , n , p) = Empty.rec (snotz (sym (+-suc n k)  p))
+Fin→FinData (suc N) (0 , n , p) = zero
+Fin→FinData (suc N) ((suc k) , n , p) = suc (Fin→FinData N (k , n , p')) where
+  p' : n + suc k  N
+  p' = injSuc (sym (+-suc n (suc k))  p)
+
+secFin : (n : )  section (FinData→Fin n) (Fin→FinData n)
+secFin 0 (k , n , p) = Empty.rec (snotz (sym (+-suc n k)  p))
+secFin (suc N) (0 , n , p) = Fin-fst-≡ refl
+secFin (suc N) (suc k , n , p) = Fin-fst-≡ (cong suc (cong fst (secFin N (k , n , p')))) where
+  p' : n + suc k  N
+  p' = injSuc (sym (+-suc n (suc k))  p)
+
+retFin : (n : )  retract (FinData→Fin n) (Fin→FinData n)
+retFin 0 ()
+retFin (suc N) zero = refl
+retFin (suc N) (suc k) = cong FinData.suc (cong (Fin→FinData N) (Fin-fst-≡ refl)  retFin N k)
+
+FinDataIsoFin : (N : )  Iso (FinData N) (Fin N)
+Iso.fun (FinDataIsoFin N) = FinData→Fin N
+Iso.inv (FinDataIsoFin N) = Fin→FinData N
+Iso.rightInv (FinDataIsoFin N) = secFin N
+Iso.leftInv (FinDataIsoFin N) = retFin N
+
+FinData≃Fin : (N : )  FinData N  Fin N
+FinData≃Fin N = isoToEquiv (FinDataIsoFin N)
+
+FinData≡Fin : (N : )  FinData N  Fin N
+FinData≡Fin N = ua (FinData≃Fin N)
+
+-- decidability of Fin
+
+DecFin : (n : )  Dec (Fin n)
+DecFin 0 = no ¬Fin0
+DecFin (suc n) = yes fzero
+
+-- propositional truncation of Fin
+
+Dec∥Fin∥ : (n : )  Dec  Fin n ∥₁
+Dec∥Fin∥ n = Dec∥∥ (DecFin n)
+
+-- some properties about cardinality
+
+Fin>0→isInhab : (n : )  0 < n  Fin n
+Fin>0→isInhab 0 p = Empty.rec (¬-<-zero p)
+Fin>0→isInhab (suc n) p = fzero
+
+Fin>1→hasNonEqualTerm : (n : )  1 < n  Σ[ i  Fin n ] Σ[ j  Fin n ] ¬ i  j
+Fin>1→hasNonEqualTerm 0 p = Empty.rec (snotz (≤0→≡0 p))
+Fin>1→hasNonEqualTerm 1 p = Empty.rec (snotz (≤0→≡0 (pred-≤-pred p)))
+Fin>1→hasNonEqualTerm (suc (suc n)) _ = fzero , fone , fzero≠fone
+
+isEmpty→Fin≡0 : (n : )  ¬ Fin n  0  n
+isEmpty→Fin≡0 0 _ = refl
+isEmpty→Fin≡0 (suc n) p = Empty.rec (p fzero)
+
+isInhab→Fin>0 : (n : )  Fin n  0 < n
+isInhab→Fin>0 0 i = Empty.rec (¬Fin0 i)
+isInhab→Fin>0 (suc n) _ = suc-≤-suc zero-≤
+
+hasNonEqualTerm→Fin>1 : (n : )  (i j : Fin n)  ¬ i  j  1 < n
+hasNonEqualTerm→Fin>1 0 i _ _ = Empty.rec (¬Fin0 i)
+hasNonEqualTerm→Fin>1 1 i j p = Empty.rec (p (isContr→isProp isContrFin1 i j))
+hasNonEqualTerm→Fin>1 (suc (suc n)) _ _ _ = suc-≤-suc (suc-≤-suc zero-≤)
+
+Fin≤1→isProp : (n : )  n  1  isProp (Fin n)
+Fin≤1→isProp 0 _ = isPropFin0
+Fin≤1→isProp 1 _ = isContr→isProp isContrFin1
+Fin≤1→isProp (suc (suc n)) p = Empty.rec (¬-<-zero (pred-≤-pred p))
+
+isProp→Fin≤1 : (n : )  isProp (Fin n)  n  1
+isProp→Fin≤1 0 _ = ≤-solver 0 1
+isProp→Fin≤1 1 _ = ≤-solver 1 1
+isProp→Fin≤1 (suc (suc n)) p = Empty.rec (fzero≠fone (p fzero fone))
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Fin.html b/docs/Cubical.Data.Fin.html new file mode 100644 index 0000000..98a5178 --- /dev/null +++ b/docs/Cubical.Data.Fin.html @@ -0,0 +1,9 @@ + +Cubical.Data.Fin
{-# OPTIONS --safe #-}
+
+module Cubical.Data.Fin where
+
+open import Cubical.Data.Fin.Base       public
+open import Cubical.Data.Fin.Properties public
+open import Cubical.Data.Fin.Literals   public
+
\ No newline at end of file diff --git a/docs/Cubical.Data.FinData.Properties.html b/docs/Cubical.Data.FinData.Properties.html new file mode 100644 index 0000000..7bea95e --- /dev/null +++ b/docs/Cubical.Data.FinData.Properties.html @@ -0,0 +1,375 @@ + +Cubical.Data.FinData.Properties
+{-# OPTIONS --safe #-}
+module Cubical.Data.FinData.Properties where
+
+-- WARNING : fromℕ' is in triple ! => to clean !
+-- sort file + mix with Fin folder
+
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Transport
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Powerset
+open import Cubical.Foundations.Isomorphism
+
+open import Cubical.Data.Sum
+open import Cubical.Data.Sigma
+open import Cubical.Data.FinData.Base as Fin
+open import Cubical.Data.Nat renaming (zero to ℕzero ; suc to ℕsuc
+                                      ;znots to ℕznots ; snotz to  ℕsnotz)
+open import Cubical.Data.Nat.Order
+open import Cubical.Data.Empty as 
+open import Cubical.Data.Maybe
+
+open import Cubical.Relation.Nullary
+
+open import Cubical.Structures.Pointed
+
+private
+ variable
+    ℓ' : Level
+   A : Type 
+   m n k : 
+
+toℕ<n :  {n} (i : Fin n)  toℕ i < n
+toℕ<n {n = ℕsuc n} zero = n , +-comm n 1
+toℕ<n {n = ℕsuc n} (suc i) = toℕ<n i .fst , +-suc _ _  cong ℕsuc (toℕ<n i .snd)
+
+znots : ∀{k} {m : Fin k}  ¬ (zero  (suc m))
+znots {k} {m} x = subst (Fin.rec (Fin k) ) x m
+
+znotsP :  {k0 k1 : } {k : k0  k1} {m1 : Fin k1}
+   ¬ PathP  i  Fin (ℕsuc (k i))) zero (suc m1)
+znotsP p = ℕznots (congP  i  toℕ) p)
+
+snotz : ∀{k} {m : Fin k}  ¬ ((suc m)  zero)
+snotz {k} {m} x = subst (Fin.rec  (Fin k)) x m
+
+snotzP :  {k0 k1 : } {k : k0  k1} {m0 : Fin k0}
+   ¬ PathP  i  Fin (ℕsuc (k i))) (suc m0) zero
+snotzP p = ℕsnotz (congP  i  toℕ) p)
+
+-- alternative from
+fromℕ' : (n : )  (k : )  (k < n)  Fin n
+fromℕ' ℕzero k infkn = ⊥.rec (¬-<-zero infkn)
+fromℕ' (ℕsuc n) ℕzero infkn = zero
+fromℕ' (ℕsuc n) (ℕsuc k) infkn = suc (fromℕ' n k (pred-≤-pred infkn))
+
+toFromId' : (n : )  (k : )  (infkn : k < n)  toℕ (fromℕ' n k infkn)  k
+toFromId' ℕzero k infkn = ⊥.rec (¬-<-zero infkn)
+toFromId' (ℕsuc n) ℕzero infkn = refl
+toFromId' (ℕsuc n) (ℕsuc k) infkn = cong ℕsuc (toFromId' n k (pred-≤-pred infkn))
+
+fromToId' : (n : )  (k : Fin n )  (r : toℕ k < n)  fromℕ' n (toℕ k) r  k
+fromToId' (ℕsuc n) zero r = refl
+fromToId' (ℕsuc n) (suc k) r = cong suc (fromToId' n k (pred-≤-pred r))
+
+inj-toℕ : {n : }  {k l : Fin n}  (toℕ k  toℕ l)  k  l
+inj-toℕ {ℕsuc n}  {zero} {zero}   x = refl
+inj-toℕ {ℕsuc n}  {zero} {suc l} x = ⊥.rec (ℕznots x)
+inj-toℕ {ℕsuc n} {suc k} {zero}   x = ⊥.rec (ℕsnotz x)
+inj-toℕ {ℕsuc n} {suc k} {suc l}  x = cong suc (inj-toℕ (injSuc x))
+
+inj-cong : {n : }  {k l : Fin n}  (p : toℕ k  toℕ l)  cong toℕ (inj-toℕ p)  p
+inj-cong p = isSetℕ _ _ _ _
+
+isPropFin0 : isProp (Fin 0)
+isPropFin0 = ⊥.rec  ¬Fin0
+
+isContrFin1 : isContr (Fin 1)
+isContrFin1 .fst = zero
+isContrFin1 .snd zero = refl
+
+injSucFin :  {n} {p q : Fin n}  suc p  suc q  p  q
+injSucFin {ℕsuc ℕzero} {zero} {zero} pf = refl
+injSucFin {ℕsuc (ℕsuc n)} pf = cong predFin pf
+
+injSucFinP :  {n0 n1 : } {pn : n0  n1} {p0 : Fin n0} {p1 : Fin n1}
+   PathP  i  Fin (ℕsuc (pn i))) (suc p0) (suc p1)
+   PathP  i  Fin (pn i)) p0 p1
+injSucFinP {one} {one} {pn} {zero} {zero} sucp =
+  transport  j  PathP  i  Fin (eqn j i)) zero zero) refl
+  where eqn : refl  pn
+        eqn = isSetℕ one one refl pn
+injSucFinP {one} {ℕsuc (ℕsuc n1)} {pn} {p0} {p1} sucp = ⊥.rec (ℕznots (injSuc pn))
+injSucFinP {ℕsuc (ℕsuc n0)} {one} {pn} {p0} {p1} sucp = ⊥.rec (ℕsnotz (injSuc pn))
+injSucFinP {ℕsuc (ℕsuc n0)} {ℕsuc (ℕsuc n1)} {pn} {p0} {p1} sucp =
+  transport  j  PathP  i  Fin (eqn j i)) p0 p1) (
+      congP  i  predFin) (
+        transport  j  PathP  i  Fin (ℕsuc (eqn (~ j) i))) (suc p0) (suc p1)) sucp
+      )
+    )
+  where pn' : 2 + n0  2 + n1
+        pn' = cong ℕsuc (injSuc pn)
+        eqn : pn'  pn
+        eqn = isSetℕ (2 + n0) (2 + n1) pn' pn
+
+discreteFin : ∀{k}  Discrete (Fin k)
+discreteFin zero zero = yes refl
+discreteFin zero (suc y) = no znots
+discreteFin (suc x) zero = no snotz
+discreteFin (suc x) (suc y) with discreteFin x y
+... | yes p = yes (cong suc p)
+... | no ¬p = no  q  ¬p (injSucFin q))
+
+isSetFin : ∀{k}  isSet (Fin k)
+isSetFin = Discrete→isSet discreteFin
+
+isWeaken? :  {n} (p : Fin (ℕsuc n))  Dec (Σ[ q  Fin n ] p  weakenFin q)
+isWeaken? {ℕzero} zero = no λ (q , eqn)  case q of λ ()
+isWeaken? {ℕsuc n} zero = yes (zero , refl)
+isWeaken? {ℕsuc n} (suc p) with isWeaken? {n} p
+... | yes (q , p≡wq) = yes (suc q , cong suc p≡wq)
+... | no  p≢wq = no λ
+  { (zero , sp≡wq)  snotz sp≡wq
+  ; (suc q , sp≡wq)  p≢wq (q , cong predFin sp≡wq)
+  }
+
+data biEq {n : } (i j : Fin n) : Type where
+  eq  :   i  j  biEq i j
+  ¬eq : ¬ i  j  biEq i j
+
+data triEq {n : } (i j a : Fin n) : Type where
+  leq : a  i  triEq i j a
+  req : a  j  triEq i j a
+  ¬eq : (¬ a  i) × (¬ a  j)  triEq i j a
+
+biEq? : (i j : Fin n)  biEq i j
+biEq? i j = case (discreteFin i j) return  _  biEq i j)
+              of λ { (yes p)  eq p ; (no ¬p)  ¬eq ¬p }
+
+triEq? : (i j a : Fin n)  triEq i j a
+triEq? i j a =
+  case (discreteFin a i) return  _  triEq i j a) of
+    λ { (yes p)  leq p
+      ; (no ¬p) 
+          case (discreteFin a j) return  _  triEq i j a) of
+            λ { (yes q)  req q
+              ; (no ¬q)  ¬eq (¬p , ¬q) }}
+
+
+weakenRespToℕ :  {n} (i : Fin n)  toℕ (weakenFin i)  toℕ i
+weakenRespToℕ zero = refl
+weakenRespToℕ (suc i) = cong ℕsuc (weakenRespToℕ i)
+
+toFin : {n : } (m : )  m < n  Fin n
+toFin {n = ℕzero} _ m<0 = ⊥.rec (¬-<-zero m<0)
+toFin {n = ℕsuc n} _ (ℕzero , _) = fromℕ n --in this case we have m≡n
+toFin {n = ℕsuc n} m (ℕsuc k , p) = weakenFin (toFin m (k , cong predℕ p))
+
+toFin0≡0 : {n : } (p : 0 < ℕsuc n)  toFin 0 p  zero
+toFin0≡0 (ℕzero , p) = subst  x  fromℕ x  zero) (cong predℕ p) refl
+toFin0≡0 {ℕzero} (ℕsuc k , p) = ⊥.rec (ℕsnotz (+-comm 1 k  (cong predℕ p)))
+toFin0≡0 {ℕsuc n} (ℕsuc k , p) =
+         subst  x  weakenFin x  zero) (sym (toFin0≡0 (k , cong predℕ p))) refl
+
+genδ-FinVec : (n k : )  (a b : A)  FinVec A n
+genδ-FinVec (ℕsuc n) ℕzero a b zero = a
+genδ-FinVec (ℕsuc n) ℕzero a b (suc x) = b
+genδ-FinVec (ℕsuc n) (ℕsuc k) a b zero = b
+genδ-FinVec (ℕsuc n) (ℕsuc k) a b (suc x) = genδ-FinVec n k a b x
+
+δℕ-FinVec : (n k : )  FinVec  n
+δℕ-FinVec n k = genδ-FinVec n k 1 0
+
+-- WARNING : harder to prove things about
+genδ-FinVec' : (n k : )  (a b : A)  FinVec A n
+genδ-FinVec' n k a b x with discreteℕ (toℕ x) k
+... | yes p = a
+... | no ¬p = b
+
+-- doing induction on toFin is awkward, so the following alternative
+enum : (m : )  m < n  Fin n
+enum {n = ℕzero} _ m<0 = ⊥.rec (¬-<-zero m<0)
+enum {n = ℕsuc n} 0 _ = zero
+enum {n = ℕsuc n} (ℕsuc m) p = suc (enum m (pred-≤-pred p))
+
+enum∘toℕ : (i : Fin n)(p : toℕ i < n)  enum (toℕ i) p  i
+enum∘toℕ {n = ℕsuc n} zero _ = refl
+enum∘toℕ {n = ℕsuc n} (suc i) p t = suc (enum∘toℕ i (pred-≤-pred p) t)
+
+toℕ∘enum : (m : )(p : m < n)  toℕ (enum m p)  m
+toℕ∘enum {n = ℕzero} _ m<0 = ⊥.rec (¬-<-zero m<0)
+toℕ∘enum {n = ℕsuc n} 0 _ = refl
+toℕ∘enum {n = ℕsuc n} (ℕsuc m) p i = ℕsuc (toℕ∘enum m (pred-≤-pred p) i)
+
+enumExt : {m m' : }(p : m < n)(p' : m' < n)  m  m'  enum m p  enum m' p'
+enumExt p p' q i = enum (q i) (isProp→PathP  i  isProp≤ {m = ℕsuc (q i)}) p p' i)
+
+enumInj : (p : m < k) (q : n < k)  enum m p  enum n q  m  n
+enumInj p q path = sym (toℕ∘enum _ p)  cong toℕ path  toℕ∘enum _ q
+
+enumIndStep :
+    (P : Fin n  Type )
+   (k : )(p : ℕsuc k < n)
+   ((m : )(q : m < n)(q' : m  k )      P (enum m q))
+   P (enum (ℕsuc k) p)
+   ((m : )(q : m < n)(q' : m  ℕsuc k)  P (enum m q))
+enumIndStep P k p f x m q q' =
+  case (≤-split q') return  _  P (enum m q)) of
+    λ { (inl r')  f m q (pred-≤-pred r')
+      ; (inr r')  subst P (enumExt p q (sym r')) x }
+
+enumElim :
+    (P : Fin n  Type )
+   (k : )(p : k < n)(h : ℕsuc k  n)
+   ((m : )(q : m < n)(q' : m  k)  P (enum m q))
+   (i : Fin n)  P i
+enumElim P k p h f i =
+  subst P (enum∘toℕ i (toℕ<n i)) (f (toℕ i) (toℕ<n i)
+    (pred-≤-pred (subst  a  toℕ i < a) (sym h) (toℕ<n i))))
+
+
+++FinAssoc : {n m k : } (U : FinVec A n) (V : FinVec A m) (W : FinVec A k)
+            PathP  i  FinVec A (+-assoc n m k i)) (U ++Fin (V ++Fin W)) ((U ++Fin V) ++Fin W)
+++FinAssoc {n = ℕzero} _ _ _ = refl
+++FinAssoc {n = ℕsuc n} U V W i zero = U zero
+++FinAssoc {n = ℕsuc n} U V W i (suc ind) = ++FinAssoc (U  suc) V W i ind
+
+++FinRid : {n : } (U : FinVec A n) (V : FinVec A 0)
+          PathP  i  FinVec A (+-zero n i)) (U ++Fin V) U
+++FinRid {n = ℕzero} U V = funExt λ i  ⊥.rec (¬Fin0 i)
+++FinRid {n = ℕsuc n} U V i zero = U zero
+++FinRid {n = ℕsuc n} U V i (suc ind) = ++FinRid (U  suc) V i ind
+
+++FinElim : {P : A  Type ℓ'} {n m : } (U : FinVec A n) (V : FinVec A m)
+           (∀ i  P (U i))  (∀ i  P (V i))   i  P ((U ++Fin V) i)
+++FinElim {n = ℕzero} _ _ _ PVHyp i = PVHyp i
+++FinElim {n = ℕsuc n} _ _ PUHyp _ zero = PUHyp zero
+++FinElim {P = P} {n = ℕsuc n} U V PUHyp PVHyp (suc i) =
+          ++FinElim {P = P} (U  suc) V  i  PUHyp (suc i)) PVHyp i
+
+++FinPres∈ : {n m : } {α : FinVec A n} {β : FinVec A m} (S :  A)
+            (∀ i  α i  S)  (∀ i  β i  S)   i  (α ++Fin β) i  S
+++FinPres∈ {n = ℕzero} S   i =  i
+++FinPres∈ {n = ℕsuc n} S   zero =  zero
+++FinPres∈ {n = ℕsuc n} S   (suc i) = ++FinPres∈ S (  suc)  i
+
+-- sends i to n+i if toℕ i < m and to i∸n otherwise
+-- then +Shuffle²≡id and over the induced path (i.e. in PathP (ua +ShuffleEquiv))
+-- ++Fin is commutative, but how to go from there?
++Shuffle : (m n : )  Fin (m + n)  Fin (n + m)
++Shuffle m n i with <Dec (toℕ i) m
+... | yes i<m = toFin (n + (toℕ i)) (<-k+ i<m)
+... | no ¬i<m = toFin (toℕ i  m)
+                  (subst  x  toℕ i  m < x) (+-comm m n) (≤<-trans (∸-≤ (toℕ i) m) (toℕ<n i)))
+
+
+finSucMaybeIso : Iso (Fin (ℕ.suc n)) (Maybe (Fin n))
+Iso.fun finSucMaybeIso zero = nothing
+Iso.fun finSucMaybeIso (suc i) = just i
+Iso.inv finSucMaybeIso nothing = zero
+Iso.inv finSucMaybeIso (just i) = suc i
+Iso.rightInv finSucMaybeIso nothing = refl
+Iso.rightInv finSucMaybeIso (just i) = refl
+Iso.leftInv finSucMaybeIso zero = refl
+Iso.leftInv finSucMaybeIso (suc i) = refl
+
+finSuc≡Maybe : Fin (ℕ.suc n)  Maybe (Fin n)
+finSuc≡Maybe = isoToPath finSucMaybeIso
+
+finSuc≡Maybe∙ : (Fin (ℕ.suc n) , zero)  Maybe∙ (Fin n)
+finSuc≡Maybe∙ = pointed-sip _ _ ((isoToEquiv finSucMaybeIso) , refl)
+
+-- Proof that Fin n ⊎ Fin m ≃ Fin (n+m)
+module FinSumChar where
+
+ fun : (n m : )  Fin n  Fin m  Fin (n + m)
+ fun ℕzero m (inr i) = i
+ fun (ℕsuc n) m (inl zero) = zero
+ fun (ℕsuc n) m (inl (suc i)) = suc (fun n m (inl i))
+ fun (ℕsuc n) m (inr i) = suc (fun n m (inr i))
+
+ invSucAux : (n m : )  Fin n  Fin m  Fin (ℕsuc n)  Fin m
+ invSucAux n m (inl i) = inl (suc i)
+ invSucAux n m (inr i) = inr i
+
+ inv : (n m : )  Fin (n + m)  Fin n  Fin m
+ inv ℕzero m i = inr i
+ inv (ℕsuc n) m zero = inl zero
+ inv (ℕsuc n) m (suc i) = invSucAux n m (inv n m i)
+
+ ret : (n m : ) (i : Fin n  Fin m)  inv n m (fun n m i)  i
+ ret ℕzero m (inr i) = refl
+ ret (ℕsuc n) m (inl zero) = refl
+ ret (ℕsuc n) m (inl (suc i)) = subst  x  invSucAux n m x  inl (suc i))
+                                       (sym (ret n m (inl i))) refl
+ ret (ℕsuc n) m (inr i) = subst  x  invSucAux n m x  inr i) (sym (ret n m (inr i))) refl
+
+ sec : (n m : ) (i : Fin (n + m))  fun n m (inv n m i)  i
+ sec ℕzero m i = refl
+ sec (ℕsuc n) m zero = refl
+ sec (ℕsuc n) m (suc i) = helperPath (inv n m i)  cong suc (sec n m i)
+  where
+  helperPath :  x  fun (ℕsuc n) m (invSucAux n m x)  suc (fun n m x)
+  helperPath (inl _) = refl
+  helperPath (inr _) = refl
+
+ Equiv : (n m : )  Fin n  Fin m  Fin (n + m)
+ Equiv n m = isoToEquiv (iso (fun n m) (inv n m) (sec n m) (ret n m))
+
+ ++FinInl : (n m : ) (U : FinVec A n) (W : FinVec A m) (i : Fin n)
+           U i  (U ++Fin W) (fun n m (inl i))
+ ++FinInl (ℕsuc n) m U W zero = refl
+ ++FinInl (ℕsuc n) m U W (suc i) = ++FinInl n m (U  suc) W i
+
+ ++FinInr : (n m : ) (U : FinVec A n) (W : FinVec A m) (i : Fin m)
+           W i  (U ++Fin W) (fun n m (inr i))
+ ++FinInr ℕzero (ℕsuc m) U W i = refl
+ ++FinInr (ℕsuc n) m U W i = ++FinInr n m (U  suc) W i
+
+-- Proof that Fin n × Fin m ≃ Fin nm
+module FinProdChar where
+
+ open Iso
+ sucProdToSumIso : (n m : )  Iso (Fin (ℕsuc n) × Fin m) (Fin m  (Fin n × Fin m))
+ fun (sucProdToSumIso n m) (zero , j) = inl j
+ fun (sucProdToSumIso n m) (suc i , j) = inr (i , j)
+ inv (sucProdToSumIso n m) (inl j) = zero , j
+ inv (sucProdToSumIso n m) (inr (i , j)) = suc i , j
+ rightInv (sucProdToSumIso n m) (inl j) = refl
+ rightInv (sucProdToSumIso n m) (inr (i , j)) = refl
+ leftInv (sucProdToSumIso n m) (zero , j) = refl
+ leftInv (sucProdToSumIso n m) (suc i , j) = refl
+
+ Equiv : (n m : )  (Fin n × Fin m)  Fin (n · m)
+ Equiv ℕzero m = uninhabEquiv  x  ¬Fin0 (fst x)) ¬Fin0
+ Equiv (ℕsuc n) m = Fin (ℕsuc n) × Fin m    ≃⟨ isoToEquiv (sucProdToSumIso n m) 
+                    Fin m  (Fin n × Fin m) ≃⟨ isoToEquiv (⊎Iso idIso (equivToIso (Equiv n m))) 
+                    Fin m  Fin (n · m)     ≃⟨ FinSumChar.Equiv m (n · m) 
+                    Fin (m + n · m)         
+
+-- Exhaustion of decidable predicate
+
+∀Dec :
+    (P : Fin m  Type )
+   (dec : (i : Fin m)  Dec (P i))
+   ((i : Fin m)  P i)  (Σ[ i  Fin m ] ¬ P i)
+∀Dec {m = 0} _ _ = inl λ ()
+∀Dec {m = ℕsuc m} P dec = helper (dec zero) (∀Dec _ (dec  suc))
+  where
+    helper :
+        Dec (P zero)
+       ((i : Fin m)  P (suc i))   (Σ[ i  Fin m ] ¬ P (suc i))
+       ((i : Fin (ℕsuc m))  P i)  (Σ[ i  Fin (ℕsuc m) ] ¬ P i)
+    helper (yes p) (inl q) = inl λ { zero  p ; (suc i)  q i }
+    helper (yes _) (inr q) = inr (suc (q .fst) , q .snd)
+    helper (no ¬p) _ = inr (zero , ¬p)
+
+∀Dec2 :
+    (P : Fin m  Fin n  Type )
+   (dec : (i : Fin m)(j : Fin n)  Dec (P i j))
+   ((i : Fin m)(j : Fin n)  P i j)  (Σ[ i  Fin m ] Σ[ j  Fin n ] ¬ P i j)
+∀Dec2 {m = 0} {n = n} _ _ = inl λ ()
+∀Dec2 {m = ℕsuc m} {n = n} P dec = helper (∀Dec (P zero) (dec zero)) (∀Dec2 (P  suc) (dec  suc))
+  where
+    helper :
+        ((j : Fin n)  P zero j)  (Σ[ j  Fin n ] ¬ P zero j)
+       ((i : Fin m)(j : Fin n)  P (suc i) j)   (Σ[ i  Fin m ] Σ[ j  Fin n ] ¬ P (suc i) j)
+       ((i : Fin (ℕsuc m))(j : Fin n)  P i j)  (Σ[ i  Fin (ℕsuc m) ] Σ[ j  Fin n ] ¬ P i j)
+    helper (inl p) (inl q) = inl λ { zero j  p j ; (suc i) j  q i j }
+    helper (inl _) (inr q) = inr (suc (q .fst) , q .snd .fst , q .snd .snd)
+    helper (inr p) _ = inr (zero , p)
+
\ No newline at end of file diff --git a/docs/Cubical.Data.FinData.html b/docs/Cubical.Data.FinData.html new file mode 100644 index 0000000..a5cf723 --- /dev/null +++ b/docs/Cubical.Data.FinData.html @@ -0,0 +1,7 @@ + +Cubical.Data.FinData
{-# OPTIONS --safe #-}
+module Cubical.Data.FinData where
+
+open import Cubical.Data.FinData.Base public
+open import Cubical.Data.FinData.Properties public
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Maybe.Properties.html b/docs/Cubical.Data.Maybe.Properties.html new file mode 100644 index 0000000..99eee15 --- /dev/null +++ b/docs/Cubical.Data.Maybe.Properties.html @@ -0,0 +1,183 @@ + +Cubical.Data.Maybe.Properties
{-# OPTIONS --safe #-}
+module Cubical.Data.Maybe.Properties where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.HLevels
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Function using (_∘_; idfun)
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Pointed.Base using (Pointed; _→∙_; pt)
+open import Cubical.Foundations.Structure using (⟨_⟩)
+
+open import Cubical.Functions.Embedding using (isEmbedding)
+
+open import Cubical.Data.Empty as  using (; isProp⊥)
+open import Cubical.Data.Unit
+open import Cubical.Data.Nat using (suc)
+open import Cubical.Data.Sum using (_⊎_; inl; inr)
+open import Cubical.Data.Sigma using (ΣPathP)
+
+open import Cubical.Relation.Nullary using (¬_; Discrete; yes; no)
+
+open import Cubical.Data.Maybe.Base as Maybe
+
+Maybe∙ :  {} (A : Type )  Pointed 
+Maybe∙ A .fst = Maybe A
+Maybe∙ A .snd = nothing
+
+-- Maybe∙ is the "free pointing" functor, that is, left adjoint to the
+-- forgetful functor forgetting the base point.
+module _ {} (A : Type ) {ℓ'} (B : Pointed ℓ') where
+
+  freelyPointedIso : Iso (Maybe∙ A →∙ B) (A   B )
+  Iso.fun freelyPointedIso f∙ = fst f∙  just
+  Iso.inv freelyPointedIso f = Maybe.rec (pt B) f , refl
+  Iso.rightInv freelyPointedIso f = refl
+  Iso.leftInv freelyPointedIso f∙ =
+    ΣPathP
+      ( funExt (Maybe.elim _ (sym (snd f∙))  a  refl))
+      , λ i j  snd f∙ (~ i  j))
+
+map-Maybe-id :  {} {A : Type }   m  map-Maybe (idfun A) m  m
+map-Maybe-id nothing = refl
+map-Maybe-id (just _) = refl
+
+-- Path space of Maybe type
+module MaybePath {} {A : Type } where
+  Cover : Maybe A  Maybe A  Type 
+  Cover nothing  nothing   = Lift Unit
+  Cover nothing  (just _)  = Lift 
+  Cover (just _) nothing   = Lift 
+  Cover (just a) (just a') = a  a'
+
+  reflCode : (c : Maybe A)  Cover c c
+  reflCode nothing  = lift tt
+  reflCode (just b) = refl
+
+  encode :  c c'  c  c'  Cover c c'
+  encode c _ = J  c' _  Cover c c') (reflCode c)
+
+  encodeRefl :  c  encode c c refl  reflCode c
+  encodeRefl c = JRefl  c' _  Cover c c') (reflCode c)
+
+  decode :  c c'  Cover c c'  c  c'
+  decode nothing  nothing  _ = refl
+  decode (just _) (just _) p = cong just p
+
+  decodeRefl :  c  decode c c (reflCode c)  refl
+  decodeRefl nothing  = refl
+  decodeRefl (just _) = refl
+
+  decodeEncode :  c c'  (p : c  c')  decode c c' (encode c c' p)  p
+  decodeEncode c _ =
+    J  c' p  decode c c' (encode c c' p)  p)
+      (cong (decode c c) (encodeRefl c)  decodeRefl c)
+
+  encodeDecode :  c c'  (d : Cover c c')  encode c c' (decode c c' d)  d
+  encodeDecode nothing nothing _ = refl
+  encodeDecode (just a) (just a') =
+    J  a' p  encode (just a) (just a') (cong just p)  p) (encodeRefl (just a))
+
+  Cover≃Path :  c c'  Cover c c'  (c  c')
+  Cover≃Path c c' = isoToEquiv
+    (iso (decode c c') (encode c c') (decodeEncode c c') (encodeDecode c c'))
+
+  Cover≡Path :  c c'  Cover c c'  (c  c')
+  Cover≡Path c c' = isoToPath
+    (iso (decode c c') (encode c c') (decodeEncode c c') (encodeDecode c c'))
+
+  isOfHLevelCover : (n : HLevel)
+     isOfHLevel (suc (suc n)) A
+      c c'  isOfHLevel (suc n) (Cover c c')
+  isOfHLevelCover n p nothing  nothing   = isOfHLevelLift (suc n) (isOfHLevelUnit (suc n))
+  isOfHLevelCover n p nothing  (just a') = isOfHLevelLift (suc n) (isProp→isOfHLevelSuc n isProp⊥)
+  isOfHLevelCover n p (just a) nothing   = isOfHLevelLift (suc n) (isProp→isOfHLevelSuc n isProp⊥)
+  isOfHLevelCover n p (just a) (just a') = p a a'
+
+isOfHLevelMaybe :  {} (n : HLevel) {A : Type }
+   isOfHLevel (suc (suc n)) A
+   isOfHLevel (suc (suc n)) (Maybe A)
+isOfHLevelMaybe n lA c c' =
+  isOfHLevelRetract (suc n)
+    (MaybePath.encode c c')
+    (MaybePath.decode c c')
+    (MaybePath.decodeEncode c c')
+    (MaybePath.isOfHLevelCover n lA c c')
+
+private
+ variable
+    : Level
+   A : Type 
+
+fromJust-def : A  Maybe A  A
+fromJust-def a nothing = a
+fromJust-def _ (just a) = a
+
+just-inj : (x y : A)  just x  just y  x  y
+just-inj x _ eq = cong (fromJust-def x) eq
+
+isEmbedding-just : isEmbedding (just {A = A})
+isEmbedding-just  w z = MaybePath.Cover≃Path (just w) (just z) .snd
+
+¬nothing≡just :  {x : A}  ¬ (nothing  just x)
+¬nothing≡just {A = A} {x = x} p = lower (subst (caseMaybe (Maybe A) (Lift )) p (just x))
+
+¬just≡nothing :  {x : A}  ¬ (just x  nothing)
+¬just≡nothing {A = A} {x = x} p = lower (subst (caseMaybe (Lift ) (Maybe A)) p (just x))
+
+isProp-x≡nothing : (x : Maybe A)  isProp (x  nothing)
+isProp-x≡nothing nothing x w =
+  subst isProp (MaybePath.Cover≡Path nothing nothing) (isOfHLevelLift 1 isPropUnit) x w
+isProp-x≡nothing (just _) p _ = ⊥.rec (¬just≡nothing p)
+
+isProp-nothing≡x : (x : Maybe A)  isProp (nothing  x)
+isProp-nothing≡x nothing x w =
+  subst isProp (MaybePath.Cover≡Path nothing nothing) (isOfHLevelLift 1 isPropUnit) x w
+isProp-nothing≡x (just _) p _ = ⊥.rec (¬nothing≡just p)
+
+isContr-nothing≡nothing : isContr (nothing {A = A}  nothing)
+isContr-nothing≡nothing = inhProp→isContr refl (isProp-x≡nothing _)
+
+discreteMaybe : Discrete A  Discrete (Maybe A)
+discreteMaybe eqA nothing nothing    = yes refl
+discreteMaybe eqA nothing (just a')  = no ¬nothing≡just
+discreteMaybe eqA (just a) nothing   = no ¬just≡nothing
+discreteMaybe eqA (just a) (just a') with eqA a a'
+... | yes p = yes (cong just p)
+... | no ¬p = no  p  ¬p (just-inj _ _ p))
+
+module SumUnit where
+  Maybe→SumUnit : Maybe A  Unit  A
+  Maybe→SumUnit nothing  = inl tt
+  Maybe→SumUnit (just a) = inr a
+
+  SumUnit→Maybe : Unit  A  Maybe A
+  SumUnit→Maybe (inl _) = nothing
+  SumUnit→Maybe (inr a) = just a
+
+  Maybe→SumUnit→Maybe : (x : Maybe A)  SumUnit→Maybe (Maybe→SumUnit x)  x
+  Maybe→SumUnit→Maybe nothing  = refl
+  Maybe→SumUnit→Maybe (just _) = refl
+
+  SumUnit→Maybe→SumUnit : (x : Unit  A)  Maybe→SumUnit (SumUnit→Maybe x)  x
+  SumUnit→Maybe→SumUnit (inl _) = refl
+  SumUnit→Maybe→SumUnit (inr _) = refl
+
+Maybe≡SumUnit : Maybe A  Unit  A
+Maybe≡SumUnit = isoToPath (iso Maybe→SumUnit SumUnit→Maybe SumUnit→Maybe→SumUnit Maybe→SumUnit→Maybe)
+  where open SumUnit
+
+congMaybeEquiv :  { ℓ'} {A : Type } {B : Type ℓ'}
+   A  B  Maybe A  Maybe B
+congMaybeEquiv e = isoToEquiv isom
+  where
+  open Iso
+  isom : Iso _ _
+  isom .fun = map-Maybe (equivFun e)
+  isom .inv = map-Maybe (invEq e)
+  isom .rightInv nothing = refl
+  isom .rightInv (just b) = cong just (secEq e b)
+  isom .leftInv nothing = refl
+  isom .leftInv (just a) = cong just (retEq e a)
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Maybe.html b/docs/Cubical.Data.Maybe.html new file mode 100644 index 0000000..592e584 --- /dev/null +++ b/docs/Cubical.Data.Maybe.html @@ -0,0 +1,7 @@ + +Cubical.Data.Maybe
{-# OPTIONS --safe #-}
+module Cubical.Data.Maybe where
+
+open import Cubical.Data.Maybe.Base public
+open import Cubical.Data.Maybe.Properties public
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Nat.Order.Recursive.html b/docs/Cubical.Data.Nat.Order.Recursive.html new file mode 100644 index 0000000..47e386b --- /dev/null +++ b/docs/Cubical.Data.Nat.Order.Recursive.html @@ -0,0 +1,194 @@ + +Cubical.Data.Nat.Order.Recursive
{-# OPTIONS --safe #-}
+module Cubical.Data.Nat.Order.Recursive where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.HLevels
+open import Cubical.Foundations.Transport
+
+open import Cubical.Data.Empty as Empty
+open import Cubical.Data.Sigma
+open import Cubical.Data.Sum as Sum
+open import Cubical.Data.Unit
+
+open import Cubical.Data.Nat.Base
+open import Cubical.Data.Nat.Properties
+
+open import Cubical.Induction.WellFounded
+
+open import Cubical.Relation.Nullary
+
+infix 4 _≤_ _<_
+
+_≤_ :     Type₀
+zero  _ = Unit
+suc m  zero = 
+suc m  suc n = m  n
+
+_<_ :     Type₀
+m < n = suc m  n
+
+_≤?_ : (m n : )  Dec (m  n)
+zero  ≤? _     = yes tt
+suc m ≤? zero  = no λ ()
+suc m ≤? suc n = m ≤? n
+
+data Trichotomy (m n : ) : Type₀ where
+  lt : m < n  Trichotomy m n
+  eq : m  n  Trichotomy m n
+  gt : n < m  Trichotomy m n
+
+private
+  variable
+     : Level
+    R : Type 
+    P :   Type 
+    k l m n : 
+
+isProp≤ : isProp (m  n)
+isProp≤ {zero} = isPropUnit
+isProp≤ {suc m} {zero}  = isProp⊥
+isProp≤ {suc m} {suc n} = isProp≤ {m} {n}
+
+≤-k+ : m  n  k + m  k + n
+≤-k+ {k = zero}  m≤n = m≤n
+≤-k+ {k = suc k} m≤n = ≤-k+ {k = k} m≤n
+
+≤-+k : m  n  m + k  n + k
+≤-+k {m} {n} {k} m≤n
+  = transport  i  +-comm k m i  +-comm k n i) (≤-k+ {m} {n} {k} m≤n)
+
+≤-refl :  m  m  m
+≤-refl zero = _
+≤-refl (suc m) = ≤-refl m
+
+≤-trans : k  m  m  n  k  n
+≤-trans {zero} _ _ = _
+≤-trans {suc k} {suc m} {suc n} = ≤-trans {k} {m} {n}
+
+≤-antisym : m  n  n  m  m  n
+≤-antisym {zero} {zero} _ _ = refl
+≤-antisym {suc m} {suc n} m≤n n≤m = cong suc (≤-antisym m≤n n≤m)
+
+≤-k+-cancel : k + m  k + n  m  n
+≤-k+-cancel {k =  zero} m≤n = m≤n
+≤-k+-cancel {k = suc k} m≤n = ≤-k+-cancel {k} m≤n
+
+≤-+k-cancel : m + k  n + k  m  n
+≤-+k-cancel {m} {k} {n}
+  = ≤-k+-cancel {k} {m} {n}  transport λ i  +-comm m k i  +-comm n k i
+
+¬m<m : ¬ m < m
+¬m<m {suc m} = ¬m<m {m}
+
+≤0→≡0 : n  0  n  0
+≤0→≡0 {zero} _ = refl
+
+¬m+n<m : ¬ m + n < m
+¬m+n<m {suc m} = ¬m+n<m {m}
+
+<-weaken : m < n  m  n
+<-weaken {zero} _ = _
+<-weaken {suc m} {suc n} = <-weaken {m}
+
+<-trans : k < m  m < n  k < n
+<-trans {k} {m} {n} k<m m<n
+  = ≤-trans {suc k} {m} {n} k<m (<-weaken {m} m<n)
+
+<-asym : m < n  ¬ n < m
+<-asym {m} m<n n<m = ¬m<m {m} (<-trans {m} {_} {m} m<n n<m)
+
+<→≢ : n < m  ¬ n  m
+<→≢ {n} {m} p q = ¬m<m {m = m} (subst {x = n} (_< m) q p)
+
+Trichotomy-suc : Trichotomy m n  Trichotomy (suc m) (suc n)
+Trichotomy-suc (lt m<n) = lt m<n
+Trichotomy-suc (eq m≡n) = eq (cong suc m≡n)
+Trichotomy-suc (gt n<m) = gt n<m
+
+_≟_ :  m n  Trichotomy m n
+zero   zero = eq refl
+zero   suc n = lt _
+suc m  zero = gt _
+suc m  suc n = Trichotomy-suc (m  n)
+
+k≤k+n :  k  k  k + n
+k≤k+n zero    = _
+k≤k+n (suc k) = k≤k+n k
+
+n≤k+n :  n  n  k + n
+n≤k+n {k} n = transport  i  n  +-comm n k i) (k≤k+n n)
+
+≤-split : m  n  (m < n)  (m  n)
+≤-split {zero} {zero} m≤n = inr refl
+≤-split {zero} {suc n} m≤n = inl _
+≤-split {suc m} {suc n} m≤n
+  = Sum.map (idfun _) (cong suc) (≤-split {m} {n} m≤n)
+
+module WellFounded where
+  wf-< : WellFounded _<_
+  wf-rec-< :  n  WFRec _<_ (Acc _<_) n
+
+  wf-< n = acc (wf-rec-< n)
+
+  wf-rec-< (suc n) m m≤n with ≤-split {m} {n} m≤n
+  ... | inl m<n = wf-rec-< n m m<n
+  ... | inr m≡n = subst⁻ (Acc _<_) m≡n (wf-< n)
+
+wf-elim : (∀ n  (∀ m  m < n  P m)  P n)   n  P n
+wf-elim = WFI.induction WellFounded.wf-<
+
+wf-rec : (∀ n  (∀ m  m < n  R)  R)    R
+wf-rec {R = R} = wf-elim {P = λ _  R}
+
+module Minimal where
+  Least : ∀{}  (  Type )  (  Type )
+  Least P m = P m × (∀ n  n < m  ¬ P n)
+
+  isPropLeast : (∀ m  isProp (P m))   m  isProp (Least P m)
+  isPropLeast pP m
+    = isPropΣ (pP m)  _  isPropΠ3 λ _ _ _  isProp⊥)
+
+  Least→ : Σ _ (Least P)  Σ _ P
+  Least→ = map-snd fst
+
+  search
+    : (∀ m  Dec (P m))
+      n  (Σ[ m   ] Least P m)  (∀ m  m < n  ¬ P m)
+  search dec zero = inr  _ b _  b)
+  search {P = P} dec (suc n) with search dec n
+  ... | inl tup = inl tup
+  ... | inr ¬P<n with dec n
+  ... | yes Pn = inl (n , Pn , ¬P<n)
+  ... | no ¬Pn = inr λ m m≤n
+       case ≤-split m≤n of λ where
+          (inl m<n)  ¬P<n m m<n
+          (inr m≡n)  subst⁻ (¬_  P) m≡n ¬Pn
+
+  →Least : (∀ m  Dec (P m))  Σ _ P  Σ _ (Least P)
+  →Least dec (n , Pn) with search dec n
+  ... | inl least = least
+  ... | inr ¬P<n  = n , Pn , ¬P<n
+
+  Least-unique :  m n  Least P m  Least P n  m  n
+  Least-unique m n (Pm , ¬P<m) (Pn , ¬P<n) with m  n
+  ... | lt m<n = Empty.rec (¬P<n m m<n Pm)
+  ... | eq m≡n = m≡n
+  ... | gt n<m = Empty.rec (¬P<m n n<m Pn)
+
+  isPropΣLeast : (∀ m  isProp (P m))  isProp (Σ _ (Least P))
+  isPropΣLeast pP (m , LPm) (n , LPn)
+    = ΣPathP λ where
+        .fst  Least-unique m n LPm LPn
+        .snd  isOfHLevel→isOfHLevelDep 1 (isPropLeast pP)
+                LPm LPn (Least-unique m n LPm LPn)
+
+  Decidable→Collapsible
+    : (∀ m  isProp (P m))  (∀ m  Dec (P m))  Collapsible (Σ  P)
+  Decidable→Collapsible pP dP = λ where
+    .fst  Least→  →Least dP
+    .snd x y  cong Least→ (isPropΣLeast pP (→Least dP x) (→Least dP y))
+
+open Minimal using (Decidable→Collapsible) public
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Nat.Order.html b/docs/Cubical.Data.Nat.Order.html new file mode 100644 index 0000000..251b64d --- /dev/null +++ b/docs/Cubical.Data.Nat.Order.html @@ -0,0 +1,525 @@ + +Cubical.Data.Nat.Order
{-# OPTIONS --no-exact-split --safe #-}
+module Cubical.Data.Nat.Order where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.HLevels
+
+
+open import Cubical.Data.Empty as 
+open import Cubical.Data.Sigma
+open import Cubical.Data.Sum as 
+
+open import Cubical.Data.Nat.Base
+open import Cubical.Data.Nat.Properties
+
+open import Cubical.Induction.WellFounded
+
+open import Cubical.Relation.Nullary
+
+private
+  variable
+     : Level
+
+infix 4 _≤_ _<_ _≥_ _>_
+
+_≤_ :     Type₀
+m  n = Σ[ k   ] k + m  n
+
+_<_ :     Type₀
+m < n = suc m  n
+
+_≥_ :     Type₀
+m  n = n  m
+
+_>_ :     Type₀
+m > n = n < m
+
+data Trichotomy (m n : ) : Type₀ where
+  lt : m < n  Trichotomy m n
+  eq : m  n  Trichotomy m n
+  gt : n < m  Trichotomy m n
+
+private
+  variable
+    k l m n : 
+
+private
+  witness-prop :  j  isProp (j + m  n)
+  witness-prop {m} {n} j = isSetℕ (j + m) n
+
+isProp≤ : isProp (m  n)
+isProp≤ {m} {n} (k , p) (l , q)
+  = Σ≡Prop witness-prop lemma
+  where
+  lemma : k  l
+  lemma = inj-+m (p  (sym q))
+
+zero-≤ : 0  n
+zero-≤ {n} = n , +-zero n
+
+suc-≤-suc : m  n  suc m  suc n
+suc-≤-suc (k , p) = k , (+-suc k _)  (cong suc p)
+
+≤-+k : m  n  m + k  n + k
+≤-+k {m} {k = k} (i , p)
+  = i , +-assoc i m k  cong (_+ k) p
+
+≤SumRight : n  k + n
+≤SumRight {n} {k} = ≤-+k zero-≤
+
+≤-k+ : m  n  k + m  k + n
+≤-k+ {m} {n} {k}
+  = subst (_≤ k + n) (+-comm m k)
+   subst (m + k ≤_) (+-comm n k)
+   ≤-+k
+
+≤SumLeft : n  n + k
+≤SumLeft {n} {k} = subst (n ≤_) (+-comm k n) (≤-+k zero-≤)
+
+pred-≤-pred : suc m  suc n  m  n
+pred-≤-pred (k , p) = k , injSuc ((sym (+-suc k _))  p)
+
+≤-refl : m  m
+≤-refl = 0 , refl
+
+≤-suc : m  n  m  suc n
+≤-suc (k , p) = suc k , cong suc p
+
+suc-< : suc m < n  m < n
+suc-< p = pred-≤-pred (≤-suc p)
+
+≤-sucℕ : n  suc n
+≤-sucℕ = ≤-suc ≤-refl
+
+≤-predℕ : predℕ n  n
+≤-predℕ {zero} = ≤-refl
+≤-predℕ {suc n} = ≤-suc ≤-refl
+
+≤-trans : k  m  m  n  k  n
+≤-trans {k} {m} {n} (i , p) (j , q) = i + j , l2  (l1  q)
+  where
+  l1 : j + i + k  j + m
+  l1 = (sym (+-assoc j i k))  (cong (j +_) p)
+  l2 : i + j + k  j + i + k
+  l2 = cong (_+ k) (+-comm i j)
+
+≤-antisym : m  n  n  m  m  n
+≤-antisym {m} (i , p) (j , q) = (cong (_+ m) l3)  p
+  where
+  l1 : j + i + m  m
+  l1 = (sym (+-assoc j i m))  ((cong (j +_) p)  q)
+  l2 : j + i  0
+  l2 = m+n≡n→m≡0 l1
+  l3 : 0  i
+  l3 = sym (snd (m+n≡0→m≡0×n≡0 l2))
+
+≤-+-≤ : m  n  l  k  m + l  n + k
+≤-+-≤ p q = ≤-trans (≤-+k p) (≤-k+ q)
+
+≤-k+-cancel : k + m  k + n  m  n
+≤-k+-cancel {k} {m} (l , p) = l , inj-m+ (sub k m  p)
+ where
+ sub :  k m  k + (l + m)  l + (k + m)
+ sub k m = +-assoc k l m  cong (_+ m) (+-comm k l)  sym (+-assoc l k m)
+
+≤-+k-cancel : m + k  n + k  m  n
+≤-+k-cancel {m} {k} {n} (l , p) = l , cancelled
+ where
+ cancelled : l + m  n
+ cancelled = inj-+m (sym (+-assoc l m k)  p)
+
+≤-+k-trans : (m + k  n)  m  n
+≤-+k-trans {m} {k} {n} p = ≤-trans (k , +-comm k m) p
+
+≤-k+-trans : (k + m  n)  m  n
+≤-k+-trans {m} {k} {n} p = ≤-trans (m , refl) p
+
+≤-·k : m  n  m · k  n · k
+≤-·k {m} {n} {k} (d , r) = d · k , reason where
+  reason : d · k + m · k  n · k
+  reason = d · k + m · k ≡⟨ ·-distribʳ d m k 
+           (d + m) · k   ≡⟨ cong ( k) r 
+           n · k         
+
+<-k+-cancel : k + m < k + n  m < n
+<-k+-cancel {k} {m} {n} = ≤-k+-cancel  subst (_≤ k + n) (sym (+-suc k m))
+
+¬-<-zero : ¬ m < 0
+¬-<-zero (k , p) = snotz ((sym (+-suc k _))  p)
+
+¬m<m : ¬ m < m
+¬m<m {m} = ¬-<-zero  ≤-+k-cancel {k = m}
+
+≤0→≡0 : n  0  n  0
+≤0→≡0 {zero} ineq = refl
+≤0→≡0 {suc n} ineq = ⊥.rec (¬-<-zero ineq)
+
+predℕ-≤-predℕ : m  n  (predℕ m)  (predℕ n)
+predℕ-≤-predℕ {zero} {zero}   ineq = ≤-refl
+predℕ-≤-predℕ {zero} {suc n}  ineq = zero-≤
+predℕ-≤-predℕ {suc m} {zero}  ineq = ⊥.rec (¬-<-zero ineq)
+predℕ-≤-predℕ {suc m} {suc n} ineq = pred-≤-pred ineq
+
+¬m+n<m : ¬ m + n < m
+¬m+n<m {m} {n} = ¬-<-zero  <-k+-cancel  subst (m + n <_) (sym (+-zero m))
+
+<-weaken : m < n  m  n
+<-weaken (k , p) = suc k , sym (+-suc k _)  p
+
+≤<-trans : l  m  m < n  l < n
+≤<-trans p = ≤-trans (suc-≤-suc p)
+
+<≤-trans : l < m  m  n  l < n
+<≤-trans = ≤-trans
+
+<-trans : l < m  m < n  l < n
+<-trans p = ≤<-trans (<-weaken p)
+
+<-asym : m < n  ¬ n  m
+<-asym m<n = ¬m<m  <≤-trans m<n
+
+<-+k : m < n  m + k < n + k
+<-+k p = ≤-+k p
+
+<-k+ : m < n  k + m < k + n
+<-k+ {m} {n} {k} p = subst  km  km  k + n) (+-suc k m) (≤-k+ p)
+
+<-+k-trans : (m + k < n)  m < n
+<-+k-trans {m} {k} {n} p = ≤<-trans (k , +-comm k m) p
+
+<-k+-trans : (k + m < n)  m < n
+<-k+-trans {m} {k} {n} p = ≤<-trans (m , refl) p
+
+<-+-< : m < n  k < l  m + k < n + l
+<-+-<  m<n k<l = <-trans (<-+k m<n) (<-k+ k<l)
+
+<-+-≤ : m < n  k  l  m + k < n + l
+<-+-≤ p q = <≤-trans (<-+k p) (≤-k+ q)
+
+<-·sk : m < n  m · suc k < n · suc k
+<-·sk {m} {n} {k} (d , r) = (d · suc k + k) , reason where
+  reason : (d · suc k + k) + suc (m · suc k)  n · suc k
+  reason = (d · suc k + k) + suc (m · suc k) ≡⟨ sym (+-assoc (d · suc k) k _) 
+           d · suc k + (k + suc (m · suc k)) ≡[ i ]⟨ d · suc k + +-suc k (m · suc k) i 
+           d · suc k + suc m · suc k         ≡⟨ ·-distribʳ d (suc m) (suc k) 
+           (d + suc m) · suc k               ≡⟨ cong ( suc k) r 
+           n · suc k                         
+
+∸-≤ :  m n  m  n  m
+∸-≤ m zero = ≤-refl
+∸-≤ zero (suc n) = ≤-refl
+∸-≤ (suc m) (suc n) = ≤-trans (∸-≤ m n) (1 , refl)
+
+≤-∸-+-cancel : m  n  (n  m) + m  n
+≤-∸-+-cancel {zero} {n} _ = +-zero _
+≤-∸-+-cancel {suc m} {zero} m≤n = ⊥.rec (¬-<-zero m≤n)
+≤-∸-+-cancel {suc m} {suc n} m+1≤n+1 = +-suc _ _  cong suc (≤-∸-+-cancel (pred-≤-pred m+1≤n+1))
+
+≤-∸-suc : m  n  suc (n  m)  suc n  m
+≤-∸-suc {zero} {n} m≤n = refl
+≤-∸-suc {suc m} {zero} m≤n = ⊥.rec (¬-<-zero m≤n)
+≤-∸-suc {suc m} {suc n} m+1≤n+1 = ≤-∸-suc (pred-≤-pred m+1≤n+1)
+
+≤-∸-k : m  n  k + (n  m)  (k + n)  m
+≤-∸-k {m} {n} {zero} r = refl
+≤-∸-k {m} {n} {suc k} r = cong suc (≤-∸-k r)  ≤-∸-suc (≤-trans r (k , refl))
+
+left-≤-max : m  max m n
+left-≤-max {zero} {n} = zero-≤
+left-≤-max {suc m} {zero} = ≤-refl
+left-≤-max {suc m} {suc n} = suc-≤-suc left-≤-max
+
+right-≤-max : n  max m n
+right-≤-max {zero} {m} = zero-≤
+right-≤-max {suc n} {zero} = ≤-refl
+right-≤-max {suc n} {suc m} = suc-≤-suc right-≤-max
+
+min-≤-left : min m n  m
+min-≤-left {zero} {n} = ≤-refl
+min-≤-left {suc m} {zero} = zero-≤
+min-≤-left {suc m} {suc n} = suc-≤-suc min-≤-left
+
+min-≤-right : min m n  n
+min-≤-right {zero} {n} = zero-≤
+min-≤-right {suc m} {zero} = ≤-refl
+min-≤-right {suc m} {suc n} = suc-≤-suc min-≤-right
+
+≤Dec :  m n  Dec (m  n)
+≤Dec zero n = yes (n , +-zero _)
+≤Dec (suc m) zero = no ¬-<-zero
+≤Dec (suc m) (suc n) with ≤Dec m n
+... | yes m≤n = yes (suc-≤-suc m≤n)
+... | no m≰n = no λ m+1≤n+1  m≰n (pred-≤-pred m+1≤n+1 )
+
+≤Stable :  m n  Stable (m  n)
+≤Stable m n = Dec→Stable (≤Dec m n)
+
+<Dec :  m n  Dec (m < n)
+<Dec m n = ≤Dec (suc m) n
+
+<Stable :  m n  Stable (m < n)
+<Stable m n = Dec→Stable (<Dec m n)
+
+Trichotomy-suc : Trichotomy m n  Trichotomy (suc m) (suc n)
+Trichotomy-suc (lt m<n) = lt (suc-≤-suc m<n)
+Trichotomy-suc (eq m=n) = eq (cong suc m=n)
+Trichotomy-suc (gt n<m) = gt (suc-≤-suc n<m)
+
+_≟_ :  m n  Trichotomy m n
+zero  zero = eq refl
+zero  suc n = lt (n , +-comm n 1)
+suc m  zero = gt (m , +-comm m 1)
+suc m  suc n = Trichotomy-suc (m  n)
+
+splitℕ-≤ : (m n : )  (m  n)  (n < m)
+splitℕ-≤ m n with m  n
+... | lt x = inl (<-weaken x)
+... | eq x = inl (0 , x)
+... | gt x = inr x
+
+splitℕ-< : (m n : )  (m < n)  (n  m)
+splitℕ-< m n with m  n
+... | lt x = inl x
+... | eq x = inr (0 , (sym x))
+... | gt x = inr (<-weaken x)
+
+≤CaseInduction : {P :     Type } {n m : }
+   (n  m  P n m)  (m  n  P n m)
+   P n m
+≤CaseInduction {n = n} {m = m} p q with n  m
+... | lt x = p (<-weaken x)
+... | eq x = p (subst (n ≤_) x ≤-refl)
+... | gt x = q (<-weaken x)
+
+<-split : m < suc n  (m < n)  (m  n)
+<-split {n = zero} = inr  snd  m+n≡0→m≡0×n≡0  snd  pred-≤-pred
+<-split {zero} {suc n} = λ _  inl (suc-≤-suc zero-≤)
+<-split {suc m} {suc n} = ⊎.map suc-≤-suc (cong suc)  <-split  pred-≤-pred
+
+≤-split : m  n  (m < n)  (m  n)
+≤-split p = <-split (suc-≤-suc p)
+
+≤→< : m  n  ¬ m  n  m < n
+≤→< p q =
+  case (≤-split p) of
+    λ { (inl r)  r
+      ; (inr r)  ⊥.rec (q r) }
+
+≤-suc-≢ : m  suc n  (m  suc n   )  m  n
+≤-suc-≢ p ¬q = pred-≤-pred (≤→< p ¬q)
+
+≤-+-split :  n m k  k  n + m  (n  k)  (m  (n + m)  k)
+≤-+-split n m k k≤n+m with n  k
+... | eq p = inl (0 , p)
+... | lt n<k = inl (<-weaken n<k)
+... | gt k<n with m  ((n + m)  k)
+... | eq p = inr (0 , p)
+... | lt m<n+m∸k = inr (<-weaken m<n+m∸k)
+... | gt n+m∸k<m =
+      ⊥.rec (¬m<m (transport  i  ≤-∸-+-cancel k≤n+m i < +-comm m n i) (<-+-< n+m∸k<m k<n)))
+
+<-asym'-case : Trichotomy m n  ¬ m < n  n  m
+<-asym'-case (lt p) q = ⊥.rec (q p)
+<-asym'-case (eq p) _ = _ , sym p
+<-asym'-case (gt p) _ = <-weaken p
+
+<-asym' : ¬ m < n  n  m
+<-asym' = <-asym'-case (_≟_ _ _)
+
+private
+  acc-suc : Acc _<_ n  Acc _<_ (suc n)
+  acc-suc a
+    = acc λ y y<sn
+     case <-split y<sn of λ
+    { (inl y<n)  access a y y<n
+    ; (inr y≡n)  subst _ (sym y≡n) a
+    }
+
+<-wellfounded : WellFounded _<_
+<-wellfounded zero = acc λ _  ⊥.rec  ¬-<-zero
+<-wellfounded (suc n) = acc-suc (<-wellfounded n)
+
+<→≢ : n < m  ¬ n  m
+<→≢ {n} {m} p q = ¬m<m (subst (_< m) q p)
+
+module _
+    (b₀ : )
+    (P :   Type₀)
+    (base :  n  n < suc b₀  P n)
+    (step :  n  P n  P (suc b₀ + n))
+  where
+  open WFI (<-wellfounded)
+
+  private
+    dichotomy :  b n  (n < b)  (Σ[ m   ] n  b + m)
+    dichotomy b n
+      = case n  b return  _  (n < b)  (Σ[ m   ] n  b + m)) of λ
+      { (lt o)  inl o
+      ; (eq p)  inr (0 , p  sym (+-zero b))
+      ; (gt (m , p))  inr (suc m , sym p  +-suc m b  +-comm (suc m) b)
+      }
+
+    dichotomy<≡ :  b n  (n<b : n < b)  dichotomy b n  inl n<b
+    dichotomy<≡ b n n<b
+      = case dichotomy b n return  d  d  inl n<b) of λ
+      { (inl x)  cong inl (isProp≤ x n<b)
+      ; (inr (m , p))  ⊥.rec (<-asym n<b (m , sym (p  +-comm b m)))
+      }
+
+    dichotomy+≡ :  b m n  (p : n  b + m)  dichotomy b n  inr (m , p)
+    dichotomy+≡ b m n p
+      = case dichotomy b n return  d  d  inr (m , p)) of λ
+      { (inl n<b)  ⊥.rec (<-asym n<b (m , +-comm m b  sym p))
+      ; (inr (m' , q))
+       cong inr (Σ≡Prop  x  isSetℕ n (b + x)) (inj-m+ {m = b} (sym q  p)))
+      }
+
+    b = suc b₀
+
+    lemma₁ : ∀{x y z}  x  suc z + y  y < x
+    lemma₁ {y = y} {z} p = z , +-suc z y  sym p
+
+    subStep : (n : )  (∀ m  m < n  P m)  (n < b)  (Σ[ m   ] n  b + m)  P n
+    subStep n _   (inl l) = base n l
+    subStep n rec (inr (m , p))
+      = transport (cong P (sym p)) (step m (rec m (lemma₁ p)))
+
+    wfStep : (n : )  (∀ m  m < n  P m)  P n
+    wfStep n rec = subStep n rec (dichotomy b n)
+
+    wfStepLemma₀ :  n (n<b : n < b) rec  wfStep n rec  base n n<b
+    wfStepLemma₀ n n<b rec = cong (subStep n rec) (dichotomy<≡ b n n<b)
+
+    wfStepLemma₁ :  n rec  wfStep (b + n) rec  step n (rec n (lemma₁ refl))
+    wfStepLemma₁ n rec
+      = cong (subStep (b + n) rec) (dichotomy+≡ b n (b + n) refl)
+       transportRefl _
+
+  +induction :  n  P n
+  +induction = induction wfStep
+
+  +inductionBase :  n  (l : n < b)  +induction n  base n l
+  +inductionBase n l = induction-compute wfStep n  wfStepLemma₀ n l _
+
+  +inductionStep :  n  +induction (b + n)  step n (+induction n)
+  +inductionStep n = induction-compute wfStep (b + n)  wfStepLemma₁ n _
+
+module <-Reasoning where
+  -- TODO: would it be better to mirror the way it is done in the agda-stdlib?
+  infixr 2 _<⟨_⟩_ _≤<⟨_⟩_ _≤⟨_⟩_ _<≤⟨_⟩_ _≡<⟨_⟩_ _≡≤⟨_⟩_ _<≡⟨_⟩_ _≤≡⟨_⟩_
+  _<⟨_⟩_ :  k  k < n  n < m  k < m
+  _ <⟨ p  q = <-trans p q
+
+  _≤<⟨_⟩_ :  k  k  n  n < m  k < m
+  _ ≤<⟨ p  q = ≤<-trans p q
+
+  _≤⟨_⟩_ :  k  k  n  n  m  k  m
+  _ ≤⟨ p  q = ≤-trans p q
+
+  _<≤⟨_⟩_ :  k  k < n  n  m  k < m
+  _ <≤⟨ p  q = <≤-trans p q
+
+  _≡≤⟨_⟩_ :  k  k  l  l  m  k  m
+  _ ≡≤⟨ p  q = subst  k  k  _) (sym p) q
+
+  _≡<⟨_⟩_ :  k  k  l  l < m  k < m
+  _ ≡<⟨ p  q = _ ≡≤⟨ cong suc p  q
+
+  _≤≡⟨_⟩_ :  k  k  l  l  m  k  m
+  _ ≤≡⟨ p  q = subst  l  _  l) q p
+
+  _<≡⟨_⟩_ :  k  k < l  l  m  k < m
+  _ <≡⟨ p  q = _ ≤≡⟨ p  q
+
+
+-- Some lemmas about ∸
+suc∸-fst : (n m : )  m < n  suc (n  m)  (suc n)  m
+suc∸-fst zero zero p = refl
+suc∸-fst zero (suc m) p = ⊥.rec (¬-<-zero p)
+suc∸-fst (suc n) zero p = refl
+suc∸-fst (suc n) (suc m) p = (suc∸-fst n m (pred-≤-pred p))
+
+n∸m≡0 : (n m : )  n  m  (n  m)  0
+n∸m≡0 zero zero p = refl
+n∸m≡0 (suc n) zero p = ⊥.rec (¬-<-zero p)
+n∸m≡0 zero (suc m) p = refl
+n∸m≡0 (suc n) (suc m) p = n∸m≡0 n m (pred-≤-pred p)
+
+n∸n≡0 : (n : )  n  n  0
+n∸n≡0 zero = refl
+n∸n≡0 (suc n) = n∸n≡0 n
+
+n∸l>0 : (n l : )  (l < n)  0 < (n  l)
+n∸l>0  zero    zero   r = ⊥.rec (¬-<-zero r)
+n∸l>0  zero   (suc l) r = ⊥.rec (¬-<-zero r)
+n∸l>0 (suc n)  zero   r = suc-≤-suc zero-≤
+n∸l>0 (suc n) (suc l) r = n∸l>0 n l (pred-≤-pred r)
+
+-- automation
+
+≤-solver-type : (m n : )  Trichotomy m n  Type
+≤-solver-type m n (lt p) = m  n
+≤-solver-type m n (eq p) = m  n
+≤-solver-type m n (gt p) = n < m
+
+≤-solver-case : (m n : )  (p : Trichotomy m n)  ≤-solver-type m n p
+≤-solver-case m n (lt p) = <-weaken p
+≤-solver-case m n (eq p) = _ , p
+≤-solver-case m n (gt p) = p
+
+≤-solver : (m n : )  ≤-solver-type m n (m  n)
+≤-solver m n = ≤-solver-case m n (m  n)
+
+
+
+-- inductive order relation taken from agda-stdlib
+data _≤'_ :     Type where
+  z≤ :  {n}  zero ≤' n
+  s≤s :  {m n}  m ≤' n  suc m ≤' suc n
+
+_<'_ :     Type
+m <' n = suc m ≤' n
+
+-- Smart constructors of _<_
+pattern z<s {n}         = s≤s (z≤ {n})
+pattern s<s {m} {n} m<n = s≤s {m} {n} m<n
+
+¬-<'-zero : ¬ m <' 0
+¬-<'-zero {zero} ()
+¬-<'-zero {suc m} ()
+
+≤'Dec :  m n  Dec (m ≤' n)
+≤'Dec zero n = yes z≤
+≤'Dec (suc m) zero = no ¬-<'-zero
+≤'Dec (suc m) (suc n) with ≤'Dec m n
+... | yes m≤'n = yes (s≤s m≤'n)
+... | no m≰'n = no λ { (s≤s m≤'n)  m≰'n m≤'n }
+
+≤'IsPropValued :  m n  isProp (m ≤' n)
+≤'IsPropValued zero n z≤ z≤ = refl
+≤'IsPropValued (suc m) zero ()
+≤'IsPropValued (suc m) (suc n) (s≤s x) (s≤s y) = cong s≤s (≤'IsPropValued m n x y)
+
+≤-∸-≤ :  m n l  m  n  m  l  n  l
+≤-∸-≤  m       n       zero   r = r
+≤-∸-≤  zero    zero   (suc l) r = ≤-refl
+≤-∸-≤  zero   (suc n) (suc l) r = (n  l) , (+-zero _)
+≤-∸-≤ (suc m)  zero   (suc l) r = ⊥.rec (¬-<-zero r)
+≤-∸-≤ (suc m) (suc n) (suc l) r = ≤-∸-≤ m n l (pred-≤-pred r)
+
+<-∸-< :  m n l  m < n  l < n  m  l < n  l
+<-∸-<  m       n       zero   r q = r
+<-∸-<  zero    zero   (suc l) r q = ⊥.rec (¬-<-zero r)
+<-∸-<  zero   (suc n) (suc l) r q = n∸l>0 (suc n) (suc l) q
+<-∸-< (suc m)  zero   (suc l) r q = ⊥.rec (¬-<-zero r)
+<-∸-< (suc m) (suc n) (suc l) r q = <-∸-< m n l (pred-≤-pred r) (pred-≤-pred q)
+
+≤-∸-≥ :  n l k  l  k  n  k  n  l
+≤-∸-≥ n  zero    zero   r = ≤-refl
+≤-∸-≥ n  zero   (suc k) r = ∸-≤ n (suc k)
+≤-∸-≥ n (suc l)  zero   r = ⊥.rec (¬-<-zero r)
+≤-∸-≥  zero   (suc l) (suc k) r = ≤-refl
+≤-∸-≥ (suc n) (suc l) (suc k) r = ≤-∸-≥ n l k (pred-≤-pred r)
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Prod.Base.html b/docs/Cubical.Data.Prod.Base.html new file mode 100644 index 0000000..5e7bec3 --- /dev/null +++ b/docs/Cubical.Data.Prod.Base.html @@ -0,0 +1,62 @@ + +Cubical.Data.Prod.Base
{-# OPTIONS --safe #-}
+module Cubical.Data.Prod.Base where
+
+open import Cubical.Core.Everything
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Function
+
+-- Here we define an inductive version of the product type, see below
+-- for its uses.
+
+-- See `Cubical.Data.Sigma` for `_×_` defined as a special case of
+-- sigma types, which is the generally preferred one.
+
+-- If × is defined using Σ then transp/hcomp will be compute
+-- "negatively", that is, they won't reduce unless we project out the
+-- first of second component. This is not always what we want so this
+-- implementation is done using a datatype which computes positively.
+
+
+private
+  variable
+     ℓ' : Level
+
+data _×_ (A : Type ) (B : Type ℓ') : Type (ℓ-max  ℓ') where
+  _,_ : A  B  A × B
+
+infixr 5 _×_
+
+proj₁ : {A : Type } {B : Type ℓ'}  A × B  A
+proj₁ (x , _) = x
+
+proj₂ : {A : Type } {B : Type ℓ'}  A × B  B
+proj₂ (_ , x) = x
+
+
+private
+  variable
+    A    : Type 
+    B C  : A  Type 
+
+intro : (∀ a  B a)  (∀ a  C a)   a  B a × C a
+intro f g a = f a , g a
+
+map : {B : Type } {D : B  Type ℓ'}
+    (∀ a  C a)  (∀ b  D b)  (x : A × B)  C (proj₁ x) × D (proj₂ x)
+map f g = intro (f  proj₁) (g  proj₂)
+
+
+×-η : {A : Type } {B : Type ℓ'} (x : A × B)  x  ((proj₁ x) , (proj₂ x))
+×-η (x , x₁) = refl
+
+
+-- The product type with one parameter in Typeω
+
+record _×ω_ {a} (A : Type a) (B : Typeω) : Typeω where
+  constructor _,_
+  field
+    fst : A
+    snd : B
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Sum.Properties.html b/docs/Cubical.Data.Sum.Properties.html new file mode 100644 index 0000000..82eab06 --- /dev/null +++ b/docs/Cubical.Data.Sum.Properties.html @@ -0,0 +1,201 @@ + +Cubical.Data.Sum.Properties
{-# OPTIONS --safe #-}
+module Cubical.Data.Sum.Properties where
+
+open import Cubical.Core.Everything
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.HLevels
+open import Cubical.Functions.Embedding
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Data.Empty
+open import Cubical.Data.Nat
+open import Cubical.Data.Sigma
+open import Cubical.Relation.Nullary
+
+open import Cubical.Data.Sum.Base
+
+open Iso
+
+
+private
+  variable
+    ℓa ℓb ℓc ℓd ℓe : Level
+    A : Type ℓa
+    B : Type ℓb
+    C : Type ℓc
+    D : Type ℓd
+    E : A  B  Type ℓe
+
+
+-- Path space of sum type
+module ⊎Path { ℓ'} {A : Type } {B : Type ℓ'} where
+
+  Cover : A  B  A  B  Type (ℓ-max  ℓ')
+  Cover (inl a) (inl a') = Lift {j = ℓ-max  ℓ'} (a  a')
+  Cover (inl _) (inr _) = Lift 
+  Cover (inr _) (inl _) = Lift 
+  Cover (inr b) (inr b') = Lift {j = ℓ-max  ℓ'} (b  b')
+
+  reflCode : (c : A  B)  Cover c c
+  reflCode (inl a) = lift refl
+  reflCode (inr b) = lift refl
+
+  encode :  c c'  c  c'  Cover c c'
+  encode c _ = J  c' _  Cover c c') (reflCode c)
+
+  encodeRefl :  c  encode c c refl  reflCode c
+  encodeRefl c = JRefl  c' _  Cover c c') (reflCode c)
+
+  decode :  c c'  Cover c c'  c  c'
+  decode (inl a) (inl a') (lift p) = cong inl p
+  decode (inl a) (inr b') ()
+  decode (inr b) (inl a') ()
+  decode (inr b) (inr b') (lift q) = cong inr q
+
+  decodeRefl :  c  decode c c (reflCode c)  refl
+  decodeRefl (inl a) = refl
+  decodeRefl (inr b) = refl
+
+  decodeEncode :  c c'  (p : c  c')  decode c c' (encode c c' p)  p
+  decodeEncode c _ =
+    J  c' p  decode c c' (encode c c' p)  p)
+      (cong (decode c c) (encodeRefl c)  decodeRefl c)
+
+  encodeDecode :  c c'  (d : Cover c c')  encode c c' (decode c c' d)  d
+  encodeDecode (inl a) (inl _) (lift d) =
+    J  a' p  encode (inl a) (inl a') (cong inl p)  lift p) (encodeRefl (inl a)) d
+  encodeDecode (inr a) (inr _) (lift d) =
+    J  a' p  encode (inr a) (inr a') (cong inr p)  lift p) (encodeRefl (inr a)) d
+
+  Cover≃Path :  c c'  Cover c c'  (c  c')
+  Cover≃Path c c' =
+    isoToEquiv (iso (decode c c') (encode c c') (decodeEncode c c') (encodeDecode c c'))
+
+  isOfHLevelCover : (n : HLevel)
+     isOfHLevel (suc (suc n)) A
+     isOfHLevel (suc (suc n)) B
+      c c'  isOfHLevel (suc n) (Cover c c')
+  isOfHLevelCover n p q (inl a) (inl a') = isOfHLevelLift (suc n) (p a a')
+  isOfHLevelCover n p q (inl a) (inr b') =
+    isOfHLevelLift (suc n) (isProp→isOfHLevelSuc n isProp⊥)
+  isOfHLevelCover n p q (inr b) (inl a') =
+    isOfHLevelLift (suc n) (isProp→isOfHLevelSuc n isProp⊥)
+  isOfHLevelCover n p q (inr b) (inr b') = isOfHLevelLift (suc n) (q b b')
+
+isEmbedding-inl : isEmbedding (inl {A = A} {B = B})
+isEmbedding-inl w z = snd (compEquiv LiftEquiv (⊎Path.Cover≃Path (inl w) (inl z)))
+
+isEmbedding-inr : isEmbedding (inr {A = A} {B = B})
+isEmbedding-inr w z = snd (compEquiv LiftEquiv (⊎Path.Cover≃Path (inr w) (inr z)))
+
+isOfHLevel⊎ : (n : HLevel)
+   isOfHLevel (suc (suc n)) A
+   isOfHLevel (suc (suc n)) B
+   isOfHLevel (suc (suc n)) (A  B)
+isOfHLevel⊎ n lA lB c c' =
+  isOfHLevelRetract (suc n)
+    (⊎Path.encode c c')
+    (⊎Path.decode c c')
+    (⊎Path.decodeEncode c c')
+    (⊎Path.isOfHLevelCover n lA lB c c')
+
+isSet⊎ : isSet A  isSet B  isSet (A  B)
+isSet⊎ = isOfHLevel⊎ 0
+
+isGroupoid⊎ : isGroupoid A  isGroupoid B  isGroupoid (A  B)
+isGroupoid⊎ = isOfHLevel⊎ 1
+
+is2Groupoid⊎ : is2Groupoid A  is2Groupoid B  is2Groupoid (A  B)
+is2Groupoid⊎ = isOfHLevel⊎ 2
+
+discrete⊎ : Discrete A  Discrete B  Discrete (A  B)
+discrete⊎ decA decB (inl a) (inl a') =
+  mapDec (cong inl)  p q  p (isEmbedding→Inj isEmbedding-inl _ _ q)) (decA a a')
+discrete⊎ decA decB (inl a) (inr b') = no  p  lower (⊎Path.encode (inl a) (inr b') p))
+discrete⊎ decA decB (inr b) (inl a') = no ((λ p  lower (⊎Path.encode (inr b) (inl a') p)))
+discrete⊎ decA decB (inr b) (inr b') =
+  mapDec (cong inr)  p q  p (isEmbedding→Inj isEmbedding-inr _ _ q)) (decB b b')
+
+⊎Iso : Iso A C  Iso B D  Iso (A  B) (C  D)
+fun (⊎Iso iac ibd) (inl x) = inl (iac .fun x)
+fun (⊎Iso iac ibd) (inr x) = inr (ibd .fun x)
+inv (⊎Iso iac ibd) (inl x) = inl (iac .inv x)
+inv (⊎Iso iac ibd) (inr x) = inr (ibd .inv x)
+rightInv (⊎Iso iac ibd) (inl x) = cong inl (iac .rightInv x)
+rightInv (⊎Iso iac ibd) (inr x) = cong inr (ibd .rightInv x)
+leftInv (⊎Iso iac ibd) (inl x)  = cong inl (iac .leftInv x)
+leftInv (⊎Iso iac ibd) (inr x)  = cong inr (ibd .leftInv x)
+
+⊎-equiv : A  C  B  D  (A  B)  (C  D)
+⊎-equiv p q = isoToEquiv (⊎Iso (equivToIso p) (equivToIso q))
+
+⊎-swap-Iso : Iso (A  B) (B  A)
+fun ⊎-swap-Iso (inl x) = inr x
+fun ⊎-swap-Iso (inr x) = inl x
+inv ⊎-swap-Iso (inl x) = inr x
+inv ⊎-swap-Iso (inr x) = inl x
+rightInv ⊎-swap-Iso (inl _) = refl
+rightInv ⊎-swap-Iso (inr _) = refl
+leftInv ⊎-swap-Iso (inl _)  = refl
+leftInv ⊎-swap-Iso (inr _)  = refl
+
+⊎-swap-≃ : A  B  B  A
+⊎-swap-≃ = isoToEquiv ⊎-swap-Iso
+
+⊎-assoc-Iso : Iso ((A  B)  C) (A  (B  C))
+fun ⊎-assoc-Iso (inl (inl x)) = inl x
+fun ⊎-assoc-Iso (inl (inr x)) = inr (inl x)
+fun ⊎-assoc-Iso (inr x)       = inr (inr x)
+inv ⊎-assoc-Iso (inl x)       = inl (inl x)
+inv ⊎-assoc-Iso (inr (inl x)) = inl (inr x)
+inv ⊎-assoc-Iso (inr (inr x)) = inr x
+rightInv ⊎-assoc-Iso (inl _)       = refl
+rightInv ⊎-assoc-Iso (inr (inl _)) = refl
+rightInv ⊎-assoc-Iso (inr (inr _)) = refl
+leftInv ⊎-assoc-Iso (inl (inl _))  = refl
+leftInv ⊎-assoc-Iso (inl (inr _))  = refl
+leftInv ⊎-assoc-Iso (inr _)        = refl
+
+⊎-assoc-≃ : (A  B)  C  A  (B  C)
+⊎-assoc-≃ = isoToEquiv ⊎-assoc-Iso
+
+⊎-⊥-Iso : Iso (A  ) A
+fun ⊎-⊥-Iso (inl x) = x
+inv ⊎-⊥-Iso x       = inl x
+rightInv ⊎-⊥-Iso _      = refl
+leftInv ⊎-⊥-Iso (inl _) = refl
+
+⊎-⊥-≃ : A    A
+⊎-⊥-≃ = isoToEquiv ⊎-⊥-Iso
+
+Π⊎Iso : Iso ((x : A  B)  E x) (((a : A)  E (inl a)) × ((b : B)  E (inr b)))
+fun Π⊎Iso f .fst a = f (inl a)
+fun Π⊎Iso f .snd b = f (inr b)
+inv Π⊎Iso (g1 , g2) (inl a) = g1 a
+inv Π⊎Iso (g1 , g2) (inr b) = g2 b
+rightInv Π⊎Iso (g1 , g2) i .fst a = g1 a
+rightInv Π⊎Iso (g1 , g2) i .snd b = g2 b
+leftInv Π⊎Iso f i (inl a) = f (inl a)
+leftInv Π⊎Iso f i (inr b) = f (inr b)
+
+Σ⊎Iso : Iso (Σ (A  B) E) ((Σ A  a  E (inl a)))  (Σ B  b  E (inr b))))
+fun Σ⊎Iso (inl a , ea) = inl (a , ea)
+fun Σ⊎Iso (inr b , eb) = inr (b , eb)
+inv Σ⊎Iso (inl (a , ea)) = (inl a , ea)
+inv Σ⊎Iso (inr (b , eb)) = (inr b , eb)
+rightInv Σ⊎Iso (inl (a , ea)) = refl
+rightInv Σ⊎Iso (inr (b , eb)) = refl
+leftInv Σ⊎Iso (inl a , ea) = refl
+leftInv Σ⊎Iso (inr b , eb) = refl
+
+Π⊎≃ : ((x : A  B)  E x)  ((a : A)  E (inl a)) × ((b : B)  E (inr b))
+Π⊎≃ = isoToEquiv Π⊎Iso
+
+Σ⊎≃ : (Σ (A  B) E)  ((Σ A  a  E (inl a)))  (Σ B  b  E (inr b))))
+Σ⊎≃ = isoToEquiv Σ⊎Iso
+
+map-⊎ : (A  C)  (B  D)  A  B  C  D
+map-⊎ f _ (inl a) = inl (f a)
+map-⊎ _ g (inr b) = inr (g b)
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Sum.html b/docs/Cubical.Data.Sum.html new file mode 100644 index 0000000..5542259 --- /dev/null +++ b/docs/Cubical.Data.Sum.html @@ -0,0 +1,7 @@ + +Cubical.Data.Sum
{-# OPTIONS --safe #-}
+module Cubical.Data.Sum where
+
+open import Cubical.Data.Sum.Base public
+open import Cubical.Data.Sum.Properties public
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Unit.Properties.html b/docs/Cubical.Data.Unit.Properties.html new file mode 100644 index 0000000..b29dc9f --- /dev/null +++ b/docs/Cubical.Data.Unit.Properties.html @@ -0,0 +1,123 @@ + +Cubical.Data.Unit.Properties
{-# OPTIONS --safe #-}
+module Cubical.Data.Unit.Properties where
+
+open import Cubical.Core.Everything
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.HLevels
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Equiv
+
+open import Cubical.Data.Nat
+open import Cubical.Data.Unit.Base
+open import Cubical.Data.Prod.Base
+
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Univalence
+
+open import Cubical.Reflection.StrictEquiv
+
+open Iso
+
+private
+  variable
+     ℓ' : Level
+
+isContrUnit : isContr Unit
+isContrUnit = tt , λ {tt  refl}
+
+isPropUnit : isProp Unit
+isPropUnit _ _ i = tt -- definitionally equal to: isContr→isProp isContrUnit
+
+isSetUnit : isSet Unit
+isSetUnit = isProp→isSet isPropUnit
+
+isOfHLevelUnit : (n : HLevel)  isOfHLevel n Unit
+isOfHLevelUnit n = isContr→isOfHLevel n isContrUnit
+
+module _ (A : Type ) where
+  UnitToType≃ : (Unit  A)  A
+  unquoteDef UnitToType≃ = defStrictEquiv UnitToType≃  f  f _) const
+
+UnitToTypePath :  {} (A : Type )  (Unit  A)  A
+UnitToTypePath A = ua (UnitToType≃ A)
+
+module _ (A : Unit  Type ) where
+
+  open Iso
+
+  ΠUnitIso : Iso ((x : Unit)  A x) (A tt)
+  fun ΠUnitIso f = f tt
+  inv ΠUnitIso a tt = a
+  rightInv ΠUnitIso a = refl
+  leftInv ΠUnitIso f = refl
+
+  ΠUnit : ((x : Unit)  A x)  A tt
+  ΠUnit = isoToEquiv ΠUnitIso
+
+module _ (A : Unit* {}  Type ℓ') where
+
+  open Iso
+
+  ΠUnit*Iso : Iso ((x : Unit*)  A x) (A tt*)
+  fun ΠUnit*Iso f = f tt*
+  inv ΠUnit*Iso a tt* = a
+  rightInv ΠUnit*Iso a = refl
+  leftInv ΠUnit*Iso f = refl
+
+  ΠUnit* : ((x : Unit*)  A x)  A tt*
+  ΠUnit* = isoToEquiv ΠUnit*Iso
+
+fiberUnitIso : {A : Type }  Iso (fiber  (a : A)  tt) tt) A
+fun fiberUnitIso = fst
+inv fiberUnitIso a = a , refl
+rightInv fiberUnitIso _ = refl
+leftInv fiberUnitIso _ = refl
+
+isContr→Iso2 : {A : Type } {B : Type ℓ'}  isContr A  Iso (A  B) B
+fun (isContr→Iso2 iscontr) f = f (fst iscontr)
+inv (isContr→Iso2 iscontr) b _ = b
+rightInv (isContr→Iso2 iscontr) _ = refl
+leftInv (isContr→Iso2 iscontr) f = funExt λ x  cong f (snd iscontr x)
+
+diagonal-unit : Unit  Unit × Unit
+diagonal-unit = isoToPath (iso  x  tt , tt)  x  tt)  {(tt , tt) i  tt , tt}) λ {tt i  tt})
+
+fibId : (A : Type )  (fiber  (x : A)  tt) tt)  A
+fibId A = ua e
+  where
+  unquoteDecl e = declStrictEquiv e fst  a  a , refl)
+
+isContr→≃Unit : {A : Type }  isContr A  A  Unit
+isContr→≃Unit contr = isoToEquiv (iso  _  tt)  _  fst contr)  _  refl) λ _  snd contr _)
+
+isContr→≡Unit : {A : Type₀}  isContr A  A  Unit
+isContr→≡Unit contr = ua (isContr→≃Unit contr)
+
+isContrUnit* :  {}  isContr (Unit* {})
+isContrUnit* = tt* , λ _  refl
+
+isPropUnit* :  {}  isProp (Unit* {})
+isPropUnit* _ _ = refl
+
+isSetUnit* :  {}  isSet (Unit* {})
+isSetUnit* _ _ _ _ = refl
+
+isOfHLevelUnit* :  {} (n : HLevel)  isOfHLevel n (Unit* {})
+isOfHLevelUnit* zero = tt* , λ _  refl
+isOfHLevelUnit* (suc zero) _ _ = refl
+isOfHLevelUnit* (suc (suc zero)) _ _ _ _ _ _ = tt*
+isOfHLevelUnit* (suc (suc (suc n))) = isOfHLevelPlus 3 (isOfHLevelUnit* n)
+
+Unit≃Unit* :  {}  Unit  Unit* {}
+Unit≃Unit* = invEquiv (isContr→≃Unit isContrUnit*)
+
+isContr→≃Unit* : {A : Type }  isContr A  A  Unit* {}
+isContr→≃Unit* contr = compEquiv (isContr→≃Unit contr) Unit≃Unit*
+
+isContr→≡Unit* : {A : Type }  isContr A  A  Unit*
+isContr→≡Unit* contr = ua (isContr→≃Unit* contr)
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Unit.html b/docs/Cubical.Data.Unit.html new file mode 100644 index 0000000..9f7f4d3 --- /dev/null +++ b/docs/Cubical.Data.Unit.html @@ -0,0 +1,7 @@ + +Cubical.Data.Unit
{-# OPTIONS --safe #-}
+module Cubical.Data.Unit where
+
+open import Cubical.Data.Unit.Base       public
+open import Cubical.Data.Unit.Properties public
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Vec.Properties.html b/docs/Cubical.Data.Vec.Properties.html new file mode 100644 index 0000000..d86d1ed --- /dev/null +++ b/docs/Cubical.Data.Vec.Properties.html @@ -0,0 +1,143 @@ + +Cubical.Data.Vec.Properties
{-# OPTIONS --safe #-}
+module Cubical.Data.Vec.Properties where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.HLevels
+open import Cubical.Foundations.Univalence
+
+import Cubical.Data.Empty as 
+open import Cubical.Data.Unit
+open import Cubical.Data.Nat
+open import Cubical.Data.Sigma
+open import Cubical.Data.Sum
+open import Cubical.Data.Vec.Base
+open import Cubical.Data.FinData
+open import Cubical.Relation.Nullary
+
+open Iso
+
+private
+  variable
+     : Level
+    A : Type 
+
+
+-- This is really cool!
+-- Compare with: https://github.com/agda/agda-stdlib/blob/master/src/Data/Vec/Properties/WithK.agda#L32
+++-assoc :  {m n k} (xs : Vec A m) (ys : Vec A n) (zs : Vec A k) 
+           PathP  i  Vec A (+-assoc m n k (~ i))) ((xs ++ ys) ++ zs) (xs ++ ys ++ zs)
+++-assoc {m = zero} [] ys zs = refl
+++-assoc {m = suc m} (x  xs) ys zs i = x  ++-assoc xs ys zs i
+
+
+-- Equivalence between Fin n → A and Vec A n
+FinVec→Vec : {n : }  FinVec A n  Vec A n
+FinVec→Vec {n = zero}  xs = []
+FinVec→Vec {n = suc _} xs = xs zero  FinVec→Vec  x  xs (suc x))
+
+Vec→FinVec : {n : }  Vec A n  FinVec A n
+Vec→FinVec xs f = lookup f xs
+
+FinVec→Vec→FinVec : {n : } (xs : FinVec A n)  Vec→FinVec (FinVec→Vec xs)  xs
+FinVec→Vec→FinVec {n = zero} xs = funExt λ f  ⊥.rec (¬Fin0 f)
+FinVec→Vec→FinVec {n = suc n} xs = funExt goal
+  where
+  goal : (f : Fin (suc n))
+        Vec→FinVec (xs zero  FinVec→Vec  x  xs (suc x))) f  xs f
+  goal zero = refl
+  goal (suc f) i = FinVec→Vec→FinVec  x  xs (suc x)) i f
+
+Vec→FinVec→Vec : {n : } (xs : Vec A n)  FinVec→Vec (Vec→FinVec xs)  xs
+Vec→FinVec→Vec {n = zero}  [] = refl
+Vec→FinVec→Vec {n = suc n} (x  xs) i = x  Vec→FinVec→Vec xs i
+
+FinVecIsoVec : (n : )  Iso (FinVec A n) (Vec A n)
+FinVecIsoVec n = iso FinVec→Vec Vec→FinVec Vec→FinVec→Vec FinVec→Vec→FinVec
+
+FinVec≃Vec : (n : )  FinVec A n  Vec A n
+FinVec≃Vec n = isoToEquiv (FinVecIsoVec n)
+
+FinVec≡Vec : (n : )  FinVec A n  Vec A n
+FinVec≡Vec n = ua (FinVec≃Vec n)
+
+isContrVec0 : isContr (Vec A 0)
+isContrVec0 = [] , λ { []  refl }
+
+-- encode - decode Vec
+module VecPath {A : Type }
+  where
+
+  code : {n : }  (v v' : Vec A n)  Type 
+  code [] [] = Unit*
+  code (a  v) (a'  v') = (a  a') × (v  v')
+
+  -- encode
+  reflEncode : {n : }  (v : Vec A n)  code v v
+  reflEncode [] = tt*
+  reflEncode (a  v) = refl , refl
+
+  encode : {n : }  (v v' : Vec A n)  (v  v')  code v v'
+  encode v v' p = J  v' _  code v v') (reflEncode v) p
+
+  encodeRefl : {n : }  (v : Vec A n)  encode v v refl  reflEncode v
+  encodeRefl v = JRefl  v' _  code v v') (reflEncode v)
+
+  -- decode
+  decode : {n : }  (v v' : Vec A n)  (r : code v v')  (v  v')
+  decode [] [] _ = refl
+  decode (a  v) (a'  v') (p , q) = cong₂ _∷_ p q
+
+  decodeRefl : {n : }  (v : Vec A n)  decode v v (reflEncode v)  refl
+  decodeRefl [] = refl
+  decodeRefl (a  v) = refl
+
+  -- equiv
+  ≡Vec≃codeVec : {n : }  (v v' : Vec A n)  (v  v')  (code v v')
+  ≡Vec≃codeVec v v' = isoToEquiv is
+    where
+    is : Iso (v  v') (code v v')
+    fun is = encode v v'
+    inv is = decode v v'
+    rightInv is = sect v v'
+      where
+      sect : {n : }  (v v' : Vec A n)  (r : code v v')
+              encode v v' (decode v v' r)  r
+      sect [] [] tt* = encodeRefl []
+      sect (a  v) (a'  v') (p , q) = J  a' p  encode (a  v) (a'  v') (decode (a  v) (a'  v') (p , q))  (p , q))
+                                       (J  v' q  encode (a  v) (a  v') (decode (a  v) (a  v') (refl , q))  (refl , q))
+                                       (encodeRefl (a  v)) q) p
+    leftInv is = retr v v'
+      where
+      retr : {n : }  (v v' : Vec A n)  (p : v  v')
+              decode v v' (encode v v' p)  p
+      retr v v' p = J  v' p  decode v v' (encode v v' p)  p)
+                    (cong (decode v v) (encodeRefl v)  decodeRefl v) p
+
+
+  isOfHLevelVec : (h : HLevel) (n : )
+                   isOfHLevel (suc (suc h)) A  isOfHLevel (suc (suc h)) (Vec A n)
+  isOfHLevelVec h zero ofLevelA [] [] = isOfHLevelRespectEquiv (suc h) (invEquiv (≡Vec≃codeVec [] []))
+                                        (isOfHLevelUnit* (suc h))
+  isOfHLevelVec h (suc n) ofLevelA (x  v) (x'  v') = isOfHLevelRespectEquiv (suc h) (invEquiv (≡Vec≃codeVec _ _))
+                                                       (isOfHLevelΣ (suc h) (ofLevelA x x')  _  isOfHLevelVec h n ofLevelA v v'))
+
+
+  discreteA→discreteVecA : Discrete A  (n : )  Discrete (Vec A n)
+  discreteA→discreteVecA DA zero [] [] = yes refl
+  discreteA→discreteVecA DA (suc n) (a  v) (a'  v') with (DA a a') | (discreteA→discreteVecA DA n v v')
+  ... | yes p | yes q = yes (invIsEq (snd (≡Vec≃codeVec (a  v) (a'  v'))) (p , q))
+  ... | yes p | no ¬q = no  r  ¬q (snd (funIsEq (snd (≡Vec≃codeVec (a  v) (a'  v'))) r)))
+  ... | no ¬p | yes q = no  r  ¬p (fst (funIsEq (snd (≡Vec≃codeVec (a  v) (a'  v'))) r)))
+  ... | no ¬p | no ¬q = no  r  ¬q (snd (funIsEq (snd (≡Vec≃codeVec (a  v) (a'  v'))) r)))
+
+  ≢-∷ : {m : }  (Discrete A)  (a : A)  (v : Vec A m)  (a' : A)  (v' : Vec A m) 
+         (a  v  a'  v'  ⊥.⊥)  (a  a'  ⊥.⊥)  (v  v'  ⊥.⊥)
+  ≢-∷ {m} discreteA a v a' v' ¬r with (discreteA a a')
+                        | (discreteA→discreteVecA discreteA m v v')
+  ... | yes p | yes q = ⊥.rec (¬r (cong₂ _∷_ p q))
+  ... | yes p | no ¬q = inr ¬q
+  ... | no ¬p | y = inl ¬p
+
\ No newline at end of file diff --git a/docs/Cubical.Data.Vec.html b/docs/Cubical.Data.Vec.html new file mode 100644 index 0000000..62809d6 --- /dev/null +++ b/docs/Cubical.Data.Vec.html @@ -0,0 +1,7 @@ + +Cubical.Data.Vec
{-# OPTIONS --safe #-}
+module Cubical.Data.Vec where
+
+open import Cubical.Data.Vec.Base public
+open import Cubical.Data.Vec.Properties public
+
\ No newline at end of file diff --git a/docs/Cubical.Foundations.Equiv.Fiberwise.html b/docs/Cubical.Foundations.Equiv.Fiberwise.html new file mode 100644 index 0000000..7926967 --- /dev/null +++ b/docs/Cubical.Foundations.Equiv.Fiberwise.html @@ -0,0 +1,101 @@ + +Cubical.Foundations.Equiv.Fiberwise
{-# OPTIONS --safe #-}
+module Cubical.Foundations.Equiv.Fiberwise where
+
+open import Cubical.Core.Everything
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Equiv.Properties
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.HLevels
+open import Cubical.Data.Sigma
+
+private
+  variable
+     ℓ' ℓ'' : Level
+
+module _ {A : Type } (P : A  Type ℓ') (Q : A  Type ℓ'')
+         (f :  x  P x  Q x)
+         where
+  private
+    total : (Σ A P)  (Σ A Q)
+    total = (\ p  p .fst , f (p .fst) (p .snd))
+
+  -- Thm 4.7.6
+  fibers-total :  {xv}  Iso (fiber total (xv)) (fiber (f (xv .fst)) (xv .snd))
+  fibers-total {xv} = iso h g h-g g-h
+   where
+    h :  {xv}  fiber total xv  fiber (f (xv .fst)) (xv .snd)
+    h {xv} (p , eq) = J (\ xv eq  fiber (f (xv .fst)) (xv .snd)) ((p .snd) , refl) eq
+    g :  {xv}  fiber (f (xv .fst)) (xv .snd)  fiber total xv
+    g {xv} (p , eq) = (xv .fst , p) , (\ i  _ , eq i)
+    h-g :  {xv} y  h {xv} (g {xv} y)  y
+    h-g {x , v} (p , eq) = J  _ eq₁  h (g (p , eq₁))  (p , eq₁)) (JRefl  xv₁ eq₁  fiber (f (xv₁ .fst)) (xv₁ .snd)) ((p , refl))) (eq)
+    g-h :  {xv} y  g {xv} (h {xv} y)  y
+    g-h {xv} ((a , p) , eq) = J  _ eq₁  g (h ((a , p) , eq₁))  ((a , p) , eq₁))
+                                (cong g (JRefl  xv₁ eq₁  fiber (f (xv₁ .fst)) (xv₁ .snd)) (p , refl)))
+                                eq
+  -- Thm 4.7.7 (fiberwise equivalences)
+  fiberEquiv : ([tf] : isEquiv total)
+                 x  isEquiv (f x)
+  fiberEquiv [tf] x .equiv-proof y = isContrRetract (fibers-total .Iso.inv) (fibers-total .Iso.fun) (fibers-total .Iso.rightInv)
+                                                    ([tf] .equiv-proof (x , y))
+
+  totalEquiv : (fx-equiv :  x  isEquiv (f x))
+                isEquiv total
+  totalEquiv fx-equiv .equiv-proof (x , v) = isContrRetract (fibers-total .Iso.fun) (fibers-total .Iso.inv) (fibers-total .Iso.leftInv)
+                                                            (fx-equiv x .equiv-proof v)
+
+
+module _ {U : Type } (_~_ : U  U  Type ℓ')
+         (idTo~ :  {A B}  A  B  A ~ B)
+         (c :  A  ∃![ X  U ] (A ~ X))
+       where
+
+  isContrToUniv :  {A B}  isEquiv (idTo~ {A} {B})
+  isContrToUniv {A} {B}
+    = fiberEquiv  z  A  z)  z  A ~ z) (\ B  idTo~ {A} {B})
+                  { .equiv-proof y
+                     isContrΣ (isContrSingl _)
+                                   \ a  isContr→isContrPath (c A) _ _
+                    })
+                 B
+
+
+{-
+  The following is called fundamental theorem of identity types in Egbert Rijke's
+  introduction to homotopy type theory.
+-}
+recognizeId : {A : Type } {a : A} (Eq : A  Type ℓ')
+   Eq a
+   isContr (Σ _ Eq)
+   (x : A)  (a  x)  (Eq x)
+recognizeId {A = A} {a = a} Eq eqRefl eqContr x = (fiberMap x) , (isEquivFiberMap x)
+  where
+    fiberMap : (x : A)  a  x  Eq x
+    fiberMap x = J  x p  Eq x) eqRefl
+
+    mapOnSigma : Σ[ x  A ] a  x  Σ _ Eq
+    mapOnSigma pair = fst pair , fiberMap (fst pair) (snd pair)
+
+    equivOnSigma : (x : A)  isEquiv mapOnSigma
+    equivOnSigma x = isEquivFromIsContr mapOnSigma (isContrSingl a) eqContr
+
+    isEquivFiberMap : (x : A)  isEquiv (fiberMap x)
+    isEquivFiberMap = fiberEquiv  x  a  x) Eq fiberMap (equivOnSigma x)
+
+fundamentalTheoremOfId : {A : Type } (Eq : A  A  Type ℓ')
+   ((x : A)  Eq x x)
+   ((x : A)  isContr (Σ[ y  A ] Eq x y))
+   (x y : A)  (x  y)  (Eq x y)
+fundamentalTheoremOfId Eq eqRefl eqContr x = recognizeId (Eq x) (eqRefl x) (eqContr x)
+
+fundamentalTheoremOfIdβ :
+  {A : Type } (Eq : A  A  Type ℓ')
+   (eqRefl : (x : A)  Eq x x)
+   (eqContr : (x : A)  isContr (Σ[ y  A ] Eq x y))
+   (x : A)
+   fst (fundamentalTheoremOfId Eq eqRefl eqContr x x) refl  eqRefl x
+fundamentalTheoremOfIdβ Eq eqRefl eqContr x = JRefl  y p  Eq x y) (eqRefl x)
+
\ No newline at end of file diff --git a/docs/Cubical.Foundations.Equiv.Properties.html b/docs/Cubical.Foundations.Equiv.Properties.html new file mode 100644 index 0000000..af3ef7d --- /dev/null +++ b/docs/Cubical.Foundations.Equiv.Properties.html @@ -0,0 +1,257 @@ + +Cubical.Foundations.Equiv.Properties
{-
+
+A couple of general facts about equivalences:
+
+- if f is an equivalence then (cong f) is an equivalence ([equivCong])
+- if f is an equivalence then pre- and postcomposition with f are equivalences ([preCompEquiv], [postCompEquiv])
+- if f is an equivalence then (Σ[ g ] section f g) and (Σ[ g ] retract f g) are contractible ([isContr-section], [isContr-retract])
+
+- isHAEquiv is a proposition [isPropIsHAEquiv]
+(these are not in 'Equiv.agda' because they need Univalence.agda (which imports Equiv.agda))
+-}
+{-# OPTIONS --safe #-}
+module Cubical.Foundations.Equiv.Properties where
+
+open import Cubical.Core.Everything
+
+open import Cubical.Data.Sigma
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Equiv.HalfAdjoint
+open import Cubical.Foundations.Univalence
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Path
+open import Cubical.Foundations.HLevels
+
+open import Cubical.Functions.FunExtEquiv
+
+private
+  variable
+     ℓ' ℓ'' : Level
+    A B C : Type 
+
+isEquivInvEquiv : isEquiv  (e : A  B)  invEquiv e)
+isEquivInvEquiv = isoToIsEquiv goal where
+  open Iso
+  goal : Iso (A  B) (B  A)
+  goal .fun = invEquiv
+  goal .inv = invEquiv
+  goal .rightInv g = equivEq refl
+  goal .leftInv f = equivEq refl
+
+invEquivEquiv : (A  B)  (B  A)
+invEquivEquiv = _ , isEquivInvEquiv
+
+isEquivCong : {x y : A} (e : A  B)  isEquiv  (p : x  y)  cong (equivFun e) p)
+isEquivCong e = isoToIsEquiv (congIso (equivToIso e))
+
+congEquiv : {x y : A} (e : A  B)  (x  y)  (equivFun e x  equivFun e y)
+congEquiv e = isoToEquiv (congIso (equivToIso e))
+
+equivAdjointEquiv : (e : A  B)   {a b}  (a  invEq e b)  (equivFun e a  b)
+equivAdjointEquiv e = compEquiv (congEquiv e) (compPathrEquiv (secEq e _))
+
+invEq≡→equivFun≡ : (e : A  B)   {a b}  invEq e b  a  equivFun e a  b
+invEq≡→equivFun≡ e = equivFun (equivAdjointEquiv e)  sym
+
+isEquivPreComp : (e : A  B)  isEquiv  (φ : B  C)  φ  equivFun e)
+isEquivPreComp e = snd (equiv→ (invEquiv e) (idEquiv _))
+
+preCompEquiv : (e : A  B)  (B  C)  (A  C)
+preCompEquiv e =  φ  φ  fst e) , isEquivPreComp e
+
+isEquivPostComp : (e : A  B)  isEquiv  (φ : C  A)  e .fst  φ)
+isEquivPostComp e = snd (equivΠCod  _  e))
+
+postCompEquiv : (e : A  B)  (C  A)  (C  B)
+postCompEquiv e = _ , isEquivPostComp e
+
+-- see also: equivΠCod for a dependent version of postCompEquiv
+
+hasSection : (A  B)  Type _
+hasSection {A = A} {B = B} f = Σ[ g  (B  A) ] section f g
+
+hasRetract : (A  B)  Type _
+hasRetract {A = A} {B = B} f = Σ[ g  (B  A) ] retract f g
+
+isEquiv→isContrHasSection : {f : A  B}  isEquiv f  isContr (hasSection f)
+fst (isEquiv→isContrHasSection isEq) = invIsEq isEq , secIsEq isEq
+snd (isEquiv→isContrHasSection isEq) (f , ε) i =  b  fst (p b i)) ,  b  snd (p b i))
+  where p :  b  (invIsEq isEq b , secIsEq isEq b)  (f b , ε b)
+        p b = isEq .equiv-proof b .snd (f b , ε b)
+
+isEquiv→hasSection : {f : A  B}  isEquiv f  hasSection f
+isEquiv→hasSection = fst  isEquiv→isContrHasSection
+
+isContr-hasSection : (e : A  B)  isContr (hasSection (fst e))
+isContr-hasSection e = isEquiv→isContrHasSection (snd e)
+
+isEquiv→isContrHasRetract : {f : A  B}  isEquiv f  isContr (hasRetract f)
+fst (isEquiv→isContrHasRetract isEq) = invIsEq isEq , retIsEq isEq
+snd (isEquiv→isContrHasRetract {f = f} isEq) (g , η) =
+    λ i   b  p b i) ,  a   q a i)
+  where p :  b  invIsEq isEq b  g b
+        p b = sym (η (invIsEq isEq b)) ∙' cong g (secIsEq isEq b)
+        -- one square from the definition of invIsEq
+        ieSq :  a  Square (cong g (secIsEq isEq (f a)))
+                            refl
+                            (cong (g  f) (retIsEq isEq a))
+                            refl
+        ieSq a k j = g (commSqIsEq isEq a k j)
+        -- one square from η
+        ηSq :  a  Square (η (invIsEq isEq (f a)))
+                           (η a)
+                           (cong (g  f) (retIsEq isEq a))
+                           (retIsEq isEq a)
+        ηSq a i j = η (retIsEq isEq a i) j
+        -- and one last square from the definition of p
+        pSq :  b  Square (η (invIsEq isEq b))
+                           refl
+                           (cong g (secIsEq isEq b))
+                           (p b)
+        pSq b i j = compPath'-filler (sym (η (invIsEq isEq b))) (cong g (secIsEq isEq b)) j i
+        q :  a  Square (retIsEq isEq a) (η a) (p (f a)) refl
+        q a i j = hcomp  k  λ { (i = i0)  ηSq a j k
+                                 ; (i = i1)  η a (j  k)
+                                 ; (j = i0)  pSq (f a) i k
+                                 ; (j = i1)  η a k
+                                 })
+                        (ieSq a j i)
+
+isEquiv→hasRetract : {f : A  B}  isEquiv f  hasRetract f
+isEquiv→hasRetract = fst  isEquiv→isContrHasRetract
+
+isContr-hasRetract : (e : A  B)  isContr (hasRetract (fst e))
+isContr-hasRetract e = isEquiv→isContrHasRetract (snd e)
+
+isEquiv→retractIsEquiv : {f : A  B} {g : B  A}  isEquiv f  retract f g  isEquiv g
+isEquiv→retractIsEquiv {f = f} {g = g} isEquiv-f retract-g = subst isEquiv f⁻¹≡g (snd f⁻¹)
+  where f⁻¹ = invEquiv (f , isEquiv-f)
+
+        retract-f⁻¹ : retract f (fst f⁻¹)
+        retract-f⁻¹ = snd (isEquiv→hasRetract isEquiv-f)
+
+        f⁻¹≡g : fst f⁻¹  g
+        f⁻¹≡g =
+          cong fst
+               (isContr→isProp (isEquiv→isContrHasRetract isEquiv-f)
+                               (fst f⁻¹ , retract-f⁻¹)
+                               (g , retract-g))
+
+
+isEquiv→sectionIsEquiv : {f : A  B} {g : B  A}  isEquiv f  section f g  isEquiv g
+isEquiv→sectionIsEquiv {f = f} {g = g} isEquiv-f section-g = subst isEquiv f⁻¹≡g (snd f⁻¹)
+  where f⁻¹ = invEquiv (f , isEquiv-f)
+
+        section-f⁻¹ : section f (fst f⁻¹)
+        section-f⁻¹ = snd (isEquiv→hasSection isEquiv-f)
+
+        f⁻¹≡g : fst f⁻¹  g
+        f⁻¹≡g =
+          cong fst
+               (isContr→isProp (isEquiv→isContrHasSection isEquiv-f)
+                               (fst f⁻¹ , section-f⁻¹)
+                               (g , section-g))
+
+cong≃ : (F : Type   Type ℓ')  (A  B)  F A  F B
+cong≃ F e = pathToEquiv (cong F (ua e))
+
+cong≃-char : (F : Type   Type ℓ') {A B : Type } (e : A  B)  ua (cong≃ F e)  cong F (ua e)
+cong≃-char F e = ua-pathToEquiv (cong F (ua e))
+
+cong≃-idEquiv : (F : Type   Type ℓ') (A : Type )  cong≃ F (idEquiv A)  idEquiv (F A)
+cong≃-idEquiv F A = cong≃ F (idEquiv A) ≡⟨ cong  p  pathToEquiv (cong F p)) uaIdEquiv  
+                    pathToEquiv refl    ≡⟨ pathToEquivRefl 
+                    idEquiv (F A)       
+
+isPropIsHAEquiv : {f : A  B}  isProp (isHAEquiv f)
+isPropIsHAEquiv {f = f} ishaef = goal ishaef where
+  equivF : isEquiv f
+  equivF = isHAEquiv→isEquiv ishaef
+
+  rCoh1 : (sec : hasSection f)  Type _
+  rCoh1 (g , ε) = Σ[ η  retract f g ]  x  cong f (η x)  ε (f x)
+
+  rCoh2 : (sec : hasSection f)  Type _
+  rCoh2 (g , ε) = Σ[ η  retract f g ]  x  Square (ε (f x)) refl (cong f (η x)) refl
+
+  rCoh3 : (sec : hasSection f)  Type _
+  rCoh3 (g , ε) =  x  Σ[ ηx  g (f x)  x ] Square (ε (f x)) refl (cong f ηx) refl
+
+  rCoh4 : (sec : hasSection f)  Type _
+  rCoh4 (g , ε) =  x  Path (fiber f (f x)) (g (f x) , ε (f x)) (x , refl)
+
+  characterization : isHAEquiv f  Σ _ rCoh4
+  characterization =
+    isHAEquiv f
+      -- first convert between Σ and record
+      ≃⟨ isoToEquiv (iso  e  (e .g , e .rinv) , (e .linv , e .com))
+                          e  record { g = e .fst .fst ; rinv = e .fst .snd
+                                       ; linv = e .snd .fst ; com = e .snd .snd })
+                          _  refl) λ _  refl) 
+    Σ _ rCoh1
+      -- secondly, convert the path into a dependent path for later convenience
+      ≃⟨  Σ-cong-equiv-snd  s  Σ-cong-equiv-snd
+                             λ η  equivΠCod
+                               λ x  compEquiv (flipSquareEquiv {a₀₀ = f x}) (invEquiv slideSquareEquiv)) 
+    Σ _ rCoh2
+      ≃⟨ Σ-cong-equiv-snd  s  invEquiv Σ-Π-≃) 
+    Σ _ rCoh3
+      ≃⟨ Σ-cong-equiv-snd  s  equivΠCod λ x  ΣPath≃PathΣ) 
+    Σ _ rCoh4
+      
+    where open isHAEquiv
+
+  goal : isProp (isHAEquiv f)
+  goal = subst isProp (sym (ua characterization))
+    (isPropΣ (isContr→isProp (isEquiv→isContrHasSection equivF))
+             λ s  isPropΠ λ x  isProp→isSet (isContr→isProp (equivF .equiv-proof (f x))) _ _)
+
+-- loop spaces connected by a path are equivalent
+conjugatePathEquiv : {A : Type } {a b : A} (p : a  b)  (a  a)  (b  b)
+conjugatePathEquiv p = compEquiv (compPathrEquiv p) (compPathlEquiv (sym p))
+
+-- composition on the right induces an equivalence of path types
+compr≡Equiv : {A : Type } {a b c : A} (p q : a  b) (r : b  c)  (p  q)  (p  r  q  r)
+compr≡Equiv p q r = congEquiv ((λ s  s  r) , compPathr-isEquiv r)
+
+-- composition on the left induces an equivalence of path types
+compl≡Equiv : {A : Type } {a b c : A} (p : a  b) (q r : b  c)  (q  r)  (p  q  p  r)
+compl≡Equiv p q r = congEquiv ((λ s  p  s) , (compPathl-isEquiv p))
+
+isEquivFromIsContr : {A : Type } {B : Type ℓ'}
+                    (f : A  B)  isContr A  isContr B
+                    isEquiv f
+isEquivFromIsContr f isContrA isContrB =
+  subst isEquiv  i x  isContr→isProp isContrB (fst B≃A x) (f x) i) (snd B≃A)
+  where B≃A = isContr→Equiv isContrA isContrB
+
+isEquiv[f∘equivFunA≃B]→isEquiv[f] : {A : Type } {B : Type ℓ'} {C : Type ℓ''}
+                  (f : B  C) (A≃B : A  B)
+                  isEquiv (f  equivFun A≃B)
+                  isEquiv f
+isEquiv[f∘equivFunA≃B]→isEquiv[f] f (g , gIsEquiv) f∘gIsEquiv  =
+  precomposesToId→Equiv f _ w w'
+    where
+      w : f  g  equivFun (invEquiv (_ , f∘gIsEquiv))  idfun _
+      w = (cong fst (invEquiv-is-linv (_ , f∘gIsEquiv)))
+
+      w' : isEquiv (g  equivFun (invEquiv (_ , f∘gIsEquiv)))
+      w' = (snd (compEquiv (invEquiv (_ , f∘gIsEquiv) ) (_ , gIsEquiv)))
+
+isEquiv[equivFunA≃B∘f]→isEquiv[f] : {A : Type } {B : Type ℓ'} {C : Type ℓ''}
+                  (f : C  A) (A≃B : A  B)
+                  isEquiv (equivFun A≃B  f)
+                  isEquiv f
+isEquiv[equivFunA≃B∘f]→isEquiv[f] f (g , gIsEquiv) g∘fIsEquiv  =
+  composesToId→Equiv _ f w w'
+    where
+      w : equivFun (invEquiv (_ , g∘fIsEquiv))  g  f  idfun _
+      w = (cong fst (invEquiv-is-rinv (_ , g∘fIsEquiv)))
+
+      w' : isEquiv (equivFun (invEquiv (_ , g∘fIsEquiv))  g)
+      w' = snd (compEquiv (_ , gIsEquiv) (invEquiv (_ , g∘fIsEquiv)))
+
\ No newline at end of file diff --git a/docs/Cubical.Foundations.Pointed.FunExt.html b/docs/Cubical.Foundations.Pointed.FunExt.html new file mode 100644 index 0000000..af0e758 --- /dev/null +++ b/docs/Cubical.Foundations.Pointed.FunExt.html @@ -0,0 +1,50 @@ + +Cubical.Foundations.Pointed.FunExt
{-# OPTIONS --safe #-}
+module Cubical.Foundations.Pointed.FunExt where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Equiv
+
+open import Cubical.Foundations.Pointed.Base
+open import Cubical.Foundations.Pointed.Properties
+open import Cubical.Foundations.Pointed.Homotopy
+
+private
+  variable
+     ℓ' : Level
+
+module _ {A : Pointed } {B : typ A  Type ℓ'} {ptB : B (pt A)} where
+
+  -- pointed function extensionality
+  funExt∙P : {f g : Π∙ A B ptB}  f ∙∼P g  f  g
+  funExt∙P (h , h∙) i .fst x = h x i
+  funExt∙P (h , h∙) i .snd = h∙ i
+
+  -- inverse of pointed function extensionality
+  funExt∙P⁻ : {f g : Π∙ A B ptB}  f  g  f ∙∼P g
+  funExt∙P⁻ p .fst a i = p i .fst a
+  funExt∙P⁻ p .snd i = p i .snd
+
+  -- function extensionality is an isomorphism, PathP version
+  funExt∙PIso : (f g : Π∙ A B ptB)  Iso (f ∙∼P g) (f  g)
+  Iso.fun (funExt∙PIso f g)  = funExt∙P {f = f} {g = g}
+  Iso.inv (funExt∙PIso f g) = funExt∙P⁻ {f = f} {g = g}
+  Iso.rightInv (funExt∙PIso f g) p i j = p j
+  Iso.leftInv (funExt∙PIso f g) h _ = h
+
+  -- transformed to equivalence
+  funExt∙P≃ : (f g : Π∙ A B ptB)  (f ∙∼P g)  (f  g)
+  funExt∙P≃ f g = isoToEquiv (funExt∙PIso f g)
+
+  -- funExt∙≃ using the other kind of pointed homotopy
+  funExt∙≃ : (f g : Π∙ A B ptB)  (f ∙∼ g)  (f  g)
+  funExt∙≃ f g = compEquiv (∙∼≃∙∼P f g) (funExt∙P≃ f g)
+
+  -- standard pointed function extensionality and its inverse
+  funExt∙ : {f g : Π∙ A B ptB}  f ∙∼ g  f  g
+  funExt∙ {f = f} {g = g} = equivFun (funExt∙≃ f g)
+
+  funExt∙⁻ : {f g : Π∙ A B ptB}  f  g  f ∙∼ g
+  funExt∙⁻ {f = f} {g = g} = equivFun (invEquiv (funExt∙≃ f g))
+
\ No newline at end of file diff --git a/docs/Cubical.Foundations.Pointed.Homogeneous.html b/docs/Cubical.Foundations.Pointed.Homogeneous.html new file mode 100644 index 0000000..867c636 --- /dev/null +++ b/docs/Cubical.Foundations.Pointed.Homogeneous.html @@ -0,0 +1,210 @@ + +Cubical.Foundations.Pointed.Homogeneous
{-
+
+Definition of a homogeneous pointed type, and proofs that pi, product, path, and discrete types are homogeneous
+
+Portions of this file adapted from Nicolai Kraus' code here:
+  https://bitbucket.org/nicolaikraus/agda/src/e30d70c72c6af8e62b72eefabcc57623dd921f04/trunc-inverse.lagda
+
+-}
+{-# OPTIONS --safe #-}
+module Cubical.Foundations.Pointed.Homogeneous where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Univalence
+open import Cubical.Foundations.Path
+open import Cubical.Data.Sigma
+open import Cubical.Data.Empty as 
+open import Cubical.Relation.Nullary
+
+open import Cubical.Foundations.GroupoidLaws
+open import Cubical.Foundations.Pointed.Base
+open import Cubical.Foundations.Pointed.Properties
+open import Cubical.Structures.Pointed
+
+{-
+  We might say that a type is homogeneous if its automorphism group acts transitively;
+  this could be phrased with a propositional truncation.
+  Here we demand something much stronger, namely that we are given automorphisms
+  that carry the base point to any given point y.
+  If in addition we require this automorphism to be the identity for the base point,
+  then we recover the notion of a left-invertible H-space, and indeed,
+  any homogeneous type in our sense gives rise to such, as shown in:
+
+    Cubical.Homotopy.HSpace
+-}
+isHomogeneous :  {}  Pointed   Type (ℓ-suc )
+isHomogeneous {} (A , x) =  y  Path (Pointed ) (A , x) (A , y)
+
+-- Pointed functions into a homogeneous type are equal as soon as they are equal
+-- as unpointed functions
+→∙Homogeneous≡ :  { ℓ'} {A∙ : Pointed } {B∙ : Pointed ℓ'} {f∙ g∙ : A∙ →∙ B∙}
+  (h : isHomogeneous B∙)  f∙ .fst  g∙ .fst  f∙  g∙
+→∙Homogeneous≡ {A∙ = A∙@(_ , a₀)} {B∙@(B , _)} {f∙@(_ , f₀)} {g∙@(_ , g₀)} h p =
+  subst  Q∙  PathP  i  A∙ →∙ Q∙ i) f∙ g∙) (sym (flipSquare fix)) badPath
+  where
+  badPath : PathP  i  A∙ →∙ (B , (sym f₀ ∙∙ funExt⁻ p a₀ ∙∙ g₀) i)) f∙ g∙
+  badPath i .fst = p i
+  badPath i .snd j = doubleCompPath-filler (sym f₀) (funExt⁻ p a₀) g₀ j i
+
+  fix : PathP  i  B∙  (B , (sym f₀ ∙∙ funExt⁻ p a₀ ∙∙ g₀) i)) refl refl
+  fix i =
+    hcomp
+       j  λ
+        { (i = i0)  lCancel (h (pt B∙)) j
+        ; (i = i1)  lCancel (h (pt B∙)) j
+        })
+      (sym (h (pt B∙))  h ((sym f₀ ∙∙ funExt⁻ p a₀ ∙∙ g₀) i))
+
+→∙Homogeneous≡Path :  { ℓ'} {A∙ : Pointed } {B∙ : Pointed ℓ'} {f∙ g∙ : A∙ →∙ B∙}
+  (h : isHomogeneous B∙)  (p q : f∙  g∙)  cong fst p  cong fst q  p  q
+→∙Homogeneous≡Path {A∙ = A∙@(A , a₀)} {B∙@(B , b)} {f∙@(f , f₀)} {g∙@(g , g₀)} h p q r =
+  transport  k
+       PathP  i
+         PathP  j  (A , a₀) →∙ newPath-refl p q r i j (~ k))
+                 (f , f₀) (g , g₀)) p q)
+      (badPath p q r)
+  where
+  newPath : (p q : f∙  g∙) (r : cong fst p  cong fst q)
+     Square (refl {x = b}) refl refl refl
+  newPath p q r i j =
+    hcomp  k  λ {(i = i0)  cong snd p j k
+                   ; (i = i1)  cong snd q j k
+                   ; (j = i0)  f₀ k
+                   ; (j = i1)  g₀ k})
+          (r i j a₀)
+
+  newPath-refl : (p q : f∙  g∙) (r : cong fst p  cong fst q)
+          PathP  i  (PathP  j  B∙  (B , newPath p q r i j))) refl refl) refl refl
+  newPath-refl p q r i j k =
+    hcomp  w  λ { (i = i0)  lCancel (h b) w k
+                    ; (i = i1)  lCancel (h b) w k
+                    ; (j = i0)  lCancel (h b) w k
+                    ; (j = i1)  lCancel (h b) w k
+                    ; (k = i0)  lCancel (h b) w k
+                    ; (k = i1)  B , newPath p q r i j})
+          ((sym (h b)  h (newPath p q r i j)) k)
+
+  badPath : (p q : f∙  g∙) (r : cong fst p  cong fst q)
+     PathP  i 
+        PathP  j  A∙ →∙ (B , newPath p q r i j))
+             (f , f₀) (g , g₀))
+              p q
+  fst (badPath p q r i j) = r i j
+  snd (badPath p q s i j) k =
+    hcomp  r  λ { (i = i0)  snd (p j) (r  k)
+                    ; (i = i1)  snd (q j) (r  k)
+                    ; (j = i0)  f₀ (k  r)
+                    ; (j = i1)  g₀ (k  r)
+                    ; (k = i0)  s i j a₀})
+          (s i j a₀)
+
+→∙HomogeneousSquare :  { ℓ'} {A∙ : Pointed } {B∙ : Pointed ℓ'} {f∙ g∙ h∙ l∙ : A∙ →∙ B∙}
+  (h : isHomogeneous B∙)  (s : f∙  h∙) (t : g∙  l∙) (p : f∙  g∙) (q : h∙  l∙)
+     Square (cong fst p) (cong fst q) (cong fst s) (cong fst t)
+     Square p q s t
+→∙HomogeneousSquare {f∙ = f∙} {g∙ = g∙} {h∙ = h∙} {l∙ = l∙} h =
+  J  h∙ s  (t : g∙  l∙) (p : f∙  g∙) (q : h∙  l∙) 
+      Square (cong fst p) (cong fst q) (cong fst s) (cong fst t) 
+      Square p q s t)
+   (J  l∙ t  (p : f∙  g∙) (q : f∙  l∙)
+       Square (cong fst p) (cong fst q) refl (cong fst t)
+       Square p q refl t)
+      (→∙Homogeneous≡Path {f∙ = f∙} {g∙ = g∙} h))
+
+isHomogeneousPi :  { ℓ'} {A : Type } {B∙ : A  Pointed ℓ'}
+                  (∀ a  isHomogeneous (B∙ a))  isHomogeneous (Πᵘ∙ A B∙)
+isHomogeneousPi h f i .fst =  a  typ (h a (f a) i)
+isHomogeneousPi h f i .snd a = pt (h a (f a) i)
+
+isHomogeneousΠ∙ :  { ℓ'} (A : Pointed ) (B : typ A  Type ℓ')
+                   (b₀ : B (pt A))
+                   ((a : typ A) (x : B a)  isHomogeneous (B a , x))
+                   (f : Π∙ A B b₀)
+                   isHomogeneous (Π∙ A B b₀ , f)
+fst (isHomogeneousΠ∙ A B b₀ h f g i) =
+  Σ[ r  ((a : typ A)  fst ((h a (fst f a) (fst g a)) i)) ]
+    r (pt A)  hcomp  k  λ {(i = i0)  snd f k
+                              ; (i = i1)  snd g k})
+                     (snd (h (pt A) (fst f (pt A)) (fst g (pt A)) i))
+snd (isHomogeneousΠ∙ A B b₀ h f g i) =
+     a  snd (h a (fst f a) (fst g a) i))
+  , λ j  hcomp  k  λ { (i = i0)  snd f (k  j)
+                          ; (i = i1)  snd g (k  j)
+                          ; (j = i0)  snd (h (pt A) (fst f (pt A))
+                                                      (fst g (pt A)) i)})
+                 (snd (h (pt A) (fst f (pt A)) (fst g (pt A)) i))
+
+isHomogeneous→∙ :  { ℓ'} {A∙ : Pointed } {B∙ : Pointed ℓ'}
+   isHomogeneous B∙  isHomogeneous (A∙ →∙ B∙ )
+isHomogeneous→∙ {A∙ = A∙} {B∙} h f∙ =
+  ΣPathP
+    (  i  Π∙ A∙  a  T a i) (t₀ i))
+    , PathPIsoPath _ _ _ .Iso.inv
+        (→∙Homogeneous≡ h
+          (PathPIsoPath  i  (a : typ A∙)  T a i)  _  pt B∙) _ .Iso.fun
+             i a  pt (h (f∙ .fst a) i))))
+    )
+  where
+  T :  a  typ B∙  typ B∙
+  T a i = typ (h (f∙ .fst a) i)
+
+  t₀ : PathP  i  T (pt A∙) i) (pt B∙) (pt B∙)
+  t₀ = cong pt (h (f∙ .fst (pt A∙)))  f∙ .snd
+
+isHomogeneousProd :  { ℓ'} {A∙ : Pointed } {B∙ : Pointed ℓ'}
+                    isHomogeneous A∙  isHomogeneous B∙  isHomogeneous (A∙ ×∙ B∙)
+isHomogeneousProd hA hB (a , b) i .fst = typ (hA a i) × typ (hB b i)
+isHomogeneousProd hA hB (a , b) i .snd .fst = pt (hA a i)
+isHomogeneousProd hA hB (a , b) i .snd .snd = pt (hB b i)
+
+isHomogeneousPath :  {} (A : Type ) {x y : A} (p : x  y)  isHomogeneous ((x  y) , p)
+isHomogeneousPath A {x} {y} p q
+  = pointed-sip ((x  y) , p) ((x  y) , q) (eqv , compPathr-cancel p q)
+  where eqv : (x  y)  (x  y)
+        eqv = compPathlEquiv (q  sym p)
+
+module HomogeneousDiscrete {} {A∙ : Pointed } (dA : Discrete (typ A∙)) (y : typ A∙) where
+
+  -- switches pt A∙ with y
+  switch : typ A∙  typ A∙
+  switch x with dA x (pt A∙)
+  ...         | yes _ = y
+  ...         | no _ with dA x y
+  ...                | yes _  = pt A∙
+  ...                | no  _  = x
+
+  switch-ptA∙ : switch (pt A∙)  y
+  switch-ptA∙ with dA (pt A∙) (pt A∙)
+  ...         | yes _ = refl
+  ...         | no ¬p = ⊥.rec (¬p refl)
+
+  switch-idp :  x  switch (switch x)  x
+  switch-idp x with dA x (pt A∙)
+  switch-idp x | yes p with dA y (pt A∙)
+  switch-idp x | yes p | yes q = q  sym p
+  switch-idp x | yes p | no  _ with dA y y
+  switch-idp x | yes p | no  _ | yes _ = sym p
+  switch-idp x | yes p | no  _ | no ¬p = ⊥.rec (¬p refl)
+  switch-idp x | no ¬p with dA x y
+  switch-idp x | no ¬p | yes p with dA y (pt A∙)
+  switch-idp x | no ¬p | yes p | yes q = ⊥.rec (¬p (p  q))
+  switch-idp x | no ¬p | yes p | no  _ with dA (pt A∙) (pt A∙)
+  switch-idp x | no ¬p | yes p | no  _ | yes _ = sym p
+  switch-idp x | no ¬p | yes p | no  _ | no ¬q = ⊥.rec (¬q refl)
+  switch-idp x | no ¬p | no ¬q with dA x (pt A∙)
+  switch-idp x | no ¬p | no ¬q | yes p = ⊥.rec (¬p p)
+  switch-idp x | no ¬p | no ¬q | no  _ with dA x y
+  switch-idp x | no ¬p | no ¬q | no  _ | yes q = ⊥.rec (¬q q)
+  switch-idp x | no ¬p | no ¬q | no  _ | no  _ = refl
+
+  switch-eqv : typ A∙  typ A∙
+  switch-eqv = isoToEquiv (iso switch switch switch-idp switch-idp)
+
+isHomogeneousDiscrete :  {} {A∙ : Pointed } (dA : Discrete (typ A∙))  isHomogeneous A∙
+isHomogeneousDiscrete {} {A∙} dA y
+  = pointed-sip (typ A∙ , pt A∙) (typ A∙ , y) (switch-eqv , switch-ptA∙)
+  where open HomogeneousDiscrete {} {A∙} dA y
+
\ No newline at end of file diff --git a/docs/Cubical.Foundations.Pointed.Homotopy.html b/docs/Cubical.Foundations.Pointed.Homotopy.html new file mode 100644 index 0000000..ee5bf81 --- /dev/null +++ b/docs/Cubical.Foundations.Pointed.Homotopy.html @@ -0,0 +1,121 @@ + +Cubical.Foundations.Pointed.Homotopy
{-# OPTIONS --safe #-}
+module Cubical.Foundations.Pointed.Homotopy where
+
+{-
+  This module defines two kinds of pointed homotopies,
+  ∙∼ and ∙∼P, and proves their equivalence
+-}
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.GroupoidLaws
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Equiv.Fiberwise
+open import Cubical.Foundations.Equiv.Properties
+open import Cubical.Foundations.Path
+open import Cubical.Foundations.Transport
+open import Cubical.Foundations.Univalence
+open import Cubical.Foundations.Pointed.Base
+open import Cubical.Foundations.Pointed.Properties
+open import Cubical.Homotopy.Base
+open import Cubical.Data.Sigma
+
+private
+  variable
+     ℓ' : Level
+
+module _ {A : Pointed } {B : typ A  Type ℓ'} {ptB : B (pt A)} where
+
+   = pt A
+
+  -- pointed homotopy as pointed Π. This is just a Σ-type, see ∙∼Σ
+  _∙∼_ : (f g : Π∙ A B ptB)  Type (ℓ-max  ℓ')
+  (f₁ , f₂) ∙∼ (g₁ , g₂) = Π∙ A  x  f₁ x  g₁ x) (f₂  g₂ ⁻¹)
+
+  -- pointed homotopy with PathP. Also a Σ-type, see ∙∼PΣ
+  _∙∼P_ : (f g : Π∙ A B ptB)  Type (ℓ-max  ℓ')
+  (f₁ , f₂) ∙∼P (g₁ , g₂) = Σ[ h  f₁  g₁ ] PathP  i  h  i  ptB) f₂ g₂
+
+  -- Proof that f ∙∼ g ≃ f ∙∼P g
+  -- using equivalence of the total map of φ
+  private
+    module _ (f g : Π∙ A B ptB) (H : f .fst  g .fst) where
+      -- convenient notation
+      f₁ = fst f
+      f₂ = snd f
+      g₁ = fst g
+      g₂ = snd g
+
+      -- P is the predicate on a homotopy H to be pointed of the ∙∼ kind
+      P : Type ℓ'
+      P = H   f₂  g₂ ⁻¹
+
+      -- Q is the predicate on a homotopy H to be pointed of the ∙∼P kind
+      Q : Type ℓ'
+      Q = PathP  i  H  i  ptB) f₂ g₂
+
+      -- simplify the notation even more to see that P≡Q
+      -- is just a jingle of paths
+      p = H 
+      r = f₂
+      s = g₂
+      P≡Q : P  Q
+      P≡Q = p  r  s ⁻¹
+              ≡⟨ isoToPath symIso 
+            r  s ⁻¹  p
+              ≡⟨ cong (r  s ⁻¹ ≡_) (rUnit p ∙∙ cong (p ∙_) (sym (rCancel s)) ∙∙ assoc p s (s ⁻¹)) 
+            r  s ⁻¹  (p  s)  s ⁻¹
+              ≡⟨ sym (ua (compr≡Equiv r (p  s) (s ⁻¹))) 
+            r  p  s
+              ≡⟨ ua (compl≡Equiv (p ⁻¹) r (p  s)) 
+            p ⁻¹  r  p ⁻¹  (p  s)
+              ≡⟨ cong (p ⁻¹  r ≡_ ) (assoc (p ⁻¹) p s ∙∙ (cong (_∙ s) (lCancel p)) ∙∙ sym (lUnit s)) 
+            p ⁻¹  r  s
+              ≡⟨ cong  z  p ⁻¹  z  s) (rUnit r) 
+            p ⁻¹  (r  refl)  s
+              ≡⟨ cong (_≡ s) (sym (doubleCompPath-elim' (p ⁻¹) r refl)) 
+            p ⁻¹ ∙∙ r ∙∙ refl  s
+              ≡⟨ sym (ua (Square≃doubleComp r s p refl)) 
+            PathP  i  p i  ptB) r s 
+
+      -- φ is a fiberwise transformation (H : f ∼ g) → P H → Q H
+      -- φ is even a fiberwise equivalence by P≡Q
+      φ : P  Q
+      φ = transport P≡Q
+
+    -- The total map corresponding to φ
+    totφ : (f g : Π∙ A B ptB)  f ∙∼ g  f ∙∼P g
+    totφ f g p .fst = p .fst
+    totφ f g p .snd = φ f g (p .fst) (p .snd)
+
+  -- transformation of the homotopies using totφ
+  ∙∼→∙∼P : (f g : Π∙ A B ptB)  (f ∙∼ g)  (f ∙∼P g)
+  ∙∼→∙∼P f g = totφ f g
+
+  -- Proof that ∙∼ and ∙∼P are equivalent using the fiberwise equivalence φ
+  ∙∼≃∙∼P : (f g : Π∙ A B ptB)  (f ∙∼ g)  (f ∙∼P g)
+  ∙∼≃∙∼P f g = Σ-cong-equiv-snd  H  pathToEquiv (P≡Q f g H))
+
+  -- inverse of ∙∼→∙∼P extracted from the equivalence
+  ∙∼P→∙∼ : {f g : Π∙ A B ptB}  f ∙∼P g  f ∙∼ g
+  ∙∼P→∙∼ {f = f} {g = g} = invEq (∙∼≃∙∼P f g)
+
+  -- ∙∼≃∙∼P transformed to a path
+  ∙∼≡∙∼P : (f g : Π∙ A B ptB)  (f ∙∼ g)  (f ∙∼P g)
+  ∙∼≡∙∼P f g = ua (∙∼≃∙∼P f g)
+
+  -- Verifies that the pointed homotopies actually correspond
+  -- to their Σ-type versions
+  _∙∼Σ_ : (f g : Π∙ A B ptB)  Type (ℓ-max  ℓ')
+  f ∙∼Σ g = Σ[ H  f .fst  g .fst ] (P f g H)
+
+  _∙∼PΣ_ : (f g : Π∙ A B ptB)  Type (ℓ-max  ℓ')
+  f ∙∼PΣ g = Σ[ H  f .fst  g .fst ] (Q f g H)
+
+  ∙∼≡∙∼Σ : (f g : Π∙ A B ptB)  f ∙∼ g  f ∙∼Σ g
+  ∙∼≡∙∼Σ f g = refl
+
+  ∙∼P≡∙∼PΣ : (f g : Π∙ A B ptB)  f ∙∼P g  f ∙∼PΣ g
+  ∙∼P≡∙∼PΣ f g = refl
+
\ No newline at end of file diff --git a/docs/Cubical.Foundations.Pointed.Properties.html b/docs/Cubical.Foundations.Pointed.Properties.html new file mode 100644 index 0000000..80367d6 --- /dev/null +++ b/docs/Cubical.Foundations.Pointed.Properties.html @@ -0,0 +1,194 @@ + +Cubical.Foundations.Pointed.Properties
{-# OPTIONS --safe #-}
+module Cubical.Foundations.Pointed.Properties where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Pointed.Base
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.GroupoidLaws
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Isomorphism
+
+open import Cubical.Data.Sigma
+
+private
+  variable
+     ℓ' ℓA ℓB ℓC ℓD : Level
+
+-- the default pointed Π-type: A is pointed, and B has a base point in the chosen fiber
+Π∙ : (A : Pointed ) (B : typ A  Type ℓ') (ptB : B (pt A))  Type (ℓ-max  ℓ')
+Π∙ A B ptB = Σ[ f  ((a : typ A)  B a) ] f (pt A)  ptB
+
+-- the unpointed Π-type becomes a pointed type if the fibers are all pointed
+Πᵘ∙ : (A : Type ) (B : A  Pointed ℓ')  Pointed (ℓ-max  ℓ')
+Πᵘ∙ A B .fst =  a  typ (B a)
+Πᵘ∙ A B .snd a = pt (B a)
+
+-- if the base and all fibers are pointed, we have the pointed pointed Π-type
+Πᵖ∙ : (A : Pointed ) (B : typ A  Pointed ℓ')  Pointed (ℓ-max  ℓ')
+Πᵖ∙ A B .fst = Π∙ A (typ  B) (pt (B (pt A)))
+Πᵖ∙ A B  .snd .fst a = pt (B a)
+Πᵖ∙ A B  .snd .snd = refl
+
+-- the default pointed Σ-type is just the Σ-type, but as a pointed type
+Σ∙ : (A : Pointed ) (B : typ A  Type ℓ') (ptB : B (pt A))  Pointed (ℓ-max  ℓ')
+Σ∙ A B ptB .fst = Σ[ a  typ A ] B a
+Σ∙ A B ptB .snd .fst = pt A
+Σ∙ A B ptB .snd .snd = ptB
+
+-- version if B is a family of pointed types
+Σᵖ∙ : (A : Pointed ) (B : typ A  Pointed ℓ')  Pointed (ℓ-max  ℓ')
+Σᵖ∙ A B = Σ∙ A (typ  B) (pt (B (pt A)))
+
+_×∙_ : (A∙ : Pointed ) (B∙ : Pointed ℓ')  Pointed (ℓ-max  ℓ')
+(A∙ ×∙ B∙) .fst = (typ A∙) × (typ B∙)
+(A∙ ×∙ B∙) .snd .fst = pt A∙
+(A∙ ×∙ B∙) .snd .snd = pt B∙
+
+-- composition of pointed maps
+_∘∙_ : {A : Pointed ℓA} {B : Pointed ℓB} {C : Pointed ℓC}
+       (g : B →∙ C) (f : A →∙ B)  (A →∙ C)
+((g , g∙) ∘∙ (f , f∙)) .fst x = g (f  x)
+((g , g∙) ∘∙ (f , f∙)) .snd = (cong g f∙)  g∙
+
+-- post composition
+post∘∙ :  {ℓX  ℓ'} (X : Pointed ℓX) {A : Pointed } {B : Pointed ℓ'}
+   (A →∙ B)  ((X →∙ A ) →∙ (X →∙ B ))
+post∘∙ X f .fst g = f ∘∙ g
+post∘∙ X f .snd =
+  ΣPathP
+    ( (funExt λ _  f .snd)
+    , (sym (lUnit (f .snd))  λ i j  f .snd (i  j)))
+
+-- pointed identity
+id∙ : (A : Pointed ℓA)  (A →∙ A)
+id∙ A .fst x = x
+id∙ A .snd = refl
+
+-- constant pointed map
+const∙ : (A : Pointed ℓA) (B : Pointed ℓB)  (A →∙ B)
+const∙ _ B .fst _ = B .snd
+const∙ _ B .snd = refl
+
+-- left identity law for pointed maps
+∘∙-idˡ : {A : Pointed ℓA} {B : Pointed ℓB} (f : A →∙ B)  f ∘∙ id∙ A  f
+∘∙-idˡ f = ΣPathP ( refl , (lUnit (f .snd)) ⁻¹ )
+
+-- right identity law for pointed maps
+∘∙-idʳ : {A : Pointed ℓA} {B : Pointed ℓB} (f : A →∙ B)  id∙ B ∘∙ f  f
+∘∙-idʳ f = ΣPathP ( refl , (rUnit (f .snd)) ⁻¹ )
+
+-- associativity for composition of pointed maps
+∘∙-assoc : {A : Pointed ℓA} {B : Pointed ℓB} {C : Pointed ℓC} {D : Pointed ℓD}
+           (h : C →∙ D) (g : B →∙ C) (f : A →∙ B)
+            (h ∘∙ g) ∘∙ f  h ∘∙ (g ∘∙ f)
+∘∙-assoc (h , h∙) (g , g∙) (f , f∙) = ΣPathP (refl , q)
+  where
+    q : (cong (h  g) f∙)  (cong h g∙  h∙)  cong h (cong g f∙  g∙)  h∙
+    q = ( (cong (h  g) f∙)  (cong h g∙  h∙)
+        ≡⟨ refl 
+        (cong h (cong g f∙))  (cong h g∙  h∙)
+        ≡⟨ assoc (cong h (cong g f∙)) (cong h g∙) h∙ 
+        (cong h (cong g f∙)  cong h g∙)  h∙
+        ≡⟨ cong  p  p  h∙) ((cong-∙ h (cong g f∙) g∙) ⁻¹) 
+        (cong h (cong g f∙  g∙)  h∙)  )
+
+module _ { ℓ' : Level} {A : Pointed } {B : Pointed ℓ'} (f : A →∙ B) where
+  isInIm∙ : (x : typ B)  Type (ℓ-max  ℓ')
+  isInIm∙ x = Σ[ z  typ A ] fst f z  x
+
+  isInKer∙ : (x : fst A)  Type ℓ'
+  isInKer∙ x = fst f x  snd B
+
+pre∘∙equiv :  { ℓ'} {A : Pointed } {B C : Pointed ℓ'}
+  (B ≃∙ C)  Iso (A →∙ B) (A →∙ C)
+pre∘∙equiv {A = A} {B = B} {C = C} eq = main
+  where
+  module _ { ℓ' : Level} (A : Pointed ) (B C : Pointed ℓ')
+           (eq : (B ≃∙ C)) where
+    to : (A →∙ B)  (A →∙ C)
+    to = ≃∙map eq ∘∙_
+
+    from : (A →∙ C)  (A →∙ B)
+    from = ≃∙map (invEquiv∙ eq) ∘∙_
+
+  lem : {  : Level} {B : Pointed }
+     ≃∙map (invEquiv∙ {A = B} ((idEquiv (fst B)) , refl))  id∙ B
+  lem = ΣPathP (refl , (sym (lUnit _)))
+
+  J-lem : { ℓ' : Level} {A : Pointed } {B C : Pointed ℓ'}
+              (eq : (B ≃∙ C))
+              retract (to A B C eq) (from _ _ _ eq)
+              × section (to A B C eq) (from _ _ _ eq)
+  J-lem {A = A} {B = B} {C = C} =
+    Equiv∙J  B eq  retract (to A B C eq) (from _ _ _ eq)
+              × section (to A B C eq) (from _ _ _ eq))
+            ((λ f  ((λ i  (lem i ∘∙ (id∙ C ∘∙ f)))
+                   λ i  ∘∙-idʳ (∘∙-idʳ f i) i))
+            , λ f  ((λ i  (id∙ C ∘∙ (lem i ∘∙ f)))
+                   λ i  ∘∙-idʳ (∘∙-idʳ f i) i))
+
+  main : Iso (A →∙ B) (A →∙ C)
+  Iso.fun main = to A B C eq
+  Iso.inv main = from A B C eq
+  Iso.rightInv main = J-lem eq .snd
+  Iso.leftInv main = J-lem eq .fst
+
+post∘∙equiv :  { ℓC} {A B : Pointed } {C : Pointed ℓC}
+   (A ≃∙ B)  Iso (A →∙ C) (B →∙ C)
+post∘∙equiv {A = A} {B = B} {C = C} eq = main
+  where
+  module _ { ℓC : Level} (A B : Pointed ) (C : Pointed ℓC)
+           (eq : (A ≃∙ B)) where
+    to : (A →∙ C)  (B →∙ C)
+    to = _∘∙ ≃∙map (invEquiv∙ eq)
+
+    from : (B →∙ C)  (A →∙ C)
+    from = _∘∙ ≃∙map eq
+
+  lem : {  : Level} {B : Pointed }
+     ≃∙map (invEquiv∙ {A = B} ((idEquiv (fst B)) , refl))  id∙ B
+  lem = ΣPathP (refl , (sym (lUnit _)))
+
+  J-lem : { ℓC : Level} {A B : Pointed } {C : Pointed ℓC}
+              (eq : (A ≃∙ B))
+              retract (to A B C eq) (from _ _ _ eq)
+              × section (to A B C eq) (from _ _ _ eq)
+  J-lem {B = B} {C = C} =
+    Equiv∙J  A eq  retract (to A B C eq) (from _ _ _ eq)
+              × section (to A B C eq) (from _ _ _ eq))
+            ((λ f  ((λ i  (f ∘∙ lem i) ∘∙ id∙ B)
+                   λ i  ∘∙-idˡ (∘∙-idˡ f i) i))
+           , λ f   i  (f ∘∙ id∙ B) ∘∙ lem i)
+                   λ i  ∘∙-idˡ (∘∙-idˡ f i) i)
+
+  main : Iso (A →∙ C) (B →∙ C)
+  Iso.fun main = to A B C eq
+  Iso.inv main = from A B C eq
+  Iso.rightInv main = J-lem eq .snd
+  Iso.leftInv main = J-lem eq .fst
+
+flip→∙∙ : {A : Pointed } {B : Pointed ℓ'} {C : Pointed ℓA}
+   (A →∙ (B →∙ C ))  B →∙ (A →∙ C )
+fst (fst (flip→∙∙ f) x) a = fst f a .fst x
+snd (fst (flip→∙∙ f) x) i = snd f i .fst x
+fst (snd (flip→∙∙ f) i) a = fst f a .snd i
+snd (snd (flip→∙∙ f) i) j = snd f j .snd i
+
+flip→∙∙Iso : {A : Pointed } {B : Pointed ℓ'} {C : Pointed ℓA}
+   Iso (A →∙ (B →∙ C )) (B →∙ (A →∙ C ))
+Iso.fun flip→∙∙Iso = flip→∙∙
+Iso.inv flip→∙∙Iso = flip→∙∙
+Iso.rightInv flip→∙∙Iso _ = refl
+Iso.leftInv flip→∙∙Iso _ = refl
+
+≃∙→ret/sec∙ :  {} {A B : Pointed }
+  (f : A ≃∙ B)  ((≃∙map (invEquiv∙ f) ∘∙ ≃∙map f)  idfun∙ A)
+                × (≃∙map f ∘∙ ≃∙map (invEquiv∙ f)  idfun∙ B)
+≃∙→ret/sec∙ {A = A} {B = B} =
+  Equiv∙J  A f  ((≃∙map (invEquiv∙ f) ∘∙ ≃∙map f)  idfun∙ A)
+                × (≃∙map f ∘∙ ≃∙map (invEquiv∙ f)  idfun∙ B))
+          ((ΣPathP (refl , sym (lUnit _)  sym (rUnit refl)))
+         , (ΣPathP (refl , sym (rUnit _)  sym (rUnit refl))))
+
\ No newline at end of file diff --git a/docs/Cubical.Foundations.Pointed.html b/docs/Cubical.Foundations.Pointed.html new file mode 100644 index 0000000..9f5f194 --- /dev/null +++ b/docs/Cubical.Foundations.Pointed.html @@ -0,0 +1,11 @@ + +Cubical.Foundations.Pointed
{-# OPTIONS --safe #-}
+module Cubical.Foundations.Pointed where
+
+open import Cubical.Foundations.Pointed.Base public
+open import Cubical.Foundations.Pointed.Properties public
+open import Cubical.Foundations.Pointed.FunExt public
+open import Cubical.Foundations.Pointed.Homotopy public
+
+open import Cubical.Foundations.Pointed.Homogeneous
+
\ No newline at end of file diff --git a/docs/Cubical.Foundations.Powerset.html b/docs/Cubical.Foundations.Powerset.html new file mode 100644 index 0000000..94e5c0c --- /dev/null +++ b/docs/Cubical.Foundations.Powerset.html @@ -0,0 +1,67 @@ + +Cubical.Foundations.Powerset
{-
+
+This file introduces the "powerset" of a type in the style of
+Escardó's lecture notes:
+
+https://www.cs.bham.ac.uk/~mhe/HoTT-UF-in-Agda-Lecture-Notes/HoTT-UF-Agda.html#propositionalextensionality
+
+-}
+{-# OPTIONS --safe #-}
+module Cubical.Foundations.Powerset where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.HLevels
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Structure
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.Univalence using (hPropExt)
+
+open import Cubical.Data.Sigma
+
+private
+  variable
+     : Level
+    X : Type 
+
+ : Type   Type (ℓ-suc )
+ X = X  hProp _
+
+isSetℙ : isSet ( X)
+isSetℙ = isSetΠ λ x  isSetHProp
+
+infix 5 _∈_
+
+_∈_ : {X : Type }  X   X  Type 
+x  A =  A x 
+
+_⊆_ : {X : Type }   X   X  Type 
+A  B =  x  x  A  x  B
+
+∈-isProp : (A :  X) (x : X)  isProp (x  A)
+∈-isProp A = snd  A
+
+⊆-isProp : (A B :  X)  isProp (A  B)
+⊆-isProp A B = isPropΠ2  x _  ∈-isProp B x)
+
+⊆-refl : (A :  X)  A  A
+⊆-refl A x = idfun (x  A)
+
+subst-∈ : (A :  X) {x y : X}  x  y  x  A  y  A
+subst-∈ A = subst (_∈ A)
+
+⊆-refl-consequence : (A B :  X)  A  B  (A  B) × (B  A)
+⊆-refl-consequence A B p = subst (A ⊆_) p (⊆-refl A)
+                         , subst (B ⊆_) (sym p) (⊆-refl B)
+
+⊆-extensionality : (A B :  X)  (A  B) × (B  A)  A  B
+⊆-extensionality A B (φ , ψ) =
+  funExt  x  TypeOfHLevel≡ 1 (hPropExt (A x .snd) (B x .snd) (φ x) (ψ x)))
+
+⊆-extensionalityEquiv : (A B :  X)  (A  B) × (B  A)  (A  B)
+⊆-extensionalityEquiv A B = isoToEquiv (iso (⊆-extensionality A B)
+                                            (⊆-refl-consequence A B)
+                                             _  isSetℙ A B _ _)
+                                             _  isPropΣ (⊆-isProp A B)  _  ⊆-isProp B A) _ _))
+
\ No newline at end of file diff --git a/docs/Cubical.Foundations.SIP.html b/docs/Cubical.Foundations.SIP.html new file mode 100644 index 0000000..c3b5bb8 --- /dev/null +++ b/docs/Cubical.Foundations.SIP.html @@ -0,0 +1,126 @@ + +Cubical.Foundations.SIP
{-
+
+In this file we apply the cubical machinery to Martin Hötzel-Escardó's
+structure identity principle:
+
+https://www.cs.bham.ac.uk/~mhe/HoTT-UF-in-Agda-Lecture-Notes/HoTT-UF-Agda.html#sns
+
+-}
+{-# OPTIONS --safe #-}
+module Cubical.Foundations.SIP where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Univalence renaming (ua-pathToEquiv to ua-pathToEquiv')
+open import Cubical.Foundations.Transport
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.Path
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Equiv
+open import Cubical.Data.Sigma
+
+open import Cubical.Foundations.Structure public
+
+private
+  variable
+     ℓ₁ ℓ₂ ℓ₃ ℓ₄ ℓ₅ : Level
+    S : Type ℓ₁  Type ℓ₂
+
+-- Note that for any equivalence (f , e) : X ≃ Y the type  ι (X , s) (Y , t) (f , e) need not to be
+-- a proposition. Indeed this type should correspond to the ways s and t can be identified
+-- as S-structures. This we call a standard notion of structure or SNS.
+-- We will use a different definition, but the two definitions are interchangeable.
+SNS : (S : Type ℓ₁  Type ℓ₂) (ι : StrEquiv S ℓ₃)  Type (ℓ-max (ℓ-max (ℓ-suc ℓ₁) ℓ₂) ℓ₃)
+SNS {ℓ₁} S ι =  {X : Type ℓ₁} (s t : S X)  ι (X , s) (X , t) (idEquiv X)  (s  t)
+
+-- We introduce the notation for structure preserving equivalences a
+-- bit differently, but this definition doesn't actually change from
+-- Escardó's notes.
+_≃[_]_ : (A : TypeWithStr ℓ₁ S) (ι : StrEquiv S ℓ₂) (B : TypeWithStr ℓ₁ S)  Type (ℓ-max ℓ₁ ℓ₂)
+A ≃[ ι ] B = Σ[ e  typ A  typ B ] (ι A B e)
+
+
+
+-- The following PathP version of SNS is a bit easier to work with
+-- for the proof of the SIP
+UnivalentStr : (S : Type ℓ₁  Type ℓ₂) (ι : StrEquiv S ℓ₃)  Type (ℓ-max (ℓ-max (ℓ-suc ℓ₁) ℓ₂) ℓ₃)
+UnivalentStr {ℓ₁} S ι =
+  {A B : TypeWithStr ℓ₁ S} (e : typ A  typ B)
+   ι A B e  PathP  i  S (ua e i)) (str A) (str B)
+
+-- A quick sanity-check that our definition is interchangeable with
+-- Escardó's. The direction SNS→UnivalentStr corresponds more or less
+-- to a dependent EquivJ formulation of Escardó's homomorphism-lemma.
+UnivalentStr→SNS : (S : Type ℓ₁  Type ℓ₂) (ι : StrEquiv S ℓ₃)
+   UnivalentStr S ι  SNS S ι
+UnivalentStr→SNS S ι θ {X = X} s t =
+  ι (X , s) (X , t) (idEquiv X)
+    ≃⟨ θ (idEquiv X) 
+  PathP  i  S (ua (idEquiv X) i)) s t
+    ≃⟨ pathToEquiv  j  PathP  i  S (uaIdEquiv {A = X} j i)) s t) 
+  s  t
+  
+
+
+SNS→UnivalentStr : (ι : StrEquiv S ℓ₃)  SNS S ι  UnivalentStr S ι
+SNS→UnivalentStr {S = S} ι θ {A = A} {B = B} e = EquivJ P C e (str A) (str B)
+  where
+  Y = typ B
+
+  P : (X : Type _)  X  Y  Type _
+  P X e' = (s : S X) (t : S Y)  ι (X , s) (Y , t) e'  PathP  i  S (ua e' i)) s t
+
+  C : (s t : S Y)  ι (Y , s) (Y , t) (idEquiv Y)  PathP  i  S (ua (idEquiv Y) i)) s t
+  C s t =
+    ι (Y , s) (Y , t) (idEquiv Y)
+      ≃⟨ θ s t 
+    s  t
+      ≃⟨ pathToEquiv  j  PathP  i  S (uaIdEquiv {A = Y} (~ j) i)) s t) 
+    PathP  i  S (ua (idEquiv Y) i)) s t
+    
+
+TransportStr : {S : Type   Type ℓ₁} (α : EquivAction S)  Type (ℓ-max (ℓ-suc ) ℓ₁)
+TransportStr {} {S = S} α =
+  {X Y : Type } (e : X  Y) (s : S X)  equivFun (α e) s  subst S (ua e) s
+
+TransportStr→UnivalentStr : {S : Type   Type ℓ₁} (α : EquivAction S)
+   TransportStr α  UnivalentStr S (EquivAction→StrEquiv α)
+TransportStr→UnivalentStr {S = S} α τ {X , s} {Y , t} e =
+  equivFun (α e) s  t
+    ≃⟨ pathToEquiv (cong (_≡ t) (τ e s)) 
+  subst S (ua e) s  t
+    ≃⟨ invEquiv (PathP≃Path _ _ _) 
+  PathP  i  S (ua e i)) s t
+  
+
+UnivalentStr→TransportStr : {S : Type   Type ℓ₁} (α : EquivAction S)
+   UnivalentStr S (EquivAction→StrEquiv α)  TransportStr α
+UnivalentStr→TransportStr {S = S} α θ e s =
+  invEq (θ e) (transport-filler (cong S (ua e)) s)
+
+invTransportStr : {S : Type   Type ℓ₂} (α : EquivAction S) (τ : TransportStr α)
+  {X Y : Type } (e : X  Y) (t : S Y)  invEq (α e) t  subst⁻ S (ua e) t
+invTransportStr {S = S} α τ e t =
+  sym (transport⁻Transport (cong S (ua e)) (invEq (α e) t))
+  ∙∙ sym (cong (subst⁻ S (ua e)) (τ e (invEq (α e) t)))
+  ∙∙ cong (subst⁻ S (ua e)) (secEq (α e) t)
+
+
+--- We can now define an invertible function
+---
+---    sip : A ≃[ ι ] B → A ≡ B
+
+module _ {S : Type ℓ₁  Type ℓ₂} {ι : StrEquiv S ℓ₃}
+  (θ : UnivalentStr S ι) (A B : TypeWithStr ℓ₁ S)
+  where
+
+  sip : A ≃[ ι ] B  A  B
+  sip (e , p) i = ua e i , θ e .fst p i
+
+  SIP : A ≃[ ι ] B  (A  B)
+  SIP =
+    sip , isoToIsEquiv (compIso (Σ-cong-iso (invIso univalenceIso) (equivToIso  θ)) ΣPathIsoPathΣ)
+
+  sip⁻ : A  B  A ≃[ ι ] B
+  sip⁻ = invEq SIP
+
\ No newline at end of file diff --git a/docs/Cubical.Functions.Embedding.html b/docs/Cubical.Functions.Embedding.html new file mode 100644 index 0000000..a30b362 --- /dev/null +++ b/docs/Cubical.Functions.Embedding.html @@ -0,0 +1,442 @@ + +Cubical.Functions.Embedding
{-# OPTIONS --safe #-}
+module Cubical.Functions.Embedding where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Equiv.Properties
+open import Cubical.Foundations.Equiv.HalfAdjoint
+open import Cubical.Foundations.HLevels
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Path
+open import Cubical.Foundations.Powerset
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Transport
+open import Cubical.Foundations.Univalence using (ua; univalence; pathToEquiv)
+open import Cubical.Functions.Fibration
+
+open import Cubical.Data.Sigma
+open import Cubical.Functions.Fibration
+open import Cubical.Functions.FunExtEquiv
+open import Cubical.Relation.Nullary using (Discrete; yes; no)
+open import Cubical.Structures.Axioms
+
+open import Cubical.Reflection.StrictEquiv
+
+open import Cubical.Data.Nat using (; zero; suc)
+open import Cubical.Data.Sigma
+
+private
+  variable
+     ℓ' ℓ'' : Level
+    A B C : Type 
+    f h : A  B
+    w x : A
+    y z : B
+
+-- Embeddings are generalizations of injections. The usual
+-- definition of injection as:
+--
+--    f x ≡ f y → x ≡ y
+--
+-- is not well-behaved with higher h-levels, while embeddings
+-- are.
+isEmbedding : (A  B)  Type _
+isEmbedding f =  w x  isEquiv {A = w  x} (cong f)
+
+isPropIsEmbedding : isProp (isEmbedding f)
+isPropIsEmbedding {f = f} = isPropΠ2 λ _ _  isPropIsEquiv (cong f)
+
+-- Embedding is injection in the aforementioned sense:
+isEmbedding→Inj
+  : {f : A  B}
+   isEmbedding f
+    w x  f w  f x  w  x
+isEmbedding→Inj {f = f} embb w x p
+  = equiv-proof (embb w x) p .fst .fst
+
+-- The converse implication holds if B is an h-set, see injEmbedding below.
+
+
+-- If `f` is an embedding, we'd expect the fibers of `f` to be
+-- propositions, like an injective function.
+hasPropFibers : (A  B)  Type _
+hasPropFibers f =  y  isProp (fiber f y)
+
+-- This can be relaxed to having all prop fibers over the image, see [hasPropFibersOfImage→isEmbedding]
+hasPropFibersOfImage : (A  B)  Type _
+hasPropFibersOfImage f =  x  isProp (fiber f (f x))
+
+-- some notation
+_↪_ : Type ℓ'  Type ℓ''  Type (ℓ-max ℓ' ℓ'')
+A  B = Σ[ f  (A  B) ] isEmbedding f
+
+hasPropFibersIsProp : isProp (hasPropFibers f)
+hasPropFibersIsProp = isPropΠ  _  isPropIsProp)
+
+private
+  lemma₀ : (p : y  z)  fiber f y  fiber f z
+  lemma₀ {f = f} p = λ i  fiber f (p i)
+
+  lemma₁ : isEmbedding f   x  isContr (fiber f (f x))
+  lemma₁ {f = f} iE x = value , path
+    where
+    value : fiber f (f x)
+    value = (x , refl)
+
+    path : ∀(fi : fiber f (f x))  value  fi
+    path (w , p) i
+      = case equiv-proof (iE w x) p of λ
+      { ((q , sq) , _)
+       hfill  j  λ { (i = i0)  (x , refl)
+                      ; (i = i1)  (w , sq j)
+                      })
+          (inS (q (~ i) , λ j  f (q (~ i  j))))
+          i1
+      }
+
+isEmbedding→hasPropFibers : isEmbedding f  hasPropFibers f
+isEmbedding→hasPropFibers iE y (x , p)
+  = subst  f  isProp f) (lemma₀ p) (isContr→isProp (lemma₁ iE x)) (x , p)
+
+private
+  fibCong→PathP
+    : {f : A  B}
+     (p : f w  f x)
+     (fi : fiber (cong f) p)
+     PathP  i  fiber f (p i)) (w , refl) (x , refl)
+  fibCong→PathP p (q , r) i = q i , λ j  r j i
+
+  PathP→fibCong
+    : {f : A  B}
+     (p : f w  f x)
+     (pp : PathP  i  fiber f (p i)) (w , refl) (x , refl))
+     fiber (cong f) p
+  PathP→fibCong p pp =  i  fst (pp i)) ,  j i  snd (pp i) j)
+
+PathP≡fibCong
+  : {f : A  B}
+   (p : f w  f x)
+   PathP  i  fiber f (p i)) (w , refl) (x , refl)  fiber (cong f) p
+PathP≡fibCong p
+  = isoToPath (iso (PathP→fibCong p) (fibCong→PathP p)  _  refl)  _  refl))
+
+hasPropFibers→isEmbedding : hasPropFibers f  isEmbedding f
+hasPropFibers→isEmbedding {f = f} iP w x .equiv-proof p
+  = subst isContr (PathP≡fibCong p) (isProp→isContrPathP  i  iP (p i)) fw fx)
+  where
+  fw : fiber f (f w)
+  fw = (w , refl)
+
+  fx : fiber f (f x)
+  fx = (x , refl)
+
+hasPropFibersOfImage→hasPropFibers : hasPropFibersOfImage f  hasPropFibers f
+hasPropFibersOfImage→hasPropFibers {f = f} fibImg y a b =
+  subst  y  isProp (fiber f y)) (snd a) (fibImg (fst a)) a b
+
+hasPropFibersOfImage→isEmbedding : hasPropFibersOfImage f  isEmbedding f
+hasPropFibersOfImage→isEmbedding = hasPropFibers→isEmbedding  hasPropFibersOfImage→hasPropFibers
+
+isEmbedding≡hasPropFibers : isEmbedding f  hasPropFibers f
+isEmbedding≡hasPropFibers
+  = isoToPath
+      (iso isEmbedding→hasPropFibers
+           hasPropFibers→isEmbedding
+            _  hasPropFibersIsProp _ _)
+            _  isPropIsEmbedding _ _))
+
+-- We use the characterization as hasPropFibers to show that naive injectivity
+-- implies isEmbedding as long as B is an h-set.
+module _
+  {f : A  B}
+  (isSetB : isSet B)
+  where
+
+  module _
+    (inj : ∀{w x}  f w  f x  w  x)
+    where
+
+    injective→hasPropFibers : hasPropFibers f
+    injective→hasPropFibers y (x , fx≡y) (x' , fx'≡y) =
+      Σ≡Prop
+         _  isSetB _ _)
+        (inj (fx≡y  sym (fx'≡y)))
+
+    injEmbedding : isEmbedding f
+    injEmbedding = hasPropFibers→isEmbedding injective→hasPropFibers
+
+  retractableIntoSet→isEmbedding : hasRetract f  isEmbedding f
+  retractableIntoSet→isEmbedding (g , ret) = injEmbedding inj
+    where
+    inj : f w  f x  w  x
+    inj {w = w} {x = x} p = sym (ret w) ∙∙ cong g p ∙∙ ret x
+
+isEquiv→hasPropFibers : isEquiv f  hasPropFibers f
+isEquiv→hasPropFibers e b = isContr→isProp (equiv-proof e b)
+
+isEquiv→isEmbedding : isEquiv f  isEmbedding f
+isEquiv→isEmbedding e = λ _ _  congEquiv (_ , e) .snd
+
+Equiv→Embedding : A  B  A  B
+Equiv→Embedding (f , isEquivF) = (f , isEquiv→isEmbedding isEquivF)
+
+iso→isEmbedding :  {} {A B : Type }
+   (isom : Iso A B)
+  -------------------------------
+   isEmbedding (Iso.fun isom)
+iso→isEmbedding {A = A} {B} isom = (isEquiv→isEmbedding (equivIsEquiv (isoToEquiv isom)))
+
+isEmbedding→Injection :
+   {} {A B C : Type }
+   (a : A  B)
+   (e : isEmbedding a)
+  ----------------------
+    {f g : C  A} 
+   x  (a (f x)  a (g x))  (f x  g x)
+isEmbedding→Injection a e {f = f} {g} x = sym (ua (cong a , e (f x) (g x)))
+
+Embedding-into-Discrete→Discrete : A  B  Discrete B  Discrete A
+Embedding-into-Discrete→Discrete (f , isEmbeddingF) _≟_ x y with f x  f y
+... | yes p = yes (invIsEq (isEmbeddingF x y) p)
+... | no ¬p = no (¬p  cong f)
+
+Embedding-into-isProp→isProp : A  B  isProp B  isProp A
+Embedding-into-isProp→isProp (f , isEmbeddingF) isProp-B x y
+  = invIsEq (isEmbeddingF x y) (isProp-B (f x) (f y))
+
+Embedding-into-isSet→isSet : A  B  isSet B  isSet A
+Embedding-into-isSet→isSet (f , isEmbeddingF) isSet-B x y p q =
+  p ≡⟨ sym (retIsEq isEquiv-cong-f p) 
+  cong-f⁻¹ (cong f p) ≡⟨ cong cong-f⁻¹ cong-f-p≡cong-f-q 
+  cong-f⁻¹ (cong f q) ≡⟨ retIsEq isEquiv-cong-f q 
+  q 
+  where
+    cong-f-p≡cong-f-q = isSet-B (f x) (f y) (cong f p) (cong f q)
+    isEquiv-cong-f = isEmbeddingF x y
+    cong-f⁻¹ = invIsEq isEquiv-cong-f
+
+Embedding-into-hLevel→hLevel
+  :  n  A  B  isOfHLevel (suc n) B  isOfHLevel (suc n) A
+Embedding-into-hLevel→hLevel zero = Embedding-into-isProp→isProp
+Embedding-into-hLevel→hLevel (suc n) (f , isEmbeddingF) Blvl x y
+  = isOfHLevelRespectEquiv (suc n) (invEquiv equiv) subLvl
+  where
+  equiv : (x  y)  (f x  f y)
+  equiv .fst = cong f
+  equiv .snd = isEmbeddingF x y
+  subLvl : isOfHLevel (suc n) (f x  f y)
+  subLvl = Blvl (f x) (f y)
+
+-- We now show that the powerset is the subtype classifier
+-- i.e. ℙ X ≃ Σ[A ∈ Type ℓ] (A ↪ X)
+Embedding→Subset : {X : Type }  Σ[ A  Type  ] (A  X)   X
+Embedding→Subset (_ , f , isEmbeddingF) x = fiber f x , isEmbedding→hasPropFibers isEmbeddingF x
+
+Subset→Embedding : {X : Type }   X  Σ[ A  Type  ] (A  X)
+Subset→Embedding {X = X} A = D , fst , Ψ
+ where
+  D = Σ[ x  X ] x  A
+
+  Ψ : isEmbedding fst
+  Ψ w x = isEmbeddingFstΣProp (∈-isProp A)
+
+Subset→Embedding→Subset : {X : Type }  section (Embedding→Subset {} {X}) (Subset→Embedding {} {X})
+Subset→Embedding→Subset _ = funExt λ x  Σ≡Prop  _  isPropIsProp) (ua (FiberIso.fiberEquiv _ x))
+
+Embedding→Subset→Embedding : {X : Type }  retract (Embedding→Subset {} {X}) (Subset→Embedding {} {X})
+Embedding→Subset→Embedding { = } {X = X} (A , f , ψ) =
+  cong (equivFun Σ-assoc-≃) (Σ≡Prop  _  isPropIsEmbedding) (retEq (fibrationEquiv X ) (A , f)))
+
+Subset≃Embedding : {X : Type }   X  (Σ[ A  Type  ] (A  X))
+Subset≃Embedding = isoToEquiv (iso Subset→Embedding Embedding→Subset
+                                    Embedding→Subset→Embedding Subset→Embedding→Subset)
+
+Subset≡Embedding : {X : Type }   X  (Σ[ A  Type  ] (A  X))
+Subset≡Embedding = ua Subset≃Embedding
+
+isEmbedding-∘ : isEmbedding f  isEmbedding h  isEmbedding (f  h)
+isEmbedding-∘ {f = f} {h = h} Embf Embh w x
+  = compEquiv (cong h , Embh w x) (cong f , Embf (h w) (h x)) .snd
+
+compEmbedding : (B  C)  (A  B)  (A  C)
+(compEmbedding (g , _ ) (f , _ )).fst = g  f
+(compEmbedding (_ , g↪) (_ , f↪)).snd = isEmbedding-∘ g↪ f↪
+
+isEmbedding→embedsFibersIntoSingl
+  : isEmbedding f
+    z  fiber f z  singl z
+isEmbedding→embedsFibersIntoSingl {f = f} isE z = e , isEmbE where
+  e : fiber f z  singl z
+  e x = f (fst x) , sym (snd x)
+
+  isEmbE : isEmbedding e
+  isEmbE u v = goal where
+    -- "adjust" ΣeqCf by trivial equivalences that hold judgementally, which should save compositions
+    Dom′ :  u v  Type _
+    Dom′ u v = Σ[ p     fst u      fst v  ] PathP  i  f (p i)  z) (snd u) (snd v)
+    Cod′ :  u v  Type _
+    Cod′ u v = Σ[ p  f (fst u)  f (fst v) ] PathP  i     p i   z) (snd u) (snd v)
+    ΣeqCf : Dom′ u v  Cod′ u v
+    ΣeqCf = Σ-cong-equiv-fst (_ , isE _ _)
+
+    dom→ : u  v  Dom′ u v
+    dom→ p = cong fst p , cong snd p
+    dom← : Dom′ u v  u  v
+    dom← p i = p .fst i , p .snd i
+
+    cod→ : e u  e v  Cod′ u v
+    cod→ p = cong fst p , cong (sym  snd) p
+    cod← : Cod′ u v  e u  e v
+    cod← p i = p .fst i , sym (p .snd i)
+
+    goal : isEquiv (cong e)
+    goal .equiv-proof x .fst .fst =
+      dom← (equivCtr ΣeqCf (cod→ x) .fst)
+    goal .equiv-proof x .fst .snd j =
+      cod← (equivCtr ΣeqCf (cod→ x) .snd j)
+    goal .equiv-proof x .snd (g , p) i .fst =
+      dom← (equivCtrPath ΣeqCf (cod→ x) (dom→ g , cong cod→ p) i .fst)
+    goal .equiv-proof x .snd (g , p) i .snd j =
+      cod← (equivCtrPath ΣeqCf (cod→ x) (dom→ g , cong cod→ p) i .snd j)
+
+isEmbedding→hasPropFibers′ : isEmbedding f  hasPropFibers f
+isEmbedding→hasPropFibers′ {f = f} iE z =
+  Embedding-into-isProp→isProp (isEmbedding→embedsFibersIntoSingl iE z) isPropSingl
+
+universeEmbedding :
+   { ℓ' : Level}
+   (F : Type   Type ℓ')
+   (∀ X  F X  X)
+   isEmbedding F
+universeEmbedding F liftingEquiv = hasPropFibersOfImage→isEmbedding propFibersF where
+  lemma :  A B  (F A  F B)  (B  A)
+  lemma A B = (F A  F B)  ≃⟨ univalence 
+              (F A  F B) ≃⟨ equivComp (liftingEquiv A) (liftingEquiv B) 
+              (A  B)     ≃⟨ invEquivEquiv 
+              (B  A)     ≃⟨ invEquiv univalence 
+              (B  A)      
+  fiberSingl :  X  fiber F (F X)  singl X
+  fiberSingl X = Σ-cong-equiv-snd  _  lemma _ _)
+  propFibersF : hasPropFibersOfImage F
+  propFibersF X = Embedding-into-isProp→isProp (Equiv→Embedding (fiberSingl X)) isPropSingl
+
+liftEmbedding : ( ℓ' : Level)
+               isEmbedding (Lift {i = } {j = ℓ'})
+liftEmbedding  ℓ' = universeEmbedding (Lift {j = ℓ'})  _  invEquiv LiftEquiv)
+
+module FibrationIdentityPrinciple {B : Type } {ℓ'} where
+  -- note that fibrationEquiv (for good reason) uses ℓ' = ℓ-max ℓ ℓ', so we have to work
+  -- some universe magic to achieve good universe polymorphism
+
+  -- First, prove it for the case that's dealt with in fibrationEquiv
+  Fibration′ = Fibration B (ℓ-max  ℓ')
+
+  module Lifted (f g : Fibration′) where
+    f≃g′ : Type (ℓ-max  ℓ')
+    f≃g′ =  b  fiber (f .snd) b  fiber (g .snd) b
+
+    Fibration′IP : f≃g′  (f  g)
+    Fibration′IP =
+        f≃g′
+      ≃⟨ equivΠCod  _  invEquiv univalence) 
+        (∀ b  fiber (f .snd) b  fiber (g .snd) b)
+      ≃⟨ funExtEquiv 
+        fiber (f .snd)  fiber (g .snd)
+      ≃⟨ invEquiv (congEquiv (fibrationEquiv B ℓ')) 
+        f  g
+      
+
+  -- Then embed into the above case by lifting the type
+  L : Type _  Type _ -- local synonym fixing the levels of Lift
+  L = Lift {i = ℓ'} {j = }
+
+  liftFibration : Fibration B ℓ'  Fibration′
+  liftFibration (A , f) = L A , f  lower
+
+  hasPropFibersLiftFibration : hasPropFibers liftFibration
+  hasPropFibersLiftFibration (A , f) =
+    Embedding-into-isProp→isProp (Equiv→Embedding fiberChar)
+      (isPropΣ (isEmbedding→hasPropFibers (liftEmbedding _ _) A)
+               λ _  isEquiv→hasPropFibers (snd (invEquiv (preCompEquiv LiftEquiv))) _)
+    where
+    fiberChar : fiber liftFibration (A , f)
+               (Σ[ (E , eq)  fiber L A ] fiber (_∘ lower) (transport⁻  i  eq i  B) f))
+    fiberChar =
+        fiber liftFibration (A , f)
+      ≃⟨ Σ-cong-equiv-snd  _  invEquiv ΣPath≃PathΣ) 
+        (Σ[ (E , g)  Fibration B ℓ' ] Σ[ eq  (L E  A) ] PathP  i  eq i  B) (g  lower) f)
+      ≃⟨ boringSwap 
+        (Σ[ (E , eq)  fiber L A ] Σ[ g  (E  B) ] PathP  i  eq i  B) (g  lower) f)
+      ≃⟨ Σ-cong-equiv-snd  _  Σ-cong-equiv-snd λ _  pathToEquiv (PathP≡Path⁻ _ _ _)) 
+        (Σ[ (E , eq)  fiber L A ] fiber (_∘ lower) (transport⁻  i  eq i  B) f))
+       where
+      unquoteDecl boringSwap =
+        declStrictEquiv boringSwap
+           ((E , g) , (eq , p))  ((E , eq) , (g , p)))
+           ((E , g) , (eq , p))  ((E , eq) , (g , p)))
+
+  isEmbeddingLiftFibration : isEmbedding liftFibration
+  isEmbeddingLiftFibration = hasPropFibers→isEmbedding hasPropFibersLiftFibration
+
+  -- and finish off
+  module _ (f g : Fibration B ℓ') where
+    open Lifted (liftFibration f) (liftFibration g)
+    f≃g : Type (ℓ-max  ℓ')
+    f≃g =  b  fiber (f .snd) b  fiber (g .snd) b
+
+    FibrationIP : f≃g  (f  g)
+    FibrationIP =
+      f≃g  ≃⟨ equivΠCod  b  equivComp (Σ-cong-equiv-fst LiftEquiv)
+                                          (Σ-cong-equiv-fst LiftEquiv)) 
+      f≃g′ ≃⟨ Fibration′IP 
+      (liftFibration f  liftFibration g) ≃⟨ invEquiv (_ , isEmbeddingLiftFibration _ _) 
+      (f  g) 
+
+_≃Fib_ : {B : Type } (f g : Fibration B ℓ')  Type (ℓ-max  ℓ')
+_≃Fib_ = FibrationIdentityPrinciple.f≃g
+
+FibrationIP : {B : Type } (f g : Fibration B ℓ')  f ≃Fib g  (f  g)
+FibrationIP = FibrationIdentityPrinciple.FibrationIP
+
+Embedding : (B : Type ℓ')  ( : Level)  Type (ℓ-max ℓ' (ℓ-suc ))
+Embedding B  = Σ[ A  Type  ] A  B
+
+module EmbeddingIdentityPrinciple {B : Type } {ℓ'} (f g : Embedding B ℓ') where
+  open Σ f renaming (fst to F)
+  open Σ g renaming (fst to G)
+  open Σ (f .snd) renaming (fst to ffun; snd to isEmbF)
+  open Σ (g .snd) renaming (fst to gfun; snd to isEmbG)
+  f≃g : Type _
+  f≃g = (∀ b  fiber ffun b  fiber gfun b) ×
+         (∀ b  fiber gfun b  fiber ffun b)
+  toFibr : Embedding B ℓ'  Fibration B ℓ'
+  toFibr (A , (f , _)) = (A , f)
+
+  isEmbeddingToFibr : isEmbedding toFibr
+  isEmbeddingToFibr w x = fullEquiv .snd where
+    -- carefully managed such that (cong toFibr) is the equivalence
+    fullEquiv : (w  x)  (toFibr w  toFibr x)
+    fullEquiv = compEquiv (congEquiv (invEquiv Σ-assoc-≃)) (invEquiv (Σ≡PropEquiv  _  isPropIsEmbedding)))
+
+  EmbeddingIP : f≃g  (f  g)
+  EmbeddingIP =
+      f≃g
+    ≃⟨ strictIsoToEquiv (invIso toProdIso) 
+      (∀ b  (fiber ffun b  fiber gfun b) × (fiber gfun b  fiber ffun b))
+    ≃⟨ equivΠCod  _  isEquivPropBiimpl→Equiv (isEmbedding→hasPropFibers isEmbF _)
+                                                 (isEmbedding→hasPropFibers isEmbG _)) 
+      (∀ b  (fiber (f .snd .fst) b)  (fiber (g .snd .fst) b))
+    ≃⟨ FibrationIP (toFibr f) (toFibr g) 
+      (toFibr f  toFibr g)
+    ≃⟨ invEquiv (_ , isEmbeddingToFibr _ _) 
+      f  g
+    
+
+_≃Emb_ : {B : Type } (f g : Embedding B ℓ')  Type _
+_≃Emb_ = EmbeddingIdentityPrinciple.f≃g
+
+EmbeddingIP : {B : Type } (f g : Embedding B ℓ')  f ≃Emb g  (f  g)
+EmbeddingIP = EmbeddingIdentityPrinciple.EmbeddingIP
+
\ No newline at end of file diff --git a/docs/Cubical.Functions.Fibration.html b/docs/Cubical.Functions.Fibration.html new file mode 100644 index 0000000..2222516 --- /dev/null +++ b/docs/Cubical.Functions.Fibration.html @@ -0,0 +1,113 @@ + +Cubical.Functions.Fibration
{-# OPTIONS --safe #-}
+module Cubical.Functions.Fibration where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.HLevels using (isOfHLevel→isOfHLevelDep)
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.GroupoidLaws
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Equiv.Properties
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Path
+open import Cubical.Foundations.Univalence
+open import Cubical.Foundations.Transport
+open import Cubical.Data.Sigma
+
+private
+  variable
+     ℓb : Level
+    B : Type ℓb
+
+module FiberIso {} (p⁻¹ : B  Type ) (x : B) where
+
+  p : Σ B p⁻¹  B
+  p = fst
+
+  fwd : fiber p x  p⁻¹ x
+  fwd ((x' , y) , q) = subst  z  p⁻¹ z) q y
+
+  bwd : p⁻¹ x  fiber p x
+  bwd y = (x , y) , refl
+
+  fwd-bwd :  x  fwd (bwd x)  x
+  fwd-bwd y = transportRefl y
+
+  bwd-fwd :  x  bwd (fwd x)  x
+  bwd-fwd ((x' , y) , q) i = h (r i)
+    where h : Σ[ s  singl x ] p⁻¹ (s .fst)  fiber p x
+          h ((x , p) , y) = (x , y) , sym p
+          r : Path (Σ[ s  singl x ] p⁻¹ (s .fst))
+                   ((x  , refl ) , subst p⁻¹ q y)
+                   ((x' , sym q) , y                            )
+          r = ΣPathP (isContrSingl x .snd (x' , sym q)
+                     , toPathP (transport⁻Transport  i  p⁻¹ (q i)) y))
+
+  -- HoTT Lemma 4.8.1
+  fiberEquiv : fiber p x  p⁻¹ x
+  fiberEquiv = isoToEquiv (iso fwd bwd fwd-bwd bwd-fwd)
+
+open FiberIso using (fiberEquiv) public
+
+module _ {} {E : Type } (p : E  B) where
+
+  -- HoTT Lemma 4.8.2
+  totalEquiv : E  Σ B (fiber p)
+  totalEquiv = isoToEquiv isom
+    where isom : Iso E (Σ B (fiber p))
+          Iso.fun isom x           = p x , x , refl
+          Iso.inv isom (b , x , q) = x
+          Iso.leftInv  isom x           i = x
+          Iso.rightInv isom (b , x , q) i = q i , x , λ j  q (i  j)
+
+module _ (B : Type ℓb) ( : Level) where
+  private
+    ℓ' = ℓ-max ℓb 
+
+  -- HoTT Theorem 4.8.3
+  fibrationEquiv : (Σ[ E  Type ℓ' ] (E  B))  (B  Type ℓ')
+  fibrationEquiv = isoToEquiv isom
+    where isom : Iso (Σ[ E  Type ℓ' ] (E  B)) (B  Type ℓ')
+          Iso.fun isom (E , p) = fiber p
+          Iso.inv isom p⁻¹     = Σ B p⁻¹ , fst
+          Iso.rightInv isom p⁻¹ i x = ua (fiberEquiv p⁻¹ x) i
+          Iso.leftInv  isom (E , p) i = ua e (~ i) , fst  ua-unglue e (~ i)
+            where e = totalEquiv p
+
+
+module ForSets {E : Type } {isSetB : isSet B} (f : E  B) where
+  module _ {x x'} {px : x  x'} {a' : fiber f x} {b' : fiber f x'} where
+    -- fibers are equal when their representatives are equal
+    fibersEqIfRepsEq : fst a'  fst b'
+                     PathP  i  fiber f (px i)) a' b'
+    fibersEqIfRepsEq p = ΣPathP (p ,
+                                (isOfHLevel→isOfHLevelDep 1
+                                                           (v , w)  isSetB (f v) w)
+                                                          (snd a') (snd b')
+                                                           i  (p i , px i))))
+-- The path type in a fiber of f is equivalent to a fiber of (cong f)
+open import Cubical.Foundations.Function
+
+fiberPath :  { ℓ'} {A : Type } {B : Type ℓ'} {f : A  B} {b : B} (h h' : fiber f b) 
+             (Σ[ p  (fst h  fst h') ] (PathP  i  f (p i)  b) (snd h) (snd h')))
+            fiber (cong f) (h .snd ∙∙ refl ∙∙ sym (h' .snd))
+fiberPath h h' = cong (Σ (h .fst  h' .fst)) (funExt λ p  flipSquarePath  PathP≡doubleCompPathʳ _ _ _ _)
+
+fiber≡ :  { ℓ'} {A : Type } {B : Type ℓ'} {f : A  B} {b : B} (h h' : fiber f b)
+   (h  h')  fiber (cong f) (h .snd ∙∙ refl ∙∙ sym (h' .snd))
+fiber≡ {f = f} {b = b} h h' =
+  ΣPath≡PathΣ ⁻¹ 
+  fiberPath h h'
+
+fiberCong :  { ℓ'} {A : Type } {B : Type ℓ'} (f : A  B) {a₀ a₁ : A} (q : f a₀  f a₁)
+   fiber (cong f) q  Path (fiber f (f a₁)) (a₀ , q) (a₁ , refl)
+fiberCong f q =
+  cong (fiber (cong f)) (cong sym (lUnit (sym q)))
+   sym (fiber≡ (_ , q) (_ , refl))
+
+FibrationStr : (B : Type ℓb)  Type   Type (ℓ-max  ℓb)
+FibrationStr B A = A  B
+
+Fibration : (B : Type ℓb)  ( : Level)  Type (ℓ-max ℓb (ℓ-suc ))
+Fibration {ℓb = ℓb} B  = Σ[ A  Type  ] FibrationStr B A
+
\ No newline at end of file diff --git a/docs/Cubical.Functions.Surjection.html b/docs/Cubical.Functions.Surjection.html new file mode 100644 index 0000000..caff5e9 --- /dev/null +++ b/docs/Cubical.Functions.Surjection.html @@ -0,0 +1,95 @@ + +Cubical.Functions.Surjection
{-# OPTIONS --safe #-}
+module Cubical.Functions.Surjection where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.HLevels
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Univalence
+open import Cubical.Foundations.Function
+open import Cubical.Functions.Embedding
+
+open import Cubical.Data.Sigma
+open import Cubical.Data.Unit
+open import Cubical.HITs.PropositionalTruncation as PT
+
+private variable
+   ℓ' : Level
+  A B C : Type 
+  f : A  B
+
+isSurjection : (A  B)  Type _
+isSurjection f =  b   fiber f b ∥₁
+
+_↠_ : Type   Type ℓ'  Type (ℓ-max  ℓ')
+A  B = Σ[ f  (A  B) ] isSurjection f
+
+section→isSurjection : {g : B  A}  section f g  isSurjection f
+section→isSurjection {g = g} s b =  g b , s b ∣₁
+
+isPropIsSurjection : isProp (isSurjection f)
+isPropIsSurjection = isPropΠ λ _  squash₁
+
+isEquiv→isSurjection : isEquiv f  isSurjection f
+isEquiv→isSurjection e b =  fst (equiv-proof e b) ∣₁
+
+isEquiv→isEmbedding×isSurjection : isEquiv f  isEmbedding f × isSurjection f
+isEquiv→isEmbedding×isSurjection e = isEquiv→isEmbedding e , isEquiv→isSurjection e
+
+isEmbedding×isSurjection→isEquiv : isEmbedding f × isSurjection f  isEquiv f
+equiv-proof (isEmbedding×isSurjection→isEquiv {f = f} (emb , sur)) b =
+  inhProp→isContr (PT.rec fib'  x  x) fib) fib'
+  where
+  hpf : hasPropFibers f
+  hpf = isEmbedding→hasPropFibers emb
+
+  fib :  fiber f b ∥₁
+  fib = sur b
+
+  fib' : isProp (fiber f b)
+  fib' = hpf b
+
+isEquiv≃isEmbedding×isSurjection : isEquiv f  isEmbedding f × isSurjection f
+isEquiv≃isEmbedding×isSurjection = isoToEquiv (iso
+  isEquiv→isEmbedding×isSurjection
+  isEmbedding×isSurjection→isEquiv
+   _  isOfHLevelΣ 1 isPropIsEmbedding (\ _  isPropIsSurjection) _ _)
+   _  isPropIsEquiv _ _ _))
+
+-- obs: for epi⇒surjective to go through we require a stronger
+-- hypothesis that one would expect:
+-- f must cancel functions from a higher universe.
+rightCancellable : (f : A  B)  Type _
+rightCancellable {} {A} {ℓ'} {B} f =  {C : Type (ℓ-suc (ℓ-max  ℓ'))}
+    (g g' : B  C)  (∀ x  g (f x)  g' (f x))   y  g y  g' y
+
+-- This statement is in Mac Lane & Moerdijk (page 143, corollary 5).
+epi⇒surjective : (f : A  B)  rightCancellable f  isSurjection f
+epi⇒surjective f rc y = transport (fact₂ y) tt*
+    where hasPreimage : (A  B)  B  _
+          hasPreimage f y =  fiber f y ∥₁
+
+          fact₁ :  x  Unit*  hasPreimage f (f x)
+          fact₁ x = hPropExt isPropUnit*
+                             isPropPropTrunc
+                              _   (x , refl) ∣₁)
+                              _  tt*)
+
+          fact₂ :  y  Unit*  hasPreimage f y
+          fact₂ = rc _ _ fact₁
+
+-- If h ∘ g is surjective, then h is surjective.
+leftFactorSurjective : (g : A  B) (h : B  C)
+                         isSurjection (h  g)
+                         isSurjection h
+leftFactorSurjective g h sur-h∘g c = PT.rec isPropPropTrunc  (x , hgx≡c)   g x , hgx≡c ∣₁) (sur-h∘g c)
+
+compSurjection : (f : A  B) (g : B  C)
+                  A  C
+compSurjection (f , sur-f) (g , sur-g) =
+   x  g (f x)) ,
+   λ c  PT.rec isPropPropTrunc
+                 (b , gb≡c)  PT.rec isPropPropTrunc  (a , fa≡b)   a , (cong g fa≡b  gb≡c) ∣₁) (sur-f b))
+                (sur-g c)
+
\ No newline at end of file diff --git a/docs/Cubical.HITs.PropositionalTruncation.MagicTrick.html b/docs/Cubical.HITs.PropositionalTruncation.MagicTrick.html new file mode 100644 index 0000000..78d8144 --- /dev/null +++ b/docs/Cubical.HITs.PropositionalTruncation.MagicTrick.html @@ -0,0 +1,90 @@ + +Cubical.HITs.PropositionalTruncation.MagicTrick
{-
+
+Based on Nicolai Kraus' blog post:
+  The Truncation Map |_| : ℕ -> ‖ℕ‖ is nearly Invertible
+  https://homotopytypetheory.org/2013/10/28/the-truncation-map-_-ℕ-‖ℕ‖-is-nearly-invertible/
+
+Defines [recover], which definitionally satisfies `recover ∣ x ∣ ≡ x` ([recover∣∣]) for homogeneous types
+
+Also see the follow-up post by Jason Gross:
+  Composition is not what you think it is! Why “nearly invertible” isn’t.
+  https://homotopytypetheory.org/2014/02/24/composition-is-not-what-you-think-it-is-why-nearly-invertible-isnt/
+
+-}
+{-# OPTIONS --safe #-}
+
+module Cubical.HITs.PropositionalTruncation.MagicTrick where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.Path
+open import Cubical.Foundations.Pointed
+open import Cubical.Foundations.Pointed.Homogeneous
+
+open import Cubical.HITs.PropositionalTruncation.Base
+open import Cubical.HITs.PropositionalTruncation.Properties
+
+module Recover {} (A∙ : Pointed ) (h : isHomogeneous A∙) where
+  private
+    A = typ A∙
+    a = pt A∙
+
+  toEquivPtd :  A ∥₁  Σ[ B∙  Pointed  ] (A , a)  B∙
+  toEquivPtd = rec isPropSingl  x  (A , x) , h x)
+  private
+    B∙ :  A ∥₁  Pointed 
+    B∙ tx = fst (toEquivPtd tx)
+
+  -- the key observation is that B∙ ∣ x ∣₁ is definitionally equal to (A , x)
+  private
+    obvs :  x  B∙  x ∣₁  (A , x)
+    obvs x = refl -- try it: `C-c C-n B∙ ∣ x ∣₁` gives `(A , x)`
+
+  -- thus any truncated element (of a homogeneous type) can be recovered by agda's normalizer!
+
+  recover :  (tx :  A ∥₁)  typ (B∙ tx)
+  recover tx = pt (B∙ tx)
+
+  recover∣∣ :  (x : A)  recover  x ∣₁  x
+  recover∣∣ x = refl -- try it: `C-c C-n recover ∣ x ∣₁` gives `x`
+
+  private
+    -- notice that the following typechecks because typ (B∙ ∣ x ∣₁) is definitionally equal to to A, but
+    --  `recover : ∥ A ∥₁ → A` does not because typ (B∙ tx) is not definitionally equal to A (though it is
+    --  judegmentally equal to A by cong typ (snd (toEquivPtd tx)) : A ≡ typ (B∙ tx))
+    obvs2 : A  A
+    obvs2 = recover  ∣_∣₁
+
+    -- one might wonder if (cong recover (squash₁ ∣ x ∣₁ ∣ y ∣₁)) therefore has type x ≡ y, but thankfully
+    --  typ (B∙ (squash₁ ∣ x ∣₁ ∣ y ∣₁ i)) is *not* A (it's a messy hcomp involving h x and h y)
+    recover-squash₁ :  x y  -- x ≡ y -- this raises an error
+                             PathP  i  typ (B∙ (squash₁  x ∣₁  y ∣₁ i))) x y
+    recover-squash₁ x y = cong recover (squash₁  x ∣₁  y ∣₁)
+
+
+-- Demo, adapted from:
+-- https://bitbucket.org/nicolaikraus/agda/src/e30d70c72c6af8e62b72eefabcc57623dd921f04/trunc-inverse.lagda
+
+private
+  open import Cubical.Data.Nat
+  open Recover ( , zero) (isHomogeneousDiscrete discreteℕ)
+
+  -- only `∣hidden∣` is exported, `hidden` is no longer in scope
+  module _ where
+    private
+      hidden : 
+      hidden = 17
+
+    ∣hidden∣ :   ∥₁
+    ∣hidden∣ =  hidden ∣₁
+
+  -- we can still recover the value, even though agda can no longer see `hidden`!
+  test : recover ∣hidden∣  17
+  test = refl -- try it: `C-c C-n recover ∣hidden∣` gives `17`
+              --         `C-c C-n hidden` gives an error
+
+  -- Finally, note that the definition of recover is independent of the proof that A is homogeneous. Thus we
+  --  still can definitionally recover information hidden by ∣_∣₁ as long as we permit holes. Try replacing
+  --  `isHomogeneousDiscrete discreteℕ` above with a hole (`?`) and notice that everything still works
+
\ No newline at end of file diff --git a/docs/Cubical.HITs.PropositionalTruncation.Properties.html b/docs/Cubical.HITs.PropositionalTruncation.Properties.html new file mode 100644 index 0000000..bac77cf --- /dev/null +++ b/docs/Cubical.HITs.PropositionalTruncation.Properties.html @@ -0,0 +1,570 @@ + +Cubical.HITs.PropositionalTruncation.Properties
{-
+
+This file contains:
+
+- Eliminator for propositional truncation
+
+-}
+{-# OPTIONS --safe #-}
+module Cubical.HITs.PropositionalTruncation.Properties where
+
+open import Cubical.Core.Everything
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.HLevels
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Univalence
+
+open import Cubical.Data.Sigma
+open import Cubical.Data.Sum hiding (rec ; elim ; map)
+open import Cubical.Data.Nat using ( ; zero ; suc)
+open import Cubical.Data.FinData using (Fin ; zero ; suc)
+
+open import Cubical.HITs.PropositionalTruncation.Base
+
+private
+  variable
+     ℓ' : Level
+    A B C : Type 
+    A′ : Type ℓ'
+
+∥∥-isPropDep : (P : A  Type )  isOfHLevelDep 1  x   P x ∥₁)
+∥∥-isPropDep P = isOfHLevel→isOfHLevelDep 1  _  squash₁)
+
+rec : {P : Type }  isProp P  (A  P)   A ∥₁  P
+rec Pprop f  x ∣₁ = f x
+rec Pprop f (squash₁ x y i) = Pprop (rec Pprop f x) (rec Pprop f y) i
+
+rec2 : {P : Type }  isProp P  (A  B  P)   A ∥₁   B ∥₁  P
+rec2 Pprop f  x ∣₁  y ∣₁ = f x y
+rec2 Pprop f  x ∣₁ (squash₁ y z i) = Pprop (rec2 Pprop f  x ∣₁ y) (rec2 Pprop f  x ∣₁ z) i
+rec2 Pprop f (squash₁ x y i) z = Pprop (rec2 Pprop f x z) (rec2 Pprop f y z) i
+
+rec3 : {P : Type }  isProp P  (A  B  C  P)   A ∥₁   B ∥₁   C ∥₁  P
+rec3 Pprop f  x ∣₁  y ∣₁  z ∣₁ = f x y z
+rec3 Pprop f  x ∣₁  y ∣₁ (squash₁ z w i) = Pprop (rec3 Pprop f  x ∣₁  y ∣₁ z) (rec3 Pprop f  x ∣₁  y ∣₁ w) i
+rec3 Pprop f  x ∣₁ (squash₁ y z i) w = Pprop (rec3 Pprop f  x ∣₁ y w) (rec3 Pprop f  x ∣₁ z w) i
+rec3 Pprop f (squash₁ x y i) z w = Pprop (rec3 Pprop f x z w) (rec3 Pprop f y z w) i
+
+-- Old version
+-- rec2 : ∀ {P : Type ℓ} → isProp P → (A → A → P) → ∥ A ∥ → ∥ A ∥ → P
+-- rec2 Pprop f = rec (isProp→ Pprop) (λ a → rec Pprop (f a))
+
+-- n-ary recursor, stated using a dependent FinVec
+recFin : {m : } {P : Fin m  Type }
+         {B : Type ℓ'} (isPropB : isProp B)
+        ((∀ i  P i)  B)
+      ---------------------
+        ((∀ i   P i ∥₁)  B)
+recFin {m = zero} _ untruncHyp _ = untruncHyp  ())
+recFin {m = suc m} {P = P} {B = B} isPropB untruncHyp truncFam =
+  curriedishTrunc (truncFam zero) (truncFam  suc)
+  where
+  curriedish : P zero  (∀ i   P (suc i) ∥₁)  B
+  curriedish p₀ = recFin isPropB
+                          famSuc  untruncHyp  { zero  p₀ ; (suc i)  famSuc i }))
+
+  curriedishTrunc :  P zero ∥₁  (∀ i   P (suc i) ∥₁)  B
+  curriedishTrunc = rec (isProp→ isPropB) curriedish
+
+recFin2 : {m1 m2 : } {P : Fin m1  Fin m2  Type }
+          {B : Type ℓ'} (isPropB : isProp B)
+         ((∀ i j  P i j)  B)
+       --------------------------
+         (∀ i j   P i j ∥₁)
+         B
+recFin2 {m1 = zero} _ untruncHyp _ = untruncHyp λ ()
+recFin2 {m1 = suc m1} {P = P} {B = B} isPropB untruncHyp truncFam =
+  curriedishTrunc (truncFam zero) (truncFam  suc)
+  where
+  curriedish : (∀ j  P zero j)  (∀ i j   P (suc i) j ∥₁)  B
+  curriedish p₀ truncFamSuc = recFin2 isPropB
+                              famSuc  untruncHyp λ { zero  p₀ ; (suc i)  famSuc i })
+                               truncFamSuc
+
+  curriedishTrunc : (∀ j   P zero j ∥₁)  (∀ i j   P (suc i) j ∥₁)  B
+  curriedishTrunc = recFin (isProp→ isPropB) curriedish
+
+
+elim : {P :  A ∥₁  Type }  ((a :  A ∥₁)  isProp (P a))
+      ((x : A)  P  x ∣₁)  (a :  A ∥₁)  P a
+elim Pprop f  x ∣₁ = f x
+elim Pprop f (squash₁ x y i) =
+  isOfHLevel→isOfHLevelDep 1 Pprop
+    (elim Pprop f x) (elim Pprop f y) (squash₁ x y) i
+
+elim2 : {P :  A ∥₁   B ∥₁  Type }
+        (Pprop : (x :  A ∥₁) (y :  B ∥₁)  isProp (P x y))
+        (f : (a : A) (b : B)  P  a ∣₁  b ∣₁)
+        (x :  A ∥₁) (y :  B ∥₁)  P x y
+elim2 Pprop f =
+  elim  _  isPropΠ  _  Pprop _ _))
+                        a  elim  _  Pprop _ _) (f a))
+
+elim3 : {P :  A ∥₁   B ∥₁   C ∥₁  Type }
+        (Pprop : ((x :  A ∥₁) (y :  B ∥₁) (z :  C ∥₁)  isProp (P x y z)))
+        (g : (a : A) (b : B) (c : C)  P ( a ∣₁)  b ∣₁  c ∣₁)
+        (x :  A ∥₁) (y :  B ∥₁) (z :  C ∥₁)  P x y z
+elim3 Pprop g = elim2  _ _  isPropΠ  _  Pprop _ _ _))
+                       a b  elim  _  Pprop _ _ _) (g a b))
+
+-- n-ary eliminator, stated using a dependent FinVec
+elimFin : {m : } {P : Fin m  Type }
+          {B : (∀ i   P i ∥₁)  Type ℓ'}
+          (isPropB :  x  isProp (B x))
+         ((x :  i  P i)  B  i   x i ∣₁))
+       ----------------------------------------
+         ((x :  i   P i ∥₁)  B x)
+elimFin {m = zero} {B = B} _ untruncHyp _ = subst B (funExt  ())) (untruncHyp  ()))
+elimFin {m = suc m} {P = P} {B = B} isPropB untruncHyp x =
+  subst B (funExt  { zero  refl ; (suc i)  refl}))
+          (curriedishTrunc (x zero) (x  suc))
+  where
+  curriedish : (x₀ : P zero) (xₛ :  i   P (suc i) ∥₁)
+              B  { zero   x₀ ∣₁ ; (suc i)  xₛ i})
+  curriedish x₀ xₛ = subst B (funExt  { zero  refl ; (suc i)  refl}))
+     (elimFin  xₛ  isPropB  { zero   x₀ ∣₁ ; (suc i)  xₛ i}))
+               y  subst B (funExt  { zero  refl ; (suc i)  refl}))
+                             (untruncHyp  { zero  x₀ ; (suc i)  y i }))) xₛ)
+
+  curriedishTrunc : (x₀ :  P zero ∥₁) (xₛ :  i   P (suc i) ∥₁)
+                   B  { zero  x₀ ; (suc i)  xₛ i})
+  curriedishTrunc = elim  _  isPropΠ λ _  isPropB _)
+                    λ x₀ xₛ  subst B (funExt  { zero  refl ; (suc i)  refl}))
+                                      (curriedish x₀ xₛ)
+
+isPropPropTrunc : isProp  A ∥₁
+isPropPropTrunc x y = squash₁ x y
+
+propTrunc≃ : A  B   A ∥₁   B ∥₁
+propTrunc≃ e =
+  propBiimpl→Equiv
+    isPropPropTrunc isPropPropTrunc
+    (rec isPropPropTrunc  a   e .fst a ∣₁))
+    (rec isPropPropTrunc  b   invEq e b ∣₁))
+
+propTruncIdempotent≃ : isProp A   A ∥₁  A
+propTruncIdempotent≃ {A = A} hA = isoToEquiv f
+  where
+  f : Iso  A ∥₁ A
+  Iso.fun f        = rec hA (idfun A)
+  Iso.inv f x      =  x ∣₁
+  Iso.rightInv f _ = refl
+  Iso.leftInv f    = elim  _  isProp→isSet isPropPropTrunc _ _)  _  refl)
+
+propTruncIdempotent : isProp A   A ∥₁  A
+propTruncIdempotent hA = ua (propTruncIdempotent≃ hA)
+
+-- We could also define the eliminator using the recursor
+elim' : {P :  A ∥₁  Type }  ((a :  A ∥₁)  isProp (P a)) 
+        ((x : A)  P  x ∣₁)  (a :  A ∥₁)  P a
+elim' {P = P} Pprop f a =
+  rec (Pprop a)  x  transp  i  P (squash₁  x ∣₁ a i)) i0 (f x)) a
+
+map : (A  B)  ( A ∥₁   B ∥₁)
+map f = rec squash₁ (∣_∣₁  f)
+
+map2 : (A  B  C)  ( A ∥₁   B ∥₁   C ∥₁)
+map2 f = rec (isPropΠ λ _  squash₁) (map  f)
+
+-- The propositional truncation can be eliminated into non-propositional
+-- types as long as the function used in the eliminator is 'coherently
+-- constant.' The details of this can be found in the following paper:
+--
+--   https://arxiv.org/pdf/1411.2682.pdf
+module SetElim (Bset : isSet B) where
+  Bset' : isSet' B
+  Bset' = isSet→isSet' Bset
+
+  rec→Set : (f : A  B) (kf : 2-Constant f)   A ∥₁  B
+  helper  : (f : A  B) (kf : 2-Constant f)  (t u :  A ∥₁)
+           rec→Set f kf t  rec→Set f kf u
+
+  rec→Set f kf  x ∣₁ = f x
+  rec→Set f kf (squash₁ t u i) = helper f kf t u i
+
+  helper f kf  x ∣₁  y ∣₁ = kf x y
+  helper f kf (squash₁ t u i) v
+    = Bset' (helper f kf t v) (helper f kf u v) (helper f kf t u) refl i
+  helper f kf t (squash₁ u v i)
+    = Bset' (helper f kf t u) (helper f kf t v) refl (helper f kf u v) i
+
+  kcomp : (f :  A ∥₁  B)  2-Constant (f  ∣_∣₁)
+  kcomp f x y = cong f (squash₁  x ∣₁  y ∣₁)
+
+  Fset : isSet (A  B)
+  Fset = isSetΠ (const Bset)
+
+  Kset : (f : A  B)  isSet (2-Constant f)
+  Kset f = isSetΠ  _  isSetΠ  _  isProp→isSet (Bset _ _)))
+
+  setRecLemma
+    : (f :  A ∥₁  B)
+     rec→Set (f  ∣_∣₁) (kcomp f)  f
+  setRecLemma f i t
+    = elim {P = λ t  rec→Set (f  ∣_∣₁) (kcomp f) t  f t}
+         t  Bset _ _)  x  refl) t i
+
+  mkKmap : ( A ∥₁  B)  Σ (A  B) 2-Constant
+  mkKmap f = f  ∣_∣₁ , kcomp f
+
+  fib : (g : Σ (A  B) 2-Constant)  fiber mkKmap g
+  fib (g , kg) = rec→Set g kg , refl
+
+  eqv : (g : Σ (A  B) 2-Constant)   fi  fib g  fi
+  eqv g (f , p) =
+    Σ≡Prop  f  isOfHLevelΣ 2 Fset Kset _ _)
+      (cong (uncurry rec→Set) (sym p)  setRecLemma f)
+
+  trunc→Set≃ : ( A ∥₁  B)  (Σ (A  B) 2-Constant)
+  trunc→Set≃ .fst = mkKmap
+  trunc→Set≃ .snd .equiv-proof g = fib g , eqv g
+
+  -- The strategy of this equivalence proof follows the paper more closely.
+  -- It is used further down for the groupoid version, because the above
+  -- strategy does not generalize so easily.
+  e : B  Σ (A  B) 2-Constant
+  e b = const b , λ _ _  refl
+
+  eval : A  (γ : Σ (A  B) 2-Constant)  B
+  eval a₀ (g , _) = g a₀
+
+  e-eval :  (a₀ : A) γ  e (eval a₀ γ)  γ
+  e-eval a₀ (g , kg) i .fst a₁ = kg a₀ a₁ i
+  e-eval a₀ (g , kg) i .snd a₁ a₂ = Bset' refl (kg a₁ a₂) (kg a₀ a₁) (kg a₀ a₂) i
+
+  e-isEquiv : A  isEquiv (e {A = A})
+  e-isEquiv a₀ = isoToIsEquiv (iso e (eval a₀) (e-eval a₀) λ _  refl)
+
+  preEquiv₁ :  A ∥₁  B  Σ (A  B) 2-Constant
+  preEquiv₁ t = e , rec (isPropIsEquiv e) e-isEquiv t
+
+  preEquiv₂ : ( A ∥₁  Σ (A  B) 2-Constant)  Σ (A  B) 2-Constant
+  preEquiv₂ = isoToEquiv (iso to const  _  refl) retr)
+    where
+    to : ( A ∥₁  Σ (A  B) 2-Constant)  Σ (A  B) 2-Constant
+    to f .fst x = f  x ∣₁ .fst x
+    to f .snd x y i = f (squash₁  x ∣₁  y ∣₁ i) .snd x y i
+
+    retr : retract to const
+    retr f i t .fst x = f (squash₁  x ∣₁ t i) .fst x
+    retr f i t .snd x y
+      = Bset'
+           j  f (squash₁  x ∣₁  y ∣₁ j) .snd x y j)
+          (f t .snd x y)
+           j  f (squash₁  x ∣₁ t j) .fst x)
+           j  f (squash₁  y ∣₁ t j) .fst y)
+          i
+
+  trunc→Set≃₂ : ( A ∥₁  B)  Σ (A  B) 2-Constant
+  trunc→Set≃₂ = compEquiv (equivΠCod preEquiv₁) preEquiv₂
+
+open SetElim public using (rec→Set; trunc→Set≃)
+
+elim→Set
+  : {P :  A ∥₁  Type }
+   (∀ t  isSet (P t))
+   (f : (x : A)  P  x ∣₁)
+   (kf :  x y  PathP  i  P (squash₁  x ∣₁  y ∣₁ i)) (f x) (f y))
+   (t :  A ∥₁)  P t
+elim→Set {A = A} {P = P} Pset f kf t
+  = rec→Set (Pset t) g gk t
+  where
+  g : A  P t
+  g x = transp  i  P (squash₁  x ∣₁ t i)) i0 (f x)
+
+  gk : 2-Constant g
+  gk x y i = transp  j  P (squash₁ (squash₁  x ∣₁  y ∣₁ i) t j)) i0 (kf x y i)
+
+elim2→Set :
+    {P :  A ∥₁   B ∥₁  Type }
+   (∀ t u  isSet (P t u))
+   (f : (x : A) (y : B)  P  x ∣₁  y ∣₁)
+   (kf₁ :  x y v  PathP  i  P (squash₁  x ∣₁  y ∣₁ i)  v ∣₁) (f x v) (f y v))
+   (kf₂ :  x v w  PathP  i  P  x ∣₁ (squash₁  v ∣₁  w ∣₁ i)) (f x v) (f x w))
+   (sf :  x y v w  SquareP  i j  P (squash₁  x ∣₁  y ∣₁ i) (squash₁  v ∣₁  w ∣₁ j))
+                              (kf₂ x v w) (kf₂ y v w) (kf₁ x y v) (kf₁ x y w))
+   (t :  A ∥₁)  (u :  B ∥₁)  P t u
+elim2→Set {A = A} {B = B} {P = P} Pset f kf₁ kf₂ sf =
+  elim→Set  _  isSetΠ  _  Pset _ _)) mapHelper squareHelper
+  where
+  mapHelper : (x : A) (u :  B ∥₁)  P  x ∣₁ u
+  mapHelper x = elim→Set  _  Pset _ _) (f x) (kf₂ x)
+
+  squareHelper : (x y : A)
+                PathP  i  (u :  B ∥₁)  P (squash₁  x ∣₁  y ∣₁ i) u) (mapHelper x) (mapHelper y)
+  squareHelper x y i = elim→Set  _  Pset _ _)  v  kf₁ x y v i) λ v w  sf x y v w i
+
+RecHProp : (P : A  hProp ) (kP :  x y  P x  P y)   A ∥₁  hProp 
+RecHProp P kP = rec→Set isSetHProp P kP
+
+module GpdElim (Bgpd : isGroupoid B) where
+  Bgpd' : isGroupoid' B
+  Bgpd' = isGroupoid→isGroupoid' Bgpd
+
+  module _ (f : A  B) (3kf : 3-Constant f) where
+    open 3-Constant 3kf
+
+    rec→Gpd :  A ∥₁  B
+    pathHelper : (t u :  A ∥₁)  rec→Gpd t  rec→Gpd u
+    triHelper₁
+      : (t u v :  A ∥₁)
+       Square (pathHelper t u) (pathHelper t v) refl (pathHelper u v)
+    triHelper₂
+      : (t u v :  A ∥₁)
+       Square (pathHelper t v) (pathHelper u v) (pathHelper t u) refl
+
+    rec→Gpd  x ∣₁ = f x
+    rec→Gpd (squash₁ t u i) = pathHelper t u i
+
+    pathHelper  x ∣₁  y ∣₁ = link x y
+    pathHelper (squash₁ t u j) v = triHelper₂ t u v j
+    pathHelper  x ∣₁ (squash₁ u v j) = triHelper₁  x ∣₁ u v j
+
+    triHelper₁  x ∣₁  y ∣₁  z ∣₁ = coh₁ x y z
+    triHelper₁ (squash₁ s t i) u v
+      = Bgpd'
+          (triHelper₁ s u v)
+          (triHelper₁ t u v)
+          (triHelper₂ s t u)
+          (triHelper₂ s t v)
+           i  refl)
+           i  pathHelper u v)
+          i
+    triHelper₁  x ∣₁ (squash₁ t u i) v
+      = Bgpd'
+          (triHelper₁  x ∣₁ t v)
+          (triHelper₁  x ∣₁ u v)
+          (triHelper₁  x ∣₁ t u)
+           i  pathHelper  x ∣₁ v)
+           i  refl)
+          (triHelper₂ t u v)
+          i
+    triHelper₁  x ∣₁  y ∣₁ (squash₁ u v i)
+      = Bgpd'
+          (triHelper₁  x ∣₁  y ∣₁ u)
+          (triHelper₁  x ∣₁  y ∣₁ v)
+           i  link x y)
+          (triHelper₁  x ∣₁ u v)
+           i  refl)
+          (triHelper₁  y ∣₁ u v)
+          i
+
+    triHelper₂  x ∣₁  y ∣₁  z ∣₁ = coh₂ x y z
+    triHelper₂ (squash₁ s t i) u v
+      = Bgpd'
+          (triHelper₂ s u v)
+          (triHelper₂ t u v)
+          (triHelper₂ s t v)
+           i  pathHelper u v)
+          (triHelper₂ s t u)
+           i  refl)
+          i
+    triHelper₂  x ∣₁ (squash₁ t u i) v
+      = Bgpd'
+          (triHelper₂  x ∣₁ t v)
+          (triHelper₂  x ∣₁ u v)
+           i  pathHelper  x ∣₁ v)
+          (triHelper₂ t u v)
+          (triHelper₁  x ∣₁ t u)
+           i  refl)
+          i
+    triHelper₂  x ∣₁  y ∣₁ (squash₁ u v i)
+      = Bgpd'
+          (triHelper₂  x ∣₁  y ∣₁ u)
+          (triHelper₂  x ∣₁  y ∣₁ v)
+          (triHelper₁  x ∣₁ u v)
+          (triHelper₁  y ∣₁ u v)
+           i  link x y)
+           i  refl)
+          i
+
+  preEquiv₁ : ( A ∥₁  Σ (A  B) 3-Constant)  Σ (A  B) 3-Constant
+  preEquiv₁ = isoToEquiv (iso fn const  _  refl) retr)
+    where
+    open 3-Constant
+
+    fn : ( A ∥₁  Σ (A  B) 3-Constant)  Σ (A  B) 3-Constant
+    fn f .fst x = f  x ∣₁ .fst x
+    fn f .snd .link x y i = f (squash₁  x ∣₁  y ∣₁ i) .snd .link x y i
+    fn f .snd .coh₁ x y z i j
+      = f (squash₁  x ∣₁ (squash₁  y ∣₁  z ∣₁ i) j) .snd .coh₁ x y z i j
+
+    retr : retract fn const
+    retr f i t .fst x = f (squash₁  x ∣₁ t i) .fst x
+    retr f i t .snd .link x y j
+      = f (squash₁ (squash₁  x ∣₁  y ∣₁ j) t i) .snd .link x y j
+    retr f i t .snd .coh₁ x y z
+      = Bgpd'
+           k j  f (cb k j i0) .snd .coh₁ x y z k j )
+           k j  f (cb k j i1) .snd .coh₁ x y z k j)
+           k j  f (cb i0 j k) .snd .link x y j)
+           k j  f (cb i1 j k) .snd .link x z j)
+           _  refl)
+           k j  f (cb j i1 k) .snd .link y z j)
+          i
+      where
+      cb : I  I  I   _ ∥₁
+      cb i j k = squash₁ (squash₁  x ∣₁ (squash₁  y ∣₁  z ∣₁ i) j) t k
+
+  e : B  Σ (A  B) 3-Constant
+  e b .fst _ = b
+  e b .snd = record
+           { link = λ _ _ _  b
+           ; coh₁ = λ _ _ _ _ _  b
+           }
+
+  eval : A  Σ (A  B) 3-Constant  B
+  eval a₀ (g , _) = g a₀
+
+  module _ where
+    open 3-Constant
+    e-eval : ∀(a₀ : A) γ  e (eval a₀ γ)  γ
+    e-eval a₀ (g , 3kg) i .fst x = 3kg .link a₀ x i
+    e-eval a₀ (g , 3kg) i .snd .link x y = λ j  3kg .coh₁ a₀ x y j i
+    e-eval a₀ (g , 3kg) i .snd .coh₁ x y z
+      = Bgpd'
+           _ _  g a₀)
+          (3kg .coh₁ x y z)
+           k j  3kg .coh₁ a₀ x y j k)
+           k j  3kg .coh₁ a₀ x z j k)
+           _  refl)
+           k j  3kg .coh₁ a₀ y z j k)
+          i
+
+  e-isEquiv : A  isEquiv (e {A = A})
+  e-isEquiv a₀ = isoToIsEquiv (iso e (eval a₀) (e-eval a₀) λ _  refl)
+
+  preEquiv₂ :  A ∥₁  B  Σ (A  B) 3-Constant
+  preEquiv₂ t = e , rec (isPropIsEquiv e) e-isEquiv t
+
+  trunc→Gpd≃ : ( A ∥₁  B)  Σ (A  B) 3-Constant
+  trunc→Gpd≃ = compEquiv (equivΠCod preEquiv₂) preEquiv₁
+
+open GpdElim using (rec→Gpd; trunc→Gpd≃) public
+
+squash₁ᵗ
+  : ∀(x y z : A)
+   Square (squash₁  x ∣₁  y ∣₁) (squash₁  x ∣₁  z ∣₁) refl (squash₁  y ∣₁  z ∣₁)
+squash₁ᵗ x y z i = squash₁  x ∣₁ (squash₁  y ∣₁  z ∣₁ i)
+
+elim→Gpd
+  : (P :  A ∥₁  Type )
+   (∀ t  isGroupoid (P t))
+   (f : (x : A)  P  x ∣₁)
+   (kf :  x y  PathP  i  P (squash₁  x ∣₁  y ∣₁ i)) (f x) (f y))
+   (3kf :  x y z
+          SquareP  i j  P (squash₁ᵗ x y z i j)) (kf x y) (kf x z) refl (kf y z))
+   (t :  A ∥₁)  P t
+elim→Gpd {A = A} P Pgpd f kf 3kf t = rec→Gpd (Pgpd t) g 3kg t
+  where
+  g : A  P t
+  g x = transp  i  P (squash₁  x ∣₁ t i)) i0 (f x)
+
+  open 3-Constant
+
+  3kg : 3-Constant g
+  3kg .link x y i
+    = transp  j  P (squash₁ (squash₁  x ∣₁  y ∣₁ i) t j)) i0 (kf x y i)
+  3kg .coh₁ x y z i j
+    = transp  k  P (squash₁ (squash₁ᵗ x y z i j) t k)) i0 (3kf x y z i j)
+
+RecHSet : (P : A  TypeOfHLevel  2)  3-Constant P   A ∥₁  TypeOfHLevel  2
+RecHSet P 3kP = rec→Gpd (isOfHLevelTypeOfHLevel 2) P 3kP
+
+∥∥-IdempotentL-⊎-≃ :   A ∥₁  A′ ∥₁   A  A′ ∥₁
+∥∥-IdempotentL-⊎-≃ = isoToEquiv ∥∥-IdempotentL-⊎-Iso
+  where ∥∥-IdempotentL-⊎-Iso : Iso (  A ∥₁  A′ ∥₁)  ( A  A′ ∥₁)
+        Iso.fun ∥∥-IdempotentL-⊎-Iso x = rec squash₁ lem x
+          where lem :  A ∥₁  A′   A  A′ ∥₁
+                lem (inl x) = map  a  inl a) x
+                lem (inr x) =  inr x ∣₁
+        Iso.inv ∥∥-IdempotentL-⊎-Iso x = map lem x
+          where lem : A  A′   A ∥₁  A′
+                lem (inl x) = inl  x ∣₁
+                lem (inr x) = inr x
+        Iso.rightInv ∥∥-IdempotentL-⊎-Iso x = squash₁ (Iso.fun ∥∥-IdempotentL-⊎-Iso (Iso.inv ∥∥-IdempotentL-⊎-Iso x)) x
+        Iso.leftInv ∥∥-IdempotentL-⊎-Iso x  = squash₁ (Iso.inv ∥∥-IdempotentL-⊎-Iso (Iso.fun ∥∥-IdempotentL-⊎-Iso x)) x
+
+∥∥-IdempotentL-⊎ :   A ∥₁  A′ ∥₁   A  A′ ∥₁
+∥∥-IdempotentL-⊎ = ua ∥∥-IdempotentL-⊎-≃
+
+∥∥-IdempotentR-⊎-≃ :  A   A′ ∥₁ ∥₁   A  A′ ∥₁
+∥∥-IdempotentR-⊎-≃ = isoToEquiv ∥∥-IdempotentR-⊎-Iso
+  where ∥∥-IdempotentR-⊎-Iso : Iso ( A   A′ ∥₁ ∥₁) ( A  A′ ∥₁)
+        Iso.fun ∥∥-IdempotentR-⊎-Iso x = rec squash₁ lem x
+          where lem : A   A′ ∥₁   A  A′ ∥₁
+                lem (inl x) =  inl x ∣₁
+                lem (inr x) = map  a  inr a) x
+        Iso.inv ∥∥-IdempotentR-⊎-Iso x = map lem x
+          where lem : A  A′  A   A′ ∥₁
+                lem (inl x) = inl x
+                lem (inr x) = inr  x ∣₁
+        Iso.rightInv ∥∥-IdempotentR-⊎-Iso x = squash₁ (Iso.fun ∥∥-IdempotentR-⊎-Iso (Iso.inv ∥∥-IdempotentR-⊎-Iso x)) x
+        Iso.leftInv ∥∥-IdempotentR-⊎-Iso x  = squash₁ (Iso.inv ∥∥-IdempotentR-⊎-Iso (Iso.fun ∥∥-IdempotentR-⊎-Iso x)) x
+
+∥∥-IdempotentR-⊎ :  A   A′ ∥₁ ∥₁   A  A′ ∥₁
+∥∥-IdempotentR-⊎ = ua ∥∥-IdempotentR-⊎-≃
+
+∥∥-Idempotent-⊎ : {A : Type } {A′ : Type ℓ'}    A ∥₁   A′ ∥₁ ∥₁   A  A′ ∥₁
+∥∥-Idempotent-⊎ {A = A} {A′} =   A ∥₁   A′ ∥₁ ∥₁ ≡⟨ ∥∥-IdempotentR-⊎ 
+                                 A ∥₁  A′ ∥₁     ≡⟨ ∥∥-IdempotentL-⊎ 
+                                A  A′ ∥₁         
+
+∥∥-IdempotentL-×-≃ :   A ∥₁ × A′ ∥₁   A × A′ ∥₁
+∥∥-IdempotentL-×-≃ = isoToEquiv ∥∥-IdempotentL-×-Iso
+  where ∥∥-IdempotentL-×-Iso : Iso (  A ∥₁ × A′ ∥₁) ( A × A′ ∥₁)
+        Iso.fun ∥∥-IdempotentL-×-Iso x = rec squash₁ lem x
+          where lem :  A ∥₁ × A′   A × A′ ∥₁
+                lem (a , a′) = map2  a a′  a , a′) a  a′ ∣₁
+        Iso.inv ∥∥-IdempotentL-×-Iso x = map lem x
+          where lem : A × A′   A ∥₁ × A′
+                lem (a , a′) =  a ∣₁ , a′
+        Iso.rightInv ∥∥-IdempotentL-×-Iso x = squash₁ (Iso.fun ∥∥-IdempotentL-×-Iso (Iso.inv ∥∥-IdempotentL-×-Iso x)) x
+        Iso.leftInv ∥∥-IdempotentL-×-Iso x  = squash₁ (Iso.inv ∥∥-IdempotentL-×-Iso (Iso.fun ∥∥-IdempotentL-×-Iso x)) x
+
+∥∥-IdempotentL-× :   A ∥₁ × A′ ∥₁   A × A′ ∥₁
+∥∥-IdempotentL-× = ua ∥∥-IdempotentL-×-≃
+
+∥∥-IdempotentR-×-≃ :  A ×  A′ ∥₁ ∥₁   A × A′ ∥₁
+∥∥-IdempotentR-×-≃ = isoToEquiv ∥∥-IdempotentR-×-Iso
+  where ∥∥-IdempotentR-×-Iso : Iso ( A ×  A′ ∥₁ ∥₁) ( A × A′ ∥₁)
+        Iso.fun ∥∥-IdempotentR-×-Iso x = rec squash₁ lem x
+          where lem : A ×  A′ ∥₁   A × A′ ∥₁
+                lem (a , a′) = map2  a a′  a , a′)  a ∣₁ a′
+        Iso.inv ∥∥-IdempotentR-×-Iso x = map lem x
+          where lem : A × A′  A ×  A′ ∥₁
+                lem (a , a′) = a ,  a′ ∣₁
+        Iso.rightInv ∥∥-IdempotentR-×-Iso x = squash₁ (Iso.fun ∥∥-IdempotentR-×-Iso (Iso.inv ∥∥-IdempotentR-×-Iso x)) x
+        Iso.leftInv ∥∥-IdempotentR-×-Iso x  = squash₁ (Iso.inv ∥∥-IdempotentR-×-Iso (Iso.fun ∥∥-IdempotentR-×-Iso x)) x
+
+∥∥-IdempotentR-× :  A ×  A′ ∥₁ ∥₁   A × A′ ∥₁
+∥∥-IdempotentR-× = ua ∥∥-IdempotentR-×-≃
+
+∥∥-Idempotent-× : {A : Type } {A′ : Type ℓ'}    A ∥₁ ×  A′ ∥₁ ∥₁   A × A′ ∥₁
+∥∥-Idempotent-× {A = A} {A′} =   A ∥₁ ×  A′ ∥₁ ∥₁ ≡⟨ ∥∥-IdempotentR-× 
+                                 A ∥₁ × A′ ∥₁     ≡⟨ ∥∥-IdempotentL-× 
+                                A × A′ ∥₁         
+
+∥∥-Idempotent-×-≃ : {A : Type } {A′ : Type ℓ'}    A ∥₁ ×  A′ ∥₁ ∥₁   A × A′ ∥₁
+∥∥-Idempotent-×-≃ {A = A} {A′} = compEquiv ∥∥-IdempotentR-×-≃ ∥∥-IdempotentL-×-≃
+
+∥∥-×-≃ : {A : Type } {A′ : Type ℓ'}   A ∥₁ ×  A′ ∥₁   A × A′ ∥₁
+∥∥-×-≃ {A = A} {A′} = compEquiv (invEquiv (propTruncIdempotent≃ (isProp× isPropPropTrunc isPropPropTrunc))) ∥∥-Idempotent-×-≃
+
+∥∥-× : {A : Type } {A′ : Type ℓ'}   A ∥₁ ×  A′ ∥₁   A × A′ ∥₁
+∥∥-× = ua ∥∥-×-≃
+
+-- using this we get a convenient recursor/eliminator for binary functions into sets
+rec2→Set : {A B C : Type } (Cset : isSet C)
+          (f : A  B  C)
+          (∀ (a a' : A) (b b' : B)  f a b  f a' b')
+           A ∥₁   B ∥₁  C
+rec2→Set {A = A} {B = B} {C = C} Cset f fconst = curry (g  ∥∥-×-≃ .fst)
+ where
+ g :  A × B ∥₁  C
+ g = rec→Set Cset (uncurry f) λ x y  fconst (fst x) (fst y) (snd x) (snd y)
+
\ No newline at end of file diff --git a/docs/Cubical.HITs.PropositionalTruncation.html b/docs/Cubical.HITs.PropositionalTruncation.html new file mode 100644 index 0000000..30cfd97 --- /dev/null +++ b/docs/Cubical.HITs.PropositionalTruncation.html @@ -0,0 +1,9 @@ + +Cubical.HITs.PropositionalTruncation
{-# OPTIONS --safe #-}
+module Cubical.HITs.PropositionalTruncation where
+
+open import Cubical.HITs.PropositionalTruncation.Base public
+open import Cubical.HITs.PropositionalTruncation.Properties public
+
+open import Cubical.HITs.PropositionalTruncation.MagicTrick
+
\ No newline at end of file diff --git a/docs/Cubical.Homotopy.Base.html b/docs/Cubical.Homotopy.Base.html new file mode 100644 index 0000000..cf1cbc7 --- /dev/null +++ b/docs/Cubical.Homotopy.Base.html @@ -0,0 +1,21 @@ + +Cubical.Homotopy.Base
{-# OPTIONS --safe #-}
+
+module Cubical.Homotopy.Base where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Equiv.Properties
+
+private
+  variable
+     ℓ' : Level
+
+_∼_ : {X : Type } {Y : X  Type ℓ'}  (f g : (x : X)  Y x)  Type (ℓ-max  ℓ')
+_∼_ {X = X} f g = (x : X)  f x  g x
+
+funExt∼ : {X : Type } {Y : X  Type ℓ'} {f g : (x : X)  Y x} (H : f  g)  f  g
+funExt∼ = funExt
+
+∼-refl : {X : Type } {Y : X  Type ℓ'} {f : (x : X)  Y x}  f  f
+∼-refl {f = f} = λ x  refl {x = f x}
+
\ No newline at end of file diff --git a/docs/Cubical.Induction.WellFounded.html b/docs/Cubical.Induction.WellFounded.html new file mode 100644 index 0000000..98f35e4 --- /dev/null +++ b/docs/Cubical.Induction.WellFounded.html @@ -0,0 +1,49 @@ + +Cubical.Induction.WellFounded
{-# OPTIONS --safe #-}
+
+module Cubical.Induction.WellFounded where
+
+open import Cubical.Foundations.Prelude
+
+Rel : ∀{}  Type    ℓ'  Type _
+Rel A  = A  A  Type 
+
+module _ { ℓ'} {A : Type } (_<_ : A  A  Type ℓ') where
+  WFRec : ∀{ℓ''}  (A  Type ℓ'')  A  Type _
+  WFRec P x =  y  y < x  P y
+
+  data Acc (x : A) : Type (ℓ-max  ℓ') where
+    acc : WFRec Acc x  Acc x
+
+  WellFounded : Type _
+  WellFounded =  x  Acc x
+
+
+module _ { ℓ'} {A : Type } {_<_ : A  A  Type ℓ'} where
+  isPropAcc :  x  isProp (Acc _<_ x)
+  isPropAcc x (acc p) (acc q)
+    = λ i  acc  y y<x  isPropAcc y (p y y<x) (q y y<x) i)
+
+  access : ∀{x}  Acc _<_ x  WFRec _<_ (Acc _<_) x
+  access (acc r) = r
+
+  private
+    wfi : ∀{ℓ''} {P : A  Type ℓ''}
+          x  (wf : Acc _<_ x)
+         (∀ x  (∀ y  y < x  P y)  P x)
+         P x
+    wfi x (acc p) e = e x λ y y<x  wfi y (p y y<x) e
+
+  module WFI (wf : WellFounded _<_) where
+    module _ {ℓ''} {P : A  Type ℓ''} (e :  x  (∀ y  y < x  P y)  P x) where
+      private
+        wfi-compute :  x ax  wfi x ax e  e x  y _  wfi y (wf y) e)
+        wfi-compute x (acc p)
+          = λ i  e x  y y<x  wfi y (isPropAcc y (p y y<x) (wf y) i) e)
+
+      induction :   x  P x
+      induction x = wfi x (wf x) e
+
+      induction-compute :  x  induction x  (e x λ y _  induction y)
+      induction-compute x = wfi-compute x (wf x)
+
\ No newline at end of file diff --git a/docs/Cubical.Structures.Axioms.html b/docs/Cubical.Structures.Axioms.html new file mode 100644 index 0000000..09f7156 --- /dev/null +++ b/docs/Cubical.Structures.Axioms.html @@ -0,0 +1,71 @@ + +Cubical.Structures.Axioms
{-
+
+Add axioms (i.e., propositions) to a structure S without changing the definition of structured equivalence.
+
+X ↦ Σ[ s ∈ S X ] (P X s) where (P X s) is a proposition for all X and s.
+
+-}
+{-# OPTIONS --safe #-}
+module Cubical.Structures.Axioms where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Function
+open import Cubical.Foundations.HLevels
+open import Cubical.Foundations.Isomorphism
+open import Cubical.Foundations.Univalence
+open import Cubical.Foundations.Path
+open import Cubical.Foundations.SIP
+open import Cubical.Data.Sigma
+
+private
+  variable
+     ℓ₁ ℓ₁' ℓ₂ : Level
+
+AxiomsStructure : (S : Type   Type ℓ₁)
+  (axioms : (X : Type )  S X  Type ℓ₂)
+   Type   Type (ℓ-max ℓ₁ ℓ₂)
+AxiomsStructure S axioms X = Σ[ s  S X ] (axioms X s)
+
+AxiomsEquivStr : {S : Type   Type ℓ₁} (ι : StrEquiv S ℓ₁')
+  (axioms : (X : Type )  S X  Type ℓ₂)
+   StrEquiv (AxiomsStructure S axioms) ℓ₁'
+AxiomsEquivStr ι axioms (X , (s , a)) (Y , (t , b)) e = ι (X , s) (Y , t) e
+
+axiomsUnivalentStr : {S : Type   Type ℓ₁}
+  (ι : (A B : TypeWithStr  S)  A .fst  B .fst  Type ℓ₁')
+  {axioms : (X : Type )  S X  Type ℓ₂}
+  (axioms-are-Props : (X : Type ) (s : S X)  isProp (axioms X s))
+  (θ : UnivalentStr S ι)
+   UnivalentStr (AxiomsStructure S axioms) (AxiomsEquivStr ι axioms)
+axiomsUnivalentStr {S = S} ι {axioms = axioms} axioms-are-Props θ {X , s , a} {Y , t , b} e =
+  ι (X , s) (Y , t) e
+    ≃⟨ θ e 
+  PathP  i  S (ua e i)) s t
+    ≃⟨ invEquiv (Σ-contractSnd λ _  isOfHLevelPathP' 0 (axioms-are-Props _ _) _ _) 
+  Σ[ p  PathP  i  S (ua e i)) s t ] PathP  i  axioms (ua e i) (p i)) a b
+    ≃⟨ ΣPath≃PathΣ 
+  PathP  i  AxiomsStructure S axioms (ua e i)) (s , a) (t , b)
+  
+
+inducedStructure : {S : Type   Type ℓ₁}
+  {ι : (A B : TypeWithStr  S)  A .fst  B .fst  Type ℓ₁'}
+  (θ : UnivalentStr S ι)
+  {axioms : (X : Type )  S X  Type ℓ₂}
+  (A : TypeWithStr  (AxiomsStructure S axioms)) (B : TypeWithStr  S)
+   (typ A , str A .fst) ≃[ ι ] B
+   TypeWithStr  (AxiomsStructure S axioms)
+inducedStructure θ {axioms} A B eqv =
+  B .fst , B .snd , subst (uncurry axioms) (sip θ _ _ eqv) (A .snd .snd)
+
+transferAxioms : {S : Type   Type ℓ₁}
+  {ι : (A B : TypeWithStr  S)  A .fst  B .fst  Type ℓ₁'}
+  (θ : UnivalentStr S ι)
+  {axioms : (X : Type )  S X  Type ℓ₂}
+  (A : TypeWithStr  (AxiomsStructure S axioms)) (B : TypeWithStr  S)
+   (typ A , str A .fst) ≃[ ι ] B
+   axioms (fst B) (snd B)
+transferAxioms θ {axioms} A B eqv =
+  subst (uncurry axioms) (sip θ _ _ eqv) (A .snd .snd)
+
\ No newline at end of file diff --git a/docs/Cubical.Structures.Pointed.html b/docs/Cubical.Structures.Pointed.html new file mode 100644 index 0000000..c22c1bb --- /dev/null +++ b/docs/Cubical.Structures.Pointed.html @@ -0,0 +1,61 @@ + +Cubical.Structures.Pointed
{-
+
+Pointed structure: X ↦ X
+
+-}
+{-# OPTIONS --safe #-}
+module Cubical.Structures.Pointed where
+
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.Equiv
+open import Cubical.Foundations.Equiv.Properties
+open import Cubical.Foundations.Univalence
+open import Cubical.Foundations.SIP
+
+open import Cubical.Foundations.Pointed.Base
+
+private
+  variable
+     : Level
+
+-- Structured isomorphisms
+
+PointedStructure : Type   Type 
+PointedStructure X = X
+
+PointedEquivStr : StrEquiv PointedStructure 
+PointedEquivStr A B f = equivFun f (pt A)  pt B
+
+pointedUnivalentStr : UnivalentStr {} PointedStructure PointedEquivStr
+pointedUnivalentStr f = invEquiv (ua-ungluePath-Equiv f)
+
+pointedSIP : (A B : Pointed )  A ≃[ PointedEquivStr ] B  (A  B)
+pointedSIP = SIP pointedUnivalentStr
+
+pointed-sip : (A B : Pointed )  A ≃[ PointedEquivStr ] B  (A  B)
+pointed-sip A B = equivFun (pointedSIP A B) -- ≡ λ (e , p) i → ua e i , ua-gluePath e p i
+
+pointed-sip-idEquiv∙ : (A : Pointed )  pointed-sip A A (idEquiv∙ A)  refl
+fst (pointed-sip-idEquiv∙ A i j) = uaIdEquiv i j
+snd (pointed-sip-idEquiv∙ A i j) = glue {φ = i  ~ j  j}  _  pt A) (pt A)
+
+{-
+  The following terms have huge normal forms, so they are abstract to avoid
+  type checking speed problems, for example in
+
+    Cubical.Homotopy.HSpace
+-}
+abstract
+  pointed-sip⁻ : (A B : Pointed )  (A  B)  A ≃[ PointedEquivStr ] B
+  pointed-sip⁻ A B = invEq (pointedSIP A B)
+
+  pointed-sip⁻-refl : (A : Pointed )  pointed-sip⁻ A A refl  idEquiv∙ A
+  pointed-sip⁻-refl A = sym (invEq (equivAdjointEquiv (pointedSIP A A)) (pointed-sip-idEquiv∙ A))
+
+pointedEquivAction : EquivAction {} PointedStructure
+pointedEquivAction e = e
+
+pointedTransportStr : TransportStr {} pointedEquivAction
+pointedTransportStr e s = sym (transportRefl _)
+
\ No newline at end of file diff --git a/docs/Realizability.PartialApplicativeStructure.html b/docs/Realizability.PartialApplicativeStructure.html new file mode 100644 index 0000000..898be6e --- /dev/null +++ b/docs/Realizability.PartialApplicativeStructure.html @@ -0,0 +1,128 @@ + +Realizability.PartialApplicativeStructure
{-# OPTIONS --cubical --allow-unsolved-metas #-}
+open import Cubical.Core.Everything
+open import Cubical.Foundations.Prelude
+open import Cubical.Foundations.HLevels
+open import Cubical.Relation.Nullary
+open import Cubical.Data.Vec
+open import Cubical.Data.Nat
+open import Cubical.Data.Fin
+
+module Realizability.PartialApplicativeStructure {𝓢} where
+
+open import Realizability.Partiality {𝓢}
+open ♯_
+record PartialApplicativeStructure {} (A : Type ) : Type (ℓ-max  (ℓ-suc 𝓢)) where
+  field
+    isSetA : isSet A
+    _⨾_ : A  A   A
+
+module _ {} {A : Type } (pas : PartialApplicativeStructure A) where
+  open PartialApplicativeStructure pas
+  infix 22 `_
+  infix 23 _̇_
+  data Term :   Type  where
+    # :  {n}  Fin n  Term n
+    `_ : A  Term zero
+    _̇_ :  {n m}  Term m  Term n  Term (max m n)
+
+  foo :  a  Term 0
+  foo a = ` a
+
+  bar : Term 1
+  bar = # fzero
+
+  baz : Term 2
+  baz = (# {n = 1} fzero) ̇ (# {n = 2} fone)
+
+  baz' : Term 1
+  baz' = (# {n = 1} fzero) ̇ (# {n = 1} fzero)
+
+  isClosed :  {n}  Term n  Type
+  isClosed {n} _ = n  zero
+
+  isClosed-foo :  a  isClosed (foo a)
+  isClosed-foo a = refl
+
+  ClosedTerm : Type 
+  ClosedTerm = Term zero
+
+  infix 23 _↓_
+  data _↓_ : ClosedTerm  ClosedTerm  Type  where
+    ↓-refl :  a  (` a)  (` a)
+    ↓-appl :  {a b c s t}  s  (` b)  t  (` c)  (s ̇ t)  a
+             
+  infix 23 _denotes
+  _denotes : ClosedTerm  Type 
+  t denotes = Σ[ a  _ ] t  a
+
+  denotationOf :  {t}  t denotes  ClosedTerm
+  denotationOf {t} (a , _) = a
+
+  record _=_ (a b : ClosedTerm) : Type  where
+    field
+      a-denotes : a denotes
+      b-denotes : b denotes
+      denote-≡ : denotationOf a-denotes  denotationOf b-denotes
+
+
+  -- Handle the case for applications later
+  postulate substitute-app :  {m n}  Term m  Term n  Vec ( A) (max m n)   A
+
+  substitute :  {n}  Term n  Vec ( A) n   A
+  substitute (` a) _ = return a
+  substitute {n} (# k) subs = lookup (Fin→FinData n k) subs
+  substitute (a ̇ b) subs = substitute-app a b subs
+
+  -- Given an element a and a vector of elements (a₁ .. aₙ)
+  -- produces the application (a a₁ .. aₙ)
+  -- Note that application associates to the left
+  applicationChain :  {n}  A  Vec A n   A
+  applicationChain a [] = return a
+  applicationChain a (x  xs) = applicationChain' a (x  xs) (return a) where
+                                 applicationChain' :  {n}  A  Vec A n   A   A
+                                 applicationChain' _ [] acc = acc
+                                 applicationChain' a (x  xs) acc = applicationChain' x xs (acc >>= λ x  x  a)
+  
+  record isInterpreted {n} (t : Term n) : Type (ℓ-max  (ℓ-suc 𝓢)) where
+    field
+      interpretation : A
+      applicationChainSupported :  (subs : Vec A n)  applicationChain interpretation subs .support
+      naturality :  (subs : Vec A n)  applicationChain interpretation subs  substitute t (map return subs)
+
+  isCombinatoriallyComplete : Type (ℓ-max  (ℓ-suc 𝓢))
+  isCombinatoriallyComplete =  {n} (t : Term n)  isInterpreted t
+
+  -- Applying combinatorial completeness on this term will create the K combinator
+  -- Essentially this is
+  -- t(x₁ , x₂) = x₁ 
+  preK : Term 2
+  preK = # 0
+
+  -- As always, Agda is unable to solve constraints
+  -- So we must put {3} to tell Agda we are constructing
+  -- terms of order 3
+  -- Essentially this is
+  -- t(x₁ , x₂ , x₃) = (x₁ x₃) (x₂ x₃)
+  preS : Term 3
+  preS = ((# {3} 0) ̇ (# {3} 2)) ̇ ((# {3} 1) ̇ (# {3} 2))
+
+  -- A few elementary developments assuming combinatorial completeness
+  -- In particular, we can finally prove one side of Feferman's theorem
+  module _ (completeness : isCombinatoriallyComplete) where
+    open isInterpreted
+    K : A
+    K = completeness preK .interpretation
+
+    S : A
+    S = completeness preS .interpretation
+
+    Kab-supported :  a b  applicationChain K (a  b  []) .support
+    Kab-supported a b = completeness preK .applicationChainSupported (a  b  [])
+
+    Kab≈a :  a b  applicationChain K (a  b  [])  return a
+    Kab≈a a b = completeness preK .naturality (a  b  [])
+
+    Sabc≈ac_bc :  a b c  applicationChain S (a  b  c  [])  (substitute preS (map return (a  b  c  [])))
+    Sabc≈ac_bc a b c = completeness preS .naturality (a  b  c  [])
+
\ No newline at end of file diff --git a/docs/Realizability.PartialCombinatoryAlgebra.html b/docs/Realizability.PartialCombinatoryAlgebra.html index 7f5d76e..60d8bbf 100644 --- a/docs/Realizability.PartialCombinatoryAlgebra.html +++ b/docs/Realizability.PartialCombinatoryAlgebra.html @@ -1,17 +1,9 @@ -Realizability.PartialCombinatoryAlgebra
{-# OPTIONS --cubical #-}
-open import Cubical.Core.Everything
-open import Cubical.Foundations.Prelude
-open import Realizability.Partiality
-open import Realizability.BinaryApplicativeStructure
+Realizability.PartialCombinatoryAlgebra
{-# OPTIONS --cubical --allow-unsolved-metas #-}
+open import Cubical.Core.Everything
+open import Cubical.Foundations.Prelude
 
-module Realizability.PartialCombinatoryAlgebra where
+module Realizability.PartialCombinatoryAlgebra {𝓢} where
 
-record PartialCombinatoryAlgebra {} (A : Type ) (pas : PartialApplicativeStructure A) : Type  where
-  open PartialApplicativeStructure pas
-  field
-    s : A
-    k : A
-    kab≡a :  (a b :  A)  (η k) ̇ a ̇ b  a
-    sabc≡ac_bc :  a b c  (η s) ̇ a ̇ b ̇ c  (a ̇ c) ̇ (b ̇ c)
+open import Realizability.Partiality {𝓢}
 
\ No newline at end of file diff --git a/docs/Realizability.Partiality.html b/docs/Realizability.Partiality.html index 82c348c..feca9ed 100644 --- a/docs/Realizability.Partiality.html +++ b/docs/Realizability.Partiality.html @@ -3,150 +3,88 @@ open import Cubical.Core.Everything open import Cubical.Foundations.Prelude open import Cubical.Data.Nat -open import Cubical.Foundations.HLevels - -module Realizability.Partiality where - --- Mutual definition --- We use the partiality monad by arXiv:1610.09254v2 --- This is done by constructing the free ω-cpo --- over a type A using QIITs -data ♯_ {} (A : Type ) : Type -data _⊑_ {} {A : Type } : A A Type -data ♯_ A where - η : A A - : A - : (s : A) - (∀ n (s n) (s (suc n))) - A - α : x y - x y - y x - x y - setTrunc : isSet ( A) -data _⊑_ {} {A} where - ⊑-refl : x x x - ⊑-trans : x y z x y y z x z - ⊑-bottom : x x - ⊑-ub : s p (∀ n s n ( s p)) - ⊑-lub : s p x (∀ n s n x) ( s p) x - propTrunc : x y isProp(x y) - -infix 20 _⊑_ -infix 21 ♯_ - --- We now define the type of --- partiality algebras over a type A --- This is similar to, but slightly more complicated than --- the kind of F-(co)algebras that naturally come up when studying --- (co)induction. --- For lower inductive types, initiality and the elimination rules --- are rather trivial to establish. For higher inductive, or --- as it is, in our case, quotient inductive inductive types, --- the elimination rule is slightly more involved. --- We show that ♯ A is exactly the initial object --- in the category of partiality algebras over A --- This gives us the induction principle for ♯ A --- TODO : Complete construction -module _ {} (A : Type ) where - -- Also, side note, the universe levels start to get real ugly really quickly - record PartialityAlgebra {ℓ' ℓ''} (X : Type ℓ') (_⊑X_ : X X Type ℓ'') : Type (ℓ-max (ℓ-max ℓ' ℓ'') (ℓ-max ℓ')) where - field - -- data structure - isSetX : isSet X - isProp⊑ : x y isProp (x ⊑X y) - ηX : A X - ⊥X : X - ⨆X : (s : X) (∀ n (s n) ⊑X (s (suc n))) X - -- logical structure - -- Conjecture : being a partiality algebra is an hProp - -- TODO : Separate logical structure into separate record - αX : x y x ⊑X y y ⊑X x x y - ⊑X-refl : x x ⊑X x - ⊑X-trans : x y z x ⊑X y y ⊑X z x ⊑X z - ⊑X-bottom : x ⊥X ⊑X x - ⊑X-ub : (s : X) (p : (∀ n (s n) ⊑X (s (suc n)))) (n : ) (s n) ⊑X (⨆X s p) - ⊑X-lub : x (s : X) (p : (∀ n (s n) ⊑X (s (suc n)))) (∀ n s n ⊑X x) (⨆X s p) ⊑X x - - -- That's one ugly universe level - record PartialityAlgebraHomomorphism {𝔁 𝔂 𝔁' 𝔂'} {X : Type 𝔁} {_⊑X_ : X X Type 𝔁'} {Y : Type 𝔂} {_⊑Y_ : Y Y Type 𝔂'} (XAlgebra : PartialityAlgebra X _⊑X_) (YAlgebra : PartialityAlgebra Y _⊑Y_) : Type (ℓ-max (ℓ-max (ℓ-max 𝔁 ) 𝔂) (ℓ-max (ℓ-max 𝔁') 𝔂')) where - open PartialityAlgebra XAlgebra - open PartialityAlgebra YAlgebra renaming (⊥X to ⊥Y ; ηX to ηY ; ⨆X to ⨆Y) - field - map : X Y - monotone : x x' x ⊑X x' (map x) ⊑Y (map x') - ⊥-preserve : map ⊥X ⊥Y - η-preserve : a map (ηX a) ηY a - ⨆-preserve : (s : X) - (p : (∀ n (s n) ⊑X (s (suc n)))) - map (⨆X s p) ⨆Y n map (s n)) n monotone (s n) (s (suc n)) (p n)) - - open PartialityAlgebra - ♯A-PartialityAlgebra : PartialityAlgebra ( A) (_⊑_ {A = A}) - ♯A-PartialityAlgebra .isSetX = setTrunc - ♯A-PartialityAlgebra .isProp⊑ = propTrunc - ♯A-PartialityAlgebra .ηX = η - ♯A-PartialityAlgebra .⊥X = - ♯A-PartialityAlgebra .⨆X = - ♯A-PartialityAlgebra .αX = α - ♯A-PartialityAlgebra .⊑X-refl = ⊑-refl - ♯A-PartialityAlgebra .⊑X-trans = ⊑-trans - ♯A-PartialityAlgebra .⊑X-bottom = ⊑-bottom - ♯A-PartialityAlgebra .⊑X-ub = ⊑-ub - ♯A-PartialityAlgebra .⊑X-lub x s p = ⊑-lub s p x - - -- Initiality of ♯A - -- ♯A is the initial object in the category of - -- partiality algebras - -- Not only would it allow for much better and easier to read code - -- it is conceptually easier to manage - -- I'm sure both are equivalent formulations anyway - - record isInitial {𝔂 𝔂'} {Y : Type 𝔂} {_⊑Y_ : Y Y Type 𝔂'} (initial : PartialityAlgebra Y _⊑Y_) : Typeω where - field - morph : {𝔁 𝔁'} (X : Type 𝔁) (_⊑X_ : X X Type 𝔁') (object : PartialityAlgebra X _⊑X_) PartialityAlgebraHomomorphism initial object - uniqueness : {𝔁 𝔁'} (X : Type 𝔁) (_⊑X_ : X X Type 𝔁') (object : PartialityAlgebra X _⊑X_) isContr (PartialityAlgebraHomomorphism initial object) - - -- Conjecture : being initial is an hProp - open PartialityAlgebraHomomorphism - - module _ {𝔁 𝔁'} (X : Type 𝔁) (_⊑X_ : X X Type 𝔁') (object : PartialityAlgebra X _⊑X_) where - {-# TERMINATING #-} - ♯A-morphs : PartialityAlgebraHomomorphism ♯A-PartialityAlgebra object - ♯A-morphs .map (η a) = object .ηX a - ♯A-morphs .map = object .⊥X - ♯A-morphs .map ( s p) = object .⨆X n ♯A-morphs .map (s n)) λ n ♯A-morphs .monotone (s n) (s (suc n)) (p n) - ♯A-morphs .map (α x y x⊑y y⊑x i) = object .αX (♯A-morphs .map x) (♯A-morphs .map y) (♯A-morphs .monotone x y x⊑y) (♯A-morphs .monotone y x y⊑x) i - ♯A-morphs .map (setTrunc x y p q i j) = object .isSetX (♯A-morphs .map x) (♯A-morphs .map y) (cong (♯A-morphs .map) p) (cong (♯A-morphs .map) q) i j - ♯A-morphs .monotone x x (⊑-refl x) = object .⊑X-refl (♯A-morphs .map x) - ♯A-morphs .monotone x z (⊑-trans x y z x⊑y y⊑z) = object .⊑X-trans (♯A-morphs .map x) (♯A-morphs .map y) (♯A-morphs .map z) (♯A-morphs .monotone _ _ x⊑y) (♯A-morphs .monotone _ _ y⊑z) - ♯A-morphs .monotone _ x (⊑-bottom x) = object .⊑X-bottom (♯A-morphs .map x) - ♯A-morphs .monotone _ _ (⊑-ub s p index) = object .⊑X-ub n ♯A-morphs .map (s n)) n ♯A-morphs .monotone _ _ (p n)) index - ♯A-morphs .monotone _ _ (⊑-lub s p x fam) = object .⊑X-lub (♯A-morphs .map x) n ♯A-morphs .map (s n)) n ♯A-morphs .monotone _ _ (p n)) n ♯A-morphs .monotone _ _ (fam n)) - ♯A-morphs .monotone _ _ (propTrunc x y p q i) = object .isProp⊑ (♯A-morphs .map x) (♯A-morphs .map y) (♯A-morphs .monotone _ _ p) (♯A-morphs .monotone _ _ q) i - ♯A-morphs .⊥-preserve = refl - ♯A-morphs .η-preserve a = refl - ♯A-morphs .⨆-preserve s p = refl - - open isInitial - ♯A-isInitial : isInitial ♯A-PartialityAlgebra - ♯A-isInitial .morph = ♯A-morphs - ♯A-isInitial .uniqueness X _⊑X_ object .fst = ♯A-isInitial .morph X _⊑X_ object - ♯A-isInitial .uniqueness X _⊑X_ object .snd f = {!!} - - -_⇀_ : { ℓ'} Type Type ℓ' Type (ℓ-max ℓ') -A B = A B - --- Monadic operations -return : {} {A : Type } A A -return = η - --- Bind -_>>=_ : { ℓ'} {A : Type } {B : Type ℓ'} A (A B) B -(η a) >>= f = (f a) - >>= f = -( s p) >>= f = n (s n) >>= f) λ n {!!} -(α x y x⊑y y⊑x i) >>= f = α (x >>= f) (y >>= f) {!!} {!!} i -(setTrunc x y p q i j) >>= f = setTrunc (x >>= f) (y >>= f) (cong x x >>= f) p) (cong x x >>= f) q) i j +open import Cubical.Data.Unit +open import Cubical.Data.Sigma +open import Cubical.Foundations.HLevels +open import Cubical.Foundations.Function +open import Cubical.Foundations.Isomorphism +open import Cubical.Foundations.Univalence +open import Cubical.Foundations.Structure +open import Cubical.Foundations.SIP + +module Realizability.Partiality {𝓢} where + +infix 20 ♯_ + +record ♯_ {} (A : Type ) : Type (ℓ-max (ℓ-suc 𝓢)) where + field + support : Type 𝓢 + isProp-support : isProp support + force : support A + +open ♯_ + +return : {} {A : Type } A A +return a .support = Unit* +return a .isProp-support = isPropUnit* +return a .force _ = a + +infixl 21 _>>=_ +_>>=_ : {} {A B : Type } A (A B) B +(♯a >>= f) .support = Σ[ s (♯a .support) ] ((f (♯a .force s)) .support) +(♯a >>= f) .isProp-support = isPropΣ (♯a .isProp-support) λ x f (♯a .force x) .isProp-support +(♯a >>= f) .force (s , s') = f (♯a .force s) .force s' + +map-♯ : {} {A B : Type } (A B) ( A B) +map-♯ f ♯a .support = ♯a .support +map-♯ f ♯a .isProp-support = ♯a .isProp-support +map-♯ f ♯a .force s = f (♯a .force s) + +-- Goofy ahh universe necessary +-- for Agda to check +join : {} {A : Type (ℓ-max (ℓ-suc 𝓢))} A A +join {} {A} ♯♯a = ♯♯a >>= (idfun ( A)) + +♯-id : {} {A : Type } map-♯ (idfun A) (idfun ( A)) +♯-id = refl + +♯-∘ : {} {A B C : Type } (f : A B) (g : B C) map-♯ (g f) map-♯ g map-♯ f +♯-∘ f g = refl + +infixl 21 _>=>_ +_>=>_ : {} {A B C : Type } (A B) (B C) (A C) +(f >=> g) a = do + b f a + g b + +isTotal : {} {A B : Type } (f : A B) Type (ℓ-max 𝓢 ) +isTotal f = x (f x) .support + +range : {} {A B : Type } (f : A B) B Type (ℓ-max (ℓ-suc 𝓢)) +range {A = A} f b = ∃[ a A ] f a return b + +domain : {} {A B : Type } (f : A B) A Type _ +domain f a = (f a) .support + +record _≈_ {} {A : Type } (x y : A) : Type (ℓ-max (ℓ-suc 𝓢)) where + field + support-≃ : x .support y .support + force-≡ : x .force y .force (support-≃ .fst) +open _≈_ + +-- The proofs are ugly af +-- TODO : Refactor +return-left-identity : {} {A B : Type } (f : A B) (x : A) (return >=> f) x f x +return-left-identity f x .support-≃ = isoToEquiv (iso (tt* , support) support) support (tt* , support)) b refl) (tt* , support) refl)) +return-left-identity f x .force-≡ i (tt* , fx-support) = f x .force fx-support + +return-right-identity : {} {A B : Type } (f : A B) (x : A) (f >=> return) x f x +return-right-identity f x .support-≃ = isoToEquiv (iso (support , tt*) support) support (support , tt*)) b refl) λ (support , tt*) refl) +return-right-identity f x .force-≡ i (fx-support , tt*) = f x .force fx-support + +-- This is just the associativity of the (dependent) product +>=>-assoc : {} {A B C D : Type } (f : A B) (g : B C) (h : C D) (x : A) (f >=> g >=> h) x (f >=> (g >=> h)) x +>=>-assoc f g h x .support-≃ = isoToEquiv (iso ((fx-support , g-fx-forces-support) , hgfx-support) fx-support , (g-fx-forces-support , hgfx-support)) (fx-support , (g-fx-forces-support , hgfx-support)) (fx-support , g-fx-forces-support) , hgfx-support) b refl) λ a refl) +>=>-assoc f g h x .force-≡ i ((fx-support , gfx-support) , hgfx-support) = (h ((g ((f x) .force fx-support)) .force gfx-support)) .force hgfx-support +
\ No newline at end of file diff --git a/docs/index.html b/docs/index.html index e1f08dc..5bcb7a9 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3,6 +3,6 @@ module index where open import Realizability.Partiality -open import Realizability.BinaryApplicativeStructure -open import Realizability.PartialCombinatoryAlgebra +open import Realizability.PartialApplicativeStructure +open import Realizability.PartialCombinatoryAlgebra \ No newline at end of file diff --git a/src/Realizability/BinaryApplicativeStructure.agda b/src/Realizability/BinaryApplicativeStructure.agda deleted file mode 100644 index c0af7a0..0000000 --- a/src/Realizability/BinaryApplicativeStructure.agda +++ /dev/null @@ -1,26 +0,0 @@ -{-# OPTIONS --cubical #-} -open import Cubical.Core.Everything -open import Cubical.Foundations.Prelude -open import Cubical.Foundations.Structure -open import Realizability.Partiality - -module Realizability.BinaryApplicativeStructure where - -record PartialApplicativeStructure {ℓ} (A : Type ℓ) : Type ℓ where - infixl 25 _̇_ - field - _̇_ : ♯ A → ♯ A → ♯ A - - -module _ {ℓ} {A : Type ℓ} (pas : PartialApplicativeStructure A) where - foo : A → ♯ A - foo a = do - return a - - bar : ∀ {B : Type ℓ} → A → (A → ♯ B) → ♯ B - bar a f = do - answer ← f a - return answer - - - diff --git a/src/Realizability/PartialApplicativeStructure.agda b/src/Realizability/PartialApplicativeStructure.agda new file mode 100644 index 0000000..d4686e1 --- /dev/null +++ b/src/Realizability/PartialApplicativeStructure.agda @@ -0,0 +1,126 @@ +{-# OPTIONS --cubical --allow-unsolved-metas #-} +open import Cubical.Core.Everything +open import Cubical.Foundations.Prelude +open import Cubical.Foundations.HLevels +open import Cubical.Relation.Nullary +open import Cubical.Data.Vec +open import Cubical.Data.Nat +open import Cubical.Data.Fin + +module Realizability.PartialApplicativeStructure {𝓢} where + +open import Realizability.Partiality {𝓢} +open ♯_ +record PartialApplicativeStructure {ℓ} (A : Type ℓ) : Type (ℓ-max ℓ (ℓ-suc 𝓢)) where + field + isSetA : isSet A + _⨾_ : A → A → ♯ A + +module _ {ℓ} {A : Type ℓ} (pas : PartialApplicativeStructure A) where + open PartialApplicativeStructure pas + infix 22 `_ + infix 23 _̇_ + data Term : ℕ → Type ℓ where + # : ∀ {n} → Fin n → Term n + `_ : A → Term zero + _̇_ : ∀ {n m} → Term m → Term n → Term (max m n) + + foo : ∀ a → Term 0 + foo a = ` a + + bar : Term 1 + bar = # fzero + + baz : Term 2 + baz = (# {n = 1} fzero) ̇ (# {n = 2} fone) + + baz' : Term 1 + baz' = (# {n = 1} fzero) ̇ (# {n = 1} fzero) + + isClosed : ∀ {n} → Term n → Type + isClosed {n} _ = n ≡ zero + + isClosed-foo : ∀ a → isClosed (foo a) + isClosed-foo a = refl + + ClosedTerm : Type ℓ + ClosedTerm = Term zero + + infix 23 _↓_ + data _↓_ : ClosedTerm → ClosedTerm → Type ℓ where + ↓-refl : ∀ a → (` a) ↓ (` a) + ↓-appl : ∀ {a b c s t} → s ↓ (` b) → t ↓ (` c) → (s ̇ t) ↓ a + + infix 23 _denotes + _denotes : ClosedTerm → Type ℓ + t denotes = Σ[ a ∈ _ ] t ↓ a + + denotationOf : ∀ {t} → t denotes → ClosedTerm + denotationOf {t} (a , _) = a + + record _=_ (a b : ClosedTerm) : Type ℓ where + field + a-denotes : a denotes + b-denotes : b denotes + denote-≡ : denotationOf a-denotes ≡ denotationOf b-denotes + + + -- Handle the case for applications later + postulate substitute-app : ∀ {m n} → Term m → Term n → Vec (♯ A) (max m n) → ♯ A + + substitute : ∀ {n} → Term n → Vec (♯ A) n → ♯ A + substitute (` a) _ = return a + substitute {n} (# k) subs = lookup (Fin→FinData n k) subs + substitute (a ̇ b) subs = substitute-app a b subs + + -- Given an element a and a vector of elements (a₁ .. aₙ) + -- produces the application (a a₁ .. aₙ) + -- Note that application associates to the left + applicationChain : ∀ {n} → A → Vec A n → ♯ A + applicationChain a [] = return a + applicationChain a (x ∷ xs) = applicationChain' a (x ∷ xs) (return a) where + applicationChain' : ∀ {n} → A → Vec A n → ♯ A → ♯ A + applicationChain' _ [] acc = acc + applicationChain' a (x ∷ xs) acc = applicationChain' x xs (acc >>= λ x → x ⨾ a) + + record isInterpreted {n} (t : Term n) : Type (ℓ-max ℓ (ℓ-suc 𝓢)) where + field + interpretation : A + applicationChainSupported : ∀ (subs : Vec A n) → applicationChain interpretation subs .support + naturality : ∀ (subs : Vec A n) → applicationChain interpretation subs ≈ substitute t (map return subs) + + isCombinatoriallyComplete : Type (ℓ-max ℓ (ℓ-suc 𝓢)) + isCombinatoriallyComplete = ∀ {n} (t : Term n) → isInterpreted t + + -- Applying combinatorial completeness on this term will create the K combinator + -- Essentially this is + -- t(x₁ , x₂) = x₁ + preK : Term 2 + preK = # 0 + + -- As always, Agda is unable to solve constraints + -- So we must put {3} to tell Agda we are constructing + -- terms of order 3 + -- Essentially this is + -- t(x₁ , x₂ , x₃) = (x₁ x₃) (x₂ x₃) + preS : Term 3 + preS = ((# {3} 0) ̇ (# {3} 2)) ̇ ((# {3} 1) ̇ (# {3} 2)) + + -- A few elementary developments assuming combinatorial completeness + -- In particular, we can finally prove one side of Feferman's theorem + module _ (completeness : isCombinatoriallyComplete) where + open isInterpreted + K : A + K = completeness preK .interpretation + + S : A + S = completeness preS .interpretation + + Kab-supported : ∀ a b → applicationChain K (a ∷ b ∷ []) .support + Kab-supported a b = completeness preK .applicationChainSupported (a ∷ b ∷ []) + + Kab≈a : ∀ a b → applicationChain K (a ∷ b ∷ []) ≈ return a + Kab≈a a b = completeness preK .naturality (a ∷ b ∷ []) + + Sabc≈ac_bc : ∀ a b c → applicationChain S (a ∷ b ∷ c ∷ []) ≈ (substitute preS (map return (a ∷ b ∷ c ∷ []))) + Sabc≈ac_bc a b c = completeness preS .naturality (a ∷ b ∷ c ∷ []) diff --git a/src/Realizability/PartialCombinatoryAlgebra.agda b/src/Realizability/PartialCombinatoryAlgebra.agda index 2da4961..7465147 100644 --- a/src/Realizability/PartialCombinatoryAlgebra.agda +++ b/src/Realizability/PartialCombinatoryAlgebra.agda @@ -1,15 +1,7 @@ -{-# OPTIONS --cubical #-} +{-# OPTIONS --cubical --allow-unsolved-metas #-} open import Cubical.Core.Everything open import Cubical.Foundations.Prelude -open import Realizability.Partiality -open import Realizability.BinaryApplicativeStructure -module Realizability.PartialCombinatoryAlgebra where +module Realizability.PartialCombinatoryAlgebra {𝓢} where -record PartialCombinatoryAlgebra {ℓ} (A : Type ℓ) (pas : PartialApplicativeStructure A) : Type ℓ where - open PartialApplicativeStructure pas - field - s : A - k : A - kab≡a : ∀ (a b : ♯ A) → (η k) ̇ a ̇ b ≡ a - sabc≡ac_bc : ∀ a b c → (η s) ̇ a ̇ b ̇ c ≡ (a ̇ c) ̇ (b ̇ c) +open import Realizability.Partiality {𝓢} diff --git a/src/Realizability/Partiality.agda b/src/Realizability/Partiality.agda index 35f102e..b75b6e1 100644 --- a/src/Realizability/Partiality.agda +++ b/src/Realizability/Partiality.agda @@ -2,149 +2,87 @@ open import Cubical.Core.Everything open import Cubical.Foundations.Prelude open import Cubical.Data.Nat +open import Cubical.Data.Unit +open import Cubical.Data.Sigma open import Cubical.Foundations.HLevels +open import Cubical.Foundations.Function +open import Cubical.Foundations.Isomorphism +open import Cubical.Foundations.Univalence +open import Cubical.Foundations.Structure +open import Cubical.Foundations.SIP + +module Realizability.Partiality {𝓢} where + +infix 20 ♯_ + +record ♯_ {ℓ} (A : Type ℓ) : Type (ℓ-max ℓ (ℓ-suc 𝓢)) where + field + support : Type 𝓢 + isProp-support : isProp support + force : support → A + +open ♯_ + +return : ∀ {ℓ} {A : Type ℓ} → A → ♯ A +return a .support = Unit* +return a .isProp-support = isPropUnit* +return a .force _ = a + +infixl 21 _>>=_ +_>>=_ : ∀ {ℓ} {A B : Type ℓ} → ♯ A → (A → ♯ B) → ♯ B +(♯a >>= f) .support = Σ[ s ∈ (♯a .support) ] ((f (♯a .force s)) .support) +(♯a >>= f) .isProp-support = isPropΣ (♯a .isProp-support) λ x → f (♯a .force x) .isProp-support +(♯a >>= f) .force (s , s') = f (♯a .force s) .force s' + +map-♯ : ∀ {ℓ} {A B : Type ℓ} → (A → B) → (♯ A → ♯ B) +map-♯ f ♯a .support = ♯a .support +map-♯ f ♯a .isProp-support = ♯a .isProp-support +map-♯ f ♯a .force s = f (♯a .force s) + +-- Goofy ahh universe necessary +-- for Agda to check +join : ∀ {ℓ} {A : Type (ℓ-max ℓ (ℓ-suc 𝓢))} → ♯ ♯ A → ♯ A +join {ℓ} {A} ♯♯a = ♯♯a >>= (idfun (♯ A)) + +♯-id : ∀ {ℓ} {A : Type ℓ} → map-♯ (idfun A) ≡ (idfun (♯ A)) +♯-id = refl + +♯-∘ : ∀ {ℓ} {A B C : Type ℓ} → (f : A → B) → (g : B → C) → map-♯ (g ∘ f) ≡ map-♯ g ∘ map-♯ f +♯-∘ f g = refl + +infixl 21 _>=>_ +_>=>_ : ∀ {ℓ} {A B C : Type ℓ} → (A → ♯ B) → (B → ♯ C) → (A → ♯ C) +(f >=> g) a = do + b ← f a + g b + +isTotal : ∀ {ℓ} {A B : Type ℓ} → (f : A → ♯ B) → Type (ℓ-max 𝓢 ℓ) +isTotal f = ∀ x → (f x) .support + +range : ∀ {ℓ} {A B : Type ℓ} → (f : A → ♯ B) → B → Type (ℓ-max ℓ (ℓ-suc 𝓢)) +range {A = A} f b = ∃[ a ∈ A ] f a ≡ return b + +domain : ∀ {ℓ} {A B : Type ℓ} → (f : A → ♯ B) → A → Type _ +domain f a = (f a) .support + +record _≈_ {ℓ} {A : Type ℓ} (x y : ♯ A) : Type (ℓ-max ℓ (ℓ-suc 𝓢)) where + field + support-≃ : x .support ≃ y .support + force-≡ : x .force ≡ y .force ∘ (support-≃ .fst) +open _≈_ + +-- The proofs are ugly af +-- TODO : Refactor +return-left-identity : ∀ {ℓ} {A B : Type ℓ} (f : A → ♯ B) (x : A) → (return >=> f) x ≈ f x +return-left-identity f x .support-≃ = isoToEquiv (iso (λ (tt* , support) → support) (λ support → (tt* , support)) (λ b → refl) (λ (tt* , support) → refl)) +return-left-identity f x .force-≡ i (tt* , fx-support) = f x .force fx-support + +return-right-identity : ∀ {ℓ} {A B : Type ℓ} (f : A → ♯ B) (x : A) → (f >=> return) x ≈ f x +return-right-identity f x .support-≃ = isoToEquiv (iso (λ (support , tt*) → support) (λ support → (support , tt*)) (λ b → refl) λ (support , tt*) → refl) +return-right-identity f x .force-≡ i (fx-support , tt*) = f x .force fx-support + +-- This is just the associativity of the (dependent) product +>=>-assoc : ∀ {ℓ} {A B C D : Type ℓ} (f : A → ♯ B) (g : B → ♯ C) (h : C → ♯ D) (x : A) → (f >=> g >=> h) x ≈ (f >=> (g >=> h)) x +>=>-assoc f g h x .support-≃ = isoToEquiv (iso (λ ((fx-support , g-fx-forces-support) , hgfx-support) → fx-support , (g-fx-forces-support , hgfx-support)) (λ (fx-support , (g-fx-forces-support , hgfx-support)) → (fx-support , g-fx-forces-support) , hgfx-support) (λ b → refl) λ a → refl) +>=>-assoc f g h x .force-≡ i ((fx-support , gfx-support) , hgfx-support) = (h ((g ((f x) .force fx-support)) .force gfx-support)) .force hgfx-support -module Realizability.Partiality where - --- Mutual definition --- We use the partiality monad by arXiv:1610.09254v2 --- This is done by constructing the free ω-cpo --- over a type A using QIITs -data ♯_ {ℓ} (A : Type ℓ) : Type ℓ -data _⊑_ {ℓ} {A : Type ℓ} : ♯ A → ♯ A → Type ℓ -data ♯_ A where - η : A → ♯ A - ⊥ : ♯ A - ⨆ : (s : ℕ → ♯ A) - → (∀ n → (s n) ⊑ (s (suc n))) - → ♯ A - α : ∀ x y - → x ⊑ y - → y ⊑ x - → x ≡ y - setTrunc : isSet (♯ A) -data _⊑_ {ℓ} {A} where - ⊑-refl : ∀ x → x ⊑ x - ⊑-trans : ∀ x y z → x ⊑ y → y ⊑ z → x ⊑ z - ⊑-bottom : ∀ x → ⊥ ⊑ x - ⊑-ub : ∀ s p → (∀ n → s n ⊑ (⨆ s p)) - ⊑-lub : ∀ s p x → (∀ n → s n ⊑ x) → (⨆ s p) ⊑ x - propTrunc : ∀ x y → isProp(x ⊑ y) - -infix 20 _⊑_ -infix 21 ♯_ - --- We now define the type of --- partiality algebras over a type A --- This is similar to, but slightly more complicated than --- the kind of F-(co)algebras that naturally come up when studying --- (co)induction. --- For lower inductive types, initiality and the elimination rules --- are rather trivial to establish. For higher inductive, or --- as it is, in our case, quotient inductive inductive types, --- the elimination rule is slightly more involved. --- We show that ♯ A is exactly the initial object --- in the category of partiality algebras over A --- This gives us the induction principle for ♯ A --- TODO : Complete construction -module _ {ℓ} (A : Type ℓ) where - -- Also, side note, the universe levels start to get real ugly really quickly - record PartialityAlgebra {ℓ' ℓ''} (X : Type ℓ') (_⊑X_ : X → X → Type ℓ'') : Type (ℓ-max (ℓ-max ℓ' ℓ'') (ℓ-max ℓ ℓ')) where - field - -- data structure - isSetX : isSet X - isProp⊑ : ∀ x y → isProp (x ⊑X y) - ηX : A → X - ⊥X : X - ⨆X : (s : ℕ → X) → (∀ n → (s n) ⊑X (s (suc n))) → X - -- logical structure - -- Conjecture : being a partiality algebra is an hProp - -- TODO : Separate logical structure into separate record - αX : ∀ x y → x ⊑X y → y ⊑X x → x ≡ y - ⊑X-refl : ∀ x → x ⊑X x - ⊑X-trans : ∀ x y z → x ⊑X y → y ⊑X z → x ⊑X z - ⊑X-bottom : ∀ x → ⊥X ⊑X x - ⊑X-ub : (s : ℕ → X) → (p : (∀ n → (s n) ⊑X (s (suc n)))) → (n : ℕ) → (s n) ⊑X (⨆X s p) - ⊑X-lub : ∀ x → (s : ℕ → X) → (p : (∀ n → (s n) ⊑X (s (suc n)))) → (∀ n → s n ⊑X x) → (⨆X s p) ⊑X x - - -- That's one ugly universe level - record PartialityAlgebraHomomorphism {𝔁 𝔂 𝔁' 𝔂'} {X : Type 𝔁} {_⊑X_ : X → X → Type 𝔁'} {Y : Type 𝔂} {_⊑Y_ : Y → Y → Type 𝔂'} (XAlgebra : PartialityAlgebra X _⊑X_) (YAlgebra : PartialityAlgebra Y _⊑Y_) : Type (ℓ-max (ℓ-max (ℓ-max 𝔁 ℓ) 𝔂) (ℓ-max (ℓ-max ℓ 𝔁') 𝔂')) where - open PartialityAlgebra XAlgebra - open PartialityAlgebra YAlgebra renaming (⊥X to ⊥Y ; ηX to ηY ; ⨆X to ⨆Y) - field - map : X → Y - monotone : ∀ x x' → x ⊑X x' → (map x) ⊑Y (map x') - ⊥-preserve : map ⊥X ≡ ⊥Y - η-preserve : ∀ a → map (ηX a) ≡ ηY a - ⨆-preserve : (s : ℕ → X) - → (p : (∀ n → (s n) ⊑X (s (suc n)))) - → map (⨆X s p) ≡ ⨆Y (λ n → map (s n)) (λ n → monotone (s n) (s (suc n)) (p n)) - - open PartialityAlgebra - ♯A-PartialityAlgebra : PartialityAlgebra (♯ A) (_⊑_ {A = A}) - ♯A-PartialityAlgebra .isSetX = setTrunc - ♯A-PartialityAlgebra .isProp⊑ = propTrunc - ♯A-PartialityAlgebra .ηX = η - ♯A-PartialityAlgebra .⊥X = ⊥ - ♯A-PartialityAlgebra .⨆X = ⨆ - ♯A-PartialityAlgebra .αX = α - ♯A-PartialityAlgebra .⊑X-refl = ⊑-refl - ♯A-PartialityAlgebra .⊑X-trans = ⊑-trans - ♯A-PartialityAlgebra .⊑X-bottom = ⊑-bottom - ♯A-PartialityAlgebra .⊑X-ub = ⊑-ub - ♯A-PartialityAlgebra .⊑X-lub x s p = ⊑-lub s p x - - -- Initiality of ♯A - -- ♯A is the initial object in the category of - -- partiality algebras - -- Not only would it allow for much better and easier to read code - -- it is conceptually easier to manage - -- I'm sure both are equivalent formulations anyway - - record isInitial {𝔂 𝔂'} {Y : Type 𝔂} {_⊑Y_ : Y → Y → Type 𝔂'} (initial : PartialityAlgebra Y _⊑Y_) : Typeω where - field - morph : ∀ {𝔁 𝔁'} → (X : Type 𝔁) → (_⊑X_ : X → X → Type 𝔁') → (object : PartialityAlgebra X _⊑X_) → PartialityAlgebraHomomorphism initial object - uniqueness : ∀ {𝔁 𝔁'} → (X : Type 𝔁) → (_⊑X_ : X → X → Type 𝔁') → (object : PartialityAlgebra X _⊑X_) → isContr (PartialityAlgebraHomomorphism initial object) - - -- Conjecture : being initial is an hProp - open PartialityAlgebraHomomorphism - - module _ {𝔁 𝔁'} (X : Type 𝔁) (_⊑X_ : X → X → Type 𝔁') (object : PartialityAlgebra X _⊑X_) where - {-# TERMINATING #-} - ♯A-morphs : PartialityAlgebraHomomorphism ♯A-PartialityAlgebra object - ♯A-morphs .map (η a) = object .ηX a - ♯A-morphs .map ⊥ = object .⊥X - ♯A-morphs .map (⨆ s p) = object .⨆X (λ n → ♯A-morphs .map (s n)) λ n → ♯A-morphs .monotone (s n) (s (suc n)) (p n) - ♯A-morphs .map (α x y x⊑y y⊑x i) = object .αX (♯A-morphs .map x) (♯A-morphs .map y) (♯A-morphs .monotone x y x⊑y) (♯A-morphs .monotone y x y⊑x) i - ♯A-morphs .map (setTrunc x y p q i j) = object .isSetX (♯A-morphs .map x) (♯A-morphs .map y) (cong (♯A-morphs .map) p) (cong (♯A-morphs .map) q) i j - ♯A-morphs .monotone x x (⊑-refl x) = object .⊑X-refl (♯A-morphs .map x) - ♯A-morphs .monotone x z (⊑-trans x y z x⊑y y⊑z) = object .⊑X-trans (♯A-morphs .map x) (♯A-morphs .map y) (♯A-morphs .map z) (♯A-morphs .monotone _ _ x⊑y) (♯A-morphs .monotone _ _ y⊑z) - ♯A-morphs .monotone _ x (⊑-bottom x) = object .⊑X-bottom (♯A-morphs .map x) - ♯A-morphs .monotone _ _ (⊑-ub s p index) = object .⊑X-ub (λ n → ♯A-morphs .map (s n)) (λ n → ♯A-morphs .monotone _ _ (p n)) index - ♯A-morphs .monotone _ _ (⊑-lub s p x fam) = object .⊑X-lub (♯A-morphs .map x) (λ n → ♯A-morphs .map (s n)) (λ n → ♯A-morphs .monotone _ _ (p n)) (λ n → ♯A-morphs .monotone _ _ (fam n)) - ♯A-morphs .monotone _ _ (propTrunc x y p q i) = object .isProp⊑ (♯A-morphs .map x) (♯A-morphs .map y) (♯A-morphs .monotone _ _ p) (♯A-morphs .monotone _ _ q) i - ♯A-morphs .⊥-preserve = refl - ♯A-morphs .η-preserve a = refl - ♯A-morphs .⨆-preserve s p = refl - - open isInitial - ♯A-isInitial : isInitial ♯A-PartialityAlgebra - ♯A-isInitial .morph = ♯A-morphs - ♯A-isInitial .uniqueness X _⊑X_ object .fst = ♯A-isInitial .morph X _⊑X_ object - ♯A-isInitial .uniqueness X _⊑X_ object .snd f = {!!} - - -_⇀_ : ∀ {ℓ ℓ'} → Type ℓ → Type ℓ' → Type (ℓ-max ℓ ℓ') -A ⇀ B = A → ♯ B - --- Monadic operations -return : ∀ {ℓ} → {A : Type ℓ} → A → ♯ A -return = η - --- Bind -_>>=_ : ∀ {ℓ ℓ'} → {A : Type ℓ} {B : Type ℓ'} → ♯ A → (A → ♯ B) → ♯ B -(η a) >>= f = (f a) -⊥ >>= f = ⊥ -(⨆ s p) >>= f = ⨆ (λ n → (s n) >>= f) λ n → {!!} -(α x y x⊑y y⊑x i) >>= f = α (x >>= f) (y >>= f) {!!} {!!} i -(setTrunc x y p q i j) >>= f = setTrunc (x >>= f) (y >>= f) (cong (λ x → x >>= f) p) (cong (λ x → x >>= f) q) i j diff --git a/src/index.agda b/src/index.agda index 5efc299..2680761 100644 --- a/src/index.agda +++ b/src/index.agda @@ -2,5 +2,5 @@ module index where open import Realizability.Partiality -open import Realizability.BinaryApplicativeStructure +open import Realizability.PartialApplicativeStructure open import Realizability.PartialCombinatoryAlgebra