3

2つのリストを乗算したいのですが、左側のリストを取得して、右側のリストの各要素を乗算します。

例えば:

?- multLists([3,4,2], [4,7,8], R).
R = [[12,16,8],[21,28,14],[24,32,16]].

そのために、リストを取得して単一のスカラーで乗算するヘルパー述語を作成しました。

multListElem([], _, _).
multListElem([H|T], Result, Elem) :- 
    multListElem(T, W, Elem),
    Z is H*Elem,
    Result = [Z|W].

しかし今、私が実行すると、次のよう?- multListElem([1,2,3], X, 3). になります。

1 ?- multListElem([1,2,3], X, 3).
X = [3, 6, 9|_G1840].

その奇妙な尻尾は何_G1840ですか?

4

2 に答える 2

5

バグはここにあります:multListElem([],_,_)。最初のリストが空の場合、結果は空になるため、次のように記述する必要があります。multListElem([],[],_).

リストを操作するときは、 maplistのような機能的なイディオムを使用できます 。

multLists(L1, L2, R) :-
    maplist(mult_one_list(L1), L2, R).

mult_one_list(L1, Elem, R) :-
    maplist(mult_2_numbers(Elem), L1, R).

mult_2_numbers(V1, V2, R) :-
    R is V1 * V2.

maplist各リストの各要素に最初の引数を適用します(引数として渡されます)。

于 2013-01-12T08:29:04.887 に答える
3

あなたのベースケースは尾をインスタンス化せずに残します:に変更します

multListElem([],[],_).

そしてそれは動作します。

@ Joel76はすでに問題に対処しており、maplistを使用したより良いアプローチを公開しています。lambda.plが利用できる場合、ここに問題を解決するコンパクトな式があります

?- maplist(\A^B^maplist(\X^Y^(Y is X*A), [3,4,2], B), [4,7,8], R).
R = [[12, 16, 8], [21, 28, 14], [24, 32, 16]].

もちろん、適切なインターフェイスを編集します

multLists(L1, L2, R) :-
    maplist(\A^B^maplist(\X^Y^(Y is X*A), L1, B), L2, R).

@falseが指摘した2番目のバグは、理解するのは難しいですが、修正するのは簡単です。

multLists(L1, L2, R) :-
    maplist(\A^maplist(\X^Y^(Y is X*A), L1), L2, R).

私が機能と呼ぶ最初のバグ:ラムダがクロージャーで動作し、それから宣言されることは非常に便利です...ちょうど私の2セント...A

于 2013-01-12T08:41:05.813 に答える