DCG を使用して文法を文字どおりにエンコードしましょう。
s --> [a], s, [b] | [c] | [d].
?- phrase(s,Xs).
ERROR: Out of local stack
このクエリは終了しないようです。つまり、Prolog の非常に単純な実行戦略では解決策が見つかりませんでした。一方、考えてみてください。あなたの文法は無限の文のセットを記述しています。無限集合を列挙している場合、「間違った端から」開始するのは簡単です。それが Prolog がここで実際に行っていることです。
しかし、物事はそれほど悪くはありません。固定長のすべての文を列挙するのはどうですか。私は5を試してみます:
?- length(Xs,5), phrase(s,Xs).
Xs = "aacbb" ;
Xs = "aadbb" ;
false.
この場合、すべての文が検出され、Prolog はそれ以上の文がないことを保証します。
?- length(Xs,4), phrase(s,Xs).
false.
長さ 4 の文はありません。
長さですべての文を列挙できるようになりました。
?- length(Xs,N), phrase(s,Xs).
Xs = "c",
N = 1 ;
Xs = "d",
N = 1 ;
Xs = "acb",
N = 3 ;
Xs = "adb",
N = 3 ;
Xs = "aacbb",
N = 5 ;
Xs = "aadbb",
N = 5 ;
Xs = "aaacbbb",
N = 7
ここではどのような派生を使用しましたか? 正直なところ、私は知りませんし、気にしません。知っておくべき重要なことは、Prolog がいつ終了するかです。この場合、長さがわかっている場合は終了します。そして、無限集合の公正な列挙を保証するために知っておく必要があるのはそれだけです。物事はさらにわずかに優れています。s//0
長さが不明な場合にも終了します
?- Xs = [a,a,b|_], phrase(s,Xs).
false.
?- Xs = [a,a,c|_], phrase(s,Xs).
Xs = "aacbb" ;
false.
?- dif(X,Y), Xs = [X,Y|_], phrase(s,Xs).
X = a,
Y = c,
Xs = "acb" ;
X = a,
Y = d,
Xs = "adb" ;
false.
"acb"
編集:リストに使用するトップレベルの回答についていくつか質問があります:説明についてはこの回答[a,c,b]
を参照し、を参照してください。library(double_quotes)