Здавалка
Главная | Обратная связь

Примеры использования одновременно работающих устройств.



??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

Оконная система на Turbo Prolog, о прямом доступе к оборудованию.

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

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

Makewindow(WindowNo, ScrAtt, FrameAtt, Framestr, Row, Column, Height, Width)

(integer,integer,integer,string,integer,integer,integer,integer)

- (i,i,i,i,i,i,i,i) (o,o,o,o,o,o,o,o)

Определяет для (i,i,i,i,i,i,i,i) область экрана в качестве окна. Каждое окно задается номером WindowNo. ScrAtt задает значение атрибута для всех позиций описываемого окна. Если FrameAtt не равно 0, окно берется в рамку и верхняя граница включает текст Framestr. Позиция левого верхнего угла окна задается параметрами Row и Col. Параметры Height и Width определяют соответственно высоту и ширину окна, которые должны быть совместимыми с размерами экрана. В случае (о,о,о,о,о,о,о,о) связывает характеристики текущего окна с выходными параметрами.

Shiftwindow(WindowNo)

(integer) – (i) (o)

Активизирует (i) окно с номером WindowNo. Окно должно быть создано заранее. Связывает (o) c параметром "номер текущего окна".

Removewindow

Удаляет текущее активное окно.

Clearwindow

Очищает текущее активное окно.

Cursor(Row,Column)

(integer,integer) – (i,i) (o,o)

Для (i,i) помещает курсор в позицию с координатами (Row,Column) или присваивает переменным Row и Column значения текущих координат курсора при (o,o).

Предикаты низкоуровневой поддержки (MISCELLANEOUS MACHINE LOWLEVEL)

port_byte(PortNo,Value) (integer,integer) - (i,i) (i,o) Посылает байт в порт или читает его из порта.

ptr_dword(String,Segment,Offset) (string,integer,integer) - (i,o,o) (o,i,i) Читает строку или адрес строки.

memword(Segment,Offset,Word) (integer,integer,integer) - (i,i,i) (i,i,o) Запоминает или считывает слово.

membyte(Segment,Offset,Byte) (integer,integer,integer) - (i,i,i) (i,i,o) Запоминает или считывает байт.

bitand(X,Y,Z) (integer,integer,integer) - (i,i,o) Логическое И : Z = X and Y.

bitor(X,Y,Z) (integer,integer,integer) - (i,i,o) Логическое ИЛИ : Z = X or Y.

bitxor(X,Y,Z) (integer,integer,integer) - (i,i,o) Исключающее ИЛИ : Z = X xor Y.

bitnot(X,Y) (integer,integer,integer) - (i,o) Логическое НЕ : : Y = not X.

bitleft(X,N,Z) (integer,integer,integer) - (i,i,o) Логический сдвиг влево на N битов.

bitright(X,N,Z) (integer,integer,integer) - (i,i,o) Логический сдвиг вправо на N битов.

bios(Interruptno,reg(AXi,BXi,CXi,DXi,SIi,DIi,DSi,ESi), reg(AXo,BXo,CXo,DXo,SIo,DIo,DSo,ESo))

(integer,REG,REG) - (i,i,o) (i,i,reg(o,o ... )) Обработка прерываний.

bios(Interruptno,reg(AXi,BXi,CXi,DXi,SIi,DIi,DSi,ESi), reg(AXo,BXo,CXo,DXo,SIo,DIo,DSo,ESo),OutFlags)

(integer,REG,REG,integer) - (i,i,o,o) (i,i,reg(o,o ... ),o) Обработка прерываний с выдачей флага.

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

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

Примером рекурсивных вычислений является известный алгоритм вычисления факториала. Hа Прологе эта программа может иметь такой вид:

Domains

N, F=real

Predicates

Factorial(N,F)

Clauses

factorial(1,1). % база рекурсии, ограничение вычислений

factorial(N,R):– N>0, N1=N-1,

factorial(N1,R1), R=R1*N.

Goal factorial(8,F),write(F).

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

