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

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

Понятие Dll.

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

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

<img src="/cache/referats/13868/image001.gif" v:shapes="_x0000_i1025">рис 1.

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

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

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

<span Courier New";mso-ansi-language:EN-US">GLOBAL PREDICATES

<span Courier New";mso-ansi-language:EN-US">   procedure add(integer A, integer B, integerC) – (i,i,o) language pascal

 

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

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

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

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

Многочисленныедекларации.

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

     

       <span Courier New";mso-ansi-language:EN-US">GLOBALPREDICATES

<span Courier New";mso-ansi-language:EN-US">     subtraction(integer, integer, integer) –(i,i,o), (i,o,i), (o,i,i), (i,i,i) language C

<span Courier New";mso-ansi-language:EN-US">     change(integer, integer) – (i,o) languageC

<span Courier New";mso-ansi-language:EN-US">   GOAL

<span Courier New";mso-ansi-language:EN-US">      subtraction(2,2,X), write(“2-2=”,X), nl,

<span Courier New";mso-ansi-language:EN-US">      subtraction(2,Y,5), write(“2-5=”,Y), nl,

<span Courier New";mso-ansi-language:EN-US">      subtraction(Z,5,4), write(“5-4=”,X), nl,

<span Courier New";mso-ansi-language:EN-US">      subtraction(2,2,5), write(“2-2

<span Courier New"">равно<span Courier New";mso-ansi-language:EN-US"> 5”), nl,

<span Courier New";mso-ansi-language:EN-US">      change(5, Ch), write(Ch).

<span Courier New";mso-ansi-language:EN-US">

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

 

        <span Courier New";mso-ansi-language:EN-US">subtraction_0 (int x, int y, int *z)

<span Courier New";mso-ansi-language:EN-US">    {*z=x-y;}

        <span Courier New";mso-ansi-language:EN-US">subtraction_1(int x, int *y, int z)

<span Courier New";mso-ansi-language:EN-US">    {*y=x-z;}

<span Courier New";mso-ansi-language:EN-US">    subtraction_2 (int *x, int y, int z)

<span Courier New";mso-ansi-language:EN-US">    {*x=y-z;}

       <span Courier New";mso-ansi-language:EN-US">subtraction_3(int x, int y, int z)

<span Courier New";mso-ansi-language:EN-US">    {if ((x-y)!=z)RUN_Fail();}

<span Courier New";mso-ansi-language:EN-US">   change(int a, int *b)

<span Courier New"">    {*

<span Courier New";mso-ansi-language:EN-US">b<span Courier New"">=<span Courier New";mso-ansi-language:EN-US">a<span Courier New"">;}

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

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

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

1.<span Times New Roman"">     

OMF имя предиката должно совпадать сименем функции.

2.<span Times New Roman"">     

COFF, к имени предиката добавляется знакподчеркивания, и после символа @ указывается количество байт, добавленных встек (например, если предикат <span Courier New"; mso-ansi-language:EN-US">name<span Courier New"">имеет 2 целых аргумента, то он должен быть объявлен как <span Courier New"">_<span Courier New";mso-ansi-language:EN-US">name<span Courier New"">@8 (см. таблицу 1)).

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

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

Конвертирует имена в верхний регистр.

 Порядок аргументов прямой.

Устанавливает указатель на стек при объявлении.

Необходимость конвертировать имена в формат COFF.

C

-

-

-

pascal

+

+

+

stdcall

+

-

+

syscall

+

+

-

<span Courier New"; mso-ansi-language:EN-US">

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

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

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

  <span Courier New";mso-ansi-language:EN-US"> GLOBAL PREDICATES

<span Courier New"; mso-ansi-language:EN-US">    add(integer,integer, integer) – (i,o) language c as “_myadd@12”

<span Courier New"; mso-ansi-language:EN-US">

<span Times New Roman",«serif»">Эквивалентность типов.

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

Тип переменной

Размер (Win32).

char, byte

1 байт

short, word

2 байт

long, dword

4 байт

unsigned, integer

4 байт

Real

8 байт

Ref

4 байт

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

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

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

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

  Преобразование списка проходит в 2 этапа:

1.<span Times New Roman"">     

2.<span Times New Roman"">     

<span Courier New"">/* Program lstar_p.pro */

<span Courier New"">project «lstar»

<span Courier New"">global domains

<span Courier New"">ilist = integer*

<span Courier New"">global predicates

