You cannot use such operators on variables that have not been instantiated. If I asked you "What is X + 2", how would you answer it?
Your program probably needs a way of knowing how many rows and columns there are, for example...
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).
Now your program can find a valid row or column number...
3 ?- row(X).
X = 2 ;
X = 1 ;
false.
4 ?- col(X).
X = 2 ;
X = 1 ;
false.
Now you can find unvisited cells as so...
candidate(X, Y) :-
% Pick a row
row(X),
% Pick a column
col(Y),
% See if it has not been visited...
\+ visited(X, Y).
Trace output
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 .
Edit
I should have set rows and cols to 4...
Here are all the answers it finds when I set that...
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.