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.
Γ⊢e1:τ→τ′Γ⊢e2:τΓ⊢e1e2:τ′Γ,x:τ⊢e:τ′Γ⊢λx:τ.e:τ→τ′
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:=e1e2|λx:τ.eτ:=τ1→τ2
e:=app(e1,e2)|lam(τ,x.e)τ:=arrow(τ1,τ2)
e:=app(e1,e2)|lam(τ,x.e)τ:=arrow(τ1,τ2)
app : term -> term -> term.
lam : typ -> (term -> term) -> term.
arrow : typ -> typ -> typ.
e:=lammany(→xs.e)|appmany(e,→es)τ:=arrowmany(→τs,τ)
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:=letrec→xs=→esine
e:=letrec(→xs.(→es,e))
letrec : bindmany term
(list term * term) -> term.
e:=letrec(→xs.(→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.
Γ⊢e:τΓ⊢τ⇝τgenΓ,x:τgen⊢e′:τ′Γ⊢letx=eine′:τ′
typeof (let E X_Body) T' :-
typeof E T,
generalize T Tgen,
(x:term -> typeof x Tgen -> typeof (X_Body x) T').
→α=fv(τ)−fv(Γ)Γ⊢τ⇝∀→α′.τ[→α′/→α]
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 ?