I'm revisiting Prolog after studying it in college, and would like to describe a type hierarchy that includes function types. So far, this is what I got (SWISH link):
% subtype/2 is true if the first argument is a direct subtype of
% the second.
subtype(bit, byte).
subtype(byte, uint16).
subtype(uint16, uint32).
subtype(uint32, uint64).
subtype(uint64, int).
subtype(int8, int16).
subtype(int16, int32).
subtype(int32, int64).
subtype(int64, int).
% isa/2 checks if there's a sequence of types that takes
% from X to Y.
isa(X,Y) :- subtype(X,Y).
isa(X,Y) :-
subtype(X,Z),
isa(Z,Y).
This program works well for the following queries:
?- subtype(bit, int).
true
?- findall(X,isa(X,int),IntTypes).
IntTypes = [uint64, int64, bit, byte, uint16, uint32, int8, int16, int32]
I then added the following definition for function subtypes just above isa
, where a function is a complex term func(ArgsTypeList, ResultType)
:
% Functions are covariant on the return type, and
% contravariant on the arguments' type.
subtype(func(Args,R1), func(Args,R2)) :-
subtype(R1, R2).
subtype(func([H1|T],R), func([H2|T],R)) :-
subtype(H2, H1).
subtype(func([H|T1],R), func([H|T2],R)) :-
subtype(func(T1,R), func(T2,R)).
Now, I am still able to do some finite checks, but even trying to enumerate all subtypes of byte
fails with stack overflow.
?- isa(func([int,int], bit), func([bit,bit], int)).
true
?- isa(X, byte).
X = bit ;
Stack limit (0.2Gb) exceeded
What am I doing wrong?