@cortex-js/compute-engine 0.4.2 → 0.4.3

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 (132) hide show
  1. package/README.md +2 -2
  2. package/dist/compute-engine.esm.js +22446 -16214
  3. package/dist/compute-engine.js +22449 -16222
  4. package/dist/compute-engine.min.esm.js +2 -7
  5. package/dist/compute-engine.min.js +2 -7
  6. package/dist/math-json.esm.js +4336 -10528
  7. package/dist/math-json.js +4353 -10531
  8. package/dist/math-json.min.esm.js +2 -7
  9. package/dist/math-json.min.js +2 -7
  10. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  11. package/dist/types/common/signals.d.ts +90 -0
  12. package/dist/types/compute-engine/assume.d.ts +21 -6
  13. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +107 -0
  14. package/dist/types/compute-engine/boxed-expression/box.d.ts +56 -0
  15. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +39 -0
  16. package/dist/types/compute-engine/boxed-expression/boxed-domain.d.ts +8 -0
  17. package/dist/types/compute-engine/boxed-expression/boxed-function-definition.d.ts +2 -0
  18. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +93 -0
  19. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +83 -0
  20. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +21 -0
  21. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +23 -0
  22. package/dist/types/compute-engine/boxed-expression/boxed-symbol-definition.d.ts +98 -0
  23. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +74 -0
  24. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +12 -0
  25. package/dist/types/compute-engine/boxed-expression/order.d.ts +52 -0
  26. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +15 -0
  27. package/dist/types/compute-engine/boxed-expression/utils.d.ts +37 -0
  28. package/dist/types/compute-engine/compute-engine.d.ts +233 -97
  29. package/dist/types/compute-engine/cost-function.d.ts +3 -0
  30. package/dist/types/compute-engine/dictionary/arithmetic-add.d.ts +11 -0
  31. package/dist/types/compute-engine/dictionary/arithmetic-divide.d.ts +9 -0
  32. package/dist/types/compute-engine/dictionary/arithmetic-multiply.d.ts +17 -0
  33. package/dist/types/compute-engine/dictionary/arithmetic-power.d.ts +9 -0
  34. package/dist/types/compute-engine/dictionary/arithmetic.d.ts +2 -12
  35. package/dist/types/compute-engine/dictionary/collections.d.ts +1 -1
  36. package/dist/types/compute-engine/dictionary/core.d.ts +2 -2
  37. package/dist/types/compute-engine/dictionary/dictionary.d.ts +18 -11
  38. package/dist/types/compute-engine/dictionary/logic.d.ts +1 -1
  39. package/dist/types/compute-engine/dictionary/polynomials.d.ts +2 -0
  40. package/dist/types/compute-engine/dictionary/relational-operator.d.ts +2 -0
  41. package/dist/types/compute-engine/dictionary/sets.d.ts +1 -1
  42. package/dist/types/compute-engine/dictionary/trigonometry.d.ts +2 -2
  43. package/dist/types/compute-engine/domain-utils.d.ts +30 -0
  44. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +2 -0
  45. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +2 -0
  46. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +2 -0
  47. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +4 -0
  48. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-inequalities.d.ts +2 -0
  49. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +2 -0
  50. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +2 -0
  51. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +2 -0
  52. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +2 -0
  53. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +2 -0
  54. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +57 -0
  55. package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +23 -0
  56. package/dist/types/compute-engine/latex-syntax/parse.d.ts +198 -0
  57. package/dist/types/compute-engine/latex-syntax/public.d.ts +550 -0
  58. package/dist/types/{common → compute-engine/latex-syntax}/serialize-number.d.ts +2 -3
  59. package/dist/types/{latex-syntax → compute-engine/latex-syntax}/serializer-style.d.ts +2 -1
  60. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +43 -0
  61. package/dist/types/{latex-syntax/core → compute-engine/latex-syntax}/tokenizer.d.ts +2 -2
  62. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +3 -0
  63. package/dist/types/compute-engine/numerics/numeric-decimal.d.ts +12 -0
  64. package/dist/types/compute-engine/numerics/numeric.d.ts +35 -0
  65. package/dist/types/compute-engine/numerics/primes.d.ts +2 -0
  66. package/dist/types/compute-engine/public.d.ts +1076 -434
  67. package/dist/types/compute-engine/rules.d.ts +16 -6
  68. package/dist/types/compute-engine/simplify-rules.d.ts +17 -0
  69. package/dist/types/compute-engine/symbolic/expand.d.ts +11 -0
  70. package/dist/types/compute-engine/symbolic/flatten.d.ts +7 -0
  71. package/dist/types/compute-engine/symbolic/negate.d.ts +12 -0
  72. package/dist/types/compute-engine/symbolic/polynomials.d.ts +52 -0
  73. package/dist/types/compute-engine/symbolic/product.d.ts +45 -0
  74. package/dist/types/compute-engine/symbolic/sum.d.ts +25 -0
  75. package/dist/types/compute-engine/symbolic/utils.d.ts +47 -0
  76. package/dist/types/compute-engine.d.ts +3 -5
  77. package/dist/types/math-json/math-json-format.d.ts +101 -0
  78. package/dist/types/math-json/utils.d.ts +97 -0
  79. package/dist/types/math-json.d.ts +5 -3
  80. package/package.json +27 -26
  81. package/dist/cortex.esm.js +0 -20989
  82. package/dist/cortex.js +0 -21011
  83. package/dist/cortex.min.esm.js +0 -7
  84. package/dist/cortex.min.js +0 -7
  85. package/dist/types/common/debug.d.ts +0 -28
  86. package/dist/types/common/utils.d.ts +0 -153
  87. package/dist/types/compute-engine/canonical-forms.d.ts +0 -74
  88. package/dist/types/compute-engine/dictionary/domains.d.ts +0 -26
  89. package/dist/types/compute-engine/dictionary/utils.d.ts +0 -5
  90. package/dist/types/compute-engine/domains.d.ts +0 -4
  91. package/dist/types/compute-engine/evaluate.d.ts +0 -13
  92. package/dist/types/compute-engine/expression-map.d.ts +0 -11
  93. package/dist/types/compute-engine/internal-compute-engine.d.ts +0 -108
  94. package/dist/types/compute-engine/numeric-complex.d.ts +0 -2
  95. package/dist/types/compute-engine/numeric-decimal.d.ts +0 -12
  96. package/dist/types/compute-engine/numeric.d.ts +0 -21
  97. package/dist/types/compute-engine/numerical-eval.d.ts +0 -5
  98. package/dist/types/compute-engine/order.d.ts +0 -18
  99. package/dist/types/compute-engine/patterns.d.ts +0 -22
  100. package/dist/types/compute-engine/predicates.d.ts +0 -42
  101. package/dist/types/compute-engine/simplify.d.ts +0 -6
  102. package/dist/types/compute-engine/utils.d.ts +0 -15
  103. package/dist/types/cortex/formatter.d.ts +0 -165
  104. package/dist/types/cortex/parse-cortex.d.ts +0 -5
  105. package/dist/types/cortex/reserved-words.d.ts +0 -1
  106. package/dist/types/cortex/serialize-cortex.d.ts +0 -14
  107. package/dist/types/cortex.d.ts +0 -8
  108. package/dist/types/latex-syntax/definitions-algebra.d.ts +0 -2
  109. package/dist/types/latex-syntax/definitions-arithmetic.d.ts +0 -3
  110. package/dist/types/latex-syntax/definitions-calculus.d.ts +0 -2
  111. package/dist/types/latex-syntax/definitions-core.d.ts +0 -3
  112. package/dist/types/latex-syntax/definitions-inequalities.d.ts +0 -2
  113. package/dist/types/latex-syntax/definitions-other.d.ts +0 -3
  114. package/dist/types/latex-syntax/definitions-sets.d.ts +0 -2
  115. package/dist/types/latex-syntax/definitions-symbols.d.ts +0 -3
  116. package/dist/types/latex-syntax/definitions-trigonometry.d.ts +0 -3
  117. package/dist/types/latex-syntax/definitions.d.ts +0 -40
  118. package/dist/types/latex-syntax/latex-syntax.d.ts +0 -27
  119. package/dist/types/latex-syntax/parse.d.ts +0 -138
  120. package/dist/types/latex-syntax/public.d.ts +0 -456
  121. package/dist/types/latex-syntax/serializer.d.ts +0 -26
  122. package/dist/types/latex-syntax/utils.d.ts +0 -10
  123. package/dist/types/point-free-parser/characters.d.ts +0 -25
  124. package/dist/types/point-free-parser/combinators.d.ts +0 -46
  125. package/dist/types/point-free-parser/core-combinators.d.ts +0 -78
  126. package/dist/types/point-free-parser/grammar.d.ts +0 -12
  127. package/dist/types/point-free-parser/identifier-parsers.d.ts +0 -7
  128. package/dist/types/point-free-parser/numeric-parsers.d.ts +0 -8
  129. package/dist/types/point-free-parser/parsers.d.ts +0 -130
  130. package/dist/types/point-free-parser/string-parsers.d.ts +0 -29
  131. package/dist/types/point-free-parser/whitespace-parsers.d.ts +0 -17
  132. package/dist/types/public.d.ts +0 -163
@@ -1,49 +1,648 @@
1
- /* 0.4.2 */
2
- import type { ExpressionMap } from './expression-map';
3
- import type { Substitution } from './patterns';
4
- import type { Decimal } from 'decimal.js';
1
+ /* 0.4.3 */
5
2
  import type { Complex } from 'complex.js';
