我正在尝试编写可以交换列表的两个元素的 Prolog 代码,但前提是它们彼此连续。那是,
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).
但是,仅通过查看代码,我就可以看出这是一种可怕的方法——重复、低效——只有像我这样的 Prolog 新手才能编写。
任何有关如何改进这一点的建议将不胜感激!