Погружение в Prolog
2.2 Среда SWI-Prolog
Версия Prolog, которую мы будем использовать называется SWI-Prolog. Она разработана в Шведском Институте Компьютерных Наук(Computer Science). Данная среда является интерактивной системой, по типу Hugs, среды для языка функционального программирования, Haskell. SWI-Prolog можно запускать в двух разных режимах: из командной строки, или через интерфейс, основанный на Emacs. В обоих случаях, перед тем как двигаться дальше, вам следует добавить следующую строку в секцию синонимов(alias) вашего .cshrc файла(файла, который запускается тогда, когда ваша рабочая оболочка запускается)(актуально для *nix систем):
alias prolog '/usr/local/bin/prolog -f none'
Не забудьте активировать данный синоним(alias), введя команду оболочки:
source `/.cshrc
Emacs - пропустите, если не используете Emacs.
Существует режим GNU Emacs для SWI-Prolog. Если вы не будете использовать Prolog в Emacs редакторе, то можете пропустить данный раздел.
Для начала вы должны добавить следующие строки(в приведенном виде) в ваш .emacs файл в домашней директории. Введите эти строки в секции, помеченной "Hooks".
(setq auto-mode-alist (append
(list
(cons "\\.pl$" ’prolog-mode))
auto-mode-alist))
(autoload ’prolog-mode "~/emacs/prolog.el" "" t)
Если вы добавили эти строки и загружаете файл, чье имя заканчивается на '.pl', Emacs автоматически войдет в режим редактирования программ Prolog.
Для того, чтобы использовать этот режим, вы создаете свою программу, дав файлу с исходным кодом расширение .pl. Как только вы создали программу, вы можете вызвать интерпретатор с помощью команды:
Control-c Shift-c
Это активирует Prolog, и в то же время, загрузит ваш файл в интерпретатор Когда загрузка закончится, вы можете начать задавать вопросы системе Prolog. Помните, что каждое правило в Prolog, так же как и запрос, оканчивается точкой.
Режим Prolog в Emacs предоставляет следующие команды:
M-x run-prolog Запускает внутренний процесс Prolog,
ввод и вывод через буфер *prolog*.
C-c K prolog-compile-buffer
C-c k prolog-compile-region
C-c C-k prolog-compile-predicate
C-c C prolog-consult-buffer
C-c c prolog-consult-region
C-c C-c prolog-consult-predicate
Использование интерпретатора
Для того, чтобы запустить интерпретатор Prolog из командной строки, вы вводите команду prolog. После инициализации вы увидите приглашение к вводу:
| ?-
Выход из системы прост. Просто введите 'halt.' в приглашение к вводу(без кавычек). Сделайте это, а затем перезапустите Prolog.
Перед тем как вы сможете ознакомиться с возможностями системы, у вас должна быть программа с которой вы собираетесь работать. Используйте предпочитаемый текстовый редактор для ввода программы(например, Sublime - мой любимый, прим. переводчика) из "Пример 2.1". Убедитесь, что дали этому файлу расширение '.pl' - предположим, что вы дали имя 'first.pl'. Для того, чтобы загрузить файл в интерпретатор, введите следующее(не забудьте о точки на конце):
| ?- ['first'].
Заметьте, что .pl расширение не указывается - и ничего не забывайте, ни квадратных скобок, ни кавычек, ни точки!
Интерпретатор SWI-Prolog похож на интерпретатор Hugs в том, что программа состоит из набора определений(считываемых из файла). Интерпретатор Hugs позволяет пользователю вычислять выражение(expression), основываясь на (функциональных) определениях в программе. Таким же образом, интерпретатор SWI-Prolog считывает программу, а затем позволяет пользователю выполнить запрос, основываясь на определениях(фактах и правилах). Запрос "спрашивает) систему, есть ли какие-либо значения, удовлетворяющие определенному предикату(или их комбинации).
Давайте попробуем посмотреть это на практике.
1. В строке ожидания ввода введите следующее:
?- edge(a, b).
Когда вы нажмете "ввод", система должна ответить "Yes" и снова вывести ожидание ввода. Попробуйте еще один ввод, который приведет к ответу "Yes". Всё, что вы вводите - это запросы. Первый спрашивает систему, удовлетворяет ли кортеж (a, b) предикату edge, и, конечно, это так. Попробуйте кортеж, который ложен. Что произойдет, если вы используете имя узла, которого нет ни в одном из фактов? Думаете, будет ошибка? Нет, будет всего лишь ответ 'No'.
2. Теперь введем составные запросы. Что система отвечает на эти запросы?
?- edge(a, b), edge(a, e).
?- edge(a, b), edge(a, c).
Что вы думаете о назначении ',' ?
3. Теперь попробуем правило. Предикат tedge определяет понятие "путь длиной 2" между двумя узлами. Составьте два запроса, основанных на tedge, которые должны возвращать истину, и два запроса, возвращающих ложь.
4. И теперь очередь финальной демонстрации мощи Prolog'а. Когда идентификатор используется в программе и, при этом, начинается с маленькой буквы, он задает константное значение. Идентификаторы, начинающиеся с большой буквы определяют переменные. Переменные используются в запросах, для того, чтобы найти все значения, которые можно подставить на место переменных, чтобы предикат стал истинным.
Попробуем следующий запрос.
?- edge(a, X).
Когда вы нажмете "Ввод", система должна вывести значение для X. Если вы нажмете точку с запятой(без нажатия "Ввод"!) - это будет означать, что вы запрашиваете еще одно значение, которое удовлетворяет запросу(если таковое имеется). Если оно есть - оно будет выведено, если нет - будет выведено 'No'. Если вы нажмете "Ввод", а не точку с запятой, новых ответов вы не увидите. Способность Prolog находить все возможные ответы является мощнейшим вычислительным средством.
Теперь, чтобы вы прочувствовали идею, введите следующий запрос и выведите все ответы, посмотрев на их количество.
?- edge(X, Y).
5. Prolog содержит некоторые встроенные отношения. Например, отношения <, <=, ==, >=, > могут быть использованы для проверки арифметических отношений на числах. Запрос '1 < 3' успешен, а запрос '3 < 3' вернет 'No'. Поиграйтесь с этим.
| ?-
Выход из системы прост. Просто введите 'halt.' в приглашение к вводу(без кавычек). Сделайте это, а затем перезапустите Prolog.
Перед тем как вы сможете ознакомиться с возможностями системы, у вас должна быть программа с которой вы собираетесь работать. Используйте предпочитаемый текстовый редактор для ввода программы(например, Sublime - мой любимый, прим. переводчика) из "Пример 2.1". Убедитесь, что дали этому файлу расширение '.pl' - предположим, что вы дали имя 'first.pl'. Для того, чтобы загрузить файл в интерпретатор, введите следующее(не забудьте о точки на конце):
| ?- ['first'].
Заметьте, что .pl расширение не указывается - и ничего не забывайте, ни квадратных скобок, ни кавычек, ни точки!
Интерпретатор SWI-Prolog похож на интерпретатор Hugs в том, что программа состоит из набора определений(считываемых из файла). Интерпретатор Hugs позволяет пользователю вычислять выражение(expression), основываясь на (функциональных) определениях в программе. Таким же образом, интерпретатор SWI-Prolog считывает программу, а затем позволяет пользователю выполнить запрос, основываясь на определениях(фактах и правилах). Запрос "спрашивает) систему, есть ли какие-либо значения, удовлетворяющие определенному предикату(или их комбинации).
Давайте попробуем посмотреть это на практике.
1. В строке ожидания ввода введите следующее:
?- edge(a, b).
Когда вы нажмете "ввод", система должна ответить "Yes" и снова вывести ожидание ввода. Попробуйте еще один ввод, который приведет к ответу "Yes". Всё, что вы вводите - это запросы. Первый спрашивает систему, удовлетворяет ли кортеж (a, b) предикату edge, и, конечно, это так. Попробуйте кортеж, который ложен. Что произойдет, если вы используете имя узла, которого нет ни в одном из фактов? Думаете, будет ошибка? Нет, будет всего лишь ответ 'No'.
2. Теперь введем составные запросы. Что система отвечает на эти запросы?
?- edge(a, b), edge(a, e).
?- edge(a, b), edge(a, c).
Что вы думаете о назначении ',' ?
3. Теперь попробуем правило. Предикат tedge определяет понятие "путь длиной 2" между двумя узлами. Составьте два запроса, основанных на tedge, которые должны возвращать истину, и два запроса, возвращающих ложь.
4. И теперь очередь финальной демонстрации мощи Prolog'а. Когда идентификатор используется в программе и, при этом, начинается с маленькой буквы, он задает константное значение. Идентификаторы, начинающиеся с большой буквы определяют переменные. Переменные используются в запросах, для того, чтобы найти все значения, которые можно подставить на место переменных, чтобы предикат стал истинным.
Попробуем следующий запрос.
?- edge(a, X).
Когда вы нажмете "Ввод", система должна вывести значение для X. Если вы нажмете точку с запятой(без нажатия "Ввод"!) - это будет означать, что вы запрашиваете еще одно значение, которое удовлетворяет запросу(если таковое имеется). Если оно есть - оно будет выведено, если нет - будет выведено 'No'. Если вы нажмете "Ввод", а не точку с запятой, новых ответов вы не увидите. Способность Prolog находить все возможные ответы является мощнейшим вычислительным средством.
Теперь, чтобы вы прочувствовали идею, введите следующий запрос и выведите все ответы, посмотрев на их количество.
?- edge(X, Y).
5. Prolog содержит некоторые встроенные отношения. Например, отношения <, <=, ==, >=, > могут быть использованы для проверки арифметических отношений на числах. Запрос '1 < 3' успешен, а запрос '3 < 3' вернет 'No'. Поиграйтесь с этим.
Задача № 1
Опираясь на примеры, приведенные выше, напишите программу на Prolog, которая описывает направленный граф, со следующей структурой(смотрите рисунок). Также включите в программу предикат, который задает отношение "путь длиной 3". Определите его двумя способами: 1) опираясь на отношение edge 2) используя отношение tedge.
Протестируйте полученное.
P.S. Извините, за скачущую верстку, веб редактор дурацкий на блогере, уже снова поставил Windows Live Writer, новые переводы в нем будут.
Комментариев нет:
Отправить комментарий