我有以下代码:
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,但是当我添加另外两行时,函数不起作用。有什么问题?
答案 0 :(得分:1)
阐述了你的问题所收到的一些评论,Prolog中的变量代表了单个值的可能实例化,就像数学和数学逻辑中的变量一样,一旦它们在上下文中被实例化,它们必须保持一致。如果我们正在处理公式0 = (a + b) - (a + b)
,我们知道如果分配给第一个a
的任何值也分配给第二个,它只能表达其意图。也就是说,我们可以替换a
的任何值,但它必须始终是相同的值。 Prolog以同样的方式处理变量。如果x = x + 1,那么2 = 3;但是数学会被打破。
解决mat对使用动态谓词的警告,这里有一种处理移动的可能方法,但是通过传递先前移动的列表来完成。使用此方法,最近的移动将始终是复合术语moves(List)
中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.
请注意,使用此方法,您可以免费获得可追溯的移动历史记录。我想你可以用有趣的方式使用它 - 例如让玩家探索可能的一系列动作,直到满足某个条件,此时它会提交或回溯。我很想知道你最终会采用什么样的解决方案。