Вы пытаетесь сделать слишком много в одном предикате. Обычно лучше разделить логику на несколько предикатов, каждый из которых выполняет определенную задачу.
Совокупные координаты
Сначала мы можем создать список значений с помощью findall/3
[swi-doc] :
all_moves(X, T, Diffs) :-
findall([T1, C1, C2, C3, C4], (move(X,C1,C2,C3,C4,T1), T1 <= T), Cs),
sort(Cs, Diffs).
Таким образом, мы здесь сортируем move/6
s по отметке времени и создаем список из 5 кортежей с [T1, C1, C2, C3, C4]
с T1
отметкой времени и C1
, C2
, C3
и C4
метки времени.
Затем мы можем определить функцию накопленной суммы, используя plus/3
[swi-doc] и maplist/3
[swi -doc]
cumsum(P, _, P).
cumsum(P, [[_|D]|R], P2) :-
maplist(plus, P, D, P1),
cumsum(P1, R, P2).
тогда мы можем получить положение объекта с помощью:
position(X,T,P1,P2,P3,P4) :-
object(X, C1, C2, C3, C4, T1),
T > T1,
all_moves(X, T, Mvs),
cumsum([C1, C2, C3, C4], Mvs, [P1, P2, P3, P4]).
Конечные координаты
Если нам нужны только окончательные координаты, мы можем улучшить вышеуказанное. В этом случае порядок ходов не имеет значения, если они правильно отфильтрованы. Таким образом, мы можем определить allmoves_unsorted/3
, например:
all_moves_unsorted(X, T, Diffs) :-
findall([C1, C2, C3, C4], (move(X, C1, C2, C3, C4, T1), T1 <= T), Diffs).
Затем мы можем суммировать их с помощью object
, с foldl/4
[swi-doc] :
final_position(X, T, S1, S2, S3, S4) :-
object(X, P1, P2, P3, P4, T1),
T1 < T,
all_moves_unsorted(X, T, Diffs),
foldl(maplist(plus), Diffs, [P1, P2, P3, P4], [S1, S2, S3, S4]).