2016-07-27 214 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