Учебная работа. Реферат: Использование Prolog совместно с другими ЯП

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...
Контрольные рефераты

Учебная работа. Реферат: Использование Prolog совместно с другими ЯП

Внедрение
Prolog вместе с иными ЯП.

понятие
Dll.

Вспомним процесс программирования в DOS. Преобразование начального текста в машинный код включал в себя 2 процесса: компиляцию и линковку. Во время линковки в код программки помещались не только лишь объявления функций и процедур, да и их полный код.

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


DLL (библиотека динамической связи) – файл, выступающий в качестве коллективной библиотеки предикатов, которые могут быть применены сразу в нескольких приложениях. Prolog способен генерировать DLL, включать DLL статически и загружать динамически.

Вызов в программке на
VP процедур и функций на остальных языках.

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

GLOBAL PREDICATES

procedure add(integer A, integer B, integer C) – (i,i,o) language pascal

Замечание:
обратите внимание, что в VP очевидно указывается язык процедуры

Передача входных/выходных характеристик и возвращение значений.

Размер входных характеристик определен совершенно точно и зависит лишь от объявленного типа. Выходной параметр – 32 битный указатель на область памяти, где хранится выходное

Необходимо подчеркнуть, что функции на Pascal не могут возвращать значения в формате чисел с плавающей точкой, а функции C — структуры (но могут, естественно, возвращать указатели на их).

Бессчетные декларации.

Предикат VP может иметь разные композиции входных/выходных характеристик, и для каждой из их нужна отдельная процедура. Идентификаторы, применяемые в Prolog должны совпадать с идентификаторами в библиотеке + суффикс _X, где X – целое число (порядковый номер процедуры, нумерация начинается с 0). Если существует лишь один вариант, то суффикс отсутствует. Разглядим пример:

GLOBAL PREDICATES

subtraction(integer, integer, integer) – (i,i,o), (i,o,i), (o,i,i), (i,i,i) language C

change(integer, integer) – (i,o) language C

GOAL

subtraction(2,2,X), write(“2-2=”,X), nl,

subtraction(2,Y,5), write(“2-5=”,Y), nl,

subtraction(Z,5,4), write(“5-4=”,X), nl,

subtraction(2,2,5), write(“2-2 равно 5”), nl,

change(5, Ch), write(Ch).

Модуль, связываемый с данной нам программкой должен содержать процедуры:

subtraction_0 (int x, int y, int *z)

{*z=x-y;}

subtraction_1 (int x, int *y, int z)

{*y=x-z;}

subtraction_2 (int *x, int y, int z)

{*x=y-z;}

subtraction_3 (int x, int y, int z)

{if ((x-y)!=z)RUN_Fail();}

change(int a, int *b)

{*b=a;}

Примечание:
если процедура написана на языке C, то характеристики заносятся в стек в оборотном порядке (опосля возврата значений указатель автоматом корректируется VP), в неприятном случае, характеристики заносятся в стек в обычном порядке (см. таблицу 1).

Форматы объектных файлов в
Win32.

Под Win32 употребляется 2 формата объектных файлов: OMF (объектно-модульный формат – употребляется, к примеру, BorlandC++ ) и COFF (Общий объектно-файловый формат, употребляется, к примеру, VisualC++ ).

1. При использовании файла в формате OMF имя предиката обязано совпадать с именованием функции.

2. При использовании файла в формате COFF, к имени предиката добавляется символ подчеркивания, и опосля знака @ указывается количество б, добавленных в стек (к примеру, если предикат nameимеет 2 целых аргумента, то он должен быть объявлен как _name@8 (см. таблицу 1)).

установка указателя на стек.

Существует два метода установки указателя на стек: при объявлении функции и при ее вызове. Так сложилось, что Pascal устанавливает указатель при объявлении функции, а С – при вызове (см. таблицу 1).


Преобразует имена в верхний регистр.
порядок аргументов прямой.
Устанавливает указатель на стек при объявлении.
Необходимость преобразовать имена в формат COFF.

