------------------------------------------------------------------------
-- Substitution matrices (action of substitutions on modality contexts).
------------------------------------------------------------------------

import Graded.Modality
open import Graded.Usage.Restrictions

module Graded.Substitution
  {a} {M : Set a}
  (open Graded.Modality M)
  (š•„ : Modality)
  (R : Usage-restrictions M)
  where

open Modality š•„

open import Definition.Untyped M
  using (Subst ; tail ; head ; Wk ; id ; step ; lift)
open import Graded.Context š•„
open import Graded.Usage š•„ R
open import Graded.Usage.Weakening š•„ R
open import Graded.Mode š•„

open import Tools.Fin
open import Tools.Nat using (Nat; 1+)

infixl 50 _<*_
infixr 50 _*>_
infix  20 ∄_∄
infixl 30 _āŠ™_

private
  variable
    k m n : Nat

-- Substitutions are matrices represented as snoc-lists of modality contexts.
-- ĪØ : Substā‚˜ m n is an nƗm-matrix.

data Substā‚˜ : (m n : Nat) → Set a where
  []  : Substā‚˜ m 0
  _āŠ™_ : Substā‚˜ m n → Conā‚˜ m → Substā‚˜ m (1+ n)

private
  variable
    ĪØ Φ : Substā‚˜ m n

-- Substitutions that contain empty usage contexts.

Īµā‚˜ : Substā‚˜ 0 n
Īµā‚˜ {n = 0}    = []
Īµā‚˜ {n = 1+ n} = Īµā‚˜ āŠ™ ε

-- Application of substitution matrix from the left

_*>_ : (ĪØ : Substā‚˜ m n) → (γ : Conā‚˜ m) → Conā‚˜ n
[] *> γ = ε
(ĪØ āŠ™ Ī“) *> γ = ĪØ *> γ āˆ™ γ * Ī“

-- Application of substitution matrix from the right

_<*_ : (γ : Conā‚˜ n) → (ĪØ : Substā‚˜ m n) → Conā‚˜ m
ε <* [] = šŸ˜į¶œ
(γ āˆ™ p) <* (ĪØ āŠ™ Ī“) = p ·ᶜ Ī“ +ᶜ (γ <* ĪØ)

substā‚˜ : (ĪØ : Substā‚˜ m n) → (γ : Conā‚˜ n) → Conā‚˜ m
substā‚˜ ĪØ γ = γ <* ĪØ

-- Composition of substitution matrices

_<*>_ : (ĪØ : Substā‚˜ m k) (Φ : Substā‚˜ k n) → Substā‚˜ m n
ĪØ <*> [] = []
ĪØ <*> (Φ āŠ™ Ī“) = (ĪØ <*> Φ) āŠ™ (Ī“ <* ĪØ)

---------------------------------------------------------------

-- Well-formed modality substitutions: if āˆ€ x. γ_xĀ ā–ø[ γ xĀ ] σ x, where
-- γ_x is the x-th row vector of ĪØ, multiplied by ⌜ γ xĀ āŒ, then
-- ĪØĀ ā–¶[ γ ] σ.

_ā–¶[_]_ : Substā‚˜ m n → Mode-vector n → Subst m n → Set a
_ā–¶[_]_ {n = n} ĪØ γ σ =
  (x : Fin n) → ((šŸ˜į¶œ , x ≔ ⌜ γ x āŒ) <* ĪØ) ā–ø[ γ x ] σ x

-- Substitution matrix inference (for modalities with natrec-star
-- operators).

∄_∄ :
  ⦃ has-star : Has-star semiring-with-meet ⦄ →
  Subst m n → Mode-vector n → Substā‚˜ m n
∄_∄ {n = 0}    _ _  = []
∄_∄ {n = 1+ n} σ ms = ∄ tail σ ∄ (tailᵐ ms) āŠ™ ⌈ head σ āŒ‰ (headᵐ ms)

---------------------------------------------------------------
-- Modality substitutions corresponding to (term) weakenings --
---------------------------------------------------------------

-- Single step weakening of a substitution matrix

wk1Substā‚˜ : Substā‚˜ m n → Substā‚˜ (1+ m) n
wk1Substā‚˜ [] = []
wk1Substā‚˜ (ĪØ āŠ™ Ī“) = (wk1Substā‚˜ ĪØ) āŠ™ wkConā‚˜ (step id) Ī“

-- Lifting a substitution matrix

liftSubstā‚˜ : Substā‚˜ m n → Substā‚˜ (1+ m) (1+ n)
liftSubstā‚˜ ĪØ = (wk1Substā‚˜ ĪØ) āŠ™ (šŸ˜į¶œ āˆ™ šŸ™)

-- Identity substitution matrix

idSubstā‚˜ : Substā‚˜ n n
idSubstā‚˜ {n = 0} = []
idSubstā‚˜ {n = 1+ n} = liftSubstā‚˜ idSubstā‚˜

-- Substitution matrix from a weakening

wkSubstā‚˜ : (ρ : Wk m n) → Substā‚˜ m n
wkSubstā‚˜ id       = idSubstā‚˜
wkSubstā‚˜ (step ρ) = wk1Substā‚˜ (wkSubstā‚˜ ρ)
wkSubstā‚˜ (lift ρ) = liftSubstā‚˜ (wkSubstā‚˜ ρ)

------------------------------------------------------------------
-- Modality substitutions corresponding to (term) substitutions --
------------------------------------------------------------------

-- Extend a  substitution matrix with a single term substitution

consSubstā‚˜ : (ĪØ : Substā‚˜ m n) → (γ : Conā‚˜ m) → Substā‚˜ m (1+ n)
consSubstā‚˜ = _āŠ™_

-- Single term substitution matrix

sgSubstā‚˜ : (γ : Conā‚˜ n) → Substā‚˜ n (1+ n)
sgSubstā‚˜ = consSubstā‚˜ idSubstā‚˜