Open In App

Lists in Prolog

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

A list is a collection of items, not necessarily homogeneous. In Prolog, lists are inbuilt data structures. Lists can be used to represent sets, stacks, queues, linked lists, and several complex data structures such as trees, graphs, etc.

Basic Notation and Properties of Lists:

  • A list in Prolog is an ordered collection of items denoted as [i1, i2, …, in].
  • Unlike arrays in other programming languages where we can directly access any element of the array, prolog lists allow direct access of the first element only which is denoted as Head. Therefore we can write a prolog list as : [Head | Rest], where Rest is the rest of the list excluding the first element Head.
  • Prolog lists allow nonhomogeneous data types of list items.
  • Nested lists of arbitrary depths are also allowed in prolog.

Some example lists are shown below :

[]            % empty list
[a]            % singleton list
[hello, world]        % 2 element list
[[1,2,3,4], p, this] % 3 element list 
[[[1, 2], [3, 4]], [[a, b], [x, y]]].    
% nested list (3 level nesting)    

Pipe (|) operator:

In prolog, lists have got only one operator, called pipe, denoted by |. This operator is used to append an element at the beginning of a list. The syntax of the pipe operator is as follows :

[a | L]
Here L is a list and a is a single element.

For example:

If, L = [b,c,d]
Then, [a | L] will result in [a,b,c,d]

Cut(!) operator:

In Prolog, the Cut operator, denoted by ! is a goal that always succeeds but cannot be backtracked. For example, consider the following program to find the max element between 2 numbers:

max_element(X, Y, X) :- X > Y.    % If X > Y, then X is the max element
max_element(X, Y, Y) :- X =< Y.    % If X <= Y, then Y is the max element

Here if we provide the goal as:

?- max_element(5, 2, Ans).

This goal matches with the first rule because 5 > 2 and the program returns Ans = 5. But the program does not stop there. It goes on checking the next rule as well. But since both the rules are complementary to each other, we can modify this program using cut as follows :

% If X > Y, max element is X and do not 
check the next rule for the current goal
max_element(X, Y, X) :- X > Y, !. 

% If the first rule fails, then Y will
definitely be the max element.

% Therefore, no need to put conditionals anymore
max_element(X, Y, Y).    

Operations on Prolog Lists:

1. Find the length of a list L

% length of empty list is 0 (base case)
list_length([], 0).
list_length([_ | L], N) :-
    list_length(L, N1),
    N is N1 + 1.     
    % If length of L is N1, then length of [_ | L] will be N1 + 1

Query:

?- list_length([a, b, c, d], N).
N = 4.

2. Determine whether an element X belongs to a list L

 is_member(X, [X | _]) :- !.    % If the head of the list is X
 
 is_member(X, [_ | Rest]) :-    % else recur for the rest of the list
     is_member(X, Rest).

Query:

?- is_member(c, [a, b, c, d]).
true.
?- is_member(f, [a, b, c, d]).
false.

3. Append a list L2 at the end of another list L1 and put the resultant list in L3

% If L1 is empty, resultant list will be equal to L2 (base case)
append_list([], L2, L2).    

append_list([X | L1], L2, [X | L3]) :-
    append_list(L1, L2, L3).

Query:

?- append_list([a, b, c], [p, q], Ans).

Ans = [a, b, c, p, q].

4. Insert an element X at the end of a list L

insert_end(L, X, NewL) :-
append_list(L, [X], NewL).

Query:

?- insert_end([1, 2, 3], 7, Ans).
Ans = [1, 2, 3, 7].

5. Delete the first occurrence of an element X from a list L

% Deletion of any element from empty list will produce empty list(base case)
delete_element(_, [], []).    

delete_element(X, [X | L], L) :- !.

delete_element(X, [Y | L], [Y | L1]) :-
    delete_element(X, L, L1).

Query:

?- delete_element(b, [a, b, c, b, d], Ans).
Ans = [a, c, b, d].

Last Updated : 21 Feb, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads