Вот еще один дубль:
nifty([], []).
nifty([[]|X], []) :-
nifty(X, []).
nifty([], [[]|X]) :-
nifty([], X).
nifty([[X|Y]|Z], [[X|Q]|R]) :-
swap(Y, R, N),
swap(Q, Z, M),
nifty(M, N).
swap([], [], []).
swap([X|Y], [[X|P]|Q], [P|R]) :-
swap(Y, Q, R).
Он занимает второе место по скорости:
?- dim(77,66,L), time((between(1,100,_), transpose(L,_), fail; true)).
% 1,577,201 inferences, 0.103 CPU in 0.104 seconds (99% CPU, 15244107 Lips)
?- dim(77,66,L), time((between(1,100,_), nifty(L,_), fail; true)).
% 521,601 inferences, 0.062 CPU in 0.063 seconds (99% CPU, 8368647 Lips)
?- dim(77,66,L), time((between(1,100,_), group(L,_), fail; true)).
% 528,300 inferences, 0.048 CPU in 0.049 seconds (98% CPU, 11105739 Lips)
Но он полностью двунаправленный, даже в SWI-Prolog:
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.4)
?- nifty([[1,2,3],[4,5,6]],X).
X = [[1, 4], [2, 5], [3, 6]].
?- nifty([[1,4],[2,5],[3,6]],X).
X = [[1, 2, 3], [4, 5, 6]] ;
false.
?- nifty(X,[[1,2,3],[4,5,6]]).
X = [[1, 4], [2, 5], [3, 6]] ;
false.
?- nifty(X,[[1,4],[2,5],[3,6]]).
X = [[1, 2, 3], [4, 5, 6]].
И если система Prolog обеспечивает своевременную индексацию с несколькими аргументами, как в Jekejeke Prolog, она даже не оставляет точек выбора без особых сложностей:
Jekejeke Prolog 3, Runtime Library 1.3.8 (23 May 2019)
?- nifty([[1,2,3],[4,5,6]], X).
X = [[1,4],[2,5],[3,6]]
?- nifty([[1,4],[2,5],[3,6]], X).
X = [[1,2,3],[4,5,6]]
?- nifty(X, [[1,2,3],[4,5,6]]).
X = [[1,4],[2,5],[3,6]]
?- nifty(X, [[1,4],[2,5],[3,6]]).
X = [[1,2,3],[4,5,6]]