Prolog Quick Reference

This is a summary of the subset of Prolog that we have learned so far in Non-Procedural Programming.

comments

A single-line comment begins with % and extends to the end of the line. Comments delimited with /* and */ can extend over multiple lines.

terms

All data in Prolog is represented as terms. A term is any of these:

predicates

A predicate in Prolog has a name and zero or more arguments. A predicate is defined by a series of clauses, which must appear together in a source file.

A clause is either a fact or a rule.

A fact contains a predicate name plus zero or more arguments:

color(blue).

is_power_of_two(1).

parent(eliska, karel).

contains(X, box(X)).

A rule consists of a head and a body, separated by the symbol :- (pronounced "if"):

path(X, Y) :- edge(X, Z), path(Z, Y).

different(P, Q, R) :- dif(P, Q), dif(Q, R), dif(P, R).

The head looks like a fact. The body contains one or more goals, which look like facts. Goals can be chained together using the operators

queries

A query in Prolog looks like the body of a rule: it contains one or more goals, possibly chained together with ',' and/or ';' .

is_prime(71).

parent(X, eliska).

color(C), color(D), dif(C, D), similar(C, D).

built-in predicates

mode indicators

Arguments in predicates listed below include the following mode indicators. (These are not part of the Prolog language; they are merely a documentation convention.)

comparing terms

?Term1 = ?Term2

True if two terms can be unified.

dif(?Term1, ?Term2)

True if two terms cannot be unified. This is a constraint that belongs to the pure language.

+Term1 @< +Term2
+Term1 @> +Term2

Tests whether Term1 precedes or follows Term2 in the standard order of terms:

testing the type of terms

atom(+Term)

True if Term is bound to an atom.

atomic(+Term)

True if Term is bound (i.e. not a variable) and is not compound.

compound(+Term)

True if Term is bound to a compound term, i.e. a structure.

float(+Term)

True if Term is bound to a floating-point number.

integer(+Term)

True if Term is bound to an integer.

number(+Term)

True if Term is bound to an integer or floating-point number.

control predicates

fail
false

Always fail. The two forms are equivalent.

true

Always succeed.

!

Cut. Discard all choice points created since entering the predicate in which the cut appears.

\+ +Goal

True if Goal cannot be proven.

(P -> Q ; R)

If P then Q else R. This predicate behaves as if defined by

(P -> Q ; R) :- P, !, Q.
(P -> Q ; R) :- R.

arithmetic expressions

An arithmetic expression is a number, a variable, or a compound expression built using these operators:

arithmetic predicates

between(+Low, +High, ?Value)

True if all arguments are integers and LowValueHigh. This predicate can generate all values between Low and High.

?Number is +Expr

True if Expr evaluates to Number.

+Expr1 =:= +Expr2
+Expr1 =\= +Expr2
+Expr1 > +Expr2
+Expr1 >= +Expr2
+Expr1 < +Expr2
+Expr1 =< +Expr2

Evaluate two arithmetic expressions and compare the results. =:= means "equals". =\= means "does not equal".

integer constraints

To use these constraints, you must import the clpfd module:

?- use_module(library(clpfd)).

I recommend putting the preceding command into the file ~/.swiplrc so that it will automatically run at the beginning of each session.

?Expr1 #= ?Expr2
?Expr1
#\= ?Expr2
?Expr1
#> ?Expr2
?Expr1
#>= ?Expr2
?Expr1
#< ?Expr2
?Expr1
#=< ?Expr2

Compare arithmetic expressions. #= means "equals". #\= means "does not equal". Unlike the predicates in the previous section, these are true relations and will work in all directions.

?Var in +Domain

Var is an element of Domain. A domain can be any of these:

Integer : A single integer

Lower .. Upper : A range of integers. In a range, inf and sup represent negative and positive infinity.

Domain1 \/ Domain2 : The union of two domains.

?Vars ins +Domain

All variables in the list Vars are elements of Domain.

all_distinct(+Vars)

All of the given variables are distinct.

indomain(+Var)

Assign a value to the given variable.

label(+Vars)

Assign a value to each variable in Vars.

list operations

append(?List1, ?List2, ?List1AndList2)

List1AndList2 is the concatenation of List1 and List2.

append(+ListOfLists, ?List)

Concatenate a list of lists. (This is a single-level flatten operation.)

length(?List, ?Int)

True if Int is the number of elements in List.

max_list(?List, -Max)

True if Max is the largest number in List. Fails if List is empty.

member(?Elem, ?List)

True if Elem is a member of List.

min_list(?List, -Max)

True if Max is the smallest number in List. Fails if List is empty.

msort(+List, -Sorted)

Sort a list by the standard order of terms, keeping duplicate elements.

nextto(?X, ?Y, ?List)

True if Y directly follows X in List.

nth1(?Index, ?List, ?Elem)

True if the Index'th element of List is Elem. The first element has index 1. For example, nth1(3, L, E) will unify E with the third element in list L.

numlist(+Low, +High, -List)

True if List is the list [Low, Low + 1, …, High]. Fails if High < Low.

permutation(?Xs, ?Ys)

True if Xs is a permutation of Ys.

reverse(?List1, ?List2)

True if List1 contains the same elements as List2 in reverse order.

same_length(?List1, ?List2)

True if List1 and List2 have the same number of elements.

select(?Elem, ?List1, ?List2)

True when List1, with Elem removed, results in List2.

select(?X, ?XList, ?Y, ?YList)

True if XList and YList are identical except for a single element, which is X in XList and is Y in YList.

sort(+List, -Sorted)

Sort a list by the standard order of terms, removing duplicate elements.

sort(+Key, +Order, +List, -Sorted)

Sort a list. If Key is 0, each list element itself is the comparison key. If Key is a positive integer N, then each element must be a structure (i.e. compound term); the Nth element of the structure is used as the comparison key.

Order may be one of the following:

subset(+SubSet, +Set)

True if all elements of SubSet are present in Set.

higher-order predicates

call(+Goal, +ExtraArg1, ...)

Invoke Goal as a goal, appending extra arguments ExtraArg1, ExtraArg2, … to the argument list.

foldl(+Goal, ?List, ?V0, ?V)
foldl(+Goal, ?List, ?List1, ?V0, ?V)

Fold List from the left, applying Goal to each element and an accumulator argument that is initially V0. For example, foldl(G, [a, b, c], V0, V) will apply

G(a, V0, V1)
G(b, V1, V2)
G(c, V2, V)

The versions with extra arguments are similar, but operate on pairs or triples of elements from multiple lists.

maplist(+Goal, ?List)
maplist(+Goal, ?List1, ?List2)
maplist(+Goal, ?List1, ?List2, ?List3)

True if Goal can successfully be applied to all elements of List. The versions with extra arguments are similar, but operate on pairs or triples of elements from multiple lists.

output

display(+Term)

Write a term in expanded form, displaying operators as ordinary functors. For example, display(2 + 3 + 4) writes "+(+(2,3),4)".

nl

Write a newline to standard output.

write(+Term)

Write Term to standard output.

writeln(+Term)

Write Term to standard output, followed by a newline.

debugging/tracing

nodebug

Stop debugging.

trace(+Pred)
trace
(+Pred, +Ports)

Put a trace point on the given predicate. Ports is a single tracing port or a list of ports; the available ports are (call, redo, exit, fail). If you omit the port list, all ports are traced.

See more hints on debugging/tracing in the lecture notes.