Определение предикатов в SICStus Prolog/SWI-Prolog REPL

Я читаю http://cs.union.edu/~striegnk/learn-prolog-now/html/node3.html#subsec.l1.kb1, но у меня возникли проблемы с запуском следующего предиката:

SICStus 4.0.1 (x86-win32-nt-4): Tue May 15 21:17:49 WEST 2007
| ?- woman(mia).
! Existence error in user:woman/1
! procedure user:woman/1 does not exist
! goal:  user:woman(mia)
| ?- 

Если, с другой стороны, я записываю его в файл и запускаю просмотр файла, кажется, что он работает нормально...

Могу ли я только определять предикаты в файле, чтобы позже обращаться к ним? Я не могу просто сделать это в самом редакторе?


person devoured elysium    schedule 06.09.2011    source источник


Ответы (2)


Вы должны ввести woman(mia). в файл, чтобы подтвердить это как факт. Если прописать в интерпретатор, то это воспринимается как запрос, а не как факт.

Из часто задаваемых вопросов по SWI Prolog:

Термины, которые вы вводите на верхнем уровне, обрабатываются как запросы, а термины, которые появляются в файле, загружаемом в Prolog, обрабатываются как набор правил и фактов. Если текст выглядит так, как показано ниже, это правило.

carnivore(X) :- animal(X), eats_meat(X).

Попытка ввести это на верхнем уровне приводит к ошибке ниже. Почему? Поскольку правило является термином :-(Head, Body), и поскольку верхний уровень интерпретирует термины как запросы. Нет предиката с именем :- и двумя аргументами.

?- carnivore(X) :- animal(X), eats_meat(X). ERROR: Undefined
procedure: (:-)/2 ERROR:   Rules must be loaded from a file ERROR:  
See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt

Разве это не глупо? Ну нет. Предположим, у нас есть термин ест_мясо (ратаплан). Если это появляется в файле, это говорит о том, что ратаплан ест мясо. Если он появляется на верхнем уровне, он просит Пролога попытаться доказать, ест ли ратаплан мясо.

Если текст читается

:- use_module(library(clpfd)).

Это директива. Директивы похожи на запросы, но вместо того, чтобы просить верхний уровень что-то сделать, они просят что-то сделать компилятор. Подобно правилам и фактам, такие термины принадлежат файлам.

Вместо записи в файл вы также можете использовать assert на верхнем уровне (как объяснено позже в FAQ).

person sepp2k    schedule 06.09.2011
comment
Итак, в данном случае assert(woman(mia)). будет делать только то, что я хочу? - person devoured elysium; 06.09.2011
comment
Сообщение об ошибке может ввести в заблуждение новичка. Так как правила также могут быть загружены от пользователя, который не является файлом. Но это общая проблема создания хороших сообщений об ошибках. - person Mostowski Collapse; 07.09.2011

Немного раздражает создание предикатов в repl. Вы могли бы сделать

| ?- ['user'].
woman(mia).
^D

т.е. консультируйтесь с пользовательским вводом, или

| ?- assertz(woman(mia)).

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

person Owen    schedule 06.09.2011