module linear.Usage.Functional where
open import Data.Nat
open import Data.Fin
open import Data.Vec hiding (_++_ ; tail ; map)
open import Data.Product
open import Function
open import Relation.Binary.PropositionalEquality
open import linear.Scope as Sc hiding (Env)
open import linear.Type
open import linear.Context as C hiding (_++_)
open import linear.Usage
open import linear.Relation.Functional
R++ : {o k : ℕ} (δ : Context o) (γ : Context k) (ΔΓ : Usages (δ C.++ γ)) → (i : Usages δ) (o : Usages γ) → Set
R++ δ γ ΔΓ Δ Γ = ΔΓ ≡ (Δ ++ Γ)
functional++ : {o k : ℕ} {δ : Context o} {γ : Context k} {ΔΓ : Usages (δ C.++ γ)} → Functional′ (R++ δ γ ΔΓ)
functional++ [] refl refl = refl
functional++ (A ∷ Δ) eq₁ eq₂ = functional++ Δ (cong tail eq₁) (cong tail eq₂)
RFin : (k : Σ[ n ∈ ℕ ] Context n × Fin n) → (let (_ , γ , _) = k in Usages γ × Usages γ) → Type → Set
RFin (_ , _ , k) (Γ , Δ) σ = Γ ⊢ k ∈[ σ ]⊠ Δ
functionalFin : Functional RFin
functionalFin _ z z = refl
functionalFin _ (s k₁) (s k₂) = cong _ $ functionalFin _ k₁ k₂
RFinPost : (k : Σ[ n ∈ ℕ ] Σ[ γ ∈ Context n ] Usages γ × Fin n) →
(let (_ , γ , _) = k in Type × Usages γ) → Set
RFinPost (_ , _ , Γ , k) (A , Δ) = Γ ⊢ k ∈[ A ]⊠ Δ
RFinPre : (k : Σ[ n ∈ ℕ ] Σ[ γ ∈ Context n ] Usages γ × Fin n) →
(let (_ , γ , _) = k in Type × Usages γ) → Set
RFinPre (_ , _ , Δ , k) (A , Γ) = Γ ⊢ k ∈[ A ]⊠ Δ
functionalFinPost : Functional′ RFinPost
functionalFinPost _ z z = refl
functionalFinPost _ (s k₁) (s k₂) = cong (map id _) $ functionalFinPost _ k₁ k₂
functionalFinPre : Functional′ RFinPre
functionalFinPre _ z z = refl
functionalFinPre _ (s k₁) (s k₂) = cong _ $ functionalFinPre _ k₁ k₂
InferTypingPost :
{T : ℕ → Set} (𝓣 : Typing T) (i : Σ[ n ∈ ℕ ] Σ[ γ ∈ Context n ] Usages γ × T n) →
(let (_ , γ , _) = i in Type × Usages γ) → Set
InferTypingPost 𝓣 (_ , _ , Γ , t) (A , Δ) = 𝓣 Γ t A Δ
CheckTypingPost :
{T : ℕ → Set} (𝓣 : Typing T) (i : Σ[ n ∈ ℕ ] Σ[ γ ∈ Context n ] Usages γ × Type × T n) →
(let (_ , γ , _) = i in Usages γ) → Set
CheckTypingPost 𝓣 (_ , _ , Γ , A , t) Δ = 𝓣 Γ t A Δ
REnvPost :
{E : ℕ → Set} (𝓔 : Typing E)
(i : Σ[ k ∈ ℕ ] Σ[ l ∈ ℕ ] Σ[ θ ∈ Context l ] Usages θ × Sc.Env E k l × Σ[ γ ∈ Context k ] Usages γ) →
(let (_ , l , θ , _) = i in Usages θ) → Set
REnvPost 𝓔 (_ , _ , _ , Τ₁ , ρ , _ , Γ) Τ₂ = Env 𝓔 Τ₁ ρ Τ₂ Γ
functionalEnvPost :
{E : ℕ → Set} {𝓔 : Typing E} → Functional′ (InferTypingPost 𝓔) → Functional′ (REnvPost 𝓔)
functionalEnvPost det𝓔 _ [] [] = refl
functionalEnvPost det𝓔 _ (T₁ ∷ ρ₁) (T₂ ∷ ρ₂) rewrite cong proj₂ (det𝓔 _ T₁ T₂) = functionalEnvPost det𝓔 _ ρ₁ ρ₂
functionalEnvPost det𝓔 _ (─∷ ρ₁) (─∷ ρ₂) = functionalEnvPost det𝓔 _ ρ₁ ρ₂
functionalEnvPost det𝓔 _ ([v]∷ ρ₁) ([v]∷ ρ₂) = cong _ $ functionalEnvPost det𝓔 _ ρ₁ ρ₂
functionalEnvPost det𝓔 _ (]v[∷ ρ₁) (]v[∷ ρ₂) = cong _ $ functionalEnvPost det𝓔 _ ρ₁ ρ₂
InferTypingPre :
{T : ℕ → Set} (𝓣 : Typing T) (i : Σ[ n ∈ ℕ ] Σ[ γ ∈ Context n ] Usages γ × T n) →
(let (_ , γ , _) = i in Type × Usages γ) → Set
InferTypingPre 𝓣 (_ , _ , Δ , t) (A , Γ) = 𝓣 Γ t A Δ
CheckTypingPre :
{T : ℕ → Set} (𝓣 : Typing T) (i : Σ[ n ∈ ℕ ] Σ[ γ ∈ Context n ] Usages γ × Type × T n) →
(let (_ , γ , _) = i in Usages γ) → Set
CheckTypingPre 𝓣 (_ , _ , Δ , A , t) Γ = 𝓣 Γ t A Δ
REnvPre :
{E : ℕ → Set} (𝓔 : Typing E)
(i : Σ[ k ∈ ℕ ] Σ[ l ∈ ℕ ] Σ[ θ ∈ Context l ] Usages θ × Sc.Env E k l × Σ[ γ ∈ Context k ] Usages γ) →
(let (_ , l , θ , _) = i in Usages θ) → Set
REnvPre 𝓔 (_ , _ , _ , Τ₂ , ρ , _ , Γ) Τ₁ = Env 𝓔 Τ₁ ρ Τ₂ Γ
functionalEnvPre :
{E : ℕ → Set} {𝓔 : Typing E} → Functional′ (InferTypingPre 𝓔) → Functional′ (REnvPre 𝓔)
functionalEnvPre det𝓔 _ [] [] = refl
functionalEnvPre det𝓔 _ (T₁ ∷ ρ₁) (T₂ ∷ ρ₂) rewrite functionalEnvPre det𝓔 _ ρ₁ ρ₂ = cong proj₂ (det𝓔 _ T₁ T₂)
functionalEnvPre det𝓔 _ (─∷ ρ₁) (─∷ ρ₂) = functionalEnvPre det𝓔 _ ρ₁ ρ₂
functionalEnvPre det𝓔 _ ([v]∷ ρ₁) ([v]∷ ρ₂) = cong _ $ functionalEnvPre det𝓔 _ ρ₁ ρ₂
functionalEnvPre det𝓔 _ (]v[∷ ρ₁) (]v[∷ ρ₂) = cong _ $ functionalEnvPre det𝓔 _ ρ₁ ρ₂
InferTyping :
{T : ℕ → Set} (𝓣 : Typing T) (ri : Σ[ n ∈ ℕ ] Σ[ γ ∈ Context n ] T n)
(ii : let (_ , γ , _) = ri in Usages γ × Usages γ) (o : Type) → Set
InferTyping 𝓣 (_ , _ , t) (Γ , Δ) A = 𝓣 Γ t A Δ