Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
IIS / Печень О.А / Тема 2 / ЛР 2 5 - Prolog задание 4.doc
Скачиваний:
24
Добавлен:
31.03.2015
Размер:
88.58 Кб
Скачать
  1. Откат и отсечение при реализации отношений вида "один-ко-многим"

Учет ассоциаций (связей) между объектами отношений служит средством оптимизации запросов в Прологе. Рассмотрим это на примере простого отношения

ОТЕЦ( ИМЯ , РЕБЕНОК )

которое в программе определяется набором некоторых фактов. Между объектами данного отношения существует ассоциация "один-ко-многим". Запрос к данной базе может заключаться: либо в поиске родителя конкретного ребенка (в этом случае имеет место простая связь), либо в поиске всех детей конкретного родителя (в этом случае имеет место множественная связь).

Самый примитивный способ реализации простой связи заключается в написании правила, которое должно выполнить поиск факта, а затем пройти через предикат отсечения. Для реализации сложной связи необходим поиск всех альтернативных решений в базе данных. Использование новой процедуры parent (родитель), которая учитывает введенные замечания, обеспечит интерфейс работы с БД father() .

Причем этот интерфейс учитывает имеющуюся связь между объектами отношения БД father() и оптимизирует выполнение запроса Прологом

Предикат bound(C) успешен в случае, если переменная С означена, а предикат free(C) успешен, если переменная С свободная.

Следует отметить, что два правила процедуры являются взаимоисключающими.

А если это так, то проверку во втором правиле состояния переменной С можно не выполнять, так как если она будет несвободной, то будет обработана первым правилом. Однако, если эти правила поменять местами, то этого делать нельзя.

/* программа 10 */

domains

namе,child = symbol

predicates

father(name,child) parеnt(namе,child)

clauses

father( "иван" , "петр" ). father( "иван" , "павел" ). father( "петр" , "олег" ). father( "олег" , "борис" ). /* поиск родителя (отца) конкретного ребенка */ parent(F,C) :- bound(C), fathеr(F,C),!. /* поиск всех детей конкретного родителя */ parent(F,C) :- free(C), fathеr(F,C).

Задание 10.

Модифицируйте программу 6 таким образом, чтобы интерфейс по работе с БД work() учитывал ассоциации между объектами этого отношения и позволял оптимизировать выполнение запросов Прологом за счет использования нового отношения СЛУЖАЩИЙ(ИМЯ,ОТДЕЛ)

С целью тестирования программы выполните различные варианты запросов, используя внешние цели. Результаты их выполнения вместе с текстом модифицированной программы приведите в отчете по лабораторной работе.

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

Задание 11.

Используя результаты выполнения задания 10, на основе программы формирования меню lab4menu.pro сформируйте запросную систему, которая должна выдавать ответы на вопросы: "В каком отделе работает конкретный служащий" (процесс 1) и "Кто работает в конкретном отделе" (процесс 2).

  1. Ступенчатые функции и отсечение

 Часто в экономических расчетах приходится использовать ступенчатые функции для вычисления различных коэффициентов, зависящих от диапазонов изменения объемов производства, прибыли или совокупного годового дохода. Для примера рассмотрим двухступенчатую функцию, аналогичную вычислению процента подоходного налога, считая, что D - совокупный доход, а N - величина налога:

На Прологе данную функцию выражают с помощью бинарного отношения F(N,D), которое можно определить набором фактов вида

F(D ,0) :- D< 10. F(D, 12) :- 10=<D,D< 15. F(D, 15) :- 15=<D.

Три правила, входящие, в отношение F(), являются взаимоисключающими, поэтому успех возможен самое большое в одном из них. Следовательно, мы (но не Пролог) знаем, что, как только успех наступил в одном из них, нет смысла проверять иные, поскольку они все равно обречены на неудачу. Для предотвращения ненужного перебора следует воспользоваться отсечением. Предикат отсечения предотвращает возврат из тех точек программ, где он поставлен. С учетом этого новая процедура

F(D ,0) :- D< 10,!. F(D, 12) :- D< 15,!. F(D, 15).

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