module A201605.AltArtemov.Old.G.Vec.Prov where open import A201605.AltArtemov.Old.G.Vec.True renaming (ᵗ⌊_⌋ to ᵗ⌊_⌋ᵀ) public data Prov (Γ : Cx) : ∀ {n} → Vec ᵍ⌊ Γ ⌋ n → Ty → Set where var[_] : ∀ n {A} (x : Var Γ A) → Prov Γ (VARs[ n ] ⁱ⌊ x ⌋) A lam[_] : ∀ n {ts : Vec (suc ᵍ⌊ Γ ⌋) n} {A B} → Prov (Γ , A) ts B → Prov Γ (LAMs[ n ] ts) (A ⊃ B) app[_] : ∀ n {ts us : Vec ᵍ⌊ Γ ⌋ n} {A B} → Prov Γ ts (A ⊃ B) → Prov Γ us A → Prov Γ (APPs[ n ] ts us) B pair[_] : ∀ n {ts us : Vec ᵍ⌊ Γ ⌋ n} {A B} → Prov Γ ts A → Prov Γ us B → Prov Γ (PAIRs[ n ] ts us) (A ∧ B) fst[_] : ∀ n {ts : Vec ᵍ⌊ Γ ⌋ n} {A B} → Prov Γ ts (A ∧ B) → Prov Γ (FSTs[ n ] ts) A snd[_] : ∀ n {ts : Vec ᵍ⌊ Γ ⌋ n} {A B} → Prov Γ ts (A ∧ B) → Prov Γ (SNDs[ n ] ts) B up[_] : ∀ n {ts : Vec ᵍ⌊ Γ ⌋ n} {u A} → Prov Γ ts (u ∶ A) → Prov Γ (UPs[ n ] ts) (! u ∶ u ∶ A) down[_] : ∀ n {ts : Vec ᵍ⌊ Γ ⌋ n} {u A} → Prov Γ ts (u ∶ A) → Prov Γ (DOWNs[ n ] ts) A ᵗ⌊_⌋ : ∀ {Γ n A} {ts : Vec ᵍ⌊ Γ ⌋ n} → Prov Γ ts A → Tm ᵍ⌊ Γ ⌋ ᵗ⌊ var[ n ] x ⌋ = VAR[ n ] ⁱ⌊ x ⌋ ᵗ⌊ lam[ n ] j ⌋ = LAM[ n ] ᵗ⌊ j ⌋ ᵗ⌊ app[ n ] j₁ j₂ ⌋ = APP[ n ] ᵗ⌊ j₁ ⌋ ᵗ⌊ j₂ ⌋ ᵗ⌊ pair[ n ] j₁ j₂ ⌋ = PAIR[ n ] ᵗ⌊ j₁ ⌋ ᵗ⌊ j₂ ⌋ ᵗ⌊ fst[ n ] j ⌋ = FST[ n ] ᵗ⌊ j ⌋ ᵗ⌊ snd[ n ] j ⌋ = SND[ n ] ᵗ⌊ j ⌋ ᵗ⌊ up[ n ] j ⌋ = UP[ n ] ᵗ⌊ j ⌋ ᵗ⌊ down[ n ] j ⌋ = DOWN[ n ] ᵗ⌊ j ⌋ true⇒ : ∀ {Γ A} → True Γ A → Prov Γ [] A true⇒ (var x) = var[ 0 ] x true⇒ (lam j) = lam[ 0 ] (true⇒ j) true⇒ (app j₁ j₂) = app[ 0 ] (true⇒ j₁) (true⇒ j₂) true⇒ (pair j₁ j₂) = pair[ 0 ] (true⇒ j₁) (true⇒ j₂) true⇒ (fst j) = fst[ 0 ] (true⇒ j) true⇒ (snd j) = snd[ 0 ] (true⇒ j) true⇒ (up j) = up[ 0 ] (true⇒ j) true⇒ (down j) = down[ 0 ] (true⇒ j) true⇐ : ∀ {Γ A} {ts : Vec ᵍ⌊ Γ ⌋ 0} → Prov Γ ts A → True Γ A true⇐ (var[ .0 ] x) = var x true⇐ (lam[ .0 ] j) = lam (true⇐ j) true⇐ (app[ .0 ] j₁ j₂) = app (true⇐ j₁) (true⇐ j₂) true⇐ (pair[ .0 ] j₁ j₂) = pair (true⇐ j₁) (true⇐ j₂) true⇐ (fst[ .0 ] j) = fst (true⇐ j) true⇐ (snd[ .0 ] j) = snd (true⇐ j) true⇐ (up[ .0 ] j) = up (true⇐ j) true⇐ (down[ .0 ] j) = down (true⇐ j) true⇒⇐-id : ∀ {Γ A} (j : True Γ A) → true⇐ (true⇒ j) ≡ j true⇒⇐-id (var x) = refl true⇒⇐-id (lam j) = cong lam (true⇒⇐-id j) true⇒⇐-id (app j₁ j₂) = cong₂ app (true⇒⇐-id j₁) (true⇒⇐-id j₂) true⇒⇐-id (pair j₁ j₂) = cong₂ pair (true⇒⇐-id j₁) (true⇒⇐-id j₂) true⇒⇐-id (fst j) = cong fst (true⇒⇐-id j) true⇒⇐-id (snd j) = cong snd (true⇒⇐-id j) true⇒⇐-id (up j) = cong up (true⇒⇐-id j) true⇒⇐-id (down j) = cong down (true⇒⇐-id j) true⇗ : ∀ {Γ A} (j : True Γ A) → Prov Γ [ ᵗ⌊ j ⌋ᵀ ] A true⇗ (var x) = var[ 1 ] x true⇗ (lam j) = lam[ 1 ] (true⇗ j) true⇗ (app j₁ j₂) = app[ 1 ] (true⇗ j₁) (true⇗ j₂) true⇗ (pair j₁ j₂) = pair[ 1 ] (true⇗ j₁) (true⇗ j₂) true⇗ (fst j) = fst[ 1 ] (true⇗ j) true⇗ (snd j) = snd[ 1 ] (true⇗ j) true⇗ (up j) = up[ 1 ] (true⇗ j) true⇗ (down j) = down[ 1 ] (true⇗ j) true⇙ : ∀ {Γ n A} {ts : Vec ᵍ⌊ Γ ⌋ n} → Prov Γ ts A → True Γ A true⇙ (var[ n ] x) = var x true⇙ (lam[ n ] j) = lam (true⇙ j) true⇙ (app[ n ] j₁ j₂) = app (true⇙ j₁) (true⇙ j₂) true⇙ (pair[ n ] j₁ j₂) = pair (true⇙ j₁) (true⇙ j₂) true⇙ (fst[ n ] j) = fst (true⇙ j) true⇙ (snd[ n ] j) = snd (true⇙ j) true⇙ (up[ n ] j) = up (true⇙ j) true⇙ (down[ n ] j) = down (true⇙ j) true⇗⇙-id : ∀ {Γ A} (j : True Γ A) → true⇙ (true⇗ j) ≡ j true⇗⇙-id (var x) = refl true⇗⇙-id (lam j) = cong lam (true⇗⇙-id j) true⇗⇙-id (app j₁ j₂) = cong₂ app (true⇗⇙-id j₁) (true⇗⇙-id j₂) true⇗⇙-id (pair j₁ j₂) = cong₂ pair (true⇗⇙-id j₁) (true⇗⇙-id j₂) true⇗⇙-id (fst j) = cong fst (true⇗⇙-id j) true⇗⇙-id (snd j) = cong snd (true⇗⇙-id j) true⇗⇙-id (up j) = cong up (true⇗⇙-id j) true⇗⇙-id (down j) = cong down (true⇗⇙-id j) prov⇗ : ∀ {Γ n A} {ts : Vec ᵍ⌊ Γ ⌋ n} (j : Prov Γ ts A) → Prov Γ (ᵗ⌊ j ⌋ ∷ ts) A prov⇗ (var[ n ] x) = var[ suc n ] x prov⇗ (lam[ n ] j) = lam[ suc n ] (prov⇗ j) prov⇗ (app[ n ] j₁ j₂) = app[ suc n ] (prov⇗ j₁) (prov⇗ j₂) prov⇗ (pair[ n ] j₁ j₂) = pair[ suc n ] (prov⇗ j₁) (prov⇗ j₂) prov⇗ (fst[ n ] j) = fst[ suc n ] (prov⇗ j) prov⇗ (snd[ n ] j) = snd[ suc n ] (prov⇗ j) prov⇗ (up[ n ] j) = up[ suc n ] (prov⇗ j) prov⇗ (down[ n ] j) = down[ suc n ] (prov⇗ j) prov⇙ : ∀ {n Γ A} {ts : Vec ᵍ⌊ Γ ⌋ (suc n)} (j : Prov Γ ts A) → Prov Γ (tail ts) A prov⇙ {n} (var[ .(suc n) ] x) = var[ n ] x prov⇙ {n} (lam[ .(suc n) ] {ts} j) rewrite tail-LAMs ts = lam[ n ] (prov⇙ j) prov⇙ {n} (app[ .(suc n) ] {ts} {us} j₁ j₂) rewrite tail-APPs ts us = app[ n ] (prov⇙ j₁) (prov⇙ j₂) prov⇙ {n} (pair[ .(suc n) ] {ts} {us} j₁ j₂) rewrite tail-PAIRs ts us = pair[ n ] (prov⇙ j₁) (prov⇙ j₂) prov⇙ {n} (fst[ .(suc n) ] {ts} j) rewrite tail-FSTs ts = fst[ n ] (prov⇙ j) prov⇙ {n} (snd[ .(suc n) ] {ts} j) rewrite tail-SNDs ts = snd[ n ] (prov⇙ j) prov⇙ {n} (up[ .(suc n) ] {ts} j) rewrite tail-UPs ts = up[ n ] (prov⇙ j) prov⇙ {n} (down[ .(suc n) ] {ts} j) rewrite tail-DOWNs ts = down[ n ] (prov⇙ j) prov⇗⇙-id : ∀ {Γ n A} {ts : Vec ᵍ⌊ Γ ⌋ n} (j : Prov Γ ts A) → prov⇙ (prov⇗ j) ≡ j prov⇗⇙-id (var[ n ] x) = refl prov⇗⇙-id (lam[ n ] j) = cong lam[ n ] (prov⇗⇙-id j) prov⇗⇙-id (app[ n ] j₁ j₂) = cong₂ app[ n ] (prov⇗⇙-id j₁) (prov⇗⇙-id j₂) prov⇗⇙-id (pair[ n ] j₁ j₂) = cong₂ pair[ n ] (prov⇗⇙-id j₁) (prov⇗⇙-id j₂) prov⇗⇙-id (fst[ n ] j) = cong fst[ n ] (prov⇗⇙-id j) prov⇗⇙-id (snd[ n ] j) = cong snd[ n ] (prov⇗⇙-id j) prov⇗⇙-id (up[ n ] j) = cong up[ n ] (prov⇗⇙-id j) prov⇗⇙-id (down[ n ] j) = cong down[ n ] (prov⇗⇙-id j) ren-prov : ∀ {Γ Γ′ n A} {ts : Vec ᵍ⌊ Γ ⌋ n} (η : Γ′ ⊇ Γ) → Prov Γ ts A → Prov Γ′ (ren-vec ʰ⌊ η ⌋ ts) A ren-prov η (var[ n ] x) rewrite ren-VARs {n} ʰ⌊ η ⌋ ⁱ⌊ x ⌋ | ren-fin-⌊⌋-var η x = var[ n ] (ren-var η x) ren-prov η (lam[ n ] {ts} j) rewrite ren-LAMs ʰ⌊ η ⌋ ts = lam[ n ] (ren-prov (lift η) j) ren-prov η (app[ n ] {ts} {us} j₁ j₂) rewrite ren-APPs ʰ⌊ η ⌋ ts us = app[ n ] (ren-prov η j₁) (ren-prov η j₂) ren-prov η (pair[ n ] {ts} {us} j₁ j₂) rewrite ren-PAIRs ʰ⌊ η ⌋ ts us = pair[ n ] (ren-prov η j₁) (ren-prov η j₂) ren-prov η (fst[ n ] {ts} j) rewrite ren-FSTs ʰ⌊ η ⌋ ts = fst[ n ] (ren-prov η j) ren-prov η (snd[ n ] {ts} j) rewrite ren-SNDs ʰ⌊ η ⌋ ts = snd[ n ] (ren-prov η j) ren-prov η (up[ n ] {ts} j) rewrite ren-UPs ʰ⌊ η ⌋ ts = up[ n ] (ren-prov η j) ren-prov η (down[ n ] {ts} j) rewrite ren-DOWNs ʰ⌊ η ⌋ ts = down[ n ] (ren-prov η j) wk-prov : ∀ {Γ n A C} {ts : Vec ᵍ⌊ Γ ⌋ n} → Prov Γ ts C → Prov (Γ , A) (wk-vec ts) C wk-prov {Γ} rewrite sym (id-⌊⌋-id Γ) = ren-prov ⊇wk wk*-prov : ∀ {Γ n C} {ts : Vec 0 n} → Prov ∅ ts C → Prov Γ (wk*-vec ts) C wk*-prov {Γ} rewrite sym (to-⌊⌋-to Γ) = ren-prov ⊇to v₀[_] : ∀ {Γ} n {A} → Prov (Γ , A) (VARs[ n ] i₀) A v₀[ n ] = var[ n ] x₀ v₁[_] : ∀ {Γ} n {A B} → Prov ((Γ , A) , B) (VARs[ n ] i₁) A v₁[ n ] = var[ n ] x₁ v₂[_] : ∀ {Γ} n {A B C} → Prov (((Γ , A) , B) , C) (VARs[ n ] i₂) A v₂[ n ] = var[ n ] x₂ I[_] : ∀ {Γ} n {A} → Prov Γ (LAMs[ n ] (VARs[ n ] i₀)) (A ⊃ A) I[ n ] = lam[ n ] v₀[ n ] K[_] : ∀ {Γ} n {A B} → Prov Γ (LAMs[ n ] (LAMs[ n ] (VARs[ n ] i₁))) (A ⊃ B ⊃ A) K[ n ] = lam[ n ] (lam[ n ] v₁[ n ]) S[_] : ∀ {Γ} n {A B C} → Prov Γ (LAMs[ n ] (LAMs[ n ] (LAMs[ n ] (APPs[ n ] (APPs[ n ] (VARs[ n ] i₂) (VARs[ n ] i₀)) (APPs[ n ] (VARs[ n ] i₁) (VARs[ n ] i₀)))))) ((A ⊃ B ⊃ C) ⊃ (A ⊃ B) ⊃ A ⊃ C) S[ n ] = lam[ n ] (lam[ n ] (lam[ n ] (app[ n ] (app[ n ] v₂[ n ] v₀[ n ]) (app[ n ] v₁[ n ] v₀[ n ])))) I≡I[0] : ∀ {Γ A} → true⇒ (I {Γ} {A}) ≡ I[ 0 ] I≡I[0] = refl ⇗I≡I[1] : ∀ {Γ A} → true⇗ (I {Γ} {A}) ≡ I[ 1 ] ⇗I≡I[1] = refl ⇗⇗I≡I[2] : ∀ {Γ A} → prov⇗ (true⇗ (I {Γ} {A})) ≡ I[ 2 ] ⇗⇗I≡I[2] = refl