@cortex-js/compute-engine 0.6.0 → 0.8.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 (91) hide show
  1. package/dist/compute-engine.esm.js +14942 -11619
  2. package/dist/compute-engine.min.esm.js +2 -2
  3. package/dist/compute-engine.min.js +2 -2
  4. package/dist/math-json.esm.js +62 -43
  5. package/dist/math-json.min.esm.js +2 -2
  6. package/dist/math-json.min.js +2 -2
  7. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  8. package/dist/types/common/signals.d.ts +1 -1
  9. package/dist/types/compute-engine/assume.d.ts +2 -2
  10. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +72 -57
  11. package/dist/types/compute-engine/boxed-expression/box.d.ts +2 -14
  12. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +4 -4
  13. package/dist/types/compute-engine/boxed-expression/boxed-domain.d.ts +36 -19
  14. package/dist/types/compute-engine/boxed-expression/boxed-function-definition.d.ts +1 -1
  15. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +46 -38
  16. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +6 -4
  17. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +5 -5
  18. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +3 -3
  19. package/dist/types/compute-engine/boxed-expression/boxed-symbol-definition.d.ts +13 -10
  20. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +28 -14
  21. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  22. package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
  23. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
  24. package/dist/types/compute-engine/boxed-expression/utils.d.ts +25 -8
  25. package/dist/types/compute-engine/compute-engine.d.ts +72 -49
  26. package/dist/types/compute-engine/cost-function.d.ts +1 -1
  27. package/dist/types/compute-engine/domain-utils.d.ts +1 -1
  28. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  29. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  30. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  31. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -3
  32. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-inequalities.d.ts +1 -1
  33. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  34. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  35. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  36. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  37. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  38. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +8 -7
  39. package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +3 -3
  40. package/dist/types/compute-engine/latex-syntax/parse.d.ts +87 -62
  41. package/dist/types/compute-engine/latex-syntax/public.d.ts +65 -46
  42. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
  43. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
  44. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +6 -4
  45. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  46. package/dist/types/compute-engine/library/arithmetic-add.d.ts +11 -0
  47. package/dist/types/compute-engine/library/arithmetic-divide.d.ts +15 -0
  48. package/dist/types/compute-engine/library/arithmetic-multiply.d.ts +19 -0
  49. package/dist/types/compute-engine/{dictionary → library}/arithmetic-power.d.ts +1 -1
  50. package/dist/types/compute-engine/library/arithmetic.d.ts +2 -0
  51. package/dist/types/compute-engine/library/calculus.d.ts +2 -0
  52. package/dist/types/compute-engine/library/collections.d.ts +2 -0
  53. package/dist/types/compute-engine/library/core.d.ts +2 -0
  54. package/dist/types/compute-engine/library/domains.d.ts +15 -0
  55. package/dist/types/compute-engine/library/library.d.ts +17 -0
  56. package/dist/types/compute-engine/library/logic.d.ts +2 -0
  57. package/dist/types/compute-engine/library/polynomials.d.ts +2 -0
  58. package/dist/types/compute-engine/library/relational-operator.d.ts +2 -0
  59. package/dist/types/compute-engine/library/sets.d.ts +2 -0
  60. package/dist/types/compute-engine/library/trigonometry.d.ts +2 -0
  61. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
  62. package/dist/types/compute-engine/numerics/numeric-decimal.d.ts +5 -1
  63. package/dist/types/compute-engine/numerics/numeric.d.ts +4 -2
  64. package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
  65. package/dist/types/compute-engine/public.d.ts +717 -504
  66. package/dist/types/compute-engine/rules.d.ts +1 -1
  67. package/dist/types/compute-engine/simplify-rules.d.ts +1 -1
  68. package/dist/types/compute-engine/symbolic/expand.d.ts +1 -1
  69. package/dist/types/compute-engine/symbolic/flatten.d.ts +1 -1
  70. package/dist/types/compute-engine/symbolic/negate.d.ts +1 -1
  71. package/dist/types/compute-engine/symbolic/polynomials.d.ts +1 -1
  72. package/dist/types/compute-engine/symbolic/product.d.ts +1 -1
  73. package/dist/types/compute-engine/symbolic/sum.d.ts +2 -2
  74. package/dist/types/compute-engine/symbolic/utils.d.ts +1 -1
  75. package/dist/types/compute-engine.d.ts +2 -2
  76. package/dist/types/math-json/math-json-format.d.ts +27 -23
  77. package/dist/types/math-json/utils.d.ts +22 -16
  78. package/dist/types/math-json.d.ts +3 -3
  79. package/package.json +20 -20
  80. package/dist/types/compute-engine/dictionary/arithmetic-add.d.ts +0 -11
  81. package/dist/types/compute-engine/dictionary/arithmetic-divide.d.ts +0 -9
  82. package/dist/types/compute-engine/dictionary/arithmetic-multiply.d.ts +0 -17
  83. package/dist/types/compute-engine/dictionary/arithmetic.d.ts +0 -2
  84. package/dist/types/compute-engine/dictionary/collections.d.ts +0 -2
  85. package/dist/types/compute-engine/dictionary/core.d.ts +0 -2
  86. package/dist/types/compute-engine/dictionary/dictionary.d.ts +0 -26
  87. package/dist/types/compute-engine/dictionary/logic.d.ts +0 -2
  88. package/dist/types/compute-engine/dictionary/polynomials.d.ts +0 -2
  89. package/dist/types/compute-engine/dictionary/relational-operator.d.ts +0 -2
  90. package/dist/types/compute-engine/dictionary/sets.d.ts +0 -2
  91. package/dist/types/compute-engine/dictionary/trigonometry.d.ts +0 -2
@@ -1,4 +1,4 @@
1
- /* 0.6.0 */
1
+ /* 0.8.0 */
2
2
  * The most important classes are {@link ComputeEngine} and
3
3
  * {@link BoxedExpression}.
4
4
  *
@@ -17,18 +17,18 @@ export * from './latex-syntax/public';
17
17
  * Metadata that can be associated with a `BoxedExpression`
18
18
  */
19
19
  export declare type Metadata = {
20
- latex?: string;
21
- wikidata?: string;
20
+ latex?: string | undefined;
21
+ wikidata?: string | undefined;
22
22
  };
23
23
  /**
24
24
  * The numeric evaluation mode:
25
25
  *
26
- * - `auto`: use machine number if precision is 15 or less, allow complex numbers.
27
- * - `machine`: 64-bit float, **IEEE 754-2008**, 64-bit float, 52-bit mantissa,
26
+ * - `"auto"`: use machine number if precision is 15 or less, allow complex numbers.
27
+ * - `"machine"`: 64-bit float, **IEEE 754-2008**, 64-bit float, 52-bit mantissa,
28
28
  * about 15 digits of precision
29
- * - `decimal`: arbitrary precision floating point numbers, as provided by the
29
+ * - `"decimal"`: arbitrary precision floating point numbers, as provided by the
30
30
  * "decimal.js" library
31
- * - `complex`: complex number represented by two machine numbers, a real and
31
+ * - `"complex"`: complex number represented by two machine numbers, a real and
32
32
  * an imaginary part, as provided by the "complex.js" library
33
33
  */
34
34
  export declare type NumericMode = 'auto' | 'machine' | 'decimal' | 'complex';
@@ -49,16 +49,16 @@ export declare type EvaluateOptions = {};
49
49
  */
50
50
  export declare type NOptions = {};
