{-# OPTIONS --allow-unsolved-metas #-}
module A201802.WIP.LR2a 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.WIP.LR1a
data IsVal {g} : Exp g → Set
where
instance
val-lam : ∀ {M} → IsVal (lam M)
val-true : IsVal true
val-false : IsVal false
record Val (g : Nat) : Set
where
constructor val
field
term : Exp g
{{iv}} : IsVal term
data EvCx (g : Nat) : Set
where
ec-[] : EvCx g
ec-app₁ : EvCx g → Exp g → EvCx g
ec-app₂ : Val g → EvCx g → EvCx g
ec-if : EvCx g → Exp g → Exp g → EvCx g
_[_] : ∀ {g} → EvCx g → Exp g → Exp g
ec-[] [ e ] = e
ec-app₁ E e₂ [ e₁ ] = app (E [ e₁ ]) e₂
ec-app₂ v E [ e ] = app (Val.term v) (E [ e ])
ec-if E e₂ e₃ [ e₁ ] = if (E [ e₁ ]) e₂ e₃
infix 3 _↦_
data _↦_ {g} : Exp g → Exp g → Set
where
red-app-lam : ∀ {e₁ e₂} → app (lam e₁) e₂ ↦ cut e₂ e₁
red-if-true : ∀ {e₁ e₂} → if true e₁ e₂ ↦ e₁
red-if-false : ∀ {e₁ e₂} → if false e₁ e₂ ↦ e₂
cong-ec : ∀ {e e′} → (E : EvCx g) → e ↦ e′
→ E [ e ] ↦ E [ e′ ]
infix 3 _⤅_
data _⤅_ {g} : Exp g → Exp g → Set
where
done : ∀ {e} → e ⤅ e
step : ∀ {e e″ e′} → e ↦ e″ → e″ ⤅ e′ → e ⤅ e′
steps : ∀ {g} → {e e″ e′ : Exp g}
→ e ⤅ e″ → e″ ⤅ e′
→ e ⤅ e′
steps done e⤅e′ = e⤅e′
steps (step e↦e‴ e‴⤅e″) e″⤅e′ = step e↦e‴ (steps e‴⤅e″ e″⤅e′)
infix 3 _⇓_
_⇓_ : ∀ {g} → Exp g → Val g → Set
e ⇓ v = e ⤅ Val.term v
_⇓ : ∀ {g} → Exp g → Set
e ⇓ = Σ (Val _) (\ v → e ⇓ v)
mutual
tp↦ : ∀ {g e e′ τ} → {Γ : Types g}
→ e ↦ e′ → Γ ⊢ e ⦂ τ
→ Γ ⊢ e′ ⦂ τ
tp↦ red-app-lam (APP (LAM D₁) D₂) = CUT D₂ D₁
tp↦ red-if-true (IF D₁ D₂ D₃) = D₂
tp↦ red-if-false (IF D₁ D₂ D₃) = D₃
tp↦ (cong-ec E e↦e′) D = PLUG E e↦e′ D
PLUG : ∀ {g e e′ τ} → {Γ : Types g}
→ (E : EvCx g) → e ↦ e′ → Γ ⊢ E [ e ] ⦂ τ
→ Γ ⊢ E [ e′ ] ⦂ τ
PLUG ec-[] e↦e′ D = tp↦ e↦e′ D
PLUG (ec-app₁ E e₂) e↦e′ (APP D₁ D₂) = APP (PLUG E e↦e′ D₁) D₂
PLUG (ec-app₂ v E) e↦e′ (APP D₁ D₂) = APP D₁ (PLUG E e↦e′ D₂)
PLUG (ec-if E e₂ e₃) e↦e′ (IF D₁ D₂ D₃) = IF (PLUG E e↦e′ D₁) D₂ D₃
tp⤅ : ∀ {g e e′ τ} → {Γ : Types g}
→ e ⤅ e′ → Γ ⊢ e ⦂ τ
→ Γ ⊢ e′ ⦂ τ
tp⤅ done D = D
tp⤅ (step e↦e″ e″⤅e′) D = tp⤅ (e″⤅e′) (tp↦ e↦e″ D)
lem-if-true : ∀ {g} → {e₁ e₂ e₂′ e₃ : Exp g}
→ e₁ ⤅ true → e₂ ⤅ e₂′
→ if e₁ e₂ e₃ ⤅ e₂′
lem-if-true done e₂⤅e₂′ = step red-if-true e₂⤅e₂′
lem-if-true (step e₁↦e₁″ e₁″⤅true) e₂⤅e₂′ = step (cong-ec (ec-if ec-[] _ _) e₁↦e₁″) (lem-if-true e₁″⤅true e₂⤅e₂′)
lem-if-false : ∀ {g} → {e₁ e₂ e₃ e₃′ : Exp g}
→ e₁ ⤅ false → e₃ ⤅ e₃′
→ if e₁ e₂ e₃ ⤅ e₃′
lem-if-false done e₃⤅e₃′ = step red-if-false e₃⤅e₃′
lem-if-false (step e₁↦e₁′ e₁′⤅false) e₃⤅e₃′ = step (cong-ec (ec-if ec-[] _ _) e₁↦e₁′) (lem-if-false e₁′⤅false e₃⤅e₃′)
private
module Impossible
where
sn : ∀ {M A} → ∙ ⊢ M ⦂ A → M ⇓
sn (VAR ())
sn (LAM D) = val (lam _) , done
sn (APP D₁ D₂) = {!!}
sn TRUE = val true , done
sn FALSE = val false , done
sn (IF D₁ D₂ D₃) with sn D₁ | sn D₂ | sn D₃
sn (IF D₁ D₂ D₃) | e₁′ , e₁⤅e₁′ | e₂⇓ | e₃⇓ with tp⤅ e₁⤅e₁′ D₁
sn (IF D₁ D₂ D₃) | val (lam e₁″) {{val-lam}} , e₁⤅lam-e₁″ | e₂⇓ | e₃⇓ | ()
sn (IF D₁ D₂ D₃) | val true {{val-true}} , e₁⤅true | e₂′ , e₂⤅e₂′ | e₃⇓ | TRUE = e₂′ , lem-if-true e₁⤅true e₂⤅e₂′
sn (IF D₁ D₂ D₃) | val false {{val-false}} , e₁⤅false | e₂⇓ | e₃′ , e₃⤅e₃′ | FALSE = e₃′ , lem-if-false e₁⤅false e₃⤅e₃′