IF Computer > IF/Prolog > Manuals > IF/Prolog V4.1 マニュアル > IF/Prolog Interfaces > IF/PrologからC言語へのインタフェ−ス > バックトラックしないProlog述語をC言語で書く > C関数のIF/PrologのC述語への変換

C関数のIF/PrologのC述語への変換

IF/Prolog by Siemens
MINERVA superseeded IF/Prolog. Please see http://www.ifcomputer.co.jp/MINERVA for details.

We discontinued to sell IF/Prolog Dec 31. 2003. For current customers, we continue to provide professional support for IF/Prolog until Dec 31, 2008.

以下に示す手続きに従って、例題プログラム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 ?- _

document: http://www.ifcomputer.co.jp/IFProlog/Manuals/v4.1/advanced_feature/c_interface/cpredw/turncp/print_en.html
published 2008/7/7 update 1995/11/7 (c) 1996-2006 IF Computer Japan
IF Computer 5-28-2 Sendagi, Bunkyo-ku Tel +81-3-5814-3352 info@ifcomputer.com
Customer Support Tokyo 113-0022 Japan   http://www.ifcomputer.com
Back> managed with ubiCMS