在Prolog中获取未访问的坐标

时间:2016-12-06 02:54:17

标签: prolog

我正在尝试在SWI-Prolog中为尚未访问过的坐标编写规则。在我目前的例子中,网格是一个简单的4x4。

visited(1,1).
visited(2,1).
visited(1,2).

candidate(X,Y) :- \+visited(A,B), X >= 1, X =< 4, Y >= 1, Y =< 4.

当我致电candidate(Xcoordinate, Ycoordinate).时,我的目标是打印出来(在这种情况下):

X = 1, Y = 3 ;
X = 1, Y = 4 ;
X = 2, Y = 2 ;
X = 2, Y = 3 ;
X = 2, Y = 4 ;
X = 3, Y = 1 ;
X = 3, Y = 2 ;
X = 3, Y = 3 ;
  ...etc...

每当我尝试调用它时,总是会得到关于参数未充分实例化的>=/2=</2的错误。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

您不能对尚未实例化的变量使用此类运算符。如果我问你&#34;什么是X + 2&#34;,你会怎么回答?

您的程序可能需要知道有多少行和列,例如......

width(2).
height(2).

row(X) :-
   height(W),
   count_down(W, X).

col(X) :-
   width(W),
   count_down(W, X).

count_down(N, N) :- N > 0.
count_down(W, X) :-
   V is W - 1,
   V > 0,
   count_down(V, X).

现在您的程序可以找到有效的行号或列号...

3 ?- row(X).
X = 2 ;
X = 1 ;
false.

4 ?- col(X).
X = 2 ;
X = 1 ;
false.

现在你可以找到未经检查的细胞......

candidate(X, Y) :-
    % Pick a row
    row(X),
    % Pick a column
    col(Y),
    % See if it has not been visited...
    \+ visited(X, Y).

跟踪输出

2 ?- trace.
true.

[trace] 2 ?- candidate(X, Y).
   Call: (6) candidate(_G3053, _G3054) ? creep
   Call: (7) row(_G3053) ? creep
   Call: (8) width(_G3138) ? creep
   Exit: (8) width(2) ? creep
   Call: (8) count_down(2, _G3053) ? creep
   Call: (9) 2>0 ? creep
   Exit: (9) 2>0 ? creep
   Exit: (8) count_down(2, 2) ? creep
   Exit: (7) row(2) ? creep
   Call: (7) col(_G3054) ? creep
   Call: (8) height(_G3138) ? creep
   Exit: (8) height(2) ? creep
   Call: (8) count_down(2, _G3054) ? creep
   Call: (9) 2>0 ? creep
   Exit: (9) 2>0 ? creep
   Exit: (8) count_down(2, 2) ? creep
   Exit: (7) col(2) ? creep
   Call: (7) visited(2, 2) ? creep
   Fail: (7) visited(2, 2) ? creep
   Redo: (6) candidate(2, 2) ? creep
   Exit: (6) candidate(2, 2) ? creep
X = Y, Y = 2 .

修改

我应该将行和列设置为4 ...

以下是我设置的所有答案......

1 ?- candidate(X, Y).
X = Y, Y = 4 ;
X = 4,
Y = 3 ;
X = 4,
Y = 2 ;
X = 4,
Y = 1 ;
X = 3,
Y = 4 ;
X = Y, Y = 3 ;
X = 3,
Y = 2 ;
X = 3,
Y = 1 ;
X = 2,
Y = 4 ;
X = 2,
Y = 3 ;
X = Y, Y = 2 ;
X = 1,
Y = 4 ;
X = 1,
Y = 3 ;
false.