Пролог подсчитывает базу знаний - PullRequest
4 голосов
/ 14 декабря 2011

У меня есть что-то вроде этого в моей базе знаний:

number(1).
number(3).
number(6).
number(8).
number(9).
number(12).

Теперь мне нужен предикат, который оценивает количество чисел в базе знаний, например:

countnumbers(X).
X = 6.

Как я могу это сделать? пожалуйста, я новичок в прологе и не могу понять это

Ответы [ 2 ]

8 голосов
/ 14 декабря 2011

Если вам нужно узнать, сколько X удовлетворяет некоторым предикатам, вам не нужно знать их все. Использование findall/3 действительно избыточно в подобных задачах. Когда у вас 6 или 606, это X - это, конечно, не так уж важно. Но когда у вас действительно большой и тяжелый генератор - вам не нужно хранить все значения в списке, а затем считать его длину.

Aggregate хорошо решает эту проблему:

numberr(1).
numberr(3).
numberr(6).
numberr(8).
numberr(9).
numberr(12).

countNumbers( Numbers ) :-
    aggregate( count, X^numberr( X ), Numbers ).

X^ означает «существует X», поэтому вся формула означает что-то вроде «посчитайте число X, которое numberr(X), и назовите это число Numbers.

So

?- countNumbers(X).
X = 6.
8 голосов
/ 14 декабря 2011

Используйте findall/3, чтобы получить все факты из вашей базы данных, а затем получить длину списка:

countnumbers(X) :-
    findall(N, number(N), Ns),
    length(Ns, X).

Обратите внимание: number/1 может быть встроенным предикатом.

...