In c language i have something like :
if(cond1)
{}
else if(cond2)
{}
else
{}
how is this possible in Prolog?
(cond1 ->
consequent1
; cond2 ->
consequent2
;
alternative
)
For the record, this is called a conditional.
if_then_else(Condition,Then,Else) :- Condition, !, Then.
if_then_else(Condition,Then,Else) :- Else.
For example:
max(X,Y,Max) :- if_then_else(X>Y,Max=X,Max=Y).
?- max(4,7,A).
A = 7
?- max(8,2,A).
A = 8
( If1 -> Then1
; If2 -> Then2
; ...
; otherwise
).
Note that if-then-else is only necessary if you cannot express the different conditions by pattern matching in different clauses. Everything that can be expressed by pattern matching should be expressed by pattern matching, as this typically leads to more general and also more efficient code.
The ->/2 is only needed if you want to impose a certain determinism. It acts like a local cut. But in case you want that your code keeps some non-determinism, it is not necessary to use ->/2.
Take the following imperative code:
boolean listOfBool(Object obj) {
if (obj instanceof ConsCell) {
if (((ConsCell)ob).head() instanceof Boolean) {
return listOfBool(((ConsCell)ob).tail());
} else {
return false;
}
} else if (obj == null) {
return true;
} else {
return false;
}
}
This can be coded in Prolog without ->/2 as follows:
% bool(+Bool)
% bool(-Bool)
bool(0).
bool(1).
% list_of_bool(+List)
% list_of_bool(-List)
list_of_bool(L) :-
(L = [X|Y], bool(X), list_of_bool(Y);
L = []).
The advantage is now that it can be used to check lists of booleans and to generate lists of booleans:
?- list_of_bool([0,1,0]).
Yes
?- list_of_bool([0,1,2]).
No
?- List=[_,_,_], list_of_bool(List).
List = [0, 0, 0] ;
List = [0, 0, 1] ;
List = [0, 1, 0] ;
List = [0, 1, 1] Etc..
Generally the disjunction (;)/2 can be distributed over multiple clauses. If this is combined with moving unification (=)/2 into the head, then some speed can be gained, since the predicate is then usually better amenable to indexing.
Here is how an alternative formulation of list_of_bool would look like by eliminating (;)/2 and (=)/2:
% list_of_bool2(+List)
% list_of_bool2(-List)
list_of_bool2([X|Y]) :- bool(X), list_of_bool2(Y).
list_of_bool2([]).
The above works exactly the same (it actually works better, since in the first query no choice point is left, what the (;)/2 usually will not detect without (->)/2):
?- list_of_bool2([0,1,0]).
Yes
?- list_of_bool2([0,1,2]).
No
?- List=[_,_,_], list_of_bool(List).
List = [0, 0, 0] ;
List = [0, 0, 1] ;
List = [0, 1, 0] ;
List = [0, 1, 1] Etc..
This is also how Prolog can be started. With rules only and no disjunction (;)/2 and no unification (=)/2. The later two are already there in the underlying Horn clauses.
Suppose you have a Prolog without (;)/2 and no (=)/2, and you don't need a cut transparent (;)/2, then you could define these constructs by yourself as follows:
X = X.
(A ; _) :- A.
(_ ; B) :- B.
Bye
Horn Clause
http://en.wikipedia.org/wiki/Horn_clause
It's not really easy to find, partly because (as noted by @mat) in Prolog there is an idiomatic alternative. You can find here SWI-Prolog documentation, albeit too much succintly, it's accurate. I cite a relevant point:
Please note that (If -> Then) acts as (If -> Then ; fail), making the construct fail if the condition fails. This unusual semantics is part of the ISO and all de-facto Prolog standards.