Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

Глазовский государственый педагогический институт им

Работа добавлена на сайт samzan.net:

Поможем написать учебную работу

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

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 6.11.2024

Федеральное агентство по образованию

ГОУ ВПО «Глазовский государственый педагогический институт  им. В.Г. Короленко»

СБОРНИК ЗАДАЧ ПО ЛОГИЧЕСКОМУ ПРОГРАММИРОВАНИЮ

Для студентов специальности «030100 – информатика»

Глазов – 2007


Сборник задач по логическому программированию/Сост. А.М. Акбашева, Р.Р. Камалов. – Глазов, ГГПИ, 2006 –
68 с.

В работе рассматриваются основные подходы к решению логических задач на языке ПРОЛОГ. Сборник задач выполнен в качестве пособия для лабораторного практикума, содержит набор вариантов заданий и методические рекомендации для их выполнения.

Составители: А.М. Акбашева, ст. преподаватель кафедры информатики,

Р.Р. Камалов, к.п.н., доцент кафедры информатики ГГПИ

Рецензенты:  В.С. Черепанов,  д.п.н., профессор

В.В. Беляев, к.ф-м.н., профессор

 


Оглавление

[1]
Часть 1. Освоение интерфейса

[2] Главное меню системы Турбо-Пролог

[3] Основные команды редактирования

[4] Использование звука и музыки

[5] Часть 2. Лабораторные работы

[6] Лабораторная работа №1. Общие сведения об языке логического программирования

[7]
Лабораторная работа №2. Арифметика. Управление логическим выводом в программах

[8]
Лабораторная работа №3. Повторение и рекурсия

[9]
Лабораторная работа №4. Применение рекурсии для обработки списков

[10]
Лабораторная работа №5. Решение логических задач.

[11]
Лабораторная работа №6. Головоломки. Игровые программы.

[12]
Лабораторная работа №7. Обработка файлов. Предикаты для работы с файлами

[13]
Лабораторная работа №8. Создание динамической базы данных. Предикаты для работы с базой данных

[14]
Лабораторная работа №9. Применение языка для решения задач ИИ. Создание экспертных систем

[15]
Литература


Введение 

Пролог – один из языков логического программирования, позволяющий использовать как традиционный процедурный подход, так и декларативный подход, то есть программировать не ход решения задачи, а ее постановку. Встроенная в Пролог машина вывода, реляционный характер языка, средства автоматического поиска позволяют использовать не только механизм вывода от цели, но и легко моделировать другие парадигмы представления знаний: семантические сети, фреймы, продукции. В прологе отсутствуют средства объектно-ориентированного программирования, однако они легко моделируются средствами самого языка.

Считается, что научиться программировать на Прологе трудно, так как он отличается от традиционных языков программирования. Однако учащиеся незнакомые ни с одним языком программирования, воспринимают Пролог не хуже, чем любой алгоритмический язык.

Целью настоящей работы является знакомство с идеями и практическое освоение приемов логического программирования студентами педагогического ВУЗа обучающихся по специальности «030100 – Информатика».

Содержание работы разделено на две части: 1 часть освоение интерфейса Пролога (может изучаться студентами самостоятельно). Теоретический материал первой часть позволяет студенту разобраться в механизме работы с окнами, рассмотреть основные приемы работы в системе Turbo Prolog 3.3, освоить команды редактирования и команды главного меню. Вторая часть — лабораторные работы. Она состоит из 9 лабораторных работ, в которых рассматриваются основные понятия и предикаты языка, а также возможности применения языка Пролог для решения логических задач, при создании экспертных систем, интерфейсов на естественном языке. Изложение сопровождается большим количеством примеров, оформленных в соответствии с правилами и синтаксисом языка. В конце каждой лабораторной работы предлагаются задания для самостоятельной работы. Представленные примеры и предлагаемые задания ориентированы на использования сисетмы программирования Turbo Prolog 3.3. В лабораторных работах реализовано более 30 примеров. Методика освоения этой части зависит от выбора преподавателя.

 


Часть 1. Освоение интерфейса

Главное меню системы Турбо-Пролог

Вся работа в рамках системы организуется при помощи различного рода меню. Главное меню, высвечиваемое в верхней части экрана имеет семь опций (команд): Files, Edit, Run, Compile, Options, Setup. Первая буква названия каждой из команд выделена при помощи увеличенной яркости с целью подсказать, что для задания команды достаточно нажать лишь первую букву ее названия.

Главное меню содержит четыре окна: окно редактора Турбо-Пролога Editor, окно диалога - Dialog, окно сообщений - Message, окно трассировки - Trase.

Верхняя строка окна редактора содержит информацию о редактируемом в этом окне файле, отражается информация о положение курсора. Надпись Indent сигнализирует о том, что включен режим  автоматического выравнивания строк, а надпись Insert- о том, что задан режим вставки.

При выборе команды Files на экране дисплея появляется специальное меню, содержащее следующие подпункты Load, Pick, New File, Save, Write to, Directory, Change dir, File Name, Edit text to Printer, OS shell, Quit

Команда Load используется для открытия уже существующего файла. Если в ответ на запрос  имени файла просто нажать клавишу Enter, то на экране в специальном окне будет высвечен перечень файлов. Теперь используя клавиши управления курсором можно выбрать интересующий файл и нажать клавишу Enter. Если же вы решили набрать имя файла с клавиатуры, нет необходимости указывать его расширение, так как по умолчанию считается, что файл имеет расширение PRO.

Команда Pick используется для открытия последних редактируемых файлов.

Команда New file применяется для создания нового программного файла. Если в окне редактора находится какой-либо другой, система запросит подтверждения, если нажать Y, то окно очистится.

Команда Save, необходима для сохранения программы.

Команда Write to  также сохраняет программу, но запрашивает имя для файла.

Команда Directory выбирается для просмотра каталога файлов какой-либо директории. На экране появится окно для ввода маски необходимых файлов. По умолчанию стоит маска *.PRO, можно оставить эту маску, а можно ввести свою. После того, как вы нажмете клавишу Enter, в окне появятся имена всех файлов, удовлетворяющие заданной маске.

Команда Change dir –смена директории. Если вы хотите просмотреть файлы другой директории, нужно указать путь к этому каталогу, используя эту команду.

Команда File Name используется для присвоения нового имени находящемуся в памяти рабочему файлу.

Команда Edit text to Printer  применяется для печати файла.

Команда OS shell –временно передает управление DOS. Для возврата в систему необходимо набрать команду EXIT.

Команда Quit осуществляет выход из программы, также можно использовать сочетание Alt+X.

При выборе команды Edit происходит переход в редактор Турбо-Пролога. В окне редактора при этом появляется курсор, так что вы можете начать вводить вашу программу или же редактировать ее. Вернуться в главное меню можно нажатием на клавиш Esc или F10.

Запуск программы осуществляется выбором пункта Run. Трансляция задается автоматически, т.е. нет необходимости прибегать к помощи специальной команды – Compile. Если программа содержит ошибку, то система выдает краткое сообщение об ошибке и помещает курсор на ту позицию текста программы, где эта ошибка была обнаружена. После исправления ошибки нужно нажать функциональную клавишу F10 для продолжения работы.

По умолчанию команда Compile хранит в памяти(Memory) объектный код программы, задание опции OBJ file позволяет создать объектный файл для дальнейшего совместного редактирования с другими объектными файлами, а выбор опции EXE file –автономный файл.

Различные опции команды Setup предназначены для создания вашего собственного варианта настройки системы Турбо-Пролог. При выборе данной команды появится меню со следующими опциями:

Info содержит информацию о версии системы и размере используемой памяти;

Colors предназначена для изменения цветов переднего плана и фона;

Window size предназначена для настройки размеров окон;

Directories  предназначена для задания имен директорий, к которым система будет обращаться по умолчанию. Таковыми являются .PRO directory (директория исходных текстов программ, т.е. файлов с расширением PRO), .OBJ directory (директория объектных текстов программ, т.е. файлов с расширением OBJ), .EXЕ directory (директория выполнимых  файлов);

Miscellaneous предназначена для настройки расширенного графического адаптера IBM EGA и для установки размера стека. По умолчанию длина стека равна 4000, длину можно задавать в интервале от 600 до 4000;

Load CFG file необходима для загрузки новой  конфигурации окон с диска;

Save CFG file позволяет сохранить текущее расположение окон для последующего его использования. Если ввести имя PROLOG.SYS и записать файл в директорию системных файлов Турбо-Пролога, то данная конфигурация в дальнейшем станет загружаться по умолчанию.

Основные команды редактирования

Управление курсором.

Передвижение курсора к определенной позиции достигается пролистыванием  экранных страниц вверх или вниз и смещением его по экрану в пределах выбранной страницы. Для страничного пролистывания верх или вниз можно использовать клавиши  PgUp(вверх) и PgDn(вниз), либо комбинациями клавиш Ctrl+R и  Ctrl+C.

Для позиционирования курсора в пределах экранной страницы используются стрелки, помещенные в правой части клавиатуры. Когда курсор достигает верхней или нижней части экрана, то он начинает действовать в режиме скроллинга. Для смещения курсора на одну строку вверх или вниз можно использовать комбинации Ctrl+E и  Ctrl+X.

Комбинации Ctrl+F сдвигает курсор на одно “слово” вправо, Ctrl+D – на один интервал вправо. Ctrl+А  сдвигает курсор на одно “слово” влево, Ctrl+S – на один интервал влево.

Ctrl+Ноme возвращает курсор на начало текста на экране, а при нажатии  Ctrl+ End курсор попадает в его конец.

Сдвинуть курсор в начало программы можно при помощи Ctrl+QR или Ctrl+PgUp, в  конец программы Ctrl+QС или Ctrl+PgDn.

Начав работать, вы заметите, что строка статуса всегда показывает текущее положение курсора( номер строки файла и номер колонки, где он находится). Поместить курсор в любую строку программы можно при помощи сочетания Ctrl и функциональной клавиши F2.

Удаление текста.

Для того чтобы удалить слово, нужно установить курсор  в начало слова и нажать Ctrl+Т. Для удаления одного символа используется комбинация Ctrl+G или клавиша Delete.

Удаление строки достигается посредством размещения курсора в произвольной колонке строки и нажатия любой из двух комбинаций Ctrl+Y или Ctrl+Backspase.

Выбор режима вставки или режима замены

Редактор текстов работает в одном из двух режимов: либо в режиме вставки, либо в режиме замены. Слова Insert(вставка) или Owerwrite(замена) в строке статуса информируе, в каком режиме находится редактор в настоящий момент. Для переключения режима нужно нажать клавишу Insert или же комбинацию Ctrl+V.

Автоматическое выравнивание.

Режим автоматического выравнивания, задаваемый по умолчанию, обозначается на экране надписью Indent в строке статуса. Для отмены этого режима нужно нажать комбинацию клавиш Ctrl+QI. Надпись Indent при этом исчезнет. Возврат к режиму автоматического выравнивания осуществляется при помощи той же комбинации.

При редактировании уже существующей программы автоматическое выравнивание функционирует только при включенном режиме вставки.

Копирование, удаление фрагмента текста.

Поместите курсор в начало нужного фрагмента и нажмите комбинацию Ctrl+K+B, затем переведите курсор в конец строки и отметьте конец копируемого фрагмента нажатием комбинации Ctrl+K+K. Теперь весь отмеченный фрагмент будет выделен на экране. Установите курсор в необходимое место  и нажмите комбинацию Ctrl+K+С.

Выделение исчезнет, если нажать комбинацию Ctrl+K+Н. Действие этой команды не зависит от положения курсора.

Удалить выделенный фрагмент можно сочетанием Ctrl+K+Y.

Использование подсказки.

Для получения полного перечня команд редактора и другой полезной информации нужно в режиме Edit главного меню нажать функциональную клавишу F1.

Использование предикатов для работы с окнами

В систему программирования Турбо-Пролог включено пять предикатов, позволяющих программе управлять окнами различных размеров. Это предикаты makewindow, shiftwindow, removewindow, clearwindow и gotowindow. С их помощью можно создавать несколько окон, выполнять ввод и вывод в определенные окна и устанавливать атрибуты окон.

Создание окон предикатом makewindow.

Предикат makewindow является основой всех операций над окнами  в Турбо-Прологе. Его синтаксическая форма:

makewindow(Window_number, Screen_attribute, Frame_attribute, Frame_string, Starting_row, Starting_column, Window_height, Window_width)

Значения восьми параметров определяют характеристики окна.

Параметр Window_number, целое число, идентифицирует окно в программе. Это число используется в качестве ссылки предикатом gotowindow и др.

