当只有一个解决方案存在时,Prolog 试图找到多个解决方案
Prolog tries to find multiple solutions when only one exists
我在 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
只是 returns false
,这本身就是一个谜 - 在同时?也许那是因为匿名_
?我定义的不够完整吗?为什么它不只是返回 true?
大多数 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.
我在 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
只是 returns false
,这本身就是一个谜 - 在同时?也许那是因为匿名_
?我定义的不够完整吗?为什么它不只是返回 true?
大多数 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.