1

私は Prolog がまったく初めてで、宿題に取り組んでいます。私のプログラムは、同じ長さの 2 つのリストを取り、D = sqrt((X1-Y1)^2 + (X2-Y2)^2 + ... + (XN-YN)^2) を実行することになっています。正しい答えを得るためのコードを書きましたが、正しく表示されません。無限ループに陥っているように見えるので、ロジックの流れに問題があるのではないかと思います。次のようになります。

?- distance([1,2,3], [2,3,4], D).
D = 1.732051.

私のコードでは正しい結果が得られますが、次のように出力されます。

?- distance([1,2,3],[2,3,4],D).
1.732051
true

そして、結果を印刷するための行があるからです。また、エンターを押すまで終了しません (ピリオドなし)。そのため、ループが発生するのではないかと心配しています。コードを言い換えたり、ロジックをリダイレクトして、正常に印刷するにはどうすればよいですか?

distance([],[],D) :-
  F is sqrt(D),
  format("~f~n", [F]).

distance([A|T1], [B|T2], D) :-
  var(D),
  S is (A-B)*(A-B),
  distance(T1, T2, S);
  C is A-B,
  E is C*C,
  F is D+E,
  distance(T1, T2, F).
4

3 に答える 3

2

プログラムは無限ループに入りません。そうしないと、ある時点でスタックオーバーフローエラーが発生する可能性があります。何が起こっているのかというと、コードが開いた選択ポイントを残しているため、最終的にインタプリタがやり直そうとします(失敗します)。呼び出し元のプロシージャで使用される変数Dがバインドされないため、期待どおりの結果が得られません。

この問題を再帰的にモデル化する方法を考えて解決したほうがよいでしょう。この場合、たとえば、入力リストが空の場合と空でない場合に問題を分割できます(ここでは、空のリストを使用してプロシージャを呼び出すと、結果として0が生成されると想定しています)。

したがって、このシナリオでは、2つの句を作成します。1つは基本ケース(空のリスト)用で、もう1つは再帰ステップ用です。また、アキュムレータの使用で構成される、プロローグで使用される一般的なアプローチを使用します。

したがって、このアキュムレータを使用する別のプロシージャを呼び出すだけのdistance/3のファクトを作成します。

distance(L1,L2,F) :-
    distance(L1, L2, 0, F).

アキュムレータを使用して、コード内のアイテムの差の2乗の合計(AB)*(AB)の部分的な結果を保持します。

ここで、基本ケース(空のリスト)から始めます。

distance([],[],S,F) :-
  F is sqrt(S).

ここでは、アイテムが残っていない場合の結果がアキュムレータの平方根であると述べています。

次に、再帰ステップを実行します。これは、各リストの最初のアイテムのアイテムの差の2乗を計算し、再帰を実行するステップです。

distance([A|T1], [B|T2], D, SQRT) :-
  S is D+(A-B)*(A-B),
  distance(T1, T2, S, SQRT).

これで完了です。

?- distance([1,2,3],[2,3,4],D).
D = 1.7320508075688772.
于 2012-04-16T22:09:32.210 に答える
0

関数の使い方がよくわからないformatので、自分で試してみることしかできません。あなたの試みには、再帰の基本ケースに関して明確に述べられていないという欠点があると思います。

以下の私のアプローチを検討してください。

distance([],[],0).
distance([A],[A],0).
distance([A|T1],[B|T2],D) :-
    distance(T1,T2,F),
    D is sqrt((A-B)*(A-B) + F*F).
于 2012-04-16T22:09:45.147 に答える
0

アキュムレータを使用する必要があると思います:

distance(L1, L2, D) :- 
    distance(L1, L2, 0, D).

distance([], [], TT, D) :-
    D is sqrt(D).

distance([X1 | Y1], [X2 | Y2], TT, D) :-
    TT1 is TT + (X1 - X2) * X1 - X2),
    distance(Y1, Y2, TT1, D).
于 2012-04-16T22:11:36.400 に答える