------------------------------------------------------------------------
-- 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ā‚˜