List Prolog相邻位置的导线测量列表

List Prolog相邻位置的导线测量列表,list,prolog,conditional-statements,List,Prolog,Conditional Statements,我正在编写一个pacman AI(是的,这是我的家庭作业),但是我是个新手,我想找到pacman当前位置的所有相邻位置(上、下、左、右)。现在,我有一个列表,列出了该级别中所有空闲的位置,但我想删除所有与当前位置不相邻的位置。以下是我的规则: adjacent((X,Y), (Xx,Yy)) :- X+1=Xx, Y=Yy. adjacent((X,Y), (Xx,Yy)) :- X-1=Xx, Y=Yy. adjacent((X,Y), (Xx,Yy)) :-

我正在编写一个pacman AI(是的,这是我的家庭作业),但是我是个新手,我想找到pacman当前位置的所有相邻位置(上、下、左、右)。现在,我有一个列表,列出了该级别中所有空闲的位置,但我想删除所有与当前位置不相邻的位置。以下是我的规则:

adjacent((X,Y), (Xx,Yy)) :-
    X+1=Xx,
    Y=Yy.
adjacent((X,Y), (Xx,Yy)) :-
    X-1=Xx,
    Y=Yy.
adjacent((X,Y), (Xx,Yy)) :-
    X=Xx,
    Y+1=Yy. 
adjacent((X,Y), (Xx,Yy)) :-
    X=Xx
    Y-1=Yy.
现在我想使用一个位置列表(Xx,Yy),并且只使用满足相邻规则之一的位置。 因此,我必须遍历列表,使用相邻(Prolog将检查所有4条规则,对吗?),如果为true,则将它们添加到新列表中

像这样的

    find_adjacent((X,Y),[(Xx,Yy)|T], Z] :-
        adjacent((X,Y),(Xx,Yy) -> add_to_new_list((Xx,Yy),Z);
这是Prolog中正确的思维方式吗?有人能给我指出正确的方向吗


谢谢。

如果您使用的是无约束的Prolog,则必须首先对表达式进行规范化/求值。即:

adjacent((X,Y), (Xx,Yy)) :-
   Xx is X+1,
   Yy = Y.
...
甚至更简单、更快的方法也会更有效

adjacent((X,Y), (X, Yy)) :-
   ( Yy is Y+1 ; Yy is Y-1 ).
adjacent((X,Y), (Xx, Y)) :-
   ( Xx is X+1 ; Xx is X-1).
如果第二个参数始终为ground(无变量):

你可以考虑使用<代码>库(CPLFD)< /C> >,它允许你像上面的版本一样紧凑地陈述所有这四条规则,但仍然允许变量无处不在。

adjacent((X,Y), (Xx, Yy)) :-
   abs(X-Xx)+abs(Y-Yy) #= 1.

然而,作为一个初学者,有更好的例子来熟悉
库(clpfd)

是的,我不想过于复杂。我将只使用4条规则,只要prolog,对于每个位置(Xx,Yy)检查所有4条规则。我不明白为什么X+1=Xx为什么替换为Xx就是X+1。它们是一样的吗?@userconservation:不,它们是不同的,看我的第一句话。您必须计算
X+1
。如图所示使用
(is)/2
(=:=)/2
。好的,理解。在第一种情况下,我还可以使用member((X+1,Y),[(Xx,Yy)| T]?它会计算X+1吗?@UserConsious:不,如前所述,您只能使用
(is)/2
(=:=)进行计算/2
和其他一些比较运算符Prolog可能会非常混乱。谢谢。Prolog中的一个常见错误是将统一的运算符
=/2
混淆为某种表达式相等运算符。因此像
X+1=Xx
这样的表达式不会像您所想的那样。它会尝试统一术语
'+'(X,1)
使用
Xx
。它不会计算
X+1
。为了计算相等,您可以使用
=:=/2
,但它确实要求两边的表达式都要完全实例化。如果您想分配表达式的值,可以使用
is/2
。例如,
Y是(X*2)mod 7.
对于
is/2
,右侧必须有所有实例化变量,左侧为单个变量。
adjacent((X,Y), (Xx, Yy)) :-
   abs(X-Xx)+abs(Y-Yy) #= 1.