Это продолжение этого более раннего ответа и его улучшение
избегая создания бесполезных точек выбора и
снижение сложности Big-O с O (N 2 ) до O (N).
list_pairs_lin([], []).
list_pairs_lin([X|Xs], XYs) :-
<a href="http://www.swi-prolog.org/pldoc/doc_for?object=reverse/2" rel="nofollow noreferrer">reverse</a>(Xs, Ys),
ahead_keys_values_pairs(Xs, [X|Xs], Ys, XYs).
ahead_keys_values_pairs([], _, _, []).
ahead_keys_values_pairs([_|Fs0], [X|Xs], [Y|Ys], [X-Y|XYs]) :-
maybe_ahead(Fs0, Fs),
ahead_keys_values_pairs(Fs, Xs, Ys, XYs).
maybe_ahead([], []).
maybe_ahead([_|Xs], Xs).
Давайте запустим несколько запросов с SWI-Prolog 7.3.15!
Получаем ли мы звуковые ответы при использовании list_pairs_lin/2
?
?- <a href="https://www.complang.tuwien.ac.at/ulrich/iso-prolog/prologue#length" rel="nofollow noreferrer">length</a>(Es, N), <a href="http://www.swi-prolog.org/pldoc/doc_for?object=numlist/3" rel="nofollow noreferrer">numlist</a>(1, N, Es), list_pairs_lin(Es, Pss).
N = 1, Es = [1] , Pss = []
; N = 2, Es = [1,2] , Pss = [1-2]
; N = 3, Es = [1,2,3] , Pss = [1-3]
; N = 4, Es = [1,2,3,4] , Pss = [1-4,2-3]
; N = 5, Es = [1,2,3,4,5] , Pss = [1-5,2-4]
; N = 6, Es = [1,2,3,4,5,6] , Pss = [1-6,2-5,3-4]
; N = 7, Es = [1,2,3,4,5,6,7] , Pss = [1-7,2-6,3-5]
; N = 8, Es = [1,2,3,4,5,6,7,8] , Pss = [1-8,2-7,3-6,4-5]
; N = 9, Es = [1,2,3,4,5,6,7,8,9], Pss = [1-9,2-8,3-7,4-6]
...
Да! А как насчет сложности?
?- <a href="http://www.swi-prolog.org/pldoc/doc_for?object=set_prolog_flag/2" rel="nofollow noreferrer">set_prolog_flag</a>(<a href="http://www.swi-prolog.org/pldoc/man?section=flags" rel="nofollow noreferrer">toplevel_print_anon</a>, false).
true.
?- <a href="http://www.swi-prolog.org/pldoc/doc_for?object=numlist/3" rel="nofollow noreferrer">numlist</a>(1, 5000, _Xs), <a href="http://www.swi-prolog.org/pldoc/doc_for?object=time/1" rel="nofollow noreferrer">time</a>(<a href="https://stackoverflow.com/a/29866271/4609915">list_pairs</a>(_Xs,_)).
% <b>6,252,500 inferences</b>, 2.302 CPU in 2.301 seconds (100% CPU, 2716404 Lips)
<i>true ; % succeeds, but leaves behind useless choicepoint</i>
% 2,503 inferences, 0.001 CPU in 0.001 seconds (100% CPU, 1716259 Lips)
false. % terminates universally
?- numlist(1, 5000, _Xs), time(list_pairs_lin(_Xs,_)).
% <b>10,003 inferences</b>, 0.003 CPU in 0.003 seconds (100% CPU, 3680523 Lips)
true. % <i>succeeds deterministically</i>