我有以下代码:
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,但是当我添加其他两行时,该函数不起作用。有什么问题?
我有以下代码:
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,但是当我添加其他两行时,该函数不起作用。有什么问题?
详细说明您的问题收到的一些评论,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.
请注意,使用此方法,您可以免费获得可追溯的移动历史。我想你可以以有趣的方式使用它——例如让玩家探索可能的一系列动作,直到满足某个条件,此时它提交或回溯。我很想知道你最终会采用什么样的解决方案。