<!-- https://mathlive.io/compute-engine/reference/sets/ -->

# Sets

<Intro>
A **set** is a collection of distinct elements.
</Intro>

The Compute Engine standard library includes definitions for common numeric sets. Checking if a value belongs to a set is done using the `Element` expression, or the $\in$ (`\in`) command in LaTeX.

```js
ce.expr(['Element', 3.14, 'NegativeIntegers']).evaluate().print();
// ➔ False

ce.parse("42 \\in \\Z").evaluate().print();
// ➔ True
```

`Element` and `NotElement` can also be used with a **type name** on the right
hand side (e.g. `integer`, `real`, `finite_real`, `number`, `any`), in which
case the check is done against the expression type.

```js
ce.declare('x', 'finite_real');
ce.expr(['Element', 'x', 'real']).evaluate().print();
// ➔ True

ce.expr(['Element', 'x', 'integer']).evaluate().print();
// ➔ False
```

Checking if an element is in a set is equivalent to checking if the type of the
element matches the type associated with the set.

```js
const x = ce.expr(42);

x.type;
// ➔ "finite_integer"

x.type.matches("integer");
// ➔ true

x.isInteger;
// ➔ true

ce.expr(['Element', x, 'Integers']).evaluate().print();
// ➔ True

ce.parse("42 \\in \\Z").evaluate().print();
// ➔ True
```


## Constants

<div className="symbols-table first-column-header" style={{"--first-col-width":"22ch"}}>

| Symbol     | Notation                                 | &nbsp; | Definition |
| :--------- | :--------------------------------------- | :--------- | :--------- |
| `EmptySet` | `\varnothing` or `\emptyset`| $$ \varnothing $$ or $$ \emptyset $$ | A set that has no elements           |
| `Numbers`               | `\mathrm{Numbers}` | $$ \mathrm{Numbers} $$ | Any number, real, imaginary, or complex |
| `ComplexNumbers`        | `\C` | $$ \C $$ | Real or imaginary numbers |
| `ExtendedComplexNumbers`        | `\overline\C` | $$ \overline\C $$ | Real or imaginary numbers, including $$+\infty$$, $$-\infty$$ and $$\tilde\infty$$ |
| `ImaginaryNumbers`           | `\imaginaryI\R` | $$ \imaginaryI\R $$ | Complex numbers with a non-zero imaginary part and no real part |
| `RealNumbers`           | `\R` | $$ \R $$ | Numbers that form the unique Dedekind-complete ordered field $$ \left( \mathbb{R} ; + ; \cdot ; \lt \right) $$, up to an isomorphism (does not include $\pm\infty$) |
| `ExtendedRealNumbers`           | `\overline\R` | $$ \overline\R $$ | Real numbers extended to include $\pm\infty$ |
| `Integers`              | `\Z` | $$ \Z$$  | Whole numbers and their additive inverse $$\lbrace \ldots -3, -2, -1,0, 1, 2, 3\ldots\rbrace$$                                       |
| `ExtendedIntegers`              | `\overline\Z` | $$ \overline\Z$$  | Integers extended to include $\pm\infty$ |
| `RationalNumbers`       | `\Q` | $$ \Q $$  | Numbers which can be expressed as the quotient $$ \nicefrac{p}{q}$$ of two integers $$p, q \in \mathbb{Z}$$.                                  |
| `ExtendedRationalNumbers`              | `\overline\Q` | $$ \overline\Q$$  | Rational numbers extended to include $\pm\infty$ |
| `NegativeNumbers`       | `\R_{<0}` | $$ \R_{<0} $$       | Real numbers $$ \lt 0 $$ |
| `NonPositiveNumbers`    | `\R_{\leq0}` | $$ \R_{\leq0} $$    | Real numbers $$ \leq 0 $$ |
| `NonNegativeNumbers`    | `\R_{\geq0}` | $$ \R_{\geq0} $$    | Real numbers $$ \geq 0 $$ |
| `PositiveNumbers`       | `\R_{>0}` | $$ \R_{>0} $$     | Real numbers $$ \gt 0$$ |
| `NegativeIntegers`      | `\Z_{<0}` | $$ \Z_{<0} $$       | Integers $$ \lt 0$$, $$\lbrace \ldots -3, -2, -1\rbrace$$                                                                          |
| `NonPositiveIntegers`   | `\Z_{\le0}` | $$ \Z_{\le0} $$    | Integers $$ \leq 0 $$, $$\lbrace \ldots -3, -2, -1, 0\rbrace$$                                                                     |
| `NonNegativeIntegers`   | `\N` | $$ \N $$    | Integers $$ \geq 0 $$, $$\lbrace 0, 1, 2, 3\ldots\rbrace$$                                                                         |
| `PositiveIntegers`      | `\N^*` | $$ \N^* $$     | Integers $$ \gt 0 $$, $$\lbrace 1, 2, 3\ldots\rbrace$$                                                                             |

