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

时间:2013-10-18 19:26:25

标签: list prolog

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

我有以下内容:

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]).

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

2 个答案:

答案 0 :(得分: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,我建议你避免使用切割操作员!一段时间此外,做IO不是最直观的事情。我会尝试一些定义自然数和递归函数的练习。例如,加上:

plus(z, X, X).
plus(s(X), Y, s(Z)) :- plus(X, Y, Z).

答案 1 :(得分: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
| ?-