----------------------------------------------------------------------------------------------------
-- strong normalization for open terms, hopefully after Schäfer
-- TODO: needs doing
module A202401.STLC-Base-WNF-CBV-SN2 where
open import A202401.STLC-Base-WNF-CBV public
----------------------------------------------------------------------------------------------------
mutual
HWN : ∀ {Γ A} → Γ ⊢ A → Set
HWN t = WN t × HWN! t
HWN! : ∀ {A Γ} → Γ ⊢ A → Set
HWN! {⌜◦⌝} t = 𝟙
HWN! {A ⌜⊃⌝ B} t₁ = ∀ {t₂} → HWN t₂ → HWN (t₁ ⌜$⌝ t₂)
mutual
stepHWN : ∀ {Γ A} {t t′ : Γ ⊢ A} → t ⇒ t′ → HWN t′ → HWN t
stepHWN r (wn′ , hwn!′) = stepWN r wn′ , stepHWN! r hwn!′
stepHWN! : ∀ {A Γ} {t t′ : Γ ⊢ A} → t ⇒ t′ → HWN! t′ → HWN! t
stepHWN! {⌜◦⌝} r unit = unit
stepHWN! {A ⌜⊃⌝ B} {t₁} r f hwn₂′ = stepHWN (cong$₁ r) (f hwn₂′)
step⇒*HWN : ∀ {Γ A} {t t′ : Γ ⊢ A} → t ⇒* t′ → HWN t′ → HWN t
step⇒*HWN done hwn′ = hwn′
step⇒*HWN (step r rs) hwn′ = stepHWN r (step⇒*HWN rs hwn′)
step⇓HWN : ∀ {Γ A} {t t′ : Γ ⊢ A} → t ⇓ t′ → HWN t′ → HWN t
step⇓HWN = step⇒*HWN ∘ fst
mutual
skipHWN : ∀ {Γ A} {t t′ : Γ ⊢ A} → t ⇒ t′ → HWN t → HWN t′
skipHWN r (wn , hwn!) = skipWN r wn , skipHWN! r hwn!
skipHWN! : ∀ {A Γ} {t t′ : Γ ⊢ A} → t ⇒ t′ → HWN! t → HWN! t′
skipHWN! {⌜◦⌝} r unit = unit
skipHWN! {A ⌜⊃⌝ B} r f hwn₂ = skipHWN (cong$₁ r) (f hwn₂)
skip⇒*HWN : ∀ {Γ A} {t t′ : Γ ⊢ A} → t ⇒* t′ → HWN t → HWN t′
skip⇒*HWN done hwn = hwn
skip⇒*HWN (step r rs) hwn = skip⇒*HWN rs (skipHWN r hwn)
skip⇓HWN : ∀ {Γ A} {t t′ : Γ ⊢ A} → t ⇓ t′ → HWN t → HWN t′
skip⇓HWN = skip⇒*HWN ∘ fst
----------------------------------------------------------------------------------------------------
-- mutual
-- renHWN : ∀ {Γ Γ′ A} {t : Γ ⊢ A} (e : Γ ⊆ Γ′) → HWN t → HWN (ren⊢ e t)
-- renHWN e (wn@(t′ , rs , p′) , hwn!) = renWN e wn , renHWN! e hwn!
-- renHWN! : ∀ {A Γ Γ′} {t : Γ ⊢ A} (e : Γ ⊆ Γ′) → HWN! t → HWN! (ren⊢ e t)
-- renHWN! {⌜◦⌝} e unit = unit
-- renHWN! {A ⌜⊃⌝ B} {t₁} e f {t₂} e′ hwn₂@(wn₂@(t₂′ , n₂@(rs₂ , p₂′)) , hwn!₂) =
-- {!!}
-- -- -- let z : HWN (ren⊢ e t₁ ⌜$⌝ t₂)
-- -- -- z = {!!}
-- -- -- in {!!} -- renHWN e (({!!} , ({!!} , {!!})) , {!!}) in {!!}
-- -- -- -- ((ren⊢ e t₁ ⌜$⌝ t₂′) , cong$₂⇒* {!!} rs₂ , {!!}) ,
-- -- -- -- {!!}
-- -- -- ----------------------------------------------------------------------------------------------------
-- -- -- data HWN* {Γ} : ∀ {Δ} → Γ ⊢* Δ → Set where
-- -- -- [] : HWN* []
-- -- -- _∷_ : ∀ {A Δ} {t : Γ ⊢ A} {ts : Γ ⊢* Δ} → HWN t → HWN* ts → HWN* (t ∷ ts)
-- -- -- {-
-- -- -- ren⊢* : ∀ {Γ Γ′ Δ} → Γ ⊆ Γ′ → Γ ⊢* Δ → Γ′ ⊢* Δ
-- -- -- ren⊢* e [] = []
-- -- -- ren⊢* e (t ∷ ts) = ren⊢ e t ∷ ren⊢* e ts
-- -- -- weak⊢* : ∀ {Γ Δ A} → Γ ⊢* Δ → A ∷ Γ ⊢* Δ
-- -- -- -}
-- -- -- postulate
-- -- -- lem₋₁ : ∀ {Γ A} → weak⊢* {Γ} {Γ} {A} (refl⊢* {Γ = Γ}) ≡ {!refl⊢* {Γ = A ∷ Γ}!}
-- -- -- mutual
-- -- -- hmm : ∀ {Γ A} → HWN {A ∷ Γ} {A} (var zero)
-- -- -- hmm = (var zero , done , nnf var-) , hmm!
-- -- -- hmm! : ∀ {Γ} → HWN! {A ∷ Γ} {A} (var zero)
-- -- -- hmm! {⌜◦⌝} = unit
-- -- -- hmm! {A ⌜⊃⌝ B} ((t₂′ , rs , p₂′) , hwn!₂) =
-- -- -- (var zero ⌜$⌝ t₂′ , cong$₂⇒* (nnf var-) rs , nnf (var- ⌜$⌝ p₂′)) ,
-- -- -- {!!}
-- -- -- refl⊢*HWN* : ∀ {Γ} → HWN* {Γ} refl⊢*
-- -- -- refl⊢*HWN* {[]} = []
-- -- -- refl⊢*HWN* {A ∷ Γ} = hmm ∷ {!refl⊢*HWN* {A ∷ Γ}!}
-- -- -- ----------------------------------------------------------------------------------------------------
-- -- -- lem₀ : ∀ {Γ Ξ A B} (ss : Ξ ⊢* Γ) (t₁ : A ∷ Γ ⊢ B) (t₂ : Ξ ⊢ A) →
-- -- -- (sub⊢ (t₂ ∷ id⊢*) ∘ sub⊢ (lift⊢* ss)) t₁ ≡ sub⊢ (t₂ ∷ ss) t₁
-- -- -- lem₀ ss t₁ t₂ = compsub⊢ (t₂ ∷ id⊢*) (lift⊢* ss) t₁ ⁻¹
-- -- -- ⋮ (flip sub⊢ t₁ ∘ (t₂ ∷_)) & ( eqsub⊢* t₂ id⊢* ss
-- -- -- ⋮ lidsub⊢* ss
-- -- -- )
-- -- -- lem₁ : ∀ {Γ Ξ A B} (ss : Ξ ⊢* Γ) (t₁ : A ∷ Γ ⊢ B) {t₂ : Ξ ⊢ A} (p₂ : NF t₂) →
-- -- -- ⌜λ⌝ (sub⊢ (lift⊢* ss) t₁) ⌜$⌝ t₂ ⇒ sub⊢ (t₂ ∷ ss) t₁
-- -- -- lem₁ ss t₁ p₂ = βred⊃ (sym (lem₀ ss t₁ _)) p₂
-- -- -- lem₂ : ∀ {Γ Ξ A B} (ss : Ξ ⊢* Γ) (t₁ : A ∷ Γ ⊢ B) {t₂ : Ξ ⊢ A} (p₂ : NF t₂) {t′ : Ξ ⊢ B} →
-- -- -- sub⊢ (t₂ ∷ ss) t₁ ⇓ t′ →
-- -- -- ⌜λ⌝ (sub⊢ (lift⊢* ss) t₁) ⌜$⌝ t₂ ⇓ t′
-- -- -- lem₂ ss t₁ p₂ (rs , p′) = (step (lem₁ ss t₁ p₂) rs) , p′
-- -- -- lem₃ : ∀ {Γ Ξ A B} (ss : Ξ ⊢* Γ) (t₁ : A ∷ Γ ⊢ B) {t₂ : Ξ ⊢ A} (p₂ : NF t₂) →
-- -- -- WN (sub⊢ (t₂ ∷ ss) t₁) →
-- -- -- WN (⌜λ⌝ (sub⊢ (lift⊢* ss) t₁) ⌜$⌝ t₂)
-- -- -- lem₃ ss t₁ p₂ (t′ , n) = t′ , lem₂ ss t₁ p₂ n
-- -- -- mutual
-- -- -- lem₄ : ∀ {Γ Ξ A B} (ss : Ξ ⊢* Γ) (t₁ : A ∷ Γ ⊢ B) {t₂ : Ξ ⊢ A} (p₂ : NF t₂) →
-- -- -- HWN (sub⊢ (t₂ ∷ ss) t₁) →
-- -- -- HWN (⌜λ⌝ (sub⊢ (lift⊢* ss) t₁) ⌜$⌝ t₂)
-- -- -- lem₄ ss t₁ p₂ (wn , hwn!) = lem₃ ss t₁ p₂ wn , lem₄! ss t₁ p₂ hwn!
-- -- -- lem₄! : ∀ {Γ Ξ A B} (ss : Ξ ⊢* Γ) (t₁ : A ∷ Γ ⊢ B) {t₂ : Ξ ⊢ A} (p₂ : NF t₂) →
-- -- -- HWN! (sub⊢ (t₂ ∷ ss) t₁) →
-- -- -- HWN! (⌜λ⌝ (sub⊢ (lift⊢* ss) t₁) ⌜$⌝ t₂)
-- -- -- lem₄! {B = ⌜◦⌝} ss t₁ p₂ unit = unit
-- -- -- lem₄! {B = B₁ ⌜⊃⌝ B₂} ss t₁ p₂ f hwn₂ = stepHWN (cong$₁ (lem₁ ss t₁ p₂)) (f hwn₂)
-- -- -- sub∋HWN : ∀ {Γ Ξ A} {ss : Ξ ⊢* Γ} (hwns : HWN* ss) (i : Γ ∋ A) → HWN (sub∋ ss i)
-- -- -- sub∋HWN (hwn ∷ hwns) zero = hwn
-- -- -- sub∋HWN (hwn ∷ hwns) (suc i) = sub∋HWN hwns i
-- -- -- mutual
-- -- -- lem₅ : ∀ {Γ Ξ A B} (ss : Ξ ⊢* Γ) (hwns : HWN* ss) (t₁ : A ∷ Γ ⊢ B) (t₁′ : Ξ ⊢ A ⌜⊃⌝ B) {t₂ : Ξ ⊢ A} →
-- -- -- HWN t₂ → HWN (⌜λ⌝ (sub⊢ (lift⊢* ss) t₁) ⌜$⌝ t₂)
-- -- -- lem₅ ss hwns t₁ t₁′ hwn₂@((t₂′ , n₂@(rs₂ , p₂′)) , hwn!₂) =
-- -- -- let hwn₂′ = skip⇓HWN n₂ hwn₂
-- -- -- in step⇒*HWN (cong$₂⇒* ⌜λ⌝- rs₂) (lem₄ ss t₁ p₂′ (sub⊢HWN (t₂′ ∷ ss) (hwn₂′ ∷ hwns) t₁))
-- -- -- sub⊢HWN : ∀ {Γ Ξ A} (ss : Ξ ⊢* Γ) (hwns : HWN* ss) (t : Γ ⊢ A) → HWN (sub⊢ ss t)
-- -- -- sub⊢HWN ss hwns (var i) = sub∋HWN hwns i
-- -- -- sub⊢HWN ss hwns (⌜λ⌝ t) = let t′ = sub⊢ ss (⌜λ⌝ t)
-- -- -- in (t′ , done , ⌜λ⌝-) , λ {t₂} → lem₅ ss hwns t t′ {t₂}
-- -- -- sub⊢HWN ss hwns (t₁ ⌜$⌝ t₂) = let wn , hwn! = sub⊢HWN ss hwns t₁
-- -- -- in hwn! (sub⊢HWN ss hwns t₂)
-- -- -- hwn : ∀ {Γ A} (t : Γ ⊢ A) → HWN t
-- -- -- hwn t = subst HWN (idsub⊢ t) (sub⊢HWN refl⊢* refl⊢*HWN* t)
-- -- -- wn : ∀ {Γ A} (t : Γ ⊢ A) → WN t
-- -- -- wn = proj₁ ∘ hwn
-- -- -- ----------------------------------------------------------------------------------------------------
-- -- -- data SN {Γ A} (t : Γ ⊢ A) : Set where
-- -- -- make : (∀ {t′} → t ⇒ t′ → SN t′) → SN t
-- -- -- recSN : ∀ {𝓍} (X : ∀ {Γ A} → Γ ⊢ A → Set 𝓍) {Γ A} {t : Γ ⊢ A} → SN t →
-- -- -- (∀ {t} → (∀ {t′} → t ⇒ t′ → X t′) → X t) →
-- -- -- X t
-- -- -- recSN X (make h) f = f λ r → recSN X (h r) f
-- -- -- SN→WN : ∀ {Γ A} {t : Γ ⊢ A} → SN t → WN t
-- -- -- SN→WN sn = recSN WN sn aux
-- -- -- where
-- -- -- aux : ∀ {t} → (∀ {t′} → t ⇒ t′ → WN t′) → WN t
-- -- -- aux {t} h with prog⇒ t
-- -- -- ... | done p = _ , done , p
-- -- -- ... | step r = let _ , rs , p′ = h r
-- -- -- in _ , step r rs , p′
-- -- -- WN→SN : ∀ {Γ A} {t : Γ ⊢ A} → WN t → SN t
-- -- -- WN→SN (t′ , done , p′) = make λ r → r ↯ NF→¬R p′
-- -- -- WN→SN (t′ , step r rs , p′) = make λ r′ → subst SN (det⇒ r r′) (WN→SN (t′ , rs , p′))
-- -- -- sn : ∀ {A} (t : [] ⊢ A) → SN t
-- -- -- sn = WN→SN ∘ wn
-- -- -- ----------------------------------------------------------------------------------------------------