Страница 26 из 56
трех элементов, а функторы - структуры языка Си из двух элементов
(они описаны более полно после этого примера).
- Модуль на Турбо Си DUBLIST.C содержит три функции. Первые
две могут брать список, состоящий из целых чисел, и возвращать
структуру с целым элементом, являющимся первым числом (из спис-
ка), или же брать структуру, в которой есть целое число, и возв-
ращать список с этим числом. Третья функция берет целое число n и
создает список из двух целых чисел, первым элементом которого яв-
ляется само число n, а вторым - число 2n.
- Необходимо отметить, что для каждого глобального предиката
Турбо Пролога возможно использование альтернативных шаблонов,
описывающих аргументы, и что каждый такой шаблон требует альтер-
нативной функции Турбо Си. Для следующего примера функция clist_0
должна соответствовать первому шаблону описания аргументов (i,о),
а функция clist_1 - второму шаблону (о,i).
global predicates
clist(ilist,ifunc) - (i,o) (o,i) language c
- Спецификация (i,o) означает, что ilist будет передана в ва-
шу функцию Турбо Си clist_0, а ifunk - указатель на структуру,
который будет определен внутри функции Турбо Си clist_0. Специфи-
кация (o,i) означает, что ifunс будет передана в clist_1, а ilist
- указатель на списковую структуру, которая будет определена
внутри clist_1.
- Если дополнительный шаблон был специфицирован в глобальном
домене вашей Турбо Пролог программы, то функция clist_2 вынуждена
будет обрабатывать этот дополнительный шаблон.
И с х о д н ы й ф а й л Турбо Си: DUBLIST.C
void fail_cc(void);
void *alloc_gstack(int size);
- 211,212 -
struct ilist {
char functor; /* тип элемента списка */
/* 1 = элемент списка */
/* 2 = конец списка */
int val; /* фактический элемент */
struct ilist *next /* указатель на следующий узел */
};
struсt ifunc {
char type; /* тип функтора */
int value; /* значение функтора */
};
void clist_0(struct ilist *in, struct ifunc **out)
{
if (in->functor != 1) fail_cc();/*завершить, если список пуст
*/
*оut = alloc_gstack(sizeof(struct ifunc));
(*out)->value = in->val; /* out присваивает значение f(x)*/
(*out)->type = 1 /* задание типа функтора */
}
void clist_1(struct ilist **out, struct ifunc *in)
{
int temp = 0;
struct ilist *endlist= alloc_gstack(sizeof(struct ilist));
endlist->functor = 2;
temp = in->value;
temp += temp;
*out = alloc_gstack(sizeof(struct ilist));
(*out)->val = temp; /* возвращается [2*X], как элемент */
/* списка */
(*out)->functor = 1;/* устанавливается тип элемента */
/* списка. Если это не выполнять, */
/* то возвращается значение лишенное */
/* смысла */
(*out)->next = endlist;
}
void dublist_0(int n, struct ilist **out) {
/*
эта функция создает список [n,n+n]
*/
struct ilist *temp;
struct ilist *endlist= alloc_gstack(sizeof(struct ilist));
- 213,214 -
endlist->functor = 2;
temp = alloc_gstack(sizeof(struct ilist));
temp->val = n; /* первому элементу списка присваивается
значение n */
temp -> functor = 1;
*out = temp;
/* теперь мы должны разместить второй элемент списка */
temp = alloc_gstack(sizeof(struct ilist));
next = temp; /* установка второго элемента после */
/* первого */
}
Вызов Турбо Пролога из Турбо Си
-----------------------------------------------------------------
Возможен не только вызов Турбо Прологом предикатов, написан-
ных на Турбо Си, но также и вызов Турбо Си прологовских предика-
тов. Если некоторый глобальный предикат описан в Турбо Прологе
как language c и существуют предложения (clauses) для данного
предиката, то Турбо Пролог создаст подпрограмму, которую можно
будет вызывать из Турбо Си.
Следующая программа на Турбо Прологе объявляет два глобаль-
ных предиката языка Си: message и hello_c. Предикат message может
быть вызван из модуля Си посредством использования имени функции
message_0 в тексте программы на Си.
global predicates
message(string) - (i) language c
hello_c - language c
clauses
message(S) :-
makewindow(13,7,7,"",10,10,3,50),
- 215,216 -
write(S), readchar(_),
removewindow.
goal
message("Привет из Турбо Пролога"),
hello_c.
Раздел goal в данном примере вызывает функцию Турбо Си
hello_c, которая, в свою очередь, вызывает предикат Турбо Пролога
message_0 для вывода сообщения.
void message_0(char *str);
void hello_c_0(void)
{
message_0("Привет из Турбо Си");
}
Вы можете использовать эту возможность для легкого доступа к
мощной библиотеке Турбо Пролога из других языков.
Вы легко можете определить ваши собственные библиотечные
подпрограммы в модуле на Турбо Прологе, например так:
project "dummy" /* подставьте сюда имя */
global predicates
myfail language c as "fail"
mymakewindow(integer,integer,integer,string,integer,integer,
integer,integer)
- (i,i,i,i,i,i,i,i) language c as "makewindow"
myshiftwindow(integer) - (i) language c as "shiftwindow"
myremovewindow language c as "removewindow"
write_integer(integer) - (i) language c as "write_integer"
write_real(real) - (i) language c as "write_real"
write_string(string) - (i) language c as "write_string"
myreadchar(char) - (o) language c as "readchar"
myreadline(string) - (o) language c as "readline"
extprog language c as "extprog"
clauses
myfail :- fail.
- 217,218 -
mymakewindow(Wno,Wattr,Fattr,Text,Srow,Scol,Rows,Cols) :-
makewindow(Wno,Wattr,Fattr,Text,Srow,Scol,Rows,Cols).
myshiftwindow(WNO) :- shiftwindow(WNO).
myremovewindow :- removewindow.
write_integer(I) :- write(I).
write_real(R) :- write(R).
write_string(S) :- write(S).
myreadchar(CH) :- readchar(CH).
myreadline(S) :- readln(S).