{-# OPTIONS --rewriting #-}
module A201802.WIP.LR3 where
open import A201801.Prelude
open import A201801.Category
open import A201801.Fin
open import A201801.FinLemmas
open import A201801.Vec
open import A201801.VecLemmas
open import A201801.AllVec
open import A201802.LR0
open import A201802.LR0Lemmas
open import A201802.LR1
open import A201802.LR2 -- TODO: which LR2?
postulate
oops : ∀ {ℓ} → {X : Set ℓ} → X
--------------------------------------------------------------------------------
-- `SN _ A` is the strong normalisation predicate on terms at type `A`.
mutual
SN : Term 0 → Type → Set
SN M A = ∙ ⊢ M ⦂ A × M ⇓ × SN! M A
SN! : Term 0 → Type → Set
SN! M 𝔹 = ⊤
SN! M (A ∨ B) = oops
SN! M 𝟘 = ⊥
SN! M 𝟙 = ⊤
SN! M (A ∧ B) = SN (FST M) A × SN (SND M) B
SN! M (A ⊃ B) = ∀ {N} → SN N A → SN (APP M N) B
-- Every SN term is well-typed.
derp : ∀ {A M} → SN M A
→ ∙ ⊢ M ⦂ A
derp (𝒟 , M⇓ , s!) = 𝒟
--------------------------------------------------------------------------------
-- `SNs _ Γ` is the strong normalisation predicate on substitutions at all types `Γ`.
SNs : ∀ {g} → (τ : Terms 0 g) → Types g → Set
SNs τ Γ = All (\ { (M , A) → SN M A }) (zip τ Γ)
-- Every SN substitution is well-typed.
derps : ∀ {g} → {τ : Terms 0 g} {Γ : Types g}
→ SNs τ Γ
→ ∙ ⊢ τ ⦂ Γ all
derps σ = maps derp σ
--------------------------------------------------------------------------------
-- -- Small-step reduction IN REVERSE preserves SN.
-- mutual
-- snpr↦ : ∀ {A M M′} → M ↦ M′ → ∙ ⊢ M ⦂ A → SN M′ A
-- → SN M A
-- snpr↦ M↦M′ 𝒟 (𝒟′ , M′⇓ , s!′) = 𝒟 , hpr↦ M↦M′ M′⇓ , sn!pr↦ M↦M′ 𝒟 s!′
-- sn!pr↦ : ∀ {A M M′} → M ↦ M′ → ∙ ⊢ M ⦂ A → SN! M′ A
-- → SN! M A
-- sn!pr↦ {𝔹} M↦M′ 𝒟 ∙ = ∙
-- sn!pr↦ {A ∨ B} M↦M′ 𝒟 x = oops
-- sn!pr↦ {𝟘} M↦M′ 𝒟 ()
-- sn!pr↦ {𝟙} M↦M′ 𝒟 ∙ = ∙
-- sn!pr↦ {A ∧ B} M↦M′ 𝒟 (s₁ , s₂) = snpr↦ (cong-fst M↦M′) (fst 𝒟) s₁ , snpr↦ (cong-snd M↦M′) (snd 𝒟) s₂
-- sn!pr↦ {A ⊃ B} M↦M′ 𝒟 f s = snpr↦ (cong-app₁ M↦M′) (app 𝒟 (derp s)) (f s)
-- -- Iterated small-step reduction IN REVERSE preserves SN.
-- snpr⤅ : ∀ {A M M′} → M ⤅ M′ → ∙ ⊢ M ⦂ A → SN M′ A
-- → SN M A
-- snpr⤅ done 𝒟 s = s
-- snpr⤅ (step M↦M″ M″⤅M′) 𝒟 s = snpr↦ M↦M″ 𝒟 (snpr⤅ M″⤅M′ (tp↦ M↦M″ 𝒟) s)
-- -- Big-step reduction IN REVERSE preserves SN.
-- snpr⇓ : ∀ {A M M′} → M ⇓ M′ → ∙ ⊢ M ⦂ A → SN M′ A
-- → SN M A
-- snpr⇓ (M⤅M′ , VM′) 𝒟 s = snpr⤅ M⤅M′ 𝒟 s
-- --------------------------------------------------------------------------------
-- -- Small-step reduction preserves SN.
-- mutual
-- snp↦ : ∀ {A M M′} → M ↦ M′ → ∙ ⊢ M ⦂ A → SN M A
-- → SN M′ A
-- snp↦ M↦M′ 𝒟 (_ , M⇓ , s!) = tp↦ M↦M′ 𝒟 , hp↦ M↦M′ M⇓ , sn!p↦ M↦M′ 𝒟 s!
-- sn!p↦ : ∀ {A M M′} → M ↦ M′ → ∙ ⊢ M ⦂ A → SN! M A
-- → SN! M′ A
-- sn!p↦ {𝔹} M↦M′ 𝒟 ∙ = ∙
-- sn!p↦ {A ∨ B} M↦M′ 𝒟 x = oops
-- sn!p↦ {𝟘} M↦M′ 𝒟 ()
-- sn!p↦ {𝟙} M↦M′ 𝒟 ∙ = ∙
-- sn!p↦ {A ∧ B} M↦M′ 𝒟 (s₁ , s₂) = snp↦ (cong-fst M↦M′) (fst 𝒟) s₁ , snp↦ (cong-snd M↦M′) (snd 𝒟) s₂
-- sn!p↦ {A ⊃ B} M↦M′ 𝒟 f s = snp↦ (cong-app₁ M↦M′) (app 𝒟 (derp s)) (f s)
-- -- Iterated small-step reduction preserves SN.
-- snp⤅ : ∀ {A M M′} → M ⤅ M′ → ∙ ⊢ M ⦂ A → SN M A
-- → SN M′ A
-- snp⤅ done 𝒟 s = s
-- snp⤅ (step M↦M″ M″⤅M′) 𝒟 s = snp⤅ M″⤅M′ (tp↦ M↦M″ 𝒟) (snp↦ M↦M″ 𝒟 s)
-- -- Big-step reduction preserves SN.
-- snp⇓ : ∀ {A M M′} → M ⇓ M′ → ∙ ⊢ M ⦂ A → SN M A
-- → SN M′ A
-- snp⇓ (M⤅M′ , VM′) 𝒟 s = snp⤅ M⤅M′ 𝒟 s
-- --------------------------------------------------------------------------------
-- -- If `M` is SN at type `A ⊃ B` and `N` is SN at type `A`, then `APP M N` is SN at type `B`.
-- sn-app : ∀ {A B M N} → SN M (A ⊃ B) → SN N A
-- → SN (APP M N) B
-- sn-app (𝒟 , M⇓ , f) s = f s
-- -- If `M` is SN at type `A` and `N` is SN at type `B`, then `PAIR M N` is SN at type `A ∧ B`.
-- sn-pair : ∀ {A B M N} → SN M A → SN N B
-- → SN (PAIR M N) (A ∧ B)
-- sn-pair s₁@(𝒟 , M⇓@(M′ , M⇓M′@(M⤅M′ , VM′)) , s!₁) s₂@(ℰ , N⇓@(N′ , N⇓N′@(N⤅N′ , VN′)) , s!₂)
-- = pair 𝒟 ℰ ,
-- halt-pair M⇓ N⇓ ,
-- snpr⇓ (big-red-fst-pair {{VM′}} {{VN′}} (congs-pair {{VM′}} {{VN′}} M⤅M′ N⤅N′)) (fst (pair 𝒟 ℰ)) (snp⤅ M⤅M′ 𝒟 s₁) ,
-- snpr⇓ (big-red-snd-pair {{VM′}} {{VN′}} ((congs-pair {{VM′}} {{VN′}} M⤅M′ N⤅N′))) (snd (pair 𝒟 ℰ)) (snp⤅ N⤅N′ ℰ s₂)
-- -- If `M` is SN at type `A ∧ B`, then `FST M` is SN at type `A`.
-- mutual
-- sn-fst : ∀ {A B M} → SN M (A ∧ B)
-- → SN (FST M) A
-- sn-fst (𝒟 , M⇓ , s!) = fst 𝒟 , halt-fst 𝒟 M⇓ , sn!-fst s!
-- sn!-fst : ∀ {A B M} → SN! M (A ∧ B)
-- → SN! (FST M) A
-- sn!-fst {𝔹} _ = ∙
-- sn!-fst {A₁ ∨ A₂} x = oops
-- sn!-fst {𝟘} ()
-- sn!-fst {𝟙} _ = ∙
-- sn!-fst {A₁ ∧ A₂} ((ℰ , FST⇓ , s) , _) = s
-- sn!-fst {A₁ ⊃ A₂} ((ℰ , FST⇓ , f) , _) s = f s
-- -- If `M` is SN at type `A ∧ B`, then `SND M` is SN at type `B`.
-- mutual
-- sn-snd : ∀ {A B M} → SN M (A ∧ B)
-- → SN (SND M) B
-- sn-snd (𝒟 , M⇓ , s!) = snd 𝒟 , halt-snd 𝒟 M⇓ , sn!-snd s!
-- sn!-snd : ∀ {B A M} → SN! M (A ∧ B)
-- → SN! (SND M) B
-- sn!-snd {𝔹} _ = ∙
-- sn!-snd {B₁ ∨ B₂} x = oops
-- sn!-snd {𝟘} ()
-- sn!-snd {𝟙} _ = ∙
-- sn!-snd {B₁ ∧ B₂} (_ , (ℰ , SND⇓ , s)) = s
-- sn!-snd {B₁ ⊃ B₂} (_ , (ℰ , SND⇓ , f)) s = f s
-- -- If `M` is SN at type `𝟘`, then `ABORT M` is SN at type `C`.
-- mutual
-- sn-abort : ∀ {C M} → SN M 𝟘
-- → SN (ABORT M) C
-- sn-abort {C} (𝒟 , M⇓ , s!) = abort 𝒟 , halt-abort 𝒟 M⇓ , sn!-abort {C} s!
-- sn!-abort : ∀ {C M} → SN! M 𝟘
-- → SN! (ABORT M) C
-- sn!-abort {𝔹} ()
-- sn!-abort {A ∨ B} x = oops
-- sn!-abort {𝟘} ()
-- sn!-abort {𝟙} ()
-- sn!-abort {A ∧ B} ()
-- sn!-abort {A ⊃ B} () _
-- -- If `M` is SN at type `A`, then `LEFT M` is SN at type `A ∨ B`.
-- sn-left : ∀ {A B M} → SN M A
-- → SN (LEFT M) (A ∨ B)
-- sn-left s@(𝒟 , M⇓@(M′ , M⇓M′@(M⤅M′ , VM′)) , s!) = left 𝒟 , halt-left M⇓ , oops
-- -- If `M` is SN at type `B`, then `RIGHT M` is SN at type `A ∨ B`.
-- sn-right : ∀ {A B M} → SN M B
-- → SN (RIGHT M) (A ∨ B)
-- sn-right s@(𝒟 , M⇓@(M′ , M⇓M′@(M⤅M′ , VM′)) , s!) = right 𝒟 , halt-right M⇓ , oops
-- -- If `M` is SN at type `𝔹` and `N` is SN at type `C` and `O` is SN at type `C`, then `IF M N O` is SN at type `C`.
-- mutual
-- sn-if : ∀ {C M N O} → SN M 𝔹 → SN N C → SN O C
-- → SN (IF M N O) C
-- sn-if (𝒟 , M⇓@(M′ , M⤅M′ , VM′) , ∙) _ _ with tp⤅ M⤅M′ 𝒟
-- sn-if (𝒟 , M⇓@(LAM _ , _ , val-lam) , ∙) _ _ | ()
-- sn-if (𝒟 , M⇓@(PAIR _ _ , _ , val-pair) , ∙) _ _ | ()
-- sn-if (𝒟 , M⇓@(UNIT , _ , val-unit) , ∙) _ _ | ()
-- sn-if (𝒟 , M⇓@(LEFT _ , _ , val-left) , ∙) _ _ | ()
-- sn-if (𝒟 , M⇓@(RIGHT _ , _ , val-right) , ∙) _ _ | ()
-- sn-if (𝒟 , M⇓@(TRUE , M⤅TRUE , val-true) , ∙) (ℰ , N⇓ , s!₁) (ℱ , O⇓ , s!₂) | true = if 𝒟 ℰ ℱ , halt-if 𝒟 M⇓ N⇓ O⇓ , sn!-if-true M⤅TRUE 𝒟 ℰ ℱ s!₁
-- sn-if (𝒟 , M⇓@(FALSE , M⤅FALSE , val-false) , ∙) (ℰ , N⇓ , s!₁) (ℱ , O⇓ , s!₂) | false = if 𝒟 ℰ ℱ , halt-if 𝒟 M⇓ N⇓ O⇓ , sn!-if-false M⤅FALSE 𝒟 ℰ ℱ s!₂
-- sn!-if-true : ∀ {C M N O} → M ⤅ TRUE → ∙ ⊢ M ⦂ 𝔹 → ∙ ⊢ N ⦂ C → ∙ ⊢ O ⦂ C → SN! N C
-- → SN! (IF M N O) C
-- sn!-if-true {𝔹} M⤅TRUE 𝒟 ℰ ℱ ∙ = ∙
-- sn!-if-true {A ∨ B} M⤅TRUE 𝒟 ℰ ℱ x = oops
-- sn!-if-true {𝟘} M⤅TRUE 𝒟 ℰ ℱ ()
-- sn!-if-true {𝟙} M⤅TRUE 𝒟 ℰ ℱ ∙ = ∙
-- sn!-if-true {A ∧ B} M⤅TRUE 𝒟 ℰ ℱ (s₁ , s₂) = snpr⤅ (congs-fst (reds-if-true M⤅TRUE done)) (fst (if 𝒟 ℰ ℱ)) s₁ ,
-- snpr⤅ (congs-snd (reds-if-true M⤅TRUE done)) (snd (if 𝒟 ℰ ℱ)) s₂
-- sn!-if-true {A ⊃ B} M⤅TRUE 𝒟 ℰ ℱ f s = snpr⤅ (congs-app₁ (reds-if-true M⤅TRUE done)) (app (if 𝒟 ℰ ℱ) (derp s)) (f s)
-- sn!-if-false : ∀ {C M N O} → M ⤅ FALSE → ∙ ⊢ M ⦂ 𝔹 → ∙ ⊢ N ⦂ C → ∙ ⊢ O ⦂ C → SN! O C
-- → SN! (IF M N O) C
-- sn!-if-false {𝔹} M⤅FALSE 𝒟 ℰ ℱ ∙ = ∙
-- sn!-if-false {A ∨ B} M⤅FALSE 𝒟 ℰ ℱ x = oops
-- sn!-if-false {𝟘} M⤅FALSE 𝒟 ℰ ℱ ()
-- sn!-if-false {𝟙} M⤅FALSE 𝒟 ℰ ℱ ∙ = ∙
-- sn!-if-false {A ∧ B} M⤅FALSE 𝒟 ℰ ℱ (s₁ , s₂) = snpr⤅ (congs-fst (reds-if-false M⤅FALSE done)) (fst (if 𝒟 ℰ ℱ)) s₁ ,
-- snpr⤅ (congs-snd (reds-if-false M⤅FALSE done)) (snd (if 𝒟 ℰ ℱ)) s₂
-- sn!-if-false {A ⊃ B} M⤅FALSE 𝒟 ℰ ℱ f s = snpr⤅ (congs-app₁ (reds-if-false M⤅FALSE done)) (app (if 𝒟 ℰ ℱ) (derp s)) (f s)
-- -- XXX
-- mutual
-- sn-app-lam : ∀ {B g M N A} → {τ : Terms 0 g} → {{_ : Vals τ}} {{_ : Val N}}
-- → ∙ ⊢ SUB τ (LAM M) ⦂ A ⊃ B → ∙ ⊢ N ⦂ A → SN (SUB (τ , N) M) B
-- → SN (APP (LAM (SUB (LIFTS τ) M)) N) B
-- sn-app-lam {M = M} 𝒟 ℰ (𝒟′ , SUB⇓ , s!) =
-- let 𝒜 = app 𝒟 ℰ in
-- 𝒜 , halt-app-lam {M = M} SUB⇓ , sn!-app-lam {M = M} 𝒜 s!
-- sn!-app-lam : ∀ {B g M N} → {τ : Terms 0 g} → {{_ : Vals τ}} {{_ : Val N}}
-- → ∙ ⊢ APP (LAM (SUB (LIFTS τ) M)) N ⦂ B → SN! (SUB (τ , N) M) B
-- → SN! (APP (LAM (SUB (LIFTS τ) M)) N) B
-- sn!-app-lam {𝔹} {M = M} 𝒜 ∙ = ∙
-- sn!-app-lam {B₁ ∨ B₂} {M = M} 𝒜 x = oops
-- sn!-app-lam {𝟘} {M = M} 𝒜 ()
-- sn!-app-lam {𝟙} {M = M} 𝒜 ∙ = ∙
-- sn!-app-lam {B₁ ∧ B₂} {M = M} 𝒜 (s₁ , s₂) = snpr↦ (cong-fst (red-app-lam {M = M})) (fst 𝒜) s₁ ,
-- snpr↦ (cong-snd (red-app-lam {M = M})) (snd 𝒜) s₂
-- sn!-app-lam {B₁ ⊃ B₂} {M = M} 𝒜 f s = snpr↦ (cong-app₁ (red-app-lam {M = M})) (app 𝒜 (derp s)) (f s)
-- --------------------------------------------------------------------------------
-- mutual
-- gen-sn : ∀ {g M A} → {τ : Terms 0 g} {Γ : Types g} → {{_ : Vals τ}}
-- → SNs τ Γ → Γ ⊢ M ⦂ A
-- → SN (SUB τ M) A
-- gen-sn σ (var i) = get σ (zip∋₂ i)
-- gen-sn σ (lam 𝒟) = gen-sn-lam σ 𝒟
-- gen-sn σ (app 𝒟 ℰ) = sn-app (gen-sn σ 𝒟) (gen-sn σ ℰ)
-- gen-sn σ (pair 𝒟 ℰ) = sn-pair (gen-sn σ 𝒟) (gen-sn σ ℰ)
-- gen-sn σ (fst 𝒟) = sn-fst (gen-sn σ 𝒟)
-- gen-sn σ (snd 𝒟) = sn-snd (gen-sn σ 𝒟)
-- gen-sn σ unit = unit , (UNIT , done , val-unit) , ∙
-- gen-sn σ (abort 𝒟) = sn-abort (gen-sn σ 𝒟)
-- gen-sn σ (left 𝒟) = sn-left (gen-sn σ 𝒟)
-- gen-sn σ (right 𝒟) = sn-right (gen-sn σ 𝒟)
-- gen-sn σ (case 𝒟 ℰ ℱ) = gen-sn-case σ 𝒟 ℰ ℱ
-- gen-sn σ true = true , (TRUE , done , val-true) , ∙
-- gen-sn σ false = false , (FALSE , done , val-false) , ∙
-- gen-sn σ (if 𝒟 ℰ ℱ) = sn-if (gen-sn σ 𝒟) (gen-sn σ ℰ) (gen-sn σ ℱ)
-- gen-sn-lam : ∀ {g M A B} → {τ : Terms 0 g} {Γ : Types g} → {{_ : Vals τ}}
-- → SNs τ Γ → Γ , A ⊢ M ⦂ B
-- → SN (LAM (SUB (LIFTS τ) M)) (A ⊃ B)
-- gen-sn-lam {M = M} {{Vτ}} σ 𝒟 =
-- let 𝒟′ = sub (derps σ) (lam 𝒟) in
-- 𝒟′ , (LAM _ , done , val-lam) , (\ { s@(ℰ , (N′ , N⇓N′@(N⤅N′ , VN′)) , s!) →
-- let s′@(ℰ′ , _ , _) = snp⇓ N⇓N′ ℰ s in
-- snpr⤅ (congs-app₂ N⤅N′)
-- (app 𝒟′ ℰ)
-- (sn-app-lam {M = M} {{Vτ}} {{VN′}}
-- 𝒟′ ℰ′
-- (gen-sn {{Vτ , VN′}} (σ , s′) 𝒟)) })
-- gen-sn-case : ∀ {g M N O A B C} → {τ : Terms 0 g} {Γ : Types g} → {{_ : Vals τ}}
-- → SNs τ Γ → Γ ⊢ M ⦂ A ∨ B → Γ , A ⊢ N ⦂ C → Γ , B ⊢ O ⦂ C
-- → SN (CASE (SUB τ M) (SUB (LIFTS τ) N) (SUB (LIFTS τ) O)) C
-- gen-sn-case {N = N} {O} {{Vτ}} σ 𝒟 ℰ ℱ with gen-sn σ 𝒟
-- gen-sn-case {N = N} {O} {{Vτ}} σ 𝒟 ℰ ℱ | s₁@(𝒟′ , (M′ , SUB⤅M′ , VM′) , s₁!) with tp⤅ SUB⤅M′ 𝒟′
-- gen-sn-case {N = N} {O} {{Vτ}} σ 𝒟 ℰ ℱ | s₁@(𝒟′ , (LAM _ , _ , val-lam) , s₁!) | ()
-- gen-sn-case {N = N} {O} {{Vτ}} σ 𝒟 ℰ ℱ | s₁@(𝒟′ , (PAIR _ _ , _ , val-pair) , s₁!) | ()
-- gen-sn-case {N = N} {O} {{Vτ}} σ 𝒟 ℰ ℱ | s₁@(𝒟′ , (UNIT , _ , val-unit) , s₁!) | ()
-- gen-sn-case {N = N} {O} {{Vτ}} σ 𝒟 ℰ ℱ | s₁@(𝒟′ , (LEFT M″ , SUB⤅LEFT , val-left {{VM″}}) , s₁!) | left _
-- = let step2 = gen-sn {M = N} {{Vτ , VM″}} (σ , {!s₁!}) ℰ in {!!}
-- -- = -- let x = snp⤅ SUB⤅LEFT {!!} {!!} in
-- -- let (ℰ′ , N⇓@(N′ , N⤅N′ , VN′) , s₂) = gen-sn (σ , {!s₁!}) ℰ in
-- --
-- -- snpr⤅ (congs-case SUB⤅LEFT)
-- -- (case 𝒟′ (sub (lifts (derps σ)) ℰ) (sub (lifts (derps σ)) ℱ))
-- -- (case (left 𝒟″) (sub (lifts (derps σ)) ℰ) (sub (lifts (derps σ)) ℱ) ,
-- -- halt-case-left {N = N} {O} N⇓ , {!!})
-- --
-- -- -- = let (ℰ′ , N⇓@(N′ , N⤅N′ , VN′) , s₂) = gen-sn (σ , unsn-left (snp⤅ SUB⤅LEFT 𝒟′ s₁)) ℰ in
-- -- -- sub (derps σ) (case 𝒟 ℰ ℱ) , (N′ , {!!} , {!!}) , {!!}
-- gen-sn-case {N = N} {O} σ 𝒟 ℰ ℱ | s₁@(𝒟′ , (RIGHT _ , SUB⤅RIGHT , val-right) , s!) | right 𝒟″
-- = {!!}
-- -- = sub (derps σ) (case 𝒟 ℰ ℱ) , ({!!} , {!!} , {!!}) , {!!}
-- gen-sn-case {N = N} {O} σ 𝒟 ℰ ℱ | s₁@(𝒟′ , (TRUE , _ , val-true) , s!) | ()
-- gen-sn-case {N = N} {O} σ 𝒟 ℰ ℱ | s₁@(𝒟′ , (FALSE , _ , val-false) , s!) | ()
-- -- let (𝒟′ , ⇓M@(M′ , M⤅M′ , VM′) , s!) = gen-sn σ 𝒟 in
-- -- sub (derps σ) (case 𝒟 ℰ ℱ) , {!!} , {!!}
-- --------------------------------------------------------------------------------
-- -- Every well-typed term is SN.
-- sn : ∀ {A M} → ∙ ⊢ M ⦂ A
-- → SN M A
-- sn {A} {M} 𝒟 = subst (\ M′ → SN M′ A) (id-SUB M) (gen-sn ∙ 𝒟)
-- -- Every SN term terminates.
-- herp : ∀ {A M} → SN M A
-- → M ⇓
-- herp (𝒟 , M⇓ , s!) = M⇓
-- -- Every well-typed term terminates.
-- halt : ∀ {A M} → ∙ ⊢ M ⦂ A
-- → M ⇓
-- halt {A} 𝒟 = herp {A} (sn 𝒟)
-- --------------------------------------------------------------------------------