计算一个条款的调用次数

Md *_*san 12 recursion count prolog clause

我有一个如下的条款:

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这样的特定值.

fal*_*lse 12

你真正想要的是略有不同:你想要计算一个目标的答案数(到目前为止).

以下谓词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).
Run Code Online (Sandbox Code Playgroud)
?- 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],
   !,
   ....


gus*_*bro 5

如果您正在使用SWI prolog,您可以使用nb_getval/2nb_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).
Run Code Online (Sandbox Code Playgroud)

其他prolog还有其他方法可以做同样的事情,在prolog实现中寻找全局变量.在这个片段中,我使用该术语ctr来保持当前的目标计数器.您可以使用程序中未使用的任何术语.

  • 关键是你不能保证不检查你的整个程序. (3认同)