@cortex-js/compute-engine 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/dist/{compute-engine.js → compute-engine.cjs} +24718 -24251
  2. package/dist/compute-engine.esm.js +24718 -24251
  3. package/dist/compute-engine.min.cjs +129 -0
  4. package/dist/compute-engine.min.esm.js +55 -68
  5. package/dist/math-json.cjs +413 -0
  6. package/dist/math-json.esm.js +287 -7
  7. package/dist/math-json.min.cjs +6 -0
  8. package/dist/math-json.min.esm.js +287 -7
  9. package/dist/types/common/ansi-codes.d.ts +1 -1
  10. package/dist/types/common/fuzzy-string-match.d.ts +2 -0
  11. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  12. package/dist/types/common/interruptible.d.ts +2 -2
  13. package/dist/types/common/json5.d.ts +3 -0
  14. package/dist/types/common/one-of.d.ts +2 -1
  15. package/dist/types/common/signals.d.ts +1 -2
  16. package/dist/types/common/type/boxed-type.d.ts +14 -0
  17. package/dist/types/common/type/parse.d.ts +1 -1
  18. package/dist/types/common/type/primitive.d.ts +2 -1
  19. package/dist/types/common/type/serialize.d.ts +1 -1
  20. package/dist/types/common/type/subtype.d.ts +1 -1
  21. package/dist/types/common/type/types.d.ts +121 -136
  22. package/dist/types/common/type/utils.d.ts +3 -7
  23. package/dist/types/common/utils.d.ts +1 -1
  24. package/dist/types/compute-engine/assume.d.ts +1 -1
  25. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +17 -18
  26. package/dist/types/compute-engine/boxed-expression/apply.d.ts +2 -2
  27. package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +5 -4
  28. package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +27 -0
  29. package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +2 -2
  30. package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
  31. package/dist/types/compute-engine/boxed-expression/box.d.ts +5 -5
  32. package/dist/types/compute-engine/boxed-expression/boxed-function-definition.d.ts +20 -14
  33. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +14 -13
  34. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +8 -10
  35. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +2 -2
  36. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +4 -5
  37. package/dist/types/compute-engine/boxed-expression/boxed-symbol-definition.d.ts +6 -5
  38. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +11 -11
  39. package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +7 -10
  40. package/dist/types/compute-engine/boxed-expression/cache.d.ts +2 -1
  41. package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
  42. package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
  43. package/dist/types/compute-engine/boxed-expression/expand.d.ts +3 -3
  44. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  45. package/dist/types/compute-engine/boxed-expression/factor.d.ts +1 -3
  46. package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
  47. package/dist/types/compute-engine/boxed-expression/hold.d.ts +3 -2
  48. package/dist/types/compute-engine/boxed-expression/match.d.ts +1 -1
  49. package/dist/types/compute-engine/boxed-expression/negate.d.ts +2 -2
  50. package/dist/types/compute-engine/boxed-expression/numerics.d.ts +3 -3
  51. package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
  52. package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
  53. package/dist/types/compute-engine/boxed-expression/product.d.ts +5 -5
  54. package/dist/types/compute-engine/boxed-expression/rules.d.ts +2 -2
  55. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +3 -3
  56. package/dist/types/compute-engine/boxed-expression/sgn.d.ts +1 -1
  57. package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
  58. package/dist/types/compute-engine/boxed-expression/solve.d.ts +1 -2
  59. package/dist/types/compute-engine/boxed-expression/terms.d.ts +2 -2
  60. package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +2 -9
  61. package/dist/types/compute-engine/boxed-expression/utils.d.ts +13 -4
  62. package/dist/types/compute-engine/boxed-expression/validate.d.ts +9 -10
  63. package/dist/types/compute-engine/collection-utils.d.ts +1 -1
  64. package/dist/types/compute-engine/compile.d.ts +2 -4
  65. package/dist/types/compute-engine/cost-function.d.ts +1 -1
  66. package/dist/types/compute-engine/function-utils.d.ts +1 -1
  67. package/dist/types/compute-engine/{boxed-expression/public.d.ts → global-types.d.ts} +887 -849
  68. package/dist/types/compute-engine/{compute-engine.d.ts → index.d.ts} +29 -19
  69. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  70. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  71. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  72. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
  73. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
  74. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
  75. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  76. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  77. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
  78. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  79. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
  80. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  81. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  82. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +2 -2
  83. package/dist/types/compute-engine/latex-syntax/parse-identifier.d.ts +2 -2
  84. package/dist/types/compute-engine/latex-syntax/parse.d.ts +2 -2
  85. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +2 -2
  86. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +2 -2
  87. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +2 -2
  88. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  89. package/dist/types/compute-engine/latex-syntax/{public.d.ts → types.d.ts} +13 -6
  90. package/dist/types/compute-engine/library/arithmetic.d.ts +1 -2
  91. package/dist/types/compute-engine/library/calculus.d.ts +1 -1
  92. package/dist/types/compute-engine/library/collections.d.ts +3 -2
  93. package/dist/types/compute-engine/library/complex.d.ts +1 -1
  94. package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
  95. package/dist/types/compute-engine/library/core.d.ts +1 -1
  96. package/dist/types/compute-engine/library/invisible-operator.d.ts +2 -2
  97. package/dist/types/compute-engine/library/library.d.ts +3 -3
  98. package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
  99. package/dist/types/compute-engine/library/logic.d.ts +1 -1
  100. package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
  101. package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
  102. package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
  103. package/dist/types/compute-engine/library/sets.d.ts +1 -1
  104. package/dist/types/compute-engine/library/statistics.d.ts +1 -1
  105. package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
  106. package/dist/types/compute-engine/library/utils.d.ts +3 -5
  107. package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +3 -4
  108. package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +3 -5
  109. package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +3 -4
  110. package/dist/types/compute-engine/numeric-value/{public.d.ts → types.d.ts} +9 -5
  111. package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
  112. package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
  113. package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
  114. package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
  115. package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
  116. package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
  117. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
  118. package/dist/types/compute-engine/numerics/numeric.d.ts +2 -7
  119. package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
  120. package/dist/types/compute-engine/numerics/rationals.d.ts +1 -5
  121. package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
  122. package/dist/types/compute-engine/numerics/special-functions.d.ts +4 -4
  123. package/dist/types/compute-engine/numerics/statistics.d.ts +2 -2
  124. package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
  125. package/dist/types/compute-engine/numerics/types.d.ts +30 -0
  126. package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
  127. package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
  128. package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
  129. package/dist/types/compute-engine/{boxed-expression → tensor}/tensor-fields.d.ts +19 -18
  130. package/dist/types/compute-engine/tensor/tensors.d.ts +9 -12
  131. package/dist/types/compute-engine/types.d.ts +11 -0
  132. package/dist/types/compute-engine.d.ts +3 -5
  133. package/dist/types/math-json/identifiers.d.ts +1 -1
  134. package/dist/types/math-json/types.d.ts +9 -7
  135. package/dist/types/math-json/utils.d.ts +3 -3
  136. package/dist/types/math-json.d.ts +3 -3
  137. package/package.json +9 -9
  138. package/dist/compute-engine.min.js +0 -142
  139. package/dist/math-json.js +0 -133
  140. package/dist/math-json.min.js +0 -4
  141. package/dist/types/common/buffer.d.ts +0 -9
  142. package/dist/types/common/styled-text.d.ts +0 -28
  143. package/dist/types/common/suggest.d.ts +0 -1
  144. package/dist/types/common/syntax-highlighter.d.ts +0 -40
  145. package/dist/types/common/terminal.d.ts +0 -19
  146. package/dist/types/compute-engine/boxed-expression/arithmetic-divide.d.ts +0 -12
  147. package/dist/types/compute-engine/boxed-expression/arithmetic-multiply.d.ts +0 -16
  148. package/dist/types/compute-engine/debug.d.ts +0 -3
  149. package/dist/types/compute-engine/numerics/bignum.d.ts +0 -12
  150. package/dist/types/compute-engine/private.d.ts +0 -29
  151. package/dist/types/compute-engine/public.d.ts +0 -42
@@ -1,17 +1,61 @@
1
- /* 0.27.0 */
2
- import type { Expression, MathJsonNumber, MathJsonString, MathJsonSymbol, MathJsonFunction, MathJsonIdentifier } from '../../math-json';
3
- import type { SerializeLatexOptions, LatexDictionaryEntry, ParseLatexOptions } from '../latex-syntax/public';
4
- import type { IndexedLatexDictionary } from '../latex-syntax/dictionary/definitions';
5
- import { Rational } from '../numerics/rationals';
6
- import { ExactNumericValueData, NumericValue, NumericValueData } from '../numeric-value/public';
7
- import { BigNum, IBigNum } from '../numerics/bignum';
8
- import { Type, TypeString } from '../../common/type/types';
9
- import { AbstractTensor } from '../tensor/tensors';
10
- import { OneOf } from '../../common/one-of';
11
- import { CompiledType, JSSource } from '../compile';
1
+ /* 0.29.0 */
2
+ import type { OneOf } from '../common/one-of';
3
+ import type { Expression, MathJsonNumber, MathJsonString, MathJsonSymbol, MathJsonFunction, MathJsonIdentifier } from '../math-json';
4
+ import { LatexDictionaryEntry, LatexString, ParseLatexOptions, SerializeLatexOptions } from './latex-syntax/types';
5
+ import { ExactNumericValueData, NumericValue, NumericValueData } from './numeric-value/types';
6
+ import { BigNum, IBigNum, Rational } from './numerics/types';
7
+ import { Type, TypeString } from '../common/type/types';
8
+ import { BoxedType } from '../common/type/boxed-type';
9
+ import { IndexedLatexDictionary } from './latex-syntax/dictionary/definitions';
10
+ /** @category Compiling */
11
+ export type CompiledType = boolean | number | string | object;
12
+ /** @category Compiling */
13
+ export type JSSource = string;
14
+ /** @category Compiling */
15
+ export type CompiledExpression = {
16
+ evaluate?: (scope: {
17
+ [symbol: string]: BoxedExpression;
18
+ }) => number | BoxedExpression;
19
+ };
20
+ /** @category Tensors */
21
+ export type DataTypeMap = {
22
+ float64: number;
23
+ float32: number;
24
+ int32: number;
25
+ uint8: number;
26
+ complex128: Complex;
27
+ complex64: Complex;
28
+ bool: boolean;
29
+ string: string;
30
+ expression: BoxedExpression;
31
+ };
32
+ /** @category Tensors */
33
+ export type TensorDataType = keyof DataTypeMap;
34
+ /** @category Tensors */
35
+ export interface TensorData<DT extends keyof DataTypeMap = 'float64'> {
36
+ dtype: DT;
37
+ shape: number[];
38
+ rank: number;
39
+ data: DataTypeMap[DT][];
40
+ }
12
41
  /**
13
42
  * :::info[THEORY OF OPERATIONS]
14
43
  *
44
+ * The `BoxedExpression` interface includes the methods and properties
45
+ * applicable to any kind of expression, for example `expr.symbol` or
46
+ * `expr.ops`.
47
+ *
48
+ * When a member function is not applicable to this `BoxedExpression`,
49
+ * for example `get symbol()` on a `BoxedNumber`, it returns `null`.
50
+ *
51
+ * This convention makes it convenient to manipulate expressions without
52
+ * having to check what kind of instance they are before manipulating them.
53
+ * :::
54
+ *
55
+ * To get a boxed expression from a LaTeX string use `ce.parse()`, and to
56
+ * get a boxed expression from a MathJSON expression use `ce.box()`.
57
+ *
58
+ *
15
59
  * To create a boxed expression:
16
60
  *
17
61
  * ### `ce.box()` and `ce.parse()`
@@ -108,52 +152,6 @@ import { CompiledType, JSSource } from '../compile';
108
152
  * used directly, for example `canonicalAdd(a, b)` instead of
109
153
  * `ce.function('Add', [a, b])`.
110
154
  *
111
- * :::
112
- */
113
- export type Sign =
114
- /** The expression is equal to 0 */
115
- 'zero'
116
- /** The expression is > 0 */
117
- | 'positive'
118
- /** The expression is < 0 */
119
- | 'negative'
120
- /** The expression is >= 0 and isPositive is either false or undefined*/
121
- | 'non-negative'
122
- /** The expression is <= 0 and isNegative is either false or undefined*/
123
- | 'non-positive'
124
- /** The expression is not equal to 0 (possibly with an imaginary part) and isPositive, isNegative, isUnsigned are all false or undefined */
125
- | 'not-zero'
126
- /** The expression has no imaginary part and a non-zero real part and isPositive and isNegative are false or undefined*/
127
- | 'real-not-zero'
128
- /** The expression has no imaginary part and isNotZero,isPositive,isNegative,isNonNegative,isNonPositive,isZero are either false or undefined*/
129
- | 'real'
130
- /** The expression is NaN */
131
- | 'nan'
132
- /** The expression is +∞ */
133
- | 'positive-infinity'
134
- /** The expression is -∞ */
135
- | 'negative-infinity'
136
- /** The expression is ~∞ */
137
- | 'complex-infinity'
138
- /** The expression has an imaginary part or is NaN */
139
- | 'unsigned';
140
- /**
141
- * :::info[THEORY OF OPERATIONS]
142
- *
143
- * The `BoxedExpression` interface includes most of the member functions
144
- * applicable to any kind of expression, for example `get symbol()` or
145
- * `get ops()`.
146
- *
147
- * When a member function is not applicable to this `BoxedExpression`,
148
- * for example `get symbol()` on a `BoxedNumber`, it returns `null`.
149
- *
150
- * This convention makes it convenient to manipulate expressions without
151
- * having to check what kind of instance they are before manipulating them.
152
- * :::
153
- *
154
- * To get a boxed expression from a LaTeX string use `ce.parse()`, or to
155
- * get a boxed expression from a MathJSON expression use `ce.box()`.
156
- *
157
155
  * @category Boxed Expression
158
156
  *
159
157
  */
