13

次のような節があります。

lock_open:-
        conditional_combination(X),
        equal(X,[8,6,5,3,6,9]),!,
        プリント (X)。

この句は成功します。equal(X,[8,6,5,3,6,9])しかし、trueになる前に conditional_combination() が呼び出された回数を知りたいです。プログラムは、いくつかの規則に従って順列を生成することです。そして、865369 のような特定の値を取得するには、いくつの順列を生成する必要があるかを知る必要があります。

4

3 に答える 3

12

実際に必要なのは、少し異なるものです: 目標の (これまでの) 回答の数を数えたいとします。

次の述語はcall_nth(Goal_0, Nth)同様に成功call(Goal_0)しますが、見つかった答えが n 番目の答えであることを示す追加の引数があります。この定義は、SWI または YAP に非常に固有のものです。一般的なプログラムのようなものは使用しないでください。ただし、このようなnb_setarg/3よくカプセル化されたケースに使用してください。これら 2 つのシステム内でさえ、これらの構成要素の正確な意味は、一般的なケースでは十分に定義されていません。SICStus の定義は次のとおりです。

call_nth(Goal_0, C) :-
   State = count(0,_), % 変数のままの余分な引数に注意してください
   ゴール_0、
   arg(1, 状態, C1),
   C2 は C1+1、
   nb_setarg(1, 状態, 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)。
私 = N 番目、N 番目 = 1 ;
私 = N 番目、N 番目 = 2 ;
I = N 番目、N 番目 = 3 ;
I = N 番目、N 番目 = 4 ;
I = N 番目、N 番目 = 5。

したがって、単純にラップします。

lock_open :-
   call_nth(conditional_combination(X), Nth),
   X = [8,6,5,3,6,9]、
   !,
   ....
于 2012-07-09T17:41:47.227 に答える
4

SWI プロローグを使用している場合はnb_getval/2、 andを使用し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).

他のプロローグには、同じことを行う別の手段があります。プロローグの実装でグローバル変数を探します。このスニペットではctr、現在の目標カウンターを保持するために用語を使用しました。プログラムで使用されていない任意の用語を使用できます。

于 2012-07-06T17:30:11.943 に答える