Вы можете преобразовать свой предикат distances/3
в предикат distances/4
, который возвращает хвост списка для последующих элементов, эффективно используя открытый список :
:- use_module(library(clpfd)).
distances([], _, Tail, Tail).
distances([BN| Bs], B, [DST| Ds], Tail) :-
DST #= abs(B - BN),
distances(Bs, B, Ds, Tail).
triangle([], []).
triangle([BN| Bs], Ds) :-
distances(Bs, BN, Ds, Tail),
triangle(Bs, Tail).
Пример вызова:
?- triangle([1,2,4,9], Ds).
Ds = [1, 3, 8, 2, 7, 5].
Чтобы лучше понять это решение, рассмотрим результаты следующего запроса:
?- distances([2,4,9], 1, Ds, Tail).
Ds = [1, 3, 8| Tail].
Это решение более эффективно, чем вызов предикатов, таких как append/2
или flatten/3
в конце.
PS Если вам все еще нужен предикат distances/3
для использования в другом месте, вы можете легко определить его:
distances(Bs, B, Ds) :-
distances(Bs, B, Ds, []).