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 forGoal1 -> 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, ifGoal1
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
, theGoal1 -> Goal2
expression is the first argument of;/2
. Here is what happens in various cases:Because of the precedence, the if-then-else constructs are often parenthesized, as in the example:
If the parentheses were not there, then
blah-blah
would become part of the else and not executed ifselectchk
succeeds.There is also something interesting that happens to the choice points. If
Goal1
succeeds, Prolog will callGoal2
, etc, but won't backtrack to more solutions, if they exist, forGoal1
. To illustrate:In the above, Prolog didn't go back to find
X = 2
fora(X)
. On the other hand, backtracking can occur for theelse
:Backtracking also occurs for
Goal2
:But as you can see, once the
Goal2
path is chosen, there's no backtracking to theelse
(Goal3
) when solutions forGoal2
are exhausted. A might be expected, executions ofGoal2
versusGoal3
are mutually exclusive depending upon the result ofGoal1
.It is the if/then/else in Prolog, for example