Antonis Stampoulis (Originate NYC), Adam Chlipala (MIT CSAIL)
tests : testsuite. %testsuite tests.
%use "00-adapted-stdlib.makam".
term : type.
typ : type.
typeof : term -> typ -> prop.
app : term -> term -> term.
lam : typ -> (term -> term) -> term.
arrow : typ -> typ -> typ.
\[\frac{\Gamma \vdash e_1 : \tau \to \tau' \hspace{1.0em} \Gamma \vdash e_2: \tau}{\Gamma \vdash e_1 \; e_2 : \tau'} \hspace{2em} \frac{\Gamma, x : \tau \vdash e : \tau'}{\Gamma \vdash \lambda x : \tau.e : \tau \to \tau'}\]
typeof (app E1 E2) T' :-
typeof E1 (arrow T T'), typeof E2 T.
typeof (lam T X_E) (arrow T T') :-
(x:term -> typeof x T -> typeof (X_E x) T').
typeof (lam _ (fun x => x)) T ?
term : type.
typ : type.
typeof : term -> typ -> prop.
\[e := e_1 e_2 \; | \; λx:\tau.e \\ \tau := \tau_1 \to \tau_2\]
\[e := \texttt{app}(e_1, e_2) \; | \; \texttt{lam}(\tau, x.e) \\ \tau := \texttt{arrow}(\tau_1, \tau_2)\]
\[e := \texttt{app}(e_1, e_2) \; | \; \texttt{lam}(\tau, x.e) \\ \tau := \texttt{arrow}(\tau_1, \tau_2)\]
app : term -> term -> term.
lam : typ -> (term -> term) -> term.
arrow : typ -> typ -> typ.
\[e := \texttt{lammany}(\vec{xs}.e) \; | \; \texttt{appmany}(e, \vec{es}) \\ \tau := \texttt{arrowmany}(\vec{\tau{}s}, \tau)\]
lammany : bindmany term term -> term.
appmany : term -> list term -> term.
arrowmany : list typ -> typ -> typ.
typeof (lammany XS_E) (arrowmany TS T) :-
openmany XS_E (pfun XS E =>
assumemany typeof XS TS (typeof E T)).
typeof (appmany E ES) T :-
typeof E (arrowmany TS T), map typeof ES TS.
\[e := \texttt{letrec} \; \vec{xs} \; = \; \vec{es} \; \texttt{in} \; e\]
\[e := \texttt{letrec}(\vec{xs}.(\vec{es}, e))\]
letrec : bindmany term
(list term * term) -> term.
\[e := \texttt{letrec}(\vec{xs}.(\vec{es}, e))\]
letrec : vbindmany term N
(vector term N * term) -> term.
typeof (letrec XS_DefsBody) T' :-
vopenmany XS_DefsBody (pfun XS (Defs, Body) =>
vassumemany typeof XS TS (vmap typeof Defs TS),
vassumemany typeof XS TS (typeof Body T')).
``We mentioned Hindley-Milner / we don't want you to be sad.
This talk is very short I feel, / I hope it isn't bad.
Please come and find me afterwards / to talk about these things,
or if you'd like to learn about / the songs that Roza sings.''
generalize : (Type: typ) (GeneralizedType: typ) -> prop.
let : term -> (term -> term) -> term.
get_types_in_environment : [A] A -> prop.
tforall : (typ -> typ) -> typ.
get_types_in_environment Gamma :-
refl.assume_get typeof Gamma.
\[\frac{\Gamma \vdash e : \tau \hspace{1em} \Gamma \vdash \tau \leadsto \tau_{gen} \hspace{1em} \Gamma, x : \tau_{gen} \vdash e' : \tau'}{\Gamma \vdash \text{let} \; x = e \; \text{in} \; e' : \tau'}\]
typeof (let E X_Body) T' :-
typeof E T,
generalize T Tgen,
(x:term -> typeof x Tgen -> typeof (X_Body x) T').
\[\frac{\vec{\alpha} = \text{fv}(\tau) - \text{fv}(\Gamma)}{\Gamma \vdash \tau \leadsto \forall \vec{\alpha'}.\tau[\vec{\alpha'}/\vec{\alpha}]}\]
generalize T T :-
not(findunif T (A: typ)).
generalize T Res :-
findunif T A,
(a:typ ->
(replaceunif A a T (T' a),
generalize (T' a) (T'' a))),
get_types_in_environment GammaTypes,
if (hasunif A GammaTypes)
then (eq Res (T'' A))
else (eq Res (tforall T'')).
replaceunif Which ToWhat Where ToWhat :-
refl.isunif Where,
refl.sameunif Which Where.
replaceunif Which ToWhat Where Where :-
refl.isunif Where,
not(refl.sameunif Which Where).
replaceunif Which ToWhat Where Result :-
not(refl.isunif Where),
structural_recursion @(replaceunif Which ToWhat)
Where Result.
typeof (let (lam _ (fun x => x)) (fun id => id)) T ?
``That's it, thank you so much folks, / the talk is now done.
A note before I leave though / and off this stage I run:
The company I work for / is hiring engineers
So if you're looking for a job / I'll pay for all the beers''
>> typeof (lam _ (fun x => x)) T ?
>> Yes:
>> T := arrow T1 T1.
>> typeof (lam _ (fun x => app x x)) T ?
>> Impossible.
typeof (lammany (bind (fun x => bind (fun y => body (app y x))))) T ?
>> Yes:
>> T := arrowmany [T_X, arrow T_X T_Y] T_Y.
typeof (letrec (vbind (fun f => vbody (vcons (lam _ (fun x => app f x)) vnil, f)))) T ?
>> Yes:
>> T := arrow T1 T2.
>> generalize (arrow T T) X ?
>> Yes:
>> X := tforall (fun a => arrow a a).
>> typeof (let (lam _ (fun x => x)) (fun id => id)) T ?
>> Yes:
>> T := tforall (fun a => arrow a a).
>> typeof (let (lam _ (fun x => let x (fun y => y))) (fun id => id)) T ?
>> Yes:
>> T := tforall (fun a => arrow a a).
run_tests X ?