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 可能是预期的,Goal2
与 Goal3
的执行是互斥的,具体取决于 Goal1
.
的结果
我注意到在某些 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 executesGoal1
and, in case of success, removes all choice-points created byGoal1
and executesGoal2
. This control construct acts like an if-then (Goal1
is the test part andGoal2
the then part). Note that ifGoal1
fails->/2
fails also.->/2
is often combined with;/2
to define an if-then-else as follows:Goal1 -> Goal2 ; Goal3
. Note thatGoal1 -> Goal2
is the first argument of the(;)/2
andGoal3
(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 executesGoal1
. In case of success, all choice-points created byGoal1
together with the choice-point for the else-part are removed andGoal2
is executed. IfGoal1
fails thenGoal3
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 可能是预期的,Goal2
与 Goal3
的执行是互斥的,具体取决于 Goal1
.