2016-05-18 4 views
1

私のflattenの実装を見てください:一般的に、それは動作しています。 my_flatten([], F)の問題のみ - F=[]ではなくF=[]; F=[[]]となります。 my_flatten(X, [1,2,3])についてはプロローグで平坦化 - 他のようなもの

my_flatten(L, X) :- 
    my_flatten(L, X, []). %, reverse(F, X). 

my_flatten([], Acc, Acc). 
my_flatten([H|T], F, Acc) :- 
    my_flatten(H, F1, Acc), 
    my_flatten(T, F, F1), !.       
my_flatten(X, [X|Acc], Acc).   

このプログラムはループ - として、無限に多くの答えが存在するので、それは、OKです:[[],[],[],[],1,2,3]
しかし、上記と同じ問題 - my_flatten(X, [])の場合もループするはずですが、[]; [[]]となります。

リバーサルですが、気にしません。reverseのコメントを外すと問題ありませんが、上記のループの代わりにfalseが返されます。

my_flatten([], X)の場合、[]を返すようにこのコードを変更することはできますか?

私は@lurkerの提案を実装:

my_flatten(L, F) :- 
    my_flatten(L, X, []), 
    reverse(F, X). 

my_flatten([], Acc, Acc). 
my_flatten([H|T], F, Acc) :- 
    is_list(H), 
    my_flatten(H, F1, Acc), 
    my_flatten(T, F, F1). 
my_flatten([X|T], F, Acc) :- 
    not(is_list(X)), 
    my_flatten(T, F, [X|Acc]). 
+2

カット演算子( '!')に親和性があるようです。 ;)最初の引数を時々リストにすると、時には面白いコードの匂いが出ないことがあります。 'my_flatten(X、[X | Acc]、Acc)'は、これらの2つの場所に現れるAccで問題があります。 'my_flatten/3'とは、論理的に不明であることを意味します。 'is_list(H)'は 'H 'がリストの場合は真であるので、それが便利であればそれを使うことができます。 – lurker

+0

私はカットオペレーターの兄弟ですが、あなたはカットオペレーターのための敵です:Dヒントをお願いします。私は最初の新しい記事を投稿しました。あなたはそれについてどう思いますか ? –

+1

カットには場所がありますが、問題を「修正」しようとすると使いにくいです。多くの初心者は、さまざまな目的のためにそれを使用しますが、しばしば途中で問題を修正しますが、それらの述語の適切な一般性を破壊してしまいます。私はカットの友人でもありますが、それが適切に意図されている場合のみです。 :) – lurker

答えて

3

私はあなたの実際の質問に答える前に、私はflatten/2を使用しての1件のコメントがあります。

をしませを行います。

理由:flatten/2は真の関係ではありません。例えば、我々が持っている:

 
?- X = [a], flatten(X, Ls). 
X = [a], 
Ls = [a]. 

しかし:

 
?- flatten(X, Ls), X = [a]. 
X = [a], 
Ls = [[a]]. 

をこれは明らかに論理的な観点からも意味がありません。

、ネスティングの正確1レベルを削除し、ことを実装しようとする代わりにappend/2を使用してください。

ヒント:を使用してください!

多くのPrologコースでflatten/2が表示されていることを知っています。それはそれが有用で価値があり、教授的なものであるということを意味するものではありません。

常にも最も一般的なクエリを試してください:そこからそれを取っ

 
?- my_flatten(X, Ls). 
X = Ls, Ls = [] ; 
X = [[]], 
Ls = []. 

スタート:この答えあまりにも特定のあまりにも一般的であるあなたの実際の質問に今

、両方とも?これについて考えます。

次に、これが意味を成立させるために必要な議論について考えてみましょう。つまり、どんな条件の下で、さらにインスタンシエーションをしても非官能的ではない健全な回答を与えることさえできますか?

これは、Prologでを読むのに役立ちます。

+0

答えに感謝します。あなたは新しい解決策を見た?最初の投稿を編集し(@lurkerの提案を使用して)、作業用のソリューションを作成しました。あなたはそれについてどう思いますか ? –

+2

まだシガーがありません: '? - my_flatten([[X]]、Ls)、X = [a] .'は' Ls = [[a]] 'で成功します。サウンドの結果を保証できない場合は、[タグ:インスタンス化エラー]をスローする必要があります。 – mat

+0

そのような場合に対処するためにそれを修正してください。 –

関連する問題