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

Использование Prolog совместно с другими ЯП.

 

Понятие Dll.

 

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

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

/>рис 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 (объектно-модульныйформат – используется, например, Borland C++ ) и COFF(Общий объектно-файловый формат, используется, например, Visual C++ ).

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.   Целые числа из списка заносятся в массив, состоящий из известногоколичества элементов.

/* Programlstar_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).

 

/* Programlstar_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.

/* Programhello_c.c */

char prowin_msg(char *);

void hello_c()

{

  while ( prowin_msg(«Hellofrom C (press 'C')») != 'C' )

    ;

}

2003 Pechenkin

pechenkin@pochtamt.ru

www.cs.vsu.ru/~pechenkin

еще рефераты
Еще работы по информатике, программированию