我对序言很陌生,我正在尝试对列表元素进行汇总。 到目前为止,我有这个:
sum([],_,_). %base case
sum([H|T], Y, _X):-
X2 is H + Y,
sum(T,X2,X2).
使用sum([1,2,3,4],0,X)进行测试会导致错误,但是我不确定这段代码有什么问题。有人可以指出我正确的方向吗?
答案 0 :(得分:0)
您提供的代码比您想像中的更接近工作,但是存在一些问题。
首先,Prolog谓词不是函数,它们不会像其他语言的函数那样返回结果。谓词则声明什么是正确的。稍后,您可以进行序言查询,它会尽力使它们成为现实。
例如,当左参数为列表,而右参数为具有列表长度的int时,对length/2的调用为true:
?- length([1, 2, 3, 4], 4).
true.
?- length([1, 2, 3, 4], X).
X = 4.
?- length(X, 2).
X = [_2300, _2306].
回顾第一行:
sum([],_,_). %base case
这表示“ sum / 3始终为true,只要第一个元素为空列表”。您可以对此进行测试:
?- sum([], -20, hello).
true.
那可能不是你想要的。
我不确定如何在不放弃答案的情况下放置其余内容,但请看一下该子句在说什么:
sum([H|T], Y, _X):-
X2 is H + Y,
sum(T,X2,X2).
“ {sum([H|T], Y, WhoCaresIllNeverUseThisVariable)
是真的,如果我们可以再次证明sum(T, H+Y, H+Y)
是真的”。
好一点,最后一个参数有点奇怪,因为您在两个子句中都将其分配给匿名变量(_
和_X
)。您要说的是,“第三个参数永远不会重要,应该从字面意义上匹配任何用途”。我认为那不是你想说的。
第二点,我不知道您是否意识到这一点,但是,您实际上是在计算总和!在尝试使sum([1, 2, 3, 4], 0, X)
为真时,Prolog将遍历列表并将每个元素添加到中间参数(累加器)中。求和部分起作用!您没有做的是从此谓词中提取总和。
通常,在Prolog中,您可以通过将其作为附加参数来“返回”结果。您可以通过这种方式查看length / 2。这是您自己编写的一种方法:
my_length([], 0).
my_length([_|Rest], Length) :-
my_length(Rest, Length1),
Length is Length1 + 1.
此函数仅在谓词的第二个参数是数组的长度时才为true,从而“返回”数组的长度。