我不得不说有一个类似的排队Sum of elements in list in Prolog needs little explanation,但仍让我感到困惑。
以下是需要解释的解决方案。
sum([H],H).
sum([H|T],R):-sum(T,P),R is H + P.
让我们说总和([1,2,3],R)。
sum([1,2,3],R)
sum([2,3],<unknown-1>)
sum([3],<unknown-2>)
那么它将实现事实总和([H],H)? 我把这个变量写成sum([H],H),这个案例的唯一输出是3, 这意味着在未知-2中这里是3,为什么?
只是prolog的初学者,任何答案都会非常感激。
答案 0 :(得分:5)
答案简短:统一。
当在谓词子句的范围内,变量名称出现多次时,所有出现的内容都将统一。统一的谓词是=/2
,并且被声明为运算符,因此=(A, A)
和A = A
表示相同。更重要的是,这个:
=(Term, Term).
是=/2
的定义(请参阅the documentation!)
在您的示例中,您有一个条款说:
sum([H], H).
这意味着:
当
sum/2
的第一个参数是一个只包含一个元素的列表时,sum/2
的第二个参数就是该元素。
因为术语统一在Prolog中是如此基本的操作,通常没有明确说明,例如:
当
sum/2
的第一个参数是一个只有一个元素的列表时,该元素和sum/2
的第二个参数相互统一。
至少在SWI-Prolog文档中,如果涉及统一,通常用&#34来表示; X是Y&#34;代替&#34; X和Y统一&#34;。例如,请参阅the documentation of min_member/2
:
min_member (
Min
,List
)。如果
Min
是标准条款顺序中的最小成员,则为真。如果List
为空,则失败。
它没有明确告诉您使用了统一,并且由此产生以下行为:
?- min_member(3, [1,2,X]).
X = 3.
我曾经asked a question about this因为我发现它太混乱了。
顺便说一句,根据您当前对sum/2
的定义,由于统一的工作方式,您也会感到惊讶。看:
?- sum([1.5, 2.5], Sum).
Sum = 4.0 ; % unnecessary choice point but at least correct
false.
?- sum([1.5, 2.5], 4).
false. % Oops!
SWI-Prolog library implementation遇到同样的问题:
?- sum_list([1.5, 2.5], Sum).
Sum = 4.0. % no choice point, at least
?- sum_list([1.5, 2.5], 4).
false. % Oops!
解决方法是首先将第二个参数保留为自由变量,然后使用=:=/2
,它进行算术比较:
?- sum_list([1.5, 2.5], Sum), Sum =:= 4.
Sum = 4.0.
您也可以使用sum/2
的定义来执行此操作。