Целочисленное значение, присвоенное аргументу Screen_attribute, определяет цвета символов и фона. Выбираемые значения атрибута зависят от того, какой монитор используется цветной или монохромный.

Целочисленные значения Screen_attribute задают комбинацию цветов текста и фона. Для монохромных мониторов эти значения приведены табл. 1. Значения атрибутов экрана для цветного графического адаптера приведены в табл. 2.

Таблица 1.

Атрибуты цвета

Цвет текста                                                                                                                      

Цвет фона                                                                                                                     

Screen_attribute

Примечание

Черный

Черный

0   

Пустой экран

Белый

Черный

7         

Позитивное изображение

Черный                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            

Белый

112  

Негативное изображение

Таблица 2.

Соответствие между значением атрибута, цветом текста и цветом фона для окон Турбо-Пролога.

Цвет текста

Значение атрибута

Цвет фона

Значение атрибута

Черный

0

Черный

0

Синий

1

Синий

16

Зеленый

2

Зеленый

32

Голубой

3

Голубой

48

Красный

4

Красный

64

Фиолетовый

5

Фиолетовый

80

Коричневый

6

Коричневый

96

Белый

7

Белый

112

Серый

8

Светло-синий

9

Светло-зеленый

10

Светло-голубой

11

Светло-красный

12

Светло-голубой

13

Желтый

14

Интенсивно-белый

15

Наряду с указанным существуют три необязательных атрибута, задание которых определяет вывод символов с подчеркиванием, изображение с высоким разрешением и вывод мерцающих символов. Вывод символов с подчеркиванием реализуется, если к значению аргумента Screen_attribute добавить 1. Для получения изображения с высоким разрешением, нужно к основному значению атрибута экрана добавить 8. Символы будут мерцающими, если к значению атрибута экрана добавить 128.

Чтобы вычислить значение Screen_attribute для различных комбинаций цветов, прежде всего, выберите необходимый цвет текста и цвет фона. Затем сложите соответствующие значения атрибутов. Если вы хотите, чтобы символы мерцали, прибавьте к результирующему значению 128. Вычисленное значение используется как второй аргумент в предикате makewindow, т.е. Screen_attribute.

Чтобы создать окно с белыми символами на черном фоне, сложите 7 (белый текст) и 0 (черный фон), результат будет 7.

Аргумент Frame_attribute предиката makewindow есть целое число, значение которого определяет рамку окна. Если значение атрибута - 0, окно не имеет видимой границы. Другие значения определяют рамку окна с параметрами, указанными в табл. 3.

Часть значений атрибута рамки окна задает ее цвет. Это делается аналогично заданию значения атрибута экрана. Если задается мерцающая граница, то она всегда будет белой, с мерцающей тонкой линией (в середине границы), имеющей указанный цвет.

Аргумент Frame_string задает метку окна. Например, меткой окна может быть "Главное Меню", "Окно Вывода". Строка, задаваемая в качестве атрибута Frame_string, будет размещена в центре верхней линии рамки окна. Значение метки окна также может быть не определено, что соответствует отсутствию метки. В этом случае вводится аргумент, состоящий из двух последовательных знаков кавычки.

Таблица 3.

Значение атрибута, определяющего цвет рамки окна в Турбо-Прологе.

Значение атрибута

Вид рамки окна

0

Нет рамки

1

Синяя рамка

2

Зеленая рамка

3

Светло-синяя рамка

4

Красная рамка

5

Фиолетовая рамка

6

Желтая рамка

7

Белая рамка

8

Коричневая рамка

-1

Мерцающая белая рамка

-2

Мерцающая желтая рамка

-3

Мерцающая фиолетовая рамка

-4

Мерцающая красная рамка

-5

Мерцающая светло-синяя рамка

-6

Мерцающая светло-зеленая рамка

-7

Мерцающая синяя рамка

-8

Мерцающая серая рамка

Аргумент Starting_row есть целое число, определяющее верхнюю строку (линию) создаваемого окна. Максимальное количество строк, умещающихся на экране, 25. Значение 4 указывает, что окно начинается с четвертой строки. Нумерация начинается с 0.

Аргумент Starting_column указывает крайний левый столбец окна. Значения аргумента изменяются от 0 до 79.

Аргумент Window_height определяет количество строк, занимаемых создаваемым окном.

Аргумент Window_width указывает число столбцов, занимаемых окном.

Предикат shiftwindow используется для смены текущего окна (переключения). Его форма:  shiftwindow(Window_number).

Параметр window_number является целым числом, приписываемым окну при его создании.

В то же время Турбо-Пролог "помнит" предыдущие окна и их атрибуты. Например, если окно 3 имеет такие атрибуты, что оно будет перекрывать текущее окно (окно 4), то выполнение предиката shiftwindow (3) вызовет появление окна 3, в которое вложено окно 4. Информация из окна 4, частично закрытая окном 3, сохраняется и появится на экране, когда произойдет переключение и окно 4 вновь станет текущим.

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

Этот предикат выполняется быстрее, чем shiftwindow, и поэтому его следует использовать для переключения между окнами, содержащими большое количество текста.

Предикат clearwindow. Данный предикат удаляет из текущего окна все текстовые и графические изображения. Предикат не имеет аргументов. Окно и рамка окна, если она имеется, не разрушаются. Окно целиком закрашивается соответствующим цветом фона.

Предикат removewindow удаляет текущее окно с экрана. Предикат аргументов не имеет. Все текстовые и графические изображения, находящиеся в окне, также удаляются. Если за данным окном находится другое окно, то это окно и его содержимое становятся видимыми. Если удаляется последнее из заданных окон, на экране появляется то изображение, которое было на нем до создания окон.

Использование окон для ввода и вывода

С любым текущим окном работают стандартные предикаты ввода и вывода – readln,readint,readchar - также.

По умолчанию, курсор расположен в верхнем левом углу окна. Используя предикат cursor и помещать курсор в любую позицию текущего окна. Этот предикат имеет вид: cursor (Row_number, Col_number ).

Аргументы Row_number и Col_number являются целыми числами, задающими номера строки и столбца, по отношению к верхней строке и крайнему левому столбцу экрана. Строки и столбцы нумеруются, начиная с нуля: предикат cursor(0,0) обеспечивает вывод текста, начиная с верхнего левого угла экрана.

Например, следующие предикаты могут быть использованы для вывода сообщения в центре экрана.

makewindow( 1,7,7,"", 1,1, 8,28),

cursor(4,12),

write("Доброе утро!").

Пример 1.

Программа 1. Работа с окнами

Predicates

start

run(integer)

do_sums

set_up_windows

clear_windows

Clauses

start:- set_up_windows, do_sums.

set_up_windows :-

 makewindow(l, 7, 7, “”, 0, 0, 25, 80),

 makewindow( 1, 7, 7, "Left operand", 2, 5, 5, 25),

 makewindow(2, 7, 7,"", 2, 35, 5, 10),

 nl, write(" PLUS"),

 makewindow(2, 7, 7, "Right operand", 2, 50, 5, 25),

 makewindow(3, 7, 7, "Gives", 10, 27, 5, 25),

 makewindow(4, 7, 7,"", 17, 22, 5, 35).

do_sums :- run(_), clear_windows, do_sums.

run(Z) :-

 shiftwindow(l),

 cursor(2, 1), readint(X),

 shiftwindow(2),

 cursor(2, 10), readint(Y),

 shiftwindow(3), Z=X+Y, cursor(2, 10), write(Z),

 shiftwindow(4),

 write(" Please press the space bar"),

 readchar(_).

Clear_windows :-

 shiftwindow(l), clearwindow,

 shiftwindow(2), clearwindow,

 shiftwindow(3), clearwindow,

 shiftwindow(4), clearwindow.

Использование звука и музыки

Пролог поддерживает два предиката генерации звука: sound и beep. Предикат beep генерирует звук высокой частоты. Он не имеет параметров. Правило, генерирующее три звуковых сигнала, имеет вид:

beep:- beep, beep, beep.

Предикат sound имеет вид: sound(Duration, Frequency). Первый параметр задает продолжительность звукового сигнала в сотых долях секунды, второй-частоту генерируемого звука.

Таблица 4.

Работа со звуком

Нота

До

До

диез

Ре

Ре

диез

Ми

Фа

Фа

диез

Соль

Соль

диез

Ля

Ля диез

Си

До

Частота

262

278

294

302

330

350

370

392

416

440

466

494

524

Рассмотрим программу обучения сложению, демонстрирующую возможности пролог управления окнами и звуком.

Программа 2. Тренажер для обучения сложению

Predicates

gen_rand_num(integer)

say_good_work

say_more_work

test_and_reward(integer, integer)

make_exercise_set(integer)

do_cal

Goal

do_cal.

Clauses

do_cal:-

 makewindow(1,7,7, “Тренажер для обучения сложению”, 2,20,20,34),

 nl,

 write(“Вашему вниманию предлагаем упражнения для выполнения”),

 make_exercise_set(3),

 nl, write(“Желаем удачи! Пока!”),

 nl, write(“Нажмите на любую клавишу”),

 readchar(_),

 removewindow.

make_exercise_set(0):-!.

make_exercise_set(Count):-

 gen_rand_num(A),

 nl, write(“1-е число ”,A), nl,

 gen_rand_num(B),

 nl, write(“2-е число ”,B), nl,

 C=A+B,

 write(“Чему равна сумма?”), nl,

 readint(U),

 test_and_reward(C,U),

 Newcount=Count-1,

 make_ exercise_set(NewCount).

gen_rand_num(X):-random(Y), X=Y*5+1.

test_and_reward(C,C):-say_good_work,!.

test_and_reward(_,_):-say_more_work.

say_good_work:-

 makewindow(2,7,7, “Хорошая работа!”, 12, 40, 8, 30), nl,

 write(“Вы правы”), nl, nl,

 write(“Музыка для победителя!”),nl,nl,

 sound(4, 262), sound(4, 350),

 sound(4, 440), sound(8, 516),

 sound(4, 440), sound(112, 516),

 nl, nl, write(“Нажмите на любую клавишу”),

 readchar(_),

 removewindow.

say_more_work:-

 makewindow(3,7,7, “Продолжим!”, 14, 6, 7, 28), nl,

 write(“Вам нужно поработать ещё”), nl, nl,

 beep, beep, beep,

 write(“Нажмите на любую клавишу”),

 readchar(_),

 removewindow.

Правило make_exercise_set задает три контрольных вопроса. Для каждого вопроса правилом gen_rand_num генерируется два случайных целых числа в диапазоне от 1 до 5, эти числа выводятся на экран, затем предлагается ввести ответ, предикат test_and_reward оценивает ответ пользователя.

Задание. Усовершенствуйте программу. Предложите пользователю выбрать 1 из 4 тренажеров и проверить его знания арифметических операций, оценив его способности по 5-бальной шкале.


Часть 2. Лабораторные работы 

Лабораторная работа №1. Общие сведения об языке логического программирования

Пример 1. Наша первая Пролог программа будет содержать информацию о военнослужащих некоторого воинского подразделения и их званиях: “Павлов генерал”, “Сабо полковник”, “Денисов капитан”, “Матвеев капитан”, “Кулёмин сержант”, “Николаев сержант”. Сформулировать на Прологе следующие вопросы: 1) Павлов генерал? 2) Кто является полковником? 3)Кем является Денисов? 4)В подразделение есть военный в звание сержанта? 5) В подразделение есть военный в звание подполковника? 6) Вывести военных, имеющих одинаковые звания.

В программе каждого военного мы представим предикатом military размерности 2, каждый компонент- атом, первый представляет фамилию, а второй – его звание.

Программа 3. База данных «Военная часть»

Domains

 s=symbol

Predicates

military(s,s)

Clauses

military(pavlov, general).

military(sabo, polkovnik).

military(denisov, kapitan).

military(matveev, kapitan).

military(kulemin, serzhant).

military(nikolaev, serzhant).

Сформулируем запросы:

1) ? military(pavlov, general)

      Ответ: yes

2) ? military(X, polkovnik)

      Ответ: X= sabo

3) ? military(denisov, X)

      Ответ: X= kapitan

4) ? military(_, serzhant)      

      Ответ: yes

5)? military(_, podpolkovnik)

      Ответ: no

6) ? military(X,Y), military(Z, Y), X<>Z

      Ответ: X= denisov Z= matveev Y= kapitan

                  X= kulemin Z= nikolaev Y= serzhant

Пример 2. Данные о крупных реках России сведены в таблицу:

Таблица 5.

Данные о крупных реках России

