你能用纯prolog在/3之间写吗?

你能用纯prolog在/3之间写吗?,prolog,backtracking,Prolog,Backtracking,我一直在试图理解如何在回溯时从Prolog谓词生成一系列值。内置谓词between/3将在回溯时一次生成一个范围内的所有整数,因此如何编写该谓词的示例可能有助于我完成任务 我在现有的Prolog系统中寻找一个实现,但是GNU Prolog的between/3的实现是一个C函数,其中的技巧是它调用另一个C函数“Pl_Create_Choice_Point”,这允许它在回溯时生成附加值 bet(N, M, K) :- N =< M, K = N. bet(N, M, K) :- N <

我一直在试图理解如何在回溯时从Prolog谓词生成一系列值。内置谓词
between/3
将在回溯时一次生成一个范围内的所有整数,因此如何编写该谓词的示例可能有助于我完成任务

我在现有的Prolog系统中寻找一个实现,但是GNU Prolog的
between/3
的实现是一个C函数,其中的技巧是它调用另一个C函数“Pl_Create_Choice_Point”,这允许它在回溯时生成附加值

bet(N, M, K) :- N =< M, K = N.
bet(N, M, K) :- N < M, N1 is N+1, bet(N1, M, K).
如果使用剪切,可以防止最终搜索失败,并恢复确切的内置/3行为:

bet(N, M, K) :- N < M, K = N.
bet(N, M, K) :- N == M, !, K = N.
bet(N, M, K) :- N < M, N1 is N+1, bet(N1, M, K).

你真正想问的是如何创建一个选择点。只要你成功地统一了,你就会得到一个解决方案。这就是@seanmcl的第一个谓词中发生的情况:

bet(N, M, K) :- N =< M, K = N.
让我们看看
成员(X[1,2])
在这里发生了什么。首先,使用第一条规则,并将
[X | |]
[1,2]
统一,生成
X=1
=[2]
。这是一个成功的统一,因此产生了一个解决方案。如果失败(例如在控制台上按
),将启动回溯。下一个选择点位于两个规则之间,因此输入下一个规则
[|Xs]
与[1,2]统一,生成绑定
Xs=[2]
,然后调用
成员(X[2])
。在重新输入时,同样的决定可以再次作出,因此应用第一条规则
成员(X,[X |)
,并生成
X=2
绑定。这是一个解决办法。如果您再次回溯,您将得到一个无害的失败,因为这两个规则都不与
[]
统一


我希望这有助于理解这种情况。

您最初的版本要好一点,因为它最终没有失败。
?- [bet].
% bet compiled 0.00 sec, 416 bytes
true.

?- between(1,5,K).
K = 1 n
K = 2 n
K = 3 n
K = 4 n
K = 5.

?- [bet].
% bet compiled 0.00 sec, 240 bytes
true.

?- bet(1,5,K).
K = 1 n
K = 2 n
K = 3 n
K = 4 n
K = 5.
bet(N, M, K) :- N =< M, K = N.
member(X, [X|_]).
member(X, [_|Xs]) :- member(X, Xs).