关键是真正的理解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/2
and trans/3
transpose_loop/3
,因为它们确实是这样。
希望这可以帮助。