@cortex-js/compute-engine 0.25.1 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/dist/compute-engine.esm.js +26832 -23014
  2. package/dist/compute-engine.js +26836 -23006
  3. package/dist/compute-engine.min.esm.js +88 -23
  4. package/dist/compute-engine.min.js +88 -23
  5. package/dist/math-json.esm.js +22 -139
  6. package/dist/math-json.js +22 -139
  7. package/dist/math-json.min.esm.js +22 -139
  8. package/dist/math-json.min.js +2 -2
  9. package/dist/types/common/ansi-codes.d.ts +30 -4
  10. package/dist/types/common/buffer.d.ts +9 -0
  11. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  12. package/dist/types/common/one-of.d.ts +9 -0
  13. package/dist/types/common/signals.d.ts +1 -1
  14. package/dist/types/common/styled-text.d.ts +28 -0
  15. package/dist/types/common/suggest.d.ts +1 -0
  16. package/dist/types/common/syntax-highlighter.d.ts +40 -0
  17. package/dist/types/common/terminal.d.ts +19 -0
  18. package/dist/types/common/type/parse.d.ts +4 -0
  19. package/dist/types/common/type/primitive.d.ts +8 -0
  20. package/dist/types/common/type/serialize.d.ts +2 -0
  21. package/dist/types/common/type/subtype.d.ts +6 -0
  22. package/dist/types/common/type/types.d.ts +249 -0
  23. package/dist/types/common/type/utils.d.ts +39 -0
  24. package/dist/types/common/utils.d.ts +2 -1
  25. package/dist/types/compute-engine/assume.d.ts +13 -13
  26. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +70 -47
  27. package/dist/types/compute-engine/boxed-expression/apply.d.ts +5 -0
  28. package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +15 -0
  29. package/dist/types/compute-engine/boxed-expression/arithmetic-divide.d.ts +12 -0
  30. package/dist/types/compute-engine/boxed-expression/arithmetic-multiply.d.ts +16 -0
  31. package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +20 -0
  32. package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +11 -0
  33. package/dist/types/compute-engine/boxed-expression/box.d.ts +13 -71
  34. package/dist/types/compute-engine/boxed-expression/boxed-function-definition.d.ts +31 -13
  35. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +66 -45
  36. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +41 -37
  37. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +2 -2
  38. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +13 -9
  39. package/dist/types/compute-engine/boxed-expression/boxed-symbol-definition.d.ts +34 -66
  40. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +63 -41
  41. package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +44 -27
  42. package/dist/types/compute-engine/boxed-expression/cache.d.ts +6 -0
  43. package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
  44. package/dist/types/compute-engine/boxed-expression/compare.d.ts +13 -0
  45. package/dist/types/compute-engine/boxed-expression/expand.d.ts +20 -0
  46. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  47. package/dist/types/compute-engine/boxed-expression/factor.d.ts +7 -6
  48. package/dist/types/compute-engine/boxed-expression/flatten.d.ts +25 -0
  49. package/dist/types/compute-engine/boxed-expression/hold.d.ts +9 -0
  50. package/dist/types/compute-engine/boxed-expression/match.d.ts +2 -4
  51. package/dist/types/compute-engine/boxed-expression/negate.d.ts +10 -0
  52. package/dist/types/compute-engine/boxed-expression/numerics.d.ts +5 -39
  53. package/dist/types/compute-engine/boxed-expression/order.d.ts +26 -14
  54. package/dist/types/compute-engine/{symbolic → boxed-expression}/polynomials.d.ts +11 -15
  55. package/dist/types/compute-engine/{symbolic → boxed-expression}/product.d.ts +18 -24
  56. package/dist/types/compute-engine/boxed-expression/public.d.ts +906 -634
  57. package/dist/types/compute-engine/boxed-expression/rules.d.ts +129 -0
  58. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +2 -2
  59. package/dist/types/compute-engine/boxed-expression/sgn.d.ts +6 -0
  60. package/dist/types/compute-engine/boxed-expression/simplify.d.ts +6 -0
  61. package/dist/types/compute-engine/{solve.d.ts → boxed-expression/solve.d.ts} +5 -5
  62. package/dist/types/compute-engine/{symbolic → boxed-expression}/tensor-fields.d.ts +3 -3
  63. package/dist/types/compute-engine/boxed-expression/terms.d.ts +10 -0
  64. package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +10 -0
  65. package/dist/types/compute-engine/boxed-expression/utils.d.ts +22 -16
  66. package/dist/types/compute-engine/boxed-expression/validate.d.ts +10 -7
  67. package/dist/types/compute-engine/collection-utils.d.ts +24 -2
  68. package/dist/types/compute-engine/compile.d.ts +3 -3
  69. package/dist/types/compute-engine/compute-engine.d.ts +132 -165
  70. package/dist/types/compute-engine/cost-function.d.ts +11 -1
  71. package/dist/types/compute-engine/function-utils.d.ts +5 -5
  72. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  73. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  74. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  75. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
  76. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
  77. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
  78. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  79. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  80. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
  81. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  82. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
  83. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  84. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  85. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
  86. package/dist/types/compute-engine/latex-syntax/parse-identifier.d.ts +2 -2
  87. package/dist/types/compute-engine/latex-syntax/parse.d.ts +25 -30
  88. package/dist/types/compute-engine/latex-syntax/public.d.ts +22 -18
  89. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +2 -2
  90. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
  91. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +5 -8
  92. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  93. package/dist/types/compute-engine/library/arithmetic.d.ts +4 -2
  94. package/dist/types/compute-engine/library/calculus.d.ts +1 -1
  95. package/dist/types/compute-engine/library/collections.d.ts +24 -1
  96. package/dist/types/compute-engine/library/complex.d.ts +1 -1
  97. package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
  98. package/dist/types/compute-engine/library/core.d.ts +1 -3
  99. package/dist/types/compute-engine/library/invisible-operator.d.ts +4 -0
  100. package/dist/types/compute-engine/library/library.d.ts +2 -4
  101. package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
  102. package/dist/types/compute-engine/library/logic.d.ts +5 -1
  103. package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
  104. package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
  105. package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
  106. package/dist/types/compute-engine/library/sets.d.ts +1 -1
  107. package/dist/types/compute-engine/library/statistics.d.ts +1 -1
  108. package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
  109. package/dist/types/compute-engine/library/utils.d.ts +46 -40
  110. package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +59 -0
  111. package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +77 -0
  112. package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +58 -0
  113. package/dist/types/compute-engine/numeric-value/public.d.ts +110 -0
  114. package/dist/types/compute-engine/numerics/bigint.d.ts +2 -0
  115. package/dist/types/compute-engine/numerics/bignum.d.ts +12 -0
  116. package/dist/types/compute-engine/numerics/expression.d.ts +4 -0
  117. package/dist/types/compute-engine/numerics/interval.d.ts +12 -0
  118. package/dist/types/compute-engine/numerics/monte-carlo.d.ts +19 -0
  119. package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +4 -14
  120. package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +6 -9
  121. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
  122. package/dist/types/compute-engine/numerics/numeric.d.ts +9 -59
  123. package/dist/types/compute-engine/numerics/primes.d.ts +3 -3
  124. package/dist/types/compute-engine/numerics/rationals.d.ts +29 -13
  125. package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
  126. package/dist/types/compute-engine/numerics/special-functions.d.ts +28 -0
  127. package/dist/types/compute-engine/numerics/strings.d.ts +2 -0
  128. package/dist/types/compute-engine/public.d.ts +8 -4
  129. package/dist/types/compute-engine/symbolic/derivative.d.ts +2 -2
  130. package/dist/types/compute-engine/symbolic/distribute.d.ts +5 -0
  131. package/dist/types/compute-engine/{simplify-rules.d.ts → symbolic/simplify-rules.d.ts} +1 -1
  132. package/dist/types/compute-engine/{symbolic → tensor}/tensors.d.ts +3 -3
  133. package/dist/types/compute-engine.d.ts +4 -2
  134. package/dist/types/math-json/identifiers.d.ts +11 -0
  135. package/dist/types/math-json/{math-json-format.d.ts → types.d.ts} +4 -9
  136. package/dist/types/math-json/utils.d.ts +15 -23
  137. package/dist/types/math-json.d.ts +3 -3
  138. package/package.json +3 -3
  139. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +0 -48
  140. package/dist/types/compute-engine/boxed-expression/boxed-domain.d.ts +0 -40
  141. package/dist/types/compute-engine/boxed-expression/coefficient-field.d.ts +0 -56
  142. package/dist/types/compute-engine/domain-utils.d.ts +0 -19
  143. package/dist/types/compute-engine/library/arithmetic-add.d.ts +0 -21
  144. package/dist/types/compute-engine/library/arithmetic-divide.d.ts +0 -16
  145. package/dist/types/compute-engine/library/arithmetic-multiply.d.ts +0 -16
  146. package/dist/types/compute-engine/library/arithmetic-power.d.ts +0 -11
  147. package/dist/types/compute-engine/library/domains.d.ts +0 -16
  148. package/dist/types/compute-engine/numerics/terms.d.ts +0 -17
  149. package/dist/types/compute-engine/rules.d.ts +0 -20
  150. package/dist/types/compute-engine/symbolic/expand.d.ts +0 -23
  151. package/dist/types/compute-engine/symbolic/flatten.d.ts +0 -9
  152. package/dist/types/compute-engine/symbolic/negate.d.ts +0 -11
  153. package/dist/types/compute-engine/symbolic/utils.d.ts +0 -22
@@ -1,10 +1,141 @@
1
- /* 0.25.1 */
2
- import Decimal from 'decimal.js';
3
- import { Expression, MathJsonNumber, MathJsonString, MathJsonSymbol, MathJsonFunction, MathJsonDictionary, MathJsonIdentifier } from '../../math-json';
1
+ /* 0.26.0 */
2
+ import type { Expression, MathJsonNumber, MathJsonString, MathJsonSymbol, MathJsonFunction, MathJsonIdentifier } from '../../math-json';
4
3
  import type { SerializeLatexOptions, LatexDictionaryEntry, ParseLatexOptions } from '../latex-syntax/public';
5
- import { IndexedLatexDictionary } from '../latex-syntax/dictionary/definitions';
4
+ import type { IndexedLatexDictionary } from '../latex-syntax/dictionary/definitions';
6
5
  import { Rational } from '../numerics/rationals';
7
- import './serialize';
6
+ import { ExactNumericValueData, NumericValue, NumericValueData } from '../numeric-value/public';
7
+ import { BigNum, IBigNum } from '../numerics/bignum';
8
+ import { Type, TypeString } from '../../common/type/types';
9
+ import { AbstractTensor } from '../tensor/tensors';
10
+ import { OneOf } from '../../common/one-of';
11
+ /**
12
+ * :::info[THEORY OF OPERATIONS]
13
+ *
14
+ * To create a boxed expression:
15
+ *
16
+ * ### `ce.box()` and `ce.parse()`
17
+ *
18
+ * Use `ce.box()` or `ce.parse()` to get a canonical expression.
19
+ * - the arguments are put in canonical form
20
+ * - invisible operators are made explicit
21
+ * - a limited number of core simplifications are applied,
22
+ * for example 0 is removed from additions
23
+ * - sequences are flattened: `["Add", 1, ["Sequence", 2, 3]]` is
24
+ * transformed to `["Add", 1, 2, 3]`
25
+ * - associative functions are flattened: `["Add", 1, ["Add", 2, 3]]` is
26
+ * transformed to `["Add", 1, 2, 3]`
27
+ * - the arguments of commutative functions are sorted
28
+ * - identifiers are **not** replaced with their values
29
+ *
30
+ * ### Algebraic methods (expr.add(), expr.mul(), etc...)
31
+ *
32
+ * The boxed expression have some algebraic methods,
33
+ * i.e. `add`, `mul`, `div`, `pow`, etc. These methods are suitable for
34
+ * internal calculations, although they may be used as part of the public
35
+ * API as well.
36
+ *
37
+ * - the operation is performed on the canonical version of the expression
38
+ *
39
+ * - the arguments are not evaluated
40
+ *
41
+ * - the canonical handler (of the corresponding operation) is not called
42
+ *
43
+ * - some additional simplifications over canonicalization are applied.
44
+ * For example number literals are combined.
45
+ * However, the result is exact, and no approximation is made. Use `.N()`
46
+ * to get an approximate value.
47
+ * This is equivalent to calling `simplify()` on the expression (but
48
+ * without simplifying the arguments).
49
+ *
50
+ * - sequences were already flattened as part of the canonicalization process
51
+ *
52
+ * For 'add' and 'mul', which take multiple arguments, separate functions
53
+ * are provided that take an array of arguments. They are equivalent
54
+ * to calling the boxed algebraic method, i.e. `ce.Zero.add(1, 2, 3)` and
55
+ * `add(1, 2, 3)` are equivalent.
56
+ *
57
+ * These methods are not equivalent to calling `expr.evaluate()` on the
58
+ * expression: evaluate will replace identifiers with their values, and
59
+ * evaluate the expression
60
+ *
61
+ * ### `ce._fn()`
62
+ *
63
+ * Use `ce._fn()` to create a new function expression.
64
+ *
65
+ * This is a low level method which is typically invoked in the canonical
66
+ * handler of a function definition.
67
+ *
68
+ * The arguments are not modified. The expression is not put in canonical
69
+ * form. The canonical handler is *not* called.
70
+ *
71
+ * A canonical flag can be set when calling the function, but it only
72
+ * asserts that the function and its arguments are canonical. The caller
73
+ * is responsible for ensuring that is the case.
74
+ *
75
+ *
76
+ * ### `ce.function()`
77
+ *
78
+ * This is a specialized version of `ce.box()`. It is used to create a new
79
+ * function expression.
80
+ *
81
+ * The arguments are put in canonical form and the canonical handler is called.
82
+ *
83
+ * For algebraic functions (add, mul, etc..), use the corresponding
84
+ * canonicalization function, i.e. `canonicalAdd(a, b)` instead of
85
+ * `ce.function('Add', a, b)`.
86
+ *
87
+ * Another option is to use the algebraic methods directly, i.e. `a.add(b)`
88
+ * instead of `ce.function('Add', a, b)`. However, the algebraic methods will
89
+ * apply further simplifications which may or may not be desirable. For
90
+ * example, number literals will be combined.
91
+ *
92
+ * ### Canonical Handlers
93
+ *
94
+ * Canonical handlers are responsible for:
95
+ * - validating the signature (type and number of arguments)
96
+ * - flattening sequences
97
+ * - flattening associative functions
98
+ * - sort the arguments (if the function is commutative)
99
+ * - calling `ce._fn()` to create a new function expression
100
+ * - if the function definition has a hold, they should also put
101
+ * their arguments in canonical form, if appropriate
102
+ *
103
+ * When the canonical handler is invoked, the arguments have been put in
104
+ * canonical form according to the `hold` flag.
105
+ *
106
+ * Some canonical handlers are available as separate functions and can be
107
+ * used directly, for example `canonicalAdd(a, b)` instead of
108
+ * `ce.function('Add', [a, b])`.
109
+ *
110
+ * :::
111
+ */
112
+ export type Sign =
113
+ /** The expression is equal to 0 */
114
+ 'zero'
115
+ /** The expression is > 0 */
116
+ | 'positive'
117
+ /** The expression is < 0 */
118
+ | 'negative'
119
+ /** The expression is >= 0 and isPositive is either false or undefined*/
120
+ | 'non-negative'
121
+ /** The expression is <= 0 and isNegative is either false or undefined*/
122
+ | 'non-positive'
123
+ /** The expression is not equal to 0 (possibly with an imaginary part) and isPositive, isNegative, isUnsigned are all false or undefined */
124
+ | 'not-zero'
125
+ /** The expression has no imaginary part and a non-zero real part and isPositive and isNegative are false or undefined*/
126
+ | 'real-not-zero'
127
+ /** The expression has no imaginary part and isNotZero,isPositive,isNegative,isNonNegative,isNonPositive,isZero are either false or undefined*/
128
+ | 'real'
129
+ /** The expression is NaN */
130
+ | 'nan'
131
+ /** The expression is +∞ */
132
+ | 'positive-infinity'
133
+ /** The expression is -∞ */
134
+ | 'negative-infinity'
135
+ /** The expression is ~∞ */
136
+ | 'complex-infinity'
137
+ /** The expression has an imaginary part or is NaN */
138
+ | 'unsigned';
8
139
  /**
9
140
  * :::info[THEORY OF OPERATIONS]
10
141
  *
@@ -19,7 +150,8 @@ import './serialize';
19
150
  * having to check what kind of instance they are before manipulating them.
20
151
  * :::
21
152
  *
22
- * To get a boxed expression, use `ce.box()` or `ce.parse()`.
153
+ * To get a boxed expression from a LaTeX string use `ce.parse()`, or to
154
+ * get a boxed expression from a MathJSON expression use `ce.box()`.
23
155
  *
24
156
  * @category Boxed Expression
25
157
  *
@@ -42,11 +174,12 @@ export interface BoxedExpression {
42
174
  *
43
175
  * @category Primitive Methods
44
176
  */
