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

-- The Category of Algebraic Kan Complexes
module Categories.Category.Instance.KanComplexes where

open import Level

open import Function using (_$_)
open import Data.Product using (Σ; _,_; proj₁)

open import Categories.Category
open import Categories.Category.SubCategory
open import Categories.Category.Construction.KanComplex
open import Categories.Category.Instance.SimplicialSet


import Categories.Category.Instance.SimplicialSet.Properties as ΔSetₚ

import Categories.Morphism.Reasoning as MR

module _ (o  : Level) where
  open Category (SimplicialSet o )
  open ΔSetₚ o 
  open IsKanComplex
  open Equiv
  open MR (SimplicialSet o )
  
  -- As we are working with Algebraic Kan Complexes, maps between two Kan Complexes ought
  -- to take the chosen filler in 'X' to the chosen filler in 'Y'.
  PreservesFiller :  {X Y : ΔSet}  IsKanComplex o  X  IsKanComplex o  Y  (X  Y)  Set (o  )
  PreservesFiller {X} {Y} X-Kan Y-Kan f =  {n} {k}  (i : Λ[ n , k ]  X)  (f  filler X-Kan {n} i)  filler Y-Kan (f  i)  

  KanComplexes : Category (suc o  suc ) (o    (o  )) (o  )
  KanComplexes = SubCategory (SimplicialSet o ) {I = Σ ΔSet (IsKanComplex o )} $ record
    { U = proj₁
    ; R = λ { {_ , X-Kan} {_ , Y-Kan} f  PreservesFiller X-Kan Y-Kan f }
    ; Rid = λ { {_ , X-Kan} i  begin
        id  filler X-Kan i   ≈⟨ identityˡ {f = filler X-Kan i} 
        filler X-Kan i        ≈˘⟨ filler-cong X-Kan (identityˡ {f = i}) 
        filler X-Kan (id  i) 
      }
    ; _∘R_ = λ { {_ , X-Kan} {_ , Y-Kan} {_ , Z-Kan} {f} {g} f-preserves g-preserves i  begin
        (f  g)  filler X-Kan i ≈⟨ assoc {f = filler X-Kan i} {g = g} {h = f} 
        f  (g  filler X-Kan i) ≈⟨ ∘-resp-≈ʳ {f = (g  filler X-Kan i)} {h = filler Y-Kan (g  i)} {g = f} (g-preserves i) 
        f  filler Y-Kan (g  i) ≈⟨ f-preserves (g  i) 
        filler Z-Kan (f  g  i) ≈˘⟨ filler-cong Z-Kan (assoc {f = i} {g = g} {h = f}) 
        filler Z-Kan ((f  g)  i) 
      }
    }
    where
      open HomReasoning