- Как работать в SWI Prolog
- Установка SWI Prolog
- Программирование в SWI Prolog
- Главная
- Инструменты пользователя
- Инструменты сайта
- Боковая панель
- Содержание
- Быстрый запуск программы в среде SWI-Prolog. Наша первая программа
- Разбираем подробнее вашу первую программу
- Работа в SWI-Prolog в Linux
- Обсуждение
- Инструменты страницы
- Настраиваем редактор исходных текстов SWI-Prolog (XPCE Emacs) для пользователя, не знакомого с клавиатурными комбинациями Emacs
- SWI-пролог до С# не работает
- Предикат сортировки SWI-Prolog не работает
Как работать в SWI Prolog
Если у вас возникают проблемы с пониманием того, как вообще выполняются программ на Prolog — посмотрите статью: Введение в логическое программирование.
В этой статье описан процесс установки SWI Prolog и запуска простой программы в консоли (терминале) с помощью утилицы swipl. Однако, для SWI Prolog есть несколько сред разработки.
Установка SWI Prolog
Я буду устанавливать SWI Prolog на 64х разрядную версию OpenSUSE 42.1. Для установки открываем центр управления Yast:
Выбираем «Управление программным обеспечением». В появившемся окне вводим swipl, в правой части окна появляется соответствующий пакет, нажимаем на него правой кнопкой мыши и выбираем «установить»:
Теперь для работы в среде SWI Prolog можно открыть терминал и ввести команду swipl. Будет запущен интерпретатор, в который можно передавать команды:
Программирование в SWI Prolog
Для присоединения файлов с исходным кодом можно выполнить команду consult(путь к файлу) или [путь к файлу] . Немного удобнее использовать редактор кода (например kate или gedit) со встроенным окном терминала (для этого во многих редакторах есть специальные плагины):
Для работы нужно открыть в редакторе файл исходного кода, в терминале перейти в соответствующий каталог и выполнить в нем команду swipl , присоединить файл исходного кода при помощи consult . Теперь можно передавать интерпретатору команды. В приведенном выше примере, в файле описаны студенты в соответствии с заданием, мы выполняем команду student(Who, Rate) для получения информации обо всех студентах в базе.
В отличии от Visual Prolog, SWI Prolog не выводит сразу все найденные решения. Выводится первое решение, при этом если полученных данных пользователю достаточно, он может ввести точку, а если ему нужны другие решения — то нужно ввести точку с запятой.
Введем в текстовом редакторе программу в соответствии с заданием:
Для обновления данных в интерпретаторе нужно повторно выполнить команду consult.
Разберем предложенную программу:
- предикаты company и student являются фактами (подобно предикату parent из предыдущей работы);
- предикат stipendya принимает имя студента, выполняет поиск студента в базе и получение его среднего балла. Затем выполняется сравнение среднего балла с константой:
- если сравнение проходит успешно, то предикат также завершится успешно и «снаружи» мы получим имя студента, для которого есть стипендия;
- если при сравнении выясняется, что балл студента меньше константы, то предикат завершается неудачей. Никакого результата (информации о студенте, с которым это случилось) «снаружи» мы при этом не получим, но будет запущен механизм поиска с возвратами (интерпретатор попробует подобрать других студентов, соответствующих нашим критериям);
- предикат может завершиться неудачей до выполнения сравнения — если передано имя студента, о котором нет информации в базе (мы просто не сможем получить для него средний балл);
- наконец, если в предикат передана анонимная переменная stipendya(Name) , то будут выведены все студенты, для которых начисляется стипендия.
- Предикат isAbleToWork принимает на вход имя студента и имя компании, выполняет поиск среднего балла студента и минимального проходного балла компании, а затем сравнивает эти баллы. Работает аналогично предикату stipendya с той разницей, что проходной балл компании не является константой, а извлекается из базы. Если в качестве имени компании передать анонимную переменную, интерпретатор попробует подобрать все компании к нашему студенту.
Чтобы составить запрос относительно получения стипендии студентом Поповым достаточно передать имя студента в качестве аргумента правилу stipendya . При выполнении такого запроса мной были получены ошибки:
Интерпретатор сообщает, что нет такого предиката в нашей программе. На самом деле, в программе содержится опечатка (имя функции написано неверно). После исправления ошибки и перекомпиляции программы командой [имя файла] или consult(имя файла) ошибка исправлена, получен ответ true , означающий, что студенту Попову положено получать стипендию.
Аналогично выполняется проверка получения стипендии студентом Федоровым (которому стипендия не положена, поэтому выводится false ):
Чтобы получить имена всех студентов, получающих стипендию передадим в качестве аргумента функции stipendiya анонимную переменную:
Чтобы получить минимальный средний балл, необходимый для трудоустройства в Microsoft нужно выполнить запрос company(‘Microsoft’, X) . Во время его выполнения нужная информация будет получена непосредственно из факта company(‘Microsoft’, 5) . Результат:
Чтобы проверить может ли Попов трудоустроиться в Microsoft нужно использовать предикат isAbleToWork :
Чтобы узнать организации, в которые может устроиться на работу Федоров, нужно передать имя студента в isAbleToWork , но в качестве названия компании передать анонимную переменную:
Чтобы получить имена студентов, способных устроиться в Apple, нужно наоборот передать в isAbleToWork имя компании, а вместо имени студента указать переменную без присвоенного заранее значения:
Аналогичный запрос, но с именем компании IBM нужно выполнить для поиска студентов, которые могут трудоустроиться в эту компанию. Результаты отличаются тем, что устроиться может несколько студентов. Для получения всех студентов нужно вводить точку с запятой после каждого результата:
Выводы: во время выполнения работы были получены навыки работы в среде SWI-Prolog Исследован код программы, выданный преподавателем; во время выполнения заданий получены некоторые навыки отладки программ в интерпретаторе SWI-Prolog.
Источник
Главная
ПРОЕКТ «ЧЕЛОВЕК. ЗЕМЛЯ. ВСЕЛЕННАЯ»
Инструменты пользователя
Инструменты сайта
Боковая панель
Содержание
Быстрый запуск программы в среде SWI-Prolog. Наша первая программа
Поздравляем! Вы научились работать и программировать в среде SWI-Prolog!
Разбираем подробнее вашу первую программу
Итак, из файла sokrat.pl вы загрузили следующую программу:
Разбёрем, что она делает и что означают её операторы.
Если вы не работаете в Linux, то можете перейти к следующему примеру.
Работа в SWI-Prolog в Linux
Графический интерфейс можно использовать в linux. Для этого необходимо запустить интерпретатор командой swipl и выполнить команду emacs., после чего будет запущена среда разработки. Emacs позволяет при помощи мыши открывать файлы, а затем загружать их содержимое в интерпретатор при помощи пунктов меню compile→consult selection:
После того, как исходный код загружен в интерпретатор (запуск командой swipl), в нем можно писать запросы. При изменении части программы, достаточно выполнить повторный consult selection для нее.
Обсуждение
Инструменты страницы
Вы можете оставить свои комментарии в разделе «Обсуждение».
Рекомендуем оформить подписку на новости данного раздела. Для этого нажмите на кнопку «Подписаться», расположенную справа снизу каждой страницы (знак конверта).
Источник
Настраиваем редактор исходных текстов SWI-Prolog (XPCE Emacs) для пользователя, не знакомого с клавиатурными комбинациями Emacs
Приступающие к изучению и/или работе с SWI-Prolog (http://www.swi-prolog.org/) часто сталкивается зачастую с не очень «дружелюбным интерфейсом командной строки вот в таком стиле:
Даже сумев вызвать-таки редактор исходного кода, многие затрудняются с ним работать по причине того, что клавиатурные комбинации соответствуют достаточно харизматичному и отличающемуся от других редактору Emacs.
Как это исправить?
Наберите в командной строке „help.“
Вы увидите примерно вот это:
В окне нужно выполнить пункт меню Settings/User init file… (если появится диалоговое окно с подтверждением — подтвердите создание файла):
Там нужно найти вот такую строку:
И убрать в ней символ „%“, после чего сохранить файл, вызвав меню File/Save buffer.
Затем, в первом окне спраки (SWI-Prolog Help) нужно выполнить пункт Help/XPCE (GUI) Manual.
Появится примерно вот такое окно:
В этом окне нужно выполнить пункт меню File/Edit Preferences/XPCE User Defaults (возможно также появиться подтверждающий диалог, где нужно ответить утвердительно).
В открывшемся окне нужно найти строку
И убрать в ней символ »!» в начале, после чего сохранить файл выполнив пункт меню File/Save buffer.
Затем нужно закрыть все окна и снова запустить SWI-Prolog.
В появившейся командной строке введите:
В появившемся файле наберите:
После чего нажмите Control + S, файл должен сохраниться на диск.
Из меню выберите Compile/Compile buffer.
Перейдите в консоль: наберите там main.:
Вы увидели решение квадратного уравнения.
Теперь вы знаете как создавать новые файлы (edit(file( ))., сохранять их привычной комбинацией (Control S) и даже как решать уравнения с помощью SWI-Prolog.
Источник
SWI-пролог до С# не работает
Я работаю над решением, использующим dll SbsSW.SwiPlCs для интеграции между приложением С# и исходным файлом proog .pl , однако я столкнулся с проблемой команды assert(atom) .
Мой пролог файл — это набор аэропортов и рейсов между аэропортами, во время моего полета я утверждаю, что новые аэропорты и рейсы выглядят следующим образом:
Это нормально, и я не получаю никаких сообщений об ошибках и исключений (я использовал их, но это было потому, что мои сообщения о полете /4 и в аэропорту /2 были статичными, я изменил оба на динамические в начале моего файла и ошибок не было).
Моя проблема в том, что я пытаюсь проконсультироваться с чем-то, связанным с новыми утверждениями, которые я получил во время выполнения.
Мой List list переменная должна возвращать список всех полетной ид, которые идут от from до to , и это работает с предварительно загруженными полетов (те, на мой vuelos.pl , который я называю на PlQuery.PlCall(«consult(vuelos)»); ), но я не принимаю во внимание любые мои новые рейсы, созданные во время работы, и я не могу понять, почему.
Моя ошибка состояла в двух ошибках. Во-первых, я очищал свой PlEngine каждый раз, когда выполнял запрос
То, что я сделал, чтобы исправить это, — это просто инициализировать мой PlEngine один раз в моем классе-конструкторе Class Prolog , таким образом, я могу использовать тот же PlEngine для всех моих методов. Я огляделся и, похоже, другое решение было бы использовать ? tell(‘file.pl’), append(listing(atom)), told. ? tell(‘file.pl’), append(listing(atom)), told. для сохранения файла во время выполнения, но я не знаю, может ли он испортить мои предыдущие данные, поэтому я выбрал PlEngine путь PlEngine . Он не сохраняет изменчивые данные, но отлично работает для одного сеанса Prolog. Я все еще создал метод очистки движка, который я вызываю, когда я завершаю свою программу.
Другая проблема, которую я обнаружил, заключается в том, что я попытался выполнить такие параметры assert:
Когда я должен был сделать:
PlQuery является эксклюзивным для запросов, которые возвращают переменные из того, что я мог понять, в то время как PlCall используется для простых консультаций или инструкций, которые возвращают true/false .
Источник
Предикат сортировки SWI-Prolog не работает
Я только что составил программу, выполнив следующую задачу: «Получить элементы, значения которых равны их индексам».
Это работает очень хорошо. Но есть одна проблема. Для списка [0, 3, 2, 4, 0] мой предикат index_equals_to_element возвращает [0, 2, 0].
Ладно, пусть это произойдет. Но когда я пытаюсь вывести только уникальные элементы, я получаю один и тот же список без каких-либо изменений. Пример:
Это очень странно для меня, потому что это прекрасно работает:
Почему sort не работает только со списком, созданным моим предикатом?
Ваш index_equals_to_element([0, 3, 2, 4, 0], List). не выводит [0, 2, 0] как вы утверждаете, но дает три ответа [0] , [2] и [0] :
Вы можете использовать findall чтобы получить то, что вы хотите:
Обновить. Вот что я считаю лучшей реализацией index_equals_to_element/2 :
Я предлагаю вам изучить его, используя функцию отслеживания вашей системы Prolog, набрав запрос:
Шаг за кадром до тех пор, пока не будет определено определение предиката.
Другие ответы лучше всего подходят для изучения гаек и болтов Prolog. Но здесь более сжатое (но также более простое) решение, использующее предикат findall/3 и nth0/3 более высокого порядка из library(lists) SWI-Prolog:
Редактировать:
Как отметил @Paulo Moura в комментарии, вышеупомянутый ответ эквивалентен только тем, которые предлагаются здесь, если все аргументы создаются. Т.е., если вышеупомянутое встречает свободную переменную в списке, я привяжу эту переменную к ее индексу в списке, вместо того, чтобы отклонять ее как неудовлетворительный элемент. Добавление теста для сильного равенства между индексом и элементом списка должно привести к тому, что ответ будет соответствовать:
Источник