当只存在一个时,Prolog 会尝试找到多个解决方案

标签 prolog prolog-toplevel

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

ascending([]).
ascending([_]).
ascending([X, Y| T]) :-
    X =< Y,
    ascending([Y|T]).
如果我查询 ?- ascending([1, 2, 4, 6]).,它会显示以下内容:
1
如,它试图找到更多的解决方案。按Next , 10 , 1001,000只返回 false ,这本身就是一个谜——同时是真的还是假的?也许是因为匿名 _ ?我定义的不够完整吗?为什么它不只是返回真实?

最佳答案

大多数 Prolog 系统都实现了第一个参数索引,这样可以避免创建虚假的选择点。假设绑定(bind)了第一个参数的调用,就您的代码而言,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.

关于当只存在一个时,Prolog 会尝试找到多个解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66054987/

相关文章:

binding - Prolog中变量的几种绑定(bind)选项

Prolog 回溯寻找解决方案并返回错误

prolog - 序言 SWI 中的未定义过程错误

PROLOG 规则在找到第一个匹配后停止

list - 替换 Prolog 列表中单个出现的元素

prolog - 在河内序言塔上实现计数器

prolog - 基于 Prolog 数据文件的多用户 Web 应用程序

list - 递归检查列表中的所有元素是否都是 Prolog 中的某个值

prolog - 如何更改 prolog 中变量打印的顺序?