Название реки

Длина, км

Годовой сток, км3

Площадь бассейна, тыс. км2

Истоки

Куда впадает

Амур

4416

350

1855

Яблоневый хребет

Татарский пролив

Лена

4400

488

2490

Байкальский хребет

Море Лаптевых

Обь

4070

400

2990

Предгорья Алтая

Карское море

Иртыш

4248

323

1643

Китай

Обь

Енисей

3487

600

2580

Восточный Саян

Карское море

Волга

3530

255

1360

Валдайская возвышенность

Каспийское море

Колыма

2129

44

643

Хребет Черского

Восточносибирское море

Урал

2428

54

231

Южный Урал

Каспийское море

Дон

2200

45

504

Среднерусская возвышенность

Азовское море

Кама

1805

130

507

Верхне — Камская возвышенность

Волга

Печора

1809

130

322

Северный Урал

Баренцево море

Ангара

1779

62

1039

Байкал

Енисей

Селенга

1024

14

447

Монголия

Байкал

Кубань

870

11

58

Кавказ

Азовское море

Составить базу данных и ответить на следующие вопросы:

1) Определить реки, впадающие в Азовское море.

2) Определить реки, исток которых находится на Валдайской возвышенности?

3) Какие реки короче Камы?

4) Какие реки длиннее Иртыша?

5) Как задать вопрос, определяющий все данные о реке Кама?

Программа 4. База данных «Реки России»

Domains

S=symbol

N=integer

Predicates

reka(S,N,N,N,S,S)

Clauses

reka(amur, 4416, 350, 1855,yablonevi_hrebet,tatar_proliv).

reka(lena, 4400, 488, 2490, baikal_hrebet, more_laptevih).

reka(ob, 4070, 400, 2990, altai, more_karskoe).

reka(irtish, 4248, 323, 1643, kitai, ob).

reka(enisei, 3487, 600, 2580, vost_cain, more_karskoe).

reka(volga, 3530, 255, 1360, valdais_vozvishennost, more_kaspi).

reka(kolima, 2129, 44, 643, hrebet_cherskogo, vost_sibir_more).

reka(ural, 2428, 54, 231, yuzhni_ural, more_kaspi).

reka(don, 2200, 45, 504, sredn_rus_vozvvishennost, more_azov).

reka(kama, 1805, 130, 507, verhne_kamsk_ vozvvishennost, volga).

reka(pechora, 1809, 130, 322, sever_ural, barenzevo_more).

reka(angara, 1779, 62, 1039, baikal, enisei).

reka(selenga, 1024, 14, 447, mongolia, baikal).

reka(kuban, 870, 11, 58, kavkaz, more_azov).

Запросы:

reka(X, _, _, _, _, more_azov)

reka(X, _, _, _, valdais_vozvishennost,_)

reka(X, Y, _, _, _, _), reka(lena, Z, _, _, _, _), Y<Z

reka(X, Y, _, _, _, _), reka(irtish, Z, _, _, _, _), Y>Z

reka(kama, A,B,C,D,E)

Пример 3. Известно, что Лене нравится теннис, Денису нравится футбол, Борису – бейсбол, Эдику – плавание, Марку нравится теннис, а Фёдору то, что нравится Борису. Записать факты на Прологе и ответить на вопросы: 1)Кому нравится теннис? 2) Что нравится Федору? 3)Кто занимается одинаковыми видами спорта?

Программа 5. База знаний «Предпочтения»

Predicates

likes(symbol,symbol)

Clauses

likes(lenа, tennis).

likes(denis, football).

likes(boris, baseball).

likes(edic, swimming).

likes(mark, tennis).

likes(fedor, Activity):- likes(boris, Activity).

/* Activity играет роль переменной*/

Запросы

1) ?   likes(X, tennis)

Ответ:

X= lenа

X= mark

2) ?   likes(fedor, X)

Ответ:

X= baseball

3) ?   likes(X, T), likes(Y, T)

Ответ:

X= lenа Y= mark T= tennis

X= mark Y= lenа T= tennis

X= boris Y= fedor T= baseball

X= fedor Y= boris T= baseball

Пример 4. Лена, Анна, Денис и Борис-люди, лада и нисан - автомобили, Лене нравится лада, Анне - пицца, Денису - футбол, а Борис - Мерседес, Ваське - рыбка. Пицца, лада, мерседес продаются. Человек может купить машину, если она продается, и она ему нравится. Сформулировать на прологе вопросы: 1)Какую машину может купить Лена? 2) Кто-нибудь может купить мерседес? 3) какие машины продаются, и ответить на них.

Программа 6. База знаний «Предпочтения и возможности»

Domains

s=symbol

Predicates

human(s)

car(s)

likes(s,s)

can_by(s,s)

cells(s)

Clauses

human( lena ).

human( anna ).

human( denis ).

human( boris ).

car( lada ).

car( nissan ).

likes( lena, lada ).

likes( anna, pizza ).

likes( denis, football ).

likes( boris, mersedes ).

likes( vasya, ribka ).

cells(pizza).

cells(lada).

cells(mersedes).

can_by(X,Y):-human(X), car(Y), likes(X,Y), cells(Y).

Запросы:

1) can_by(lena, X)

X=lada

2) can_by(_,mersedes)

no

3)  car(X),cells(X)

X=lada

Пример 5. Программа иллюстрирует различные способы ввода данных.

Программа 7. Ввод данных

Predicates

vvod_int

vvod_ch

vvod_s

Clauses

vvod_int:- readint(N1), readint(N2), N=N1+N2, write(N).

vvod_ch:-  readchar(N1), readchar(N2), N=N1+N2, write(N).

vvod_s:-   readln(N1), readln(N2), concat(N1,N2,N), write(N).

Пример 6. Вывести в каждой строке сообщения: Леонард отец Катерины, Карл  отец Джейсона, Карл  отец Марины.

Программа 8. База знаний «Семья»

Domains

name = symbol

Predicates

father(name, name)

everybody

clauses

father(leonard, katherine).

father(carl, jason).

father(carl, marinа).

everybody :-

 father(X, Y),

 write(X, " is ", Y, "s father\n"),

 fail.

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

Проверьте работу программы с и без использования предиката fail.

Отрицание задается с помощью предиката not.

Пример 7. У нас есть информация о странах-партнерах Европы, имеющих общую границу. Предположим, нас интересуют какие страны-партнеры не имеют общей границы.

Программа 9. База знаний «Страны Европы»

Domains

country=symbol

Predicates

euro_pair(country, country)

border(country, country)

find_non_border_pair

Clauses

euro_pair(France, Germany).

euro_pair(France, Spain).

euro_pair(France, Italy).

euro_pair(Germany, Spain).

euro_pair(Germany, Italy).

euro_pair(Spain”, Italy).

border(France, Germany).

border(France, Spain”).

border (France, Italy).

find_non_border_pair:-

 euro_pair(X,Y),

 not(border(X,Y)),

 write(X,”  – “,Y),fail,nl.

Goal

 find_non_border_pair

Результатом запроса будет ответ

Germany - Spain. Germany - Italy. Spain - Italy.

Пример 8. Использование составных объектов

Программа 10. База данных «Коллекция»(Вариант 1)

Domains

personal_library=book(title, author, publisher, year)

collector, title, author, publisher=symbol

year=integer

Predicates

collection(collector, personal_library)

Clauses

collection(ivanov, book(Zolushka, Denis Tarakanov, Dinamo, 2003)).

collection(petrov, book(Maslenniza, Anna Zimina, Zenit, 2005)).

collection( petrov, book(Repka,Irina Larina, Mir, 1999)).

/*Демонстрация двухуровневого составного объекта*/

Программа 11. База данных «Коллекция»(Вариант 2)

Domains

personal_library=book(title, author, publiсation)

publiсation= publiсation (publisher, year)

collector, title, author, publisher =symbol

year=integer

Predicates

collection(collector, personal_library)

Clauses

collection(ivanov,book(Zolushka,Den Taran, publiсation (Dina, 2003))).

collection(petrov,book(Maslenniza,Anna Zima,publiсation(Zenit,2005))).

collection( petrov, book(Repka,Irina Larina,publiсation (Mir, 1999))).

/*Демонстрация использования конструкций альтернативных доменов*/

Программа 12. База знаний «Клуб по интересам»

Domains

thing=misc_ thing (whatever);

 book(author, title);

 record(artist, album, type)

person, whatever, title, author,artist, album, type =symbol

Predicates

owns(person, thing)

show_misc_things

show_books

show_records

Clauses

owns (Ivanov, misc_things(sports car)).

owns (Petrov, misc_things(motor cycle)).

owns (Smirnov, misc_things(piano)).

owns (“Ivanov”, book (James A.Mishener,Space)).

owns (“Petrov”, book (Frank Herbert, Dune)).

owns (“Sidorov”, book (J.R.R. Tolkein,Return of the Ring)).

owns (Ivanov, record (Elton John, Ice Fair, popular)).

owns (“Petrov”, record(Michael Jackson, We are the World,popular)).

owns (“Sidorov”, record (Madonna,Madonna, popular)).

show_misc_things:- owns (X, misc_things(Y)),write( X, “ ”,Y), nl, fail.

show_books:- owns (X, book (_,Y)),write( X, “ ”,Y), nl, fail.

show_records:- owns (X, record (_,Y,_)),write( X, “ ”,Y), nl, fail.

Задания для самостоятельной работы

  1.  Дана база данных “Родители и дети”:

родитель(полина, борис), родитель(анатолий, борис), родитель(анатолий, лиза), родитель(борис, катя), родитель(борис, валентина), родитель(полина, евгений).

Сформулировать вопросы на Прологе: Кто является родителем Кати? Есть ли у Лизы ребенок? Кто дети Бориса? Кто чей родитель?

  1.  Дана база данных “Теремок”:

живет (муха, горюха), живет(комар, пискун), живет(мышка, погрызуха), живет(лягушка, квакушка), живет(заюнок, кривоног),

живет( лиса, краса), живет(волк, хватыш), не_живет(медведь, пригнетыш).

Указать ответы на следующие вопросы:

?-живет(мышка, погрызуха). ? -живет(волк, X).

?-живет(Х, кривоног). ?-не_живет(М,P).

Сформулировать вопросы на Прологе: Живет ли лягушка в теремке? Какое прозвище у лисы? Кто имеет прозвище горюха? Какой следует задать вопрос, чтобы узнать обитателей теремка (без прозвищ)?

  1.  База данных “Рождение и хобби друзей”:

рождение(иванова, лена, 22, июнь, 1971), рождение(петров, сергей, 25, октябрь, 1973), рождение(сидорова, оля, 1, декабрь, 1974), любит(иванова, лена, книги), любит(иванова, лена, танцы), любит(петров, сергей, видео), любит(сидорова, оля, кино).

Сформулировать вопросы на Прологе: Кто родился в 1971 году? Кто родился в октябре? Кто любит книги? Кто любит и книги и танцы?

  1.  База данных “Колобок”: ушел(колобок,дедушка), ушел(колобок, бабушка), ушел(колобок, заяц), ушел(колобок, волк), ушел(колобок, медведь), не_ушел(колобок, лиса).

Сформулировать вопросы на Прологе: Кто ушел от волка? Кто не ушел от лисы? Кто ушел от волка и от бабушки? Какой следует задать вопрос, чтобы узнать всех персонажей сказки?

  1.  База данных “Распорядок дня”:

занятие(0, 7, сон), занятие(7, 8, завтрак), занятие(8, 13, школа), занятие(13, 14,обед), занятие(14, 19, свобода), занятие(19, 20, ужин), занятие(20, 23, отдых), занятие(23, 24, сон).

Сформулировать вопросы на Прологе: Когда бывает обед? Что бывает между 14 и 19 часами? Когда бывает сон? (сколько будет решений?)

  1.  Построить базу данных “Важнейшие события Древнего Мира”  на основе установленных фактов, произошедших с 31 по 6 век до нашей эры.

Каждый факт приводить в виде событие(Х,Y,Z), где X — название государства, где произошло событие,     Y - в каком веке произошло событие, Z — какое произошло событие.

