2017-09-26 11 views
2

質問は、最初のリストの特定の要素(X)をxのような別の要素(Y)に置き換えて最終的にそれを格納する述語を作成することでした最後の引数に新しいリストを追加します。明らかに私のベースケース(?)に間違っていることは分かっていますが、私はそれを理解できないようです。このコードをトレースすると、通常の状態になりますが、最初のリストが空の場合は、匿名変数の追加が開始されます。私はPrologを初めて使っています。ループに入るのをやめる方法がわかりません

replace([], _, _, []). 
replace([H|T], X, Y, N):- 
    H = X, 
    append(N, [Y], NL), 
    replace(T, X, Y, NL). 
replace([H|T], X, Y, N):- 
    H \= X, 
    append(N, [H], NL), 
    replace(T, X, Y, NL). 
+0

をあなたは間違った方法を追加...それは 'アペンド(NLでなければなりません、[Y]、N) 'と' append(NL、[H]、N) 'と呼ばれる。しかし、それはまだ非効率的であり、さらにあなたは 'append/3'を全く必要としません。 –

+0

私は確かにこれすべてを行う効率的な方法があるかもしれないと考えました。しかし、私は動作しないものを考えているようです。 – Boomer

+0

私はそれを 'append([Y]、NL、N)'と 'append([H]、NL、N)'に変更しました。今は動作しますが、私はもっと効率的な方法が何であるかを知りたいです。 – Boomer

答えて

3

append/3ない単純な、より効率的なソリューションは次のようになります。代わりに\=オペレータの述語dif/2を使用することがはるかに優れていることを

replace([], _, _, []). 
replace([X|T], X, Y, [Y|T1]):-replace(T, X, Y, T1). 
replace([H|T], X, Y, [H|T1]):-dif(X,H), replace(T, X, Y, T1). 

注(それはより多くのリレーショナル振る舞いがあります。ただ、テストをdif(X,Y).X\=Y.その違いを見るためには、X、Yのアンバウンド変数)。

例:

?- replace([2,4,5,7,8,2,3,4],2,12,L). 
L = [12, 4, 5, 7, 8, 12, 3, 4] ; 
false. 

別の解決策は、DCGを使用することになります。

replace([],_,_) -->[]. 
replace([X|T],X,Y) --> [Y],replace(T,X,Y). 
replace([H|T],X,Y) --> [H],{dif(H,X)},replace(T,X,Y). 

final_replace(In_L,X,Y,Out_L):- phrase(replace(In_L,X,Y),Out_L). 

例:

?- final_replace([2,4,5,7,8,2,3,4],2,12,L). 
L = [12, 4, 5, 7, 8, 12, 3, 4] ; 
false. 
+0

'dif/2'は素晴らしいですが、* ISO *ではありません。 [この回答は@false](https://stackoverflow.com/a/13770020/812818)を参照してください。 –

+0

@DanielLyons、私の間違いなく感謝!!! – coder

関連する問題