What is a set? It is **a collection of things or objects, such as animals, plants, vowels** (a, e, i, o, u), swearwords, etc. Yes, you’ve guessed it, I am not going to give examples of these! Basically, it is **a list or a group of unordered items** which means: The order is irrelevant, {1, 2} is the same set as {2, 1}; and the elements are not repeated.

We can easily work with sets in Maxima. Let’s define sets in this free and useful application. It is very easy, just list the elements that form the set. For instance, *mySet:{a, b, c, d, f};* Do not forget the semicolon “;” and simultaneously press Shift + Enter. Please observe that the elements are grouped in brackets “{ … }” and separated by commas “,”.

The *number of elements that make up or are contained in a set* is called the **cardinality**. The cardinality of mySet is five and we use the following command to obtain it from Maxima: *cardinality(mySet);*

*mySet:{a, b, c, d, f};* is a definition by extension, that is, writing down or listing all the elements that belong to the set. Maxima also allows **definition by intension**. We describe a set by a defining property, a common feature that all of the set’s elements share. One example is *otherSet: divisors(32);* In other words, otherSet is the set of all the divisors of 32: {1, 2, 4, 8, 16, 32}.

Here’s another way to define complex sets in Maxima: *setify (makelist (fib (n), n, 1, 10));* This gives a set formed from the list (setify converts a list into a set — it removes duplicates) of the Fibonacci series’ first elements (fib(n) returns the n-th Fibonacci number, fib (0) = 0, fib (1) = 1, fib (2) = 1, fib (3) = 2, etc. — fib(n) = fib(n-1) + fib(n-2)).

Observe the result: {1, 2, 3, 5, 8, 13, 21, 34, 55}. There is something funny going on. Can you guess what it is?

We have asked for the first 10 elements of the Fibonacci series: makelist(fib(n), n, 1, 10). It indeed gives us back ten numbers: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]. However, the cardinality of {1, 2, 3, 5, 8, 13, 21, 34, 55} is 9. Do you know why? Of course, *makelist (fib (n), n, 1, 10);* actually returns 10 numbers, but one of the “1"s is removed from the list by setify to form a set.

Therefore, it is very important to understand that all elements have to be different. Thus, we can define sets as *C = setify ([1, 2, 3, a, b, c]);* and the result will be the same as if we write *C = setify ([1, 2, 3, a, b, c, 1, b, b]);*.

Two sets are **equal** *if they have the same elements*. Please let me insist again on the fact that the order within a set is not relevant at all, so *setequalp({a, b, c, d, e, f}, {f, e, d, c, b, a});* returns true because **setequalp** returns true if the two sets passed as arguments are equal.

On the contrary, *setequalp({a, b, c, d, e, f}, {f, e, d, c, b, a, h});* returns false.

Let’s work with sets in Python:

```
>>> rainbow_colors = {"Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet", "Red"}
>>> print(rainbow_colors) # sets cannot contain duplicate values and sets don't have an order:
{'Indigo', 'Red', 'Yellow', 'Violet', 'Green', 'Blue', 'Orange'}
>>> print(len(rainbow_colors)) # Get the length/cardinality of the set,
7
>>> traffic_light_colors = {"Red", "Yellow", "Blue"}
>>> traffic_light_colors.remove("Blue") # We can remove items from a set with the remove method.
>>> traffic_light_colors.add("Green") # We can add items from a set with the add method.
>>> print(traffic_light_colors)
{'Green', 'Red', 'Yellow'}
>>> if (rainbow_colors==traffic_light_colors): # Comparing sets in Python. Obviously, both sets are not equal.
... print("Both sets are equal")
... else:
... print("Both sets are not equal")
```

The **intersection** A ∩ B of two sets A and B is *a new set containing all the elements common to both sets*. Formally, mySet ∩ yourSet = {element: element ∈ mySet and element ∈ yourSet}. If the intersection is empty (mySet ∩ yourSet = ∅), the sets are said to be **disjoint** because they do not have any common members or elements.

Let’s ask Maxima for the intersection of two sets: *intersect(mySet, otherSet);* It returns {1, 2, 8} where mySet: setify(makelist(fib(n), n, 1, 10)); and otherSet: divisors(32); It gives back all the elements that are both in mySet ({1, 2, 3, 5, 8, 13, 21, 34, 55}) and otherSet ({1, 2, 4, 8, 16, 32}).

The command *disjointp (mySet, otherSet);* returns false because both sets are not disjointed, actually they share 1, 2, and 8. However, *disjointp({2, 4, 6, 8}, {1, 3, 5, 7});* is true.

