2

我是 Prolog 的新手。我想要一个带有列表的谓词,用 maplist/3 处理它,创建一个相应的列表,用零代替小于均值的数字,用 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 谓词错误

所以我的问题是,为什么我会在 nGMean 谓词上遇到这种类型错误?

编辑-正如下面评论中的要求是整个事情。正如我解释的那样,这是唯一的部分,因为我正在单独测试它。谢谢你的回答。下次我将发布完整的代码。或者明确表示我只想解决一个谓词。

numAtOrAboveMean 的映射表

编辑器上的完整代码图片

4

1 回答 1

3

您应该发布可以复制和运行的完整代码。在您发布的内容中,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在右侧包含数学计算时使用。设置一个值=就可以了。)

于 2017-11-30T04:01:36.837 回答