# Pascal Programming/Sets

## the notion of sets[edit]

Sets are accumulations of distinguishable objects. Either a set contains an object, or it does not. Especially note, sets can contain no objects at all. This is denoted in mathematics as ∅ (“empty set”).

Let's say we know the objects “apple”, “banana” and “pencil”. The set Fruit ≔ {“apple”, “banana”} contains the objects “apple” and “banana”. Its cardinality is two then, because it holds two elements.

Sets can be compared, by looking at each element in both sets. Two sets are equal, if both contain the same objects (neither set contains an object, the other set does not contain).

## sets in Pascal[edit]

### general[edit]

With enumerations, there comes the opportunity to use sets. Sets store multiple values of an enumeration. They act as a set of switches, so to speak. I suppose an example should give a clearer meaning to this.

```
program setDemo(input, output, stderr);
type
skill = (cooking, cleaning, driving, videogames, eating);
var
slob: set of skill;
begin
slob := [videogames, eating];
end.
```

Here, we have declared a variable `slob`

, which represents a set of the `skill`

enumeration.

By default, set types are usually internally implemented by compilers as `longword`

s if their base type has at most 32 values^{[note 1]}.
Anything above that, and they are stored as one byte per element.
Modern compilers limit set types to to 256 values maximum, though.

### operations on sets[edit]

Sets can be combined using the `+`

operator:

```
// combine the set slob
// with the literal set containing "driving" only
// and assign the result to slob
slob := slob + [driving];
```

The result of unifying two sets into one is called union.

You can then test, whether a set variable (or a literal set) contains an element utilizing the `in`

operator.
The element you are testing for, has to be a value of the base type.

```
// if the set "slob" contains the "videogames" value
if videogames in slob then
begin
writeLn('Is she a level 45 dungeon master?');
end;
```

Of course sets can be deprived of a set of elements by using `-`

operator.

```
// remove all elements in [] ("empty set")
// from slob, and store the result in slob
slob := slob - [];
```

For adding and removing single element from a set, some compilers come with handy routines.
For example in FreePascal `include(slob, driving)`

is equivalent to `slob := slob + [driving]`

, and `exclude`

respectively.

Furthermore you can intersect sets. The intersection of two sets is defined as the set of elements, both operands contain.

```
blueCollar := [cooking, cleaning, driving, eating];
slob := [driving, videogames, eating];
// intersect both sets
common := blueCollar * slob;
// common = [driving, eating]
```

A disjunct result to the intersection gives the symmetric difference.
It is the union of the operands *without* the elements contained in both sets.

```
unique := blueCollar >< slob;
// unique = [cooking, cleaning, videogames]
```

One last comparison operator allows to check, whether a set is completely contained by another set.

```
slobDoesLessThanBlueCollar := slob <= blueCollar;
// evaluates to false, since "videogames" is not in blueCollar
```

## notes[edit]

- ↑ To be precise,
`ord(high(skill))`

has to be less than 32, since some dialects allow specification of ordinal values along identifiers in enumeration types (`skill = (cooking = 1, cleaning = 42)`

would not fit in a “small set” using`longword`

). Again, this depends on the implementation.