Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Conspekt.doc
Скачиваний:
11
Добавлен:
31.08.2019
Размер:
1.39 Mб
Скачать

5.10 Определение структур управления

 if-then-else

Введем понятие метаусловия ("мета"-соответствует приставке -над) - переменная, которая записывается не только в л.ч. правила в качестве аргумента, но и в п.ч. правила в качестве условия.

p(A,B,C) :- A,B,C.

переменные A,B,C -метаусловия

правило

Каждый раз при обращении к такому правилу, вместо переменных A,B,C должны подставляться конкретные условия.

ПРИМЕР :

if(Если,То,Иначе) :-

Если, !, То; используем для того, чтобы м.б.

Иначе.  оценить -X

abs(X,Y) :-if( X>=0, Y=X, Y is -X )

min(X,Y,Z):-if( X<=Y, Z=X, Z=Y )

Метаусловиями удобно воспользоваться при определении предиката отрицания :

not(Условие):-

Условие, !,fail;

succeed.

не_явл_элем(X,L):-

not(элемент(X,L)).

вып_один_раз(Условие) :-

Условие, !.

Если выполнится Условие хотя-бы один раз, то

отсечь все оставшиеся т. выбора.

5.11 Организация циклов в языке пролог

Ниже рассматриваются способы организации циклов без использования рекурсии.

 Цикл с возвратом

родители(Отец,Ребенок).

родители(сидоров,дмитрий).

родители(иванов,ира).

родители(петров,андрей).

Требуется написать предикат, который просмотрел бы всю БД и выдал бы на экран/печать всех детей какого-либо родителя.

Как только ПРОЛОГ-Система достигает fail она начинает искать дополнительные т. выбора. Т.о., необходимо создавать искусственную неудачу, направляя процесс решения в обратную сторону.

все_дети(Отец) :-

родитель(Отец,Жеребенок),

print(Жеребенок),

fail;

succeed.

?- все_дети(сидоров).

родитель(сидоров,Жеребенок),print(Жеребенок),fail

. . . succeed

f(БД) - зависит от БД

Жеребенок=дмитрий

print(Жеребенок),fail

fail - Заставит ПРОЛОГ-С искать новую т. выбора

Такие структуры, в которых путем создания искусственной неудачи мы принуждаем систему к повторному выполнению операций называются циклом с возвратом.

Вышеизложенный предикат все_дети() м. обобщить и определить предикат все_решения().

все_решения(Условия,Перем):-

Условие, print(Перем), fail;

succeed.

все_решения(родитель(Отец,Ребенок),Ребенок).

Вложенные циклы

Пусть даны {L1}, {L2} и требуется вывести на экран общие элементы обоих списков. Предполагается, что списки м. содержать повторяющиеся элементы.

общие_элементы(L1,L2):-

элемент(X,L1), элемент(X,L2), print(X), fail;

succeed.

. . .

L11 L12 L1i L1N

... ...

L21 L22 L2M L21 L22 L2M

Здесь Пролог проверяет оба пути, т.е. происходит как бы двойной цикл.

Для решения задачи: "Если выполняется 1-ое условие, то необходимо выполнить решение для 2-го условия " рассмотрим пример.

Пусть имеется БД, которая хранит сведения о сотрудниках организации:

работник(Имя,Отдел,Языки). - пусть мы имеем много подобных

фактов.

Факт "некоторый сотрудник работает в отделе ПРОЛОГ" имеет вид:

нек_сотр_раб_в_отд_пролог(X):-

работник(X,пролог,_).

знает_англ_яз(X):-

работник(X,_,Языки),элемент(англ,Языки).

Выясним следующее обстоятельство: "Знают ли все сотрудники отдела ПРОЛОГ английский язык ?". Сначала определим этот предикат не для Arity Prolog:

все_сотр_знают_англ_яз :-

работник(X,Пролог),

(знают_англ_яз(X), /, fail;

!, fail);

succeed.

Зарисуем этот предикат в виде схемы

запрос нового решения

решение м.б.

полученно ?

Запрет вариантов

Условия 2

succeed fail

Фактически нами определен предикат :"Для каждой реализации Условия 1 реализуется ли решение Условия 2 ? "

Для Arity Prolog :

Заменим предикат "/" , которого нет в Arity Prolog. Можно заметить, что предикат "/" есть не что иное, как "Предикат Условия 2 выполнить 1 раз для тех значений переменных, для которых выполнилось Условие 1 ".

следует( Условие1, Условие2) :-

Условие1, ( вып_один_раз( Условие2 ), fail ;

not(вып_один_раз( Условие2 )),

, !, fail ) ;

succeed.

"Для всех ли решений Условия 1 выполняется Условие 2 ?"

Т.о., Пролог проверяет выполнение первого условия и для каждого полученного решения проверяет второе условие.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]