В 31-м веке до нашей эры возникли первые города-государства. Единое государство в Египте образовалось в 30 веке до нашей эры. В 27 веке до нашей эры в Индии появились первые древнейшие города, а в Египте построена пирамида Хеопса. Первые греческие государства появились в 18 веке до нашей эры. В этом же веке в Египте произошло крупное восстание бедняков и рабов. В 15 веке до нашей эры появились первые государства в Китае. Тутмос III правил в Египте в 15 веке до нашей эры. Греция вела троянскую войну в 13 веке до нашей эры. Вторжение борийских племен в Грецию произошло в 11 веке до нашей эры. В 8 веке до нашей эры был основан город Рим. Олимпийские игры стали проводиться в Греции в 8 веке до нашей эры. В 6 веке до нашей эры в Риме была установлена республика, а в Греции произошли реформы Солона. В этом же веке персы взяли Вавилон в Междуречье и завоевали Египет.

  1.  Составить 3 запроса к этой базе данных.
  2.  Какие события произошли в период с 15 до 7 в. до н.э.
    1.  В таблице даны некоторые характеристики движения планет Солнечной системы(числовые величины округлены):

Таблица 6.

Характеристики движения планет солнечной системы

Планета

Расстояние до Солнца (у.е.)

Период обращения

Средние солнечные сутки

Меркурий

39

88 суток

176 суток

Венера

72

225 суток

117 суток

Земля

100

365 суток

24 часа

Марс

152

687 суток

25 часов

Юпитер

520

12 лет

10 часов

Сатурн

954

29 лет

10 часов

Уран

1920

84 года

24 часа

Нептун

3010

165 лет

22 часа

Плутон

3950

247 лет

6 суток

Составить базу данных, учитывая измерение по некоторым параметрам в разных еденицах.

Ответить на вопросы: Какие планеты ближе к Солнцу, чем Земля? Какие планеты дальше от Солнца, чем Земля? На каких планетах солнечные сутки меньше, чем земные? На каких планетах период обращения измеряется в годах?

  1.  Построить базу знаний “Рабочая смена”:

Мария работает в дневную смену. Сергей работает в вечернюю смену. Борис работает в вечернюю смену. Валентина работает в вечернюю смену.  Два служащих знают друг друга, если они работают в одну смену. Определить: Знает ли Сергей Бориса? Кого знает Валентина? Кого знает Мария?

  1.  Даны результаты сдачи экзаменов для группы из пяти учеников:

Таблица 7.

Успеваемость

Фамилия

Алгебра

Геометрия

История

Бобров

5

3

2

Вяткин

5

5

5

Кротов

2

3

3

Соснин

4

4

4

Вавилов

4

2

1

Построить базу знаний о результатах экзаменов, определив в ней следующие правила:

отличник - человек, у которого по всем предметам пятерки;

двоечник - есть хотя бы одна двойка;

математик - по алгебре и по геометрии учится на 4 и 5;

введите предикаты алгебра, геометрия, история  для определения оценки Y для ученика X.

Получить ответы на следующие вопросы: Является ли Вяткин отличником? Определить всех отличников. Является ли Соснин математиком? Определить всех неуспевающих по истории.

  1.  Сформировать базу знаний Квартет из следующих фактов и правил:

Мартышка играет на скрипке. Осел играет на альте. Козел играет на виолончели. Мишка играет на контрабасе. Четверо музыкантов X,Y,Z и W могут образовать квартет, если один из них играет на скрипке, другой — на альте, третий — на виолончели и четвертый — на контрабасе.

Ответить на вопросы: Кто играет на альте? На чем играет мартышка? Образуют ли квартет Мартышка, Осел, Козел и Мишка? Кто из музыкантов данной базы знаний может образовать квартет?

  1.  База знаний Воинская служба:

возраст(борис ,18), возраст(андрей, 17), возраст(михаил,18), возраст(анна,18), возраст(юлия ,17), мужчина(андрей), мужчина(борис), мужчина(михаил), женщина(анна), женщина(юлия).

Определить правило подлежит призыву, не_подлежит_призыву.

Сформулировать вопросы: Кто подлежит призыву? Подлежит ли призыву Анна?

  1.  База знаний "Семья”:

мать(екатерина, юлия),  мать(екатерина, мария),  мать(анна, екатерина), отец(петр, юлия), отец(виктор,петр), отец(андрей, екатерина).

Дополните базу данных предикатом мужчина, женщина. Определите правила дед, бабушка, внук, внучка, тетя, дядя.

Сформулировать вопросы на Прологе:

Кто является ребенком Екатерины и Петра? Кто является дедом Юлии? Кто является бабкой Юлии?

  1.  Построить базу знаний и сформулировать к ней вопросы, основываясь на следующих утверждениях: Резвый - это собака. Рекс-это собака. Белка – это кошка. Быстрая - это лошадь. Резвый - черная. Белка - белая. Рекс -рыжая. Быстрая - белая. Домашние животные - это собака или кошка. Животные – это либо лошадь, либо домашние животные. Том владеет тем, кто собака и не черного цвета. Кейт владеет тем, кто либо черного цвета, либо лошадь.
  2.  Построить базу знаний. Муська — коричневая кошка, Стрелка — черная кошка, Мурка — рыжая кошка. Рекс, Дружок и Мухтар — собаки. Дружок — рыжая, Мухтар — белая. Все животные, которыми владеют Анатолий и Николай, имееют родословные. Анатолий владеет всеми черными и коричневыми животными, а Николай владеет всеми собаками небелого цвета, которые не являются собственностью Анатолия. Иван владеет Муркой, если Николай не владеет Муськой и если Мухгар не имеет родословной. Рекс — пятнистая собака. Определить, какие животные не имеют хозяев.
  3.  Составить базу знаний Знакомства из следующих фактов и правил:

Мери прелестна. Джон добрый. Джон мужественный. Джон сильный. Некто счастлив, если богатый или нравится женщинам. Мужчина нравится женщине, если женщина нравится мужчине и он добрый, либо мужчина добрый и сильный. Мужчине нравится женщина, если она прелестна.

Сформулировать вопрос: счастлив ли Джон? Найти мужчин, которые могут нравиться женщинам.

  1.  Ответьте на вопрос Что ест моя кошка?, если:

Птицам нравятся червяки. Кошкам нравятся рыбы. Друзья нравятся друг другу. Моя кошка мой друг. Моя кошка ест все, что ей нравится.

  1.  Запрограммируйте утверждения.

Число четное. Число не четное. Ни одно число не является четным и нечетным одновременно. Число не четное, если следующее за ним четное. Число, следующее за данным числом нечетное, если данное число четное, число, следующее за данным числом  четное, если данное число нечетное.

Рекомендуемая литература

  1.  Стобо Д.Ж. Язык программирования Пролог: Пер. с англ.- М.- Радио и связь, 1993.-368 с.:ил.
  2.  Ин Ц., Соломон Д. Использование Турбо-Пролога: Пер. с англ.-М.:Мир, 1993.-608 с.,ил.
  3.  Информатика. Задачник-практикум в 2 т./Под ред. И.Г.Семакина, Е.К. Хеннера: Том.2.-М.:-БИНОМ. Лаборатория знаний, 2003.-278 с.:ил.
  4.  Каймин В.А. Основы компьютерной технологии.- М.:Финансы и статистика, 1992.-208 с.: ил.


Лабораторная работа №2. Арифметика. Управление логическим выводом в программах

Пример 1. Описать предикаты для вычисления суммы, разности, произведения, частного двух чисел, возведения числа в квадрат, вывода остатка при деление на 3, вывод случайного числа из интервала [1,100].

Программа 13. Арифметика

Domains

N=integer

R=real

Predicates

add(N,N)

sub(N,N,N)

multi(N,N,N)

division(N,N,R)

kvadrat(N,N)

ostat(N,N)

vivod(N)

Clauses

add(X,Y):-S=X+Y, write(“Sum=  ”,S),nl.

sub(X,Y,S):-S=X-Y.

multi(X,Y,P):-P=X*Y.

division(X,Y,R):-Y<>0, R=X/Y.

kvadrat(X,N):-N=X*X.

ostat(X,N):-N=X mod 3.

vivod(N):-random(Y), N=1+Y*100.

Пример 2. Программирование взаимоисключающих утверждений. Процедуру нахождения наибольшего из двух чисел можно записать в виде отношения

max(X,Y,X):-X>=Y.

max(X,Y,Y):-X<Y.

Эти правила являются взаимоисключающими. Возможна более экономная формулировка: если X>=Y, то максимум=X, иначе =Y. На Прологе это запишется следующим образом:

max(X,Y,X):-X>=Y, !.

max(_,Y,Y).

Программа 14. Максимум

Domains

N=integer

Predicates

max(N,N,N)

Clauses

max(X, Y, X):-X>Y,!.

max(_,Y,Y).

Пример 3. Рассмотрим различные способы записи предиката different, определяющего различны ли числа, использующие сочетание встроенных предикатов ! и fail.

different(X,X):-!,fail.

different(_,_).

или

different(X,Y):-X=Y,!,fail.

different(_,_).

или

different(X,Y):-X=Y,!,fail; true. 

/* true –встроенный предикат, который всегда истиннен*/

или

different(X,Y):-not(X=Y).

Задания для самостоятельной работы

№1. Описать предикаты:

  1.  Найти квадрат числа X; куб числа X.
  2.  Найти значение функций у = а*х + b, где a, b и х — целые числа.
  3.  Найти периметр треугольника, если все его стороны известны.
  4.  Найти площадь прямоугольного треугольника по двум его катетам.
  5.  Найти площадь трапеции с основаниями А и В и высотой Н.
  6.  Найти квадрат гипотенузы в прямоугольном треугольнике по двум его катетам.
  7.  Найти объем прямоугольного параллелепипеда со сторонами А, В и С.
  8.  Зная скорость V и время Т, определите путь.
  9.  Найти последнюю цифру в записи натурального числа.
  10.  Найти цифры в десятичной записи двузначного натурального числа.
  11.  Найти первую цифру в десятичной записи трехзначного натурального числа.
  12.  Найти сумму цифр в десятичной записи трехзначного натурального числа.

2.

  1.  Найти

А. Наименьшее значение из двух чисел;

Б. Наименьшее значение из трех чисел на основе первой задачи;

В. Наименьшее значение из шести чисел на основе второй задачи.

  1.  Определить, удовлетворяют ли длины трех отрезков условию прямоугольного треугольника.
  2.  Определить, удовлетворяют ли длины трех отрезков условию треугольника.
  3.  Найти модуль числа X.
  4.  Описать предикат для вычисления функции, заданной соотношением:

Рекомендуемая литература

  1.  Ин Ц., Соломон Д. Использование Турбо-Пролога: Пер. с англ.-М.:Мир, 1993.-608 с.,ил.
  2.  Информатика. Задачник-практикум в 2 т./Под ред. И.Г.Семакина, Е.К. Хеннера: Том.2.-М.:-БИНОМ. Лаборатория знаний, 2003.-278 с.:ил.


Лабораторная работа №3. Повторение и рекурсия

Пример 1. Выводить на экран квадрат числа, вводимого пользователем, пока не будет введен 0.

Программа 15. Вывод квадрата числа

Domains

x=integer

Predicates

go

repeat

check(x)

Clauses

repeat.

repeat:- repeat.

go:-  repeat, write (“Введите число пожалуйста или 0-для выхода   ”),

 readint(A), check(A).

check(0):-nl,write(“ok”),!.

check(A):-B=A*A, write(B),nl, fail.

Или

go:- repeat, write (“Введите число   ”), readint(A),

 B=A*A, write(А, “^2= ” ,B),nl,

 write(“прервать да/нет (y/n) ”), readchar(C), C= “n”,!.

Пример 2. Организовать меню для выбора арифметической операции.

Программа 16. Меню

Domains

x=integer

Predicates

menu

actions(x)

repeat

Clauses

repeat.

repeat:- repeat.

menu:- repeat,

 write(“Введите 1 для +, 2 для *, 3-для -, 0-для выхода\n”),

 readint(N),

 actions(N).

actions(0):-!.

actions(1):-write(“Введите первое число”), nl, readint(A),

  write(“Введите второе число”) nl, readint(B),

  С=A+B,write(C),nl,fail.

actions(2):- write(“Введите первое число”), nl, readint(A),

  write(“Введите второе число”) nl, readint(B),

  С=A*B,write(C),nl,fail.

actions(3):- write(“Введите первое число”), nl, readint(A),

  write(“Введите второе число”) nl, readint(B),

  С=A-B,write(C),nl,fail.

Пример 3. Вычислить n-ый член последовательности Фибоначчи. N-ый член последовательности Фибоначчи, начиная с третьего, определяется суммой 2-х предыдущих, а 1-ый и 2-ой члены равняются единице.

Введем двуместный предикат fib, первый аргумент будет определять порядковый номер члена, а второй будет записываться для записи ответа. Введем два факта, первый - первый член  последовательности Фибоначчи равен 1, второй - второй член  последовательности равен 1, а для определения n-го члена запишем правило. Действительно, чтобы определить n-ый член, мы должны определить значения двух предыдущих и сложить их.

