Reputation: 770
I am a newbye in Prolog, so basically the error may be obvious for others.
My last question was about an algorithm about tiling.
Problem
Suppose we have a square with side length S, and N copies of rectangular tile with length X and width Y. The program must show all the ways in which these copies can be arranged in a grid so that no two copies can touch each other.
By showing, I mean that it must show the set of coordinates of upper left corners of every copy in a grid.
Coordinates start from 1, not 0.
Algorithm
Find all (x, y) where 0 > x > S, 0 < y < S such that
(x - 1, y) not in A, (x + 1, y) not in A, (x + 2, y) not in A..., (x + X + 1, Y) not in A...
(same for y's)
I wrote the following code (ntiles rule is used to compute).
% TX/TY - tile dimensions
% GridSize - length of grid side
% N - number of copies
% P - container for result
% Cor - upper left corners
% Rest - cells where it is not allowed to place corner
rest(TX/TY, X/Y, Rest) :-
(
X - 1 > 0,
append([NewX/Y], [], Rest),
NewX is X - 1
)
; (
X + L =< GridSize,
X + L =< X + TX,
append([NewX/Y], [], Rest),
NewX is X + L
)
; (
Y - 1 > 0,
append([X/NewY], [], Rest),
NewY is Y - 1
)
; (
Y + L =< GridSize,
Y + L =< Y + TY,
append([X/NewY], [], Rest),
NewY is X + L
).
corners(TX/TY, GridSize, Cor, Rest) :-
not(member(X/Y, Rest)),
X =< GridSize, Y =< GridSize,
X > 0, Y > 0,
rest(TX/TY, X/Y, Rest),
append([X/Y], [], Cor).
ntilesHelper(TX/TY, GridSize, 0, P, Cor, Rest) :- append(Cor, [], P).
ntilesHelper(TX/TY, GridSize, N, P, Cor, Rest) :-
corners(TX/TY, GridSize, Cor, Rest),
ntilesHelper(TX/TY, GridSize, X, P, Cor, Rest),
X is N - 1, append(Cor, [], P).
ntiles(TX/TY, GridSize, N, P) :-
ntilesHelper(TX/TY, GridSize, N, P, [], []).
It shows
=</2: Arguments are not sufficiently instantiated.
I can't find an error (I know that one of the "=<" operators is complaining). A bit of help will be appreciated.
Upvotes: 2
Views: 162
Reputation: 60014
the error arise because of
not(member(X/Y, Rest)),
not Goal
(usually written \+ Goal
) undoes any binding established while proving Goal. Then X (and Y as well) cannot be tested.
In this case you can provide X (and Y) using between(1, GridSize, X), to be placed before not(member(...))
.
Upvotes: 2