确定列表是否为空 [英] Determining if a list is empty or not

查看:89
本文介绍了确定列表是否为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果|序言中的其他内容.下面是我的代码,如果我的输入列表不为空,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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