Prolog中的“->”运算符是什么,如何使用它?

9

我在一本书中读到了这个,但是它没有被解释。我也从来没有在程序中看到过它。它是Prolog语法的一部分吗?它有什么作用?你会使用它吗?


我读到它可以用来编写解析器。SUM -> O1 + O2或者类似的东西... - Juanjo Conti
2
那个 -->(请注意两个-字符),请参阅SWI手册:http://www.swi-prolog.org/pldoc/doc_for?object=section%282%2c%20%274.12%27%2c%20swi%28%27%2fdoc%2fManual%2fDCG.html%27%29%29 - starblue
3个回答

10

它代表着暗示。只有当左侧为真时,右侧才会被执行。因此,如果您有以下代码:

implication(X) :-
  (X = a ->
    write('Argument a received.'), nl
  ; X = b ->
    write('Argument b received.'), nl
  ;
    write('Received unknown argument.'), nl
  ).

然后它将根据其参数编写不同的内容:

?- implication(a).
Argument a received.
true.

?- implication(b).
Argument b received.
true.

?- implication(c).
Received unknown argument.
true.

(link to documentation.)


2
等等,如果这是蕴含的话,那么逻辑上的 false -> false 应该输出 true,但实际上并不是这样。这是怎么回事? - Błażej Michalik
3
@BłażejMichalik 不是逻辑蕴含关系,而是一个带有内部隐式剪枝的条件-then-else命令。 - Will Ness

3
这是一个本地版本的剪枝,例如在SWI手册中控制预测部分中可以看到。
它主要用于通过(条件 -> 真分支;假分支)实现if-then-else。一旦条件成功,就不会从真分支返回到条件或假分支,但仍然可以回溯出if-then-else:
?- member(X,[1,2,3]), (X=1 -> Y=a ; X=2 -> Y=b ; Y=c).
X = 1,
Y = a ;
X = 2,
Y = b ;
X = 3,
Y = c.

?- member(X,[1,2,3]), (X=1, !, Y=a ; X=2 -> Y=b ; Y=c).
X = 1,
Y = a.

因此它被称为本地剪切。

2
在SWI中,可以使用“*->”而不是“->”来进行软切换! - mat

1

可以通过写更多的文字来避免使用它。如果我重写Stephan's谓词:

implication(X) :-
  (
    X = a,
    write('Argument a received.'), nl
  ; 
    X = b,
    write('Argument b received.'), nl
  ;
    X \= a,
    X \= b,
    write('Received unknown argument.'), nl
  ).

(是的,我不认为使用它有任何问题,但我的老板出于某种原因很偏执,所以我们总是使用上述方法。)

无论哪个版本,你都需要小心,确保覆盖所有你打算覆盖的情况,特别是如果你有许多分支。

预计到:如果你有implication(X),由于回溯,我不确定这是否完全等同于Stephan的。但我现在没有Prolog解释器来检查。


嗯,我不太熟悉Prolog,但这似乎违反了DRY原则。我不确定这是否值得!我的意思是,特别是如果前提条件变得稍微复杂一些,这可能会变得很混乱。至于回溯:对于这个版本(SWI-Prolog),当使用“implication(a)”和“implication(b)”时不会立即返回提示符,因此确实会尝试回溯。 - Stephan202
是的,我绝对不是说这是一种更好的选择,只是它是一种选择。 :) - pfctdayelise

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接