Внутренняя база данных
В настоящей главе рассматриваются циклы, управляемые откатом, факты-переменные и внутренние базы данных. Приводятся средства, которые используются для создания, хранения и изменения состояний внутренних баз данных. Рассматриваются примеры работы с файлами.
Внутренние базы данных в языке Пролог состоят из последовательности фактов. Эти факты могут добавляться или удаляться во время исполнения программы, обрабатывается база данных в оперативной памяти компьютера. Поэтому внутреннюю базу данных называют динамической. Предикаты, которые определяются в базе данных, объявляются в разделе (class) facts.
4.1. Факт-переменная
Факты-переменные являются аналогами глобальных переменных в процедурных языках программирования. Они объявляются следующим образом:
class facts счетчик : positive := 0. список : string* := [].
После знака двоеточия указывается домен факта-переменной, справа от знака := начальное значение. Для изменения значений фактов-переменных используется оператор присваивания :=. Значения можно изменять следующим образом:
счетчик := счетчик + 1, список := ["Маша" | список]
С помощью факта-переменной подсчитать количество мужчин можно так:
class facts counter : positive := 0. clauses run():- мужчина(¬_), counter := counter + 1, fail; write(counter), _ = readLine().
4.2. Цикл fail
Рассмотрим циклы, которые управляются только с помощью отката. В них будет выполняться перебор следующих фактов:
мужчина("Иван"). мужчина("Павел"). мужчина("Петр"). женщина("Мария"). женщина("Анна").
Цикл fail неоднократно использовался ранее. Он устроен следующим образом:
<действие с возвратом>, fail.
Например, рассмотрим цикл:
run():- женщина(X), write(X), nl fail; _ = readLine().
В этом цикле один за другим печатаются имена всех женщин:
Мария Анна
С помощью этой же конструкции можно реализовать вложенные циклы. Рассмотрим, например, цикл:
run():- женщина(X), nl, мужчина(Y), write(X, " - ", Y, "\t"), fail; _ = readLine().
В этом цикле для очередной женщины перебираются все мужчины, затем идет откат к следующей женщине. Результат выглядит следующим образом:
Мария - Иван Мария - Павел Мария - Петр Анна - Иван Анна - Павел Анна - Петр