Membership and Search: member/2
member(X, List) succeeds if X unifies with some element of List. Used with X unbound, it enumerates every element on backtracking; used with List unbound, it can even generate lists that contain X. Its own definition is a small recursive predicate in its own right: member(X,[X|_]). and member(X,[_|T]) :- member(X,T)., making it a good first example of how library predicates are themselves built from the [H|T] recursion pattern.
Cricket analogy: member/2 is like checking whether a player's name appears anywhere in a squad list: asking member(kohli, SquadList) succeeds if Kohli is named anywhere from opener to number eleven, not just at the top.
Building and Combining: append/3 and reverse/2
append(L1, L2, L3) is a relation, not just a function: with L1 and L2 known it concatenates them into L3, but with L1 and L2 left unbound and L3 given, it enumerates every possible way to split L3 into a prefix and a suffix via backtracking, a classic demonstration of Prolog's relational, multi-directional nature. reverse/2 flips a list end to end and is commonly implemented internally with an accumulator for efficiency rather than by repeatedly appending to the front.
Cricket analogy: append/3 concatenating two lists is like joining the first innings batting order with the second innings order into one full match scorecard, and run backwards it can split a combined scorecard back into its two separate innings.
?- append([1,2],[3,4],L).
L = [1, 2, 3, 4].
?- append(X, Y, [1,2,3]).
X = [], Y = [1, 2, 3] ;
X = [1], Y = [2, 3] ;
X = [1, 2], Y = [3] ;
X = [1, 2, 3], Y = [] ;
false.
?- reverse([1,2,3], R).
R = [3, 2, 1].
Indexing, Length, and Sorting
length(List, N) computes a list's length when List is known, and, given N with List unbound, generates a fresh list of N unbound variables. nth0/3 and nth1/3 access an element by a zero- or one-based index (and can also be used in reverse to find the index of a given element). sort/2 arranges elements into standard order of terms and removes duplicates, while msort/2 sorts without removing duplicates, and predsort/3 allows sorting by a custom comparison.
Cricket analogy: length/2 is like asking how many players are in a squad list, while nth0/3 is like asking who batted at zero-indexed slot 3, nth0(3, BattingOrder, Player), pulling a specific player by position.
sort/2 both sorts and removes duplicates using standard order of terms; if you need a sorted list that keeps duplicates, use msort/2 instead. For sorting by a specific key, such as a field inside a compound term, use predsort/3 with a custom comparison predicate, or sort/4 with a key index and order specifier.
Mapping and Aggregating: maplist/2-5 and findall/3
maplist(Goal, List) applies Goal to every element, and maplist(Goal, L1, L2) applies a binary relation elementwise across two lists in lockstep, for example maplist([X,Y]>>(Y is X*X), Ins, Outs) using a library(yall) lambda. findall(Template, Goal, List) collects every solution of Goal into a list, making it the standard bridge from Prolog's nondeterministic backtracking search to a concrete, deterministic list result that later code can process normally.
Cricket analogy: maplist/3 is like applying add 4 to every ball as a boundary-adjustment rule across an entire over's delivery list at once, rather than adjusting each ball's score by hand one at a time.
?- maplist([X,Y]>>(Y is X*X), [1,2,3], Squares).
Squares = [1, 4, 9].
?- findall(X, member(X, [1,2,3,4]), Evens0),
include([N]>>(N mod 2 =:= 0), Evens0, Evens).
Evens = [2, 4].
findall/3 always succeeds and returns [] if the goal has no solutions; it never fails the way a plain goal call would. If you need to know whether at least one solution exists, check the resulting list rather than relying on findall/3 itself to fail.
- member(X, List) checks or enumerates elements of List, and can backtrack through every match.
- append(L1, L2, L3) is a true relation: it concatenates when L1/L2 are known and splits L3 into every possible prefix/suffix pair when they're not.
- length(List, N) computes a list's length or, given N, generates a fresh list of N unbound variables.
- nth0/3 and nth1/3 access elements by zero- or one-based index, and can also find an element's index.
- sort/2 sorts and removes duplicates; msort/2 sorts while keeping duplicates.
- maplist/2-5 applies a goal across one or more lists element by element.
- findall/3 collects every solution of a goal into a list, always succeeding even with zero solutions (returning []).
Practice what you learned
1. What does ?- append(X, Y, [1,2,3]). produce on backtracking?
2. What is the difference between sort/2 and msort/2?
3. What does findall/3 return when its goal has zero solutions?
4. What does maplist([X,Y]>>(Y is X*X), [1,2,3], Squares) compute?
5. Which predicate would you use to check if 'kohli' appears anywhere in a list, backtracking through all matches?
Was this page helpful?
You May Also Like
Lists in Prolog
Learn how Prolog represents lists as recursive [Head|Tail] structures and how unification lets you construct, deconstruct, and pattern-match them.
Recursive Predicates
Understand how Prolog predicates call themselves to process structures like lists and numbers, and how base cases and recursive cases work together.
Arithmetic in Prolog
Learn how Prolog evaluates arithmetic expressions with is/2, the difference between unification and arithmetic comparison, and common numeric predicates.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics