2

私は以前に Prolog を学んだことがありますが、Mercury 言語の完全な初心者です。水星の新しい側面の 1 つは、脱皮症です。main関数は決定論的でなければなりません。そのためには、変数が値に統合/バインドされているかどうかを確認する必要がありますが、その方法が見つかりません。特にコードを参照してください。

main(!IO) :-
mother(X,"john"),
( if bound(X)    <-----this is my failed try; how to check if X is unified?
  then
    io.format("%s\n", [s(X)], !IO)
  else
    io.write_string("Not available\n",!IO)
).

そのようなmainものは失敗することはありませんでした。つまり、決定論的制約を満たします (私は推測します)。問題は、変数がバインドされているかどうかを確認する方法です。

4

3 に答える 3

1

変数のインスタンス化状態をチェックする必要はありません。ほぼ 10 年間 Mercury を日常的に使用してきましたが、一度も実行したことがありません。各述語と述語のモードについて、Mercuryはプログラムの各ポイントでの各変数のインスタンス化を静的に認識します。だからあなたの例を使用して:

% I'm making some assumptions here.
:- pred mother(string::out, string::in) is det.

main(!IO) :-
    mother(X,"john"),
    io.format("%s\n", [s(X)], !IO).

Mother の宣言は、その最初の引数が出力引数であることを示しています。これは、mother の呼び出し後にその値がグラウンドになることを意味します。印刷することができます。var 述語を使用した場合 (標準ライブラリにある場合)、常に失敗します。

これを行うために、Mercury はプログラマーに他の要件を課します。例えば。

(
    X = a,
    Y = b
;
    X = c
)
io.write(Y, !IO)

上記のコードは違法です。Y は最初のケースでは生成されますが、2 番目のケースでは生成されないため、その根拠は明確に定義されていません。コンパイラは、選言がスイッチであることも認識しています (X が既に接地されている場合)。そのため、1 つの答えしか生成しません。

マルチモードの述語がある場合、この静的な根拠が難しくなる可能性があります。Mercury は、プログラム モードを正しくするために接続詞の順序を変更する必要がある場合があります。たとえば、生成後に変数を使用する場合などです。それにもかかわらず、変数の使用とインスタンス化の状態は常に静的に認識されます。

これは実際には Prolog とはまったく異なり、かなりの量の未学習が必要になる可能性があることを理解しています。

これが役に立てば幸いです。

于 2016-10-16T22:12:13.313 に答える