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
| Symbol | Notation | 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 |
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.
| Function | Operation | |
|---|---|---|
CartesianProduct | \operatorname{A} \times \operatorname{B} | A.k.a the product set, the set direct product or cross product. 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 |
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.
| Function | Notation | |
|---|---|---|
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 |
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}"
\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.
| Function | Notation | |
|---|---|---|
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} \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:
| 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) |
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.