如何检查prolog中不存在

How to check non existence in prolog

我有一个在序言中定义的塔模型: 每个块都有一个位置块(ID,POS)。块的级别以不同的方式计算。

rows(3).

block(a, 1).
block(b, 3).

在这种情况下,3 个块(行 (3))将有 space,因此有 3 个不同的位置 1、2、3。在这种情况下,如何定义一个 returns me 2 作为空闲位置的方法?

另一个例子:

rows(4).

block(a, 2).
block(b, 3).

在这种情况下,方法应该 return 1 和 4。

Prolog 有某种形式的否定(但称它为否定时必须小心),定义为:\+。您可以搜索未被占用的行:

empty(X) :-
    rows(N),
    empty(1,N,X).

empty(I,_,I) :-
    \+ block(_,I).
empty(I,N,X) :-
    I < N,
    I1 is I+1,
    empty(I1,N,X).

代码定义了两个谓词:empty/1empty/3empty/1首先检查行数,然后用empty(1,N,X)调用empty/3X用于与空的space统一,N是行数。

empty/3 使用某种 for 循环 ,它遍历 I。对于给定的 I,它检查是否存在 block(_,I),换句话说:是否存在放置在 space I 的块,如果存在,则该分支失败(我们使用下一个)。否则,X=I为空是事实。

在第二种情况下,我们简单地执行增量:我们首先检查是否I < N,否则,我们到达了行的末尾。如果是这样,我们将 I 增加到 I1 is I+1 然后我们调用 empty(I1,N,X) 来检查下一行是否为空。

如果在第二个例子中调用这个 empty/1 谓词,它 returns:

?- empty(X).
X = 1 ;
X = 4 ;
false.

对于实例化查询:

?- empty(1).
true ;
false.

?- empty(4).
true .

?- empty(3).
false.

虽然对于已知索引的查询,这个谓词并不是很有效。对于这些你可以建立一个查询:

isEmpty(I) :-
    \+ block(_,I).

然而,如果 I 是有界的(不是变量),这将 仅工作