module A201605.AbelChapmanExtended2.Reflection where open import Data.Product using (_,_) open import Data.Unit using () renaming (tt to unit) open import A201605.AbelChapmanExtended.Convergence open import A201605.AbelChapmanExtended2.Syntax open import A201605.AbelChapmanExtended2.Renaming open import A201605.AbelChapmanExtended2.Normalization open import A201605.AbelChapmanExtended2.Semantics open import A201605.AbelChapmanExtended2.RenamingLemmas.Convergence mutual reify : ∀ {Γ} (a : Ty) (v : Val Γ a) → V⟦ a ⟧ v → readback v ⇓ reify ⊥ (ne v) (n , ⇓n) = (ne n , ⇓map ne ⇓n) reify (a ∨ b) (ne v) (n , ⇓n) = (ne n , ⇓map ne ⇓n) reify (a ∨ b) (inl v) (.v , ⇓now , ⟦v⟧) = let (n , ⇓n) = reify a v ⟦v⟧ in (inl n , ⇓map inl ⇓n) reify (a ∨ b) (inr v) (.v , ⇓now , ⟦v⟧) = let (n , ⇓n) = reify b v ⟦v⟧ in (inr n , ⇓map inr ⇓n) reify (a ⇒ b) v ⟦v⟧ = let w = nev₀ ⟦w⟧ = reflect-var {a = a} top (vw , ⇓vw , ⟦vw⟧) = ⟦v⟧ wk w ⟦w⟧ (n , ⇓n) = reify b vw ⟦vw⟧ ⇓λn = ⇓bind ⇓vw (⇓bind ⇓n ⇓now) in (lam n , ⇓later ⇓λn) reify (a ∧ b) v (c₁ , c₂) = let (v₁ , ⇓v₁ , ⟦v₁⟧) = c₁ (v₂ , ⇓v₂ , ⟦v₂⟧) = c₂ (n₁ , ⇓n₁) = reify a v₁ ⟦v₁⟧ (n₂ , ⇓n₂) = reify b v₂ ⟦v₂⟧ ⇓ψn = ⇓bind ⇓v₁ (⇓bind ⇓v₂ (⇓bind ⇓n₁ (⇓bind ⇓n₂ ⇓now))) in (pair n₁ n₂ , ⇓later ⇓ψn) reify ⊤ v ⟦v⟧ = (unit , ⇓now) reflect : ∀ {Γ} (a : Ty) (v : Ne Val Γ a) → readback-ne v ⇓ → V⟦ a ⟧ (ne v) reflect ⊥ v ⟦v⟧ = ⟦v⟧ reflect (a ∨ b) v ⟦v⟧ = ⟦v⟧ reflect (a ⇒ b) v (n , ⇓n) = λ η w ⟦w⟧ → let (m , ⇓m) = reify a w ⟦w⟧ n′ = ren-nen η n ⇓n′ = ⇓ren-readback-ne η v ⇓n vw = app (ren-nev η v) w ⟦vw⟧ = reflect b vw (app n′ m , ⇓bind ⇓n′ (⇓bind ⇓m ⇓now)) in (ne vw , ⇓now , ⟦vw⟧) reflect (a ∧ b) v (n , ⇓n) = let v₁ = fst v v₂ = snd v ⟦v₁⟧ = reflect a v₁ (fst n , ⇓bind ⇓n ⇓now) ⟦v₂⟧ = reflect b v₂ (snd n , ⇓bind ⇓n ⇓now) in (ne v₁ , ⇓now , ⟦v₁⟧) , (ne v₂ , ⇓now , ⟦v₂⟧) reflect ⊤ v ⟦v⟧ = unit reflect-var : ∀ {Γ a} (x : Var Γ a) → V⟦ a ⟧ ne (var x) reflect-var {a = a} x = reflect a (var x) (var x , ⇓now)