web-dev-qa-db-ja.com

プロローグのシングルトン変数

私はSWIプロローグの私の新しいバージョンをテストしていましたが、エラーに遭遇し続けました:singleton variable

例:

member(X,[X|T]).

member(X,[X|T]) :- member(X,T).

次のようなリストのメンバーを検索します。

member(yolands,[yolanda,tim])

X = yes

しかし、代わりに私はシングルトン変数 XとTのエラーを取得します

私が次のことをしたら:

member(X,[X|_]).
member(X,[_|T]) :- member(X,T).

動作しますが、見苦しいです!

誰が単一の変数が許可されないのか、そしてこのANSI規格かどうかを説明できますか?

21
Timothy Lawman

シングルトン変数は、Prologでは役に立たないであり、タイプミスを編集することで簡単に導入できます。

警告は、このような頻繁なエラーの原因を簡単に見つけることができるため、歓迎されています。

警告として、あなたはcanシングルトンを含むコードを実行しますが、これらが最終的に想定する値は失われます。

[〜#〜] iso [〜#〜]標準([〜#〜] ansi [〜#〜]について聞いたことがない)はそのようなことを禁止するとは思わない変数。

この方法で例を書き換えることができます

member(X, [Y|T]) :- X = Y ; member(X, T).

そして、シングルトンを忘れます。

15
CapelliC

ここにバグがあります:

_member(X,[X|T]) :- member(X,T).
_

あなたが実際にと言っていること(あなたが言っていると思うこととは対照的に)は、Xがリストの先頭にある場合は_member/2_が成り立つということですandリストの末尾に存在します。この述部は、リストの先頭にある同じものの最初のNコピーに対してのみ真であるため、非常に奇妙なことです。

_?- member(X, [a,a,c]).
X = a ;
X = a ;
false.

?- member(X, [b,a,a]).
X = b ;
false.
_

これで、次のような操作を行うことで、バグを修正できますが、シングルトン警告が表示されます。

_member(X, [Y|T]) :- member(X, T).
_

しかし、これは、2つのヘッドを持つ従来の定義や、明示的なORを持つ@CapelliCのバージョン(+1)ほど優れていません。 Prologのコードの美観に多くのストックを置く前に、Prologをもう少しよく理解するまで待つべきだと思います。しばらくこのままにしておくと、この警告と匿名変数の使用に感謝することになります。

Prologでシングルトン変数が役に立たないのは、それらに名前が付けられているが、それらについては何も知られていないため、残りの計算に影響を与えないということです。アンダースコアは、意味に影響を与えることなく、絶対に何でもそこに入れることができることを強調しています。何が

_member(X, [X|T]).
_

trueは、Xの位置1が位置2のリストの先頭のXと同じであることです。リストは空にするか、先頭と末尾を持つ必要がありますが、末尾の内容はここでは関係ありません。 Xは頭でもあります。 Tはリストの残りの部分である場合もあれば、不適切なリストである場合もあれば、ブレッドボックスや稲妻、春の日の空気の匂いである場合もあります。 member(X, [X|T])の真実には関係ありません。

シングルトン警告は、「ここで何かの名前を予約しましたが、その名前で何かを呼び出すことはありません」と伝えます。このメッセージを受け取ったときに最初に行うことは、タイプミスが明らかでないことです。名前を_に置き換えて、コードがまだ意味をなさないかどうかを確認します。そうでない場合、論理エラーがあります。もしそうなら、おそらく不要でした。

10
Daniel Lyons

SWI-Prolog FAQ の公式ページでそれについて読むことができます

この警告が表示される最も一般的なケースは次のとおりです。

  1. 変数のスペルミス
  2. 変数の使用/バインドを忘れる

SWIはそれを無視するいくつかの方法を提案します:

  1. この目的には、_という名前の匿名変数を使用します。
  2. 警告を避け、無視する内容を文書化するには、_で始まる変数(__T_、__X_など)を使用します。
  3. 自分が何をしているのかわかっている場合は、:- style_check(-singleton).を使用すると、すべての警告が消えます。
3