recursion count prolog clause

recursion - contar el número de llamadas de una cláusula



count prolog (2)

Si está utilizando el prólogo de SWI, puede usar nb_getval/2 y nb_setval/2 para lograr lo que desea:

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).

Otros prólogos tienen otros medios para hacer lo mismo, buscar variables globales en la implementación de su prólogo. En este fragmento utilicé el término ctr para contener el contador de objetivos actual. Puede usar cualquier término que no se use en su programa.

Tengo una cláusula como la siguiente:

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

esta cláusula tiene éxito. Pero quiero saber cuántas veces se llama a conditional_combination () antes de que equal(X,[8,6,5,3,6,9]) se haga verdadero. el programa es generar una permutación siguiendo algunas reglas. Y necesito cuántas permutación es necesario generar para obtener un valor particular como 865369.


Lo que realmente desea es algo ligeramente diferente: desea contar el número de respuestas (hasta ahora) de un objetivo.

El siguiente predicado call_nth(Goal_0, Nth) tiene éxito como call(Goal_0) pero tiene un argumento adicional que indica que la respuesta encontrada es la n-ésima respuesta. Esta definición es altamente específica para SWI o YAP. No use cosas como nb_setarg/3 en sus programas generales, pero nb_setarg/3 para casos bien encapsulados como este. Incluso dentro de esos dos sistemas, el significado preciso de estos constructos no está bien definido para el caso general. Aquí hay una definición para 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 proporciona una abstracción más robusta:

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.

Así que simplemente envuélvelo:

lock_open :- call_nth(conditional_combination(X), Nth), X = [8,6,5,3,6,9], !, ....