我是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)值之和,但我不知道该怎么做。
答案 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}},C2
和C3
时间戳。
接下来,我们可以通过使用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