3

リストの 2 つの要素を交換できる 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 は連続していません)。

アイテムがリストに表示されるのは 1 回だけであると想定できます。

次のコードがありますが、実際には正常に動作しています。

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 の初心者だけが書くことができます。

これを改善する方法についての提案は大歓迎です!

4

3 に答える 3