取消分组的不连续目标和切割

huangapple go评论54阅读模式
英文:

ungrouping grouped disjunctive goals and the cut

问题

以下是翻译好的内容:

众所周知,以下两条规则:

fruit(X) :- yellow(X).
fruit(X) :- red(X).

可以更简洁地写成以下形式,使用逻辑或 ;

fruit(X) :- ( yellow(X); red(X) )。

现在,让我们看一下以下引入了切割操作符 ! 的情况,它出现在逻辑或组合之前:

test(specific) :- !, ( goal1 ; goal2 ).
test(General) :- goal3。

思路是如果 test(specific) 匹配成功,那么 test(General) 就不会被执行。

问题: 上述的形式是否等同于以下形式?

test(specific) :- goal1.
test(specific) :- !, goal2.
test(General) :- goal3。

我之所以提出这个问题是因为在第一种形式中,切割操作符出现在包含两个目标 ( goal1 ; goal2 ) 的组合之前,但在第二种形式中,它仅出现在 goal2 之前,这感觉有一种不对称,通常会促使我核查自己的理解。

这个问题的背景是试图更好地理解这个问题的答案:https://stackoverflow.com/questions/27235148/implementing-cut-in-tracing-meta-interpreter-prolog/27255452#27255452。

英文:

It is well known that the following two rules

fruit(X) :- yellow(X).
fruit(X) :- red(X).

can be written more concisely as following using the disjunction ;.

fruit(X) :- ( yellow(X); red(X) ).

Now, let's look at the following which introduces a cut before the disjunctive group.

test(specific) :- !, ( goal1 ; goal2 ).
test(General) :- goal3.

The idea is that if test(specific) matches, then test(General) is not executed.

Question: Is the above equivalent to the following?

test(specific) :- goal1.
test(specific) :- !, goal2.
test(General) :- goal3.

I ask because in the first form, the cut is present before the group consisting of both goals ( goal1 ; goal2 ), but in the second form it is only present before goal2, which feels asymmetric and that usually prompts me to check my understanding.

The context of this question is trying to better understand the answer to this question: https://stackoverflow.com/questions/27235148/implementing-cut-in-tracing-meta-interpreter-prolog/27255452#27255452

答案1

得分: 4

Here's the translated portion:

"这一切都取决于你所说的等同。除了子句检查之外,存在以下区别:

?- freeze(X,writeq(h(X))), test(X).

这将成功两次,其中X = specific,但只有第二个版本会写出两次h(specific)。

这是一个没有副作用的变种:

test1(specific) :- !, ( true ; true ).
test1(_).

test2(specific).
test2(specific) :- !.
test2(_).

?- freeze(X,(Y=a;Y=b)), test1(X).
X = specific, Y = a
; X = specific, Y = a.
?- freeze(X,(Y=a;Y=b)), test2(X).
X = specific, Y = a
; X = specific, Y = b
; X = specific, Y = a.
?- freeze(X,(Y=a;Y=b)), test1(X), Y = b.
false.
?- freeze(X,(Y=a;Y=b)), test2(X), Y = b.
X = specific, Y = b
; false."

Is there anything else you'd like to know or discuss?

英文:

> Is the above equivalent to the following?

It all depends on what you mean by equivalent. Apart from clause inspection, there is the following difference:

?- freeze(X,writeq(h(X))), test(X).

which will succeed twice with X = specific, but only the second version will write out h(specific) twice.

Here is a variant without side effects:

test1(specific) :- !, ( true ; true ).
test1(_).

test2(specific).
test2(specific) :- !.
test2(_).

?- freeze(X,(Y=a;Y=b)), test1(X).
   X = specific, Y = a
;  X = specific, Y = a.
?- freeze(X,(Y=a;Y=b)), test2(X).
   X = specific, Y = a
;  X = specific, Y = b
;  X = specific, Y = a.
?- freeze(X,(Y=a;Y=b)), test1(X), Y = b.
   false.
?- freeze(X,(Y=a;Y=b)), test2(X), Y = b.
   X = specific, Y = b
;  false.

In other words, this variation may even make a declarative difference. What would be needed to make this safe, is to test for the appropriate instantiation first.

huangapple
  • 本文由 发表于 2023年1月6日 11:20:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75026619.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定