Подтвердить что ты не робот

Подсчитать количество вызовов пункта

У меня есть предложение вроде:

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

этот пункт преуспевает. Но я хочу знать, сколько раз вызывается условное_комбинация() до того, как equal(X,[8,6,5,3,6,9]) станет истинным. программа должна сгенерировать перестановку, следуя некоторым правилам. И мне нужно, сколько перестановок нужно генерировать, чтобы получить определенное значение, например, 865369.

4b9b3361

Ответ 1

То, что вы действительно хотите, немного другое: вы хотите подсчитать количество ответов (до сих пор) цели.

Следующий предикат call_nth(Goal_0, Nth) преуспевает как call(Goal_0), но имеет дополнительный аргумент, который указывает, что найденный ответ является n-м ответом. Это определение очень специфично для SWI или YAP. Do не используйте такие вещи, как 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).
?- 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],
   !,
   ....

Ответ 2

Если вы используете пролог SWI, вы можете использовать nb_getval/2 и 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 для хранения текущего счетчика цели. Вы можете использовать любой термин там, который не используется в вашей программе.