module CC.CanonicalErased where
open import Data.Nat
open import Data.Unit using (⊤; tt)
open import Data.Bool using (true; false) renaming (Bool to 𝔹)
open import Data.List
open import Data.Product using (_×_; ∃-syntax; proj₁; proj₂) renaming (_,_ to ⟨_,_⟩)
open import Data.Maybe
open import Relation.Nullary using (¬_; Dec; yes; no)
open import Relation.Nullary.Negation using (contradiction)
open import Relation.Binary.PropositionalEquality using (_≡_; refl; sym; trans; subst; subst₂)
open import Function using (case_of_)
open import Common.Utils
open import Common.Types
open import Memory.Heap
open import CC.CCStatics
open import CC.WellTyped
open import CC.Erasure
data ErasedFun : Term → Set where
ϵ-fun-● : ErasedFun ●
ϵ-fun-ƛ : ∀ {pc A N} → ErasedFun (ƛ⟦ pc ⟧ A ˙ N of low)
canonical-fun-erase : ∀ {Σ gc gc′ pc A B g V}
→ [] ; Σ ; gc ; pc ⊢ V ⦂ ⟦ gc′ ⟧ A ⇒ B of g
→ Value V
→ ∃[ V′ ] V′ ≡ erase V × ErasedFun V′
canonical-fun-erase {gc = gc} {pc = pc} ⊢V v =
case canonical-fun ⊢V v of λ where
(Fun-ƛ {ℓ = low} _ _) → ⟨ _ , refl , ϵ-fun-ƛ ⟩
(Fun-ƛ {ℓ = high} _ _) → ⟨ _ , refl , ϵ-fun-● ⟩
(Fun-proxy fun i sub) →
case v of λ where
(V-cast w _) →
canonical-fun-erase {gc = gc} {pc = pc} (fun-wt fun) w
data ErasedRef : Term → Set where
ϵ-ref-● : ErasedRef ●
ϵ-ref-addr : ∀ {n} → ErasedRef (addr a⟦ low ⟧ n of low)
canonical-ref-erase : ∀ {Σ gc pc A g V}
→ [] ; Σ ; gc ; pc ⊢ V ⦂ Ref A of g
→ Value V
→ ∃[ V′ ] V′ ≡ erase V × ErasedRef V′
canonical-ref-erase {gc = gc} {pc} ⊢V v =
case canonical-ref ⊢V v of λ where
(Ref-addr {ℓ = low} {low} _ _) → ⟨ _ , refl , ϵ-ref-addr ⟩
(Ref-addr {ℓ = low} {high} _ _) → ⟨ _ , refl , ϵ-ref-● ⟩
(Ref-addr {ℓ = high} {low} _ _) → ⟨ _ , refl , ϵ-ref-● ⟩
(Ref-addr {ℓ = high} {high} _ _) → ⟨ _ , refl , ϵ-ref-● ⟩
(Ref-proxy ref i sub) →
case v of λ where
(V-cast w _) →
canonical-ref-erase {gc = gc} {pc} (ref-wt ref) w