私はプロローグの世界で初めてです。順列が「1サイクル」かどうかを調べたい。
順列からサイクルを生成する述語を書こうとしています。これが私のコードです(動作していません):
find_next([E|_], [N|_], E, N).
find_next([_|L1], [_|L2], E, N) :-
find_next(L1, L2, E, N).
find_cycle(L1, L2, E, C) :-
append(C, [E], C1),
find_next(L1, L2, E, N),
find_cycle(L1, L2, N, C1).
順列は 2 つのリストで表されます (例: [1, 2, 3, 4]、[3, 4, 2, 1])。
find_next
要素 (E) の次のサイクル要素 (N) を生成します (例: E=1、N=3)。
find_cycle
要素 E から始まるサイクル (C) を探します。
残念ながら、find_next がサイクル C の最初の要素と同じ N を返すときに、再発を停止する方法がわかりません。
編集:いくつかの例。
find_cycle([1, 2, 3, 4], [3, 4, 2, 1], 1, X).
返す必要があります:
X = [1, 3, 2, 4];
false.
と:
find_cycle([1, 2, 3, 4], [4, 2, 1, 3], 1, X).
返す必要があります:
X = [1, 4, 3];
false.
なんで?これは、バラバラなサイクルへの順列の単純な分解です。2 番目の順列を分析してみましょう: [1, 2, 3, 4], [4, 2, 1, 3]
.
Take first element: 1.
1 goes into 4
4 goes into 3
3 goes into 1
end of cycle.
この順列は、1 つのサイクルに分解できません (生成されるサイクルの長さは、順列の長さよりも短くなります)。