我注意到了运营商的使用 - >在一些Prolog程序中,但它的含义我不知道。 这是一个使用它的例子:
swish_add_user(User, Passwd, Fields) :-
phrase("$1$", 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存储库中的swish文件,顺便提一下Prolog IDE online的优秀实现。
答案 0 :(得分:2)
这是Prolog中的if / then / else,例如
( X mod 2 =:= 0
-> writeln(even)
; writeln(odd)).
答案 1 :(得分:1)
Joel76的答案给出了->/2
控件构造最常见的用法,它在ISO Prolog中定义。 GNU Prolog manual中Goal1 -> Goal2
的说明是:
Goal1 -> Goal2
首先执行Goal1
,如果成功,则删除由Goal1
创建的所有选择点并执行Goal2
。此控件构造的行为类似于if-then (Goal1
是测试部分,Goal2
则是当时的部分。请注意,如果Goal1
失败,->/2
也会失败。->/2
通常与;/2
结合使用,以定义 if-then-else ,如下所示:Goal1 -> Goal2 ; Goal3
。请注意,Goal1 -> Goal2
是(;)/2
的第一个参数,Goal3
(else部分)是第二个参数。这样的if-then-else控件构造首先为else-part创建一个选择点(直观地与;/2
相关联),然后执行Goal1
。如果成功,将删除Goal1
创建的所有选择点以及else部分的选择点,并执行Goal2
。如果Goal1
失败,则会执行Goal3
。
它不像数学逻辑蕴涵(如其符号形式可能暗示的那样),因为在这样的蕴涵条款中,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
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
路径,当else
的解决方案为Goal3
时,Goal2
(Goal2
)无法回溯累。可以预期,Goal3
与Goal1
的执行是互斥的,具体取决于{{1}}的结果。