Название: базы знаний и экспертные системы(Р.Г. Шахмаметов)

Жанр: Технические

Просмотров: 1209


1. цель работы

 

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

 

2. Основные теоретические положения

 

2.1. Внутренняя база данных

 

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

 

assert ( факт [, имя_ВБД] )                          - добавление фактов в ВБД

asserta ( факт [, имя_ВБД] )                        - добавление фактов в начало ВБД

assertz  (факт [, имя_ВБД] )                        - добавление фактов в конец ВБД

retract ( факт [, имя_ВБД] )                         - удаление отдельного факта из ВБД 

retractall ( факт [, имя_ВБД] )                          - удаление всех фактов из ВБД 

consult ( имя_файла [, имя_ВБД] )              - загрузка ВБД из файла

save ( имя_файла [, имя_ВБД] )                  - сохранение ВБД в файле.

 

Аргумент имя_ВБД является необязательным. В ВБД могут храниться только факты (но не правила). Предикаты для них должны быть объявлены в секции database. Эти факты не должны содержать свободных переменных. Турбо-Пролог интерпретирует факты из ВБД точно так же, как факты из секции clauses. Иногда ВБД называют динамической БД, в отличие от набора фактов секции  clauses, рассматриваемого в качестве статической БД. Факты в динамической БД можно легко изменять, тогда как факты в статической БД после компиляции изменить невозможно.

 

2.2. Списки и рекурсия

 

Список – это последовательность разделенных запятыми термов, заключенная в квадратные скобки. Возможен пустой список – [ ]. Длина списка заранее не задается. Домен списка объявляется следующим образом:

 

domains                                /* mylist – имя домена, образованного списками */

                mylist = element_dom*      /* element_dom – имя домена элементов списков */

 

Если требуется включить в список элементы, относящиеся к разным типам данных (в том числе и к типу список), то нужно определить домен с альтернативами объектов разного типа, например, следующим образом: 

 

domains

     item = c (char);  i (integer);  s (string)         /* c, i, s – функторы предикатов */

     item _list = item*                                                           /* домен списков смешанного типа */

predicates

     list (item _list)

clauses

      list ([i (10), i (12), i (2000), s («НГТУ – АСУ»), c (‘N’)]).

 

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

 

list = [a, b, c]

                                                                      /

                                                                    a   T

                                                                          /

                                                                        b   T

                                                                             /

c   [ ]

 

Поэтому основным способом обработки списка является последовательная выборка его элементов до полного исчерпания, то есть до образования хвоста списка в виде пустого списка (T = [ ]). При этом в программе нужно иметь два предложения, одно из которых определяет действия с непустым списком, а другое – действия с пустым списком.

2.3. Нахождение всех решений целевого утверждения

 

Эту задачу решает встроенный предикат findall. Он использует целевое утверждение в качестве одного из своих аргументов и собирает все решения для этого целевого утверждения в список. Формат записи этого предиката:

 

findall (varname, mypredicate, listparam),

 

где          varname - имя параметра, значения которого собираются в список

                mypredicate          - предикат, из которого собираются значения

                listparam               - список значений, собранных методом поиска с откатом.

 

/* ПРИМЕР: ОПРЕДЕЛЕНИЕ СРЕДНЕГО ВОЗРАСТА */

 

 domains

     list = integer *

predicates

     person (string, string, integer)

     sumlist (list, integer, integer)

goal

     findall (Age, person (_, _, Age), L), sumlist (L, Sum, N), R = Sum/N, write («Result:», R).

clauses

     sumlist ([ ], 0, 0).

     sumlist ([H|T], Sum, N) :- sumlist (T, S1, N1), Sum = H + S1, N = N1 + 1.

     person («Иванов Иван», «Космическая, 21», 23).

     person («Кузьмин Кузьма», «пр. Маркса, 21», 19).

     .........

 

3. Порядок выполнения лабораторной работы

 

1. Изучите теорию к лабораторной работе по следующим источникам:

– описание данной лабораторной работы;

– текстовый файл, указанный преподавателем (каталог PROLOGHELP);

– соответствующие разделы рекомендованной литературы

[1. С. 140-141, 153-155, 158-186, 363-368;  2. С. 376-387; 3. С. 31-37, 94-109, 226-231, 234-235; 4. С. 32-34, 43-54, 144-146; 5. С. 110-113, 114-119, 159-161, 167-168, 174; 6. С. 34-37; 7. С. 68-73, 76-84, 116-119].

2. Измените программу, разработанную ранее по индивидуальному заданию, таким образом, чтобы все основные факты программы хранились во внутренней базе данных (ВБД). Теперь раздел clauses в программе не содержит никаких фактических данных задачи. Дополните программу предикатами, выполняющими в диалоговом режиме следующие операции:

загрузка ВБД из файла

запись фактов в ВБД

изменение в ВБД фактов, выбираемых по ключу

удаление фактов из ВБД

сохранение ВБД в файле.

 

3. Разработайте отдельную программу обработки списка по одному из следующих вариантов заданий:

 

Задание

1

Написать программу, которая

переносит первый элемент непустого списка L в его конец

переносит последний элемент непустого списка L в его начало

проверяет, есть ли в списке L хотя бы два одинаковых элемента

2

Написать программу, которая ·

вставляет в список L за первым вхождением элемента X элементы списка L1

подсчитывает число вхождений каждого элемента списка L  и формирует новый список L1, в котором каждый элемент становится списком, состоящим из элемента и числа его вхождений в L, например:  [1, 3, 4, 1]  ®  [ [1,2], [3,1], [4,1] ]

3

Определить предикат бращение_списка (Список_исходный,Список_обращенный), который изменяет исходный порядок элементов списка на обратный, например:  [1, 2, 3, 4]  ®  [4, 3, 2, 1]

4

Определить предикат именование_элементов_списка (Список_цифр, Список_имен_цифр), который заменяет в списке  цифры на их имена, например:  [3, 1, 0, ... , 5]  ®  [три, один, нуль, ... , пять]

5

Определить предикат  дублирование_элементов_списка (Список_исходный, Список_дублированный), который формирует список, содержащий каждый элемент исходного списка в двух экземплярах, например: [конфетки, бараночки]  ®  [конфетки, конфетки, бараночки, бараночки]

6

Определить предикат подстановка (X, Y, Список_исходный,Список_конечный), который формирует список, содержащий исходный список, где вместо каждого элемента X подставлен элемент Y

7

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

8

Написать программу, которая вставляет·

в список L элемент X перед каждым вхождением элемента Y

в список L элементы X1 и X2 перед его последним элементом·

в список L, упорядоченный по возрастанию, новый элемент X с сохра    нением упорядоченности списка

9

Написать программу, которая удаляет

из списка L один элемент после каждого вхождения элемента X, если такой элемент существует и отличен от X

из списка L один элемент, предшествующий каждому вхождению элемента X, если такой элемент существует и отличен от X

10

Определить предикат список_четной_длины (Список) таким образом, чтобы он был истинным тогда, когда его аргумент-список имеет четную длину

 

5. Содержание отчета

 

1. Цель работы.

2. Задание на модернизацию программы по индивидуальному заданию.

3. Текст модернизированной программы с комментариями.

4. Примеры выполненных запросов к модернизированной программе.

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

 

Вопросы для самопроверки

 

1. Как в программе объявляется внутренняя база данных?

2. Перечислите предикаты для внутренней базы данных.

3. Как в программе представляется список?

4. Приведите пример использования предиката findall.

5. Как в программе объявляется домен списков?

6. Как создать список с элементами смешанного типа?