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/3between2/3 的签名都是 (+From,+To,?X)。这意味着 FromTo 必须绑定,而 X 可以绑定或不绑定。另请注意 FromTo 必须是满足 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.