1

我有以下代码:

position(0,0).
move(f):-
    position(X,Y),
    number(X),
    number(Y),
    Y is Y+1,
    X is X+1.

但是当我调用 move(f) 时,它返回 false。number(X) 和 number(Y) 返回 true,但是当我添加其他两行时,该函数不起作用。有什么问题?

4

1 回答 1

1

详细说明您的问题收到的一些评论,Prolog 中的变量代表单个值的可能实例化,就像数学和数理逻辑中的变量一样,一旦它们在上下文中实例化,它们必须保持一致。如果我们正在处理一个公式,我们知道只有分配给第一个的任何值也分配给第二个0 = (a + b) - (a + b),它才能表达其预期意义。a也就是说,我们可以用任何值代替a,但它必须始终是相同的值。Prolog 以同样的方式处理变量。如果 x = x + 1,则 2 = 3;但随后数学会被打破。

解决 mat 对使用动态谓词的警告,这是一种处理移动的可能方法,但通过传递先前移动的列表来完成。使用此方法,最近的移动将始终是复合 term 中 List 的第一个元素moves(List)

假设当前的移动历史如下:

moves([position(0,0), position(0,1), position(1,1)]).

move/3接受一个方向,一个表示先前移动的复杂术语,并告诉我们更新的移动列表是什么。

move(Direction, moves([From|Ms]), moves([To,From|Ms])) :-
    move_in_direction(Direction,From,To).

move_in_direction/3获取一个方向和一个位置,并告诉我们该方向的下一个位置是:

move_in_direction(left,  position(X1,Y1), position(X2,Y1)) :- X2 is X1 - 1.
move_in_direction(right, position(X1,Y1), position(X2,Y1)) :- X2 is X1 + 1.
move_in_direction(up,    position(X1,Y1), position(X1,Y2)) :- Y2 is Y1 + 1.
move_in_direction(down,  position(X1,Y1), position(X1,Y2)) :- Y2 is Y1 - 1.

请注意,使用此方法,您可以免费获得可追溯的移动历史。我想你可以以有趣的方式使用它——例如让玩家探索可能的一系列动作,直到满足某个条件,此时它提交或回溯。我很想知道你最终会采用什么样的解决方案。

于 2013-10-24T22:28:26.580 回答