Prolog 尝试在只有一个解决方案时找到多个解决方案

时间:2021-02-04 22:46:14

标签: prolog prolog-toplevel

我在 https://swish.swi-prolog.org 上做了一个基本谓词 ascending/1 来检查列表是否按升序排列。

ascending([]).
ascending([_]).
ascending([X, Y| T]) :-
    X =< Y,
    ascending([Y|T]).

如果我查询 ?- ascending([1, 2, 4, 6]).,它会显示以下内容:

1

正如,它试图找到更多的解决方案。按 Next101001,000 只会返回 false,这本身就是一个谜 - 同时真假?也许那是因为匿名_?我的定义还不够完整吗?为什么它不只是返回 true?

1 个答案:

答案 0 :(得分:4)

大多数 Prolog 系统实现了第一参数索引,这样可以避免创建虚假的选择点。假设并绑定了第一个参数的调用,在您的代码的情况下,Prolog 运行时能够区分第一个子句(其第一个参数是原子)和其他两个子句(其第一个参数是列表) .但不能(通常)区分第二个和第三个子句,并避免为第一个参数是列表的目标而尝试两者。这导致创建选择点。因此你得到的结果:

?- ascending([1, 2, 4, 6]).
true ;
false.

但我们可以改进您的解决方案。例如:

ascending([]).
ascending([Head| Tail]) :-
    ascending(Tail, Head).

ascending([], _).
ascending([Head| Tail], Previous) :-
    Previous =< Head,
    ascending(Tail, Head).

我们现在将得到:

?- ascending([1, 2, 4, 6]).
true.

?- ascending([1, 2, 4, 6, 1]).
false.