2010-12-03 7 views
1

警告、私はPrologにはかなり新しいです。リスナークラッシュより何度も同じ答えを返す - Prolog

私はPrologで分割述語を書いています。これは、リストを2つの新しいリストに分割します。 Keyより大きい項目を含むもの、およびKey以下の項目を含むもの。それは一組の答えだけを返すべきです。問題は私が入力する場合です。より多くの答えをチェックするために、それは私に既に得た答えを与え続け、ついにリスナーがクラッシュする。あなたが私にこれを解決するのを手伝ってもらえるかしら?

コード:

split([],_,[],[]). 
split([H|T],Key,Small,Big):- 
    H=<Key, 
    removeFirst(Small,H,NewSmall), 
    split(T,Key,NewSmall,Big). 
split([H|T],Key,Small,Big):- 
    H>Key, 
    removeFirst(Big,H,NewBig), 
    split(T,Key,Small,NewBig). 

removeFirst([H|T],H,T). 
removeFirst(L,Key,Result):- 
    divide(L,Key,F,E), 
    X = F, 
    Y = E, 
    append(X,Y,Z), 
    Result = Z. 

出力:

?- split([1,2,3,4,5],3,S,B).

S = [1, 2, 3]
B = [4, 5] ;

S = [1, 2, 3]
B = [4, 5] ;

S = [1, 2, 3]
B = [4, 5] ;
リスナーは、第四の試みでクラッシュします。

答えて

2

私はあなたが別の方法でこのアルゴリズムを解決する提案:

  • あなたは、入力リストの各項目をチェックしなかったとして、再帰述語(スプリット/ 4)を定義しますが、のリターンに結果のリストを作成再帰(つまり、現在の項目を節の先頭にある適切なリストの先頭に追加する)。それはこのようなものになるだろう

split([], _, [], []). % Base case 
split([Item|Tail], Key, [Item|Small], Big):- 
    Item =< Key, 
    !, % Optimization, the cut here is to avoid the comparison in the next clause 
    split(Tail, Key, Small, Big). 
split([Item|Tail], Key, Small, [Item|Big]):- 
    split(Tail, Key, Small, Big). 
+1

+1;これは、私もそのような述語を書くことに行く方法です。もし純粋さのためにcut( '!')を使いたくないのならば、最初にOPのように 'Item/Key>を' split/4'の最後の節の最初の副目標として残しておけば十分です。 – sharky

関連する問題