I'm trying to write Prolog code that can swap two elements of a list, but only if they are consecutive to each other. That is,
conseq_swap(d, e, [a, g, d, e, f], X).
should give:
X = [a, g, e, d, f].
(d and e are consecutive.)
However,
conseq_swap(a, e, [a, g, d, e, f], X).
should always fail (a and e are not consecutive.)
I can assume that an item appears in the list only once.
I have the following code, which is actually working fine:
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).
However, just by looking at the code, I can tell that this is a horrible way to do this - repetitive, inefficient - something only a Prolog newbie like me could write.
Any suggestions on how to improve this would be greatly appreciated!