Внутренняя база данных
В настоящей главе рассматриваются циклы, управляемые откатом, факты-переменные и внутренние базы данных. Приводятся средства, которые используются для создания, хранения и изменения состояний внутренних баз данных. Рассматриваются примеры работы с файлами.
Внутренние базы данных в языке Пролог состоят из последовательности фактов. Эти факты могут добавляться или удаляться во время исполнения программы, обрабатывается база данных в оперативной памяти компьютера. Поэтому внутреннюю базу данных называют динамической. Предикаты, которые определяются в базе данных, объявляются в разделе (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().
В этом цикле для очередной женщины перебираются все мужчины, затем идет откат к следующей женщине. Результат выглядит следующим образом:
Мария - Иван Мария - Павел Мария - Петр Анна - Иван Анна - Павел Анна - Петр