Sets in Programming Languages
Sets in Programming Languages
Sets
Sets are a simple yet surprisingly important mathematical notion. In fact, there was
a time when it was believed that all of mathematics could be formalised using the
Theory of Sets (Set Theory). Even though that dream was never realised (we shall
see later why), sets have proven themselves extraordinarily useful in computer
science.
We shall not worry too much about defining sets here; let’s assume that you already
have a good idea about sets. Instead we shall confine ourselves to reminding
ourselves about certain basic concepts and properties about sets, and later how to
specify and then implement them in an algorithmic framework. In the following,
we do not assume a universe from which elements are drawn — those restrictions
will come later.
The first notion we encounter about sets is that two sets are equal if they have the
same members. More precisely:
Definition 0.1 (Set Equality) Two sets S1, S2 are equal, written S1 = S2, exactly
when x ∈ S1 if and only if x ∈ S2 for any element x.
From the mathematical definition of set equality, one can show the following.
Exercise 0.0 (Reflexivity of set equality). Show that S = S, for any set S.
Exercise 0.1 (Symmetry of set equality). Show that if S1 = S2 then S2 = S1 for any
sets S1, S2.
Proof. Suppose S1 = S2. So (by 0.1), x ∈ S1 if and only if x ∈ S2.
Therefore, x ∈ S2 if and only if x ∈ S1 . That is, S2 = S1. (By definition 0.1) □
Exercise 0.2 (Transitivity of set equality). Show that if S1 = S2 and S2 = S3, then
S1 = S3 for any sets S1, S2, S3.
[We will soon find that the properties of reflexivity, symmetry and transitivity apply in many
contexts; together these properties characterise a notion of equivalence. When an
equivalence is maintained within every construction, it is called a congruence.]
This notion of “extensionality” implies that members of a set are not listed multiple
times (there is a different notion, called a multiset, where the number of times an
element appears does indeed matter) and that the order in which the members are
listed is also not important (as is the case in a sequence or list).
Page 1 of 11
0.3 Specifying sets and membership
Given the importance of sets in most mathematics, most programming languages
(oddly enough) do not directly support sets. Many languages support lists, where
multiple occurrences and the order of elements does matter.
We will represent sets using PROLOG lists, with the empty list, written [],
representing the empty set. (Note that this will only allow us to represent finite
sets.) The variable X denotes any element (note the capital/upper case letter; a
word beginning with a capital letter in PROLOG indicates it is a logical variable).
Note however that we are only specifying sets in terms of their abstract properties
related to membership, not implementing them, as we would in a Data Structures
course.
0.4 Subsets
The next important notion is that of subsets.
Definition 0.2 (Subset). A set S1 is a subset of another set S2, written S1 ⊆ S2, if
for any element x, whenever x ∈ S1 then x ∈ S2.
[Note that we will be liberal in considering a set to be a subset of itself. When we need to be
pedantic, and want to exclude this case, we will use the terminology “proper subset”]
Using just this specification of the notion of subset in terms of membership, one can
show the following:
Page 2 of 11
Exercise 0.3 (Reflexivity of subset). Show that S ⊆ S, for any set S.
Exercise 0.4 (Transitivity of subset). Show that if S1 ⊆ S2 and S2 ⊆ S3, then
S1 ⊆ S3 for any sets S1, S2, S3.
Exercise 0.5 (Antisymmetry of subset). Show that if S1 ⊆ S2 and S2 ⊆ S1, then
S1 = S2 for any sets S1, S2.
Proof: Let S1 ⊆ S2. Therefore if x ∈ S1 then x ∈ S2.
Now if also S2 ⊆ S1, then if x ∈ S2 then x ∈ S1. Thus x ∈ S1 if and only if x ∈ S2.
So S1 = S2.
[We will soon find that the properties of reflexivity and transitivity apply in many contexts;
together these properties characterise a notion of pre-ordering or a quasi-ordering. When
antisymmetry also applies, the notion is called a partial ordering. When a partial ordering is
preserved under every construction, it is called a pre-congruence.]
Definition 0.3 (Least and greatest elements in a partially ordered set). Let (S, ⊑ )
be any set with a partially ordering. An element x ∈ S is called a least element of S
if for any element y ∈ S, x ⊑ y. Dually, an element z ∈ S is called a greatest
element of S if for any element y ∈ S, y ⊑ z.
[Note that in a partially ordered set, least and greatest elements are unique (due to
antisymmetry). In a quasi-ordered set, however, we may have multiple minimal or maximal
elements.]
/* equal sets */
eqset(L1, L2) :- subset(L1,L2), subset(L2,L1).
Antisymmetry allows us to define a set equality predicate using subset(L1,L2).
The next interesting concept is set theory is that of intersection of two sets.
Definition 0.5 (Intersection) The intersection of two sets S1, S2, written S1 ∩ S2, is
defined as the greatest set S less than S1, S2 under the subset ordering such that
x ∈ S if (x ∈ S1 and x ∈ S2). In “set builder notation”,
S1 ∩ S2 = {x | x ∈ S1 ∧ x ∈ S2}.
/* Intersection */
mem(X,inter(S1,S2)) :- mem(X,S1),mem(X,S2).
We can represent intersection as a construction, denoted inter(S1,S2), where
there is a single clause that takes a conjunction of the membership checks.
From the mathematical specifications of empty set, union and intersection, prove
the following (from first principles).
Union and Intersection exhibit a nice duality — see the relationship between the
statements in Exercises 0.10-1.12 with those in 0.14-0.16; 0.18-0.19 with 0.20-0.21;
and 0.22 with 0.23.
In fact, union and intersection exhibit (nice) dual distributive properties as well:
Programming Activity 0.0: Design tests for checking that the programs written
above indeed behave the way they are expect to. You may wish to check that
membership behaves the way it should on empty and non-empty sets, where a
particular element is and is not a member. You should check that membership
works irrespective of order of elements in a list representation of a set, and
irrespective of whether duplicates are present in the list representation or not.
For each of the exercises, you should design concrete tests and check that
membership (and non-membership) behave as indicated by the property.
The notion of a universal set allows us to state the identity for intersection, dual to
Exercise 0.13:
Exercise 0.24 (Identity of intersection): Show that S ∩ = S = ∩ S.
Page 5 of 11
𝒰
𝒰
𝒰
𝒰
as well as the annihilator for union, dual to Exercise 0.17
Exercise 0.25 (Annihilation for union): Show that S ∪ = = ∪ S.
Further, once we have a complementation operation, we can complete the story for
the boolean algebraic laws, by presenting the so-called De Morgan Laws:
Exercise 0.26 (Complement of union): Show that S1 ∪ S2 = S1 ∩ S2.
Exercise 0.27 (Complement of intersection): Show that S1 ∩ S2 = S1 ∪ S2.
Definition 0.8 (Symmetric Difference) The symmetric difference of two sets S1, S2,
written S1 ⊖ S2, is defined as the set S such that x ∈ S if ((x ∈ S1 and x ∉ S2) or
(x ∈ S2 and x ∉ S1)).
Exercise 0.32: Show that S1 ⊖ S2 = (S1 − S2) ∪ (S2 − S1).
0.8 Powerset.
Definition 0.9 (Powerset of S) The powerset of a given set S, written (S ) or
more punnily as 2S , is defined as the set of all subsets of S. In “set builder notation”,
(S ) = {S′| S′ ⊆ S}.
Proposition 0.0: The powerset (S ) of a given set S forms a partially ordered set
under the subset ordering. We will write this as ( (S ), ⊆ ).
Exercise 0.33: Prove Proposition 0.0.
Notation: The powerset of the empty set 0 is a singleton set with a single element,
namely the empty set. That is 20 = {0}. So it makes sense to call this set 1,
and we can punnily write the equation 20 = 1.
Since the empty set is a subset of any set S, it can be considered the least subset of
any given set S, and hence the least element in ( (S ), ⊆ ) Likewise, since all
subsets of set S are contained in it, S is the greatest element in ( (S ), ⊆ ).
/* Powerset */
mem(X, power(S)) :- subset(X,S).
Every subset of S is a member of the powerset (S ).
What is the Cartesian product of a set S with the empty set 0? You should be able to
see that since (for any y) y ∉ 0, S × 0 = 0, and since (for any x) x ∉ 0, 0 × S = 0.
Which is a nice pun!
And what is the Cartesian product of a set S with the singleton set 1? You should be
able to see that S × 1 = {(x, 0) | x ∈ S}, and 1 × S = {(0, y) | y ∈ S}. While these
sets are not technically equal to the set S, we shall see (after we introduce the
concept of isomorphism ≅ between sets) that S × 1 ≅ S ≅ 1 × S. Another nice pun!
When S1, S2 are the same, i.e., R ⊆ S × S, then we say “the relation R is over set S.”
Definition 0.16 (Identity Relation) Given any set S, the identity relation on S,
written id(S ) , is the binary relation comprising all pairs (x, x) for x ∈ S. In “set
builder notation”, id(S ) = {(x, x) | x ∈ S}.
/* Identity Relation on a set S */
mem((X,X), id(S)) :- mem(X,S), !.
The constructor id(S) is used to denote the identity relation over set S.
Page 7 of 11
R1 ∘ R2 ⊆ S1 × S3, is the binary relation comprising all pairs (x, z) ∈ S1 × S3 such
that for some y ∈ S2 : (x, y) ∈ R1 and (y, z) ∈ R2. In “set builder notation”,
R1 ∘ R2 = {(x, z) ∈ S1 × S3 | ∃y ∈ S2 : (x, y) ∈ R1 ∧ (y, z) ∈ R2}.
/* Relational Composition */
mem((X,Z), comp(R1, R2)) :- mem((X,Y),R1),
mem((Y,Z),R2).
The constructor comp(R1, R2) is used to specify relational composition.
Proposition 0.1: For any binary relation R ⊆ S1 × S2, the relations id(S1) and
id(S2) are the left- and right- identities of relational composition. That is,
id(S1) ∘ R = R = R ∘ id(S2).
Exercise 0.34: Prove Proposition 0.1.
Proposition 0.2: Relational composition is associative. That is, for any binary
relations R1 ⊆ S1 × S2, R2 ⊆ S2 × S3 and R3 ⊆ S3 × S4: (R1 ∘ R2) ∘ R3 = R1 ∘ (R2 ∘ R3)
Exercise 0.35: Prove Proposition 0.2.
Proposition 0.3: Relational composition is monotone. That is, for any binary
relations R1, R′1 ⊆ S1 × S2, and R2, R′2 ⊆ S2 × S3 such that R1 ⊆ R′1 and R2 ⊆ R′2 .
Then R1 ∘ R2 ⊆ R′1 ∘ R′2.
Proof. Let (x, y) ∈ R1 and (y, z) ∈ R2. Then (x, z) ∈ R1 ∘ R2. But from the
definition of subset, (x, y) ∈ R′1 and (y, z) ∈ R′2. Therefore (x, z) ∈ R′1 ∘ R′2. □
Definition 0.18 (Relational Inverse) For any binary relation R ⊆ S1 × S2, its
inverse, written R − ⊆ S2 × S1, is the binary relation comprising all pairs (y, x) for
(x, y) ∈ R. In “set builder notation”, R − = {(y, x) ∈ S2 × S1 | (x, y) ∈ R}.
/* Inverse Relation */
mem( (Y,X), inv(R)) :- mem( (X,Y), R).
The constructor inv(R) is used to denote the inverse of the relation R.
Definition 0.22 (Reflexive Closure) For any binary relation R ⊆ S × S, its reflexive
closure, written R = ⊆ S × S, is the least reflexive relation containing R. That is, (i)
R ⊆ R = , (ii) R = is reflexive, and (iii) for any other R′ ⊆ S × S such that R ⊆ R′
and R′ is reflexive, R = ⊆ R′.
Proposition 0.12: R ↔ = R ∪ R −
/* Symmetric Closure */
mem((X,Y), symclos(R)) :- mem((X,Y), R), !.
mem((X,Y), symclos(R)) :- mem((X,Y), inv(R)).
We use Proposition 0.12 to specify membership of the symmetric closure of R,
denoted using the construction symclos(R).
Page 9 of 11











