module QWI.SizeIndexedStructure where

open import QWI.ColimitsOfSizedIndexedDiagrams public

----------------------------------------------------------------------
-- Size-indexed structures for an indexed signature Σ (3.26)
-- and system of equations ε (3.31)
----------------------------------------------------------------------
module SizeIdxStruct
  {l : Level}
  (I : Set l)
  (Σ : Slice.Sig I)
  (ε : Slice.Syseq I Σ)
  -- We give the definition for an arbitrary type of sizes; later on
  -- this gets instantiated with a type of sizes associated with Σ,ε
  -- whose existence is given by Theorem 5.6
  -- (CocontinuityOfTakingPowers)
  (Size : Set l)
  {{ssz : SizeStructure Size}}
  where
  open Slice I

  private
    Γ = Syseq.Γ ε
    lhs = Syseq.lhs ε
    rhs = Syseq.rhs ε

  open Colim Size {{ssz}}

  -- Definition 6.2
  record IdxStruct : Set (lsuc l) where
    constructor mkIdxStruct
    field
      D : Size → Setᴵ l -- D aka dom
      τ : ∀ i → ∏ᵇ j < i , (T{Σ}(D j) ⇁ D i)
  open IdxStruct public

  -- (↓ i)-indexed structure (i : Size),
  -- i.e. indexed for all j : Size and j < i
  record IdxStructᵇ (i : Size) : Set (lsuc l) where
    constructor mkIdxStructᵇ
    field
      Dᵇ : ∏ᵇ j < i , Setᴵ l
      τᵇ : ∏ᵇ j < i , ∏ᵇ k < j , (T{Σ}(Dᵇ k) ⇁ Dᵇ j)
  open IdxStructᵇ public

  infixl 6 _↓_
  -- restriction of a (any) Size-indexed alg to a (↓ i)-indexed alg
  _↓_ : IdxStruct → ∀ i → IdxStructᵇ i
  Dᵇ (A ↓ _) j   = D A j
  τᵇ (A ↓ _) j k = τ A j k

  infixl 6 _↓ᵇ_
  -- restriction of a (↓ i)-indexed alg to a (↓ j)-indexed alg,
  -- when j < i
  _↓ᵇ_ : {i : Size} → IdxStructᵇ i → ∏ᵇ j < i , IdxStructᵇ j
  Dᵇ (A ↓ᵇ _) j  = Dᵇ A j
  τᵇ (A ↓ᵇ _) j k = τᵇ A j k

  Wᵇ : ∀{i} → IdxStructᵇ i → Setᴵ l
  Wᵇ {i} A n = ∑ᵇ j < i , T{Σ} (Dᵇ A j) n

  -- (6.4)
  data Rᵇ
    {i : Size}
    (A : IdxStructᵇ i)
    (n : I)
    : ----------------------
    Wᵇ A n → Wᵇ A n → Prop l
    where
    τεᵇ : ∀ᵇ j < i ,
      ((e : Op Γ n)
       (ρ : Ar Γ n e ⇁ Dᵇ A j)
        → ---------------------------------------------------------------
        Rᵇ A n (pairᵇ j (T' ρ n (lhs n e))) (pairᵇ j (T' ρ n (rhs n e))))
    τηᵇ : ∀ᵇ j < i , ∀ᵇ k < j ,
      ((t : T{Σ}(Dᵇ A k) n)
        → ------------------------------------------
        Rᵇ A n (pairᵇ j (η n (τᵇ A j k n t))) (pairᵇ k t))
    τσᵇ : ∀ᵇ j < i , ∀ᵇ k < j ,
      ((a : Op Σ n)
        (f : Ar Σ n a ⇁ T (Dᵇ A k))
        → ------------------------------------------------
        Rᵇ A n (pairᵇ k (σ n (a , f)))
            (pairᵇ j (σ n (a , λ m b → η m (τᵇ A j k m (f m b))))))

  -- (6.3)
  ◇ : ∀{i} → IdxStructᵇ i → Setᴵ l
  ◇ A n = Wᵇ A n / Rᵇ A n

  -- Definition 6.3
  ◇fix : IdxStruct → Prop (lsuc l)
  ◇fix alg =
    ∀ i → (∀ n → D alg i n == ◇ (alg ↓ i) n) ∧
    ∀ᵇ j < i , (∀ n t → τ alg i j n t === [ pairᵇ j t ]/ Rᵇ (alg ↓ i) n)

  -- We will show (Proposition 6.4) that any element of the folowing
  -- type yields an initial algebra for the equational systen (Σ,ε)
  -- when Size,ssz is instantiated with a suitable type of sizes
  FixSizeStruct : Set (lsuc l)
  FixSizeStruct = set IdxStruct ◇fix

  -- To actually construct an element of FixSizeStruct we will use
  -- well-founded recursion to construct an element of the following
  -- size-indexed family and then take its colimit (Theorem 6.1)
  FixSizeStructᵇ : Size → Set (lsuc l)
  FixSizeStructᵇ i = set (IdxStructᵇ i) isFixSizeStructᵇ
    module _ where
    isFixSizeStructᵇ : IdxStructᵇ i → Prop (lsuc l)
    isFixSizeStructᵇ alg =
      ∀ᵇ j < i , ((∀ n → Dᵇ alg j n == ◇ (alg ↓ᵇ j) n)
        ∧ ∀ᵇ k < j ,
          ((n : I)
          (t : T {Σ} (Dᵇ (mkIdxStructᵇ (Dᵇ alg) (τᵇ alg)) k) n)
          → ---------------------------------------------------
          τᵇ alg j k n t === [ pairᵇ k t ]/ Rᵇ (alg ↓ᵇ j) n    ))