The **union** A ∪ B of two sets A and B is **a new set containing all the elements of A plus all the elements of B and nothing else**. Formally, mySet ∪ yourSet = {element: element ∈ mySet or element ∈ yourSet}.

Let’s obtain the union of two sets: *union(mySet, otherSet);* return {1, 2, 3, 4, 5, 8, 13, 16, 21, 32, 34, 55} and *union(setify ([1, 2]), setify([6, 2, 7]));* = {1, 2, 6, 7}. It gives back all the elements in the two sets and no others.

The **Cartesian product** A x B of two sets A and B is **the set of all ordered pairs (a, b), where the first element of each pair, a, is an element from A, and the second, b, is an element from B**. We could express this in mathematical language as A x B = {(item1, item2) where item1 ∈ A and item2 ∈ B}.

We can request Maxima for the Cartesian product: *cartesian_product(mySet, otherSet);* = {[1,1],[1,2],[1,4],[1,8],[1,16],[1,32],[2,1],[2,2],[2,4],[2,8],[2,16],[2,32],[3,1],[3,2],[3,4],[3,8],[3,16],[3,32],[5,1],[5,2],[5,4],[5,8],[5,16],[5,32],[8,1],[8,2],[8,4],[8,8],[8,16],[8,32],[13,1],[13,2],[13,4],[13,8],[13,16],[13,32],[21,1],[21,2],[21,4],[21,8],[21,16],[21,32],[34,1],[34,2],[34,4],[34,8],[34,16],[34,32],[55,1],[55,2],[55,4],[55,8],[55,16],[55,32]}. *cartesian_product(setify ([1, 2, 5]), setify([5, 7]));* = {[1,5],[1,7],[2,5],[2,7],[5,5],[5,7]}

The **difference** A - B between two sets A and B is **the set containing all the elements that are in the first set, but not in the second one**. We can formulate it as: mySet - otherSet = {element: element ∈ mySet and element ∉ otherSet}. Then, we are going to ask Maxima for the difference between two sets: *setdifference (mySet, otherSet);* = {3, 5, 13, 21, 34, 55}. *setdifference(setify ([1, 2, 5]), setify([5, 7]));* = {1, 2}

The **symmetric difference** A △ B of two sets A and B is **the set containing all the elements that are in either of the sets, but not in both sets**. Strictly speaking: A △ B = { element: (element ∈ A ∧ element ∉ B) or (element ∉ A ∧ element ∈ B) }. Let’s require the symmetric difference in Maxima: *symmdifference (mySet, otherSet);* ={3, 4, 5, 13, 16, 21, 32, 34, 55}. *symmdifference(setify ([1, 2, 5]), setify([5, 7]));* = {1, 2, 7}

```
>>> rainbow_colors = {"Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet"}
>>> my_favourite_colors = {"Red", "White"}
>>> print(rainbow_colors & my_favourite_colors) # Intersection of sets with the operator
{'Red'}
>>> print(rainbow_colors.isdisjoint(my_favourite_colors)) # Two sets are disjoint if they have no elements in common
False
>>> print(rainbow_colors | my_favourite_colors) # Union of sets with the operator "|"
{'White', 'Violet', 'Indigo', 'Yellow', 'Blue', 'Red', 'Orange', 'Green'}
>>> print(rainbow_colors - my_favourite_colors) # Difference of sets with the operator "-"
{'Violet', 'Orange', 'Indigo', 'Green', 'Yellow', 'Blue'}
>>> print(rainbow_colors ^ my_favourite_colors) # Symmetric difference is performed using the operator "^"
{'Green', 'Blue', 'White', 'Yellow', 'Orange', 'Violet', 'Indigo'}
```

Let’s do some queries: intersection (*A intersect B*), union (*A union B*), symmetric difference (*symmetric difference of A and B*), and a more complex operation: *(A union B) insersect B)* = (A ∪ B) ∩ C.

It returns a graphical representation called **a Venn diagram** in which the colored part of the image represents the result. **A Venn diagram is a graphical way of representing the relationships between a finite collection of sets**.

After that, you could try to ask for the intersection (*Intersect[{a, b, c, d, e}, {a, c, j}]*), difference (*complement[{a, b, c, d, e}, {a, c, j}]*), and union (*union[{a, b, c, d, e}, {a, c, j}]*) of the sets {a, b, c, d, e} and {a, c, j}. Finally, *DisjointQ[{a, b, c, d, e}, {a, c, j}]* return false because these two sets share “a” and “c” as common elements.

You may want to check our Python class for representing and operating on natural numbers, Magic, happy, automorphic, narcissistic, handsome… numbers, and Abacus, Ascii Art, and Set of numbers.