#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. Спасибо, я добавил в свой ответ примечание, указывающее на ваш комментарий.