この質問は、重複する要素の有限セットから形成されたすべてのシーケンスを生成する (ビットを一般化する)に関する StackOverflow に関する別の質問に答えているときに出てきました。
ボリスがコメントで正しく示したように、この問題には多くの既存の解決策があります。ただし、アキュムレータ (つまり、新しく選択された要素と比較される既に選択された要素のリスト) を使用せず、dif/2
代わりにステートメントを使用するソリューションに興味があります。
説明のために、次のプログラムには 4 つの要素があり、4 回の再帰呼び出しの後、div/2
これまでに選択された 4 つの要素がペアごとに異なることを示すいくつかのステートメントがあります。このことから、再帰を続けて 5 番目の要素を探すのは無意味であると推測できます。これは、div/2
ステートメントに与えられた要素が残っていないためです。この「知識」をプログラムにエンコードして、ループしないようにする方法はありますか?
:- use_module(library(apply)).
:- use_module(library(dif)).
sequences([]).
sequences([H|T]):-
maplist(dif(H), T),
between(1, 4, H),
sequences(T).
現在のループ動作:
?- sequences(X).
X = [] ;
X = [1] ;
...
X = [4, 3, 1, 2] ;
X = [4, 3, 2, 1] ;
<LOOP>