あなたは私が別々に議論したい2つの問題に直面しています:
インスタンス化エラー
あなたが述べたように、私たちは得ます:
?- 食料品 (Vs)、ラベル (Vs)。
エラー: 引数が十分にインスタンス化されていません
ラベル付けでは、ラベル付けされるすべての変数が有限ドメインを持っている必要があります。あなたの場合、いくつかの変数のドメインがまだ無限であるため、インスタンス化エラーlabel/1
がスローされます。
?- 食料品([A,B,C,D])。
A in inf.. -1\/1..sup ,
100*A#=_9006,
_9006 in inf.. -100\/100..sup,
_9006+_9084+_9078+_9072#=711,
_9006*_9084#=_9102,
_9084 in inf.. -100\/100..sup,
100*B#=_9084、
_9102 in inf.. -1\/1..sup,
_9102*_9078#=_9222,
_9078 in inf.. -100\/100..sup,
100*C#=_9078,
C in inf.. -1\/1..sup、
_9222 in -71100000000.. -1\/1..71100000000,
_9222*_9072#=71100000000,
_9072 in -71100000000.. -100\/100..71100000000,
100*D#=_9072,
D in -711000000.. -1\/1..711000000,
B in inf.. -1\/1..sup .
これを修正する唯一の方法は、プログラムの適切な特殊化を作成することです。この場合、変数は最終的に有限領域になります。[Vs]
の代わりに書くことVs
は明らかに解決策ではありません:
?- 食料品(Vs)、ラベル([Vs])。
エラー: タイプ エラー: 'integer' が必要ですが、'[_8206,_9038,_8670,_8930]' (リスト) が見つかりました
これはlabel/1
、引数がリストのリストではなく、有限ドメイン変数のリストである必要があるため です。
適切な専門化の例は次のとおりです。
?- 食料品 (Vs)、Vs ins 0..sup、ラベル (Vs)。
偽。
結果のプログラムには解がありませんが、インスタンス化エラーがなくなるため、少なくとも絶対に解がないことがわかります。
解決策なし
このようにして、2 番目のかなり独立した問題に到達しました。なぜ、この結果のプログラムには解がないのでしょうか?
Prolog のようなロジック プログラミング言語を使用する主な利点は、たとえばGUPUで示されているように、宣言型デバッグアプローチを 適用できることです。
GUPU と同様に、次の定義を使用してアウェイゴールを一般化します。
:- op(950,fy, *).
*_.
たとえば、プログラムの最後の目標を一般化できます。
食料品(Vars):-
Vars = [A、B、C、D]、
X #= 100 * A,
Y #= 100 * B,
Z #= 100 * C、
W #= 100 * D、
X+Y+Z+W #= 711,
* X*Y*Z*W #= 71100000000 .
純粋で単調なProlog プログラムから制約を取り除いたので、結果のプログラムは明らかに元のプログラムよりも一般的です。
ここで、前のクエリを取得します。
?- 食料品(Vs)、Vs ins 0..sup、ラベル(Vs)。
偽。
そして今、私たちは知っています:より一般的なプログラムでさえ解決策がありません.
この場合の解決策を期待する場合は、残りのプログラムの一部を変更して、定式化の誤りを修正する必要があります。
このアプローチの詳細については、program-slicingおよびlogical-purityを参照してください。