diff src/Impure.v @ 190:094bd1e353dd

Import predicative Impure example
author Adam Chlipala <adamc@hcoop.net>
date Tue, 18 Nov 2008 12:44:46 -0500
parents
children cf5ddf078858
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Impure.v	Tue Nov 18 12:44:46 2008 -0500
@@ -0,0 +1,164 @@
+(* Copyright (c) 2008, Adam Chlipala
+ * 
+ * This work is licensed under a
+ * Creative Commons Attribution-Noncommercial-No Derivative Works 3.0
+ * Unported License.
+ * The license text is available at:
+ *   http://creativecommons.org/licenses/by-nc-nd/3.0/
+ *)
+
+(* begin hide *)
+Require Import Arith List Omega.
+
+Require Import Axioms Tactics.
+
+Set Implicit Arguments.
+(* end hide *)
+
+
+(** %\chapter{Modeling Impure Languages}% *)
+
+(** TODO: Prose for this chapter *)
+
+Section var.
+  Variable var : Type.
+
+  Inductive term : Type :=
+  | Var : var -> term
+  | App : term -> term -> term
+  | Abs : (var -> term) -> term
+  | Unit : term.
+End var.
+
+Implicit Arguments Unit [var].
+
+Notation "# v" := (Var v) (at level 70).
+Notation "()" := Unit.
+
+Infix "@" := App (left associativity, at level 72).
+Notation "\ x , e" := (Abs (fun x => e)) (at level 73).
+Notation "\ ? , e" := (Abs (fun _ => e)) (at level 73).
+
+
+Module predicative.
+
+  Inductive val : Type :=
+  | Func : nat -> val
+  | VUnit.
+
+  Inductive computation : Type :=
+  | Return : val -> computation
+  | Bind : computation -> (val -> computation) -> computation
+  | CAbs : (val -> computation) -> computation
+  | CApp : val -> val -> computation.
+
+  Definition func := val -> computation.
+
+  Fixpoint get (n : nat) (ls : list func) {struct ls} : option func :=
+    match ls with
+      | nil => None
+      | x :: ls' =>
+        if eq_nat_dec n (length ls')
+          then Some x
+          else get n ls'
+    end.
+
+  Inductive eval : list func -> computation -> list func -> val -> Prop :=
+  | EvalReturn : forall ds d,
+    eval ds (Return d) ds d
+  | EvalBind : forall ds c1 c2 ds' d1 ds'' d2,
+    eval ds c1 ds' d1
+    -> eval ds' (c2 d1) ds'' d2
+    -> eval ds (Bind c1 c2) ds'' d2
+  | EvalCAbs : forall ds f,
+    eval ds (CAbs f) (f :: ds) (Func (length ds))
+  | EvalCApp : forall ds i d2 f ds' d3,
+    get i ds = Some f
+    -> eval ds (f d2) ds' d3
+    -> eval ds (CApp (Func i) d2) ds' d3.
+
+  Fixpoint termDenote (e : term val) : computation :=
+    match e with
+      | Var v => Return v
+      | App e1 e2 => Bind (termDenote e1) (fun f =>
+        Bind (termDenote e2) (fun x =>
+          CApp f x))
+      | Abs e' => CAbs (fun x => termDenote (e' x))
+
+      | Unit => Return VUnit
+    end.
+
+  Definition Term := forall var, term var.
+  Definition TermDenote (E : Term) := termDenote (E _).
+
+  Definition ident : Term := fun _ => \x, #x.
+  Eval compute in TermDenote ident.
+
+  Definition unite : Term := fun _ => ().
+  Eval compute in TermDenote unite.
+
+  Definition ident_self : Term := fun _ => ident _ @ ident _.
+  Eval compute in TermDenote ident_self.
+
+  Definition ident_unit : Term := fun _ => ident _ @ unite _.
+  Eval compute in TermDenote ident_unit.
+
+  Theorem eval_ident_unit : exists ds, eval nil (TermDenote ident_unit) ds VUnit.
+    compute.
+    repeat econstructor.
+    simpl.
+    rewrite (eta Return).
+    reflexivity.
+  Qed.
+
+  Hint Constructors eval.
+
+  Lemma app_nil_start : forall A (ls : list A),
+    ls = nil ++ ls.
+    reflexivity.
+  Qed.
+
+  Lemma app_cons : forall A (x : A) (ls : list A),
+    x :: ls = (x :: nil) ++ ls.
+    reflexivity.
+  Qed.
+
+  Theorem eval_monotone : forall ds c ds' d,
+    eval ds c ds' d
+    -> exists ds'', ds' = ds'' ++ ds.
+    Hint Resolve app_nil_start app_ass app_cons.
+
+    induction 1; firstorder; subst; eauto.
+  Qed.
+
+  Lemma length_app : forall A (ds2 ds1 : list A),
+    length (ds1 ++ ds2) = length ds1 + length ds2.
+    induction ds1; simpl; intuition.
+  Qed.
+
+  Lemma get_app : forall ds2 d ds1,
+    get (length ds2) (ds1 ++ d :: ds2) = Some d.
+    Hint Rewrite length_app : cpdt.
+
+    induction ds1; crush;
+      match goal with
+        | [ |- context[if ?E then _ else _] ] => destruct E
+      end; crush.
+  Qed.
+
+  Theorem invert_ident : forall (E : Term) ds ds' d,
+    eval ds (TermDenote (fun _ => ident _ @ E _)) ds' d
+    -> eval ((fun x => Return x) :: ds) (TermDenote E) ds' d.
+    inversion 1; subst.
+    clear H.
+    inversion H3; clear H3; subst.
+    inversion H6; clear H6; subst.
+    generalize (eval_monotone H2); crush.
+    inversion H5; clear H5; subst.
+    rewrite get_app in H3.
+    inversion H3; clear H3; subst.
+    inversion H7; clear H7; subst.
+    assumption.
+  Qed.
+
+End predicative.