Definition 0.24 (Transitive Closure) For any binary relation R ⊆ S × S, its
transitive closure, written R + ⊆ S × S, is the least transitive relation containing R.
That is, (i) R ⊆ R + , (ii) R + is transitive, and (iii) for any other R′ ⊆ S × S such
that R ⊆ R′ and R′ is transitive, R + ⊆ R′.
Proposition 0.14 R + = Ri
⋃
i≥1
R i is a transitive relation containing R
⋃
Proof. We first show that
i≥1
(i) Since R 1 = R, from the definition of (generalised) union, R ⊆ Ri
⋃
i≥1
i i
⋃ ⋃
(ii) Let (x, y) ∈ R and (y, z) ∈ R . So, from the definition of union,
i≥1 i≥1
(x, y) ∈ R j and (y, z) ∈ R k for some j, k ≥ 1. Therefore (x, z) ∈ R j+k
(Proposition 0.13). But since R j+k ⊆ R i by the definition of generalised
⋃
i≥1
R i. So R i is a transitive relation.
⋃ ⋃
union (for j + k = i) , (x, z) ∈
i≥1 i≥1
(iii) Let R′ ⊆ S × S be such that R ⊆ R′ and R′ is transitive. (So by Proposition
0.10, R′ ∘ R′ ⊆ R′)
We show by induction that for each i ≥ 1, R i ⊆ R′.
Base case (i = 1). By assumption: R 1 = R ⊆ R′.
Induction hypothesis: Suppose we have shown that for i = k that R i ⊆ R′.
Induction step: Consider R 1+k = R ∘ R k.
But R ⊆ R′ (by assumption) and R k ⊆ R′ (by IH).
So by Proposition 0.3 and 0.10, R 1+k = R ∘ R k ⊆ R′ ∘ R′ ⊆ R′.
Hence by induction, for each i ≥ 1, R i ⊆ R′.
Definition 0.28 (Reflexive Symmetric Transitive Closure) For any binary relation
R ⊆ S × S, its reflexive-symmetric-transitive closure, written R ≡ ⊆ S × S, is the
least reflexive, symmetric and transitive relation containing R. That is,
(i) R ⊆ R ≡, (ii) R ≡ is reflexive, (ii) R ≡ is symmetric, (iv) R ≡ is transitive, and (v)
for any other R′ ⊆ S × S such that R ⊆ R′ and R′ is reflexive, symmetric and
transitive, R ≡ ⊆ R′.
Page 11 of 11