【问题标题】:How to tell if list length is odd or even in Prolog如何在 Prolog 中判断列表长度是奇数还是偶数
【发布时间】:2015-12-05 21:12:06
【问题描述】:

我正在尝试确定 Prolog 列表的元素数是奇数还是偶数。我意识到使用length/2 可能有更好的解决方案,我愿意将比这个更好的解决方案标记为正确答案,我只想知道我在这个例子中做错了什么。

我的代码详细如下:

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

我尝试测试此代码时收到的输出是:

1 ?- oddSize([]).
false.

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

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

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

似乎在检测哪些列表有奇数个元素,但是为什么我得到false的额外结果?

【问题讨论】:

  • 每个子句在 Prolog 中创建所谓的“选择点”。如果堆栈上有一个选择点,Prolog 将为您提供要求另一个答案的选项。由于您的谓词在逻辑上是正确的,因此这个选择点是无害的。删除这些被称为使您的谓词确定性,并且可以成为学习切割(!)或once/1的一个很好的练习。

标签: prolog


【解决方案1】:

请注意,您可以定义一个最多成功一次的 odd_size/1 谓词,即不留下任何选择点 (*):

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

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

(*) 假设您的 Prolog 系统使用第一个参数索引(现代系统为真),这样可以避免在使用实例化参数调用 even_size/1 谓词时创建选择点。

一些示例查询:

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

?- odd_size([1]).
true.

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

【讨论】:

  • 非常感谢,这真的很好。
【解决方案2】:

在我看来您的代码是正确的,我认为您只是误解了 Prolog 的输出。我在 stackoverflow 上找到了其他人的更全面的回复,并将其链接在下面。抱歉,我是 stackoverflow 的新手,所以我不知道如何最好地链接它。

“这个答案是正确的。在Prolog中,你的事实是规则的顺序决定了它们将被查询找到的顺序。更具体地说,'backtrack'选项“;”本质上告诉强制查询引擎丢弃返回的结果并回答“还有其他答案吗?”。因此,f(a,b) 不是既对又错;而是它是对的,如果您选择忽略该结果引擎会告诉你没有其他 f(a,b) 事实条目。要证明这一点,请观察如果添加第二个 f(a,b) 事实会发生什么。 – 阿萨夫 2010 年 7 月 24 日 2:17

来源: Why is this prolog query both true and false?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 2015-05-01
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多