2016-07-27 9 views
0

私はまだPrologの新人です。リストを含むエクササイズでは問題がありました。任意のデータのリストがあれば、リストを2つのリスト実数値を含むものとし、元のリストの他の項目は無視します。リストをタイプ別に2つの別々のリストに分類する

私がこれまでに以下のことを書いた:

?- splitList([1, 2.5, 6, 7.0, -1, -0.5], I, F). 
ERROR: toplevel: Undefined procedure: splitList/3 (DWIM could not correct goal) 

このエラーの通常の容疑者はいないようです:

isInteger(I, IntegerListHead):- 
    integer(I), 
    IntegerListHead is I. 

isFloat(F, FloatListHead):- 
    float(F), 
    FloatListHead is F. 

splitList([]). 
splitList([H|T], [IntHead|IntList],[FloatHead|FloatList]):- 
    isInteger(H, IntHead), 
    isFloat(H, FloatHead), 
    splitList(T, IntList, FloatList). 

は、しかし、私は特定のエラーを取得する理由はわからないんだけど場合には、しかし、多分私は何かを逃したのですか?

編集:私は、ファイルを再読み込みし、それを私は、次しまった二度目に走っ:

?- splitList([1, 2.5, 6, 7.0, -1, -0.5], I, F). 
false. 
+1

'splitList'述部には、基本case節に1つの引数がありますが、再帰的節には3つの引数があります。それは動作しません。基本ケースにも3が必要で、他の2つの対応する値を提供する必要があります(この場合、 '[]'が適切ではないでしょうか?)。あなたのエラーは、Prologが3引数の述語を定義していないように見えるので、正しく表示しているコードをロードしてはいけません。 – lurker

+0

あなたのエラーメッセージにはタイプミスが含まれています:あなたは 'splitList/1'を呼び出していますが、これは単純な事実ですが、' splitList/3'についてはエラーが出ます。それ無理。 – false

+0

ああ、謝罪 - 私は間違った行をコピーしました。私はそれを速く編集させてください。 –

答えて

1

あなたのベースケースは、より完全にする必要があります。統合リストが空の場合、分割リストの外観を定義します。だから、基本ケースは次のようになります。

splitList([], [], []). % Split lists are empty iff the unified list is empty 

あなたの再帰的な句は、一度にすべてを行うためにしようとしますが、必ずしも偽の状態で、その結果、リストの頭の上にフロートテスト対整数の組み合わせになります。

isInteger(H, IntHead), 
isFloat(H, FloatHead) 

あなたは別の句を使用しているを分割することができます。つまり、次はHがfloatと整数の両方である場合にのみ当てはまります。結果述語は次のようになります。

splitList([], [], []). 
splitList([H|T], [IntHead|IntList], FloatList):- 
    isInteger(H, IntHead), 
    splitList(T, IntList, FloatList). 
splitList([H|T], IntList, [FloatHead|FloatList]):- 
    isFloat(H, FloatHead), 
    splitList(T, IntList, FloatList). 

最後に、あなたが本当にisIntegerまたはisFloatを必要としません。彼らはそのタイプを確認した後でしか値の不要な「コピー」を作成しません。あなただけHをテストする必要があります:あなたのリストがそれに非数字を持っている場合

@CapelliCが示されているように
splitList([], [], []). 
splitList([H|T], [H|IntList], FloatList):- 
    integer(H), 
    splitList(T, IntList, FloatList). 
splitList([H|T], IntList, [H|FloatList]):- 
    float(H), 
    splitList(T, IntList, FloatList). 


、これは単に失敗します。非数値要素をスキップするより一般的な方法として、以下のアプローチをとることができます。これは、非数値要素を別のリストに保持するように簡単に変更されます。

splitList([], [], []). 
splitList([H|T], IntList, FloatList):- 
    ( integer(H) 
    -> IntList = [H|Ints], 
     FloatList = Floats 
    ; float(H) 
    -> IntList = Ints, 
     FloatList = [H|Floats] 
    ; IntList = Ints, 
     FloatList = Floats 
    ), 
    splitList(T, Ints, Floats). 
+0

整数でない要素や浮動小数点をスキップするのを忘れないでください。 – CapelliC

+0

@CapelliC確かに、良いキャッチ!私はリストが "よく振る舞われた"と仮定することによってそれを単純に保つように努めていました。 :) – lurker

関連する問題