Prolog курсовая работа

Решение логической задачи на языке Prolog

Московский Авиационный Институт

КУРСОВАЯ РАБОТА

по дисциплине «Интеллектуальные Информационные Системы»

Решение логической задачи на языке Prolog

Выполнил: студент группы 03-432

Москва 2012г

Введение

Пролог — язык и система логического программирования, основанные на языке предикатов математической логики дизъюнктов Хорна, представляющей собой подмножество логики предикатов первого порядка.

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

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

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

Факты в базах знаний на языке Пролог представляют конкретные сведения (знания). Обобщённые сведения и знания в языке Пролог задаются правилами логического вывода (определениями) и наборами таких правил вывода (определений) над конкретными фактами и обобщёнными сведениями.

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

Почему Prolog?

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

История головоломок

Некоторые головоломки известны с глубокой древности. Оригинальные логические задачи находят на стенах египетских пирамид, в древнегреческих манускриптах и в других исторических памятниках. Эпохой расцвета в средневековой истории головоломок можно считать конец IX века. Рост уровня образования и снижение религиозной нетерпимости к наукам привели к расширению круга любителей логических задач. В это время появилась и первая книга головоломок в Европе — сборник ирландского просветителя Алкуина «Задачи для развития молодого ума».

Наиболее широкое распространение головоломки получили на рубеже XIX и XX веков. Благодаря деятельности американца Сэма Лойда и англичанина Генри Дьюдени головоломки проникли во многие периодические издания, стали популярны среди широких слоев населения. Лойд считается автором популярнейшей во всем мире головоломки «Пятнашки». Игра была настолько популярной, что некоторые работодатели вынуждены были издать приказ о запрете приносить её на работу.

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

С 1992 года проводятся чемпионаты мира по пазлспорту — интеллектуальному виду состязаний, в котором участники соревнуются в скоростном решении головоломок на бумаге.

Задача

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

Некий мистер Энтони присутствовал однажды на суде. Слушалось дело по обвинению в шпионаже. На скамье подсудимых сидело трое А, В и С, относительно которых в начале заседания было известно лишь, что один из них рыцарь, другой лжец и третий шпион.

Подсудимого А судья спросил: Вы шпион? А ответил односложно («да» или «нет»). Затем судья спросил подсудимого В: Правду ли сказал А? В дал односложный ответ («да» или «нет»), после чего судья, указав на одного из подсудимых, заявил: Вы не шпион, освобождаетесь из-под стражи и можете быть свободны! Тот с радостью покинул зал заседаний. Затем судья спросил у одного из двух оставшихся на скамье подсудимых, шпион ли его сосед. Тот ответил односложно («да» или «нет»), после чего судья с уверенностью установил, кто шпион.

Пока ты еще не можешь определить, кто шпион, сказал Король Алисе, необходимы дополнительные данные.

Слушай, что было дальше.

Мистер Энтони рассказал о процессе своему другу, по профессии адвокату. Разобравшись в деле, друг сказал: Я считаю, что данных недостаточно. Не мог бы ты сообщить мне по крайней мере, одинаковые ли ответы получил судья на все три вопроса? Мистер Энтони ответил. Смог ли адвокат решить после этого задачу, неизвестно.

При случае мистер Энтони задал ту же логическую задачу другому своему приятелю, по профессии также адвокату. Выслушав обстоятельства дела, этот приятель спросил: Получил ли судья по крайней мере два отрицательных ответа на свои вопросы? Мистер Энтони удовлетворил любознательность своего приятеля, но смог ли тот после этого решить задачу, неизвестно. Зато известно, продолжал Король, что эту логическую задачу либо решили, либо не решили оба приятеля мистера Энтони.

А теперь, сказал в заключение Король, я хочу спросить тебя, кто же был шпионом? Разве такую задачу можно решить? — вскричала в изумлении Алиса. Да, вполне, ответил Король. Торжественно заверяю тебя в этом.

prolog язык программирование логический

Листинг

персонаж = персонаж(имя,тип)

ответ,имя,тип = symbol

список_ответов = ответ*

список_типов = тип*

список_персонажей = персонаж*

процесс = процесс(список_персонажей,ответ,ответ,имя,ответ)

вердикт = вердикт(персонаж,процесс)

список_процессов = процесс*

список_вердиктов = вердикт*

номер = integer

количество = integer

PREDICATES

nondeterm один_из(персонаж,список_персонажей)

nondeterm один_из(тип,список_типов)

nondeterm один_из(процесс,список_процессов)

nondeterm один_из(вердикт,список_вердиктов)

nondeterm количество_вхождений(ответ,список_ответов,количество)

nondeterm количество_элементов(список_вердиктов,количество)

nondeterm выбрать_уникальные(список_вердиктов,список_вердиктов);

nondeterm выбрать_уникальные(список_персонажей,список_персонажей);

nondeterm пересечение(список_вердиктов,список_вердиктов,список_вердиктов)

nondeterm один_из_ответов(ответ)

nondeterm один_из_участников(имя)

nondeterm сказал(персонаж,номер,процесс)

nondeterm проверка(персонаж,номер,процесс)

nondeterm шпион(имя,список_процессов,список_процессов)

nondeterm не_шпион(имя,список_процессов,список_процессов)

nondeterm исключить_невозможные_ответы(список_процессов,список_процессов,список_процессов)

nondeterm не_возможен(процесс,список_процессов)

nondeterm исключить_подозреваемого(имя,список_персонажей,список_персонажей)

nondeterm гипотеза(процесс)

nondeterm суд1(процесс)

nondeterm суд2(процесс)

nondeterm конец_суда(вердикт)

nondeterm подсказка1(вердикт,ответ)

nondeterm подсказка2(вердикт,ответ)

nondeterm решение1(список_вердиктов)

nondeterm решение2(список_вердиктов)

nondeterm итог(персонаж)

nondeterm уникальный_итог(персонаж)

CLAUSES

один_из(Что,[Что|_]).

один_из(Что,[_|Хвост]):-один_из(Что,Хвост).

%Количество

количество_вхождений(_,[],0).

количество_вхождений(Что,[Что|Хвост],Число) :-

количество_вхождений(Что,Хвост,Число_в_хвосте),

Число = Число_в_хвосте+1.

количество_вхождений(Что,[Нечто|Хвост],Число) :-

not(Что = Нечто),

количество_вхождений(Что,Хвост,Число).

количество_элементов([],0).

количество_элементов([_|Хвост_Списка],Количество):-

количество_элементов(Хвост_Списка,Количество_в_хвосте),

Количество=Количество_в_хвосте+1.

%Поиск пересечения множеств

пересечение([],_,[]).

пересечение([Head1|Tail1],List2,[Head1|TailOut]) :-

один_из(Head1,List2),пересечение(Tail1,List2,TailOut).

пересечение([Head1|Tail1],List2,ListOut) :-(один_из(Head1,List2)),пересечение(Tail1,List2,ListOut).

один_из_ответов(да).

один_из_ответов(нет).

один_из_участников(а).

один_из_участников(б).

один_из_участников(в).

выбрать_уникальные([],[]).

выбрать_уникальные([Голова|Хвост],[Голова|ХвостУ]) :-

not(один_из(Голова,Хвост)),выбрать_уникальные (Хвост,ХвостУ).

выбрать_уникальные([Голова|Хвост],СписокУ) :-

один_из(Голова,Хвост),выбрать_уникальные(Хвост,СписокУ).

сказал(персонаж(а,Тип),1,процесс(_,Ответ,_,_,_)) :-

Ответ = «да», Тип = «шпион»;

Ответ = «нет», not(Тип = «шпион»).

сказал(персонаж(б,_),1,Процесс) :-

Процесс = процесс(Персонажи,_,Ответ,_,_),

Ответ = «да», А = персонаж(а,_), один_из(А,Персонажи), сказал (А,1,Процесс);

Процесс = процесс(Персонажи,_,Ответ,_,_),

Ответ = «нет», А = персонаж(а,_), один_из(А,Персонажи), not(сказал (А,1,Процесс)).

сказал(Персонаж,2,Процесс) :-

Процесс = процесс(Персонажи,_,_,_,Ответ),

Ответ=»да», один_из(Сосед,Персонажи), not(Сосед = Персонаж), Сосед = персонаж(_,шпион);

Процесс = процесс(Персонажи,_,_,_,Ответ),

Ответ=»нет», один_из(Сосед,Персонажи), not(Сосед = Персонаж), Сосед = персонаж(_,Тип), not(Тип = «шпион»).

проверка(Персонаж,Номер,Процесс) :- Персонаж = персонаж(_,рыцарь),сказал(Персонаж,Номер,Процесс).

проверка(Персонаж,Номер,Процесс) :- Персонаж = персонаж(_,лжец),not(сказал(Персонаж,Номер,Процесс)).

проверка(Персонаж,_,_) :- Персонаж = персонаж(_,шпион).

исключить_подозреваемого(_,[],[]).

исключить_подозреваемого(Имя,[персонаж(Имя,_)|InT],OutList) :- исключить_подозреваемого(Имя,InT,OutList).

исключить_подозреваемого(Имя,[InH|InT],[InH|OutT]) :- not(InH = персонаж(Имя,_)),исключить_подозреваемого

(Имя,InT,OutT).

гипотеза(Процесс) :-

ПерсонажА = персонаж(а, ТипА),

один_из(ТипА,[рыцарь,лжец,шпион]),

ПерсонажБ = персонаж(б,ТипБ),

один_из(ТипБ,[рыцарь,лжец,шпион]), not(ТипБ = ТипА),

ПерсонажВ = персонаж(в,ТипВ),

один_из(ТипВ,[рыцарь,лжец,шпион]), not(ТипВ = ТипА),not(ТипВ = ТипБ),

один_из_ответов(Ответ1),один_из_ответов(Ответ2),

один_из_участников(ДалОтвет3),один_из_ответов(Ответ3),

Персонажи = [ПерсонажА,ПерсонажБ,ПерсонажВ],

Процесс = процесс(Персонажи,Ответ1,Ответ2,ДалОтвет3,Ответ3).

суд1(Процесс) :-

гипотеза(Процесс), Процесс = процесс(Персонажи,_,_,_,_),

% из процесса выбираются персонажи

ПерсонажА = персонаж(а,_),один_из(ПерсонажА,Персонажи),

% выбока персонажа

проверка(ПерсонажА,1,Процесс),

% проверка что сказал перонаж А

% выборка персонажа

проверка(ПерсонажБ,1,Процесс).

% проверка что сказал перонаж Б

суд2(Процесс2) :-

findall(Процесс1,суд1(Процесс1),Результаты),

%получаем в результате список всех гипотез удовлетворяющих первым двум высказываниям

один_из_участников(Предполагаем_Не_Шпион),

шпион(Предполагаем_Не_Шпион,Результаты,Невозможные_Результаты),

исключить_невозможные_ответы(Результаты,Невозможные_Результаты,Возможные_Результаты),

один_из(процесс(Персонажи1,Ответ1,Ответ2,ДалОтвет3,Ответ3),Возможные_Результаты),

исключить_подозреваемого(Предполагаем_Не_Шпион,Персонажи1,Персонажи2),

Процесс2 = процесс(Персонажи2,Ответ1,Ответ2,ДалОтвет3,Ответ3),

Подозреваемый = персонаж(ДалОтвет3,_),один_из(Подозреваемый,Персонажи2),

проверка(Подозреваемый,2,Процесс2).

конец_суда(вердикт(Шпион,Итоговый_Результат)) :-

findall(Процесс,суд2(Процесс),Результаты),

один_из_участников(Предполагаем_Шпион),

не_шпион(Предполагаем_Шпион,Результаты,Невозможные_Результаты),

исключить_невозможные_ответы(Результаты,Невозможные_Результаты,Возможные_Результаты),

один_из(Итоговый_Результат,Возможные_Результаты),

Итоговый_Результат = процесс(Персонажи,_,_,_,_),

Шпион = персонаж(_,шпион),один_из(Шпион,Персонажи).

подсказка1(Вердикт,Ответ4) :-

Ответ4 = «да», Вердикт = вердикт(_,процесс(_,Ответ1,Ответ2,_,Ответ3)),

конец_суда(Вердикт),

Ответ1 = Ответ2, Ответ1 = Ответ3;

Ответ4 = «нет», Вердикт = вердикт(_,процесс(_,Ответ1,Ответ2,_,_)),

конец_суда(Вердикт),

not(Ответ1 = Ответ2);

Ответ4 = «нет»,Вердикт = вердикт(_,процесс(_,Ответ1,_,_,Ответ3)),

конец_суда(Вердикт),

not(Ответ1 = Ответ3);

Ответ4 = «нет»,Вердикт = вердикт(_,процесс(_,_,Ответ2,_,Ответ3)),

конец_суда(Вердикт),

not(Ответ2 = Ответ3).

подсказка2(Вердикт,Ответ5) :-

Ответ5 = «да», Вердикт = вердикт(_,процесс(_,Ответ1,Ответ2,_,Ответ3)),

конец_суда(Вердикт),

количество_вхождений(«нет»,[Ответ1,Ответ2,Ответ3],ОтветовНет),

ОтветовНет >= 2;

Ответ5 = «нет», Вердикт = вердикт(_,процесс(_,Ответ1,Ответ2,_,Ответ3)),

конец_суда(Вердикт),

количество_вхождений(«нет»,[Ответ1,Ответ2,Ответ3],ОтветовНет),

ОтветовНет < 2.

%Формируем список гипотез в которых человек с именем Имя является шпионом

шпион(_,[],[]).

%Проверка если человек с именем Имя не является шпионом, то не добавляем в исходящий список

шпион(Имя,[процесс(Персонажи,_,_,_,_)|InT],Out):-not(один_из(персонаж(Имя,шпион),Персонажи)),шпион(Имя,InT,Out).

%Проверка если человек с именем Имя является шпионом, то добавляем его в список Out

шпион(Имя,[InH|InT],[InH|OutT]):-InH = процесс(Персонажи,_,_,_,_),один_из(персонаж(Имя,шпион),Персонажи),шпион

(Имя,InT,OutT).

%Формируем список гипотез в которых человек с именем Имя не является шпионом

не_шпион(_,[],[]).

%Проверка если человек с именем Имя является шпионом, то не добавляем в исходящий список

не_шпион(Имя,[процесс(Персонажи,_,_,_,_)|InT],Out):-один_из(персонаж(Имя,шпион),Персонажи),не_шпион(Имя,InT,Out).

%Проверка если человек с именем Имя не является шпионом, то добавляем его в список Out

не_шпион(Имя,[InH|InT],[InH|OutT]):-InH = процесс(Персонажи,_,_,_,_),not(один_из(персонаж

(Имя,шпион),Персонажи)),не_шпион(Имя,InT,OutT).

%Исключение невозможных гипотез

исключить_невозможные_ответы([],_,[]):-!.

исключить_невозможные_ответы([InH|InT],Ans,Out) :- не_возможен(InH,Ans),исключить_невозможные_ответы

(InT,Ans,Out).

исключить_невозможные_ответы([InH|InT],Ans,[InH|OutT]) :- not(не_возможен(InH,Ans)),исключить_невозможные_ответы

(InT,Ans,OutT).

не_возможен(процесс(_,Ответ11,Ответ21,Имя,Ответ31),[процесс(_,Ответ11,Ответ21,Имя,Ответ31)|_]).

