prolog - 子句开头的算术运算

标签 prolog logic-programming

我是一个编写 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.

为什么我无法得到“西方”的答案。或任何其他?

最佳答案

原因是默认情况下 Prolog 不解释 + , - 和其他算术运算符。 1+1就是1+1 (这是 +(1,1) 的语法糖),不是 2。例如,如果您想定义自己的表达式计算器,并且您看到 +,这可能很有用。作为 bool 总和,或者完全不同的东西。

但是,有一种方法可以折叠这样的表达式,使其派生 21+1使用 (is)/2 谓词。例如:

turn_to_east(NX,Y) :-
    myPosition(X,Y),
    NX is X+1,
    write('East.').

给定您的查询turn_to_east/2turn_to_east(1,2) , NX = 1 。现在您获取 myPosition/2数据:X = 2Y = 2 。 Prolog 同时进行等价检查,发现 turn_to_east/2 的 Y 坐标与 myPosition 之一相同。接下来它崩溃了2+13并发现这不等于 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 stuff:这不仅适用于 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变体进行计算。

关于prolog - 子句开头的算术运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34242509/

相关文章:

vector - 如何将 Prolog CLP(R) 与实向量连接?

functional-programming - 函数返回 "No Solution"而不是 "Nothing"

prolog - 逻辑引擎中的不确定性(根据本地地理产生合理的相对位置)

prolog - 是否可以用一阶逻辑来表达Prolog的切割?

prolog - Prolog 中的 CHR 解输出

prolog - Prolog 3 路比较中的关系运算符符号

list - Prolog - 列表中最常见的长度为 N 的序列

Prolog 列表中的空列表

prolog - 是纯Prolog Turing-complete,如果是,为什么不能实现列表交集?

database - 什么是 clojure 中用于逻辑编程的好的/已建立的数据库支持策略