【问题标题】:Prolog: Failure driven loopsProlog:失败驱动的循环
【发布时间】:2012-10-24 20:44:12
【问题描述】:

我使用以下失败驱动循环来列出所有内容而不使用 分号。

happiness(fred,5).
happiness(john,3).
happiness(grace,2).

someGoal(X) :-
        happiness(X,Y), write(Y), tab(4), fail.

在查询模式下,我得到了预期的结果

?- someGoal(_).
5    3    2 

如何将这些数字插入列表而不是将它们写入屏幕? 我无法在 someGoal 内处理这个问题,因为回溯似乎是隐含的。

【问题讨论】:

    标签: prolog logic-programming prolog-setof


    【解决方案1】:

    你是对的,回溯是 Prolog 处理替代方案的方式。

    使用findall/3,使用“内部”回溯收集所有个备选方案:

    someGoal(X, Values) :-
        findall(Value, happiness(X, Value), Values).
    

    然后?- someGoal(_, Values). 将实例化 Values = [5, 3, 2]

    【讨论】:

    • 谢谢,太好了,拯救了我的一天。尽管尝试了另一种方式,但我建立了很多序言技能:P
    【解决方案2】:

    故障驱动的循环通常会使某些部分处于打开状态且未指定,迟早会导致一些问题。特别是变量的精确量化很容易保持开放。 Often, such loops can be avoided alltogether。在您的示例中,我不清楚为什么您对someGoal/1 有一个论据。至少你不使用它。所以出现了几个问题:

    1. 如果没有匹配的值,您期望什么?您的原始程序不打印任何内容并失败。

    2. 如果存在冗余条目,您会期待什么?您想多次打印吗?

    3. 您是坚持值的精确顺序,还是可以想象另一种顺序?

    4. 您为什么对查看这些值感兴趣?大多数情况下,您要么希望将它们与具体名称相关联,要么希望对其进行某种聚合,例如总和或平均值。

    鉴于我不知道这些问题的答案,我可以为您提供几种解决方案。我将用一个额外的(冗余的)事实来举你的例子:

    幸福(弗雷德,5)。 幸福(约翰,3)。 幸福(约翰,3)。 幸福(恩典,2)。 ?- setof(P-H,happiness(P,H), PHs). PHs = [fred-5,grace-2,john-3]。 ?- setof(H,P^happiness(P,H), PHs). PH = [2, 3, 5]。 ?- bagof(H,P^happiness(P,H), PHs). PH = [5, 3, 3, 2]。

    【讨论】:

    • 非常感谢您的进一步说明和案例研究。为了便于阅读,我的玩具示例从更复杂的示例中简化。
    猜你喜欢
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 1970-01-01
    • 2018-03-13
    • 2014-04-23
    • 1970-01-01
    • 2020-01-12
    相关资源
    最近更新 更多