module A201802.WIP.NotLocallyNameless where
open import A201801.Prelude
open import A201801.Category
open import A201801.List
open import A201801.ListLemmas
open import A201801.AllList
open import A201801.FullIPLPropositions
open import A201802.WIP.Bool
open import A201802.WIP.Name
open import A201802.WIP.ListRemovals
fresh : Name → List Name → Bool
fresh x ∙ = true
fresh x (И , y) = and (x ≠ y) (fresh x И)
_∪_ : List Name → List Name → List Name
И₁ ∪ ∙ = И₁
И₁ ∪ (И₂ , x) with fresh x И₁
И₁ ∪ (И₂ , x) | true = (И₁ ∪ И₂) , x
И₁ ∪ (И₂ , x) | false = И₁ ∪ И₂
lem∪₁ : ∀ x И₁ И₂ → {{_ : T (fresh x (И₁ ∪ И₂))}}
→ T (fresh x И₁)
lem∪₁ x И₁ ∙ {{φ}} = φ
lem∪₁ x И₁ (И₂ , y) with fresh y И₁
lem∪₁ x И₁ (И₂ , y) | true = lem∪₁ x И₁ И₂ {{lem-and₂ x y}}
lem∪₁ x И₁ (И₂ , y) | false = lem∪₁ x И₁ И₂
lem-and∪ : ∀ x y И₁ И₂ → {{_ : T (fresh x ((И₁ , y) ∪ И₂))}}
→ T (and (x ≠ y) (fresh x (И₁ ∪ И₂)))
lem-and∪ x y И₁ ∙ {{φ}} = φ
lem-and∪ x y И₁ (И₂ , z) with fresh z И₁
lem-and∪ x y И₁ (И₂ , z) | true with z ≟ y
lem-and∪ x y И₁ (И₂ , .y) | true | yes refl with x ≟ y
lem-and∪ x .x И₁ (И₂ , .x) | true | yes refl | yes refl = lem-and∪ x x И₁ И₂ ↯ lem-and₃ x
lem-and∪ x y И₁ (И₂ , .y) | true | yes refl | no x≢y = lem-and₂ x y {{lem-and∪ x y И₁ И₂}}
lem-and∪ x y И₁ (И₂ , z) | true | no z≢y with x ≟ y
lem-and∪ x .x И₁ (И₂ , z) | true | no z≢y | yes refl = lem-and∪ x x И₁ И₂ {{lem-and₂ x z}} ↯ lem-and₃ x
lem-and∪ x y И₁ (И₂ , z) {{φ}} | true | no z≢y | no x≢y = lem-and₅ x z {{lem-and₄ x z {{φ}}}}
{{lem-and₂ x y {{lem-and∪ x y И₁ И₂ {{lem-and₂ x z}}}}}}
lem-and∪ x y И₁ (И₂ , z) | false with x ≟ y
lem-and∪ x .x И₁ (И₂ , z) | false | yes refl with z ≟ x
lem-and∪ x .x И₁ (И₂ , .x) | false | yes refl | yes refl = lem-and∪ x x И₁ И₂ ↯ lem-and₃ x
lem-and∪ x .x И₁ (И₂ , z) | false | yes refl | no z≢x = lem-and∪ x x И₁ И₂ ↯ lem-and₃ x
lem-and∪ x y И₁ (И₂ , z) | false | no x≢y with z ≟ y
lem-and∪ x y И₁ (И₂ , .y) | false | no x≢y | yes refl = lem-and₂ x y {{lem-and∪ x y И₁ И₂}}
lem-and∪ x y И₁ (И₂ , z) | false | no x≢y | no z≢y = lem-and₂ x y {{lem-and∪ x y И₁ И₂}}
lid∪ : ∀ И → ∙ ∪ И ≡ И
lid∪ ∙ = refl
lid∪ (И , x) = (_, x) & lid∪ И
lem∪₂ : ∀ x И₁ И₂ → {{_ : T (fresh x (И₁ ∪ И₂))}}
→ T (fresh x И₂)
lem∪₂ x ∙ И₂ {{φ}} rewrite lid∪ И₂ = φ
lem∪₂ x (И₁ , y) И₂ = lem∪₂ x И₁ И₂ {{lem-and₂ x y {{lem-and∪ x y И₁ И₂}}}}
lem∪₃ : ∀ x И₁ И₂ → {{_ : T (fresh x И₁)}} {{_ : T (fresh x И₂)}}
→ T (fresh x (И₁ ∪ И₂))
lem∪₃ x И₁ ∙ {{φ₁}} {{φ₂}} = φ₁
lem∪₃ x И₁ (И₂ , y) {{φ₁}} {{φ₂}} with fresh y И₁
lem∪₃ x И₁ (И₂ , y) {{φ₁}} {{φ₂}} | true = lem-and₅ x y {{lem-and₄ x y {{φ₂}}}}
{{lem∪₃ x И₁ И₂ {{φ₁}} {{lem-and₂ x y {{φ₂}}}}}}
lem∪₃ x И₁ (И₂ , y) {{φ₁}} {{φ₂}} | false = lem∪₃ x И₁ И₂ {{φ₁}} {{lem-and₂ x y {{φ₂}}}}
infix 3 _⊢_true
data _⊢_true : List Form → Form → Set
where
fvar : ∀ {A Γ} → Name
→ Γ ⊢ A true
bvar : ∀ {A Γ} → Γ ∋ A
→ Γ ⊢ A true
lam : ∀ {A B Γ} → Γ , A ⊢ B true
→ Γ ⊢ A ⊃ B true
app : ∀ {A B Γ} → Γ ⊢ A ⊃ B true → Γ ⊢ A true
→ Γ ⊢ B true
pair : ∀ {A B Γ} → Γ ⊢ A true → Γ ⊢ B true
→ Γ ⊢ A ∧ B true
fst : ∀ {A B Γ} → Γ ⊢ A ∧ B true
→ Γ ⊢ A true
snd : ∀ {A B Γ} → Γ ⊢ A ∧ B true
→ Γ ⊢ B true
unit : ∀ {Γ} → Γ ⊢ 𝟏 true
abort : ∀ {C Γ} → Γ ⊢ 𝟎 true
→ Γ ⊢ C true
inl : ∀ {A B Γ} → Γ ⊢ A true
→ Γ ⊢ A ∨ B true
inr : ∀ {A B Γ} → Γ ⊢ B true
→ Γ ⊢ A ∨ B true
case : ∀ {A B C Γ} → Γ ⊢ A ∨ B true → Γ , A ⊢ C true → Γ , B ⊢ C true
→ Γ ⊢ C true
fvs : ∀ {Γ A} → Γ ⊢ A true
→ List Name
fvs (fvar x) = ∙ , x
fvs (bvar i) = ∙
fvs (lam 𝒟) = fvs 𝒟
fvs (app 𝒟 ℰ) = fvs 𝒟 ∪ fvs ℰ
fvs (pair 𝒟 ℰ) = fvs 𝒟 ∪ fvs ℰ
fvs (fst 𝒟) = fvs 𝒟
fvs (snd 𝒟) = fvs 𝒟
fvs unit = ∙
fvs (abort 𝒟) = fvs 𝒟
fvs (inl 𝒟) = fvs 𝒟
fvs (inr 𝒟) = fvs 𝒟
fvs (case 𝒟 ℰ ℱ) = fvs 𝒟 ∪ (fvs ℰ ∪ fvs ℱ)
free : ∀ {Γ A C} x → (i : Γ ∋ A) (𝒟 : Γ ⊢ C true) {{_ : T (fresh x (fvs 𝒟))}} → Γ - i ⊢ C true
free x i (fvar y) = fvar y
free x i (bvar j) with i ≟∋ j
free x i (bvar .i) | same .i = fvar x
free x i (bvar ._) | diff .i j = bvar j
free x i (lam 𝒟) = lam (free x (suc i) 𝒟)
free x i (app 𝒟 ℰ) = app (free x i 𝒟 {{lem∪₁ x (fvs 𝒟) (fvs ℰ)}})
(free x i ℰ {{lem∪₂ x (fvs 𝒟) (fvs ℰ)}})
free x i (pair 𝒟 ℰ) = pair (free x i 𝒟 {{lem∪₁ x (fvs 𝒟) (fvs ℰ)}})
(free x i ℰ {{lem∪₂ x (fvs 𝒟) (fvs ℰ)}})
free x i (fst 𝒟) = fst (free x i 𝒟)
free x i (snd 𝒟) = snd (free x i 𝒟)
free x i unit = unit
free x i (abort 𝒟) = abort (free x i 𝒟)
free x i (inl 𝒟) = inl (free x i 𝒟)
free x i (inr 𝒟) = inr (free x i 𝒟)
free x i (case 𝒟 ℰ ℱ) = case (free x i 𝒟 {{lem∪₁ x (fvs 𝒟) (fvs ℰ ∪ fvs ℱ)}})
(free x (suc i) ℰ {{lem∪₁ x (fvs ℰ) (fvs ℱ) {{lem∪₂ x (fvs 𝒟) (fvs ℰ ∪ fvs ℱ)}}}})
(free x (suc i) ℱ {{lem∪₂ x (fvs ℰ) (fvs ℱ) {{lem∪₂ x (fvs 𝒟) (fvs ℰ ∪ fvs ℱ)}}}})
free-lam : ∀ {Γ A B} x → {𝒟 : Γ , A ⊢ B true}
(𝒟′ : Γ ⊢ A ⊃ B true) {{_ : 𝒟′ ≡ lam 𝒟}}
{{_ : T (fresh x (fvs 𝒟))}}
→ Γ ⊢ B true
free-lam x (lam 𝒟) {{refl}} = free x zero 𝒟
free-case : ∀ {Γ A B C} x y → {𝒟 : Γ ⊢ A ∨ B true} {ℰ : Γ , A ⊢ C true} {ℱ : Γ , B ⊢ C true}
(𝒟′ : Γ ⊢ C true) {{_ : 𝒟′ ≡ case 𝒟 ℰ ℱ}}
{{_ : T (fresh x (fvs ℰ))}} {{_ : T (fresh y (fvs ℱ))}}
→ Γ ⊢ A ∨ B true × Γ ⊢ C true × Γ ⊢ C true
free-case x y (case 𝒟 ℰ ℱ) {{refl}} = 𝒟 , free x zero ℰ , free y zero ℱ