Skip to main content

Sets

A set is a collection of distinct elements.

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.

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.

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.

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

SymbolNotation Definition
EmptySet\varnothing or \emptyset\varnothing or \emptysetA set that has no elements
Numbers\mathrm{Numbers}\mathrm{Numbers}Any number, real, imaginary, or complex
ComplexNumbers\C\CReal or imaginary numbers
ExtendedComplexNumbers\overline\C\overline\CReal or imaginary numbers, including +\infty, -\infty and \tilde\infty
ImaginaryNumbers\imaginaryI\R\imaginaryI\RComplex numbers with a non-zero imaginary part and no real part
RealNumbers\R\RNumbers 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\RReal numbers extended to include \pm\infty
Integers\Z \ZWhole numbers and their additive inverse \lbrace \ldots -3, -2, -1,0, 1, 2, 3\ldots\rbrace
ExtendedIntegers\overline\Z \overline\ZIntegers extended to include \pm\infty
RationalNumbers\Q\QNumbers which can be expressed as the quotient \nicefrac{p}{q} of two integers p, q \in \mathbb{Z}.
ExtendedRationalNumbers\overline\Q \overline\QRational 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\NIntegers \geq 0, \lbrace 0, 1, 2, 3\ldots\rbrace
PositiveIntegers\N^*\N^*Integers \gt 0, \lbrace 1, 2, 3\ldots\rbrace

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

["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.

FunctionOperation
CartesianProduct\operatorname{A} \times \operatorname{B}A.k.a the product set, the set direct product or cross product. Q173740
Complement\operatorname{A}^\complementThe 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
Intersection\operatorname{A} \cap \operatorname{B}The set of elements that are in \operatorname{A} and in \operatorname{B} Q185837
Union\operatorname{A} \cup \operatorname{B}The set of elements that are in \operatorname{A} or in \operatorname{B} Q173740
Set\lbrace 1, 2, 3 \rbrace Set builder notation
SetMinus\operatorname{A} \setminus \operatorname{B}Q18192442
SymmetricDifference\operatorname{A} \triangle \operatorname{B}Disjunctive union = (\operatorname{A} \setminus \operatorname{B}) \cup (\operatorname{B} \setminus \operatorname{A}) Q1147242

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.

FunctionNotation 
Adjoin\Z[\sqrt{2}]The ring \Z with \sqrt{2} adjoined
QuotientRing\Z_n or \Z/n\ZThe quotient of \Z by the ideal generated by n, i.e. the integers modulo n

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

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:

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:

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.

FunctionNotation 
Elementx \in \operatorname{A}x \in \operatorname{A}
NotElementx \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}
\operatorname{A} \subsetneq \operatorname{B}
\operatorname{A} \varsubsetneqq \operatorname{B}
\operatorname{A} \subset \operatorname{B}
\operatorname{A} \subsetneq \operatorname{B}
\operatorname{A} \varsubsetneqq \operatorname{B}
SubsetEqual\operatorname{A} \subseteq \operatorname{B}\operatorname{A} \subseteq \operatorname{B}
Superset\operatorname{A} \supset \operatorname{B}
\operatorname{A} \supsetneq \operatorname{B}
\operatorname{A} \varsupsetneq \operatorname{B}
\operatorname{A} \supset \operatorname{B}
\operatorname{A} \supsetneq \operatorname{B}
\operatorname{A} \varsupsetneq \operatorname{B}
SupersetEqual\operatorname{A} \supseteq \operatorname{B}\operatorname{A} \supseteq \operatorname{B}

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:

NotationLaTeXMathJSONDescription
[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)

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
// 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]]
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:

// 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):

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:

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:

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.