module linear.Completeness where
open import Data.Nat
import Data.Fin as F
open import Data.Nat.Properties.Simple
open import Data.List as List hiding ([_] ; _∷ʳ_)
open import Data.List.Properties
open import Data.Vec as V hiding ([_] ; _∷ʳ_ ; fromList)
open import Data.Product as Prod
open import Data.Sum as Sum
open import Function
open import Relation.Binary.PropositionalEquality as Eq hiding ([_])
open import linear.ILL
open import linear.Type
open import linear.Context as C
open import linear.Scope as S
open import linear.Usage as U hiding ([_])
open import linear.Usage.Erasure
open import linear.Context.Pointwise as CP
open import linear.Usage.Pointwise as UP
open import linear.Language as L
open import linear.Typing
open import linear.Typing.Extensional
open import linear.Typing.Substitution as T
open import linear.Usage.Mix
open import linear.Typing.Mix
lemma₁ : ∀ (γ : List Type) δ → S.Mergey (length γ) (length (δ List.++ γ))
lemma₁ γ [] = finish
lemma₁ γ (σ ∷ δ) = insert (lemma₁ γ δ)
Lemma₁ : ∀ γ δ → C.Mergey (lemma₁ γ δ)
Lemma₁ γ [] = finish
Lemma₁ γ (σ ∷ δ) = insert σ (Lemma₁ γ δ)
Lemma₁-eq : ∀ γ δ → Context[ _≡_ ] (V.fromList (δ List.++ γ)) (V.fromList γ C.⋈ Lemma₁ γ δ)
Lemma₁-eq γ [] = CP.refl
Lemma₁-eq γ (σ ∷ δ) = Eq.refl ∷ Lemma₁-eq γ δ
𝓛emma₁ : ∀ γ δ (Δ : Usages (V.fromList δ)) → U.Mergey (Lemma₁ γ δ)
𝓛emma₁ γ [] [] = finish
𝓛emma₁ γ (σ ∷ δ) (S ∷ Δ) = insert S (𝓛emma₁ γ δ Δ)
𝓛emma₁-[[eq]] : ∀ γ δ → Usages[ _≡_ , UsageEq ] (Lemma₁-eq γ δ)
[[ V.fromList (δ List.++ γ) ]]
([[ V.fromList γ ]] U.⋈ 𝓛emma₁ γ δ [[ V.fromList δ ]])
𝓛emma₁-[[eq]] γ [] = UP.refl
𝓛emma₁-[[eq]] γ (σ ∷ δ) = Eq.refl ∷ 𝓛emma₁-[[eq]] γ δ
𝓛emma₁-]]eq[[ : ∀ γ δ → Usages[ _≡_ , UsageEq ] (Lemma₁-eq γ δ)
]] V.fromList (δ List.++ γ) [[
(]] V.fromList γ [[ U.⋈ 𝓛emma₁ γ δ ]] V.fromList δ [[)
𝓛emma₁-]]eq[[ γ [] = UP.refl
𝓛emma₁-]]eq[[ γ (σ ∷ δ) = Eq.refl ∷ 𝓛emma₁-]]eq[[ γ δ
lemma₂ : ∀ (γ : List Type) δ → S.Mergey (length γ) (length (γ List.++ δ))
lemma₂ [] [] = finish
lemma₂ [] (σ ∷ δ) = insert (lemma₂ [] δ)
lemma₂ (σ ∷ γ) δ = copy (lemma₂ γ δ)
Lemma₂ : ∀ γ δ → C.Mergey (lemma₂ γ δ)
Lemma₂ [] [] = finish
Lemma₂ [] (σ ∷ δ) = insert σ (Lemma₂ [] δ)
Lemma₂ (σ ∷ γ) δ = copy (Lemma₂ γ δ)
Lemma₂-eq : ∀ γ δ → Context[ _≡_ ] (V.fromList (γ List.++ δ)) (V.fromList γ C.⋈ Lemma₂ γ δ)
Lemma₂-eq [] [] = []
Lemma₂-eq [] (σ ∷ δ) = Eq.refl ∷ Lemma₂-eq [] δ
Lemma₂-eq (σ ∷ γ) δ = Eq.refl ∷ Lemma₂-eq γ δ
Lemma₁₂-eq : ∀ γ δ → Context[ _≡_ ] (V.fromList δ C.⋈ Lemma₁ δ γ)
(V.fromList γ C.⋈ Lemma₂ γ δ)
Lemma₁₂-eq γ δ = CP.trans (CP.sym (Lemma₁-eq δ γ)) (Lemma₂-eq γ δ)
Lemma₂₁-eq : ∀ γ δ → Context[ _≡_ ] (V.fromList γ C.⋈ Lemma₂ γ δ)
(V.fromList δ C.⋈ Lemma₁ δ γ)
Lemma₂₁-eq γ δ = CP.trans (CP.sym (Lemma₂-eq γ δ)) (Lemma₁-eq δ γ)
𝓛emma₂ : ∀ γ δ (Δ : Usages (V.fromList δ)) → U.Mergey (Lemma₂ γ δ)
𝓛emma₂ [] [] Δ = finish
𝓛emma₂ [] (σ ∷ δ) (S ∷ Δ) = insert S (𝓛emma₂ [] δ Δ)
𝓛emma₂ (σ ∷ γ) δ Δ = copy (𝓛emma₂ γ δ Δ)
𝓛emma₂-[[eq]] : ∀ γ δ → Usages[ _≡_ , UsageEq ] (Lemma₂-eq γ δ)
[[ V.fromList (γ List.++ δ) ]]
([[ V.fromList γ ]] U.⋈ 𝓛emma₂ γ δ [[ V.fromList δ ]])
𝓛emma₂-[[eq]] [] [] = []
𝓛emma₂-[[eq]] [] (σ ∷ δ) = Eq.refl ∷ 𝓛emma₂-[[eq]] [] δ
𝓛emma₂-[[eq]] (x ∷ γ) δ = Eq.refl ∷ 𝓛emma₂-[[eq]] γ δ
𝓛emma₂-]]eq[[ : ∀ γ δ → Usages[ _≡_ , UsageEq ] (Lemma₂-eq γ δ)
]] V.fromList (γ List.++ δ) [[
(]] V.fromList γ [[ U.⋈ 𝓛emma₂ γ δ ]] V.fromList δ [[)
𝓛emma₂-]]eq[[ [] [] = []
𝓛emma₂-]]eq[[ [] (σ ∷ δ) = Eq.refl ∷ 𝓛emma₂-]]eq[[ [] δ
𝓛emma₂-]]eq[[ (σ ∷ γ) δ = Eq.refl ∷ 𝓛emma₂-]]eq[[ γ δ
𝓛emma₁₂-]]eq[[ : ∀ γ δ → Usages[ _≡_ , UsageEq ] (Lemma₁₂-eq γ δ)
(]] V.fromList δ [[ U.⋈ 𝓛emma₁ δ γ [[ V.fromList γ ]])
([[ V.fromList γ ]] U.⋈ 𝓛emma₂ γ δ ]] V.fromList δ [[)
𝓛emma₁₂-]]eq[[ (σ ∷ γ) δ = Eq.refl ∷ 𝓛emma₁₂-]]eq[[ γ δ
𝓛emma₁₂-]]eq[[ [] [] = UP.refl
𝓛emma₁₂-]]eq[[ [] (σ ∷ δ) = Eq.refl ∷ 𝓛emma₁₂-]]eq[[ [] δ
𝓛emma₁₂-[[eq]] : ∀ γ δ → Usages[ _≡_ , UsageEq ] (Lemma₁₂-eq γ δ)
([[ V.fromList δ ]] U.⋈ 𝓛emma₁ δ γ ]] V.fromList γ [[)
(]] V.fromList γ [[ U.⋈ 𝓛emma₂ γ δ [[ V.fromList δ ]])
𝓛emma₁₂-[[eq]] (σ ∷ γ) δ = Eq.refl ∷ 𝓛emma₁₂-[[eq]] γ δ
𝓛emma₁₂-[[eq]] [] [] = UP.refl
𝓛emma₁₂-[[eq]] [] (σ ∷ δ) = Eq.refl ∷ 𝓛emma₁₂-[[eq]] [] δ
𝓛emma₂₁-[[eq]] : ∀ γ δ → Usages[ _≡_ , UsageEq ] (Lemma₂₁-eq γ δ)
([[ V.fromList γ ]] U.⋈ 𝓛emma₂ γ δ [[ V.fromList δ ]])
([[ V.fromList δ ]] U.⋈ 𝓛emma₁ δ γ [[ V.fromList γ ]])
𝓛emma₂₁-[[eq]] (σ ∷ γ) δ = Eq.refl ∷ 𝓛emma₂₁-[[eq]] γ δ
𝓛emma₂₁-[[eq]] [] [] = []
𝓛emma₂₁-[[eq]] [] (σ ∷ δ) = Eq.refl ∷ 𝓛emma₂₁-[[eq]] [] δ
𝓛emma₂₁-]]eq[[ : ∀ γ δ → Usages[ _≡_ , UsageEq ] (Lemma₂₁-eq γ δ)
(]] V.fromList γ [[ U.⋈ 𝓛emma₂ γ δ [[ V.fromList δ ]])
([[ V.fromList δ ]] U.⋈ 𝓛emma₁ δ γ ]] V.fromList γ [[)
𝓛emma₂₁-]]eq[[ (σ ∷ γ) δ = Eq.refl ∷ 𝓛emma₂₁-]]eq[[ γ δ
𝓛emma₂₁-]]eq[[ [] [] = []
𝓛emma₂₁-]]eq[[ [] (σ ∷ δ) = Eq.refl ∷ 𝓛emma₂₁-]]eq[[ [] δ
`0L : (γ : List Type) (σ : Type) → ∃ λ t → U.[ 𝟘 ] ∷ [[ V.fromList γ ]] ⊢ t ∈ σ ⊠ ] 𝟘 [ ∷ ]] V.fromList γ [[
`0L [] τ = , `exfalso τ (`var z)
`0L (σ ∷ γ) τ =
let (t , T) = `0L γ (σ ─o τ)
in , `app (T.weakInfer (copy (insert U.[ σ ] finish)) T) (`neu (`var (s z)))
complete : {γ : List Type} {σ : Type} → γ ⊢ σ →
∃ λ t → [[ V.fromList γ ]] ⊢ σ ∋ t ⊠ ]] V.fromList γ [[
complete ax = , `neu (`var z)
complete (cut {γ} {δ} {σ} {τ} t u) =
let (rT , T) = complete t
(rU , U) = complete u
U′ : [[ V.fromList (σ ∷ δ) ]] U.⋈ copy (𝓛emma₁ δ γ [[ V.fromList γ ]])
⊢ τ ∋ _ ⊠
]] V.fromList (σ ∷ δ) [[ U.⋈ copy (𝓛emma₁ δ γ [[ V.fromList γ ]])
U′ = T.weakCheck (copy (𝓛emma₁ δ γ [[ V.fromList γ ]])) U
T′ : [[ V.fromList γ ]] U.⋈ 𝓛emma₂ γ δ ]] V.fromList δ [[
⊢ σ ∋ _ ⊠
]] V.fromList γ [[ U.⋈ 𝓛emma₂ γ δ ]] V.fromList δ [[
T′ = T.weakCheck (𝓛emma₂ γ δ ]] V.fromList δ [[) T
F : [[ V.fromList γ ]] U.⋈ 𝓛emma₂ γ δ [[ V.fromList δ ]]
⊢ _ ∈ σ ─o τ ⊠
[[ V.fromList γ ]] U.⋈ 𝓛emma₂ γ δ ]] V.fromList δ [[
F = extensionalInfer (Lemma₂₁-eq γ δ) (Lemma₁₂-eq γ δ)
(𝓛emma₂₁-[[eq]] γ δ) (𝓛emma₁₂-]]eq[[ γ δ)
$ `cut (`lam U′)
FT : [[ V.fromList (γ List.++ δ) ]]
⊢ _ ∈ τ ⊠
]] V.fromList (γ List.++ δ) [[
FT = extensionalInfer (Lemma₂-eq γ δ) (CP.sym (Lemma₂-eq γ δ))
(𝓛emma₂-[[eq]] γ δ) (UP.sym (𝓛emma₂-]]eq[[ γ δ))
$ `app F T′
in , `neu FT
complete (⊗R {γ} {δ} {σ} {τ} t u) =
let (rT , T) = complete t
(rU , U) = complete u
T′ : [[ V.fromList δ ]] U.⋈ 𝓛emma₁ δ γ [[ V.fromList γ ]]
⊢ σ ∋ _ ⊠
[[ V.fromList δ ]] U.⋈ 𝓛emma₁ δ γ ]] V.fromList γ [[
T′ = extensionalCheck (Lemma₁₂-eq γ δ) (Lemma₂₁-eq γ δ)
(UP.irrelevance _ (UP.sym (𝓛emma₂₁-[[eq]] γ δ)))
(𝓛emma₂₁-]]eq[[ γ δ)
$ T.weakCheck (𝓛emma₂ γ δ [[ V.fromList δ ]]) T
U′ : [[ V.fromList δ ]] U.⋈ 𝓛emma₁ δ γ ]] V.fromList γ [[
⊢ τ ∋ _ ⊠
]] V.fromList δ [[ U.⋈ 𝓛emma₁ δ γ ]] V.fromList γ [[
U′ = T.weakCheck (𝓛emma₁ δ γ ]] V.fromList γ [[) U
TU : [[ V.fromList (γ List.++ δ) ]]
⊢ σ ⊗ τ ∋ _ ⊠
]] V.fromList (γ List.++ δ) [[
TU = extensionalCheck (Lemma₁-eq δ γ) (CP.sym (Lemma₁-eq δ γ))
(𝓛emma₁-[[eq]] δ γ) (UP.sym (𝓛emma₁-]]eq[[ δ γ))
$ `prd⊗ T′ U′
in , TU
complete (⊗L t) =
let (rT , T) = complete t
T′ = T.weakCheck (copy (copy (U.inserts (_ ∷ _ ∷ _ ∷ []) finish))) T
in , `let `v ,, `v ∷= `var z
`in `neu `app (`app (`cut (`lam (`lam T′))) (`neu `var z)) (`neu (`var (s z)))
complete 1R = , `unit
complete (1L t) =
let (rt , T) = complete t
in , `let `⟨⟩ ∷= `var z `in T.weakCheck (insert _ finish) T
complete 0L = , `neu (`exfalso _ (proj₂ (`0L _ _)))
complete (─oR t) = , `lam (proj₂ $ complete t)
complete (─oL {γ} {δ} {σ} {τ} {ν} t u) =
let (rT , T) = complete t
(rU , U) = complete u
U′ : [[ V.fromList ((σ ─o τ) ∷ γ) ]] U.⋈ 𝓛emma₂ ((σ ─o τ) ∷ γ) δ [[ V.fromList δ ]]
⊢ τ ─o ν ∋ _ ⊠
[[ V.fromList ((σ ─o τ) ∷ γ) ]] U.⋈ 𝓛emma₂ ((σ ─o τ) ∷ γ) δ ]] V.fromList δ [[
U′ = extensionalCheck (Lemma₂₁-eq ((σ ─o τ) ∷ γ) δ) (Lemma₁₂-eq ((σ ─o τ) ∷ γ) δ)
(𝓛emma₂₁-[[eq]] ((σ ─o τ) ∷ γ) δ) (𝓛emma₁₂-]]eq[[ ((σ ─o τ) ∷ γ) δ)
$ T.weakCheck (𝓛emma₁ δ ((σ ─o τ) ∷ γ) [[ V.fromList ((σ ─o τ) ∷ γ) ]]) (`lam U)
T′ : ] σ ─o τ [ ∷ ([[ V.fromList γ ]] U.⋈ 𝓛emma₂ γ δ ]] V.fromList δ [[)
⊢ σ ∋ _ ⊠
] σ ─o τ [ ∷ (]] V.fromList γ [[ U.⋈ 𝓛emma₂ γ δ ]] V.fromList δ [[)
T′ = T.weakCheck (insert _ (𝓛emma₂ γ δ ]] V.fromList δ [[)) T
UT : [[ V.fromList ((σ ─o τ) ∷ γ List.++ δ) ]]
⊢ _ ∈ ν ⊠
]] V.fromList ((σ ─o τ) ∷ γ List.++ δ) [[
UT = extensionalInfer (Eq.refl ∷ Lemma₂-eq γ δ) (Eq.refl ∷ CP.sym (Lemma₂-eq γ δ))
(Eq.refl ∷ 𝓛emma₂-[[eq]] γ δ)
(Eq.refl ∷ UP.sym (𝓛emma₂-]]eq[[ γ δ))
$ `app (`cut U′) (`neu (`app (`var z) T′))
in , `neu UT
complete (&R t u) = , `prd& (proj₂ $ complete t) (proj₂ $ complete u)
complete (&₁L t) =
let (rT , T) = complete t
T′ = T.weakCheck (copy (insert _ finish)) T
in , `neu `app (`cut (`lam T′)) (`neu (`fst (`var z)))
complete (&₂L t) =
let (rT , T) = complete t
T′ = T.weakCheck (copy (insert _ finish)) T
in , `neu `app (`cut (`lam T′)) (`neu (`snd (`var z)))
complete (⊕₁R t) = , `inl (proj₂ $ complete t)
complete (⊕₂R t) = , `inr (proj₂ $ complete t)
complete (⊕L t u) =
let (rT , T) = complete t
(rU , U) = complete u
T′ = T.weakCheck (copy (insert _ finish)) T
U′ = T.weakCheck (copy (insert _ finish)) U
in , `neu (`case `var z return _ of T′ %% U′)
complete (mix t inc) =
let (rT , T) = complete t
T′ = mixCheck ([[fromList]] trivial) (]]fromList[[ trivial)
([[fromList]] inc) (]]fromList[[ inc) T
in T′