- •1.1 Знакомство с интерпретатором Hugs.
- •1.2 Выполнение математических операций в интерпретаторе.
- •1.3. Простейшие генераторы списков.
- •1.4 Логические функции, функции сравнения, функции работы с перечислимыми типами данных.
- •1.5 Простейшие списочные и кортежные функции.
- •Задание на лабораторную работу №1.
- •Вариант 1.
- •Вариант 2.
- •Вариант 3.
- •Вариант 4.
- •Вариант 5.
- •Вариант 6.
- •Вариант 7.
- •Вариант 8.
- •Вариант 9.
- •Вариант 10.
- •Пример выполнения лабораторной работы 1.
- •Лабораторная работа 2. Создание простейших рекурсивных программ. Функции работы со строками и множествами. Сообщения об ошибках и преобразования типов.
- •2.1 Создание простейших рекурсивных программ.
- •2.2 Функции работы со строками и множествами.
- •2.3 Сообщения об ошибках и преобразования типов
- •Задание на лабораторную работу 2.
- •Вариант 1.
- •Вариант 2.
- •Вариант 3.
- •Вариант 4.
- •Вариант 5.
- •Вариант 6.
- •Вариант 7.
- •Вариант 8.
- •Вариант 9.
- •Вариант 10.
- •Пример выполнения работы
- •Лабораторная работа 3. Функции высших порядков.
- •Задание на лабораторную работу 3.
- •Вариант 1.
- •Вариант 2.
- •Вариант 3.
- •Вариант 4.
- •Вариант 5.
- •Вариант 6.
- •Вариант 7.
- •Вариант 8.
- •Вариант 9.
- •Вариант 10.
- •Лабораторная работа 4. Текстовые файлы. Факторизация, простые числа, разные задачи.
- •4. 1 Работа с текстовыми файлами в Haskell
- •Задание на лабораторную работу 4.
- •Вариант 1.
- •Вариант 2.
- •Вариант 3.
- •Вариант 4.
- •Вариант 5.
- •Вариант 6.
- •Вариант 7.
- •Вариант 8.
- •Вариант 9.
- •Вариант 10.
- •Лабораторная работа 5. Управление выводом в Прологе. Простейшие рекурсивные программы.
- •5.1 Факты и правила. База знаний. Запросы.
- •5.2 Управление выводом.
- •5.3 Рекурсия
- •Задание на лабораторную работу 5.
- •Вариант 1
- •Вариант 2
- •Вариант 3
- •Вариант 4
- •Вариант 5
- •Вариант 6
- •Вариант 7
- •Вариант 8
- •Вариант 9
- •Вариант 10
- •Лабораторная работа №6. Работа со списками в Прологе.
- •6.1 Списки в Прологе.
- •6.2 Алгоритмы обработки списков
- •6.3 Алгоритмы сортировки
- •Лабораторная работа № 7. Решение логических задач на Прологе.
- •Пример выполнения работы.
- •Лабораторная работа № 8.
Пример выполнения работы.
1. На донорском пункте работали Джеймс, Генри и Томас. Один был вампиром, другой - оборотнем, третий - лишь маньяком.
Сыщик из Скотланд-Ярда расследуя дело, опросил всех троих. Вот что он услышал:
ДЖЕЙМС: "Генри - вампир"
ГЕНРИ: "Либо Джеймс, либо Томас - оборотень"
ТОМАС: "На самом деле вампир - Джеймс!"
Солгал только оборотень, а остальные говорили правду. Но полицию интересовал только маньяк, которого и арестовали.
Кого же арестовала полиция?
Решение.
Будем искать решение с помощью предиката solution с тремя аргументами – первый соответствует виду Джеймса, второй Генри и третий – Томаса.
Сначала запишем в решение все возможные варианты с учетом того, что виды не совпадают:
solution(X,Y,Z):-kind(X),kind(Y),kind(Z),X<>Y,X<>Z,Y<>Z,
Теперь рассуждаем следующим образом – пусть Джеймс и Генри сказали правду, а соврал Томас, тогда добавим условия:
solution(X,Y,Z):-kind(X),kind(Y),kind(Z),X<>Y,X<>Z,Y<>Z,
Y="vampire", /*Джеймс сказал правду, что Генри вампир*/
X="werevolf", /*Генри сказал правду, что Джеймс оборотень…*/
X<>"vampire", /*Томас соврал, что Джеймс вампир*/
Z="werevolf"; /*совравший является оборотнем, значит Томас оборотень*/
kind(X),kind(Y),kind(Z),X<>Y,X<>Z,Y<>Z,
Y="vampire",
Z="werevolf", /*или Генри сказал правду, что Томас оборотень*/
X<>"vampire",
Z="werevolf".
Два варианта нам пришлось написать для реализации дизъюнкции в утверждении Генри.
Далее возможен второй вариант – врал Генри, соответствующие условия будут:
solution(X,Y,Z):-kind(X),kind(Y),kind(Z),X<>Y,X<>Z,Y<>Z,
Y="vampire",
X<>"werevolf",Z<>"werevolf",
X="vampire",
Y="werevolf".
Поскольку здесь отрицание дизъюнкции, правило получилось короче. И, наконец, последний вариант – врал Томас:
solution(X,Y,Z):-kind(X),kind(Y),kind(Z),X<>Y,X<>Z,Y<>Z,
Y<>"vampire",
X="werevolf",
X="vampire",
X="werevolf";
kind(X),kind(Y),kind(Z),X<>Y,X<>Z,Y<>Z,
Y<>"vampire",
Z="werevolf",
X="vampire",
X="werevolf".
Для ответа непосредственно на вопрос задачи, напишем последний предикат:
И получаем решение:
2. В семье пять человек: муж, жена, их сын, сестра мужа и отец жены. Их профессии - инженер, юрист, слесарь, учитель и экономист. Известно, что юрист и учитель - не кровные родственники. Слесарь младше экономиста, и оба играют в футбол за сборную своего завода. Инженер моложе учителя, но старше жены своего брата. Назовите профессии каждого.
Решение. Опишем предикаты для названий родственников и их профессий в виде фактов.
Далее, начинаем составлять соответствие, пусть переменные вида означают профессии, а - родственников. Одну из этих категорий можно задать в виде констант – присвоить им значения. Поскольку в задаче говорится об отношениях людей с определенными профессиями, то профессии и зададим как константы. На этом этапе можно убрать факты prof, они нам не понадобятся. Введены факты prof были для того, чтобы показать, с чего надо начинать решать подобные задачи. Впрочем, наличие этих фактов нам никак не помешает. Итак, начинаем писать основной предикат:
sootv(X1,Y1,X2,Y2,X3,Y3,X4,Y4,X5,Y5):-X1="engineer",X2="lawyer",X3="locksmith",X4="teacher",X5="economist",
Далее, другую категорию – родственников формируем с помощью фактов men, указывая, что у всех людей разная профессия:
sootv(X1,Y1,X2,Y2,X3,Y3,X4,Y4,X5,Y5):- X1="engineer",X2="lawyer",X3="locksmith",X4="teacher",X5="economist", men(Y1),men(Y2),men(Y3),men(Y4),men(Y5),Y1<>Y2,Y1<>Y3,Y1<>Y4, Y1<>Y5,Y2<>Y3,Y2<>Y4,Y2<>Y5,Y3<>Y4,
Y3<>Y5,Y4<>Y5,
Если запустить программу на этом этапе, у нас будет 120 вариантов решения, так как мы еще не указали дополнительных условий. Начинаем внимательно читать условия задачи: «Известно, что юрист и учитель - не кровные родственники». Добавим новый предикат для кровных родственников – relative. Очевидно, кровными родственниками будут являться пары муж-сын, жена-сын, муж-сестра и жена-отец.
Юрист у нас является родственником по имени Y2, а учитель – Y4. Добавляем в предикат sootv условия
not(relative(Y2,Y4)), not(relative(Y4,Y2)),
Заметьте, что добавить надо именно два условия, либо обойтись , например, одним первым условием, но тогда придется в предикате relative добавить строку вида
relative(X,Y):-relative(Y,X).
для учета всех пар кровных родственников.
Далее идет достаточно сложное условие «слесарь младше экономиста», сложность состоит в том, что мы не можем быть уверены насчет соотношения возрастов персонажей. Скажем, младше ли жена сестры, сын сестры, муж отца жены или наоборот? Тут лучше ввести новый предикат, означающий «старше» и задать в нем пары, относительно которых есть точная уверенность, а именно : муж и жена старше сына, отец жены старше сына – своего внука, отец старше жены.
Добавляем в sootv условие, что слесарь не старше экономиста
not(older(Y3,Y5))
Учесть, что слесарь и экономист играют в футбол, можно введя новый предикат male, скорее всего, имеется в виду, что в футбол играют только мужчины в этой семье.
Добавляем в sootv условия
male(Y3),male(Y5)
Аналогично, учтем, что инженер не старше учителя
not(older(Y4,Y1)) .
Далее сказано, что инженер старше жены своего брата ,но ведь только у одного персонажа в семье есть брат – у сестры мужа! Значит, можно смело написать
Y1="sister"
Осталось учесть последнее условие, что инженер старше жены – тут можно указать, что в этом случае жена не учитель (иначе инженер получится и младше учителя-жены и одновременно старше):
Y4<>"wife".
Окончательно, предикат sootv и цель будут выглядеть так:
После запуска получаем единственный ответ: