简体   繁体   English

如何在Prolog中判断列表长度是奇数还是偶数

[英]How to tell if list length is odd or even in Prolog

I'm attempting to determine whether a Prolog list has an odd or even number of elements. 我试图确定Prolog列表中的元素是否为奇数或偶数。 I realize there are likely better solutions using length/2 and I would be willing to mark a better solution than this one the right answer, I would just like to know what I am doing wrong in this example. 我意识到使用length/2可能会有更好的解决方案,并且我愿意为这个解决方案标记一个比这个正确的答案更好的解决方案,我只想知道我在本示例中做错了什么。

I have code detailed as: 我的代码详细如下:

oddSize([]) :-
    false.
oddSize([_]).
oddSize([_,_|T]) :-
    oddSize(T).

The output I receive when I attempt to test this code is: 尝试测试此代码时收到的输出是:

1 ?- oddSize([]).
false.

2 ?- oddSize([1]).
true ;
false.

3 ?- oddSize([1,2]).
false.

4 ?- oddSize([1,2,3]).
true ;
false.

It seems to be detecting which of the lists have an odd number of elements, but why do I get the extra result of false ? 似乎正在检测哪个列表中的元素数量为奇数,但是为什么我得到false的额外结果呢?

Note that you can define an odd_size/1 predicate that succeeds at most once, ie without leaving any choice-point (*): 注意,您可以定义一个成功最多一次的odd_size/1谓词,即不留下任何选择点(*):

odd_size([_| Tail]) :-
    even_size(Tail).

even_size([]).
even_size([_| Tail]) :-
    odd_size(Tail).

(*) Assuming that your Prolog systems uses first-argument indexing (true for modern systems), which avoids creating a choice-point when calling the even_size/1 predicate with an instantiated argument. (*)假设您的Prolog系统使用第一参数索引(对于现代系统为true),这避免了在使用实例化参数调用even_size/1谓词时避免创建选择点。

Some sample queries: 一些示例查询:

?- odd_size([1,2,3]).
true.

?- odd_size([1]).
true.

?- odd_size([1,2]).
false.

It looks to me like your code is correct, I think you are just misunderstanding Prolog's output. 在我看来,您的代码是正确的,我认为您只是误解了Prolog的输出。 I've found a more comprehensive response from someone else on stackoverflow and linked it below. 我发现了其他人对stackoverflow的更全面的响应,并将其链接到下面。 Sorry, I'm new to stackoverflow so I don't know how best to link it. 抱歉,我是stackoverflow的新手,所以我不知道如何最好地链接它。

"This answer is correct. In Prolog, the order in which your facts are rules are written determines the order they will be found by a query. More specifically, the 'backtrack' option ";" essentially tells forces the query engine to discard the returned result and answer the question "are there any other answers?". So, it is not that f(a,b) is both true and false; but rather that it is true and if you choose to ignore that result the engine will tell you there are no other f(a,b) fact entries. To prove this, watch what happens if you add a second f(a,b) fact." “这个答案是正确的。在Prolog中,事实是规则的写入顺序决定了查询将找到它们的顺序。更具体地说,'backtrack'选项“;”本质上告诉强制查询引擎放弃该规则。返回结果并回答问题“还有其他答案吗?”。因此,并不是f(a,b)是对还是错;而是它是对的,如果您选择忽略该结果,引擎将告诉您没有其他f(a,b)事实条目。为证明这一点,请注意如果添加第二个f(a,b)事实会发生什么。” – Assaf Jul 24 '10 at 2:17 –阿萨夫10年7月24日在2:17

Source: Why is this prolog query both true and false? 资料来源: 为什么这个序言查询是对还是错?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM