0

我有这个代码,序言代码。它的目的是获得给定方阵的转置矩阵。有人可以向我解释这段代码一步一步做了什么吗?

trans([], []).
trans([F|Fs], Ts) :-
    trans(F, [F|Fs], Ts).

trans([], _, []).
trans([_|Rs], Ms, [Ts|Tss]) :-
        lists_firsts_rests(Ms, Ts, Ms1),
        trans(Rs, Ms1, Tss).

lists_firsts_rests([], [], []).
lists_firsts_rests([[F|Os]|Rest], [F|Fs], [Os|Oss]) :-
        lists_firsts_rests(Rest, Fs, Oss).
4

1 回答 1

1

关键是真正的理解lists_firsts_rests/3,鲍里斯的话是正确的。让我们通过跟踪运行它:

?- trace.
[trace]  ?- lists_firsts_rests([[a,b,c],[d,e,f],[g,h,i]], X, Y).

   Call: (6) lists_firsts_rests([[a, b, c], [d, e, f], [g, h, i]], _G1914, _G1915) ? creep
   Call: (7) lists_firsts_rests([[d, e, f], [g, h, i]], _G2030, _G2033) ? creep
   Call: (8) lists_firsts_rests([[g, h, i]], _G2036, _G2039) ? creep
   Call: (9) lists_firsts_rests([], _G2042, _G2045) ? creep
   Exit: (9) lists_firsts_rests([], [], []) ? creep
   Exit: (8) lists_firsts_rests([[g, h, i]], [g], [[h, i]]) ? creep
   Exit: (7) lists_firsts_rests([[d, e, f], [g, h, i]], [d, g], [[e, f], [h, i]]) ? creep
   Exit: (6) lists_firsts_rests([[a, b, c], [d, e, f], [g, h, i]], [a, d, g], [[b, c], [e, f], [h, i]]) ? creep
X = [a, d, g],
Y = [[b, c], [e, f], [h, i]].

所以你可以看到这里发生的事情lists_firsts_rests/3就是剥离每个参数列表中的第一个项目并将它们返回到他们自己的列表中,以及另一个包含所有其余部分的列表。这里的效果是,当它看到 时[[a,b,c],[d,e,f],[g,h,i]],它真正看到的是[[a|X],[d|Y],[g|Z]],它返回了两个东西,列表[a,d,g][X,Y,Z]

trans/3只是一个经典的 Prolog 归纳循环。lists_firsts_rests/3它在矩阵上折叠。应该清楚这将如何产生转置矩阵,因为在跟踪中它清楚地将 3x3 矩阵转换为长度为 3 的向量和 2x3 矩阵“余数”。

trans/2是另一种经典的 Prolog 模式,它设置了递归trans/3并开始循环。这里更经典的命名策略是调用trans/2 transpose/2and trans/3 transpose_loop/3,因为它们确实是这样。

希望这可以帮助。

于 2013-04-04T21:30:01.360 回答