在回溯上增加值

发布于 2025-01-24 06:16:48 字数 687 浏览 0 评论 0 原文

我该如何在回溯方面进行增量...以便该目标会收到增量的数字..每次下一个运行失败时,我想获得下一个数字

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(...).

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

S1 is S + 1,goal(S1)

does not work, because :

?- 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.

this work

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

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


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

this is not working, i think cause the recursive foo() would force baz() to initialize counter(0)... but i'm good with @sligo solution above

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

溇涏 2025-01-31 06:16:48

这样,该目标会收到增量的数字。每次下一个运行失败时,我都想获得下一个数字

,即/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在/3之间

( +低, +高,?value)

之间

低和高的是整数,高> =低。如果值是整数,
low =< value =<高。当值是变量时,它是连续的
与低和高之间的所有整数绑定。如果高是 inf
Infinite /3之间是正确的,如果value> = low,一个功能是
从一定值中产生整数特别有趣。

(并查看逻辑学院的帮助页面上的评论)

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

That's what between/3 does? Every time on backtracking it makes the next number:

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

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

e.g.

?- 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 ;

Edit: From the 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.

(And see the comments on the help page by LogicalCaptain)

七婞 2025-01-31 06:16:48

使用 不可用的破坏性分配谓词

?- 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).

Use non-backtrackable destructive assignment predicate 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.

Alternatives:

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.

Examples:

?- foo(C).
C = 10.

?- baz(C).
C = counter(10).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文