2

我是 Prolog 的新手,所以基本上这个错误对其他人来说可能很明显。

我的最后一个问题是关于平铺的算法。

问题

假设我们有一个边长为 S 的正方形,以及 N 个长 X 宽 Y 的矩形瓷砖副本。程序必须显示这些副本可以在网格中排列的所有方式,这样两个副本就不会相互接触

通过显示,我的意思是它必须显示网格中每个副本的左上角坐标集。

坐标从 1 开始,而不是 0。

算法

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)

我写了以下代码(ntiles规则用于计算)。

% 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, [], []).

表明

=</2: Arguments are not sufficiently instantiated.

我找不到错误(我知道其中一个“=<”运算符在抱怨)。一点帮助将不胜感激。

4

1 回答 1

2

错误的出现是因为

not(member(X/Y, Rest)),

not Goal(通常写成)撤消证明 Goal时\+ Goal建立的任何绑定。然后无法测试 X(和 Y)。

在这种情况下,您可以使用 between(1, GridSize, X) 提供 X(和 Y),以放置在not(member(...)).

于 2013-06-11T23:35:36.547 回答