не_возможен(Процесс,[_|AnsT]) :- не_возможен(Процесс,AnsT).

решение1(Список_Уникальных_Решений) :-

один_из_ответов(Ответ4),findall(Решение,подсказка1(Решение,Ответ4),Список_Решений),выбрать_уникальные

(Список_Решений,Список_Уникальных_Решений).

решение2(Список_Уникальных_Решений) :-

(Список_Решений,Список_Уникальных_Решений).

решили_вместе(Решения1,Решения2,»да») :- решение1(Решения1),количество_элементов(Решения1,1),

решение2(Решения2),количество_элементов(Решения2,1).

решили_вместе(Решения1,Решения2,»нет») :- решение1(Решения1),количество_элементов(Решения1,К1),not(К1=1),

решение2(Решения2),количество_элементов(Решения2,К2),not(К2=1).

итог(Шпион) :- один_из_ответов(Решили),решили_вместе(Решения1,Решения2,Решили),

пересечение(Решения1,Решения2,ИтоговыеРешения),

один_из(Решение,ИтоговыеРешения),Решение = вердикт(Шпион,_).

уникальный_итог(Шпион) :- findall(Персонаж, итог(Персонаж), Список_Решений), выбрать_уникальные

(Список_Решений,Список_Уникальных_Решений), один_из(Шпион,Список_Уникальных_Решений).

GOAL

уникальный_итог(Шпион).

Вывод

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

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

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

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

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

от 25%

Подписываем

договор

Оглавление

Введение ………………………………….……………..……………….…..2 стр.

1.История создания и развития языка Prolog ………………………….…… 3 стр.

2. Сферы использования ………………..……….…….……….…………… 4 стр.

3. Среда разработки «SWIProlog«…………….……………….…………… 5 стр.

4. Среда разработки «Тurbo Prolog» ………………………..………..………22 стр.

5. Среда разработки « Visual Prolog » ..…………………….…….…………..28 стр.

6. Заключение  ..…………………………………………….…………….…..32 стр.

7. Глоссарий терминов ……………………………………………………….33 стр.

8. Список литературы………………………………………………………..35 стр.

Введение

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

Логическое программирование — это подход к информатике, при котором в качестве языка высокого уровня используется логика предикатов первого порядка в форме фраз Хорна. Логика предикатов первого порядка — это универсальный абстрактный язык предназначенный для представления знаний и для решения задач. Его можно рассматривать как общую теорию отношений. Логическое программирование базируется на подмножестве логики предикатов первого порядка, при этом оно одинаково широко с ней по сфере охвата. Логическое программирование дает возможность программисту описывать ситуацию при помощи формул логики предикатов, а затем, для выполнения выводов из этих формул, применить автоматический решатель задач (т. е. некоторую процедуру). При использовании языка логического программирования основное внимание уделяется описанию структуры прикладной задачи, а не выработке предписаний компьютеру о том, что ему следует делать. Другие понятия информатики из таких областей, как теория реляционных баз данных, программная инженерия и представление знаний, также можно описать (и, следовательно, реализовать) с помощью логических программ. Однако вернемся к языку Prolog: первая часть введения посвящена истории языка Prolog.

  1.  История создания и развития языка Prolog

Разработка языка Prolog началась в 1970 году Аланом Кулмероэ и Филиппом Расселом. Их целью было создание языка, который мог бы делать логические заключения на основе заданного текста. Название Prolog является сокращением от «Programming in logic». Итак, Prolog, как язык, был разработан в Марселе в 1972 году. Предварительно на основе некоторого «принцип резолюции» Ковальского, сотрудника Эдинбургского университета, была создана модель, на основе которой и был разработан механизм логических выводов.

Первая реализация языка Prolog с использованием компилятора Никлауса Вирта «Algol-W» была закончена в 1972 году, а основы современного языка были заложены позднее, в 1973 г. Использование языка Prolog постепенно распространялось среди тех, кто занимался логическим программированием, в основном благодаря личным контактам, а не через коммерциализацию продукта. В настоящее время существует несколько различных, но довольно похожих между собой версий языка. Хотя стандарта языка Prolog не существует, однако версия, разработанная в Эдинбургском университете, стала наиболее широко используемым вариантом.

Теория логического программирования со временем совершенствовалась. Существенный вклад в ее развитие внесла работа Р. Ковальского «Логика предикатов как язык программирования». В 1976 г. Ковальский и М. ван Эмден предложили два подхода к прочтению текстов логических программ — процедурный и декларативный. Оба этих подхода стали активно использоваться при написании программ на языке Prolog.

Только в 1977 году Д. Уоррен и Ф. Перейра создают в университете Эдинбурга интерпретатор/компилятор языка Prolog для ЭВМ DEC-10, тем самым переведя методы логического программирования в практическую плоскость. Позднее в 1980 году К. Кларк и Ф. Маккейб в Великобритании разработали версию Prolog для персональных ЭВМ.

Также есть интересный факт: в октябре 1981 года мир облетела новость о японском проекте создания ЭВМ пятого поколения. В основу методологии разработки программных средств было положено логическое программирование. Целью проекта декларировалось создание систем обработки информации, базирующихся на знаниях, а главным средством реализации должен был стать именно язык Prolog. В это же время (начало 1980-х годов) появляется множество коммерческих реализаций Prolog практически для всех типов компьютеров. К наиболее известным можно отнести «Visual Prolog», «Тurbo Prolog», «SWI-Prolog». и др.

Существует мнение, что Prolog — уже почти умерший язык, что он за небольшой промежуток времени (1970-1980-е годы) смог пройти весь жизненный цикл — от начальных разработок, стремительного повышения интереса со стороны узких специалистов, затем стремительный взлет популярности, падение интереса и почти полное забвение. Мнение вызвано тем, что такая судьба — обычное явление в мире информационных технологий, где новые, более совершенные, дидактически верные и теоретически более красивые языки программирования возникают каждый год и тихо умирают. Сторонники мнения аргументируют его тем, что структура Prolog-программ очень трудна для восприятия из-за того, что иногда невозможно визуально предугадать ход логического вывода — единственный предикат-факт, запрятанный где-то в конце текста программы, может направить работу в совершенно непредсказуемое русло. В некотором они правы: трудность сопровождения Prolog-программ и трудность мышления на Prolog для рядовых программистов оказались непреодолимыми препятствиями для его широкого распространения. Да и, конечно, во времена разработки Prolog ждали от него большего, но потом оказалось, что сам по себе язык программирования помочь в решении серьезнейших задач, например, связанных с принятием компьютером решений (machine reasoning), не может. Но всё же язык Prolog используется и сегодня при решении целого класса достаточно специфических задач.

  1.  Сферы использования

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

Для Prolog это задачи, связанные с разработкой систем искусственного интеллекта (различные экспертные системы, программы-переводчики, интеллектуальные игры). Он используется для обработки естественного языка и обладает мощными средствами, позволяющими извлекать информацию из баз данных, причем методы поиска, используемые в нем, принципиально отличаются от «традиционных».

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

Prolog используется в различных системах, но обычно не в качестве основного языка, а в качестве языка для разработки некоторой части системы. Так Prolog достаточно часто используется для написания функций взаимодействия с базами данных. Prolog используется при разработки расширенных поисковых систем, то есть систем, которые не просто занимаются поиском текста (поиск текста — задача техническая, инженерная), но и играют роль некоторой «отвечающей системы» — программного комплекса, который умеет извлекать информацию (знания) из большой выборки текстовых файлов, а затем вести диалог с пользователем, отвечая (в обычном понимании этого слова) на вопросы посвященный этой теме. Почему в таком случае используется именно Prolog, а не какой-либо другой язык? Потому что именно он разрабатывался для задач, связанных с так называемым «искусственным интеллектом».

Также Prolog используется при написании новых специфичных языков программирования. Например, функциональный язык Erland постороен на основе Prolog. По сути, Erland является усовершенствованием Prolog для некоторых специфических целей, связанных с задами реального времени.

Некоторые приложения в таких областях, как экспертные системы, планирование, машинное обучение, так называемый «искусственный интеллект» игр, реализованы именно с помощью Prolog. Так что, несмотря на то, что сферы использования этого языка, хоть и не так велики и обширны, как сферы применения «традиционных» языков (C, Java и т.п.), представляют свой интерес.

  1.  Среда разработки «SWI-Prolog»

Интерактивная среда разработки «SWI-Prolog» была разработана в Swedish Institute of Computer Science, отсюда происходит и название этой версии.

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

Программа интерпретатора языка Пролог выполняет следующие функции:

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

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

  1.  создание нового файла программы;
  2.  открытие существующего файла программы;
  3.  сохранение файла;
  4.  сохранение файла под новым именем;
  5.  выход из системы;
  6.  редактирование файла с использованием буфера обмена;
  7.  настройку параметров программы Пролог;
  8.  настройку редактора;
  9.  запуск программы на исполнение;
  10.  временную остановку работы программы;
  11.  доступ к файлу справки.

Определение отношений

В отличие от других языков программирования Prolog не является универсальным языком программирования. Он ориентирован на решение задач с использованием исчисления предикатов. Напомним, что предикатом в логике называется понятие, определяющее предмет суждения (субъект) и раскрывающее его содержание.

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

Язык Prolog, как интерпретатор, приглашает пользователя вводить информацию. Пользователь набирает запрос или имя функции. Выводится значение (истина — yes, или ложь — no) этого запроса, а также возможные значения переменных запроса, присвоение которых делает запрос истинным (то есть унифицирует запрос). Если ввести символ «;», тогда отображается следующий набор значений переменных, унифицирующий запрос, и так до тех пор, пока не исчерпается весь набор возможных подстановок, после чего Prolog печатает no и ждет следующего запроса. Возврат каретки воспринимается как прекращение поиска дополнительных решений.

Хотя выполнение программы на языке Prolog основывается на спецификации предикатов, оно напоминает выполнение программ на аппликативных языках LISP или ML Разработка правил языка Prolog требует того же рекурсивного мышления, что и разработка программ на этих аппликативных языках.

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

Язык Prolog изначально призван оперировать не с числами, а с нечисловыми объектами и отношениями между ними. Например мы можем, что называется, «совершенно не стеснясь в выражениях», задать любое отношение из жизни:

street( saint-petersburg, nevskii).

street( moscow, arbat).

Как вы уже поняли отношение street( , ) задает отношение принадлежности улицы к городу. Теперь мы можем задать системе Prolog вопрос, в каком городе находится, к примеру, Невский проспект (nevskii). Причем сделаем мы это вполне ясным образом:

?- street( X, nevskii).

Система Prolog конкретизирует переменную X и выдаст ответ

X = saint-petersburg.

Но это еще не все: если Невский проспект есть и в каком-нибудь Бобруйске, и это отношение мы так же задали:

street( bobruisk, nevskii).

То в ответе на наш вопрос система Prolog укажет оба города:

X = saint-petersburg;

X = bobruisk;

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

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

Основополагающие факты, связанные с программированием на языке Prolog:

— Отношение может быть определено на основе фактов путем задания n-элементных кортежей объектов, которые удовлетворяют отношению, или путем задания правил, касающихся этого отношения.

— Процедура представляет собой набор предложений, касающихся одного и того же отношения.

— Выполнение запросов об отношениях, передаваемых системе в виде вопросов, напоминает выполнение запросов к базам данных. Ответ системы Prolog на вопрос состоит их множества объектов, которые соответствуют этому вопросу.

— В системе Prolog для определения того, соответствует ли объект вопросу, часто применяется сложный процесс, который связан с выполнением логического вывода, рассмотрением многих альтернатив и, возможно, перебора с возвратами. Все эти операции выполняются системой Prolog автоматически и, в принципе, скрыты для пользователя.

Объекты данных

Система Prolog распознает тип объекта по его синтаксической форме. Это возможно благодаря тому, что в синтаксисе языка Prolog определены разные формы для объектов данных каждого типа. Различие между атомами и переменными в том, что переменные начинаются с прописных букв, а атомы — со строчных букв. Системе Prolog не требуется сообщать какую-либо дополнительную информацию (наподобие объявления типа данных) для того, чтобы она распознала тип объекта.

Атомы представляют собой строки, состоящие из следующих символов:

прописные буквы A, B,…Z;

строчные буквы a, b, …, z;

цифры 0, 1, 2, …, 9;

специальные символы, такие как «+», «-«, «*», «/», «<«, «>», «=», «:», «.», «&», «_», «~».

Атомы могут формироваться тремя перечисленными ниже способами:

1.Как строки букв, цифр и символов подчеркивания, начинающиеся с прописной буквы: anna, x_25, alpha_beta_procedure, miss_Jones.

2.Как строки специальных символов: <—>, ===>, …, ::= (При использовании атомов в этой форме необходимо соблюдать осторожность, поскольку некоторые строки специальных символов уже имеют предопределенное значение; в качестве примера можно привести «:-«).

3.Как строки символов, заключенных в одинарные кавычки. Такой формат является удобным, если, требуется, например, применить атом, который начинается с прописной буквы. Заключив его в кавычки, можно подчеркнуть его отличие от переменных: ‘Tom’, ‘South_America’.

Числа в Prolog бывают целыми и вещественными. Синтаксис целых чисел прост, как это видно из следующих примеров: 1, 1313, 0, -97. Не все целые числа могут быть представлены в машине, поэтому диапазон целых чисел ограничен интервалом между некоторыми минимальным и максимальным числами, определяемыми конкретной реализацией Prolog. Обычно реализация допускает диапазон хотя бы от -16383 до 16383, а часто, и значительно более широкий.

Синтаксис вещественных чисел виден из следующих примеров: 3.14, -0.0035, 100.2. При обычном программировании на Prolog вещественные числа используются редко. Причина этого кроется в том, что Prolog — это язык, предназначенный в первую очередь для обработки символьной, а не числовой информации, в противоположность языкам типа Фортрана, ориентированным на числовую обработку. При символьной обработке часто используются целые числа, например, для подсчета количества элементов списка; нужда же в вещественных числах невелика.

Кроме отсутствия необходимости в использовании вещественных чисел в обычных применениях Prolog, существует и другая причина избегать их. Мы всегда стремимся поддерживать наши программы в таком виде, чтобы их смысл был предельно ясен. Введение вещественных чисел в некоторой степени нарушает эту ясность из-за ошибок вычислений, связанных с округлением во время выполнения арифметических действий.

Правила записи имен переменных

Имена переменных — это строки, состоящие из букв, цифр и символов подчеркивания. Начинаться имена переменных должны с прописной буквы или символа подчеркивания: X, Result, Answer1, _x. Область определения одной переменной представляет собой одно предложение, то есть если одно и то же имя встречается в нескольких предложениях, то в каждом из них оно означает разные переменные. В свою очередь каждое вхождение некоторой переменной в одном и том же предложении соответствует одной и той же переменной. Для констант же ситуация иная: один и тот же атом всегда обозначает во всех предложениях, а, следовательно, и во всей программе, один и тот же объект.

Структура объекта

Структурированными объектами (или структурами) называются объекты, которые имеют несколько компонентов. Сами компоненты, в свою очередь, также могут быть структурами. Например, дата может рассматриваться как структура с тремя компонентами: число, месяц, год. Несмотря на то, что структуры состоят из нескольких компонентов, они рассматриваются в программе как целостные объекты. Для соединения компонентов в целостный объект необходимо выбрать функтор. В данном примере подходящим функтором является date. Например, дату «5 декабря 2005 года» можно записать следующим образом:

