module linear.Usage.Consumption where
open import Data.Nat
open import Data.Vec hiding (map ; [_] ; split ; _++_ ; tail)
open import Data.Product hiding (swap)
open import Function
open import linear.Type
open import linear.Scope as Sc
open import linear.Context as C hiding (_++_)
open import linear.Usage as U hiding (_++_ ; tail)
import Relation.Binary.PropositionalEquality as PEq
infix 3 _─_≡_─_
data _─_≡_─_ : {n : ℕ} {γ : Context n} (Γ Δ θ ξ : Usages γ) → Set where
[] : [] ─ [] ≡ [] ─ []
─∷_ : {n : ℕ} {γ : Context n} {Γ Δ θ ξ : Usages γ} {a : Type} {A B : Usage a} →
Γ ─ Δ ≡ θ ─ ξ → A ∷ Γ ─ A ∷ Δ ≡ B ∷ θ ─ B ∷ ξ
_∷_ : {n : ℕ} {γ : Context n} {Γ Δ θ ξ : Usages γ} (a : Type) →
Γ ─ Δ ≡ θ ─ ξ → [ a ] ∷ Γ ─ ] a [ ∷ Δ ≡ [ a ] ∷ θ ─ ] a [ ∷ ξ
tail : {n : ℕ} {γ : Context n} {Γ Δ θ ξ : Usages γ} {a : Type} {S T U V : Usage a} →
S ∷ Γ ─ T ∷ Δ ≡ U ∷ θ ─ V ∷ ξ → Γ ─ Δ ≡ θ ─ ξ
tail (─∷ p) = p
tail (a ∷ p) = p
infix 3 _⊆_
_⊆_ : {n : ℕ} {γ : Context n} (Γ Δ : Usages γ) → Set
Γ ⊆ Δ = Γ ─ Δ ≡ Γ ─ Δ
pure : {n : ℕ} (γ : Context n) → [[ γ ]] ⊆ ]] γ [[
pure [] = []
pure (a ∷ γ) = a ∷ pure γ
refl : {n : ℕ} {γ : Context n} (Γ : Usages γ) → Γ ⊆ Γ
refl [] = []
refl (_ ∷ Γ) = ─∷ refl Γ
trans : {n : ℕ} {γ : Context n} {Γ Δ θ : Usages γ} → Γ ⊆ Δ → Δ ⊆ θ → Γ ⊆ θ
trans [] [] = []
trans (─∷ p) (─∷ q) = ─∷ trans p q
trans (a ∷ p) (─∷ q) = a ∷ trans p q
trans (─∷ p) (a ∷ q) = a ∷ trans p q
antisym : {n : ℕ} {γ : Context n} {Γ Δ : Usages γ} → Γ ⊆ Δ → Δ ⊆ Γ → Γ PEq.≡ Δ
antisym [] [] = PEq.refl
antisym (─∷ p) (─∷ q) = PEq.cong _ $ antisym p q
antisym (a ∷ p) ()
irrelevance : {n : ℕ} {γ : Context n} {Γ Δ : Usages γ} (p q : Γ ⊆ Δ) → p PEq.≡ q
irrelevance [] [] = PEq.refl
irrelevance (─∷ p) (─∷ q) = PEq.cong ─∷_ $ irrelevance p q
irrelevance (a ∷ p) (.a ∷ q) = PEq.cong (a ∷_) $ irrelevance p q
infixr 3 _++_
_++_ : {m n : ℕ} {γ : Context m} {δ : Context n} {Γ Δ θ ξ : Usages γ} {χ Φ : Usages δ} →
χ ⊆ Φ → Γ ─ Δ ≡ θ ─ ξ → χ U.++ Γ ─ Φ U.++ Δ ≡ χ U.++ θ ─ Φ U.++ ξ
[] ++ q = q
─∷ p ++ q = ─∷ (p ++ q)
a ∷ p ++ q = a ∷ (p ++ q)
swap : {n : ℕ} {γ : Context n} {Γ Δ θ : Usages γ} → Γ ⊆ Δ → Δ ⊆ θ →
∃ λ Δ′ → Γ ─ Δ ≡ Δ′ ─ θ × Δ ─ θ ≡ Γ ─ Δ′
swap [] [] = [] , [] , []
swap (─∷ p) (─∷ q) = map _ (map ─∷_ ─∷_) $ swap p q
swap (─∷ p) (a ∷ q) = map _ (map ─∷_ (a ∷_)) $ swap p q
swap (a ∷ p) (─∷ q) = map _ (map (a ∷_) ─∷_) $ swap p q
split : {m n : ℕ} {γ : Context m} {δ : Context n} (Γ₁ Γ₂ : Usages γ) {Δ₁ Δ₂ : Usages δ} →
Γ₁ U.++ Δ₁ ⊆ Γ₂ U.++ Δ₂ → Γ₁ ⊆ Γ₂ × Δ₁ ⊆ Δ₂
split [] [] p = [] , p
split (_ ∷ _) (_ ∷ _) (─∷ p) = map ─∷_ id $ split _ _ p
split (_ ∷ _) (_ ∷ _) (a ∷ p) = map (a ∷_) id $ split _ _ p
truncate : {m n : ℕ} (γ : Context m) {δ : Context n} {Δ₁ Δ₂ : Usages δ} →
[[ γ ]] U.++ Δ₁ ⊆ ]] γ [[ U.++ Δ₂ → Δ₁ ⊆ Δ₂
truncate γ = proj₂ ∘ split [[ γ ]] ]] γ [[
divide : {n : ℕ} {γ : Context n} {Γ Δ θ ξ χ : Usages γ} → Γ ─ Δ ≡ θ ─ ξ → Γ ⊆ χ → χ ⊆ Δ →
∃ λ Φ → Γ ─ χ ≡ θ ─ Φ × χ ─ Δ ≡ Φ ─ ξ
divide [] [] [] = [] , [] , []
divide (a ∷ eq) (─∷ p) (.a ∷ q) = map _ (map ─∷_ (a ∷_)) $ divide eq p q
divide (a ∷ eq) (.a ∷ p) (─∷ q) = map _ (map (a ∷_) ─∷_) $ divide eq p q
divide (─∷ eq) (─∷ p) (─∷ q) = map _ (map ─∷_ ─∷_) $ divide eq p q
divide (─∷ eq) (a ∷ p) ()
weaken⁻¹ : {k l : ℕ} {γ : Context k} {m : Sc.Mergey k l} {M : C.Mergey m} (𝓜 : U.Mergey M)
{Γ Δ : Usages γ} {χ : Usages (γ C.⋈ M)} → Γ U.⋈ 𝓜 ⊆ χ → χ ⊆ Δ U.⋈ 𝓜 →
∃ λ χ′ → χ PEq.≡ (χ′ U.⋈ 𝓜)
weaken⁻¹ finish p q = , PEq.refl
weaken⁻¹ (copy 𝓜) {T ∷ Γ} {.T ∷ Δ} (─∷ p) (─∷ q) = map (_ ∷_) (PEq.cong (_ ∷_)) $ weaken⁻¹ 𝓜 p q
weaken⁻¹ (copy 𝓜) {.([ a ]) ∷ Γ} {.(] a [) ∷ Δ} (─∷ p) (a ∷ q) = map (_ ∷_) (PEq.cong (_ ∷_)) $ weaken⁻¹ 𝓜 p q
weaken⁻¹ (copy 𝓜) {.([ a ]) ∷ Γ} {.(] a [) ∷ Δ} (a ∷ p) (─∷ q) = map (_ ∷_) (PEq.cong (_ ∷_)) $ weaken⁻¹ 𝓜 p q
weaken⁻¹ (insert A 𝓜) (─∷ p) (─∷ q) = map id (PEq.cong (_ ∷_)) $ weaken⁻¹ 𝓜 p q
weaken⁻¹ (insert .([ a ]) 𝓜) (a ∷ p) ()
equality : {n : ℕ} {γ : Context n} {Γ θ ξ : Usages γ} → Γ ─ Γ ≡ θ ─ ξ → θ PEq.≡ ξ
equality [] = PEq.refl
equality (─∷ p) = PEq.cong _ $ equality p
Consumption : {T : ℕ → Set} (𝓣 : Typing T) → Set
Consumption {T} 𝓣 = {n : ℕ} {γ : Context n} {t : T n} {A : Type} {Γ Δ : Usages γ} → 𝓣 Γ t A Δ → Γ ⊆ Δ
Framing : {T : ℕ → Set} (𝓣 : Typing T) → Set
Framing {T} 𝓣 =
{n : ℕ} {γ : Context n} {Γ Δ θ ξ : Usages γ} {t : T n} {A : Type} →
Γ ─ Δ ≡ θ ─ ξ → 𝓣 Γ t A Δ → 𝓣 θ t A ξ
consumptionFin : Consumption TFin
consumptionFin z = _ ∷ refl _
consumptionFin (s k) = ─∷ consumptionFin k
framingFin : Framing TFin
framingFin (A ∷ p) z rewrite equality p = z
framingFin (─∷ p) (s k) = s framingFin p k