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


open import Level

-- Kan Complexes
--
-- These are technically "Algebraic" Kan Complexes, as they come with a choice of fillers
-- However, this notion is far easier than the more geometric flavor,
-- as we can sidestep questions about choice.

module Categories.Category.Construction.KanComplex (o  : Level) where

open import Data.Nat using ()
open import Data.Fin using (Fin; inject₁)

open import Categories.Category using (Category)

open import Categories.Category.Instance.SimplicialSet using (SimplicialSet)
open import Categories.Category.Instance.SimplicialSet.Properties o  using (ΔSet; Δ[_]; Λ[_,_]; Λ-inj)

open Category (SimplicialSet o )

-- A Kan complex is a simplicial set where every k-horn has a filler.
record IsKanComplex (X : ΔSet) : Set (o  ) where
  field
    filler      :  {n} {k}  Λ[ n , k ]  X  Δ[ n ]  X
    filler-cong :  {n} {k}  {f g : Λ[ n , k ]  X}  f  g  filler {n} f  filler g
    is-filler   :  {n} {k}  (f : Λ[ n , k ]  X)  filler f  Λ-inj k  f

-- 'inner k' will embed 'k : Fin n' into the "inner" portion of 'Fin (n + 2)'
-- Visually, it looks a little something like:
-- 
--   * * *
--   | | | 
--   v v v
-- * * * * *
-- 
-- Note that this is set up in such a way that we can normalize
-- as far as possible without pattern matching on 'i' in proofs.
inner :  {n}  Fin n  Fin (ℕ.suc (ℕ.suc n))
inner i = Fin.suc (inject₁ i)

-- A Weak Kan complex is similar to a Kan Complex, but where only "inner horns" have fillers.
--
-- The indexing here is tricky, but it lets us avoid extra proof conditions that the horn is an inner horn.
-- The basic idea is that if we want an n-dimensional inner horn, then we only want to allow the faces {1,2,3...n-1}
-- to be missing. We could do this by requiring proofs that the missing face is greater than 0 and less than n, but
-- this makes working with the definition _extremely_ difficult.
--
-- To avoid this, we only allow an missing face index that ranges from 0 to n-2, and then embed that index
-- into the full range of face indexes via 'inner'. This does require us to shift our indexes around a bit.
-- To make this indexing more obvious, we use the suggestively named variable 'n-2'.
record IsWeakKanComplex (X : ΔSet) : Set (o  ) where
  field
    filler      :  {n-2} {k : Fin n-2}  Λ[ ℕ.suc (ℕ.suc n-2) , inner k ]  X  Δ[ ℕ.suc (ℕ.suc n-2) ]  X
    filler-cong :  {n-2} {k : Fin n-2}  {f g : Λ[ ℕ.suc (ℕ.suc n-2) , inner k ]  X}  f  g  filler f  filler g
    is-filler   :  {n-2} {k : Fin n-2}  (f : Λ[ ℕ.suc (ℕ.suc n-2) , inner k ]  X)  filler f  Λ-inj (inner k)  f

KanComplex⇒WeakKanComplex :  {X}  IsKanComplex X  IsWeakKanComplex X
KanComplex⇒WeakKanComplex complex = record { IsKanComplex complex }