date( 5, december, 2005)

Простые объекты в языке Prolog — это атомы, переменные и числа. Для представления объектов, имеющих несколько компонентов, используются структуры. Структуры создаются с помощью функторов, каждый из которых определяется своим именем и арностью. При этом, тип объекта распознается системой Prolog исключительно по его синтаксической форме.

Арифметические операции

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

+    — сложение

–    — вычитание

*    — умножение

/    — деление

**   — возведение в степень

//   — целочисленное деление

mod  — деление по модулю, вычисление остатка от целочисленного деления

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

?- X = 1 + 2

Система Prolog «послушно» ответит:

X = 1 + 2

а не X = 3, как следовало ожидать. Причина этого проста — выражение 1 + 2 просто обозначает терм Prolog, в котором знак + является функтором, а 1 и 2 — его параметрами. В приведенной выше цели нет ничего, что могло бы вынудить систему Prolog фактически активизировать операцию сложения. Для определения этой проблемы предусмотрена специальная предопределенная операция is. Операция is вынуждает систему выполнить вычисление, поэтому правильный способ вызова арифметической операции состоит в следующем:

?- X is 1 + 2

В этом случае будет получен ответ:

X = 3

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

Кроме того, в Prolog предусмотрены такие стандартные функции, как sin(x), cos(x), atan(x), log(x), exp(x) и т.д. Эти функции могут находиться справа от знака операции is.

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

Ниже перечислены операции сравнения:

X > Y.    — X больше Y.

X < Y.    — X меньше Y.

X >= Y.   — X больше или равен Y.

X =< Y.   — X меньше или равен Y.

X =:= Y.  — Значения X и Y равны.

X == Y.  — Значения X и Y не равны.

Списки

Одной из наиболее полезных, но, тем не менее, простых, структур считается список. Списки широко используются в нечисловом программировании, поскольку они представляют собой последовательности, состоящие из любого количества элементов. Как и все структуры, списки представляются системой Prolog в виде дерева, вершиной которого является первый элемент списка. Кстати, список может быть пустым — тогда он записывается в виде атома [], в остальных же случаях список можно рассматривать как объект, состоящий из двух компонентов: головы списка (первый компонент), хвост (остальная часть списка). В общем случае, головой может быть что угодно (любой объект Prolog, например, дерево или переменная); хвост же должен быть списком. Голова (Head) соединяется с хвостом (Tail) при помощи специального функтора:

.( Head, Tail)

Поскольку Tail — это список, он либо пуст, либо имеет свои собственную голову и хвост. Таким образом, выбранного способа представления списков достаточно для представления списков любой длины.

Важно то, что над списком можно проводить некоторые операции, среди которых:

-проверка, является ли некоторый объект элементом списка, что соответствует проверке объекта на принадлежность множеству;

-конкатенация двух списков, что соответствует объединению множеств;

-добавление нового объекта в список или удаление некоторого объекта из него.

Описание этих операций на языке Prolog достаточно понятно для тех, кто знаком с рассматриваемой структурой, поэтому здесь приведем в качестве примера лишь операцию принадлежности к списку. Представим отношение принадлежности как member( X, L), где Х — объект, а L — список. Цель member( X, L) истинна, если элемент Х встречается в L. Например, верно что member( b, [а, b, с] ) и, наоборот, не верно, что member( b, [а, [b, с] ] ), но member( [b, с], [а, [b, с]] ) истинно. Поэтому программа проверки отношения принадлежности к списку может быть основана на приведенных ниже рассуждениях.

X входит в состав L, если истинно одно из утверждений:

1) Х есть голова L, либо

2) Х принадлежит хвосту L.

Эту программу можно записать в виде двух предложений, первое из которых есть простой факт, а второе — правило:

member( X, [X | Tail] ).

member( X, [Head | Tail] ) :- member( X, Tail).

Ввод и вывод

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

Поэтому этот основной метод обмена данными необходимо дополнить в следующих областях:

-Ввод данных в форматах, отличных от вопросов, например в форме английских предложений;

-Вывод информации в любом требуемом формате;

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

Обмен данными с несколькими файлами.

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

В любой момент времени в ходе выполнения программы Prolog «активны» только два файла: один для ввода, а другой для вывода. Эти два файла, соответственно, называются текущим входным потоком и текущим выходным потоком. В начале выполнения программы эти два потока соответствуют пользовательскому терминалу.

Файлы могут обрабатываться в языке Prolog двумя основными способами, в зависимости от формы представления в них информации. Один из способов состоит в том, что основным элементом файла является символ. В соответствии с этим один запрос на ввод и вывод вызывает чтение или запись единственного символа, для этого служат встроенные предикаты get, get0 и put.

Еще один способ обработки файлов состоит в том, что в качестве основных структурных блоков файла рассматриваются более крупные информационные единицы. Вполне естественно, что в качестве такой более крупной единицы, принят терм потока или в текущий выходной поток передается, соответственно, целый терм. Предикатами для передачи термов являются read и write. Разумеется, в этом случае информация в файле должна находиться в форме, совместимой с синтаксисом термов.

Встроенный предикат read используется для чтения термов из текущего входного потока, а цель read( X) вызывает чтение следующего терма, T, и согласование этого терма с X. Если X представляет собой переменную, то в результате X становится конкретизированной значением T, а если согласование оканчивается неудачей, цель read( X) не достигается.

Предикат read является детерминированным, поэтому в случае неудачи не выполняется перебор с возвратами для ввода другого терма. За каждым термом во входном файле должны следовать точка и пробел (или символ с обозначением конца строки).

Если предикат read( X) вызывается на выполнение после достижения конца текущего входного файла, то переменная X становится конкретизированной значением атома end_of_file.

Встроенный предикат write выводит терм, поэтому цель write( X) выводит терм X в текущий выходной файл. Терм X выводится в такой же стандартной синтаксической форме, в которой Prolog обычно отображает значения переменных. Полезным средством языка Prolog является то, что процедура write «умеет» отображать любые термы, независимо от того, насколько они могут быть сложными.

Принципы программирования на языке Prolog

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

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

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

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

Программируя на языке Prolog, нельзя забывать о его встроенных средствах, которые в случае грамотного использования, позволяют значительно упростить программу. Прежде всего, речь идёт об использовании рекурсии. Одна из причин того, что рекурсия так естественна для определения отношений на Prolog, состоит в том, что объекты данных часто сами имеют рекурсивную структуру. К таким объектам относятся списки и деревья. Список либо пуст (граничный случай), либо имеет голову и хвост, который сам является списком (общий случай). Двоичное дерево либо пусто (граничный случай), либо у него есть корень и два поддерева, которые сами являются двоичными деревьями (общий случай). Поэтому для обработки всего непустого дерева необходимо сначала что-то сделать с его корнем, а затем обработать поддеревья.

Часто бывает полезно обобщить исходную задачу таким образом, чтобы полученная более общая задача допускала рекурсивную формулировку. Исходная задача решается, тогда как частный случай ее более общего варианта. Обобщение отношения обычно требует введения одного или более дополнительных аргументов. Главная проблема состоит в отыскании подходящего обобщения, что может потребовать более тщательного изучения задачи.

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

Использование графического представления при решении задач полезно всегда, однако похоже, что в Prolog оно работает особенно хорошо. Происходит это по следующим причинам:

1.Prolog особенно хорошо приспособлен для задач, в которых фигурируют объекты и отношения между ними. Часто такие задачи естественно иллюстрировать графами, в которых узлы соответствуют объектам, а дуги — отношениям.

2.Естественным наглядным изображением структурных объектов Prolog являются деревья.

3.Декларативный характер Prolog-программ облегчает перевод графического представления на Prolog. В принципе, порядок описания «картинки» не играет роли, мы просто помещаем в программу то, что видим, в произвольном порядке.

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

Prolog как язык для работы с базой данных

Использования языка Prolog в системе, оперирующей базой данных, например, в словаре. Коротко опишем структуру такого словаря. Вся хранимая информация в словаре является по сути своей реляционной базой данных (РБД). Например, есть список словарных статей. У каждой статьи есть свой уникальный код (primary key в терминологии РБД). Это целое число, которое однозначно идентифицирует статью в лексиконе. Более того, так как этот код присваивается статье при ее создании и не зависит от индекса статьи в списке, то оказывается возможным в ходе компиляции, например, продукционного правила запомнить ключ статьи — и в ходе выполнения правила оперировать именно ключами статей.

Аналогичный подход применяется для хранения любой другой информации в словаре. Грамматические координаты представляют собой именованные списки значений. Координатная пара — это имя координаты и имя состояния. В словаре координатная пара представляется двумя целыми числами — индексом координаты и индексом состояния. В данном случае вместо абстрактных ключей используется физический индекс элемента во внутреннем списке. Это упрощает работу и ускоряет доступ, но накладывает ограничения: после компиляции словаря нельзя менять списки с описаниями координат.

При работе грамматического конвейера использование ключей вместо самих описаний (например, вместо строковых констант) позволяет значительно увеличить эффективность — сравнение целых чисел в любом случае быстрее сравнения текстовых строк. Все это, однако, внутреннее устройство, которое внешне ничем себя не выдает. Манипуляции с записями во внутренних таблицах происходят под управлением алгоритмов, которые конструкции языка Prolog переводят в запросы к БД.

Но есть часть системы — Prolog-автомат — которая и внутренне и внешне является настоящей СУБД. Может показаться странным использование достаточно экзотичного языка вместо индустриального стандарта SQL. Тому есть простое объяснение. Prolog прост и в смысле описания (в принципе, это пара десятков страниц с примерами), и в смысле реализации. Движок SQL-базы данных очень сложен, начиная от парсера выражений (синтаксис SQL достаточно витиеват и разнообразен), и заканчивая необходимостью писать планировщик-оптимизатор запросов, который будет строить алгоритм доступа к данным для каждого поступающего SELECT, UPDATE и DELETE. Кроме этого, средства процедурного программирования — различные языки (например, PL/SQL или TSQL) — сами являются предметом отдельного изучения со своим синтаксисом и идеологией.

Prolog предлагает однородные средства как описания данных, так и доступа к ним. SQL таблицам прямо соответствуют предикаты. SQL отображения (VIEW) без каких-либо усложнений языка реализуются также через предикаты-теоремы ( :- ). Процедуры для работы с множествами записей в Prolog реализуются просто через AND-связку команд-предикатов.

Чтобы получить список сущностей, относящихся к типу action, в общем случае на SQL надо написать:

SELECT E.desc

FROM ENTITY E, ENTYTY_TYPE T

WHERE T.desc = ‘action’ AND E.id_type = T.id;

На Prolog этот запрос выглядит так:

subject( Sbj) :- entity_type( Id_type, «action»), entity( _, Sbj, Id_type)?

Различия невелики, она даже скорее формальны. К примеру, для подсчета записей о сущностях типа action потребуется минимальные дополнения в оба кода: SELECT COUNT(E.desc) … и count( subject(_), C )?

В данном случае count/2 — это встроенный предикат расширенного Prolog, который функционально аналогичен оператору COUNT языка SQL.

Разумеется, язык SQL предлагает некоторые мощные средства обеспечения целостности данных, которые отсутствуют в стандартном Prolog. Primary keys и foreign keys — удобные и эффективные способы гарантировать, что в БД не появятся записи, ссылающиеся на отсутствующие данные в других таблицах. Чтобы компенсировать этот изъян Prolog, в него были введены некоторые средства. В частности, с помощью встроенных предикатов можно объявлять требования к таблицам, то есть предикатам-записям одинаковой структуры и с одинаковым корневым атомом.

Построение экспертной системы с помощью языка Prolog

Экспертная система – это программа, которая ведет себя подобно эксперту в некоторой, обычно узкой, прикладной области. Типичные применения экспертных систем включают в себя такие задачи, как медицинская диагностика, локализация неисправностей в оборудовании и интерпретация результатов измерений. Экспертные системы должны решать задачи, требующие для своего решения экспертных знаний в некоторой конкретной области. В той или иной форме экспертные системы должны обладать этими знаниями. Поэтому их также называют системами, основанными на знаниях. Однако не всякую систему, основанную на знаниях, можно рассматривать как экспертную. Экспертная система должна также уметь каким-то образом объяснять свое поведение и свои решения пользователю, так же, как это делает эксперт-человек. Это особенно необходимо в областях, для которых характерна неопределенность, неточность информации (например, в медицинской диагностике). Часто к экспертным системам предъявляют дополнительное требование — способность иметь дело с неопределенностью и неполнотой.

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

1.решение задач с использованием знаний о конкретной предметной области — возможно, при этом возникнет необходимость иметь дело с неопределенностью

2.взаимодействие с пользователем, включая объяснение намерений и решений системы во время и после окончания процесса решения задачи.

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

1.база знаний,

2.машина логического вывода,

3.интерфейс с пользователем.

База знаний содержит знания, относящиеся к конкретной прикладной области, в том числе отдельные факты, правила, описывающие отношения или явления, а также, возможно, методы, эвристики и различные идеи, относящиеся к решению задач в этой прикладной области. Машина логического вывода умеет активно использовать информацию, содержащуюся в базе знаний. Интерфейс с пользователем отвечает за бесперебойный обмен информацией между пользователем и системой; он также дает пользователю возможность наблюдать за процессом решения задач, протекающим в машине логического вывода. Принято рассматривать машину вывода и интерфейс как один крупный модуль, обычно называемый оболочкой экспертной системы, или, для краткости, просто оболочкой.

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

1.Выбрать формальный аппарат для представления знаний.

2.Разработать механизм логического вывода, соответствующий этому формализму.

3.Добавить средства взаимодействия с пользователем.

4.Обеспечить возможность работы в условиях неопределенности.

В качестве кандидата на использование в экспертной системе можно рассматривать, в принципе, любой непротиворечивый формализм, в рамках которого можно описывать знания о некоторой проблемной области. Однако самым популярным формальным языком представления знаний является язык правил типа «if-else» (или кратко: «if-else»-правил), называемых также продукциями. Каждое такое правило есть, вообще говоря, некоторое условное утверждение, но возможны и различные другие интерпретации. Кроме того, они обладают следующими привлекательными свойствами:

1.Модульность: каждое правило описывает небольшой, относительно независимый фрагмент знаний.

2.Возможность инкрементного наращивания: добавление новых правил в базу знаний происходит относительно независимо от других правил.

3.Удобство модификации (как следствие модульности): старые правила можно изменять и заменять на новые относительно независимо от других правил.

4.Применение правил способствует прозрачности системы.

Правила, содержащиеся в базе знаний, имеют вид

RuleName :: if Condition then Conclusion.

Где Conclusion (Заключение) — это простое утверждение, а Condition (Условие) — это набор простых утверждений, соединенных между собой операторами и и или.

Разработка оболочки. Если придерживаться правилам в том виде, в котором  они заданы, сразу видна, что они по своему смыслу эквивалентны правилам Prolog. Однако, с точки зрения синтаксиса Prolog, эти правила в том виде, как они написаны, соответствуют всего лишь фактам. Для того, чтобы заставить их работать, самое простое, что может прийти в голову, это переписать их в виде настоящих Prolog-правил. Тогда программа сможет отвечать на запросы, руководствуясь фактами, находящимися в нашей базе данных. Но в этом случае, хотя Prolog-система и отвечает на вопросы, используя для этого нашу базу знаний, нельзя сказать, что ее поведение вполне соответствует поведению эксперта. Это происходит по крайней мере по двум причинам:

