Лабораторная работа № 1 «Основные сведения (элементы) языка Пролог» по курсу «Системы искусственного интеллекта»

Цель работы:

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

 

Задание 1:

1.1) Ознакомьтесь с примером программы, со структурой и разделами программы.

Текст программы:

/* Словарь:

baseball - бейсбол

person - индивидуум

activity - род занятий

swimming - плавание */

goal

likes(bill, baseball)

domains

person, activity = symbol

predicates

likes(person,activity)

clauses

likes(ellen,tennis).

likes(john,football).

likes(tom,baseball).

likes(eric,swimming).

likes(mark,tennis).

likes(bill,X_var) if likes(tom,X_var).

 

Программа на Турбо Прологе имеет следующую основную структуру:

domains ( поля )

/* ...операторы domain ... */

predicates ( предикаты )

/* ... операторы предикатов ... */

goal ( цель )

/* ... подцель_1, подцель_2, и т.д.*/

clauses ( утверждения )

/* ... утверждения (правила и факты)..*/

 

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

X_var используется в качестве переменной для обозначения неизвестного действия.

Примеры недопустимых имён: 1stattempt, second, 'disaster.

 

Факты, описанные в разделе утверждений в программе, содержат отношения (relations) между одним и более объектами (objects).

Например, likes(tom,baseball), где отношение = likes, объекты = tom, baseball.

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

Имена отношений - любые комбинации букв, цифр и знака подчеркивания.

Отношение (relation) может содержать 1, 2 и более объектов.

Примеры фактов и правил в Турбо-Прологе:

likes(ellen, reading)

likes(john, computers)

likes(enc, swimming)

likes(marybeth, X) if likes (john, X)

likes(gina,X) if likes (enc, X)

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

Например,

domains

person, activity = symbol

predicates

likes (person,activity)

Здесь отношение «likes» устанавливается между объектами, которые принадлежат к символьному полю.

Если ввести цель: «likes (12, X)», то система ответит: «type error», т.е. 12 не может быть в таких отношениях, т.к. 12 не относится к символьному полю.

Например, likes (bill, tom, baseball) также ошибочно, т.к. отношение «likes» должно включать только 2 объекта (см. predicates).

 

 

Программа в Турбо-Пролог включает следующие разделы:

- domains /*(домены) - раздел объявлений*/;

- database /* описания предикатов динамической базы данных */;

- predicates /* описания предикатов */;

- goal /* целевое утверждение */;

- clauses /* утверждения - факты и правила */.

В программе обязательными являются разделы predicates и clauses.

Факт – это утверждение, истинность которого безусловна.

Правило – это утверждение, зависящее от условии.

Цель – это вопрос пользователя к системе о том, какие утверждения являются истинными.

Факты описываются в программе в разделе утверждений (clauses):

likes(ellen, tennis).

likes(john, football).

likes(tom, baseball).

likes(eric, swimming).

likes(mark, tennis).

 

Отметьте, что в фактах нет информации о том: «likes (bill, baseball)», т.е. прямого указания на цель. Поэтому, если при выполнении программы в качестве цели (goal) задать: «likes (bill, baseball)», то для доказательства этого Пролог использует правило: «likes (bill, X) if likes (tom, X)».

 

1.2) Реализуйте программу и выполните её, задав в качестве целей функции с разными параметрами. Например, «likes (bill, baseball), likes (bill, tennis)».

Для реализации необходимо создать файл с расширением «pro».

Для выполнения в диалоговом окне программы после «Goal:» нужно ввести цель.

 

Отметьте, что при доказательстве первой цели Турбо-Пролог ответит: True, так как он скомбинировал правило «like (bill, X) if likes(tom, X)» с фактом «likes(tom, baseball)» и определил истинность «likes (bill, baseball)».

А при цели «likes (bill, tennis)» система ответит «No solutions», так как нет факта «likes(bill,tennis)» и нет правила, из которого может быть сделан вывод.

 

Задание 2: Примеры использования полей целей и правил.

2.1) Реализовать программу.

 

Текст программы:

/* Словарь:

car - машина

brand - марка

color - цвет

age - срок эксплуатации

price - цена

mileage - число пройденных миль

body - корпус*/

goal

car(Make,Odometer,Years_on_road,Body,25000)

domains

brand, color = symbol

age, price = integer

mileage = real

predicates

car(brand,mileage,age,color,price)

/* <== удалить с данной строки до ... */

goal

car(Renault,13,3,5,red,12000).

/* 2200 type error: сообщение об ошибке в окне диалога.

3.5 не является целым числом.

age должно быть целым.

Удалите цель и продолжайте. */

/* ...этой ==> */

clauses

car(chrysler,130000,3,red,12000).

car(ford,90000,4,gray,25000).

car(datsun,8000,1,red,30000).

 

2.2) В программу намеренно внесена ошибка. Для выполнения программы удалите отмеченную область.

Здесь предикат «car» содержит объекты, принадлежащие к полям «age» и «price», которые имеют целый тип. Поле «mileage» относится к вещественным числам.

 

Цель программы: car (Make, Odometer, Years_on_road, Body, 25000), т.е. найти машину в базе данных, которая стоит 25000$.

Турбо-Пролог ответит: «Make= ford, Odometer= 90000, Years_on_road=4, Body=gray. 1 Solution».

 

Удалите правила и введите следующие:

car (renault,13,3,5, red,12000).

car (ford,90000, gray,4,25000).

car (1,red,30000,80000,datsun).

Все поля содержат ошибки.

 

2.3) Задание сложных целей.

Осуществите запрос на поиск в базе данных машины стоимостью менее 25000$. Для этого нужно составить целевую функцию как: car(Make,Odometer,Year_on_road,Body,Cost) and Cost<25000.

