Polarized PCF

From The Twelf Project
Jump to: navigation, search
This is Literate Twelf
Code: here
Status: %% OK %%
Output: here.

Polarized PCF with a stack machine semantics

  1. Interalizes the composition/leftist substitution principles (left-commutative cuts), so there are no meta-ops in evaluation other than LF substitution
  2. force+ binds a positive value variable, rather than requiring an immediate left inversion
  3. Proves completeness of focusing, so you can see what direct-style terms mean
  4. Does purely negative stream using (non-canonical) negative continuation variables; completeness of focusing does some sort of CPS conversion

Syntax

pos : type.
neg : type.

down : neg -> pos.
nat  : pos.

up  : pos -> neg.
arr : pos -> neg -> neg.
stream : neg -> neg.

val+  : pos -> type.
cont+ : pos -> pos -> type.
val-  : neg -> type.
cont- : neg -> pos -> type.
exp   : pos -> type.

%% positive values
zero   : val+ nat.
succ   : val+ nat -> val+ nat.
delay- : val- A- -> val+ (down A-).

%% positive conts
ifz      : exp A+ -> (val+ nat -> exp A+) -> cont+ nat A+.
force-   : (val- A- -> exp C+) -> cont+ (down A-) C+.
%% internalize composition
comp+    : cont+ A+ B+ -> (val+ B+ -> exp C+) -> cont+ A+ C+.

%% negative values
lam    : (val+ A+ -> val- B-) -> val- (arr A+ B-).
delay+ : exp A+ -> val- (up A+).
fix    : (val- A- -> val- A-) -> val- A-.
cons   : ({C+} cont- A- C+ -> exp C+) 
	  -> ({C+} cont- (stream A-) C+ -> exp C+)
	  -> val- (stream A-).

%% negative conts
app    : val+ A+ -> cont- B- C+ -> cont- (arr A+ B-) C+.
force+ : (val+ A+ -> exp C+) -> cont- (up A+) C+.
%% internalize composition
comp-  : cont- A- B+ -> (val+ B+ -> exp C+) -> cont- A- C+.
head   : cont- A- C+ -> cont- (stream A-) C+ .
tail   : cont- (stream A-) A+ -> cont- (stream A-) A+.

%% expressions
ret : val+ A+ -> exp A+.
%% internalize arbitrary cuts.
%% these two are canonical when the value is a variable,
%% but if we'ere only running closed terms, then that
%% distinction is moot.  
cut+ : val+ A+ -> cont+ A+ C+ -> exp C+. 
cut- : val- A- -> cont- A- C+ -> exp C+.
%% internalize composition
let  : exp A+ -> (val+ A+ -> exp C+) -> exp C+.

%% these terms are not eta-long, because we use the same
%% val judgements on the left as on the right
%block posb : some {A+ : pos} block {x : val+ A+}. 
%block negb : some {A- : neg} block {x : val- A-}.
%block negcb : some {A- : neg} block {A+ : pos} {k : cont- A- A+}.
%worlds (posb | negb | negcb) (val+ _) (cont+ _ _) (val- _) (cont- _ _) (exp _).

%% FIXME: weirldly asymetric: we need both pos and neg assumptions,
%% but not both kinds of conclusion??

Step

Note that all rules are axioms.

step : exp A+ -> exp A+ -> type.
%mode step +X1 -X2.

step/ifz-0 : step (cut+ zero (ifz E0 E1)) E0. 
step/ifz-1 : step (cut+ (succ V) (ifz E0 E1)) (E1 V). 
step/force- : step (cut+ (delay- V-) (force- E)) (E V-).
step/fix    : step (cut- (fix E) K-) (cut- (E (fix E)) K-).
step/app    : step (cut- (lam V-) (app V+ K-)) (cut- (V- V+) K-).
step/force+ : step (cut- (delay+ E1) (force+ E)) (let E1 E).
step/head   : step (cut- (cons E1 E2) (head K-)) (E1 _ K-).
step/tail   : step (cut- (cons E1 E2) (tail K-)) (E2 _ K-).
%% left commutative cuts:
step/letret  : step (let (ret V+) E2) (E2 V+).
step/letcut+ : step (let (cut+ V+ K+) E2) (cut+ V+ (comp+ K+ E2)).
step/letcut- : step (let (cut- V- K-) E2) (cut- V- (comp- K- E2)).
step/letlet  : step (let (let E1 E2) E3) (let E1 ([x] (let (E2 x) E3))).
step/cconv-ifz    : step (cut+ V+ (comp+ (ifz E0 E1) E))
		     (cut+ V+ (ifz (let E0 E) ([y] let (E1 y) E))). 