1.Система не может объяснить свой ответ.

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

Для того чтобы исправить эти два недостатка,  система нуждается в более совершенном способе взаимодействия между пользователем и системой во время и после завершения процесса рассуждений. Интерпретатор должен принимать вопрос и искать на него ответ. Язык правил допускает, чтобы в условной части правила была and/or-комбинация условий. Вопрос на входе интерпретатора может быть такой же комбинацией под вопросов.

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

Множество появляющихся направлений в интернет-бизнесе приносит пользу в виде  развития логических языков программирования. Обмен данными между системами, совершенно отличающимися друг от друга, а также изощренность таких систем приводит к тому, что использование «обычных» языков программирования становится слишком сложным для решения поставленных задач. На помощь «приходят»  такие языки, как Prolog. Чтобы проиллюстрировать возможности языка Prolog, рассмотрим интернет-проект http://www.yourbet.com и применение Prolog для решения проблем поставленных проектом.

Проект http://www.yourbet.com представляет собой online-букмекер. Он предоставляет такие услуги, как online видео и аудио трансляции, отображение в режиме реального времени текущих результатов скачек и заключение букмекерских пари. Он предоставляет доступ к 60 ипподромам таких стран, как США, Канада и Австралия. Получить доступ к сервису можно или через web браузер, или скачав специальное приложение, которое доступно для скачивания на сайте.

Для быстрого обмена данными и доступа к базе данных используется связка «Java плюс Prolog». Следует отметить, что использование одновременно процедурного и логического языков программирования в разработке проекта сложно для программиста, так как стили мышления на этих двух типах языков различаются очень сильно. Но Java в данной связке используется только, как инструмент, для преобразования информации в такой вид, который будет «удобен для понимания» модулем, написанном на Prolog.

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

Рассмотрим основы реализации такой системы. Сам процесс обработки информации можно поделить на пять частей:

1.Внешний сервер посылает сообщения, содержащие информацию с ипподромов.

2.Java-сервер принимает сообщения и вызывает обработчик.

3.Сообщение по особым правилам приводится к «необработанному» XML виду.

4.Из «необработанного» XML вида оно переводится в «специфический» XML вид.

5.В этом «специфическом» XML виде сообщение передается уже к серверу, где запущено основное приложение, обрабатывающему информацию в реальном времени.

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

Например, в XML некоторый отрывок из сообщения выглядит так:

<odds track=’AQUEDUCT’ race=’3’ type=’WIN’>

   <entry horse=’1’ value=’3-2’/>

   <entry horse=’2’ value=’5-1’/>

</odds>

что эквивалентно следующей структуре на Prolog:

odds([track(‘AQUEDUCT’),race(3),type(‘WIN’)],[

  entry([horse(1),value(‘3-2’)],[]),

  entry([horse(1),value(‘3-2’)],[])])

Трудно себе представить успешный интернет-бизнес, который не требует выполнение таких задач, как обмен большим количеством информации, которая может быть при этом разной по своей «природе», и последующей фильтрации данной информации. Учитывая суть поставленной задачи, а также сложность реализации её на процедурных языках программирования, программист для ее решения применяет логический язык программирования, например, такой как Prolog.

Проект http://www.yourbet.com применил технологии так называемого «искусственного интеллекта» и общей архитектуры, чтобы развить подход к решению проблемы, который связывает Prolog и технологии обмена данными вместе. Такой подход позволяет эффективно решать данные проблемы в контексте пользовательских программ.

Таким образом, можно сделать вывод, что при надобности Prolog можно использовать в самых различных областях, разумеется, прежде всего, в качестве языка для написания некоторого «интеллектуального» ядра, обрабатывающего информацию и выдающего ответы на запросы по этой информации.

  1.  Среда разработки «Тurbo Prolog«

Наибольшую популярность получила система программирования Turbo Prolog — коммерческая реализация языка для IBM-совместимых ПК. Его первая версия была разработана датской компанией Prolog Development Center (PDC) в содружестве с фирмой Borland International в 1986 г. Система создавалась с серьезными отступлениями от неофициального стандарта языка, самым существенным из которых было введение строгой типизации данных, но это позволило значительно ускорить трансляцию и выполнение программ. Новый компилятор сразу же был по достоинству оценен праграммистами-практиками, хотя и вызвал критику в академических кругах.

Турбо-Пролог является компиляторно-ориентированным языком программирования высокого уровня. Он предназначен для программирования задач из области искусственного интеллекта. Как язык программирования ИИ Турбо-Пролог особенно хорош для создания экспертных систем, динамических баз данных, программ с применением естественно-языковых конструкций. Он также может быть использован и для других задач общего характера. Турбо-Пролог имеет окна, цветную графику и интерактивные средства ввода-вывода. Встроенные предикаты Турбо-Пролога и другие дополнительные возможности делают его пригодным для решения многих стандартных задач из сферы бизнеса, включая бухгалтерский учет, расчет зарплаты и представление графиков.

Наряду с Турбо-Прологом в США были созданы еще несколько реализаций Пролога: Arity Prolog, Prolog II, Wisdom Prolog и Micro Prolog. В отличие от них Турбо-Пролог имел великолепный полноэкранный редактор, множество рабочих окон и интерактивный диалоговый отладчик. Он поддерживал цветную графику IBM PC, снабженного цветным графическим адаптером (CGA) и расширенным графическим адаптером (EGA). Предикаты графики и система с графическим экранным пером являются составной частью Турбо-Пролога. Он также был снабжен средствами работы с последовательными файлами, файлами прямого доступа и двоичными файлами.

Такие языки программирования, как Паскаль, Бэйсик и Си относятся к разряду императивных или процедурных. Программа, написанная на императивном языке, состоит из последовательности команд, определяющих шаги, необходимые для достижения назначения программы. Пролог является декларативным языком. Программа на декларативном языке являет собой набор логический описаний, определяющих цель, ради которой она написана. Таким образом, в Прологе отсутствуют такие явные управляющие структуры, как DO WHILE и IF … THEN. Вместо расписывания шагов выполнения программы программист должен определить логический метод для достижения цели программы. Мощные внутренние унификационные процедуры  будут затем искать решение поставленной задачи.

Турбо-Пролог — это осуществленная реализация языка программирования высокого уровня Пролог компиляторного типа. Ее отличает большая скорость компиляции и счета. Турбо-Пролог предназначен для выдачи ответов, которые он логически выводит при посредстве своих мощных внутренних процедур. Так, программа на Турбо-Прологе в несколько строк, может заменить несколько страниц текста при программировании на каком-либо другом языке. Благодаря наличию мощных средств сопоставления, Турбо-Пролог пригоден не только для использования в приложениях, относящихся к области искусственного интеллекта и обработке естественно-языковых конструкций, но также применим в таких традиционных областях, как, например, управление базами данных.

В 1988 г. вышла значительно более мощная версия Turbo Prolog 2.0, включающая усовершенствованную интегрированную среду разработки программ, быстрый компилятор и средства низкоуровневого программирования. Кроме того, она предоставляла возможность работы с собственными внешними БД, dBase III и Reflex, интегрированным пакетом Lotus 1-2-3, графическим пакетом Paint Brush и другими приложениями. Фирма Borland распространяла эту версию до 1990 г., а затем компания PDC приобрела монопольное право на использование исходных текстов компилятора и дальнейшее продвижение системы программирования на рынок под названием PDC Prolog. В июне 1992 г. появилась версия 3.31 — эффективный универсальный инструмент профессиональных программистов, который вскоре стал одним из наиболее широко используемых. PDC Prolog 3.31 работал в среде  MS DOS, OS/2, UNIX, XENIX, PharLap DOS Extender, MS Windows. Эта версия была хорошо совместима с традиционными языками программирования, в первую очередь с Си. В ней были расширены возможности создания приложений с интерфейсом GUI (Graphical User Interface), принятым в MS Windows и OS/2.

Главное меню Турбо-Пролога высвечивает 7 доступных пользователю опций (команд) в верхней части экрана.

Команды определяются 7 функциями Турбо-Пролога, каковыми являются:

1. Запуск программы на счет (Run).

2. Трансляция программы (Compile).

3. Редактирование текста программы (Edit).

4. Заданий опций компилятора (Options).

5. Работа с файлами (Files).

6. Настройка системы в соответствии с индивидуальными потребностями (Setup).

7. Выход из системы (Quit).

Структура программ Турбо-Пролога

Любая программа, написанная на Турбо-Прологе, состоит из пяти разделов. Таковыми являются раздел описания доменов, раздел базы данных, раздел описания предикатов, раздел описания цели и раздел описания утверждений. Ключевые слова domains, database, predicates, goal и clauses отмечают начала соответствующих разделов. Назначение этих разделов таково:

— раздел domains содержит определения доменов, которые описывают раз-

личные классы объектов, используемых в программе;

— раздел database содержит утверждения базы данных, которые являются

предикатами динамической базы данных;

— раздел predicates служит для описания используемых программой предикатов;

— в разделе goal на языке Турбо-Пролога формулируется назначение создаваемой программы. Составными частями при этом могут являться некие подцели, из которых формируется единая цель программы;

— в раздел clauses заносятся факты и правила, известные априорно. О содержимом этого раздела можно говорить как о данных, необходимых для работы программы.

Внутренние подпрограммы унификации Турбо-Пролога

Турбо-Пролог (как и другие реализации Пролога) имеет внутренние подпрограммы для выполнения сопоставления и связанных  с ним процессов. Эти неотъемлемые части языка называются внутренними  подпрограммами унификации. Эти подпрограммы выполняют сопоставление целей и подцелей с фактами и  головами  правил  для того,  что чтобы доказать (или вычислить) эти цели или подцели.

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

Турбо-Пролог обеспечивает возможность включения в программу комментариев, которые обрамляются символами /* и */. Комментарии можно помещать в любом месте программы, причем на их длину нет практически никаких ограничений. Для того, чтобы служить своему назначению, комментарии должны содержать информацию о самой программе, имени программного файла, компиляторе, базе данных, а также о назначении каждого из предикатов и правил, которые не являются в достаточной степени очевидными.

Правила образования имен в Турбо-Прологе

Любое имя, используемое в Турбо-Прологе, должно состоять не более чем из 250 символов, первый из которых при этом должен обязательно быть строчной буквой латинского алфавита (от a до z). Пробелы в записи имени недопустимы, однако можно использовать подчерк (_) в качестве разделителя компонент так, как это сделано ниже:

employee_name

color_of_box

wild_animal_kingdom

beginning_of_year_to_date_activities_report

Большинство программистов, однако, предпочитают пользоваться более краткими именами. Имена, приведенные в качестве примера очень удобны для понимания программы, однако у них есть весьма существенный недостаток — они длинны. В Турбо-Прологе предусмотрена возможность задавать имена, состоящие всего из одной буквы:

domains

a, b = symbol

predicates

s(a,b)

clauses

