module QW.SizeIndexedStructure where

open import QW.ColimitsOfSizedIndexedDiagrams public

----------------------------------------------------------------------
-- Size-indexed structures for a signature Σ and system of equations ε
-- (Definitions 6.2 and 6.3)
----------------------------------------------------------------------
module SizeIdxStruct
  {l : Level}
  (Σ : Sig {l})
  (ε : Syseq Σ)
  -- 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
  private
    Γ = fst ε
    lhs = fst (snd ε)
    rhs = snd (snd ε)
  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{l}{Σ}(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{l}{Σ}(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 ↓ i) j   = D A j
  τᵇ (A ↓ i) 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 = ∑ᵇ j < i , T{l}{Σ} (Dᵇ A j)

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

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

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

  -- 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 , (Dᵇ alg j == ◇ (alg ↓ᵇ j)
        ∧ ∀ᵇ k < j ,
          ((t : T{l}{Σ}(Dᵇ (mkIdxStructᵇ (Dᵇ alg) (τᵇ alg)) k))
            → τᵇ alg j k t === [ pairᵇ k t ]/ Rᵇ (alg ↓ᵇ j)
          )
      )