Пролог подсчитывает количество истинных предикатов - PullRequest
23 голосов
/ 19 мая 2011

Я хочу посчитать, сколько раз пользовательский предикат имеет значение true.Например, у меня есть следующий код:

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

X вернет john, затем, если я нажму точку с запятой, она также вернет alex, затем false.

Я хочу создать что-то вроде:

count(is_man(X), Count).

И это вернуть

Count = 2

Как я могу это сделать?

Ответы [ 3 ]

27 голосов
/ 19 мая 2011

В SWI-прологе:

aggregate_all(count, is_man(X), Count).
11 голосов
/ 19 мая 2011

Для стандартного решения Prolog ISO вы можете использовать findall / 3 , чтобы создать список всех решений, а затем установить Count равным длине полученного списка. Может быть немного сложно заключить это в пользовательский предикат count / 2 , как вы предлагаете, потому что нам нужно сформировать первый аргумент findall / 3 таким образом, чтобы учитывает любые свободные (несвязанные) переменные в цели, которую вы хотите передать в качестве первого аргумента count / 2 .

Многие прологи предоставляют «счетчики» или другие формы изменяемых глобальных значений, нестандартное расширение, которые можно использовать в связи с «циклом», управляемым отказами, для выполнения одинакового подсчета. Чуть более громоздким, но придерживающимся буквы стандарта Prolog было бы использовать assert и retract , чтобы создать свой собственный "счетчик" путем корректировки динамического факта.

Ниже приводится иллюстрация последнего подхода. Чтобы сделать его «многопоточным безопасным», потребовалась бы дополнительная логика.

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)).
5 голосов
/ 20 мая 2011

count(P,Count) :-
        findall(1,P,L),
        length(L,Count).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...