我正在尝试在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
的错误。
我做错了什么?
答案 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.