module A201605.AltArtemov.Try2.ProvVec where
open import A201605.AltArtemov.Try2.True renaming (ᵗ⌊_⌋ to ᵗ⌊_⌋ᵀ) public
data Prov (Γ : Cx) : ∀ {k n} → Vec ᵍ⌊ Γ ⌋ k n → Ty k → Set where
var : ∀ {k n} {A : Ty k} (x : Var Γ A) →
Prov Γ (VARs {k = k} {n = n} ⁱ⌊ x ⌋) A
lam : ∀ {k n} {ts : Vec (suc ᵍ⌊ Γ ⌋) k n} {A B : Ty k} → Prov (Γ , A) ts B →
Prov Γ (LAMs ts) (A ⊃ B)
app : ∀ {k n} {ts₁ ts₂ : Vec ᵍ⌊ Γ ⌋ k n} {A B : Ty k} → Prov Γ ts₁ (A ⊃ B) → Prov Γ ts₂ A →
Prov Γ (APPs ts₁ ts₂) B
pair : ∀ {k n} {ts₁ ts₂ : Vec ᵍ⌊ Γ ⌋ k n} {A B : Ty k} → Prov Γ ts₁ A → Prov Γ ts₂ B →
Prov Γ (PAIRs ts₁ ts₂) (A ∧ B)
fst : ∀ {k n} {ts : Vec ᵍ⌊ Γ ⌋ k n} {A B : Ty k} → Prov Γ ts (A ∧ B) →
Prov Γ (FSTs ts) A
snd : ∀ {k n} {ts : Vec ᵍ⌊ Γ ⌋ k n} {A B : Ty k} → Prov Γ ts (A ∧ B) →
Prov Γ (SNDs ts) B
up : ∀ {k n} {ts : Vec ᵍ⌊ Γ ⌋ (suc k) n} {u : Tm 0 k} {A : Ty k} → Prov Γ ts (u ∶ A) →
Prov Γ (UPs ts) ((! u ∶ u ∶ A))
down : ∀ {k n} {ts : Vec ᵍ⌊ Γ ⌋ (suc k) n} {u : Tm 0 k} {A : Ty k} → Prov Γ ts (u ∶ A) →
Prov Γ (DOWNs ts) A
ᵗ⌊_⌋ : ∀ {Γ k n} {A : Ty k} {ts : Vec ᵍ⌊ Γ ⌋ k n} → Prov Γ ts A → Tm ᵍ⌊ Γ ⌋ (n + k)
ᵗ⌊ var x ⌋ = VAR ⁱ⌊ x ⌋
ᵗ⌊ lam j ⌋ = LAM ᵗ⌊ j ⌋
ᵗ⌊ app j₁ j₂ ⌋ = APP ᵗ⌊ j₁ ⌋ ᵗ⌊ j₂ ⌋
ᵗ⌊ pair j₁ j₂ ⌋ = PAIR ᵗ⌊ j₁ ⌋ ᵗ⌊ j₂ ⌋
ᵗ⌊ fst j ⌋ = FST ᵗ⌊ j ⌋
ᵗ⌊ snd j ⌋ = SND ᵗ⌊ j ⌋
ᵗ⌊_⌋ {Γ} {n = n} (up {k} j) = subst (Tm ᵍ⌊ Γ ⌋) (suc-plus (suc k) n) (UP ᵗ⌊ j ⌋)
ᵗ⌊_⌋ {Γ} {n = n} (down {k} j) = DOWN (subst (Tm ᵍ⌊ Γ ⌋) (sym (suc-plus k n)) ᵗ⌊ j ⌋)
true⇒ : ∀ {Γ k} {A : Ty k} → True Γ A → Prov Γ [] A
true⇒ (var x) = var x
true⇒ (lam j) = lam (true⇒ j)
true⇒ (app j₁ j₂) = app (true⇒ j₁) (true⇒ j₂)
true⇒ (pair j₁ j₂) = pair (true⇒ j₁) (true⇒ j₂)
true⇒ (fst j) = fst (true⇒ j)
true⇒ (snd j) = snd (true⇒ j)
true⇒ (up j) = up (true⇒ j)
true⇒ (down j) = down (true⇒ j)
true⇐ : ∀ {Γ k} {A : Ty k} {ts : Vec ᵍ⌊ Γ ⌋ k 0} → Prov Γ ts A → True Γ A
true⇐ (var x) = var x
true⇐ (lam j) = lam (true⇐ j)
true⇐ (app j₁ j₂) = app (true⇐ j₁) (true⇐ j₂)
true⇐ (pair j₁ j₂) = pair (true⇐ j₁) (true⇐ j₂)
true⇐ (fst j) = fst (true⇐ j)
true⇐ (snd j) = snd (true⇐ j)
true⇐ (up j) = up (true⇐ j)
true⇐ (down j) = down (true⇐ j)
true⇒⇐-id : ∀ {Γ k} {A : Ty k} (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⇗ : ∀ {Γ k} {A : Ty k} (j : True Γ A) → Prov Γ [ ᵗ⌊ j ⌋ᵀ ] A
true⇗ (var x) = var x
true⇗ (lam j) = lam (true⇗ j)
true⇗ (app j₁ j₂) = app (true⇗ j₁) (true⇗ j₂)
true⇗ (pair j₁ j₂) = pair (true⇗ j₁) (true⇗ j₂)
true⇗ (fst j) = fst (true⇗ j)
true⇗ (snd j) = snd (true⇗ j)
true⇗ (up j) = up (true⇗ j)
true⇗ (down j) = down (true⇗ j)
true⇙ : ∀ {Γ k n} {A : Ty k} {ts : Vec ᵍ⌊ Γ ⌋ k n} → Prov Γ ts A → True Γ A
true⇙ (var x) = var x
true⇙ (lam j) = lam (true⇙ j)
true⇙ (app j₁ j₂) = app (true⇙ j₁) (true⇙ j₂)
true⇙ (pair j₁ j₂) = pair (true⇙ j₁) (true⇙ j₂)
true⇙ (fst j) = fst (true⇙ j)
true⇙ (snd j) = snd (true⇙ j)
true⇙ (up j) = up (true⇙ j)
true⇙ (down j) = down (true⇙ j)
true⇗⇙-id : ∀ {Γ k} {A : Ty k} (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⇗ : ∀ {Γ k n} {A : Ty k} {ts : Vec ᵍ⌊ Γ ⌋ k n} (j : Prov Γ ts A) →
Prov Γ (ᵗ⌊ j ⌋ ∷ ts) A
prov⇗ (var x) = var x
prov⇗ (lam j) = lam (prov⇗ j)
prov⇗ (app j₁ j₂) = app (prov⇗ j₁) (prov⇗ j₂)
prov⇗ (pair j₁ j₂) = pair (prov⇗ j₁) (prov⇗ j₂)
prov⇗ (fst j) = fst (prov⇗ j)
prov⇗ (snd j) = snd (prov⇗ j)
prov⇗ (up j) = up (prov⇗ j)
prov⇗ (down j) = down (prov⇗ j)
prov⇙ : ∀ {Γ k n} {A : Ty k} {ts : Vec ᵍ⌊ Γ ⌋ k (suc n)} (j : Prov Γ ts A) →
Prov Γ (tail ts) A
prov⇙ (var x) = var x
prov⇙ (lam {ts = ts} j) rewrite tail-LAMs ts = lam (prov⇙ j)
prov⇙ (app {ts₁ = ts₁} {ts₂} j₁ j₂) rewrite tail-APPs ts₁ ts₂ = app (prov⇙ j₁) (prov⇙ j₂)
prov⇙ (pair {ts₁ = ts₁} {ts₂} j₁ j₂) rewrite tail-PAIRs ts₁ ts₂ = pair (prov⇙ j₁) (prov⇙ j₂)
prov⇙ (fst {ts = ts}j) rewrite tail-FSTs ts = fst (prov⇙ j)
prov⇙ (snd {ts = ts}j) rewrite tail-SNDs ts = snd (prov⇙ j)
prov⇙ (up {ts = ts}j) rewrite tail-UPs ts = up (prov⇙ j)
prov⇙ (down {ts = ts}j) rewrite tail-DOWNs ts = down (prov⇙ j)
prov⇗⇙-id : ∀ {Γ k n} {A : Ty k} {ts : Vec ᵍ⌊ Γ ⌋ k n} (j : Prov Γ ts A) →
prov⇙ (prov⇗ j) ≡ j
prov⇗⇙-id (var x) = refl
prov⇗⇙-id (lam j) = cong lam (prov⇗⇙-id j)
prov⇗⇙-id (app j₁ j₂) = cong₂ app (prov⇗⇙-id j₁) (prov⇗⇙-id j₂)
prov⇗⇙-id (pair j₁ j₂) = cong₂ pair (prov⇗⇙-id j₁) (prov⇗⇙-id j₂)
prov⇗⇙-id (fst j) = cong fst (prov⇗⇙-id j)
prov⇗⇙-id (snd j) = cong snd (prov⇗⇙-id j)
prov⇗⇙-id (up j) = cong up (prov⇗⇙-id j)
prov⇗⇙-id (down j) = cong down (prov⇗⇙-id j)
_∴_ : ∀ {Γ k n} (ts : Vec ᵍ⌊ Γ ⌋ k n) (A : Ty k) → Ty (n + k)
[] ∴ A = A
(t ∷ ts) ∴ A = t ∶ (ts ∴ A)
infixr 15 _∴_