nurgasemetey
nurgasemetey

Reputation: 770

Prolog:Tiling program

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

Answers (1)

CapelliC
CapelliC

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

Related Questions