51
51
  export declare type ReplaceOptions = {
52
- /** If true, apply replacement rules to all sub-expressions.
53
- * If false, only consider the top-level expression.
52
+ /** If `true`, apply replacement rules to all sub-expressions.
53
+ * If `false`, only consider the top-level expression.
54
54
  *
55
55
  * **Default**: `true`
56
56
  */
57
57
  recursive?: boolean;
58
58
  /**
59
- * If true, stop after the first rule that matches.
59
+ * If `true`, stop after the first rule that matches.
60
60
  *
61
- * If false, apply all the remaining rules even after the first match.
61
+ * If `false`, apply all the remaining rules even after the first match.
62
62
  *
63
63
  * **Default**: `true`
64
64
  */
@@ -81,6 +81,9 @@ export declare type ReplaceOptions = {
81
81
  * rule whose `lhs` is always a symbol.
82
82
  */
83
83
  export declare type Substitution = {
84
+ [symbol: string]: SemiBoxedExpression;
85
+ };
86
+ export declare type BoxedSubstitution = {
84
87
  [symbol: string]: BoxedExpression;
85
88
  };
86
89
  /** A LaTeX string starts and end with `$`, for example
@@ -111,7 +114,7 @@ export declare type Rule = [
111
114
  lhs: LatexString | SemiBoxedExpression | Pattern,
112
115
  rhs: LatexString | SemiBoxedExpression,
113
116
  options?: {
114
- condition?: LatexString | ((wildcards: Substitution) => boolean);
117
+ condition?: LatexString | ((wildcards: BoxedSubstitution) => boolean);
115
118
  priority?: number;
116
119
  }
117
120
  ];
@@ -119,51 +122,44 @@ export declare type BoxedRule = [
119
122
  lhs: Pattern,
120
123
  rhs: BoxedExpression,
121
124
  priority: number,
122
- condition: undefined | ((wildcards: Substitution) => boolean)
125
+ condition: undefined | ((wildcards: BoxedSubstitution) => boolean)
123
126
  ];
124
127
  export declare type BoxedRuleSet = Set<BoxedRule>;
125
- export declare type ParametricDomainFunction = 'Function' | 'Union' | 'List' | 'Record' | 'Tuple' | 'Intersection' | 'Range' | 'Interval' | 'Optional' | 'Some' | 'Head' | 'Symbol' | 'Literal';
126
- export declare type ParametricDomain = [
127
- ParametricDomainFunction,
128
- ...DomainExpression[]
129
- ];
130
- export declare type DomainExpression = string | ParametricDomain;
131
- /**
132
- * Domains can be defined as a union or intersection of domains:
133
- * - `["Union", "Number", "Boolean"]` A number or a boolean.
134
- * - `["SetMinus", "Number", 1]` Any number except "1".
135
- *
136
- */
137
- export interface Domain extends BoxedExpression {
138
- isSubdomainOf(dom: Domain | string): boolean;
139
- isMemberOf(expr: BoxedExpression): boolean;
140
- readonly domainExpression: DomainExpression;
141
- codomain: Domain | null;
128
+ export declare type DomainCompatibility = 'covariant' | 'contravariant' | 'bivariant' | 'invariant';
129
+ /** A domain constructor is the head of a domain expression. */
130
+ export declare type DomainConstructor = 'Error' | 'Matrix' | 'SquareMatrix' | 'Vector' | 'Function' | 'List' | 'Dictionary' | 'Tuple' | 'Range' | 'Interval' | 'Intersection' | 'Union' | 'Maybe' | 'Sequence' | 'Head' | 'Symbol' | 'Value' | 'Covariant' | 'Contravariant' | 'Bivariant' | 'Invariant';
131
+ export declare type DomainLiteral = string;
132
+ export declare type DomainExpression<T = SemiBoxedExpression> = DomainLiteral | [DomainConstructor, ...(string | T | DomainExpression<T>)[]] | ['Error', T] | ['Error', T, T] | ['Union', ...DomainExpression<T>[]] | ['Intersection', ...DomainExpression<T>[]] | ['Matrix', DomainExpression<T>, T, T] | ['SquareMatrix', DomainExpression<T>, T] | ['Vector', DomainExpression<T>, T] | ['List', DomainExpression<T>] | ['Dictionary', DomainExpression<T>] | ['Tuple', ...DomainExpression<T>[]] | ['Maybe', DomainExpression<T>] | ['Sequence', DomainExpression<T>] | ['Range'] | ['Range', T] | ['Range', T, T] | ['Range', T, T, T] | ['Interval', T, T] | ['Interval', ['Open', T], T] | ['Interval', T, ['Open', T]] | ['Interval', ['Open', T], ['Open', T]] | ['Value', T] | ['Head', string] | ['Symbol', string] | ['Covariant', DomainExpression<T>] | ['Contravariant', DomainExpression<T>] | ['Bivariant', DomainExpression<T>] | ['Invariant', DomainExpression<T>] | ['Function', ...DomainExpression<T>[]];
133
+ export interface BoxedDomain extends BoxedExpression {
134
+ is(s: BoxedDomain): boolean;
135
+ /** True if a valid domain, and compatible with `dom` */
136
+ isCompatible(dom: BoxedDomain | DomainLiteral, kind?: DomainCompatibility): boolean;
137
+ get literal(): string | null;
138
+ get ctor(): DomainConstructor | null;
139
+ get domainArgs(): (DomainExpression<BoxedExpression> | BoxedExpression | string)[] | null;
140
+ get domainArg1(): string | BoxedExpression | DomainExpression<BoxedExpression> | null;
141
+ get codomain(): BoxedDomain | null;
142
+ get canonical(): BoxedDomain;
143
+ get json(): Expression;
142
144
  readonly isNothing: boolean;
143
- is(s: BoxedExpression): boolean;
144
- readonly isBoolean: boolean;
145
145
  readonly isNumeric: boolean;
146
146
  readonly isFunction: boolean;
147
- readonly isPredicate: boolean;
148
147
  /**
149
148
  * If true, when all the arguments are numeric, the result of the
150
149
  * evaluation is numeric. Numeric is any value with a domain of `Number`.
151
150
  *
152
151
  * Example of numeric functions: `Add`, `Multiply`, `Power`, `Abs`
153
152
  *
154
- * Default: false
153
+ * Default: `false`
155
154
  */
156
- readonly isNumericFunction: boolean;
157
- readonly isRealFunction: boolean;
158
155
  /**
159
156
  * If true, when all the arguments are boolean, the result of the
160
157
  * evaluation is a boolean. Boolean is any value with a domain of `MaybeBoolean`.
161
158
  *
162
159
  * Example of logic functions: `And`, `Or`, `Not`, `Implies`
163
160
  *
164
- * **Default:** false
161
+ * **Default:** `false`
165
162
  */
166
- readonly isLogicOperator: boolean;
167
163
  /**
168
164
  * The function represent a relation between the first argument and
169
165
  * the second argument, and evaluates to a boolean indicating if the relation
@@ -171,7 +167,7 @@ export interface Domain extends BoxedExpression {
171
167
  *
172
168
  * For example, `Equal`, `Less`, `Approx`, etc...
173
169
  *
174
- * **Default:** false
170
+ * **Default:** `false`
175
171
  */
176
172
  readonly isRelationalOperator: boolean;
177
173
  }
@@ -194,7 +190,7 @@ export declare type JsonSerializationOptions = {
194
190
  /** A list of space separated keywords indicating which MathJSON expressions
195
191
  * can use a shorthand.
196
192
  *
197
- * **Default**: `['all']`
193
+ * **Default**: `["all"]`
198
194
  */
199
195
  shorthands: ('all' | 'number' | 'symbol' | 'function' | 'dictionary' | 'string')[];
200
196
  /** A list of space separated keywords indicating which metadata should be
@@ -235,542 +231,638 @@ export interface BoxedExpression {
235
231
  readonly engine: IComputeEngine;
236
232
  /** From `Object.valueOf()`, return a primitive value for the expression.
237
233
  *
238
- * If the expression is a machine number, or a Decimal that can be
234
+ * If the expression is a machine number, or a Decimal or rational that can be
239
235
  * converted to a machine number, return a `number`.
240
236
  *
241
- * If the expression is a rational number, return `[number, number]`.
242
- *
243
237
  * If the expression is a symbol, return the name of the symbol as a `string`.
244
238
  *
245
239
  * Otherwise return a LaTeX representation of the expression.
246
240
  *
247
- * @category Object Methods
241
+ * @category Primitive Methods
248
242
  */
249
- valueOf(): number | string | [number, number];
243
+ valueOf(): number | string | boolean;
250
244
  /** From `Object.toString()`, return a LaTeX representation of the expression.
251
245
  *
252
- * @category Object Methods
246
+ * Used when coercing a `BoxedExpression` to a `String`.
247
+ *
248
+ * @category Primitive Methods
253
249
  */
254
250
  toString(): string;
255
- /** From `Object.toJSON()`, equivalent to `JSON.stringify(this.json)`
251
+ /** Similar to`expr.valueOf()` but includes a hint.
252
+ * @category Primitive Methods
253
+ */
254
+ [Symbol.toPrimitive](hint: 'number' | 'string' | 'default'): number | string | null;
255
+ /** Used by `JSON.stringify()` to serialize this object to JSON.
256
+ *
257
+ * Method version of `expr.json`.
258
+ *
259
+ * @category Primitive Methods
260
+ */
261
+ toJSON(): Expression;
262
+ /** If `true`, this expression is in a canonical form.
263
+ *
264
+ * **Note** applicable to canonical and non-canonical expressions.
256
265
  *
257
- * @category Object Methods
258
266
  */
259
- toJSON(): string;
267
+ get isCanonical(): boolean;
268
+ /** For internal use only, set when a canonical expression is created.
269
+ * @internal
270
+ */
271
+ set isCanonical(val: boolean);
272
+ /** MathJSON representation of this expression.
273
+ *
274
+ * **Note** applicable to canonical and non-canonical expressions.
275
+ *
276
+ */
277
+ readonly json: Expression;
260
278
  /** From `Object.is()`. Equivalent to `BoxedExpression.isSame()`
261
279
  *
262
- * @category Object Methods
280
+ * @category Primitive Methods
263
281
  *
264
282
  */
265
283
  is(rhs: unknown): boolean;
266
284
  /** @internal */
267
- get hash(): number;
268
- /** An optional short description of the symbol or function head.
285
+ readonly hash: number;
286
+ /** LaTeX representation of this expression.
269
287
  *
270
- * May include markdown. Each string is a paragraph. */
271
- readonly description: string[];
272
- /** An optional URL pointing to more information about the symbol or function head */
273
- readonly url: string;
274
- /** All boxed expressions have a head.
288
+ * The serialization can be customized with `ComputeEngine.latexOptions`
275
289
  *
276
- * If not a function this can be `Symbol`, `String`, `Number` or `Dictionary`.
290
+ * **Note** applicable to canonical and non-canonical expressions.
277
291
  *
278
- * If the head expression can be represented as a string, it is returned
279
- * as a string.
280
292
  */
281
- get head(): BoxedExpression | string;
293
+ get latex(): LatexString;
282
294
  /**
283
- * If `this.isPure` is `true`, this is a synonym for `this.evaluate()`.
284
- * Otherwise, it returns `undefined`.
285
- */
286
- get value(): BoxedExpression | undefined;
287
- /** Only the value of variables can be changed (symbols that are not constants) */
288
- set value(value: BoxedExpression | number | undefined);
289
- /** Return an approximation of the value of this expression. Floating-point
290
- * operations may be performed.
291
295
  *
292
- * Just like `this.value`, it returns `undefined` for impure expressions.
296
+ * **Note** applicable to canonical and non-canonical expressions.
297
+ * @internal
293
298
  */
294
- get numericValue(): BoxedExpression | undefined;
295
- /** If true, the value of the expression never changes and evaluating it has
296
- * no side-effects.
297
- * If false, the value of the expression may change, if the
298
- * value of other expression changes or for other reasons.
299
+ set latex(val: string);
300
+ /** If this expression is a symbol, return the name of the symbol as a string.
301
+ * Otherwise, return `null`.
299
302
  *
300
- * If `this.isPure` is `false`, `this.value` is undefined. Call
301
- * `this.evaluate()` to determine the value of the expression instead.
303
+ * **Note** applicable to canonical and non-canonical expressions.
304
+
305
+ * @category Symbol Expression
302
306
  *
303
- * As an example, the `Random` function is not pure.
304
307
  */
305
- get isPure(): boolean;
308
+ readonly symbol: string | null;
306
309
  /**
307
- * If `true`, this expression represents a value that was not calculated
308
- * or that does not reference another expression.
309
- * This means the expression is either a number, a string or a dictionary.
310
- * Functions and symbols are not literals.
311
- */
312
- get isLiteral(): boolean;
313
- /** If `true`, this expression is in a canonical form */
314
- get isCanonical(): boolean;
315
- /** For internal use only, set when a canonical expression is created.
316
- * @internal
310
+ * If this is the `Nothing` symbol, return `true`.
311
+ *
312
+ * **Note** applicable to canonical and non-canonical expressions.
317
313
  */
318
- set isCanonical(val: boolean);
319
- /** `ops` is the list of arguments of the function, its "tail"
314
+ readonly isNothing: boolean;
315
+ /** If this expression is a string, return the value of the string.
316
+ * Otherwise, return `null`.
320
317
  *
321
- * @category Function Expression
318
+ * **Note** applicable to canonical and non-canonical expressions.
319
+
320
+ * @category String Expression
322
321
  *
323
322
  */
324
- get ops(): null | BoxedExpression[];
325
- /** If this expression is a function, the number of operands, otherwise 0.
326
- *
327
- * Note that a function can have 0 operands, so to check if this expression
328
- * is a function, check if `this.ops !== null` instead.
323
+ readonly string: string | null;
324
+ /** All the subexpressions matching the head
329
325
  *
330
- * @category Function Expression
326
+ * **Note** applicable to canonical and non-canonical expressions.
331
327
  *
332
328
  */
333
- get nops(): number;
334
- /** First operand, i.e.`this.ops[0]`
329
+ getSubexpressions(head: string): BoxedExpression[];
330
+ /** All the subexpressions in this expression, recursively
335
331
  *
332
+ * **Note** applicable to canonical and non-canonical expressions.
336
333
  *
337
- * @category Function Expression
334
+ */
335
+ readonly subexpressions: BoxedExpression[];
336
+ /** All the symbols in the expression, recursively
338
337
  *
338
+ * **Note** applicable to canonical and non-canonical expressions.
339
339
  *
340
340
  */
341
- get op1(): BoxedExpression;
342
- /** Second operand, i.e.`this.ops[0]`
341
+ readonly symbols: BoxedExpression[];
342
+ /** All the `["Error"]` subexpressions
343
343
  *
344
+ * **Note** applicable to canonical and non-canonical expressions.
344
345
  *
345
- * @category Function Expression
346
+ */
347
+ readonly errors: BoxedExpression[];
348
+ /** All boxed expressions have a head.
349
+ *
350
+ * If not a function this can be `Symbol`, `String`, `Number` or `Dictionary`.
346
351
  *
352
+ * If the head expression can be represented as a string, it is returned
353
+ * as a string.
347
354
  *
355
+ * **Note** applicable to canonical and non-canonical expressions. The head
356
+ * of a non-canonical expression may be different than the head of its
357
+ * canonical counterpart. For example the canonical counterpart of `["Divide", 5, 7]` is `["Rational", 5, 5]`.
348
358
  */
349
- get op2(): BoxedExpression;
350
- /** Third operand, i.e. `this.ops[2]`
359
+ readonly head: BoxedExpression | string;
360
+ /** The list of arguments of the function, its "tail".
351
361
  *
362
+ * If the expression is not a function, return `null`.
352
363
  *
353
- * @category Function Expression
364
+ * **Note** applicable to canonical and non-canonical expressions.
354
365
  *
366
+ * @category Function Expression
355
367
  *
356
368
  */
357
- get op3(): BoxedExpression;
358
- /** The keys of the dictionary.
369
+ readonly ops: null | BoxedExpression[];
370
+ /** If this expression is a function, the number of operands, otherwise 0.
359
371
  *
360
- * If this expression not a dictionary, return `null`
372
+ * Note that a function can have 0 operands, so to check if this expression
373
+ * is a function, check if `this.ops !== null` instead.
361
374
  *
362
- * @category Dictionary Expression
375
+ * **Note** applicable to canonical and non-canonical expressions.
363
376
  *
364
- */
365
- get keys(): IterableIterator<string> | null;
366
- /**
377
+ * @category Function Expression
367
378
  *
368
- * @category Dictionary Expression
369
379
  */
370
- get keysCount(): number;
371
- /**
372
- * If this expression is a dictionary, return the value of the `key` entry.
380
+ readonly nops: number;
381
+ /** First operand, i.e.`this.ops[0]`
373
382
  *
374
- * @category Dictionary Expression
383
+ * **Note** applicable to canonical and non-canonical expressions.
375
384
  *
376
- */
377
- getKey(key: string): BoxedExpression | undefined;
378
- /**
379
- * If this expression is a dictionary, return true if the dictionary has a
380
- * `key` entry.
385
+ * @category Function Expression
381
386
  *
382
- * @category Dictionary Expression
383
387
  *
384
388
  */
385
- hasKey(key: string): boolean;
386
- /**
387
- * Return the value of this number or symbol, if stored as a machine number.
389
+ readonly op1: BoxedExpression;
390
+ /** Second operand, i.e.`this.ops[1]`
388
391
  *
389
- * Note it is possible for `machineValue` to be `null`, and for `isNotZero` to be true.
390
- * For example, when a symbol has been defined with an assumption.
392
+ * **Note** applicable to canonical and non-canonical expressions.
391
393
  *
392
- * If `machineValue` is not `null`, then `decimalValue`, `rationalValue`
393
- * and `complexValue` are `null.
394
+ * @category Function Expression
394
395
  *
395
- * @category Numeric Expression
396
396
  *
397
397
  */
398
- get machineValue(): number | null;
399
- /** If the value of this expression is a rational number, return it.
400
- * Otherwise, return `[null, null]`.
398
+ readonly op2: BoxedExpression;
399
+ /** Third operand, i.e. `this.ops[2]`
401
400
  *
402
- * If `rationalValue` is not `[null, null]`, then `machineValue`, `decimalValue`
403
- * and `complexValue` are `null.
401
+ * **Note** applicable to canonical and non-canonical expressions.
402
+ *
403
+ * @category Function Expression
404
404
  *
405
- * @category Numeric Expression
406
405
  *
407
406
  */
408
- get rationalValue(): [numer: number, denom: number] | [null, null];
409
- /** If the value of this expression is a `Decimal` number, return it.
410
- * Otherwise, return `null`.
407
+ readonly op3: BoxedExpression;
408
+ /** `true` if this expression or any of its subexpressions is an `["Error"]`
409
+ * expression.
411
410
  *
412
- * A `Decimal` number is an arbitrarily long floating point number.
411
+ * **Note** applicable to canonical and non-canonical expressions. For
412
+ * non-canonical expression, this may indicate a syntax error while parsing
413
+ * LaTeX. For canonical expression, this may indicate argument domain
414
+ * mismatch, or missing or unexpected arguments.
413
415
  *
414
- * If `decimalValue` is not `null`, then `machineValue`
415
- * and `complexValue` are `null` and `rationalValue` is `[null, null]`.
416
- *
417
- * @category Numeric Expression
416
+ * @category Symbol Expression
418
417
  *
419
418
  */
420
- get decimalValue(): Decimal | null;
421
- /** If the value of this expression is a `Complex` number, return it.
422
- * Otherwise, return `null`.
419
+ readonly isValid: boolean;
420
+ /**
421
+ * If `true`, this expression represents a value that was not calculated
422
+ * and that does not reference another expression.
423
423
  *
424
- * If `complexValue` is not `null`, then `machineValue`, `rationalValue`
425
- * and `decimalValue` are `null.
424
+ * This means the expression is either a number, a string or a dictionary.
425
+ * Functions and symbols are not literals.
426
426
  *
427
- * @category Numeric Expression
427
+ * **Note** applicable to canonical and non-canonical expressions.
428
+ */
429
+ readonly isLiteral: boolean;
430
+ /** If true, the value of the expression never changes and evaluating it has
431
+ * no side-effects.
432
+ * If false, the value of the expression may change, if the
433
+ * value of other expression changes or for other reasons.
428
434
  *
435
+ * If `this.isPure` is `false`, `this.value` is undefined. Call
436
+ * `this.evaluate()` to determine the value of the expression instead.
437
+ *
438
+ * As an example, the `Random` function is not pure.
429
439
  *
440
+ * **Note** applicable to canonical and non-canonical expressions.
430
441
  */
431
- get complexValue(): Complex | null;
432
- /** Return an approximation of the numeric value of this expression as
433
- * a 64-bit floating point number.
442
+ readonly isPure: boolean;
443
+ /** True if the expression is a free variable, that is a symbol with no value */
444
+ readonly isFree: boolean;
445
+ /** True if the expression is a constant, that is a symbol with an immutable value */
446
+ readonly isConstant: boolean;
447
+ /**
448
+ * Return the canonical form of this expression.
434
449
  *
435
- * If the value is a machine number, return it exactly.
450
+ * If a function, after putting all the arguments in canonical form, find
451
+ * a corresponding function definition in the current context.
436
452
  *
437
- * If the value is a rational number, return the numerator divided by the
438
- * denominator.
453
+ * Apply the function definition flags:
454
+ * - `associative`: \\( f(a, f(b), c) \longrightarrow f(a, b, c) \\)
455
+ * - `idempotent`: \\( f(f(a)) \longrightarrow f(a) \\)
456
+ * - `involution`: \\( f(f(a)) \longrightarrow a \\)
457
+ * - `commutative`: sort the arguments.
439
458
  *
440
- * If the value is a Decimal number that can be represented by a machine
441
- * number, return this value. There might be a small loss of precision due
442
- * to the limitations of the binary representation of numbers as machine
443
- * numbers.
459
+ * Additionally, some simplifications involving exact computations on
460
+ * small integers may be performed.
444
461
  *
445
- * If the value of this expression cannot be represented by a float,
446
- * return `null`.
462
+ * For example:
463
+ * - \\( 2 + x + 1 \longrightarrow x + 3 \\)
464
+ * - \\( \sqrt{4} \longrightarrow 2 \\)
465
+ * - \\(\frac{4}{10} \longrightarrow \frac{2}{5} \\).
447
466
  *
448
- * @category Numeric Expression
467
+ * However, no calculation is performed involving floating point numbers, so
468
+ * \\( \sqrt(2) \longrightarrow \sqrt(2) \\).
449
469
  *
470
+ * **Note** applicable to canonical and non-canonical expressions.
471
+ * Expressions that are already canonical return themselves.
450
472
  *
451
473
  */
452
- get asFloat(): number | null;
474
+ get canonical(): BoxedExpression;
453
475
  /**
454
- * If the value of this expression is an integer with a 'small' absolute value,
455
- * return this value. Otherwise, return `null`.
476
+ * If this expression is a function, apply the function `fn` to all its operands.
456
477
  *
457
- * Some calculations, for example to put in canonical forms, are only
458
- * performed if they are safe from overflow. This method makes it easy
459
- * to check for this, whether the value is a Decimal or a number.
478
+ * Replace the head of this expression with `head`, if defined.
460
479
  *
461
- * By default, "small" is less than 10,000.
480
+ * If this expression is a dictionary, return a new dictionary with the values
481
+ * modified by `fn`.
462
482
  *
463
- * @category Numeric Expression
483
+ * If `head` is provided, return a function expression with the modified
484
+ * dictionary as operand, otherwise return the modified dictionary.
464
485
  *
465
- */
466
- get asSmallInteger(): number | null;
486
+ * **Note** applicable to canonical and non-canonical expressions.
487
+ *
488
+ * */
489
+ apply(fn: (x: BoxedExpression) => SemiBoxedExpression, head?: string): BoxedExpression;
467
490
  /**
468
- * If the value of this an expression is a small integer or a rational,
469
- * return this value. Otherwise, return `[null, null`].
491
+ * Replace all the symbols in the expression as indicated.
470
492
  *
471
- * @category Numeric Expression
493
+ * Note the same effect can be achieved with `this.replace()`, but
494
+ * using `this.subs()` is more efficient, and simpler.
495
+ *
496
+ * **Note** applicable to canonical and non-canonical expressions.
472
497
  *
473
498
  */
474
- get asRational(): [number, number] | [null, null];
499
+ subs(sub: Substitution): BoxedExpression;
475
500
  /**
476
- * Return the following, depending on the value of this expression:
501
+ * Transform the expression by applying the rules:
502
+ * if the `lhs` of a rule matches, it is replaced by its `rhs`.
477
503
  *
478
- * * `-1` if it is < 0
479
- * * `0` if it is = 0
480
- * * `+1` if it is > 0
481
- * * `undefined` this value may be positive, negative or zero. We don't know
482
- * right now (a symbol with an Integer domain, but no currently assigned
483
- * value, for example)
484
- * * `null` this value will never be positive, negative or zero (`NaN`,
485
- * a string or a complex number for example)
504
+ * If no rules apply, return `null`.
486
505
  *
487
- * Note that complex numbers have no natural ordering,
488
- * so if the value is a complex number, `sgn` is either 0, or `null`
506
+ * See also `subs` for a simple substitution.
489
507
  *
490
- * If a symbol, this does take assumptions into account, that is `this.sgn` will return
491
- * `1` if `isPositive` is `true`, even if this expression has no value
492
508
  *
493
- * @category Numeric Expression
509
+ * **Note** applicable to canonical and non-canonical expressions.
494
510
  *
495
511
  */
496
- get sgn(): -1 | 0 | 1 | undefined | null;
497
- /** If this expression is a symbol, return the name of the symbol as a string.
498
- * Otherwise, return `null`.
499
- *
500
- * @category Symbol Expression
512
+ replace(rules: BoxedRuleSet, options?: ReplaceOptions): null | BoxedExpression;
513
+ /**
514
+ * True if the expression includes a symbol `v` or a function head `v`.
501
515
  *
516
+ * **Note** applicable to canonical and non-canonical expressions.
502
517
  */
503
- get symbol(): string | null;
504
- /** Shortcut for `this.symbol === "Missing"`
505
- *
506
- * @category Symbol Expression
518
+ has(v: string | string[]): boolean;
519
+ /** Structural/symbolic equality (weak equality).
507
520
  *
508
- */
509
- get isMissing(): boolean;
510
- /** If this expression is a string, return the value of the string.
511
- * Otherwise, return `null`.
521
+ * `ce.parse('1+x').isSame(ce.parse('x+1'))` is `false`
512
522
  *
513
- * @category String Expression
523
+ * **Note** applicable to canonical and non-canonical expressions.
514
524
  *
525
+ * @category Relational Operator
515
526
  */
516
- get string(): string | null;
517
- /** True if the value of this expression is a number.
527
+ isSame(rhs: BoxedExpression): boolean;
528
+ /** Attempt to match this expression to the `rhs` expression.
518
529
  *
519
- * `isExtendedComplex || isNaN` = `isReal || isImaginary || isInfinity || isNaN`
530
+ * If `rhs` does not match, return `null`.
520
531
  *
521
- * Note that in a fateful twist of cosmic irony, `NaN` ("Not a Number")
522
- * is a number.
532
+ * Otherwise return an object literal.
523
533
  *
524
- * @category Expression Properties
525
- */
526
- get isNumber(): boolean | undefined;
527
- /** The value of this expression is an element of the set ℤ: ...,-2, -1, 0, 1, 2...
534
+ * If this expression includes wildcards (symbols with a name that starts
535
+ * with `_`), the object literal will include a prop for each matching named
536
+ * wildcard.
528
537
  *
538
+ * If `rhs` matches this pattern but there are no named wildcards, return
539
+ * the empty object literal, `{}`.
529
540
  *
530
- * @category Expression Properties
541
+ * **Note** applicable to canonical and non-canonical expressions.
531
542
  *
532
543
  */
533
- get isInteger(): boolean | undefined;
534
- /** The value of this expression is an element of the set ℚ, p/q with p ∈ ℕ, q ∈ ℤ ⃰ q >= 1
544
+ match(rhs: BoxedExpression, options?: PatternMatchOption): Substitution | null;
545
+ /**
546
+ * "Not a Number".
535
547
  *
536
- * Note that every integer is also a rational.
548
+ * A value representing undefined result of computations, such as `0/0`,
549
+ * as per the floating point format standard IEEE-754.
537
550
  *
551
+ * Note that if `isNaN` is true, `isNumber` is also true (yes, `NaN` is a
552
+ * number).
538
553
  *
539
554
  * @category Expression Properties
540
555
  *
541
556
  */
542
- get isRational(): boolean | undefined;
557
+ readonly isNaN: boolean | undefined;
543
558
  /**
544
- * The value of this expression is a number that is the root of a non-zero
545
- * univariate polynomial with rational coefficients.
546
- *
547
- * All integers and rational numbers are algebraic.
548
- *
549
- * Transcendental numbers, such as \\( \pi \\) or \\( e \\) are not algebraic.
550
- *
559
+ * The numeric value of this expression is 0.
551
560
  *
552
561
  * @category Expression Properties
553
- *
554
562
  */
555
- get isAlgebraic(): boolean | undefined;
563
+ readonly isZero: boolean | undefined;
556
564
  /**
557
- * The value of this expression is real number: finite and not imaginary.
558
- *
559
- * `isFinite && !isImaginary`
560
- *
561
- *
565
+ * The numeric value of this expression is not 0.
562
566
  * @category Expression Properties
563
567
  */
564
- get isReal(): boolean | undefined;
565
- /** Real or ±Infinity
566
- *
567
- * `isReal || isInfinity`
568
- *
569
- *
568
+ readonly isNotZero: boolean | undefined;
569
+ /**
570
+ * The numeric value of this expression is not 1.
570
571
  * @category Expression Properties
571
572
  */
572
- get isExtendedReal(): boolean | undefined;
573
+ readonly isOne: boolean | undefined;
573
574
  /**
574
- * The value of this expression is a number, but not `NaN` or any Infinity
575
- *
576
- * `isReal || isImaginary`
577
- *
578
- *
575
+ * The numeric value of this expression is not -1.
579
576
  * @category Expression Properties
580
- *
581
577
  */
582
- get isComplex(): boolean | undefined;
583
- /** `isReal || isImaginary || isInfinity`
584
- *
578
+ readonly isNegativeOne: boolean | undefined;
579
+ /** The numeric value of this expression is ±Infinity or Complex Infinity
585
580
  *
586
581
  * @category Expression Properties
587
582
  */
588
- get isExtendedComplex(): boolean | undefined;
589
- /** The value of this expression is a number with a imaginary part
590
- *
583
+ readonly isInfinity: boolean | undefined;
584
+ /** This expression is a number, but not ±Infinity and not `NaN`
591
585
  *
592
586
  * @category Expression Properties
593
587
  */
594
- get isImaginary(): boolean | undefined;
588
+ readonly isFinite: boolean | undefined;
595
589
  /**
596
590
  * @category Expression Properties
597
591
  */
598
- get isZero(): boolean | undefined;
592
+ readonly isEven: boolean | undefined;
599
593
  /**
600
594
  * @category Expression Properties
601
595
  */
602
- get isNotZero(): boolean | undefined;
596
+ readonly isOdd: boolean | undefined;
603
597
  /**
604
598
  * @category Expression Properties
605
599
  */
606
- get isOne(): boolean | undefined;
600
+ readonly isPrime: boolean | undefined;
607
601
  /**
608
602
  * @category Expression Properties
609
603
  */
610
- get isNegativeOne(): boolean | undefined;
611
- /** ±Infinity or Complex Infinity
612
- *
613
- * @category Expression Properties
614
- */
615
- get isInfinity(): boolean | undefined;
604
+ readonly isComposite: boolean | undefined;
616
605
  /**
617
- * "Not a Number".
606
+ * Return the value of this expression, if stored as a machine
607
+ * number.
618
608
  *
619
- * A value representing undefined result of computations, such as `0/0`,
620
- * as per the floating point format standard IEEE-754.
609
+ * Note it is possible for `machineValue` to be `null`, and for `isNotZero`
610
+ * to be true. For example, when a symbol has been defined with an assumption.
621
611
  *
622
- * Note that if `isNaN` is true, `isNumber` is also true (yes, `NaN` is a
623
- * number).
612
+ * If `machineValue` is not `null`, then `decimalValue`, `rationalValue`
613
+ * and `complexValue` are `null.
624
614
  *
625
- * @category Expression Properties
615
+ * @category Numeric Expression
626
616
  *
627
617
  */
628
- get isNaN(): boolean | undefined;
629
- /** Not ±Infinity and not `NaN`
618
+ readonly machineValue: number | null;
619
+ /** If the value of this expression is a rational number, return it.
620
+ * Otherwise, return `[null, null]`.
621
+ *
622
+ * If `rationalValue` is not `[null, null]`, then `machineValue`, `decimalValue`
623
+ * and `complexValue` are `null.
624
+ *
625
+ * @category Numeric Expression
630
626
  *
631
- * @category Expression Properties
632
- */
633
- get isFinite(): boolean | undefined;
634
- /**
635
- * @category Expression Properties
636
- */
637
- get isEven(): boolean | undefined;
638
- /**
639
- * @category Expression Properties
640
627
  */
641
- get isOdd(): boolean | undefined;
642
- /**
643
- * @category Expression Properties
628
+ readonly rationalValue: [numer: number, denom: number] | [null, null];
629
+ /** If the value of this expression is a `Decimal` number, return it.
630
+ * Otherwise, return `null`.
631
+ *
632
+ * A `Decimal` number is an arbitrarily long floating point number.
633
+ *
634
+ * If `decimalValue` is not `null`, then `machineValue`
635
+ * and `complexValue` are `null` and `rationalValue` is `[null, null]`.
636
+ *
637
+ * @category Numeric Expression
638
+ *
644
639
  */
645
- get isPrime(): boolean | undefined;
646
- /**
647
- * @category Expression Properties
640
+ readonly decimalValue: Decimal | null;
641
+ /** If the value of this expression is a `Complex` number, return it.
642
+ * Otherwise, return `null`.
643
+ *
644
+ * If `complexValue` is not `null`, then `machineValue`, `rationalValue`
645
+ * and `decimalValue` are `null.
646
+ *
647
+ * @category Numeric Expression
648
+ *
649
+ *
648
650
  */
649
- get isComposite(): boolean | undefined;
650
- /** Structural/symbolic equality (weak equality).
651
+ readonly complexValue: Complex | null;
652
+ /** Return an approximation of the numeric value of this expression as
653
+ * a 64-bit floating point number.
654
+ *
655
+ * If the value is a machine number, return it exactly.
656
+ *
657
+ * If the value is a rational number, return the numerator divided by the
658
+ * denominator.
659
+ *
660
+ * If the value is a Decimal number return an approximation of the decimal
661
+ * number to a machine number. There might be a loss of precision or a
662
+ * round to 0 or Infinity, depending on the value.
663
+ *
664
+ * If the value of this expression cannot be represented by a float,
665
+ * return `null`.
666
+ *
667
+ * @category Numeric Expression
651
668
  *
652
- * `ce.parse('1+x').isSame(ce.parse('x+1'))` is `false`
653
669
  *
654
- * @category Relational Operator
655
670
  */
656
- isSame(rhs: BoxedExpression): boolean;
671
+ readonly asFloat: number | null;
657
672
  /**
658
- * True if the expression includes a symbol `v` or a function head `v`.
659
- */
660
- has(v: string | string[]): boolean;
661
- /** Attempt to match this expression to the `rhs` expression.
673
+ * If the value of this expression is an integer with a 'small' absolute
674
+ * value, return this value. Otherwise, return `null`.
662
675
  *
663
- * If `rhs` does not match, return `null`.
676
+ * Some calculations, for example to put in canonical forms, are only
677
+ * performed if they are safe from overflow. This method makes it easy
678
+ * to check for this, whether the value is a Decimal or a number.
664
679
  *
665
- * Otherwise return an object literal.
680
+ * By default, "small" is less than 1,000,000.
666
681
  *
667
- * If this expression includes wildcards (symbols with a name that starts
668
- * with `_`), the object literal will include a prop for each matching named
669
- * wildcard.
682
+ * @category Numeric Expression
670
683
  *
671
- * If `rhs` matches this pattern but there are no named wildcards, return
672
- * the empty object literal, `{}`.
673
684
  */
674
- match(rhs: BoxedExpression, options?: PatternMatchOption): Substitution | null;
675
- /** Mathematical equality (strong equality), that is the value
676
- * of this expression and of `rhs` are numerically equal.
685
+ readonly asSmallInteger: number | null;
686
+ /**
687
+ * If the value of this an expression is a small integer or a rational,
688
+ * return this value. Otherwise, return `[null, null]`.
689
+ *
690
+ * @category Numeric Expression
691
+ *
692
+ */
693
+ readonly asRational: [number, number] | [null, null];
694
+ /**
695
+ * Return the following, depending on the value of this expression:
696
+ *
697
+ * * `-1` if it is < 0
698
+ * * `0` if it is = 0
699
+ * * `+1` if it is > 0
700
+ * * `undefined` this value may be positive, negative or zero. We don't know
701
+ * right now (a symbol with an Integer domain, but no currently assigned
702
+ * value, for example)
703
+ * * `null` this value will never be positive, negative or zero (`NaN`,
704
+ * a string or a complex number for example)
677
705
  *
678
- * Both expressions are numerically evaluated.
706
+ * Note that complex numbers have no natural ordering,
707
+ * so if the value is a complex number, `sgn` is either 0, or `null`
679
708
  *
680
- * Numbers whose difference is less than `engine.tolerance` are
681
- * considered equal. This tolerance is set when the `engine.precision` is
682
- * changed to be such that the last two digits are ignored.
709
+ * If a symbol, this does take assumptions into account, that is `this.sgn`
710
+ * will return `1` if `isPositive` is `true`, even if this expression has
711
+ * no value
712
+ *
713
+ * @category Numeric Expression
683
714
  *
684
- * @category Relational Operator
685
715
  */
686
- isEqual(rhs: BoxedExpression): boolean;
687
- /** If the expressions cannot be compared, `undefined` is returned
716
+ readonly sgn: -1 | 0 | 1 | undefined | null;
717
+ /** If the expressions cannot be compared, return `undefined`
718
+ *
719
+ * The numeric value of both expressions are compared.
688
720
  *
689
721
  * @category Relational Operator
690
722
  */
691
723
  isLess(rhs: BoxedExpression): boolean | undefined;
692
724
  /**
725
+ * The numeric value of both expressions are compared.
693
726
  * @category Relational Operator
694
727
  */
695
728
  isLessEqual(rhs: BoxedExpression): boolean | undefined;
696
729
  /**
730
+ * The numeric value of both expressions are compared.
697
731
  * @category Relational Operator
698
732
  */
699
733
  isGreater(rhs: BoxedExpression): boolean | undefined;
700
734
  /**
735
+ * The numeric value of both expressions are compared.
701
736
  * @category Relational Operator
702
737
  */
703
738
  isGreaterEqual(rhs: BoxedExpression): boolean | undefined;
704
- /** The value of this expression is > 0, same as `isGreater(0)`
739
+ /** The numeric value of this expression is > 0, same as `isGreater(0)`
705
740
  *
706
741
  * @category Expression Properties
707
742
  */
708
- get isPositive(): boolean | undefined;
709
- /** The value of this expression is >= 0, same as `isGreaterEqual(0)`
743
+ readonly isPositive: boolean | undefined;
744
+ /** The numeric value of this expression is >= 0, same as `isGreaterEqual(0)`
710
745
  *
711
746
  * @category Expression Properties
712
747
  */
713
- get isNonNegative(): boolean | undefined;
714
- /** The value of this expression is < 0, same as `isLess(0)`
748
+ readonly isNonNegative: boolean | undefined;
749
+ /** The numeric value of this expression is < 0, same as `isLess(0)`
715
750
  *
716
751
  * @category Expression Properties
717
752
  */
718
- get isNegative(): boolean | undefined;
719
- /** The value of this expression is <= 0, same as `isLessEqual(0)`
753
+ readonly isNegative: boolean | undefined;
754
+ /** The numeric value of this expression is <= 0, same as `isLessEqual(0)`
720
755
  *
721
756
  * @category Expression Properties
722
757
  */
723
- get isNonPositive(): boolean | undefined;
724
- /** Wikidata identifier */
725
- get wikidata(): string;
726
- set wikidata(val: string);
727
- /** MathJSON representation of this expression */
728
- get json(): Expression;
729
- /** LaTeX representation of this expression */
730
- get latex(): LatexString;
731
- set latex(val: string);
758
+ readonly isNonPositive: boolean | undefined;
759
+ /** The keys of the dictionary.
760
+ *
761
+ * If this expression not a dictionary, return `null`
762
+ *
763
+ * @category Dictionary Expression
764
+ *
765
+ */
766
+ readonly keys: IterableIterator<string> | null;
767
+ /**
768
+ *
769
+ * @category Dictionary Expression
770
+ */
771
+ readonly keysCount: number;
772
+ /**
773
+ * If this expression is a dictionary, return the value of the `key` entry.
774
+ *
775
+ * @category Dictionary Expression
776
+ *
777
+ */
778
+ getKey(key: string): BoxedExpression | undefined;
779
+ /**
780
+ * If this expression is a dictionary, return true if the
781
+ * dictionary has a `key` entry.
782
+ *
783
+ * @category Dictionary Expression
784
+ *
785
+ */
786
+ hasKey(key: string): boolean;
787
+ /** Wikidata identifier.
788
+ *
789
+ * **Note** `undefined` if not a canonical expression.
790
+ *
791
+ *
792
+ */
793
+ get wikidata(): string | undefined;
794
+ set wikidata(val: string | undefined);
795
+ /** An optional short description if the symbol or function head.
796
+ *
797
+ * May include markdown. Each string is a paragraph.
798
+ *
799
+ * **Note** `undefined` if not a canonical expression.
800
+ *
801
+ */
802
+ readonly description: undefined | string[];
803
+ /** An optional URL pointing to more information about the symbol or
804
+ * function head
805
+ *
806
+ * **Note** `undefined` if not a canonical expression.
807
+ *
808
+ */
809
+ readonly url: string | undefined;
732
810
  /** Expressions with a higher complexity score are sorted
733
811
  * first in commutative functions
812
+ *
813
+ * **Note** `undefined` if not a canonical expression.
734
814
  */
735
- get complexity(): number;
736
- /** The domain of this expression. */
737
- get domain(): Domain;
738
- /** Symbols that represent a variable, can have their domain modified */
739
- set domain(domain: Domain | string);
740
- /** The domain of the value of this expression, using the value of the expression,
741
- * definitions associated with this expression and assumptions if necessary.
815
+ readonly complexity: number | undefined;
816
+ /**
817
+ * For symbols and functions, a possible definition associated with the
818
+ * expression. `basedDefinition` is the base class of symbol and function
819
+ * definition.
820
+ *
821
+ * **Note** `undefined` if not a canonical expression.
742
822
  *
743
- * For symbols, the `domain` and `valueDomain` are the same. For functions,
744
- * the `valueDomain` is the codomain of the function.
745
823
  */
746
- get valueDomain(): Domain;
747
- /** For symbols and functions, a possible definition associated with the expression */
748
- get functionDefinition(): BoxedFunctionDefinition | undefined;
749
- get symbolDefinition(): BoxedSymbolDefinition | undefined;
824
+ readonly basedDefinition: BoxedBaseDefinition | undefined;
750
825
  /**
751
- * Return the canonical form of this expression.
826
+ * For functions, a possible definition associated with the expression.
752
827
  *
753
- * If a function, consider the function definition flags:
754
- * - `associative`: \\( f(a, f(b), c) \longrightarrow f(a, b, c) \\)
755
- * - `idempotent`: \\( f(f(a)) \longrightarrow f(a) \\)
756
- * - `involution`: \\( f(f(a)) \longrightarrow a \\)
757
- * - `commutative`: sort the arguments.
828
+ * **Note** `undefined` if not a canonical expression or not a function.
758
829
  *
759
- * Additionally, some simplifications involving exact computations on
760
- * small integers may be performed.
830
+ */
831
+ readonly functionDefinition: BoxedFunctionDefinition | undefined;
832
+ /**
833
+ * For symbols, a possible definition associated with the expression.
761
834
  *
762
- * For example:
763
- * - \\( 2 + x + 1 \longrightarrow x + 3 \\)
764
- * - \\( \sqrt{4} \longrightarrow 2 \\)
765
- * - \\(\frac{4}{10} \longrightarrow \frac{2}{5} \\).
835
+ * **Note** `undefined` if not a symbol
766
836
  *
767
- * However, no calculation is performed involving floating point numbers, so
768
- * \\( \sqrt(2) \longrightarrow \sqrt(2) \\).
837
+ */
838
+ readonly symbolDefinition: BoxedSymbolDefinition | undefined;
839
+ /**
840
+ * The domain of this expression, without accounting for any inferred domain
841
+ * or `ce.defaultDomain`. If no domain has been explicitly set via assignment
842
+ * or via an `.assume()` directive, the `expr.explicitDomain` is `undefined`.
843
+ *
844
+ * This is useful to determine if the domain of an expression is inferred.
845
+ *
846
+ * In most cases you'll want to use `expr.domain` instead.
847
+ *
848
+ * **Note** `undefined` if not a canonical expression or not a function.
769
849
  *
770
- * Determining the canonical form does not depend on the values assigned to,
771
- * or assumptions about, symbols.
772
850
  */
773
- get canonical(): BoxedExpression;
851
+ readonly explicitDomain: BoxedDomain | undefined;
852
+ /**
853
+ * Update the definition associated with this expression, taking
854
+ * into account the specified scope.
855
+ *
856
+ * **Note**: applicable only to canonical expressions
857
+ *
858
+ * @internal
859
+ */
860
+ bind(scope: RuntimeScope | null): void;
861
+ /**
862
+ *
863
+ * @internal
864
+ */
865
+ unbind(): void;
774
866
  /**
775
867
  * Return a simpler form of this expression.
776
868
  *
@@ -830,45 +922,141 @@ export interface BoxedExpression {
830
922
  N(options?: NOptions): BoxedExpression;
831
923
  solve(vars: Iterable<string>): null | BoxedExpression[];
832
924
  /**
833
- * If this expression is a function, apply the function `fn` to all its operands.
834
- * Replace the head of this expression with `head`, if defined.
925
+ * Synonym for `evaluate()`. If the expression is pure, the value may be
926
+ * cached.
835
927
  *
836
- * If this expression is a dictionary, return a new dictionary with the values
837
- * modified by `fn`.
928
+ * It returns `undefined` for expressions that are not pure or that may
929
+ * not be evaluated.
838
930
  *
839
- * If `head` is provided, return a function
840
- * with the modified dictionary as operand, otherwise return the
841
- * modified dictionary. */
842
- apply(fn: (x: BoxedExpression) => SemiBoxedExpression, head?: string): BoxedExpression;
931
+ * **Note**: If non-canonical, return the value of its canonical counterpart
932
+ */
933
+ get value(): BoxedExpression | undefined;
934
+ /** Only the value of variables can be changed (symbols that are not
935
+ * constants).
936
+ *
937
+ * **Note**: If non-canonical, does nothing.
938
+ *
939
+ */
940
+ set value(value: BoxedExpression | number | undefined);
941
+ /** An approximation of the value of this expression. Floating-point
942
+ * operations may be performed.
943
+ *
944
+ * Just like `this.value`, it returns `undefined` for expressions that are
945
+ * not pure.
946
+ *
947
+ * **Note**: If non-canonical, return the numeric value of its canonical
948
+ * counterpart
949
+ */
950
+ readonly numericValue: BoxedExpression | undefined;
951
+ /** The domain of the value of this expression.
952
+ *
953
+ * If a function expression, the domain of the value of the function (the codomain of the function).
954
+ *
955
+ * If a symbol the domain of the value of the symbol.
956
+ *
957
+ * Use `expr.head` to determine if an expression is a symbol or function.
958
+ *
959
+ * **Note**: If non-canonical, return the domain of its canonical
960
+ * counterpart
961
+ */
962
+ get domain(): BoxedDomain;
963
+ /** Modify the domain of a symbol that represent a variable
964
+ * (or a function name).
965
+ *
966
+ * **Note**: If non-canonical, does nothing.
967
+ *
968
+ */
969
+ set domain(domain: BoxedDomain | string);
970
+ /** `true` if the value of this expression is a number.
971
+ *
972
+ * `isExtendedComplex || isNaN` = `isReal || isImaginary || isInfinity || isNaN`
973
+ *
974
+ * Note that in a fateful twist of cosmic irony, `NaN` ("Not a Number")
975
+ * **is** a number.
976
+ *
977
+ * @category Domain Properties
978
+ */
979
+ readonly isNumber: boolean | undefined;
980
+ /** The value of this expression is an element of the set ℤ: ...,-2, -1, 0, 1, 2...
981
+ *
982
+ *
983
+ * @category Domain Properties
984
+ *
985
+ */
986
+ readonly isInteger: boolean | undefined;
987
+ /** The value of this expression is an element of the set ℚ, p/q with p ∈ ℕ, q ∈ ℤ ⃰ q >= 1
988
+ *
989
+ * Note that every integer is also a rational.
990
+ *
991
+ *
992
+ * @category Domain Properties
993
+ *
994
+ */
995
+ readonly isRational: boolean | undefined;
843
996
  /**
844
- * Transform the expression by according to the rules:
845
- * the matching `lhs` of a rule is replaced by its `rhs`.
997
+ * The value of this expression is a number that is the root of a non-zero
998
+ * univariate polynomial with rational coefficients.
846
999
  *
847
- * If no rules apply, return `null`.
1000
+ * All integers and rational numbers are algebraic.
1001
+ *
1002
+ * Transcendental numbers, such as \\( \pi \\) or \\( e \\) are not algebraic.
1003
+ *
1004
+ *
1005
+ * @category Domain Properties
848
1006
  *
849
- * See also `subs` for a simple substitution.
850
1007
  */
851
- replace(rules: BoxedRuleSet, options?: ReplaceOptions): null | BoxedExpression;
1008
+ readonly isAlgebraic: boolean | undefined;
852
1009
  /**
853
- * Replace all the symbols in the expression as indicated.
1010
+ * The value of this expression is real number: finite and not imaginary.
1011
+ *
1012
+ * `isFinite && !isImaginary`
854
1013
  *
855
- * Note the same effect can be achieved with `this.replace()`, but
856
- * using `this.subs()` is more efficient, and simpler.
857
1014
  *
1015
+ * @category Domain Properties
858
1016
  */
859
- subs(sub: Substitution): BoxedExpression;
1017
+ readonly isReal: boolean | undefined;
1018
+ /** Real or ±Infinity
1019
+ *
1020
+ * `isReal || isInfinity`
1021
+ *
1022
+ *
1023
+ * @category Domain Properties
1024
+ */
1025
+ readonly isExtendedReal: boolean | undefined;
860
1026
  /**
861
- * Update the definition associated with this expression, taking
862
- * into account the current context.
1027
+ * The value of this expression is a number, but not `NaN` or any Infinity
1028
+ *
1029
+ * `isReal || isImaginary`
1030
+ *
1031
+ *
1032
+ * @category Domain Properties
863
1033
  *
864
- * @internal
865
1034
  */
866
- _repairDefinition(): void;
867
- /** Purge any cached values.
1035
+ readonly isComplex: boolean | undefined;
1036
+ /** `isReal || isImaginary || isInfinity`
868
1037
  *
869
- * @internal
1038
+ *
1039
+ * @category Domain Properties
1040
+ */
1041
+ readonly isExtendedComplex: boolean | undefined;
1042
+ /** The value of this expression is a number with a imaginary part
1043
+ *
1044
+ *
1045
+ * @category Domain Properties
1046
+ */
1047
+ readonly isImaginary: boolean | undefined;
1048
+ /** Mathematical equality (strong equality), that is the value
1049
+ * of this expression and of `rhs` are numerically equal.
1050
+ *
1051
+ * The numeric value of both expressions are compared.
1052
+ *
1053
+ * Numbers whose difference is less than `engine.tolerance` are
1054
+ * considered equal. This tolerance is set when the `engine.precision` is
1055
+ * changed to be such that the last two digits are ignored.
1056
+ *
1057
+ * @category Relational Operator
870
1058
  */
871
- _purge(): undefined;
1059
+ isEqual(rhs: BoxedExpression): boolean;
872
1060
  }
873
1061
  /** A semi boxed expression is an MathJSON expression which can include some
874
1062
  * boxed terms.
@@ -893,7 +1081,7 @@ export interface Pattern extends BoxedExpression {
893
1081
  * equal to the expression. If there are no named wildcards and the expression
894
1082
  * matches the pattern, and empty object literal `{}` is returned.
895
1083
  */
896
- match(expr: BoxedExpression, options?: PatternMatchOption): Substitution | null;
1084
+ match(expr: BoxedExpression, options?: PatternMatchOption): BoxedSubstitution | null;
897
1085
  /** If `expr` matches the pattern, return `true`, otherwise `false` */
898
1086
  test(expr: BoxedExpression, options?: PatternMatchOption): boolean;
899
1087
  /** Return the number of exprs that matched the pattern */
@@ -909,25 +1097,25 @@ export interface ExpressionMapInterface<U> {
909
1097
  [Symbol.iterator](): IterableIterator<[BoxedExpression, U]>;
910
1098
  }
911
1099
  /**
912
- * A dictionary contains definitions for symbols, functions and rules.
1100
+ * A symbol table contains definitions for symbols, functions and rules.
913
1101
  *
914
1102
  */
915
- export declare type Dictionary = {
1103
+ export declare type SymbolTable = {
916
1104
  symbols?: SymbolDefinition[];
917
1105
  functions?: FunctionDefinition[];
918
1106
  simplifyRules?: BoxedRuleSet;
919
1107
  };
920
1108
  /**
921
- * The entries of a `CompiledDictionary` have been validated and
1109
+ * The entries of a `RuntimeSymbolTable` have been validated and
922
1110
  * optimized for faster evaluation.
923
1111
  *
924
1112
  * When a new scope is created with `pushScope()` or when creating a new
925
1113
  * engine instance, new instances of `RuntimeDictionary` are created as needed.
926
1114
  */
927
- export declare type RuntimeDictionary = {
1115
+ export declare type RuntimeSymbolTable = {
928
1116
  symbols: Map<string, BoxedSymbolDefinition>;
929
1117
  symbolWikidata: Map<string, BoxedSymbolDefinition>;
930
- functions: Map<string, BoxedFunctionDefinition[]>;
1118
+ functions: Map<string, BoxedFunctionDefinition>;
931
1119
  functionWikidata: Map<string, BoxedFunctionDefinition>;
932
1120
  };
933
1121
  /**
@@ -976,7 +1164,7 @@ export declare type Scope = {
976
1164
  };
977
1165
  export declare type RuntimeScope = Scope & {
978
1166
  parentScope: RuntimeScope;
979
- dictionary?: RuntimeDictionary;
1167
+ symbolTable?: RuntimeSymbolTable;
980
1168
  assumptions: undefined | ExpressionMapInterface<boolean>;
981
1169
  /** The location of the call site that created this scope */
982
1170
  origin?: {
@@ -995,9 +1183,9 @@ export declare type BaseDefinition = {
995
1183
  * The name of a symbol or function is an arbitrary string of Unicode
996
1184
  * characters, however the following conventions are recommended:
997
1185
  *
998
- * - Use only letters, digits and `-`, and the first character should be
999
- * a letter: `/^[a-zA-Z][a-zA-Z0-9-]+/`
1000
- * - Built-in functions and symbols should start with an uppercase letter
1186
+ * - Use only letters, digits and `-`: `/[a-zA-Z0-9-]+/`
1187
+ * - The first character should be a letter: `/^[a-zA-Z]/`
1188
+ * - Functions and symbols exported from a library should start with an uppercase letter `/^[A-Z]/`
1001
1189
  *
1002
1190
  */
1003
1191
  name: string;
@@ -1012,25 +1200,8 @@ export declare type BaseDefinition = {
1012
1200
  * for the `Pi` constant.
1013
1201
  */
1014
1202
  wikidata?: string;
1015
- /**
1016
- * The domain of this item.
1017
- *
1018
- * For dictionaries, this is the domain of all the items in the dictionary.
1019
- *
1020
- * For strings, it's always 'String'.
1021
- *
1022
- * For symbols, this is the domain of their value.
1023
- *
1024
- * For functions, this is the signature of the function
1025
- *
1026
- * When `domain` is a handler, calculate the domain (or signature) based on
1027
- * the arguments (for expressions others than functions, `args` is an empty
1028
- * array). If the function cannot be applied to the arguments, return
1029
- * `null`.
1030
- */
1031
- domain?: Domain | DomainExpression | string | ((ce: IComputeEngine, args: BoxedExpression[]) => Domain | DomainExpression);
1032
1203
  };
1033
- export declare type BoxedBaseDefinition = {
1204
+ export interface BoxedBaseDefinition {
1034
1205
  name: string;
1035
1206
  wikidata?: string;
1036
1207
  description?: string | string[];
@@ -1041,32 +1212,35 @@ export declare type BoxedBaseDefinition = {
1041
1212
  * This field is usually undefined, but its value is set by `getDefinition()`
1042
1213
  */
1043
1214
  scope: RuntimeScope | undefined;
1044
- domain?: Domain | ((ce: IComputeEngine, args: BoxedExpression[]) => Domain | DomainExpression);
1045
- _purge(): undefined;
1046
- };
1215
+ /** When the environment changes, for example the numerical precision,
1216
+ * call `reset()` so that any cached values can be recalculated.
1217
+ */
1218
+ reset(): any;
1219
+ }
1047
1220
  /**
1048
1221
  * A function definition can have some flags to indicate specific
1049
1222
  * properties of the function.
1050
1223
  */
1051
1224
  export declare type FunctionDefinitionFlags = {
1052
- /** If true, the function is applied element by element to lists, matrices
1053
- * and equations.
1225
+ /** If `true`, the function is applied element by element to lists, matrices
1226
+ * (`["List"]` or `["Tuple"]` expressions) and equations (relational
1227
+ * operators).
1054
1228
  *
1055
1229
  * **Default**: `false`
1056
1230
  */
1057
1231
  threadable: boolean;
1058
- /** If true, `["f", ["f", a], b]` simplifies to `["f", a, b]`
1232
+ /** If `true`, `["f", ["f", a], b]` simplifies to `["f", a, b]`
1059
1233
  *
1060
1234
  * **Default**: `false`
1061
1235
  */
1062
1236
  associative: boolean;
1063
- /** If true, `["f", a, b]` equals `["f", b, a]`. The canonical
1237
+ /** If `true`, `["f", a, b]` equals `["f", b, a]`. The canonical
1064
1238
  * version of the function will order the arguments.
1065
1239
  *
1066
1240
  * **Default**: `false`
1067
1241
  */
1068
1242
  commutative: boolean;
1069
- /** If true, when the function is univariate, `["f", ["Add", x, c]]` where `c`
1243
+ /** If `true`, when the function is univariate, `["f", ["Add", x, c]]` where `c`
1070
1244
  * is constant, is simplified to `["Add", ["f", x], c]`.
1071
1245
  *
1072
1246
  * When the function is multivariate, additivity is considered only on the
@@ -1076,7 +1250,7 @@ export declare type FunctionDefinitionFlags = {
1076
1250
  *
1077
1251
  * **Default**: `false`
1078
1252
  */
1079
- /** If true, when the function is univariate, `["f", ["Multiply", x, y]]`
1253
+ /** If `true`, when the function is univariate, `["f", ["Multiply", x, y]]`
1080
1254
  * simplifies to `["Multiply", ["f", x], ["f", y]]`.
1081
1255
  *
1082
1256
  * When the function is multivariate, multiplicativity is considered only on the
@@ -1085,26 +1259,26 @@ export declare type FunctionDefinitionFlags = {
1085
1259
  *
1086
1260
  * **Default**: `false`
1087
1261
  */
1088
- /** If true, when the function is univariate, `["f", ["Multiply", x, c]]`
1262
+ /** If `true`, when the function is univariate, `["f", ["Multiply", x, c]]`
1089
1263
  * simplifies to `["Multiply", ["f", x], c]` where `c` is constant
1090
1264
  *
1091
- * When the function is multivariate, multiplicativity is considered only on the
1092
- * first argument: `["f", ["Multiply", x, y], z]` simplifies to
1265
+ * When the function is multivariate, multiplicativity is considered only on
1266
+ * the first argument: `["f", ["Multiply", x, y], z]` simplifies to
1093
1267
  * `["Multiply", ["f", x, z], ["f", y, z]]`
1094
1268
  *
1095
1269
  * Default: `false`
1096
1270
  */
1097
- /** If true, `["f", ["f", x]]` simplifies to `["f", x]`.
1271
+ /** If `true`, `["f", ["f", x]]` simplifies to `["f", x]`.
1098
1272
  *
1099
1273
  * **Default**: `false`
1100
1274
  */
1101
1275
  idempotent: boolean;
1102
- /** If true, `["f", ["f", x]]` simplifies to `x`.
1276
+ /** If `true`, `["f", ["f", x]]` simplifies to `x`.
1103
1277
  *
1104
1278
  * **Default**: `false`
1105
1279
  */
1106
1280
  involution: boolean;
1107
- /** If true, the value of this function is always the same for a given
1281
+ /** If `true`, the value of this function is always the same for a given
1108
1282
  * set of arguments and it has no side effects.
1109
1283
  *
1110
1284
  * An expression using this function is pure if the function and all its
@@ -1114,7 +1288,7 @@ export declare type FunctionDefinitionFlags = {
1114
1288
  *
1115
1289
  * This information may be used to cache the value of expressions.
1116
1290
  *
1117
- * **Default:** true
1291
+ * **Default:** `true`
1118
1292
  */
1119
1293
  pure: boolean;
1120
1294
  /**
@@ -1125,46 +1299,30 @@ export declare type FunctionDefinitionFlags = {
1125
1299
  * **Default:** false
1126
1300
  */
1127
1301
  inert: boolean;
1128
- };
1129
- /**
1130
- * Definition record for a function.
1131
- *
1132
- */
1133
- export declare type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlags> & {
1134
- /**
1135
- * A number used to order arguments. Argument with higher
1136
- * complexity are placed after arguments with lower complexity when
1137
- * ordered canonically in commutative functions.
1138
- *
1139
- * - Additive functions: 1000-1999
1140
- * - Multiplicative functions: 2000-2999
1141
- * - Root and power functions: 3000-3999
1142
- * - Log functions: 4000-4999
1143
- * - Trigonometric functions: 5000-5999
1144
- * - Hypertrigonometric functions: 6000-6999
1145
- * - Special functions (factorial, Gamma, ...): 7000-7999
1146
- * - Collections: 8000-8999
1147
- * - Inert and styling: 9000-9999
1148
- * - Logic: 10000-10999
1149
- * - Relational: 11000-11999
1150
- *
1151
- * **Default**: 100,000
1152
- */
1153
- complexity?: number;
1154
1302
  /**
1155
- * - `none` Each of the arguments is evaluated (default)
1156
- * - `all` None of the arguments are evaluated and they are passed as is
1157
- * - `first` The first argument is not evaluated, the others are
1158
- * - `rest` The first argument is evaluated, the others aren't
1303
+ * All the arguments of a numeric function are numeric,
1304
+ * and its value is numeric.
1159
1305
  */
1160
- hold?: 'none' | 'all' | 'first' | 'rest' | 'last' | 'most';
1306
+ numeric: boolean;
1161
1307
  /**
1162
- * If true, `Sequence` arguments appearing in the arguments of a function
1163
- * should not automatically be flattened out
1308
+ * When true, evaluating the function create a temporary scope.
1309
+ * This is used for example by the `Lambda` function to keep track of the
1310
+ * inferred domain of its wildcard `_` arguments
1164
1311
  */
1165
- sequenceHold?: boolean;
1312
+ scoped: boolean;
1313
+ };
1314
+ /**
1315
+ *
1316
+ */
1317
+ export declare type FunctionSignature = {
1318
+ /** The domain of this signature, a domain compatible with the `Function`
1319
+ * domain) */
1320
+ domain?: BoxedDomain | DomainExpression;
1166
1321
  /** The minimum and maximum values of the result of the function */
1167
- range?: [min: number, max: number];
1322
+ /** An optional handler to determine the codomain of the function.
1323
+ * If not provided, the codomain of the function is determined from `domain`
1324
+ */
1325
+ codomain?: (ce: IComputeEngine, args: BoxedDomain[]) => BoxedDomain | null;
1168
1326
  /**
1169
1327
  * Return the canonical form of the expression with the arguments `args`.
1170
1328
  *
@@ -1284,11 +1442,9 @@ export declare type FunctionDefinition = BaseDefinition & Partial<FunctionDefini
1284
1442
  /** Return a compiled (optimized) expression. */
1285
1443
  compile?: (expr: BoxedExpression) => CompiledExpression;
1286
1444
  };
1287
- export declare type BoxedFunctionDefinition = BoxedBaseDefinition & FunctionDefinitionFlags & {
1288
- complexity: number;
1289
- hold: 'none' | 'all' | 'first' | 'rest' | 'last' | 'most';
1290
- sequenceHold: boolean;
1291
- range?: [min: number, max: number];
1445
+ export declare type BoxedFunctionSignature = {
1446
+ domain: BoxedDomain;
1447
+ codomain?: BoxedDomain | ((ce: IComputeEngine, args: BoxedDomain[]) => BoxedDomain | null);
1292
1448
  canonical?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression;
1293
1449
  simplify?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | undefined;
1294
1450
  evaluate?: BoxedLambdaExpression | ((ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | undefined);
@@ -1297,6 +1453,50 @@ export declare type BoxedFunctionDefinition = BoxedBaseDefinition & FunctionDefi
1297
1453
  sgn?: (ce: IComputeEngine, args: BoxedExpression[]) => -1 | 0 | 1 | undefined;
1298
1454
  compile?: (expr: BoxedExpression) => CompiledExpression;
1299
1455
  };
1456
+ /**
1457
+ * Definition record for a function.
1458
+ *
1459
+ */
1460
+ export declare type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlags> & {
1461
+ /**
1462
+ * A number used to order arguments.
1463
+ *
1464
+ * Argument with higher complexity are placed after arguments with lower
1465
+ * complexity when ordered canonically in commutative functions.
1466
+ *
1467
+ * - Additive functions: 1000-1999
1468
+ * - Multiplicative functions: 2000-2999
1469
+ * - Root and power functions: 3000-3999
1470
+ * - Log functions: 4000-4999
1471
+ * - Trigonometric functions: 5000-5999
1472
+ * - Hypertrigonometric functions: 6000-6999
1473
+ * - Special functions (factorial, Gamma, ...): 7000-7999
1474
+ * - Collections: 8000-8999
1475
+ * - Inert and styling: 9000-9999
1476
+ * - Logic: 10000-10999
1477
+ * - Relational: 11000-11999
1478
+ *
1479
+ * **Default**: 100,000
1480
+ */
1481
+ complexity?: number;
1482
+ /**
1483
+ * - `"none"` Each of the arguments is evaluated (default)
1484
+ * - `"all"` None of the arguments are evaluated and they are passed as is
1485
+ * - `"first"` The first argument is not evaluated, the others are
1486
+ * - `"rest"` The first argument is evaluated, the others aren't
1487
+ * - `"last"`: The last argument is not evaluated, the others are
1488
+ * - `"most"`: All the arguments are evaluated, except the last one
1489
+ *
1490
+ * **Default**: `"none"`
1491
+ */
1492
+ hold?: 'none' | 'all' | 'first' | 'rest' | 'last' | 'most';
1493
+ signature?: FunctionSignature;
1494
+ };
1495
+ export declare type BoxedFunctionDefinition = BoxedBaseDefinition & FunctionDefinitionFlags & {
1496
+ complexity: number;
1497
+ hold: 'none' | 'all' | 'first' | 'rest' | 'last' | 'most';
1498
+ signature: BoxedFunctionSignature;
1499
+ };
1300
1500
  /**
1301
1501
  * When used in a `SymbolDefinition`, these flags are optional.
1302
1502
  *
@@ -1340,7 +1540,7 @@ export declare type SymbolDefinitionFlags = {
1340
1540
  */
1341
1541
  constant: boolean;
1342
1542
  /**
1343
- * If false, the value of the symbol is substituted during canonicalization
1543
+ * If `false`, the value of the symbol is substituted during canonicalization
1344
1544
  * or simplification.
1345
1545
  *
1346
1546
  * If true, the value is only replaced during a `ce.N()` or `ce.evaluate()`.
@@ -1358,11 +1558,12 @@ export declare type SymbolDefinition = BaseDefinition & Partial<SymbolFlags> & P
1358
1558
  * `Pi`, the actual value depends on the `precision` setting of the
1359
1559
  * `ComputeEngine` */
1360
1560
  value?: LatexString | SemiBoxedExpression | ((ce: IComputeEngine) => SemiBoxedExpression | null);
1361
- domain?: string | Domain;
1561
+ domain?: string | BoxedDomain;
1362
1562
  };
1363
1563
  export interface BoxedSymbolDefinition extends BoxedBaseDefinition, Partial<SymbolFlags>, SymbolDefinitionFlags {
1364
1564
  get value(): BoxedExpression | undefined;
1365
1565
  set value(val: BoxedExpression | undefined);
1566
+ domain: BoxedDomain | undefined;
1366
1567
  at?: (index: string | number) => undefined | BoxedExpression;
1367
1568
  }
1368
1569
  export declare type AssumeResult = 'internal-error' | 'not-a-predicate' | 'contradiction' | 'tautology' | 'ok';
@@ -1379,41 +1580,41 @@ export interface ComputeEngineStats {
1379
1580
  /** @internal */
1380
1581
  export interface IComputeEngine {
1381
1582
  /** @internal */
1382
- readonly ZERO: BoxedExpression;
1583
+ readonly _ZERO: BoxedExpression;
1383
1584
  /** @internal */
1384
- readonly ONE: BoxedExpression;
1585
+ readonly _ONE: BoxedExpression;
1385
1586
  /** @internal */
1386
- readonly TWO: BoxedExpression;
1587
+ readonly _TWO: BoxedExpression;
1387
1588
  /** @internal */
1388
- readonly HALF: BoxedExpression;
1589
+ readonly _HALF: BoxedExpression;
1389
1590
  /** @internal */
1390
- readonly NEGATIVE_ONE: BoxedExpression;
1591
+ readonly _NEGATIVE_ONE: BoxedExpression;
1391
1592
  /** @internal */
1392
- readonly I: BoxedExpression;
1593
+ readonly _I: BoxedExpression;
1393
1594
  /** @internal */
1394
- readonly NAN: BoxedExpression;
1595
+ readonly _NAN: BoxedExpression;
1395
1596
  /** @internal */
1396
- readonly POSITIVE_INFINITY: BoxedExpression;
1597
+ readonly _POSITIVE_INFINITY: BoxedExpression;
1397
1598
  /** @internal */
1398
- readonly NEGATIVE_INFINITY: BoxedExpression;
1599
+ readonly _NEGATIVE_INFINITY: BoxedExpression;
1399
1600
  /** @internal */
1400
- readonly COMPLEX_INFINITY: BoxedExpression;
1601
+ readonly _COMPLEX_INFINITY: BoxedExpression;
1401
1602
  /** @internal */
1402
- readonly DECIMAL_NAN: Decimal;
1603
+ readonly _DECIMAL_NAN: Decimal;
1403
1604
  /** @internal */
1404
- readonly DECIMAL_ZERO: Decimal;
1605
+ readonly _DECIMAL_ZERO: Decimal;
1405
1606
  /** @internal */
1406
- readonly DECIMAL_ONE: Decimal;
1607
+ readonly _DECIMAL_ONE: Decimal;
1407
1608
  /** @internal */
1408
- readonly DECIMAL_TWO: Decimal;
1609
+ readonly _DECIMAL_TWO: Decimal;
1409
1610
  /** @internal */
1410
- readonly DECIMAL_HALF: Decimal;
1611
+ readonly _DECIMAL_HALF: Decimal;
1411
1612
  /** @internal */
1412
- readonly DECIMAL_PI: Decimal;
1613
+ readonly _DECIMAL_PI: Decimal;
1413
1614
  /** @internal */
1414
- readonly DECIMAL_NEGATIVE_ONE: Decimal;
1615
+ readonly _DECIMAL_NEGATIVE_ONE: Decimal;
1415
1616
  /** The current scope */
1416
- context: RuntimeScope;
1617
+ context: RuntimeScope | null;
1417
1618
  /** Absolute time beyond which evaluation should not proceed
1418
1619
  * @internal
1419
1620
  */
@@ -1424,7 +1625,7 @@ export interface IComputeEngine {
1424
1625
  readonly iterationLimit: number;
1425
1626
  /** @experimental */
1426
1627
  readonly recursionLimit: number;
1427
- defaultDomain: null | Domain;
1628
+ defaultDomain: null | BoxedDomain;
1428
1629
  /** {@inheritDoc NumericMode} */
1429
1630
  numericMode: NumericMode;
1430
1631
  tolerance: number;
@@ -1445,13 +1646,17 @@ export interface IComputeEngine {
1445
1646
  * If a definition existed previously, it is replaced.
1446
1647
  */
1447
1648
  defineSymbol(def: SymbolDefinition): BoxedSymbolDefinition;
1448
- getSymbolDefinition(name: string, wikidata?: string): undefined | BoxedSymbolDefinition;
1449
1649
  /**
1450
- * Return `undefined` if no definition exist for this `head.
1650
+ * Associate a new definition to a function in the current context.
1651
+ *
1652
+ * If a definition existed previously, it is replaced.
1451
1653
  */
1452
- getFunctionDefinition(head: string, args?: BoxedExpression[]): undefined | BoxedFunctionDefinition;
1654
+ defineFunction(def: FunctionDefinition): BoxedFunctionDefinition;
1655
+ lookupSymbol(name: string, wikidata?: string, scope?: RuntimeScope): undefined | BoxedSymbolDefinition;
1656
+ /** Return `undefined` if no definition exist for this `head` */
1657
+ lookupFunction(head: string, scope?: RuntimeScope): undefined | BoxedFunctionDefinition;
1453
1658
  /**
1454
- * Returned a boxed expression from the input.
1659
+ * Return a boxed expression from the input.
1455
1660
  *
1456
1661
  * The result may not be canonical.
1457
1662
  */
@@ -1462,14 +1667,22 @@ export interface IComputeEngine {
1462
1667
  symbol(sym: string, metadata?: Metadata): BoxedExpression;
1463
1668
  /** Return a canonical boxed string */
1464
1669
  string(s: string, metadata?: Metadata): BoxedExpression;
1465
- /** Return a canonical boxed domain */
1466
- domain(domain: SemiBoxedExpression | Domain | string, metadata?: Metadata): Domain;
1467
- /** Return a canonical expression.
1670
+ /** Return a canonical boxed domain.
1671
+ *
1672
+ * If the domain is invalid, may return an `["Error"]` expression
1673
+ *
1674
+ */
1675
+ domain(domain: SemiBoxedExpression | BoxedDomain | string, metadata?: Metadata): BoxedDomain;
1676
+ /** Return a canonical lambda expression */
1677
+ lambda(expr: SemiBoxedExpression, sig: BoxedDomain): BoxedLambdaExpression;
1678
+ /**
1679
+ * Return a canonical expression.
1468
1680
  *
1469
1681
  * Note that the result may not be a function, or may have a different
1470
1682
  * `head` than the one specified.
1471
1683
  *
1472
- * For example `ce.fn("Add", [ce.number(2), ce.number(3)]))` \( \to \) 5
1684
+ * For example:
1685
+ * `ce.fn("Rational", [ce.number(1), ce.number(2)]))` \( \to \) `ce.number([1,2])`
1473
1686
  *
1474
1687
  */
1475
1688
  fn(head: string | SemiBoxedExpression, ops: SemiBoxedExpression[], metadata?: Metadata): BoxedExpression;
@@ -1480,15 +1693,15 @@ export interface IComputeEngine {
1480
1693
  * In general, consider using `fn()` or `box()` instead.
1481
1694
  *
1482
1695
  * The result is canonical, but the caller has to ensure that all the
1483
- * conditions are met (i.e. ops properly normalized and sorted, all
1484
- * ops canonical, etc..) so that the result is actually canonical.
1696
+ * conditions are met (i.e. `ops` properly normalized and sorted, all
1697
+ * `ops` canonical, etc..) so that the result is actually canonical.
1485
1698
  */
1486
1699
  _fn(head: string | BoxedExpression, ops: BoxedExpression[], metadata?: Metadata): BoxedExpression;
1487
1700
  /** Shortcut for `this.fn("Error"...)`.
1488
1701
  *
1489
1702
  * The result is canonical.
1490
1703
  */
1491
- error(val: BoxedExpression, message: string, messageArg: SemiBoxedExpression): any;
1704
+ error(message: string | [string, ...SemiBoxedExpression[]], where?: SemiBoxedExpression): BoxedExpression;
1492
1705
  /** Shortcut for `this.fn("Add"...)`.
1493
1706
  *
1494
1707
  * The result is canonical.
@@ -1545,7 +1758,7 @@ export interface IComputeEngine {
1545
1758
  */
1546
1759
  serialize(expr: SemiBoxedExpression): LatexString;
1547
1760
  /**
1548
- * Options to control the serailization of MathJSON expression to LaTeX
1761
+ * Options to control the serialization of MathJSON expression to LaTeX
1549
1762
  * when using `this.latex` or `this.engine.serialize()`.
1550
1763
  *
1551
1764
  *
@@ -1574,7 +1787,7 @@ export interface IComputeEngine {
1574
1787
  *
1575
1788
  *
1576
1789
  */
1577
- assume(symbol: LatexString | SemiBoxedExpression, domain: Domain): AssumeResult;
1790
+ assume(symbol: LatexString | SemiBoxedExpression, domain: BoxedDomain): AssumeResult;
1578
1791
  assume(predicate: LatexString | SemiBoxedExpression): AssumeResult;
1579
1792
  assume(arg1: LatexString | SemiBoxedExpression, arg2?: BoxedExpression): AssumeResult;
1580
1793
  /** Remove all assumptions about one or more symbols */
@@ -1582,7 +1795,7 @@ export interface IComputeEngine {
1582
1795
  get assumptions(): ExpressionMapInterface<boolean>;
1583
1796
  ask(pattern: LatexString | SemiBoxedExpression): Substitution[];
1584
1797
  pushScope(options?: {
1585
- dictionary?: Readonly<Dictionary> | Readonly<Dictionary>[];
1798
+ symbolTable?: Readonly<SymbolTable> | Readonly<SymbolTable>[];
1586
1799
  assumptions?: (LatexString | Expression | BoxedExpression)[];
1587
1800
  scope?: Partial<Scope>;
1588
1801
  }): void;
@@ -1605,7 +1818,7 @@ export interface IComputeEngine {
1605
1818
  cache<T>(name: string, build: () => T, purge?: (T: any) => T | undefined): T;
1606
1819
  readonly stats: ComputeEngineStats;
1607
1820
  /** @internal */
1608
- purge(): void;
1821
+ reset(): void;
1609
1822
  /** @internal */
1610
1823
  _register(expr: BoxedExpression): void;
1611
1824
  /** @internal */