Сумма значений переменных? - PullRequest
1 голос
/ 22 июня 2019

Я новичок в Прологе и пытаюсь создать предикат, который находит конкретный факт и суммирует значения.

Это мой предикат:

position(X,T,P1,P2,P3,P4) :- object(X,C1,C2,C3,C4,T1),
                 T>T1,
                 move(X,S1,S2,S3,S4,T2),
                 T2>T1,
                 T2=<T,
                 P1 is C1+S1,P2 is C2+S2,P3 is C3+S3,P4 is C4+S4.

И что я получаю, это:

    ?- position(car0,31,P1,P2,P3,P4).
    P1 = 930,
    P2 = 278,
    P3 = 1057,
    P4 = 365 ;
    P1 = 943,
    P2 = 288,
    P3 = 1058,
    P4 = 370 ;
    false.

Мне нужна сумма всех (S1, S2, S3, S4) значений перемещения объекта (C1, C2, C3, C4), но я не знаю, как это сделать.

1 Ответ

1 голос
/ 22 июня 2019

Вы пытаетесь сделать слишком много в одном предикате. Обычно лучше разделить логику на несколько предикатов, каждый из которых выполняет определенную задачу.

Совокупные координаты

Сначала мы можем создать список значений с помощью 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]).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...