我是 Prolog 新手。我想要一个采用列表的谓词,使用 maplist/3 处理它,创建一个相应的列表,用 0 代替小于平均值的数字,用 1 代替高于平均值的数字。然后我想要第二个谓词对 1 求和,以找出有多少数字高于平均值。然后,第二个谓词返回该数字,该数字对应于高于平均值的总数。
我知道下面的代码工作正常:
numAtOrAboveMean(Mean, Num, Val) :- Num > Mean -> Val is 1; Val is 0.
maplist(numAtOrAboveMean(Mean), [], List), sumlist(List, Below).
当我修改它时,我得到一个类型错误,预期是 [] 但找到了一个列表。这些评论与我对谓词行为的看法相对应。
nGMean(Mean, Num, Val) :- Num > Mean -> Val is 1; Val is 0.%sorts list
nGMean([], _ , []). %takes a list, a constant, relates to a list
nGMean(L, Mean, List) : - maplist(nGMean(Mean), L, List). %maplist call sort
然后总而言之,我将使用第二个谓词。像这样的事情:
sumtotal(L,V) :- mean(L, M), M2 is M, nGMean(L, M2, List), sum(List, V).
这不起作用可能主要是因为 nGMean 抛出错误。 nGMean 完整错误如下所示:
所以我的问题是,为什么我在 nGMean 谓词上遇到类型错误?
编辑 - 正如下面评论中所要求的那样,这就是全部内容。正如我所解释的,这是唯一的部分,因为我正在单独测试它。 谢谢您的回答。下次我将发布完整的代码。或者明确表示我只想解决一个谓词的问题。
最佳答案
您应该发布可以复制和运行的完整代码。在您发布的内容中,mean/2
和sum/2
未定义。
(补充:)错误的原因似乎是您正在比较一个值和一个列表( 2<[2,3|...]
)。发生这种情况的原因是因为您的第一个子句 nGMean/3
有Mean
作为第一个参数,而其他子句具有列表,即列表变为 Mean
用于比较( Num > Mean
)。我不知道怎么办>
变成<
.
此外,请调用maplist/3
在空列表上没有意义。
递归谓词应该有两个子句。一个递归子句(通常)对列表的头部执行某些操作,然后在尾部和基本情况(空列表)上递归调用。
nGMean([Num|Nums],Mean,[Val|List]) :-
( Num > Mean ->
Val = 1
; Val = 0 ),
nGMean(Nums,Mean,List).
nGMean([],_,[]).
通过这个定义,我得到与上面前两行相同的输出,所以我相信这就是你想要的。
(前面补充:只有当右侧包含数学计算时,才需要使用is
。如果只是设置一个值,=
就可以。)
关于prolog - 为什么我在使用 maplist/3 prolog 时会收到 Type error : `[]' expected,found `[21,3,4,5,6,7,8]' (a list) ("x"must keep one character) ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47513349/