我有一个像下面的条款:
lock_open:- conditional_combination(X), equal(X,[8,6,5,3,6,9]),!, print(X).
这一条款成功。 但我想知道有多少次conditional_combination()被调用之前equal(X,[8,6,5,3,6,9])
中成为现实。 该方案是由以下一些规则生成置换。 我需要多少置换需要生成得到像865369一个特定的值。
我有一个像下面的条款:
lock_open:- conditional_combination(X), equal(X,[8,6,5,3,6,9]),!, print(X).
这一条款成功。 但我想知道有多少次conditional_combination()被调用之前equal(X,[8,6,5,3,6,9])
中成为现实。 该方案是由以下一些规则生成置换。 我需要多少置换需要生成得到像865369一个特定的值。
你真正想要的是什么略有不同:你要算的答案(到目前为止)的进球数。
以下谓词call_nth(Goal_0, Nth)
成功等call(Goal_0)
但具有其指示找到了答案是第n个应答的附加自变量。 这个定义是非常具体的,以SWI或YAP。 不要使用之类的东西nb_setarg/3
在您的一般程序,但使用它们以及封装的情况下,因为这一个。 即使是那些两个系统内,这些构建体的确切含义没有很好地用于一般情况下定义的。 下面是SICStus的定义 。
call_nth(Goal_0, C) :- State = count(0,_), % note the extra argument which remains a variable Goal_0, arg(1, State, C1), C2 is C1+1, nb_setarg(1, State, C2), C = C2.
更健壮的抽象Eclipse提供:
call_nth(Goal_0, Nth) :-
shelf_create(counter(0), CounterRef),
call(Goal_0),
shelf_inc(CounterRef, 1),
shelf_get(CounterRef, 1, Nth).
?- call_nth(between(1,5,I),Nth). I = Nth, Nth = 1 ; I = Nth, Nth = 2 ; I = Nth, Nth = 3 ; I = Nth, Nth = 4 ; I = Nth, Nth = 5.
所以,简单地将其套在:
lock_open :- call_nth(conditional_combination(X), Nth), X = [8,6,5,3,6,9], !, ....
如果你正在使用SWI序言中,你可以使用nb_getval/2
和nb_setval/2
,以达到你想要的东西:
lock_open:-
nb_setval(ctr, 0), % Initialize counter
conditional_combination(X),
nb_inc(ctr), % Increment Counter
equal(X,[8,6,5,3,6,9]),
% Here you can access counter value with nb_getval(ctr, Value)
!,
print(X).
nb_inc(Key):-
nb_getval(Key, Old),
succ(Old, New),
nb_setval(Key, New).
其他prologs有其他方式做同样的,看在你的序言实现全局变量。 在这个片段中我用了ctr
,以保持当前的目标计数器。 你可以使用任何长期存在未在程序中使用。
虽然在模块“微”的工作,我最近发明了支点。 它们由线程/管模式的启发,绕过数据。 枢轴是最大长度为1的有界队列时,pivot_put / 1确实给定术语的副本,以及。 但是,出于性能的考虑,他们不使用同步,并且是无阻塞。
在据他们都非常相似,nb_setarg / 3,但他们不破坏一个Prolog项,而是他们更新Java数据结构。 因此,他们比非逻辑运算一词更安全一点。 此外,他们并不需要一些call_cleanup / 3,因为它们是Java的垃圾回收。
在据它们比nb_setarg / 3,比使用一些明确分配和结构的dealloccate更相似。 因此,例如用于SICStus Prolog的一个解决办法是:
call_nth(Goal_0, Nth) :-
new(unsigned_32, Counter),
call_cleanup(call_nth1(Goal_0, Counter, Nth),
dispose(Counter)).
call_nth1(Goal_0, Counter, Nth) :-
call(Goal_0),
get_contents(Counter, contents, Count0),
Count1 is Count0+1,
put_contents(Counter, contents, Count1),
Nth = Count1.
有了支点,甚至有没有32位的限制,我们可以直接做:
call_nth(G, C) :-
pivot_new(P),
pivot_put(P, 0),
call(G),
pivot_take(P, M),
N is M+1,
pivot_put(P, N),
C = N.