Подсчитывает, сколько раз объявляется правило — SWIProlog

#prolog #swi-prolog

#prolog #swi-prolog

Вопрос:

Я хотел бы подсчитать, сколько раз было объявлено определенное правило.

Например, «my_rule/3»:

         my_rule(1,A,B) :- A is 1, B is 2.
        my_rule(2,A,B) :- A is 2, B is 3.
        my_rule(3,A,B) :- A is 3, B is 4.
        my_rule(4,A,B) :- A is 21, B is 1.

        ?- count_myrule(C).
        C = 4.
 

Обратите внимание, что я хочу подсчитать правило, а не факт. В предыдущем примере семантика правил не имеет значения, я просто хочу понять, можно ли подсчитать, сколько раз я объявлял определенное правило.
Есть ли способ добиться этого? Заранее спасибо.

Ответ №1:

Вы можете использовать clause/2 , чтобы получить определения всех предложений для предиката. Первый аргумент — это заголовок интересующего вас предложения, второй аргумент — это тело. Тело будет true , если предложение является фактом (или если оно записано как «правило» с таким true же телом).

Например, учитывая:

 foo(a, b).
foo(b, c).
foo(C, D) :-
    foo(D, C).
 

мы получаем:

 ?- clause(foo(X, Y), Body).
X = a,
Y = b,
Body = true ;
X = b,
Y = c,
Body = true ;
Body = foo(Y, X).
 

Первые два ответа относятся к двум фактам ( Body is true ), третий ответ относится к правилу. Итак, чтобы получить только правила:

 ?- clause(foo(X, Y), Body), Body = true.
Body = foo(Y, X).
 

Чтобы подсчитать количество правил, вы можете использовать любой подход, который подсчитывает количество решений этого запроса. Например, используйте findall/3 для сбора списка решений и определения его длины или используйте SWI-Prolog aggregate/3 .

Редактировать: обратите внимание на комментарий Пауло Моуры о переносимости на другие системы Prolog.

Комментарии:

1. Это работает, какое хорошее решение!! Большое вам спасибо.

2. Обратите внимание, что в большинстве систем Prolog вы можете вызывать только clause/2 динамические предикаты. Это решение работает в SWI-Prolog (который, как объявляет OP, используется), предполагая protect_static_code , что для него установлено значение false (его значение по умолчанию, но изменяемое значение).

3. Спасибо, я добавил в свой ответ примечание, указывающее на ваш комментарий.