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