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.

Разберем предложенную программу:

  1. предикаты company и student являются фактами (подобно предикату parent из предыдущей работы);
  2. предикат stipendya принимает имя студента, выполняет поиск студента в базе и получение его среднего балла. Затем выполняется сравнение среднего балла с константой:
    1. если сравнение проходит успешно, то предикат также завершится успешно и «снаружи» мы получим имя студента, для которого есть стипендия;
    2. если при сравнении выясняется, что балл студента меньше константы, то предикат завершается неудачей. Никакого результата (информации о студенте, с которым это случилось) «снаружи» мы при этом не получим, но будет запущен механизм поиска с возвратами (интерпретатор попробует подобрать других студентов, соответствующих нашим критериям);
    3. предикат может завершиться неудачей до выполнения сравнения — если передано имя студента, о котором нет информации в базе (мы просто не сможем получить для него средний балл);
    4. наконец, если в предикат передана анонимная переменная stipendya(Name) , то будут выведены все студенты, для которых начисляется стипендия.
  3. Предикат 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 в комментарии, вышеупомянутый ответ эквивалентен только тем, которые предлагаются здесь, если все аргументы создаются. Т.е., если вышеупомянутое встречает свободную переменную в списке, я привяжу эту переменную к ее индексу в списке, вместо того, чтобы отклонять ее как неудовлетворительный элемент. Добавление теста для сильного равенства между индексом и элементом списка должно привести к тому, что ответ будет соответствовать:

Источник

Оцените статью