Любое рекурсивное определение содержит по крайней мере одно нерекурсивное правило и одно или несколько правил с рекурсией. В большинстве случаев имеется по одному правилу каждого типа. Считается, что используется хвостовая рекурсия, если последнее условие в последнем правиле является рекурсивным. Такая рекурсия имеет преимущество перед нехвостовой рекурсией, так как позволяет ограничить рост стека и строго контролировать процесс возврата. Это происходит благодаря очистке стека после успешного сопоставления условия, содержащего рекурсию.

 

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

Для увеличения производительности программ и экономии стека следует применять остаточную рекурсию (или итерационное определение предиката).

Вычисление факториала с помощью остаточной рекурсии (итерационное вычисление).

PREDICATES

factorial(INTEGER,INTEGER)

factorial_it(INTEGER,INTEGER,INTEGER)

CLAUSES

factorial(N,X):-factorial_it(N,1,X),!.

factorial_it(N,X,C):-

not(N=1),

M = N-1,

Y = X*N,!,

factorial_it(M,Y,C).

factorial_it(_,X,X):-!.

 

Списки

Списки – одна из наиболее часто употребляемых структур в ПРОЛОГе. Список – это набор объектов одного и того же типа. При записи список заключают в квадратные скобки, а элементы списка разделяют запятыми, например:

[1,2,3]

[“вчера”,”сегодня”,”завтра”]

Элементами списка могут быть любые термы ПРОЛОГа, т.е. атомы, числа, переменные и составные термы.

Каждый непустой список может быть разделен на голову – первый элемент списка и хвост – остальные элементы списка. Это позволяет всякий список представить в виде бинарного дерева (рис. 2).

У списка, состоящего только из одного элемента, головой является этот элемент, а хвостом – пустой список.

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

Пусть L1 и L2 – две переменные, представляющие входные списки.L3 – выходной список, получаемый слиянием L1 и L2.

append([ ],L,L).

append( [N|L1], L2, [N|L3] ):- append(L1, L2, L3).

Операция разделения списка на голову и хвост обозначается с помощью вертикальной черты:

[Head|Tail]

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

print_list([ ]).

print_list([X|Y]) :- write(X),nl, print_list([Y]).

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

Если необходимо установить наличие некоторого элемента в списке,то применяется правило:

find_it( X,[X| _ ]).

find_it( X,[ _ |Y]):- find_it( X,[Y]).

В первом описании происходит сравнение объекта поиска и головы текущего списка. Если это сравнение неуспешно, то происходит откат и попытка повторения со вторым вариантом.

 

6.4 Работа со списками, примеры программ.

??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

Обработка строк.

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

frontchar(String,FrontChar,RestString)

(string,char,string) – (i,o,o) (i,i,o) (i,o,i) (i,i,i) (o,i,i)

Разделяет заданную строку String согласно поточному шаблону на две части: первый символ FrontChar и оставшаяся часть строки RestString.

fronttoken(String,Token,RestString)

(string,string,string) – (i,o,o) (i,i,o)(i,o,i) (i,i,i) (o,i,i)

Разделяет строку, заданную параметром String, на лексему Token и остаток RestString согласно поточному шаблону. (Лексема – это последовательность символов, имеющих смысл. Она определяется либо как имя в соответствии с синтаксисом Турбо-Пролога, либо как строчное представление числа, при этом знак возвращается отдельно, либо как отдельный символ.)

frontstr(Lenght,Inpstring,StartString,RestString)

(integer,string,string,string) – (i,i,o,o)

Разделяет строку Inpstring на две части. StartString будет иметь длину Lenght первых символов исходной строки, RestString представляет собой остаток строки InpString.

concat(String1,String2,String3)

(string,string,string) – (i,i,o) (i,o,i) (o,i,i) (i,i,i)

Слияние строк , согласно поточному шаблону, по формуле: String3 = String1 + String2.

str_len(String,Length)

(string,integer) – (i,i) (i,o) (o,i)

Определяет длину Length строки String.

isname(StringParam)

(string) – (i)

Завершается успешно, если StringParam есть имя, удовлетворяющее синтаксису Пролога.

 







©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.