
-
Структура продукционного правила.
Основными элементами продукционного правила являются посылка (условная часть) и заключение (действие).
Условная часть правила - это набор условий ("больше", "меньше", "равно" и т.д.). Будем считать, что все условия, составляющие условную часть правила, объединены логической операцией “и”.
Заключение правила - это действие, выполняемое при истинности его условной части. Для простоты будем считать, что в правилах возможно только одно действие: присваивание значения переменной. Будем также считать, что в каждом правиле может быть только одно действие.
При реализации базы знаний для продукционной ЭС средствами языка Пролог каждое правило будем представлять в виде предиката базы данных. Этот предикат будет содержать основные элементы правила (посылку и заключение), а также его номер. Для предикатов, описывающих правила, будем использовать имя rule (правило). Эти предикаты можно объявить следующим образом:
global facts
rule (integer, usl, zakl)
В предикате rule первый аргумент (с типом integer) - номер правила; usl - условная часть правила (посылка); zakl - заключение (действие). Очевидно, что типы usl и zakl - нестандартные (в Прологе таких типов нет). Поэтому их необходимо объявить в разделе global domains.
Условную часть правила объявим в разделе global domains следующим образом:
uslovie=gt(string,string);
lt(string,string);
eq(string,string)
usl=uslovie*
Здесь gt, lt, eq - функторы, с помощью которых будут представляться отдельные условия, составляющие условную часть. Функтором eq будем обозначать условие "равно", gt- "больше", lt - "меньше". Будем считать, что во всех этих функторах первым аргументом является имя переменной, а вторым - некоторая константа, с которой сравнивается значение переменной. Для простоты будем считать, что все величины, обрабатываемые в ЭС - строковые.
Тип uslovie - альтернативный домен. Объект этого типа может представлять собой любой из функторов gt, lt, eq (но только один). Тип usl - список объектов типа uslovie. Таким образом, объект с типом uslovie может представлять собой список из любого количества функторов. Такое объявление позволяет описывать условные части правил, состоящие из произвольного количества различных условий.
Заключение правила объявим в разделе global domains следующим образом:
zakl = assign (string, string)
Здесь assign - функтор, которым будет обозначаться присваивание переменной некоторого значения (вместо assign можно использовать любое другое имя). Имя переменной будем указывать первым аргументом, а присваиваемое значение - вторым.
-
Представление продукционных правил средствами языка Пролог.
ВАРИАНТ 4
Составляется набор правил для определения вероятности наводнения на основе анализа 3 признаков: уровня снега в горах, температуры, состояния погоды (есть дожди или нет). Экспертом приведены следующие примеры:
1) если температура ниже 5 С, то наводнение исключено;
2) если уровень снега высокий, и температура от 5 до 15 С, то наводнение вероятно;
3) если уровень снега средний, температура от 5 до 15 С, и дождей нет, то наводнение маловероятно;
4) если уровень снега низкий, температура от 5 до 15 С, и дождей нет, то наводнение маловероятно;
5) если температура от 5 до 15 С, и дожди есть, то наводнение вероятно;
6) если уровень снега высокий, температура от 15 до 20 С, и дожди есть, то наводнение угрожает;
7) если уровень снега средний, температура от 15 до 20 С, и дожди есть, то наводнение угрожает;
8) если уровень снега средний, температура от 15 до 20 С, и дождей нет, то наводнение угрожает;
9) если уровень снега низкий, температура от 15 до 20 С, то наводнение маловероятно;
10) если уровень снега высокий, температура выше 20 С, то наводнение угрожает;
11) если уровень снега средний, температура выше 20 С, то наводнение вероятно;
12) если уровень снега низкий, температура выше 20 С, и дожди есть, то наводнение маловероятно;
12) если уровень снега низкий, температура выше 20 С, и дождей нет, то наводнение исключено.
Построить набор правил.
База знаний, содержащая эти правила, может выглядеть так:
goal_var("obrab")
var("C","BBEDuвe ypoBeHb cHera(high/mid/low): ")
var("T","BBEDuвe вemnepaвypy: ")
var("D","EcTb Do>|<Db (da/net): ")
var("HaBoDHeHue","")
rule(1,[lt("T","5")],assign("HaBoDHeHue","uck/||-O4eHo"))
rule(2,[eq("C","high"),gt("T","5"),lt("T","15")],assign("HaBoDHeHue","Bepo9|THo"))
rule(3,[eq("C","mid"),gt("T","5"),lt("T","15"),eq("D","net")],assign("HaBoDHeHue","Ma/|OBepo9|THo"))
rule(4,[eq("C","low"),gt("T","5"),lt("T","15"),eq("D","net")],assign("HaBoDHeHue","Ma/|OBepo9|THo"))
rule(5,[gt("T","5"),lt("T","15"),eq("D","da")],assign("HaBoDHeHue","Bepo9|THo"))
rule(6,[eq("c","high"),gt("T","15"),lt("T","20"),eq("D","da")],assign("HaBoDHeHue","yrpo>|<aeT"))
rule(7,[eq("C","mid"),gt("T","15"),lt("T","20"),eq("D","da")],assign("HaBoDHeHue","yrpo>|<aeT"))
rule(8,[eq("C","mid"),gt("T","15"),lt("T","20"),eq("D","net")],assign("HaBoDHeHue","yrpo>|<aeT"))
rule(9,[eq("C","low"),gt("T","15"),lt("T","20")],assign("HaBoDHeHue","Ma/|OBepo9|THo"))
rule(10,[eq("C","high"),gt("T","20")],assign("HaBoDHeHue","yrpo>|<aeT"))
rule(11,[eq("C","mid"),gt("T","20")],assign("HaBoDHeHue","Bepo9|THo"))
rule(12,[eq("C","low"),gt("T","20"),eq("D","da")],assign("HaBoDHeHue","Ma/|OBepo9|THo"))
rule(13,[eq("C","low"),gt("T","20"),eq("D","net")],assign("HaBoDHeHue","uck/||-O4eHo"))
Здесь переменная HaBoDHeHue объявлена как целевая.
Для переменных HaBoDHeHue не указан текст запроса, так как эта переменная не запрашиваются у пользователя, а определяются самой ЭС на основе правил и данных, предоставленных пользователем (температуры и вибрации). Однако указание пустой строки (“”) вместо текста запроса для этих переменных обязательно, так как в объявлении предиката var указано, что он имеет два аргумента.
Приведем текст нашей программы:
global domains
uslovie=gt(string,string);
lt(string,string);
eq(string,string)
usl=uslovie*
zakl=assign(string,string)
global facts
rule(integer,usl,zakl)
var(string,string)
goal_var(string)
znach(string,string)
predicates
nondeterm zagruzka
nondeterm prosmotr
nondeterm vyvod
nondeterm start
nondeterm repeat
nondeterm obrab(integer)
goal
start.
clauses
start:-clearwindow,
makewindow(1,7,7,"База данных",0,0,14,40), /*Ba3a DaHHbIX*/
repeat,clearwindow,
write("1 - Загрузить"),nl, /*3arpy3uTb*/
write("2 - Просмотр списка правил"),nl, /*npocMOTp CnuCKa npaBu/\ */
write("3 - Консультация"),nl, /*KoHcy/\bTaL|u9I*/
write("4 - Выход"),nl, /*BbIXOD*/
write("Сделайте ваш выбор: "),readint(N), /*BBEDuTE HOMEP*/
obrab(N),removewindow.
obrab(1):- makewindow(2,7,7,"Загрузить",12,0,3,60), zagruzka, /*3arpy3uTb*/
removewindow,shiftwindow(1),!,fail.
obrab(2):- makewindow(3,7,7,"Просмотр списка правил",12,0,10,80), prosmotr, /*npocMOTp CnuCKa npaBu/\ */
removewindow,shiftwindow(1),!,fail.
obrab(3):- makewindow(5,7,7,"Консультация",12,0,10,80), vyvod, /*KoHcy/\bTaLLu9I*/
removewindow,shiftwindow(1),!,fail.
obrab(4).
zagruzka:-retractall(_),consult("d:\\Work\\320601\\sada\\5\\baza.dba"),write("База успешно загружена"),readchar(_),!. /*Ba3a ycnewHo 3arpy>|<eHa*/
zagruzka.
prosmotr:-var(X,_),
write("Переменная: ",X),nl, /*nepemeHHa9|*/
readchar(_),fail.
prosmotr:-rule(N,Rule,Zakl),write("Номер: ",N," если: ",Rule," тогда: ",Zakl),nl,readchar(_),fail. /*Homep ec/\u Torda*/
prosmotr.
vyvod.
repeat.
repeat:-repeat.