2016-03-20 12 views
0

再帰を使用してリストから整数を削除しようとしています。私はこのremove_integers述語を作ったが、それがなぜ機能しないのか分からない。明らかに私はPrologについて非常に本質的な何かを欠いている。Prolog:リストから整数を削除する

remove_integers([], L, L). 
remove_integers([H|T], A, L) :- 
    \+ integer(H), 
    remove_integers(T, [A|H], L). 

私はこの述語のトレースをしたし、次のように得た:

[trace] ?- remove_integers([foo, bar, 1, 2, foo], [], L). 
    Call: (7) remove_integers([foo, bar, 1, 2, foo], [], _G8188) ? 
    Call: (8) integer(foo) ? 
    Fail: (8) integer(foo) ? 
    Redo: (7) remove_integers([foo, bar, 1, 2, foo], [], _G8188) ? 
    Call: (8) remove_integers([bar, 1, 2, foo], [[]|foo], _G8188) ? 
    Call: (9) integer(bar) ? 
    Fail: (9) integer(bar) ? 
    Redo: (8) remove_integers([bar, 1, 2, foo], [[]|foo], _G8188) ? 
    Call: (9) remove_integers([1, 2, foo], [[[]|foo]|bar], _G8188) ? 
    Call: (10) integer(1) ? 
    Exit: (10) integer(1) ? 
    Fail: (9) remove_integers([1, 2, foo], [[[]|foo]|bar], _G8188) ? 
    Fail: (8) remove_integers([bar, 1, 2, foo], [[]|foo], _G8188) ? 
    Fail: (7) remove_integers([foo, bar, 1, 2, foo], [], _G8188) ? 
false. 

ので仲介リストはいくつかの点で、それは項目を削除開始し、なぜ私は理解していない[[[]|foo]|bar]奇妙に見えるという事実のほかにすでにアキュムレータに入っています。

答えて

1

原溶液の主な問題は、(1)Xが整数である場合が全く処理されない、および(2)あなたの通話をremove_integers(T, [A|H], L).は、リストの末尾に要素Hを使用しますが、これはこのコンテキストでは正しくありません。おそらく、remove_integers(T, [H|A], L)を意味するでしょう。

あなたがもたらすであろう持っているコードの修正:

remove_integers([], L, L). 
remove_integers([H|T], A, L) :- 
    integer(H), 
    remove_integers(T, A, L). 
remove_integers([H|T], A, L) :- 
    \+ integer(H), 
    remove_integers(T, [H|A], L). 

をしかし、なぜあなたはここに追加の引数を使用しているが不明です。補助述語を定義しているように見えますが、主述語は定義していません。また、このアプローチは逆の順序で残りの要素が残ります:

| ?- remove_integers([a,b,c,3,4,d], [], L). 

L = [d,c,b,a] ? ; 

no 

あなたが補助述語または3例を考慮して、カットせずにこれを行うことができます:(1)基本ケース(空のリスト)、( 2)問題の現在のリストの頭部が整数であり、ケース(3)現在のリストの先頭が整数でない場合:

remove_integers([], []). 
remove_integers([X|T], R) :- 
    integer(X), 
    remove_integers(T, R). 
remove_integers([X|T], [X|R]) :- 
    \+ integer(X), 
    remove_integers(T, R). 

| ?- remove_integers([a,b,c,3,4,d], L). 

L = [a,b,c,d] ? ; 

no 

| ?- 

あなたはまた、プロローグを使用することができます「の場合を-then-else "構成:

remove_integers([], []). 
remove_integers([X|T], R) :- 
    ( integer(X) 
    -> R = R1 
    ; R = [X|R1] 
    ), 
    remove_integers(T, R1). 
+0

これはまさに私が探していた答えの種類です。ありがとうございます。 – skamsie

0

私たちの問題は常にです!

remove_integers([],[]). 
remove_integers([X|Xs],[X|Ys]) :- 
     \+integer(X),!, 
     remove_integers(Xs,Ys). 
remove_integers([_|Xs],Ys) :- 
     remove_integers(Xs,Ys). 

試験:

| ?- remove_integers([a,b,c,dfg,1,5,m,8,a],L). 
L = [a,b,c,dfg,m,a] ? ; 
no 
+0

ありがとう。あなたは答えを思いついたか少し説明できますか?私はプロローグを勉強しています。私は、コード自体よりもこのルーチンにどのように来るのかに興味があります。 – skamsie

+0

@skamsie私はプロローグには新しく、このサイトはそれを学ぶのに多くの助けになりました –

+2

Prologロジックの問題を解決するためにカットを使用するという暗い道を進むことをお勧めしません。 Cutsは、より一般的な述語のために有効な解を不必要に切り捨てる可能性があり、特に必要な場合を除いては使用しないでください。 – lurker