# Lecture 2: Verified Interpreters

Teacher: François Pottier

# From operational semantics to (verified) interpreter

You have different semantics and want to translate between them.

## A naïve interpreter

An interpreter:

executes a program.

Of course, OCaml doesn’t perform naïve step-by-step $β$-reductions, but for the sake of simplicity, we’ll study a simplified example of small-step semantic to begin with.

 type var = int (* a de Bruijn index *)

type term =
| Var of var
| Lam of (* bind: *) term
| App of term * term

(* Example: *)
let id = Lam (Var 0)


Now: definition of $⇑^i (+k)$:

 let rec lift_ i k (t : term) : term = match t with
| Var x -> if x < i then t else Var (x + k)
| Lam t -> Lam (lift_ (i + 1) k t)
| App (t1, t2) -> App (lift_ i k t1, lift_ i k t2)

let lift k t = lift_ 0 k t


And substitutions:

 let rec subst_ i (sigma : var -> term) (t : term) : term =
match t with
| Var x -> if x < i then t else lift i (sigma (x - i))
| Lam t -> Lam (subst_ (i + 1) sigma t)
| App (t1, t2) -> App (subst_ i sigma t1, subst_ i sigma t2)

let subst sigma t = subst_ 0 sigma t


and then the substitution $u · id$:

 let singleton (u : term) : var -> term = function
0 -> u
| x -> Var (x - 1)


Small-step call-by-value reduction:

let in_context f ox = match ox with
| None -> None
| Some x -> Some (f x)

let is_value = function
| Var _ | Lam _ -> true
| App _ -> false

let rec step (t : term) : term option =
match t with
| Lam _ | Var _ -> None
(* Plotkin’s BetaV *)
| App (Lam t, v) when is_value v ->
Some (subst (singleton v) t)
(* Plotkin’s AppL *)
| App (t, u) when not (is_value t) ->
in_context (fun t’ -> App (t’, u)) (step t)
(* Plotkin’s AppVR *)
| App (v, u) when is_value v ->
in_context (fun u’ -> App (v, u’)) (step u)
(* All cases covered already, but OCaml cannot see it. *)
| App (_, _) -> assert false


⟶ Very inefficient

## Natural/Big-step Semantics

Reduction sequence of $t t’$ has the form:

t t' ⟶^\ast_{cbv} (λx.u) t' ⟶^\ast_{cbv} (λx.u) v ⟶_{cbv} u[v/x] ⟶^\ast_{cbv} v

where $t ⟶^\ast_{cbv} λx.u$ and $t’ ⟶^\ast_{cbv} v$

### Big-step relation $↓_{cbv}$

\cfrac{}{v \, ↓_{cbv} \, v} \qquad \cfrac{t_1 \, ↓_{cbv} \, λx.u_1 \qquad t_2 \, ↓_{cbv} \, v_2 \qquad u_1[v_2/x] ↓_{cbv} v}{t_1 t_2 \, ↓_{cbv} \, v}

A proof of

• $t ⟶^\ast_{cbv} t’$ has linear structure
• $t ↓_{cbv} v$ has tree structure.

### Big-step interpreter

exception RuntimeError

let rec eval (t : term) : term =
match t with
| Lam _ | Var _ -> t
| App (t1, t2) ->
let v1 = eval t1 in
let v2 = eval t2 in
match v1 with
| Lam u1 -> eval (subst (singleton v2) u1)
|_ -> raise RuntimeError


NB: May not terminate (evaluate $Ω$ for example)

## Big-step vs. Small-step

Lemma (From Big-step to Small-step): If $t ↓{cbv} v$, then $t ⟶^\ast{cbv} v$.

Lemma (From Small-step to Big-step): If $t_1 ⟶{cbv} t_2$ and $t_2 ↓{cbv} v$, then $t_1 ↓_{cbv} v$.

# Environments and closures

Environment:

finite map of variables to (closed) values.

Idea: record $x$ being bounded to $v$ while evaluating a $t$. Instead of applying the substitution $[v/x]$ to the code, record the binding $x ⟼ v$ in an environment.

Closure:

a pair $⟨λx.t \; \mid \; e⟩$, where $e$ is an environment and $fv(λx.t) ⊆ dom(e)$ (a closure is closed)

bigcbv: $t ↓_{cbv} v$

ebigcbv: $∅ ⊢ t ↓_{cbv} c$

Tags:

Updated: