{- Evaluation contexts -}

module CC2.Frame where

open import Relation.Nullary using (¬_; Dec; yes; no)
open import Relation.Binary.PropositionalEquality using (_≡_; _≢_; refl; sym)
open import Function using (case_of_)

open import CC2.Statics


data Frame : Set where

  -- app  L M A B ℓ
  app□   : (M : Term)  (A B : Type)  StaticLabel  Frame
  app_□  : (V : Term)  Value V  (A B : Type)  StaticLabel  Frame
  -- app⋆ L M A T
  app⋆□  : (M : Term)  (A : Type)  (T : RawType)  Frame
  app⋆_□ : (V : Term)  Value V  (A : Type)  (T : RawType)  Frame

  -- ref⟦ ℓ ⟧ M
  ref⟦_⟧□ : StaticLabel  Frame
  -- ref?⟦ ℓ ⟧ M p
  ref?⟦_⟧□ : StaticLabel  BlameLabel  Frame

  -- ! M A ℓ
  !□ : Type  StaticLabel  Frame
  -- !⋆ M T
  !⋆□ : RawType  Frame

  -- assign  L M T ℓ̂ ℓ
  assign□   : (M : Term)  RawType  (ℓ̂  : StaticLabel)  Frame
  assign_□  : (V : Term)  Value V  RawType  (ℓ̂  : StaticLabel)  Frame
  -- assign? L M T ĝ p
  assign?□  : (M : Term)  RawType  ( : Label)  BlameLabel  Frame
  assign?_□ : (V : Term)  Value V  RawType  ( : Label)  BlameLabel  Frame

  -- let M A N
  let□ : Type  Term  Frame

  -- if  L A ℓ M N
  if□  : Type  StaticLabel  (M N : Term)  Frame
  -- if⋆ L T M N
  if⋆□ : RawType  (M N : Term)  Frame

  -- M ⟨ c ⟩
  □⟨_⟩ :  {A B}  (c : Cast A  B)  Frame


plug : Term  Frame  Term
plug L (app□ M A B )          = app  L M A B 
plug M (app V  v A B )       = app  V M A B 
plug L (app⋆□ M A T)           = app⋆ L M A T
plug M (app⋆ V  v A T)        = app⋆ V M A T
plug M (ref⟦  ⟧□)             = ref⟦   M
plug M (ref?⟦  ⟧□ p)          = ref?⟦   M p
plug M (!□ A )                = ! M A 
plug M (!⋆□ T)                 = !⋆ M T
plug L (assign□ M T ℓ̂ )       = assign L M T ℓ̂ 
plug M (assign V  v T ℓ̂ )    = assign V M T ℓ̂ 
plug L (assign?□ M    T  p)   = assign? L M T  p
plug M (assign? V  v T  p)   = assign? V M T  p
plug M (let□ A N)              = `let M A N
plug L (if□  A  M N)          = if  L A  M N
plug L (if⋆□ T M N)            = if⋆ L T M N
plug M □⟨ c                   = M  c 


plug-not-● :  {M}  (F : Frame)  ¬ (plug M F  )
plug-not-● (app□ M A B x) ()
plug-not-● (app V  x A B x₁) ()
plug-not-● (app⋆□ M A B) ()
plug-not-● (app⋆ V  x A B) ()
plug-not-● ref⟦  ⟧□ ()
plug-not-● (ref?⟦  ⟧□ x₁) ()
plug-not-● (!□ x x₁) ()
plug-not-● (!⋆□ x) ()
plug-not-● (assign□ M x ℓ̂ ) ()
plug-not-● (assign V  x x₁ ℓ̂ ) ()
plug-not-● (assign?□ M x  x₁) ()
plug-not-● (assign? V  x x₁  x₂) ()
plug-not-● (let□ x x₁) ()
plug-not-● (if□ x x₁ M N) ()
plug-not-● (if⋆□ x M N) ()
plug-not-● □⟨ c  ()

plug-not-bl :  {M p}  (F : Frame)  ¬ (plug M F  blame p)
plug-not-bl (app□ M A B x) ()
plug-not-bl (app V  x A B x₁) ()
plug-not-bl (app⋆□ M A B) ()
plug-not-bl (app⋆ V  x A B) ()
plug-not-bl ref⟦  ⟧□ ()
plug-not-bl (ref?⟦  ⟧□ x₁) ()
plug-not-bl (!□ x x₁) ()
plug-not-bl (!⋆□ x) ()
plug-not-bl (assign□ M x ℓ̂ ) ()
plug-not-bl (assign V  x x₁ ℓ̂ ) ()
plug-not-bl (assign?□ M x  x₁) ()
plug-not-bl (assign? V  x x₁  x₂) ()
plug-not-bl (let□ x x₁) ()
plug-not-bl (if□ x x₁ M N) ()
plug-not-bl (if⋆□ x M N) ()
plug-not-bl □⟨ c  ()

plug-not-raw :  {M}  (F : Frame)  ¬ RawValue (plug M F)
plug-not-raw (app□ M A B x) ()
plug-not-raw (app V  x A B x₁) ()
plug-not-raw (app⋆□ M A B) ()
plug-not-raw (app⋆ V  x A B) ()
plug-not-raw ref⟦  ⟧□ ()
plug-not-raw (ref?⟦  ⟧□ x₁) ()
plug-not-raw (!□ x x₁) ()
plug-not-raw (!⋆□ x) ()
plug-not-raw (assign□ M x ℓ̂ ) ()
plug-not-raw (assign V  x x₁ ℓ̂ ) ()
plug-not-raw (assign?□ M x  x₁) ()
plug-not-raw (assign? V  x x₁  x₂) ()
plug-not-raw (let□ x x₁) ()
plug-not-raw (if□ x x₁ M N) ()
plug-not-raw (if⋆□ x M N) ()
plug-not-raw □⟨ c  ()