回溯增加价值
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 在帮助页面上的评论)
我怎样才能在回溯上增加...以便目标(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
orinfinite
between/3 is true iff Value >=Low, a feature that is particularly interesting for generating integers from a certain value.
(并查看 LogicalCaptain 在帮助页面上的评论)