回溯增加价值

Incrementing value on backtrack

我怎样才能在回溯上增加...以便目标(S)收到递增的数字..每次它在下一个失败时运行我想获得下一个数字

S1 is S + 1,goal(S1)

不起作用,因为 :

?- S=0, S1 is S+1.
S = 0,
S1 = 1.

?- S=0,between(1,3,_), S1 is S+1.
S = 0,
S1 = 1 ;
S = 0,
S1 = 1 ;
S = 0,
S1 = 1.

这项工作

%%counting
baz(..,C) :- .... arg(...), Y is X + 1, nb_setarg(...), goal(Y), ...

foo(..C) :- ....baz(....,C)..., foo(...C).


%%counter
blah :- ....foo(....,counter(0))...

这是行不通的,我认为递归 foo() 会强制 baz() 初始化计数器 (0)...但我对上面的 @sligo 解决方案很满意

baz(..) :- C = counter(0), ....  arg(...), Y is X + 1, nb_setarg(...), goal(Y), ...
foo(..) :- ....baz(....)..., foo(...).

使用non-backtrackable破坏性赋值谓词nb_setarg/3:

?- C = counter(0), between(1, 3, _), arg(1, C, X), Y is X + 1, nb_setarg(1, C, Y).
C = counter(1),
X = 0,
Y = 1 ;
C = counter(2),
X = 1,
Y = 2 ;
C = counter(3),
X = 2,
Y = 3.

备选方案:

foo(C) :-
    between(1, inf, C), 
    goal(C),
    !.

baz(C) :-
    C = counter(0),
    repeat,
        arg(1, C, X),
        Y is X + 1,
        nb_setarg(1, C, Y),
        goal(Y),
        !.

goal(X) :-
    X > 9.

示例:

?- foo(C).
C = 10.

?- baz(C).
C = counter(10).

so that goal(S) receives incremented number .. every time it fails on the next run I want to get the next number

这就是 between/3 的作用?每次回溯它都会产生下一个数字:

goal(X) :- 
  write('inside goal, X is '), 
  write(X),
  nl.

test :-
  between(0, 3, S),
  goal(S).

例如

?- test.
inside goal, X is 0
true ;
inside goal, X is 1
true ;
inside goal, X is 2
true ;
inside goal, X is 3
true ;

编辑:来自 help for between/3

between(+Low, +High, ?Value)

Low and High are integers, High >=Low. If Value is an integer, Low =<Value =<High. When Value is a variable it is successively bound to all integers between Low and High. If High is inf or infinite between/3 is true iff Value >=Low, a feature that is particularly interesting for generating integers from a certain value.

(并查看 LogicalCaptain 在帮助页面上的评论)