To, czego naprawdę chcesz, to coś innego: chcesz policzyć liczbę odpowiedzi (jak dotąd) na cel.
Następujący predykat call_nth(Goal_0, Nth)
zastępuje, tak jak call(Goal_0)
, ale ma dodatkowy argument, który wskazuje, że znaleziona odpowiedź jest n-tą odpowiedzią. Ta definicja jest bardzo specyficzna dla SWI lub YAP. Czy nie używać rzeczy takich jak nb_setarg/3
w swoich ogólnych programach, ale używaj ich do dobrze zakapsułowanych przypadków jak ten. Nawet w tych dwóch systemach dokładne znaczenie tych konstrukcji nie jest dobrze zdefiniowane w ogólnym przypadku. 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.
Bardziej wytrzymałe abstrakcji jest przez 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.
Więc po prostu owinąć go wokół:
lock_open :-
call_nth(conditional_combination(X), Nth),
X = [8,6,5,3,6,9],
!,
....
Widzę sposób na ** agregator ** O (N) w czasie ** i ** za pomocą takich prymitywów. Dzięki! – CapelliC
Musimy ponownie przemyśleć implementację limitu/2 i przesunięcia/2, może bardziej prymitywnym i uniwersalnym predykatem będzie call_nth/2. –
Nie zdawałem sobie sprawy, że cel można nazwać w ten sposób (trzecia linia listy 'call_nth/2'). Myślałem, że zawsze potrzebuję 'call (Goal)', ale oczywiście wystarczy 'Goal'! –