@cortex-js/compute-engine 0.4.1 → 0.4.4

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