Prolog - 通过一组动态选项回溯
Prolog - Backtracking through a set of dynamic options
我正在尝试以动态方式触发目标回溯,如果可能的话。为了更好地举例说明我的问题,假设我们有以下 PROLOG 代码:
num(1).
num(2).
num(3).
num(4).
num(5).
然后我前往 SWI-Prolog 并调用:num(X)
。这会通过键入 ;
触发回溯寻找所有解决方案。
我想要的是删除这些事实(num(1)
、num(2)
等)并用动态生成这些事实的代码替换该代码。有什么办法可以做到这一点?也许吧?
num(X):- for X in 1..5
产生与上述代码相同的解决方案?
据我所知,findall
谓词 returns 是一个列表,这不是我要找的。我想回溯所有答案并在控制台中使用 ;
查看它们。
SWI-Prolog 具有(非 ISO)谓词 between/3
:
num(X) :- between(1, 5, X).
您可以像这样实现谓词(对于其他 Prolog 和进一步调整):
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
的整数。 (哦,而且这些整数必须使用阿拉伯数字书写,前面有可选的加号或减号。并且使用 ASCII。是否还遗漏了一些不明显的东西?而且整数不能太大或太小,尽管 SWI-Prolog 是通常编译时支持无限整数,所以 between(1, 100000000000000000000000000000000000000000000, X)
和 between2(1, 100000000000000000000000000000000000000000000, X)
通常都可以。)
是的,你已经很接近了!
:- 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.
我正在尝试以动态方式触发目标回溯,如果可能的话。为了更好地举例说明我的问题,假设我们有以下 PROLOG 代码:
num(1).
num(2).
num(3).
num(4).
num(5).
然后我前往 SWI-Prolog 并调用:num(X)
。这会通过键入 ;
触发回溯寻找所有解决方案。
我想要的是删除这些事实(num(1)
、num(2)
等)并用动态生成这些事实的代码替换该代码。有什么办法可以做到这一点?也许吧?
num(X):- for X in 1..5
产生与上述代码相同的解决方案?
据我所知,findall
谓词 returns 是一个列表,这不是我要找的。我想回溯所有答案并在控制台中使用 ;
查看它们。
SWI-Prolog 具有(非 ISO)谓词 between/3
:
num(X) :- between(1, 5, X).
您可以像这样实现谓词(对于其他 Prolog 和进一步调整):
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
的整数。 (哦,而且这些整数必须使用阿拉伯数字书写,前面有可选的加号或减号。并且使用 ASCII。是否还遗漏了一些不明显的东西?而且整数不能太大或太小,尽管 SWI-Prolog 是通常编译时支持无限整数,所以 between(1, 100000000000000000000000000000000000000000000, X)
和 between2(1, 100000000000000000000000000000000000000000000, X)
通常都可以。)
是的,你已经很接近了!
:- 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.