如何在prolog中检查不存在

时间:2015-04-11 20:00:12

标签: prolog

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

rows(3).

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

在这种情况下,将有3个区块(行(3))的空间,因此有3个不同的位置1,2,3。在这种情况下,如何定义一个返回2作为自由位置的方法?

另一个例子:

rows(4).

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

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

1 个答案:

答案 0 :(得分:1)

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/3调用empty(1,N,X)X用于统一空格,N是行数。

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

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

如果为第二个示例调用此empty/1谓词,则返回:

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

对于实例化的查询:

?- empty(1).
true ;
false.

?- empty(4).
true .

?- empty(3).
false.

虽然对于具有已知索引的查询,此谓词并不是非常有效。对于这些,您可以构建查询:

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

如果I有界(不是变量),只能