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