s(brave,daring

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

Турбо-Пролог требует указания типов объектов для каждого предиката программы. Некоторые из этих объектов могут быть, к примеру, числовыми данными, другие же – символьными строками. В разделе predicates, поэтому, Вы должны задать тип объектов каждого из предикатов. Для того чтобы предикат likes можно было использовать в программе, необходимо сделать следующее описание:

predicates

likes(symbol, symbol)

Это описание означает, что оба объекта предиката likes относятся к типу symbol. Этот тип является одним из базисных типов Турбо-Пролога. В некоторых случаях, однако, представляется необходимым иметь возможность несколько больше конкретизировать тип используемого предикатом объекта. Например, в предикате likes объекты имеют смысл «тот, кто любит» и «вещь, которую любят». Турбо-Пролог позволяет конструировать свои собственные типы объектов из базисных типов доменов. Предположим, для примера, что объектам предиката likes Вы хотите присвоить соответственно имена person и thing. Тогда в разделе программы domains должны появиться такие описания:

domains

person, thing = symbol

predicates

likes(person, thing)

Имена person и thing при этом будут обозначать некие совокупности (домены) значений.

Использование файлов на внешних носителях

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

  Турбо-Пролог обеспечивает великолепные возможности  для удобной и эффективной обработки файлов. Сюда можно  включить встроенные  предикаты для открытия и закрытия файлов, чтения из файла и записи в файл, изменения данных в файле, а  также дозапись  в уже существующий файл. Данные из файла могут обрабатываться либо как непрерывный поток символов,  либо  как структурированные объекты типа записей базы данных.

Большинство современных языков программирования высокого уровня обеспечивает интерфейс  с  операционной  системой, который позволяет работать с различными физическими устройствами. Турбо-Пролог обеспечивает эту возможность путем  поддержания  предикатов,  осуществляющих  назначения логических устройств. Встроенный  предикат  Турбо-Пролога readdevice позволяет переадресовать логическое  устройство  ввода.  Аналогично встроенный предикат writedevice  осуществляет  переадресацию устройства вывода информации.

Стандартная конфигурация устройств

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

Использование окон, графики, звука

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

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

Средства  языка поддерживают Цветной Графический Адаптер и Расширенный Графический Адаптер, обеспечивая тем самым возможность работать в различных графических режимах. Графические предикаты Турбо-Пролога  поддерживают  Цветной Графический  Адаптер  (CGA) фирмы IBM и Расширенный Графический Адаптер (EGA) фирмы IBM, а также совместимые с ними. Графика в системе программирования Турбо-Пролог в основном реализуется  предикатами  dot и line. С помощью зтих предикатов на экран дисплея выводятся изображения, состоящие из  геометрических  фигур. Управление графическими режимами и цветами в Турбо-Прологе осуществляется  с  помощью  параметров, задаваемых в предикатах graphics и makewindow. Предикат graphics используется для включения графического режима CGA или EGA. Предикат   graphics   и   параметры   Screen_attribute   и Frame_attribute предиката makewindow  взаимодействуют  довольно сложным  образом.  И  если говорить о версии 1.1, то можно сказать, что Турбо-Пролог в этом случае ведет себя причудливо. Однако данное замечание не касается  более  поздних  версий  Турбо-Пролога. При  программировании компьютерной графики необходимо учитывать некоторые технические аспекты, усложняющие задачу  программиста.  Разработчики  графических  мониторов и адаптеров используют отличающуюся от рассмотренной шкалу  горизонтальных  и вертикальных  размеров.  Эти размеры масштабируются посредством параметра, называемого видовым отношением (aspect ratio). Видовое отношение определяется как отношение высоты  экрана  к  его ширине и измеряатся в единицах линий электронного луча, помещающихся  на экране (video scan lines).

Кроме поддержки многооконности  и  цветной  графики,  Турбо-Пролог предоставляет звуковые средства. Программа Турбо-Пролога используя звуковые средства, способна производить музыкальные  тоны  в  широком  диапазоне частот, управляя продолжительностью их звучания. Турбо-Пролог  поддерживает  два предиката генерации звука: sound и beep. Предикат beep генерирует звук высокой  тональности. Его вид прост, поскольку этот предикат параметров не имеет. Правило beep используется для  различных  целей,  например для того, чтобы привлечь внимание пользователя в ситуации, когда  требуется ввод какой-либо информации либо чтобы уведомить о наличии ошибочного состояния. Даже простые музыкальные фрагменты сделают любую программу более интересной и информативной.

  1.  Среда разработки « Visual Prolog «

Версия PDC Prolog 3.31 уже включала средства для написания программ, работающих под управлением графических операционных систем, процесс разработки подобных приложений все еще носил рутинный характер. Для того чтобы сделать более простыми, удобными и быстрыми процессы написания, тестирования и модификации приложений на языке PDC Prolog, специалисты Prolog Development Center создали систему программирования под названием Visual Prolog 4.0, выпущенную 7 января 1996 г. В этой работе участвовал коллектив российских программистов под руководством Виктора Юхтенко, который позже стал техническим директором компании «Пролог-Софт», представляющей интересы PDC в России.

В декабре 1997 г. фирма PDC выпустила Visual Prolog 5.0, а с января 1999 г. приступила к распространению версии 5.1 Personal Edition функционирующую в средах Windows 3.1/95/98, NT, OS/2, SCO UNIX и Linux.

Вариант Personal Edition предназначен для некоммерческого использования, и сообщения об этом постоянно имеются во всех приложениях, созданных с его помощью. Кроме того, владельцы Personal Edition не обеспечиваются бесплатной технической поддержкой и на них не распространяются льготы и скидки при приобретении новых версий. В последней версии появились такие усовершенствования, как отладчик, специальный инструментарий и примеры разработки Web-узлов.

При разработке приложений в среде Visual Prolog используется подход, получивший название «визуальное программирование», при котором внешний вид и поведение программ определяются с помощью специальных графических средств проектирования без традиционного программирования на алгоритмическом языке. В результате получили систему программирования, отличающуюся исключительной логичностью, простотой и эффективностью.

В Visual Prolog входят различные элементы: прежде всего, интерактивная среда визуальной разработки (VDE — Visual Develop Environment), которая включает текстовый и различные графические редакторы, инструментальные средства генерации кода, конструирующие управляющую логику (Experts), а также являющийся расширением языка интерфейс визуального программирования (VPI — Visual Programming Interface), Пролог-компилятор, набор различных подключаемых файлов и библиотек, редактор связей, файлы, содержащие примеры и помощь.

Visual Prolog поддерживается различными ОС, в том числе MS-DOS PharLap-Extended DOS, всеми версиями Windows, 16- и 32-битовыми целевыми платформами OS/2, а также некоторыми другими системами, требующими графического пользовательского интерфейса. Все продукты PDC, включая Visual Prolog, — это системы, порождающие исполняемый код (EXE или DLL), что еще раз подтверждает высокую эффективность Пролога.

В зависимости от выбранного интерфейса разработчику обеспечивается доступ к множеству генераторов кода (Code Expert), всевозможным ресурсным редакторам и особым дополнительным VPI-предикатам, определениям и библиотекам. Ресурсные редакторы применяются для создания, компоновки и редактирования окон, диалогов, меню, панелей инструментов, строк помощи, строковых таблиц, ярлыков, курсоров, битовых карт и оперативной помощи. Генераторы кода на основе подобных структур создают необходимый первичный Prolog-код. В результате появляется первичный код («скелет»), готовый для компиляции, редактирования связей и выполнения. На листинге в качестве примера такого рода представлен автоматически сгенерированный первичный код.

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

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

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

Кнопка панели инструментов

Команда меню

Кнопка панели инструментов

Команда меню

File | New

Edit | Сору

File | Open

Edit | Paste

File | Save

Project (Compile file)

Edit | Undo

Project | Build

Edit | Redo

Project | Run

Edit | Cut

Project | Debug

Project | Test Goal

Options | Temporary | Font

Project | Browse

Help | Local Help

Project | Tree

С помощью VPI можно создать мобильный исходный текст, а затем перекомпилировать его для работы как в 16-битовом режиме под управлением MS DOS или Windows, так и в 32-битовом режиме под управлением Windows NT, OS/2 PM и других ОС.

  1.  Заключение

Можно констатировать, что по большому счету ПРОЛОГ не занял в 90-е годы тех позиций, которые ему пророчили в начале 80-х. Нашумевший проект создания ЭВМ пятого поколения привел не к тем последствиям, которые от него ожидали. В практическом плане широкое внедрение графического интерфейса систем разработки программ и развитие визуального программирования придали «второе дыхание» традиционным процедурным языкам программирование. Широкую популярность завоевал объектно-ориентированный подход, позволяющий объединить описание объектов предметной области с процедурами их обработки, а также строить иерархические описания объектов с помощью механизма наследования.

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

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

В данном курсовом проекте была рассмотрена  история создания и развития языка Prolog, сферы его использования.  Также рассмотрены структура программы  SWIProlog, Тurbo Prolog и Visual Prolog. Начиная с первой версии SWIProlog этот язык программирования  окончательно превратился в язык, способный решать практически любые задачи современного программирования, система программирования, которая с успехом может применяться не только в традиционных для логического программирования приложениях.  

Тем не менее, корни этого языка находятся в области логического программирования: имеется достаточно широкий круг задач, традиционно относящихся к задачам искусственного интеллекта, для которых первоначально предназначался, а впоследствии совершенствовался, язык Пролог (Программирование на основе Логики).

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

  1.  Глоссарий терминов

Атом — имя, число без знака или символ.

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

База знаний — динамическая база данных; обычно является составной частью экспертной системы.

Внешняя цель  — целевое утверждение,  вводимое пользователем во время работы программы на Турбо-прологе.

Внутренняя цель — целевое утверждение,  содержащееся  в  тексте  программы на Турбо-прологе.

Динамическая база данных — база данных,  в которую можно добавлять новые факты, корректировать их и удалять. Может располагаться на диске или в оперативной памяти.

Домен — диапазон и тип значений, определенные для базисного типа данных.  В  ТУРБО-ПРОЛОГе  базисными типами являются char,integer, real, string и symbol.

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

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

Искусственный интеллект  (ИИ) — область науки об ЭВМ, связанная с проектированием компьютерных систем,  имеющих свойства, ассоциирующиеся с разумным поведением человека. Лексический анализ — метод анализа текста с использованием лексикона допустимых слов и фраз.

Метод деления списка на голову и хвост — в ПРОЛОГе метод работы с элементами непустого списка,  рассматриваемого как комбинация головы и хвоста списка.

Модуль — совокупность правил и предикатов ТУРБО-ПРОЛОГа для выполнения логически законченного набора операций.

Предикат — утверждение о наличии связи между объектами посредством задания имени отношения и доменов его аргументов. Примером может  служить  утверждение  likes(domain1,domain2),  где likes является именем предиката, а domain1 и domain2 — именами доменов объектов.

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

ПРОЛОГ (Prolog) — язык программирования; аббревиатура словосочетания «PROgramming LOGic».  Структура языка базируется на логике предикатов.

Рекурсия — свойство структуры или правила, заключающееся в возможности обращения к самой (-му) себе один  или  более  число раз.

Синтаксический анализ  —  метод  обработки текста путем анализа синтаксиса предложений; обычно требует синтаксического разбора предложений.

Структурная схема (СС) —  схема,  в  рамках  которой  программа представляется в форме иерархической структуры модулей.

Цель — совокупность подцелей,  которые  пытается  удовлетворить ТУРБО-ПРОЛОГ. Может быть внешней или внутренней.

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

8. Список литературы

1. Л. Стерлинг, Э. Шапиро « Искусство программирования на языке Пролог»

2. Малпас Дж. «Реляционный язык Пролог и его применение»

3. У.Клоксин, К.Меллиш « Программирование на языке Prolog»

4. Братко И. «Программирование на Prolog»

5. В. В. Терёхин «Учебное пособие TURBO PROLOG»

6. Анатолий Адаменко, Андрей Кучуков «Логическое программирование и Visual Prolog »

7. Ин Ц., Соломон Д. «Использование Турбо-Пролога»  /Пер. с англ. — М.: Мир, 1993.

8. Солдатова О.П, Лёзина И.В. «Логическое программирование на языке Visual Prolog» Учебное пособие Самара 2010

Уфимский
государственный авиационный технический
университет

Курсовой проект

по  дисциплине

«Системы
искусственного интеллекта»

Вариант 12

Специальность 230102
Автоматизированные системы

обработки
информации и управления

Факультет
информатики и робототехники

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

Курс 4

Семестр 8

Оценка
________________ Исполнитель

Консультант
проф. каф. АСУ студ. гр.

(зач.
кн. )

________ Алыпов
Ю.Е. _______.

«___» ____________ 2007
г. «___» ___________ 2007 г.

Содержание

  1. Введение…………………………………………………………………3

  2. Задачи на
    проектирование………………………………………………4

2.1. Задание
1…………………………………………………………………4

2.2. Задание
2………………………………………………………………..6

2.3. Задание
3………………………………………………………………..7

  1. Список
    литературы………………………………………………..……..7

Приложение………………………………………………………..……..8

Введение.

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

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

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

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

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

Пролог-программа
состоит из предложений. Каждое предложение
заканчивается точкой. Аргументы отношения
могут быть (среди прочего): конкретными
объектами, или константами, или
абстрактными объектами, такими, как X и
Y. Объекты первого типа называются
атомами. Объекты второго типа — переменными.

Задание 1.

Цель — Знакомство
с основами логического программирования
(Prolog).

Используя предикаты
parent(symbol,symbol), man(symbol), woman(symbol),
married(symbol,symbol), записать
факты, описывающие Вашу семью. Записать
8 правил вывода для любых родственных
отношений в Вашей семье (например: мать,
отец, сестра, брат, племянница, племянник,
тетя, дядя, внучка, внук, бабушка, дедушка,
двоюродная сестра, двоюродный брат и
т.д.).

Рис1. Дерево
родственных отношений

Листинг
программы.

PREDICATES

parent(String,String)

man(String)

woman(String)

married(String,String)

plem(String,String)

mother(String,String)

father(String,String)

grandma(String,String)

grandfa(String,String)

son(String,String)

brother(String,String)

print

CLAUSES

man(«Evgeniy»).

man(«Alex»).

man(«Iliya»).

man(«Yan»).

man(«Sergey»).

woman(«Olga»).

parent(«Evgeniy»,»Alex»).

parent(«Evgeniy»,»Iliya»).

parent(«Olga»,»Alex»).

parent(«Olga»,»Alex»).

parent(«Iliya»,»Yan»).

parent(«Iliya»,»Sergey»).

married(«Evgeniy»,»olga»).

mother(X,Y):-woman(X),parent(X,Y).

father(X,Y):-man(X),parent(X,Y).

son(X,Y):-man(Y),parent(X,Y).

grandma(X,Z):-parent(X,Y),parent(Y,Z),woman(X).

grandfa(X,F):-parent(X,Y),parent(Y,F),man(X).

brother(X,Y):-parent(Z,X),parent(Z,Y),man(X),X<>Y.

plem(X,F):-parent(Z,F),man(F),parent(P,X),parent(P,Z),Z<>X.

print:-mother(X,Y),write(X,»-mother-«,Y),nl,fail.

print:-father(X,Y),write(X,»-father-«,Y),nl,fail.

print:-son(X,Y),write(Y,»-son-«,X),nl,fail.

print:-grandma(X,Z),write(X,»-grandma-«,Z),nl,fail.

print:-grandfa(X,F),write(X,»-grandfa-«,F),nl,fail.

print:-brother(X,Y),write(X,»-brother-«,Y),nl,fail.

print:-plem(X,F),write(F,»-plemannik-«,X),nl,fail.

print.

GOAL

print,

readln(I).

Вывод.

Построив дерево
родственных отношений, и используя
язык логического программирования
Prolog, я написал программу,
в которой отображаются все родственные
отношения, с помощью заданных правил и
фактов. Использовались такие
предикаты, как
parent(string, string), man(string), woman(string), married(string
,string).

Задание
2. (7)

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

PREDICATES

operation(symbol,real,real)
GOAL
write(«Enter
number»),nl,readreal(X),nl,readreal(Y),nl,

operation(«+»,X,Y),
operation(«-«,X,Y),

operation(«*»,X,Y),
operation(«/»,X,Y).
CLAUSES

operation(«+»,X,Y):-Z=X+Y,
write(X,»+»,Y,»=»,Z),nl.

operation(«-«,X,Y):-Z=X-Y,
write(X,»-«,Y,»=»,Z),nl.

operation(«*»,X,Y):-Z=X*Y,
write(X,»*»,Y,»=»,Z),nl.

operation(«/»,X,Y):-Z=X/Y,
write(X,»/»,Y,»=»,Z),

nl,readln(I).

Вывод.

Используя язык
логического программирования Prolog,
я написал программу, реализующую четыре
арифметические действия над двумя
числами: сложение, вычитание, деление
и умножение. В программе использовался
предикат operation(symbol,real,real).

Задание
3.(2)

Подсчитать, сколько
раз встречается некоторая буква в
строке. Строка и буква должны вводиться
с клавиатуры. Для разделения строки на
символы использовать стандартный
предикат frontchar (String, Char, StringRest),
позволяющий разделять строку String на
первый символ Char и остаток строки
StringRest.

PREDICATES

count(string,char,integer)

CLAUSES

count(Str,Ch,Counter):-

frontchar(Str,H,T),

Str<>»»,H=Ch,!,

New_Counter=Counter+1,

count(T,Ch,New_Counter).

count(Str,Ch,Counter):-

frontchar(Str,H,T),

H<>Ch,Str<>»»,!,

count(T,Ch,Counter).

count(_,Ch,Counter):-write(«Simvol
`»,Ch,»` vstrechaetsa v kolichestve «,Counter).

GOAL

write(«Input
string: «), readln(Str),

write(«Input
char: «), readchar(Ch), write(Ch),readln(X),

Amount=0,
count(Str,Ch,Amount),nl,

readln(KLJ).

Вывод.

Используя язык логического программирования
Prolog, я написал программу,
реализующую подсчет повторов буквы в
строке. В программе использовался
предикаты operation
и frontchar.

Список литературы.

  1. И. Братко Программирование на языке
    Пролог для искусственного интеллекта:
    Пер. с англ.-М.: Мир, 1990.- 560 с.

  2. Ин Ц.,
    Соломон Д. Использование Турбо-Пролога.
    – М.: Мир, 1993. – 608 С.

  3. Доорс Дж.,
    Рейблейн А.Р., Вадера С. Пролог ‑
    язык программирования будущего. – М.:
    ФиС, 1990. – 144 С.

  4. Стерлинг Л., Шапиро Э. Искусство
    программирования на языке Пролог. –
    М.: Мир, 1990. – 235 с.

Приложение

Рисунок к задаче
1.

Рисунок к задаче
2.

Рисунок к задаче
3.

9

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

Задание:
Создать экспретную систему по породам
дерева

Теория:

Структура
экспертных систем

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

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

1.
База знаний (БЗ).

2.
Механизм вывода (МВ).

3.
Система пользовательского интерфейса
(СПИ).

База
знаний — центральная часть экспертной
системы. Она содержит правила, описывающие
отношения или явления, методы и знания
для решения задач из области применения
системы. Можно представлять базу знаний
состоящей из фактических знаний и зна
ний, которые используются для вывода
других знаний. Утверждение «Джон Ф.
Кеннеди был 35-м президентом Соединенных
Штатов» — пример фактического знания.
«Если у вас болит голова,то примите
две таблетки цитрамона» — пример
знания для вывода. Сама база знаний
обычно располагается на диске или другом
носителе.

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

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

и
передает результаты программе интерфейса
с пользователем.

Когда
вопрос должен быть предварительно
обработан, то доступ к базе знаний
осуществляется через интерфейс с
пользователем. Интерфейс — это часть
экспертной системы, которая взаимодействует
с пользователем.

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

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

Хорошо
разработанные оболочки экспертных
систем обычно содержат механизм для
добавления и обновления информации в
базе знаний.

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

Представление
знаний

Представление
знаний — это множество соглашений по
синтаксису и семантике, согласно которым
описываются объекты. Хорошее правило
при проектировании представления знаний
— это организация знаний в такой форме,
которая позволяет легко осуществлять
доступ с помощью естественных и простых
механиз мов. «Чем проще, тем лучше»
— правило, которое нужно помнить, при
работе с представлением знаний.

Экспертные
системы часто создаются «инженером
по знаниям»(или проектировщиками
экспертных систем), которые работают с
человеком-экспертом, чтобы закодировать
знания эксперта в базе знаний.

Первый
способ — это классификация и помещение
фактов и чисел (фрагментов фактического
знания) в правила Турбо-Пролога.

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

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

Система
пользовательского интерфейса

Система
пользовательского интерфейса обеспечивает
взаимодействие между экспертной системой
и пользователем. Это взаимодействие
обычно включает несколько функций:

1.
Обработка данных, полученных с клавиатуры,
и высвечивание вводимых и выводимых
данных на экране.

2.
Поддержка диалога между пользователем
и системой.

3.
Распознавание ситуации непонимания
между пользователем и системой.

4.
Обеспечение «дружественности» по
отношению к пользователю.

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

Кроме
того, система интерфейса должна
поддерживать соответствующий диалог
между пользователем и системой. Диалог
— это общая форма консультации с экспертной
системой.

Консультация
должна завершаться ясным утверждением,
выдаваемым системой, и объяснением
последовательности вывода, приведшей
к этому утверждению.

Система
пользовательского интерфейса должна
также распознавать непонимание, между
пользователем и системой, возникшее
либо из-за ошибки, либо на принципиальной
основе . Система должна реагировать
соответствующим образом на эту ситуацию.
Например, не должно произойти сбоя
системы, если пользователь вводит 1,
когда ожидается «да» или «нет»,
или когда пользователь задает бессмысленный
вопрос.

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

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

Пользователь
также должен иметь возможность
взаимодействовать с экспертной системой
естественным образом. В идеале пользователь
должен иметь возможность использовать
естественный язык

Экспертная
система на правилах

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

Таким
образом, экспертная система, базирующаяся
на правилах (на Турбо-Прологе) содержит
множество правил, которые вызываются
посредством входных данных в момент
сопоставления. Экспертная система также
содержит интерпретатор в механизме
вывода, который выбирает и активизирует
различные модули системы.

Работу
этого интерпретатора можно описать
последовательностью трех шагов:

1.
Интерпретатор сопоставляет образец
правила с элементами данных в базе
знаний.

2.
Если можно вызвать более одного правила,то
интерпретатор использует механизм
разрешения конфликта для выбора правила.

3.
Интерпретатор применяет выбранное
правило , чтобы найти ответ на вопрос.

Этот
трехшаговый процесс интерпретации
является циклическим и называется
циклом «распознавание-действие».

В
системе, базирующейся на правилах,
количество продукционных правил
определяет размер базы знаний. Некоторые
наиболее сложные системы имеют базы
знаний с более чем 5000 продукционных
правил.

1.
Использовать минимально достаточное
множество условий при определении
продукционного правила.

2.
Избегать противоречащих продукционных
правил.

3.
Конструировать правила, опираясь на
структуру присущую предметной области.

Экспертные
системы, базирующиеся на логике

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

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

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

Интерпретатор
выполняет различные функции внутри
системы на основе следующей схемы:

1.
Система имеет предложения в базе знаний,
которые управляют поиском и сопоставлением.
Интерпретатор сопоставляет эти
предложения с элементами данных в базе
данных.

2.
Если может быть вызвано более одного
правила , то система использует возможности
Турбо-Пролога для разрешения конфликта.
Следовательно пользователю/программисту
не нужно рассматривать потенциально
возможные конфликты.

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

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

Красота
и большие возможности системы, основанной
на логике, заключаются в том, что она
отражает структуру самого Турбо-Пролога.
Этим объясняется тот факт, что она очень
эффективна в работе.

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

Структура
базы знаний экспертной системы для
выбора породы дерева.

Для
идентификации породы внутри каждого
подмножества можно использовать список
атрибутов. Количество характеристик
будет определять степень точности
классификации. Различающей не обязательно
является какая-нибудь единственная
характеристика — все множество атрибутов
используется для достижения целей в

строящихся
правилах.

Все
перечисленные ниже атрибуты являются
необходимыми, так как ни один из них не
характерен для всех пород одновременно.

1)
лиственная;

