Лабораторный практикум пролог. Методические рекомендации по дисциплине Анализ данных
Скачать 311.21 Kb.
|
1.5 Списки Краткие теоретические сведения Список - это объект, который содержит конечное число других объектов. Список в ПРОЛОГе заключается в квадратные скобки и элементы списка разделяются запятыми. Список, который не содержит ни одного элемента, называется пустым списком. Список является рекурсивным объектом. Он состоит из головы (первого элемента списка) и хвоста (все последующие элемента). Хвост также является списком. В ПРОЛОГе имеется операция “|”, которая позволяет делить список на голову и хвост. Пустой список нельзя разделить на голову и хвост. Тип данных "список" объявляется в программе на Прологе следующим образом: DOMAINS списковый_тип = тип* где "тип" - тип элементов списка; это может быть как стандартный тип, так и нестандартный, заданный пользователем и объявленный в разделе DOMAINS ранее. Основными операциями на списками являются: формирование списка; объединение списков; поиск элемента в списке; вставка элемента в список и удаление из списка. Пример 1 Сформировать список вида [7,6,5,4,3,2,1] Решение DOMAINS list = integer* PREDICATES genl(integer, list) CLAUSES genl(0,[]):-!. genl(N,[N|L]):-N1=N-1, genl(N1,L). GOAL genl(7,L),write(L),nl. Результат выполнения программы: [7,6,5,4,3,2,1] Пример 2 Сформировать список из N элементов, начиная с 2. Каждый следующий на 4 больше предыдущего. Решение DOMAINS list = integer* PREDICATES genl( integer, integer, list ) CLAUSES genl(N2,N2,[]):-!. genl(N1,N2,[N1|L]):-N1 genl(N,N2,L). GOAL write("N="),readint(N),K=4*(N+1)-2, genl(2,K,L),write(L),nl. Результат выполнения программы: N=5 [2,6,10,14,18] Пример 3 Сформировать список последовательных натуральных чисел от 4 до 20 и найти количество его элементов. Решение: DOMAINS list = integer* PREDICATES genl1(integer, integer, list ) len(integer, list ) CLAUSES genl1(N2,N2,[]):-!. genl1(N1,N2,[N1|L]):-N1 len(X,[_|L]):-len(X1,L), X=X1+1. GOAL genl1 (4,21,L ),write(L),nl, len(X, L),write("Количество элементов=",Х),п1. Результат выполнения программы: [4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] Количество элементов=17 Пример 4 Определить, содержится ли введенное число Х в заданном списке L. Решение: DOMAINS list = integer* PREDICATES member(integer, list) CLAUSES member(X,[X|_]):-write("yes"),!. member(X,[]):-write("no"),!. member(X,[_|L]) :- member(X, L). GOAL L=[1,2,3,4], write(L),nl, write("X="),readint(X), member(X, L),nl. Результат выполнения программы: й случай: [1,2,3,4] X=3 yes й случай: [1,2,3,4] X=5 no Пример 5 Сформировать списки L1=[1,2,3], L2=[10,11,12,13,14,15] и объединить их в список L3. Решение: DOMAINS list = integer* PREDICATES genl1(integer,integer,list) append(list,list,list) CLAUSES genl1(N2,N2,[]):-!. genl1(N1,N2,[N1|L]):-N1 append([X|L1],L2,[X|L3]):-append(L1,L2,L3). GOAL genl1(1,4,L1),write("L1=",L1),nl, genl1(10,16,L2),write("L2=",L2),nl, append(L1,L2,L3),write("L3=",L3),nl. Результат выполнения программы: L1=[1,2,3] L2=[10,11,12,13,14,15] L3=[1,2,3,10,11,12,13,14,15] Пример 6 Удалить из списка, элементами которого являются названия дней недели, указанный элемент. Решение: DOMAINS list = symbol* PREDICATES del(symbol,list,list) CLAUSES del(X,[X|L],L). del(X,[Y|L],[Y|L1]):-del(X,L,L1). GOAL Ь=[пн, вт, ср, чт, пт, сб, Ed^^te^'L^^L^nl, write("X="),readln(X), del(X,L,L1),write("L1=",L1),!; write("Элемент отсутствует в списке"),nl. Результат выполнения программы: й случай: L=["пн","вт","ср","чт","пт","сб","вс"] X=ср L1=["пн","вт","чт","пт","сб","вс"] й случай: L=["пн","вт","ср","чт","пт","сб","вс"] X=пр Элемент отсутствует в списке Пример 7 Вставить в список имен новый элемент, значение которого вводится с клавиатуры. Вывести все возможные варианты вставок. Решение: DOMAINS list = symbol* PREDICATES del(symbol,list,list) ins(symbol,list,list) CLAUSES del(X,[X|L],L). del(X,[Y|L],[Y|L1]):-del(X,L,L1). ins(X,L1,L):-del(X,L,L1). GOAL L=[olga, oksana, toma, dima],write("L=",L),nl, write("X="),readln(X), ins(X,L,L1),write("L1=",L1),nl, fail. Результат выполнения программы: L=["olga","oksana","toma","dima"] X=vera L1=["vera","olga","oksana","toma","dima"] L1=["olga","vera","oksana","toma","dima"] L1=["olga","oksana","vera","toma","dima"] L1=["olga","oksana","toma","vera","dima"] L1=["olga","oksana","toma","dima","vera"] Пример 8 Найти сумму элементов списка целых чисел. Решение: DOMAINS list=integer* PREDICATES sum_list(list, integer) CLAUSES sum_list([],0). sum_list([X|L],S):-sum_list(L,S1),S=S1+X. GOAL L=[1,2,3,4,5],sum_list(L,S), write("S=",S). Результат выполнения программы: S=15 ЗАДАНИЯ ДЛЯ САМОСТОЯТЕЛЬНОЙ РАБОТЫ 1. 2. 3. 4. 5. 6. 7. 8. Сформировать список [2, 4, 6, 8, 10] и удалить из него введенное число. Сформировать списки [1, 3, 5, 7, 9] и [2, 4, б, 8, 10] и объединить их в один. Сформировать список [3, 6, 9, 12, 15, 18] и вставить в него введенное число. Сформировать список из N натуральных чисел, начиная с 10. Каждое следующее на 5 больше предыдущего. Сформировать список [3, 6, 9, 12, 15] и найти сумму его элементов Сформировать список [6, 5, 4, 3, 2] и найти сумму его элементов Сформировать список [7, 5, 3, 1] и найти произведение его элементов Сформировать список из N последовательных натуральных чисел, начиная с 10. Найти сумму его элементов 1.6 Создание экспертных систем средствами ПРОЛОГа Краткие теоретические сведения Экспертные системы (ЭС) - это сложные программные комплексы, аккумулирующие знания специалистов в конкретных предметных областях и тиражирующие этот эмпирический опыт для консультаций менее квалифицированных пользователей. При разработке экспертной системы на ПРОЛОГе база знаний записывается в виде предикатов, которые описывают обобщённые и конкретные сведения об объектах данной предметной области, выражают правила определения понятий, а формулируют запросы. В программе на ПРОЛОГе в разделе clauses перечисляются факты, содержащие сведения, которые являются постоянными для данной предметной области. Такая база данных является статичной, т.к. факты невозможно удалить или добавить новые в ходе выполнения программы. Для работы с данными, которые ЭС получает от пользователя в процессе работы и сохраняет их в рабочей памяти, используется внутренняя (динамическая) база данных. Динамическая база данных состоит из фактов, которые в ходе выполнения программы можно добавлять и удалять из базы, кроме того в ПРОЛОГе есть средства для сохранения их в файл и загрузки из файла в БД. Во внутренней базе данных могут храниться только факты, а не правила. Таблица 1. Предикаты и их назначение [5].
Построим небольшую экспертную систему, которая будет определять одну из нескольких рыб по признакам, указанным пользователем. Система будет задавать вопросы и строить логические выводы на основе полученных ответов. Типичный диалог экспертной системы с пользователем может выглядеть следующим образом (рис.27): рис.27. Диалог экспертной системы с пользователем Первым шагом построения такой системы является обеспечение ее знаниями, необходимыми для выполнения рассуждений. Программа должна во время консультаций выводить заключения из информации, имеющейся в базе знаний, а также использовать новую информацию, полученную от пользователя. Поэтому минимальная ЭС должна включать: базу знаний; механизм вывода; пользовательский интерфейс. Разработку любой ЭС следует начать с исследования предметной области. Пусть на основе бесед с экспертом были получены следующие эмпирические правила: ЕСЛИ это отряд карпообразные и И у рыбы желто-золотистый окрас И губы с 4 усиками ТО это сазан ЕСЛИ это отряд карпообразные И у рыбы плавники с розовыми перьями ТО это плотва ЕСЛИ спинной плавник узкий И у рыбы желто-золотистый окрас И это отряд карпообразные ТО это лещ ЕСЛИ у рыбы нет зубов И одиночный спинной лучевой плавник И это костная рыба И это пресноводная рыба TO это отряд карпообразные ЕСЛИ у рыбы есть костный скелет ИЛИ у рыбы есть жаберные крышки TO это костная рыба ЕСЛИ рыба плавает в озерах ИЛИ рыба плавает в реках ТО это пресноводная рыба Для создания базы знаний используем предикаты: fish(symbol) otrajd(symbol) vid(symbol) priznak(symbol) Базу знаний будут составлять следующие правила:
рг1гпак("у рыбы желто-золотистый окрас"), рг1гпак("у рыбы спинной плавник узкий"). Необходимо предусмотреть, что искомой рыбы в базе знаний нет: fish("Данной рыбы в базе знаний не обнаружено"). otrajd("отряg карпообразные"):- vid("nресноводная рыба"), vid("костная рыба"), priznak("одиночный спинной лучевой плавник"), priznak("y рыбы нет зубов"). vid("костная рыба"):- priznak("y рыбы есть жаберные крышки"); priznak("y рыбы есть костный скелет"). vid("пресноводная рыба"):- priznak("рыба плавает в реках или озерах"). Для хранения информации, полученной от пользователя, используются предикаты yes и no, составляющие внутреннюю базу фактов. Предикат yes служит для хранения фактов, соответствующих положительному ответу, а предикат no - для хранения отрицательных ответов. Т.е. предикат yes утверждает наличие какого-либо признака у рыбы, а no - отсутствие указанного признака. Эти предикаты объявляются в разделе внутренней базы фактов: global facts yes (symbol) no (symbol) Добавить новые факты во внутреннюю базу можно с помощью правила add_to_database, состоящего из двух частей. Первая часть добавляет факты, соответствующие положительному ответу (с клавиатуры вводится ‘y'). Вторая часть правила добавляет факты, указывающие на отсутствие данного признака у рыбы. add_to_database (Y,'y') :- assertz (yes (Y)). add_to_database (Y,'n') :- assertz (no (Y)),fail. Необходимо предусмотреть очистку внутренней базы фактов. Для этого создадим правило: clear_from_database :- retract(yes(_)),fail. clear_from_database :- retract(no(_)),fail. Для проверки наличия у рыбы определенного признака создадим правило priznak (Y): priznak (Y) :- yes (Y),!. priznak (Y) :- not(no (Y)), question (Y). Формулировка вопроса, ввод ответа и сохранение соответствующего правила осуществляется с помощью правил: answer :- fish(X),!,nl, save("BF1.dbf"), write (" Ответ: ",X,"."),nl. question(Y) :- write ("Вопрос: ",Y,"?(y/n) "), otvet(X), write(X),nl, add_to_database (Y,X). otvet(C):-readchar(C). И, наконец, правило begin, запускающее сеанс консультации: begin :- write ("Ответьте на вопросы :"),nl,nl, answer, clear_from_database, nl,nl,nl,nl, exit. Полный листинг программы выглядит следующим образом: GLOBAL FACTS yes (symbol) no (symbol) PREDICATES fish(symbol) otrajd(symbol) vid(symbol) begin answer question(symbol) add_to_database(symbol,char) otvet(char) clear_from_database priznak(symbol) GOAL begin. CLAUSES begin :- write ("Ответьте на вопросы :"),nl,nl, answer, clear_from_database, nl,nl,nl,nl, exit. answer :- fish(X),!,nl, save("BF1.dbf"), write (" Ответ: ",X,"."),nl. question(Y) :- write ("Вопрос: ",Y,"? "), otvet(X), write(X),nl, add_to_database (Y,X). otvet(C):- readchar(C). |