确定列表是否为空 [英] Determining if a list is empty or not
问题描述
如果|序言中的其他内容.下面是我的代码,如果我的输入列表不为空,Prolog将返回"R = false",如果我的列表为空,则Prolog将返回"false".我想念什么?
I want to do some if | else stuff in prolog. Below is my code, Prolog will return 'R = false' if my input list is not empty, it will return 'false' if my list is empty. What do I miss?
代码:
isEmpty([H|T],R) :-
length([H|T],L),
( L > 0 -> R = 'false'
;
L =:= 0 -> R = 'true'
).
序言输出:
1 ?- isEmpty([],R).
false.
2 ?- isEmpty([1],R).
R = false.
3 ?- isEmpty([1,2,3],R).
R = false.
推荐答案
定义此方法的一种方法是使用统一(模式匹配"):
One way to define this would be to use unification ("pattern matching"):
list_empty([], true).
list_empty([_|_], false).
如果您坚持使用if-then-else,则需要传递列表,而无需尝试以任何方式将其匹配:
If you insist on using an if-then-else, you need to pass the list without trying to match it in any way:
list_zerolength(List, Empty) :-
length(List, Len),
( Len == 0
-> Empty = true
; Empty = false
).
...但这不是最佳选择.如果第一个参数确实是列表,则两个谓词的行为相同:
... but this is not optimal. The two predicates behave identically if the first argument is indeed a list:
?- list_empty([], R).
R = true.
?- list_empty([_], R).
R = false.
?- list_zerolength([], R).
R = true.
?- list_zerolength([_], R).
R = false.
但是,如果第一个参数不是 ground (即未完全实例化),则会发生令人讨厌的事情:
However, something annoying happens if the first argument is not ground (that is, is not fully instantiated):
?- list_zerolength(L, true).
L = [] ;
ERROR: Out of global stack
因此,我们尝试请求一个空列表,然后我们得到了;但是,Prolog坚持可能还会有另一个答案.当我们尝试获取它时,会出现错误.
So, we try to ask for an empty list, and we get it; however, Prolog insists there might be another answer. When we try to get it, we get an error.
(额外的信用:找出会发生什么!)
(Extra credit: figure out what happens!)
谓词list_empty/2
也不完美.考虑:
?- list_empty([_|a], R).
R = false.
这成功了,我们可以将答案解释为:列表[_|a]
不为空".但是,这永远不是正确的列表!
This succeeds, and we could interpret the answer as: "The list [_|a]
is not empty". However, this is not ever a proper list!
?- is_list([_|a]).
false.
使用length/2
并不是一个坏主意.我们可以用它来写一个比list_empty/2
有用的谓词.我称它为list_nonempty/2
来迷惑这种情况:
Using length/2
is not at all a bad idea. We can use it to write a predicate that is arguably a bit more useful than list_empty/2
. I call it list_nonempty/2
to confuse the situation:
list_nonempty([], false).
list_nonempty([_|T], true) :-
length(T, _).
length/2
所做的不仅仅是查找列表的长度.它可用于生成长度增加的列表,或检查其第一个参数是否为正确的列表:
length/2
does a lot more than just finding the length of a list. It can be used to generate lists of increasing length, or check whether its first argument is a proper list:
?- list_nonempty(L, NE).
L = [],
NE = false ;
L = [_G904],
NE = true ;
L = [_G904, _G907],
NE = true . % and so on
?- list_nonempty(L, false).
L = [].
?- list_nonempty([], true).
false.
?- list_nonempty([_|a], true).
ERROR: length/2: Type error: `list' expected, found `a' (an atom)
如果未给length/2
提供列表,则
SWI-Prolog会引发错误.更致力于ISO遵从性的实现应失败.使用GNU Prolog:
SWI-Prolog throws an error when length/2
is not given a list. Implementations that are more committed to ISO-compliance should fail instead. With GNU Prolog:
?- list_nonempty([_|a], true).
no
这篇关于确定列表是否为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!