step/cconv-force- : step (cut+ V+ (comp+ (force- E1) E))
		     (cut+ V+ (force- [y] (let (E1 y) E))).
step/cconv-comp+  : step (cut+ V+ (comp+ (comp+ E1 E2) E))
		     (cut+ V+ (comp+ E1 ([y] (let (E2 y) E)))).
step/cconv-app    : step (cut- V- (comp- (app V+ K-) E))
		     (cut- V- (app V+ (comp- K- E))).
step/cconv-force+ : step (cut- V- (comp- (force+ E1) E))
		     (cut- V- (force+ ([y] (let (E1 y) E)))).
step/cconv-comp- : step (cut- V- (comp- (comp- K- E1) E2))
	  	     (cut- V- (comp- K- ([y] (let (E1 y) E2)))).
step/cconv-head  : step (cut- V- (comp- (head K-) E))
		    (cut- V- (head (comp- K- E))).
step/cconv-tail  : step (cut- V- (comp- (tail K-) E))
		    (cut- V- (tail (comp- K- E))).

%worlds () (step _ _).

Progress

ok : exp A+ -> type.
ok/final : ok (ret V+).
ok/step  : ok E
	    <- step E E'.

progress : {E : exp A+} ok E -> type.
%mode progress +E -O.

- : progress _ ok/final.
- : progress _ (ok/step step/ifz-0).
- : progress _ (ok/step step/ifz-1).
- : progress _ (ok/step step/force-).
- : progress _ (ok/step step/fix).
- : progress _ (ok/step step/app).
- : progress _ (ok/step (step/force+)).
- : progress _ (ok/step step/head).
- : progress _ (ok/step step/tail).
- : progress _ (ok/step step/letret).
- : progress _ (ok/step step/letcut+).
- : progress _ (ok/step step/letcut-).
- : progress _ (ok/step step/letlet).
- : progress _ (ok/step step/cconv-ifz).
- : progress _ (ok/step step/cconv-force-).
- : progress _ (ok/step step/cconv-comp+).
- : progress _ (ok/step step/cconv-app).
- : progress _ (ok/step step/cconv-force+).
- : progress _ (ok/step step/cconv-head).
- : progress _ (ok/step step/cconv-tail).
- : progress _ (ok/step step/cconv-comp-).

%worlds () (progress _ _).
%total {} (progress _ _).

EL

Syntax

etp : type.				%name etp T.
enat : etp.
earr : etp -> etp -> etp.
estream : etp -> etp.

eexp : etp -> type.			%name eexp E.  %postfix 1 eexp.
ez : enat eexp.
es : enat eexp -> enat eexp.
eifz : enat eexp -> T eexp -> (enat eexp -> T eexp) -> T eexp.
efun : {T1:etp} {T2:etp} ((earr T1 T2) eexp -> T1 eexp -> T2 eexp) -> (earr T1 T2) eexp.
eapp : (earr T1 T2) eexp -> T1 eexp -> T2 eexp.
econs : T eexp -> (estream T) eexp -> (estream T) eexp.
estreamfix : ((estream T) eexp -> (estream T) eexp) -> (estream T) eexp.
ehead : (estream T) eexp -> T eexp.
etail : (estream T) eexp -> (estream T) eexp.

Completeness of focusing

poltp : etp -> pos -> type.
%mode poltp +X1 -X2.

poltp/nat : poltp enat nat.
poltp/arr : poltp (earr T1 T2) (down (arr A1 (up A2)))
	     <- poltp T1 A1
	     <- poltp T2 A2.
poltp/stream : poltp (estream T) (down (stream (up A)))
		<- poltp T A.

%worlds () (poltp _ _).
%total T (poltp T _).
%unique poltp +T -1A.

can-poltp : {T} poltp T A -> type.
%mode can-poltp +X1 -X3.
%worlds () (can-poltp _ _).
% not really a trustme: Twelf proved this totality above!
%trustme %total {} (can-poltp _ _).

id : pos -> pos -> type.
refl : id A A.

unique-poltp : poltp T A' -> poltp T A -> id A A' -> type.
%mode unique-poltp +X1 +X2 -X3.
%worlds () (unique-poltp _ _ _).
% not really a trustme: Twelf proved this totality above!
%trustme %total {} (unique-poltp _ _ _).

retype : exp A -> id A A' -> exp A' -> type.
%mode retype +X1 +X2 -X3.
- : retype D refl D.
%worlds (posb | negb) (retype _ _ _).
%total {} (retype _ _ _).

complete : poltp T A -> T eexp -> exp A -> type.
%mode complete +X1 +X2 -X3.

