Control
Prefer separate clauses over ; for readability.
12.1 Conjunction, disjunction
Prefer separate clauses over ; for readability.
a :- b, c. % b AND c
a :- b ; c. % b OR c
a :- (b, c ; d). % (b AND c) OR d12.2 If-then-else
(Cond -> Then ; Else) commits to the first solution of Cond. Without ; Else, the construct fails if Cond fails.
*-> (soft-cut, SWI): (Cond *-> Then ; Else) backtracks into all solutions of Cond.
if_/3 from library(reif) gives a pure, monotonic if-then-else (§27).
classify(N, Type) :-
( N < 0 -> Type = negative
; N =:= 0 -> Type = zero
; Type = positive
).12.3 Negation as failure: \+
\+ G succeeds if G cannot be proven. It is not logical negation:
Rule: only call \+ on sufficiently instantiated goals (ground is safest). Use dif/2 for sound disequality.
not_member(X, L) :- \+ member(X, L).
bachelor(X) :- male(X), \+ married(X).?- \+ X = a. % false — because X = a is provable
?- X = b, \+ X = a. % true12.4 true, fail, false, repeat
true. % always succeeds
fail. false. % always fail
repeat. % succeeds infinitely on backtracking
print_all :- member(X, [1, 2, 3]), writeln(X), fail. % failure-driven loop
print_all.
read_loop :- repeat, read(T), ( T == end_of_file -> ! ; process(T), fail ).12.5 call, once, ignore, forall
call(G) % call a goal stored in a variable
call(format, "~w~n", [x]) % call/N adds arguments
once(G) % first solution only (= (G -> true))
ignore(G) % call G, succeed anyway
forall(Cond, Action) % for every solution of Cond, Action succeeds (= \+ (Cond, \+ Action))?- forall(member(X, [1, 2, 3]), X > 0). % true
?- forall(member(X, [a, b]), format("~w~n", [X])).