module CC2.Values where open import Data.Nat open import Data.List open import Data.Maybe open import Data.Product using (_×_; ∃; ∃-syntax; Σ; Σ-syntax) renaming (_,_ to ⟨_,_⟩) open import Relation.Binary.PropositionalEquality using (_≡_; _≢_; refl; subst; subst₂; cong; cong₂; sym) open import Function using (case_of_) open import Common.Utils open import Common.Types open import Common.Coercions open import Memory.HeapContext open import CC2.Syntax open import CC2.Typing data Err : Term → Set where E-blame : ∀ {p} → Err (blame p) data RawValue : Term → Set where V-addr : ∀ {n} → RawValue (addr n) V-ƛ : ∀ {N} → RawValue (ƛ N) V-const : ∀ {ι} {k : rep ι} → RawValue ($ k) data Value : Term → Set where V-raw : ∀ {V} → RawValue V → Value V V-cast : ∀ {A B V} {c : Cast A ⇒ B} → RawValue V → Irreducible c → Value (V ⟨ c ⟩) V-● : Value ● data Result : Term → Set where success : ∀ {V} → Value V → Result V fail : ∀ {p} → Result (blame p) canonical⋆ : ∀ {Γ Σ gc ℓv V T} → Value V → Γ ; Σ ; gc ; ℓv ⊢ V ⇐ T of ⋆ → ∃[ A ] Σ[ c ∈ Cast A ⇒ T of ⋆ ] ∃[ W ] (V ≡ W ⟨ c ⟩) × (Irreducible c) × (Γ ; Σ ; gc ; ℓv ⊢ W ⇐ A) canonical⋆ (V-raw V-addr) () canonical⋆ (V-raw V-ƛ) () canonical⋆ (V-raw V-const) () canonical⋆ (V-cast {V = W} {c} w i) (⊢cast ⊢W) = ⟨ _ , c , _ , refl , i , ⊢W ⟩ ⊢value-pc : ∀ {Γ Σ gc gc′ ℓv ℓv′ V A} → Γ ; Σ ; gc ; ℓv ⊢ V ⇐ A → Value V → Γ ; Σ ; gc′ ; ℓv′ ⊢ V ⇐ A ⊢value-pc (⊢addr eq) (V-raw V-addr) = ⊢addr eq ⊢value-pc (⊢lam ⊢N) (V-raw V-ƛ) = ⊢lam ⊢N ⊢value-pc ⊢const (V-raw V-const) = ⊢const ⊢value-pc (⊢cast ⊢V) (V-cast v i) = ⊢cast (⊢value-pc ⊢V (V-raw v))