Prolog运算符'->'的含义是什么

What's the meaning of Prolog operator '->'

我注意到在某些 Prolog 程序中使用了运算符 -> ,但我不知道它的含义。 这是一个使用示例:

swish_add_user(User, Passwd, Fields) :-
    phrase("$", E, _), % use Unix MD5 hashes
    crypt(Passwd, E),
    string_codes(Hash, E),
    Entry = passwd(User, Hash, Fields),
    absolute_file_name(swish(passwd), File,
    [access(write)]),
    ( exists_file(File)
    -> http_read_passwd_file(File, Data)
    ; Data = []
    ),
    ( selectchk(passwd(User, _, _), Data, Entry, NewData)
    -> true
    ; append(Data, [Entry], NewData)
    ),
    http_write_passwd_file(File, NewData).

它在这个子句中有什么用?我什么时候应该使用这个运算符,什么时候不应该?

PS:代码段取自authenticate.pl file in the swish repository, an excellent implementation of a Prolog IDE online,顺便说一下

就是Prolog中的if/then/else,例如

( X mod 2 =:= 0
-> writeln(even)
;  writeln(odd)).

Joel76 的回答给出了 ->/2 控制结构最常见的用法,它在 ISO Prolog. The description given for Goal1 -> Goal2 in the GNU Prolog manual 中定义为:

Goal1 -> Goal2 first executes Goal1 and, in case of success, removes all choice-points created by Goal1 and executes Goal2. This control construct acts like an if-then (Goal1 is the test part and Goal2 the then part). Note that if Goal1 fails ->/2 fails also. ->/2 is often combined with ;/2 to define an if-then-else as follows: Goal1 -> Goal2 ; Goal3. Note that Goal1 -> Goal2 is the first argument of the (;)/2 and Goal3 (the else part) is the second argument. Such an if-then-else control construct first creates a choice-point for the else-part (intuitively associated with ;/2) and then executes Goal1. In case of success, all choice-points created by Goal1 together with the choice-point for the else-part are removed and Goal2 is executed. If Goal1 fails then Goal3 is executed.

它不像 数学逻辑蕴涵(正如其符号形式可能暗示的那样),因为在这样的蕴涵子句中,F -> T 为真,而在 Prolog 中,如上所述,如果 Goal1 失败,则 ->/2 表达式失败。

在这种情况下,请务必注意运算符的优先级。在 Prolog 中,优先顺序是 ,,然后是 ->,然后是 ;。因此,如描述中所述,在 if-then-else 结构 Goal1 -> Goal2 ; Goal3 中,Goal1 -> Goal2 表达式是 ;/2 的第一个参数。以下是各种情况下发生的情况:

Goal1  ->  Goal2  ;  Goal3     if-then-else  Notes
-----      -----     -----     ------------  -----
Succeeds   Succeeds  NE*       Succeeds      Goal1 choice point removed
                                             Goal2 choice point remains (if it exists)
Succeeds   Fails     NE        Fails         Goal1 choice point removed
Fails      NE        Succeeds  Succeeds      Goal3 choice point remains (if it exists)
Fails      NE        Fails     Fails

*NE = not executed

由于优先级的原因,if-then-else 结构通常带有括号,例如:

( selectchk(passwd(User, _, _), Data, Entry, NewData)
-> true
; append(Data, [Entry], NewData)
),
blah-blah

如果括号不存在,那么 blah-blah 将成为 else 的一部分,如果 selectchk 成功则不会执行。

选择点也发生了一些有趣的事情。如果 Goal1 成功,Prolog 将调用 Goal2,等等,但不会回溯到 Goal1 的更多解决方案(如果存在)。举例说明:

a(1).
a(2).

test :-
    (  a(X)
    -> write(X), nl
    ;  write('no a'), nl
    ).

| ?- test.
1

yes

上面Prolog没有回去找X = 2 for a(X)。另一方面,回溯可能发生在 else:

foo :-
    (  false
    -> write('not gonna happen'), nl
    ;  a(X),
       write(X), nl
    ).

| ?- foo.
1

true ? ;
2

yes

Goal2:

也会发生回溯
foo :-
    (   true
    ->  a(X), write(X), nl
    ;   write('else'), nl
    ).

| ?- foo.
1

true ? ;
2

yes

但是正如您所看到的,一旦选择了 Goal2 路径,当 Goal2 的解决方案用尽时,就不会回溯到 else (Goal3)。 A 可能是预期的,Goal2Goal3 的执行是互斥的,具体取决于 Goal1.

的结果