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′