2016-07-27 211 views
0

對於Prolog,我還是比較新的,並且涉及列表的練習一直存在困難:給定任意數據列表,將列表分成兩個列表 - 一個列表包含整數值,一個包含實數值,然後忽略原始列表中的任何其他項目。按類型將列表分類爲兩個單獨的列表

我寫到目前爲止以下:

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). 
ERROR: toplevel: Undefined procedure: splitList/3 (DWIM could not correct goal) 

通常嫌疑犯這個錯誤似乎並沒有是這樣,但也許我錯過了什麼?

編輯:當我重新加載該文件,並運行它第二次我有以下幾點:

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

您的'splitList'謂詞對於基本情況子句有一個參數,但遞歸子句有3個參數。這是行不通的。你也需要3的基本情況,它需要爲其他兩個提供相應的值(在這種情況下,不適合'[]'?)。你的錯誤看起來像Prolog沒有定義三參數謂詞,所以你不能加載你正確顯示的代碼。 – lurker

+0

你的錯誤信息確實包含一個錯字:你正在調用'splitList/1',這是一個簡單的事實,但是你會得到一個關於'splitList/3'的錯誤。這不可能。 – false

+0

啊,道歉 - 我複製了不正確的行。讓我快速編輯它。 –

回答

1

你的基本情況需要更加完整。它定義瞭如果統一列表爲空,拆分列表的外觀。所以基本情況應該是:

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

你的遞歸條款試圖同時做的一切,但使得在列表的頭部整數與浮點測試的結合,產生了一定是假的條件。換句話說,下面是真實的只有H既是浮子和一個整數:

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

您可以使用其他條款分割了這一點。生成的謂詞是這樣的:

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). 

最後,你真的不需要isIntegerisFloat。他們在確認其類型後只會做出不必要的值的「複製」。你只需要測試H

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). 


作爲@CapelliC表示,如果您的列表中有非數字,這將只是失敗。您可以採用以下方法來獲得更多的通用性,這將跳過非數字元素。它很容易修改,以將非數字元素保留在單獨的列表中。

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