Prolog - 参数没有充分实例化 - 骑士/棋盘

时间:2014-11-22 19:30:31

标签: prolog instantiation-error

我对Prolog很新,我试图写一个简单的方法来确定棋盘上的骑士是否可以跳到另一个方格,或输出骑士可以跳到的所有方格给了一个正方形。对于此方法,假设必须始终实例化第一个参数。它给出了两个参数,它可以正常工作,但我不确定为什么它不会只输出一个。

% validSquare/2
% validSquare(X1/Y1, X2/Y2) iff the coordinate is a valid position on an 8x8 chessboard.
validSquare(X1/Y1, X2/Y2) :-
  X1 >= 1, X1 =< 8,
  Y1 >= 1, Y1 =< 8,
  X2 >= 1, X2 =< 8,
  Y2 >= 1, Y2 =< 8.


% jump/2
% jump(Square1, Square2) iff a knight could jump to the coordinate
% Square1/Square2 on a chessboard.
jump(X1/Y1, X2/Y2) :-
  validSquare(X1/Y1, X2/Y2),
  X2 is X1 + 1,
  Y2 is Y1 + 2.
jump(X1/Y1, X2/Y2) :-
  validSquare(X1/Y1, X2/Y2),
  X2 is X1 + 2,
  Y2 is Y1 + 1.
jump(X1/Y1, X2/Y2) :-
  validSquare(X1/Y1, X2/Y2),
  X2 is X1 + 1,
  Y2 is Y1 - 2.
jump(X1/Y1, X2/Y2) :-
  validSquare(X1/Y1, X2/Y2),
  X2 is X1 + 2,
  Y2 is Y1 - 1.
jump(X1/Y1, X2/Y2) :-
  validSquare(X1/Y1, X2/Y2),
  X2 is X1 - 1,
  Y2 is Y1 - 2.
jump(X1/Y1, X2/Y2) :-
  validSquare(X1/Y1, X2/Y2),
  X2 is X1 - 2,
  Y2 is Y1 - 1.
jump(X1/Y1, X2/Y2) :-
  validSquare(X1/Y1, X2/Y2),
  X2 is X1 - 1,
  Y2 is Y1 + 2.
jump(X1/Y1, X2/Y2) :-
  validSquare(X1/Y1, X2/Y2),
  X2 is X1 - 2,
  Y2 is Y1 + 1.

就像我说的,我对Prolog很新,所以我不确定如何格式化查询。此查询为false。

?- jump(1/1, X2/Y2).
ERROR: >=/2: Arguments are not sufficiently instantiated

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

:- use_module(library(clpfd)).

jump(X0/Y0, X/Y) :-
   abs(X0-X)+abs(Y0-Y)#=3,
   X0 #\= X,
   Y0 #\= Y,
   [X0,Y0,X,Y]ins 1..8.

答案 1 :(得分:1)

它打破了validSquare中的&gt; =测试。当两者都未绑定时,您无法确定X <= Y的真值,基本上,因为数字运算符不会分配值。您可以通过使用成员将坐标绑定到有效方块来解决此问题,即

validSquare(X1/Y1, X2/Y2):-
    member(X1, [1,2,3,4,5,6,7,8]),
    member(X2, [1,2,3,4,5,6,7,8]),
    member(Y1, [1,2,3,4,5,6,7,8]),
    member(Y2, [1,2,3,4,5,6,7,8]).

根据您正在使用的Prolog方言,member可能是内置的(例如SWI-Prolog)。

答案 2 :(得分:1)

以下是this fine answer中提供的代码的替代方法。它也基于

jump(X0/Y0, X/Y) :-
   D_x #= X0-X,
   D_y #= Y0-Y,
   abs(D_x) #\= abs(D_y),
   [D_x , D_y] ins (-2 .. -1)\/(1..2),
   [X0,X,Y0,Y] ins 1..8.

效率 1,2

脚注1:使用版本4.3.2(64位)和版本7.3.11(64位)进行测试。
脚注2: SICStus Prolog需要(ins)/2的合适定义才能运行代码。