<span Courier New"">inclist(ilist,ilist) — (i,o) language c

<span Courier New"">goal

<span Courier New"">inclist([1,2,3,4,5,6,7],L), write(L).

<span Courier New"">

<span Courier New"">/* Program lstar_c.c */

<span Courier New"">#definelistfno 1

<span Courier New"">#definenilfno  2

<span Courier New"">typedef unsigned char BYTE;

<span Courier New"">void *MEM_AllocGStack(unsigned);

<span Courier New"">typedef structilist {

<span Courier New"">BYTE Functor;

<span Courier New"">int Value;

<span Courier New"">struct ilist *Next;

<span Courier New"">} INTLIST;

<span Courier New"">intListToArray(INTLIST *List,int **ResultArray)

<span Courier New"">{

<span Courier New"">INTLIST *SaveList = List;

<span Courier New"">int *Array, len;

<span Courier New"">register int *ArrP;

<span Courier New"">register int i;

<span Courier New"; mso-ansi-language:RU">/* количество элементов в списке */

<span Courier New"">i = 0;

<span Courier New"">while ( List->Functor == listfno ) {

<span Courier New"">  i++;

<span Courier New"">  List = List->Next;

<span Courier New"">}

<span Courier New"">len = i;

<span Courier New"">Array =MEM_AllocGStack(i*sizeof(int));

<span Courier New"">ArrP = Array;

<span Courier New"; mso-ansi-language:RU">/* перемещение элементов списка в массив */

<span Courier New"">List = SaveList;

<span Courier New"">while ( i != 0 ){

<span Courier New"">  *ArrP++ = List->Value;

<span Courier New"">  List = List->Next;

<span Courier New"">  i--;

<span Courier New"">}

<span Courier New"">*ResultArray = Array;

<span Courier New"">return(len);

<span Courier New"">}

<span Courier New"">voidArrayToList(register int *ArrP,register int n,
register INTLIST **ListPP)

<span Courier New"">{

<span Courier New"">while ( n != 0 ) {

<span Courier New"">  *ListPP =MEM_AllocGStack(sizeof(INTLIST));

<span Courier New"">  (*ListPP)->Functor =listfno;

<span Courier New"">  (*ListPP)->Value =*ArrP++;

<span Courier New"">  ListPP =&(*ListPP)->Next;

<span Courier New"">  n--;

<span Courier New"">}

<span Courier New"">*ListPP = MEM_AllocGStack(sizeof((*ListPP)->Functor));
                          /*

<span Courier New"; mso-ansi-language:RU">конец<span Courier New""> <span Courier New";mso-ansi-language: RU">списка<span Courier New""> */

<span Courier New"">(*ListPP)->Functor = nilfno;

<span Courier New"">}

<span Courier New"">voidinclist(INTLIST *InList,INTLIST **OutList)

<span Courier New"">{

<span Courier New"">register int *ArrP, i, len;

<span Courier New"">int *Array;

<span Courier New"">len = ListToArray(InList,&Array);

<span Courier New"">ArrP = Array;

<span Courier New"">for ( i = 0; i < len; i++)

<span Courier New"">  ++*ArrP++;

<span Courier New"">ArrayToList(Array,len,OutList);

<span Courier New"">}

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

  VP способен нетолько вызывать предикаты, но и предоставлять их другим программам. Нижеприведен пример вызова предиката <span Courier New"">prowin_msg

из программы на С:

<span Courier New";mso-ansi-language:RU">   

<span Courier New"">/* Programhello_p.pro */

<span Courier New"">global predicates

<span Courier New"">charprowin_msg(string) — (i) language c

<span Courier New"">hello_c — language c

<span Courier New"">clauses

<span Courier New"">prowin_msg(S,C):-

<span Courier New"">write(S," (press any key)"), readchar(C).

<span Courier New"">goal

<span Courier New"">prowin_msg(«Hello from PDC Prolog»),

hello_c.

<span Courier New"">/* Program hello_c.c */

<span Courier New"">char prowin_msg(char *);

<span Courier New"">void hello_c()

<span Courier New"">{

<span Courier New"">  while ( prowin_msg(«Hellofrom C (press 'C')») != 'C' )

<span Courier New"">    ;

<span Courier New"; mso-ansi-language:EN-US">}

2003 Pechenkin

pechenkin@pochtamt.ru

www.cs.vsu.ru/~pechenkin

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