我有一个在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。
答案 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/1
和empty/3
。 empty/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
有界(不是变量),只能 。