Mercurial > cpdt > repo
diff src/StackMachine.v @ 14:8aed4562b62b
Typed expression language
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Wed, 03 Sep 2008 14:26:52 -0400 |
parents | ea400f692b07 |
children | d8c81e19e7d3 |
line wrap: on
line diff
--- a/src/StackMachine.v Wed Sep 03 13:45:59 2008 -0400 +++ b/src/StackMachine.v Wed Sep 03 14:26:52 2008 -0400 @@ -11,6 +11,8 @@ Require Import List. Require Import Tactics. + +Set Implicit Arguments. (* end hide *) @@ -465,3 +467,159 @@ reflexivity. Qed. + + +(** * Typed expressions *) + +(** In this section, we will build on the initial example by adding additional expression forms that depend on static typing of terms for safety. *) + +(** ** Source language *) + +Inductive type : Set := Nat | Bool. + +Inductive tbinop : type -> type -> type -> Set := +| TPlus : tbinop Nat Nat Nat +| TTimes : tbinop Nat Nat Nat +| TEq : forall t, tbinop t t Bool +| TLt : tbinop Nat Nat Bool. + +Inductive texp : type -> Set := +| TNConst : nat -> texp Nat +| TBConst : bool -> texp Bool +| TBinop : forall arg1 arg2 res, tbinop arg1 arg2 res -> texp arg1 -> texp arg2 -> texp res. + +Definition typeDenote (t : type) : Set := + match t with + | Nat => nat + | Bool => bool + end. + +Definition eq_bool (b1 b2 : bool) : bool := + match b1, b2 with + | true, true => true + | false, false => true + | _, _ => false + end. + +Fixpoint eq_nat (n1 n2 : nat) {struct n1} : bool := + match n1, n2 with + | O, O => true + | S n1', S n2' => eq_nat n1' n2' + | _, _ => false + end. + +Fixpoint lt (n1 n2 : nat) {struct n1} : bool := + match n1, n2 with + | O, S _ => true + | S n1', S n2' => lt n1' n2' + | _, _ => false + end. + +Definition tbinopDenote arg1 arg2 res (b : tbinop arg1 arg2 res) + : typeDenote arg1 -> typeDenote arg2 -> typeDenote res := + match b in (tbinop arg1 arg2 res) return (typeDenote arg1 -> typeDenote arg2 -> typeDenote res) with + | TPlus => plus + | TTimes => mult + | TEq Nat => eq_nat + | TEq Bool => eq_bool + | TLt => lt + end. + +Fixpoint texpDenote t (e : texp t) {struct e} : typeDenote t := + match e in (texp t) return (typeDenote t) with + | TNConst n => n + | TBConst b => b + | TBinop _ _ _ b e1 e2 => (tbinopDenote b) (texpDenote e1) (texpDenote e2) + end. + + +(** ** Target language *) + +Definition tstack := list type. + +Inductive tinstr : tstack -> tstack -> Set := +| TINConst : forall s, nat -> tinstr s (Nat :: s) +| TIBConst : forall s, bool -> tinstr s (Bool :: s) +| TIBinop : forall arg1 arg2 res s, + tbinop arg1 arg2 res + -> tinstr (arg1 :: arg2 :: s) (res :: s). + +Inductive tprog : tstack -> tstack -> Set := +| TNil : forall s, tprog s s +| TCons : forall s1 s2 s3, + tinstr s1 s2 + -> tprog s2 s3 + -> tprog s1 s3. + +Fixpoint vstack (ts : tstack) : Set := + match ts with + | nil => unit + | t :: ts' => typeDenote t * vstack ts' + end%type. + +Definition tinstrDenote ts ts' (i : tinstr ts ts') : vstack ts -> vstack ts' := + match i in (tinstr ts ts') return (vstack ts -> vstack ts') with + | TINConst _ n => fun s => (n, s) + | TIBConst _ b => fun s => (b, s) + | TIBinop _ _ _ _ b => fun s => + match s with + (arg1, (arg2, s')) => ((tbinopDenote b) arg1 arg2, s') + end + end. + +Fixpoint tprogDenote ts ts' (p : tprog ts ts') {struct p} : vstack ts -> vstack ts' := + match p in (tprog ts ts') return (vstack ts -> vstack ts') with + | TNil _ => fun s => s + | TCons _ _ _ i p' => fun s => tprogDenote p' (tinstrDenote i s) + end. + + +(** ** Translation *) + +Fixpoint tconcat ts ts' ts'' (p : tprog ts ts') {struct p} : tprog ts' ts'' -> tprog ts ts'' := + match p in (tprog ts ts') return (tprog ts' ts'' -> tprog ts ts'') with + | TNil _ => fun p' => p' + | TCons _ _ _ i p1 => fun p' => TCons i (tconcat p1 p') + end. + +Fixpoint tcompile t (e : texp t) (ts : tstack) {struct e} : tprog ts (t :: ts) := + match e in (texp t) return (tprog ts (t :: ts)) with + | TNConst n => TCons (TINConst _ n) (TNil _) + | TBConst b => TCons (TIBConst _ b) (TNil _) + | TBinop _ _ _ b e1 e2 => tconcat (tcompile e2 _) + (tconcat (tcompile e1 _) (TCons (TIBinop _ b) (TNil _))) + end. + +Print tcompile. + + +(** ** Translation correctness *) + +Lemma tcompileCorrect' : forall t (e : texp t) + ts (s : vstack ts), + tprogDenote (tcompile e ts) s + = (texpDenote e, s). + induction e; crush. +Abort. + +Lemma tconcatCorrect : forall ts ts' ts'' (p : tprog ts ts') (p' : tprog ts' ts'') + (s : vstack ts), + tprogDenote (tconcat p p') s + = tprogDenote p' (tprogDenote p s). + induction p; crush. +Qed. + +Hint Rewrite tconcatCorrect : cpdt. + +Lemma tcompileCorrect' : forall t (e : texp t) + ts (s : vstack ts), + tprogDenote (tcompile e ts) s + = (texpDenote e, s). + induction e; crush. +Qed. + +Hint Rewrite tcompileCorrect' : cpdt. + +Theorem tcompileCorrect : forall t (e : texp t), tprogDenote (tcompile e nil) tt = (texpDenote e, tt). + crush. +Qed.