# Set Expressions

## Introduction

A **set expression** is an expression that when evaluated results in a set.
It is a *non-explicit* way of defining a set, which contrasts
with the *explicit* definition that we make
when we assign values to a set in a data section,
listing them one by one.

The difference between defining a set explicitly and implicitly is exemplified below. Both statements
result in the same set, but the first is an assignment statement that explicitly lists all values
of the set, while the second is a declaration statement that defines the set using a set of numbers
constructor

*outside*a data section (see Statement Types).

Set expressions can appear in a variety of different contexts in an AMPL program. The above declaration statement is just an example of one place in which they may occur. Set expressions are the basic components of indexing expressions, and we use indexing expressions for many different purposes.

A set expression can be as simple as the name of a single set,

## Set Theory Operators

We can use the standard operators of set theory to define sets.

The

The resulting set of the above expression is the union of all sets in the set collection **S**.

## Set of Numbers

The *first value* of the set, which in the example is 1. The next value in the set
will be 1 plus the gap between consecutive values: 1 + 2 = 3. And so on, up to the *maximum value*.

The value on the right of the *maximum value (M)*, which may or may not be included in the set.
It is only included if *M - gap* is also included.
The *gap*

## Set Constructor

The

We can also construct multidimensional sets with the *tuple*. A tuple
can be a pair, a triplet, a quartet, and so on. For instance, suppose that we have a set
**NotebookModels**, where each model can have 4, 8 or 16 GB of RAM. So we want to construct a set
of the possible *model-memory* pairs, which can be done like this:

## Indexing Expressions and Iterators

Indexing expressions alone can also be used as set constructors. The resulting set of an indexing expression is a set with all the possible tuples that satisfy the condition in the expression. The dimension of the resulting set is the number of set expressions in the indexing expression, which are separated by commas. The above example produces a 2 dimensional set with all the possible pairs of different cities.

Any set expression in an indexing expression can be preceded by an **iterator** of the resulting set.
An iterator is basically an object that represents any and all members of a set:

There are two main occasions when we
want to use iterators. First, when we want to **filter** out the tuples of an indexing expression
according to a logical condition. Second, when subsequent expressions in the same scope
of a given set expression will need to **refer** to the members of the resulting set of that expression.

We have used iterators to **filter** the tuples of the indexing expression in the previous section:
**Cities**
that go in the first position of any resulting pair, and an iterator **Cities** that go in the second position of any resulting pair.
We filter out the pairs where *a equals b* by by imposing the condition

We have used iterators to **refer** to the members of a set in the set constructor example: