POPL Tutorial/New language

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

Arithmetic Primitives

nat : type.  
z : nat.
s : nat -> nat.

add : nat -> nat -> nat -> type.
%mode add +M +N -P.

add/z : add z N N.

add/s : add (s M) N (s P)
         <- add M N P.

%worlds () (add _ _ _).
%total M (add M _ _).


mult : nat -> nat -> nat -> type.
%mode mult +M +N -P.

mult/z : mult z N z.

mult/s : mult (s M) N Q
          <- mult M N P
          <- add P N Q.

%worlds () (mult _ _ _).
%total M (mult M _ _).

Language Syntax

tp : type.

num : tp.
arrow : tp -> tp -> tp.
prod : tp -> tp -> tp.

exp : type.

numeral : nat -> exp.
plus : exp -> exp -> exp.
times : exp -> exp -> exp.

lam : tp -> (exp -> exp) -> exp.
app : exp -> exp -> exp.

pair : exp -> exp -> exp.
split : exp -> (exp -> exp -> exp) -> exp.

Dynamic Semantics

value : exp -> type.
step : exp -> exp -> type.

%%% argh, too many rules!

value/numeral : value (numeral N).

value/lam : value (lam T [x] E x).

value/pair : value (pair E1 E2)
              <- value E1
              <- value E2.