6
- export declare type Numeric = number | Decimal | Complex;
7
- export declare type Pattern<T extends number = Numeric> = Expression<T>;
8
- export declare type Rule<T extends number = Numeric> = [
9
- lhs: string | Pattern<T>,
10
- rhs: string | Pattern<T>,
11
- condition?: string | ((ce: ComputeEngine<T>, args: Substitution<T>) => boolean)
3
+ import { SignalMessage, WarningSignal, WarningSignalHandler } from '../common/signals';
4
+ import { Expression, MathJsonDictionary, MathJsonFunction, MathJsonNumber, MathJsonString, MathJsonSymbol } from '../math-json/math-json-format';
5
+ import { NumberFormattingOptions, ParseLatexOptions, SerializeLatexOptions } from '../math-json';
6
+ export declare const DEFAULT_COMPLEXITY = 100000;
7
+ export declare const DEBUG = true;
8
+ /**
9
+ * Metadata that can be associated with a BoxedExpression
10
+ */
11
+ export declare type Metadata = {
12
+ latex?: string;
13
+ wikidata?: string;
14
+ };
15
+ /**
16
+ * The numeric evaluation mode:
17
+ *
18
+ * - `machine`: 64-bit float, **IEEE 754-2008**, 52-bit, about 15 digits of precision
19
+ * - `decimal`: arbitrary precision floating point numbers
20
+ * - `complex`: complex number represented by two machine numbers, a real and
21
+ * an imaginary part
22
+ * - `auto`: use machine number if precision is 15 or less, allow complex numbers.
23
+ */
24
+ export declare type NumericMode = 'auto' | 'machine' | 'decimal' | 'complex';
25
+ /** Options for `expr.simplify()` */
26
+ export declare type SimplifyOptions = EvaluateOptions & {
27
+ recursive?: boolean;
28
+ rules?: BoxedRuleSet;
29
+ };
30
+ /** Options for `expr.evaluate()` */
31
+ export declare type EvaluateOptions = {};
32
+ /** Options for `expr.N()` */
33
+ export declare type NOptions = {};
34
+ export declare type ReplaceOptions = {
35
+ /** If true, apply replacement rules to all sub-expressions.
36
+ * If false, only consider the top-level expression.
37
+ *
38
+ * **Default**: true*/
39
+ recursive?: boolean;
40
+ /** If true, stop after the first rule that matches.
41
+ * If false, apply all the remaining rules even after the first match.
42
+ *
43
+ * **Default**: true*/
44
+ once?: boolean;
45
+ /**
46
+ * If `iterationLimit` > 1, the rules will be repeatedly applied
47
+ * until no rules apply, up to `maxIterations` times.
48
+ *
49
+ * Note that if `once` is true, `maxIterations` has no effect.
50
+ *
51
+ * **Default**: 1
52
+ */
53
+ iterationLimit?: number;
54
+ };
55
+ /**
56
+ * A substitution describes the values of the wildcards in a pattern so that
57
+ * the pattern is equal to a target expression.
58
+ *
59
+ * A substitution can also be considered a more constrained version of a
60
+ * rule whose `lhs` is always a symbol.
61
+ */
62
+ export declare type Substitution = {
63
+ [symbol: string]: BoxedExpression;
64
+ };
65
+ /** A LaTeX string starts and end with `$`, for example
66
+ * `"$\frac{\pi}{2}$"`.
67
+ */
68
+ export declare type LatexString = string;
69
+ /**
70
+ * A rule describes how to modify an expressions that matches a `lhs` pattern
71
+ * into a new expressions matching `rhs`.
72
+ *
73
+ * `x-1` -> `1-x`
74
+ * `(x+1)(x-1)` -> `x^2-1
75
+ *
76
+ * The `lhs` can be expressed as a LaTeX string or a MathJSON expression.
77
+ *
78
+ * Unbound variables (`x`, but not `Pi`) are matched structurally with a
79
+ * a target expression, then the expression is rewritten as the `rhs`, with
80
+ * the corresponding unbound variables in the `rhs` replaced by their values
81
+ * in the `lhs.
82
+ *
83
+ * Pattern symbols (e.g. `_1`, `_a`) can be used as well.
84
+ *
85
+ * In addition:
86
+ * - `__1` (`__a`, etc..) match a sequence of one or more expressions
87
+ * - `___1` (`___a`, etc...) match a sequence of zero or more expressions
88
+ */
89
+ export declare type Rule = [
90
+ lhs: LatexString | SemiBoxedExpression | Pattern,
91
+ rhs: LatexString | SemiBoxedExpression,
92
+ options?: {
93
+ condition?: LatexString | ((wildcards: Substitution) => boolean);
94
+ priority?: number;
95
+ }
96
+ ];
97
+ export declare type BoxedRule = [
98
+ lhs: Pattern,
99
+ rhs: BoxedExpression,
100
+ priority: number,
101
+ condition: undefined | ((wildcards: Substitution) => boolean)
12
102
  ];
13
- export declare type RuleSet<T extends number = Numeric> = Iterable<Rule<T>>;
103
+ export declare type BoxedRuleSet = Set<BoxedRule>;
104
+ /**
105
+ * Domains can be defined as a union or intersection of domains:
106
+ * - `["Union", "Number", "Boolean"]` A number or a boolean.
107
+ * - `["SetMinus", "Number", 1]` Any number except "1".
108
+ *
109
+ */
110
+ export declare type DomainExpression = BoxedExpression;
111
+ export declare type JsonSerializationOptions = {
112
+ /** A list of space separated function names that should be excluded from
113
+ * the JSON output.
114
+ *
115
+ * Those functions are replaced with an equivalent, for example, `Square` with
116
+ * `Power`, etc...
117
+ *
118
+ * Possible values include `Sqrt`, `Root`, `Square`, `Exp`, `Subtract`,
119
+ * `Rational`, `Complex`
120
+ *
121
+ * **Default**: `[]` (none)
122
+ */
123
+ exclude: string[];
124
+ /** A list of space separated keywords indicating which MathJSON expressions
125
+ * can use a shorthand.
126
+ *
127
+ * **Default**: `['all']`
128
+ */
129
+ shorthands: ('all' | 'number' | 'symbol' | 'function' | 'dictionary' | 'string')[];
130
+ /** A list of space separated keywords indicating which metadata should be
131
+ * included in the MathJSON. If metadata is included, shorthand notation
132
+ * is not used.
133
+ *
134
+ * **Default**: `[]`
135
+ */
136
+ metadata: ('all' | 'wikidata' | 'latex')[];
137
+ /** If true, repeating decimals are detected and serialized accordingly
138
+ * For example:
139
+ * - `1.3333333333333333` -> `1.(3)`
140
+ * - `0.142857142857142857142857142857142857142857142857142` -> `0.(1428571)`
141
+ *
142
+ * **Default**: `true`
143
+ */
144
+ repeatingDecimal: boolean;
145
+ };
14
146
  /**
15
- * A dictionary maps a MathJSON name to a definition.
147
+ * **Theory of Operations**
16
148
  *
17
- * A named entry in a dictionary can refer to a symbol, as in the expression,
18
- * `"Pi"`, to a function: "Add" in the expression `["Add", 2, 3]`, or
19
- * to a `"Set`".
149
+ * The `BoxedExpression` interface includes most of the methods applicable
150
+ * to any kind of expression, for example `get string()` or
151
+ * `get machineValue()`.
20
152
  *
21
- * The name can be an arbitrary string of Unicode characters, however
22
- * the following conventions are recommended:
153
+ * When they are not applicable, for example `get string()` on a
154
+ * `BoxedNumber`, they return `null`.
23
155
  *
24
- * - Use only letters, digits and `-`, and the first character should be
25
- * a letter: `/^[a-zA-Z][a-zA-Z0-9-]+/`
26
- * - Built-in functions and symbols should start with an uppercase letter
156
+ * This convention makes it convenient to manipulate expressions without
157
+ * having to check what kind of instance they are before manipulating them.
158
+ *
159
+ */
160
+ export interface BoxedExpression {
161
+ /** The Compute Engine associated with this expression provides
162
+ * a context in which to interpret it, such as definition of symbols
163
+ * and functions.
164
+ */
165
+ readonly engine: IComputeEngine;
166
+ /** From Object.valueOf() */
167
+ valueOf(): number | string | [number, number];
168
+ /** From Object.toString() */
169
+ toString(): string;
170
+ /** From Object.toJSON(), equivalent to `JSON.stringify(this.json)` */
171
+ toJSON(): string;
172
+ /** From Object.is(). Equivalent to `isSame()` */
173
+ is(rhs: any): boolean;
174
+ get hash(): number;
175
+ /** A short description of the symbol or function head. May include markdown.
176
+ * Each string is a paragraph. */
177
+ readonly description: string[];
178
+ /** A URL pointing to more information about the symbol or function head */
179
+ readonly url: string;
180
+ /** All boxed expressions have a head.
181
+ *
182
+ * If not a function this can be `Symbol`, `String`, `Number` or `Dictionary`.
183
+ *
184
+ * If the head expression can be represented as a string, it is returned
185
+ * as a string.
186
+ */
187
+ get head(): BoxedExpression | string;
188
+ /**
189
+ * If `expr.isPure` is `true`, this is a synonym for `expr.evaluate()`.
190
+ * Otherwise, it returns `undefined`.
191
+ */
192
+ get value(): BoxedExpression | undefined;
193
+ /** Only the value of variables can be changed (symbols that are not constants) */
194
+ set value(value: BoxedExpression | undefined);
195
+ /** Return an approximation of the value of this expression. Floating-point
196
+ * operations may be performed.
197
+ *
198
+ * Just like `expr.value`, it returns `undefined` for impure expressions.
199
+ */
200
+ get numericValue(): BoxedExpression | undefined;
201
+ /** If true, the value of the expression never changes and evaluating it has
202
+ * no side-effects.
203
+ * If false, the value of the expression may change, if the
204
+ * value of other expression changes or for other reasons.
205
+ *
206
+ * If `expr.isPure` is `false`, `expr.value` is undefined. Call
207
+ * `expr.evaluate()` to determine the value of the expression instead.
208
+ *
209
+ * As an example, the `Random` function is not pure.
210
+ */
211
+ get isPure(): boolean;
212
+ /**
213
+ * If `true`, this expression represents a value that was not calculated
214
+ * or that does not reference another expression.
215
+ * This means the expression is either a number, a string or a dictionary.
216
+ * Functions and symbols are not literals.
217
+ */
218
+ get isLiteral(): boolean;
219
+ /** If `true`, this expression is in a canonical form */
220
+ get isCanonical(): boolean;
221
+ /** For internal use only, set when a canonical expression is created. */
222
+ set isCanonical(val: boolean);
223
+ /** `ops` is the list of arguments of the function, its "tail" */
224
+ get ops(): null | BoxedExpression[];
225
+ /** If a function, the number of operands, otherwise 0.
226
+ *
227
+ * Note that a function can have 0 operands, so to check if this expression
228
+ * is a function, check if `expr.tail !== null` instead. */
229
+ get nops(): number;
230
+ /** First operand, i.e. first element of `this.tail` */
231
+ get op1(): BoxedExpression;
232
+ /** Second operand, i.e. second element of `this.tail` */
233
+ get op2(): BoxedExpression;
234
+ /** Third operand, i.e. third element of `this.tail` */
235
+ get op3(): BoxedExpression;
236
+ /** The keys of the dictionary. If this expression not a dictionary, return `null` */
237
+ get keys(): IterableIterator<string> | null;
238
+ get keysCount(): number;
239
+ getKey(key: string): BoxedExpression | undefined;
240
+ hasKey(key: string): boolean;
241
+ /**
242
+ * Return the value of this number or symbol, if stored as a machine number.
243
+ *
244
+ * Note it is possible for `machineValue` to be `null`, and for `isNotZero` to be true.
245
+ * For example, when a symbol has been defined with an assumption.
246
+ *
247
+ * If `machineValue` is not `null`, then `decimalValue`, `rationalValue`
248
+ * and `complexValue` are `null.
249
+ *
250
+ */
251
+ get machineValue(): number | null;
252
+ /** If the value of this expression is a rational number, return it.
253
+ * Otherwise, return `[null, null]`.
254
+ *
255
+ * If `rationalValue` is not `[null, null]`, then `machineValue`, `decimalValue`
256
+ * and `complexValue` are `null.
257
+ */
258
+ get rationalValue(): [numer: number, denom: number] | [null, null];
259
+ /** If the value of this expression is a `Decimal` number, return it.
260
+ * Otherwise, return `null`.
261
+ *
262
+ * A `Decimal` number is an arbitrarily long floating point number.
263
+ *
264
+ * If `decimalValue` is not `null`, then `machineValue`
265
+ * and `complexValue` are `null` and `rationalValue` is `[null, null]`.
266
+ */
267
+ get decimalValue(): Decimal | null;
268
+ /** If the value of this expression is a `Complex` number, return it.
269
+ * Otherwise, return `null`.
270
+ *
271
+ * If `complexValue` is not `null`, then `machineValue`, `rationalValue`
272
+ * and `decimalValue` are `null.
273
+ *
274
+ */
275
+ get complexValue(): Complex | null;
276
+ /** Return an approximation of the numeric value of this expression as
277
+ * a 64-bit floating point number.
278
+ *
279
+ * If the value is a machine number, return it exactly.
280
+ *
281
+ * If the value is a rational number, return the numerator divided by the
282
+ * denominator.
283
+ *
284
+ * If the value is a Decimal number that can be represented by a machine
285
+ * number, return this value. There might be a small loss of precision due
286
+ * to the limitations of the binary representation of numbers as machine
287
+ * numbers.
288
+ *
289
+ * If the value of this expression cannot be represented by a float,
290
+ * return `null`.
291
+ *
292
+ */
293
+ get asFloat(): number | null;
294
+ /**
295
+ * If the value of this expression is an integer with a 'small' absolute value,
296
+ * return this value. Otherwise, return `null`.
297
+ *
298
+ * Some calculations, for example to put in canonical forms, are only
299
+ * performed if they are safe from overflow. This method makes it easy
300
+ * to check for this, whether the value is a Decimal or a number.
301
+ *
302
+ * By default, "small" is less than 10,000.
303
+ */
304
+ get asSmallInteger(): number | null;
305
+ /**
306
+ * If the value of this an expression is a small integer or a rational,
307
+ * return this value. Otherwise, return `[null, null`].
308
+ */
309
+ get asRational(): [number, number] | [null, null];
310
+ /**
311
+ * Return the following, depending on the value of this expression:
312
+ *
313
+ * * `-1`: if it is < 0
314
+ * * `0`: if it is = 0
315
+ * * `+1`: if it is > 0
316
+ * * `undefined`: this value may be positive, negative or zero. We don't know
317
+ * right now (a symbol with an Integer domain, but no currently assigned
318
+ * value, for example)
319
+ * * `null`: this value will never be positive, negative or zero (`NaN`,
320
+ * a string or a complex number for example)
321
+ *
322
+ * Note that complex numbers have no natural ordering,
323
+ * so if the value is a complex number, `sgn` is either 0, or `null`
324
+ *
325
+ * If a symbol, this does take assumptions into account, that is `expr.sgn` will return
326
+ * `1` if `isPositive` is `true`, even if this expression has no value
327
+ */
328
+ get sgn(): -1 | 0 | 1 | undefined | null;
329
+ /** If this expression is a symbol, return the name of the symbol as a string.
330
+ * Otherwise, return `null`. */
331
+ get symbol(): string | null;
332
+ /** Shortcut for `this.symbol === 'Missing'` */
333
+ get isMissing(): boolean;
334
+ /** If this expression is a string, return the value of the string.
335
+ * Otherwise, return `null`.
336
+ */
337
+ get string(): string | null;
338
+ /** True if this domain is a subset of domain d */
339
+ isSubsetOf(d: BoxedExpression | string): undefined | boolean;
340
+ /** True if the value of this expression is a number.
341
+ *
342
+ * `isExtendedComplex || isNaN` = `isReal || isImaginary || isInfinity || isNaN`
343
+ *
344
+ * Note that in a fateful twist of cosmic irony, `NaN` ("Not a Number")
345
+ * is a number.
346
+ */
347
+ get isNumber(): boolean | undefined;
348
+ /** The value of this expression is an element of the set ℤ: ...,-2, -1, 0, 1, 2... */
349
+ get isInteger(): boolean | undefined;
350
+ /** The value of this expression is an element of the set ℚ, p/q with p ∈ ℕ, q ∈ ℤ ⃰ q >= 1
351
+ *
352
+ * Note that every integer is also a rational.
353
+ *
354
+ */
355
+ get isRational(): boolean | undefined;
356
+ /**
357
+ * The value of this expression is a number that is the root of a non-zero
358
+ * univariate polynomial with rational coefficients.
359
+ *
360
+ * All integers and rational numbers are algebraic.
361
+ *
362
+ * Transcendental numbers, such as \\( \pi \\) or \\( e \\) are not algebraic.
363
+ *
364
+ */
365
+ get isAlgebraic(): boolean | undefined;
366
+ /**
367
+ * The value of this expression is real number: finite and not imaginary.
368
+ *
369
+ * `isFinite && !isImaginary`
370
+ */
371
+ get isReal(): boolean | undefined;
372
+ /** Real or ±Infinity
373
+ *
374
+ * `isReal || isInfinity`
375
+ */
376
+ get isExtendedReal(): boolean | undefined;
377
+ /**
378
+ * The value of this expression is a number, but not `NaN` or any Infinity
379
+ *
380
+ * `isReal || isImaginary`
381
+ *
382
+ */
383
+ get isComplex(): boolean | undefined;
384
+ /** `isReal || isImaginary || isInfinity` */
385
+ get isExtendedComplex(): boolean | undefined;
386
+ /** The value of this expression is a number with a imaginary part */
387
+ get isImaginary(): boolean | undefined;
388
+ get isZero(): boolean | undefined;
389
+ get isNotZero(): boolean | undefined;
390
+ get isOne(): boolean | undefined;
391
+ get isNegativeOne(): boolean | undefined;
392
+ /** ±Infinity or Complex Infinity */
393
+ get isInfinity(): boolean | undefined;
394
+ /**
395
+ * "Not a Number".
396
+ *
397
+ * A value representing undefined result of computations, such as `0/0`,
398
+ * as per the the floating point format standard IEEE-754.
399
+ *
400
+ * Note that if `isNaN` is true, `isNumber` is also true.
401
+ *
402
+ */
403
+ get isNaN(): boolean | undefined;
404
+ /** Not ±Infinity and not NaN */
405
+ get isFinite(): boolean | undefined;
406
+ get isEven(): boolean | undefined;
407
+ get isOdd(): boolean | undefined;
408
+ get isPrime(): boolean | undefined;
409
+ get isComposite(): boolean | undefined;
410
+ /** Structural/symbolic equality (weak equality).
411
+ *
412
+ * `ce.parse('1+x').isSame(ce.parse('x+1'))` is `true`
413
+ *
414
+ */
415
+ isSame(rhs: BoxedExpression): boolean;
416
+ /**
417
+ * True if the expression includes a symbol `v`, or a function head `v`.
418
+ */
419
+ has(v: string | string[]): boolean;
420
+ /** Attempt to match this pattern to the `rhs`.
421
+ *
422
+ * If `rhs` does not match, return `null`.
423
+ * Otherwise return an object literal, with a prop for
424
+ * each matching named wildcard. If `rhs` matches
425
+ * this pattern but there are no named wildcards, return
426
+ * the empty object literal, `{}`.
427
+ */
428
+ match(rhs: BoxedExpression, options?: PatternMatchOption): Substitution | null;
429
+ /** Mathematical equality (strong equality), that is the value
430
+ * of this expression and of `rhs` are numerically equal.
431
+ *
432
+ * Both expressions are numerically evaluated.
433
+ *
434
+ * Numbers whose difference is less than `engine.tolerance` are
435
+ * considered equal. This value is set when the `engine.precision` is
436
+ * changed to be such that the last two digits are ignored.
437
+ */
438
+ isEqual(rhs: BoxedExpression): boolean;
439
+ /** If the expressions cannot be compared, `undefined` is returned */
440
+ isLess(rhs: BoxedExpression): boolean | undefined;
441
+ isLessEqual(rhs: BoxedExpression): boolean | undefined;
442
+ isGreater(rhs: BoxedExpression): boolean | undefined;
443
+ isGreaterEqual(rhs: BoxedExpression): boolean | undefined;
444
+ /** The value of this expression is > 0, same as `isGreater(0)` */
445
+ get isPositive(): boolean | undefined;
446
+ /** The value of this expression is >= 0, same as `isGreaterEqual(0)` */
447
+ get isNonNegative(): boolean | undefined;
448
+ /** The value of this expression is < 0, same as `isLess(0)` */
449
+ get isNegative(): boolean | undefined;
450
+ /** The value of this expression is <= 0, same as `isLessEqual(0)` */
451
+ get isNonPositive(): boolean | undefined;
452
+ /** Wikidata identifier */
453
+ get wikidata(): string;
454
+ set wikidata(val: string);
455
+ /** MathJSON representation of this expression */
456
+ get json(): Expression;
457
+ /** LaTeX representation of this expression */
458
+ get latex(): LatexString;
459
+ set latex(val: string);
460
+ /** Expressions with a higher complexity score are sorted
461
+ * first in commutative functions
462
+ */
463
+ get complexity(): number;
464
+ /** The domain of this expression, using the value of the expression,
465
+ * definitions associated with this expression and assumptions if necessary */
466
+ get domain(): BoxedExpression;
467
+ /** Symbols that represent a variable, can have their domain modified */
468
+ set domain(domain: BoxedExpression | string);
469
+ /** For symbols and functions, a possible definition associated with the expression */
470
+ get functionDefinition(): BoxedFunctionDefinition | undefined;
471
+ get symbolDefinition(): BoxedSymbolDefinition | undefined;
472
+ /**
473
+ * Return the canonical form of this expression.
474
+ *
475
+ * If a function, consider the function definition flags:
476
+ * - `associative`: \\( f(a, f(b), c) \longrightarrow f(a, b, c) \\)
477
+ * - `idempotent`: \\( f(f(a)) \longrightarrow f(a) \\)
478
+ * - `involution`: \\( f(f(a)) \longrightarrow a \\)
479
+ * - `commutative`: sort the arguments.
480
+ *
481
+ * Additionally, some simplifications involving exact computations on
482
+ * small integers may be performed.
483
+ *
484
+ * For example:
485
+ * - \\( 2 + x + 1 \longrightarrow x + 3 \\)
486
+ * - \\( \sqrt{4} \longrightarrow 2 \\)
487
+ * - \\(\frac{4}{10} \longrightarrow \frac{2}{5} \\).
488
+ *
489
+ * However, no calculation is performed involving floating point numbers, so
490
+ * \\( \sqrt(2) \longrightarrow \sqrt(2) \\).
491
+ *
492
+ * Determining the canonical form does not depend on the values assigned to,
493
+ * or assumptions about, symbols.
494
+ */
495
+ get canonical(): BoxedExpression;
496
+ /**
497
+ * Return a simpler form of this expression.
498
+ *
499
+ * The expression is first converted to canonical form. Then a series of
500
+ * rewriting rules are applied repeatedly, until no rules apply.
501
+ *
502
+ * If a custom `simplify` handler is associated with this function definition,
503
+ * it is invoked.
504
+ *
505
+ * The values assigned to symbols and the assumptions about symbols may be
506
+ * used, for example `arg.isInteger` or `arg.isPositive`.
507
+ *
508
+ * No calculations involving floating point numbers are performed but exact
509
+ * calculations may be performed, for example
510
+ * \\( \sin(\frac{\pi}{4}) \longrightarrow \frac{\sqrt{2}}{2} \\).
511
+ *
512
+ * The result is in canonical form.
513
+ *
514
+ */
515
+ simplify(options?: SimplifyOptions): BoxedExpression;
516
+ /**
517
+ * Return the value of this expression.
518
+ *
519
+ * The expression is first converted to canonical form.
520
+ *
521
+ * A pure expression always return the same value and has no side effects.
522
+ * If `expr.isPure` is `true`, `expr.value` and `expr.evaluate()` are synonyms.
523
+ * For an impure expression, `expr.value` is undefined.
524
+ *
525
+ * Evaluating an impure expression may have some side effects, for
526
+ * example modifying the `ComputeEngine` environment, such as its set of assumptions.
527
+ *
528
+ * Only exact calculations are performed, no floating point calculations.
529
+ * To perform approximate floating point calculations, use `N()` instead.
530
+ *
531
+ * The result of `expr.evaluate()` may be the same as `expr.simplify()`.
532
+ *
533
+ * The result is in canonical form.
534
+ *
535
+ */
536
+ evaluate(options?: EvaluateOptions): BoxedExpression;
537
+ /** Return a numerical approximation of this expression.
538
+ *
539
+ * The expression is first converted to canonical form.
540
+ *
541
+ * Any necessary calculations, including on floating point numbers,
542
+ * are performed. The calculations are performed according
543
+ * to the `numericMode` and `precision` properties of the `ComputeEngine`.
544
+ *
545
+ * If the function is not numeric, this is equivalent to `expr.evaluate()`.
546
+ *
547
+ * The result is in canonical form.
548
+ */
549
+ N(options?: NOptions): BoxedExpression;
550
+ solve(vars: Iterable<string>): null | BoxedExpression[];
551
+ /**
552
+ * If this expression is a function, apply the function `fn` to all its operands.
553
+ * Replace the head of this expression with `head`, if defined.
554
+ *
555
+ * If this expression is a dictionary, return a new dictionary with the values
556
+ * modified by `fn`.
557
+ *
558
+ * If `head` is provided, return a function
559
+ * with the modified dictionary as operand, otherwise return the
560
+ * modified dictionary. */
561
+ apply(fn: (x: BoxedExpression) => SemiBoxedExpression, head?: string): BoxedExpression;
562
+ /**
563
+ * Transform the expression by according to the rules:
564
+ * the matching `lhs` of a rule is replaced by its `rhs`.
565
+ *
566
+ * If no rules apply, return `null`.
567
+ */
568
+ replace(rules: BoxedRuleSet, options?: ReplaceOptions): null | BoxedExpression;
569
+ /**
570
+ * Replace all the symbols in the expression as indicated.
571
+ *
572
+ * Note the same effect can be achieved with `expr.replace()`, but
573
+ * this is more efficient, and simpler.
574
+ *
575
+ */
576
+ subs(sub: Substitution): BoxedExpression;
577
+ /**
578
+ * Update the definition associated with this expression, taking
579
+ * into account the current context.
580
+ *
581
+ * For internal use only.
582
+ */
583
+ _repairDefinition(): void;
584
+ /** Purge any cached values */
585
+ _purge(): undefined;
586
+ }
587
+ /** A semi boxed expression is an MathJSON expression which can include some
588
+ * boxed terms.
27
589
  *
28
- * As a shorthand for a numeric symbol definition, a number can be used as
29
- * well. In that case the domain is determined automatically.
590
+ * This is convenient when creating new expressions from portions
591
+ * of an existing `BoxedExpression` while avoiding unboxing and reboxing.
592
+ */
593
+ export declare type SemiBoxedExpression = BoxedExpression | number | Decimal | Complex | MathJsonNumber | MathJsonString | MathJsonSymbol | string | MathJsonFunction | MathJsonDictionary | SemiBoxedExpression[];
594
+ export declare type LambdaExpression = SemiBoxedExpression;
595
+ export declare type BoxedLambdaExpression = BoxedExpression;
596
+ export declare type PatternMatchOption = {
597
+ recursive?: boolean;
598
+ numericTolerance?: number;
599
+ exact?: boolean;
600
+ };
601
+ export interface Pattern extends BoxedExpression {
602
+ /**
603
+ * If `expr` does not match the pattern, return `null`.
604
+ * Otherwise, return a substitution describing the values that the named
605
+ * wildcard in the pattern should be changed to in order for the pattern to be
606
+ * equal to the expression. If there are no named wildcards and the expression
607
+ * matches the pattern, and empty object literal `{}` is returned.
608
+ */
609
+ match(expr: BoxedExpression, options?: PatternMatchOption): Substitution | null;
610
+ /** If `expr` matches the pattern, return `true`, otherwise `false` */
611
+ test(expr: BoxedExpression, options?: PatternMatchOption): boolean;
612
+ /** Return the number of exprs that matched the pattern */
613
+ count(exprs: Iterable<BoxedExpression>, options?: PatternMatchOption): number;
614
+ subs(sub: Substitution): Pattern;
615
+ }
616
+ export interface ExpressionMapInterface<U> {
617
+ has(expr: BoxedExpression): boolean;
618
+ get(expr: BoxedExpression): U | undefined;
619
+ set(expr: BoxedExpression, value: U): void;
620
+ delete(expr: BoxedExpression): void;
621
+ clear(): void;
622
+ [Symbol.iterator](): IterableIterator<[BoxedExpression, U]>;
623
+ }
624
+ /**
625
+ * A dictionary contains definitions for symbols, functions and rules.
30
626
  *
31
- * ```json
32
- * { "x": 1.0 }
33
- * { "x" : { "domain": "RealNumber", "value": 1.0 } }
34
- * ```
35
627
  */
36
- export declare type Dictionary<T extends number = number> = {
37
- [name: string]: T | Definition<T>;
628
+ export declare type Dictionary = {
629
+ symbols?: SymbolDefinition[];
630
+ functions?: FunctionDefinition[];
631
+ simplifyRules?: BoxedRuleSet;
38
632
  };
39
633
  /**
40
634
  * The entries of a `CompiledDictionary` have been validated and
41
635
  * optimized for faster evaluation.
42
636
  *
43
637
  * When a new scope is created with `pushScope()` or when creating a new
44
- * engine instance, new instances of `CompiledDictionary` are created as needed.
638
+ * engine instance, new instances of `RuntimeDictionary` are created as needed.
45
639
  */
46
- export declare type CompiledDictionary<T extends number = number> = Map<string, Definition<T>>;
640
+ export declare type RuntimeDictionary = {
641
+ symbols: Map<string, BoxedSymbolDefinition>;
642
+ symbolWikidata: Map<string, BoxedSymbolDefinition>;
643
+ functions: Map<string, BoxedFunctionDefinition[]>;
644
+ functionWikidata: Map<string, BoxedFunctionDefinition>;
645
+ };
47
646
  /**
48
647
  * A scope is a set of names in a dictionary that are bound (defined) in
49
648
  * a MathJSON expression.
@@ -78,10 +677,10 @@ export declare type Scope = {
78
677
  * scope is exceeded. Default: no limits.*/
79
678
  iterationLimit?: number;
80
679
  };
81
- export declare type RuntimeScope<T extends number = number> = Scope & {
82
- parentScope: RuntimeScope<T>;
83
- dictionary?: CompiledDictionary<T>;
84
- assumptions: undefined | ExpressionMap<T, boolean>;
680
+ export declare type RuntimeScope = Scope & {
681
+ parentScope: RuntimeScope;
682
+ dictionary?: RuntimeDictionary;
683
+ assumptions: undefined | ExpressionMapInterface<boolean>;
85
684
  /** The location of the call site that created this scope */
86
685
  origin?: {
87
686
  name?: string;
@@ -93,11 +692,57 @@ export declare type RuntimeScope<T extends number = number> = Scope & {
93
692
  /** Set when one or more warnings have been signaled in this scope */
94
693
  warnings?: WarningSignal[];
95
694
  };
695
+ export declare type BaseDefinition = {
696
+ /** The name of the symbol or function for this definition
697
+ *
698
+ * The name of a symbol or function is an arbitrary string of Unicode
699
+ * characters, however the following conventions are recommended:
700
+ *
701
+ * - Use only letters, digits and `-`, and the first character should be
702
+ * a letter: `/^[a-zA-Z][a-zA-Z0-9-]+/`
703
+ * - Built-in functions and symbols should start with an uppercase letter
704
+ *
705
+ */
706
+ name: string;
707
+ /** A short (about 1 line) description. May contain Markdown. */
708
+ description?: string | string[];
709
+ /** A URL pointing to more information about this symbol or head. */
710
+ url?: string;
711
+ /**
712
+ * A short string representing an entry in a wikibase.
713
+ *
714
+ * For example `Q167` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
715
+ * for the `Pi` constant.
716
+ */
717
+ wikidata?: string;
718
+ /**
719
+ * The domain of this item.
720
+ * For dictionaries, this is the domain of all the items in the dictionary
721
+ * For strings, it's always 'String'
722
+ * For symbols, this is the domain of their value.
723
+ * For functions, this is the domain of their result (aka codomain)
724
+ */
725
+ domain?: BoxedExpression | string;
726
+ };
727
+ export declare type BoxedBaseDefinition = {
728
+ name: string;
729
+ wikidata?: string;
730
+ description?: string | string[];
731
+ url?: string;
732
+ /**
733
+ * The scope this definition belongs to.
734
+ *
735
+ * This field is usually undefined, but its value is set by `getDefinition()`
736
+ */
737
+ scope: RuntimeScope | undefined;
738
+ domain?: BoxedExpression;
739
+ _purge(): undefined;
740
+ };
96
741
  /**
97
- * A function definition can have some flags set indicating specific
742
+ * A function definition can have some flags to indicate specific
98
743
  * properties of the function.
99
744
  */
100
- export declare type FunctionFeatures = {
745
+ export declare type FunctionDefinitionFlags = {
101
746
  /** If true, the function is applied element by element to lists, matrices
102
747
  * and equations.
103
748
  *
@@ -109,7 +754,8 @@ export declare type FunctionFeatures = {
109
754
  * Default: false
110
755
  */
111
756
  associative: boolean;
112
- /** If true, [f, a, b] simplifies to [f, b, a]
757
+ /** If true, `[f, a, b]` equals `[f, b, a]`. The canonical
758
+ * version of the function will order the arguments.
113
759
  *
114
760
  * Default: false
115
761
  */
@@ -120,19 +766,19 @@ export declare type FunctionFeatures = {
120
766
  * When the function is multivariate, additivity is considered only on the
121
767
  * first argument: `[f, ["Add", x, c], y]` simplifies to `["Add", [f, x, y], c]`.
122
768
  *
769
+ * For example, `log` is additive.
770
+ *
123
771
  * Default: false
124
772
  */
125
- additive: boolean;
126
773
  /** If true, when the function is univariate, `[f, ["Multiply", x, y]]`
127
774
  * simplifies to `["Multiply", [f, x], [f, y]]`.
128
775
  *
129
- * When the function is multivariate, multipicativity is considered only on the
776
+ * When the function is multivariate, multiplicativity is considered only on the
130
777
  * first argument: `[f, ["Multiply", x, y], z]` simplifies to
131
778
  * `["Multiply", [f, x, z], [f, y, z]]`
132
779
  *
133
780
  * Default: false
134
781
  */
135
- multiplicative: boolean;
136
782
  /** If true, when the function is univariate, `[f, ["Multiply", x, c]]`
137
783
  * simplifies to `["Multiply", [f, x], c]` where `c` is constant
138
784
  *
@@ -142,7 +788,6 @@ export declare type FunctionFeatures = {
142
788
  *
143
789
  * Default: false
144
790
  */
145
- outtative: boolean;
146
791
  /** If true, `[f, [f, x]]` simplifies to `[f, x]`.
147
792
  *
148
793
  * Default: false
@@ -154,152 +799,285 @@ export declare type FunctionFeatures = {
154
799
  */
155
800
  involution: boolean;
156
801
  /**
157
- * If true, the input arguments and the result are expected to be `number`.
802
+ * If true, when all the arguments are numeric, the result of the
803
+ * evaluation is numeric. Numeric is any value with a domain of `Number`.
804
+ *
805
+ * Example of numeric functions: `Add`, `Multiply`, `Power`, `Abs`
158
806
  *
159
807
  * Default: false
160
808
  */
161
809
  numeric: boolean;
162
- /** If true, invoking the function with a given set of arguments will
163
- * always return the same value, i.e. `Sin` is pure, `Random` isn't.
164
- * This is used to cache the result of the function.
810
+ /**
811
+ * If true, when all the arguments are boolean, the result of the
812
+ * evaluation is a boolean. Boolean is any value with a domain of `MaybeBoolean`.
165
813
  *
166
- * Default: true
814
+ * Example of logic functions: `And`, `Or`, `Not`, `Implies`
815
+ *
816
+ * **Default:** false
167
817
  */
168
- pure: boolean;
169
- };
170
- /** A domain such as 'Number' or 'Boolean' represents a set of values.
171
- *
172
- * Domains can be defined as a union or intersection of domains:
173
- * - `["Union", "Number", "Boolean"]` A number or a boolean.
174
- * - `["SetMinus", "Number", 1]` Any number except "1".
175
- *
176
- * Domains are defined in a hierarchy (a lattice).
177
- */
178
- export declare type Domain<T extends number = number> = Expression<T>;
179
- export declare type BaseDefinition<T extends number = number> = {
180
- domain: Domain<T> | ((...args: Expression<T>[]) => Domain<T>);
818
+ logic: boolean;
181
819
  /**
182
- * A short string representing an entry in a wikibase.
820
+ * The function represent a relation between the first argument and
821
+ * the second argument, and evaluates to a boolean indicating if the relation
822
+ * is satisfied.
183
823
  *
184
- * For example `Q167` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
185
- * for the `Pi` constant.
824
+ * For example, `Equal`, `Less`, `Approx`, etc...
825
+ *
826
+ * **Default:** false
186
827
  */
187
- wikidata?: string;
828
+ relationalOperator: boolean;
829
+ /** If true, the value of this function is always the same for a given
830
+ * set of arguments and it has no side effects.
831
+ *
832
+ * An expression using this function is pure if the function and all its
833
+ * arguments are pure.
834
+ *
835
+ * For example `Sin` is pure, `Random` isn't.
836
+ *
837
+ * This information may be used to cache the value of expressions.
838
+ *
839
+ * **Default:** true
840
+ */
841
+ pure: boolean;
188
842
  /**
189
- * The scope this definition belongs to.
843
+ * An inert function evaluates directly to one of its argument, typically
844
+ * the first one. They may be used to provide formating hints, but do
845
+ * not affect simplification or evaluation.
190
846
  *
191
- * This field is usually undefined, but its value is set by `getDefinition()`,
192
- * `getFunctionDefinition()` and `getSymbolDefinition()`.
847
+ * **Default:** false
193
848
  */
194
- scope?: Scope;
849
+ inert: boolean;
195
850
  };
196
851
  /**
197
852
  *
198
853
  *
199
854
  */
200
- export declare type FunctionDefinition<T extends number = number> = BaseDefinition<T> & Partial<FunctionFeatures> & {
855
+ export declare type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlags> & {
856
+ /**
857
+ * A number used to order expressions. Expressions with higher
858
+ * complexity are placed after expressions with lower complexity when
859
+ * ordered canonically.
860
+ *
861
+ * Additive functions: 1000-1999
862
+ * Multiplicative functions: 2000-2999
863
+ * Root and power functions: 3000-3999
864
+ * Log functions: 4000-4999
865
+ * Trigonometric functions: 5000-5999
866
+ * Hypertrigonometric functions: 6000-6999
867
+ * Special functions (factorial, Gamma, ...): 7000-7999
868
+ * Collections: 8000-8999
869
+ * Inert and styling: 9000-9999
870
+ * Logic: 10000-10999
871
+ * Relational: 11000-11999
872
+ *
873
+ * **Default**: 100,000 (DEFAULT_COMPLEXITY)
874
+ */
875
+ complexity?: number;
201
876
  /**
202
- * - `none`: Each of the arguments is evaluated
203
- * - `all`: The arguments will not be evaluated and will be passed as is
877
+ * - `none`: Each of the arguments is evaluated (default)
878
+ * - `all`: None of the arguments are evaluated and they are passed as is
204
879
  * - `first`: The first argument is not evaluated, the others are
205
880
  * - `rest`: The first argument is evaluated, the others aren't
206
881
  */
207
- hold?: 'none' | 'all' | 'first' | 'rest';
882
+ hold?: 'none' | 'all' | 'first' | 'rest' | 'last' | 'most';
208
883
  /**
209
- * If true, `Sequence` arguments are not automatically spliced in
884
+ * If true, `Sequence` arguments appearing in the arguments of a function
885
+ * should not automatically be flattened out
210
886
  */
211
887
  sequenceHold?: boolean;
888
+ /** The minimum and maximum values of the result of the function */
889
+ range?: [min: number, max: number];
212
890
  /**
213
- * The number and domains of the arguments for this function.
891
+ * Return the canonical form of the expression with the arguments `args`.
892
+ *
893
+ * All the arguments that are not subject to a hold are in canonical form.
894
+ * Any `Nothing` argument has been removed.
895
+ *
896
+ * If the function is associative, idempotent or an involution,
897
+ * it should handle its arguments accordingly. Notably, if it
898
+ * is commutative, the arguments should be sorted in canonical order.
899
+ *
900
+ * The handler can make transformations based on the value of the arguments
901
+ * that are literal and either rational numbers (i.e.
902
+ * `arg.isLiteral && arg.isRational`) or integers (i.e.
903
+ * `isLiteral && arg.isInteger`).
904
+ *
905
+ * The handler should not consider the value of the arguments
906
+ * that are symbols or functions.
907
+ *
908
+ * The handler should not consider any assumptions about any of the
909
+ * arguments that are symbols or functions i.e. `arg.isZero`,
910
+ * `arg.isInteger`, etc...
911
+ *
912
+ * The handler should not make transformations based on the value of
913
+ * floating point numbers.
914
+ *
915
+ * The result of the handler should be a canonical expression.
214
916
  *
215
917
  */
216
- inputDomain?: Domain[];
918
+ canonical?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression;
217
919
  /**
920
+ * Rewrite an expression into a simpler form.
218
921
  *
219
- * The domain of the result.
922
+ * The arguments are in canonical form and have been simplified.
220
923
  *
221
- * If `range` is a function, the arguments of `range()` are the
222
- * the arguments of the function. The `range()` function can
223
- * make use of available assumptions to determine its result.
924
+ * The handler can use the values assigned to symbols and the assumptions about
925
+ * symbols, for example with `arg.machineValue`, `arg.isInteger` or
926
+ * `arg.isPositive`.
224
927
  *
225
- * The range should be as precise as possible. A range of
226
- * `Anything` is correct, but won't be very helpful.
928
+ * Even though a symbol may not have a value, there may be some information
929
+ * about it reflected for example in `expr.isZero` or `expr.isPrime`.
227
930
  *
228
- * A range of `Number` is good, a range of `RealNumber` is better
229
- * and a range of `["Interval", 0, "+Infinity"]` is even better.
931
+ * The handler should not perform approximate numeric calculations, such
932
+ * as calculations involving floating point numbers. Making exact
933
+ * calculations on integers or rationals is OK. It is recommended, but not
934
+ * required, that the calculations be limited to `expr.smallIntegerValue`
935
+ * (i.e. numeric representations of the expression as an integer of small
936
+ * magnitude).
937
+ *
938
+ * This handler should not have any side-effects: do not modify
939
+ * the environment of the `ComputeEngine` instance, do not perform I/O,
940
+ * do not do calculations that depend on random values.
941
+ *
942
+ * If no simplification can be performed due to the values, domains or assumptions
943
+ * about its arguments, for example, return `undefined`.
230
944
  *
231
945
  */
232
- range: Domain<T> | ((engine: ComputeEngine, ...args: Expression<T>[]) => Expression<T>);
946
+ simplify?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | undefined;
233
947
  /**
234
- * The value of this function, as a lambda function.
235
- * The arguments are `_`, `_2`, `_3`, etc...
948
+ * Evaluate symbolically an expression.
949
+ *
950
+ * The arguments have been symbolically evaluated, except the arguments to
951
+ * which a `hold` apply.
952
+ *
953
+ * It is not necessary to further simplify or evaluate the arguments.
954
+ *
955
+ * If the expression cannot be evaluated, due to the values, domains, or
956
+ * assumptions about its arguments, for example, return `undefined`.
957
+ *
236
958
  *
237
- * This property may be used to perform some simplification, or
238
- * to numerically evaluate the function if no `evalNumber` property
239
- * is provided.
240
959
  */
241
- value?: T | Expression;
960
+ evaluate?: LambdaExpression | ((ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | undefined);
242
961
  /**
243
- * Rewrite the expression into a simplified form.
962
+ * Evaluate numerically `expr`.
244
963
  *
245
- * If appropriate, make use of assumptions with `ce.is()`.
964
+ * The arguments of `expr` have been simplified and evaluated, numerically
965
+ * if possible, except the arguments to which a `hold` apply.
246
966
  *
247
- * Do not resolve the values of variables, that is `ce.simplify("x+1")` is
248
- * `x + 1` even if `x = 0`. However, resolving constants is OK.
967
+ * The arguments of `expr` may be a combination of numbers, symbolic
968
+ * expressions and other expressions.
249
969
  *
250
- * Do not make approximate evaluations (i.e. floating point operations).
970
+ * Perform as many calculations as possible, and return the result.
251
971
  *
252
- * Do not perform complex or lengthy operations: do these in `ce.evaluate()`.
972
+ * Return `undefined` if there isn't enough information to perform
973
+ * the evaluation, for example one of the arguments is a symbol with
974
+ * no value. If the handler returns `undefined`, symbolic evaluation of
975
+ * the expression will be returned instead to the caller.
253
976
  *
254
- * Only make simple rewrites of the expression.
977
+ * Return `NaN` if there is enough information to perform the
978
+ * evaluation, but a literal argument is out of range or
979
+ * not of the expected type.
255
980
  *
256
- * The passed-in arguments have been simplified already,
257
- * except for those to which a `hold` apply.
258
- */
259
- simplify?: (engine: ComputeEngine, ...args: Expression<T>[]) => Expression<T>;
260
- /**
261
- * Make a numeric evaluation of the arguments.
981
+ * Also return `NaN` if the result of the evaluation would be a complex
982
+ * number, but complex numbers are not allowed (the `engine.numericMode`
983
+ * is not `complex` or `auto`).
262
984
  *
263
- * The passed-in arguments have already been numerically evaluated
264
- * unless the arguments have a `hold` property.
985
+ * If the `expr.engine.numericMode` is `auto` or `complex`, you may return
986
+ * a Complex number as a result. Otherwise, if the result is a complex
987
+ * value, return `NaN`. If Complex are not allowed, none of the arguments
988
+ * will be complex literals.
265
989
  *
266
- * If the function is `numeric` all the arguments are guaranteed to be
267
- * numbers and the function should return a number.
990
+ * If the `expr.engine.numericMode` is `decimal` or `auto` and
991
+ * `expr.engine.precision` is > 15, you may return a Decimal number.
992
+ * Otherwise, return a `machine` number approximation. If Decimal are
993
+ * not allowed, none of the arguments will be Decimal literal.
994
+ *
995
+ * You may perform any necessary computations, including approximate
996
+ * calculations on floating point numbers.
268
997
  *
269
998
  */
270
- evalNumber?: (engine: ComputeEngine, ...args: number[]) => number;
271
- /** Like `evalNumber()` but for `Complex` numbers */
272
- evalComplex?: (engine: ComputeEngine, ...args: (number | Complex)[]) => Complex;
273
- /** Live `evalNumber()` but for Decimal numbers (arbitrary large floating
274
- * point numbers).
275
- */
276
- evalDecimal?: (engine: ComputeEngine, ...args: (number | Decimal)[]) => Decimal;
999
+ N?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | undefined;
277
1000
  /**
278
- * Evaluate the arguments.
279
1001
  *
280
- * This will be invoked by the `ce.evaluate()` function, and
281
- * after the `simplify()` and `evalNumber()` definition methods have been
282
- * called.
1002
+ * Calculate the domain of the result, based on the value of the arguments.
1003
+ *
1004
+ * If the domain of the result is always the same, use the `domain` property
1005
+ * instead.
1006
+ *
1007
+ * The argument `args` represent the arguments of the function.
1008
+ *
1009
+ * The return value is `null` if the input arguments cannot be handled by
1010
+ * this definition.
1011
+ *
1012
+ * Otherwise, the return value is the domain of the result.
283
1013
  *
284
- * If a function must perform any computations that may take a long time
285
- * (>100ms), because they are computationally expensive, or because they
286
- * require a network fetch, defer these computations to `ce.evaluate()`
287
- * rather than `ce.simplify()`.
1014
+ * Return `Nothing` if the arguments are acceptable, but the evaluation
1015
+ * will fail, for example in some cases if there are missing arguments.
288
1016
  *
289
- * If a synchronous `ce.evaluate()` function is provided it will be used and
290
- * `ce.evaluateAsync()` will not be called.
1017
+ * This function is used to select the correct definition when there are
1018
+ * multiple definitions for the same function name.
1019
+ *
1020
+ * For example it allows to distinguish between a `Add` function that
1021
+ * applies to numbers and an `Add` function that applies to tensors.
291
1022
  *
292
- * The arguments have been simplified and numerically evaluated, except
293
- * the arguments to which a `hold` apply.
294
1023
  */
295
- evaluate?: (engine: ComputeEngine, ...args: Expression<T>[]) => Expression<T>;
296
- evaluateAsync?: (engine: ComputeEngine, ...args: Promise<Expression<T>>[]) => Promise<Expression<T>>;
297
- /** Return a compiled (optimized) function. */
298
- compile?: (engine: ComputeEngine, ...args: CompiledExpression<T>[]) => CompiledExpression<T>;
1024
+ evalDomain?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | string | null;
299
1025
  /** Dimensional analysis */
300
- dimension?: (engine: ComputeEngine, ...args: Expression<T>[]) => Expression<T>;
1026
+ evalDimension?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression;
1027
+ /** Return the sign of the function given a list of arguments. */
1028
+ sgn?: (ce: IComputeEngine, args: BoxedExpression[]) => -1 | 0 | 1 | undefined;
1029
+ /** Return a compiled (optimized) expression. */
1030
+ compile?: (expr: BoxedExpression) => CompiledExpression;
1031
+ };
1032
+ export declare type BoxedFunctionDefinition = BoxedBaseDefinition & FunctionDefinitionFlags & {
1033
+ complexity: number;
1034
+ hold: 'none' | 'all' | 'first' | 'rest' | 'last' | 'most';
1035
+ sequenceHold: boolean;
1036
+ range?: [min: number, max: number];
1037
+ canonical?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression;
1038
+ simplify?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | undefined;
1039
+ evaluate?: BoxedLambdaExpression | ((ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | undefined);
1040
+ N?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | undefined;
1041
+ evalDomain?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | string | null;
1042
+ evalDimension?: (ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression;
1043
+ sgn?: (ce: IComputeEngine, args: BoxedExpression[]) => -1 | 0 | 1 | undefined;
1044
+ compile?: (expr: BoxedExpression) => CompiledExpression;
1045
+ };
1046
+ /**
1047
+ * When used in a `SymbolDefinition`, these flags are optional.
1048
+ * If provided, they will override the value derived from
1049
+ * the symbol's value.
1050
+ *
1051
+ * For example, it might be useful to override `algebraic = false`
1052
+ * for a transcendental number.
1053
+ */
1054
+ export declare type SymbolFlags = {
1055
+ number: boolean | undefined;
1056
+ integer: boolean | undefined;
1057
+ rational: boolean | undefined;
1058
+ algebraic: boolean | undefined;
1059
+ real: boolean | undefined;
1060
+ extendedReal: boolean | undefined;
1061
+ complex: boolean | undefined;
1062
+ extendedComplex: boolean | undefined;
1063
+ imaginary: boolean | undefined;
1064
+ positive: boolean | undefined;
1065
+ nonPositive: boolean | undefined;
1066
+ negative: boolean | undefined;
1067
+ nonNegative: boolean | undefined;
1068
+ zero: boolean | undefined;
1069
+ notZero: boolean | undefined;
1070
+ one: boolean | undefined;
1071
+ negativeOne: boolean | undefined;
1072
+ infinity: boolean | undefined;
1073
+ NaN: boolean | undefined;
1074
+ finite: boolean | undefined;
1075
+ even: boolean | undefined;
1076
+ odd: boolean | undefined;
1077
+ prime: boolean | undefined;
1078
+ composite: boolean | undefined;
301
1079
  };
302
- export declare type SymbolFeatures = {
1080
+ export declare type SymbolDefinitionFlags = {
303
1081
  /**
304
1082
  * If true the value of the symbol is constant.
305
1083
  *
@@ -307,342 +1085,206 @@ export declare type SymbolFeatures = {
307
1085
  */
308
1086
  constant: boolean;
309
1087
  /**
310
- * If false, the value of the symbol is substituted during a `ce.simplify().
311
- * If true, the symbol is unchanged during a `ce.simplify()` and the value
312
- * is only used during a `ce.N()` or `ce.evaluate()`.
1088
+ * If false, the value of the symbol is substituted during canonicalization
1089
+ * or simplification.
1090
+ *
1091
+ * If true, the value is only replaced during a `ce.N()` or `ce.evaluate()`.
313
1092
  *
314
- * True by default;
1093
+ * **Default:** `true`
315
1094
  */
316
- hold?: boolean;
1095
+ hold: boolean;
317
1096
  };
318
- export declare type SymbolDefinition<T extends number = number> = BaseDefinition<T> & SymbolFeatures & {
319
- value?: Expression<T> | ((ce: ComputeEngine) => Expression<T>);
320
- /** For dimensional analysis, e.g. `Scalar`, `Meter`, `["Divide", "Meter", "Second"]` */
321
- unit?: Expression<T>;
1097
+ /**
1098
+ * A bound symbol (i.e. one with an associated definition) has either a domain
1099
+ * (e.g. x ℝ), a value (x = 5) or both (π: value = 3.14... domain = TranscendentalNumber)
1100
+ */
1101
+ export declare type SymbolDefinition = BaseDefinition & Partial<SymbolFlags> & Partial<SymbolDefinitionFlags> & {
1102
+ /** `value` can be a function since for some constants, such as
1103
+ * `Pi`, the actual value depends on the `precision` setting of the
1104
+ * `ComputeEngine` */
1105
+ value?: LatexString | SemiBoxedExpression | ((ce: IComputeEngine) => SemiBoxedExpression | null);
1106
+ domain?: string | BoxedExpression;
322
1107
  };
323
- export declare type CollectionDefinition<T extends number = number> = BaseDefinition<T> & {
324
- /** If true, the elements of the collection can be iterated over using
325
- * the `iterator() function
326
- */
327
- iterable?: boolean;
328
- iterator?: {
329
- next: () => Expression<T>;
330
- done: () => boolean;
331
- };
332
- /** If true, elements of the collection can be accessed with a numerical
333
- * index with the `at()` function
334
- */
335
- indexable?: boolean;
336
- at?: (index: number) => Expression<T>;
337
- /** If true, the size of the collection is finite.
338
- *
339
- */
340
- countable: boolean;
341
- /** Return the number of elements in the collection.
342
- */
343
- size?: () => number;
344
- /** A predicate function to determine if an expression
345
- * is a member of the collection or not (answers `True`, `False` or `Maybe`).
346
- */
347
- isElementOf?: (expr: Expression<T>) => boolean;
1108
+ export interface BoxedSymbolDefinition extends BoxedBaseDefinition, Partial<SymbolFlags>, SymbolDefinitionFlags {
1109
+ get value(): BoxedExpression | undefined;
1110
+ set value(val: BoxedExpression | undefined);
1111
+ at?: (index: string | number) => undefined | BoxedExpression;
1112
+ }
1113
+ export declare type AssumeResult = 'internal-error' | 'not-a-predicate' | 'contradiction' | 'tautology' | 'ok';
1114
+ export declare type CompiledExpression = {
1115
+ evaluate?: (scope: {
1116
+ [symbol: string]: BoxedExpression;
1117
+ }) => number | BoxedExpression;
348
1118
  };
349
- export declare type SetDefinition<T extends number = number> = CollectionDefinition<T> & {
350
- /** The supersets of this set: they should be symbol with a `Set` domain */
351
- supersets: string[];
352
- /** If a set can be defined explicitely in relation to other sets,
353
- * the `value` represents that relationship.
354
- * For example `"NaturalNumber"` = `["Union", "PrimeNumber", "CompositeNumber"]`.
1119
+ export interface ComputeEngineStats {
1120
+ symbols: Set<BoxedExpression>;
1121
+ expressions: null | Set<BoxedExpression>;
1122
+ highwaterMark: number;
1123
+ }
1124
+ export interface IComputeEngine {
1125
+ readonly ZERO: BoxedExpression;
1126
+ readonly ONE: BoxedExpression;
1127
+ readonly TWO: BoxedExpression;
1128
+ readonly HALF: BoxedExpression;
1129
+ readonly NEGATIVE_ONE: BoxedExpression;
1130
+ readonly I: BoxedExpression;
1131
+ readonly NAN: BoxedExpression;
1132
+ readonly POSITIVE_INFINITY: BoxedExpression;
1133
+ readonly NEGATIVE_INFINITY: BoxedExpression;
1134
+ readonly COMPLEX_INFINITY: BoxedExpression;
1135
+ readonly DECIMAL_NAN: Decimal;
1136
+ readonly DECIMAL_ZERO: Decimal;
1137
+ readonly DECIMAL_ONE: Decimal;
1138
+ readonly DECIMAL_TWO: Decimal;
1139
+ readonly DECIMAL_HALF: Decimal;
1140
+ readonly DECIMAL_PI: Decimal;
1141
+ readonly DECIMAL_NEGATIVE_ONE: Decimal;
1142
+ context: RuntimeScope;
1143
+ /** Absolute time beyond which evaluation should not proceed */
1144
+ deadline?: number;
1145
+ readonly timeLimit: number;
1146
+ readonly iterationLimit: number;
1147
+ readonly recursionLimit: number;
1148
+ readonly defaultDomain: null | BoxedExpression;
1149
+ numericMode: NumericMode;
1150
+ tolerance: number;
1151
+ chop(n: number): number;
1152
+ chop(n: Decimal): Decimal | 0;
1153
+ chop(n: Complex): Complex | 0;
1154
+ chop(n: number | Decimal | Complex): number | Decimal | Complex;
1155
+ decimal: (a: Decimal.Value) => Decimal;
1156
+ complex: (a: number | Complex, b?: number) => Complex;
1157
+ set precision(p: number | 'machine');
1158
+ get precision(): number;
1159
+ costFunction: (expr: BoxedExpression) => number;
1160
+ /**
1161
+ * Associate a new definition to a symbol in the current context.
1162
+ *
1163
+ * If a definition existed previously, it is replaced.
355
1164
  */
356
- value?: Expression<T>;
1165
+ defineSymbol(def: SymbolDefinition): BoxedSymbolDefinition;
1166
+ getSymbolDefinition(name: string, wikidata?: string): undefined | BoxedSymbolDefinition;
357
1167
  /**
358
- * A function that determins if a set is a subset of another.
359
- * The `rhs` argument is either the name of the symbol, or a function
360
- * with the head of the symbol.
1168
+ * Return `undefined` if no definition exist for this `head.
361
1169
  */
362
- isSubsetOf?: (engine: ComputeEngine, lhs: Expression<T>, rhs: Expression<T>) => boolean;
363
- };
364
- export declare type Definition<T extends number = number> = SymbolDefinition<T> | FunctionDefinition | SetDefinition | CollectionDefinition<T>;
365
- export declare type CompiledExpression<T extends number = number> = {
366
- evaluate?: (scope: {
367
- [symbol: string]: T | Expression<T>;
368
- }) => Expression<T>;
369
- asyncEvaluate?: (scope: {
370
- [symbol: string]: T | Expression<T>;
371
- }) => Promise<T | Expression<T>>;
372
- };
373
- export declare type Simplification = 'simplify-all' | 'simplify-arithmetic';
374
- export declare type NumericFormat = 'auto' | 'machine' | 'decimal' | 'complex';
375
- /**
376
- * Create a `CustomEngine` instance to customize its behavior and the syntax
377
- * and operation dictionaries it uses.
378
- *
379
- * The constructor of `ComputeEngine` will compile and optimize the dictionary
380
- * upfront.
381
- */
382
- export declare class ComputeEngine<T extends number = Numeric> {
1170
+ getFunctionDefinition(head: string, wikidata?: string): undefined | BoxedFunctionDefinition;
383
1171
  /**
384
- * Return dictionaries suitable for the specified categories, or `"all"`
385
- * for all categories (`"arithmetic"`, `"algebra"`, etc...).
1172
+ * Returned a boxed expression from the input.
386
1173
  *
387
- * A symbol dictionary defines how the symbols and function names in a MathJSON
388
- * expression should be interpreted, i.e. how to evaluate and manipulate them.
1174
+ * The result may not be canonical.
1175
+ */
1176
+ box(expr: Decimal | Complex | [num: number, denom: number] | SemiBoxedExpression): BoxedExpression;
1177
+ /** Return a canonical boxed number */
1178
+ number(value: number | MathJsonNumber | Decimal | Complex | [num: number, denom: number], metadata?: Metadata): BoxedExpression;
1179
+ /** Return a canonical boxed symbol */
1180
+ symbol(sym: string, metadata?: Metadata): BoxedExpression;
1181
+ /** Return a canonical boxed string */
1182
+ string(s: string, metadata?: Metadata): BoxedExpression;
1183
+ /** Return a canonical boxed domain */
1184
+ domain(domain: BoxedExpression | string, metadata?: Metadata): BoxedExpression;
1185
+ /** Return a canonical expression.
1186
+ *
1187
+ * Note that the result may not be a function, or may have a different
1188
+ * `head` than the one specified.
1189
+ *
1190
+ * For example `ce.fn('Add', [ce.number(2), ce.number(3)]))` -> 5
389
1191
  *
390
1192
  */
391
- static getDictionaries(categories: DictionaryCategory[] | 'all'): Readonly<Dictionary<any>>[];
1193
+ fn(head: string | SemiBoxedExpression, ops: SemiBoxedExpression[], metadata?: Metadata): BoxedExpression;
392
1194
  /**
393
- * The current scope.
1195
+ * This is a primitive to create a boxed function. It doesn't perform
1196
+ * any checks or normalization on its arguments.
394
1197
  *
395
- * A scope is a dictionary that contains the definition of local symbols.
396
- *
397
- * Scopes form a stack, and definitions in more recent
398
- * scopes can obscure definitions from older scopes.
1198
+ * In general, consider using `fn()` or `box()` instead.
399
1199
  *
1200
+ * The result is canonical, but the caller has to ensure that all the
1201
+ * conditions are met (i.e. ops properly normalized and sorted, all
1202
+ * ops canonical, etc..) so that the result is actually canonical.
400
1203
  */
401
- context: RuntimeScope<T>;
402
- readonly assumptions: ExpressionMap<T, boolean>;
403
- /** Absolute time beyond which evaluation should not proceed */
404
- deadline?: number;
405
- readonly timeLimit?: number;
406
- readonly iterationLimit?: number;
407
- readonly recursionLimit?: number;
408
- /** The default precision of the compute engine: the number of significant
409
- * digits when performing numeric evaluations, such as when calling `ce.N()`.
1204
+ _fn(head: string | BoxedExpression, ops: BoxedExpression[], metadata?: Metadata): BoxedExpression;
1205
+ /** Shortcut for `fn('Error'...)`.
410
1206
  *
411
- * To make calculations using machine floating point representation, set
412
- * `precision` to `"machine"` (15 by default).
1207
+ * The result is canonical.
1208
+ */
1209
+ error(val: BoxedExpression, message: string, messageArg: SemiBoxedExpression): any;
1210
+ /** Shortcut for `fn('Add'...)`.
413
1211
  *
414
- * To make calculations using more digits, at the cost of expended memory
415
- * usage and slower computations, set the `precision` higher.
1212
+ * The result is canonical.
1213
+ */
1214
+ add(ops: BoxedExpression[], metadata?: Metadata): BoxedExpression;
1215
+ /** Shortcut for `fn('Multiply'...)`
416
1216
  *
417
- * Trigonometric operations are accurate for precision up to 1,000.
1217
+ * The result is canonical.
1218
+ */
1219
+ mul(ops: BoxedExpression[], metadata?: Metadata): BoxedExpression;
1220
+ /** Shortcut for `fn('Power'...)`
418
1221
  *
419
- * Some functions, such as `ce.N()` have an option to specify the precision.
420
- * If no precision is specified in these functions, the precision of
421
- * the compute engine is used.
1222
+ * The result is canonical.
1223
+ */
1224
+ power(base: BoxedExpression, exponent: number | [number, number] | BoxedExpression, metadata?: Metadata): BoxedExpression;
1225
+ /** Shortcut for `fn('Divide', 1, expr)`
422
1226
  *
1227
+ * The result is canonical.
423
1228
  */
424
- set precision(p: number | 'machine');
425
- get precision(): number;
426
- /**
427
- * Internal format to represent numbers:
428
- * - `auto`: the best format is determined based on the calculations to perform
429
- * and the requested precision.
430
- * - `number`: use the machine format (64-bit float, 52-bit, about 15 digits
431
- * of precision).
432
- * - `decimal`: arbitrary precision floating-point numbers, as provided by the
433
- * "decimal.js" library
434
- * - `complex`: complex numbers: two 64-bit float, as provided by the
435
- * "complex.js" library
1229
+ inverse(expr: BoxedExpression, metadata?: Metadata): BoxedExpression;
1230
+ /** Shortcut for `fn('Negate'...)`
436
1231
  *
1232
+ * The result is canonical.
437
1233
  */
438
- numericFormat: NumericFormat;
439
- /**
440
- * Values smaller than the tolerance are considered to be zero for the
441
- * purpose of comparison, i.e. if `|b - a| <= tolerance`, `b` is considered
442
- * equal to `a`.
1234
+ negate(expr: BoxedExpression, metadata?: Metadata): BoxedExpression;
1235
+ /** Shortcut for `fn('Divide'...)`
1236
+ *
1237
+ * The result is canonical.
443
1238
  */
444
- tolerance: number;
445
- /**
446
- * Construct a new `ComputeEngine` environment.
1239
+ divide(num: BoxedExpression, denom: BoxedExpression, metadata?: Metadata): BoxedExpression;
1240
+ /** Shortcut for `fn('Pair'...)`
447
1241
  *
448
- * If no `options.dictionaries` is provided a default set of dictionaries
449
- * is used. The `ComputeEngine.getDictionaries()` method can be called
450
- * to access some subset of dictionaries, e.g. for arithmetic, calculus, etc...
451
- * The order of the dictionaries matter: the definitions from the later ones
452
- * override the definitions from earlier ones. The first dictionary should
453
- * be the `'core'` dictionary which include some basic definitions such
454
- * as domains (`Boolean`, `Number`, etc...) that are used by later dictionaries.
1242
+ * The result is canonical.
455
1243
  */
456
- constructor(options?: {
457
- dictionaries?: Readonly<Dictionary<T>>[];
458
- });
459
- /** Create a new scope and add it to the top of the scope stack */
460
- pushScope(dictionary: Readonly<Dictionary<T>>, scope?: Partial<Scope>): void;
461
- /** Remove the topmost scope from the scope stack.
1244
+ pair(first: BoxedExpression, second: BoxedExpression, metadata?: Metadata): BoxedExpression;
1245
+ /** Shortcut for `fn('Tuple'...)`
1246
+ *
1247
+ * The result is canonical.
462
1248
  */
463
- popScope(): void;
1249
+ tuple(elements: BoxedExpression[], metadata?: Metadata): BoxedExpression;
1250
+ rules(rules: Rule[]): BoxedRuleSet;
1251
+ pattern(expr: LatexString | SemiBoxedExpression): Pattern;
464
1252
  /**
465
- * Call this function if an unexpected condition occurs during execution of a
466
- * function in the engine.
467
- *
468
- * An `ErrorSignal` is a problem that cannot be recovered from.
1253
+ * Parse a string of LaTeX and return a corresponding `BoxedExpression`.
469
1254
  *
470
- * A `WarningSignal` indicates a minor problem that does not prevent the
471
- * execution to continue.
1255
+ * The result may not be canonical.
472
1256
  *
473
1257
  */
474
- signal(sig: ErrorSignal | WarningSignal): void;
475
- /**
476
- * Return false if the execution should stop.
477
- *
478
- * This can occur if:
479
- * - an error has been signaled
480
- * - the time limit or memory limit has been exceeded
1258
+ parse(s: null | string | LatexString): BoxedExpression | null;
1259
+ /** Serialize a `BoxedExpression` or a `MathJSON` expression to
1260
+ * a LaTeX string
481
1261
  */
1262
+ serialize(expr: SemiBoxedExpression): LatexString;
1263
+ get latexOptions(): Required<NumberFormattingOptions> & Required<ParseLatexOptions> & Required<SerializeLatexOptions>;
1264
+ set latexOptions(opts: NumberFormattingOptions & ParseLatexOptions & SerializeLatexOptions);
1265
+ get jsonSerializationOptions(): JsonSerializationOptions;
1266
+ set jsonSerializationOptions(val: Partial<JsonSerializationOptions>);
1267
+ assume(symbol: LatexString | SemiBoxedExpression, domain: BoxedExpression): AssumeResult;
1268
+ assume(predicate: LatexString | SemiBoxedExpression): AssumeResult;
1269
+ assume(arg1: LatexString | SemiBoxedExpression, arg2?: BoxedExpression): AssumeResult;
1270
+ forget(symbol?: string | string[]): void;
1271
+ get assumptions(): ExpressionMapInterface<boolean>;
1272
+ ask(pattern: LatexString | SemiBoxedExpression): Substitution[];
1273
+ pushScope(options?: {
1274
+ dictionary?: Readonly<Dictionary> | Readonly<Dictionary>[];
1275
+ assumptions?: (LatexString | Expression | BoxedExpression)[];
1276
+ scope?: Partial<Scope>;
1277
+ }): void;
1278
+ popScope(): void;
1279
+ assert(condition: boolean, expr: BoxedExpression, msg: string, code?: SignalMessage): any;
1280
+ signal(expr: BoxedExpression, msg: string, code?: SignalMessage): void;
1281
+ signal(sig: WarningSignal): void;
482
1282
  shouldContinueExecution(): boolean;
483
1283
  checkContinueExecution(): void;
484
- getFunctionDefinition(name: string): FunctionDefinition | null;
485
- getSymbolDefinition(name: string): SymbolDefinition<T> | null;
486
- getSetDefinition(name: string): SetDefinition | null;
487
- getCollectionDefinition(name: string): CollectionDefinition<T> | null;
488
- getDefinition(name: string): Definition<T> | null;
489
- /** Format the expression to the canonical form.
490
- *
491
- * In the canonical form, some operations are simplified (subtractions
492
- * becomes additions of negative, division become multiplications of inverse,
493
- * etc...) and terms are ordered using a deglex order. This can make
494
- * subsequent operations easier.
495
- */
496
- canonical(expr: Expression<T> | null): Expression<T> | null;
497
- /** Format the expression according to the specified forms.
498
- *
499
- * If no form is provided, the expression is formatted with the 'canonical'
500
- * form.
501
- *
502
- */
503
- format(expr: Expression<T> | null, forms?: Form | Form[]): Expression<T> | null;
504
- /**
505
- * Evaluate the expression `exp` asynchronously.
506
- *
507
- * Evaluating some expressions can take a very long time. Some can invole
508
- * making network queries. Therefore to avoid blocking the main event loop,
509
- * a promise is returned.
510
- *
511
- * Use `result = await engine.evaluate(expr)` to get the result without
512
- * blocking.
513
- */
514
- evaluate(expr: Expression<T>, options?: {
515
- timeLimit?: number;
516
- iterationLimit?: number;
517
- }): Promise<Expression<T> | null>;
518
- /**
519
- * Simplify an expression.
520
- */
521
- simplify(exp: Expression<T>, options?: {
522
- timeLimit?: number;
523
- iterationLimit?: number;
524
- simplifications?: Simplification[];
525
- }): Expression<T> | null;
526
- /**
527
- * Return a numerical approximation of an expression.
528
- */
529
- N(exp: Expression<T>, options?: {
530
- precision?: number;
531
- }): T | Expression<T> | null;
532
- /**
533
- * Determines if the predicate is satisfied based on the known assumptions.
534
- *
535
- * Return `undefined` if the value of the predicate cannot be determined.
536
- *
537
- * ```js
538
- * ce.is(["Equal", "x", 0]);
539
- * ce.is(["Equal", 3, 4]);
540
- * ```
541
- *
542
- */
543
- is(symbol: Expression<T>, domain: Domain): boolean | undefined;
544
- is(predicate: Expression<T>): boolean | undefined;
545
- is(arg1: Expression<T>, arg2?: Domain): boolean | undefined;
546
- /**
547
- * Return a list of all the assumptions that match a pattern.
548
- *
549
- * ```js
550
- * ce.assume(x, 'PositiveInteger');
551
- * ce.ask(['Greater', 'x', '_val'])
552
- * // -> [{'val': 0}]
553
- * ```
554
- */
555
- ask(pattern: Expression<T>): Substitution<T>[];
556
- /**
557
- * Apply repeatedly a set of rules to an expression.
558
- */
559
- replace(rules: RuleSet<T>, expr: Expression<T>): Expression<T>;
560
- /**
561
- * Add an assumption.
562
- *
563
- * Return `contradiction` if the new assumption is incompatible with previous
564
- * ones.
565
- *
566
- * Return `tautology` if the new assumption is redundant with previous ones.
567
- *
568
- * Return `ok` if the assumption was successfully added to the assumption set.
569
- *
570
- * Note that the assumption is put into normal form before being added.
571
- *
572
- */
573
- assume(symbol: Expression<T>, domain: Domain): 'contradiction' | 'tautology' | 'ok';
574
- assume(predicate: Expression<T>): 'contradiction' | 'tautology' | 'ok';
575
- assume(arg1: Expression<T>, arg2?: Domain): 'contradiction' | 'tautology' | 'ok';
576
- parse(s: string): Expression<T>;
577
- serialize(x: Expression<T>): string;
578
- getRules(topic: string | string[]): RuleSet;
579
- /** Return the domain of the expression */
580
- domain(expr: Expression<T>): Expression<T> | null;
581
- /** Return the variables in the expression */
582
- getVars(expr: Expression<T>): Set<string>;
583
- chop(n: Numeric): Numeric;
584
- isZero(x: Expression<T>): boolean | undefined;
585
- isNotZero(x: Expression<T>): boolean | undefined;
586
- isNumeric(x: Expression<T>): boolean | undefined;
587
- isInfinity(x: Expression<T>): boolean | undefined;
588
- isFinite(x: Expression<T>): boolean | undefined;
589
- isNonNegative(x: Expression<T>): boolean | undefined;
590
- isPositive(x: Expression<T>): boolean | undefined;
591
- isNegative(x: Expression<T>): boolean | undefined;
592
- isNonPositive(x: Expression<T>): boolean | undefined;
593
- isInteger(x: Expression<T>): boolean | undefined;
594
- isRational(x: Expression<T>): boolean | undefined;
595
- isAlgebraic(x: Expression<T>): boolean | undefined;
596
- isReal(x: Expression<T>): boolean | undefined;
597
- isExtendedReal(x: Expression<T>): boolean | undefined;
598
- isComplex(x: Expression<T>): boolean | undefined;
599
- isOne(x: Expression<T>): boolean | undefined;
600
- isNegativeOne(x: Expression<T>): boolean | undefined;
601
- isElement(x: Expression<T>, set: Expression<T>): boolean | undefined;
602
- isSubsetOf(lhs: Domain | null, rhs: Domain | null): boolean;
603
- isEqual(lhs: Expression<T>, rhs: Expression<T>): boolean | undefined;
604
- isLess(lhs: Expression<T>, rhs: Expression<T>): boolean | undefined;
605
- isLessEqual(lhs: Expression<T>, rhs: Expression<T>): boolean | undefined;
606
- isGreater(lhs: Expression<T>, rhs: Expression<T>): boolean | undefined;
607
- isGreaterEqual(lhs: Expression<T>, rhs: Expression<T>): boolean | undefined;
1284
+ cache<T>(name: string, build: () => T, purge?: (T: any) => T | undefined): T;
1285
+ readonly stats: ComputeEngineStats;
1286
+ purge(): void;
1287
+ _register(expr: BoxedExpression): void;
1288
+ _unregister(expr: BoxedExpression): void;
608
1289
  }
609
- /**
610
- * Transform an expression by applying one or more rewriting rules to it,
611
- * recursively.
612
- *
613
- * There are many ways to symbolically manipulate an expression, but
614
- * transformations with `form` have the following characteristics:
615
- *
616
- * - they don't require calculations or assumptions about the domain of free
617
- * variables or the value of constants
618
- * - the output expression is expressed with more primitive functions,
619
- * for example subtraction is replaced with addition
620
- *
621
- *
622
- */
623
- export declare function format<T extends number = number>(expr: Expression<T>, forms: Form[], options?: {
624
- dictionaries?: Readonly<Dictionary<T>>[];
625
- }): Expression<T>;
626
- /**
627
- * Apply the definitions in the supplied dictionary to an expression
628
- * and return the result.
629
- *
630
- * Unlike `format` this may entail performing calculations and irreversible
631
- * transformations.
632
- *
633
- * See also `[ComputeEngine.evaluate()](#(ComputeEngine%3Aclass).(evaluate%3Ainstance))`.
634
- *
635
- * @param dictionaries - An optional set of functions and constants to use
636
- * when evaluating the expression. Evaluating the expression may modify the
637
- * scope, for example if the expression is an assignment or definition.
638
- */
639
- export declare function evaluate<T extends number = number>(expr: Expression<T>, options?: {
640
- dictionaries?: Readonly<Dictionary<T>>[];
641
- }): Promise<Expression<T> | null>;
642
- /**
643
- * A given mathematical expression can be represented in multiple equivalent
644
- * ways as a MathJSON expression.
645
- *
646
- * Learn more about [Canonical Forms](https://cortexjs.io/guides/compute-engine/forms/).
647
- */
648
- export declare type Form = 'canonical' | 'canonical-add' | 'canonical-boolean' | 'canonical-constants' | 'canonical-divide' | 'canonical-domain' | 'canonical-exp' | 'canonical-list' | 'canonical-multiply' | 'canonical-power' | 'canonical-negate' | 'canonical-number' | 'canonical-rational' | 'canonical-root' | 'canonical-subtract' | 'canonical-domain' | 'flatten' | 'json' | 'object-literal' | 'sorted' | 'stripped-metadata' | 'sum-product';
1290
+ export declare function getVars(expr: BoxedExpression): string[];