Мне удалось избежать проблемы неограниченной левой рекурсии, включив логику для супертипов и используя ту или иную зависимость в зависимости от того, какие из переменных связаны.
Сначала я определил предложение для простоготипы, перечисляющие все, что используется позже явно:
simple_type(bit).
simple_type(byte).
% ...
simple_type(int).
Затем я ограничил правило subtype
только для случаев, когда первый член уже связан, используя nonvar
.
subtype(func(Args,R1), func(Args,R2)) :-
nonvar(R1),
subtype(R1, R2).
subtype(func([H1|T],R), func([H2|T],R)) :-
nonvar(H1),
supertype(H1, H2).
subtype(func([H|T1],R), func([H|T2],R)) :-
nonvar(T1),
subtype(func(T1,R), func(T2,R)).
Затем я определил правило supertype
, которое противоположно subtype
для простых типов ...
supertype(X, Y) :-
simple_type(X),
subtype(Y, X).
... но полностью дублируется для типов функций.
supertype(func(Args,R1), func(Args,R2)) :-
nonvar(R1),
supertype(R1, R2).
supertype(func([H1|T],R), func([H2|T],R)) :-
nonvar(H1),
subtype(H1, H2).
supertype(func([H|T1],R), func([H|T2],R)) :-
nonvar(T1),
supertype(func(T1,R), func(T2,R)).
isa
все тот же, с двумя дополнениями:
- Тип такой же, как и он сам (т. Е. Int is-a int).
- Если первое слагаемое не является связанным, а второе слагаемым, используйте обратное правило
typeof
.
_
isa(X,Y) :- X = Y.
isa(X,Y) :- subtype(X,Y).
isa(X,Y) :-
nonvar(X),
subtype(X,Z),
isa(Z,Y).
isa(X,Y) :-
var(X), nonvar(Y), typeof(Y,X).
Наконец, typeof
является противоположностью isa
, используя supertype
вместо subtype
:
typeof(X,Y) :- X = Y.
typeof(X,Y) :- supertype(X,Y).
typeof(X,Y) :-
nonvar(X),
supertype(X,Z),
typeof(Z,Y).
typeof(X,Y) :-
var(X), nonvar(Y), isa(Y,X).
Я заметил, что существует лот неэффективности иДублируем результаты с этими правилами, но, по крайней мере, это работает :)
?- setof(X, isa(func([byte, byte], uint32), X), All), length(All, L).
All = [func([bit, bit], int), func([bit, bit], uint32), func([bit, bit], uint64), func([bit, byte], int), func([bit, byte], uint32), func([bit, byte], uint64), func([byte, bit], int), func([byte, bit], uint32), func([byte, bit], uint64), func([byte, byte], int), func([byte, byte], uint32), func([byte, byte], uint64)],
L = 12