我是一个Prolog谓词,它将笛卡尔坐标系中的某些点(myPosition(2,2)
)与邻域中的其他点进行比较。因此,它应该显示我们应该选择从myPosition(2,2)
到那个点的方向(北,东,南,西)。以下是我的.pl
文件的代码:
myPosition(2,2).
turn_to_east(X+1,Y) :-
myPosition(X,Y),
write('East.').
turn_to_west(X-1,Y) :-
myPosition(X,Y),
write('West.').
turn_to_north(X,Y+1) :-
myPosition(X,Y),
write('North.').
turn_to_south(X,Y-1) :-
myPosition(X,Y),
write('South.').
turn_to_the_point(X,Y) :- turn_to_east(X,Y).
turn_to_the_point(X,Y) :- turn_to_west(X,Y).
turn_to_the_point(X,Y) :- turn_to_north(X,Y).
turn_to_the_point(X,Y) :- turn_to_south(X,Y).
然后,当我将文件上传到SWI-Prolog并写下:
turn_to_the_point(1,2).
我得到了:
false.
为什么我不能得到答案'西方'。还是其他什么?
答案 0 :(得分:2)
原因是默认情况下Prolog会不解释+
,-
和其他算术运算符。 1+1
只是1+1
(这是+(1,1)
的语法糖),不是2 。如果您想要定义自己的表达式求值程序,并且看到+
作为布尔求和,或者完全不同的话,那么这可能很有用。
然而,有一种方法可以崩溃这样的表达式,以便使用(is)/2
谓词从2
中导出1+1
。例如:
turn_to_east(NX,Y) :-
myPosition(X,Y),
NX is X+1,
write('East.').
鉴于您使用turn_to_east/2
,turn_to_east(1,2)
查询NX = 1
。现在,您获取myPosition/2
数据:X = 2
和Y = 2
。 Prolog在此期间进行等价检查,并发现turn_to_east/2
的Y坐标与myPosition
的Y坐标相同。接下来,它会将2+1
折叠为3
并看到这不等同于NX = 1
,因此此谓词失败。但如果您查询过turn_to_east(3,1)
,它就会成功,从而写出East.
。
如果您使用上面讨论的概念修改整个理论,例如:
myPosition(2,2).
turn_to_east(NX,Y) :-
myPosition(X,Y),
NX is X+1,
write('East.').
turn_to_west(NX,Y) :-
myPosition(X,Y),
NX is X-1,
write('West.').
turn_to_north(X,NY) :-
myPosition(X,Y),
NY is Y+1,
write('North.').
turn_to_south(X,NY) :-
myPosition(X,Y),
NY is Y-1,
write('South.').
turn_to_the_point(X,Y) :- turn_to_east(X,Y).
turn_to_the_point(X,Y) :- turn_to_west(X,Y).
turn_to_the_point(X,Y) :- turn_to_north(X,Y).
turn_to_the_point(X,Y) :- turn_to_south(X,Y).
它正确回答了查询:
?- turn_to_the_point(1,2).
West.
true ;
false.
一般说明,谓词最好没有像write/1
这样的副作用:这不仅适用于Prolog,几乎所有编程语言都建议将程序拆分为计算和相互作用。也许更好的解决方法是将方向视为参数:
myPosition(2,2).
turn_to_point(NX,Y,east) :-
myPosition(X,Y),
NX is X+1.
turn_to_point(NX,Y,west) :-
myPosition(X,Y),
NX is X-1.
turn_to_point(X,NY,north) :-
myPosition(X,Y),
NY is Y+1.
turn_to_point(X,NY,south) :-
myPosition(X,Y),
NY is Y-1.
turn_to_the_point(X,Y) :-
turn_to_point(X,Y,D),
write(D).
在这种情况下,turn_to_the_point/2
谓词显然是交互谓词,而其turn_to_the_point/3
变体则进行计算。