fib(1,1).

fib(2,1).

fib(N,F):- N1=N-1, fib(N1,F1), N2=N-2, fib(N2,F2), F=F1+F2.

? fib(1,F)

Ответом будет F=1, и Пролог сделает попытку сопоставить с запросом второй факт и потерпит неудачу. Однако сопоставление головы третьего утверждения с запросом происходит успешно и осуществляется попытка доказать цель fib(-1,F1), что в свою очередь, приводит к цели fib(-2, …)и так далее, т.е. образуется бесконечный цикл. Эту ситуацию можно устранить, используя отсечение и тем самым, указывая Прологу, что не существует других решений в случае успешного согласования граничного условия.

Программа 17. Последовательность Фибоначчи

Domains

x=integer

Predicates

fib(x,x)

Clauses

fib(1,1):-!.

fib(2,1):-!.

fib(N,F):- N1=N-1, fib(N1,F1), N2=N-2, fib(N2,F2), F=F1+F2.

Задания для самостоятельной работы

  1.  Вычислить N!.
  2.  Вычислить n-ый член последовательности Фибоначчи.
  3.  Вывести все числа от n до 1.
  4.  Вывести все числа от 1 до n.
  5.  Вычислить сумму чисел от 1 до n.
  6.  Определите  xn, n>0.
  7.  Определите  2n, n>0.
  8.  Определите  N5, n>0.
  9.  Вычислите сумму четных чисел от 1 до n.
  10.  Вычислите сумму квадратов нечетных чисел от 1 до n.
  11.  Вычислите сумму ak, где ak=1/(1+k).
  12.  Вычислить.
  13.  Вычислить.
  14.  Определите корень уравнения методом половинного деления.
  15.  Найти наибольший общий делитель двух чисел, трех чисел.
  16.  Определить число сочетаний .
  17.  Вычислить N!+(N-1)!+...+2!+1!.
  18.  Вычислить количество четных элементов на заданном интервале.
  19.  Перевести число из десятичной системы счисления в систему с основанием N, где N<10, N>1.

Рекомендуемая литература

  1.  Стобо Д.Ж. Язык программирования Пролог: Пер. с англ.- М.- Радио и связь, 1993.-368 с.:ил.
    1.  Ин Ц., Соломон Д. Использование Турбо-Пролога: Пер. с англ.-М.:Мир, 1993.-608 с.,ил.
    2.  Информатика:Учеб.пособие для студ.пед.вузов/А.В.Могилев, Н.И.Пак, Е.К.Хеннер;Под ред. Е.К.Хеннера.-3-е изд., перераб. и доп.-М.:Издательский центр “Академия”, 2004.-848 с.


Лабораторная работа №4. Применение рекурсии для обработки списков

Пример 1. Определить количество элементов в списке.

Количество элементов пустого списка равно 0, в противном случае, нужно определить количество элементов в хвосте и найденное значение увеличить на единицу.

Программа 18. Определение длины списка

Domains

list = integer*

Predicates

length_of(list, integer)

Clauses

length_of([], 0):-!.

length_of([_|T], N) :- length_of(T, N1),N = N1 + 1.

?- length ([2, 12, 45]), X).

Ответ: Х=3.

Пример 2. Найти сумму элементов в списке.

Сумма элементов пустого списка равна 0, сумма элементов непустого списка определяется сложением головы списка с суммой элементов хвоста.

sum ([], 0):-!.

sum ([H|T], S) :- sum (T, S1), S = S1+H.

?-sum ([2, 12, 45]), X).

Ответ: Х=59

Пример 3. Определить принадлежность элемента списку.

Программа 19. Определение принадлежности элемента списку

Domains

 type=integer

 list=type*

Predicates 

 member(type,list)

Clauses

member(H,[H|_]):-!.

member(H,[_|T]):-member(H,T).

Запрос:

member (4,[1,3,4,9]).

Ответ: Yes.

Данная программа имеет очень простой декларативный смысл: элемент принадлежит списку, если он является его головой или принадлежит хвосту списка.

Пример 4. Объединить два списка.

Эту задачу можно описать с помощью следующих предикатов:

а) если к пустому списку [] добавить список Р, то в результате получится Р;

б) чтобы добавить список Р к концу списка [X|Y], нужно Р добавить к хвосту Y и затем присоединить к голове Х, при этом получается список [Х|Т].

Программа 20. Объединение двух списков

Domains

type=integer

list=type*

Predicates

append(list,list,list)

Clauses

append([],L,L):-!.

append([H|T],P,[H|Y]):-append(T,P,Y).

? append ([3, 5, 7], [12,5],K).

Ответ: К=[3,5,7,12,5]

Процедуру append можно использовать:

  1.   для разбиения списка на подсписки:

? append (X,Y,[1,2])

Ответ: X=[ ]Y=[l,2]

           X=[l] Y=[2]

           X=[l,2] Y=[]

  1.  Для вывода последнего элемента списка:

 last(X,L):-append(_,[X],L)

Пример 5. Удаление элементов из списка.

Первый аргумент указывает удаляемый элемент, второй аргумент - исходный список и третий - список-результат.

Программа 21. Удаление элементов из списка

Domains 

 type=integer

list=type*

Predicates

delete(type,list,list)

Clauses

delete(X,[X|T],T):-!.

delete(X,[Y|T],[Y|T1]):-delete(X,T,T1).

Смысл: результат удаления произвольного элемента из пустого списка, есть пустой список, если удаляемый элемент совпадает с головой списка, то результатом программы является хвост списка, иначе удаление производится из хвоста списка.

Данная программа удаляет первое вхождение элемента в список. Знак отсечения "!" в конце правила предотвращает последующий поиск и вывод лишних вариантов ответов после выполнения ограничительного факта.

Для удаления всех вхождений элемента Х программу надо дополнить:

delete(_, [], []) :-!.

delete(X, [X | T], W) :- delete(X, T, W),!.

delete(X, [Y | T], [Y|W]) :- delete(X, T, W) .

Смысл программы таков: пока список не пуст, удалить элемент, если он совпадает с головой списка, а затем удалять его из хвоста, иначе надо сразу удалять элемент из хвоста.

Пример 6. Индексация элементов списка.

Определить номер элемента X.

nomer([X |_], 1, X):-!.

nomer ([_| T], N, X) :- nomer(T, N1, X), N=N1+1.

Пример 7. Вывести максимальный элемент.

max ( [X] , X) .

max ([X | T], X) :- max (T, M), X>M, !.

max ( [_| T] , M) :- max (T, M) .

Смысл программы: если в списке один элемент - он и является максимальным, если более одного, то это голова списка, если она больше максимального элемента хвоста, или максимальный элемент хвоста.

Пример 8. Обращение списка.

Обратить список из одного элемента - означает оставить список без изменения. Обратить более длинный список - обратить его хвост, а потом справа добавить к нему голову исходного списка.

reverse([X], [X]):-!.

reverse ([X | T], Z) :- reverse (T, W), append(W, [X], Z).

Пример 9. Иногда бывает полезно представить в виде списка информацию, содержащуюся в известных фактах. В Прологе для этой цели служит предикат findall. Полный формат предиката: findall(Переменная, Атом, Список), здесь Атом- отношения, которое определяет список элементов, конкретизирующих переменную в качестве аргумента предиката атом. Рассмотрим предикат на примере вычисления общей суммы окладов служащих

Прорамма 22. Сумма окладов служащих

Domains

i=integer

sp=i*

fam,im,dolgnost=symbol

Predicates

sum(sp,i)

go

spisok(fam,im,dolgnost,i)

Clauses

sum([],0):-!.

sum([H|T],S):-sum(T,S1),S=S1+H.

spisok(ivanov, ivan, slesar,400).

spisok(petrov, petr,tokar,200).

spisok(sidorov, denis,plotnik,100).

go:-findall(X,spisok(_,_,_,X),L), sum(L,A).

Задания для самостоятельной работы

  1.  Определите количество элементов в списке.
  2.  Определите сумму элементов списка
  3.  Определите количество нечетных элементов в списке.
  4.  Определите, принадлежит ли заданный элемент списку.
  5.  Определите, сколько раз заданный элемент входит в список.
  6.  Выведите максимальный элемент.
  7.  Выведите голову списка.
  8.  Выведите последний элемент.
  9.  Замените голову списка.
  10.  Определите номер элемента X.
  11.  Выведите элемент под номером N.
  12.  Удалите из списка все вхождения заданного элемента.
  13.  Объедините два списка.
  14.  Перепишите список в обратном порядке.
  15.  Объедините два списка без дублирования элементов.
  16.  Удалите первое вхождение заданного элемента.
  17.  Сложить поэлементно 2 списка.
  18.  Сложить два списка следующим образом: a1+bn, a2+bn-1, ...,an-1+b2, an+b1.
  19.  Найти количество элементов, предшествующих первому(последнему) максимальному.
  20.  Переместите голову списка в конец списка.
  21.  Найти сумму максимального и минимального элементов списка.
  22.  Поменяйте местами элементы с нечетными индексами с элементами с четными индексами.
  23.  Составить список из цифр заданного числа в обратном порядке. Например, 127645: [5,4,6,7,2,1].
  24.  Выполните N последовательных перестановок головы в конец списка.
  25.  Увеличьте каждый элемент списка на заданный элемент.
  26.  Увеличьте элемент с заданным номером на заданное число.
  27.  Все вхождения заданного элемента уменьшите на заданное число.
  28.  Удалите элемент с заданным номером N.
  29.  Создать список, элементами которого являются 2n, n!, члены последовательности Фибоначчи.
  30.  Определите среднее элементов списка.
  31.  Замените четные элементы списка нулем.
  32.  Определите сумму элементов, больше заданного N.
  33.  Отсортируйте список методом пузырька.
  34.  Отсортируйте список методом вставками.
  35.  Отсортируйте список быстрым методом сортировки.
  36.  Используя предикат findall, решите следующие задачи:
    1.  Вывести самых молодых жильцов дома и номера квартир, в которых они живут.
    2.  Вывести фамилии студентов и их возраст с максимальным размером стипендии.
    3.  Вывести фамилии сотрудников предприятия и их оклады, оклады которых меньше среднего.
    4.  Вывести студентов с заданной фамилией и посчитать их количество.

Рекомендуемая литература

  1.  Ин Ц., Соломон Д. Использование Турбо-Пролога: Пер. с англ.-М.:Мир, 1993.-608 с.,ил.
  2.  Практикум по логическому программированию: Методические рекомендации для студентов и преподавателей по лабораторному практикуму по курсу «Логическое программирование»/ Сост. Р.И. Баженов, И.И. Раскина. – Омск: Изд-во ОГПУ, 1995. – 85 с.


Лабораторная работа №5. Решение логических задач.

Пример 1. Беседует трое друзей: Белокуров, Рыжов, Чернов. Брюнет сказал Белокурову: “Любопытно, что один из нас блондин, другой брюнет, третий - рыжий, но ни у кого цвет волос не соответствует фамилии”. Какой цвет волос у каждого из друзей?

Для решения построим вспомогательную таблицу:

Таблица 8.

Вспомогательная таблица соответствия

Цвет          Фамилия

Белокуров

Рыжов

Чернов

блондин

-

рыжий

-

брюнет

-

-

Выводы:

  1.  Белокуров не  брюнет и не блондин;
    1.  Чернов не черный, цвет волос Чернова и Белокурова не совпадают;
    2.  Рыжов не рыжий, цвет волос у Рыжова и Белокурова,  Рыжова и Чернова не совпадают.

Программа 23. Логическая задача на соответствие

Predicates

fam(symbol)

color(symbol)

cootvet(symbol, symbol)

Clauses

fam(belokurov).

fam(ryzov).

fam(chernov).

color(ryziy).

color(cherniy).

color(beliy).

cootvet(X,Y):- fam(X), color(Y), X=belokurov,

  not(Y=cherniy), not(Y=beliy).

