我正在尝试编写一个带有weird_sum(List, Result)
个数字的谓词List
,并计算列表中大于或等于5的数字的平方和,减去小于或等于2的数字的绝对值之和。例如:
?- weird_sum([3,6,2,-1], Result).
Result = 33
那是6×6 - 2 - 1.
我正在尝试使用两个条件来检查数字是>= 5
还是<= 2
。但每当我调用谓词“computerResult”时,它只会检查第一个条件并退出。它永远不会达到第二个条件。如果第一个条件失败,如何检查第二个条件?
这是我的代码:
%base case
weird_sum([], 0).
%figuring out if number is large or small
computeResult(Head, Result + Head*Head):-
Head >= 5.
computeResult(Head, Result - abs(Head)):-
Head @=< 2.
%recursive case
weird_sum([Head|Tail], Result):-
weird_sum(Tail, Result),
computeResult(Head,Result).
答案 0 :(得分:0)
问题不在于它不会尝试第二个子句。问题是computeResult/2
谓词中的第二个参数。您编写Result + Head*Head
等等,这意味着Prolog将尝试统一一个数字0
,其格式为+(Result,*(Head,Head))
,这显然会失败。
但您可以轻松修改结果,如:
%base case
weird_sum([], 0).
%recursive case
weird_sum([Head|Tail], Result) :-
weird_sum(Tail, SubResult),
computeResult(Head,Adder),
Result is SubResult+Adder.
%figuring out if number is large or small
computeResult(Head, Head*Head):-
Head >= 5.
computeResult(Head, -abs(Head)):-
Head =< 2.
computeResult(Head, 0) :-
Head < 5,
Head > 2.
您还可以将剪切(!
)添加到条件中,以防止回溯computeResult/2
子句。在这种情况下,您可以省略最后一句中的检查。
%figuring out if number is large or small
computeResult(Head, Head*Head):-
Head >= 5,
!.
computeResult(Head, -abs(Head)):-
Head =< 2,
!.
computeResult(_, 0).
然而,使用累加器更有效,例如:
weird_sum(List, Result) :-
weird_sum(List, 0, Result).
weird_sum([], Result, Result).
weird_sum([Head|Tail], SubResult, Result) :-
computeResult(Head,Adder),
SubResult2 is SubResult+Adder,
weird_sum(Tail, SubResult2, Result).