2012-07-06 6 views
12

のコール数を数える:私は次のような句が句

lock_open:- 
     conditional_combination(X), 
     equal(X,[8,6,5,3,6,9]),!, 
     print(X). 

この句は成功。しかし、equal(X,[8,6,5,3,6,9])がtrueになる前に、conditional_combination()が何回呼び出されたのかを知りたいです。プログラムはいくつかの規則に従って順列を生成することです。そして、私はあなたがプロローグSWIを使用している場合は、あなたが望むものを達成するためにnb_getval/2nb_setval/2を使用することができます865369.

答えて

12

あなたが実際に望むのは、少し異なるものです。目標の回答数(これまでのところ)を数えたいとします。

次の述語call_nth(Goal_0, Nth)は、call(Goal_0)のように成功しますが、見つかった回答がn番目の回答であることを示す追加の引数があります。この定義は、SWIまたはYAPに特有のものです。 ではなくは一般的なプログラムでnb_setarg/3のようなものを使用しますが、このようにカプセル化された場合に使用してください。 の2つのシステムであっても、これらの構成要素の正確な意味は一般的なケースでは明確に定義されていません。 Here is a definition for 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], 
    !, 
    .... 
+1

私は時間**の**アグリゲータ** O(N)とそのようなプリミティブを使った**空間を行う方法を見ています。ありがとう! – CapelliC

+0

limit/2とoffset/2の実装を再考する必要があります。おそらくより基本的で普遍的な述語はcall_nth/2です。 –

+0

「call_nth/2」のリストの3行目のように目標を呼び出すことができないことはわかりませんでした。私は誰かが常に「コール(ゴール)」を必要としていると思っていましたが、明らかに「ゴール」だけで十分です! –

4

のように特定の値を取得するために生成する必要がされてどのように多くの順列に必要があります。

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を使用しました。プログラムで使用されていない用語を使用することができます。

+1

/conditional_combination '内2' /' nb_setvalへの呼び出しを1 'が結果に影響する。他の計算には 'ctr'のような名前を使うかもしれません... – false

+0

@false:true、OPは彼のプログラムで使われていない言葉を使うべきです。 – gusbro

+3

ポイントは、プログラム全体を検査せずに保証することができないということでした。 – false