%%% Lambda-Calculus Fragment of Mini-ML. %%% Author: Frank Pfenning % Simple types tp : type. %name tp T. arrow : tp -> tp -> tp. % T1 => T2 % Expressions exp : type. %name exp E. lam : (exp -> exp) -> exp. % lam x. E app : exp -> exp -> exp. % (E1 E2) % Type inference % |- E : T (expression E has type T) of : exp -> tp -> type. %name of P. %mode of +E *T. % %mode of +E +T. % incorrect at tp_app % %mode of +E -T. % incorrect at tp_lam tp_lam : of (lam E) (arrow T1 T2) % |- lam x. E : T1 => T2 <- ({x:exp} % if x:T1 |- E : T2. of x T1 -> of (E x) T2). tp_app : of (app E1 E2) T1 % |- E1 E2 : T1 <- of E1 (arrow T2 T1) % if |- E1 : T2 => T1 <- of E2 T2. % and |- E2 : T2. % Evaluation (call-by-value) % E ==> V (expression E evaluates to value V) eval : exp -> exp -> type. %name eval D. %mode eval +E -V. ev_lam : eval (lam E) (lam E). % lam x.E ==> lam x.E. ev_app : eval (app E1 E2) V % E1 E2 ==> V <- eval E1 (lam E1') % if E1 ==> lam x. E1' <- eval E2 V2 % and E2 ==> V2 <- eval (E1' V2) V. % and [V2/x]E1' ==> V. % Regular world for type-checking %block tp_var : some {T:tp} block {x:exp} {u:of x T}. %worlds (tp_var) (of E T). % Type inference terminates %terminates E (of E T). % There is at least one typing rule for every expression %covers of +E *T. % Next fails, because T is neither input nor output % %total E (of E T). % Closed worlds for evaluation %worlds () (eval E V). % There is a at least one evaluation rule for every closed expression %covers eval +E -V. % %terminates E (eval E V). % fails for ev_app % Type preservation as higher-level family tps : eval E V -> of E T -> of V T -> type. tps_lam : tps (ev_lam) (tp_lam P) (tp_lam P). tps_app : tps (ev_app D3 D2 D1) (tp_app P2 P1) Q <- tps D1 P1 (tp_lam Q1') <- tps D2 P2 Q2 <- tps D3 (Q1' V2 Q2) Q. %mode tps +D +P -Q. %worlds () (tps D P _). %total D (tps D P _). % Type preservation proven automatically %theorem tpsa : forall* {E:exp} {V:exp} {T:tp} forall {D:eval E V} {P:of E T} exists {Q:of V T} true. %prove 5 D (tpsa D P Q). % Applying type preservation e0 = (app (lam [x] x) (lam [y] y)). %solve p0 : of e0 T. %solve d0 : eval e0 V. %solve tps0 : tps d0 p0 Q. % Example of regular worlds % cp copies input to output. cp : exp -> exp -> type. cp_app : cp (app E1 E2) (app F1 F2) <- cp E1 F1 <- cp E2 F2. cp_lam : cp (lam [x] E x) (lam [x] F x) <- ({x:exp} cp x x -> cp (E x) (F x)). %mode cp +E -F. %block cp_var : block {x:exp} {u:cp x x}. %worlds (cp_var) (cp E _). %total E (cp E _). % Following version cannot be checked % Input coverage on parameter y is violated %{ cp : exp -> exp -> type. cp_app : cp (app E1 E2) (app F1 F2) <- cp E1 F1 <- cp E2 F2. cp_lam : cp (lam [x] E x) (lam [x] F x) <- ({x:exp} {y:exp} cp x y -> cp (E x) (F y)). %mode cp +E -F. %block cp_var : block {x:exp} {y:exp} {u:cp x y}. %worlds (cp_var) (cp E _). %total E (cp E _). }% % Following version cannot be checked % Output coverage on (F y) is violated. %{ cp : exp -> exp -> type. cp_app : cp (app E1 E2) (app F1 F2) <- cp E1 F1 <- cp E2 F2. cp_lam : cp (lam [x] E x) (lam [x] F x) <- ({x:exp} {y:exp} cp x y -> cp y y -> cp (E x) (F y)). %mode cp +E -F. %block cp_var : block {x:exp} {y:exp} {u:cp x y} {w:cp y y}. %worlds (cp_var) (cp E _). %total E (cp E _). }% %theorem cpt : forallG (pi {x:exp} {y:cp x x}) forall {E:exp} exists {F:exp} {C:cp E F} true. %prove 5 E (cpt E _ _).