
- •Введение
- •1. Методические указания к лабораторным работам
- •3. Лабораторные работы по курсу "Системы искусственного интеллекта"
- •5. Индивидуальные задания к лабораторным работам
- •6. Учебные демонстрационные примеры
- •Литература
- •Приложение 1.Руководство по применению системы "Turbo-prolog"
- •Приложение 2. Краткое руководство по применению языка Турбо-пролог версии 2.0
- •Содержание
Приложение 2. Краткое руководство по применению языка Турбо-пролог версии 2.0
1.Имя состоит из букв, цифр и знака подчеркивания.
2.Константы могут быть одного из шести типов:
•Char - символ в одиночных апострофах: ‘f’, ‘/13’, ‘B’, ‘#’, ‘%’
•Integer - целое со знаком из диапазона от –32768 до 32767: –63, 84, 32763
•Real - вещественное со знаком из диапазона от +/–1е–307 до
+/–1е +308:
–42769, 86.72, –521е238, 5.1е–9, –79.83е+21 Integer может автоматически переводиться в Real
•String - строка, представляющая последовательность символов в двойных апострофах: "123", "today", "Ау"
•Symbol - последовательность букв, цифр и подчерков, где впереди строчная буква либо строка: pay_check, flower, "railway_ticket", "Был сильный мороз"
•File - файлы с именем в DOS: mail.txt, BIRDS.DBA
Данные типа symbol, в отличие от данных типа string, находятся в таблице символов, которая располагается в оперативной памяти. Поэтому использование данных типа symbol ускоряет работу программы, однако вначале для построения таблицы символов требуется дополнительное время.
3. Выражения - переменные, структуры, списки и составные выражения.
Переменные бывают свободными и связанными. Структуры - предикаты разных арностей, факты и правила. Список - набор объектов одного доменного типа.
Составной объект или функтор - совокупность простых объектов. Составное выражение - функтор и совокупность альтернативных подобъектов.
Составная структура - объект или выражение (предикат в предикате) не имеет типа, но допускает списки составных структур.
4. Структура программы. Обычно программа на языке Турбопролог имеет в своем составе:
•опции компилятора;
81
•произвольное количество произвольно следующих друг за другом секций:
constants - объявление констант, domains - объявление типов данных, predicates - объявление предикатов, clauses - объявление фактов и правил;
•программные секции:
goal - определение внутренней цели,
global domains ; global predicates - определение глобальных доменов и предикатов, что позволяет обеспечить межмодульный интерфейс.
Содержимое разделов constants и domains может отсутствовать, но для улучшения читаемости и ясности программы рекомендуется всегда описывать константы и домены в тексте.
Секция определения цели goal может быть только одна или может отсутствовать, если цель определяется в диалоге. Если секция goal присутствует, в ней определяется внутренняя цель, которую необходимо достичь для решения поставленной задачи. Цель может состоять из нескольких подцелей. Если разрабатываемая программа предназначена для работы в пакетном режиме, т.е. если необходимо создать exe-файл, секция goal не может быть опущена. Наконец, перед секцией predicates может быть дополнительный раздел
database - определение предикатов динамической базы данных. Таким образом, программа на языке Турбо-пролог может состоять из следующих секций: clauses, constants, database, domains, global domains, global predicates, goal, predicates.
Секцияdomains содержитвсеобъявления доменовчетырех форматов:
name = d |
/* стандартный домен */ |
mylist = elementDom* |
/* списочный домен */ |
myCompDom = f1(d11,d12,...,d1n); f2(d21,d22,...,d2n); |
|
/* домен составного объекта */ |
|
file = name1; name2; ...; namen |
/* файловый домен */ |
Секция predicates определяет предикаты (отношения). Каждый |
|
предикат определяется со |
своим именем и аргументами |
(параметрами). Если типы данных некоторых аргументов предопределены, то они должны быть описаны заранее в разделе domains.
82
Раздел clauses определяет факты и правила.
•Факт представляется именем предиката, за которым следуют объекты, заключенные в круглые скобки. Заканчивается запись факта точкой. Все имена предикатов должны начинаться со строчной буквы.
•Правило состоит из заголовка и тела. Заголовок представляет собой предикат, тело состоит из термов, которые могут быть связаны между собой словами or или and (в транскрипции 'Turbo-Prolog' ";" и ","). Между заголовком и телом стоит знак ":-", означающий "если". Каждое правило должно заканчиваться точкой.
Имена переменных должны начинаться с прописной буквы и могут содержать буквы, цифры и знак подчеркивания "_". Максимальная длина имени - 250 знаков. Особую роль играют анонимные переменные, значения которых недоступны, они представляются знаком "_".
Комментарии могут располагаться в произвольных местах программы. Они начинаются с символов "/*" и заканчиваются символами"*/".
Пример правила для сложения двух десятичных чисел: sum(X,Y,Z) :– Z=X+Y.
5. Приемы повторения.
•Предикат fail вызывает откат (бэктрекинг).
•Предикат отсечения ! прерывает откат (бэктрекинг не распространяется на предшествующие предикаты).
•Правила, выполняющие повторения, используют откат, а правила, выполняющие рекурсию, используют самовызов.
•Вид правила, выполняющего повторение:
repetitive_rule :- |
/* правило повторения */ |
< предикаты и правила >, |
|
fail. |
/* неудача */ |
•Вид правила повторения, определяемого пользователем:
repeat. |
|
/* повторить */ |
|
repeat :- repeat. |
|
|
|
• |
Вид правила, выполняющего рекурсию: |
||
recursive_rule :- |
|
/* правило рекурсии */ |
|
< предикаты и правила >, |
|
|
|
recursive_rule. |
|
|
|
• |
Пример правила рекурсии |
с |
условием выхода - циклически |
считывается введенный символ и, |
если он не совпадает с некоторым |
||
|
|
|
83 |
заданным символом, например, {, то выдается на экран, а при вводе
этого символа { рекурсия прерывается: |
|
read_char :- |
|
readchar(Char_data), |
|
Char_data <> '{', |
|
write(Char_data), |
|
read_char. |
|
• Обобщенное правило рекурсии: |
|
<имя правила рекурсии> :- |
|
<список предикатов>, |
(1) |
<предикат условия выхода>, |
(2) |
<список предикатов>, |
(3) |
<имя правила рекурсии>, |
(4) |
<список предикатов>. |
(5) |
6. Встроенные предикаты обмена данными с экраном дисплея и клавиатурой (или файлом):
•чтения строки символов целиком : readln(Line)
•считывания целого числа с клавиатуры или из файла в переменную Num: readint(Num)
•считывания десятичного числа с клавиатуры в переменную Val: readreal(Val)
•считывания символа с клавиатуры в переменную Char: readchar(Char)
•выдачи на экран (предикат с произвольным числом аргументов) строк и/или строковых переменных Name: write(" <строка1> ", Name1," <строка2> ", Name2,...," <строкаn> ", Namen)
•перехода на новую строку экрана: nl
•форматированного вывода: writef(FormatString, Arg1,Arg2, ...,
ArgN)
•readdevice(myfile) и writedevice(yourfile) настраивают устройство ввода на файл myfile, а устройство вывода - на файл yourfile
•по умолчанию устройство ввода - клавиатура, а устройство вывода - экран
•переадресации вывода на принтер: writedev(printer)
7.Встроенные предикаты работы со строками для:
84
•определения длины String_length некоторой строки String_value: str_len(String_value, String_length)
•конкатенации (слияния) строк:
concat(Input_string1,Input_string2,Output_string)
•создания из строки L подстроки L1 заданной длины N c
остатком в подстроке L2: |
frontstr(N,L,L1,L2) |
•преобразования типов: upper_lower(S1, S2), str_char(S, C), str_int(S, I), str_real(S, R), char_int('S', N)
•конкатенации префикса Char к строке Str: frontchar(Charstr, Char, Str)
•проверки, является ли строка именем: isname(String)
•формирования атома из строки: fronttoken(String, Token, Rest_of_string).
8.Примеры правил работы со строками:
• соединения двух входных целых списков L1 и L2 с созданием выходного списка L3 с помощью некоторого списочного предиката soedin(integer*,integer*,integer*):
soedin([],L,L).
soedin([N|L1],L2,[N|L3]) :- soedin(L1,L2,L3)
•преобразования строки в символ: conv(Str,Sym) :- Str=Sym
•преобразования некоторой строки Str в список символов Sps:
cnv("", [])
cnv(Str, [Head|Tail] :- frontchar(Str, Head,Sps), cnv(Sps, Tail)
• преобразования некоторой строки S в список атомов Tok: conv(S, [Head|Tail]) :- fronttoken(S, Head, Tok),!,conv(Tok,Tail). сonv(_, [])
9.Встроенные предикаты для работы с файлами:
• |
уничтожение файла |
deletefile(DOS_filename) |
• |
сохранение файла |
save(DOS_filename) |
•переименование файла
• |
renamefile(Old_DOS_filename, New_DOS_filename) |
|
тест на наличие файла с данным именем |
|
|
existfile(DOS_filename) |
|
|
• |
сброс данных из внутреннего буфера |
flush(file_domain) |
85
• |
выбор пути доступа |
disk(Path) |
• выдача каталога файлов с расширением File_spec с выбором |
||
нужного в переменную File_name |
|
|
dir(Path, File_spec, File_name) |
|
|
• закрытие файла встроенным предикатом |
closefile(datafile) |
|
• |
обнаружение конца файла |
eof(datafile) |
• выдача каталога файлов с расширением File_spec с выбором нужного в переменную File_name:
dir(Path, File_spec, File_name)
•Пример описания файлового домена на три имени файлов DOS: file = datafile1; datafile2; datafile3
•Пример открытия DOS-файла "FILE1.DAT" на чтение для файлового домена datafile1:
openread(datafile1, "FILE1.DAT").
•Пример открытия DOS-файла "FILE1.DAT" на чтение и запись для файлового домена datafile1:
openmodify(datafile1, "FILE1.DAT").
•Пример дозаписи в конец DOS-файла "FILE1.DAT" из файлового домена datafile1:
openappend(datafile1, "FILE1.DAT").
10.Встроенные предикаты динамической базы данных.
•Раздел database предназначен для описания предикатов динамической базы данных, тогда как предикаты статической базы данных описываются в разделе predicates.
•В динамической базе данных (ДБД) содержатся только факты, но не правила. ДБД состоит из резидентной части (находящейся в оперативной памяти) и долговременной части (находящейся в файле).
•asserta(Clause) - занесение нового факта в резидентную часть ДБД перед всеми уже внесенными утверждениями данного предиката;
•assertz (Clause) - занесение нового факта в резидентную часть ДБД после всех уже внесенных утверждений данного предиката;
•retract(Clause) - удаление из резидентной части ДБД одного из ранее внесенных утверждений;
•save(Dos_file_name) - перенос резидентной части ДБД в долговременную, т.е. из оперативной памяти в файл;
86
•consult(Dos_file_name) - перенос долговременной части ДБД в резидентную, т.е. из файла в оперативную память;
•readterm(dom, b(A1,A2,...,An)) - чтение из открытого файла значений аргументов A1,A2,...An данного домена dom, описанного в разделе domains как, например,
A1 = string
A2 = integer
. . .
An = real
dom = b(A1, A2. ..., An),
findall(Variable_name, Predicate_expression, List_name) - сбор
данных, относящихся к аргументу Variable_name, |
входного |
предиката |
|
Predicate_expression, из ДБД в список List_name. |
|
11. Примерыблоковэкспертнойсистемы, базирующейсянаправилах.
Интерфейсом реализуются следующие функции:
•обработка данных, принимаемых с клавиатуры, и визуализация входных и выходных данных;
•поддержка диалога между пользователем и системой;
•распознавание ситуации непонимания между пользователем и системой;
•обеспечение "дружественности" по отношению к пользователю.
Блоки строятся как наборы правил в разделе clauses. Трассы ответов клиента сохраняются в базе данных
database |
qda(symbol,symbol) |
qnet(symbol, symbol) |
Целевое |
правило do_usluga |
создает дружественное меню, |
облегчающее диалог, и исполняет экспертную функцию с помощью правила do_poisk, контролируя окончание диалога:
/*ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС*
do_usluga:- makewindow(1,7,6,"ЭКСПЕРТНАЯ СИСТЕМА",1,18,22,58), nl,write("**************************************************
******"),
nl,write("Нужна кошка"),
87
nl,write("Отвечайте только <да> или <нет>"), nl, do_poisk.
do_usluga:- nl, write("На выходENTER"),nl, readln(_),
removewindow, exit.
ask(X,Y):- write("Она ", X,Y), readln(Reply), remember (X,Y,Reply).
Продукционное правило исполнения экспертной функции do_poisk уточняет запрос клиента и запрашивает необходимую информацию в базе данных, сообщая результаты клиенту при успехе и извиняясь, если имеющихся данных недостаточно:
do_poisk:- variant(X),!,nl, write("Кошка для Вас - ",X," ."),nl, clear.
do_poisk:- nl,write("Жаль, не могу Вам помочь!"), clear.
Модуль вывода просматривает базу данных и оценивает ответы клиента:
da(X,Y):- qda(X,Y),!.
da(X,Y):- not(net(X,Y),!, ask(X,Y). net(X,Y):- qnet(X,Y),!.
запоминает их:
remember(X,Y, "да"):- asserta(qda(X,Y)). remember(X,Y,"нет"):- asserta(qnet(X,Y)),fail.
и очищает трассу ответов: clear:- retract(qda((_,_)), fail. clear:- retract(qnet(_,_)), fail.
Пользователь может пополнить набор правил этой экспертной системы, дописав нужные строки в раздел clauses, а затем повторить диалог:
/*ПРОДУКЦИОННЫЕ ПРАВИЛА */ variant("Мурка"):-
pasport("стоит","до 50$"), pasport("имеет возраст","4 года"),!.
variant("Кэтти"):-
88
pasport("стоит","от 50$"), pasport("имеет возраст","3 года"),!.
. . .
/*КОНЕЦ*/
89