我正在尝试触发目标,但如果可能的话,以动态的方式进行回溯。为了更好地体现我的问题,假设我们有以下序言代码:
num(1).
num(2).
num(3).
num(4).
num(5).
然后我前往swi-promog并致电: num(X)
。通过键入;
,这触发了寻找所有解决方案的回溯。
我想要的是删除这些事实(num(1)
,num(2)
等),然后用动态生成这些事实的东西替换该代码。有什么办法可以实现这一目标?某些情况,也许?
num(X):- for X in 1..5
产生与上面代码相同的解决方案?
据我所知,findall
谓词返回列表,这不是我想要的。我想回溯所有答案,并使用控制台中的;
浏览它们。
是的,您已经非常接近了!
:- use_module(library(clpfd)).
num(X) :-
X in 1..5.
?- num(X).
X in 1..5.
?- num(X), X #>3.
X in 4..5.
?- num(X), labeling([], [X]).
X = 1
; X = 2
; X = 3
; X = 4
; X = 5.
swi-prolog具有(非ISO)谓词between/3
:
num(X) :- between(1, 5, X).
您可以实现谓词(对于其他序言,并且要进行进一步的调整):
between2(A, A, A) :- !. % green cut
between2(A, B, A) :- A < B.
between2(A, B, C) :-
A < B,
A1 is A + 1,
between2(A1, B, C).
between/3
和between2/3
的签名是(+From,+To,?X)
。这意味着From
和To
必须绑定,并且X
可以绑定或不绑定。另请注意,From
和To
必须是整数,以便From <= To
。(哦,这些整数必须在以前使用带有可选plus或负号的阿拉伯数字编写。使用ASCII。是否仍然错过了某些东西?尽管Swi-Promog是通常在无界整数支持的情况下编译,因此between(1, 100000000000000000000000000000000000000000000, X)
和between2(1, 100000000000000000000000000000000000000000000, X)
通常都可以工作。)