2)
хвойная;

3)
мягкая;

4)
твердая;

5)
очень твердая;

6)
серо-коричневая;

7)
светло-красная;

8)
светлая;

9)
темная;

10)
смолистая;

11)
очень смолистая;

12)
Крупная текстура;

13)
Мелкая текстура.

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

Порода
Характеристики

Дуб 1,4,6,13

Бук 1,4,7,12

Осина 1,3,8,13

Тис 1,5,9

Ель 2,3,8,10

Сосна 2,3,8,11

Способ
использования этой информации зависит
от реализации экспертной системы.

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

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

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

Сначала
необходимо сделать декларации базы
данных. База данных будет хранить ответы
пользователя на вопросы системы
пользовательского интерфейса (СПИ). Эти
данные являются утвердительными или
отрицательными ответами.

Далее
нужно
объявить
предикаты для выполнения вывода (машина
вывода) и для взаимодействия с пользователем
(система пользовательского интерфейса).

Все
вместе это следующие декларации:

database

xpositive(symbol,symbol)

xnegative(symbol,symbol)

predicates

do_expert_job

do_consulting

ask(symbol,symbol)

dog_is(symbol)

it_is(symbol)

positive(symbol,symbol)

negative(symbol,symbol)

remember(symbol,symbol,symbol)

clear_facts

Предикаты
базы данных xpositive и xnegative используются
для хранения утвердительных и отрицательных
ответов пользователя. Первые четыре
предиката нужны для взаимодействия с
пользователем, а остальные шесть — для
механизма вывода.

Должны
быть составлены восемь продукционных
правил : по одному для каждой породы.
Каждое правило должно идентифицировать
породу по признаку принадлежности к
группе длинношерстных или короткошерстных.

Правило
it_is производит эту идентификацию. Затем
правило positive идентифицирует характеристики
собаки в каждом случае.

И
it_is и positive используются механизмом
вывода. Ниже приведено полное продукционное
правило для дуба:

tree_is(«Дуб»):-

positive(tree,»Лиственная»),

positive(tree,»Твердая»),

positive(tree,»Серо_Коричневая»),

positive(tree,»Мелкая_текстура»),!.

Механизм
вывода должен иметь правила для управления
данными вводимыми пользователем, для
сопоставления их с продукционными
правилами и сохранения «трассы»
(или запоминания) отрицательных и
утвердительных ответов. Правила positive
и negative
используются
для сопоставления данных пользователя
с данными в продукционных правилах.
Правило remember (запоминание) производит
добавление предложений с ответами yes
(да) и no (нет), для использования при
сопоставлении с образцом:

positive(X,Y)
:-

xpositive(X,Y),!.

positive(X,Y)
:-

not(negative(X,Y)),!,

ask(X,Y).

negative(X,Y)
:-

xnegative(X,Y),!.

remember(X,Y,yes)
:-

asserta(xpositive(X,Y)).

remember(X,Y,no)
:-

asserta(xnegative(X,Y)),

fail.

clear_facts
:-

retract(xpositive(_,_)),

fail.

clear_facts
:-

retract(xnegative(_,_)),

fail.

Назначение
системы пользовательского интерфейса
(СПИ) — связь вводимых пользователем
данных с системой логического вывода.
Главный модуль do_expert_job (выполни экспертную
работу) и модуль do_consulting (выполни
консультацию)

осуществляют
эту связь. Модуль ask(X,Y) (спроси) запрашивает
данные у пользователя и сохраняет ответы
в базе знаний. Кроме того, окно обеспечивает
дополнительное удобство во время
консультации. Система пользовательского
интерфейса полностью приведена ниже:

do_expert_job
:-

setup_window,

do_consulting,

write(«Press
space bar.»),nl,

readch(_),

removewindow,

exit.

setup_window
:-

makewindow(1,7,7,»AN
EXPERT SYSTEM»,1,16,22,58),

nl,write(«*
* * * * * * * * * * * * * * * * * * *»),

nl,write(»
A Tree
Expert «),

nl,write(»
«),

nl,write(«This
is a tree
identification system. «),

nl,write(«Please
answer the question about «),

nl,write(«the
dog you would like by typing in «),

nl,write(«‘yes’
or ‘no’. «),

nl,write(«*
* * * * * * * * * * * * * * * * * * *»),

nl,nl.

do_consulting
:-

dog_is(X),!,nl,

write(«the
tree
you have indicated is a(n)»,X,».»),nl,

clear_facts.

do_consulting
:-

nl,write(«Sorry
I can’t help you ! «),

clear_facts.

ask(X,Y)
:-

write(»
Question :- «,X,» it «,Y,» ?»),

readln(Reply),

remember(X,Y,Reply).

Заметьте,
что главный модуль do_expert_job вызывает
модули setup_window (установи окно) и
do_consulting (выполни консультацию).
Консультирующий модуль имеет две
альтернативные формы. Первая взаимодействует
с механизмом вывода; если результат
цикла «распознавание — действие»
положительный, то результат
сообщается
пользователю. Вторая форма сообщает о
негативном результате.

Теперь
можно соединить отдельные компоненты
и сформировать полную экспертную систему
на правилах для выбора породы дерева.

Эта
программа просит пользователя выбрать
режим консультации или выход из программы.
Затем экспертная система выбирает
породу собаки на основании ответов
пользователя на вопросы, или в конце
неудачного поиска выдает сообщение
“Sorry!”

Реализация:

domains

database

xpositive(symbol,symbol)

xnegative(symbol,symbol)

predicates

do_expert_bird.

do_consulting

ask(symbol,symbol)

tree_is(symbol)

positive(symbol,symbol)

negative(symbol,symbol)

remember(symbol,symbol,symbol)

clear_facts

goal

do_expert_bird.

clauses

do_expert_bird:-

makewindow(1,7,7,»Expert
System»,1,3,22,71),

nl,write(»
—————————————————«),

nl,write(»
A Tree
Expert «),

nl,write(»
«),

nl,write(»
Please answer the questions ‘yes’ or ‘no’.»),

nl,write(»
—————————————————«),

nl,nl,

do_consulting,

write(«Press
space bar.»),nl,

readchar(_),

removewindow,

exit.

do_consulting:-

tree_is(X),!,nl,

write(«Tree
«,X,».»),nl,

clear_facts.

do_consulting:-

nl,write(«Sorry
!»),

clear_facts.

ask(X,Y):-

write(»
expert> «,X,» «,Y,» ?»),

readln(Reply),

remember(X,Y,Reply).

positive(X,Y):-

xpositive(X,Y),!.

positive(X,Y):-

not(negative(X,Y)),!,

ask(X,Y).

negative(X,Y):-

xnegative(X,Y),!.

remember(X,Y,yes):-

asserta(xpositive(X,Y)).

remember(X,Y,no):-

asserta(xnegative(X,Y)),

fail.

clear_facts:-

retract(xpositive(_,_)),

fail.

clear_facts:-

retract(xnegative(_,_)),

fail.

tree_is(«Дуб»):-

positive(tree,»Лиственная»),

positive(tree,»Твердая»),

positive(tree,»Серо_Коричневая»),

positive(tree,»Мелкая_текстура»),!.

tree_is(«Бук»):-

positive(tree,»Лиственная»),

positive(tree,»Твердая»),

positive(tree,»Светло_Красная»),

positive(tree,»Крупная_текстура»),!.

tree_is(«Осина»):-

positive(tree,»Лиственная»),

positive(tree,»Мягкая»),

positive(tree,»Светлая»),

positive(tree,»Мелкая_текстура»),!.

tree_is(«Тис»):-

positive(tree,»Лиственная»),

positive(tree,»Очень_твердая»),

positive(tree,»Темная»),!.

tree_is(«Ель»):-

positive(tree,»Хвойная»),

positive(tree,»Мягкая»),

positive(tree,»Светлая»),

positive(tree,»Смолистая»),!.

tree_is(«Сосна»):-

positive(tree,»Хвойная»),

positive(tree,»Мягкая»),

positive(tree,»Светлая»),

positive(tree,»Очень_Смолистая»),!.

tree_is(«Столб»):-

positive(tree,»Не_дерево»),

positive(tree,»Очень_Твердый»),!.

1. Интегрировання Среда языка Turbo Prolog.

2. Структура программы

3. Стандартные типы доменов

4. Прототипы предиката

5. Утверждения и цели

6. Арифметические выражения.

7. Встроенные прдикаты языка

1. Интегрированная среда языка Turbo Prolog.

Функционирование Т.Р. требует наличие следующих стандартных каталогов:

корневой Prolog, в котором должны находится следующие файлы:

prolog.exe

prolog.ovl для создания exe файла

prolog.r тексты сообщения об ошибках

prolog.hlp файл помощи

prolog.sys конфигурация среды

prolog.lib библиотеки

prolog.obj вспомагательный файл для создания пользов-их exe файлов

подкаталог PRO для пользовательских исходных файлов (расширение .pro)

подкаталог OBJ для пользовательских обьктных и prg файлов

подкаталог EXE для хранения пользовательских exe файлов

подкаталог DOS для команд ОС в том случае, если предполагается их использование из пользовательских программ. (min command.com)

2 Структура программы на TURBO PROLOG

1 Для определения типов доменов или данных, используемых в программе

2 описание прототипов пользовательских предикатов

3 “утверждения” включает описание фактов в виде предикатов и правил, т.е. декларативных и процедурных знаний

4 содержит цель решения задач, при его отсутствии система запрашивает цель решения задачи в окне диалога и в этом-же окне получаем ответ, при его присутствии в нем помещаем пользовательский интерфейс.

Место для печатания

-35—36—37-

readint (<целое>)

(integer): (0) — читает целое число, чтение заканчивается нажатием <Enter>

readreal (<вещественное>)

(real): (0) — вещ.

readchar(<знак>)

(char): (0) — читает единичный символ

readln (<строка>) (string): (0) — читает строку символов

inkey (<знак>) (char): (0) — заканчивается истиной, если после предыдущей операции была нажата клавиша, возвращается её код. Если не была нажата, то предикат оканчивается неудачей

nl — код двух клавиш — переход на новую строку

write (x1, x2, …)

(переменные и константы): (i, i, …) — выдает на текущее устройство записи констант и содержание переменных

writef (<формат>, x1, x2, …)

(string, <переменные и константы>): (i, i, …)

Структура формата:

“ % — m.pw “, где % — признак форматного вывода

если задан “-”, то знаки должны выравниваться по левому краю, если не задан — по правому

m — длина поля вывода

p — кол-во цифр после точки

