0

私は次のコードを持っています

isInRange(Point1,Point2,Range):-
manhatan2(Point1,Point2,Manhatan),
Range>Manhatan.

manhatan2 は、2 要素リスト [X,Y] として与えられる 2 点間のマンハッタン距離を計算します。

isInRange が常に true と評価される理由がわかりません

isInRange([0,0],[0,10],9) は true と評価されます isInRange([0,0],[0,10],100) も true と評価されます

私はmanhatan関数を正しく実行したと確信しています。多くの値でテストしました

私のコードの何が問題なのかを理解してくれる人はいますか?

%ここから編集開始

だから私はいまいましいことを追跡しました、そしてここに私が使用するより多くのコードがあります

modul(A,B,R):-A<B,R is B-A.
modul(A,B,R):-A>B,R is A-B.

extractFromList([H|_],X,R):- X is 0,R is H.
extractFromList([_|T],X,R):- X1 is X-1,extractFromList(T,X1,R).

manhatan(X1,Y1,X2,Y2,R):- modul(X1,X2,R1),modul(Y1,Y2,R2),R is R1+R2.

manhatan2(P1,P2,R):-
extractFromList(P1,0,X1),
extractFromList(P1,1,Y1),
extractFromList(P2,0,X2),
extractFromList(P2,1,Y2),
manhatan(X1,Y1,X2,Y2,R).

extract fromFromList は、指定されたリストから X 番目の要素を抽出します

モジュールは|AB|を返す必要があります

トレース isInRange([0,0],[0,10],100) 私が望んだときはいつでも。

isInRange([0,0],[0,10],9) のトレースは、manhatan を範囲と比較するときに停止し、_GXXX を -10 に評価する modul(0,10,_GXXX) のやり直しを開始したため、Manhatan < Range 条件は次のように評価されました。 true したがって、すべての isInRange が true に評価されます

なぜそれをするのですか?

このようにモジュル計算をやり直すのはなぜですか?

4

1 に答える 1

0

簡単な答え:次のコードはあなたが望むことをします:

manhattan(L1,L2,Result) :- manhattan(L1,L2,0,Result).

manhattan([],[],Res,Res).
manhattan([H1|T1],[H2|T2],Acc,Res) :-
    AccNew is Acc + abs(H1-H2),
    manhattan(T1,T2,AccNew,Res).

isInRange(P1, P2, Range) :-
    manhattan(P1, P2, Distance),
    Range > Distance.

より長い答え: 私はあなたのコードを試しましたが、あなたが説明したように動作しません。私にとっては、A==B の場合に「modul」が失敗するため、isInRange は常に失敗します。最初のケースのテストを A =< B に変更する必要があります。または、組み込みの 'abs' 関数を使用することをお勧めします。

以前のバージョンでは、2 番目のケースのテストがなかったと思います。その場合、Prolog は、最初のケースが失敗したときに 2 番目のケースを試みます (たとえば、Range > Manhatan が失敗したため)。この問題を解決する 1 つの方法で、2 番目のケースにテストを追加します。

于 2013-10-27T09:17:14.083 に答える