CK machine

module Scoped.CK where
open import Function
open import Data.Bool using (Bool;true;false)
open import Data.Nat
open import Data.String
open import Data.Sum
open import Data.Product
open import Relation.Binary.PropositionalEquality using (refl;inspect;subst;sym;_≡_;trans;cong) renaming ([_] to [[_]])
open import Data.Unit
open import Data.Nat using (_+_;suc)
open import Data.Nat.Properties
open import Type
open import Type.BetaNormal
open import Scoped
open import Scoped.Reduction hiding (step;trans;Error)
open import Builtin
open import Scoped.RenamingSubstitution
open import Relation.Nullary
open import Utils
open import Data.Vec hiding ([_])

data Frame : Set where
  -·_ : ScopedTm Z  Frame
  _·- : {t : ScopedTm Z}  Value t  Frame

  -·⋆_ :  (A : ScopedTy 0)  Frame

  wrap- :  ScopedTy 0  ScopedTy 0  Frame
  unwrap- : Frame

data Stack : Set where
  ε   : Stack
  _,_ : Stack  Frame  Stack

data State : Set where
  _▻_ : Stack  ScopedTm Z  State
  _◅_ : Stack  {t : ScopedTm Z}  Value t  State
     : {t : ScopedTm Z}   Value t  State
     : State

open import Data.Product renaming (_,_ to _,,_)
open import Data.Empty

-- this function, apart from making a step, also determines the
-- contexts and provides a proof.  These things could be done
-- seperately.

-- this could also be presented as a relation and then there would be
-- more function rather like progress

step : State  State
step (s  Λ K L)    = s  V-Λ {K = K} L
step (s  (L ·⋆ A)) = (s , (-·⋆ A))  L
step (s  ƛ A L)    = s  V-ƛ A L
step (s  (L · M))  = (s , ( M))  L
step (s  con cn)   = s  V-con cn
step (s  error A) = 
step (s  wrap pat arg L) = (s , wrap- pat arg)  L
step (s  unwrap L) = (s , unwrap-)  L
step (s  ibuiltin b) = s  ival b
step (ε  V) =  V
step ((s , ( M))  V) = (s , (V ·-))  M
step (_◅_ (s , (V-ƛ A L ·-)) {M} W) = s  (L [ M ])
step ((s , (V-builtin b t p q base vs ·-))  V) =
  s  IBUILTIN' b p q (vs , _ , V) 
step ((s , (V-builtin b t p q (skipT r) vs ·-))  V) =
  s  V-builtin⋆ b (t · deval V) p q r (vs , _ , V)
step ((s , (V-builtin b t p q (skipS r) vs ·-))  V) =
  s  V-builtin b (t · deval V) p q r (vs , _ , V)
step ((s , (V-Λ V ·-))  W) = 
step ((s , (V-con tcn ·-))  W) = 
step ((s , (V-wrap A B V ·-))  W) = 
step ((s , (V-builtin⋆ b t p q r vs ·-))  V) = 

step ((s , (-·⋆ A))  V-Λ  t)  = s  (t [ A ]⋆)
step ((s , (-·⋆ A))  V-builtin⋆ b t p q base vs) = s  IBUILTIN' b p q vs
step ((s , (-·⋆ A))  V-builtin⋆ b t p q (skipT r) vs) =
  s  V-builtin⋆ b (t ·⋆ A) p q r vs
step ((s , (-·⋆ A))  V-builtin⋆ b t p q (skipS r) vs) =
  s  V-builtin b (t ·⋆ A) p q r vs
step ((s , wrap- A B)  V) = s  V-wrap A B V
step ((s , (-·⋆ A))  V-ƛ A' L) = 
step ((s , (-·⋆ A))  V-con tcn) = 
step ((s , (-·⋆ A))  V-wrap A' B V) = 
step ((s , (-·⋆ A))  V-builtin b t p q r vs) = 

step ((s , unwrap-)  V-wrap A B V) = s  V
step ((s , unwrap-)  V-builtin a b c d e f) = 
step ((s , unwrap-)  V-builtin⋆ a b c d e f) = 
step ((s , unwrap-)  V-ƛ A t) = 
step ((s , unwrap-)  V-Λ V) = 
step ((s , unwrap-)  V-con tcn) = 

step ( V) =  V
step      = 

discharge : {t : ScopedTm Z}  Value t  ScopedTm Z
discharge {t} _ = t
open import Utils
stepper :   State  Either RuntimeError State
stepper zero st = inj₁ gasError
stepper (suc n) st with step st
stepper (suc n) st | s  M = stepper n (s  M)
stepper (suc n) st | s  V = stepper n (s  V)
stepper (suc n) st |  V   = return ( V)
stepper (suc n) st |      = return