- •Лабораторная работа № 7 Программирование интеллектуальных систем на языке Пролог Управление ходом выполнения программ в системе Турбо-Пролог (2 часть)
- •Организация повторяющихся процессов
- •Управление поиском с возвратом
- •Управление ходом выполнения программ с использованием отсечения
- •Использование метода отката и отсечения
- •Откат и отсечение при реализации отношений вида "один-ко-многим"
- •Ступенчатые функции и отсечение
- •Порядок выполнения лабораторной работы
Откат и отсечение при реализации отношений вида "один-ко-многим"
Учет ассоциаций (связей) между объектами отношений служит средством оптимизации запросов в Прологе. Рассмотрим это на примере простого отношения
ОТЕЦ( ИМЯ , РЕБЕНОК )
которое в программе определяется набором некоторых фактов. Между объектами данного отношения существует ассоциация "один-ко-многим". Запрос к данной базе может заключаться: либо в поиске родителя конкретного ребенка (в этом случае имеет место простая связь), либо в поиске всех детей конкретного родителя (в этом случае имеет место множественная связь).
Самый примитивный способ реализации простой связи заключается в написании правила, которое должно выполнить поиск факта, а затем пройти через предикат отсечения. Для реализации сложной связи необходим поиск всех альтернативных решений в базе данных. Использование новой процедуры 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).
Ступенчатые функции и отсечение
Часто в экономических расчетах приходится использовать ступенчатые функции для вычисления различных коэффициентов, зависящих от диапазонов изменения объемов производства, прибыли или совокупного годового дохода. Для примера рассмотрим двухступенчатую функцию, аналогичную вычислению процента подоходного налога, считая, что 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).
дает тот же результат, что и исходная, но она значительно более эффективна при реализации в программе на Прологе.