5

私は Prolog の学習を始めています。指定された整数が整数などに与えるプログラムがP必要です。この式を満たすとの値がない場合は、が返されます。ABP = A² + B²ABfalse

例: の場合、 and (またはand )P = 5を与える必要があります。A = 1B = 2A = 2B = 11² + 2² = 5

私はこれがうまくいくはずだと思っていました:

giveSum(P, A, B) :- integer(A), integer(B), integer(P), P is A*A + B*B.

クエリで:

giveSum(5, A, B).

ただし、そうではありません。私は何をすべきか?私は Prolog に非常に慣れていないので、まだ多くの間違いを犯しています。

前もって感謝します!

4

2 に答える 2

6

integer/1非単調述語です。この場合に適用すると予想される推論を可能にする関係ではありません。これを例証するには:

?- 整数 (I)。

整数は存在しませんよね?控えめに言っても、私を驚かせてください

このような非リレーショナル構造の代わりに、Prolog システムのCLP(FD) 制約を使用して整数について推論します。

例えば:

?- 5 #= A*A + B*B.
-2..-1\/1..2 の A、
A^2#=_G1025,
1..4 の _G1025、
_G1025+_G1052#=5,
1..4 の _G1052、
B^2#=_G406,
B in -2..-1\/1..2

具体的な解決策については、次のとおりです。

?- 5 #= A*A + B*B, ラベル([A,B]).
A = -2、
B = -1;
A = -2、
B = 1;
A = -1、
B = -2;
等

CLP(FD) 制約は、期待どおりに使用できる完全に純粋な関係です。詳細については、 を参照してください。

私が気づいた他のこと:

  • use_underscores_for_readability_as_is_the_convention_in_prolog代わりにofMixingTheCasesToMakePredicatesHardToRead
  • 宣言的な名前を使用し、命令を避けます。たとえば、なぜそれを呼び出すのgive_sumですか? この述語は、合計がすでに与えられている場合にも完全に意味があります。では、sum_of_squares/3たとえば はどうでしょうか。
于 2016-07-20T12:37:37.857 に答える
1

効率のために、Prolog の実装者は、何年も前に、いくつかの妥協を選択しました。現在、CLP(FD) のように、Prolog が高度な整数演算を実装している可能性があります。この場合、マットの答えは完璧です。しかし、一部のプロローグ (おそらくナイーブな ISO プロローグ準拠のプロセッサー) は、label/1 と (#=)/2 の欠落について文句を言う可能性があります。したがって、従来の Prolog ソリューション: この手法はgenerate および testと呼ばれます。

giveSum(P, A, B) :-
  ( integer(P) -> between(1,P,A), between(1,P,B) ; integer(A),integer(B) ),
  P is A*A + B*B.

between/3 ISO 組み込みではありませんが、(#=)/2 と label/1 よりも書きやすいです :)

とにかく、マットのアドバイスに従い、「必須」の命名は避けてください。多くの場合、関係の記述の方が適切です。なぜなら、Prolog は関係言語だからです。

于 2016-07-20T13:37:40.353 に答える