sintaxis semantica reglas listas genealogico funciones ejemplo conocimiento arbol animales prolog

semantica - reglas en prolog



Prólogo cuenta la cantidad de veces que un predicado es verdadero (3)

En SWI-Prolog:

aggregate_all(count, is_man(X), Count).

Quiero contar el número de veces que un predicado personalizado es verdadero. Por ejemplo, tengo el siguiente código:

is_man(john). is_man(alex). ?:-is_man(X).

X devolverá a John, luego, si presiono el punto y coma, también devolverá alex, y luego false.

Quiero construir algo como:

count(is_man(X), Count).

Y esto para volver.

Count = 2

¿Cómo puedo hacer eso?


Para una solución Prolog estándar ISO, puede usar findall / 3 para generar una lista de todas las soluciones y luego establecer Count en la longitud de la lista resultante. Podría ser un poco complicado incluir esto en un recuento de predicado definido por el usuario / 2 como usted lo propone, porque debemos formar el primer argumento de findall / 3 de una manera que tenga en cuenta cualquier variable libre (no vinculada) en el objetivo que usted busca. Quiero pasar como el primer argumento de cuenta / 2 .

Muchos Prólogos proporcionan "contadores" u otras formas de valores globales mutables, una extensión no estándar, que podrían usarse en conexión con un "bucle" controlado por falla para hacer el mismo conteo. Un poco más engorroso, pero el apego a la letra del estándar de Prolog sería utilizar afirmar y retractarse para crear su propio "contador" ajustando un hecho dinámico.

A continuación se muestra una ilustración de este último enfoque. Hacerlo "seguro multihilo" requeriría una lógica adicional.

count(Goal,_) :- setGoalCount(0), call(Goal), incGoalCount(1), fail. /* or false in some Prologs */ count(_,Count) :- getGoalCount(Count). setGoalCount(_) :- retract(getGoalCount(_)), fail. setGoalCount(X) :- assert(getGoalCount(X)). incGoalCount(Y) :- retract(getGoalCount(X)), !, Z is X + Y, assert(getGoalCount(Z)).


count(P,Count) :- findall(1,P,L), length(L,Count).