0

如何检查列表中的元素是否为空列表: [] ?

我有以下内容:

display_degrees([A,B,C,D]):- write(B).

display_degrees([A,B,C,D]):- B==[], nl,write('has no degree'), nl, !.

当我输入以下内容时:

display_degrees([1,[],3,4]).

我只是得到: [] 而不是“没有学位”。我的语法错了吗?我不能像这样在这个谓词中添加一个子句吗?

4

2 回答 2

2

你得到这种行为是因为当目标成功时证明搜索停止。当您键入

display_degrees([1,[],3,4]).

第一条规则统一,写为 B。既然成功了,就停止。你可以让 Prolog 继续搜索,然后它会找到第二个子句。在swipl,我得到

?- [foo].
?- display_degrees([1,[],3,4]).
[]
true r  % I type 'r' there
has no degree
true.

如果您只是学习 Prolog,我建议您避免使用 cut 运算符!一段时间。另外,做 IO 也不是最直观的事情。我会尝试一些练习来定义诸如自然数和递归函数之类的东西。例如,加上:

plus(z, X, X).
plus(s(X), Y, s(Z)) :- plus(X, Y, Z).
于 2013-10-18T19:50:47.977 回答
1

你所拥有的问题是更一般的规则将首先触发。您可以切换顺序:

display_degrees([A,[],C,D]) :- nl, write('has no degree'), nl, !.
display_degrees([A,B,C,D]) :- write(B).

我也可以为第一个谓词编写:

display_degrees([A,B,C,D]) :- B == [], nl, write('has no degree'), nl, !.

但是我最初展示的“快捷方式”对于像这样的 Prolog 谓词来说更为惯用。

我保留了削减,因为您知道您确定性地想要一个选择。当且仅当第二个列表元素是 时,第一条规则才会匹配[]

| ?- display_degrees([1,[],3,4]).

has no degree

yes
| ?- display_degrees([1,2,3,4]).
2

yes
| ?-
于 2013-10-18T20:25:51.627 回答