在Prolog中乘以列表和列表列表

时间:2014-03-07 02:58:51

标签: list prolog matrix-multiplication

我目前正在开发一个Prolog程序,并且在确定如何实现它时遇到了很多麻烦。

我想将[1,2,2,1]等列表放入函数中。我想通过这个例子来增加自己来制作一个新的矩阵。

1 * [1,2,2,1] which would yield [1,2,2,1]
2 * [1,2,2,1] which would yield [2,4,4,2]
2 * [1,2,2,1] which would yield [2,4,4,2]
1 * [1,2,2,1] which would yield [1,2,2,1]

我希望它能在矩阵中一起创建所有这些:

[[1,2,2,1],[2,4,4,2],[2,4,4,2],[1,2,2,1]].

最后一部分是我想在我自己乘以时将其归零。所以第二个位置会将第二个位置归零,形成最终矩阵:

[[0,2,2,1],[2,0,4,2],[2,4,0,2],[1,2,2,0]].

我希望有一个谓词调用另一个生成每个列表的谓词。继承了我的想法:

main(A,O):-
    second(A,A,O).

second([],_,[]).
second([A|As],B,[O|Os]):- %creates the list of lists.
    third(A,B,O),
    second(As,B,Os).

third(_,[],[]).
third(A,[B|Bs],[O|Os]):-
    fourth(A,B,O),
    third(A,Bs,Os). %multiplies single digit by list.
fourth(A,B,0):- A == B.
fourth(A,B,O):- O is A * B.

我得到的是正确的矩阵,但不能得到零对角线。

我只是想弄清楚一个正确的方法来获得对角线下的零矩阵。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您可以通过引入指示您所在行和列的索引并检查匹配来执行零:

main(A, O) :-
    second(A, A, 0, O).

second([], _, _, []).
second([A|As], B, R, [O|Os]) :- %creates the list of lists.
    third(A, B, 0, R, O),
    R1 is R + 1,
    second(As, B, R1, Os).

third(_, [], _, _, []).
third(A, [B|Bs], C, R, [O|Os]) :-
    fourth(A, B, C, R, O),
    C1 is C + 1,
    third(A, Bs, C1, R, Os). %multiplies single digit by list.

fourth(_, _, X, X, 0).
fourth(A, B, C, R, O) :- C \== R, O is A * B.

检查:

| ?-  main([1,2,2,1], L).

L = [[0,2,2,1],[2,0,4,2],[2,4,0,2],[1,2,2,0]] ? ;

no

<小时/> 另一个有趣的方法是创建一个maplist_with_index谓词,它就像maplist一样工作但是管理一个索引并隐含地假设给定的谓词接受索引作为它的第一个参数:

maplist_with_index(Pred, L, M) :-
    maplist_with_index_(Pred, 0, L, M).
maplist_with_index_(Pred, I, [H|T], [M|Ms]) :-
    Pred =.. [P|Pt],
    append([P,I|Pt], [H], NewPred),
    Call =.. NewPred,
    call(Call, M),
    I1 is I + 1,
    maplist_with_index_(Pred, I1, T, Ms).
maplist_with_index_(_, _, [], []).

然后,使用此谓词的矩阵程序如下所示:

main(A, O) :-
    second(A, A, O).

second(M, A, O) :-
    maplist_with_index(third(A), M, O).

third(R, A, E, O) :-
    maplist_with_index(fourth(R, E), A, O).

fourth(X, X, _, _, 0).
fourth(C, R, A, B, O) :- C \== R, O is A * B.