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

3.4.3 Использование рекурсии

В VIP допускается использование рекурсивных правил. Рекурсия – вызов в теле правила самого. Рекурсивные вызовы используются для организации циклического выполнения определенных действий в программах. В программах написанных на VIP существует понятие оптимизированной хвостовой рекурсии. Если рекурсия не оптимизирована, то при вызове правила резервируется дополнительная стековая оперативная память ЭВМ, в результате возникает ошибка – отсутствие свободной оперативной памяти.

Причины возникновения не оптимизированной рекурсии:

Рекурсивный вызов не последний в теле правила;

Наличие условия перед рекурсивным вызовом;

Если в теле правила вызывается предикат, содержащий условия.

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

Пример. Составить программу для опроса клавиатуры. Программа реагирует на нажатие клавиш «1», «2» и «3». При нажатии клавиши «ESC» (код 27) программа завершает свою работу.

predicates

action(char)

repeat

clauses

repeat. %рекурсивное правило

repeat:-

repeat.%рекурсия оптимизирована

action('1'):-

write("\nКлавиша 1"),readchar(_).

action('2'):-

write("\nКлавиша 2"),readchar(_).

action('3'):-

write("\nКлавиша 3"),readchar(_).

action('\27'):-

write("\nКонец работы\n").

goal %меню, зацикливание

repeat,

write("\n1-Певый пежим”),write(“\n2-Второй режим”),

write(“\n3-Третий режим\nВведите цифру”),

readchar(Num),action(Num),Num='\27',!.

Для прекращения работы программы использовано отсечение в целевом утверждении программы.

3.4.4. Управление потоком ввода–вывода

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

Пример. Написать программу для вычисления по условиям.

Дано:

Программа:

domains

a,b,c,d,e,f=integer

predicates

getE(a,b,e)-(i,i,o)

getF(e,f) -(i,o)

clauses

%Правила сравнения чисел

getE(A,B,E):-

A<B,E=A.

getE(A,B,E):-

A>B,E=B.

%Правила получения итогового значения

getF(E,F):-

E<=0,F=0.

getF(E,F):-

E>0,F=1.

goal

A=9,B=10,C=8,D=-89,

getE(A,B,X),getE(C,D,Y),X1=X,Y1=Y,

getE(X1,Y1,Z),write("Emin=",Z),nl,

getF(Z,F),

write("F=",F),nl.

В программе использованы промежуточные переменные X1 и Y1 для хранения временных значений результата сравнения исходных чисел.

При составлении программ для правильного обращения к предикатам рекомендуется выполнить спецификацию входных и выходных параметров (переменных). Для этого используются ключевые символы o – означает, что аргумент возвращает значение, i – аргумент принимает значение.

Тогда описание предикатов примет вид:

predicates

getE(a,b,e)-(i,i,o)%первые аргументы принимают

%значение, а тритий его

%возвращает

getF(e,f) -(i,o)%первый аргумент принимает

%значение, а втораой возвращает

Для контроля потока параметров, в процессе работы программы, используются системные предикаты bound(X) – контроль задания исходного значение, и free(X) – проверка отсутствия значения в переменной. Первый предикат возвращает значение ИСТИНА, если аргумент – связанная переменная, а второй возвращает значение ИСТИНА, если аргумент – свободная переменная.

Пример предиката с контролем потока параметров

getE(A,B,E):- %(i,i,o)

bound(A),bound(B),free(E),

A<B,E=A.

Для более точного и гибкого описания предметной области VIP предлагает технологию описания связей в виде структур и альтернативных доменов.

Соседние файлы в папке Dop