45
- valueOf(): number | Object | string | boolean;
177
+ valueOf(): number | any | string | boolean;
46
178
  /** From `Object.toString()`, return a string representation of the
47
179
  * expression. This string is suitable to be output to the console
48
- * for debugging, for example. To get a LaTeX representation of the
49
- * expression, use `expr.latex`.
180
+ * for debugging, for example. It is formatted as a ASCIIMath expression.
181
+ *
182
+ * To get a LaTeX representation of the expression, use `expr.latex`.
50
183
  *
51
184
  * Used when coercing a `BoxedExpression` to a `String`.
52
185
  *
@@ -60,6 +193,7 @@ export interface BoxedExpression {
60
193
  */
61
194
  print(): void;
62
195
  /** Similar to`expr.valueOf()` but includes a hint.
196
+ *
63
197
  * @category Primitive Methods
64
198
  */
65
199
  [Symbol.toPrimitive](hint: 'number' | 'string' | 'default'): number | string | null;
@@ -77,12 +211,15 @@ export interface BoxedExpression {
77
211
  * Will ignore any LaTeX metadata.
78
212
  */
79
213
  toLatex(options?: Partial<SerializeLatexOptions>): LatexString;
214
+ verbatimLatex?: string;
80
215
  /** If `true`, this expression is in a canonical form. */
81
216
  get isCanonical(): boolean;
82
217
  /** For internal use only, set when a canonical expression is created.
83
218
  * @internal
84
219
  */
85
220
  set isCanonical(val: boolean);
221
+ /** If `true`, this expression is in a structural form. */
222
+ get isStructural(): boolean;
86
223
  /** MathJSON representation of this expression.
87
224
  *
88
225
  * This representation always use shorthands when possible. Metadata is not
@@ -93,7 +230,7 @@ export interface BoxedExpression {
93
230
  * The expression is represented exactly and no sugaring is applied. For
94
231
  * example, `["Power", "x", 2]` is not represented as `["Square", "x"]`.
95
232
  *
96
- * For more control over the serialization, use `ce.serialize()`.
233
+ * For more control over the serialization, use `expr.toMathJson()`.
97
234
  *
98
235
  * :::info[Note]
99
236
  * Applicable to canonical and non-canonical expressions.
@@ -103,15 +240,19 @@ export interface BoxedExpression {
103
240
  readonly json: Expression;
104
241
  /**
105
242
  * The scope in which this expression has been defined.
106
- * Is null when the expression is not canonical.
243
+ *
244
+ * Is `null` when the expression is not canonical.
107
245
  */
108
246
  readonly scope: RuntimeScope | null;
109
- /** From `Object.is()`. Equivalent to `BoxedExpression.isSame()`
247
+ /**
248
+ * Equivalent to `BoxedExpression.isSame()` but the argument can be
249
+ * a JavaScript primitive. For example, `expr.is(2)` is equivalent to
250
+ * `expr.isSame(ce.number(2))`.
110
251
  *
111
252
  * @category Primitive Methods
112
253
  *
113
254
  */
114
- is(rhs: unknown): boolean;
255
+ is(rhs: any): boolean;
115
256
  /** @internal */
116
257
  readonly hash: number;
117
258
  /** LaTeX representation of this expression.
@@ -119,7 +260,7 @@ export interface BoxedExpression {
119
260
  * If the expression was parsed from LaTeX, the LaTeX representation is
120
261
  * the same as the input LaTeX.
121
262
  *
122
- * Otherwise, the serialization can be customized with `ComputeEngine.latexOptions`
263
+ * To customize the serialization, use `expr.toLatex()`.
123
264
  *
124
265
  * :::info[Note]
125
266
  * Applicable to canonical and non-canonical expressions.
@@ -141,11 +282,16 @@ export interface BoxedExpression {
141
282
  * :::info[Note]
142
283
  * Applicable to canonical and non-canonical expressions.
143
284
  * :::
144
-
145
- * @category Symbol Expression
285
+ *
286
+ * @category Symbol Expression
146
287
  *
147
288
  */
148
289
  readonly symbol: string | null;
290
+ /**
291
+ * @category Symbol Expression
292
+ *
293
+ */
294
+ readonly tensor: null | AbstractTensor<'expression'>;
149
295
  /** If this expression is a string, return the value of the string.
150
296
  * Otherwise, return `null`.
151
297
  *
@@ -157,14 +303,14 @@ export interface BoxedExpression {
157
303
  *
158
304
  */
159
305
  readonly string: string | null;
160
- /** All the subexpressions matching the head
306
+ /** All the subexpressions matching the named operator, recursively.
161
307
  *
162
308
  * :::info[Note]
163
309
  * Applicable to canonical and non-canonical expressions.
164
310
  * :::
165
311
  *
166
312
  */
167
- getSubexpressions(head: string): ReadonlyArray<BoxedExpression>;
313
+ getSubexpressions(name: string): ReadonlyArray<BoxedExpression>;
168
314
  /** All the subexpressions in this expression, recursively
169
315
  *
170
316
  * :::info[Note]
@@ -195,7 +341,10 @@ export interface BoxedExpression {
195
341
  *
196
342
  */
197
343
  readonly freeVariables: ReadonlyArray<string>;
198
- /** All the `["Error"]` subexpressions
344
+ /** All the `["Error"]` subexpressions.
345
+ *
346
+ * If an expression includes an error, the expression is also an error.
347
+ * In that case, the `this.isValid` property is `false`.
199
348
  *
200
349
  * :::info[Note]
201
350
  * Applicable to canonical and non-canonical expressions.
@@ -203,22 +352,34 @@ export interface BoxedExpression {
203
352
  *
204
353
  */
205
354
  readonly errors: ReadonlyArray<BoxedExpression>;
206
- /** All boxed expressions have a head.
207
- *
208
- * If not a function this can be `Symbol`, `String`, `Number` or `Dictionary`.
209
- *
210
- * If the head expression can be represented as a string, it is returned
211
- * as a string.
355
+ /** `true` if this expression or any of its subexpressions is an `["Error"]`
356
+ * expression.
212
357
  *
213
358
  * :::info[Note]
214
- * Applicable to canonical and non-canonical expressions. The head
215
- * of a non-canonical expression may be different than the head of its
216
- * canonical counterpart. For example the canonical counterpart of `["Divide", 5, 7]` is `["Rational", 5, 7]`.
359
+ * Applicable to canonical and non-canonical expressions. For
360
+ * non-canonical expression, this may indicate a syntax error while parsing
361
+ * LaTeX. For canonical expression, this may indicate argument type
362
+ * mismatch, or missing or unexpected arguments.
217
363
  * :::
218
-
219
- */
220
- readonly head: BoxedExpression | string;
221
- /** The list of arguments of the function, its "tail".
364
+ *
365
+ * @category Symbol Expression
366
+ *
367
+ */
368
+ readonly isValid: boolean;
369
+ /**
370
+ * The name of the operator of the expression.
371
+ *
372
+ * For example, the name of the operator of `["Add", 2, 3]` is `"Add"`.
373
+ *
374
+ * A string literal has a `"String"` operator.
375
+ *
376
+ * A symbol has a `"Symbol"` operator.
377
+ *
378
+ * A number has a `"Number"`, `"Real"`, `"Rational"` or `"Integer"` operator.
379
+ *
380
+ */
381
+ readonly operator: string;
382
+ /** The list of operands of the function.
222
383
  *
223
384
  * If the expression is not a function, return `null`.
224
385
  *
@@ -243,7 +404,9 @@ export interface BoxedExpression {
243
404
  *
244
405
  */
245
406
  readonly nops: number;
246
- /** First operand, i.e.`this.ops[0]`
407
+ /** First operand, i.e.`this.ops[0]`.
408
+ *
409
+ * If there is no first operand, return the symbol `Nothing`.
247
410
  *
248
411
  * :::info[Note]
249
412
  * Applicable to canonical and non-canonical expressions.
@@ -255,6 +418,8 @@ export interface BoxedExpression {
255
418
  */
256
419
  readonly op1: BoxedExpression;
257
420
  /** Second operand, i.e.`this.ops[1]`
421
+ *
422
+ * If there is no second operand, return the symbol `Nothing`.
258
423
  *
259
424
  * :::info[Note]
260
425
  * Applicable to canonical and non-canonical expressions.
@@ -266,6 +431,8 @@ export interface BoxedExpression {
266
431
  */
267
432
  readonly op2: BoxedExpression;
268
433
  /** Third operand, i.e. `this.ops[2]`
434
+ *
435
+ * If there is no third operand, return the symbol `Nothing`.
269
436
  *
270
437
  * :::info[Note]
271
438
  * Applicable to canonical and non-canonical expressions.
@@ -276,37 +443,9 @@ export interface BoxedExpression {
276
443
  *
277
444
  */
278
445
  readonly op3: BoxedExpression;
279
- /** `true` if this expression or any of its subexpressions is an `["Error"]`
280
- * expression.
281
- *
282
- * :::info[Note]
283
- * Applicable to canonical and non-canonical expressions. For
284
- * non-canonical expression, this may indicate a syntax error while parsing
285
- * LaTeX. For canonical expression, this may indicate argument domain
286
- * mismatch, or missing or unexpected arguments.
287
- * :::
288
- *
289
- * @category Symbol Expression
290
- *
291
- */
292
- readonly isValid: boolean;
293
- /**
294
- * An exact value is not further transformed when evaluated. To get an
295
- * approximate evaluation of an exact value, use `.N()`.
296
- *
297
- * Exact numbers are:
298
- * - rationals (including integers)
299
- * - complex numbers with integer real and imaginary parts (Gaussian integers)
300
- * - square root of rationals
301
- *
302
- * Non-exact values includes:
303
- * - numbers with a fractional part
304
- * - complex numbers with a real or imaginary fractional part
305
- *
306
- */
307
- readonly isExact: boolean;
308
446
  /** If true, the value of the expression never changes and evaluating it has
309
447
  * no side-effects.
448
+ *
310
449
  * If false, the value of the expression may change, if the
311
450
  * value of other expression changes or for other reasons.
312
451
  *
@@ -320,7 +459,17 @@ export interface BoxedExpression {
320
459
  * :::
321
460
  */
322
461
  readonly isPure: boolean;
323
- /** True if the expression is a constant, that is a symbol with an immutable value */
462
+ /**
463
+ * True if the the value of the expression does not depend on the value of
464
+ * any other expression.
465
+ *
466
+ * For example, a number literal, a symbol with a constant value.
467
+ * - `2` is constant
468
+ * - `Pi` is constant
469
+ * - `["Add", "Pi", 2]` is constant
470
+ * - `x` is not constant
471
+ * - `["Add", "x", 2]` is not constant
472
+ */
324
473
  readonly isConstant: boolean;
325
474
  /**
326
475
  * Return the canonical form of this expression.
@@ -340,11 +489,31 @@ export interface BoxedExpression {
340
489
  *
341
490
  */
342
491
  get canonical(): BoxedExpression;
492
+ /**
493
+ * Return the structural form of this expression.
494
+ *
495
+ * Some expressions, such as rational numbers, are represented with
496
+ * a `BoxedExpression` object. In some cases, for example when doing a
497
+ * structural comparison of two expressions, it is useful to have a
498
+ * structural representation of the expression where the rational numbers
499
+ * is represented by a function expression instead.
500
+ *
501
+ * If there is a structural representation of the expression, return it,
502
+ * otherwise return `this`.
503
+ *
504
+ */
505
+ get structural(): BoxedExpression;
343
506
  /**
344
507
  * Replace all the symbols in the expression as indicated.
345
508
  *
346
509
  * Note the same effect can be achieved with `this.replace()`, but
347
- * using `this.subs()` is more efficient, and simpler.
510
+ * using `this.subs()` is more efficient, and simpler, but limited
511
+ * to replacing symbols.
512
+ *
513
+ * The result is bound to the current scope, not to `this.scope`.
514
+ *
515
+ * If `options.canonical` is not set, the result is canonical if `this`
516
+ * is canonical.
348
517
  *
349
518
  * :::info[Note]
350
519
  * Applicable to canonical and non-canonical expressions.
@@ -355,38 +524,42 @@ export interface BoxedExpression {
355
524
  canonical?: CanonicalOptions;
356
525
  }): BoxedExpression;
357
526
  /**
358
- * Recursively replace all the terms in the expression as indicated.
527
+ * Recursively replace all the subexpressions in the expression as indicated.
359
528
  *
360
- * To remove a subexpression, return an empty Sequence expression.
529
+ * To remove a subexpression, return an empty `["Sequence"]` expression.
361
530
  *
362
531
  * The canonical option is applied to each function subexpression after
363
532
  * the substitution is applied.
364
533
  *
365
- * **Default**: `{canonical: true, recursive: true}`
534
+ * If no `options.canonical` is set, the result is canonical if `this`
535
+ * is canonical.
536
+ *
537
+ * **Default**: `{ canonical: this.isCanonical, recursive: true }`
366
538
  */
367
539
  map(fn: (expr: BoxedExpression) => BoxedExpression, options?: {
368
540
  canonical: CanonicalOptions;
369
541
  recursive?: boolean;
370
542
  }): BoxedExpression;
371
543
  /**
372
- * Transform the expression by applying the rules:
544
+ * Transform the expression by applying one or more replacement rules:
373
545
  *
374
- * If the expression matches the `match` pattern, replace it with
375
- * the `replace` pattern.
546
+ * - If the expression matches the `match` pattern and the `condition`
547
+ * predicate is true, replace it with the `replace` pattern.
376
548
  *
377
- * If no rules apply, return `null`.
549
+ * - If no rules apply, return `null`.
378
550
  *
379
- * See also `subs` for a simple substitution.
551
+ * See also `expr.subs()` for a simple substitution of symbols.
380
552
  *
553
+ * If `options.canonical` is not set, the result is canonical if `this`
554
+ * is canonical.
381
555
  *
382
556
  * :::info[Note]
383
- * Applicable to canonical and non-canonical expressions. If the
384
- * expression is non-canonical, the result is also non-canonical.
557
+ * Applicable to canonical and non-canonical expressions.
385
558
  * :::
386
559
  */
387
- replace(rules: BoxedRuleSet | Rule | Rule[], options?: ReplaceOptions): null | BoxedExpression;
560
+ replace(rules: BoxedRuleSet | Rule | Rule[], options?: Partial<ReplaceOptions>): null | BoxedExpression;
388
561
  /**
389
- * True if the expression includes a symbol `v` or a function head `v`.
562
+ * True if the expression includes a symbol `v` or a function operator `v`.
390
563
  *
391
564
  * :::info[Note]
392
565
  * Applicable to canonical and non-canonical expressions.
@@ -395,7 +568,9 @@ export interface BoxedExpression {
395
568
  has(v: string | string[]): boolean;
396
569
  /** Structural/symbolic equality (weak equality).
397
570
  *
398
- * `ce.parse('1+x').isSame(ce.parse('x+1'))` is `false`
571
+ * `ce.parse('1+x').isSame(ce.parse('x+1'))` is `false`.
572
+ *
573
+ * See `expr.isEqual()` for mathematical equality.
399
574
  *
400
575
  * :::info[Note]
401
576
  * Applicable to canonical and non-canonical expressions.
@@ -404,6 +579,12 @@ export interface BoxedExpression {
404
579
  * @category Relational Operator
405
580
  */
406
581
  isSame(rhs: BoxedExpression): boolean;
582
+ /**
583
+ * Return this expression expressed as a numerator and denominator.
584
+ */
585
+ get numerator(): BoxedExpression;
586
+ get denominator(): BoxedExpression;
587
+ get numeratorDenominator(): [BoxedExpression, BoxedExpression];
407
588
  /**
408
589
  * If this expression matches `pattern`, return a substitution that makes
409
590
  * `pattern` equal to `this`. Otherwise return `null`.
@@ -422,7 +603,7 @@ export interface BoxedExpression {
422
603
  * :::
423
604
  *
424
605
  */
425
- match(pattern: Decimal | Complex | [num: number, denom: number] | SemiBoxedExpression | BoxedExpression, options?: PatternMatchOptions): BoxedSubstitution | null;
606
+ match(pattern: BoxedExpression, options?: PatternMatchOptions): BoxedSubstitution | null;
426
607
  /**
427
608
  * "Not a Number".
428
609
  *
@@ -437,119 +618,199 @@ export interface BoxedExpression {
437
618
  */
438
619
  readonly isNaN: boolean | undefined;
439
620
  /**
440
- * The numeric value of this expression is 0.
621
+ * The numeric value of this expression is `±Infinity` or Complex Infinity
441
622
  *
442
623
  * @category Numeric Expression
443
624
  */
444
- readonly isZero: boolean | undefined;
445
- /**
446
- * The numeric value of this expression is not 0.
625
+ readonly isInfinity: boolean | undefined;
626
+ /** This expression is a number, but not `±Infinity`, 'ComplexInfinity` or
627
+ * `NaN`
628
+ *
447
629
  * @category Numeric Expression
448
630
  */
449
- readonly isNotZero: boolean | undefined;
631
+ readonly isFinite: boolean | undefined;
450
632
  /**
451
- * The numeric value of this expression is not 1.
452
633
  * @category Numeric Expression
453
634
  */
454
- readonly isOne: boolean | undefined;
635
+ readonly isEven: boolean | undefined;
455
636
  /**
456
- * The numeric value of this expression is not -1.
457
637
  * @category Numeric Expression
458
638
  */
459
- readonly isNegativeOne: boolean | undefined;
460
- /** The numeric value of this expression is ±Infinity or Complex Infinity
639
+ readonly isOdd: boolean | undefined;
640
+ /**
641
+ * Return the value of this expression, if a number literal.
642
+ *
643
+ * Note it is possible for `this.numericValue` to be `null`, and for
644
+ * `this.isNotZero` to be true. For example, when a symbol has been
645
+ * defined with an assumption.
646
+ *
647
+ * Conversely, `this.isNumber` may be true even if `numericValue` is `null`,
648
+ * example the symbol `Pi` return `true` for `isNumber` but `numericValue` is
649
+ * `null`. Its value can be accessed with `.N().numericValue`.
650
+ *
651
+ * To check if an expression is a number literal, use `this.isNumberLiteral`.
652
+ * If `this.isNumberLiteral` is `true`, `this.numericValue` is not `null`
461
653
  *
462
654
  * @category Numeric Expression
655
+ *
463
656
  */
464
- readonly isInfinity: boolean | undefined;
465
- /** This expression is a number, but not ±Infinity and not `NaN`
657
+ readonly numericValue: number | NumericValue | null;
658
+ /**
659
+ * Return `true` if this expression is a number literal, for example
660
+ * `2`, `3.14`, `1/2`, `√2` etc.
661
+ *
662
+ * This is equivalent to checking if `this.numericValue` is not `null`.
466
663
  *
467
664
  * @category Numeric Expression
665
+ *
468
666
  */
469
- readonly isFinite: boolean | undefined;
667
+ readonly isNumberLiteral: boolean;
470
668
  /**
471
- * @category Numeric Expression
669
+ * Return `true` if this expression is a function expression.
670
+ *
671
+ * If `true`, `this.ops` is not `null`, and `this.operator` is the name
672
+ * of the function.
472
673
  */
473
- readonly isEven: boolean | undefined;
674
+ readonly isFunctionExpression: boolean;
474
675
  /**
676
+ * If this expression is a number literal or a symbol with a value that
677
+ * is a number literal, return the real part of the value.
678
+ *
679
+ * If the expression is not a number literal, or a symbol with a value
680
+ * that is a number literal, return `NaN` (not a number).
681
+ *
475
682
  * @category Numeric Expression
476
683
  */
477
- readonly isOdd: boolean | undefined;
684
+ readonly re: number;
478
685
  /**
686
+ * If this expression is a number literal or a symbol with a value that
687
+ * is a number literal, return the imaginary part of the value. If the value
688
+ * is a real number, the imaginary part is 0.
689
+ *
690
+ * If the expression is not a number literal, or a symbol with a value
691
+ * that is a number literal, return `NaN` (not a number).
692
+ *
479
693
  * @category Numeric Expression
480
694
  */
481
- readonly isPrime: boolean | undefined;
695
+ readonly im: number;
482
696
  /**
697
+ * If this expression is a number literal or a symbol with a value that
698
+ * is a number literal, return the real part of the value as a `BigNum`.
699
+ *
700
+ * If the value is not available as a bignum return `undefined`. That is,
701
+ * the value is not upconverted to a bignum.
702
+ *
703
+ * To get the real value either as a bignum or a number, use
704
+ * `this.bignumRe ?? this.re`. When using this pattern, the value is
705
+ * returned as a bignum if available, otherwise as a number or NaN if
706
+ * the value is not a number literal or a symbol with a value that is a
707
+ * number literal.
708
+ *
483
709
  * @category Numeric Expression
710
+ *
484
711
  */
485
- readonly isComposite: boolean | undefined;
712
+ readonly bignumRe: BigNum | undefined;
486
713
  /**
487
- * Return the value of this expression, if a number literal.
714
+ * If this expression is a number literal, return the imaginary part as a
715
+ * `BigNum`.
488
716
  *
489
- * Note it is possible for `numericValue` to be `null`, and for `isNotZero`
490
- * to be true. For example, when a symbol has been defined with an assumption.
717
+ * It may be 0 if the number is real.
491
718
  *
492
- * Conversely, `isNumber` may be true even if `numericValue` is `null`,
493
- * example the symbol `Pi` return true for `isNumber` but `numericValue` is
494
- * `null`. Its value can be accessed with `.value.numericValue`
719
+ * If the expression is not a number literal or the value is not available
720
+ * as a bignum return `undefined`. That is, the value is not upconverted
721
+ * to a bignum.
495
722
  *
496
- * @category Numeric Expression
723
+ * To get the imaginary value either as a bignum or a number, use
724
+ * `this.bignumIm ?? this.im`. When using this pattern, the value is
725
+ * returned as a bignum if available, otherwise as a number or NaN if
726
+ * the value is not a number literal or a symbol with a value that is a
727
+ * number literal.
497
728
  *
729
+ * @category Numeric Expression
498
730
  */
499
- readonly numericValue: number | Decimal | Complex | Rational | null;
500
- /** The shape describes the axis of the expression.
731
+ readonly bignumIm: BigNum | undefined;
732
+ /**
733
+ * Attempt to factor a numeric coefficient `c` and a `rest` out of a
734
+ * canonical expression such that `rest.mul(c)` is equal to `this`.
735
+ *
736
+ * Attempts to make `rest` a positive value (i.e. pulls out negative sign).
737
+ *
738
+ * For example:
739
+ *
740
+ * ['Multiply', 2, 'x', 3, 'a']
741
+ * -> [NumericValue(6), ['Multiply', 'x', 'a']]
742
+ *
743
+ * ['Divide', ['Multiply', 2, 'x'], ['Multiply', 3, 'y', 'a']]
744
+ * -> [NumericValue({rational: [2, 3]}), ['Divide', 'x', ['Multiply, 'y', 'a']]]
745
+ */
746
+ toNumericValue(): [NumericValue, BoxedExpression];
747
+ neg(): BoxedExpression;
748
+ inv(): BoxedExpression;
749
+ abs(): BoxedExpression;
750
+ add(rhs: number | BoxedExpression): BoxedExpression;
751
+ sub(rhs: BoxedExpression): BoxedExpression;
752
+ mul(rhs: NumericValue | number | BoxedExpression): BoxedExpression;
753
+ div(rhs: number | BoxedExpression): BoxedExpression;
754
+ pow(exp: number | BoxedExpression): BoxedExpression;
755
+ root(exp: number | BoxedExpression): BoxedExpression;
756
+ sqrt(): BoxedExpression;
757
+ ln(base?: number | BoxedExpression): BoxedExpression;
758
+ /**
759
+ *
760
+ * The shape describes the axis of the expression.
761
+ *
501
762
  * When the expression is a scalar (number), the shape is `[]`.
502
- * When the expression is a vector, the shape is `[n]`.
503
- * When the expression is a matrix, the shape is `[n, m]`.
763
+ *
764
+ * When the expression is a vector of length `n`, the shape is `[n]`.
765
+ *
766
+ * When the expression is a `n` by `m` matrix, the shape is `[n, m]`.
504
767
  */
505
768
  readonly shape: number[];
506
- /** Return 0 for a scalar, 1 for a vector, 2 for a matrix, > 2 for a multidimensional matrix. It's the length of `expr.shape` */
769
+ /** Return 0 for a scalar, 1 for a vector, 2 for a matrix, > 2 for
770
+ * a multidimensional matrix.
771
+ *
772
+ * The rank is equivalent to the length of `expr.shape` */
507
773
  readonly rank: number;
508
774
  /**
509
- * Return the following, depending on the value of this expression:
510
- *
511
- * * `-1` if it is < 0
512
- * * `0` if it is = 0
513
- * * `+1` if it is > 0
514
- * * `undefined` this value may be positive, negative or zero. We don't know
515
- * right now (a symbol with an Integer domain, but no currently assigned
516
- * value, for example)
517
- * * `null` this value will never be positive, negative or zero (`NaN`,
518
- * a string or a complex number for example)
775
+ * Return the sign of the expression.
519
776
  *
520
777
  * Note that complex numbers have no natural ordering,
521
- * so if the value is a complex number, `sgn` is either 0, or `null`
778
+ * so if the value is an imaginary number (a complex number with a non-zero
779
+ * imaginary part), `this.sgn` will return `unsigned`.
522
780
  *
523
781
  * If a symbol, this does take assumptions into account, that is `this.sgn`
524
- * will return `1` if `isPositive` is `true`, even if this expression has
525
- * no value
782
+ * will return `positive` if the symbol is assumed to be positive
783
+ * (using `ce.assume()`).
526
784
  *
527
785
  * @category Numeric Expression
528
786
  *
529
787
  */
530
- readonly sgn: -1 | 0 | 1 | undefined | null;
788
+ readonly sgn: Sign | undefined;
531
789
  /** If the expressions cannot be compared, return `undefined`
532
790
  *
533
791
  * The numeric value of both expressions are compared.
534
792
  *
793
+ * The expressions are evaluated before being compared, which may be
794
+ * expensive.
795
+ *
535
796
  * @category Relational Operator
536
797
  */
537
- isLess(rhs: BoxedExpression): boolean | undefined;
798
+ isLess(other: number | BoxedExpression): boolean | undefined;
538
799
  /**
539
800
  * The numeric value of both expressions are compared.
540
801
  * @category Relational Operator
541
802
  */
542
- isLessEqual(rhs: BoxedExpression): boolean | undefined;
803
+ isLessEqual(other: number | BoxedExpression): boolean | undefined;
543
804
  /**
544
805
  * The numeric value of both expressions are compared.
545
806
  * @category Relational Operator
546
807
  */
547
- isGreater(rhs: BoxedExpression): boolean | undefined;
808
+ isGreater(other: number | BoxedExpression): boolean | undefined;
548
809
  /**
549
810
  * The numeric value of both expressions are compared.
550
811
  * @category Relational Operator
551
812
  */
552
- isGreaterEqual(rhs: BoxedExpression): boolean | undefined;
813
+ isGreaterEqual(other: number | BoxedExpression): boolean | undefined;
553
814
  /** The numeric value of this expression is > 0, same as `isGreater(0)`
554
815
  *
555
816
  * @category Numeric Expression
@@ -570,34 +831,6 @@ export interface BoxedExpression {
570
831
  * @category Numeric Expression
571
832
  */
572
833
  readonly isNonPositive: boolean | undefined;
573
- /** The keys of the dictionary.
574
- *
575
- * If this expression not a dictionary, return `null`
576
- *
577
- * @category Dictionary Expression
578
- *
579
- */
580
- readonly keys: IterableIterator<string> | null;
581
- /**
582
- *
583
- * @category Dictionary Expression
584
- */
585
- readonly keysCount: number;
586
- /**
587
- * If this expression is a dictionary, return the value of the `key` entry.
588
- *
589
- * @category Dictionary Expression
590
- *
591
- */
592
- getKey(key: string): BoxedExpression | undefined;
593
- /**
594
- * If this expression is a dictionary, return true if the
595
- * dictionary has a `key` entry.
596
- *
597
- * @category Dictionary Expression
598
- *
599
- */
600
- hasKey(key: string): boolean;
601
834
  /** Wikidata identifier.
602
835
  *
603
836
  * :::info[Note]
@@ -616,7 +849,7 @@ export interface BoxedExpression {
616
849
  */
617
850
  readonly description: undefined | string[];
618
851
  /** An optional URL pointing to more information about the symbol or
619
- * function head.
852
+ * function operator.
620
853
  *
621
854
  * :::info[Note]
622
855
  * `undefined` if not a canonical expression.
@@ -633,8 +866,8 @@ export interface BoxedExpression {
633
866
  */
634
867
  readonly complexity: number | undefined;
635
868
  /**
636
- * For symbols and functions, a possible definition associated with the
637
- * expression. `baseDefinition` is the base class of symbol and function
869
+ * For symbols and functions, a definition associated with the
870
+ * expression. `this.baseDefinition` is the base class of symbol and function
638
871
  * definition.
639
872
  *
640
873
  * :::info[Note]
@@ -644,7 +877,7 @@ export interface BoxedExpression {
644
877
  */
645
878
  readonly baseDefinition: BoxedBaseDefinition | undefined;
646
879
  /**
647
- * For functions, a possible definition associated with the expression.
880
+ * For functions, a definition associated with the expression.
648
881
  *
649
882
  * :::info[Note]
650
883
  * `undefined` if not a canonical expression or not a function.
@@ -653,7 +886,7 @@ export interface BoxedExpression {
653
886
  */
654
887
  readonly functionDefinition: BoxedFunctionDefinition | undefined;
655
888
  /**
656
- * For symbols, a possible definition associated with the expression.
889
+ * For symbols, a definition associated with the expression.
657
890
  *
658
891
  * Return `undefined` if not a symbol
659
892
  *
@@ -661,17 +894,17 @@ export interface BoxedExpression {
661
894
  readonly symbolDefinition: BoxedSymbolDefinition | undefined;
662
895
  /**
663
896
  *
664
- * Infer the domain of this expression.
897
+ * Infer the type of this expression.
665
898
  *
666
- * If the domain of this expression is already known, return `false`.
899
+ * If the type of this expression is already known, return `false`.
667
900
  *
668
- * If the domain was not set, set it to the inferred domain, return `true`
669
- * If the domain was previously inferred, adjust it by widening it,
901
+ * If the type was not set, set it to the inferred type, return `true`
902
+ * If the type was previously inferred, adjust it by widening it,
670
903
  * return `true`
671
904
  *
672
905
  * @internal
673
906
  */
674
- infer(domain: BoxedDomain): boolean;
907
+ infer(t: Type): boolean;
675
908
  /**
676
909
  * Update the definition associated with this expression, using the
677
910
  * current scope (`ce.context`).
@@ -690,16 +923,13 @@ export interface BoxedExpression {
690
923
  */
691
924
  reset(): void;
692
925
  /**
693
- * Return a simpler form of the canonical form of this expression.
926
+ * Return a simpler form of this expression.
694
927
  *
695
928
  * A series of rewriting rules are applied repeatedly, until no more rules
696
929
  * apply.
697
930
  *
698
- * If a custom `simplify` handler is associated with this function
699
- * definition, it is invoked.
700
- *
701
931
  * The values assigned to symbols and the assumptions about symbols may be
702
- * used, for example `arg.isInteger` or `arg.isPositive`.
932
+ * used, for example `expr.isInteger` or `expr.isPositive`.
703
933
  *
704
934
  * No calculations involving decimal numbers (numbers that are not
705
935
  * integers) are performed but exact calculations may be performed,
@@ -707,10 +937,12 @@ export interface BoxedExpression {
707
937
  *
708
938
  * \\( \sin(\frac{\pi}{4}) \longrightarrow \frac{\sqrt{2}}{2} \\).
709
939
  *
710
- * The result is in canonical form.
940
+ * The result is canonical.
941
+ *
942
+ * To manipulate symbolically non-canonical expressions, use `expr.replace()`.
711
943
  *
712
944
  */
713
- simplify(options?: SimplifyOptions): BoxedExpression;
945
+ simplify(options?: Partial<SimplifyOptions>): BoxedExpression;
714
946
  /**
715
947
  * Return the value of the canonical form of this expression.
716
948
  *
@@ -724,11 +956,11 @@ export interface BoxedExpression {
724
956
  * example modifying the `ComputeEngine` environment, such as its set of
725
957
  * assumptions.
726
958
  *
727
- * Only exact calculations are performed, no approximate calculations on
728
- * decimal numbers (non-integer numbers). Constants, rational numbers and
729
- * square root of rational numbers are preserved.
959
+ * The result may be a rational number or the product of a rational number
960
+ * and the square root of an integer.
730
961
  *
731
- * To perform approximate calculations, use `expr.N()` instead.
962
+ * To perform approximate calculations, use `expr.N()` instead,
963
+ * or set `options.numericApproximation` to `true`.
732
964
  *
733
965
  * The result of `expr.evaluate()` may be the same as `expr.simplify()`.
734
966
  *
@@ -741,8 +973,8 @@ export interface BoxedExpression {
741
973
  * Any necessary calculations, including on decimal numbers (non-integers),
742
974
  * are performed.
743
975
  *
744
- * The calculations are performed according to the `numericMode` and
745
- * `precision` properties of the `ComputeEngine`.
976
+ * The calculations are performed according to the
977
+ * `precision` property of the `ComputeEngine`.
746
978
  *
747
979
  * To only perform exact calculations, use `this.evaluate()` instead.
748
980
  *
@@ -751,10 +983,35 @@ export interface BoxedExpression {
751
983
  *
752
984
  * The result is in canonical form.
753
985
  */
754
- N(options?: NOptions): BoxedExpression;
986
+ N(): BoxedExpression;
987
+ /**
988
+ * Compile the expression to a JavaScript function.
989
+ *
990
+ * The function takes an object as argument, with the keys being the
991
+ * symbols in the expression, and returns the value of the expression.
992
+ *
993
+ *
994
+ * ```javascript
995
+ * const expr = ce.parse('x^2 + y^2');
996
+ * const f = expr.compile('javascript');
997
+ * console.log(f({x: 2, y: 3}));
998
+ * ```
999
+ */
755
1000
  compile(to?: 'javascript', options?: {
756
1001
  optimize: ('simplify' | 'evaluate')[];
757
1002
  }): ((args: Record<string, any>) => any | undefined) | undefined;
1003
+ /**
1004
+ * If this is an equation, solve the equation for the variables in vars.
1005
+ * Otherwise, solve the equation `this = 0` for the variables in vars.
1006
+ *
1007
+ *
1008
+ * ```javascript
1009
+ * const expr = ce.parse('x^2 + 2*x + 1 = 0');
1010
+ * console.log(expr.solve('x'));
1011
+ * ```
1012
+ *
1013
+ *
1014
+ */
758
1015
  solve(vars: Iterable<string> | string | BoxedExpression | Iterable<BoxedExpression>): null | ReadonlyArray<BoxedExpression>;
759
1016
  /**
760
1017
  * Return a JavaScript primitive representing the value of this expression.
@@ -762,7 +1019,7 @@ export interface BoxedExpression {
762
1019
  * Equivalent to `expr.N().valueOf()`.
763
1020
  *
764
1021
  */
765
- get value(): number | boolean | string | Object | undefined;
1022
+ get value(): number | boolean | string | object | undefined;
766
1023
  /**
767
1024
  * Only the value of variables can be changed (symbols that are not
768
1025
  * constants).
@@ -774,7 +1031,7 @@ export interface BoxedExpression {
774
1031
  * :::
775
1032
  *
776
1033
  */
777
- set value(value: boolean | string | Decimal | Complex | {
1034
+ set value(value: boolean | string | BigNum | {
778
1035
  re: number;
779
1036
  im: number;
780
1037
  } | {
@@ -783,44 +1040,47 @@ export interface BoxedExpression {
783
1040
  } | number[] | BoxedExpression | number | undefined);
784
1041
  /**
785
1042
  *
786
- * The domain of the value of this expression.
787
- *
788
- * If a function expression, the domain of the value of the function
789
- * (the codomain of the function).
1043
+ * The type of the value of this expression.
790
1044
  *
791
- * If a symbol the domain of the value of the symbol.
1045
+ * If a function expression, the type of the value of the function
1046
+ * (the result type).
792
1047
  *
793
- * Use `expr.head` to determine if an expression is a symbol or function
794
- * expression.
795
- *
796
- * :::info[Note]
797
- * If non-canonical or not valid, return `undefined`.
798
- * :::
799
- *
800
- */
801
- get domain(): BoxedDomain | undefined;
802
- /** Modify the domain of a symbol.
1048
+ * If a symbol the type of the value of the symbol.
803
1049
  *
804
1050
  * :::info[Note]
805
- * If non-canonical does nothing
1051
+ * If not valid, return `"error"`.
1052
+ * If non-canonical, return `undefined`.
1053
+ * If the type is not known, return `"unknown"`.
806
1054
  * :::
807
1055
  *
808
1056
  */
809
- set domain(domain: DomainExpression | BoxedDomain | undefined);
1057
+ get type(): Type;
1058
+ set type(type: Type);
810
1059
  /** `true` if the value of this expression is a number.
811
1060
  *
812
- * `isExtendedComplex || isNaN` = `isReal || isImaginary || isInfinity || isNaN`
813
1061
  *
814
1062
  * Note that in a fateful twist of cosmic irony, `NaN` ("Not a Number")
815
1063
  * **is** a number.
816
1064
  *
817
- * @category Domain Properties
1065
+ * If `isNumber` is `true`, this indicates that evaluating the expression
1066
+ * will return a number.
1067
+ *
1068
+ * This does not indicate that the expression is a number literal. To check
1069
+ * if the expression is a number literal, use `expr.isNumberLiteral`.
1070
+ *
1071
+ * For example, the expression `["Add", 1, "x"]` is a number if "x" is a
1072
+ * number and `expr.isNumber` is `true`, but `isNumberLiteral` is `false`.
1073
+ *
1074
+ * @category Type Properties
818
1075
  */
819
1076
  readonly isNumber: boolean | undefined;
820
- /** The value of this expression is an element of the set ℤ: ...,-2, -1, 0, 1, 2...
1077
+ /**
821
1078
  *
1079
+ * The value of this expression is an element of the set ℤ: ...,-2, -1, 0, 1, 2...
822
1080
  *
823
- * @category Domain Properties
1081
+ * Note that ±∞ and NaN are not integers.
1082
+ *
1083
+ * @category Type Properties
824
1084
  *
825
1085
  */
826
1086
  readonly isInteger: boolean | undefined;
@@ -828,75 +1088,107 @@ export interface BoxedExpression {
828
1088
  *
829
1089
  * Note that every integer is also a rational.
830
1090
  *
1091
+ * This is equivalent to `this.type === "rational" || this.type === "integer"`
1092
+ *
1093
+ * Note that ±∞ and NaN are not rationals.
831
1094
  *
832
- * @category Domain Properties
1095
+ * @category Type Properties
833
1096
  *
834
1097
  */
835
1098
  readonly isRational: boolean | undefined;
836
1099
  /**
837
- * The value of this expression is a number that is the root of a non-zero
838
- * univariate polynomial with rational coefficients.
1100
+ * The value of this expression is a real number.
839
1101
  *
840
- * All integers and rational numbers are algebraic.
1102
+ * This is equivalent to `this.type === "rational" || this.type === "integer" || this.type === "real"`
841
1103
  *
842
- * Transcendental numbers, such as \\( \pi \\) or \\( e \\) are not algebraic.
1104
+ * Note that ±∞ and NaN are not real numbers.
843
1105
  *
1106
+ * @category Type Properties
1107
+ */
1108
+ readonly isReal: boolean | undefined;
1109
+ /** Mathematical equality (strong equality), that is the value
1110
+ * of this expression and the value of `other` are numerically equal.
844
1111
  *
845
- * @category Domain Properties
1112
+ * Both expressions are evaluated and the result is compared numerically.
846
1113
  *
847
- */
848
- readonly isAlgebraic: boolean | undefined;
849
- /**
850
- * The value of this expression is real number: finite and not imaginary.
1114
+ * Numbers whose difference is less than `engine.tolerance` are
1115
+ * considered equal. This tolerance is set when the `engine.precision` is
1116
+ * changed to be such that the last two digits are ignored.
851
1117
  *
852
- * `isFinite && !isImaginary`
1118
+ * The evaluations may be expensive operations. Other options to consider
1119
+ * to compare two expressions include:
1120
+ * - `expr.isSame(other)` for a structural comparison
1121
+ * - `expr.is(other)` for a comparison of a number literal
853
1122
  *
1123
+ * ## Examples
854
1124
  *
855
- * @category Domain Properties
856
- */
857
- readonly isReal: boolean | undefined;
858
- /** Real or ±Infinity
1125
+ * ```js
1126
+ * let expr = ce.parse('2 + 2');
1127
+ * console.log(expr.isEqual(4)); // true
1128
+ * console.log(expr.isSame(ce.parse(4))); // false
1129
+ * console.log(expr.is(4)); // false
859
1130
  *
860
- * `isReal || isInfinity`
1131
+ * expr = ce.parse('4');
1132
+ * console.log(expr.isEqual(4)); // true
1133
+ * console.log(expr.isSame(ce.parse(4))); // true
1134
+ * console.log(expr.is(4)); // true (fastest)
861
1135
  *
1136
+ * ```
862
1137
  *
863
- * @category Domain Properties
1138
+ * @category Relational Operator
864
1139
  */
865
- readonly isExtendedReal: boolean | undefined;
1140
+ isEqual(other: number | BoxedExpression): boolean | undefined;
866
1141
  /**
867
- * The value of this expression is a number, but not `NaN` or any Infinity
868
- *
869
- * `isReal || isImaginary`
1142
+ * Return true if the expression is a collection: a list, a vector, a matrix, a map, a tuple, etc...
1143
+ */
1144
+ isCollection: boolean;
1145
+ /**
1146
+ * If this is a collection, return true if the `rhs` expression is in the
1147
+ * collection.
870
1148
  *
1149
+ * Return `undefined` if the membership cannot be determined.
1150
+ */
1151
+ contains(rhs: BoxedExpression): boolean | undefined;
1152
+ /**
1153
+ * If this is a collection, return the number of elements in the collection.
871
1154
  *
872
- * @category Domain Properties
1155
+ * If the collection is infinite, return `Infinity`.
873
1156
  *
874
1157
  */
875
- readonly isComplex: boolean | undefined;
876
- /** `isReal || isImaginary || isInfinity`
1158
+ get size(): number;
1159
+ /**
1160
+ * If this is a collection, return an iterator over the elements of the collection.
877
1161
  *
1162
+ * If `start` is not specified, start from the first element.
878
1163
  *
879
- * @category Domain Properties
1164
+ * If `count` is not specified or negative, return all the elements from `start` to the end.
1165
+ *
1166
+ * ```js
1167
+ * const expr = ce.parse('[1, 2, 3, 4]');
1168
+ * for (const e of expr.each()) {
1169
+ * console.log(e);
1170
+ * }
1171
+ * ```
880
1172
  */
881
- readonly isExtendedComplex: boolean | undefined;
882
- /** The value of this expression is a number with a imaginary part
1173
+ each: (start?: number, count?: number) => Iterator<BoxedExpression, undefined>;
1174
+ /** If this is an indexable collection, return the element at the specified
1175
+ * index.
883
1176
  *
1177
+ * If the index is negative, return the element at index `size() + index + 1`.
884
1178
  *
885
- * @category Domain Properties
886
1179
  */
887
- readonly isImaginary: boolean | undefined;
888
- /** Mathematical equality (strong equality), that is the value
889
- * of this expression and of `rhs` are numerically equal.
890
- *
891
- * The numeric value of both expressions are compared.
1180
+ at(index: number): BoxedExpression | undefined;
1181
+ /** If this is a map or a tuple, return the value of the corresponding key.
892
1182
  *
893
- * Numbers whose difference is less than `engine.tolerance` are
894
- * considered equal. This tolerance is set when the `engine.precision` is
895
- * changed to be such that the last two digits are ignored.
1183
+ * If `key` is a `BoxedExpression`, it should be a string.
896
1184
  *
897
- * @category Relational Operator
898
1185
  */
899
- isEqual(rhs: BoxedExpression): boolean;
1186
+ get(key: string | BoxedExpression): BoxedExpression | undefined;
1187
+ /**
1188
+ * If this is an indexable collection, return the index of the first element
1189
+ * that matches the target expression.
1190
+ */
1191
+ indexOf(expr: BoxedExpression): number | undefined;
900
1192
  }
901
1193
  /** A semi boxed expression is a MathJSON expression which can include some
902
1194
  * boxed terms.
@@ -906,7 +1198,7 @@ export interface BoxedExpression {
906
1198
  *
907
1199
  * @category Boxed Expression
908
1200
  */
909
- export type SemiBoxedExpression = number | string | Decimal | Complex | MathJsonNumber | MathJsonString | MathJsonSymbol | MathJsonFunction | MathJsonDictionary | SemiBoxedExpression[] | BoxedExpression;
1201
+ export type SemiBoxedExpression = number | bigint | string | BigNum | MathJsonNumber | MathJsonString | MathJsonSymbol | MathJsonFunction | readonly [MathJsonIdentifier, ...SemiBoxedExpression[]] | BoxedExpression;
910
1202
  /**
911
1203
  * @category Definitions
912
1204
  *
@@ -922,96 +1214,108 @@ export interface BoxedBaseDefinition {
922
1214
  * This field is usually undefined, but its value is set by `getDefinition()`
923
1215
  */
924
1216
  scope: RuntimeScope | undefined;
1217
+ collection?: Partial<CollectionHandlers>;
925
1218
  /** When the environment changes, for example the numerical precision,
926
1219
  * call `reset()` so that any cached values can be recalculated.
927
1220
  */
928
- reset(): any;
1221
+ reset(): void;
929
1222
  }
930
1223
  /**
931
- * Use `contravariant` for the arguments of a function.
932
- * Use `covariant` for the result of a function.
933
- * Use `bivariant` to check the domain matches exactly.
1224
+ * These handlers compare two expressions.
934
1225
  *
935
- * @category Boxed Expression
936
- */
937
- export type DomainCompatibility = 'covariant' | 'contravariant' | 'bivariant' | 'invariant';
938
- /** A domain constructor is the head of a domain expression.
1226
+ * If only one of the handlers is provided, the other is derived from it.
939
1227
  *
940
- * @category Boxed Expression
1228
+ * Having both may be useful if comparing non-equality is faster than equality.
941
1229
  *
942
- */
943
- export type DomainConstructor = 'FunctionOf' | 'ListOf' | 'DictionaryOf' | 'TupleOf' | 'Intersection' | 'Union' | 'OptArg' | 'VarArg' | 'Covariant' | 'Contravariant' | 'Bivariant' | 'Invariant';
944
- /**
945
- * @noInheritDoc
1230
+ * @category Definitions
946
1231
  *
947
- * @category Boxed Expression
948
1232
  */
949
- export interface BoxedDomain extends BoxedExpression {
950
- get canonical(): BoxedDomain;
951
- get json(): Expression;
952
- /** True if a valid domain, and compatible with `dom`
953
- * `kind` is '"covariant"' by default, i.e. `this <: dom`
954
- */
955
- isCompatible(dom: BoxedDomain | DomainLiteral, kind?: DomainCompatibility): boolean;
956
- get base(): DomainLiteral;
957
- get ctor(): DomainConstructor | null;
958
- get params(): DomainExpression[];
959
- readonly isNumeric: boolean;
960
- readonly isFunction: boolean;
961
- }
1233
+ export type EqHandlers = {
1234
+ eq: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1235
+ neq: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1236
+ };
962
1237
  /**
963
- * The handlers are the primitive operations that can be performed on
1238
+ * These handlers are the primitive operations that can be performed on
964
1239
  * collections.
965
1240
  *
966
1241
  * There are two types of collections:
1242
+ *
967
1243
  * - finite collections, such as lists, tuples, sets, matrices, etc...
968
1244
  * The `size()` handler of finite collections returns the number of elements
1245
+ *
969
1246
  * - infinite collections, such as sequences, ranges, etc...
970
1247
  * The `size()` handler of infinite collections returns `Infinity`
971
- * Infinite collections are not indexable, they have no `at()` handler.
1248
+ * Infinite collections are not indexable: they have no `at()` handler.
972
1249
  *
973
1250
  * @category Definitions
974
1251
  */
975
1252
  export type CollectionHandlers = {
1253
+ /** Return the number of elements in the collection.
1254
+ *
1255
+ * An empty collection has a size of 0.
1256
+ */
1257
+ size: (collection: BoxedExpression) => number;
1258
+ /**
1259
+ * Return `true` if the target
1260
+ * expression is in the collection, `false` otherwise.
1261
+ */
1262
+ contains: (collection: BoxedExpression, target: BoxedExpression) => boolean;
976
1263
  /** Return an iterator
977
1264
  * - start is optional and is a 1-based index.
978
1265
  * - if start is not specified, start from index 1
979
1266
  * - count is optional and is the number of elements to return
980
- * - if count is not specified or negative, return all the elements from start to the endna
1267
+ * - if count is not specified or negative, return all the elements from
1268
+ * start to the end
981
1269
  *
982
1270
  * If there is a `keys()` handler, there is no `iterator()` handler.
983
1271
  *
984
1272
  * @category Definitions
985
1273
  */
986
- iterator: (expr: BoxedExpression, start?: number, count?: number) => Iterator<BoxedExpression, undefined>;
987
- /** Return the element at the specified index.
1274
+ iterator: (collection: BoxedExpression, start?: number, count?: number) => Iterator<BoxedExpression, undefined>;
1275
+ /**
1276
+ * Return the element at the specified index.
1277
+ *
988
1278
  * The first element is `at(1)`, the last element is `at(-1)`.
1279
+ *
989
1280
  * If the index is &lt;0, return the element at index `size() + index + 1`.
990
- * The index can also be a string for example for dictionaries.
1281
+ *
1282
+ * The index can also be a string for example for maps. The set of valid keys
1283
+ * is returned by the `keys()` handler.
1284
+ *
991
1285
  * If the index is invalid, return `undefined`.
992
1286
  */
993
- at: (expr: BoxedExpression, index: number | string) => undefined | BoxedExpression;
994
- /** Return the number of elements in the collection.
995
- * An empty collection has a size of 0.
996
- */
997
- size: (expr: BoxedExpression) => number;
1287
+ at: (collection: BoxedExpression, index: number | string) => undefined | BoxedExpression;
998
1288
  /**
999
- * If the collection is indexed by strings, return the valid values
1289
+ * If the collection can be indexed by strings, return the valid values
1000
1290
  * for the index.
1001
1291
  */
1002
- keys: (expr: BoxedExpression) => undefined | Iterator<string>;
1292
+ keys: (collection: BoxedExpression) => undefined | Iterable<string>;
1003
1293
  /**
1004
1294
  * Return the index of the first element that matches the target expression.
1295
+ *
1005
1296
  * The comparison is done using the `target.isEqual()` method.
1297
+ *
1006
1298
  * If the expression is not found, return `undefined`.
1299
+ *
1007
1300
  * If the expression is found, return the index, 1-based.
1008
- * If the expression is found multiple times, return the index of the first
1009
- * match.
1010
1301
  *
1011
- * From is the starting index for the search. If negative, start from the end
1012
- * and search backwards.
1302
+ * Return the index of the first match.
1303
+ *
1304
+ * `from` is the starting index for the search. If negative, start from
1305
+ * the end and search backwards.
1013
1306
  */
1014
- indexOf: (expr: BoxedExpression, target: BoxedExpression, from?: number) => number | string | undefined;
1307
+ indexOf: (collection: BoxedExpression, target: BoxedExpression, from?: number) => number | undefined;
1308
+ /**
1309
+ * Return `true` if all the elements of `target` are in `expr`.
1310
+ * Both `expr` and `target` are collections.
1311
+ * If strict is `true`, the subset must be strict, that is, `expr` must
1312
+ * have more elements than `target`.
1313
+ */
1314
+ subsetOf: (collection: BoxedExpression, target: BoxedExpression, strict: boolean) => boolean;
1315
+ /** Return the sign of all the elements of the collection. */
1316
+ eltsgn: (collection: BoxedExpression) => Sign | undefined;
1317
+ /** Return the widest type of all the elements in the collection */
1318
+ elttype: (collection: BoxedExpression) => Type | undefined;
1015
1319
  };
1016
1320
  /**
1017
1321
  * A function definition can have some flags to indicate specific
@@ -1019,6 +1323,17 @@ export type CollectionHandlers = {
1019
1323
  * @category Definitions
1020
1324
  */
1021
1325
  export type FunctionDefinitionFlags = {
1326
+ /**
1327
+ * If `true`, the arguments of the functions are held unevaluated.
1328
+ *
1329
+ * It will be up to the `evaluate()` handler to evaluate the arguments as
1330
+ * needed. This is conveninent to pass symbolic expressions as arguments
1331
+ * to functions without having to explicitly use a `Hold` expression.
1332
+ *
1333
+ * This also applies to the `canonical()` handler.
1334
+ *
1335
+ */
1336
+ hold: boolean;
1022
1337
  /** If `true`, the function is applied element by element to lists, matrices
1023
1338
  * (`["List"]` or `["Tuple"]` expressions) and equations (relational
1024
1339
  * operators).
@@ -1037,25 +1352,15 @@ export type FunctionDefinitionFlags = {
1037
1352
  * **Default**: `false`
1038
1353
  */
1039
1354
  commutative: boolean;
1040
- /** If `true`, when the function is univariate, `["f", ["Add", x, c]]` where `c`
1041
- * is constant, is simplified to `["Add", ["f", x], c]`.
1042
- *
1043
- * When the function is multivariate, additivity is considered only on the
1044
- * first argument: `["f", ["Add", x, c], y]` simplifies to `["Add", ["f", x, y], c]`.
1045
- *
1046
- * For example, `Log` is additive.
1047
- *
1048
- * **Default**: `false`
1049
- */
1050
- /** If `true`, when the function is univariate, `["f", ["Multiply", x, y]]`
1051
- * simplifies to `["Multiply", ["f", x], ["f", y]]`.
1355
+ /**
1356
+ * If `commutative` is `true`, the order of the arguments is determined by
1357
+ * this function.
1052
1358
  *
1053
- * When the function is multivariate, multiplicativity is considered only on the
1054
- * first argument: `["f", ["Multiply", x, y], z]` simplifies to
1055
- * `["Multiply", ["f", x, z], ["f", y, z]]`
1359
+ * If the function is not provided, the arguments are ordered by the
1360
+ * default order of the arguments.
1056
1361
  *
1057
- * **Default**: `false`
1058
1362
  */
1363
+ commutativeOrder: ((a: BoxedExpression, b: BoxedExpression) => number) | undefined;
1059
1364
  /** If `true`, when the function is univariate, `["f", ["Multiply", x, c]]`
1060
1365
  * simplifies to `["Multiply", ["f", x], c]` where `c` is constant
1061
1366
  *
@@ -1088,19 +1393,6 @@ export type FunctionDefinitionFlags = {
1088
1393
  * **Default:** `true`
1089
1394
  */
1090
1395
  pure: boolean;
1091
- /**
1092
- * An inert function evaluates directly to one of its argument, typically
1093
- * the first one. They may be used to provide formating hints, but do
1094
- * not affect simplification or evaluation.
1095
- *
1096
- * **Default:** false
1097
- */
1098
- inert: boolean;
1099
- /**
1100
- * All the arguments of a numeric function are numeric,
1101
- * and its value is numeric.
1102
- */
1103
- numeric: boolean;
1104
1396
  };
1105
1397
  /** @category Compiling */
1106
1398
  export type CompiledExpression = {
@@ -1108,34 +1400,35 @@ export type CompiledExpression = {
1108
1400
  [symbol: string]: BoxedExpression;
1109
1401
  }) => number | BoxedExpression;
1110
1402
  };
1111
- /**
1112
- * @category Definitions
1113
- *
1114
- */
1115
- export type BoxedFunctionSignature = {
1116
- inferredSignature: boolean;
1117
- params: BoxedDomain[];
1118
- optParams: BoxedDomain[];
1119
- restParam?: BoxedDomain;
1120
- result: BoxedDomain | ((ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => BoxedDomain | null | undefined);
1121
- canonical?: (ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => BoxedExpression | null;
1122
- simplify?: (ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => BoxedExpression | undefined;
1123
- evaluate?: (ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => BoxedExpression | undefined;
1124
- N?: (ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => BoxedExpression | undefined;
1125
- evalDimension?: (ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => BoxedExpression;
1126
- sgn?: (ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => -1 | 0 | 1 | undefined;
1127
- compile?: (expr: BoxedExpression) => CompiledExpression;
1128
- };
1129
1403
  /** @category Definitions */
1130
1404
  export type Hold = 'none' | 'all' | 'first' | 'rest' | 'last' | 'most';
1131
1405
  /**
1132
1406
  * @category Definitions
1133
1407
  *
1134
1408
  */
1135
- export type BoxedFunctionDefinition = BoxedBaseDefinition & Partial<CollectionHandlers> & FunctionDefinitionFlags & {
1409
+ export type BoxedFunctionDefinition = BoxedBaseDefinition & FunctionDefinitionFlags & {
1136
1410
  complexity: number;
1137
- hold: Hold;
1138
- signature: BoxedFunctionSignature;
1411
+ hold: boolean;
1412
+ inferredSignature: boolean;
1413
+ signature: Type;
1414
+ type?: (ops: ReadonlyArray<BoxedExpression>, options: {
1415
+ engine: IComputeEngine;
1416
+ }) => Type | TypeString | undefined;
1417
+ sgn?: (ops: ReadonlyArray<BoxedExpression>, options: {
1418
+ engine: IComputeEngine;
1419
+ }) => Sign | undefined;
1420
+ eq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1421
+ neq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1422
+ canonical?: (ops: ReadonlyArray<BoxedExpression>, options: {
1423
+ engine: IComputeEngine;
1424
+ }) => BoxedExpression | null;
1425
+ evaluate?: (ops: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
1426
+ engine: IComputeEngine;
1427
+ }) => BoxedExpression | undefined;
1428
+ evalDimension?: (ops: ReadonlyArray<BoxedExpression>, options: {
1429
+ engine: IComputeEngine;
1430
+ }) => BoxedExpression;
1431
+ compile?: (expr: BoxedExpression) => CompiledExpression;
1139
1432
  };
1140
1433
  /**
1141
1434
  * @category Definitions
@@ -1143,7 +1436,7 @@ export type BoxedFunctionDefinition = BoxedBaseDefinition & Partial<CollectionHa
1143
1436
  */
1144
1437
  export type SymbolAttributes = {
1145
1438
  /**
1146
- * If `true` the value of the symbol is constant. The value or domain of
1439
+ * If `true` the value of the symbol is constant. The value or type of
1147
1440
  * symbols with this attribute set to `true` cannot be changed.
1148
1441
  *
1149
1442
  * If `false`, the symbol is a variable.
@@ -1157,61 +1450,36 @@ export type SymbolAttributes = {
1157
1450
 
1158
1451
  <div className="symbols-table">
1159
1452
 
1160
- | Operation | `"never"` | `"simplify"` | `"evaluate"` | `"N"` |
1161
- | :--- | :----- |
1162
- | `canonical()`| (X) | | | |
1163
- | `simplify()` | (X) | (X) | | |
1164
- | `evaluate()` | (X) | (X) | (X) | |
1165
- | `"N()"` | (X) | (X) | (X) | (X) |
1453
+ | Operation | `"never"` | `"evaluate"` | `"N"` |
1454
+ | :--- | :-----: | :----: | :---: |
1455
+ | `canonical()` | (X) | | |
1456
+ | `evaluate()` | (X) | (X) | |
1457
+ | `"N()"` | (X) | (X) | (X) |
1166
1458
 
1167
1459
  </div>
1168
1460
 
1169
1461
  * Some examples:
1170
- * - `i` has `holdUntil: 'never'`
1171
- * - `GoldenRatio` has `holdUntil: 'simplify'` (symbolic constant)
1462
+ * - `ImaginaryUnit` has `holdUntil: 'never'`: it is substituted during canonicalization
1172
1463
  * - `x` has `holdUntil: 'evaluate'` (variables)
1173
1464
  * - `Pi` has `holdUntil: 'N'` (special numeric constant)
1174
1465
  *
1175
1466
  * **Default:** `evaluate`
1176
1467
  */
1177
- holdUntil: 'never' | 'simplify' | 'evaluate' | 'N';
1468
+ holdUntil: 'never' | 'evaluate' | 'N';
1178
1469
  };
1179
1470
  /**
1180
- * When used in a `SymbolDefinition`, these flags are optional.
1471
+ * When used in a `SymbolDefinition` or `Functiondefinition` these flags
1472
+ * provide additional information about the value of the symbol or function.
1181
1473
  *
1182
1474
  * If provided, they will override the value derived from
1183
1475
  * the symbol's value.
1184
1476
  *
1185
- * For example, it might be useful to override `algebraic = false`
1186
- * for a transcendental number.
1187
- *
1188
1477
  * @category Definitions
1189
1478
  */
1190
1479
  export type NumericFlags = {
1191
- number: boolean | undefined;
1192
- integer: boolean | undefined;
1193
- rational: boolean | undefined;
1194
- algebraic: boolean | undefined;
1195
- real: boolean | undefined;
1196
- extendedReal: boolean | undefined;
1197
- complex: boolean | undefined;
1198
- extendedComplex: boolean | undefined;
1199
- imaginary: boolean | undefined;
1200
- positive: boolean | undefined;
1201
- nonPositive: boolean | undefined;
1202
- negative: boolean | undefined;
1203
- nonNegative: boolean | undefined;
1204
- zero: boolean | undefined;
1205
- notZero: boolean | undefined;
1206
- one: boolean | undefined;
1207
- negativeOne: boolean | undefined;
1208
- infinity: boolean | undefined;
1209
- NaN: boolean | undefined;
1210
- finite: boolean | undefined;
1480
+ sgn: Sign | undefined;
1211
1481
  even: boolean | undefined;
1212
1482
  odd: boolean | undefined;
1213
- prime: boolean | undefined;
1214
- composite: boolean | undefined;
1215
1483
  };
1216
1484
  /**
1217
1485
  * @noInheritDoc
@@ -1219,14 +1487,34 @@ export type NumericFlags = {
1219
1487
  */
1220
1488
  export interface BoxedSymbolDefinition extends BoxedBaseDefinition, SymbolAttributes, Partial<NumericFlags> {
1221
1489
  get value(): BoxedExpression | undefined;
1222
- set value(val: SemiBoxedExpression | number | undefined);
1223
- domain: BoxedDomain | undefined;
1224
- inferredDomain: boolean;
1490
+ set value(val: BoxedExpression | number | undefined);
1491
+ readonly isFunction: boolean;
1492
+ readonly isConstant: boolean;
1493
+ eq?: (a: BoxedExpression) => boolean | undefined;
1494
+ neq?: (a: BoxedExpression) => boolean | undefined;
1495
+ cmp?: (a: BoxedExpression) => '=' | '>' | '<' | undefined;
1496
+ inferredType: boolean;
1497
+ type: Type;
1225
1498
  }
1499
+ /**
1500
+ * Given an expression and set of wildcards, return a new expression.
1501
+ *
1502
+ * For example:
1503
+ *
1504
+ * ```ts
1505
+ * {
1506
+ * match: '_x',
1507
+ * replace: (expr, {_x}) => { return ['Add', 1, _x] }
1508
+ * }
1509
+ * ```
1510
+ *
1511
+ * @category Rules */
1512
+ export type RuleReplaceFunction = (expr: BoxedExpression, wildcards: BoxedSubstitution) => BoxedExpression | undefined;
1226
1513
  /** @category Rules */
1227
- export type PatternReplaceFunction = (expr: BoxedExpression, wildcards: BoxedSubstitution) => BoxedExpression;
1514
+ export type RuleConditionFunction = (wildcards: BoxedSubstitution, ce: IComputeEngine) => boolean;
1228
1515
  /** @category Rules */
1229
- export type PatternConditionFunction = (wildcards: BoxedSubstitution, ce: IComputeEngine) => boolean;
1516
+ export type RuleFunction = (expr: BoxedExpression) => undefined | BoxedExpression | RuleStep;
1517
+ export declare function isRuleStep(x: any): x is RuleStep;
1230
1518
  /**
1231
1519
  * A rule describes how to modify an expressions that matches a pattern `match`
1232
1520
  * into a new expression `replace`.
@@ -1249,8 +1537,15 @@ export type PatternConditionFunction = (wildcards: BoxedSubstitution, ce: ICompu
1249
1537
  * a sequence of one or more expressions, and bind the sequence to the
1250
1538
  * wildcard name.
1251
1539
  *
1252
- * If `exact` is false, the rule will match variants. For example
1253
- * 'x' will match 'a + x', 'x' will match 'ax', etc...
1540
+ * Sequence wildcards are useful when the number of elements in the sequence
1541
+ * is not known in advance. For example, in a sum, the number of terms is
1542
+ * not known in advance. ["Add", 0, `__a`] will match two or more terms and
1543
+ * the `__a` wildcard will be a sequence of the matchign terms.
1544
+ *
1545
+ * If `exact` is false, the rule will match variants.
1546
+ *
1547
+ * For example 'x' will match 'a + x', 'x' will match 'ax', etc...
1548
+ *
1254
1549
  * For simplification rules, you generally want `exact` to be true, but
1255
1550
  * to solve equations, you want it to be false. Default to true.
1256
1551
  *
@@ -1258,25 +1553,45 @@ export type PatternConditionFunction = (wildcards: BoxedSubstitution, ce: ICompu
1258
1553
  *
1259
1554
  * @category Rules
1260
1555
  */
1261
- export type Rule = string | {
1262
- match: LatexString | SemiBoxedExpression | Pattern;
1263
- replace: LatexString | SemiBoxedExpression | PatternReplaceFunction;
1264
- condition?: LatexString | PatternConditionFunction;
1265
- exact?: boolean;
1266
- priority?: number;
1556
+ export type Rule = string | RuleFunction | {
1557
+ match?: LatexString | SemiBoxedExpression | Pattern;
1558
+ replace: LatexString | SemiBoxedExpression | RuleReplaceFunction | RuleFunction;
1559
+ condition?: LatexString | RuleConditionFunction;
1560
+ useVariations?: boolean;
1267
1561
  id?: string;
1268
1562
  };
1269
- /** @category Rules */
1563
+ /**
1564
+ *
1565
+ * If the `match` property is `undefined`, all expressions match this rule
1566
+ * and `condition` should also be `undefined`. The `replace` property should
1567
+ * be a `BoxedExpression` or a `RuleFunction`, and further filtering can be
1568
+ * done in the `replace` function.
1569
+ *
1570
+ * @category Rules */
1270
1571
  export type BoxedRule = {
1271
- match: Pattern;
1272
- replace: BoxedExpression | PatternReplaceFunction;
1273
- condition: undefined | PatternConditionFunction;
1274
- priority: number;
1275
- exact?: boolean;
1572
+ /** @internal */
1573
+ readonly _tag: 'boxed-rule';
1574
+ match: undefined | Pattern;
1575
+ replace: BoxedExpression | RuleReplaceFunction | RuleFunction;
1576
+ condition: undefined | RuleConditionFunction;
1577
+ useVariations?: boolean;
1276
1578
  id?: string;
1277
1579
  };
1278
- /** @category Rules */
1279
- export type BoxedRuleSet = Iterable<BoxedRule>;
1580
+ export declare function isBoxedRule(x: any): x is BoxedRule;
1581
+ export type RuleStep = {
1582
+ value: BoxedExpression;
1583
+ because: string;
1584
+ };
1585
+ export type RuleSteps = RuleStep[];
1586
+ /**
1587
+ * To create a BoxedRuleSet use the `ce.rules()` method.
1588
+ *
1589
+ * Do not create a `BoxedRuleSet` directly.
1590
+ *
1591
+ * @category Rules */
1592
+ export type BoxedRuleSet = {
1593
+ rules: ReadonlyArray<BoxedRule>;
1594
+ };
1280
1595
  /**
1281
1596
  * @noInheritDoc
1282
1597
  *
@@ -1315,47 +1630,31 @@ export type BoxedSubstitution = Substitution<BoxedExpression>;
1315
1630
  */
1316
1631
  export type CanonicalForm = 'InvisibleOperator' | 'Number' | 'Multiply' | 'Add' | 'Power' | 'Divide' | 'Flatten' | 'Order';
1317
1632
  export type CanonicalOptions = boolean | CanonicalForm | CanonicalForm[];
1318
- /** @category Boxed Expression */
1319
- export type DomainLiteral = 'Anything' | 'Values' | 'Domains' | 'Void' | 'NothingDomain' | 'Booleans' | 'Strings' | 'Symbols' | 'Collections' | 'Lists' | 'Dictionaries' | 'Sequences' | 'Tuples' | 'Sets' | 'Functions' | 'Predicates' | 'LogicOperators' | 'RelationalOperators' | 'NumericFunctions' | 'RealFunctions' | 'Numbers' | 'ComplexNumbers' | 'ExtendedRealNumbers' | 'ImaginaryNumbers' | 'Integers' | 'Rationals' | 'PositiveNumbers' | 'PositiveIntegers' | 'NegativeNumbers' | 'NegativeIntegers' | 'NonNegativeNumbers' | 'NonNegativeIntegers' | 'NonPositiveNumbers' | 'NonPositiveIntegers' | 'ExtendedComplexNumbers' | 'TranscendentalNumbers' | 'AlgebraicNumbers' | 'RationalNumbers' | 'RealNumbers';
1320
- /** @category Boxed Expression */
1321
- export type DomainExpression<T = SemiBoxedExpression> = DomainLiteral | ['Union', ...DomainExpression<T>[]] | ['Intersection', ...DomainExpression<T>[]] | ['ListOf', DomainExpression<T>] | ['DictionaryOf', DomainExpression<T>] | ['TupleOf', ...DomainExpression<T>[]] | ['OptArg', ...DomainExpression<T>[]] | ['VarArg', DomainExpression<T>] | ['Covariant', DomainExpression<T>] | ['Contravariant', DomainExpression<T>] | ['Bivariant', DomainExpression<T>] | ['Invariant', DomainExpression<T>] | ['FunctionOf', ...DomainExpression<T>[]];
1322
1633
  /** Options for `BoxedExpression.simplify()`
1323
1634
  *
1324
1635
  * @category Compute Engine
1325
1636
  */
1326
1637
  export type SimplifyOptions = {
1327
- recursive?: boolean;
1328
- rules?: null | BoxedRuleSet;
1638
+ /**
1639
+ * The set of rules to apply. If `null`, use no rules. If not provided,
1640
+ * use the default simplification rules.
1641
+ */
1642
+ rules?: null | Rule | ReadonlyArray<BoxedRule | Rule> | BoxedRuleSet;
1643
+ /**
1644
+ * Use this cost function to determine if a simplification is worth it.
1645
+ *
1646
+ * If not provided, `ce.costFunction`, the cost function of the engine is
1647
+ * used.
1648
+ */
1649
+ costFunction?: (expr: BoxedExpression) => number;
1329
1650
  };
1330
1651
  /** Options for `BoxedExpression.evaluate()`
1331
1652
  *
1332
1653
  * @category Boxed Expression
1333
1654
  */
1334
1655
  export type EvaluateOptions = {
1335
- numericMode?: boolean;
1656
+ numericApproximation?: boolean;
1336
1657
  };
1337
- /** Options for `BoxedExpression.N()`
1338
- *
1339
- * @category Boxed Expression
1340
- */
1341
- export type NOptions = {};
1342
- /**
1343
- * The numeric evaluation mode:
1344
- *
1345
- <div className="symbols-table">
1346
-
1347
- | Mode | |
1348
- | :--- | :----- |
1349
- | `"auto"`| Use bignum or complex numbers. |
1350
- | `"machine"` | **IEEE 754-2008**, 64-bit floating point numbers: 52-bit mantissa, about 15 digits of precision |
1351
- | `"bignum"` | Arbitrary precision floating point numbers, as provided by the "decimal.js" library |
1352
- | `"complex"` | Complex number represented by two machine numbers, a real and an imaginary part, as provided by the "complex.js" library |
1353
-
1354
- </div>
1355
-
1356
- * @category Compute Engine
1357
- */
1358
- export type NumericMode = 'auto' | 'machine' | 'bignum' | 'complex';
1359
1658
  /**
1360
1659
  * Metadata that can be associated with a `BoxedExpression`
1361
1660
  *
@@ -1378,22 +1677,19 @@ export type Metadata = {
1378
1677
  */
1379
1678
  export type AngularUnit = 'rad' | 'deg' | 'grad' | 'turn';
1380
1679
  /** @category Compute Engine */
1381
- export type ArrayValue = boolean | number | string | Decimal | Complex | BoxedExpression | undefined;
1680
+ export type ArrayValue = boolean | number | string | BigNum | BoxedExpression | undefined;
1382
1681
  /** @category Assumptions */
1383
1682
  export type AssumeResult = 'internal-error' | 'not-a-predicate' | 'contradiction' | 'tautology' | 'ok';
1384
1683
  /** @category Compute Engine */
1385
- export type AssignValue = boolean | number | string | Decimal | Complex | LatexString | SemiBoxedExpression | ((ce: IComputeEngine, args: any) => BoxedExpression) | undefined;
1684
+ export type AssignValue = boolean | number | string | LatexString | SemiBoxedExpression | ((args: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
1685
+ engine: IComputeEngine;
1686
+ }) => BoxedExpression) | undefined;
1386
1687
  /** @internal */
1387
- export interface IComputeEngine {
1688
+ export interface IComputeEngine extends IBigNum {
1388
1689
  latexDictionary: readonly LatexDictionaryEntry[];
1389
1690
  /** @private */
1390
1691
  indexedLatexDictionary: IndexedLatexDictionary;
1391
1692
  decimalSeparator: LatexString;
1392
- readonly Anything: BoxedDomain;
1393
- readonly Void: BoxedDomain;
1394
- readonly Strings: BoxedDomain;
1395
- readonly Booleans: BoxedDomain;
1396
- readonly Numbers: BoxedDomain;
1397
1693
  readonly True: BoxedExpression;
1398
1694
  readonly False: BoxedExpression;
1399
1695
  readonly Pi: BoxedExpression;
@@ -1409,54 +1705,63 @@ export interface IComputeEngine {
1409
1705
  readonly NegativeInfinity: BoxedExpression;
1410
1706
  readonly ComplexInfinity: BoxedExpression;
1411
1707
  /** @internal */
1412
- readonly _BIGNUM_NAN: Decimal;
1708
+ readonly _BIGNUM_NAN: BigNum;
1413
1709
  /** @internal */
1414
- readonly _BIGNUM_ZERO: Decimal;
1710
+ readonly _BIGNUM_ZERO: BigNum;
1415
1711
  /** @internal */
1416
- readonly _BIGNUM_ONE: Decimal;
1712
+ readonly _BIGNUM_ONE: BigNum;
1417
1713
  /** @internal */
1418
- readonly _BIGNUM_TWO: Decimal;
1714
+ readonly _BIGNUM_TWO: BigNum;
1419
1715
  /** @internal */
1420
- readonly _BIGNUM_HALF: Decimal;
1716
+ readonly _BIGNUM_HALF: BigNum;
1421
1717
  /** @internal */
1422
- readonly _BIGNUM_PI: Decimal;
1718
+ readonly _BIGNUM_PI: BigNum;
1423
1719
  /** @internal */
1424
- readonly _BIGNUM_NEGATIVE_ONE: Decimal;
1720
+ readonly _BIGNUM_NEGATIVE_ONE: BigNum;
1425
1721
  /** The current scope */
1426
1722
  context: RuntimeScope | null;
1427
1723
  /** Absolute time beyond which evaluation should not proceed
1428
1724
  * @internal
1429
1725
  */
1430
1726
  deadline?: number;
1727
+ generation: number;
1431
1728
  /** @hidden */
1432
1729
  readonly timeLimit: number;
1433
1730
  /** @hidden */
1434
1731
  readonly iterationLimit: number;
1435
1732
  /** @hidden */
1436
1733
  readonly recursionLimit: number;
1437
- numericMode: NumericMode;
1438
- tolerance: number;
1439
- angularUnit: AngularUnit;
1440
1734
  chop(n: number): number;
1441
- chop(n: Decimal): Decimal | 0;
1442
- chop(n: Complex): Complex | 0;
1443
- chop(n: number | Decimal | Complex): number | Decimal | Complex;
1444
- bignum: (a: Decimal.Value | bigint) => Decimal;
1445
- isBignum(a: unknown): a is Decimal;
1735
+ chop(n: BigNum): BigNum | 0;
1736
+ chop(n: number | BigNum): number | BigNum;
1737
+ bignum: (a: string | number | bigint | BigNum) => BigNum;
1446
1738
  complex: (a: number | Complex, b?: number) => Complex;
1447
- isComplex(a: unknown): a is Complex;
1448
- set precision(p: number | 'machine');
1739
+ /** @internal */
1740
+ _numericValue(value: number | bigint | OneOf<[BigNum | NumericValueData | ExactNumericValueData]>): NumericValue;
1741
+ /** If the precision is set to `machine`, floating point numbers
1742
+ * are represented internally as a 64-bit floating point number (as
1743
+ * per IEEE 754-2008), with a 52-bit mantissa, which gives about 15
1744
+ * digits of precision.
1745
+ *
1746
+ * If the precision is set to `auto`, the precision is set to 300 digits.
1747
+ *
1748
+ */
1749
+ set precision(p: number | 'machine' | 'auto');
1449
1750
  get precision(): number;
1751
+ tolerance: number;
1752
+ angularUnit: AngularUnit;
1450
1753
  costFunction: (expr: BoxedExpression) => number;
1451
1754
  strict: boolean;
1452
- box(expr: Decimal | Complex | [num: number, denom: number] | SemiBoxedExpression, options?: {
1755
+ box(expr: NumericValue | SemiBoxedExpression, options?: {
1453
1756
  canonical?: CanonicalOptions;
1757
+ structural?: boolean;
1454
1758
  }): BoxedExpression;
1455
- function(head: string | BoxedExpression, ops: ReadonlyArray<SemiBoxedExpression>, options?: {
1759
+ function(name: string, ops: ReadonlyArray<SemiBoxedExpression>, options?: {
1456
1760
  metadata?: Metadata;
1457
1761
  canonical?: CanonicalOptions;
1762
+ structural?: boolean;
1458
1763
  }): BoxedExpression;
1459
- number(value: number | bigint | string | MathJsonNumber | Decimal | Complex | Rational, options?: {
1764
+ number(value: number | bigint | string | NumericValue | MathJsonNumber | BigNum | Complex | Rational, options?: {
1460
1765
  metadata?: Metadata;
1461
1766
  canonical?: CanonicalOptions;
1462
1767
  }): BoxedExpression;
@@ -1465,22 +1770,14 @@ export interface IComputeEngine {
1465
1770
  canonical?: CanonicalOptions;
1466
1771
  }): BoxedExpression;
1467
1772
  string(s: string, metadata?: Metadata): BoxedExpression;
1468
- domain(domain: BoxedDomain | DomainExpression, metadata?: Metadata): BoxedDomain;
1469
- error(message: MathJsonIdentifier | [MathJsonIdentifier, ...ReadonlyArray<SemiBoxedExpression>], where?: SemiBoxedExpression): BoxedExpression;
1470
- domainError(expectedDomain: BoxedDomain | DomainLiteral, actualDomain: undefined | BoxedDomain, where?: SemiBoxedExpression): BoxedExpression;
1773
+ error(message: string | string[], where?: string): BoxedExpression;
1774
+ typeError(expectedType: Type, actualType: undefined | Type, where?: SemiBoxedExpression): BoxedExpression;
1471
1775
  hold(expr: SemiBoxedExpression): BoxedExpression;
1472
- add(...ops: ReadonlyArray<BoxedExpression>): BoxedExpression;
1473
- mul(...ops: ReadonlyArray<BoxedExpression>): BoxedExpression;
1474
- pow(base: BoxedExpression, exponent: number | Rational | BoxedExpression): BoxedExpression;
1475
- sqrt(base: BoxedExpression): BoxedExpression;
1476
- inv(expr: BoxedExpression): BoxedExpression;
1477
- neg(expr: BoxedExpression): BoxedExpression;
1478
- div(num: BoxedExpression, denom: BoxedExpression): BoxedExpression;
1479
- pair(first: BoxedExpression, second: BoxedExpression, metadata?: Metadata): BoxedExpression;
1480
- tuple(elements: ReadonlyArray<number>, metadata?: Metadata): BoxedExpression;
1481
- tuple(elements: ReadonlyArray<BoxedExpression>, metadata?: Metadata): BoxedExpression;
1482
- array(elements: ArrayValue[] | ArrayValue[][], metadata?: Metadata): BoxedExpression;
1483
- rules(rules: Rule[]): BoxedRuleSet;
1776
+ tuple(...elements: ReadonlyArray<number>): BoxedExpression;
1777
+ tuple(...elements: ReadonlyArray<BoxedExpression>): BoxedExpression;
1778
+ rules(rules: Rule | ReadonlyArray<Rule | BoxedRule> | BoxedRuleSet | undefined | null, options?: {
1779
+ canonical?: boolean;
1780
+ }): BoxedRuleSet;
1484
1781
  /**
1485
1782
  * Return a set of built-in rules.
1486
1783
  */
@@ -1488,7 +1785,8 @@ export interface IComputeEngine {
1488
1785
  /**
1489
1786
  * This is a primitive to create a boxed function.
1490
1787
  *
1491
- * In general, consider using `ce.box()` or `canonicalXXX()` instead.
1788
+ * In general, consider using `ce.box()` or `ce.function()` or
1789
+ * `canonicalXXX()` instead.
1492
1790
  *
1493
1791
  * The caller must ensure that the arguments are in canonical form:
1494
1792
  * - arguments are `canonical()`
@@ -1497,7 +1795,7 @@ export interface IComputeEngine {
1497
1795
  *
1498
1796
  * @internal
1499
1797
  */
1500
- _fn(head: string | BoxedExpression, ops: ReadonlyArray<BoxedExpression>, options?: Metadata & {
1798
+ _fn(name: string, ops: ReadonlyArray<BoxedExpression>, options?: Metadata & {
1501
1799
  canonical?: boolean;
1502
1800
  }): BoxedExpression;
1503
1801
  parse(latex: null, options?: Partial<ParseLatexOptions> & {
@@ -1516,7 +1814,7 @@ export interface IComputeEngine {
1516
1814
  defineSymbol(name: string, def: SymbolDefinition): BoxedSymbolDefinition;
1517
1815
  lookupSymbol(name: string, wikidata?: string, scope?: RuntimeScope): undefined | BoxedSymbolDefinition;
1518
1816
  defineFunction(name: string, def: FunctionDefinition): BoxedFunctionDefinition;
1519
- lookupFunction(head: string | BoxedExpression, scope?: RuntimeScope | null): undefined | BoxedFunctionDefinition;
1817
+ lookupFunction(name: string, scope?: RuntimeScope | null): undefined | BoxedFunctionDefinition;
1520
1818
  assign(ids: {
1521
1819
  [id: string]: AssignValue;
1522
1820
  }): IComputeEngine;
@@ -1525,23 +1823,23 @@ export interface IComputeEngine {
1525
1823
  [id: string]: AssignValue;
1526
1824
  }, arg2?: AssignValue): IComputeEngine;
1527
1825
  declare(identifiers: {
1528
- [id: string]: BoxedDomain | DomainExpression | SymbolDefinition | FunctionDefinition;
1826
+ [id: string]: Type | TypeString | OneOf<[SymbolDefinition | FunctionDefinition]>;
1529
1827
  }): IComputeEngine;
1530
- declare(id: string, def: BoxedDomain | DomainExpression | SymbolDefinition | FunctionDefinition): IComputeEngine;
1828
+ declare(id: string, def: Type | TypeString | SymbolDefinition | FunctionDefinition): IComputeEngine;
1531
1829
  declare(arg1: string | {
1532
- [id: string]: BoxedDomain | DomainExpression | SymbolDefinition | FunctionDefinition;
1533
- }, arg2?: BoxedDomain | DomainExpression | SymbolDefinition | FunctionDefinition): IComputeEngine;
1534
- assume(predicate: SemiBoxedExpression): AssumeResult;
1830
+ [id: string]: Type | TypeString | OneOf<[SymbolDefinition | FunctionDefinition]>;
1831
+ }, arg2?: Type | OneOf<[SymbolDefinition | FunctionDefinition]>): IComputeEngine;
1832
+ assume(predicate: BoxedExpression): AssumeResult;
1535
1833
  forget(symbol?: string | string[]): void;
1536
1834
  get assumptions(): ExpressionMapInterface<boolean>;
1537
- ask(pattern: SemiBoxedExpression): BoxedSubstitution[];
1538
- verify(query: SemiBoxedExpression): boolean;
1835
+ ask(pattern: BoxedExpression): BoxedSubstitution[];
1836
+ verify(query: BoxedExpression): boolean;
1539
1837
  /** @internal */
1540
1838
  shouldContinueExecution(): boolean;
1541
1839
  /** @internal */
1542
1840
  checkContinueExecution(): void;
1543
1841
  /** @internal */
1544
- cache<T>(name: string, build: () => T, purge?: (T: any) => T | undefined): T;
1842
+ cache<T>(name: string, build: () => T, purge?: (t: T) => T | undefined): T;
1545
1843
  /** @internal */
1546
1844
  readonly stats: ComputeEngineStats;
1547
1845
  /** @internal */
@@ -1585,7 +1883,7 @@ export type JsonSerializationOptions = {
1585
1883
  *
1586
1884
  * **Default**: `["all"]`
1587
1885
  */
1588
- shorthands: ('all' | 'number' | 'symbol' | 'function' | 'dictionary' | 'string')[];
1886
+ shorthands: ('all' | 'number' | 'symbol' | 'function' | 'string')[];
1589
1887
  /** A list of space separated keywords indicating which metadata should be
1590
1888
  * included in the MathJSON. If metadata is included, shorthand notation
1591
1889
  * is not used.
@@ -1619,10 +1917,16 @@ export type LatexString = string;
1619
1917
  /**
1620
1918
  * Control how a pattern is matched to an expression.
1621
1919
  *
1622
- * - `substitution`: if present, assumes these values for the named wildcards, and ensure that subsequent occurence of the same wildcard have the same value.
1623
- * - `recursive`: if true, match recursively, otherwise match only the top level.
1624
- * - `numericTolerance`: if present, the tolerance for numeric comparison.
1625
- * - `exact`: if true, only match expressions that are structurally identical. If false, match expressions that are structurally identical or equivalent. For example, when false, `["Add", '_a', 2]` matches `2`, with a value of `_a` of `0`. If true, the expression does not match.
1920
+ * - `substitution`: if present, assumes these values for the named wildcards,
1921
+ * and ensure that subsequent occurrence of the same wildcard have the same
1922
+ * value.
1923
+ * - `recursive`: if true, match recursively, otherwise match only the top
1924
+ * level.
1925
+ * - `exact`: if true, only match expressions that are structurally identical.
1926
+ * If false, match expressions that are structurally identical or equivalent.
1927
+ *
1928
+ * For example, when false, `["Add", '_a', 2]` matches `2`, with a value of
1929
+ * `_a` of `0`. If true, the expression does not match. **Default**: `true`
1626
1930
  *
1627
1931
  * @category Pattern Matching
1628
1932
  *
@@ -1630,20 +1934,21 @@ export type LatexString = string;
1630
1934
  export type PatternMatchOptions = {
1631
1935
  substitution?: BoxedSubstitution;
1632
1936
  recursive?: boolean;
1633
- numericTolerance?: number;
1634
- exact?: boolean;
1937
+ useVariations?: boolean;
1635
1938
  };
1636
1939
  /**
1637
1940
  * @category Boxed Expression
1638
1941
  *
1639
1942
  */
1640
1943
  export type ReplaceOptions = {
1641
- /** If `true`, apply replacement rules to all sub-expressions.
1944
+ /**
1945
+ * If `true`, apply replacement rules to all sub-expressions.
1946
+ *
1642
1947
  * If `false`, only consider the top-level expression.
1643
1948
  *
1644
1949
  * **Default**: `false`
1645
1950
  */
1646
- recursive?: boolean;
1951
+ recursive: boolean;
1647
1952
  /**
1648
1953
  * If `true`, stop after the first rule that matches.
1649
1954
  *
@@ -1651,23 +1956,44 @@ export type ReplaceOptions = {
1651
1956
  *
1652
1957
  * **Default**: `false`
1653
1958
  */
1654
- once?: boolean;
1959
+ once: boolean;
1960
+ /**
1961
+ * If `true` the rule will use some equivalent variations to match.
1962
+ *
1963
+ * For example when `useVariations` is true:
1964
+ * - `x` matches `a + x` with a = 0
1965
+ * - `x` matches `ax` with a = 1
1966
+ * - etc...
1967
+ *
1968
+ * Setting this to `true` can save time by condensing multiple rules
1969
+ * into one. This can be particularly useful when describing equations
1970
+ * solutions. However, it can lead to infinite recursion and should be
1971
+ * used with caution.
1972
+ *
1973
+ */
1974
+ useVariations: boolean;
1655
1975
  /**
1656
1976
  * If `iterationLimit` > 1, the rules will be repeatedly applied
1657
1977
  * until no rules apply, up to `maxIterations` times.
1658
1978
  *
1659
- * Note that if `once` is true, `maxIterations` has no effect.
1979
+ * Note that if `once` is true, `iterationLimit` has no effect.
1660
1980
  *
1661
1981
  * **Default**: `1`
1662
1982
  */
1663
- iterationLimit?: number;
1983
+ iterationLimit: number;
1984
+ /**
1985
+ * Indicate if the expression should be canonicalized after the replacement.
1986
+ * If not provided, the expression is canonicalized if the the expression
1987
+ * that matched the pattern is canonical.
1988
+ */
1989
+ canonical: CanonicalOptions;
1664
1990
  };
1665
1991
  /**
1666
1992
  * A substitution describes the values of the wildcards in a pattern so that
1667
1993
  * the pattern is equal to a target expression.
1668
1994
  *
1669
1995
  * A substitution can also be considered a more constrained version of a
1670
- * rule whose `lhs` is always a symbol.
1996
+ * rule whose `match` is always a symbol.
1671
1997
 
1672
1998
  * @category Boxed Expression
1673
1999
  */
@@ -1692,7 +2018,7 @@ export interface ExpressionMapInterface<U> {
1692
2018
  *
1693
2019
  * @category Definitions
1694
2020
  */
1695
- export type RuntimeIdentifierDefinitions = Map<string, BoxedSymbolDefinition | BoxedFunctionDefinition>;
2021
+ export type RuntimeIdentifierDefinitions = Map<string, OneOf<[BoxedSymbolDefinition, BoxedFunctionDefinition]>>;
1696
2022
  /**
1697
2023
  * A scope is a set of names in a dictionary that are bound (defined) in
1698
2024
  * a MathJSON expression.
@@ -1744,13 +2070,13 @@ export type RuntimeScope = Scope & {
1744
2070
  assumptions: undefined | ExpressionMapInterface<boolean>;
1745
2071
  };
1746
2072
  /**
1747
- * A bound symbol (i.e. one with an associated definition) has either a domain
1748
- * (e.g. ∀ x ∈ ℝ), a value (x = 5) or both (π: value = 3.14... domain = TranscendentalNumbers)
2073
+ * A bound symbol (i.e. one with an associated definition) has either a type
2074
+ * (e.g. ∀ x ∈ ℝ), a value (x = 5) or both (π: value = 3.14... type = 'real')
1749
2075
  * @category Definitions
1750
2076
  */
1751
2077
  export type SymbolDefinition = BaseDefinition & Partial<SymbolAttributes> & {
1752
- domain?: DomainLiteral | BoxedDomain;
1753
- /** If true, the domain is inferred, and could be adjusted later
2078
+ type?: Type | TypeString;
2079
+ /** If true, the type is inferred, and could be adjusted later
1754
2080
  * as more information becomes available or if the symbol is explicitly
1755
2081
  * declared.
1756
2082
  */
@@ -1758,20 +2084,67 @@ export type SymbolDefinition = BaseDefinition & Partial<SymbolAttributes> & {
1758
2084
  /** `value` can be a JS function since for some constants, such as
1759
2085
  * `Pi`, the actual value depends on the `precision` setting of the
1760
2086
  * `ComputeEngine` and possible other environment settings */
1761
- value?: LatexString | SemiBoxedExpression | ((ce: IComputeEngine) => SemiBoxedExpression | null);
2087
+ value?: LatexString | SemiBoxedExpression | ((ce: IComputeEngine) => BoxedExpression | null);
1762
2088
  flags?: Partial<NumericFlags>;
2089
+ eq?: (a: BoxedExpression) => boolean | undefined;
2090
+ neq?: (a: BoxedExpression) => boolean | undefined;
2091
+ cmp?: (a: BoxedExpression) => '=' | '>' | '<' | undefined;
2092
+ collection?: Partial<CollectionHandlers>;
1763
2093
  };
1764
2094
  /**
1765
2095
  * Definition record for a function.
1766
2096
  * @category Definitions
1767
2097
  *
1768
2098
  */
1769
- export type FunctionDefinition = BaseDefinition & Partial<CollectionHandlers> & Partial<FunctionDefinitionFlags> & {
2099
+ export type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlags> & {
2100
+ /**
2101
+ * The function signature.
2102
+ *
2103
+ * If a `type` handler is provided, the return type of the function should
2104
+ * be a subtype of the return type in the signature.
2105
+ *
2106
+ */
2107
+ signature?: Type | TypeString;
2108
+ /**
2109
+ * The actual type of the result based on the arguments.
2110
+ *
2111
+ * Should be a subtype of the type indicated in the signature.
2112
+ *
2113
+ * Do not evaluate the arguments.
2114
+ *
2115
+ * The type of the arguments can be used to determine the type of the
2116
+ * result.
2117
+ *
2118
+ */
2119
+ type?: (ops: ReadonlyArray<BoxedExpression>, options: {
2120
+ engine: IComputeEngine;
2121
+ }) => Type;
2122
+ /** Return the sign of the function expression.
2123
+ *
2124
+ * If the sign cannot be determined, return `undefined`.
2125
+ *
2126
+ * When determining the sign, only literal values and the values of
2127
+ * symbols, if they are literals, should be considered.
2128
+ *
2129
+ * Do not evaluate the arguments.
2130
+ *
2131
+ * The type and sign of the arguments can be used to determine the sign.
2132
+ *
2133
+ */
2134
+ sgn?: (ops: ReadonlyArray<BoxedExpression>, options: {
2135
+ engine: IComputeEngine;
2136
+ }) => Sign | undefined;
2137
+ /** Return true of the function expression is even, false if it is odd and
2138
+ * undefined if it is neither.
2139
+ */
2140
+ even?: (ops: ReadonlyArray<BoxedExpression>, options: {
2141
+ engine: IComputeEngine;
2142
+ }) => boolean | undefined;
1770
2143
  /**
1771
2144
  * A number used to order arguments.
1772
2145
  *
1773
- * Argument with higher complexity are placed after arguments with lower
1774
- * complexity when ordered canonically in commutative functions.
2146
+ * Argument with higher complexity are placed after arguments with
2147
+ * lower complexity when ordered canonically in commutative functions.
1775
2148
  *
1776
2149
  * - Additive functions: 1000-1999
1777
2150
  * - Multiplicative functions: 2000-2999
@@ -1788,69 +2161,21 @@ export type FunctionDefinition = BaseDefinition & Partial<CollectionHandlers> &
1788
2161
  * **Default**: 100,000
1789
2162
  */
1790
2163
  complexity?: number;
1791
- /**
1792
- * - `"none"` Each of the arguments is evaluated (default)
1793
- * - `"all"` None of the arguments are evaluated and they are passed as is
1794
- * - `"first"` The first argument is not evaluated, the others are
1795
- * - `"rest"` The first argument is evaluated, the others aren't
1796
- * - `"last"`: The last argument is not evaluated, the others are
1797
- * - `"most"`: All the arguments are evaluated, except the last one
1798
- *
1799
- * **Default**: `"none"`
1800
- */
1801
- hold?: Hold;
1802
- signature: FunctionSignature;
1803
- };
1804
- /**
1805
- * @category Definitions
1806
- *
1807
- */
1808
- export type BaseDefinition = {
1809
- /** A short (about 1 line) description. May contain Markdown. */
1810
- description?: string | string[];
1811
- /** A URL pointing to more information about this symbol or head. */
1812
- url?: string;
1813
- /**
1814
- * A short string representing an entry in a wikibase.
1815
- *
1816
- * For example `Q167` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
1817
- * for the `Pi` constant.
1818
- */
1819
- wikidata?: string;
1820
- };
1821
- /**
1822
- * @category Definitions
1823
- *
1824
- */
1825
- export type FunctionSignature = {
1826
- /** The domain of this signature, a domain compatible with the `Functions`
1827
- * domain).
1828
- *
1829
- * @deprecated Use params, optParams, restParam and result instead
1830
- */
1831
- domain?: DomainExpression;
1832
- params?: DomainExpression[];
1833
- optParams?: DomainExpression[];
1834
- restParam?: DomainExpression;
1835
- /** The domain of the result of the function. Either a domain
1836
- * expression, or a function that returns a boxed domain.
1837
- */
1838
- result?: DomainExpression | ((ce: IComputeEngine, args: BoxedDomain[]) => BoxedDomain | null | undefined);
1839
2164
  /**
1840
2165
  * Return the canonical form of the expression with the arguments `args`.
1841
2166
  *
1842
2167
  * The arguments (`args`) may not be in canonical form. If necessary, they
1843
2168
  * can be put in canonical form.
1844
2169
  *
1845
- * This handler should validate the domain and number of the arguments.
2170
+ * This handler should validate the type and number of the arguments.
1846
2171
  *
1847
2172
  * If a required argument is missing, it should be indicated with a
1848
2173
  * `["Error", "'missing"]` expression. If more arguments than expected
1849
2174
  * are present, this should be indicated with an
1850
2175
  * ["Error", "'unexpected-argument'"]` error expression
1851
2176
  *
1852
- * If the domain of an argument is not compatible, it should be indicated
1853
- * with an `incompatible-domain` error.
2177
+ * If the type of an argument is not compatible, it should be indicated
2178
+ * with an `incompatible-type` error.
1854
2179
  *
1855
2180
  * `["Sequence"]` expressions are not folded and need to be handled
1856
2181
  * explicitly.
@@ -1859,9 +2184,6 @@ export type FunctionSignature = {
1859
2184
  * this handler should account for it. Notably, if it is commutative, the
1860
2185
  * arguments should be sorted in canonical order.
1861
2186
  *
1862
- * The handler can make transformations based on the value of the arguments
1863
- * that are exact and literal (i.e.
1864
- * `arg.numericValue !== null && arg.isExact`).
1865
2187
  *
1866
2188
  * Values of symbols should not be substituted, unless they have
1867
2189
  * a `holdUntil` attribute of `"never"`.
@@ -1877,35 +2199,9 @@ export type FunctionSignature = {
1877
2199
  * the handler should return `null`.
1878
2200
  *
1879
2201
  */
1880
- canonical?: (ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => BoxedExpression | null;
1881
- /**
1882
- * Rewrite an expression into a simpler form.
1883
- *
1884
- * The arguments are in canonical form and have been simplified.
1885
- *
1886
- * The handler can use the values assigned to symbols and the assumptions
1887
- * about symbols, for example with `arg.numericValue`, `arg.isInteger` or
1888
- * `arg.isPositive`.
1889
- *
1890
- * Even though a symbol may not have a value, there may be some information
1891
- * about it reflected for example in `this.isZero` or `this.isPrime`.
1892
- *
1893
- * The handler should not perform approximate numeric calculations, such
1894
- * as calculations involving decimal numbers (non-integers). Making exact
1895
- * calculations on integers or rationals is OK.
1896
- *
1897
- * Do not reduce constants with a `holdUntil` attribute of `"N"`
1898
- * or `"evaluate"`.
1899
- *
1900
- * This handler should not have any side-effects: do not modify
1901
- * the environment of the `ComputeEngine` instance, do not perform I/O,
1902
- * do not do calculations that depend on random values.
1903
- *
1904
- * If no simplification can be performed due to the values, domains or
1905
- * assumptions about its arguments, for example, return `undefined`.
1906
- *
1907
- */
1908
- simplify?: (ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => BoxedExpression | undefined;
2202
+ canonical?: (ops: ReadonlyArray<BoxedExpression>, options: {
2203
+ engine: IComputeEngine;
2204
+ }) => BoxedExpression | null;
1909
2205
  /**
1910
2206
  * Evaluate a function expression.
1911
2207
  *
@@ -1914,70 +2210,46 @@ export type FunctionSignature = {
1914
2210
  *
1915
2211
  * It is not necessary to further simplify or evaluate the arguments.
1916
2212
  *
1917
- * If performing numerical calculations, if all the arguments are exact,
1918
- * return an exact expression. If any of the arguments is not exact, that is
1919
- * if it is a literal decimal (non-integer) number, return an approximation.
1920
- * In this case, the value may be the same as `expr.N()`.
2213
+ * If performing numerical calculations and `options.numericalApproximation`
2214
+ * is `false` return an exact numeric value, for example return a rational
2215
+ * number or a square root, rather than a floating point approximation.
2216
+ * Use `ce.number()` to create the numeric value.
1921
2217
  *
1922
- * When doing an exact calculation:
2218
+ * When `numericalApproximation` is `false`, return a floating point number:
1923
2219
  * - do not reduce rational numbers to decimal (floating point approximation)
1924
- * - do not down convert bignums to machine numbers
1925
2220
  * - do not reduce square roots of rational numbers
1926
- * - do not reduce constants with a `holdUntil` attribute of `"N"`
1927
2221
  *
1928
- * If the expression cannot be evaluated, due to the values, domains, or
2222
+ * If the expression cannot be evaluated, due to the values, types, or
1929
2223
  * assumptions about its arguments, for example, return `undefined` or
1930
2224
  * an `["Error"]` expression.
1931
2225
  */
1932
- evaluate?: SemiBoxedExpression | ((ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => BoxedExpression | undefined);
1933
- /**
1934
- * Evaluate numerically a function expression.
1935
- *
1936
- * The arguments `args` have been simplified and evaluated, numerically
1937
- * if possible, except the arguments to which a `hold` apply.
1938
- *
1939
- * The arguments may be a combination of numbers, symbolic
1940
- * expressions and other expressions.
1941
- *
1942
- * Perform as many calculations as possible, and return the result.
1943
- *
1944
- * Return `undefined` if there isn't enough information to perform
1945
- * the evaluation, for example one of the arguments is a symbol with
1946
- * no value. If the handler returns `undefined`, symbolic evaluation of
1947
- * the expression will be returned instead to the caller.
1948
- *
1949
- * Return `NaN` if there is enough information to perform the
1950
- * evaluation, but a literal argument is out of range or
1951
- * not of the expected type.
1952
- *
1953
- * Use the value of `ce.numericMode` to determine how to perform
1954
- * the numeric evaluation.
1955
- *
1956
- * Note that regardless of the current value of `ce.numericMode`, the
1957
- * arguments may be boxed numbers representing machine numbers, bignum
1958
- * numbers, complex numbers, rationals or big rationals.
1959
- *
1960
- * If the numeric mode does not allow complex numbers (the
1961
- * `engine.numericMode` is not `"complex"` or `"auto"`) and the result of
1962
- * the evaluation would be a complex number, return `NaN` instead.
1963
- *
1964
- * If `ce.numericMode` is `"bignum"` or `"auto"` the evaluation should
1965
- * be done using bignums.
1966
- *
1967
- * Otherwise, `ce.numericMode` is `"machine", the evaluation should be
1968
- * performed using machine numbers.
1969
- *
1970
- * You may perform any necessary computations, including approximate
1971
- * calculations on floating point numbers.
1972
- *
1973
- */
1974
- N?: (ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => BoxedExpression | undefined;
2226
+ evaluate?: ((ops: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
2227
+ engine: IComputeEngine;
2228
+ }) => BoxedExpression | undefined) | BoxedExpression;
1975
2229
  /** Dimensional analysis
1976
2230
  * @experimental
1977
2231
  */
1978
- evalDimension?: (ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => BoxedExpression;
1979
- /** Return the sign of the function expression. */
1980
- sgn?: (ce: IComputeEngine, args: ReadonlyArray<BoxedExpression>) => -1 | 0 | 1 | undefined;
2232
+ evalDimension?: (args: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
2233
+ engine: IComputeEngine;
2234
+ }) => BoxedExpression;
1981
2235
  /** Return a compiled (optimized) expression. */
1982
2236
  compile?: (expr: BoxedExpression) => CompiledExpression;
2237
+ collection?: Partial<CollectionHandlers>;
2238
+ };
2239
+ /**
2240
+ * @category Definitions
2241
+ *
2242
+ */
2243
+ export type BaseDefinition = {
2244
+ /** A short (about 1 line) description. May contain Markdown. */
2245
+ description?: string | string[];
2246
+ /** A URL pointing to more information about this symbol or operator. */
2247
+ url?: string;
2248
+ /**
2249
+ * A short string representing an entry in a wikibase.
2250
+ *
2251
+ * For example `Q167` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
2252
+ * for the `Pi` constant.
2253
+ */
2254
+ wikidata?: string;
1983
2255
  };