2012-07-06 40 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()。該程序是通過遵循一些規則來生成排列。我需要多少置換需要生成得到像865369.

回答

12

你實際上想要的是稍微不同的東西:你想計算一個目標的回答數量(到目前爲止)。

以下謂詞call_nth(Goal_0, Nth)成功如call(Goal_0),但有一個額外的參數,指示找到的答案是第n個答案。該定義對於SWI或YAP非常具​​體。做不是在你的一般程序中使用諸如nb_setarg/3之類的東西,但是將它們用於封裝良好的情況下。即使在 這兩個系統中,這些結構的確切含義在一般情況下也沒有很好的定義。 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 2012-11-27 09:20:45

+0

必須重新考慮limit/2和offset/2的實現,也許更原始的和通用的謂詞是call_nth/2。 – 2015-09-27 09:28:58

+0

我沒有意識到可以像這樣調用一個目標(call_nth/2列表的第三行)。我以爲一個人總是需要打電話(目標)',但顯然,只要「目標」就夠了! – 2016-02-02 12:58:37

4

一個特定的值如果您正在使用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). 

其他prologs有其他的方法來做同樣的事情,在你的prolog實現中尋找全局變量。在這個片段中,我使用術語ctr來保存當前的目標計數器。你可以使用那些在你的程序中沒有使用的術語。

+1

到'調用nb_setval/2'內'conditional_combination/1'會影響結果。像ctr這樣的名字可能用於其他計數... – false 2012-07-09 17:43:35

+0

@false:true,OP應該使用他的程序中沒有使用的任何術語。 – gusbro 2012-07-09 19:11:47

+3

關鍵是你不能保證沒有檢查你的整個程序。 – false 2012-07-10 05:46:45