@@ -163,7 +161,7 @@ export interface BoxedExpression {
163
161
  * and functions.
164
162
  *
165
163
  */
166
- readonly engine: IComputeEngine;
164
+ readonly engine: ComputeEngine;
167
165
  /** From `Object.valueOf()`, return a primitive value for the expression.
168
166
  *
169
167
  * If the expression is a machine number, or bignum or rational that can be
@@ -288,11 +286,6 @@ export interface BoxedExpression {
288
286
  *
289
287
  */
290
288
  readonly symbol: string | null;
291
- /**
292
- * @category Symbol Expression
293
- *
294
- */
295
- readonly tensor: null | AbstractTensor<'expression'>;
296
289
  /** If this expression is a string, return the value of the string.
297
290
  * Otherwise, return `null`.
298
291
  *
@@ -304,6 +297,7 @@ export interface BoxedExpression {
304
297
  *
305
298
  */
306
299
  readonly string: string | null;
300
+ readonly tensor: null | TensorData<'expression'>;
307
301
  /** All the subexpressions matching the named operator, recursively.
308
302
  *
309
303
  * :::info[Note]
@@ -736,13 +730,13 @@ export interface BoxedExpression {
736
730
  *
737
731
  * Attempts to make `rest` a positive value (i.e. pulls out negative sign).
738
732
  *
739
- * For example:
740
- *
733
+ *```json
741
734
  * ['Multiply', 2, 'x', 3, 'a']
742
735
  * -> [NumericValue(6), ['Multiply', 'x', 'a']]
743
736
  *
744
737
  * ['Divide', ['Multiply', 2, 'x'], ['Multiply', 3, 'y', 'a']]
745
738
  * -> [NumericValue({rational: [2, 3]}), ['Divide', 'x', ['Multiply, 'y', 'a']]]
739
+ * ```
746
740
  */
747
741
  toNumericValue(): [NumericValue, BoxedExpression];
748
742
  neg(): BoxedExpression;
@@ -900,8 +894,9 @@ export interface BoxedExpression {
900
894
  * If the type of this expression is already known, return `false`.
901
895
  *
902
896
  * If the type was not set, set it to the inferred type, return `true`
903
- * If the type was previously inferred, adjust it by widening it,
904
- * return `true`
897
+ * If the type was previously inferred, widen it and return `true`.
898
+ *
899
+ * If the type cannot be inferred, return `false`.
905
900
  *
906
901
  * @internal
907
902
  */
@@ -917,8 +912,8 @@ export interface BoxedExpression {
917
912
  *
918
913
  * Reset the cached value associated with this expression.
919
914
  *
920
- * Use when the environment has changed, for example the numeric mode
921
- * or precision, to force the expression to be re-evaluated.
915
+ * Use when the environment, for example the precision, has changed to
916
+ * force the expression to be re-evaluated.
922
917
  *
923
918
  * @internal
924
919
  */
@@ -936,7 +931,7 @@ export interface BoxedExpression {
936
931
  * integers) are performed but exact calculations may be performed,
937
932
  * for example:
938
933
  *
939
- * \\( \sin(\frac{\pi}{4}) \longrightarrow \frac{\sqrt{2}}{2} \\).
934
+ * $$ \sin(\frac{\pi}{4}) \longrightarrow \frac{\sqrt{2}}{2} $$.
940
935
  *
941
936
  * The result is canonical.
942
937
  *
@@ -974,6 +969,13 @@ export interface BoxedExpression {
974
969
  *
975
970
  */
976
971
  evaluate(options?: Partial<EvaluateOptions>): BoxedExpression;
972
+ /** Asynchronous version of `evaluate()`.
973
+ *
974
+ * The `options` argument can include a `signal` property, which is an
975
+ * `AbortSignal` object. If the signal is aborted, a `CancellationError` is thrown.
976
+ *
977
+ */
978
+ evaluateAsync(options?: Partial<EvaluateOptions>): Promise<BoxedExpression>;
977
979
  /** Return a numeric approximation of the canonical form of this expression.
978
980
  *
979
981
  * Any necessary calculations, including on decimal numbers (non-integers),
@@ -1010,7 +1012,7 @@ export interface BoxedExpression {
1010
1012
  vars?: Record<MathJsonIdentifier, CompiledType>;
1011
1013
  imports?: unknown[];
1012
1014
  preamble?: string;
1013
- }): ((args?: Record<string, CompiledType>) => CompiledType | undefined) | undefined;
1015
+ }): (args?: Record<string, CompiledType>) => CompiledType;
1014
1016
  /**
1015
1017
  * If this is an equation, solve the equation for the variables in vars.
1016
1018
  * Otherwise, solve the equation `this = 0` for the variables in vars.
@@ -1023,7 +1025,7 @@ export interface BoxedExpression {
1023
1025
  *
1024
1026
  *
1025
1027
  */
1026
- solve(vars: Iterable<string> | string | BoxedExpression | Iterable<BoxedExpression>): null | ReadonlyArray<BoxedExpression>;
1028
+ solve(vars?: Iterable<string> | string | BoxedExpression | Iterable<BoxedExpression>): null | ReadonlyArray<BoxedExpression>;
1027
1029
  /**
1028
1030
  * Return a JavaScript primitive representing the value of this expression.
1029
1031
  *
@@ -1065,8 +1067,8 @@ export interface BoxedExpression {
1065
1067
  * :::
1066
1068
  *
1067
1069
  */
1068
- get type(): Type;
1069
- set type(type: Type);
1070
+ get type(): BoxedType;
1071
+ set type(type: Type | TypeString | BoxedType);
1070
1072
  /** `true` if the value of this expression is a number.
1071
1073
  *
1072
1074
  *
@@ -1131,7 +1133,7 @@ export interface BoxedExpression {
1131
1133
  * - `expr.isSame(other)` for a structural comparison
1132
1134
  * - `expr.is(other)` for a comparison of a number literal
1133
1135
  *
1134
- * ## Examples
1136
+ * **Examples**
1135
1137
  *
1136
1138
  * ```js
1137
1139
  * let expr = ce.parse('2 + 2');
@@ -1210,30 +1212,6 @@ export interface BoxedExpression {
1210
1212
  * @category Boxed Expression
1211
1213
  */
1212
1214
  export type SemiBoxedExpression = number | bigint | string | BigNum | MathJsonNumber | MathJsonString | MathJsonSymbol | MathJsonFunction | readonly [MathJsonIdentifier, ...SemiBoxedExpression[]] | BoxedExpression;
1213
- /**
1214
- * @category Definitions
1215
- *
1216
- */
1217
- export interface BoxedBaseDefinition {
1218
- name: string;
1219
- wikidata?: string;
1220
- description?: string | string[];
1221
- url?: string;
1222
- /**
1223
- * The scope this definition belongs to.
1224
- *
1225
- * This field is usually undefined, but its value is set by `getDefinition()`
1226
- */
1227
- scope: RuntimeScope | undefined;
1228
- /** If this is the definition of a collection, the set of primitive operations
1229
- * that can be performed on this collection (counting the number of elements,
1230
- * enumerating it, etc...). */
1231
- collection?: Partial<CollectionHandlers>;
1232
- /** When the environment changes, for example the numerical precision,
1233
- * call `reset()` so that any cached values can be recalculated.
1234
- */
1235
- reset(): void;
1236
- }
1237
1215
  /**
1238
1216
  * These handlers compare two expressions.
1239
1217
  *
@@ -1244,267 +1222,403 @@ export interface BoxedBaseDefinition {
1244
1222
  * @category Definitions
1245
1223
  *
1246
1224
  */
1247
- export type EqHandlers = {
1225
+ export interface EqHandlers {
1248
1226
  eq: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1249
1227
  neq: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1250
- };
1228
+ }
1229
+ /** @category Definitions */
1230
+ export type Hold = 'none' | 'all' | 'first' | 'rest' | 'last' | 'most';
1251
1231
  /**
1252
- * These handlers are the primitive operations that can be performed on
1253
- * collections.
1254
- *
1255
- * There are two types of collections:
1256
- *
1257
- * - finite collections, such as lists, tuples, sets, matrices, etc...
1258
- * The `size()` handler of finite collections returns the number of elements
1259
- *
1260
- * - infinite collections, such as sequences, ranges, etc...
1261
- * The `size()` handler of infinite collections returns `Infinity`
1262
- * Infinite collections are not indexable: they have no `at()` handler.
1232
+ * Options to control the serialization to MathJSON when using `BoxedExpression.toMathJson()`.
1263
1233
  *
1264
- * @category Definitions
1234
+ * @category Serialization
1265
1235
  */
1266
- export type CollectionHandlers = {
1267
- /** Return the number of elements in the collection.
1236
+ export type JsonSerializationOptions = {
1237
+ /** If true, the serialization applies some transformations to make
1238
+ * the JSON more readable. For example, `["Power", "x", 2]` is serialized
1239
+ * as `["Square", "x"]`.
1240
+ */
1241
+ prettify: boolean;
1242
+ /** A list of space separated function names that should be excluded from
1243
+ * the JSON output.
1268
1244
  *
1269
- * An empty collection has a size of 0.
1245
+ * Those functions are replaced with an equivalent, for example, `Square` with
1246
+ * `Power`, etc...
1247
+ *
1248
+ * Possible values include `Sqrt`, `Root`, `Square`, `Exp`, `Subtract`,
1249
+ * `Rational`, `Complex`
1250
+ *
1251
+ * **Default**: `[]` (none)
1270
1252
  */
1271
- size: (collection: BoxedExpression) => number;
1272
- /**
1273
- * Return `true` if the target
1274
- * expression is in the collection, `false` otherwise.
1253
+ exclude: string[];
1254
+ /** A list of space separated keywords indicating which MathJSON expressions
1255
+ * can use a shorthand.
1256
+ *
1257
+ * **Default**: `["all"]`
1275
1258
  */
1276
- contains: (collection: BoxedExpression, target: BoxedExpression) => boolean;
1277
- /** Return an iterator
1278
- * - start is optional and is a 1-based index.
1279
- * - if start is not specified, start from index 1
1280
- * - count is optional and is the number of elements to return
1281
- * - if count is not specified or negative, return all the elements from
1282
- * start to the end
1259
+ shorthands: ('all' | 'number' | 'symbol' | 'function' | 'string')[];
1260
+ /** A list of space separated keywords indicating which metadata should be
1261
+ * included in the MathJSON. If metadata is included, shorthand notation
1262
+ * is not used.
1283
1263
  *
1284
- * If there is a `keys()` handler, there is no `iterator()` handler.
1264
+ * **Default**: `[]` (none)
1265
+ */
1266
+ metadata: ('all' | 'wikidata' | 'latex')[];
1267
+ /** If true, repeating decimals are detected and serialized accordingly
1268
+ * For example:
1269
+ * - `1.3333333333333333` \( \to \) `1.(3)`
1270
+ * - `0.142857142857142857142857142857142857142857142857142` \( \to \) `0.(1428571)`
1285
1271
  *
1286
- * @category Definitions
1272
+ * **Default**: `true`
1287
1273
  */
1288
- iterator: (collection: BoxedExpression, start?: number, count?: number) => Iterator<BoxedExpression, undefined>;
1274
+ repeatingDecimal: boolean;
1289
1275
  /**
1290
- * Return the element at the specified index.
1291
- *
1292
- * The first element is `at(1)`, the last element is `at(-1)`.
1276
+ * The maximum number of significant digits in serialized numbers.
1277
+ * - `"max"`: all availabe digits are serialized.
1278
+ * - `"auto"`: use the same precision as the compute engine.
1293
1279
  *
1294
- * If the index is &lt;0, return the element at index `size() + index + 1`.
1280
+ * **Default**: `"auto"`
1281
+ */
1282
+ fractionalDigits: 'auto' | 'max' | number;
1283
+ };
1284
+ /**
1285
+ * Control how a pattern is matched to an expression.
1286
+ *
1287
+ * - `substitution`: if present, assumes these values for the named wildcards,
1288
+ * and ensure that subsequent occurrence of the same wildcard have the same
1289
+ * value.
1290
+ * - `recursive`: if true, match recursively, otherwise match only the top
1291
+ * level.
1292
+ * - `useVariations`: if false, only match expressions that are structurally identical.
1293
+ * If true, match expressions that are structurally identical or equivalent.
1294
+ *
1295
+ * For example, when true, `["Add", '_a', 2]` matches `2`, with a value of
1296
+ * `_a` of `0`. If false, the expression does not match. **Default**: `false`
1297
+ *
1298
+ * @category Pattern Matching
1299
+ *
1300
+ */
1301
+ export type PatternMatchOptions = {
1302
+ substitution?: BoxedSubstitution;
1303
+ recursive?: boolean;
1304
+ useVariations?: boolean;
1305
+ };
1306
+ /**
1307
+ * @category Boxed Expression
1308
+ *
1309
+ */
1310
+ export type ReplaceOptions = {
1311
+ /**
1312
+ * If `true`, apply replacement rules to all sub-expressions.
1295
1313
  *
1296
- * The index can also be a string for example for maps. The set of valid keys
1297
- * is returned by the `keys()` handler.
1314
+ * If `false`, only consider the top-level expression.
1298
1315
  *
1299
- * If the index is invalid, return `undefined`.
1316
+ * **Default**: `false`
1300
1317
  */
1301
- at: (collection: BoxedExpression, index: number | string) => undefined | BoxedExpression;
1318
+ recursive: boolean;
1302
1319
  /**
1303
- * If the collection can be indexed by strings, return the valid values
1304
- * for the index.
1320
+ * If `true`, stop after the first rule that matches.
1321
+ *
1322
+ * If `false`, apply all the remaining rules even after the first match.
1323
+ *
1324
+ * **Default**: `false`
1305
1325
  */
1306
- keys: (collection: BoxedExpression) => undefined | Iterable<string>;
1326
+ once: boolean;
1307
1327
  /**
1308
- * Return the index of the first element that matches the target expression.
1328
+ * If `true` the rule will use some equivalent variations to match.
1309
1329
  *
1310
- * The comparison is done using the `target.isEqual()` method.
1330
+ * For example when `useVariations` is true:
1331
+ * - `x` matches `a + x` with a = 0
1332
+ * - `x` matches `ax` with a = 1
1333
+ * - etc...
1311
1334
  *
1312
- * If the expression is not found, return `undefined`.
1335
+ * Setting this to `true` can save time by condensing multiple rules
1336
+ * into one. This can be particularly useful when describing equations
1337
+ * solutions. However, it can lead to infinite recursion and should be
1338
+ * used with caution.
1313
1339
  *
1314
- * If the expression is found, return the index, 1-based.
1340
+ */
1341
+ useVariations: boolean;
1342
+ /**
1343
+ * If `iterationLimit` > 1, the rules will be repeatedly applied
1344
+ * until no rules apply, up to `maxIterations` times.
1315
1345
  *
1316
- * Return the index of the first match.
1346
+ * Note that if `once` is true, `iterationLimit` has no effect.
1317
1347
  *
1318
- * `from` is the starting index for the search. If negative, start from
1319
- * the end and search backwards.
1348
+ * **Default**: `1`
1320
1349
  */
1321
- indexOf: (collection: BoxedExpression, target: BoxedExpression, from?: number) => number | undefined;
1350
+ iterationLimit: number;
1322
1351
  /**
1323
- * Return `true` if all the elements of `target` are in `expr`.
1324
- * Both `expr` and `target` are collections.
1325
- * If strict is `true`, the subset must be strict, that is, `expr` must
1326
- * have more elements than `target`.
1352
+ * Indicate if the expression should be canonicalized after the replacement.
1353
+ * If not provided, the expression is canonicalized if the expression
1354
+ * that matched the pattern is canonical.
1327
1355
  */
1328
- subsetOf: (collection: BoxedExpression, target: BoxedExpression, strict: boolean) => boolean;
1329
- /** Return the sign of all the elements of the collection. */
1330
- eltsgn: (collection: BoxedExpression) => Sign | undefined;
1331
- /** Return the widest type of all the elements in the collection */
1332
- elttype: (collection: BoxedExpression) => Type | undefined;
1356
+ canonical: CanonicalOptions;
1333
1357
  };
1334
1358
  /**
1335
- * A function definition can have some flags to indicate specific
1336
- * properties of the function.
1359
+ * A bound symbol (i.e. one with an associated definition) has either a type
1360
+ * (e.g. x ∈ ℝ), a value (x = 5) or both (π: value = 3.14... type = 'real')
1337
1361
  * @category Definitions
1338
1362
  */
1339
- export type FunctionDefinitionFlags = {
1363
+ export type SymbolDefinition = BaseDefinition & Partial<SymbolAttributes> & {
1364
+ type?: Type | TypeString;
1365
+ /** If true, the type is inferred, and could be adjusted later
1366
+ * as more information becomes available or if the symbol is explicitly
1367
+ * declared.
1368
+ */
1369
+ inferred?: boolean;
1370
+ /** `value` can be a JS function since for some constants, such as
1371
+ * `Pi`, the actual value depends on the `precision` setting of the
1372
+ * `ComputeEngine` and possible other environment settings */
1373
+ value?: LatexString | SemiBoxedExpression | ((ce: ComputeEngine) => BoxedExpression | null);
1374
+ flags?: Partial<NumericFlags>;
1375
+ eq?: (a: BoxedExpression) => boolean | undefined;
1376
+ neq?: (a: BoxedExpression) => boolean | undefined;
1377
+ cmp?: (a: BoxedExpression) => '=' | '>' | '<' | undefined;
1378
+ collection?: Partial<CollectionHandlers>;
1379
+ };
1380
+ /**
1381
+ * Definition record for a function.
1382
+ * @category Definitions
1383
+ *
1384
+ */
1385
+ export type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlags> & {
1340
1386
  /**
1341
- * If `true`, the arguments to this function are not automatically
1342
- * evaluated. The default is `false` (the arguments are evaluated).
1387
+ * The function signature.
1343
1388
  *
1344
- * This can be useful for example for functions that take symbolic
1345
- * expressions as arguments, such as `D` or `Integrate`.
1389
+ * If a `type` handler is provided, the return type of the function should
1390
+ * be a subtype of the return type in the signature.
1346
1391
  *
1347
- * This is also useful for functions that take an argument that is
1348
- * potentially an infinite collection.
1392
+ */
1393
+ signature?: Type | TypeString;
1394
+ /**
1395
+ * The actual type of the result based on the arguments.
1349
1396
  *
1350
- * It will be up to the `evaluate()` handler to evaluate the arguments as
1351
- * needed. This is conveninent to pass symbolic expressions as arguments
1352
- * to functions without having to explicitly use a `Hold` expression.
1397
+ * Should be a subtype of the type indicated in the signature.
1353
1398
  *
1354
- * This also applies to the `canonical()` handler.
1399
+ * Do not evaluate the arguments.
1355
1400
  *
1356
- */
1357
- lazy: boolean;
1358
- /** If `true`, the function is applied element by element to lists, matrices
1359
- * (`["List"]` or `["Tuple"]` expressions) and equations (relational
1360
- * operators).
1401
+ * The type of the arguments can be used to determine the type of the
1402
+ * result.
1361
1403
  *
1362
- * **Default**: `false`
1363
1404
  */
1364
- threadable: boolean;
1365
- /** If `true`, `["f", ["f", a], b]` simplifies to `["f", a, b]`
1405
+ type?: (ops: ReadonlyArray<BoxedExpression>, options: {
1406
+ engine: ComputeEngine;
1407
+ }) => Type | TypeString | BoxedType | undefined;
1408
+ /** Return the sign of the function expression.
1366
1409
  *
1367
- * **Default**: `false`
1368
- */
1369
- associative: boolean;
1370
- /** If `true`, `["f", a, b]` equals `["f", b, a]`. The canonical
1371
- * version of the function will order the arguments.
1410
+ * If the sign cannot be determined, return `undefined`.
1411
+ *
1412
+ * When determining the sign, only literal values and the values of
1413
+ * symbols, if they are literals, should be considered.
1414
+ *
1415
+ * Do not evaluate the arguments.
1416
+ *
1417
+ * The type and sign of the arguments can be used to determine the sign.
1372
1418
  *
1373
- * **Default**: `false`
1374
1419
  */
1375
- commutative: boolean;
1420
+ sgn?: (ops: ReadonlyArray<BoxedExpression>, options: {
1421
+ engine: ComputeEngine;
1422
+ }) => Sign | undefined;
1423
+ /** Return true of the function expression is even, false if it is odd and
1424
+ * undefined if it is neither.
1425
+ */
1426
+ even?: (ops: ReadonlyArray<BoxedExpression>, options: {
1427
+ engine: ComputeEngine;
1428
+ }) => boolean | undefined;
1376
1429
  /**
1377
- * If `commutative` is `true`, the order of the arguments is determined by
1378
- * this function.
1430
+ * A number used to order arguments.
1379
1431
  *
1380
- * If the function is not provided, the arguments are ordered by the
1381
- * default order of the arguments.
1432
+ * Argument with higher complexity are placed after arguments with
1433
+ * lower complexity when ordered canonically in commutative functions.
1434
+ *
1435
+ * - Additive functions: 1000-1999
1436
+ * - Multiplicative functions: 2000-2999
1437
+ * - Root and power functions: 3000-3999
1438
+ * - Log functions: 4000-4999
1439
+ * - Trigonometric functions: 5000-5999
1440
+ * - Hypertrigonometric functions: 6000-6999
1441
+ * - Special functions (factorial, Gamma, ...): 7000-7999
1442
+ * - Collections: 8000-8999
1443
+ * - Inert and styling: 9000-9999
1444
+ * - Logic: 10000-10999
1445
+ * - Relational: 11000-11999
1382
1446
  *
1447
+ * **Default**: 100,000
1383
1448
  */
1384
- commutativeOrder: ((a: BoxedExpression, b: BoxedExpression) => number) | undefined;
1385
- /** If `true`, when the function is univariate, `["f", ["Multiply", x, c]]`
1386
- * simplifies to `["Multiply", ["f", x], c]` where `c` is constant
1449
+ complexity?: number;
1450
+ /**
1451
+ * Return the canonical form of the expression with the arguments `args`.
1387
1452
  *
1388
- * When the function is multivariate, multiplicativity is considered only on
1389
- * the first argument: `["f", ["Multiply", x, y], z]` simplifies to
1390
- * `["Multiply", ["f", x, z], ["f", y, z]]`
1453
+ * The arguments (`args`) may not be in canonical form. If necessary, they
1454
+ * can be put in canonical form.
1391
1455
  *
1392
- * Default: `false`
1393
- */
1394
- /** If `true`, `["f", ["f", x]]` simplifies to `["f", x]`.
1456
+ * This handler should validate the type and number of the arguments.
1395
1457
  *
1396
- * **Default**: `false`
1397
- */
1398
- idempotent: boolean;
1399
- /** If `true`, `["f", ["f", x]]` simplifies to `x`.
1458
+ * If a required argument is missing, it should be indicated with a
1459
+ * `["Error", "'missing"]` expression. If more arguments than expected
1460
+ * are present, this should be indicated with an
1461
+ * ["Error", "'unexpected-argument'"]` error expression
1400
1462
  *
1401
- * **Default**: `false`
1402
- */
1403
- involution: boolean;
1404
- /** If `true`, the value of this function is always the same for a given
1405
- * set of arguments and it has no side effects.
1463
+ * If the type of an argument is not compatible, it should be indicated
1464
+ * with an `incompatible-type` error.
1406
1465
  *
1407
- * An expression using this function is pure if the function and all its
1408
- * arguments are pure.
1466
+ * `["Sequence"]` expressions are not folded and need to be handled
1467
+ * explicitly.
1409
1468
  *
1410
- * For example `Sin` is pure, `Random` isn't.
1469
+ * If the function is associative, idempotent or an involution,
1470
+ * this handler should account for it. Notably, if it is commutative, the
1471
+ * arguments should be sorted in canonical order.
1411
1472
  *
1412
- * This information may be used to cache the value of expressions.
1413
1473
  *
1414
- * **Default:** `true`
1415
- */
1416
- pure: boolean;
1417
- };
1418
- /** @category Compiling */
1419
- export type CompiledExpression = {
1420
- evaluate?: (scope: {
1421
- [symbol: string]: BoxedExpression;
1422
- }) => number | BoxedExpression;
1423
- };
1424
- /** @category Definitions */
1425
- export type Hold = 'none' | 'all' | 'first' | 'rest' | 'last' | 'most';
1426
- /**
1427
- * @category Definitions
1428
- *
1429
- */
1430
- export type BoxedFunctionDefinition = BoxedBaseDefinition & FunctionDefinitionFlags & {
1431
- complexity: number;
1432
- /** If true, the signature was inferred from usage and may be modified
1433
- * as more information becomes available.
1434
- */
1435
- inferredSignature: boolean;
1436
- /** The type of the arguments and return value of this function */
1437
- signature: Type;
1438
- /** If present, this handler can be used to more precisely determine the
1439
- * return type based on the type of the arguments. The arguments themselves
1440
- * should *not* be evaluated, only their types should be used.
1441
- */
1442
- type?: (ops: ReadonlyArray<BoxedExpression>, options: {
1443
- engine: IComputeEngine;
1444
- }) => Type | TypeString | undefined;
1445
- /** If present, this handler can be used to determine the sign of the
1446
- * return value of the function, based on the sign and type of its
1447
- * arguments.
1474
+ * Values of symbols should not be substituted, unless they have
1475
+ * a `holdUntil` attribute of `"never"`.
1448
1476
  *
1449
- * The arguments themselves should *not* be evaluated, only their types and
1450
- * sign should be used.
1477
+ * The handler should not consider the value or any assumptions about any
1478
+ * of the arguments that are symbols or functions (i.e. `arg.isZero`,
1479
+ * `arg.isInteger`, etc...) since those may change over time.
1480
+ *
1481
+ * The result of the handler should be a canonical expression.
1482
+ *
1483
+ * If the arguments do not match, they should be replaced with an appropriate
1484
+ * `["Error"]` expression. If the expression cannot be put in canonical form,
1485
+ * the handler should return `null`.
1451
1486
  *
1452
- * This can be used in some case for example to determine when certain
1453
- * simplifications are valid.
1454
1487
  */
1455
- sgn?: (ops: ReadonlyArray<BoxedExpression>, options: {
1456
- engine: IComputeEngine;
1457
- }) => Sign | undefined;
1458
- eq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1459
- neq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1460
1488
  canonical?: (ops: ReadonlyArray<BoxedExpression>, options: {
1461
- engine: IComputeEngine;
1489
+ engine: ComputeEngine;
1462
1490
  }) => BoxedExpression | null;
1463
- evaluate?: (ops: ReadonlyArray<BoxedExpression>, options: Partial<EvaluateOptions> & {
1464
- engine?: IComputeEngine;
1465
- }) => BoxedExpression | undefined;
1466
- evalDimension?: (ops: ReadonlyArray<BoxedExpression>, options: {
1467
- engine: IComputeEngine;
1491
+ /**
1492
+ * Evaluate a function expression.
1493
+ *
1494
+ * The arguments have been evaluated, except the arguments to which a
1495
+ * `hold` applied.
1496
+ *
1497
+ * It is not necessary to further simplify or evaluate the arguments.
1498
+ *
1499
+ * If performing numerical calculations and `options.numericalApproximation`
1500
+ * is `false` return an exact numeric value, for example return a rational
1501
+ * number or a square root, rather than a floating point approximation.
1502
+ * Use `ce.number()` to create the numeric value.
1503
+ *
1504
+ * When `numericalApproximation` is `false`, return a floating point number:
1505
+ * - do not reduce rational numbers to decimal (floating point approximation)
1506
+ * - do not reduce square roots of rational numbers
1507
+ *
1508
+ * If the expression cannot be evaluated, due to the values, types, or
1509
+ * assumptions about its arguments, for example, return `undefined` or
1510
+ * an `["Error"]` expression.
1511
+ */
1512
+ evaluate?: ((ops: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
1513
+ engine: ComputeEngine;
1514
+ }) => BoxedExpression | undefined) | BoxedExpression;
1515
+ /**
1516
+ * An option asynchronous version of `evaluate`.
1517
+ *
1518
+ */
1519
+ evaluateAsync?: (ops: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
1520
+ engine: ComputeEngine;
1521
+ }) => Promise<BoxedExpression | undefined>;
1522
+ /** Dimensional analysis
1523
+ * @experimental
1524
+ */
1525
+ evalDimension?: (args: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
1526
+ engine: ComputeEngine;
1468
1527
  }) => BoxedExpression;
1528
+ /** Return a compiled (optimized) expression. */
1469
1529
  compile?: (expr: BoxedExpression) => CompiledExpression;
1530
+ eq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1531
+ neq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1532
+ collection?: Partial<CollectionHandlers>;
1470
1533
  };
1471
1534
  /**
1472
1535
  * @category Definitions
1473
1536
  *
1474
1537
  */
1475
- export type SymbolAttributes = {
1538
+ export type BaseDefinition = {
1539
+ /** A short (about 1 line) description. May contain Markdown. */
1540
+ description?: string | string[];
1541
+ /** A URL pointing to more information about this symbol or operator. */
1542
+ url?: string;
1476
1543
  /**
1477
- * If `true` the value of the symbol is constant. The value or type of
1478
- * symbols with this attribute set to `true` cannot be changed.
1479
- *
1480
- * If `false`, the symbol is a variable.
1544
+ * A short string representing an entry in a wikibase.
1481
1545
  *
1482
- * **Default**: `false`
1546
+ * For example `Q167` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
1547
+ * for the `Pi` constant.
1483
1548
  */
1484
- constant: boolean;
1549
+ wikidata?: string;
1550
+ };
1551
+ /** Options for `BoxedExpression.simplify()`
1552
+ *
1553
+ * @category Boxed Expression
1554
+ */
1555
+ export type SimplifyOptions = {
1485
1556
  /**
1486
- * If the symbol has a value, it is held as indicated in the table below.
1487
- * A green checkmark indicate that the symbol is substituted.
1488
-
1489
- <div className="symbols-table">
1490
-
1491
- | Operation | `"never"` | `"evaluate"` | `"N"` |
1492
- | :--- | :-----: | :----: | :---: |
1493
- | `canonical()` | (X) | | |
1494
- | `evaluate()` | (X) | (X) | |
1495
- | `"N()"` | (X) | (X) | (X) |
1496
-
1497
- </div>
1498
-
1499
- * Some examples:
1500
- * - `ImaginaryUnit` has `holdUntil: 'never'`: it is substituted during canonicalization
1501
- * - `x` has `holdUntil: 'evaluate'` (variables)
1502
- * - `Pi` has `holdUntil: 'N'` (special numeric constant)
1503
- *
1504
- * **Default:** `evaluate`
1505
- */
1506
- holdUntil: 'never' | 'evaluate' | 'N';
1557
+ * The set of rules to apply. If `null`, use no rules. If not provided,
1558
+ * use the default simplification rules.
1559
+ */
1560
+ rules?: null | Rule | ReadonlyArray<BoxedRule | Rule> | BoxedRuleSet;
1561
+ /**
1562
+ * Use this cost function to determine if a simplification is worth it.
1563
+ *
1564
+ * If not provided, `ce.costFunction`, the cost function of the engine is
1565
+ * used.
1566
+ */
1567
+ costFunction?: (expr: BoxedExpression) => number;
1507
1568
  };
1569
+ /**
1570
+ * A table mapping identifiers to their definition.
1571
+ *
1572
+ * Identifiers should be valid MathJSON identifiers. In addition, the
1573
+ * following rules are recommended:
1574
+ *
1575
+ * - Use only latin letters, digits and `-`: `/[a-zA-Z0-9-]+/`
1576
+ * - The first character should be a letter: `/^[a-zA-Z]/`
1577
+ * - Functions and symbols exported from a library should start with an uppercase letter `/^[A-Z]/`
1578
+ *
1579
+ * @category Definitions
1580
+ *
1581
+ */
1582
+ export type IdentifierDefinition = OneOf<[
1583
+ SymbolDefinition,
1584
+ FunctionDefinition,
1585
+ SemiBoxedExpression
1586
+ ]>;
1587
+ /**
1588
+ * @category Definitions
1589
+ *
1590
+ */
1591
+ export type IdentifierDefinitions = Readonly<{
1592
+ [id: string]: IdentifierDefinition;
1593
+ }>;
1594
+ /** @category Numerics */
1595
+ export type Sign =
1596
+ /** The expression is equal to 0 */
1597
+ 'zero'
1598
+ /** The expression is > 0 */
1599
+ | 'positive'
1600
+ /** The expression is < 0 */
1601
+ | 'negative'
1602
+ /** The expression is >= 0 and isPositive is either false or undefined*/
1603
+ | 'non-negative'
1604
+ /** The expression is <= 0 and isNegative is either false or undefined*/
1605
+ | 'non-positive'
1606
+ /** The expression is not equal to 0 (possibly with an imaginary part) and isPositive, isNegative, isUnsigned are all false or undefined */
1607
+ | 'not-zero'
1608
+ /** The expression has no imaginary part and a non-zero real part and isPositive and isNegative are false or undefined*/
1609
+ | 'real-not-zero'
1610
+ /** The expression has no imaginary part and isNotZero,isPositive,isNegative,isNonNegative,isNonPositive,isZero are either false or undefined*/
1611
+ | 'real'
1612
+ /** The expression is NaN */
1613
+ | 'nan'
1614
+ /** The expression is +∞ */
1615
+ | 'positive-infinity'
1616
+ /** The expression is -∞ */
1617
+ | 'negative-infinity'
1618
+ /** The expression is ~∞ */
1619
+ | 'complex-infinity'
1620
+ /** The expression has an imaginary part or is NaN */
1621
+ | 'unsigned';
1508
1622
  /**
1509
1623
  * When used in a `SymbolDefinition` or `Functiondefinition` these flags
1510
1624
  * provide additional information about the value of the symbol or function.
@@ -1520,7 +1634,150 @@ export type NumericFlags = {
1520
1634
  odd: boolean | undefined;
1521
1635
  };
1522
1636
  /**
1523
- * @noInheritDoc
1637
+ * These handlers are the primitive operations that can be performed on
1638
+ * collections.
1639
+ *
1640
+ * There are two types of collections:
1641
+ *
1642
+ * - finite collections, such as lists, tuples, sets, matrices, etc...
1643
+ * The `size()` handler of finite collections returns the number of elements
1644
+ *
1645
+ * - infinite collections, such as sequences, ranges, etc...
1646
+ * The `size()` handler of infinite collections returns `Infinity`
1647
+ * Infinite collections are not indexable: they have no `at()` handler.
1648
+ *
1649
+ * @category Definitions
1650
+ */
1651
+ export type CollectionHandlers = {
1652
+ /** Return the number of elements in the collection.
1653
+ *
1654
+ * An empty collection has a size of 0.
1655
+ */
1656
+ size: (collection: BoxedExpression) => number;
1657
+ /**
1658
+ * Return `true` if the target
1659
+ * expression is in the collection, `false` otherwise.
1660
+ */
1661
+ contains: (collection: BoxedExpression, target: BoxedExpression) => boolean;
1662
+ /** Return an iterator
1663
+ * - start is optional and is a 1-based index.
1664
+ * - if start is not specified, start from index 1
1665
+ * - count is optional and is the number of elements to return
1666
+ * - if count is not specified or negative, return all the elements from
1667
+ * start to the end
1668
+ *
1669
+ * If there is a `keys()` handler, there is no `iterator()` handler.
1670
+ *
1671
+ * @category Definitions
1672
+ */
1673
+ iterator: (collection: BoxedExpression, start?: number, count?: number) => Iterator<BoxedExpression, undefined>;
1674
+ /**
1675
+ * Return the element at the specified index.
1676
+ *
1677
+ * The first element is `at(1)`, the last element is `at(-1)`.
1678
+ *
1679
+ * If the index is &lt;0, return the element at index `size() + index + 1`.
1680
+ *
1681
+ * The index can also be a string for example for maps. The set of valid keys
1682
+ * is returned by the `keys()` handler.
1683
+ *
1684
+ * If the index is invalid, return `undefined`.
1685
+ */
1686
+ at: (collection: BoxedExpression, index: number | string) => undefined | BoxedExpression;
1687
+ /**
1688
+ * If the collection can be indexed by strings, return the valid values
1689
+ * for the index.
1690
+ */
1691
+ keys: (collection: BoxedExpression) => undefined | Iterable<string>;
1692
+ /**
1693
+ * Return the index of the first element that matches the target expression.
1694
+ *
1695
+ * The comparison is done using the `target.isEqual()` method.
1696
+ *
1697
+ * If the expression is not found, return `undefined`.
1698
+ *
1699
+ * If the expression is found, return the index, 1-based.
1700
+ *
1701
+ * Return the index of the first match.
1702
+ *
1703
+ * `from` is the starting index for the search. If negative, start from
1704
+ * the end and search backwards.
1705
+ */
1706
+ indexOf: (collection: BoxedExpression, target: BoxedExpression, from?: number) => number | undefined;
1707
+ /**
1708
+ * Return `true` if all the elements of `target` are in `expr`.
1709
+ * Both `expr` and `target` are collections.
1710
+ * If strict is `true`, the subset must be strict, that is, `expr` must
1711
+ * have more elements than `target`.
1712
+ */
1713
+ subsetOf: (collection: BoxedExpression, target: BoxedExpression, strict: boolean) => boolean;
1714
+ /** Return the sign of all the elements of the collection. */
1715
+ eltsgn: (collection: BoxedExpression) => Sign | undefined;
1716
+ /** Return the widest type of all the elements in the collection */
1717
+ elttype: (collection: BoxedExpression) => Type | undefined;
1718
+ };
1719
+ /**
1720
+ * @category Definitions
1721
+ *
1722
+ */
1723
+ export interface BoxedBaseDefinition {
1724
+ name: string;
1725
+ wikidata?: string;
1726
+ description?: string | string[];
1727
+ url?: string;
1728
+ /**
1729
+ * The scope this definition belongs to.
1730
+ *
1731
+ * This field is usually undefined, but its value is set by `getDefinition()`
1732
+ */
1733
+ scope: RuntimeScope | undefined;
1734
+ /** If this is the definition of a collection, the set of primitive operations
1735
+ * that can be performed on this collection (counting the number of elements,
1736
+ * enumerating it, etc...). */
1737
+ collection?: Partial<CollectionHandlers>;
1738
+ /** When the environment changes, for example the numerical precision,
1739
+ * call `reset()` so that any cached values can be recalculated.
1740
+ */
1741
+ reset(): void;
1742
+ }
1743
+ /**
1744
+ * @category Definitions
1745
+ *
1746
+ */
1747
+ export type SymbolAttributes = {
1748
+ /**
1749
+ * If `true` the value of the symbol is constant. The value or type of
1750
+ * symbols with this attribute set to `true` cannot be changed.
1751
+ *
1752
+ * If `false`, the symbol is a variable.
1753
+ *
1754
+ * **Default**: `false`
1755
+ */
1756
+ constant: boolean;
1757
+ /**
1758
+ * If the symbol has a value, it is held as indicated in the table below.
1759
+ * A green checkmark indicate that the symbol is substituted.
1760
+
1761
+ <div className="symbols-table">
1762
+
1763
+ | Operation | `"never"` | `"evaluate"` | `"N"` |
1764
+ | :--- | :-----: | :----: | :---: |
1765
+ | `canonical()` | (X) | | |
1766
+ | `evaluate()` | (X) | (X) | |
1767
+ | `"N()"` | (X) | (X) | (X) |
1768
+
1769
+ </div>
1770
+
1771
+ * Some examples:
1772
+ * - `ImaginaryUnit` has `holdUntil: 'never'`: it is substituted during canonicalization
1773
+ * - `x` has `holdUntil: 'evaluate'` (variables)
1774
+ * - `Pi` has `holdUntil: 'N'` (special numeric constant)
1775
+ *
1776
+ * **Default:** `evaluate`
1777
+ */
1778
+ holdUntil: 'never' | 'evaluate' | 'N';
1779
+ };
1780
+ /**
1524
1781
  * @category Definitions
1525
1782
  */
1526
1783
  export interface BoxedSymbolDefinition extends BoxedBaseDefinition, SymbolAttributes, Partial<NumericFlags> {
@@ -1532,115 +1789,204 @@ export interface BoxedSymbolDefinition extends BoxedBaseDefinition, SymbolAttrib
1532
1789
  neq?: (a: BoxedExpression) => boolean | undefined;
1533
1790
  cmp?: (a: BoxedExpression) => '=' | '>' | '<' | undefined;
1534
1791
  inferredType: boolean;
1535
- type: Type;
1792
+ type: BoxedType;
1536
1793
  }
1537
1794
  /**
1538
- * Given an expression and set of wildcards, return a new expression.
1539
- *
1540
- * For example:
1541
- *
1542
- * ```ts
1543
- * {
1544
- * match: '_x',
1545
- * replace: (expr, {_x}) => { return ['Add', 1, _x] }
1546
- * }
1547
- * ```
1548
- *
1549
- * @category Rules */
1550
- export type RuleReplaceFunction = (expr: BoxedExpression, wildcards: BoxedSubstitution) => BoxedExpression | undefined;
1551
- /** @category Rules */
1552
- export type RuleConditionFunction = (wildcards: BoxedSubstitution, ce: IComputeEngine) => boolean;
1553
- /** @category Rules */
1554
- export type RuleFunction = (expr: BoxedExpression) => undefined | BoxedExpression | RuleStep;
1555
- export declare function isRuleStep(x: any): x is RuleStep;
1556
- /**
1557
- * A rule describes how to modify an expressions that matches a pattern `match`
1558
- * into a new expression `replace`.
1559
- *
1560
- * - `x-1` \( \to \) `1-x`
1561
- * - `(x+1)(x-1)` \( \to \) `x^2-1
1562
- *
1563
- * The patterns can be expressed as LaTeX strings or a MathJSON expressions.
1795
+ * A scope is a set of names in a dictionary that are bound (defined) in
1796
+ * a MathJSON expression.
1564
1797
  *
1565
- * As a shortcut, a rule can be defined as a LaTeX string: `x-1 -> 1-x`.
1566
- * The expression to the left of `->` is the `match` and the expression to the
1567
- * right is the `replace`. When using LaTeX strings, single character variables
1568
- * are assumed to be wildcards.
1798
+ * Scopes are arranged in a stack structure. When an expression that defined
1799
+ * a new scope is evaluated, the new scope is added to the scope stack.
1800
+ * Outside of the expression, the scope is removed from the scope stack.
1569
1801
  *
1570
- * When using MathJSON expressions, anonymous wildcards (`_`) will match any
1571
- * expression. Named wildcards (`_x`, `_a`, etc...) will match any expression
1572
- * and bind the expression to the wildcard name.
1802
+ * The scope stack is used to resolve symbols, and it is possible for
1803
+ * a scope to 'mask' definitions from previous scopes.
1573
1804
  *
1574
- * In addition the sequence wildcard (`__1`, `__a`, etc...) will match
1575
- * a sequence of one or more expressions, and bind the sequence to the
1576
- * wildcard name.
1805
+ * Scopes are lexical (also called a static scope): they are defined based on
1806
+ * where they are in an expression, they are not determined at runtime.
1577
1807
  *
1578
- * Sequence wildcards are useful when the number of elements in the sequence
1579
- * is not known in advance. For example, in a sum, the number of terms is
1580
- * not known in advance. ["Add", 0, `__a`] will match two or more terms and
1581
- * the `__a` wildcard will be a sequence of the matchign terms.
1808
+ * @category Compute Engine
1809
+ */
1810
+ export type Scope = Record<string, any>;
1811
+ /** Options for `BoxedExpression.evaluate()`
1582
1812
  *
1583
- * If `exact` is false, the rule will match variants.
1584
- *
1585
- * For example 'x' will match 'a + x', 'x' will match 'ax', etc...
1586
- *
1587
- * For simplification rules, you generally want `exact` to be true, but
1588
- * to solve equations, you want it to be false. Default to true.
1589
- *
1590
- * When set to false, infinite recursion is possible.
1591
- *
1592
- * @category Rules
1813
+ * @category Boxed Expression
1593
1814
  */
1594
- export type Rule = string | RuleFunction | {
1595
- match?: LatexString | SemiBoxedExpression | Pattern;
1596
- replace: LatexString | SemiBoxedExpression | RuleReplaceFunction | RuleFunction;
1597
- condition?: LatexString | RuleConditionFunction;
1598
- useVariations?: boolean;
1599
- id?: string;
1815
+ export type EvaluateOptions = {
1816
+ numericApproximation: boolean;
1817
+ signal: AbortSignal;
1600
1818
  };
1601
1819
  /**
1602
- *
1603
- * If the `match` property is `undefined`, all expressions match this rule
1604
- * and `condition` should also be `undefined`. The `replace` property should
1605
- * be a `BoxedExpression` or a `RuleFunction`, and further filtering can be
1606
- * done in the `replace` function.
1607
- *
1608
- * @category Rules */
1609
- export type BoxedRule = {
1610
- /** @internal */
1611
- readonly _tag: 'boxed-rule';
1612
- match: undefined | Pattern;
1613
- replace: BoxedExpression | RuleReplaceFunction | RuleFunction;
1614
- condition: undefined | RuleConditionFunction;
1615
- useVariations?: boolean;
1616
- id?: string;
1617
- };
1618
- export declare function isBoxedRule(x: any): x is BoxedRule;
1619
- export type RuleStep = {
1620
- value: BoxedExpression;
1621
- because: string;
1820
+ * A function definition can have some flags to indicate specific
1821
+ * properties of the function.
1822
+ * @category Definitions
1823
+ */
1824
+ export type FunctionDefinitionFlags = {
1825
+ /**
1826
+ * If `true`, the arguments to this function are not automatically
1827
+ * evaluated. The default is `false` (the arguments are evaluated).
1828
+ *
1829
+ * This can be useful for example for functions that take symbolic
1830
+ * expressions as arguments, such as `D` or `Integrate`.
1831
+ *
1832
+ * This is also useful for functions that take an argument that is
1833
+ * potentially an infinite collection.
1834
+ *
1835
+ * It will be up to the `evaluate()` handler to evaluate the arguments as
1836
+ * needed. This is conveninent to pass symbolic expressions as arguments
1837
+ * to functions without having to explicitly use a `Hold` expression.
1838
+ *
1839
+ * This also applies to the `canonical()` handler.
1840
+ *
1841
+ */
1842
+ lazy: boolean;
1843
+ /** If `true`, the function is applied element by element to lists, matrices
1844
+ * (`["List"]` or `["Tuple"]` expressions) and equations (relational
1845
+ * operators).
1846
+ *
1847
+ * **Default**: `false`
1848
+ */
1849
+ threadable: boolean;
1850
+ /** If `true`, `["f", ["f", a], b]` simplifies to `["f", a, b]`
1851
+ *
1852
+ * **Default**: `false`
1853
+ */
1854
+ associative: boolean;
1855
+ /** If `true`, `["f", a, b]` equals `["f", b, a]`. The canonical
1856
+ * version of the function will order the arguments.
1857
+ *
1858
+ * **Default**: `false`
1859
+ */
1860
+ commutative: boolean;
1861
+ /**
1862
+ * If `commutative` is `true`, the order of the arguments is determined by
1863
+ * this function.
1864
+ *
1865
+ * If the function is not provided, the arguments are ordered by the
1866
+ * default order of the arguments.
1867
+ *
1868
+ */
1869
+ commutativeOrder: ((a: BoxedExpression, b: BoxedExpression) => number) | undefined;
1870
+ /** If `true`, when the function is univariate, `["f", ["Multiply", x, c]]`
1871
+ * simplifies to `["Multiply", ["f", x], c]` where `c` is constant
1872
+ *
1873
+ * When the function is multivariate, multiplicativity is considered only on
1874
+ * the first argument: `["f", ["Multiply", x, y], z]` simplifies to
1875
+ * `["Multiply", ["f", x, z], ["f", y, z]]`
1876
+ *
1877
+ * Default: `false`
1878
+ */
1879
+ /** If `true`, `["f", ["f", x]]` simplifies to `["f", x]`.
1880
+ *
1881
+ * **Default**: `false`
1882
+ */
1883
+ idempotent: boolean;
1884
+ /** If `true`, `["f", ["f", x]]` simplifies to `x`.
1885
+ *
1886
+ * **Default**: `false`
1887
+ */
1888
+ involution: boolean;
1889
+ /** If `true`, the value of this function is always the same for a given
1890
+ * set of arguments and it has no side effects.
1891
+ *
1892
+ * An expression using this function is pure if the function and all its
1893
+ * arguments are pure.
1894
+ *
1895
+ * For example `Sin` is pure, `Random` isn't.
1896
+ *
1897
+ * This information may be used to cache the value of expressions.
1898
+ *
1899
+ * **Default:** `true`
1900
+ */
1901
+ pure: boolean;
1622
1902
  };
1623
- export type RuleSteps = RuleStep[];
1624
1903
  /**
1625
- * To create a BoxedRuleSet use the `ce.rules()` method.
1626
- *
1627
- * Do not create a `BoxedRuleSet` directly.
1904
+ * @category Definitions
1628
1905
  *
1629
- * @category Rules */
1630
- export type BoxedRuleSet = {
1631
- rules: ReadonlyArray<BoxedRule>;
1906
+ */
1907
+ export type BoxedFunctionDefinition = BoxedBaseDefinition & FunctionDefinitionFlags & {
1908
+ complexity: number;
1909
+ /** If true, the signature was inferred from usage and may be modified
1910
+ * as more information becomes available.
1911
+ */
1912
+ inferredSignature: boolean;
1913
+ /** The type of the arguments and return value of this function */
1914
+ signature: BoxedType;
1915
+ /** If present, this handler can be used to more precisely determine the
1916
+ * return type based on the type of the arguments. The arguments themselves
1917
+ * should *not* be evaluated, only their types should be used.
1918
+ */
1919
+ type?: (ops: ReadonlyArray<BoxedExpression>, options: {
1920
+ engine: ComputeEngine;
1921
+ }) => Type | TypeString | BoxedType | undefined;
1922
+ /** If present, this handler can be used to determine the sign of the
1923
+ * return value of the function, based on the sign and type of its
1924
+ * arguments.
1925
+ *
1926
+ * The arguments themselves should *not* be evaluated, only their types and
1927
+ * sign should be used.
1928
+ *
1929
+ * This can be used in some case for example to determine when certain
1930
+ * simplifications are valid.
1931
+ */
1932
+ sgn?: (ops: ReadonlyArray<BoxedExpression>, options: {
1933
+ engine: ComputeEngine;
1934
+ }) => Sign | undefined;
1935
+ eq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1936
+ neq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
1937
+ canonical?: (ops: ReadonlyArray<BoxedExpression>, options: {
1938
+ engine: ComputeEngine;
1939
+ }) => BoxedExpression | null;
1940
+ evaluate?: (ops: ReadonlyArray<BoxedExpression>, options: Partial<EvaluateOptions> & {
1941
+ engine?: ComputeEngine;
1942
+ }) => BoxedExpression | undefined;
1943
+ evaluateAsync?: (ops: ReadonlyArray<BoxedExpression>, options?: Partial<EvaluateOptions> & {
1944
+ engine?: ComputeEngine;
1945
+ }) => Promise<BoxedExpression | undefined>;
1946
+ evalDimension?: (ops: ReadonlyArray<BoxedExpression>, options: {
1947
+ engine: ComputeEngine;
1948
+ }) => BoxedExpression;
1949
+ compile?: (expr: BoxedExpression) => CompiledExpression;
1632
1950
  };
1633
1951
  /**
1634
- * @noInheritDoc
1952
+ * The entries have been validated and optimized for faster evaluation.
1635
1953
  *
1636
- * @category Pattern Matching
1954
+ * When a new scope is created with `pushScope()` or when creating a new
1955
+ * engine instance, new instances of this type are created as needed.
1956
+ *
1957
+ * @category Definitions
1637
1958
  */
1638
- export type Pattern = BoxedExpression;
1959
+ export type RuntimeIdentifierDefinitions = Map<string, OneOf<[BoxedSymbolDefinition, BoxedFunctionDefinition]>>;
1960
+ /** @category Assumptions */
1961
+ export interface ExpressionMapInterface<U> {
1962
+ has(expr: BoxedExpression): boolean;
1963
+ get(expr: BoxedExpression): U | undefined;
1964
+ set(expr: BoxedExpression, value: U): void;
1965
+ delete(expr: BoxedExpression): void;
1966
+ clear(): void;
1967
+ [Symbol.iterator](): IterableIterator<[BoxedExpression, U]>;
1968
+ entries(): IterableIterator<[BoxedExpression, U]>;
1969
+ }
1970
+ /** @category Assumptions */
1971
+ export type AssumeResult = 'internal-error' | 'not-a-predicate' | 'contradiction' | 'tautology' | 'ok';
1639
1972
  /**
1640
- * @category Boxed Expression
1973
+ * When a unitless value is passed to or returned from a trigonometric function,
1974
+ * the angular unit of the value.
1975
+ *
1976
+ * - `rad`: radians, 2π radians is a full circle
1977
+ * - `deg`: degrees, 360 degrees is a full circle
1978
+ * - `grad`: gradians, 400 gradians is a full circle
1979
+ * - `turn`: turns, 1 turn is a full circle
1641
1980
  *
1981
+ * @category Compute Engine
1642
1982
  */
1643
- export type BoxedSubstitution = Substitution<BoxedExpression>;
1983
+ export type AngularUnit = 'rad' | 'deg' | 'grad' | 'turn';
1984
+ /** @category Compute Engine */
1985
+ export type RuntimeScope = Scope & {
1986
+ parentScope?: RuntimeScope;
1987
+ ids?: RuntimeIdentifierDefinitions;
1988
+ assumptions: undefined | ExpressionMapInterface<boolean>;
1989
+ };
1644
1990
  /**
1645
1991
  * When provided, canonical forms are used to put an expression in a
1646
1992
  * "standard" form.
@@ -1667,32 +2013,8 @@ export type BoxedSubstitution = Substitution<BoxedExpression>;
1667
2013
  * @category Boxed Expression
1668
2014
  */
1669
2015
  export type CanonicalForm = 'InvisibleOperator' | 'Number' | 'Multiply' | 'Add' | 'Power' | 'Divide' | 'Flatten' | 'Order';
2016
+ /** @category Boxed Expression */
1670
2017
  export type CanonicalOptions = boolean | CanonicalForm | CanonicalForm[];
1671
- /** Options for `BoxedExpression.simplify()`
1672
- *
1673
- * @category Compute Engine
1674
- */
1675
- export type SimplifyOptions = {
1676
- /**
1677
- * The set of rules to apply. If `null`, use no rules. If not provided,
1678
- * use the default simplification rules.
1679
- */
1680
- rules?: null | Rule | ReadonlyArray<BoxedRule | Rule> | BoxedRuleSet;
1681
- /**
1682
- * Use this cost function to determine if a simplification is worth it.
1683
- *
1684
- * If not provided, `ce.costFunction`, the cost function of the engine is
1685
- * used.
1686
- */
1687
- costFunction?: (expr: BoxedExpression) => number;
1688
- };
1689
- /** Options for `BoxedExpression.evaluate()`
1690
- *
1691
- * @category Boxed Expression
1692
- */
1693
- export type EvaluateOptions = {
1694
- numericApproximation: boolean;
1695
- };
1696
2018
  /**
1697
2019
  * Metadata that can be associated with a `BoxedExpression`
1698
2020
  *
@@ -1703,38 +2025,137 @@ export type Metadata = {
1703
2025
  wikidata?: string | undefined;
1704
2026
  };
1705
2027
  /**
1706
- * When a unitless value is passed to or returned from a trigonometric function,
1707
- * the angular unit of the value.
2028
+ * A substitution describes the values of the wildcards in a pattern so that
2029
+ * the pattern is equal to a target expression.
1708
2030
  *
1709
- * - `rad`: radians, radians is a full circle
1710
- * - `deg`: degrees, 360 degrees is a full circle
1711
- * - `grad`: gradians, 400 gradians is a full circle
1712
- * - `turn`: turns, 1 turn is a full circle
2031
+ * A substitution can also be considered a more constrained version of a
2032
+ * rule whose `match` is always a symbol.
2033
+
2034
+ * @category Pattern Matching
2035
+ */
2036
+ export type Substitution<T = SemiBoxedExpression> = {
2037
+ [symbol: string]: T;
2038
+ };
2039
+ /**
2040
+ * @category Pattern Matching
1713
2041
  *
1714
- * @category Compute Engine
1715
2042
  */
1716
- export type AngularUnit = 'rad' | 'deg' | 'grad' | 'turn';
1717
- /** @category Compute Engine */
1718
- export type ArrayValue = boolean | number | string | BigNum | BoxedExpression | undefined;
1719
- /** @category Assumptions */
1720
- export type AssumeResult = 'internal-error' | 'not-a-predicate' | 'contradiction' | 'tautology' | 'ok';
1721
- /** @category Compute Engine */
1722
- export type AssignValue = boolean | number | string | LatexString | SemiBoxedExpression | ((args: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
1723
- engine: IComputeEngine;
1724
- }) => BoxedExpression) | undefined;
1725
- /** @internal */
1726
- export interface IComputeEngine extends IBigNum {
1727
- latexDictionary: readonly LatexDictionaryEntry[];
1728
- /** @private */
1729
- indexedLatexDictionary: IndexedLatexDictionary;
1730
- decimalSeparator: LatexString;
1731
- readonly True: BoxedExpression;
1732
- readonly False: BoxedExpression;
1733
- readonly Pi: BoxedExpression;
1734
- readonly E: BoxedExpression;
1735
- readonly Nothing: BoxedExpression;
1736
- readonly Zero: BoxedExpression;
1737
- readonly One: BoxedExpression;
2043
+ export type BoxedSubstitution = Substitution<BoxedExpression>;
2044
+ /**
2045
+ * Given an expression and set of wildcards, return a new expression.
2046
+ *
2047
+ * For example:
2048
+ *
2049
+ * ```ts
2050
+ * {
2051
+ * match: '_x',
2052
+ * replace: (expr, {_x}) => { return ['Add', 1, _x] }
2053
+ * }
2054
+ * ```
2055
+ *
2056
+ * @category Rules */
2057
+ export type RuleReplaceFunction = (expr: BoxedExpression, wildcards: BoxedSubstitution) => BoxedExpression | undefined;
2058
+ /** @category Rules */
2059
+ export type RuleConditionFunction = (wildcards: BoxedSubstitution, ce: ComputeEngine) => boolean;
2060
+ /** @category Rules */
2061
+ export type RuleFunction = (expr: BoxedExpression) => undefined | BoxedExpression | RuleStep;
2062
+ /** @category Rules */
2063
+ export type RuleStep = {
2064
+ value: BoxedExpression;
2065
+ because: string;
2066
+ };
2067
+ /** @category Rules */
2068
+ export type RuleSteps = RuleStep[];
2069
+ /**
2070
+ * A rule describes how to modify an expressions that matches a pattern `match`
2071
+ * into a new expression `replace`.
2072
+ *
2073
+ * - `x-1` \( \to \) `1-x`
2074
+ * - `(x+1)(x-1)` \( \to \) `x^2-1
2075
+ *
2076
+ * The patterns can be expressed as LaTeX strings or a MathJSON expressions.
2077
+ *
2078
+ * As a shortcut, a rule can be defined as a LaTeX string: `x-1 -> 1-x`.
2079
+ * The expression to the left of `->` is the `match` and the expression to the
2080
+ * right is the `replace`. When using LaTeX strings, single character variables
2081
+ * are assumed to be wildcards.
2082
+ *
2083
+ * When using MathJSON expressions, anonymous wildcards (`_`) will match any
2084
+ * expression. Named wildcards (`_x`, `_a`, etc...) will match any expression
2085
+ * and bind the expression to the wildcard name.
2086
+ *
2087
+ * In addition the sequence wildcard (`__1`, `__a`, etc...) will match
2088
+ * a sequence of one or more expressions, and bind the sequence to the
2089
+ * wildcard name.
2090
+ *
2091
+ * Sequence wildcards are useful when the number of elements in the sequence
2092
+ * is not known in advance. For example, in a sum, the number of terms is
2093
+ * not known in advance. ["Add", 0, `__a`] will match two or more terms and
2094
+ * the `__a` wildcard will be a sequence of the matchign terms.
2095
+ *
2096
+ * If `exact` is false, the rule will match variants.
2097
+ *
2098
+ * For example 'x' will match 'a + x', 'x' will match 'ax', etc...
2099
+ *
2100
+ * For simplification rules, you generally want `exact` to be true, but
2101
+ * to solve equations, you want it to be false. Default to true.
2102
+ *
2103
+ * When set to false, infinite recursion is possible.
2104
+ *
2105
+ * @category Rules
2106
+ */
2107
+ export type Rule = string | RuleFunction | {
2108
+ match?: LatexString | SemiBoxedExpression | BoxedExpression;
2109
+ replace: LatexString | SemiBoxedExpression | RuleReplaceFunction | RuleFunction;
2110
+ condition?: LatexString | RuleConditionFunction;
2111
+ useVariations?: boolean;
2112
+ id?: string;
2113
+ };
2114
+ /**
2115
+ *
2116
+ * If the `match` property is `undefined`, all expressions match this rule
2117
+ * and `condition` should also be `undefined`. The `replace` property should
2118
+ * be a `BoxedExpression` or a `RuleFunction`, and further filtering can be
2119
+ * done in the `replace` function.
2120
+ *
2121
+ * @category Rules
2122
+ */
2123
+ export type BoxedRule = {
2124
+ /** @internal */
2125
+ readonly _tag: 'boxed-rule';
2126
+ match: undefined | BoxedExpression;
2127
+ replace: BoxedExpression | RuleReplaceFunction | RuleFunction;
2128
+ condition: undefined | RuleConditionFunction;
2129
+ useVariations?: boolean;
2130
+ id?: string;
2131
+ };
2132
+ /**
2133
+ * To create a BoxedRuleSet use the `ce.rules()` method.
2134
+ *
2135
+ * Do not create a `BoxedRuleSet` directly.
2136
+ *
2137
+ * @category Rules
2138
+ */
2139
+ export type BoxedRuleSet = {
2140
+ rules: ReadonlyArray<BoxedRule>;
2141
+ };
2142
+ /** @category Compute Engine */
2143
+ export type AssignValue = boolean | number | SemiBoxedExpression | ((args: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
2144
+ engine: ComputeEngine;
2145
+ }) => BoxedExpression) | undefined;
2146
+ /** @internal */
2147
+ export interface ComputeEngine extends IBigNum {
2148
+ latexDictionary: readonly LatexDictionaryEntry[];
2149
+ /** @private */
2150
+ indexedLatexDictionary: IndexedLatexDictionary;
2151
+ decimalSeparator: LatexString;
2152
+ readonly True: BoxedExpression;
2153
+ readonly False: BoxedExpression;
2154
+ readonly Pi: BoxedExpression;
2155
+ readonly E: BoxedExpression;
2156
+ readonly Nothing: BoxedExpression;
2157
+ readonly Zero: BoxedExpression;
2158
+ readonly One: BoxedExpression;
1738
2159
  readonly Half: BoxedExpression;
1739
2160
  readonly NegativeOne: BoxedExpression;
1740
2161
  readonly I: BoxedExpression;
@@ -1761,14 +2182,30 @@ export interface IComputeEngine extends IBigNum {
1761
2182
  /** Absolute time beyond which evaluation should not proceed
1762
2183
  * @internal
1763
2184
  */
1764
- deadline?: number;
2185
+ _deadline?: number;
2186
+ /** Time remaining before _deadline */
2187
+ _timeRemaining: number;
2188
+ /** @private */
1765
2189
  generation: number;
1766
- /** @hidden */
1767
- readonly timeLimit: number;
1768
- /** @hidden */
1769
- readonly iterationLimit: number;
1770
- /** @hidden */
1771
- readonly recursionLimit: number;
2190
+ /** Throw a `CancellationError` when the duration of an evaluation exceeds
2191
+ * the time limit.
2192
+ *
2193
+ * Time in milliseconds, default 2000 ms = 2 seconds.
2194
+ *
2195
+ */
2196
+ timeLimit: number;
2197
+ /** Throw `CancellationError` `iteration-limit-exceeded` when the iteration limit
2198
+ * in a loop is exceeded. Default: no limits.
2199
+ *
2200
+ * @experimental
2201
+ */
2202
+ iterationLimit: number;
2203
+ /** Signal `recursion-depth-exceeded` when the recursion depth for this
2204
+ * scope is exceeded.
2205
+ *
2206
+ * @experimental
2207
+ */
2208
+ recursionLimit: number;
1772
2209
  chop(n: number): number;
1773
2210
  chop(n: BigNum): BigNum | 0;
1774
2211
  chop(n: number | BigNum): number | BigNum;
@@ -1809,10 +2246,11 @@ export interface IComputeEngine extends IBigNum {
1809
2246
  }): BoxedExpression;
1810
2247
  string(s: string, metadata?: Metadata): BoxedExpression;
1811
2248
  error(message: string | string[], where?: string): BoxedExpression;
1812
- typeError(expectedType: Type, actualType: undefined | Type, where?: SemiBoxedExpression): BoxedExpression;
2249
+ typeError(expectedType: Type, actualType: undefined | Type | BoxedType, where?: SemiBoxedExpression): BoxedExpression;
1813
2250
  hold(expr: SemiBoxedExpression): BoxedExpression;
1814
2251
  tuple(...elements: ReadonlyArray<number>): BoxedExpression;
1815
2252
  tuple(...elements: ReadonlyArray<BoxedExpression>): BoxedExpression;
2253
+ type(type: Type | TypeString | BoxedType): BoxedType;
1816
2254
  rules(rules: Rule | ReadonlyArray<Rule | BoxedRule> | BoxedRuleSet | undefined | null, options?: {
1817
2255
  canonical?: boolean;
1818
2256
  }): BoxedRuleSet;
@@ -1845,8 +2283,8 @@ export interface IComputeEngine extends IBigNum {
1845
2283
  parse(latex: LatexString | null, options?: Partial<ParseLatexOptions> & {
1846
2284
  canonical?: CanonicalOptions;
1847
2285
  }): BoxedExpression | null;
1848
- pushScope(scope?: Partial<Scope>): IComputeEngine;
1849
- popScope(): IComputeEngine;
2286
+ pushScope(scope?: Partial<Scope>): ComputeEngine;
2287
+ popScope(): ComputeEngine;
1850
2288
  swapScope(scope: RuntimeScope | null): RuntimeScope | null;
1851
2289
  resetContext(): void;
1852
2290
  defineSymbol(name: string, def: SymbolDefinition): BoxedSymbolDefinition;
@@ -1855,18 +2293,18 @@ export interface IComputeEngine extends IBigNum {
1855
2293
  lookupFunction(name: string, scope?: RuntimeScope | null): undefined | BoxedFunctionDefinition;
1856
2294
  assign(ids: {
1857
2295
  [id: string]: AssignValue;
1858
- }): IComputeEngine;
1859
- assign(id: string, value: AssignValue): IComputeEngine;
2296
+ }): ComputeEngine;
2297
+ assign(id: string, value: AssignValue): ComputeEngine;
1860
2298
  assign(arg1: string | {
1861
2299
  [id: string]: AssignValue;
1862
- }, arg2?: AssignValue): IComputeEngine;
2300
+ }, arg2?: AssignValue): ComputeEngine;
1863
2301
  declare(identifiers: {
1864
2302
  [id: string]: Type | TypeString | OneOf<[SymbolDefinition | FunctionDefinition]>;
1865
- }): IComputeEngine;
1866
- declare(id: string, def: Type | TypeString | SymbolDefinition | FunctionDefinition): IComputeEngine;
2303
+ }): ComputeEngine;
2304
+ declare(id: string, def: Type | TypeString | SymbolDefinition | FunctionDefinition): ComputeEngine;
1867
2305
  declare(arg1: string | {
1868
2306
  [id: string]: Type | TypeString | OneOf<[SymbolDefinition | FunctionDefinition]>;
1869
- }, arg2?: Type | OneOf<[SymbolDefinition | FunctionDefinition]>): IComputeEngine;
2307
+ }, arg2?: Type | OneOf<[SymbolDefinition | FunctionDefinition]>): ComputeEngine;
1870
2308
  assume(predicate: BoxedExpression): AssumeResult;
1871
2309
  forget(symbol?: string | string[]): void;
1872
2310
  get assumptions(): ExpressionMapInterface<boolean>;
@@ -1893,403 +2331,3 @@ export interface ComputeEngineStats {
1893
2331
  expressions: null | Set<BoxedExpression>;
1894
2332
  highwaterMark: number;
1895
2333
  }
1896
- /**
1897
- * Options to control the serialization to MathJSON when using `BoxedExpression.toMathJson()`.
1898
- *
1899
- * @category Compute Engine
1900
- */
1901
- export type JsonSerializationOptions = {
1902
- /** If true, the serialization applies some transformations to make
1903
- * the JSON more readable. For example, `["Power", "x", 2]` is serialized
1904
- * as `["Square", "x"]`.
1905
- */
1906
- prettify: boolean;
1907
- /** A list of space separated function names that should be excluded from
1908
- * the JSON output.
1909
- *
1910
- * Those functions are replaced with an equivalent, for example, `Square` with
1911
- * `Power`, etc...
1912
- *
1913
- * Possible values include `Sqrt`, `Root`, `Square`, `Exp`, `Subtract`,
1914
- * `Rational`, `Complex`
1915
- *
1916
- * **Default**: `[]` (none)
1917
- */
1918
- exclude: string[];
1919
- /** A list of space separated keywords indicating which MathJSON expressions
1920
- * can use a shorthand.
1921
- *
1922
- * **Default**: `["all"]`
1923
- */
1924
- shorthands: ('all' | 'number' | 'symbol' | 'function' | 'string')[];
1925
- /** A list of space separated keywords indicating which metadata should be
1926
- * included in the MathJSON. If metadata is included, shorthand notation
1927
- * is not used.
1928
- *
1929
- * **Default**: `[]` (none)
1930
- */
1931
- metadata: ('all' | 'wikidata' | 'latex')[];
1932
- /** If true, repeating decimals are detected and serialized accordingly
1933
- * For example:
1934
- * - `1.3333333333333333` \( \to \) `1.(3)`
1935
- * - `0.142857142857142857142857142857142857142857142857142` \( \to \) `0.(1428571)`
1936
- *
1937
- * **Default**: `true`
1938
- */
1939
- repeatingDecimal: boolean;
1940
- /**
1941
- * The maximum number of significant digits in serialized numbers.
1942
- * - `"max"`: all availabe digits are serialized.
1943
- * - `"auto"`: use the same precision as the compute engine.
1944
- *
1945
- * **Default**: `"auto"`
1946
- */
1947
- fractionalDigits: 'auto' | 'max' | number;
1948
- };
1949
- /** A LaTeX string starts and end with `$`, for example
1950
- * `"$\frac{\pi}{2}$"`.
1951
- *
1952
- * @category Latex Parsing and Serialization
1953
- */
1954
- export type LatexString = string;
1955
- /**
1956
- * Control how a pattern is matched to an expression.
1957
- *
1958
- * - `substitution`: if present, assumes these values for the named wildcards,
1959
- * and ensure that subsequent occurrence of the same wildcard have the same
1960
- * value.
1961
- * - `recursive`: if true, match recursively, otherwise match only the top
1962
- * level.
1963
- * - `exact`: if true, only match expressions that are structurally identical.
1964
- * If false, match expressions that are structurally identical or equivalent.
1965
- *
1966
- * For example, when false, `["Add", '_a', 2]` matches `2`, with a value of
1967
- * `_a` of `0`. If true, the expression does not match. **Default**: `true`
1968
- *
1969
- * @category Pattern Matching
1970
- *
1971
- */
1972
- export type PatternMatchOptions = {
1973
- substitution?: BoxedSubstitution;
1974
- recursive?: boolean;
1975
- useVariations?: boolean;
1976
- };
1977
- /**
1978
- * @category Boxed Expression
1979
- *
1980
- */
1981
- export type ReplaceOptions = {
1982
- /**
1983
- * If `true`, apply replacement rules to all sub-expressions.
1984
- *
1985
- * If `false`, only consider the top-level expression.
1986
- *
1987
- * **Default**: `false`
1988
- */
1989
- recursive: boolean;
1990
- /**
1991
- * If `true`, stop after the first rule that matches.
1992
- *
1993
- * If `false`, apply all the remaining rules even after the first match.
1994
- *
1995
- * **Default**: `false`
1996
- */
1997
- once: boolean;
1998
- /**
1999
- * If `true` the rule will use some equivalent variations to match.
2000
- *
2001
- * For example when `useVariations` is true:
2002
- * - `x` matches `a + x` with a = 0
2003
- * - `x` matches `ax` with a = 1
2004
- * - etc...
2005
- *
2006
- * Setting this to `true` can save time by condensing multiple rules
2007
- * into one. This can be particularly useful when describing equations
2008
- * solutions. However, it can lead to infinite recursion and should be
2009
- * used with caution.
2010
- *
2011
- */
2012
- useVariations: boolean;
2013
- /**
2014
- * If `iterationLimit` > 1, the rules will be repeatedly applied
2015
- * until no rules apply, up to `maxIterations` times.
2016
- *
2017
- * Note that if `once` is true, `iterationLimit` has no effect.
2018
- *
2019
- * **Default**: `1`
2020
- */
2021
- iterationLimit: number;
2022
- /**
2023
- * Indicate if the expression should be canonicalized after the replacement.
2024
- * If not provided, the expression is canonicalized if the expression
2025
- * that matched the pattern is canonical.
2026
- */
2027
- canonical: CanonicalOptions;
2028
- };
2029
- /**
2030
- * A substitution describes the values of the wildcards in a pattern so that
2031
- * the pattern is equal to a target expression.
2032
- *
2033
- * A substitution can also be considered a more constrained version of a
2034
- * rule whose `match` is always a symbol.
2035
-
2036
- * @category Boxed Expression
2037
- */
2038
- export type Substitution<T = SemiBoxedExpression> = {
2039
- [symbol: string]: T;
2040
- };
2041
- /** @category Assumptions */
2042
- export interface ExpressionMapInterface<U> {
2043
- has(expr: BoxedExpression): boolean;
2044
- get(expr: BoxedExpression): U | undefined;
2045
- set(expr: BoxedExpression, value: U): void;
2046
- delete(expr: BoxedExpression): void;
2047
- clear(): void;
2048
- [Symbol.iterator](): IterableIterator<[BoxedExpression, U]>;
2049
- entries(): IterableIterator<[BoxedExpression, U]>;
2050
- }
2051
- /**
2052
- * The entries have been validated and optimized for faster evaluation.
2053
- *
2054
- * When a new scope is created with `pushScope()` or when creating a new
2055
- * engine instance, new instances of this type are created as needed.
2056
- *
2057
- * @category Definitions
2058
- */
2059
- export type RuntimeIdentifierDefinitions = Map<string, OneOf<[BoxedSymbolDefinition, BoxedFunctionDefinition]>>;
2060
- /**
2061
- * A scope is a set of names in a dictionary that are bound (defined) in
2062
- * a MathJSON expression.
2063
- *
2064
- * Scopes are arranged in a stack structure. When an expression that defined
2065
- * a new scope is evaluated, the new scope is added to the scope stack.
2066
- * Outside of the expression, the scope is removed from the scope stack.
2067
- *
2068
- * The scope stack is used to resolve symbols, and it is possible for
2069
- * a scope to 'mask' definitions from previous scopes.
2070
- *
2071
- * Scopes are lexical (also called a static scope): they are defined based on
2072
- * where they are in an expression, they are not determined at runtime.
2073
- *
2074
- * @category Compute Engine
2075
- */
2076
- export type Scope = {
2077
- /** Signal `timeout` when the execution time for this scope is exceeded.
2078
- *
2079
- * Time in seconds, default 2s.
2080
- *
2081
- * @experimental
2082
- */
2083
- timeLimit: number;
2084
- /** Signal `out-of-memory` when the memory usage for this scope is exceeded.
2085
- *
2086
- * Memory is in Megabytes, default: 1Mb.
2087
- *
2088
- * @experimental
2089
- */
2090
- memoryLimit: number;
2091
- /** Signal `recursion-depth-exceeded` when the recursion depth for this
2092
- * scope is exceeded.
2093
- *
2094
- * @experimental
2095
- */
2096
- recursionLimit: number;
2097
- /** Signal `iteration-limit-exceeded` when the iteration limit
2098
- * in a loop is exceeded. Default: no limits.
2099
- *
2100
- * @experimental
2101
- */
2102
- iterationLimit: number;
2103
- };
2104
- /** @category Compute Engine */
2105
- export type RuntimeScope = Scope & {
2106
- parentScope?: RuntimeScope;
2107
- ids?: RuntimeIdentifierDefinitions;
2108
- assumptions: undefined | ExpressionMapInterface<boolean>;
2109
- };
2110
- /**
2111
- * A bound symbol (i.e. one with an associated definition) has either a type
2112
- * (e.g. ∀ x ∈ ℝ), a value (x = 5) or both (π: value = 3.14... type = 'real')
2113
- * @category Definitions
2114
- */
2115
- export type SymbolDefinition = BaseDefinition & Partial<SymbolAttributes> & {
2116
- type?: Type | TypeString;
2117
- /** If true, the type is inferred, and could be adjusted later
2118
- * as more information becomes available or if the symbol is explicitly
2119
- * declared.
2120
- */
2121
- inferred?: boolean;
2122
- /** `value` can be a JS function since for some constants, such as
2123
- * `Pi`, the actual value depends on the `precision` setting of the
2124
- * `ComputeEngine` and possible other environment settings */
2125
- value?: LatexString | SemiBoxedExpression | ((ce: IComputeEngine) => BoxedExpression | null);
2126
- flags?: Partial<NumericFlags>;
2127
- eq?: (a: BoxedExpression) => boolean | undefined;
2128
- neq?: (a: BoxedExpression) => boolean | undefined;
2129
- cmp?: (a: BoxedExpression) => '=' | '>' | '<' | undefined;
2130
- collection?: Partial<CollectionHandlers>;
2131
- };
2132
- /**
2133
- * Definition record for a function.
2134
- * @category Definitions
2135
- *
2136
- */
2137
- export type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlags> & {
2138
- /**
2139
- * The function signature.
2140
- *
2141
- * If a `type` handler is provided, the return type of the function should
2142
- * be a subtype of the return type in the signature.
2143
- *
2144
- */
2145
- signature?: Type | TypeString;
2146
- /**
2147
- * The actual type of the result based on the arguments.
2148
- *
2149
- * Should be a subtype of the type indicated in the signature.
2150
- *
2151
- * Do not evaluate the arguments.
2152
- *
2153
- * The type of the arguments can be used to determine the type of the
2154
- * result.
2155
- *
2156
- */
2157
- type?: (ops: ReadonlyArray<BoxedExpression>, options: {
2158
- engine: IComputeEngine;
2159
- }) => Type | TypeString | undefined;
2160
- /** Return the sign of the function expression.
2161
- *
2162
- * If the sign cannot be determined, return `undefined`.
2163
- *
2164
- * When determining the sign, only literal values and the values of
2165
- * symbols, if they are literals, should be considered.
2166
- *
2167
- * Do not evaluate the arguments.
2168
- *
2169
- * The type and sign of the arguments can be used to determine the sign.
2170
- *
2171
- */
2172
- sgn?: (ops: ReadonlyArray<BoxedExpression>, options: {
2173
- engine: IComputeEngine;
2174
- }) => Sign | undefined;
2175
- /** Return true of the function expression is even, false if it is odd and
2176
- * undefined if it is neither.
2177
- */
2178
- even?: (ops: ReadonlyArray<BoxedExpression>, options: {
2179
- engine: IComputeEngine;
2180
- }) => boolean | undefined;
2181
- /**
2182
- * A number used to order arguments.
2183
- *
2184
- * Argument with higher complexity are placed after arguments with
2185
- * lower complexity when ordered canonically in commutative functions.
2186
- *
2187
- * - Additive functions: 1000-1999
2188
- * - Multiplicative functions: 2000-2999
2189
- * - Root and power functions: 3000-3999
2190
- * - Log functions: 4000-4999
2191
- * - Trigonometric functions: 5000-5999
2192
- * - Hypertrigonometric functions: 6000-6999
2193
- * - Special functions (factorial, Gamma, ...): 7000-7999
2194
- * - Collections: 8000-8999
2195
- * - Inert and styling: 9000-9999
2196
- * - Logic: 10000-10999
2197
- * - Relational: 11000-11999
2198
- *
2199
- * **Default**: 100,000
2200
- */
2201
- complexity?: number;
2202
- /**
2203
- * Return the canonical form of the expression with the arguments `args`.
2204
- *
2205
- * The arguments (`args`) may not be in canonical form. If necessary, they
2206
- * can be put in canonical form.
2207
- *
2208
- * This handler should validate the type and number of the arguments.
2209
- *
2210
- * If a required argument is missing, it should be indicated with a
2211
- * `["Error", "'missing"]` expression. If more arguments than expected
2212
- * are present, this should be indicated with an
2213
- * ["Error", "'unexpected-argument'"]` error expression
2214
- *
2215
- * If the type of an argument is not compatible, it should be indicated
2216
- * with an `incompatible-type` error.
2217
- *
2218
- * `["Sequence"]` expressions are not folded and need to be handled
2219
- * explicitly.
2220
- *
2221
- * If the function is associative, idempotent or an involution,
2222
- * this handler should account for it. Notably, if it is commutative, the
2223
- * arguments should be sorted in canonical order.
2224
- *
2225
- *
2226
- * Values of symbols should not be substituted, unless they have
2227
- * a `holdUntil` attribute of `"never"`.
2228
- *
2229
- * The handler should not consider the value or any assumptions about any
2230
- * of the arguments that are symbols or functions (i.e. `arg.isZero`,
2231
- * `arg.isInteger`, etc...) since those may change over time.
2232
- *
2233
- * The result of the handler should be a canonical expression.
2234
- *
2235
- * If the arguments do not match, they should be replaced with an appropriate
2236
- * `["Error"]` expression. If the expression cannot be put in canonical form,
2237
- * the handler should return `null`.
2238
- *
2239
- */
2240
- canonical?: (ops: ReadonlyArray<BoxedExpression>, options: {
2241
- engine: IComputeEngine;
2242
- }) => BoxedExpression | null;
2243
- /**
2244
- * Evaluate a function expression.
2245
- *
2246
- * The arguments have been evaluated, except the arguments to which a
2247
- * `hold` applied.
2248
- *
2249
- * It is not necessary to further simplify or evaluate the arguments.
2250
- *
2251
- * If performing numerical calculations and `options.numericalApproximation`
2252
- * is `false` return an exact numeric value, for example return a rational
2253
- * number or a square root, rather than a floating point approximation.
2254
- * Use `ce.number()` to create the numeric value.
2255
- *
2256
- * When `numericalApproximation` is `false`, return a floating point number:
2257
- * - do not reduce rational numbers to decimal (floating point approximation)
2258
- * - do not reduce square roots of rational numbers
2259
- *
2260
- * If the expression cannot be evaluated, due to the values, types, or
2261
- * assumptions about its arguments, for example, return `undefined` or
2262
- * an `["Error"]` expression.
2263
- */
2264
- evaluate?: ((ops: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
2265
- engine: IComputeEngine;
2266
- }) => BoxedExpression | undefined) | BoxedExpression;
2267
- /** Dimensional analysis
2268
- * @experimental
2269
- */
2270
- evalDimension?: (args: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
2271
- engine: IComputeEngine;
2272
- }) => BoxedExpression;
2273
- /** Return a compiled (optimized) expression. */
2274
- compile?: (expr: BoxedExpression) => CompiledExpression;
2275
- eq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
2276
- neq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
2277
- collection?: Partial<CollectionHandlers>;
2278
- };
2279
- /**
2280
- * @category Definitions
2281
- *
2282
- */
2283
- export type BaseDefinition = {
2284
- /** A short (about 1 line) description. May contain Markdown. */
2285
- description?: string | string[];
2286
- /** A URL pointing to more information about this symbol or operator. */
2287
- url?: string;
2288
- /**
2289
- * A short string representing an entry in a wikibase.
2290
- *
2291
- * For example `Q167` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
2292
- * for the `Pi` constant.
2293
- */
2294
- wikidata?: string;
2295
- };