</div>

`Union` and `Intersection` accept any finite collections, including lists. The
result is a `Set`, so duplicate elements are removed:

```json example
["Intersection", ["List", 1, 2], ["List", 2, 3]]
// ➔ ["Set", 2]
```

A MathJSON `List` is always a collection here, including when it has two
elements. Interval notation is interpreted as an `Interval` while parsing
LaTeX, before the set operation is constructed.

## Functions

New sets can be defined using one of the following operators.

<div className="symbols-table first-column-header" style={{"--first-col-width":"19ch"}}>

| Function              | Operation                                           |                                                                                                                                                                                                                     |
| :-------------------- | :-------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `CartesianProduct`    | $$ \operatorname{A} \times \operatorname{B} $$    | A.k.a the product set, the set direct product or cross product. [Q173740](https://www.wikidata.org/wiki/Q173740)                                                                                                    |
| `Complement`          | $$ \operatorname{A}^\complement $$                | The set of elements that are not in $$ \operatorname{A} $$. If $$\operatorname{A}$$ is a numeric type, the universe is assumed to be the set of all numbers. [Q242767](https://www.wikidata.org/wiki/Q242767) |
| `Intersection`        | $$ \operatorname{A} \cap \operatorname{B} $$      | The set of elements that are in $$\operatorname{A}$$ and in $$\operatorname{B}$$ [Q185837](https://www.wikidata.org/wiki/Q185837)                                                                               |
| `Union`               | $$ \operatorname{A} \cup \operatorname{B} $$      | The set of elements that are in $$\operatorname{A}$$ or in $$\operatorname{B}$$ [Q173740](https://www.wikidata.org/wiki/Q173740)                                                                                |
| `Set`                 | $$\lbrace 1, 2, 3 \rbrace $$                      | Set builder notation                                                                                                                                                                                                |
| `SetMinus`            | $$ \operatorname{A} \setminus \operatorname{B} $$ | [Q18192442](https://www.wikidata.org/wiki/Q18192442)                                                                                                                                                                |
| `SymmetricDifference` | $$ \operatorname{A} \triangle \operatorname{B} $$ | Disjunctive union = $$ (\operatorname{A} \setminus \operatorname{B}) \cup (\operatorname{B} \setminus \operatorname{A})$$ [Q1147242](https://www.wikidata.org/wiki/Q1147242)                                      |

</div>

## Ring Constructions

The two standard notations for building a new ring from an existing one are
recognized on the blackboard-bold ring and field constants — $$\Z$$, $$\Q$$,
$$\R$$ and $$\C$$.

<div className="symbols-table first-column-header" style={{"--first-col-width":"19ch"}}>

| Function       | Notation                                    | &nbsp;                                                                        |
| :------------- | :------------------------------------------ | :---------------------------------------------------------------------------- |
| `Adjoin`       | $$ \Z[\sqrt{2}] $$                          | The ring $$\Z$$ with $$\sqrt{2}$$ adjoined                                     |
| `QuotientRing` | $$ \Z_n $$ or $$ \Z/n\Z $$                  | The quotient of $$\Z$$ by the ideal generated by $$n$$, i.e. the integers modulo $$n$$ |

</div>

**Adjunction** accepts one or more adjuncts, and reads an undeclared symbol as
an indeterminate, i.e. a polynomial ring:

```js
ce.parse("\\Z[\\sqrt{2}]");
// ➔ ["Adjoin", "Integers", ["Sqrt", 2]]

ce.parse("\\Z[\\sqrt{2},\\sqrt{3}]");
// ➔ ["Adjoin", "Integers", ["Sqrt", 2], ["Sqrt", 3]]

ce.parse("\\Z[i]");   // the Gaussian integers
// ➔ ["Adjoin", "Integers", ["Complex", 0, 1]]

ce.parse("\\Z[x]");   // polynomials in x with integer coefficients
// ➔ ["Adjoin", "Integers", "x"]
```

Field adjunction written with **parentheses** — $$\Q(\sqrt{2})$$ — is not
parsed: parentheses following a symbol are read as multiplication or function
application everywhere else in the grammar. Use the bracket form.

**Quotients** can be written with a subscript or in the longer ideal notation.
Both parse to the same expression, which serializes back to the subscript form:

```js
ce.parse("\\Z_n");
// ➔ ["QuotientRing", "Integers", "n"]

ce.parse("\\Z/n\\Z");
// ➔ ["QuotientRing", "Integers", "n"]

ce.box(["QuotientRing", "Integers", 12]).latex;
// ➔ "\Z_{12}"
```

:::warning
$$\Z_p$$ is read as the integers **modulo** $$p$$, that is $$\Z/p\Z$$. Some
texts use the same notation for the ring of $$p$$-adic integers; that reading
is not available. The mod-$$n$$ reading is by far the more common one in the
material this engine parses.
:::

A subscript that marks a **sign restriction** is not a quotient: $$\Z_+$$,
$$\R_-$$ and $$\Z_{\geq 0}$$ still name `PositiveIntegers`, `NegativeNumbers`
and `NonNegativeIntegers`, as before.

Both operators are **inert**: they stay symbolic, and there is no membership
test (`Element`), no enumeration of residues, and no arithmetic in the
constructed ring. They do carry a type, formed by joining the base ring's
element type with the types of the adjoined elements:

```js
ce.parse("\\Z[\\sqrt{2}]").type;   // ➔ set<finite_real>
ce.parse("\\Z[i]").type;           // ➔ set<finite_complex>
ce.parse("\\Z[x]").type;           // ➔ set<unknown>
ce.parse("\\Z_n").type;            // ➔ set<finite_integer>
```

## Relations

To check the membership of an element in a set or the relationship between two sets using the following operators.

<div className="symbols-table first-column-header">

| Function        | Notation                                                                                                                                                                 | &nbsp;                                                                                                      |
| :-------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------- |
| `Element`       | $$ x \in \operatorname{A} $$                                                                                                                                            | `x \in \operatorname{A}`                                                                                   |
| `NotElement`    | $$ x \not\in \operatorname{A} $$                                                                                                                                        | `x \not\in \operatorname{A}`                                                                               |
| `NotSubset`     | $$ \operatorname{A} \nsubset \operatorname{B} $$                                                                                                                                       | `\operatorname{A} \nsubset \operatorname{B}`                                                                              |
| `NotSuperset`   | $$ \operatorname{A} \nsupset \operatorname{B} $$                                                                                                                                       | `\operatorname{A} \nsupset \operatorname{B}`                                                                              |
| `Subset`        | $$ \operatorname{A} \subset \operatorname{B} $$ <br/> $$ \operatorname{A} \subsetneq \operatorname{B} $$ <br/> $$ \operatorname{A} \varsubsetneqq \operatorname{B} $$ | `\operatorname{A} \subset \operatorname{B}` <br/> `\operatorname{A} \subsetneq \operatorname{B}` <br/> `\operatorname{A} \varsubsetneqq \operatorname{B}` |
| `SubsetEqual`   | $$ \operatorname{A} \subseteq \operatorname{B} $$                                                                                                                       | `\operatorname{A} \subseteq \operatorname{B}`                                                              |
| `Superset`      | $$ \operatorname{A} \supset \operatorname{B} $$<br/> $$ \operatorname{A} \supsetneq \operatorname{B} $$<br/>$$ \operatorname{A} \varsupsetneq \operatorname{B} $$     | `\operatorname{A} \supset \operatorname{B}`<br/> `\operatorname{A} \supsetneq \operatorname{B}`<br/>`\operatorname{A} \varsupsetneq \operatorname{B}` |
| `SupersetEqual` | $$ \operatorname{A} \supseteq \operatorname{B} $$                                                                                                                       | `\operatorname{A} \supseteq \operatorname{B}`                                                              |

</div>

## Intervals

An **interval** is a set of real numbers that contains all numbers between two endpoints. Intervals can be open (excluding endpoints), closed (including endpoints), or half-open (including one endpoint but not the other).

### Interval Notation

The Compute Engine supports both American and ISO/European interval notation:

<div className="symbols-table first-column-header" style={{"--first-col-width":"16ch"}}>

| Notation | LaTeX | MathJSON | Description |
| :------- | :---- | :------- | :---------- |
| $[a, b]$ | `[a, b]` | `["Interval", a, b]` | Closed interval (both endpoints included) |
| $(a, b)$ | `(a, b)` | `["Interval", ["Open", a], ["Open", b]]` | Open interval (both endpoints excluded) |
| $[a, b)$ | `[a, b)` | `["Interval", a, ["Open", b]]` | Half-open (closed-open) |
| $(a, b]$ | `(a, b]` | `["Interval", ["Open", a], b]` | Half-open (open-closed) |
| $]a, b[$ | `]a, b[` | `["Interval", ["Open", a], ["Open", b]]` | Open interval (ISO notation) |

</div>

The `Open` wrapper indicates that an endpoint is excluded from the interval.

### Delimiter Variants

All interval notations support LaTeX delimiter sizing commands:

- **Explicit bracket commands**: `\lbrack`, `\rbrack`, `\lparen`, `\rparen`
- **Sizing prefixes**: `\left`/`\right`, `\bigl`/`\bigr`, `\Bigl`/`\Bigr`, `\biggl`/`\biggr`, `\Biggl`/`\Biggr`
- **Spacing commands**: `\mathopen`/`\mathclose`

```js
// All of these parse to the same Interval expression:
ce.parse('[3, 4)').json;
ce.parse('\\lbrack 3, 4\\rparen').json;
ce.parse('\\left[ 3, 4 \\right)').json;
ce.parse('\\bigl[ 3, 4 \\bigr)').json;
ce.parse('\\mathopen\\lbrack 3, 4\\mathclose\\rparen').json;
// → ["Interval", 3, ["Open", 4]]
```

```js
ce.parse('[0, 1)').json;
// ➔ ["Interval", 0, ["Open", 1]]

ce.parse('(-\\infty, 0]').json;
// ➔ ["Interval", ["Open", ["Negate", "PositiveInfinity"]], 0]
```

### Contextual Interval Parsing

When bracket notation appears in a set context (such as with `\in`, `\cup`, `\cap`, `\subset`, etc.), the Compute Engine automatically interprets it as an interval:

```js
// In set context: [0, 1] becomes an Interval
ce.parse('x \\in [0, 1]').json;
// ➔ ["Element", "x", ["Interval", 0, 1]]

ce.parse('[0, 1] \\cup [2, 3]').json;
// ➔ ["Union", ["Interval", 0, 1], ["Interval", 2, 3]]

// Standalone: [0, 1] remains a List for backward compatibility
ce.parse('[0, 1]').json;
// ➔ ["List", 0, 1]
```

### Interval Serialization

An interval is always serialized so that it reads back as an `Interval`. Which
spelling is used depends on the position it appears in.

**In a set position** — the right side of `\in`/`\notin`, either side of `\cup`,
`\cap`, `\setminus`, `\subset`, `\subseteq`, `\supset`, `\supseteq` — the
conventional bracket notation is used, because the operator forces the set
reading when the LaTeX is parsed back (see **Contextual Interval Parsing**
above):

```js
ce.expr(['Element', 'x', ['Interval', 0, 1]]).latex;
// ➔ "x\\in\\lbrack0, 1\\rbrack"

ce.expr(['Union', ['Interval', 0, 1], ['Interval', 2, 3]]).latex;
// ➔ "\\lbrack0, 1\\rbrack\\cup\\lbrack2, 3\\rbrack"
```

**Anywhere else** nothing disambiguates the interval, so the serialization has
to stand on its own. Half-open intervals use American notation and an open
interval uses the ISO reversed brackets; both are unambiguous:

```js
ce.expr(['Interval', 0, ['Open', 1]]).latex;
// ➔ "\\lbrack0, 1\\rparen"

ce.expr(['Interval', ['Open', 0], ['Open', 1]]).latex;
// ➔ "\\rbrack0, 1\\lbrack"
```

A **closed** interval has no unambiguous bracket spelling — `[a, b]` is also how
a two-element list is written, and that is how the parser reads it — so it uses
the function form:

```js
ce.expr(['Interval', 0, 1]).latex;
// ➔ "\\mathrm{Interval}(0, 1)"

ce.parse('\\mathrm{Interval}(0, 1)').json;
// ➔ ["Interval", 0, 1]
```

This matters wherever the list reading would also be valid. For example
`["RandomChoice", ["Interval", 0, 1], n]` draws `n` uniform reals, while
`["RandomChoice", ["List", 0, 1], n]` picks `n` times between the two *values*
`0` and `1` — both produce a list of numbers in range, so a lossy round-trip
would be undetectable downstream.
