如果另一个谓词失败,则调用谓词 [英] Call a predicate if another predicate failed

查看:44
本文介绍了如果另一个谓词失败,则调用谓词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果对另一个谓词的所有调用都失败了,我如何调用一个谓词?

How can I call a predicate if all calls to another predicate failed?

我有:

foo(A, B, C, D) :-
    (bar1(Y,Z); bar2(L, K, M)),
    foo(A, B, C, D).

我想要的:

  • 在任何时候,如果 bar1/2 成功,bar2/3 将永远不会被执行.
  • 如果所有 bar1/2 调用失败,那么 bar2/3 最终会被执行.
  • at any time, If bar1/2 has succeded, bar2/3 will never be executed.
  • if all bar1/2 calls failed, then bar2/3 will eventually be executed.

样本回溯树

            root                                           root                 
                                                            |
           /   \                                            |
          /     \          all bar1 failed                  |
         /       \                                          |
        / | \     \        ===>>>======>>>>                 |
       /  |  \     \                                        |
      F   F  F     F                                        E
time  0   1  2     3                                        4 

Abbreviation:
       Bar1 failed : F
       Bar2 executed : E

推荐答案

您正在寻找所谓的软剪辑",

You're looking for what's known as "soft cut",

A *-> B ; C.

这相当于 (A,B) ;(\+A,C):如果A至少成功一次,上面等价于A,B.如果不是,它就相当于 C.目标 A 不会重试.

This is equivalent to (A,B) ; (\+A,C): if A succeeds at least once, the above is equivalent to A,B. If not, it's equivalent to just C. The goal A is not retried.

简单的 if 构造允许测试谓词只成功一次:

Simple if construct allows the test predicate to succeed only once:

A -> B ; C.

等价于 (几乎 - 详情请参见手册)(once(A),B) ;(\+A,C),除了不重试目标 A.

is equivalent (almost - see you manual for details) to (once(A),B) ; (\+A,C), except that the goal A isn't retried.

你的情况应该是

foo(A, B, C, D) :-
    (bar1(Y,Z) *-> true ; bar2(L, K, M)),
    foo(A, B, C, D).

补充:一些 Prolog 实现可能没有这个结构 *-> 可用(例如 gprolog).在那种情况下,我看到了两种可能性.要么

addition: Some Prolog implementations might not have this construct *-> available (e.g. gprolog). In that case I see two possibilities. Either

(A , B) ; (\+A , C)

虽然它会重试A,或者(为A编写goal(X))

although it would retry A, or (writing goal(X) for A)

bagof(g(X), goal(X), L) -> ( member(g(X), L), B ) ; C 

当然,副作用的顺序会因此而改变.应该选择变量的名称L,这样它在B 中不会出现自由.

Of course the order of side-effects will be changed by this. The name L of the variable should be chosen such that it does not appear free in B.

这篇关于如果另一个谓词失败,则调用谓词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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