module linear.Usage.Mix where
open import Data.Product as Prod
open import Data.Vec as V hiding ([_] ; _∷ʳ_ ; fromList)
open import Function
open import Relation.Binary.PropositionalEquality hiding ([_])
open import linear.Context
open import linear.Context.Mix as CM hiding (_++ˡ_)
open import linear.Usage as U hiding ([_])
import linear.Usage.Erasure as UE
open import linear.Relation.Functional
infix 2 [_]_++_≅_
infixr 4 _∷ˡ_ _∷ʳ_
data [_]_++_≅_ : ∀ {m n p} {γ : Context m} {δ : Context n} {θ : Context p} →
γ ++ δ ≅ θ → Usages γ → Usages δ → Usages θ → Set where
[] : [ [] ] [] ++ [] ≅ []
_∷ˡ_ : ∀ {m n p σ} {γ : Context m} {δ : Context n} {θ : Context p}
{p : γ ++ δ ≅ θ} {Γ Δ Θ} (S : Usage σ) →
[ p ] Γ ++ Δ ≅ Θ → [ σ ∷ˡ p ] S ∷ Γ ++ Δ ≅ S ∷ Θ
_∷ʳ_ : ∀ {m n p σ} {γ : Context m} {δ : Context n} {θ : Context p}
{p : γ ++ δ ≅ θ} {Γ Δ Θ} (S : Usage σ) →
[ p ] Γ ++ Δ ≅ Θ → [ σ ∷ʳ p ] Γ ++ S ∷ Δ ≅ S ∷ Θ
≅-inj : ∀ {m n p} {γ : Context m} {δ : Context n} {θ : Context p}
{Γ₁ Γ₂ Δ₁ Δ₂ Θ} (p : γ ++ δ ≅ θ) →
[ p ] Γ₁ ++ Δ₁ ≅ Θ → [ p ] Γ₂ ++ Δ₂ ≅ Θ →
Γ₁ ≡ Γ₂ × Δ₁ ≡ Δ₂
≅-inj [] [] [] = refl , refl
≅-inj (a ∷ˡ p) (S ∷ˡ eq₁) (.S ∷ˡ eq₂) = Prod.map (cong (S ∷_)) id $ ≅-inj p eq₁ eq₂
≅-inj (σ ∷ʳ p) (S ∷ʳ eq₁) (.S ∷ʳ eq₂) = Prod.map id (cong (S ∷_)) $ ≅-inj p eq₁ eq₂
_++ˡ_ : ∀ {m n p} {γ : Context m} {δ : Context n} {θ : Context p}
{p : γ ++ δ ≅ θ} {Γ Δ Θ} {o} {φ : Context o} (Φ : Usages φ) →
[ p ] Γ ++ Δ ≅ Θ → [ φ CM.++ˡ p ] Φ U.++ Γ ++ Δ ≅ Φ U.++ Θ
[] ++ˡ eq = eq
(S ∷ Φ) ++ˡ eq = S ∷ˡ (Φ ++ˡ eq)
[[fromList]] : ∀ {γ δ θ} (p : γ UE.++ δ ≅ θ) →
[ CM.fromList p ] [[ _ ]] ++ [[ _ ]] ≅ [[ V.fromList θ ]]
[[fromList]] UE.[] = []
[[fromList]] (a UE.∷ˡ p) = U.[ a ] ∷ˡ [[fromList]] p
[[fromList]] (a UE.∷ʳ p) = U.[ a ] ∷ʳ [[fromList]] p
]]fromList[[ : ∀ {γ δ θ} (p : γ UE.++ δ ≅ θ) →
[ CM.fromList p ] ]] _ [[ ++ ]] _ [[ ≅ ]] V.fromList θ [[
]]fromList[[ UE.[] = []
]]fromList[[ (a UE.∷ˡ p) = ] a [ ∷ˡ ]]fromList[[ p
]]fromList[[ (a UE.∷ʳ p) = ] a [ ∷ʳ ]]fromList[[ p
open import Data.Nat
open import Data.Unit
MixSplit :
(ri : Σ[ γδθ ∈ ∃ Context × ∃ Context × ∃ Context ]
let ((_ , γ) , (_ , δ) , (_ , θ)) = γδθ in
(γ ++ δ ≅ θ) × Usages γ × Usages δ) →
let ((_ , _ , (_ , θ)) , eq , Γ , Δ) = ri in Usages θ → Set
MixSplit (_ , eq , Γ , Δ) Θ = [ eq ] Γ ++ Δ ≅ Θ
functionalMix : Functional′ MixSplit
functionalMix (_ , [] , _) [] [] = refl
functionalMix (_ , (σ ∷ˡ eq) , _) (_ ∷ˡ o₁) (_ ∷ˡ o₂) =
cong _ (functionalMix (_ , eq , _) o₁ o₂)
functionalMix (_ , (σ ∷ʳ eq) , _) (_ ∷ʳ o₁) (_ ∷ʳ o₂) =
cong _ (functionalMix (_ , eq , _) o₁ o₂)