cootvet(X,Y):- fam(X), color(Y), X= chernov,

  not(Y=cherniy),not(cootvet(belokurov,Y).

cootvet(X,Y):- fam(X), color(Y), X= ryzov,

  not(cootvet(belokurov, Y), not(cootvet(chernov, Y).

Пример 2. На скамейке сидели Петя, Боря, Коля. Петя справа от Бори, Боря справа от Коли. Кто сидел посередине? Кто сидел с правого(левого) края? Кто сидел между указанными объектами(увеличьте число объектов)?

Программа 24. Логическая задача на выяснение порядка

Predicates

rayd(symbol, symbol, symbol)

sprava(symbol, symbol)

seredina(symbol

kr_cl(symbol)

kr_cpr(symbol)

Clauses

sprava(kolya, boray).       /*Справа от Коли Боря*/

sprava(boray, petay).

rayd(X,Y,Z):-  sprava(X,Y), sprava(Y, Z).

seredina(X):-   rayd(_,X,_).

kr_cl(X):- rayd(X,_,_).

kr_cpr(X):- rayd(_,_,X).

Задания для самостоятельной работы

  1.  Коля и Саша носят фамилии Шилов и Гвоздев. Какую фамилию носит каждый из них, если Саша с Шиловым живут в разных домах.
  2.  В соревнованиях по бегу Юра, Гриша и Толя заняли три первых места. Какое место занял каждый ребенок, если Гриша занял не второе и не третье место, а Толя не третье?
  3.  Три подруги вышли в белом, зеленом и синем платьях и туфлях. Известно, что только у Ани цвета платья и туфлей совпадали. Ни туфли, ни платье Вали не были белыми. Наташа была в зеленых туфлях. Определить цвета платья и туфель на каждой из подруг.
  4.  На заводе работали три друга: слесарь, токарь и сварщик. Их фамилии Борисов, Иванов и Семенов. У слесаря нет ни братьев, ни сестер. Он самый младший из друзей. Семенов, женатый на сестре Борисова, старше токаря. Назвать фамилии слесаря, токаря и сварщика.
  5.  В бутылке, стакане, кувшине и банке находятся молоко, лимонад, квас и вода. Известно, что вода и молоко не в бутылке, сосуд с лимонадом находится между кувшином и сосудом с квасом, в банке - не лимонад и не вода. Стакан находится около банки и сосуда с молоком. Как распределены эти жидкости по  сосудам.
  6.  Воронов, Павлов, Левицкий и Сахаров – четыре талантливых молодых человека. Один из них танцор, другой художник, третий-певец, а четвертый-писатель. О них известно следующее: Воронов и Левицкий сидели в зале консерватории в тот вечер, когда певец дебютировал в сольном концерте. Павлов и писатель вместе позировали художнику. Писатель написал биографическую повесть о Сахарове и собирается написать о Воронове. Воронов никогда не слышал о Левицком. Кто чем занимается?
  7.  Три друга заняли первое, второе, третье места в соревнованиях универсиады. Друзья разной национальности, зовут их по-разному, и любят они разные виды спорта. Майкл предпочитает баскетбол и играет лучше, чем американец. Израильтянин Саймон играет лучше теннисиста. Игрок в крикет занял первое место. Кто является австралийцем? Каким спортом увлекается Ричард?
  8.  Три девочки Маша, Рита, Лена пошли гулять. На улице было жарко, и они купили мороженое «Белка», «Стрелка», «Гагара». Какое мороженое купила каждая из девочек, если Лена купила не «Белку» и не «Гагару», а Рита – не «Гагару».
  9.  В комнате находятся Коля, Света, Оля. Каждый из них сидит на отдельной мебели (кровать, стул, диван). Известно, что Коля сидит не на стуле и не на кровати. Света не сидит на стуле. Кто где сидит?
  10.  На столе лежат ручка, карандаш, фломастер, красного, синего и зеленого цвета. Известно, что ручка лежит между предметом красного и зеленого цвета. Карандаш либо зеленый, либо синий.
  11.  Однажды в Артеке за круглым столом оказалось пятеро ребят из Москвы, Санкт-Петербурга, Новгорода, Перми, Томска: Денис, Игорь, Иван, Алеша, Сергей. Москвич сидел между томичем и Сергеем, санкт-петербуржец - между Денисом и Игорем, а напротив него сидел пермяк и Иван. Алеша ни разу не был в Санкт-Петербурге, а Денис не бывал в Москве и Томске, а томич с Игорем регулярно переписываются. Определите, кто в каком городе живет каждый из ребят.
  12.  На улице, встав в кружок, беседует четыре девочки: Аня, Валя, Надя, Галя. Девочка в зеленом платье – не Аня и не Валя - стоит между девочкой в голубом платье и Галей. Девочка в белом платье стоит между девочкой в розовом платье и Валей. Какого цвета платье у каждой из девочек?
  13.   Трое юношей: Коля, Дима и Юра влюблены в трех девушек: Аню, Лену, Вику. Но эта любовь без взаимности. Коля любит девушку, влюбленную в юношу, который любит Лену. Дима любит девушку, влюбленную в юношу, который любит Вику. Лена не любит Юру.
  14.  Составить базу знаний по сказке “Репка”. Фактами в этой базе должны быть утверждения типа тянет(X,Y). Составить правила, определяющие: кто первый тянет репку, кто последний тянет реку, кто тянет после бабки, кто тянет на четвертом месте.
  15.  Даны числа X, Y, Z, T. X меньше Yи меньше T; Y больше Z и больше T; Z больше X и меньше T. В каком порядке расположены эти числа.
  16.  На одной yлице стоят 5 домов, окpашенных в 5 pазных цветов. В каждом доме живет гpажданин дpyгой стpаны. Каждый из них пьёт свой напиток, курит свои сигареты и содержит своё домашнее животное. Определите, кто из них содержит рыб?  Британец живёт в красном доме. У шведа есть собака. Датчанин пьёт чай.  Зелёный дом стоит слева от белого и вплотную к немy.  Хозяин зелёного дома пьёт кофе. У того, кто курит Pall-Mall, есть птицы.  Хозяин желтого дома курит Dunhills.  Хозяин среднего дома пьёт молоко. Норвежец живёт в пеpвом доме. Человек, который курит Blends, живёт рядом с хозяином котов.  Тот, кто содержит лошадей, живёт pядом с тем, кто кypит Dunhills. Тот, кто курит Blue Master, пьёт пиво.  Hемец кypит Prince. Норвежец живёт рядом с синим домом.  У того, кто курит Blends, есть сосед, который пьёт водy.


Рекомендуемая литература

  1.  Информатика. Задачник-практикум в 2 т./Под ред. И.Г.Семакина, Е.К. Хеннера: Том.2.-М.:-БИНОМ. Лаборатория знаний, 2003.-278 с.:ил.
  2.  Практикум по логическому программированию: Методические рекомендации для студентов и преподавателей по лабораторному практикуму по курсу «Логическое программирование»/ Сост. Р.И. Баженов, И.И. Раскина. – Омск: Изд-во ОГПУ, 1995. – 85 с.


Лабораторная работа №6. Головоломки. Игровые программы.

Пример 1. Нарисовать конверт, не отрывая карандаша от бумаги и не проводя два раза по одной и той же линии. Введем обозначения, ребра – латинскими буквами, вершины - цифрами.

Знания о структуре графа можно представить следующим образом: rebro(a,1,2), rebro(a,2,1), rebro(b,2,3), rebro(b,3,2), rebro(c,1,3), rebro(c,1,2), rebro(c,3,1), rebro(d,2,4), rebro(d,4,2), rebro(e,2,5), rebro(e,5,2), rebro(f,3,4), rebro(f,4,3), rebro(g,3,5), rebro(g,5,3), rebro(h,4,5), rebro(h,5,4).

Решением задачи должен явиться список пройденных ребер графа, причем длина его должна быть равна 8, и в нем не должно быть повторяющихся ребер, что можно описать так:

prohod(T,P):-length(P,8),write_list(P),!.

prohod(T,P):-rebro(R,T,H), not(member(R,P), prohod(H,[R|P).

T-текущая вершина графа, а P-список пройденных ребер. Первое правило означает, что если длина списка P пройденных вершин становится равной 8, то список P выводится на печать. Это правило ограничивает рекурсивный перебор вершин и ребер, проводимый вторым правилом. Второе правило является генератором перебора, оно перебирает предикаты “rebro()” и находит такое ребро R, из текущей вершины Т в новую H, чтобы оно не принадлежало списку P, зато это ребро  добавляется в качестве головы к списку P, и поиск дальнейшего пути производится уже из новой вершины H.

Пример 2. Программа “Угадай число”.

Программа 25. Логическая игра «Угадай число»

Predicates

play_the_game

give_info

play_it

generate_rand(integer)

play_it_sam(integer)

test_and_tell(integer,integer)

say_you_got_it_right(integer)

say_too_big

say_too_small

Clauses

play_the_game:-give_info, play_it.

 /*информация для пользователя*/

give_info:-makewindow(1,7,7,"",0,0,25,80),

 makewindow(2,7,7,"Угадай число", 2,20,22,45),

 nl, write("Это игра Угадай число"),

 nl, write("Я загадаю число из"),    

 nl, write("интервала [1,100]"),    

 nl, write("Я буду подсказывать больше"),    

 nl, write("или меньше задуманное число"),nl,    

 nl, write("Кода будешь готов- нажми space bar"),    

 nl,readchar(_),

 clearwindow.

  /*выполнение игры*/

play_it:-generate_rand(A),

 play_it_sam(A).

  /*генерация случайного числа*/

generate_rand(X):-

 random(R),

 X=1+R*100,

 nl,write("Я загадал число"),

 nl,write("Теперь дело за Вами"),nl.

  /*запрос к пользователю */

play_it_sam(X):-

 nl, write ("Введите свой вариант"),        

 nl, readint(G),

 test_and_tell(X,G),

 play_it_sam(X).

  /* проверка и выдача результата*/

test_and_tell(X,X):-  say_you_got_it_right(X),!.

test_and_tell(X,Y):-  X>Y, say_too_big,!.

test_and_tell(_,_):- say_too_small.

  /*выдача сообщений*/

say_too_big:-nl, write("Загаданное число больше").

say_too_small:-nl, write("Загаданное число меньше").

say_you_got_it_right(X):-nl, write("Вы правы"),

    nl,write("Я загадал ",X),

    nl, write("До новых встреч!"),

    nl, write("Нажмите space bar"),

    nl,readchar(_),

    exit.

Goal

play_the_game.

Пример 3. Игра Баше – 23 спички. На столе 23 спички, 2 игрока по очереди берут от 1 до 3 спичек, проигравшим считается тот, кто возьмет последнюю спичку.

Программа 26. Логическая игра «Игра Баше – 23 спички»

Predicates

play_the_game

do_windows

play(integer,integer,integer)

play_it_again(integer,integer,integer)

real_int(real,integer)

Clauses

play_the_game:-do_windows,play(23,0,0).

 /*правило для образования окон*/

do_windows:-makewindow(1,7,7,"",0,0,25,80),

 makewindow(2,7,7,"Игра 23 спички", 1,5,22,40),

 nl, write("Добро пожаловать!"),    

 M=23, H=0, C=0,

 nl, write("Всего ",M,"  спички"   ),    

 nl, write("По очереди мы будем перемещать "    ),    

 nl, write("спички в свои кучки"),    

 nl, write("За раз можно взять 1, 2, 3 спички"),nl,

 nl, write("Проиграет, тот кто заберет последнюю спичку"),

 nl, write("Итак, начнем, всего ", M, "сп."),nl,

 nl, write("я взял ",C," сп. Вы взяли ",H, " сп."),nl.

play(M,H,C):-play_it_again(M,H,C).

 /*правило определения победителя*/

play_it_again(M,_,_):-

 M<=0,

 nl, write("Вы выиграли!"),

 nl, write("Нажмите любую клавишу для выхода"),

 readchar(_), clearwindow,!,exit.

play_it_again(1,_,_):-

 nl, write("Я выиграл!"),

 nl, write("Нажмите любую клавишу для выхода"),

 readchar(_), clearwindow,!,exit.

play_it_again(M,_,_):-

 nl, write("Ваш ход"),

 nl, write("Сколько спичек вы хотите взять?"),

 readint(Hn),

 M2=M-Hn, H2=Hn,

 write("Осталось ",M2,"сп."),

 nl,write("Мой ход"),

 random(F), Rea=1+3*F,

 real_int(Rea,Rint),

 M3=M2-Rint,

 nl, write("Я беру ",Rint," сп."),

 nl, write("Осталось ",M3, " сп."),nl,

 M7=M3,H7=H2,C7=Rint,

 play_it_again(M7,H7,C7).

 /*вспомогательное правило*/

real_int(Re,In):-In=trunc(Re).

Goal

play_the_game

Задания для самостоятельной работы

  1.  Отгадать число, загаданное  компьютером, максимум за 3 попытки.
  2.  23 спички. Разработать выигрышную стратегию для компьютера.
  3.  Имеется два сосуда – на 3 и 5 литров. Как отмерить с их помощью 4 литра воды?
  4.  Решите задачу о перевозке фермером через реку волка, козы, капусты.
  5.  Раскрасить плоскую карту так, чтобы никакие две смежные области на ней не были раскрашены в одинаковый цвет. В наборе 4 цвета.


Таблица 9.

Поле для раскраски

a

b

c

d

e

f

  1.  Лабиринт задан матрицей соединений, в которой для каждой пары комнат указано, соединены ли они коридором. Построить путь перехода из комнаты “a” в комнату “g”:

Таблица 10.

Поле для лабиринта

A

B

C

D

E

F

G

A

-

1

0

0

0

0

0

B

1

-

1

0

1

0

0

C

0

1

-

1

0

0

0

D

0

0

1

-

1

0

0

E

0

1

0

1

-

0

0

F

0

0

0

0

1

0

0

G

0

0

0

0

1

0

-

  1.  Имеется n городов. Некоторые из них соединены дорогами известной длины. Вся система дорог задана квадратной матрицей n*n, элемент aij<0, если между городами дороги нет, в противном случае равен расстоянию между городами.
  2.  Задан лабиринт. Напишите программу для нахождения маршрутов для выхода из этого лабиринта. Начало маршрута точка О. Закрашенная клетка – стена.

Таблица 11.

О

  1.  Быки и коровы. Игрок A выбирает секретный код, представляющий последовательность из N различных десятичных цифр (N=4). Игрок пытается угадать задуманный код  и спрашивает игрока А о числе быков” (“быки” - количество совпадающих цифр в одинаковых позициях предполагаемого и задуманного кодов; число коров”- количество совпадающих цифр, входящих в предполагаемый и задуманный код, но находящиеся на разных позициях).

Рекомендуемая литература

  1.  Ин Ц., Соломон Д. Использование Турбо-Пролога: Пер. с англ.-М.:Мир, 1993.-608 с.,ил.
  2.  Информатика:Учеб.пособие для студ.пед.вузов/А.В.Могилев, Н.И.Пак, Е.К.Хеннер;Под ред. Е.К.Хеннера.-3-е изд., перераб. и доп.-М.:Издательский центр “Академия”, 2004.-848 с.


Лабораторная работа №7. Обработка файлов. Предикаты для работы с файлами

deletefile(DOS_filename)-удаление файла

save(DOS_filename) –сохранение файла

renamefile(old_DOS_filename, new_DOS_filename)-переименовыфвание файла

existfile(DOS_filename)-проверка на наличие файла с таким именем

flush(file_domain)-сброс данных из внутреннего буфера, отведенного для данного устройства записи

disk(Path) –выбор дисковода и пути доступа

dir(Path, File_spec, File_name) –Переменой Path должен быть присвоен корректный путь доступа, переменная File_spec задает расширение представляющей интерес группы файлов. Данный предикат выдает каталог имен файлов с заданным расширением; вы можете выбрать среди них нужный и нажать Enter. Имя файла будет присвоено переменой File_name.

При описании файловых доменов тип домена записывается по левую сторону от знака равенства, а имя доомена по правую.

Пример:

file=datafile

file=datafile1;datafile2

openwrite(datafile,filename) - открытие файла для записи или создание, где datafile- введеннный пользователем файловый домен, filename-имя файла в DOS, теперь ссылки на datafile будут означать обращение к filename.

writedevice(datafile) -назначение файла в качестве устройства записи

openread(datafile,filename) - открытие файла для чтения.

readdevice(datafile) -назначение файла устройством чтения

openmodify(datafile,filename) - открытие файла для редактирования, указатель помещается в начало файла, сместить указатель можно при помощи предиката filepos.

openappend(datafile,filename) - открытие файла для добавления данных в конец файла.

closefile(datafile) -закрытие файла

Рассмотрим примеры работы с файлами.

Пример 1. Вывести информацию на экран дисплея и в файл на диске.

Программа 27. Запись данных в файл

Domains

str = string

file = datafile

Predicates

data(str)

write_lines

Goal

openwrite(datafle,"file1.dat"),

write_lines,

closefile(datafile).

Clauses

data("Старому году оставьте печали,!").

data("Забудьте обиду, беду.").

data("Только успехов, здоровья и счастья,").

data("Мы Вам желаем в Новом году!").

write_lines:-

 data(Line),

 write("  ",Line),nl,

 writedevice(datafile),

 write("  ",Line),nl,

 writedevice(screen), /*для вывода данных на экран*/

 fail, write_lines.

Пример 2. Вывести данные файла на экран.

Программа 28. Чтение данныхиз файла

Domains

str = string

file = datafile

Predicates

read_write_lines

Goal

openread(datafile,"file1.dat"),

read_write_lines,

closefile(datafile).

Clauses

read_write_lines :-

 readdevice(datafile),

 not(eof(datafile)),

 readln(Line),

 writedevice(screen),

 write("  ",Line),nl,

 read_write_lines.

Пример 3. Записать в файл данные, вводимые с клавиатуры

Программа 29. Запись в файл данных, вводимых с клавиатуры

Domains

file = datafile

dstring, cstring = string

Predicates

readin(dstring,cstring)

create_a_file

Goal

create_a_file.

Clauses

create_a_file :-

 nl,nl,

 write("Пожалуйста, введите полное имя файла."),

 nl,nl,

 readln(Filename), openwrite(datafile,Filename),

 writedevice(datafile),

 readln(Dstr),

 concat(Dstr,"\13\10",Cstr),

 readin(Dstr,Cstr),

 closefile(datafile).

readin("done",_) :- !.

/*ввод данных завершится после вода слова "done"*/

readin(_,Cstr) :-

 write(Cstr),

 readln(Dstrl),

 concat(Dstrl, "\13\10",Cstr1),

 writedevice(datafile),

 readin(Dstrl,Cstr1).

Предикаты для работы с файлами прямого доступа

Openmodify(fn,filename)-связывает логическое имя файла fn с именем файла

Filepos(fn, pos, mode)-устанавливает указатель файла в заданную позицию

Таблица 12.

Действие системы при операциях с файлами прямого доступа

Режим mode

Действия системы

0

Смещение берется относительно начала файла

1

Смещение берется относительно текущей позиции

2

Смещение берется относительно конца файла

Пример 4. Данные, вводимые с клавиатуры, записать в файл прямого доступа.

Программа 30. Запись данных в файл прямого доступа

Domains

file = datafile

Predicates

create_a_random_access_file

write_read_more(real, string)

pad_str (strIng,string,integer)

Goal

create_a_random_access_file.

Clauses

create_a_random_access_file :-

 write("Please enter filename:"),nl,

 readln(Filename),

 openwrite(datafile,Filename),

 closefile(datafile),

 openmodify(datafile,Filename),

 write("Введите строку"),nl,

 readln(Dstr),

 write_read_more(0,Dstr),

 closefile(datafile).

write_read_more(_,"done") :-

 nl, write(" Press the space bar."),

 readchar(_),exit.

write_read_more(Index,Dstr) :-

 writedevice(datafile),

 filepos(datafile,Index,0),

 pad_str(Dstr,Padstr,38),

 concat(Padstr, "\10\13", Cstr),

 write(Cstr),

 writedevice(screen),

 write("Введите строку"),nl,

 readln(Dstr1),

 Index1 = Index + 40,

 write_read_more (Index1, Dstr1).

pad_str (Instr,Instr,Length) :-

 str_len(Instr,Testlength),

 Testlength >= Length,!.

 pad_str (Instr,Padstr,Length) :-

 concat(Instr,"-",Newstr),

 pad_str(Newstr,Padstr,Length).

Пример 5. Вывести на экран заданную строку файла прямого  доступа и выдача их на экран

Программа 31. Вывод данных из файла прямого доступа

Domains

file = datafile

Predicates

read_a_random_access_file

Goal

read_a_random_access_file.

Clauses

read_a_random_access_file:-

 write("Please enter filename:"), nl, readln(Filename),

 openread(datafile,Filename),

 write("Type 1n record number: "),nl,

 readreal(Record),

 Index = (Record - 1) * 40,

 readdevice(datafile),

 filepos(datafile,Index,0),

 readln(Cstr),

 write(Cstr), nl,nl,

 write("Press the space bar."),nl,

 readdevice(keyboard),

 readchar(_),

 closefile(datafile),

 exit.

Задание для самостоятельной работы

  1.  В файле задана последовательность целых чисел, найти сумму чисел, предшествующих первому отрицательному.
  2.  Переписать данные файла в обратном порядке.
  3.  Вывести на экран данные файла в неубывающем порядке.
  4.  Записать результат сложения  чисел, содержащихся в файлах в       третий.
  5.  Переписать числа из файла в другой, дописав за каждым его квадрат.


Лабораторная работа №8. Создание динамической базы данных. Предикаты для работы с базой данных

Для описания предикатов динамической базой данных предназначен раздел database. База данных  (БД) называется динамической потому, что во время работы можно добавлять, удалять содержащиеся в них утверждения. Другая важная особенность динамических баз данных состоит в том, что она может быть записана на диск и считана с диска в оперативную память.

Иногда предпочтительно иметь часть информации БД в виде утверждений статической БД. Эти данные заносятся в динамическую сразу после активизации программы. В общем случае, предикаты статической БД имеют другое имя, но ту же самую форму представления данных, что и предикаты динамической.

Предикаты для работы с динамической БД:

Asserta заносит новый факт в БД, новый факт помещается перед всеми уже внесенными утверждениями.

Assertz помещает новый факт в БД за всеми имеющимися утверждениями.

Retract удаляет утверждение из БД.

Save сохраняет находящуюся в оперативной памяти БД в текстовом файле. Синтаксис этого предиката таков Save(DOS_file_name)

consult(DOS_file_name) считывает в память файл БД

readterm(Domain,Term) используется для чтения из файла объектов, относящихся к определенному в программе домену.

Предикат findall позволяет собрать все имеющиеся в базе данные в список, который может быть полезен при дальнейшей работе.

В качестве примера  рассмотрим БД по игрокам футбольных команд, БД допускает следующие операции: добавление, удаление и просмотр данных. Эта программа создает БД и содержит её в оперативной памяти. Для работы с ней использовался предикат player с аргументами p_name-имя игрока, k_name-название клуба, p_number-номер игрока, pos-позиция игрока, height -рост, weight-вес, nfl_exp-стаж выступлений, college-учебное заведение)

Программа 32. Динамическая база данных «Футбольная команда»

Domains

p_name,k_name, pos, college = string

p_number, height, weight, nfl_exp = integer

Database

dplayer(p_name, k_name,p_number,pos, height,weight,nfl_exp, college)

Predicates

repeat

do_mbase

assert_database

menu

process(integer)

clear_database

player(p_name, k_name,p_number,pos, height,weight,nfl_exp, college)

error

Goal

do_mbase.

Clauses

repeat.

repeat:-repeat.

  /*База данных футбол*/

player("Иванов Иван","Спартак",13,"з", 205,90,3, "ГГПИ").

player("Петров Петр","Динамо",96,"пз", 185,78,4, "ГТК").

player("Сидоров Денис","Локомотив",69,"в", 190,88,2, "ГТУ").

player("Васечкин Илья","Торпедо",5,"в", 195,80,5, "ГГПИ").

player("Алексеев Дима","ЦСКА",1,"н", 165,67,2, "ГТК").

player("Карпов Павел","Зенит",12,"н",170,74,1, "ГКК").

  /*конец начальных данных*/

assert_database:-

player(P_name,K_name,P_number,Pos,Height,Weight,Nfl_exp,College), assertz(dplayer(P_name,K_name,P_number,Pos,Height,Weight,Nfl_exp,

  College)),

fail.

assert_database:-!.

clear_database:-

 retract(dplayer(_,_,_,_,_,_,_,_)),

 fail.

clear_database:-!.

do_mbase :-

 assert_database,

 makewindow(1,7,7," FOOTBALL DATABASE ",0,0,25,80),

 menu,

 clear_database.

menu :-

 repeat, clearwindow,

 nl,

 write(" ************************************* "),nl,

 write(" * 1. Добавление нового игрока в БД  * "),nl,

 write(" * 2. Удаление игрока из БД          * "),nl,

 write(" * 3. Просмотр данных                * "),nl,

 write(" * 4. Выход из программы             * "),nl,

 write(" ************************************* "),nl,

 write(" Пожалуйста, сделайте свой выбор 1, 2, 3 or 4 : "),

 readint(Vibor),nl,process(Vibor),Vibor = 4,!.

 /* Добавление информации об игроке в БД */

process(1) :-

 makewindow(2,7,7,"Добавление данных",2,20,18,58),shiftwindow(2),

 write("Введите, пожалуйста:"),nl,

 write("Имя игрока: "), readln(P_name),

 write("Название клуба: "), readln(K_name),

 write("Номер игрока: "), readint(P_num),

 write("Позицию: "), readln(Pos),

 write("Рост: "), readint(Ht),

 write("Вес: "), readint(Wt),

 write("Стаж выступлений: "), readint(Exp),

 write("Название учебного заведения: "), readln(College),

  assertz(dplayer(P_name, K_name, P_num,Pos,Ht,Wt,Exp, College)),

 write(P_name," добавлен в БД"), nl,!,

 write("Press space bar. "), readchar(_),

 removewindow, shiftwindow(1).

  /* Удаление */

process(2) :-

 makewindow(3,7,7,"Удаление данных",10,30,7,40),shiftwindow(3),

 write("Введите имя удаляемого игрока: "), readln(P_name),

 retract(dplayer(P_name,_,_,_,_,_,_,_)),

 write(P_name," удален из БД "), nl, !,

  write("Press space bar."), readchar(_), removewindow,

 shiftwindow(1).

  /* Просмотр данных об игроке*/

process(3) :-

 makewindow(4,7,7," Просмотр ", 7,30,16,47),  shiftwindow(4),

 write("Введите имя для просмотра: "), readln(P_name),

 dplayer(P_name,T_name,P_number,Pos,Ht,Wt,Exp,College),nl,

 write(" Имя игрока         : ",P_name),nl,

 write(" Название клуба     : ",T_name),nl,

 write(" Номер игрока       : ",P_number),nl,

 write(" Позиция            : ",Pos),nl,

 write(" Рост               : ",Ht), nl,

 write(" Вес                : ",Wt),nl,

 write(" Стаж выступлений   : ",Exp), nl,

 write(" Учебное заведение  : ",College),nl, nl,!,

 write("Press space bar"), readchar(_),  

 removewindow, shiftwindow(1).

process(3) :-

 makewindow(5,7,7," Неудача ",14,7,5,60), shiftwindow(5),

 write("К сожалению, данных нет."),nl,

 write("Извините, пока!"),nl,!,

 write("Press space bar."),readchar(_),

 removewindow,shiftwindow(1).

  /* Выход */

process(4) :-

 write("До новых встреч! "),readchar(_),exit.

  /*Обработка ошибки*/

process(Vibor):-

 Vibor<1, error; Vibor>5, error.

error:-

 write("Пожалуйста выберите число от 1 до 4"),

 write("(Press the spase bar to continue)"),readchar(_).

Задание для самостоятельной работы

Модифицируйте программу, добавив в меню пункты:

  1.  Вывод списка игроков.
  2.  Сохранение данных в файл.
  3.  Выборка данных по 1 из трех критериев.


Лабораторная работа №9. Применение языка для решения задач ИИ. Создание экспертных систем

Пример 1.Рассмотрим пример ЭС для идентификации породы собак. Она помогает потенциальному хозяину выбрать породу собаки в соответствие с определенными критериями.

В данной ЭС используются следующие характеристики:

  1.  Короткая шерсть;
  2.  Длинная шерсть;
  3.  Рост меньше 30 дюймов;
  4.  Рост меньше 22 дюймов;
  5.  Низкопосаженный хвост;
  6.  Длинные уши;
  7.  Хороший характер
  8.  Вес больше 100 фунтов.

Каждая характеристика для конкретной породы либо верна, либо не верна. Для каждой породы справедливы следующие характеристики:

Таблица 13.

Характеристики собак

Порода

Характеристики

Английский бульдог

1,4,5,7

Гончая

1,4,6,7

Дог

1,3,6,7,8

Амер.гончая

1,5,6,7

Кокер-спаниэль

2,4,5,6,7

Ирландский сеттер

2,3,6

Колли

2,3,5,7

Сенбернар

2,5,7,8

Программа 33. «Эксперт по породам собак»

*Эксперт по породам собак*/

/*Назначение: Демонстрация работы  ЭС*/

Domains

n=integer

list=n*

dog=symbol

Predicates

rule(n,dog,list)

cond(n,string)

do_expert

show_menu

do_consulting

process(n)

test(n,list)

topic

repeat

Goal

do_expert.

Clauses

rule(1,"английский бульдог",[1,4,5,7]).

rule(2,"гончая",[1,4,6,7]).

rule(3,"дог",[1,3,6,7,8]).

rule(4,"американская гончая",[1,5,6,7]).

rule(5,"коккер-спаниель",[2,4,5,6,7]).

rule(6,"ирландский сеттер",[2,3,6]).

rule(7,"колли",[2,3,5,7]).

rule(8,"сенбернар",[2,5,7,8]).

 /*Характеристики*/

cond(1,"короткошерстная").

cond(2,"длинношерстная").

cond(3,"рост ниже 30 дюймов").

cond(4,"рост ниже 22 дюймов").

cond(5,"низкопосаженный хвост").

cond(6,"большие уши").

cond(7,"хороший характер").

cond(8,"вес более 100 фунтов").

 

do_expert:-

 makewindow(1,7,5 ,"ЭКСПЕРТНАЯ СИСТЕМА",0,0,25,80),

 show_menu.

repeat.

repeat:-repeat.

  /*Вывод меню*/

show_menu:-

 repeat,

 write("***************************"),nl,

 write("*****Добро пожаловать!*****"),nl,

 write("*                         *"),nl,

 write("*****1-консультация********"),nl,

 write("*****2-список**************"),nl,

 write("*****3-выход***************"),nl,

 write("*                         *"),nl,

 write("****Сделайте свой выбор****"),nl,

 readint(X),

 process(X),fail.

  /*Обработка 1 пункта меню “Консультация”*/

process(1):-

 do_consulting,

 readchar(_),

 shiftwindow(1),

 clearwindow.

  /*Обработка 2 пункта меню “Вывод списка”*/

process(2):-

 makewindow(2,7,7,"",5,20,12,25),

 topic,

 readchar(_),

 shiftwindow(1),

 clearwindow.

  /* Обработка 3 пункта меню “Выход”*/

process(3):-

 removewindow,

 exit.

  /*Вывод пород собак*/

topic:-

 rule(X,Y,_),

 write(X,".  ",Y),

 nl,fail.

topic.

  /*Консультация*/

do_consulting:-

 test(1,List),

 rule(_,X,List),

 write("Ваш выбор:"  ,X),!.

do_consulting:-

 write("Мне жаль, что не смог Вам помочь.").

  /*Тестирование*/

test(9,[]):-!.

test(1,[N|List]):-

 cond(N,Text),

 makewindow(2,7,7,"",5,20,10,35),

 write("Вопрос:-",Text,"?"),nl,

 write("1-да"),nl,

 write("0-нет"),nl,

 readint(R),R=1,!,test(3,List).

test(1,List):- test(2,List),!.

test(N,[N|List]):-

 cond(N,Text),

 makewindow(2,7,7,"",5,20,10,35),

 write("Вопрос:-",Text,"?"),nl,

 write("1-да"), nl,

 write("0-нет"), nl,

 readint(R),M=N+1,

 R=1,!,test(M,List).

 test(N,List):-M=N+1,test(M,List).

Задания для самостоятельной работы

Разработать экспертную систему, тему выбрать самостоятельно. Отчет должен содержать следующие пункты:

  1.  Тема ЭС.
  2.  Назначение, возможности программы.
  3.  Разработать структурно-функциональную схему.
  4.  Определить базу знаний, разработать механизм вывода, интерфейс программы.
  5.  По каким параметрам программу можно отнести к классу ЭС.


Рекомендуемая литература

  1.  Братко И. Программирование на языке Пролог для ИИ: Пер. с англ.- М.- Мир, 1990
  2.  Ин Ц., Соломон Д. Использование Турбо-Пролога: Пер. с англ.-М.:Мир, 1993.-608 с.,ил.
  3.  Марселлус Д. Программирование экспертных систем на ТурбоПрологе: Пер. с англ./Предисл. С.В.Трубицына.-М.-Финансы и статистика, 1994.-256с.:ил.
  4.  Стерлинг Л., Шапиро Э. Искусство программирования на языке Пролог: Пер.с англ.-М.: Мир, 1990.-235 с., ил.
  5.  Таунсенд К., Фохт Д. Проектирование и программная реализация экспертных систем на персональных ЭВМ: Пер. с англ./Предисл. Г.С.Осипова.-М. .-Финансы и статистика, 1990.-320с.:ил.


Литература

  1.  Братко И. Программирование на языке Пролог для ИИ: Пер. с англ.- М.- Мир, 1990
  2.  Доорс Дж., Рейблейн А.Р., Вадера С. Пролог-язык программирования будущего: Пер. с англ.- М.- Финансы и статистика, 1990
  3.  Стобо Д.Ж. Язык программирования Пролог: Пер. с англ.- М.- Радио и связь, 1993.-368 с.:ил.
  4.  Ин Ц., Соломон Д. Использование Турбо-Пролога: Пер. с англ.-М.:Мир, 1993.-608 с.,ил.
  5.  Информатика. Задачник-практикум в 2 т./Под ред. И.Г.Семакина, Е.К. Хеннера: Том.2.-М.:-БИНОМ. Лаборатория знаний, 2003.-278 с.:ил.
  6.  Информатика:Учеб.пособие для студ.пед.вузов/А.В.Могилев, Н.И.Пак, Е.К.Хеннер;Под ред. Е.К.Хеннера.-3-е изд., перераб. и доп.-М.:Издательский центр “Академия”, 2004.-848 с.
  7.  Каймин В.А. Основы компьютерной технологии.- М.:Финансы и статистика, 1992.-208 с.: ил.
  8.  Каймин В.А. Информатика: Учебник.-2-е изд., перераб. и доп.-М.-ИНФРА-М,2001.-272 с.
  9.  Кларк К., Маккей Ф. Введение в логическое программирование на микро-Прологе. Пер. с англ.- М.- Радио и связь, 1987.
  10.  Клоксин У., Меллиш К. Программирование на языке Пролог: Пер.с англ.-М.: Мир, 1987.
  11.  Малпас Дж. Реляционный язык Пролог и его применение. Пер. с англ./Под ред. В.Н. Соболева.-М.-Наука, 1990
  12.  Марселлус Д. Программирование экспертных систем на ТурбоПрологе: Пер. с англ./Предисл. С.В.Трубицына.-М.-Финансы и статистика, 1994.-256с.:ил.
  13.  Стерлинг Л., Шапиро Э. Искусство программирования на языке Пролог: Пер.с англ.-М.: Мир, 1990.-235 с., ил.
  14.  Таунсенд К., Фохт Д. Проектирование и программная реализация экспертных систем на персональных ЭВМ: Пер. с англ./Предисл. Г.С.Осипова.-М. .-Финансы и статистика, 1990.-320с.:ил.
  15.  Хоггер К. Введение в логическое программирование: Пер. с англ.-М.: Мир, 1988.-348 с.


Пособие подготовлено на кафедре информатики Глазовского государственного педагогического института им. В.Г. Короленко

Сборник задач по логическому программированию

Составители:

Акбашева Альфия Мударисовна

Камалов Ренат Рифович




1. William Blake
2. Маркетинговая деятельность на примере ООО Гвики
3. Становление абсолютной монархии в России
4. 4 минут; нагреванию льда 2 2 мин; нагреванию льда 3 2 мин; плавлению льда Определите энергию которая.
5. Загартування сталей
6. Одноэтажное промышленное здание
7. Эволюционное учение Кафедра биологи МГМСУ А
8. Курсовая работа- Новые информационные технологии в документационном обеспечении управлении
9. Предмет экономической теории и её функции
10. РОССИЙСКИЙ ГОСУДАРСТВЕННЫЙ ТОРГОВОЭКОНОМИЧЕСКИЙ УНИВЕРСИТЕТ Кафедра Финансы и кредит
11. Состав административного правонарушения1
12. Об утверждении Положения о государственной санитарноэпидемиологической службе Российской Федерации и Пол
13. Статья- Сколько можно заработать на фондовом рынке
14. Типы темпераментов, их психологическая характеристика
15.  Соціальна поведінка особистості та фактори її формування 2
16. сличение в одиночку или вподчитку ~ поиск орфографических и пунктуационных ошибок; сквозное смысловое ч
17. I Mon p~re s~ppelle Nikols
18. . Початок Місяцьрік Кінець місяцьрік Назва підприємстваорганізації де працювали Поса
19. 04 Затверджено наказом МОНМС України 29
20. Коммуникационная политика