МЕНЮ


Фестивали и конкурсы
Семинары
Издания
О МОДНТ
Приглашения
Поздравляем

НАУЧНЫЕ РАБОТЫ


  • Инновационный менеджмент
  • Инвестиции
  • ИГП
  • Земельное право
  • Журналистика
  • Жилищное право
  • Радиоэлектроника
  • Психология
  • Программирование и комп-ры
  • Предпринимательство
  • Право
  • Политология
  • Полиграфия
  • Педагогика
  • Оккультизм и уфология
  • Начертательная геометрия
  • Бухучет управленчучет
  • Биология
  • Бизнес-план
  • Безопасность жизнедеятельности
  • Банковское дело
  • АХД экпред финансы предприятий
  • Аудит
  • Ветеринария
  • Валютные отношения
  • Бухгалтерский учет и аудит
  • Ботаника и сельское хозяйство
  • Биржевое дело
  • Банковское дело
  • Астрономия
  • Архитектура
  • Арбитражный процесс
  • Безопасность жизнедеятельности
  • Административное право
  • Авиация и космонавтика
  • Кулинария
  • Наука и техника
  • Криминология
  • Криминалистика
  • Косметология
  • Коммуникации и связь
  • Кибернетика
  • Исторические личности
  • Информатика
  • Инвестиции
  • по Зоология
  • Журналистика
  • Карта сайта
  • Использование Prolog совместно с другими ЯП

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

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

    Понятие Dll.

    Вспомним процесс программирования в DOS. Преобразование исходного текста

    в машинный код включал в себя 2 процесса: компиляцию и линковку. Во время

    линковки в код программы помещались не только объявления функций и

    процедур, но и их полный код.

    В многозадачной среде подобный подход был бы весьма расточителен, так

    как огромное количество функций, отвечающих за прорисовку элементов

    пользовательского интерфейса, за обращение к системным ресурсам и т.п.

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

    была предложена концепция динамической компоновки (см. рис. 1).

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

    количества элементов.

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


    Приглашения

    09.12.2013 - 16.12.2013

    Международный конкурс хореографического искусства в рамках Международного фестиваля искусств «РОЖДЕСТВЕНСКАЯ АНДОРРА»

    09.12.2013 - 16.12.2013

    Международный конкурс хорового искусства в АНДОРРЕ «РОЖДЕСТВЕНСКАЯ АНДОРРА»




    Copyright © 2012 г.
    При использовании материалов - ссылка на сайт обязательна.