Я пытаюсь написать код на Прологе, который может поменять местами два элемента списка, но только если они последовательны друг другу. Это,
conseq_swap(d, e, [a, g, d, e, f], X).
должен дать:
X = [a, g, e, d, f].
(d и e идут подряд.)
Тем не мение,
conseq_swap(a, e, [a, g, d, e, f], X).
всегда должно терпеть неудачу (a и e не являются последовательными.)
Я могу предположить, что элемент появляется в списке только один раз.
У меня есть следующий код, который на самом деле работает нормально:
swap_conseq(X, Y, MainList, SwappedList) :-
indexOf(MainList, X, Xpos),
indexOf(MainList, Y, Ypos),
Diff is Ypos - Xpos,
Diff is 1,
Xpos < Ypos,
swap_ordered(X, Y, Xpos, Ypos, MainList, SwappedList).
swap_conseq(X, Y, MainList, SwappedList) :-
indexOf(MainList, X, Xpos),
indexOf(MainList, Y, Ypos),
Diff is Xpos - Ypos,
Diff is 1,
Ypos < Xpos,
swap_ordered(Y, X, Ypos, Xpos, MainList, SwappedList).
swap_ordered(Min, Max, Minpos, Maxpos, MainList, SwappedList) :-
compute_lists(MainList, Min, Minpos, Pre, _),
compute_lists(MainList, Max, Maxpos, _, Post),
append(Pre, [Max, Min], Temp),
append(Temp, Post, SwappedList).
indexOf([Element|_], Element, 1):- !.
indexOf([_|Tail], Element, Index):-
indexOf(Tail, Element, Index1),
!,
Index is Index1+1.
compute_lists(MainList, X, Xpos, A, B) :-
L is Xpos - 1,
append(A, [X | B], MainList),
length(A, L).
Однако, просто взглянув на код, я могу сказать, что это ужасный способ сделать это - повторяющийся, неэффективный - то, что может написать только новичок в Прологе, такой как я.
Любые предложения о том, как улучшить это, будут очень признательны!