標準用語順序 (ISO/IEC 13211-1 7.2 用語順序) は、変数を含むすべての用語に対して定義されます。これには良い用途があります — の実装を考えてみてsetof/3
ください。これにより、8.4 用語比較のビルトインのクリーンで論理的な多くの使用法が、あらゆる場所で imps (命令型構造の短縮形) を使用した宣言型の悪夢になります。8.4 用語比較機能:
8.4 用語の比較
8.4.1 (@=<)/2、(==)/2、(\==)/2、(@<)/2、(@>)/2、(@>=)/2。
8.4.2 比較/3 .
8.4.3 並べ替え/2 .
8.4.4 キーソート/2 .
例を挙げると、次のことを考慮してください。
?- X @< a.
true.
これは成功するので、
7.2 タームオーダー
順序付けterm_precedes (3.181) は
、用語X
term-precedes が term に先行するかどうかを定義しY
ます。
X
とY
が同一の用語である場合、X
term_precedesY
とY
term_precedesX
は両方とも false です。
X
との型が異なる場合Y
:X
term_precedesY
の
型がの型のX
前にY
次の順序である場合:
variable
先行floating point
する 先行integer
する 先行atom
するcompound
。注 — 用語の順序をテストする組み込みの述語
は、8.4 で定義されています。
...
したがって、すべての変数は より小さいですa
。しかし、一度X
インスタンス化されます:
?- X @< a, X = a.
X = a.
結果は無効になります。
それが問題です。これを克服するために、制約を使用するか、コアの動作のみに固執してinstantiation_error
.
7.12.2 エラー分類
エラーは次の形式に従って分類され
Error_term
ます。
a)引数またはそのコンポーネントの 1 つが変数であり、
インスタンス化された引数またはコンポーネントが必要な場合、インスタンス化エラーが発生します。
の形をしていinstantiation_error
ます。
このようにして、インスタンス化エラーが発生しない限り、結果が適切に定義されていることが確実にわかります。
の場合、制約を使用するか、クリーン インスタンス化エラーを生成するかの(\==)/2
いずれかが既に存在します。dif/2
iso_dif/2
iso_dif(X, Y) :-
X \== Y,
( X \= Y -> true
; throw(error(instantiation_error,iso_dif/2))
).
だから私の質問は何ですか: ISO Prologで対応する安全な用語比較述語を定義 (および名前付け) する方法は? 理想的には、明示的な用語トラバーサルなしで。たぶん明確にするために:上記iso_dif/2
では、トラバーサルという明示的な用語を使用していません。と の両方が内部的に用語(\==)/2
を(\=)/2
トラバースしますが、このオーバーヘッドは(=..)/2
orによる明示的なトラバーサルと比較して非常に低くなりますfunctor/3, arg/3
。