2013-04-14 6 views
2

Я изучаю книгу Ивана Братко: «Программирование для искусственного интеллекта» для универсального exame и использования SWI Prolog, и у меня есть некоторые сомнения в примере, показанном в этой книге относительно утверждают и retract предикаты.Некоторые проблемы с утверждением нового правила в SWI-Prolog

Он просто представить следующий код, который декларировать некоторые факты, как динамические:

:-dynamic fast(ann). 
:-dynamic slow(tom). 
:-dynamic slow(pat). 

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

[debug] 59 ?- assert((faster(X,Y) :- fast(X), slow(Y))). 
true. 

Итак, новое правило, похоже, добавлено в мою базу данных.

Теперь я пытаюсь выполнить этот запрос, и он не в состоянии:

[debug] 64 ?- faster(X,Y). 
false. 

О книге говорит, что вывод должен быть таким:

A = ann 
B = tom 

и это звучит хорошо и рационально, потому что у меня есть проконсультируйтесь с предыдущей программой, где говорится, что укажите, кто быстро, а кто медленный, и позже я добавляю более быстрое правило, утверждающее это ...

Почему бы не сработать? возможно, это зависит от реализации Prolog (SWI-Prolog)?

+3

Использование директивы 'dynamic' должен просто указать предикат и его количество аргументов, например ': - динамический быстрый/1' и': -динамический медленный/1'. Утверждение фактов для этих динамических предикатов является отдельным (runtime) шагом. – hardmath

+0

ok, tnx для уточнения – AndreaNobili

+0

Интересное оповещение: Вещи утверждаются только в памяти на время выполнения программы. Я играю с ним, и когда я пытаюсь отменить факты, которые я определил с помощью 'assertz' на отдельных прогонах, он терпит неудачу, потому что их нет. Чтобы постоянно добавлять базу знаний, вам нужен выходной поток с добавлением. –

ответ

4

Директива dynamic в Prolog полезна в скомпилированных программах (и обычно используется в исходном файле для компиляции). Если вы используете assert или эквивалентный механизм для создания фактов (или правил) в интерактивной оболочке, тогда SWI-Prolog уже предполагает, что эти предикаты являются динамическими.

Однако директива dynamic полезна в случае, когда вы хотите обратиться к предикату через предложение в правиле, прежде чем определять какие-либо факты для этого предиката. То есть, предположим, что мы сначала сделать это:

?- assert((faster(X,Y) :- fast(X), slow(Y))). 
true. 

, а затем попробовать запрос:

?- faster(X,Y). 

Вы могли бы ожидать, что это просто не получится, потому что никакие факты не существуют (пока) для fast/1 или slow/1.Но на самом деле SWI-Пролог (дизайн) бросить исключение об ошибке:

ERROR: faster/2: Undefined procedure: fast/1 

Чтобы предотвратить это, мы должны добавить динамические директивы в режиме ввода пользователя:

?- [user]. 
|: :-dynamic fast/1, slow/1. 
|: (type Ctrl-z to exit user entry mode) 
% user://1 compiled 0.00 sec, 1 clauses 

Теперь мы получим ожидаемый провал поведение (при условии, что ранее правила):

?- faster(X,Y). 
false. 

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

?- [user]. 
|: fast(ann). 
|: slow(tom). 
|: slow(pat). 
|: (type Ctrl-z to exit user entry mode) 
% user://2 compiled 0.00 sec, 4 clauses 
true. 

Теперь faster запрос успешно двумя различными способами:

?- faster(X,Y). 
X = ann, 
Y = tom ; 
X = ann, 
Y = pat. 
Смежные вопросы