:- prompt(_, '').
:- use_module(library(readutil)).
kind
(KC
,var(Z
),K1
) :- first
(Z
:K
,KC
), instantiate
(K
,K1
).kind(KC,F $ G, K2) :- kind(KC,F,K1 -> K2), kind(KC,G,K1).
kind(KC,A -> B,o) :- kind(KC,A,o), kind(KC,B,o).
type
(KC
,C
,var(X
), T1
) --> { first
(X
:T
,C
) }, inst_type
(KC
,T
,T1
).type(KC,C,lam(X,E), A->B) --> type(KC,[X:mono(A)|C],E,B), [kind(KC,A->B,o)].
type(KC,C,X $ Y, B) --> type(KC,C,X,A->B), type(KC,C,Y,A).
type(KC,C,let(X=E0,E1),T) --> type(KC,C,E0,A), type(KC,[X:poly(C,A)|C],E1,T).
first(X:T,[X1:T1|_]) :- X = X1, T = T1.
first(X:T,[X1:_|Zs]) :- X\==X1, first(X:T, Zs).
instantiate(mono(T),T).
instantiate
(poly
(C
,T
),T1
) :- copy_term(t
(C
,T
),t
(C
,T1
)).
inst_type(KC,poly(C,T),T2) -->
free_variables(T,Xs), free_variables(T1,Xs1) }, % Xs and Xs1 are same length
samekinds(KC,Xs,Xs1), { T1=T2 }. %% unify T1 T2 later (T2 might not be var)
inst_type(_ ,mono(T),T) --> [].
samekinds(KC,[X|Xs],[Y|Ys]) --> { X\==Y }, [kind(KC,X,K),kind(KC,Y,K)],
samekinds(KC,Xs,Ys).
samekinds(KC,[X|Xs],[X|Ys]) --> [], samekinds(KC,Xs,Ys).
samekinds(_ ,[],[]) --> [].
variablize
(var(X
)) :- gensym
(t
,X
).
main:-
process,
type_and_print(KC,C,E,T) :-
phrase(type(KC,C,E,T),Gs),
(bagof(Ty
, X^Y^member
(kind
(X
,Ty
,Y
),Gs
), Tys
); Tys
=[]), free_variables
(Tys
,Xs
), maplist
(variablize
,Xs
), maplist
(call,Gs
), write("kind ctx instantiated as
: "
), print
(KC
), nl, print
(E
: T
), nl.
process:-
/* your code goes here */
type_and_print
(_
,[],lam
(x
,var(x
)),_
), nl, type_and_print
(_
,[],lam
(x
,lam
(y
,var(y
)$var
(x
))),_
), nl, type_and_print
(_
,[],let
(id
=lam
(x
,var(x
)),var(id
)$var
(id
)),_
), nl, KC0 =
[ 'Nat':mono(o)
, 'List':mono(o->o)
],
Nat
= var('Nat'), List
= var('List'), C0 =
[ 'Zero':mono(Nat)
, 'Succ':mono(Nat -> Nat)
, 'Nil' :poly([], List$A)
, 'Cons':poly([], A->((List$A)->(List$A)))
],
append(KC0,_,KC1),
type_and_print
(KC1
,C0
,lam
(x
,lam
(n
,var(x
)$var
('Succ')$var
(n
))),_
),
%% haven't really shown examples of type constructor polymorphsim or
%% kind polymorphism here but you get the idea what strucutural extensions
%% to HM are needed to support type constructor and kind polymoprhisms
:- main.
Oi0gc2V0X3Byb2xvZ19mbGFnKHZlcmJvc2Usc2lsZW50KS4KOi0gcHJvbXB0KF8sICcnKS4KOi0gdXNlX21vZHVsZShsaWJyYXJ5KHJlYWR1dGlsKSkuCgo6LSBzZXRfcHJvbG9nX2ZsYWcob2NjdXJzX2NoZWNrLHRydWUpLgo6LSBvcCg1MDAseWZ4LCQpLgoKa2luZChLQyx2YXIoWiksSzEpIDotIGZpcnN0KFo6SyxLQyksIGluc3RhbnRpYXRlKEssSzEpLgpraW5kKEtDLEYgJCBHLCBLMikgOi0ga2luZChLQyxGLEsxIC0+IEsyKSwga2luZChLQyxHLEsxKS4Ka2luZChLQyxBIC0+IEIsbykgIDotIGtpbmQoS0MsQSxvKSwga2luZChLQyxCLG8pLgoKdHlwZShLQyxDLHZhcihYKSwgICAgIFQxKSAtLT4geyBmaXJzdChYOlQsQykgfSwgaW5zdF90eXBlKEtDLFQsVDEpLgp0eXBlKEtDLEMsbGFtKFgsRSksIEEtPkIpIC0tPiB0eXBlKEtDLFtYOm1vbm8oQSl8Q10sRSxCKSwgW2tpbmQoS0MsQS0+QixvKV0uCnR5cGUoS0MsQyxYICQgWSwgICAgICAgQikgLS0+IHR5cGUoS0MsQyxYLEEtPkIpLCB0eXBlKEtDLEMsWSxBKS4KdHlwZShLQyxDLGxldChYPUUwLEUxKSxUKSAtLT4gdHlwZShLQyxDLEUwLEEpLCB0eXBlKEtDLFtYOnBvbHkoQyxBKXxDXSxFMSxUKS4KCmZpcnN0KFg6VCxbWDE6VDF8X10pIDotIFggPSBYMSwgVCA9IFQxLgpmaXJzdChYOlQsW1gxOl98WnNdKSA6LSBYXD09WDEsIGZpcnN0KFg6VCwgWnMpLgoKaW5zdGFudGlhdGUobW9ubyhUKSxUKS4KaW5zdGFudGlhdGUocG9seShDLFQpLFQxKSA6LSBjb3B5X3Rlcm0odChDLFQpLHQoQyxUMSkpLgoKaW5zdF90eXBlKEtDLHBvbHkoQyxUKSxUMikgLS0+CiAgeyBjb3B5X3Rlcm0odChDLFQpLHQoQyxUMSkpLCAKICAgIGZyZWVfdmFyaWFibGVzKFQsWHMpLCBmcmVlX3ZhcmlhYmxlcyhUMSxYczEpIH0sICUgWHMgYW5kIFhzMSBhcmUgc2FtZSBsZW5ndGgKICBzYW1la2luZHMoS0MsWHMsWHMxKSwgeyBUMT1UMiB9LiAlJSB1bmlmeSBUMSBUMiBsYXRlciAoVDIgbWlnaHQgbm90IGJlIHZhcikKaW5zdF90eXBlKF8gLG1vbm8oVCksVCkgLS0+IFtdLgoKc2FtZWtpbmRzKEtDLFtYfFhzXSxbWXxZc10pIC0tPiB7IFhcPT1ZIH0sIFtraW5kKEtDLFgsSyksa2luZChLQyxZLEspXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYW1la2luZHMoS0MsWHMsWXMpLgpzYW1la2luZHMoS0MsW1h8WHNdLFtYfFlzXSkgLS0+IFtdLCBzYW1la2luZHMoS0MsWHMsWXMpLgpzYW1la2luZHMoXyAsW10sW10pIC0tPiBbXS4KCnZhcmlhYmxpemUodmFyKFgpKSA6LSBnZW5zeW0odCxYKS4KCm1haW46LQoJcHJvY2VzcywKCWhhbHQuCgp0eXBlX2FuZF9wcmludChLQyxDLEUsVCkgOi0KICBwaHJhc2UodHlwZShLQyxDLEUsVCksR3MpLAogIChiYWdvZihUeSwgWF5ZXm1lbWJlcihraW5kKFgsVHksWSksR3MpLCBUeXMpOyBUeXM9W10pLAogIGZyZWVfdmFyaWFibGVzKFR5cyxYcyksIG1hcGxpc3QodmFyaWFibGl6ZSxYcyksIG1hcGxpc3QoY2FsbCxHcyksCiAgd3JpdGUoImtpbmQgY3R4IGluc3RhbnRpYXRlZCBhczogIiksIHByaW50KEtDKSwgbmwsIHByaW50KEUgOiBUKSwgbmwuCgpwcm9jZXNzOi0KCS8qIHlvdXIgY29kZSBnb2VzIGhlcmUgKi8KCXR5cGVfYW5kX3ByaW50KF8sW10sbGFtKHgsdmFyKHgpKSxfKSwgbmwsCgl0eXBlX2FuZF9wcmludChfLFtdLGxhbSh4LGxhbSh5LHZhcih5KSR2YXIoeCkpKSxfKSwgbmwsCgl0eXBlX2FuZF9wcmludChfLFtdLGxldChpZD1sYW0oeCx2YXIoeCkpLHZhcihpZCkkdmFyKGlkKSksXyksIG5sLAoJS0MwID0KCSBbICdOYXQnOm1vbm8obykKICAgICAsICdMaXN0Jzptb25vKG8tPm8pCiAgICAgXSwKCU5hdCA9IHZhcignTmF0JyksIExpc3QgPSB2YXIoJ0xpc3QnKSwKICAgIEMwID0KICAgICBbICdaZXJvJzptb25vKE5hdCkKICAgICAsICdTdWNjJzptb25vKE5hdCAtPiBOYXQpCiAgICAgLCAnTmlsJyA6cG9seShbXSwgTGlzdCRBKQogICAgICwgJ0NvbnMnOnBvbHkoW10sIEEtPigoTGlzdCRBKS0+KExpc3QkQSkpKQogICAgIF0sCiAgICBhcHBlbmQoS0MwLF8sS0MxKSwKICAgIHR5cGVfYW5kX3ByaW50KEtDMSxDMCxsYW0oeCxsYW0obix2YXIoeCkkdmFyKCdTdWNjJykkdmFyKG4pKSksXyksCgl0cnVlLgoKJSUgaGF2ZW4ndCByZWFsbHkgc2hvd24gZXhhbXBsZXMgb2YgdHlwZSBjb25zdHJ1Y3RvciBwb2x5bW9ycGhzaW0gb3IKJSUga2luZCBwb2x5bW9ycGhpc20gaGVyZSBidXQgeW91IGdldCB0aGUgaWRlYSB3aGF0IHN0cnVjdXR1cmFsIGV4dGVuc2lvbnMKJSUgdG8gSE0gYXJlIG5lZWRlZCB0byBzdXBwb3J0IHR5cGUgY29uc3RydWN0b3IgYW5kIGtpbmQgcG9seW1vcHJoaXNtcwoKOi0gbWFpbi4=