以下に示す手続きに従って、例題プログラムprintit.cを見てみましょう。以下のように打って、新しい"作業用"コピ−を作り、ファイルnewpreds.cで6つのステップを実行させましょう。 cp printit.c newpreds.c
<C関数をIF/PrologのC述語に変換する6つのステップ>
1:Cル−チンからmain()を取り除く
2:第一行に#include "cpred.h"というステ−トメントを加える
3:C関数をProlog述語とリンクする(CPRIM())
4:C関数がPrologのパラメ−タを受けとったり、返すようにする 5:C関数がPrologにおいて成功か失敗かを確実に返すようにする
6:あなたの述語をコンパイルし、それらをIF/Prologにリンクする 図C-4
ステツプ1: IF/Prologがすでにmain()関数を持っているので、これをあなたのスタンドアロ−ンプログラムから取り除き、たとえば、Print_predicate()のように関数の名前を変えなければなりません。
ステップ2: ファイルnewpreds.cの第一行に次のステ−トメントを加えます。# include "cpred.h"(cpred.hの一覧表は、Cインタフェ−スマニュアルの付録に載せてあります)
ステップ3: ファイルに以下の記述を加えます。
int Cboot() { CPRIM("PROLOG_FUNCTOR",ARITY,C_FUNCTION); . . . ・ ・ ・ }
Prolog述語にリンクしたいと思うC関数のひとつひとつに対して、Cboot()の中にあるCPRIM()が必要です。これらの記述が新しいPrologの組み込み述語の名前、関数子、引数の数を設定します。ファイルnewpreds.cの中では、以下のように記述されていなければなりません。
int Cboot() { CPRIM("print_it",2, Print_predicate); }
注意:CPRIM()やCPRED()(バックトラッキングの頁を参照)は、実際には整数型C関数を宣言し、Cprim()やCpred()を呼び出すcpred.h(付録を参照)においてマクロ定義されています。
ステップ4: Arg(N)は、述語の第N番目のパラメ−タを返します。型チェックやC変数への変換を扱う様々なC関数があります。IF/PrologのC関数、Unify()やUnifyArg()は、Cル−チンとProlog述語の間で引数を引き渡します。Print_predicate()では、C整数であるstring_lengthはPrologの第2引数と単一化されます。IntCP()は、整数をCの表現形式からPrologの表現形式に変換します。
UnifyArg( 2, IntCP((INT) string_length) );
ステップ5: Prolog述語が成功したり失敗するためには、C関数が返り値を持たなければなりません。1が返された場合は、述語が成功したことを示し、0が返された場合は、失敗か例外と見なされたことを示しています。この例の場合、返り値は以下の結果が結合されたものとなっています。
- C関数XChk()は、第1引数が正しい型でない場合には、例外を返します(IsAt()が引数がアトムかどうかを調べます)。XChk()は、この方法により戻りステ−トメントを返します。これは例外の型をチェックするのに便利です。
- Print_it()は、1を返します。AtStr()は、PrologのアトムをCの文字列に変換します。
- UnifyArg()によって、計算された文字列の長さと述語の第2引数の単一化が試みられます。
この段階であなたのプログラムは、以下のようになっていると思います。
/*------------------------------------------------------*/
/* filename : $PROROOT/demos/c/newpreds.c */ /*------------------------------------------------------*/ #include "cpred.h" int Cboot() { CPRIM("print_it", 2, Print_predicate); } /*----------------------------------------------------*/ int Print_predicate(); /*Prolog goal:print_it(Text,Length).*/ Term Text = Arg(1); int string_length;
return XChk(IsAt(Text), "atom_expected") && Printit(AtStr(Text), &string_length) && UnifyArg(2, IntCP((INT) string_length)); } /*----------------------------------------------------*/ Printit(text, length) /*simple output routine */ char *text; int *length; { printf("text = %S\n", text); *length= strlen(text); return 1; /*success of a Prolog routine */ } /*----------------------------------------------------*/
ステップ6: 以下のように打って、newpreds.cをコンパイルし、IF/Prologにリンクします。
% ifcc newpreds.c % iflink newprolog newpreds.o
以下のように打って、IF/Prologの新しいバ−ジョンと新しい述語を試してみましょう。
% newprolog IF/Prolog Version 3.4.0 created 8/8/88 Copyright (C) 1984,88 InterFace Computer GmbH
?- print_it(test_string,Length). text = test_string Length = 11
yes ?- _
| 冒頭へ |
|