变量的总和?

时间:2019-06-22 15:35:53

标签: prolog

我是Prolog的新手,我正在尝试创建一个查找特定事实并求和的谓词。

这是我的谓词:

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.

我想要与对象的(C1,C2,C3,C4)一起移动的所有(S1,S2,S3,S4)值之和,但我不知道该怎么做。

1 个答案:

答案 0 :(得分:1)

您尝试在单个谓词中做太多事情。通常最好将逻辑分成多个谓词,每个谓词执行特定任务。

累积坐标

我们首先可以使用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进行排序,并创建一个包含[T1, C1, C2, C3, C4]T1时间戳以及C1,{{ 1}},C2C3时间戳。

接下来,我们可以通过使用plus/3 [swi-doc]maplist/3 [swi-doc]来定义累积和函数:

C4

然后我们可以使用以下方法获取对象的位置:

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). foldl/4 [swi-doc]来总结:

object