module operational where -- Small step and big step semantics of the language of arith1.agda -- -- G. Plotkin, The Origins of Structural Operational Semantics -- https://homepages.inf.ed.ac.uk/gdp/publications/Origins_SOS.pdf -- G. Kahn, Natural semantics, 1987 -- -- We reuse the syntax Exp, the one step relation => , its closure =>* -- and the values from arith1.agda, and add the -big step- relation. open import arith1 ------------------------------------------------------------------------ -- 1. Big step semantics: e ⇓ v is "e evaluates to the value v" -- -- No intermediate state is mentioned. A derivation of e ⇓ v is the -- whole computation tree at once, not a sequence of steps. ------------------------------------------------------------------------ data _⇓_ : Exp -> Exp -> Set where -- a value evaluates to itself vtrue : ------------------ true ⇓ true vfalse : ------------------ false ⇓ false v0 : ------------------ zero ⇓ zero ⇓suc : {e v : Exp} -> e ⇓ v -> ------------------------------ suc e ⇓ suc v ⇓isZ0 : {e : Exp} -> e ⇓ zero -> ------------------------------ isZ e ⇓ true ⇓isZS : {e v : Exp} -> e ⇓ suc v -> ------------------------------------ isZ e ⇓ false ⇓pred0 : {e : Exp} -> e ⇓ zero -> ------------------------------ pred e ⇓ zero ⇓predS : {e v : Exp} -> e ⇓ suc v -> ------------------------------------ pred e ⇓ v ⇓iftrue : {e e0 e1 v : Exp} -> e ⇓ true -> e0 ⇓ v -> --------------------------------------------------- if e e0 e1 ⇓ v ⇓iffalse : {e e0 e1 v : Exp} -> e ⇓ false -> e1 ⇓ v -> ---------------------------------------------------- if e e0 e1 ⇓ v -- the same expression as before, evaluated in one derivation tree test⇓ : exp0 ⇓ zero test⇓ = ⇓iftrue (⇓isZ0 v0) v0 ------------------------------------------------------------------------ -- 2. Values evaluate to themselves ------------------------------------------------------------------------ ⇓valnat : {e : Exp} -> isValnat e -> e ⇓ e ⇓valnat isValnat0 = v0 ⇓valnat (isValnatS v) = ⇓suc (⇓valnat v) ⇓val : {e : Exp} -> isVal e -> e ⇓ e ⇓val Valtrue = vtrue ⇓val Valfalse = vfalse ⇓val (Valnat v) = ⇓valnat v -- Warning: without types, the result of ⇓ need not be a value. -- Indeed suc true ⇓ suc true by ⇓suc vtrue, and suc true is not a value. -- This is the big step counterpart of a stuck term. ------------------------------------------------------------------------ -- 3. The congruence rules of =>* , which => has and =>* inherits ------------------------------------------------------------------------ =>*suc : {e e' : Exp} -> e =>* e' -> suc e =>* suc e' =>*suc nil = nil =>*suc (cons x p) = cons (=>suc x) (=>*suc p) =>*pred : {e e' : Exp} -> e =>* e' -> pred e =>* pred e' =>*pred nil = nil =>*pred (cons x p) = cons (=>pred x) (=>*pred p) =>*isZ : {e e' : Exp} -> e =>* e' -> isZ e =>* isZ e' =>*isZ nil = nil =>*isZ (cons x p) = cons (=>isZ x) (=>*isZ p) =>*if : {e e' e0 e1 : Exp} -> e =>* e' -> if e e0 e1 =>* if e' e0 e1 =>*if nil = nil =>*if (cons x p) = cons (=>if x) (=>*if p) ------------------------------------------------------------------------ -- 4. The two semantics agree: if e ⇓ v then e =>* v -- -- by induction on the derivation of e ⇓ v ; each big step is replayed -- as: reduce the subexpression, then take the computation step ------------------------------------------------------------------------ sound⇓ : {e v : Exp} -> e ⇓ v -> e =>* v sound⇓ vtrue = nil sound⇓ vfalse = nil sound⇓ v0 = nil sound⇓ (⇓suc p) = =>*suc (sound⇓ p) sound⇓ (⇓isZ0 p) = isTrans (=>*isZ (sound⇓ p)) (oneStep =>isZ0) sound⇓ (⇓isZS p) = isTrans (=>*isZ (sound⇓ p)) (oneStep =>isZS) sound⇓ (⇓pred0 p) = isTrans (=>*pred (sound⇓ p)) (oneStep =>pred0) sound⇓ (⇓predS p) = isTrans (=>*pred (sound⇓ p)) (oneStep =>predS) sound⇓ (⇓iftrue p q) = isTrans (=>*if (sound⇓ p)) (cons =>true (sound⇓ q)) sound⇓ (⇓iffalse p q) = isTrans (=>*if (sound⇓ p)) (cons =>false (sound⇓ q)) ------------------------------------------------------------------------ -- 5. Typing the big step semantics -- -- The analogue of preservation: evaluation does not change the type. ------------------------------------------------------------------------ ⇓preservation : {e v : Exp} -> {T : Typ} -> e :: T -> e ⇓ v -> v :: T ⇓preservation eT vtrue = eT ⇓preservation eT vfalse = eT ⇓preservation eT v0 = eT ⇓preservation (typeS eT) (⇓suc p) = typeS (⇓preservation eT p) ⇓preservation (typeZ eT) (⇓isZ0 p) = typet ⇓preservation (typeZ eT) (⇓isZS p) = typef ⇓preservation (typep eT) (⇓pred0 p) = type0 ⇓preservation (typep eT) (⇓predS p) = predlem (⇓preservation eT p) where predlem : {v : Exp} -> suc v :: nat -> v :: nat predlem (typeS vT) = vT ⇓preservation (typeif eT eT0 eT1) (⇓iftrue p q) = ⇓preservation eT0 q ⇓preservation (typeif eT eT0 eT1) (⇓iffalse p q) = ⇓preservation eT1 q ------------------------------------------------------------------------ -- Exercises -- -- 1. Show that => is deterministic: if e => e1 and e => e2 then e1 ≡ e2 -- 2. Show the converse of sound⇓ : if e =>* v and isVal v then e ⇓ v -- (first prove: e => e' and e' ⇓ v imply e ⇓ v) -- 3. Show that isZ true has no value: ¬ (Σ Exp (λ v -> isZ true ⇓ v)) -- 4. Show that a well typed e has a value: e :: T implies Σ Exp (λ v -> e ⇓ v) -- Which induction does this need? ------------------------------------------------------------------------