w — тип числа, вместо w записывается f, если выводится число в десятичном виде, e — в экспотенциальной форме, q — в самом коротком формате.

Предикаты работы с символьными данными.

str_lon (<строка>, <длина>)

(string, integer): (i, i) (i, 0)

если задано (i, i), проверяется длина строки, если (i, 0) — возвращается длина строки

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

Все предикатные преобразования действуют в обе стороны. Случай (i, i) проверяет истинность для всех типов, кроме real. Преобразование между типами string, symbol и real, integer пр-ся (?) автоматически.

char_int (<знак>, <целое>)

(сhar, integer): (i, 0) (0, i) (i, i)

str_char (<знак как строка>, <знак>)

(string, сhar): (i, 0) (0, i) (i, i)

str_int (<строка>, <вещ.>)

(string, real): (i, 0) (0, i)

и т. д.

Работа с командами операционной системы

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

system (<команда OS>)

(string): (i) — передает команду OS

date (<год>, <месяц>, <день>)

(integer, integer, integer): (i, i, i) (0, 0, 0) — устанавливает, если (i, i, i), или возвращает, если (0, 0, 0) системную дату

time… — то же

dir (<маршрут>, <спецификатор файла>, <имя файла>)

(string, string, string): (i, i, 0) — выдаются на экран специфицированные файлы из каталога по маршруту. Возможно выбрать из каталога имя одного файла с помощью стрелок управления курсором, при нажатии <Enter> имя этого файла присваивается третьему аргументу предиката

Специальные предикаты языка Turbo Prolog

bouncl (<переменная>) — “истина, если переменная является конкретизированной

free (<переменная>) — “истина, если переменная не является конкретизированной

fail — всегда ложн. вызывает возврат для проверки базы в правилах

! — (cat) — предикат отсечения, ограничивает возврат

exit — останавливает выполнение пользовательской программы и передает управление меню Turbo Prolog

trace — общее включение режима отладки. Указывается в начале исходной программы

trace (<статус>)

(symbol): (i) (0) — устанавливает, если i, или возвращает, если 0, текущий режим отладки. В качестве статуса можно использовать on/off. Использование этого предиката предполагает наличие trace в начале программы

diagnostics — позволяет выдать анализ программы в процессе компиляции. Анализ включает имена используемых предикатов. Для каждого имени определяется, являются ли аргументы конкретного предиката фактами или указывается конкретность предиката.

nowarnings — отключает предупреждения в процессе компиляции

project “имя файла” — данная программа является частью проекта

include “имя файла” — в компиляцию включается файл с указанным именем

Управление ходом выполнения программ на языке ТР.

1. Рекурсия.

В механизм обработки программ на языке ТР заложена рекурсия, то есть вычисление значения функции с помощью той же функции, но с измененными параметрами. Рекурсия в ТР реализуется в 2 этапа:

1) исходная задача разбивается на более мелкие частные задачи и формируются частные решения и на основе которых затем будет получено общее решение задачи.

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

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

<имя правила рекурсии с аргументами или без них> if

<список предикатов> (1)

<предикат условия выхода из рекурсии> (2)

<список предикатов> (3)

<имя правила рекурсии с аргументами или без них > (4)

<список предикатов> (5)

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

Пример.

Определение n-го терма последовательности 1, 1, 2, 6, 24, …

N 0 1 2 3 4 …

0 терм=1 3 терм=2*3

1 терм=1*1 4 терм=6*4

2 терм=1*2 5 терм=24*5

Для обозначения того факта, что n-й член последовательности равен V, вводится предикат следующего вида: posl (N, V)

Фрагмент программы:

domains

N, V = integer

predicates

posl = (N, V)

clauses

posl (0, 1)

posl (N, V) if

1) N>0

2) M=N-1

3) posl (M, U)

4) V=U*N

goal

posl (3, x)

Решение задачи производится в 2 этапа:

I этап.

1. Производится попытка удовлетворить запрос пользователя, используя первое утверждение в разделе clauses (posl (3,x) сопоставляется с posl (0, 1)). Так как 0 не сопоставляется с 3, то попытка завершается неудачей. После этого posl (3, x) сопоставляется с заголовком 2-го утверждения posl (N, V). Отсюда N получает значение 3, а V связывается с х и система переходит к доказательству подцели в теле правила:

1) N>0 согласуется при N1 =3

2) M1 =N1 -3 согласуется при N1 =3 и M1 =2

3) posl (2, U1 ) приводит ко второму рекурсивному обращению и так как это обращение не согласовано с первым, то последнее утверждение (V=U*N) откладывается.

2. Согласование posl (2, U1 ) с posl (0, 1) приводит к неудаче. Происходит сопоставление с заголовком 2-го утверждения, что заканчивается удачей, при этом N2 =2 и V=U1. происходит доказательство по цели этого утверждения:

1) согласуется при N2 =2

2) согласуется при N2 =2 и М2 =1

3) posl (1, U2 ) приводит к повторному рекурсивному обращению

4) откладывается

3. Согласование posl (1, U2 ) с posl (0, 1) приводит к неудаче. Сопоставление с заголовком 2-го утверждения заканчивается неудачей, при N3 =1 и V=U2. Происходит доказательство по цели этого утверждения:

1) согласуется при N3 =1

2) согласуется при N3 =1 и М3 =0

3) posl (0, N3 ) приводит к повторному рекурсивному обращению.

Полученное целевое утверждение сопоставляется с первым целевым утверждением posl (0, 1), при этом U3 получает заначение 1.

На этом этап разбиения заканчивается.

II. Этап сборки решения.

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

1) U2 =U3 *1, так как U3 =1 то U2 =1

2) U1 =U2 *2 U1 =2

3) X=U1 *3 X=6

2. Возврат и отсечение.

В процессе реализации запроса интерпретатору языка необходимо анализировать множество фактов и правил, к-рые извлекаются в процессе нескольких просмотров соответственных баз фактов. При этом в процессе одного просмотра формируется частичное решение. Процесс в PROLOGе выполняется автоматически путем пометки или заполнения тех модулей, к-рые анализировались перед текущей целью, с тем, чтобы исключить полученное частное решение из дальнейнего рассмотрения. Этот механизм в PROLOGе наз-ся возвратом и реализуется через использование стандартного предиката fail, к-рый всегда имеет значение “ложь”. Этот предикат заставляет интерпретатор проанализировать ещё раз базу фактов, чтобы выполнить более целевое утверждение для других значений переменных. Он позволяет получить в базе все возможные решения.

ПРИМЕР:

domains

p,T=symbo L

predicat s

like (P,T)

poleg (T)

dauses

like (“Иванов”,” пиво”).

like (“Иванов”,” сок”).

poleg(“cok”)…

otv if

like (P,T) and

poleg (T),nl,

write (P),

fail.

goal

otv.

Для управления процессом выполнения программ в PROLOG имеется встроенный предикей cut, кот. кодируется в turbo-PROLOG как!.. Основное назначение — остановка процесса возврата, т.е. приостановка выработки дальнейших решений.

Этот процесс в Прологе наз. ОТСЕЧЕНИЕМ. Чаще всего предикей cut используется совместно с fail.

ПРИМЕР

.

.

.

goal

like (P,T)

T= “кефир”,

nl,

write ( “любитель кефира найден”)

!.

fail

Отсечение используется для устранения бесконечных циклов (см. пред. пример):

clauses

posl (0,1) if !

posl(N,V) if

M=N-1

posl (M,U)

V=U*N

Отсечение также используется для устр. взаимоисключающих утверждений.

ПРИМЕР

ball (M,’A”) if M> so,!

ball(M, “B”) if M< so an M>60,!.

Министерство образования 
и науки Российской Федерации

Федеральное государственное 
бюджетное учреждение

высшего профессионального 
образования

«Комсомольский-на-Амуре 
государственный

технический университет»

Факультет компьютерных технологий

Кафедра информационных систем

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к курсовому проекту

по дисциплине «Интеллектуальные
информационные системы»

Программирование на языке 
Prolog

Студент группы 9-ПИ             
______________                  
К.А. Страхова

подпись, дата

Руководитель проекта             
______________    А.А. Сиротин

подпись, дата

Нормоконтролёр                      
______________    А.В. Еськова

подпись, дата

2013

Содержание

1 Структурное, 
функциональное и логическое 
программирование. 3

2 Основные 
конструкции языка 6

3 Ход работы 16

3.1Построение 
треугольника Паскаля 16

3.2 Работа 
со списками 24

3.3 Работа 
с внешними базами данных в 
Prolog 29

3.4 Задачи 
использующие структуру графа 34

3.5 Построение 
экспертной системы 39

3.6 Реализация 
головоломки о Ханоской башне 44

Список использованных
источников 53

1 Структурное, функциональное и 
логическое программирование.

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

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

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

Недостатки алгоритмических 
языков:

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

Функциональное и логическое
программирование похожи по способу 
реализации.

Функциональное 
программирование. Любую сложную программу можно
рассматривать как функцию. Основной принцип
— суперпозиция функций.

Пример 1

Пусть программа вычисляет 
длину вектора:

Н0(0;0) — начальное значение

НК(5;4) — конечное значение.

length (5,4)=sqrt(K,N), где K=mul(X,X), N=mul(Y,Y)
— примитивные функции.

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

Достоинства:

  • функциональное программирование имеет надежное математическое обоснование;
  • возможность оптимизации и верификации программ;
  • простота механизма перехода от простых объектов к более сложным;
  • возможность стандартизации и параллельной обработки информации.

Недостатки:

  • неформальный подход при разработке программ;
  • неудобства при работе с базами данных.

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

Создание логического 
программирования можно приписать 
Ковальскому и Колмэроэ.

Ковальский разработал процедурную 
интерпретацию хорновских дизъюнктов
и показал, что аксиома A if B1and B2 and B3…and BN
может рассматриваться и выполняться
в качестве процедуры рекурсивного языка
программирования.

В этом случае, А — заголовок
процедуры, а BI — «тело».

В дополнение к декларативному
пониманию — «А истинно, если истинно
B1 и B2 и B3…и BN», утверждение допускает
и процедурное понимание
— «для решения (выполнения) А, следует
решить (выполнить)  B1 и B2 и B3…и BN». При
таком понимании процедура доказательства
хорновского дизъюнкта сводится к интерпретации
языка и к алгоритму унификации, который,
в свою очередь, является сердцевиной
процедуры доказательства теорем методом
резолюций и обеспечивает основные операции
с данными при изменении значений переменных,
передачу параметров, выбор и создание
данных.

В основе логического программирования
лежит метод резолюций.

2 Основные конструкции языка

Существует единственная
структура данных — логический терм.
Термы могут быть простыми и составными.

    1. Простой терм может быть константой или переменной. Константа — это атом или число. Атом начинается со строчной буквы, знака или резервного имени. Константы в Прологе могут быть шести типов: integer, real, char, symbol, string, file.

Рисунок 2 – Конструкция 
языка

Пример 2

Константы:

0, -l, 123.4, 0.23E-5, а, +, :, ‘Фред Блогс’

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

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

  • анонимная переменная обозначается символом ‘_’ и показывает, что конкретное значение данной переменной не представляет интереса;
  • явные переменные обозначаются любой последовательностью символов, начиная с заглавной буквы латинского алфавита (X, D1, Wer и т.д.).

Область действия
переменных.

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

Единственным исключением 
из правила определения области 
действия переменных является анонимная 
переменная, например, “_” в цели
любит(Х,_). Каждая анонимная переменная
есть отдельная сущность. Она применяется
тогда, когда конкретное значение переменной
несущественно для данного утверждения.
Таким образом, каждая анонимная переменная
четко отличается от всех других анонимных
переменных в утверждении.

Переменные, отличные от анонимных,
называются именованными
или связными, а не
конкретизированные (переменные, которым
не было присвоено значение) называются свободными.

    1. Составной терм — состоит из функтора и последовательности одного или нескольких аргументов, являющихся термами.

Функтор задается именем (суть
атом) и арностью (число
аргументов).

Пример 3

Составные термы:

dog(“рекс”), parent(Х,У)./ рекс –
собака, родителем Y является X

В данном примере структура dog имеет арность
1 (записывается как dog /1), а структура parent — арность
2 (parent /2). Заметим,
что атом можно рассматривать как структуру
арности 0. Для некоторых типов структур
допустимо использование альтернативных
форм синтаксиса. Это синтаксис операторов
для структур арности 1 и 2, синтаксис списков
для структур в форме списков и синтаксис
строк для структур, являющихся списками
кодов символов.

Утверждения

Программа на Прологе есть
совокупность утверждений. Утверждения 
состоят из целей и хранятся в 
базе данных Пролога. Таким образом,
база данных Пролога может рассматриваться 
как программа на Прологе. В конце 
утверждения ставится точка “.”.
Иногда утверждение называется предложением.
Утверждения бывают трех видов: факты,
правила, вопросы.

Факты используются для констатации
того, что выполнено отношение между объектами
и представляют собой одиночную цель,
которая безусловно истинна. Факты могут
быть унарные и бинарные, а
также простые и универсальные.

Простые факты служат для констатации конкретных
свойств и отношений.

Пример 4

like(jhon, apple) — Джон любит яблоки.

Универсальные факты определяют
совокупность всех возможных решений,
удовлетворяющих этому факту.

Пример 5

like(X, apple) — все любят яблоки.

Конечное множество фактов
образует программу. Это простейший
вид программы. Множество фактов,
с другой стороны, составляет описание
ситуации.

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

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

Пример 6

dog(X).

parent (Х,Y), dog (Y).

Поиск ответа на вопрос состоит 
в том, чтобы определить, является
ли вопрос логическим следствием программы.
Логические следствия выводятся 
путем применения правил. Простейшее
правило вывода – совпадение: из Р выводимо Р.

Вопрос иногда называют управляющей 
командой (директивой), так как он
требует от Пролог-системы выполнения
некоторых действий.

Формальное определение 
синтаксиса Пролога, используя форму 
записи Бэкуса-Наура, иногда называемую
бэкусовской нормальной формой (БНФ), выглядит
так:

запрос ::- голова утверждения

правило ::– голова утверждения
:- хвост утверждения

факт ::- голова утверждения

голова утверждения ::-атом
| структура

хвост утверждения ::- атом структура,

термы ::-терм [,термы]

терм ::- число | переменная |
атом | структура

структура ::-атом (термы)

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

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

Простой вопрос состоит из одной
цели. Процедура поиска ответа на простой
вопрос осуществляется непосредственно.
В программе ищется факт, предполагаемый
в вопросе. Если факт, тождественный вопросу,
найден, то ответ – да. Ответ нет дается в
том случае, когда факт, тождественный
вопросу, не найден, поскольку данный факт
не является логическим следствием программы.
Такой ответ не подвергает сомнению истинность
вопроса, он просто показывает, что не
удалось доказать истинность вопроса
с помощью программы.

Пример 7

В Пролог-программе хранятся
факты:

dog(jek).                           
// jek — собака

dog(rex).                          
// rex — собака

dog(holly).                       
// holly – собака

Программе задается вопрос:

dog(jek).

Ответ утвердительный – yes, так как в
программе существует тождественный факт.

При вопросе:

dog(mikky).

Ответ отрицательный – no, поскольку
в программе не существует тождественного
факта, хотя где-то и может существовать
собака с такой кличкой.

Экзистенциальный вопрос
в общем случае содержит переменные и
может иметь несколько решений.

