2017-03-29 14 views
1

Prolog(私はバージョン7.4.0-rc1を使用しています)で述語を定義しようとしましたが、insertPermutation/2を定義しようとしました。これは、両方の引数がリストであり、 。Prologの置換述語

delete(X,[X|T],T). % Base case, element equals head. 
delete(X,[A|B],[A|C]) :- delete(X,B,C). % And/or repeat for the tail. 

insert(X,Y,Z) :- delete(X,Z,Y). % Inserting is deletion in reverse. 

insertPermutation([],[]). % Base case. 
insertPermutation([H|T],P) :- insertPermutation(Q,T), insert(H,Q,P). % P permutation of T, H inserted. 

私は既に削除が上記のヘルパー述語の良い名前ではないことを認識しました。これらの述部を記述する必要があり、組み込み述部を使用することはできません。これが私がこのようにして上記のコードを書いた理由です。私はその名前を選んだのです(最初に要素を削除するために書きました)。第3引数がリストであり、第1引数の最初のインスタンスが削除された第2引数のリストと等しい場合にのみ、真となります。

insertPermutation述部は、Pが最初のリストの末尾の置換と等しく、頭部が置換の任意の位置に追加されたかどうかを再帰的に検定します。このようにして、両方の空のリストであるベースケースに作用します。

しかし、置換述語は、私が望むように振る舞いません。たとえば、クエリに

?- insertPermutation([1,2,2],[1,2,3]). 

Prologはfalseを返さずにフリーズします。クエリに

?- insertPermutation(X,[a,b,c]). 

Prologはそれが再びフリーズした後

X = [a, b, c] ; 
X = [b, a, c] ; 
X = [c, a, b] ; 
X = [a, c, b] ; 
X = [b, c, a] ; 
X = [c, b, a] ; 

で応答します。私はこれらの問題が関連しているのを見ていますが、どうしてそうではありません。誰かが私が行方不明のケースを指摘できますか?

編集:これは宿題であり、私は挿入述部を使用してこの問題を解決する必要があります。私はこれを書いた。

+0

Prologがどうしているのですか? [permutation/2](http://www.swi-prolog.org/pldoc/man?predicate=permutation/2)を参照してください。両方のバージョンを[標準形式]に変換することです(https://en.wikipedia .org/wiki/Canonical_form)を比較して比較する。彼らが同じ正準形式を持っているならば、それらは互いの順列であっても、互いに同じであってもよい。 –

+0

この問題では、要素を挿入する関数を使用する必要があります。そのためです!私はすでに動作する代替定義を書いていますが、挿入述部を使用して動作させることはできません。 – Kermit

+1

あなたはその質問に、宿題であればそうだと言ってください。 –

答えて

0

答えは最後の行を変更することである

% P permutation of T, H inserted. 
insertPermutation([H|T],P) :- 
    insertPermutation(Q,T), 
    insert(H,Q,P). 

% P permutation of T, H inserted. 
insertPermutation(P,[H|T]) :- 
    insertPermutation(Q,T), 
    insert(H,Q,P). 

最初の要素だけが後者ではなく、他の方法の周りに(またはその逆)の順列であるかどうかを確認するために必要なユースケース。反気候ですが、私の問題に対する答えです。

+1

Y尾の再帰を使用しませんか? –