C
-
-
-

pascal
+
+
+

stdcall
+
-
+

syscall
+
+
-

Таблица 1: вызов модулей из
VP.

Неавтоматическое обозначение наружных предикатов.

Идентификатор процедуры либо функции в VP не непременно должен совпадать с идентификатором во наружном модуле. В этом случае объявление такового предиката имеет вид:

GLOBAL PREDICATES

add(integer, integer, integer) – (i,o) language c as “_myadd@12”

Эквивалентность типов.

Большая часть обычных типов переменных в VP имеют эквиваленты в остальных языках программирования, но размер резервируемой для их памяти может не совпадать (см. таблицу 2).


Тип переменной
Размер (Win32).

char, byte
1 б

short, Word
2 б

long, dword
4 б

unsigned, integer
4 б

Real
8 б

Ref
4 б

Таблица 2: размер переменных в
VP.

Обработка списков.

Ниже приведен пример программки, модифицирующей перечень в массив, и потом вновь возвращающей данные в перечень.

программка ListToArray на языке С конвертирует перечень целых чисел в массив, записывает в стек элементы массива и возвращает количество частей (массив и количество частей передаются в программку как характеристики).

Преобразование перечня проходит в 2 шага:

1. Просматривается перечень и находится количество частей в нем.

2. Целые числа из перечня заносятся в массив, состоящий из известного количества частей.

/* Program lstar_p.pro */

project «lstar»

global domains

ilist = integer*

global predicates

inclist(ilist,ilist) — (i,o) language c

goal

inclist([1,2,3,4,5,6,7],L), write(L).

/* Program lstar_c.c

#define listfno 1

#define nilfno 2

typedef unsigned char BYTE;

void *MEM_AllocGStack(unsigned);

typedef struct ilist {

BYTE Functor;

int Value;

struct ilist *Next;

} INTLIST;

int ListToArray(INTLIST *List,int **ResultArray)

{

INTLIST *SaveList = List;

int *Array, len;

register int *ArrP;

register int i;

/* количество частей в перечне */

i = 0;

while ( List->Functor == listfno ) {

i++;

List = List->Next;

}

len = i;

Array = MEM_AllocGStack(i*sizeof(int));

ArrP = Array;

/* перемещение частей перечня в массив */

List = SaveList;

while ( i != 0 ) {

*ArrP++ = List->Value;

List = List->Next;

i—;

}

*ResultArray = Array;

return(len);

}

void ArrayToList(register int *ArrP,register int n,
register INTLIST **ListPP)

{

while ( n != 0 ) {

*ListPP = MEM_AllocGStack(sizeof(INTLIST));

(*ListPP)->Functor = listfno;

(*ListPP)->Value = *ArrP++;

ListPP = &(*ListPP)->Next;

n—;

}

*ListPP = MEM_AllocGStack(sizeof((*ListPP)->Functor));
/* конецсписка */

(*ListPP)->Functor = nilfno;

}

void inclist(INTLIST *InList,INTLIST **OutList)

{

register int *ArrP, i, len;

int *Array;

len = ListToArray(InList,&Array);

ArrP = Array;

for ( i = 0; i < len; i++)

++*ArrP++;

ArrayToList(Array,len,OutList);

}

Вызов предикатов
VP.

VP способен не только лишь вызывать предикаты, да и предоставлять их остальным программкам. Ниже приведен пример вызова предиката prowin_msg из программки на С:

/* Program hello_p.pro */

global predicates

char prowin_msg(string) — (i) language c

hello_c — language c

clauses

prowin_msg(S,C) :-

write(S,» (press any key)»), readchar(C).

goal

prowin_msg(«Hello from PDC Prolog»),

hello_c.

/* Program hello_c.c */

char prowin_msg(char *);

void hello_c()

{

while ( prowin_msg(«Hello from C (press ‘C’)») != ‘C’ )

;

}

2003 Pechenkin

pechenkin@pochtamt.ru

www.cs.vsu.ru/~pechenkin

]]>