При доказательстве Турбо-Пролог разбивает её на 2 подцели:

1) car(Make,Odometer,Year_on_road,Body,Cost);

2) Cost<25000.

 

2.4) Задание целей с безымянными переменными.

Анонимные (безымянные) переменные используются вместо имён объектов, не существенных для пользователя. Записываются они как символ подчёркивания («_»).

Анонимная переменная может использоваться вместо любой переменной, но она никогда не принимает конкретного значения.

Также они могут использоваться в фактах, например, owns(_, shirt) /*everyone owns a shirt (все люди носят рубашку)*/.

 

Задайте цель как: car(_,_,Age,_,Cost) and Cost>12700.

И получите ответ Турбо-Пролога:

Age= 3, Cost= 32000

Age= 4, Cost= 25000

2 Solutions

 

Задание 3: Нахождение решения при сложных целях – поиск с возвратом.

Реализуйте программу, на основе представленной, где необходимо организовать соревнования по пинг-понгу между учениками 9 лет. Цель – выбрать возможные пары: pupil (Person1, 9) and pupil (Person2, 9) and Person1<>Person2. Проследите выполнение программы по удовлетворению подцелей.

Текс программы:

/* Словарь:

child - ребенок

age - возраст

pupil - ученик

person - индивидуум */

domains

child = symbol

age = integer

predicates

pupil(child,age)

clauses

pupil(peter,9).

pupil(paul,10).

pupil(chris,9).

pupil(susan,9).

 

Задание 4: Отношение not и связка объектов.

Реализуйте программу.

Текст программы:

/* Словарь:

person - индивидуум

male - мужчина

smoker - курящий

date - назначать свидание, кандидатура

vegetarian - вегетарианец

possible - возможный */

domains

person = symbol

predicates

male(person)

smoker(person)

vegetarian(person)

sophie_could_date(person)

goal

sophie_could_date(X) and

write("a possible date for sophie is ",X) and nl.

clauses

male(joshua).

male(bill).

male(tom).

smoker(guiseppe).

smoker(tom).

vegetarian(joshua).

vegetarian(tom).

sophie_could_date(X) if male(X) and not(smoker(X)).

sophie_could_date(X) if male(X) and vegetarian(X).

 

После выполнения Турбо-Пролог сообщит только об одном решении: «a possible date for sophie is joshua».

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

 

Обратите внимание, что для того, чтобы проверить, что объект male(X) не является smoker(X), значение X должно быть связанным перед обработкой.

Это значит, что запись: «sophie_could_date(X) if not(smoker(X)) and male(X)» является неверной, т.к. поиск будет идти среди smoker(X), а после будет браться отрицание факта, что приведёт к невозможности нахождения цели.

 

Задание 5: Пример базы данных «отношения в семье».

Реализовать программу, дополнив её целями.

В результате выполнения программы ответьте:

1) alan является братом ivan?

2) Кто дедушка marilyn?

3) Кто сестра fay?

4) Какая родственная связь между marilyn и beverly, если она есть?

 

Обратите внимание: при компиляции с целью получения модуля (.EXE) цель должна быть включена в программу.

 

Внутренняя цель, если она не верна, не будет удовлетворена, и решение не высвечивается.

Текст программы:

/* Словарь:

father - отец

parent - родитель

uncle - дядя

brother - брат

grandfather - дедушка

male - мужчина

female - женщина

sister - сестра

mother - мать

is - есть, является */

domains

person = symbol

predicates

male(person)

female(person)

father(person,person)

mother(person,person)

sister(person,person)

parent(person,person)

brother(person,person)

uncle(person,person)

grandfather(person,person)

clauses

male(alan).

male(charles).

male(bob).

male(ivan).

female(beverly).

female(fay).

female(marilyn).

female(sally).

mother(marilyn,beverly).

mother(alan,sally).

father(alan,bob).

father(beverly,charles).

father(fay,bob).

father(marilyn,alan).

parent(X,Y) if mother(X,Y).

parent(X,Y) if father(X,Y).

brother(X,Y) if /*Брат Х есть Y, если */

male(Y) and /*Y есть мужчина и */

parent(X,P) and /*родитель Х есть Р и */

parent(Y,P) and /*родитель Y есть Р и */

X <> Y. /* X и Y не один человек */

sister(X,Y) if /*Сестра Х есть Y если */

female(Y) and /*Y - женщина и */

parent(X,P) and /*родитель X есть P и */

parent(Y,P) and /*родитель Y есть P и */

X <> Y. /*X и Y не один человек */

uncle(X,U) if /*Дядя X есть U если */

mother(X,P) and /*мать X есть P и */

brother(P,U). /*брат P есть U. */

uncle(X,U) if /*Дядя X есть U если */

father(X,P) and /*отец X есть P и */

brother(P,U). /*брат P есть U */

grandfather(X,G) if /*Дед X есть G */

father(P,G) and /*если отец P есть G */

mother(X,P). /*и мать X есть P. */

grandfather(X,G) if /*Дед X есть G */

father(X,P) and /*если отец X есть P */

father(P,G). /*отец P есть G */

 

 

При удовлетворении данных целей будут получены следующие

результаты:

1) «brother(ivan,alan)» - неверно; в качестве решения ничего не высвечивается;

2) «grandfather(marilyn,Gf),write(Gf)» - в качестве решения возвращается: «charles»; в качестве решения для внешней цели возвращается также: «bob»;

3) «sister(fay,Sis),write(Sis)» - ничего не возвращается;

4) «sister(marilyn,beverly) and write("marilyn is beverly's sister") or mother(marilyn,beverly) and write("marilyn is beverly's mother")» - возвращает: «marilyn is beverly's mother».