Mercurial > cpdt > repo
diff src/Extensional.v @ 175:022feabdff50
STLC cpsExp
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Mon, 10 Nov 2008 11:05:49 -0500 |
parents | |
children | 9b1f58dbc464 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Extensional.v Mon Nov 10 11:05:49 2008 -0500 @@ -0,0 +1,299 @@ +(* 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 String List. + +Require Import AxiomsImpred Tactics. + +Set Implicit Arguments. +(* end hide *) + + +(** %\chapter{Certifying Extensional Transformations}% *) + +(** TODO: Prose for this chapter *) + + +(** * Simply-Typed Lambda Calculus *) + +Module STLC. + Module Source. + Inductive type : Type := + | TNat : type + | Arrow : type -> type -> type. + + Notation "'Nat'" := TNat : source_scope. + Infix "-->" := Arrow (right associativity, at level 60) : source_scope. + + Open Scope source_scope. + Bind Scope source_scope with type. + Delimit Scope source_scope with source. + + Section vars. + Variable var : type -> Type. + + Inductive exp : type -> Type := + | Var : forall t, + var t + -> exp t + + | Const : nat -> exp Nat + | Plus : exp Nat -> exp Nat -> exp Nat + + | App : forall t1 t2, + exp (t1 --> t2) + -> exp t1 + -> exp t2 + | Abs : forall t1 t2, + (var t1 -> exp t2) + -> exp (t1 --> t2). + End vars. + + Definition Exp t := forall var, exp var t. + + Implicit Arguments Var [var t]. + Implicit Arguments Const [var]. + Implicit Arguments Plus [var]. + Implicit Arguments App [var t1 t2]. + Implicit Arguments Abs [var t1 t2]. + + Notation "# v" := (Var v) (at level 70) : source_scope. + + Notation "^ n" := (Const n) (at level 70) : source_scope. + Infix "+^" := Plus (left associativity, at level 79) : source_scope. + + Infix "@" := App (left associativity, at level 77) : source_scope. + Notation "\ x , e" := (Abs (fun x => e)) (at level 78) : source_scope. + Notation "\ ! , e" := (Abs (fun _ => e)) (at level 78) : source_scope. + + Bind Scope source_scope with exp. + + Definition zero : Exp Nat := fun _ => ^0. + Definition one : Exp Nat := fun _ => ^1. + Definition zpo : Exp Nat := fun _ => zero _ +^ one _. + Definition ident : Exp (Nat --> Nat) := fun _ => \x, #x. + Definition app_ident : Exp Nat := fun _ => ident _ @ zpo _. + Definition app : Exp ((Nat --> Nat) --> Nat --> Nat) := fun _ => + \f, \x, #f @ #x. + Definition app_ident' : Exp Nat := fun _ => app _ @ ident _ @ zpo _. + + Fixpoint typeDenote (t : type) : Set := + match t with + | Nat => nat + | t1 --> t2 => typeDenote t1 -> typeDenote t2 + end. + + Fixpoint expDenote t (e : exp typeDenote t) {struct e} : typeDenote t := + match e in (exp _ t) return (typeDenote t) with + | Var _ v => v + + | Const n => n + | Plus e1 e2 => expDenote e1 + expDenote e2 + + | App _ _ e1 e2 => (expDenote e1) (expDenote e2) + | Abs _ _ e' => fun x => expDenote (e' x) + end. + + Definition ExpDenote t (e : Exp t) := expDenote (e _). + End Source. + + Module CPS. + Inductive type : Type := + | TNat : type + | Cont : type -> type + | TUnit : type + | Prod : type -> type -> type. + + Notation "'Nat'" := TNat : cps_scope. + Notation "'Unit'" := TUnit : cps_scope. + Notation "t --->" := (Cont t) (at level 61) : cps_scope. + Infix "**" := Prod (right associativity, at level 60) : cps_scope. + + Bind Scope cps_scope with type. + Delimit Scope cps_scope with cps. + + Section vars. + Variable var : type -> Type. + + Inductive prog : Type := + | PHalt : + var Nat + -> prog + | App : forall t, + var (t --->) + -> var t + -> prog + | Bind : forall t, + primop t + -> (var t -> prog) + -> prog + + with primop : type -> Type := + | Var : forall t, + var t + -> primop t + + | Const : nat -> primop Nat + | Plus : var Nat -> var Nat -> primop Nat + + | Abs : forall t, + (var t -> prog) + -> primop (t --->) + + | Pair : forall t1 t2, + var t1 + -> var t2 + -> primop (t1 ** t2) + | Fst : forall t1 t2, + var (t1 ** t2) + -> primop t1 + | Snd : forall t1 t2, + var (t1 ** t2) + -> primop t2. + End vars. + + Implicit Arguments PHalt [var]. + Implicit Arguments App [var t]. + + Implicit Arguments Var [var t]. + Implicit Arguments Const [var]. + Implicit Arguments Plus [var]. + Implicit Arguments Abs [var t]. + Implicit Arguments Pair [var t1 t2]. + Implicit Arguments Fst [var t1 t2]. + Implicit Arguments Snd [var t1 t2]. + + Notation "'Halt' x" := (PHalt x) (no associativity, at level 75) : cps_scope. + Infix "@@" := App (no associativity, at level 75) : cps_scope. + Notation "x <- p ; e" := (Bind p (fun x => e)) + (right associativity, at level 76, p at next level) : cps_scope. + Notation "! <- p ; e" := (Bind p (fun _ => e)) + (right associativity, at level 76, p at next level) : cps_scope. + + Notation "# v" := (Var v) (at level 70) : cps_scope. + + Notation "^ n" := (Const n) (at level 70) : cps_scope. + Infix "+^" := Plus (left associativity, at level 79) : cps_scope. + + Notation "\ x , e" := (Abs (fun x => e)) (at level 78) : cps_scope. + Notation "\ ! , e" := (Abs (fun _ => e)) (at level 78) : cps_scope. + + Notation "[ x1 , x2 ]" := (Pair x1 x2) (at level 73) : cps_scope. + Notation "#1 x" := (Fst x) (at level 72) : cps_scope. + Notation "#2 x" := (Snd x) (at level 72) : cps_scope. + + Bind Scope cps_scope with prog primop. + + Open Scope cps_scope. + + Fixpoint typeDenote (t : type) : Set := + match t with + | Nat => nat + | t' ---> => typeDenote t' -> nat + | Unit => unit + | t1 ** t2 => (typeDenote t1 * typeDenote t2)%type + end. + + Fixpoint progDenote (e : prog typeDenote) : nat := + match e with + | PHalt n => n + | App _ f x => f x + | Bind _ p x => progDenote (x (primopDenote p)) + end + + with primopDenote t (p : primop typeDenote t) {struct p} : typeDenote t := + match p in (primop _ t) return (typeDenote t) with + | Var _ v => v + + | Const n => n + | Plus n1 n2 => n1 + n2 + + | Abs _ e => fun x => progDenote (e x) + + | Pair _ _ v1 v2 => (v1, v2) + | Fst _ _ v => fst v + | Snd _ _ v => snd v + end. + + Definition Prog := forall var, prog var. + Definition Primop t := forall var, primop var t. + Definition ProgDenote (E : Prog) := progDenote (E _). + Definition PrimopDenote t (P : Primop t) := primopDenote (P _). + End CPS. + + Import Source CPS. + + Fixpoint cpsType (t : Source.type) : CPS.type := + match t with + | Nat => Nat%cps + | t1 --> t2 => (cpsType t1 ** (cpsType t2 --->) --->)%cps + end%source. + + Reserved Notation "x <-- e1 ; e2" (right associativity, at level 76, e1 at next level). + + Section cpsExp. + Variable var : CPS.type -> Type. + + Import Source. + Open Scope cps_scope. + + Fixpoint cpsExp t (e : exp (fun t => var (cpsType t)) t) {struct e} + : (var (cpsType t) -> prog var) -> prog var := + match e in (exp _ t) return ((var (cpsType t) -> prog var) -> prog var) with + | Var _ v => fun k => k v + + | Const n => fun k => + x <- ^n; + k x + | Plus e1 e2 => fun k => + x1 <-- e1; + x2 <-- e2; + x <- x1 +^ x2; + k x + + | App _ _ e1 e2 => fun k => + f <-- e1; + x <-- e2; + kf <- \r, k r; + p <- [x, kf]; + f @@ p + | Abs _ _ e' => fun k => + f <- CPS.Abs (var := var) (fun p => + x <- #1 p; + kf <- #2 p; + r <-- e' x; + kf @@ r); + k f + end + + where "x <-- e1 ; e2" := (cpsExp e1 (fun x => e2)). + End cpsExp. + + Notation "x <-- e1 ; e2" := (cpsExp e1 (fun x => e2)) : cps_scope. + Notation "! <-- e1 ; e2" := (cpsExp e1 (fun _ => e2)) + (right associativity, at level 76, e1 at next level) : cps_scope. + + Implicit Arguments cpsExp [var t]. + Definition CpsExp (E : Exp Nat) : Prog := + fun var => cpsExp (E _) (PHalt (var := _)). + + Eval compute in CpsExp zero. + Eval compute in CpsExp one. + Eval compute in CpsExp zpo. + Eval compute in CpsExp app_ident. + Eval compute in CpsExp app_ident'. + + Eval compute in ProgDenote (CpsExp zero). + Eval compute in ProgDenote (CpsExp one). + Eval compute in ProgDenote (CpsExp zpo). + Eval compute in ProgDenote (CpsExp app_ident). + Eval compute in ProgDenote (CpsExp app_ident'). + +End STLC.