Expression Compiler


Require Import List. (* to obtain "::" notation *)

Section Compilation.
Variable value : Type.
Definition binop : Type := value -> value -> value.

Inductive exp : Type :=
| Val : value -> exp
| Binop : binop -> exp -> exp -> exp.

Fixpoint eval (e : exp) : value :=
  match e with
    | Val v => v
    | Binop o e1 e2 => o (eval e1) (eval e2)
  end.

Stack Machine

Inductive instr : Type :=
| iVal : value -> instr
| iBinop : binop -> instr.

Definition prog := list instr.
Definition stack := list value.

Definition runInstr (i : instr) (s : stack) : option stack :=
  match i with
    | iVal v => Some (v :: s)
    | iBinop o =>
      match s with
        | arg1 :: arg2 :: s' => Some (o arg1 arg2 :: s')
        | _ => None
      end
  end.

Fixpoint runProg (p : prog) (s : stack) : option stack :=
  match p with
    | nil => Some s
    | i :: p' =>
      match runInstr i s with
        | None => None
        | Some s' => runProg p' s'
      end
  end.

Compiler

Fixpoint compile (e : exp) : prog :=
  match e with
    | Val v => iVal v :: nil
    | Binop o e1 e2 => compile e2 ++ compile e1 ++ iBinop o :: nil
  end.

Correctness

Lemma compile_correct' e p s:
runProg (compile e ++ p) s = runProg p (eval e :: s).

Proof. revert p s. induction e ; intros p s ; simpl.
reflexivity.
rewrite <- app_assoc. rewrite IHe2.
rewrite <- app_assoc. rewrite IHe1. simpl. reflexivity. Qed.

Theorem compile_correct e s :
runProg (compile e) s = Some (eval e :: s).

Proof. rewrite <- (app_nil_r (compile e)).
  rewrite compile_correct'. simpl. reflexivity. Qed.

Relational Semantics

Inductive evalp : exp -> value -> Prop :=
| evalpV v :
  evalp (Val v) v
| evalpB o e1 e2 v1 v2 :
  evalp e1 v1 -> evalp e2 v2 ->
  evalp (Binop o e1 e2) (o v1 v2).

Goal forall e, evalp e (eval e).

Proof. induction e ; simpl ; constructor ; assumption. Qed.

Goal forall e v, evalp e v <-> eval e = v.

Proof. split ; intros A.
induction A ; simpl ; congruence. (* induction on e more tedious *)
rewrite <- A. clear v A. (* essential, otherwise induction generalizes A *)
induction e ; simpl ; constructor ; assumption. Qed.

Decompiler

Fixpoint decompile' (p : prog) (s : list exp) : option exp :=
match p, s with
 | nil, e :: nil => Some e
 | iVal v :: p', s => decompile' p' (Val v :: s)
 | iBinop o :: p', e1 :: e2 :: s' => decompile' p' (Binop o e1 e2 :: s')
 | _, _ => None
end.

Definition decompile (p : prog) := decompile' p nil.

Lemma decompile_correct' e p s:
decompile' (compile e ++ p) s = decompile' p (e :: s).

Proof. revert p s. induction e; intros p s ; simpl ; try reflexivity.
rewrite <-app_assoc, IHe2. rewrite <-app_assoc, IHe1. reflexivity. Qed.

Lemma decompile_correct e :
decompile (compile e) = Some e.

Proof. rewrite <- (app_nil_r (compile e)).
exact (decompile_correct' e nil nil). Qed.

End Compilation.

This page has been generated by coqdoc