Prolog Cheat Sheet
Core Prolog concepts covering facts, rules, queries, list operations, and built-in predicates for logic programming.
Facts & Rules
Defining facts and a derived rule.
% Factsparent(tom, bob).parent(bob, ann).parent(bob, pat).% Rule: X is a grandparent of Z if X is a parent of Y% and Y is a parent of Zgrandparent(X, Z) :- parent(X, Y), parent(Y, Z).% Rule with a not-equal checksibling(X, Y) :- parent(P, X), parent(P, Y), X \= Y.
Queries
Asking questions against the knowledge base.
?- parent(tom, bob).true.?- grandparent(tom, X).X = ann ;X = pat.?- parent(X, Y), parent(Y, ann).X = tom,Y = bob.
List Operations
Working with Prolog lists.
- [H|T]- Head/tail list decomposition pattern
- length(List, N)- N unifies with the length of List
- append(L1, L2, L3)- L3 is L1 concatenated with L2
- member(X, List)- True if X occurs in List
- reverse(L1, L2)- L2 is L1 reversed
- nth0(Index, List, Elem)- Elem is the element at the 0-based Index
Built-in Predicates
Commonly used core predicates.
- =- Unification of two terms
- \=- True if two terms do not unify
- is/2- Arithmetic evaluation, e.g. X is 2 + 3
- !- Cut; commits to choices made so far and prunes backtracking
- findall(Template, Goal, List)- Collects all solutions of Goal into List
- write/1, nl/0- Print a term / print a newline
Recursion Example
A classic recursive factorial predicate.
factorial(0, 1).factorial(N, F) :- N > 0, N1 is N - 1, factorial(N1, F1), F is N * F1.?- factorial(5, X).X = 120.
Cut & Negation
Control backtracking with cut and negation-as-failure.
% cut (!) commits to choices made so farmax(X, Y, X) :- X >= Y, !.max(_, Y, Y).% negation as failurenot_member(X, L) :- \+ member(X, L).% if-then-elseclassify(N, Sign) :- ( N > 0 -> Sign = positive ; N < 0 -> Sign = negative ; Sign = zero ).
Findall & Aggregation
Collect all solutions into lists.
parent(tom, bob).parent(tom, liz).% collect every solution?- findall(C, parent(tom, C), Kids).% Kids = [bob, liz].% bagof/setof group by free vars; setof sorts + dedups?- setof(C, parent(tom, C), Kids).% aggregate_all for counts/sums?- aggregate_all(count, parent(tom, _), N).% N = 2.
Definite Clause Grammars
Parsing with DCG rules and phrase/2.
digits([D|T]) --> digit(D), digits(T).digits([D]) --> digit(D).digit(D) --> [D], { code_type(D, digit) }.% greeting grammargreeting --> [hello], name.name --> [world].?- phrase(greeting, [hello, world]).% true.
Arithmetic & Comparison
Evaluating and comparing numeric terms.
- X is 2 + 3 * 4- evaluate an arithmetic expression, bind result to X
- X =:= Y- arithmetic equality (evaluates both sides)
- X == Y- term equality without evaluation or unification
- X \= Y- true if X and Y cannot unify
- between(Low, High, X)- generate/test integers in an inclusive range
- succ_or_zero / succ(X, Y)- Y is X + 1, usable in both directions
Dynamic Database
Modifying the clause database at runtime.
- :- dynamic(fact/1).- declare a predicate as modifiable at runtime
- assertz(fact(a))- add a clause at the end of the database
- asserta(fact(a))- add a clause at the beginning
- retract(fact(a))- remove the first matching clause
- retractall(fact(_))- remove all matching clauses
- forall(Cond, Action)- succeed if Action holds for every Cond solution
Use the cut (!) sparingly and only after you understand its effect on backtracking — an overused cut silently discards valid solutions and makes predicates hard to reuse.