step/plus/1 : step (plus E1 E2) (plus E1' E2)
               <- step E1 E1'.

step/plus/2 : step (plus V1 E2) (plus V1 E2')
               <- value V1
               <- step E2 E2'.

step/plus/add : step (plus (numeral N1) (numeral N2)) (numeral N3)
                 <- add N1 N2 N3.

step/times/1 : step (times E1 E2) (times E1' E2)
                <- step E1 E1'.

step/times/2 : step (times V1 E2) (times V1 E2')
                <- value V1
                <- step E2 E2'.

step/times/mult : step (times (numeral N1) (numeral N2)) (numeral N3)
                   <- mult N1 N2 N3.

step/app/fun : step (app E1 E2) (app E1' E2)
                <- step E1 E1'.

step/app/arg : step (app V1 E2) (app V1 E2')
                <- value V1
                <- step E2 E2'.

step/app/beta : step (app (lam T ([x] E x)) V) (E V)
                 <- value V.

step/pair/1 : step (pair E1 E2) (pair E1' E2)
               <- step E1 E1'.

step/pair/2 : step (pair V1 E2) (pair V1 E2')
               <- value V1
               <- step E2 E2'.

step/split/arg : step (split E1 ([x] [y] E2 x y)) (split E1' ([x] [y] E2 x y))
                  <- step E1 E1'.

step/split/pair : step (split (pair V1 V2) ([x] [y] E x y)) (E V1 V2)
                   <- value V1
                   <- value V2.

%worlds () (value _).
%worlds () (step _ _).

Static Semantics

of : exp -> tp -> type.

of/numeral : of (numeral N) num.

of/plus : of (plus E1 E2) num
           <- of E1 num
           <- of E2 num.

of/times : of (times E1 E2) num
            <- of E1 num
            <- of E2 num.

of/lam : of (lam T1 [x] E x) (arrow T1 T2)
          <- ({x} of x T1 -> of (E x) T2).

of/app : of (app E1 E2) T
          <- of E1 (arrow T2 T)
          <- of E2 T2.

of/pair : of (pair E1 E2) (prod T1 T2)
           <- of E1 T1
           <- of E2 T2.

of/split : of (split E ([x] [y] Ebody x y)) T
            <- of E (prod T1 T2)
            <- ({x} of x T1 -> {y} of y T2 -> of (Ebody x y) T).

%block tbind : some {T:tp} block {x:exp} {dx:of x T}.
%worlds (tbind) (of _ _).

Progress

notstuck : exp -> type.

notstuck/value	: notstuck E
		   <- value E.

notstuck/step	: notstuck E
		   <- step E E'.


progress-app	: of E1 (arrow T1 T2)
		   -> notstuck E1
		   -> notstuck E2
		   -> notstuck (app E1 E2)
		   -> type.
%mode progress-app +Dof +Dns1 +Dns2 -Dns3.

-	: progress-app Dof (notstuck/step Dstep) Dns2
	   (notstuck/step (step/app/fun Dstep)).

-	: progress-app Dof (notstuck/value Dval) (notstuck/step Dstep)
	   (notstuck/step (step/app/arg Dstep Dval)).

-	: progress-app (of/lam Dof') (notstuck/value value/lam)
	   (notstuck/value Dval2)
	   (notstuck/step (step/app/beta Dval2)).

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



progress-pair	: notstuck E1
		   -> notstuck E2
		   -> notstuck (pair E1 E2)
		   -> type.
%mode progress-pair +Dns1 +Dns2 -Dns3.

-	: progress-pair (notstuck/step Dstep) Dns2
	   (notstuck/step (step/pair/1 Dstep)).

-	: progress-pair (notstuck/value Dval1) (notstuck/step Dstep2)
	   (notstuck/step (step/pair/2 Dstep2 Dval1)).

-	: progress-pair (notstuck/value Dval1) (notstuck/value Dval2)
	   (notstuck/value (value/pair Dval2 Dval1)).

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



progress-split	: of E1 (prod T1 T2)
		   -> notstuck E1
		   -> {Ebody} notstuck (split E1 Ebody)
		   -> type.
%mode progress-split +Dof1 +Dns1 +Ebody -Dns2.

-	: progress-split Dof (notstuck/step Dstep) Ebody
	   (notstuck/step (step/split/arg Dstep)).

-	: progress-split (of/pair Dof2 Dof1) 
	   (notstuck/value (value/pair Dval2 Dval1)) Ebody
	   (notstuck/step (step/split/pair Dval2 Dval1)).

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



can-add	: {N1} {N2} add N1 N2 N3
	   -> type.
%mode can-add +N1 +N2 -Dadd.

-	: can-add z N add/z.

-	: can-add (s N1) N2 (add/s Dadd)
	   <- can-add N1 N2 Dadd.

%worlds () (can-add _ _ _).
%total (D1) (can-add D1 _ _). 



progress-plus	: of E1 num
		   -> of E2 num
		   -> notstuck E1
		   -> notstuck E2
		   -> notstuck (plus E1 E2)
		   -> type.
%mode progress-plus +Dof1 +Dof2 +Dns1 +Dns2 -Dns3.

-	: progress-plus Dof1 Dof2 (notstuck/step Dstep) Dns2
	   (notstuck/step (step/plus/1 Dstep)).

-	: progress-plus Dof1 Dof2 (notstuck/value Dval1) (notstuck/step Dstep2)
	   (notstuck/step (step/plus/2 Dstep2 Dval1)).

-	: progress-plus of/numeral of/numeral
	   (notstuck/value value/numeral) (notstuck/value value/numeral)
	   (notstuck/step (step/plus/add Dadd))
	   <- can-add N1 N2 (Dadd : add N1 N2 N3).

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



can-mult	: {N1} {N2} mult N1 N2 N3
	   -> type.
%mode can-mult +N1 +N2 -Dmult.

-	: can-mult z N mult/z.

-	: can-mult (s N1) N2 (mult/s Dadd Dmult)
	   <- can-mult N1 N2 (Dmult : mult N1 N2 N3)
	   <- can-add N3 N2 Dadd.

%worlds () (can-mult _ _ _).
%total (D1) (can-mult D1 _ _). 



progress-times	: of E1 num
		   -> of E2 num
		   -> notstuck E1
		   -> notstuck E2
		   -> notstuck (times E1 E2)
		   -> type.
%mode progress-times +Dof1 +Dof2 +Dns1 +Dns2 -Dns3.

-	: progress-times Dof1 Dof2 (notstuck/step Dstep) Dns2
	   (notstuck/step (step/times/1 Dstep)).

-	: progress-times Dof1 Dof2 (notstuck/value Dval1) (notstuck/step Dstep2)
	   (notstuck/step (step/times/2 Dstep2 Dval1)).

-	: progress-times of/numeral of/numeral
	   (notstuck/value value/numeral) (notstuck/value value/numeral)
	   (notstuck/step (step/times/mult Dmult))
	   <- can-mult N1 N2 (Dmult : mult N1 N2 N3).

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



progress : of E T
	    -> notstuck E
	    -> type.
%mode progress +Dof -Dns.

-	: progress of/numeral
	   (notstuck/value value/numeral). 

-	: progress (of/plus Dof2 Dof1) Dns3
	   <- progress Dof1 Dns1
	   <- progress Dof2 Dns2
	   <- progress-plus Dof1 Dof2 Dns1 Dns2 Dns3.

-	: progress (of/times Dof2 Dof1) Dns3
	   <- progress Dof1 Dns1
	   <- progress Dof2 Dns2
	   <- progress-times Dof1 Dof2 Dns1 Dns2 Dns3.

-	: progress (of/lam Dof1)
	   (notstuck/value value/lam). 

-	: progress (of/app Dof2 Dof1) Dns3
	   <- progress Dof1 Dns1
	   <- progress Dof2 Dns2
	   <- progress-app Dof1 Dns1 Dns2 Dns3.

-	: progress (of/pair Dof2 Dof1) Dns3
	   <- progress Dof1 Dns1
	   <- progress Dof2 Dns2
	   <- progress-pair Dns1 Dns2 Dns3.

-	: progress (of/split 
		      (Dbody : {x} of x T1 -> {y} of y T2 -> of (Ebody x y) T)
		      Dof1) Dns2
	   <- progress Dof1 Dns1
	   <- progress-split Dof1 Dns1 Ebody Dns2.

%worlds () (progress _ _).
%total (D1) (progress D1 _).

Preservation

preservation	: of E1 T1
		   -> step E1 E2
		   -> of E2 T1
		   -> type.
%mode preservation +Dof1 +Dstep -Dof2.

-	: preservation (of/plus Dof2 Dof1) (step/plus/1 Dstep1)
	   (of/plus Dof2 Dof1')
	   <- preservation Dof1 Dstep1 Dof1'.

-	: preservation (of/plus Dof2 Dof1) (step/plus/2 Dstep2 Dval1)
	   (of/plus Dof2' Dof1)
	   <- preservation Dof2 Dstep2 Dof2'.

-	: preservation (of/plus Dof2 Dof1) (step/plus/add Dadd) 
	   of/numeral.

-	: preservation (of/times Dof2 Dof1) (step/times/1 Dstep1)
	   (of/times Dof2 Dof1')
	   <- preservation Dof1 Dstep1 Dof1'.

-	: preservation (of/times Dof2 Dof1) (step/times/2 Dstep2 Dval1)
	   (of/times Dof2' Dof1)
	   <- preservation Dof2 Dstep2 Dof2'.

-	: preservation (of/times Dof2 Dof1) (step/times/mult Dmult) 
	   of/numeral.

-	: preservation (of/pair Dof2 Dof1) (step/pair/1 Dstep1)
	   (of/pair Dof2 Dof1')
	   <- preservation Dof1 Dstep1 Dof1'.

-	: preservation (of/pair Dof2 Dof1) (step/pair/2 Dstep2 Dval)
	   (of/pair Dof2' Dof1)
	   <- preservation Dof2 Dstep2 Dof2'.

-	: preservation (of/split Dbody Dof1) (step/split/arg Dstep1)
	   (of/split Dbody Dof1')
	   <- preservation Dof1 Dstep1 Dof1'.

-	: preservation (of/split Dbody (of/pair Dof2 Dof1))
	   (step/split/pair Dval2 Dval1)
	   (Dbody E1 Dof1 E2 Dof2).

-	: preservation (of/app Dof2 Dof1) (step/app/fun Dstep1)
	   (of/app Dof2 Dof1')
	   <- preservation Dof1 Dstep1 Dof1'.

-	: preservation (of/app Dof2 Dof1) (step/app/arg Dstep2 Dval)
	   (of/app Dof2' Dof1)
	   <- preservation Dof2 Dstep2 Dof2'.

-	: preservation (of/app Dof2 (of/lam Dbody)) (step/app/beta Dval1)
	   (Dbody E2 Dof2).

%worlds () (preservation _ _ _).
%total (D1) (preservation _ D1 _).