我试图在以下程序中增加变量U,D,L,R。然而,它们似乎根本没有增加。
maze(4,0,3,0,0).
cell(0,0,[d],[0.391538986557049]).
cell(1,0,[r,d],[16.597130417636, 0.889878639213553]).
cell(2,0,[l,d],[0.011123208182191, 18.6496954092342]).
cell(3,0,[],[]).
cell(0,1,[u,r],[63.1258159853081, 3.14882640637611]).
cell(1,1,[u,l,r,d],[0.577082416767899, 11.2788559044107, 0.0116108917113176, 25.6907194043197]).
cell(2,1,[u,l,r,d],[89.8399554017928, 0.120311605902415, 0.0687987167581341, 198.151088713489]).
cell(3,1,[l,d],[0.0114526228490019, 152.662532290366]).
cell(0,2,[r,d],[0.0148854629087619, 0.019301544005463]).
cell(1,2,[u,l,r],[9.93466159987408, 0.199913563972552, 1.26393492879008]).
cell(2,2,[u,l,d],[12.3336316807166, 1.59269860596813, 0.680879328533728]).
cell(3,2,[u],[18.8277117544323]).
cell(0,3,[u],[15.6415340291405]).
cell(1,3,[],[]).
cell(2,3,[u,r],[0.216152697975287, 0.0138637250041849]).
cell(3,3,[l],[0.0113867473179591]).
genXY(N,R) :- R = [X,Y], succ(N1, N), between(0, N1, X), between(0, N1, Y).
isMem(U, Dir, C, R) :- not(member(U,Dir)), R is C + 0.
isMem(U, Dir, C, R) :- member(U,Dir), R is C + 1.
stats(U,D,L,R) :-
U is 0, D is 0, L is 0, R is 0,
maze(Len,_,_,_,_),
genXY(Len,Out),
[H,T|_] = Out,
cell(H,T,Dir,_),
isMem(u, Dir, U, U1), %from here
U is U1,
isMem(d, Dir, D, D1),
D is D1,
isMem(l, Dir, L, L1),
L is L1,
isMem(r, Dir, R, R1),
R is R1. %to here
IsMem函数检查元素是否在列表中,如果是,则递增变量。如果不是,则返回相同的值。据我所知,正在从isMem返回正确的值,但变量U,L,D,R似乎没有更新。
编辑:
预期产出:
?- stats(U,D,L,R).
U = D, D = 8,
L = R, R = 7.
澄清一下,该程序会查看第一个单元格。第一个细胞的Dir是[d]。因此,变量D应该增加1,其他变量应该保持不变。下一个单元格有Dir [r,d]。所以R和D都应该增加。现在R应该保持值1而D应该保持2.所以基本上它计算在给定的一组单元格中有多少u,l,d,r。
答案 0 :(得分:1)
Prolog和范围逻辑编程和声明性编程以不同的方式处理变量命令式编程语言:变量只能是设置一次。在逻辑编程的情况下,某些部分可能仍然是可变的。但是,一旦您说X=a
,就无法将其重置为X=b
(除非您有回溯,或使用非可回溯商店一些Prolog系统提供)。
所以如果你设置了:
U is 0, D is 0, L is 0, R is 0,
这意味着U
,D
,L
和R
永远设置为零。
但是,我不明白你为什么要覆盖这些值,你可以简单地使用零并返回所需的值:
stats(U,D,L,R) :-
maze(Len,_,_,_,_),
genXY(Len,Out),
[H,T|_] = Out,
cell(H,T,Dir,_),
isMem(u, Dir, 0, U),
isMem(d, Dir, 0, D),
isMem(l, Dir, 0, L),
isMem(r, Dir, 0, R).
换句话说,直接使用0
调用谓词并使用U
等来捕获结果并将其返回。
此外,您可以使用以下内容优化isMem
:
isMem(U,Dir,C,R) :-
member(U,Dir),
!,
R is C + 1.
isMem(_,_,C,C).
这将提高性能,并且在许多情况下是指定程序的更安全的方式,因为最后一个句子使谓词在句法上完全合并。
修改强>
根据您希望在答案中计算的内容,您可以考虑将程序重新设计为。首先编写一个程序,根据迷宫的大小增加坐标。
coorinc(X,Y,X1,Y) :-
X1 is X+1,
maze(N,_,_,_,_),
X1 < N,
!.
coorinc(_,Y,0,Y1) :-
Y1 is Y+1,
maze(N,_,_,_,_),
Y1 < N.
现在您可以使用累加器来计算统计信息:
stat(U,D,L,R) :-
stats(0,0,0,0,0,0,U,D,L,R).
现在需要实现stat/10
的逻辑:
stats(X,Y,U0,D0,L0,R0,U,D,L,R) :-
coorinc(X,Y,X1,Y1),
!,
cell(X,Y,Dir,_),
isMem(u,Dir,U0,U1),
isMem(d,Dir,D0,D1),
isMem(l,Dir,L0,L1),
isMem(r,Dir,R0,R1),
stats(X1,Y1,U1,D1,L1,R1,U,D,L,R).
stats(X,Y,U0,D0,L0,R0,U,D,L,R) :-
cell(X,Y,Dir,_),
isMem(u,Dir,U0,U),
isMem(d,Dir,D0,D),
isMem(l,Dir,L0,L),
isMem(r,Dir,R0,R).