complete/z : complete poltp/nat ez (ret zero).
complete/s : complete poltp/nat (es E) (let E' ([x] (ret (succ x))))
	      <- complete poltp/nat E E'.
complete/ifz : complete (Dpol : poltp T A) (eifz E E0 E1)
		(let E' ([x] cut+ x (ifz E0' E1')))
		<- complete poltp/nat E E'
		<- complete Dpol E0 E0'
		<- ({x : enat eexp} 
		      {x' : val+ nat}
		      {d : {A1' : pos} {D' : poltp enat A1'}
			    {Did : id nat A1'} {E : exp A1'}
 			  complete D' x E
			    <- unique-poltp D' poltp/nat Did
			    <- retype (ret x') Did E}
		      complete Dpol (E1 x) (E1' x')).

complete/fun : complete (poltp/arr (Dp2 : poltp T2 A2) (Dp1 : poltp T1 A1))
		(efun T1 T2 E) 
		(ret (delay- (fix ([f'] (lam [x'] (delay+ (E' (delay- f') x')))))))
		<- {f : (earr T1 T2) eexp} {f' : val+ (down (arr A1 (up A2)))} 
		   {d : {A1' : pos} {D' : poltp (earr T1 T2) A1'} 
			 {Did : id (down (arr A1 (up A2))) A1'} {E : exp A1'}
 			  complete D' f E
			  <- unique-poltp D' (poltp/arr Dp2 Dp1) Did
			  <- retype (ret f') Did E}
		   {x : T1 eexp} {x' : val+ A1} 
		   {d : {A1' : pos} {D' : poltp T1 A1'} 
			 {Did : id A1 A1'} {E : exp A1'}
 			  complete D' x E
			 <- unique-poltp D' Dp1 Did
			 <- retype (ret x') Did E}
		   complete Dp2 (E f x) (E' f' x').
complete/app : complete (D : poltp T A) (eapp (E1 : (earr T2 T) eexp) E2) 
		(let E1'
		   ([f] 
		      let E2'
		      ([x]
			 (cut+ f 
			      (force- [y] 
				 (cut- y (app x (force+ [z] (ret z)))))))))
		<- can-poltp T2 (Dp2 : poltp T2 A2)
		<- complete (poltp/arr D Dp2) E1 E1'
		<- complete Dp2 E2 E2'.

%% cons is lazy in both components
complete/cons : complete (poltp/stream Dp) (econs E1 E2) 
		 (ret (delay- (cons 
				 ([C+] [k] (let E1' [y] (cut- (delay+ (ret y)) k)))
				 ([C+] [k] (let E2' [y] 
					      (cut+ y (force- [w] 
							 (cut- w k))))))))
		 <- complete Dp E1 E1'
		 <- complete (poltp/stream Dp) E2 E2'.
complete/head : complete D (ehead E) 
		 (let E' 
		    ([x] 
		       (cut+ x (force- [y] 
				  (cut- y (head 
					     %% this is like an identity cont.
					     (force+ ([z] ret z))))))))
		 <- complete (poltp/stream D) E E'.
complete/tail : complete (poltp/stream D) (etail E) 
		 (let E' 
		    ([x] 
		       (cut+ x (force- [y] 
				  (ret (delay- 
					  (cons 
					     ([C] [hobs] 
						(cut- y (tail (head hobs))))
					     ([C] [tobs]
						(cut- y (tail (tail tobs))))
					     )))))))
		 <- complete (poltp/stream D) E E'.
complete/streamfix : complete (poltp/stream D) (estreamfix E1) 
		      (ret (delay- (fix [f] (cons 
					       ([C] [hobs] 
						  let (E1' (delay- f)) [r]
						  (cut+ r (force- [r'] 
							     (cut- r' (head hobs)))))
					       ([C] [tobs] 
						  let (E1' (delay- f)) [r]
						  (cut+ r (force- [r'] 
							     (cut- r' (tail tobs)))))
					       ))))
		      <- {x : _ eexp} {x' : val+ _} 
			 {d : {A1' : pos} {D' : poltp _ A1'} 
			       {Did : id _ A1'} {E : exp A1'}
			       complete D' x E
			       <- unique-poltp D' (poltp/stream D) Did
			       <- retype (ret x') Did E}
			 complete (poltp/stream D) (E1 x) (E1' x').

%block completeb : some {T1:etp} {A1:pos} {D : poltp T1 A1} 
		    block 
		    {x : T1 eexp} {x' : val+ A1} 
 		    {d : {A1' : pos} {D' : poltp T1 A1'}
			  {Did : id A1 A1'} {E : exp A1'}
 			  complete D' x E
			  <- unique-poltp D' D Did
			  <- retype (ret x') Did E}.

%worlds (completeb) (complete _ E _).
%total (E) (complete _ E _).