Is there a way to do an if in prolog, e.g. if a variable is 0, then to do some actions (write text to the terminal). An else isn\'t even needed, but I can\'t find any docume
Prolog program actually is big condition for "if" with "then" which prints "Goal is reached" and "else" which prints "No sloutions was found". A, Bmeans "A is true and B is true", most of prolog systems will not try to satisfy "B" if "A" is not reachable (i.e. X=3, write('X is 3'),nl will print 'X is 3' when X=3, and will do nothing if X=2).
First, let's recall some classical first order logic:
"If P then Q else R" is equivalent to "(P and Q) or (non_P and R)".
Let's take the following concrete example:
If
Xis a member of list[1,2]thenXequals2elseXequals4.
We can match above pattern ("If P then Q else R") if ...
P is list_member([1,2],X),non_P is non_member([1,2],X),Q is X=2, andR is X=4.To express list (non-)membership in a pure way, we define:
list_memberd([E|Es],X) :-
( E = X
; dif(E,X),
list_memberd(Es,X)
).
non_member(Es,X) :-
maplist(dif(X),Es).
Let's check out different ways of expressing "if-then-else" in Prolog!
(P,Q ; non_P,R)
?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4). X = 2 ; X = 4. ?- X=2, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2. X = 2 ; false. ?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2. X = 2 ; false. ?- X=4, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4. X = 4. ?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4. X = 4.
Correctness score 5/5. Efficiency score 3/5.
(P -> Q ; R)
?- (list_memberd([1,2],X) -> X=2 ; X=4). false. % WRONG ?- X=2, (list_memberd([1,2],X) -> X=2 ; X=4), X=2. X = 2. ?- (list_memberd([1,2],X) -> X=2 ; X=4), X=2. false. % WRONG ?- X=4, (list_memberd([1,2],X) -> X=2 ; X=4), X=4. X = 4. ?- (list_memberd([1,2],X) -> X=2 ; X=4), X=4. false. % WRONG
Correctness score 2/5. Efficiency score 2/5.
(P *-> Q ; R)
?- (list_memberd([1,2],X) *-> X=2 ; X=4). X = 2 ; false. % WRONG ?- X=2, (list_memberd([1,2],X) *-> X=2 ; X=4), X=2. X = 2 ; false. ?- (list_memberd([1,2],X) *-> X=2 ; X=4), X=2. X = 2 ; false. ?- X=4, (list_memberd([1,2],X) *-> X=2 ; X=4), X=4. X = 4. ?- (list_memberd([1,2],X) *-> X=2 ; X=4), X=4. false. % WRONG
Correctness score 3/5. Efficiency score 1/5.
(Preliminary) summary:
(P,Q ; non_P,R) is correct, but needs a discrete implementation of non_P.
(P -> Q ; R) loses declarative semantics when instantiation is insufficient.
(P *-> Q ; R) is "less" incomplete than (P -> Q ; R), but still has similar woes.
Luckily for us, there are alternatives:
Enter the logically monotone control construct if_/3!
We can use if_/3 together with the reified list-membership predicate memberd_t/3 like so:
?- if_(memberd_t(X,[1,2]), X=2, X=4). X = 2 ; X = 4. ?- X=2, if_(memberd_t(X,[1,2]), X=2, X=4), X=2. X = 2. ?- if_(memberd_t(X,[1,2]), X=2, X=4), X=2. X = 2 ; false. ?- X=4, if_(memberd_t(X,[1,2]), X=2, X=4), X=4. X = 4. ?- if_(memberd_t(X,[1,2]), X=2, X=4), X=4. X = 4.
Correctness score 5/5. Efficiency score 4/5.
Prolog predicates 'unify' -
So, in an imperative langauge I'd write
function bazoo(integer foo)
{
if(foo == 5)
doSomething();
else
doSomeOtherThing();
}
In Prolog I'd write
bazoo(5) :- doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.
which, when you understand both styles, is actually a lot clearer.
"I'm bazoo for the special case when foo is 5"
"I'm bazoo for the normal case when foo isn't 5"
( A == B ->
writeln("ok")
;
writeln("nok")
),
The else part is required
A standard prolog predicate will do this.
isfive(5).
will evaluate to true if you call it with 5 and fail(return false) if you run it with anything else. For not equal you use \=
isNotEqual(A,B):- A\=B.
Technically it is does not unify, but it is similar to not equal.
Learn Prolog Now is a good website for learning prolog.
Edit: To add another example.
isEqual(A,A).
The best thing to do is to use the so-called cuts, which has the symbol !.
if_then_else(Condition, Action1, Action2) :- Condition, !, Action1.
if_then_else(Condition, Action1, Action2) :- Action2.
The above is the basic structure of a condition function.
To exemplify, here's the max function:
max(X,Y,X):-X>Y,!.
max(X,Y,Y):-Y=<X.
I suggest reading more documentation on cuts, but in general they are like breakpoints.
Ex.: In case the first max function returns a true value, the second function is not verified.
PS: I'm fairly new to Prolog, but this is what I've found out.