我在 https://swish.swi-prolog.org 上做了一个基本谓词 ascending/1
来检查列表是否按升序排列。
ascending([]).
ascending([_]).
ascending([X, Y| T]) :-
X =< Y,
ascending([Y|T]).
如果我查询 ?- ascending([1, 2, 4, 6]).
,它会显示以下内容:
正如,它试图找到更多的解决方案。按 Next
、10
、100
或 1,000
只会返回 false
,这本身就是一个谜 - 同时真假?也许那是因为匿名_
?我的定义还不够完整吗?为什么它不只是返回 true?
答案 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.