本文介绍了Prolog运算符'->'是什么意思的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到在一些 Prolog 程序中使用了操作符 ->,但我不知道它的含义.这是它的使用示例:

swish_add_user(用户、密码、字段):-短语("$1$", E, _), % 使用 Unix MD5 哈希地穴(密码,E),string_codes(哈希,E),条目 = passwd(用户,哈希,字段),绝对文件名(swish(密码),文件,[访问(写入)]),(存在_文件(文件)->http_read_passwd_file(文件,数据);数据 = []),( selectchk(passwd(User, _, _), Data, Entry, NewData)->真的;附加(数据,[条目],新数据)),http_write_passwd_file(文件,新数据).

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

PS:代码段取自authenticate.plswish 存储库中的 文件,Prolog IDE 在线.

解决方案

Joel76 的回答给出了 ->/2 控件构造的最常见用法,该构造定义在ISO 序言.Goal1 -> 的描述GNU Prolog 手册 中的目标 2 是:

Goal1 ->Goal2 首先执行 Goal1,如果成功,则删除由 Goal1 创建的所有选择点并执行 Goal2.这个控制结构就像一个 if-then(Goal1 是测试部分,Goal2 是 then 部分).请注意,如果 Goal1 失败 ->/2 也会失败.->/2 经常与 ;/2 结合来定义一个 if-then-else 如下: 目标1 ->目标2;目标 3.请注意,Goal1 ->Goal2(;)/2 的第一个参数,Goal3(else 部分)是第二个参数.这样的 if-then-else 控制结构首先为 else 部分(直观地与 ;/2 相关联)创建一个选择点,然后执行 Goal1.在成功的情况下,由 Goal1 创建的所有选择点以及 else-part 的选择点都将被删除并执行 Goal2.如果 Goal1 失败,则执行 Goal3.

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

在这种情况下,注意运算符的优先级很重要.在 Prolog 中,优先顺序是 ,,然后是 ->,然后是 ;.因此,如描述中所述,在 if-then-else 构造中,Goal1 ->;目标2;Goal3Goal1 ->Goal2 表达式是 ;/2 的第一个参数.以下是各种情况下会发生的情况:

Goal1 ->目标2;Goal3 if-then-else 注释----- ----- ----- ------------ -----成功 成功 NE* 成功 目标 1 选择点已移除目标 2 选择点仍然存在(如果存在)成功 失败 NE 失败 Goal1 选择点被移除失败 NE 成功 成功 Goal3 选择点仍然存在(如果存在)失败 NE 失败 失败*NE = 未执行

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

( selectchk(passwd(User, _, _), Data, Entry, NewData)->真的;附加(数据,[条目],新数据)),胡说八道

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

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

a(1).a2).测试 :-(一(X)->写(X),NL;写('没有'),NL).|?- 测试.1是的

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

foo :-(  错误的->write('不会发生'), nl;斧头),写(X),NL).|?- 富.1真的 ?;2是的

Goal2 也会发生回溯:

foo :-(   真的->a(X), 写(X), nl;写('其他'),NL).|?- 富.1真的 ?;2是的

但正如您所见,一旦选择了 Goal2 路径,当解决方案 else (Goal3)code>Goal2 已用尽.A 可能是预期的,Goal2Goal3 的执行是互斥的,具体取决于 Goal1 的结果.

I have noticed the use of the operator -> in some Prolog programs, but its meaning is unknown to me.This is an example of its use:

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).

What is its use in this clause? When should I use this operator and when not?

PS: The code segment is taken from the authenticate.pl file in the swish repository, an excellent implementation of a Prolog IDE online, by the way.

解决方案

Joel76's answer gives what is probably by far the most common usage of the ->/2 control construct, which is defined in ISO Prolog. The description given for Goal1 -> Goal2 in the GNU Prolog manual is:

It doesn't act like a mathematical logical implication (as its symbolic form might suggest) because, in such an implication clause, F -> T is true, whereas in Prolog, as mentioned above, if Goal1 fails, then the ->/2 expression fails.

It's important to note operator precedence in this case. In Prolog, the order of precedence is ,, then ->, then ;. Thus, as stated in the description, in an if-then-else construct, Goal1 -> Goal2 ; Goal3, the Goal1 -> Goal2 expression is the first argument of ;/2. Here is what happens in various cases:

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

Because of the precedence, the if-then-else constructs are often parenthesized, as in the example:

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

If the parentheses were not there, then blah-blah would become part of the else and not executed if selectchk succeeds.

There is also something interesting that happens to the choice points. If Goal1 succeeds, Prolog will call Goal2, etc, but won't backtrack to more solutions, if they exist, for Goal1. To illustrate:

a(1).
a(2).

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

| ?- test.
1

yes

In the above, Prolog didn't go back to find X = 2 for a(X). On the other hand, backtracking can occur for the else:

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

| ?- foo.
1

true ? ;
2

yes

Backtracking also occurs for Goal2:

foo :-
    (   true
    ->  a(X), write(X), nl
    ;   write('else'), nl
    ).

| ?- foo.
1

true ? ;
2

yes

But as you can see, once the Goal2 path is chosen, there's no backtracking to the else (Goal3) when solutions for Goal2 are exhausted. A might be expected, executions of Goal2 versus Goal3 are mutually exclusive depending upon the result of Goal1.

这篇关于Prolog运算符'->'是什么意思的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-22 01:33