如果对另一个谓词的所有调用都失败了,我如何调用谓词?
我有:
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
。示例反馈树
root root
|
/ \ |
/ \ all bar1 failed |
/ \ |
/ | \ \ ===>>>======>>>> |
/ | \ \ |
F F F F E
time 0 1 2 3 4
Abbreviation:
Bar1 failed : F
Bar2 executed : E
答案 0 :(得分:1)
你正在寻找所谓的“软切”,
A *-> B ; C.
这相当于(A,B) ; (\+A,C)
:如果A
成功至少一次,则上述内容相当于A,B
。如果没有,则相当于C
。目标A
未重试。
简单if
构造允许测试谓词只成功一次:
A -> B ; C.
等同于(几乎 - 请参阅手册了解详情)至(once(A),B) ; (\+A,C)
,但目标A
未重试。
因此,您的案件应为
foo(A, B, C, D) :-
(bar1(Y,Z) *-> true ; bar2(L, K, M)),
foo(A, B, C, D).
另外: 某些Prolog实现可能没有此构造*->
可用(例如gprolog)。在那种情况下,我看到两种可能性。任
(A , B) ; (\+A , C)
虽然它会重试A
,或者(写goal(X)
代表A)
bagof(g(X), goal(X), L) -> ( member(g(X), L), B ) ; C
当然,副作用的顺序会因此而改变。应选择变量的名称L
,使其在B
中不显示为空闲。