2

クエリsum(X,Y)は、X のすべての正の約数 (X 自体を除く) の合計を返します。たとえば、1、2、3、4、6 は 12 の約数であるため、sum(12,Y)答えます。Y=16

次のプロローグ プログラムを実装しようとしましたが、一部の変数がインスタンス化されていないと言って失敗しました。

sum(X,Y) :- f(X,Y,1).
f(X,Y,F) :- X>Y,X>F, 0 is X mod F, F1 is F+1, f(X,Y1,F1), Y is F+Y1.
f(X,Y,F) :- X>Y,X>F, not(0 is X mod F), F1 is F+1, f(X,Y,F1).

上記のプログラムの問題は何ですか?

あなたの助けに感謝します!

4

2 に答える 2

2

完全な宣言型演算の場合、既に提案されているように CLP(FD) を使用できます。たとえば、SWI-Prolog では、単純に (is)/2 を (#=)/2 などに置き換えて、プリミティブ算術演算を一般化し、両側の変数でも機能するようにすると、次のようになります。

:- use_module(library(clpfd)).

sum(X,Y) :- f(X,Y,1).

f(X,Y,F) :- X#>Y,X#>F, 0 #= X mod F, F1 #= F+1, f(X,Y1,F1), Y #= F+Y1.
f(X,Y,F) :- X#>Y,X#>F, 0 #\= X mod F, F1 #= F+1, f(X,Y,F1).

これで、サンプル クエリは次のようになります。

?- sum(12, Y).
false.

明らかにプログラムが具体的すぎるので、重要なケースを説明するのを忘れていないか確認してください。

于 2012-12-03T22:12:36.563 に答える
2

sum_of_divisors 関数のコーディング方法は、あまり参考にならないので、ここでは説明しません。代わりに、クエリの何が問題だったのかを理解する方法を示すことができsum(12,Y)ます。

エラーを見てみましょう:

?- sum(12, Y).
ERROR: >/2: Arguments are not sufficiently instantiated
   Exception: (8) f(12, _G215, 1) ? a
% Execution Aborted

クエリを実行した後

?- sum(12, Y).

Prolog エンジンは次sum(X,Y) :- f(X,Y,1).のように読み取り、2 番目の述語を評価します。

f(X,Y,F) 

ここでX = 12F = 1およびYはバインドされていません。したがって、これを試します:

:- X>Y

これは

12 > _G350

ここ_G350Y、 はインスタンス化されていない変数です。

(>)/2問題は、 (および like (+)/2andなど) のような算術述語では、比較する変数の両方がインスタンス化されている(*)/2必要があることです。次のようにクエリすることはできません。

?- 12 > X

そして、Prolog エンジンが 12 未満のすべてのバインディングを見つけることを期待します。したがって、問題へのアプローチを再考する必要があります。また、数値と変数ではなく、NUMBERS のみで算術を実行できることを覚えておいてくださいXX

于 2012-12-03T21:31:41.747 に答える