Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методические указания по ИИС.doc
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
4 Мб
Скачать
☆

Сохранение базы данных фактов во время выполнения программы

Предикат save сохраняет факты из указанной секции фактов в файл. save требует один или два аргумента.

Если вы вызываете, save только с одним аргументом (без имени секции фактов), то он сохранит факты из базы данных dbasedom в файл по имени fileName.

Если вы вызываете, save с двумя аргументами (именем файла и именем секции фактов), то он сохранит все факты секции фактов databaseName в указанный файл.

К предикатам, принадлежащим секции фактов, можно обращаться точно так же как и к другим предикатам. Единственное различие состоит в том, что описания для предикатов находятся в секции фактов, а не в секции предикатов.

Рассмотрим пример, в котором необходимо найти всех женщин:

  1. Для решения этой задачи опишем раздел доменов:

DOMAINS

имя = string

пол = char

  1. Следующий раздел, который мы опишем - раздел фактов:

FACTS

человек(имя,пол)

  1. Раздел предложений будет выглядеть следующим образом:

CLAUSES

человек("Helen",'Ж').

человек("Maggie",'Ж').

человек("Suzanne",'Ж').

человек("Per",'M').

  1. Для нахождения женщин необходимо задать следующую цель (рис. 1):

GOAL

человек(Name,'Ж').

Рис. 1. Вывод результата первой цели

  1. или человек("Maggie",'Ж'), чтобы проверить, описана ли женщина по имени Maggie (Мэгги) в секции фактов. Пролог ответит «Да» (рис. 2).

Рис. 2. Вывод результата второй цели

Предикаты, находящиеся в секции фактов, всегда не определены. Поскольку факты можно добавить в любое время в периоде исполнения программы, компилятор должен всегда предполагать, что возможно найти альтернативные решения в процессе бэктрэкинга. Если вы имеете предикат в секции фактов, для которого вы никогда не будете иметь больше чем одного факта, вы можете описать его как детерминированный, при помощи директивы компилятора determ:

FACTS

determ daylight_saving(integer)

Вы получите ошибку, если пробуете добавить факт для детерминированного предиката, который уже имеет факт (рис. 3).

Рис. 3. Сообщение об ошибке

  1. Рассмотрим другой пример. Предположим, что вы имеете следующие секции фактов в вашей программе:

DATABASE

person(string, string, integer)

FACTS-likesDatabase

likes(string, string)

dislikes(string, string)

CLAUSES

person(“Fred”, “Capitola”, 35).

person(“Fred”, “Omaha”, 37).

person(“Michael”, “Brooklyn”, 26).

likes(“John”, “money”).

likes(“Jane”, “money”).

likes(“Chris”, “chocolate”).

likes(“John”, “broccoli”).

dislikes(“Fred”, “broccoli”).

dislikes(“Michael”, “beer”).

При помощи этих секций фактов, вы можете объявить следующие цели:

retract(person("Fred", _, _)). /* 1 */

retract(likes(_, "broccoli")). /* 2 */

retract(likes(_, "money"), likesDatabase). /* 3 */

retract(person("Fred", _, _), likesDatabase) /* 4 */

Первая цель удаляет первый факт для person о Фреде из секции фактов dbasedom (по умолчанию) и выводит ответ (рис. 4).

Рис. 4. Результат первой цели

Вторая цель удаляет первый факт, соответствующий, предикату likes(X, "broccoli") из секции фактов likesDatabase и выводит сообщение (рис. 5).

Рис. 5. Результат второй цели

При обработке обеих из этих целей, Лабораторная работа № 1 знает, какая секция фактов редактируется потому, что имена предикатов секций фактов являются уникальными: person относится только к секции фактов dbasedom и likes - likesDatabase.

Третьи и четвертые цели иллюстрируют, как вы можете использовать дополнительный второй аргумент для проверки типа. Третья цель успешна, при её достижении удаляется первый факт из likesDatabase, соответствующий предикату likes(_, "money") (рис. 6).

Рис. 6. Результат третьей цели

Но четвертая - не компилируется, потому что в секции фактов likesDatabase нет (и может быть) фактов person. Сообщение об ошибке, выданное компилятором будет следующим:

506 Type error: The functor does not belong to the domain.