如何获得规则以在退出前检查所有条件? [英] How to get a rule to check all the conditions before exiting?

查看:29
本文介绍了如何获得规则以在退出前检查所有条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个谓词 weird_sum(List, Result),它采用数字的 List,并计算大于或等于 5 的列表减去小于或等于 2 的数字的绝对值之和.例如:

I'm trying to write a predicate weird_sum(List, Result) which takes a List of numbers, and computes the sum of the squares of the numbers in the list that are greater than or equal to 5, minus the sum of the absolute values of the numbers that are less than or equal to 2. For example:

?- weird_sum([3,6,2,-1], Result).
Result = 33 

那是 6×6 - 2 - 1.

That's 6×6 - 2 - 1.

我正在尝试使用两个条件来检查数字是 >= 5 还是 <= 2.但是每当我调用谓词computerResult"时,它只会检查第一个条件并退出.它永远不会达到第二个条件.如果第一个条件失败,我如何让它检查第二个条件?

I'm trying to check using two conditions whether the number is >= 5 or <= 2. But whenever I call the predicate "computerResult" it will only check the first condition and exit. It never reaches the 2nd condition. How do I make it check the 2nd condition if it fails the first condition?

这是我的代码:

%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).

推荐答案

问题不在于它没有尝试第二个子句.问题在于 computeResult/2 谓词中的第二个参数.你写了 Result + Head*Head 等等,这意味着 Prolog 会尝试统一一个数字(0)与某种形式的东西+(Result,*(Head,Head)) 这显然失败了.

The problem is not that it does not try the second clause. The problem is the second parameter in the computeResult/2 predicate. You write Result + Head*Head, etc. so that means that Prolog will try to unify a number (0) with something of the form +(Result,*(Head,Head)) and this obviously fails.

然而,您可以轻松修改结果,例如:

You can however easily modify the result like:

%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.

您还可以在条件中添加 cuts (!) 以防止回溯 computeResult/2 子句.在这种情况下,您可以省略最后一个子句中的检查.

You can also add cuts (!) to the conditions to prevent backtracking over the computeResult/2 clauses. In that case you can omit the checks in the last clause.

%figuring out if number is large or small
computeResult(Head, Head*Head):-
    Head >= 5,
    !.
computeResult(Head, -abs(Head)):-
    Head =< 2,
    !.
computeResult(_, 0).

尽管如此,使用累加器更有效,例如:

Nevertheless it is more efficient to use an accumulator, like:

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).

这篇关于如何获得规则以在退出前检查所有条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