ボンジュール・マドモアゼル

本サイトの情報は自己責任にてご利用下さい。

[Prolog] SWI-Prolog − 4.1 Notation of Predicate Descriptions

 

引数モードについて
SWI-Prolog 5.10.2 Reference Manual の
4.1 Notation of Predicate Descriptions を翻訳。
誤訳があるかもしれない。色付き文字は訳者の補足。

4.1 述語説明の表記法

述語の説明を、明白かつ簡潔に記すよう努める。まず、述語名はボールド体で記され、後にイタリック体で記された引数が続く。引数の名前の先頭には、mode indicator が付与される。 mode indicator の表記については、Prologのコミュニティにおいて完全な合意がない。我々は、以下の定義に従う。
+
引数は、要求された型を満たす項として具体化されている必要がある。このモードは、入力用の引数を意図している。@モードとの違いは、+モードでは、引数が変数を含む複合項の場合、述語の呼び出しによって、その変数が具体化されることが起りうる。下の例では、述語 retract(+Term) が変数を含む引数で呼び出され、変数が具体化されている。

retract(father(X,Y)).
X = john,
Y = taro.


-
引数は、束縛されていてはならない。型が適合する変数項でなければならない。このモードは、出力用の引数を意図している。

?
引数は、示された型の部分項に束縛されなければならない。変数は、任意の型に適合する部分項となることに注意せよ。このモードは、入力か出力、または、入力かつ出力用を意図している。
例)stream_property(S, reposition(Bool)). 項の reposition の部分は、入力であり、代入されていない Bool は出力である。

:
引数は、メタ引数である。+ を含意する。モジュール操作の詳細については、section 5 を見よ。

@
引数は、述語の呼び出しで(部分的にも)更なる代入が行われることはない。典型的な用途は、type-tests である。

!
引数は、変更可能な構造を含む。それは、setarg/3 か nb_setarg/3 を使い、変更されるだろう。
実行テキストの中で述語を言及するには、述語指示子 (predicate indicator)を使う。述語指示子の正規で最も一般的な形式は、<module>:<name>/<arity> という項である。モジュール名は、モジュールと無関係(組込み述語)か、コンテキストから推測可能な場合、しばしば、省略される。
DCG(section 4.11参照)に関するISO標準草案に準拠するSWI-Prolog は、[<module>]:<name>//<arity> という形で文法規則を言及することも許す。
すべての負でない整数 arity については、<name>//<arity><name>/<arity+2> と同じである。

参照される述語が定義されるかどうか、文法規則として使えるかどうかに関わらず、
//記法は、伝統的に述語指示子の指定が許されるすべての箇所で使うことができる。例:spy/1, dynamic/1.

翻訳ここまで

上述のとおり、SWI-Prolog において述語指示子 (predicate indicator) は、[<module>]:<name>//<arity> という形でも書ける。
<name>//<arity - 2><name>/<arity> と同じである。
ただし arity - 2 がマイナスになる場合は、<name>//(<arity - 2>) と括弧を付加する必要がある。



?- spy(foo/0).



?- spy(foo//(-2)).

という形でも書ける。

以下は、述語指示子 (predicate indicator) 関する SWI-Prolog 5.10.2 の実装。
算術演算子として判定されているのが面白い。


pl-proc.c
int
get_functor(term_t descr, functor_t *fdef, Module *m, term_t h, int how)
{ GET_LD
  term_t head = PL_new_term_ref();
  int dcgpi=FALSE;

  PL_strip_module(descr, m, head);

  if ( PL_is_functor(head, FUNCTOR_divide2) ||
       関数子が '/' 除算かどうか
       (dcgpi=PL_is_functor(head, FUNCTOR_gdiv2)) )
        関数子が '//' 端数処理付き除算かどうか
  { term_t a = PL_new_term_ref();
    atom_t name;
    int arity = 0;

    _PL_get_arg(1, head, a);
    if ( !PL_get_atom_ex(a, &name) )
      fail;
    _PL_get_arg(2, head, a);
    if ( !get_arity(a,
        (dcgpi ? 2 : 0),
        dcgpi フラグが立っているとき、arity に加える数として
        引数 extra に 2 を渡す
        (how&GF_PROCEDURE) ? MAXARITY : -1,
        &arity ) )
      fail;
[...]

pl-proc.c
static int
get_arity(term_t t, int extra, int maxarity, int *arity)
{ int a;

  if ( !PL_get_integer_ex(t, &a) )
    fail;
  if ( a < 0 )
    return PL_error(NULL, 0, NULL, ERR_DOMAIN,
		    ATOM_not_less_than_zero, t);
  a += extra;   引数の数を加算する

  if ( maxarity >= 0 && a > maxarity )
  { char buf[100];

    return PL_error(NULL, 0,
		    tostr(buf, "limit is %d, request = %d",
			  maxarity, a),
		    ERR_REPRESENTATION, ATOM_max_arity);
  }

  *arity = a;

  return TRUE;
}
<<Coroutining | ホーム | SWI-Prolog − モジュール>>

コメント

コメントの投稿

管理者にだけ表示を許可する

画像の文字を半角数字で下記ボックスに記入ください。
文字が読みにくい場合はブラウザの更新をすると新しい文字列が表示されます。