Пример 8

Программе, описанной в 
Примере 7, задается вопрос:

dog(X).

В качестве ответа будет 
получен результат:

X =jek

X= rex

X= holly

Отрицательный ответ может 
быть получен в том случае, если
в программе не найдется ни одного
факта, тождественного вопросу.

Конъюнктивный вопрос – это
конъюнкция целей, поставленная в виде
вопроса. Подцели отделяются друг от друга
запятой.

Пример 9

dog(jek),dog(rex),dog(X).

Простой вопрос является частным 
случаем конъюнктивных вопросов
с единственной целью. В простейшем
конъюнктивном вопросе все подцели 
простые. 

Правило  — это утверждение
вида A¬B1, B2,…,Bn, где n³0. A называется заголовком правила,
а B1, B2,…,Bn 
— телом правила.
Как A, так и Bi
должны быть целями. Правило состоит из
одной головной цели и одной или более
хвостовых целей, которые истинны при
некоторых условиях.

Правило обычно имеет несколько 
хвостовых целей в форме конъюнкции
целей. Конъюнкцию можно рассматривать 
как логическую функцию И. Таким
образом, правило согласовано, если согласованы
все его хвостовые цели.

Пример10

dog(X) :- parent(X,Y),dog(Y).    
// X является собакой, если у него есть
родитель Y и Y — собака        

homo(Х) :-men(Х).                     
// X – человек, если X – мужчина

Разница между правилами 
и фактами чисто семантическая.
Хотя, для правил мы используем синтаксис
операторов (более подробное рассмотрение
операторного и процедурного синтаксисов
выходит за рамки курса), нет никакого
синтаксического различия между правилом
и фактом.

Так, правило:

dog(X) :- parent(X,Y),dog(Y).    
может быть задано как

:- dog(X)’,’ parent(X,Y)’,’dog(Y).

Запись верна, поскольку
:- является оператором “при условии, что”,
а ‘,’ — это оператор конъюнкции. Однако
удобнее записывать это как:

dog(X) :- parent(X,Y),dog(Y).

и читать следующим образом:
“ Х — собака при условии, что родителем 
Х является Y и Y — собака”.

Логические программы 
могут включать альтернативные определения 
или, более формально, — дизъюнкцию,
применяя альтернативные правила.

Пример 11

Родственное отношение «внук»
можно описать так:

vnuk(X,Y):-fath(Y,Z),fath(Z,X). // X- внук Y,
если Y – отец Z и Z – отец X

vnuk(X,Y):-moth(Y,Z),fath(Z,X). //X- внук Y,
если Y –мать Z и Z – отец X

vnuk(X,Y):-fath(Y,Z),moth(Z,X). //X- внук Y,
если Y –отец Z и Z – мать X

vnuk(X,Y):-moth(Y,Z),moth(Z,X). //X- внук Y,
если  –мать Z и Z –мать X

Однако, то же самое отношение 
можно записать компактнее, определив 
«промежуточное» отношение parent (родитель):

parent(X,Y):- fath(X,Y). //X – родительY,
если X – отец Y

parent(X,Y):-moth(X,Y). //X – родительY,
если X – мать Y

Тогда родственное отношение 
«внук» можно определить так:

  vnuk(X,Y):- parent(Y,Z), parent(Z,X).         

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

Простой абстрактный 
интерпретатор.

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

Абстрактный интерпретатор
выполняет вычисления с ответами «да/нет».
Он получает программу P и основной
вопрос Q и дает ответ да, если Q выводимо из P, и ответ нет, в противном
случае. Кроме того, если цель не выводима,
интерпретатор может вообще не завершить
работу. В этом случае не выдается никакого
ответа. Работу интерпретатора схематично
можно описать следующим образом:

Вход:                          
Основной вопрос Q и программа P

Результат:                  
да, если найден вывод Q из программы
P,

                                   
нет – в противном случае

Алгоритм:                 
Положить резольвенту равной Q.

Пока резольвента A1,A2,…,An
не пуста –

начало цикла

Выбрать цель Ai, 1 £ i  £  n, и такой основной пример

предложения  A¬B1,B2,…,Bk, где k³0 в Р, что A=Ai

(если такого предложения 
нет — выйти из цикла);

положить резольвенту 
равной

A1,…,Ai-1, B1,…,Bk ,Ai+1,…,An

конец цикла

если резольвента пуста,
то результат – да, иначе результат 
– нет.  

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

Рассмотрим протокол поиска
ответа на примере.

Пример 12

Программа, определяющая родственное 
отношение «сын»:

fath(abram,isak).

fath(aran,lot).

men(abram).

men(lot).

men(isak).

sun(X,Y):-fath(Y,X),men(X).

Вопрос: sun(lot, aran)                                

Протокол интерпретатора:

Вход: sun(lot, aran) и программа

Резольвента не пуста

 Выбор: sun(lot, aran) (единственный
выбор)

 Выбор: sun(lot, aran):- fath(aran,lot),
men(lot).      Новая резольвента: fath(aran,lot),
men(lot).

Резольвента не пуста.

    Выбор: fath(aran,lot)                               
// первая подцель в новой резольвенте

   Выбор: fath(aran,lot).                              
//из двух фактов fath(abram,isak), fath(aran,lot) подходит
последний

Резольвента не пуста.

Выбор: men(lot)                                      
// вторая подцель в новой резольвенте

Выбор: men(lot).                                    
//из трех фактов men(abram), men(isak),men(lot)  подходит
последний

Новая резольвента пуста.

Результат: да

3 Ход работы

3.1Построение треугольника
Паскаля

Пример 
выполнения:

Задание: Написать программу, которая
выводит треугольник Паскаля до введенного
пользователем уровня. В программе должна
быть предусмотрена элементарная справка
и защита от ошибок.

Числа, стоящие в одной 
строке, являются биномиальными коэффициентами
соответствующей степени, которые 
можно найти следующим образом:

Ход выполнения:

Был создан проект под названием 
«ТреугольникПаскаля» (рисунок 3), состоящий
из основного окна Task Window и трех диалоговых
окон: AboutDialog, Help, MyDialog. В окне MyDialog  пользователь
будет вводить требуемый уровень треугольника
и нажимать на кнопку OK для отображения
соответствующего треугольника на экран.
Для создания диалоговых окон необходимо
нажать на кнопку Dialog в окне проекта, создать
нужное диалоговое окно и разместить нужные
элементы управления на нем (пример окна
MyDialog на рисунок 4.

Двойным щелчком мыши на
кнопке OK открывается окно атрибутов 
данной кнопки (рисунок 5), в котором можно
установить соответствующие атрибуты,
включая и идентификатор данного элемента
(в нашем случае idc_ok). Именно для данного
идентификатора будет прописан основной
код программы. Идентификатор для поля
ввода текста зададим idc_mydialog_1. Для перехода
к написанию кода для данного объекта
в окне проекта (рисунок 6) необходимо нажать
кнопку Dialog, выбрать нужное диалоговое
окно и нажать на кнопку CodeExpert в результе
чего будет открыто окно Dialog and Window Expert
(рисунок 7). Для перехода к написанию кода
элемента управления необходимо в секции
Dialog or Window Selection выбрать соответствующее
окно (в нашем случае выбрано диалоговое
окно MyDialog). В секции Place Source Code in… выбрать
модуль проекта (в нашем случае выбран
проект ТреугольникПаскаля.pro). В списке
типа событий Event Type выбрать нужный тип
(в нашем случае выбран Control – элементы
управления), в списке Event or Item (событие
или элемент) выбрать нужную позицию (в
нашем случае выбран идентификатор кнопки
OK – idc_ok). После указанных действий необходимо
нажать на кнопку Edit Clause – редактировать
правила (рисунок 7). Если правила для события
или элемента еще не существовали, то кнопка
Edit Clause первоначально называется Add Clause
– добавить правила.

Рисунок 3 — Окно проекта

Рисунок 4 — Окно MyDialog

Рисунок 5 — Атрибуты кнопки
Ок

Рисунок. 7 — Dialog and Window Expert

После нажатия на кнопку
Edit Clause мы переходим к редактору кода соответствующего
элемента (рисунок 8). Именно здесь прописывается
программный код Prolog-приложения. Основной
код нашей программы следующий (просим
обратить внимание читателей, что представленный
код не является панацеей и является не
самым оптимальным с точки зрения затрат
вычислительных ресурсов, код представлен
в книге лишь в качестве примера prolog-программы,
в которой присутствует все основные секции):

Рисунок 8 — Редактор кода

domains

r=real    % задаем r типа real (действительные
числа)

s=string   % задаем s типа string (строки)

predicates

nondeterm calculate1(r,r) 

nondeterm calculate2(r,r,r,r,r,r,r,r)

nondeterm proverka (s)

% определяем предикаты calculate1,
calculate2, proverka. Ключевое слово nondeterm означает,
что данные предикаты недетерминированные,
т.е. для каждого из объявленных предикатов
существует более одной альтернативы.
Предикат calculate1(номер уровня введенный
пользователем, номер уровня в «данный
момент») отвечает за проверку достижимости
требуемого уровня. Предикат calculate2(номер
уровня введенный пользователем, номер
уровня в данный момент, искомый элемент
данного уровня, …вспомогательные переменные).

Clauses

% обработка нажатия кнопки 
Ok

dlg_mydialog_eh(_Win,e_Control(idc_ok,_CtrlType,_CtrlWin,_CtlInfo),0):-!,

EDIT_WIN=win_GetCtlHandle(_WIN,idc_mydialog_1), P=win_GetText(EDIT_WIN),
proverka(P),!.

proverka (P):- str_real(P,P1),!,nl, write («Треуголик
Паскаля с уровнем равным «,P),calculate1(P1,1),!.

proverka(P):- dlg_MessageBox(«Ошибка»,»Вы
должны ввести ЧИСЛО большее 0 «,2,0,0,0).

calculate1(X,N):- X<=0,nl,write («Ошибка!!!Введите
положительное целое число, большее 0»).

calculate1(X,N):- N<=X,nl,calculate2(X,N,1,0,1,N,1,0),!.

calculate2(X,N,X1,Y1,Z1,T1,F1,F3):- X1>0, write
(X1,» «), Y2=Y1+1,Z2=Z1*Y2,

T2=T1-F3,F2=F1*T2,X2=F2/Z2,F4=F3+1, !,calculate2(X,N,X2,Y2,Z2,T1,F2,F4).

calculate2(X,N,X1,_,_,_,_,_):- N1=N+1,calculate1(X,N1).

Работу программы можно 
описать следующим образом: в 
переменную Edit_WIN передаем управление
компонентом mydialog_1 (поле ввода требуемого
уровня), который имеет идентификатор
idc_mydialog_1. В P мы записываем значение, введенное
пользователем, используя встроенный
предикат win_GetText. Далее вызываем предикат
proverka, предназначенный для проверки корректности
введенного пользователем значения. Для
этого используется встроенный предикат
str_real, который переводит переменные типа
string в переменные типа real. В случае успеха
в переменную P1 записывается значение
пользователя, но уже в числовом виде и
происходит вызов предиката calculate1, который
совместно c предикатом calculate2 отвечают
за нахождение элементов треугольника.
В случае неудачи выдается соответствующее
сообщение, извещающее пользователя о
необходимости ввода только чисел. При
вызове предиката calculate1 переменная X содержит
значение введенного пользователем уровня,
а переменная N содержит номер уровня на
текущий момент поиска решения. При успешной
проверке X<=N (то есть требуемый уровень
еще не достигнут) происходит вызов предиката
calculate2. Предисат calculate2 рекурсивно вычисляет
элементы очередного уровня треугольника
Паскаля. По окончании вычислений всех
элементов очередного уровня вторая альтернатива
предиката calculate2 вызывает предикат calculate1
с увеличенным на единицу значением уровня
треугольника. Программа завершает свою
работу по мере достижения требуемого
уровня.

Основной код программы 
прописан, но он сработает только после 
нажатия на кнопку OK диалогового окна
MyDialog, которое пользователю еще необходимо
вызвать. В нашем проекте вызов диалогового
окна будет производиться нажатием одного
из пунктов меню. Для этого необходимо
в окне проекта (рисунок 3) нажать на кнопку
Menu, двойным щелчком открыть окно меню,
в котором создать дополнительный пункт
(рисунок 9.) при помощи кнопки New (в нашем
проекте был создан пункт меню Paskal) и установить
соответствующие атрибуты пункта меню,
включая его идентификатор (в нашем случае
id_paskal).

Рисунок 9 — Окно редактирования
меню проекта

Для перехода к редактору 
кода данного пункта меню необходимо
проделать операции аналогичные 
действиям описанным для перехода к коду
кнопки OK, но при этомнеобходимо выбрать
окно Task Window, выбрать в списке Event Type позицию
Menu, в списке Event or Item выбрать идентификатор
нужного пункта меню (в нашем проекте это
id_paskal, рисунок 10) и нажать соответствующую
кнопку для перехода к редактору кода.

Рисунок 10 — Dialog and Window Expert

В редакторе кода необходимо
прописать вызов диалогового 
окна MyDialog:

task_win_eh(_Win,e_Menu(id_paskal,_ShiftCtlAlt),0):-!,

dlg_mydialog_Create(_Win),!.

Для запуска проекта необходимо
нажать на клавиатуре кнопку F9 либо соответствующие
кнопки в меню или на панели инструментов.

При запуске программы, пользователь
вызывает окно MyDialog нажатием кнопки Paskal
меню. В появившемся окне пользователь
вводит требуемый уровень и нажимает на
кнопку OK. В окне Messages выводится результат
выполнения программы (рисунок 11).

Рисунок 11 — Результат работы
Prolog-программы

Вывод:

В ходе выполнения работы я 
освоил основные секции prolog-программы
и научился использовать рекурсию для
поиска решений.

3.2 Работа со списками

Задание: Объединить два списка, найти
максимальный элемент и удалить его.

Ход выполнения:

В среде Visual Prolog 5.2 создан соответствующий 
проект.

Логика программы:

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

В теоретической части нужно написать несколько слов про логическое и функциональное программирование, описать программу Prolog, как она применяется и какие задачи можно выполнить. Для практической части нужно определить предметную область. А именно: нужно определить отношения объектов.

Предметная область выбирается самостоятельно из любых источников. Главное-показать правильность заданных условий

По самому тексту:

  1. отступы у каждого абзаца 1,25 см;
  2. Выравнивание текста по ширине;
  3. шрифт у текста и заголовков Times New Roman 14;
  4. во Введении 5-6 строк.
  5. межстрочный интервал 1,0 без каких либо добавлений пробелов после заголовков или абзацев;
  6. нумерация страниц, кроме титульного листа;
  7. названия заголовков не одним словом;
  8. указать числовую нумерацию заголовков. Введение, Теоретическая и практическая часть, Заключение, Список литературы не нумеруются;
  9. дополнить текст. Можно добавить заголовок про функции Prolog, какие задачи можно выполнять с его помощью;
  10. рисунки должны быть подписаны и них должны быть ссылки в тексте.
  11. описание практической части оформляется точно также, как и теоретическая часть. Практическая часть включает в себя словесное описание вашей работы с подзаголовками и рисунками.
  12. Список литературы, оформить нужно приблизительно по ГОСТу 7.0.100 — 2018. Существует множество сервисов, которые сами формируют правильно список литературы по одному источнику.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *