Prolog Language
単調性
サーチ…
単調述語についての推論
単調述語は、 宣言的推論を適用することによってデバッグできます。
純粋なPrologでは、プログラミングミスは以下の現象の1つまたはすべてにつながります。
- 述部は、 失敗した場合に間違って成功 する
- 述語は、それが成功すべき場合には間違って失敗 する
- 述語は予期せずに、有限集合の解のみを生成すべきところでループする。
例として、宣言的推論によってcase(2)をデバッグする方法を考えてみましょう。述語の句の目標を体系的に削除し 、 依然としてクエリが失敗するかどうかを確認できます。単調なコードでは、ゴールを取り除くことで、多くの場合、得られるプログラムをより一般的にすることができます。したがって、予期せぬ失敗につながるゴールを見て、エラーを特定することができます。
単調述語の例
単調述語の例は次のとおりです。
- 統一
(=)/2
又はunify_with_occurs_check/2
-
dif/2
、項の病気を表現する - 単調な実行モードを使用して、
(#=)/2
と(#>)/2
ようなCLP(FD)制約 。
単調な目標のみを使用するProlog述語自体が単調である
単調述語は宣言的推論を可能にする:
- クエリに制約(つまり、目標)を追加することで、ソリューションのセットを減らすことはできますが、決して拡張することはできません。
- そのような述語の目標を削除することは、せいぜい、一連のソリューションを拡張し 、決して減らすことはできません。
非単調述語
単調でない述部の例を次に示します。
-
var/1
、integer/1
などのメタ論理述語 -
(@<)/2
と(@>=)/2
ような長期比較述語 -
!/0
、(\+)/1
、および単調性を破る他の構文を使用する述語 -
findall/3
とsetof/3
ような全解述語 。
これらの述語を使用すると、目標を追加することでより多くのソリューションにつながる可能性があります。これは、制約を追加することで最大限にソリューションを拡張することができます。
結果として、宣言的なデバッグやその他の推論に依存する他のプロパティも破損します。例えば、単調でない述語は、一次論理から知られる結合論理の可換性の基本概念を破る。次の例は、これを示しています。
?- var(X), X = a.
X = a.
?- X = a, var(X).
false.
findall/3
ような全解述語も単調性を破ります。節を追加すると、これまでに行っていた目標の失敗につながる可能性があります。これはまた、一次論理から知られているように、事実を加えることがせいぜい増加する可能性があり、結果の集合を決して減らすことはできない、単調性に反する。
非単調構造の単調選択
ここでは、プログラム内に純粋で非単調な構文の代わりに単調な述語を使用する方法の例を示します。
-
dif/2
は、(\=)/2
ような単調でない構文の代わりに使われることを意図しています - 算術制約 (CLP(FD)、CLP(Q)など)は、修飾された算術述語の代わりに使用されることを意図しています
-
!/0
ほとんど常に非単調なプログラムにつながり、完全に避けるべきです。 - この時点で健全な判断を下すことができない状況でインスタンス化エラーが発生する可能性があります。
単調性と効率性の組み合わせ
効率を上げるためには、実際のPrologプログラムで非単調な構造の使用を受け入れなければならないと主張されることがあります。
これについての証拠はない。最近の研究は、Prologの純粋な単調なサブセットは、ほとんどの現実世界のプログラムを表現するのに十分であるだけでなく、実際には許容できるほど効率的であることを示しています。最近発見され、この見解を奨励するコンストラクトはif_/3
です:単調性と選択肢の減少を組み合わせます。 dif / 2の索引付けを参照してください。
たとえば、次の形式のコード。
pred(L, Ls) :- condition(L), then(Ls). pred(L, Ls) :- \+ condition(L), else(Ls).
if_/3
は次のように書くことができます:
pred(L, Ls) :- if_(condition(L), then(Ls), else(Ls)).
単調性と決定論を組み合わせます。