2017-10-19 7 views
1

私はPrologで独自のソートルールを作成しようとしていますが、多くの試行錯誤の後で、を押したとき以外は動作させることができました。スウィープでは、私のリストの最後の値をリストに追加します。次のようにPrologがセミコロンの後で私のリストの最後の値を繰り返すのはなぜですか?

使用されるコードは次のとおりです。

分は、リスト内の最小値を検出し、それを

min([H|[]],H). 
min([H|T],Min) :- 
    min(T,CurrentMin), 
    H < CurrentMin, 
    Min = H. 
min([H|T],Min) :- 
    min(T,CurrentMin), 
    CurrentMin =< H, 
    Min = CurrentMin. 

を返す削除は、リストで削除したい要素を見つけ、とのリストを返します。要素が昇順にソートされたリストを作成するために、上記のルールを使用しようとsort_inc、最後

を除去します。

sort_inc([H|[]],[H]). 
sort_inc(UnOrderedList,[H|OrderedTail]) :- 
    min(UnOrderedList,H), 
    remove(H,UnOrderedList,T), 
    sort_inc(T,OrderedTail). 

ソートは素晴らしい作品が、私は、リスト上でルールを実行した後swiplでセミコロンを押したときにように、それはリストの最後の値を繰り返すことになります:

sort_inc([3,6,8,4],List). 
List = [3, 4, 6, 8] ; 
List = [3, 4, 6, 8, 8] ; 
List = [3, 4, 6, 8, 8, 8] ; 
List = [3, 4, 6, 8, 8, 8, 8] ; 
List = [3, 4, 6, 8, 8, 8, 8, 8] ; 
List = [3, 4, 6, 8, 8, 8, 8, 8, 8] ; 
List = [3, 4, 6, 8, 8, 8, 8, 8, 8|...] . 

なぜそれがありませんセミコロンが入力されたときにfalseを返す代わりに、この最後の値を繰り返します。

答えて

4

あなたが代わりにこのしようと、あなたの削除/ 3の実装に問題があります。正確には

remove(X, [X|Rest], Result) :- 
    !, remove_sub(X, [X|Rest], Result). 
remove(X, [Y|Rest], Z) :- 
    X \= Y, 
    remove(X, Rest, RestRemoved), 
    Z = [Y|RestRemoved]. 
remove(_, [], []). 

remove_sub(X, [X|Rest], Rest). 
remove_sub(X, [Y|Rest], Z) :- 
    remove_sub(X, Rest, RestRemoved), 
    Z = [Y|RestRemoved]. 

を、削除/ 3のあなたの最初の句は、要素が削除された場合でも、完全なリストを残すことによって、不適切な解を生成しますまた、バンドルされた多くのPrologの実装は/ 3を削除し、/ 2の実装(だけでなく、コースのようなものを、)最小必要がありますことを、心に留めておいてください

?- remove(1, [1, 2, 3], L). 
L = [2, 3] ; 
L = [1, 2, 3]. 

:そのメンバーです。例えば、SWIをPrologは含まれています:

  • 一度
  • にある要素のすべてのインスタンスを削除除き、ご自分の削除/ 3が行うことになっていたものはほとんど何をされ、/ 3を削除するには、/ 3を選択し、そのリストの最小要素を見つけるのに
  • min_list/2とmin_member/2を削除できないことを除いて、あなたのremove/3がやるべきことはほとんどありません。
  • sort/2、実際の並べ替えを行うには、msort/2、predsort/3、

独自の実装を作成することを目的としていても、独自の実装をテストするためにカスタム実装を使用する価値はあります。削除/ 3へのコールをすぐに削除/ 3で置き換えて、問題がどこにあるかを知ることができます。

+0

remove/3の最初の節では、remove(_、[]、[])を参照していますか?空のリストから何かを削除しようとすると空のリストだけが返されると思いました。要素が属していない場合、これは良い最後の再帰的なステップと考えました。 –

+0

また、あなたが書いた削除ルールでは、remove(1、[2]、List)はList = []を返します。私は、単一の要素リストが適切な呼び出しなしでアイテムを失うことを望んでいません。 –

+1

あなたが正しいと思われます、私の最初の実装であるremove/3は壊れました、残念です。これは現在修正済みです(うまくいけば)、私は答えを更新しました。また、私が言及したdelete/3は、remove/3が要素のすべての出現を即座に削除する点でremove/3とは異なりますが、remove/3はバックトラック中に要素を1つずつ削除します。 –

関連する問題