@cortex-js/compute-engine 0.29.0 → 0.30.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.
- package/dist/compute-engine.esm.js +28330 -24627
- package/dist/compute-engine.min.esm.js +70 -68
- package/dist/compute-engine.min.umd.js +131 -0
- package/dist/{compute-engine.cjs → compute-engine.umd.js} +28330 -24627
- package/dist/math-json.esm.js +22 -294
- package/dist/math-json.min.esm.js +22 -294
- package/dist/math-json.min.umd.js +4 -0
- package/dist/math-json.umd.js +141 -0
- package/dist/types/common/ansi-codes.d.ts +1 -1
- package/dist/types/common/configuration-change.d.ts +28 -0
- package/dist/types/common/fuzzy-string-match.d.ts +1 -1
- package/dist/types/common/grapheme-splitter.d.ts +1 -1
- package/dist/types/common/interruptible.d.ts +1 -1
- package/dist/types/common/one-of.d.ts +1 -1
- package/dist/types/common/signals.d.ts +1 -1
- package/dist/types/common/type/boxed-type.d.ts +20 -4
- package/dist/types/common/type/parse.d.ts +4 -4
- package/dist/types/common/type/primitive.d.ts +3 -2
- package/dist/types/common/type/serialize.d.ts +1 -1
- package/dist/types/common/type/subtype.d.ts +1 -1
- package/dist/types/common/type/types.d.ts +91 -25
- package/dist/types/common/type/utils.d.ts +2 -1
- package/dist/types/common/utils.d.ts +1 -1
- package/dist/types/compute-engine/assume.d.ts +2 -2
- package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +72 -73
- package/dist/types/compute-engine/boxed-expression/apply.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +2 -2
- package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +19 -1
- package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/box.d.ts +6 -6
- package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +42 -0
- package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +48 -27
- package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +17 -5
- package/dist/types/compute-engine/boxed-expression/{boxed-function-definition.d.ts → boxed-operator-definition.d.ts} +12 -12
- package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +7 -8
- package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +91 -52
- package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +22 -25
- package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +46 -0
- package/dist/types/compute-engine/boxed-expression/cache.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +5 -0
- package/dist/types/compute-engine/boxed-expression/canonical.d.ts +2 -2
- package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expand.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/factor.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/hold.d.ts +2 -2
- package/dist/types/compute-engine/boxed-expression/match.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/negate.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/numerics.d.ts +30 -3
- package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/product.d.ts +2 -2
- package/dist/types/compute-engine/boxed-expression/rules.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/sgn.d.ts +41 -1
- package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/solve.d.ts +3 -1
- package/dist/types/compute-engine/boxed-expression/terms.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/utils.d.ts +23 -23
- package/dist/types/compute-engine/boxed-expression/validate.d.ts +2 -1
- package/dist/types/compute-engine/collection-utils.d.ts +22 -57
- package/dist/types/compute-engine/compile.d.ts +61 -10
- package/dist/types/compute-engine/cost-function.d.ts +1 -1
- package/dist/types/compute-engine/function-utils.d.ts +46 -29
- package/dist/types/compute-engine/global-types.d.ts +1432 -893
- package/dist/types/compute-engine/index.d.ts +154 -124
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +3 -3
- package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +21 -0
- package/dist/types/compute-engine/latex-syntax/parse.d.ts +14 -12
- package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer.d.ts +2 -2
- package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/types.d.ts +51 -39
- package/dist/types/compute-engine/latex-syntax/utils.d.ts +5 -0
- package/dist/types/compute-engine/library/arithmetic.d.ts +2 -2
- package/dist/types/compute-engine/library/calculus.d.ts +2 -2
- package/dist/types/compute-engine/library/collections.d.ts +3 -3
- package/dist/types/compute-engine/library/combinatorics.d.ts +2 -0
- package/dist/types/compute-engine/library/complex.d.ts +2 -2
- package/dist/types/compute-engine/library/control-structures.d.ts +2 -2
- package/dist/types/compute-engine/library/core.d.ts +2 -2
- package/dist/types/compute-engine/library/invisible-operator.d.ts +1 -1
- package/dist/types/compute-engine/library/library.d.ts +5 -5
- package/dist/types/compute-engine/library/linear-algebra.d.ts +2 -2
- package/dist/types/compute-engine/library/logic.d.ts +2 -2
- package/dist/types/compute-engine/library/number-theory.d.ts +2 -0
- package/dist/types/compute-engine/library/polynomials.d.ts +2 -2
- package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
- package/dist/types/compute-engine/library/relational-operator.d.ts +2 -2
- package/dist/types/compute-engine/library/sets.d.ts +2 -2
- package/dist/types/compute-engine/library/statistics.d.ts +2 -2
- package/dist/types/compute-engine/library/trigonometry.d.ts +2 -2
- package/dist/types/compute-engine/library/utils.d.ts +24 -2
- package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +3 -4
- package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +3 -3
- package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +3 -4
- package/dist/types/compute-engine/numeric-value/types.d.ts +7 -5
- package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
- package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
- package/dist/types/compute-engine/numerics/monte-carlo.d.ts +4 -19
- package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric.d.ts +9 -1
- package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
- package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
- package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
- package/dist/types/compute-engine/numerics/special-functions.d.ts +1 -1
- package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
- package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
- package/dist/types/compute-engine/numerics/types.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/antiderivative.d.ts +3 -0
- package/dist/types/compute-engine/symbolic/derivative.d.ts +2 -4
- package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensor-fields.d.ts +5 -46
- package/dist/types/compute-engine/tensor/tensors.d.ts +4 -14
- package/dist/types/compute-engine/types.d.ts +2 -5
- package/dist/types/compute-engine.d.ts +1 -1
- package/dist/types/math-json/symbols.d.ts +11 -0
- package/dist/types/math-json/types.d.ts +19 -11
- package/dist/types/math-json/utils.d.ts +18 -9
- package/dist/types/math-json.d.ts +2 -2
- package/package.json +9 -11
- package/dist/compute-engine.min.cjs +0 -129
- package/dist/math-json.cjs +0 -413
- package/dist/math-json.min.cjs +0 -6
- package/dist/types/common/json5.d.ts +0 -3
- package/dist/types/compute-engine/boxed-expression/boxed-symbol-definition.d.ts +0 -64
- package/dist/types/compute-engine/latex-syntax/parse-identifier.d.ts +0 -21
- package/dist/types/math-json/identifiers.d.ts +0 -11
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
/* 0.
|
|
1
|
+
/* 0.30.0 */
|
|
2
2
|
import type { OneOf } from '../common/one-of';
|
|
3
|
-
import type { Expression,
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
3
|
+
import type { Expression, MathJsonNumberObject, MathJsonStringObject, MathJsonFunctionObject, MathJsonSymbolObject, MathJsonSymbol, MathJsonDictionaryObject } from '../math-json';
|
|
4
|
+
import type { Type, TypeReference, TypeResolver, TypeString } from '../common/type/types';
|
|
5
|
+
import type { BoxedType } from '../common/type/boxed-type';
|
|
6
|
+
import type { ConfigurationChangeListener } from '../common/configuration-change';
|
|
7
|
+
import type { ExactNumericValueData, NumericValue, NumericValueData } from './numeric-value/types';
|
|
8
|
+
import type { BigNum, IBigNum, Rational } from './numerics/types';
|
|
9
|
+
import type { LatexDictionaryEntry, LatexString, ParseLatexOptions, SerializeLatexOptions } from './latex-syntax/types';
|
|
10
|
+
import type { IndexedLatexDictionary } from './latex-syntax/dictionary/definitions';
|
|
10
11
|
/** @category Compiling */
|
|
11
12
|
export type CompiledType = boolean | number | string | object;
|
|
12
13
|
/** @category Compiling */
|
|
@@ -17,7 +18,10 @@ export type CompiledExpression = {
|
|
|
17
18
|
[symbol: string]: BoxedExpression;
|
|
18
19
|
}) => number | BoxedExpression;
|
|
19
20
|
};
|
|
20
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Map of `TensorDataType` to JavaScript type.
|
|
23
|
+
*
|
|
24
|
+
* @category Tensors */
|
|
21
25
|
export type DataTypeMap = {
|
|
22
26
|
float64: number;
|
|
23
27
|
float32: number;
|
|
@@ -26,199 +30,373 @@ export type DataTypeMap = {
|
|
|
26
30
|
complex128: Complex;
|
|
27
31
|
complex64: Complex;
|
|
28
32
|
bool: boolean;
|
|
29
|
-
string: string;
|
|
30
33
|
expression: BoxedExpression;
|
|
31
34
|
};
|
|
32
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* The type of the cells in a tensor.
|
|
37
|
+
* @category Tensors */
|
|
33
38
|
export type TensorDataType = keyof DataTypeMap;
|
|
39
|
+
/** @internal */
|
|
40
|
+
export type NestedArray<T> = NestedArray_<T>[];
|
|
41
|
+
/** @internal */
|
|
42
|
+
export type NestedArray_<T> = T | NestedArray_<T>[];
|
|
43
|
+
/**
|
|
44
|
+
* A record representing the type, shape and data of a tensor.
|
|
45
|
+
* @category Tensors */
|
|
46
|
+
export interface TensorData<DT extends TensorDataType> {
|
|
47
|
+
dtype: DT;
|
|
48
|
+
shape: number[];
|
|
49
|
+
rank?: number;
|
|
50
|
+
data: DataTypeMap[DT][];
|
|
51
|
+
}
|
|
34
52
|
/** @category Tensors */
|
|
35
|
-
export interface
|
|
53
|
+
export interface TensorField<T extends number | Complex | BoxedExpression | boolean | string = number> {
|
|
54
|
+
readonly one: T;
|
|
55
|
+
readonly zero: T;
|
|
56
|
+
readonly nan: T;
|
|
57
|
+
cast(x: T, dtype: 'float64'): undefined | number;
|
|
58
|
+
cast(x: T, dtype: 'float32'): undefined | number;
|
|
59
|
+
cast(x: T, dtype: 'int32'): undefined | number;
|
|
60
|
+
cast(x: T, dtype: 'uint8'): undefined | number;
|
|
61
|
+
cast(x: T, dtype: 'complex128'): undefined | Complex;
|
|
62
|
+
cast(x: T, dtype: 'complex64'): undefined | Complex;
|
|
63
|
+
cast(x: T, dtype: 'bool'): undefined | boolean;
|
|
64
|
+
cast(x: T, dtype: 'expression'): undefined | BoxedExpression;
|
|
65
|
+
cast(x: T[], dtype: 'float64'): undefined | number[];
|
|
66
|
+
cast(x: T[], dtype: 'float32'): undefined | number[];
|
|
67
|
+
cast(x: T[], dtype: 'int32'): undefined | number[];
|
|
68
|
+
cast(x: T[], dtype: 'uint8'): undefined | number[];
|
|
69
|
+
cast(x: T[], dtype: 'complex128'): undefined | Complex[];
|
|
70
|
+
cast(x: T[], dtype: 'complex64'): undefined | Complex[];
|
|
71
|
+
cast(x: T[], dtype: 'bool'): undefined | boolean[];
|
|
72
|
+
cast(x: T[], dtype: 'expression'): undefined | BoxedExpression[];
|
|
73
|
+
cast(x: T | T[], dtype: TensorDataType): undefined | Complex | number | boolean | BoxedExpression | Complex[] | number[] | boolean[] | BoxedExpression[];
|
|
74
|
+
expression(x: T): BoxedExpression;
|
|
75
|
+
isZero(x: T): boolean;
|
|
76
|
+
isOne(x: T): boolean;
|
|
77
|
+
equals(lhs: T, rhs: T): boolean;
|
|
78
|
+
add(lhs: T, rhs: T): T;
|
|
79
|
+
addn(...xs: T[]): T;
|
|
80
|
+
neg(x: T): T;
|
|
81
|
+
sub(lhs: T, rhs: T): T;
|
|
82
|
+
mul(lhs: T, rhs: T): T;
|
|
83
|
+
muln(...xs: T[]): T;
|
|
84
|
+
div(lhs: T, rhs: T): T;
|
|
85
|
+
pow(rhs: T, n: number): T;
|
|
86
|
+
conjugate(x: T): T;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* @category Tensors
|
|
90
|
+
*/
|
|
91
|
+
export interface Tensor<DT extends TensorDataType> extends TensorData<DT> {
|
|
36
92
|
dtype: DT;
|
|
37
93
|
shape: number[];
|
|
38
94
|
rank: number;
|
|
39
95
|
data: DataTypeMap[DT][];
|
|
96
|
+
readonly field: TensorField<DT>;
|
|
97
|
+
readonly expression: BoxedExpression;
|
|
98
|
+
readonly array: NestedArray<DataTypeMap[DT]>;
|
|
99
|
+
readonly isSquare: boolean;
|
|
100
|
+
readonly isSymmetric: boolean;
|
|
101
|
+
readonly isSkewSymmetric: boolean;
|
|
102
|
+
readonly isDiagonal: boolean;
|
|
103
|
+
readonly isUpperTriangular: boolean;
|
|
104
|
+
readonly isLowerTriangular: boolean;
|
|
105
|
+
readonly isTriangular: boolean;
|
|
106
|
+
readonly isIdentity: boolean;
|
|
107
|
+
readonly isZero: boolean;
|
|
108
|
+
at(...indices: number[]): DataTypeMap[DT] | undefined;
|
|
109
|
+
diagonal(axis1?: number, axis2?: number): undefined | DataTypeMap[DT][];
|
|
110
|
+
trace(axis1?: number, axis2?: number): undefined | DataTypeMap[DT];
|
|
111
|
+
reshape(...shape: number[]): Tensor<DT>;
|
|
112
|
+
slice(index: number): Tensor<DT>;
|
|
113
|
+
flatten(): DataTypeMap[DT][];
|
|
114
|
+
upcast<DT extends TensorDataType>(dtype: DT): Tensor<DT>;
|
|
115
|
+
transpose(axis1?: number, axis2?: number): undefined | Tensor<DT>;
|
|
116
|
+
conjugateTranspose(axis1?: number, axis2?: number): undefined | Tensor<DT>;
|
|
117
|
+
determinant(): undefined | DataTypeMap[DT];
|
|
118
|
+
inverse(): undefined | Tensor<DT>;
|
|
119
|
+
pseudoInverse(): undefined | Tensor<DT>;
|
|
120
|
+
adjugateMatrix(): undefined | Tensor<DT>;
|
|
121
|
+
minor(axis1: number, axis2: number): undefined | DataTypeMap[DT];
|
|
122
|
+
map1(fn: (lhs: DataTypeMap[DT], rhs: DataTypeMap[DT]) => DataTypeMap[DT], scalar: DataTypeMap[DT]): Tensor<DT>;
|
|
123
|
+
map2(fn: (lhs: DataTypeMap[DT], rhs: DataTypeMap[DT]) => DataTypeMap[DT], rhs: Tensor<DT>): Tensor<DT>;
|
|
124
|
+
add(other: Tensor<DT> | DataTypeMap[DT]): Tensor<DT>;
|
|
125
|
+
subtract(other: Tensor<DT> | DataTypeMap[DT]): Tensor<DT>;
|
|
126
|
+
multiply(other: Tensor<DT> | DataTypeMap[DT]): Tensor<DT>;
|
|
127
|
+
divide(other: Tensor<DT> | DataTypeMap[DT]): Tensor<DT>;
|
|
128
|
+
power(other: Tensor<DT> | DataTypeMap[DT]): Tensor<DT>;
|
|
129
|
+
equals(other: Tensor<DT>): boolean;
|
|
40
130
|
}
|
|
41
131
|
/**
|
|
42
132
|
* :::info[THEORY OF OPERATIONS]
|
|
43
133
|
*
|
|
44
134
|
* The `BoxedExpression` interface includes the methods and properties
|
|
45
|
-
* applicable to
|
|
46
|
-
* `expr.ops
|
|
135
|
+
* applicable to all kinds of expression. For example it includes `expr.symbol`
|
|
136
|
+
* which only applies to symbols or `expr.ops` which only applies to
|
|
137
|
+
* function expressions.
|
|
47
138
|
*
|
|
48
|
-
* When a
|
|
49
|
-
*
|
|
139
|
+
* When a property is not applicable to this `BoxedExpression` its value is
|
|
140
|
+
* `null`. For example `expr.symbol` for a `BoxedNumber` is `null`.
|
|
50
141
|
*
|
|
51
142
|
* This convention makes it convenient to manipulate expressions without
|
|
52
143
|
* having to check what kind of instance they are before manipulating them.
|
|
53
144
|
* :::
|
|
54
145
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
146
|
+
* :::info[THEORY OF OPERATIONS]
|
|
147
|
+
* A boxed expression can represent a canonical or a non-canonical
|
|
148
|
+
* expression. A non-canonical expression is a "raw" form of the
|
|
149
|
+
* expression. For example, the non-canonical representation of `\frac{10}{20}`
|
|
150
|
+
* is `["Divide", 10, 20]`. The canonical representation of the same
|
|
151
|
+
* expression is the boxed number `1/2`.
|
|
152
|
+
*
|
|
153
|
+
* The canonical representation of symbols and function expressions are
|
|
154
|
+
* bound to a definition. The definition contains metadata about the symbol
|
|
155
|
+
* or function operator, such as its type, its signature, and other attributes.
|
|
156
|
+
* The value of symbols are tracked in a separate table for each
|
|
157
|
+
* evaluation context.
|
|
158
|
+
*
|
|
159
|
+
* The binding only occurs when the expression is constructed, if it is created
|
|
160
|
+
* as a canonical expression. If the expression is constructed as a
|
|
161
|
+
* non-canonical expression, no binding is done.
|
|
162
|
+
*
|
|
163
|
+
* <!--
|
|
164
|
+
* Rules:
|
|
165
|
+
* - nothing should cause the binding to occur outside of the constructor
|
|
166
|
+
* - if an operation require a canonical expression (e.g. evaluate()),
|
|
167
|
+
* it should return undefined or throw an error if the expression is not
|
|
168
|
+
* canonical
|
|
169
|
+
* -->
|
|
170
|
+
*
|
|
171
|
+
*
|
|
172
|
+
* :::
|
|
173
|
+
*
|
|
174
|
+
* :::info[THEORY OF OPERATIONS]
|
|
175
|
+
* The **value** of an expression is a number, a string, a boolean or a tensor.
|
|
176
|
+
*
|
|
177
|
+
* The value of number literals and strings are themselves.
|
|
178
|
+
*
|
|
179
|
+
* A symbol can have a value associated with it, in which case the value
|
|
180
|
+
* of the symbol is the value associated with it.
|
|
181
|
+
*
|
|
182
|
+
* Some symbols (unknowns) are purely symbolic and have no value associated
|
|
183
|
+
* with them.
|
|
57
184
|
*
|
|
185
|
+
* Function expressions do not have a value associated with them.
|
|
186
|
+
* For example, `["Add", 2, 3]` has no value associated with it, it is a
|
|
187
|
+
* symbolic expression.
|
|
188
|
+
*
|
|
189
|
+
* Some properties of a Boxed Expression are only applicable if the expression
|
|
190
|
+
* has a value associated with it. For example, `expr.isNumber` is only
|
|
191
|
+
* applicable if the value of the expression is a number, that is if the
|
|
192
|
+
* expression is a number literal or a symbol with a numeric value.
|
|
193
|
+
*
|
|
194
|
+
* The following properties are applicable to expressions with a value:
|
|
195
|
+
* - `expr.isNumber`
|
|
196
|
+
* :::
|
|
58
197
|
*
|
|
59
198
|
* To create a boxed expression:
|
|
60
199
|
*
|
|
61
200
|
* ### `ce.box()` and `ce.parse()`
|
|
62
201
|
*
|
|
63
|
-
* Use `ce.box()` or `ce.parse()
|
|
202
|
+
* Use `ce.box()` or `ce.parse()`.
|
|
203
|
+
*
|
|
204
|
+
* Use `ce.parse()` to get a boxed expression from a LaTeX string.
|
|
205
|
+
* Use `ce.box()` to get a boxed expression from a MathJSON expression.
|
|
206
|
+
*
|
|
207
|
+
* By default, the result of these methods is a canonical expression. For
|
|
208
|
+
* example, if it is a rational literal, it is reduced to its canonical form.
|
|
209
|
+
* If it is a function expression:
|
|
64
210
|
* - the arguments are put in canonical form
|
|
211
|
+
* - the arguments of commutative functions are sorted
|
|
65
212
|
* - invisible operators are made explicit
|
|
66
213
|
* - a limited number of core simplifications are applied,
|
|
67
|
-
* for example
|
|
214
|
+
* for example rationals are reduced
|
|
68
215
|
* - sequences are flattened: `["Add", 1, ["Sequence", 2, 3]]` is
|
|
69
216
|
* transformed to `["Add", 1, 2, 3]`
|
|
70
217
|
* - associative functions are flattened: `["Add", 1, ["Add", 2, 3]]` is
|
|
71
218
|
* transformed to `["Add", 1, 2, 3]`
|
|
72
|
-
* -
|
|
73
|
-
*
|
|
219
|
+
* - symbols are **not** replaced with their values (unless they have
|
|
220
|
+
* a `holdUntil` flag set to `never`).
|
|
74
221
|
*
|
|
75
|
-
* ###
|
|
222
|
+
* ### `ce.function()`
|
|
76
223
|
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
224
|
+
* This is a specialized version of `ce.box()` for creating a new function
|
|
225
|
+
* expression.
|
|
226
|
+
*
|
|
227
|
+
* The canonical handler of the operator is called.
|
|
228
|
+
*
|
|
229
|
+
*
|
|
230
|
+
* ### Algebraic methods (`expr.add()`, `expr.mul()`, etc...)
|
|
231
|
+
*
|
|
232
|
+
* The boxed expression have some algebraic methods, i.e. `add()`, `mul()`,
|
|
233
|
+
* `div()`, `pow()`, etc. These methods are suitable for
|
|
79
234
|
* internal calculations, although they may be used as part of the public
|
|
80
235
|
* API as well.
|
|
81
236
|
*
|
|
82
|
-
* -
|
|
83
|
-
*
|
|
237
|
+
* - a runtime error is thrown if the expression is not canonical
|
|
84
238
|
* - the arguments are not evaluated
|
|
85
|
-
*
|
|
86
239
|
* - the canonical handler (of the corresponding operation) is not called
|
|
87
|
-
*
|
|
88
240
|
* - some additional simplifications over canonicalization are applied.
|
|
89
241
|
* For example number literals are combined.
|
|
90
242
|
* However, the result is exact, and no approximation is made. Use `.N()`
|
|
91
243
|
* to get an approximate value.
|
|
92
244
|
* This is equivalent to calling `simplify()` on the expression (but
|
|
93
245
|
* without simplifying the arguments).
|
|
94
|
-
*
|
|
95
246
|
* - sequences were already flattened as part of the canonicalization process
|
|
96
247
|
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
248
|
+
* For 'add()' and 'mul()', which take multiple arguments, separate functions
|
|
249
|
+
* are provided that take an array of arguments. They are equivalent
|
|
250
|
+
* to calling the boxed algebraic method, i.e. `ce.Zero.add(1, 2, 3)` and
|
|
251
|
+
* `add(1, 2, 3)` are equivalent.
|
|
101
252
|
*
|
|
102
253
|
* These methods are not equivalent to calling `expr.evaluate()` on the
|
|
103
|
-
* expression: evaluate will replace
|
|
104
|
-
* evaluate the expression
|
|
254
|
+
* expression: evaluate will replace symbols with their values, and
|
|
255
|
+
* evaluate the expression.
|
|
105
256
|
*
|
|
106
|
-
*
|
|
257
|
+
* For algebraic functions (`add()`, `mul()`, etc..), use the corresponding
|
|
258
|
+
* canonicalization function, i.e. `canonicalAdd(a, b)` instead of
|
|
259
|
+
* `ce.function('Add', [a, b])`.
|
|
260
|
+
*
|
|
261
|
+
* Another option is to use the algebraic methods directly, i.e. `a.add(b)`
|
|
262
|
+
* instead of `ce.function('Add', [a, b])`. However, the algebraic methods will
|
|
263
|
+
* apply further simplifications which may or may not be desirable. For
|
|
264
|
+
* example, number literals will be combined.
|
|
107
265
|
*
|
|
108
|
-
*
|
|
266
|
+
* ### `ce._fn()`
|
|
109
267
|
*
|
|
110
|
-
* This is a low level method
|
|
111
|
-
* handler of
|
|
268
|
+
* This method is a low level method to create a new function expression which
|
|
269
|
+
* is typically invoked in the canonical handler of an operator definition.
|
|
112
270
|
*
|
|
113
271
|
* The arguments are not modified. The expression is not put in canonical
|
|
114
272
|
* form. The canonical handler is *not* called.
|
|
115
273
|
*
|
|
116
|
-
* A canonical flag can be set when calling
|
|
117
|
-
* asserts that the function
|
|
118
|
-
*
|
|
274
|
+
* A canonical flag can be set when calling this method, but it only
|
|
275
|
+
* asserts that the function expression is canonical. The caller is responsible
|
|
276
|
+
* for ensuring that is the case.
|
|
119
277
|
*
|
|
120
278
|
*
|
|
121
|
-
* ### `ce.function()`
|
|
122
|
-
*
|
|
123
|
-
* This is a specialized version of `ce.box()`. It is used to create a new
|
|
124
|
-
* function expression.
|
|
125
|
-
*
|
|
126
|
-
* The arguments are put in canonical form and the canonical handler is called.
|
|
127
|
-
*
|
|
128
|
-
* For algebraic functions (add, mul, etc..), use the corresponding
|
|
129
|
-
* canonicalization function, i.e. `canonicalAdd(a, b)` instead of
|
|
130
|
-
* `ce.function('Add', a, b)`.
|
|
131
|
-
*
|
|
132
|
-
* Another option is to use the algebraic methods directly, i.e. `a.add(b)`
|
|
133
|
-
* instead of `ce.function('Add', a, b)`. However, the algebraic methods will
|
|
134
|
-
* apply further simplifications which may or may not be desirable. For
|
|
135
|
-
* example, number literals will be combined.
|
|
136
279
|
*
|
|
137
280
|
* ### Canonical Handlers
|
|
138
281
|
*
|
|
139
282
|
* Canonical handlers are responsible for:
|
|
140
|
-
* - validating the signature
|
|
283
|
+
* - validating the signature: this can involve checking the
|
|
284
|
+
* number of arguments. It is recommended to avoid checking the
|
|
285
|
+
* type of non-literal arguments, since the type of symbols or
|
|
286
|
+
* function expressions may change. Similarly, the canonicalization
|
|
287
|
+
* process should not rely on the value of or assumptions about non-literal
|
|
288
|
+
* arguments.
|
|
141
289
|
* - flattening sequences
|
|
142
|
-
* - flattening associative
|
|
290
|
+
* - flattening arguments if the function is associative
|
|
143
291
|
* - sort the arguments (if the function is commutative)
|
|
144
292
|
* - calling `ce._fn()` to create a new function expression
|
|
145
|
-
* - if the function definition has a hold, they should also put
|
|
146
|
-
* their arguments in canonical form, if appropriate
|
|
147
293
|
*
|
|
148
294
|
* When the canonical handler is invoked, the arguments have been put in
|
|
149
|
-
* canonical form
|
|
295
|
+
* canonical form unless the `lazy` flag is set to `true`.
|
|
150
296
|
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* `
|
|
297
|
+
* Note that the result of a canonical handler should be a canonical expression,
|
|
298
|
+
* but not all arguments need to be canonical. For example, the arguments of
|
|
299
|
+
* `["Declare", "x", 2]` are not canonical, since `x` refers to the name
|
|
300
|
+
* of the symbol, not its value.
|
|
154
301
|
*
|
|
155
302
|
* @category Boxed Expression
|
|
156
303
|
*
|
|
157
304
|
*/
|
|
158
305
|
export interface BoxedExpression {
|
|
159
|
-
/**
|
|
306
|
+
/** @internal */
|
|
307
|
+
readonly hash: number;
|
|
308
|
+
/**
|
|
309
|
+
* The Compute Engine instance associated with this expression provides
|
|
160
310
|
* a context in which to interpret it, such as definition of symbols
|
|
161
311
|
* and functions.
|
|
162
|
-
*
|
|
163
312
|
*/
|
|
164
313
|
readonly engine: ComputeEngine;
|
|
165
|
-
/**
|
|
314
|
+
/**
|
|
166
315
|
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
316
|
+
* Return a JavaScript primitive value for the expression, based on
|
|
317
|
+
* `Object.valueOf()`.
|
|
169
318
|
*
|
|
170
|
-
*
|
|
319
|
+
* This method is intended to make it easier to work with JavaScript
|
|
320
|
+
* primitives, for example when mixing JavaScript computations with
|
|
321
|
+
* symbolic computations from the Compute Engine.
|
|
171
322
|
*
|
|
172
|
-
*
|
|
323
|
+
* If the expression is a **machine number**, a **bignum**, or a **rational**
|
|
324
|
+
* that can be converted to a machine number, return a JavaScript `number`.
|
|
325
|
+
* This conversion may result in a loss of precision.
|
|
326
|
+
*
|
|
327
|
+
* If the expression is the **symbol `"True"`** or the **symbol `"False"`**,
|
|
328
|
+
* return `true` or `false`, respectively.
|
|
329
|
+
*
|
|
330
|
+
* If the expression is a **symbol with a numeric value**, return the numeric
|
|
331
|
+
* value of the symbol.
|
|
332
|
+
*
|
|
333
|
+
* If the expression is a **string literal**, return the string value.
|
|
334
|
+
*
|
|
335
|
+
* If the expression is a **tensor** (list of number or multidimensional
|
|
336
|
+
* array or matrix), return an array of numbers, or an array of
|
|
337
|
+
* arrays of numbers, or an array of arrays of arrays of numbers.
|
|
338
|
+
*
|
|
339
|
+
* If the expression is a function expression return a string representation
|
|
340
|
+
* of the expression.
|
|
341
|
+
*
|
|
342
|
+
* @category Primitive Methods
|
|
343
|
+
*/
|
|
344
|
+
valueOf(): number | number[] | number[][] | number[][][] | string | boolean;
|
|
345
|
+
/** Similar to`expr.valueOf()` but includes a hint.
|
|
173
346
|
*
|
|
174
347
|
* @category Primitive Methods
|
|
175
348
|
*/
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
*
|
|
179
|
-
*
|
|
349
|
+
[Symbol.toPrimitive](hint: 'number' | 'string' | 'default'): number | string | null;
|
|
350
|
+
/**
|
|
351
|
+
* Return an ASCIIMath representation of the expression. This string is
|
|
352
|
+
* suitable to be output to the console for debugging, for example.
|
|
353
|
+
*
|
|
354
|
+
* Based on `Object.toString()`.
|
|
180
355
|
*
|
|
181
356
|
* To get a LaTeX representation of the expression, use `expr.latex`.
|
|
182
357
|
*
|
|
358
|
+
* Note that lazy collections are eagerly evaluated.
|
|
359
|
+
*
|
|
183
360
|
* Used when coercing a `BoxedExpression` to a `String`.
|
|
184
361
|
*
|
|
185
362
|
* @category Primitive Methods
|
|
186
363
|
*/
|
|
187
364
|
toString(): string;
|
|
188
|
-
/**
|
|
189
|
-
* Output to the console a string representation of the expression.
|
|
365
|
+
/** Serialize to a LaTeX string.
|
|
190
366
|
*
|
|
191
|
-
*
|
|
367
|
+
* Note that lazy collections are eagerly evaluated.
|
|
368
|
+
*
|
|
369
|
+
* Will ignore any LaTeX metadata.
|
|
192
370
|
*/
|
|
193
|
-
|
|
194
|
-
/**
|
|
371
|
+
toLatex(options?: Partial<SerializeLatexOptions>): LatexString;
|
|
372
|
+
/** LaTeX representation of this expression.
|
|
373
|
+
*
|
|
374
|
+
* If the expression was parsed from LaTeX, the LaTeX representation is
|
|
375
|
+
* the same as the input LaTeX.
|
|
376
|
+
*
|
|
377
|
+
* To customize the serialization, use `expr.toLatex()`.
|
|
378
|
+
*
|
|
379
|
+
* Note that lazy collections are eagerly evaluated.
|
|
380
|
+
*
|
|
381
|
+
* :::info[Note]
|
|
382
|
+
* Applicable to canonical and non-canonical expressions.
|
|
383
|
+
* :::
|
|
195
384
|
*
|
|
196
|
-
* @category Primitive Methods
|
|
197
385
|
*/
|
|
198
|
-
|
|
386
|
+
get latex(): LatexString;
|
|
199
387
|
/** Used by `JSON.stringify()` to serialize this object to JSON.
|
|
200
388
|
*
|
|
201
389
|
* Method version of `expr.json`.
|
|
202
390
|
*
|
|
391
|
+
* Based on `Object.toJSON()`.
|
|
392
|
+
*
|
|
393
|
+
* Note that lazy collections are *not* eagerly evaluated.
|
|
394
|
+
*
|
|
203
395
|
* @category Primitive Methods
|
|
204
396
|
*/
|
|
205
397
|
toJSON(): Expression;
|
|
206
|
-
/** Serialize to a MathJSON expression with specified options*/
|
|
398
|
+
/** Serialize to a MathJSON expression with specified options */
|
|
207
399
|
toMathJson(options?: Readonly<Partial<JsonSerializationOptions>>): Expression;
|
|
208
|
-
/** Serialize to a LaTeX string.
|
|
209
|
-
*
|
|
210
|
-
* Will ignore any LaTeX metadata.
|
|
211
|
-
*/
|
|
212
|
-
toLatex(options?: Partial<SerializeLatexOptions>): LatexString;
|
|
213
|
-
verbatimLatex?: string;
|
|
214
|
-
/** If `true`, this expression is in a canonical form. */
|
|
215
|
-
get isCanonical(): boolean;
|
|
216
|
-
/** For internal use only, set when a canonical expression is created.
|
|
217
|
-
* @internal
|
|
218
|
-
*/
|
|
219
|
-
set isCanonical(val: boolean);
|
|
220
|
-
/** If `true`, this expression is in a structural form. */
|
|
221
|
-
get isStructural(): boolean;
|
|
222
400
|
/** MathJSON representation of this expression.
|
|
223
401
|
*
|
|
224
402
|
* This representation always use shorthands when possible. Metadata is not
|
|
@@ -231,6 +409,8 @@ export interface BoxedExpression {
|
|
|
231
409
|
*
|
|
232
410
|
* For more control over the serialization, use `expr.toMathJson()`.
|
|
233
411
|
*
|
|
412
|
+
* Note that lazy collections are *not* eagerly evaluated.
|
|
413
|
+
*
|
|
234
414
|
* :::info[Note]
|
|
235
415
|
* Applicable to canonical and non-canonical expressions.
|
|
236
416
|
* :::
|
|
@@ -238,75 +418,161 @@ export interface BoxedExpression {
|
|
|
238
418
|
*/
|
|
239
419
|
readonly json: Expression;
|
|
240
420
|
/**
|
|
241
|
-
*
|
|
421
|
+
* Output to the console a string representation of the expression.
|
|
422
|
+
*
|
|
423
|
+
* Note that lazy collections are eagerly evaluated when printed.
|
|
242
424
|
*
|
|
243
|
-
* Is `null` when the expression is not canonical.
|
|
244
425
|
*/
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
*
|
|
248
|
-
|
|
249
|
-
|
|
426
|
+
print(): void;
|
|
427
|
+
/** If the expression was constructed from a LaTeX string, the verbatim LaTeX
|
|
428
|
+
* string it was parsed from.
|
|
429
|
+
*/
|
|
430
|
+
verbatimLatex?: string;
|
|
431
|
+
/** If `true`, this expression is in a canonical form. */
|
|
432
|
+
get isCanonical(): boolean;
|
|
433
|
+
/** For internal use only, set when a canonical expression is created.
|
|
434
|
+
* @internal
|
|
435
|
+
*/
|
|
436
|
+
set isCanonical(val: boolean);
|
|
437
|
+
/** If `true`, this expression is in a structural form.
|
|
250
438
|
*
|
|
251
|
-
*
|
|
439
|
+
* The structural form of an expression is used when applying rules to
|
|
440
|
+
* an expression. For example, a rational number is represented as a
|
|
441
|
+
* function expression instead of a `BoxedExpression` object.
|
|
252
442
|
*
|
|
253
443
|
*/
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
|
|
257
|
-
/** LaTeX representation of this expression.
|
|
444
|
+
get isStructural(): boolean;
|
|
445
|
+
/**
|
|
446
|
+
* Return the canonical form of this expression.
|
|
258
447
|
*
|
|
259
|
-
* If
|
|
260
|
-
*
|
|
448
|
+
* If a function expression or symbol, they are first bound with a definition
|
|
449
|
+
* in the current scope.
|
|
261
450
|
*
|
|
262
|
-
*
|
|
451
|
+
* When determining the canonical form the following operator definition
|
|
452
|
+
* flags are applied:
|
|
453
|
+
* - `associative`: \\( f(a, f(b), c) \longrightarrow f(a, b, c) \\)
|
|
454
|
+
* - `idempotent`: \\( f(f(a)) \longrightarrow f(a) \\)
|
|
455
|
+
* - `involution`: \\( f(f(a)) \longrightarrow a \\)
|
|
456
|
+
* - `commutative`: sort the arguments.
|
|
457
|
+
*
|
|
458
|
+
* If this expression is already canonical, the value of canonical is
|
|
459
|
+
* `this`.
|
|
460
|
+
*
|
|
461
|
+
* The arguments of a canonical function expression may not all be
|
|
462
|
+
* canonical, for example in the `["Declare", "i", 2]` expression,
|
|
463
|
+
* `i` is not canonical since it is used only as the name of a symbol, not
|
|
464
|
+
* as a (potentially) existing symbol.
|
|
263
465
|
*
|
|
264
466
|
* :::info[Note]
|
|
265
|
-
*
|
|
467
|
+
* Partially canonical expressions, such as those produced through
|
|
468
|
+
* `CanonicalForm`, also yield an expression which is marked as `canonical`.
|
|
469
|
+
* This means that, likewise for partially canonical expressions, the
|
|
470
|
+
* `canonical` property will return the self-same expression (and
|
|
471
|
+
* 'isCanonical' will also be true).
|
|
266
472
|
* :::
|
|
267
473
|
*
|
|
268
474
|
*/
|
|
269
|
-
get
|
|
475
|
+
get canonical(): BoxedExpression;
|
|
270
476
|
/**
|
|
477
|
+
* Return the structural form of this expression.
|
|
478
|
+
*
|
|
479
|
+
* Some expressions, such as rational numbers, are represented with
|
|
480
|
+
* a `BoxedExpression` object. In some cases, for example when doing a
|
|
481
|
+
* structural comparison of two expressions, it is useful to have a
|
|
482
|
+
* structural representation of the expression where the rational numbers
|
|
483
|
+
* is represented by a function expression instead.
|
|
484
|
+
*
|
|
485
|
+
* If there is a structural representation of the expression, return it,
|
|
486
|
+
* otherwise return `this`.
|
|
487
|
+
*
|
|
488
|
+
*/
|
|
489
|
+
get structural(): BoxedExpression;
|
|
490
|
+
/** `false` if this expression or any of its subexpressions is an `["Error"]`
|
|
491
|
+
* expression.
|
|
271
492
|
*
|
|
272
493
|
* :::info[Note]
|
|
273
|
-
* Applicable to canonical and non-canonical expressions.
|
|
494
|
+
* Applicable to canonical and non-canonical expressions. For
|
|
495
|
+
* non-canonical expression, this may indicate a syntax error while parsing
|
|
496
|
+
* LaTeX. For canonical expression, this may indicate argument type
|
|
497
|
+
* mismatch, or missing or unexpected arguments.
|
|
274
498
|
* :::
|
|
275
|
-
*
|
|
499
|
+
*
|
|
276
500
|
*/
|
|
277
|
-
|
|
278
|
-
/** If this expression
|
|
279
|
-
*
|
|
501
|
+
readonly isValid: boolean;
|
|
502
|
+
/** If *true*, evaluating this expression has no side-effects (does not
|
|
503
|
+
* change the state of the Compute Engine).
|
|
504
|
+
*
|
|
505
|
+
* If *false*, evaluating this expression may change the state of the
|
|
506
|
+
* Compute Engine or it may return a different value each time it is
|
|
507
|
+
* evaluated, even if the state of the Compute Engine is the same.
|
|
508
|
+
*
|
|
509
|
+
* As an example, the ["Add", 2, 3]` function expression is pure, but
|
|
510
|
+
* the `["Random"]` function expression is not pure.
|
|
511
|
+
*
|
|
512
|
+
* For a function expression to be pure, the function itself (its operator)
|
|
513
|
+
* must be pure, and all of its arguments must be pure too.
|
|
514
|
+
*
|
|
515
|
+
* A pure function expression may return a different value each time it is
|
|
516
|
+
* evaluated if its arguments are not constant. For example, the
|
|
517
|
+
* `["Add", "x", 1]` function expression is pure, but it is not
|
|
518
|
+
* constant, because `x` is not constant.
|
|
280
519
|
*
|
|
281
520
|
* :::info[Note]
|
|
282
|
-
* Applicable to canonical
|
|
521
|
+
* Applicable to canonical expressions only
|
|
283
522
|
* :::
|
|
523
|
+
*/
|
|
524
|
+
readonly isPure: boolean;
|
|
525
|
+
/**
|
|
526
|
+
* `True` if evaluating this expression always returns the same value.
|
|
284
527
|
*
|
|
285
|
-
*
|
|
528
|
+
* If *true* and a function expression, implies that it is *pure* and
|
|
529
|
+
* that all of its arguments are constant.
|
|
286
530
|
*
|
|
531
|
+
* Number literals, symbols with constant values, and pure numeric functions
|
|
532
|
+
* with constant arguments are all *constant*, i.e.:
|
|
533
|
+
* - `42` is constant
|
|
534
|
+
* - `Pi` is constant
|
|
535
|
+
* - `["Divide", "Pi", 2]` is constant
|
|
536
|
+
* - `x` is not constant, unless declared with a constant flag.
|
|
537
|
+
* - `["Add", "x", 2]` is either constant only if `x` is constant.
|
|
287
538
|
*/
|
|
288
|
-
readonly
|
|
289
|
-
/**
|
|
290
|
-
*
|
|
539
|
+
readonly isConstant: boolean;
|
|
540
|
+
/** All the `["Error"]` subexpressions.
|
|
541
|
+
*
|
|
542
|
+
* If an expression includes an error, the expression is also an error.
|
|
543
|
+
* In that case, the `this.isValid` property is `false`.
|
|
291
544
|
*
|
|
292
545
|
* :::info[Note]
|
|
293
546
|
* Applicable to canonical and non-canonical expressions.
|
|
294
547
|
* :::
|
|
295
|
-
|
|
296
|
-
* @category String Expression
|
|
297
548
|
*
|
|
298
549
|
*/
|
|
299
|
-
readonly
|
|
300
|
-
readonly tensor: null | TensorData<'expression'>;
|
|
550
|
+
readonly errors: ReadonlyArray<BoxedExpression>;
|
|
301
551
|
/** All the subexpressions matching the named operator, recursively.
|
|
552
|
+
*
|
|
553
|
+
* Example:
|
|
554
|
+
*
|
|
555
|
+
* ```js
|
|
556
|
+
* const expr = ce.parse('a + b * c + d');
|
|
557
|
+
* const subexpressions = expr.getSubexpressions('Add');
|
|
558
|
+
* // -> `[['Add', 'a', 'b'], ['Add', 'c', 'd']]`
|
|
559
|
+
* ```
|
|
302
560
|
*
|
|
303
561
|
* :::info[Note]
|
|
304
562
|
* Applicable to canonical and non-canonical expressions.
|
|
305
563
|
* :::
|
|
306
564
|
*
|
|
307
565
|
*/
|
|
308
|
-
getSubexpressions(
|
|
566
|
+
getSubexpressions(operator: string): ReadonlyArray<BoxedExpression>;
|
|
309
567
|
/** All the subexpressions in this expression, recursively
|
|
568
|
+
*
|
|
569
|
+
* Example:
|
|
570
|
+
*
|
|
571
|
+
* ```js
|
|
572
|
+
* const expr = ce.parse('a + b * c + d');
|
|
573
|
+
* const subexpressions = expr.subexpressions;
|
|
574
|
+
* // -> `[['Add', 'a', 'b'], ['Add', 'c', 'd'], 'a', 'b', 'c', 'd']`
|
|
575
|
+
* ```
|
|
310
576
|
*
|
|
311
577
|
* :::info[Note]
|
|
312
578
|
* Applicable to canonical and non-canonical expressions.
|
|
@@ -318,6 +584,12 @@ export interface BoxedExpression {
|
|
|
318
584
|
*
|
|
319
585
|
* All the symbols in the expression, recursively
|
|
320
586
|
*
|
|
587
|
+
* ```js
|
|
588
|
+
* const expr = ce.parse('a + b * c + d');
|
|
589
|
+
* const symbols = expr.symbols;
|
|
590
|
+
* // -> ['a', 'b', 'c', 'd']
|
|
591
|
+
* ```
|
|
592
|
+
*
|
|
321
593
|
* :::info[Note]
|
|
322
594
|
* Applicable to canonical and non-canonical expressions.
|
|
323
595
|
* :::
|
|
@@ -325,42 +597,220 @@ export interface BoxedExpression {
|
|
|
325
597
|
*/
|
|
326
598
|
readonly symbols: ReadonlyArray<string>;
|
|
327
599
|
/**
|
|
328
|
-
* All the
|
|
600
|
+
* All the symbols used in the expression that do not have a value
|
|
329
601
|
* associated with them, i.e. they are declared but not defined.
|
|
330
602
|
*/
|
|
331
603
|
readonly unknowns: ReadonlyArray<string>;
|
|
332
604
|
/**
|
|
605
|
+
* Return `true` if this expression is a number literal, for example
|
|
606
|
+
* `2`, `3.14`, `1/2`, `√2` etc.
|
|
607
|
+
*
|
|
608
|
+
* When `true`, `expr.numericValue` is not `null`.
|
|
333
609
|
*
|
|
334
|
-
*
|
|
335
|
-
* not a local variable or a parameter of that function.
|
|
610
|
+
* @category Numeric Expression
|
|
336
611
|
*
|
|
337
612
|
*/
|
|
338
|
-
readonly
|
|
339
|
-
/**
|
|
613
|
+
readonly isNumberLiteral: boolean;
|
|
614
|
+
/**
|
|
615
|
+
* Return the value of this expression, if a number literal.
|
|
340
616
|
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
617
|
+
* Note it is possible for `expr.numericValue` to be `null`, and for
|
|
618
|
+
* `expr.isNotZero` to be true. For example, when a symbol has been
|
|
619
|
+
* defined with an assumption.
|
|
343
620
|
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
621
|
+
* Conversely, `expr.isNumber` may be true even if `expr.numericValue` is
|
|
622
|
+
* `null`, for example the symbol `Pi` return `true` for `isNumber` but
|
|
623
|
+
* `expr.numericValue` is `null` (it's a symbol, not a number literal).
|
|
624
|
+
* Its value can be accessed with `expr.value`.
|
|
625
|
+
*
|
|
626
|
+
* To check if an expression is a number literal, use `expr.isNumberLiteral`.
|
|
627
|
+
* If `expr.isNumberLiteral` is `true`, `expr.numericValue` is not `null`.
|
|
628
|
+
*
|
|
629
|
+
* @category Numeric Expression
|
|
347
630
|
*
|
|
348
631
|
*/
|
|
349
|
-
readonly
|
|
350
|
-
/**
|
|
351
|
-
*
|
|
632
|
+
readonly numericValue: number | NumericValue | null;
|
|
633
|
+
/**
|
|
634
|
+
* Attempt to factor a numeric coefficient `c` and a `rest` out of a
|
|
635
|
+
* canonical expression such that `rest.mul(c)` is equal to `this`.
|
|
636
|
+
*
|
|
637
|
+
* Attempts to make `rest` a positive value (i.e. pulls out negative sign).
|
|
638
|
+
*
|
|
639
|
+
*```json
|
|
640
|
+
* ['Multiply', 2, 'x', 3, 'a']
|
|
641
|
+
* -> [NumericValue(6), ['Multiply', 'x', 'a']]
|
|
642
|
+
*
|
|
643
|
+
* ['Divide', ['Multiply', 2, 'x'], ['Multiply', 3, 'y', 'a']]
|
|
644
|
+
* -> [NumericValue({rational: [2, 3]}), ['Divide', 'x', ['Multiply, 'y', 'a']]]
|
|
645
|
+
* ```
|
|
646
|
+
*/
|
|
647
|
+
toNumericValue(): [NumericValue, BoxedExpression];
|
|
648
|
+
/**
|
|
649
|
+
* If the value of this expression is not an **integer** return `undefined`.
|
|
650
|
+
*
|
|
651
|
+
* @category Numeric Expression
|
|
652
|
+
*/
|
|
653
|
+
readonly isEven: boolean | undefined;
|
|
654
|
+
/**
|
|
655
|
+
* If the value of this expression is not an **integer** return `undefined`.
|
|
656
|
+
*
|
|
657
|
+
* @category Numeric Expression
|
|
658
|
+
*/
|
|
659
|
+
readonly isOdd: boolean | undefined;
|
|
660
|
+
/**
|
|
661
|
+
* Return the real part of the value of this expression, if a number.
|
|
662
|
+
*
|
|
663
|
+
* Otherwise, return `NaN` (not a number).
|
|
664
|
+
*
|
|
665
|
+
* @category Numeric Expression
|
|
666
|
+
*/
|
|
667
|
+
readonly re: number;
|
|
668
|
+
/**
|
|
669
|
+
* If value of this expression is a number, return the imaginary part of the
|
|
670
|
+
* value. If the value is a real number, the imaginary part is 0.
|
|
671
|
+
*
|
|
672
|
+
* Otherwise, return `NaN` (not a number).
|
|
673
|
+
*
|
|
674
|
+
* @category Numeric Expression
|
|
675
|
+
*/
|
|
676
|
+
readonly im: number;
|
|
677
|
+
/**
|
|
678
|
+
* If the value of this expression is a number, return the real part of the
|
|
679
|
+
* value as a `BigNum`.
|
|
680
|
+
*
|
|
681
|
+
* If the value is not available as a bignum return `undefined`. That is,
|
|
682
|
+
* the value is not upconverted to a bignum.
|
|
683
|
+
*
|
|
684
|
+
* To get the real value either as a bignum or a number, use
|
|
685
|
+
* `expr.bignumRe ?? expr.re`.
|
|
686
|
+
*
|
|
687
|
+
* When using this pattern, the value is returned as a bignum if available,
|
|
688
|
+
* otherwise as a number or `NaN` if the value is not a number.
|
|
689
|
+
*
|
|
690
|
+
* @category Numeric Expression
|
|
691
|
+
*
|
|
692
|
+
*/
|
|
693
|
+
readonly bignumRe: BigNum | undefined;
|
|
694
|
+
/**
|
|
695
|
+
* If the value of this expression is a number, return the imaginary part as
|
|
696
|
+
* a `BigNum`.
|
|
697
|
+
*
|
|
698
|
+
* It may be 0 if the number is real.
|
|
699
|
+
*
|
|
700
|
+
* If the value of the expression is not a number or the value is not
|
|
701
|
+
* available as a bignum return `undefined`. That is, the value is not
|
|
702
|
+
* upconverted to a bignum.
|
|
703
|
+
*
|
|
704
|
+
* To get the imaginary value either as a bignum or a number, use
|
|
705
|
+
* `expr.bignumIm ?? expr.im`.
|
|
706
|
+
*
|
|
707
|
+
* When using this pattern, the value is returned as a bignum if available, otherwise as a number or `NaN` if the value is not a number.
|
|
708
|
+
*
|
|
709
|
+
* @category Numeric Expression
|
|
710
|
+
*/
|
|
711
|
+
readonly bignumIm: BigNum | undefined;
|
|
712
|
+
/**
|
|
713
|
+
* Return the sign of the expression.
|
|
714
|
+
*
|
|
715
|
+
* Note that complex numbers have no natural ordering, so if the value is an
|
|
716
|
+
* imaginary number (a complex number with a non-zero imaginary part),
|
|
717
|
+
* `this.sgn` will return `unsigned`.
|
|
718
|
+
*
|
|
719
|
+
* If a symbol, this does take assumptions into account, that is `this.sgn`
|
|
720
|
+
* will return `positive` if the symbol is assumed to be positive
|
|
721
|
+
* using `ce.assume()`.
|
|
722
|
+
*
|
|
723
|
+
* Non-canonical expressions return `undefined`.
|
|
724
|
+
*
|
|
725
|
+
* @category Numeric Expression
|
|
726
|
+
*
|
|
727
|
+
*/
|
|
728
|
+
readonly sgn: Sign | undefined;
|
|
729
|
+
/** The value of this expression is > 0, same as `isGreaterEqual(0)`
|
|
730
|
+
*
|
|
731
|
+
* @category Numeric Expression
|
|
732
|
+
*/
|
|
733
|
+
readonly isPositive: boolean | undefined;
|
|
734
|
+
/** The value of this expression is >= 0, same as `isGreaterEqual(0)`
|
|
735
|
+
*
|
|
736
|
+
* @category Numeric Expression
|
|
737
|
+
*/
|
|
738
|
+
readonly isNonNegative: boolean | undefined;
|
|
739
|
+
/** The value of this expression is < 0, same as `isLess(0)`
|
|
740
|
+
*
|
|
741
|
+
* @category Numeric Expression
|
|
742
|
+
*/
|
|
743
|
+
readonly isNegative: boolean | undefined;
|
|
744
|
+
/** The value of this expression is <= 0, same as `isLessEqual(0)`
|
|
745
|
+
*
|
|
746
|
+
* @category Numeric Expression
|
|
747
|
+
*/
|
|
748
|
+
readonly isNonPositive: boolean | undefined;
|
|
749
|
+
/** Negate (additive inverse) */
|
|
750
|
+
neg(): BoxedExpression;
|
|
751
|
+
/** Inverse (multiplicative inverse) */
|
|
752
|
+
inv(): BoxedExpression;
|
|
753
|
+
/** Absolute value */
|
|
754
|
+
abs(): BoxedExpression;
|
|
755
|
+
/** Addition */
|
|
756
|
+
add(rhs: number | BoxedExpression): BoxedExpression;
|
|
757
|
+
/** Subtraction */
|
|
758
|
+
sub(rhs: BoxedExpression): BoxedExpression;
|
|
759
|
+
/** Multiplication */
|
|
760
|
+
mul(rhs: NumericValue | number | BoxedExpression): BoxedExpression;
|
|
761
|
+
/** Division */
|
|
762
|
+
div(rhs: number | BoxedExpression): BoxedExpression;
|
|
763
|
+
/** Power */
|
|
764
|
+
pow(exp: number | BoxedExpression): BoxedExpression;
|
|
765
|
+
/** Exponentiation */
|
|
766
|
+
root(exp: number | BoxedExpression): BoxedExpression;
|
|
767
|
+
/** Square root */
|
|
768
|
+
sqrt(): BoxedExpression;
|
|
769
|
+
/** Logarithm (natural by default) */
|
|
770
|
+
ln(base?: number | BoxedExpression): BoxedExpression;
|
|
771
|
+
/**
|
|
772
|
+
* Return this expression expressed as a numerator.
|
|
773
|
+
*/
|
|
774
|
+
get numerator(): BoxedExpression;
|
|
775
|
+
/**
|
|
776
|
+
* Return this expression expressed as a denominator.
|
|
777
|
+
*/
|
|
778
|
+
get denominator(): BoxedExpression;
|
|
779
|
+
/**
|
|
780
|
+
* Return this expression expressed as a numerator and denominator.
|
|
781
|
+
*/
|
|
782
|
+
get numeratorDenominator(): [BoxedExpression, BoxedExpression];
|
|
783
|
+
/** If this expression is a symbol, return the name of the symbol as a string.
|
|
784
|
+
* Otherwise, return `null`.
|
|
352
785
|
*
|
|
353
786
|
* :::info[Note]
|
|
354
|
-
* Applicable to canonical and non-canonical expressions.
|
|
355
|
-
* non-canonical expression, this may indicate a syntax error while parsing
|
|
356
|
-
* LaTeX. For canonical expression, this may indicate argument type
|
|
357
|
-
* mismatch, or missing or unexpected arguments.
|
|
787
|
+
* Applicable to canonical and non-canonical expressions.
|
|
358
788
|
* :::
|
|
359
789
|
*
|
|
360
790
|
* @category Symbol Expression
|
|
361
791
|
*
|
|
362
792
|
*/
|
|
363
|
-
readonly
|
|
793
|
+
readonly symbol: string | null;
|
|
794
|
+
/** If this expression is a string, return the value of the string.
|
|
795
|
+
* Otherwise, return `null`.
|
|
796
|
+
*
|
|
797
|
+
* :::info[Note]
|
|
798
|
+
* Applicable to canonical and non-canonical expressions.
|
|
799
|
+
* :::
|
|
800
|
+
|
|
801
|
+
* @category String Expression
|
|
802
|
+
*
|
|
803
|
+
*/
|
|
804
|
+
readonly string: string | null;
|
|
805
|
+
/**
|
|
806
|
+
* Return `true` if this expression is a function expression.
|
|
807
|
+
*
|
|
808
|
+
* If `true`, `expr.ops` is not `null`, and `expr.operator` is the name
|
|
809
|
+
* of the function.
|
|
810
|
+
*
|
|
811
|
+
* @category Function Expression
|
|
812
|
+
*/
|
|
813
|
+
readonly isFunctionExpression: boolean;
|
|
364
814
|
/**
|
|
365
815
|
* The name of the operator of the expression.
|
|
366
816
|
*
|
|
@@ -370,8 +820,11 @@ export interface BoxedExpression {
|
|
|
370
820
|
*
|
|
371
821
|
* A symbol has a `"Symbol"` operator.
|
|
372
822
|
*
|
|
373
|
-
* A number has a `"Number"`, `"Real"`, `"Rational"` or `"Integer"` operator.
|
|
823
|
+
* A number has a `"Number"`, `"Real"`, `"Rational"` or `"Integer"` operator; amongst some others.
|
|
824
|
+
* Practically speaking, for fully canonical and valid expressions, all of these are likely to
|
|
825
|
+
* collapse to `"Number"`.
|
|
374
826
|
*
|
|
827
|
+
* @category Function Expression
|
|
375
828
|
*/
|
|
376
829
|
readonly operator: string;
|
|
377
830
|
/** The list of operands of the function.
|
|
@@ -438,71 +891,18 @@ export interface BoxedExpression {
|
|
|
438
891
|
*
|
|
439
892
|
*/
|
|
440
893
|
readonly op3: BoxedExpression;
|
|
441
|
-
/** If true, the
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
* If false, the value of the expression may change, if the
|
|
445
|
-
* value of other expression changes or for other reasons.
|
|
446
|
-
*
|
|
447
|
-
* If `this.isPure` is `false`, `this.value` is undefined. Call
|
|
448
|
-
* `this.evaluate()` to determine the value of the expression instead.
|
|
449
|
-
*
|
|
450
|
-
* As an example, the `Random` function is not pure.
|
|
451
|
-
*
|
|
452
|
-
* :::info[Note]
|
|
453
|
-
* Applicable to canonical and non-canonical expressions.
|
|
454
|
-
* :::
|
|
455
|
-
*/
|
|
456
|
-
readonly isPure: boolean;
|
|
457
|
-
/**
|
|
458
|
-
* True if the the value of the expression does not depend on the value of
|
|
459
|
-
* any other expression.
|
|
460
|
-
*
|
|
461
|
-
* For example, a number literal, a symbol with a constant value.
|
|
462
|
-
* - `2` is constant
|
|
463
|
-
* - `Pi` is constant
|
|
464
|
-
* - `["Add", "Pi", 2]` is constant
|
|
465
|
-
* - `x` is not constant
|
|
466
|
-
* - `["Add", "x", 2]` is not constant
|
|
894
|
+
/** If true, the expression has its own local scope that can be used
|
|
895
|
+
* for local variables and arguments. Only true if the expression is a
|
|
896
|
+
* function expression.
|
|
467
897
|
*/
|
|
468
|
-
readonly
|
|
469
|
-
/**
|
|
470
|
-
|
|
471
|
-
*
|
|
472
|
-
* If this is a function expression, a definition is associated with the
|
|
473
|
-
* canonical expression.
|
|
474
|
-
*
|
|
475
|
-
* When determining the canonical form the following function definition
|
|
476
|
-
* flags are applied:
|
|
477
|
-
* - `associative`: \\( f(a, f(b), c) \longrightarrow f(a, b, c) \\)
|
|
478
|
-
* - `idempotent`: \\( f(f(a)) \longrightarrow f(a) \\)
|
|
479
|
-
* - `involution`: \\( f(f(a)) \longrightarrow a \\)
|
|
480
|
-
* - `commutative`: sort the arguments.
|
|
481
|
-
*
|
|
482
|
-
* If this expression is already canonical, the value of canonical is
|
|
483
|
-
* `this`.
|
|
484
|
-
*
|
|
485
|
-
*/
|
|
486
|
-
get canonical(): BoxedExpression;
|
|
487
|
-
/**
|
|
488
|
-
* Return the structural form of this expression.
|
|
489
|
-
*
|
|
490
|
-
* Some expressions, such as rational numbers, are represented with
|
|
491
|
-
* a `BoxedExpression` object. In some cases, for example when doing a
|
|
492
|
-
* structural comparison of two expressions, it is useful to have a
|
|
493
|
-
* structural representation of the expression where the rational numbers
|
|
494
|
-
* is represented by a function expression instead.
|
|
495
|
-
*
|
|
496
|
-
* If there is a structural representation of the expression, return it,
|
|
497
|
-
* otherwise return `this`.
|
|
498
|
-
*
|
|
499
|
-
*/
|
|
500
|
-
get structural(): BoxedExpression;
|
|
898
|
+
readonly isScoped: boolean;
|
|
899
|
+
/** If this expression has a local scope, return it. */
|
|
900
|
+
get localScope(): Scope | undefined;
|
|
501
901
|
/**
|
|
502
902
|
* Replace all the symbols in the expression as indicated.
|
|
503
903
|
*
|
|
504
904
|
* Note the same effect can be achieved with `this.replace()`, but
|
|
505
|
-
* using `this.subs()` is more efficient
|
|
905
|
+
* using `this.subs()` is more efficient and simpler, but limited
|
|
506
906
|
* to replacing symbols.
|
|
507
907
|
*
|
|
508
908
|
* The result is bound to the current scope, not to `this.scope`.
|
|
@@ -511,396 +911,281 @@ export interface BoxedExpression {
|
|
|
511
911
|
* is canonical.
|
|
512
912
|
*
|
|
513
913
|
* :::info[Note]
|
|
514
|
-
* Applicable to canonical and non-canonical expressions.
|
|
515
|
-
* :::
|
|
516
|
-
*
|
|
517
|
-
*/
|
|
518
|
-
subs(sub: Substitution, options?: {
|
|
519
|
-
canonical?: CanonicalOptions;
|
|
520
|
-
}): BoxedExpression;
|
|
521
|
-
/**
|
|
522
|
-
* Recursively replace all the subexpressions in the expression as indicated.
|
|
523
|
-
*
|
|
524
|
-
* To remove a subexpression, return an empty `["Sequence"]` expression.
|
|
525
|
-
*
|
|
526
|
-
* The canonical option is applied to each function subexpression after
|
|
527
|
-
* the substitution is applied.
|
|
528
|
-
*
|
|
529
|
-
* If no `options.canonical` is set, the result is canonical if `this`
|
|
530
|
-
* is canonical.
|
|
531
|
-
*
|
|
532
|
-
* **Default**: `{ canonical: this.isCanonical, recursive: true }`
|
|
533
|
-
*/
|
|
534
|
-
map(fn: (expr: BoxedExpression) => BoxedExpression, options?: {
|
|
535
|
-
canonical: CanonicalOptions;
|
|
536
|
-
recursive?: boolean;
|
|
537
|
-
}): BoxedExpression;
|
|
538
|
-
/**
|
|
539
|
-
* Transform the expression by applying one or more replacement rules:
|
|
540
|
-
*
|
|
541
|
-
* - If the expression matches the `match` pattern and the `condition`
|
|
542
|
-
* predicate is true, replace it with the `replace` pattern.
|
|
543
|
-
*
|
|
544
|
-
* - If no rules apply, return `null`.
|
|
545
|
-
*
|
|
546
|
-
* See also `expr.subs()` for a simple substitution of symbols.
|
|
547
|
-
*
|
|
548
|
-
* If `options.canonical` is not set, the result is canonical if `this`
|
|
549
|
-
* is canonical.
|
|
550
|
-
*
|
|
551
|
-
* :::info[Note]
|
|
552
|
-
* Applicable to canonical and non-canonical expressions.
|
|
553
|
-
* :::
|
|
554
|
-
*/
|
|
555
|
-
replace(rules: BoxedRuleSet | Rule | Rule[], options?: Partial<ReplaceOptions>): null | BoxedExpression;
|
|
556
|
-
/**
|
|
557
|
-
* True if the expression includes a symbol `v` or a function operator `v`.
|
|
558
|
-
*
|
|
559
|
-
* :::info[Note]
|
|
560
|
-
* Applicable to canonical and non-canonical expressions.
|
|
561
|
-
* :::
|
|
562
|
-
*/
|
|
563
|
-
has(v: string | string[]): boolean;
|
|
564
|
-
/** Structural/symbolic equality (weak equality).
|
|
565
|
-
*
|
|
566
|
-
* `ce.parse('1+x').isSame(ce.parse('x+1'))` is `false`.
|
|
567
|
-
*
|
|
568
|
-
* See `expr.isEqual()` for mathematical equality.
|
|
569
|
-
*
|
|
570
|
-
* :::info[Note]
|
|
571
|
-
* Applicable to canonical and non-canonical expressions.
|
|
572
|
-
* :::
|
|
573
|
-
*
|
|
574
|
-
* @category Relational Operator
|
|
575
|
-
*/
|
|
576
|
-
isSame(rhs: BoxedExpression): boolean;
|
|
577
|
-
/**
|
|
578
|
-
* Return this expression expressed as a numerator and denominator.
|
|
579
|
-
*/
|
|
580
|
-
get numerator(): BoxedExpression;
|
|
581
|
-
get denominator(): BoxedExpression;
|
|
582
|
-
get numeratorDenominator(): [BoxedExpression, BoxedExpression];
|
|
583
|
-
/**
|
|
584
|
-
* If this expression matches `pattern`, return a substitution that makes
|
|
585
|
-
* `pattern` equal to `this`. Otherwise return `null`.
|
|
586
|
-
*
|
|
587
|
-
* If `pattern` includes wildcards (identifiers that start
|
|
588
|
-
* with `_`), the substitution will include a prop for each matching named
|
|
589
|
-
* wildcard.
|
|
590
|
-
*
|
|
591
|
-
* If this expression matches `pattern` but there are no named wildcards,
|
|
592
|
-
* return the empty substitution, `{}`.
|
|
593
|
-
*
|
|
594
|
-
* Read more about [**patterns and rules**](/compute-engine/guides/patterns-and-rules/).
|
|
595
|
-
*
|
|
596
|
-
* :::info[Note]
|
|
597
|
-
* Applicable to canonical and non-canonical expressions.
|
|
598
|
-
* :::
|
|
599
|
-
*
|
|
600
|
-
*/
|
|
601
|
-
match(pattern: BoxedExpression, options?: PatternMatchOptions): BoxedSubstitution | null;
|
|
602
|
-
/**
|
|
603
|
-
* "Not a Number".
|
|
604
|
-
*
|
|
605
|
-
* A value representing undefined result of computations, such as `0/0`,
|
|
606
|
-
* as per the floating point format standard IEEE-754.
|
|
607
|
-
*
|
|
608
|
-
* Note that if `isNaN` is true, `isNumber` is also true (yes, `NaN` is a
|
|
609
|
-
* number).
|
|
610
|
-
*
|
|
611
|
-
* @category Numeric Expression
|
|
612
|
-
*
|
|
613
|
-
*/
|
|
614
|
-
readonly isNaN: boolean | undefined;
|
|
615
|
-
/**
|
|
616
|
-
* The numeric value of this expression is `±Infinity` or Complex Infinity
|
|
617
|
-
*
|
|
618
|
-
* @category Numeric Expression
|
|
619
|
-
*/
|
|
620
|
-
readonly isInfinity: boolean | undefined;
|
|
621
|
-
/** This expression is a number, but not `±Infinity`, 'ComplexInfinity` or
|
|
622
|
-
* `NaN`
|
|
914
|
+
* Applicable to canonical and non-canonical expressions.
|
|
915
|
+
* :::
|
|
623
916
|
*
|
|
624
|
-
* @category Numeric Expression
|
|
625
|
-
*/
|
|
626
|
-
readonly isFinite: boolean | undefined;
|
|
627
|
-
/**
|
|
628
|
-
* @category Numeric Expression
|
|
629
|
-
*/
|
|
630
|
-
readonly isEven: boolean | undefined;
|
|
631
|
-
/**
|
|
632
|
-
* @category Numeric Expression
|
|
633
917
|
*/
|
|
634
|
-
|
|
918
|
+
subs(sub: Substitution, options?: {
|
|
919
|
+
canonical?: CanonicalOptions;
|
|
920
|
+
}): BoxedExpression;
|
|
635
921
|
/**
|
|
636
|
-
*
|
|
922
|
+
* Recursively replace all the subexpressions in the expression as indicated.
|
|
637
923
|
*
|
|
638
|
-
*
|
|
639
|
-
* `this.isNotZero` to be true. For example, when a symbol has been
|
|
640
|
-
* defined with an assumption.
|
|
924
|
+
* To remove a subexpression, return an empty `["Sequence"]` expression.
|
|
641
925
|
*
|
|
642
|
-
*
|
|
643
|
-
*
|
|
644
|
-
* `null`. Its value can be accessed with `.N().numericValue`.
|
|
926
|
+
* The `canonical` option is applied to each function subexpression after
|
|
927
|
+
* the substitution is applied.
|
|
645
928
|
*
|
|
646
|
-
*
|
|
647
|
-
*
|
|
929
|
+
* If no `options.canonical` is set, the result is canonical if `this`
|
|
930
|
+
* is canonical.
|
|
648
931
|
*
|
|
649
|
-
*
|
|
932
|
+
* **Default**: `{ canonical: this.isCanonical, recursive: true }`
|
|
650
933
|
*
|
|
934
|
+
* :::info[Note]
|
|
935
|
+
* Applicable to canonical and non-canonical expressions.
|
|
936
|
+
* :::
|
|
651
937
|
*/
|
|
652
|
-
|
|
938
|
+
map(fn: (expr: BoxedExpression) => BoxedExpression, options?: {
|
|
939
|
+
canonical: CanonicalOptions;
|
|
940
|
+
recursive?: boolean;
|
|
941
|
+
}): BoxedExpression;
|
|
653
942
|
/**
|
|
654
|
-
*
|
|
655
|
-
*
|
|
943
|
+
* Transform the expression by applying one or more replacement rules:
|
|
944
|
+
*
|
|
945
|
+
* - If the expression matches the `match` pattern and the `condition`
|
|
946
|
+
* predicate is true, replace it with the `replace` pattern.
|
|
656
947
|
*
|
|
657
|
-
*
|
|
948
|
+
* - If no rules apply, return `null`.
|
|
658
949
|
*
|
|
659
|
-
*
|
|
950
|
+
* See also `expr.subs()` for a simple substitution of symbols.
|
|
951
|
+
*
|
|
952
|
+
* If `options.canonical` is not set, the result is canonical if `this`
|
|
953
|
+
* is canonical.
|
|
660
954
|
*
|
|
955
|
+
* :::info[Note]
|
|
956
|
+
* Applicable to canonical and non-canonical expressions.
|
|
957
|
+
* :::
|
|
661
958
|
*/
|
|
662
|
-
|
|
959
|
+
replace(rules: BoxedRuleSet | Rule | Rule[], options?: Partial<ReplaceOptions>): null | BoxedExpression;
|
|
663
960
|
/**
|
|
664
|
-
*
|
|
961
|
+
* True if the expression includes a symbol `v` or a function operator `v`.
|
|
665
962
|
*
|
|
666
|
-
*
|
|
667
|
-
*
|
|
963
|
+
* :::info[Note]
|
|
964
|
+
* Applicable to canonical and non-canonical expressions.
|
|
965
|
+
* :::
|
|
668
966
|
*/
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
* If this expression is a number literal or a symbol with a value that
|
|
672
|
-
* is a number literal, return the real part of the value.
|
|
967
|
+
has(v: string | string[]): boolean;
|
|
968
|
+
/** Structural/symbolic equality (weak equality).
|
|
673
969
|
*
|
|
674
|
-
*
|
|
675
|
-
* that is a number literal, return `NaN` (not a number).
|
|
970
|
+
* `ce.parse('1+x', {canonical: false}).isSame(ce.parse('x+1', {canonical: false}))` is `false`.
|
|
676
971
|
*
|
|
677
|
-
*
|
|
678
|
-
*/
|
|
679
|
-
readonly re: number;
|
|
680
|
-
/**
|
|
681
|
-
* If this expression is a number literal or a symbol with a value that
|
|
682
|
-
* is a number literal, return the imaginary part of the value. If the value
|
|
683
|
-
* is a real number, the imaginary part is 0.
|
|
972
|
+
* See `expr.isEqual()` for mathematical equality.
|
|
684
973
|
*
|
|
685
|
-
*
|
|
686
|
-
*
|
|
974
|
+
* :::info[Note]
|
|
975
|
+
* Applicable to canonical and non-canonical expressions.
|
|
976
|
+
* :::
|
|
687
977
|
*
|
|
688
|
-
* @category
|
|
978
|
+
* @category Relational Operator
|
|
689
979
|
*/
|
|
690
|
-
|
|
980
|
+
isSame(rhs: BoxedExpression): boolean;
|
|
691
981
|
/**
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
* If the value is not available as a bignum return `undefined`. That is,
|
|
696
|
-
* the value is not upconverted to a bignum.
|
|
697
|
-
*
|
|
698
|
-
* To get the real value either as a bignum or a number, use
|
|
699
|
-
* `this.bignumRe ?? this.re`. When using this pattern, the value is
|
|
700
|
-
* returned as a bignum if available, otherwise as a number or NaN if
|
|
701
|
-
* the value is not a number literal or a symbol with a value that is a
|
|
702
|
-
* number literal.
|
|
982
|
+
* Equivalent to `BoxedExpression.isSame()` but the argument can be
|
|
983
|
+
* a JavaScript primitive. For example, `expr.is(2)` is equivalent to
|
|
984
|
+
* `expr.isSame(ce.number(2))`.
|
|
703
985
|
*
|
|
704
|
-
* @category
|
|
986
|
+
* @category Primitive Methods
|
|
705
987
|
*
|
|
706
988
|
*/
|
|
707
|
-
|
|
989
|
+
is(other: BoxedExpression | number | bigint | boolean | string): boolean;
|
|
708
990
|
/**
|
|
709
|
-
* If this expression
|
|
710
|
-
* `
|
|
991
|
+
* If this expression matches `pattern`, return a substitution that makes
|
|
992
|
+
* `pattern` equal to `this`. Otherwise return `null`.
|
|
711
993
|
*
|
|
712
|
-
*
|
|
994
|
+
* If `pattern` includes wildcards (symbols that start
|
|
995
|
+
* with `_`), the substitution will include a prop for each matching named
|
|
996
|
+
* wildcard.
|
|
997
|
+
*
|
|
998
|
+
* If this expression matches `pattern` but there are no named wildcards,
|
|
999
|
+
* return the empty substitution, `{}`.
|
|
713
1000
|
*
|
|
714
|
-
*
|
|
715
|
-
* as a bignum return `undefined`. That is, the value is not upconverted
|
|
716
|
-
* to a bignum.
|
|
1001
|
+
* Read more about [**patterns and rules**](/compute-engine/guides/patterns-and-rules/).
|
|
717
1002
|
*
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
*
|
|
721
|
-
* the value is not a number literal or a symbol with a value that is a
|
|
722
|
-
* number literal.
|
|
1003
|
+
* :::info[Note]
|
|
1004
|
+
* Applicable to canonical and non-canonical expressions.
|
|
1005
|
+
* :::
|
|
723
1006
|
*
|
|
724
|
-
* @category Numeric Expression
|
|
725
1007
|
*/
|
|
726
|
-
|
|
727
|
-
/**
|
|
728
|
-
*
|
|
729
|
-
* canonical expression such that `rest.mul(c)` is equal to `this`.
|
|
1008
|
+
match(pattern: BoxedExpression, options?: PatternMatchOptions): BoxedSubstitution | null;
|
|
1009
|
+
/** If this expression is a tensor, return the tensor data.
|
|
1010
|
+
* Otherwise, return `null`.
|
|
730
1011
|
*
|
|
731
|
-
*
|
|
1012
|
+
* :::info[Note]
|
|
1013
|
+
* Applicable to canonical and non-canonical expressions.
|
|
1014
|
+
* :::
|
|
732
1015
|
*
|
|
733
|
-
|
|
734
|
-
* ['Multiply', 2, 'x', 3, 'a']
|
|
735
|
-
* -> [NumericValue(6), ['Multiply', 'x', 'a']]
|
|
1016
|
+
* @category Tensor Expression
|
|
736
1017
|
*
|
|
737
|
-
* ['Divide', ['Multiply', 2, 'x'], ['Multiply', 3, 'y', 'a']]
|
|
738
|
-
* -> [NumericValue({rational: [2, 3]}), ['Divide', 'x', ['Multiply, 'y', 'a']]]
|
|
739
|
-
* ```
|
|
740
1018
|
*/
|
|
741
|
-
|
|
742
|
-
neg(): BoxedExpression;
|
|
743
|
-
inv(): BoxedExpression;
|
|
744
|
-
abs(): BoxedExpression;
|
|
745
|
-
add(rhs: number | BoxedExpression): BoxedExpression;
|
|
746
|
-
sub(rhs: BoxedExpression): BoxedExpression;
|
|
747
|
-
mul(rhs: NumericValue | number | BoxedExpression): BoxedExpression;
|
|
748
|
-
div(rhs: number | BoxedExpression): BoxedExpression;
|
|
749
|
-
pow(exp: number | BoxedExpression): BoxedExpression;
|
|
750
|
-
root(exp: number | BoxedExpression): BoxedExpression;
|
|
751
|
-
sqrt(): BoxedExpression;
|
|
752
|
-
ln(base?: number | BoxedExpression): BoxedExpression;
|
|
1019
|
+
readonly tensor: null | Tensor<any>;
|
|
753
1020
|
/**
|
|
754
1021
|
*
|
|
755
|
-
* The shape describes the
|
|
1022
|
+
* The **shape** describes the **axes** of the expression, where each axis
|
|
1023
|
+
* represent a way to index the elements of the expression.
|
|
756
1024
|
*
|
|
757
1025
|
* When the expression is a scalar (number), the shape is `[]`.
|
|
758
1026
|
*
|
|
759
1027
|
* When the expression is a vector of length `n`, the shape is `[n]`.
|
|
760
1028
|
*
|
|
761
1029
|
* When the expression is a `n` by `m` matrix, the shape is `[n, m]`.
|
|
1030
|
+
*
|
|
1031
|
+
* @category Tensor Expression
|
|
1032
|
+
*
|
|
762
1033
|
*/
|
|
763
1034
|
readonly shape: number[];
|
|
764
|
-
/** Return 0 for a scalar, 1 for a vector, 2 for a matrix, > 2 for
|
|
765
|
-
* a multidimensional matrix.
|
|
766
|
-
*
|
|
767
|
-
* The rank is equivalent to the length of `expr.shape` */
|
|
768
|
-
readonly rank: number;
|
|
769
1035
|
/**
|
|
770
|
-
*
|
|
1036
|
+
* The **rank** refers to the number of dimensions (or axes) of the
|
|
1037
|
+
* expression.
|
|
771
1038
|
*
|
|
772
|
-
*
|
|
773
|
-
*
|
|
774
|
-
* imaginary part), `this.sgn` will return `unsigned`.
|
|
1039
|
+
* Return 0 for a scalar, 1 for a vector, 2 for a matrix, > 2 for
|
|
1040
|
+
* a multidimensional matrix.
|
|
775
1041
|
*
|
|
776
|
-
*
|
|
777
|
-
* will return `positive` if the symbol is assumed to be positive
|
|
778
|
-
* (using `ce.assume()`).
|
|
1042
|
+
* The rank is equivalent to the length of `expr.shape`
|
|
779
1043
|
*
|
|
780
|
-
*
|
|
1044
|
+
* :::info[Note]
|
|
1045
|
+
* There are several definitions of rank in the literature.
|
|
1046
|
+
* For example, the row rank of a matrix is the number of linearly
|
|
1047
|
+
* independent rows. The rank can also refer to the number of non-zero
|
|
1048
|
+
* singular values of a matrix.
|
|
1049
|
+
* :::
|
|
781
1050
|
*
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
1051
|
+
* @category Tensor Expression
|
|
1052
|
+
* */
|
|
1053
|
+
readonly rank: number;
|
|
1054
|
+
/**
|
|
785
1055
|
*
|
|
786
|
-
* The
|
|
1056
|
+
* The value of both expressions are compared.
|
|
787
1057
|
*
|
|
788
|
-
*
|
|
789
|
-
* expensive.
|
|
1058
|
+
* If the expressions cannot be compared, return `undefined`
|
|
790
1059
|
*
|
|
791
1060
|
* @category Relational Operator
|
|
792
1061
|
*/
|
|
793
1062
|
isLess(other: number | BoxedExpression): boolean | undefined;
|
|
794
1063
|
/**
|
|
795
|
-
* The
|
|
1064
|
+
* The value of both expressions are compared.
|
|
1065
|
+
*
|
|
1066
|
+
* If the expressions cannot be compared, return `undefined`
|
|
796
1067
|
* @category Relational Operator
|
|
797
1068
|
*/
|
|
798
1069
|
isLessEqual(other: number | BoxedExpression): boolean | undefined;
|
|
799
1070
|
/**
|
|
800
|
-
* The
|
|
1071
|
+
* The value of both expressions are compared.
|
|
1072
|
+
*
|
|
1073
|
+
* If the expressions cannot be compared, return `undefined`
|
|
801
1074
|
* @category Relational Operator
|
|
802
1075
|
*/
|
|
803
1076
|
isGreater(other: number | BoxedExpression): boolean | undefined;
|
|
804
1077
|
/**
|
|
805
|
-
* The
|
|
1078
|
+
* The value of both expressions are compared.
|
|
1079
|
+
*
|
|
1080
|
+
* If the expressions cannot be compared, return `undefined`
|
|
806
1081
|
* @category Relational Operator
|
|
807
1082
|
*/
|
|
808
1083
|
isGreaterEqual(other: number | BoxedExpression): boolean | undefined;
|
|
809
|
-
/**
|
|
1084
|
+
/**
|
|
1085
|
+
* If true, the value of this expression is "Not a Number".
|
|
810
1086
|
*
|
|
811
|
-
*
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
1087
|
+
* A value representing undefined result of computations, such as `0/0`,
|
|
1088
|
+
* as per the floating point format standard IEEE-754.
|
|
1089
|
+
*
|
|
1090
|
+
* Note that if `isNaN` is true, `isNumber` is also true (yes, `NaN` is a
|
|
1091
|
+
* number).
|
|
815
1092
|
*
|
|
816
1093
|
* @category Numeric Expression
|
|
1094
|
+
*
|
|
817
1095
|
*/
|
|
818
|
-
readonly
|
|
819
|
-
/**
|
|
1096
|
+
readonly isNaN: boolean | undefined;
|
|
1097
|
+
/**
|
|
1098
|
+
* The numeric value of this expression is `±Infinity` or ComplexInfinity.
|
|
820
1099
|
*
|
|
821
1100
|
* @category Numeric Expression
|
|
822
1101
|
*/
|
|
823
|
-
readonly
|
|
824
|
-
/**
|
|
1102
|
+
readonly isInfinity: boolean | undefined;
|
|
1103
|
+
/** This expression is a number, but not `±Infinity`, `ComplexInfinity` or
|
|
1104
|
+
* `NaN`
|
|
825
1105
|
*
|
|
826
1106
|
* @category Numeric Expression
|
|
827
1107
|
*/
|
|
828
|
-
readonly
|
|
829
|
-
/**
|
|
1108
|
+
readonly isFinite: boolean | undefined;
|
|
1109
|
+
/**
|
|
1110
|
+
* Wikidata identifier.
|
|
1111
|
+
*
|
|
1112
|
+
* If not a canonical expression, return `undefined`.
|
|
830
1113
|
*
|
|
831
|
-
* :::info[Note]
|
|
832
|
-
* `undefined` if not a canonical expression.
|
|
833
|
-
* :::
|
|
834
1114
|
*/
|
|
835
1115
|
readonly wikidata: string | undefined;
|
|
836
1116
|
/** An optional short description if a symbol or function expression.
|
|
837
1117
|
*
|
|
838
1118
|
* May include markdown. Each string is a paragraph.
|
|
839
1119
|
*
|
|
840
|
-
*
|
|
841
|
-
* `undefined` if not a canonical expression.
|
|
842
|
-
* :::
|
|
1120
|
+
* If not a canonical expression, return `undefined`.
|
|
843
1121
|
*
|
|
844
1122
|
*/
|
|
845
1123
|
readonly description: undefined | string[];
|
|
846
1124
|
/** An optional URL pointing to more information about the symbol or
|
|
847
1125
|
* function operator.
|
|
848
1126
|
*
|
|
849
|
-
*
|
|
850
|
-
* `undefined` if not a canonical expression.
|
|
851
|
-
* :::
|
|
1127
|
+
* If not a canonical expression, return `undefined`.
|
|
852
1128
|
*
|
|
853
1129
|
*/
|
|
854
1130
|
readonly url: string | undefined;
|
|
855
1131
|
/** Expressions with a higher complexity score are sorted
|
|
856
1132
|
* first in commutative functions
|
|
857
1133
|
*
|
|
858
|
-
*
|
|
859
|
-
* `undefined` if not a canonical expression.
|
|
860
|
-
* :::
|
|
1134
|
+
* If not a canonical expression, return `undefined`.
|
|
861
1135
|
*/
|
|
862
1136
|
readonly complexity: number | undefined;
|
|
863
1137
|
/**
|
|
864
1138
|
* For symbols and functions, a definition associated with the
|
|
865
|
-
*
|
|
866
|
-
*
|
|
1139
|
+
* expression. `this.baseDefinition` is the base class of symbol and function
|
|
1140
|
+
* definition.
|
|
867
1141
|
*
|
|
868
|
-
*
|
|
869
|
-
* `undefined` if not a canonical expression.
|
|
870
|
-
* :::
|
|
1142
|
+
* If not a canonical expression, return `undefined`.
|
|
871
1143
|
*
|
|
872
1144
|
*/
|
|
873
1145
|
readonly baseDefinition: BoxedBaseDefinition | undefined;
|
|
874
1146
|
/**
|
|
875
|
-
* For
|
|
1147
|
+
* For function expressions, the definition of the operator associated with
|
|
1148
|
+
* the expression. For symbols, the definition of the symbol if it is an
|
|
1149
|
+
* operator, for example `"Sin"`.
|
|
876
1150
|
*
|
|
877
|
-
*
|
|
878
|
-
*
|
|
879
|
-
* :::
|
|
1151
|
+
* If not a canonical expression or not a function expression,
|
|
1152
|
+
* its value is `undefined`.
|
|
880
1153
|
*
|
|
881
1154
|
*/
|
|
882
|
-
readonly
|
|
1155
|
+
readonly operatorDefinition: BoxedOperatorDefinition | undefined;
|
|
883
1156
|
/**
|
|
884
|
-
* For symbols, a definition associated with the expression
|
|
1157
|
+
* For symbols, a definition associated with the expression, if it is
|
|
1158
|
+
* not an operator.
|
|
885
1159
|
*
|
|
886
|
-
*
|
|
1160
|
+
* If not a canonical expression, or not a value, its value is `undefined`.
|
|
887
1161
|
*
|
|
888
1162
|
*/
|
|
889
|
-
readonly
|
|
1163
|
+
readonly valueDefinition: BoxedValueDefinition | undefined;
|
|
890
1164
|
/**
|
|
891
1165
|
*
|
|
892
1166
|
* Infer the type of this expression.
|
|
893
1167
|
*
|
|
894
|
-
*
|
|
1168
|
+
* For symbols, inference may take place for undeclared symbols,
|
|
1169
|
+
* symbols with an `unknown` type, or symbols with an inferred type.
|
|
895
1170
|
*
|
|
896
|
-
*
|
|
897
|
-
*
|
|
1171
|
+
* Constant symbols always have a defined type, and will return `false`.
|
|
1172
|
+
*
|
|
1173
|
+
* For functions, inference only takes place if it has an *inferred
|
|
1174
|
+
* signature*.
|
|
1175
|
+
*
|
|
1176
|
+
*
|
|
1177
|
+
* For a successful inference, *narrows* the type for symbols,
|
|
1178
|
+
* and for functions, narrows the *(return) type*.
|
|
1179
|
+
*
|
|
1180
|
+
* Subsequent inferences can be made and will refine previous ones if valid.
|
|
1181
|
+
*
|
|
1182
|
+
* If the given type is incompatible with the declared or previously inferred
|
|
1183
|
+
* type, return `false`.
|
|
898
1184
|
*
|
|
899
|
-
* If the type cannot be inferred, return `false`.
|
|
900
1185
|
*
|
|
901
1186
|
* @internal
|
|
902
1187
|
*/
|
|
903
|
-
infer(t: Type): boolean;
|
|
1188
|
+
infer(t: Type, inferenceMode?: 'narrow' | 'widen'): boolean;
|
|
904
1189
|
/**
|
|
905
1190
|
* Update the definition associated with this expression, using the
|
|
906
1191
|
* current scope (`ce.context`).
|
|
@@ -947,23 +1232,18 @@ export interface BoxedExpression {
|
|
|
947
1232
|
/**
|
|
948
1233
|
* Return the value of the canonical form of this expression.
|
|
949
1234
|
*
|
|
950
|
-
* A pure expression always
|
|
951
|
-
*
|
|
952
|
-
*
|
|
953
|
-
*
|
|
954
|
-
* For an impure expression, `expr.value` is undefined.
|
|
955
|
-
*
|
|
956
|
-
* Evaluating an impure expression may have some side effects, for
|
|
957
|
-
* example modifying the `ComputeEngine` environment, such as its set of
|
|
958
|
-
* assumptions.
|
|
1235
|
+
* A pure expression always returns the same value (provided that it
|
|
1236
|
+
* remains constant / values of sub-expressions or symbols do not change),
|
|
1237
|
+
* and has no side effects.
|
|
959
1238
|
*
|
|
960
|
-
*
|
|
961
|
-
*
|
|
1239
|
+
* Evaluating an impure expression may return a varying value, and may have
|
|
1240
|
+
* some side effects such as adjusting symbol assumptions.
|
|
962
1241
|
*
|
|
963
1242
|
* To perform approximate calculations, use `expr.N()` instead,
|
|
964
|
-
* or
|
|
1243
|
+
* or call with `options.numericApproximation` to `true`.
|
|
965
1244
|
*
|
|
966
|
-
*
|
|
1245
|
+
* It is possible that the result of `expr.evaluate()` may be the same as
|
|
1246
|
+
* `expr.simplify()`.
|
|
967
1247
|
*
|
|
968
1248
|
* The result is in canonical form.
|
|
969
1249
|
*
|
|
@@ -1000,72 +1280,101 @@ export interface BoxedExpression {
|
|
|
1000
1280
|
*
|
|
1001
1281
|
*
|
|
1002
1282
|
* ```javascript
|
|
1003
|
-
* const expr = ce.parse(
|
|
1283
|
+
* const expr = ce.parse("x^2 + y^2");
|
|
1004
1284
|
* const f = expr.compile();
|
|
1005
1285
|
* console.log(f({x: 2, y: 3}));
|
|
1286
|
+
* // -> 13
|
|
1006
1287
|
* ```
|
|
1288
|
+
*
|
|
1289
|
+
* If the expression is a function literal, the function takes the
|
|
1290
|
+
* arguments of the function as arguments, and returns the value of the
|
|
1291
|
+
* expression.
|
|
1292
|
+
*
|
|
1293
|
+
* ```javascript
|
|
1294
|
+
* const expr = ce.parse("(x) \mapsto 2x");
|
|
1295
|
+
* const f = expr.compile();
|
|
1296
|
+
* console.log(f(42));
|
|
1297
|
+
* // -> 84
|
|
1298
|
+
* ```
|
|
1299
|
+
*
|
|
1300
|
+
* If the expression cannot be compiled, a JS function is returned that
|
|
1301
|
+
* falls back to the interpreting the expression, unless the
|
|
1302
|
+
* `options.fallback` is set to `false`. If it is set to `false`, the
|
|
1303
|
+
* function will throw an error if it cannot be compiled.
|
|
1304
|
+
*
|
|
1007
1305
|
*/
|
|
1008
1306
|
compile(options?: {
|
|
1009
1307
|
to?: 'javascript';
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
imports?: unknown[];
|
|
1308
|
+
functions?: Record<MathJsonSymbol, JSSource | ((...any: any[]) => any)>;
|
|
1309
|
+
vars?: Record<MathJsonSymbol, CompiledType>;
|
|
1310
|
+
imports?: ((...any: any[]) => any)[];
|
|
1014
1311
|
preamble?: string;
|
|
1015
|
-
|
|
1312
|
+
fallback?: boolean;
|
|
1313
|
+
}): ((...args: any[]) => any) & {
|
|
1314
|
+
isCompiled?: boolean;
|
|
1315
|
+
};
|
|
1016
1316
|
/**
|
|
1017
1317
|
* If this is an equation, solve the equation for the variables in vars.
|
|
1018
1318
|
* Otherwise, solve the equation `this = 0` for the variables in vars.
|
|
1019
1319
|
*
|
|
1020
1320
|
*
|
|
1021
1321
|
* ```javascript
|
|
1022
|
-
* const expr = ce.parse(
|
|
1023
|
-
* console.log(expr.solve(
|
|
1322
|
+
* const expr = ce.parse("x^2 + 2*x + 1 = 0");
|
|
1323
|
+
* console.log(expr.solve("x"));
|
|
1024
1324
|
* ```
|
|
1025
1325
|
*
|
|
1026
1326
|
*
|
|
1027
1327
|
*/
|
|
1028
1328
|
solve(vars?: Iterable<string> | string | BoxedExpression | Iterable<BoxedExpression>): null | ReadonlyArray<BoxedExpression>;
|
|
1029
1329
|
/**
|
|
1030
|
-
*
|
|
1330
|
+
* If this expression is a number literal, a string literal or a function
|
|
1331
|
+
* literal, return the expression.
|
|
1031
1332
|
*
|
|
1032
|
-
*
|
|
1333
|
+
* If the expression is a symbol, return the value of the symbol.
|
|
1334
|
+
*
|
|
1335
|
+
* Otherwise, the expression is a symbolic expression, including an unknown
|
|
1336
|
+
* symbol, i.e. a symbol with no value, return `undefined`.
|
|
1033
1337
|
*
|
|
1034
1338
|
*/
|
|
1035
|
-
get value():
|
|
1339
|
+
get value(): BoxedExpression | undefined;
|
|
1036
1340
|
/**
|
|
1037
|
-
*
|
|
1038
|
-
* constants).
|
|
1341
|
+
* If the expression is a symbol, set the value of the symbol.
|
|
1039
1342
|
*
|
|
1040
|
-
*
|
|
1343
|
+
* Will throw a runtime error if either not a symbol, or a symbol with the
|
|
1344
|
+
* `constant` flag set to `true`.
|
|
1041
1345
|
*
|
|
1042
|
-
*
|
|
1043
|
-
*
|
|
1044
|
-
* :::
|
|
1346
|
+
* Setting the value of a symbol results in the forgetting of all assumptions
|
|
1347
|
+
* about it in the current scope.
|
|
1045
1348
|
*
|
|
1046
1349
|
*/
|
|
1047
|
-
set value(value: boolean | string | BigNum |
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1350
|
+
set value(value: boolean | string | BigNum | OneOf<[
|
|
1351
|
+
{
|
|
1352
|
+
re: number;
|
|
1353
|
+
im: number;
|
|
1354
|
+
},
|
|
1355
|
+
{
|
|
1356
|
+
num: number;
|
|
1357
|
+
denom: number;
|
|
1358
|
+
},
|
|
1359
|
+
BoxedExpression
|
|
1360
|
+
]> | number[] | number | undefined);
|
|
1054
1361
|
/**
|
|
1055
1362
|
*
|
|
1056
1363
|
* The type of the value of this expression.
|
|
1057
1364
|
*
|
|
1365
|
+
* If a symbol the type of the value of the symbol.
|
|
1366
|
+
*
|
|
1058
1367
|
* If a function expression, the type of the value of the function
|
|
1059
1368
|
* (the result type).
|
|
1060
1369
|
*
|
|
1061
|
-
* If a symbol
|
|
1370
|
+
* If a symbol with a `"function"` type (a function literal), returns the
|
|
1371
|
+
* signature.
|
|
1062
1372
|
*
|
|
1063
|
-
* :::info[Note]
|
|
1064
1373
|
* If not valid, return `"error"`.
|
|
1065
|
-
*
|
|
1374
|
+
*
|
|
1066
1375
|
* If the type is not known, return `"unknown"`.
|
|
1067
|
-
* :::
|
|
1068
1376
|
*
|
|
1377
|
+
* @category Type Properties
|
|
1069
1378
|
*/
|
|
1070
1379
|
get type(): BoxedType;
|
|
1071
1380
|
set type(type: Type | TypeString | BoxedType);
|
|
@@ -1128,9 +1437,10 @@ export interface BoxedExpression {
|
|
|
1128
1437
|
* considered equal. This tolerance is set when the `engine.precision` is
|
|
1129
1438
|
* changed to be such that the last two digits are ignored.
|
|
1130
1439
|
*
|
|
1131
|
-
*
|
|
1440
|
+
* Evaluating the expressions may be expensive. Other options to consider
|
|
1132
1441
|
* to compare two expressions include:
|
|
1133
|
-
* - `expr.isSame(other)` for a structural comparison
|
|
1442
|
+
* - `expr.isSame(other)` for a structural comparison which does not involve
|
|
1443
|
+
* evaluating the expressions.
|
|
1134
1444
|
* - `expr.is(other)` for a comparison of a number literal
|
|
1135
1445
|
*
|
|
1136
1446
|
* **Examples**
|
|
@@ -1152,29 +1462,51 @@ export interface BoxedExpression {
|
|
|
1152
1462
|
*/
|
|
1153
1463
|
isEqual(other: number | BoxedExpression): boolean | undefined;
|
|
1154
1464
|
/**
|
|
1155
|
-
*
|
|
1465
|
+
* Is `true` if the expression is a collection.
|
|
1466
|
+
*
|
|
1467
|
+
* When `isCollection` is `true`, the expression:
|
|
1468
|
+
*
|
|
1469
|
+
* - has an `each()` method that returns a generator over the elements
|
|
1470
|
+
* of the collection.
|
|
1471
|
+
* - has a `size` property that returns the number of elements in the
|
|
1472
|
+
* collection.
|
|
1473
|
+
* - has a `contains(other)` method that returns `true` if the `other`
|
|
1474
|
+
* expression is in the collection.
|
|
1475
|
+
*
|
|
1156
1476
|
*/
|
|
1157
1477
|
isCollection: boolean;
|
|
1158
1478
|
/**
|
|
1159
|
-
*
|
|
1160
|
-
*
|
|
1479
|
+
* Is `true` if this is an indexed collection, such as a list, a vector,
|
|
1480
|
+
* a matrix, a tuple, etc...
|
|
1161
1481
|
*
|
|
1162
|
-
*
|
|
1482
|
+
* The elements of an indexed collection can be accessed by a one-based
|
|
1483
|
+
* index.
|
|
1484
|
+
*
|
|
1485
|
+
* When `isIndexedCollection` is `true`, the expression:
|
|
1486
|
+
* - has an `each()`, `size()` and `contains(rhs)` methods
|
|
1487
|
+
* as for a collection.
|
|
1488
|
+
* - has an `at(index: number)` method that returns the element at the
|
|
1489
|
+
* specified index.
|
|
1490
|
+
* - has an `indexWhere(predicate: (element: BoxedExpression) => boolean)`
|
|
1491
|
+
* method that returns the index of the first element that matches the
|
|
1492
|
+
* predicate.
|
|
1163
1493
|
*/
|
|
1164
|
-
|
|
1494
|
+
isIndexedCollection: boolean;
|
|
1165
1495
|
/**
|
|
1166
|
-
*
|
|
1496
|
+
* False if not a collection, or if the elements of the collection
|
|
1497
|
+
* are not computed lazily.
|
|
1167
1498
|
*
|
|
1168
|
-
*
|
|
1499
|
+
* The elements of a lazy collection are computed on demand, when
|
|
1500
|
+
* iterating over the collection using `each()`.
|
|
1501
|
+
*
|
|
1502
|
+
* Use `ListFrom` and related functions to create eager collections from
|
|
1503
|
+
* lazy collections.
|
|
1169
1504
|
*
|
|
1170
1505
|
*/
|
|
1171
|
-
|
|
1506
|
+
isLazyCollection: boolean;
|
|
1172
1507
|
/**
|
|
1173
|
-
* If this is a collection, return an iterator over the elements of the
|
|
1174
|
-
*
|
|
1175
|
-
* If `start` is not specified, start from the first element.
|
|
1176
|
-
*
|
|
1177
|
-
* If `count` is not specified or negative, return all the elements from `start` to the end.
|
|
1508
|
+
* If this is a collection, return an iterator over the elements of the
|
|
1509
|
+
* collection.
|
|
1178
1510
|
*
|
|
1179
1511
|
* ```js
|
|
1180
1512
|
* const expr = ce.parse('[1, 2, 3, 4]');
|
|
@@ -1183,25 +1515,62 @@ export interface BoxedExpression {
|
|
|
1183
1515
|
* }
|
|
1184
1516
|
* ```
|
|
1185
1517
|
*/
|
|
1186
|
-
each
|
|
1187
|
-
/**
|
|
1188
|
-
*
|
|
1518
|
+
each(): Generator<BoxedExpression>;
|
|
1519
|
+
/**
|
|
1520
|
+
* If this is a collection, return true if the `rhs` expression is in the
|
|
1521
|
+
* collection.
|
|
1522
|
+
*
|
|
1523
|
+
* Return `undefined` if the membership cannot be determined without
|
|
1524
|
+
* iterating over the collection.
|
|
1525
|
+
*/
|
|
1526
|
+
xcontains(rhs: BoxedExpression): boolean | undefined;
|
|
1527
|
+
/**
|
|
1528
|
+
* Check if this collection is a subset of another collection.
|
|
1529
|
+
*
|
|
1530
|
+
* @param other The other collection to check against.
|
|
1531
|
+
* @param strict If true, the subset relation is strict (i.e., proper subset).
|
|
1532
|
+
*/
|
|
1533
|
+
subsetOf(other: BoxedExpression, strict: boolean): boolean | undefined;
|
|
1534
|
+
/**
|
|
1535
|
+
* If this is a collection, return the number of elements in the collection.
|
|
1536
|
+
*
|
|
1537
|
+
* If the collection is infinite, return `Infinity`.
|
|
1538
|
+
*
|
|
1539
|
+
* If the number of elements cannot be determined, return `undefined`, for
|
|
1540
|
+
* example, if the collection is lazy and not finite and the size cannot
|
|
1541
|
+
* be determined without iterating over the collection.
|
|
1542
|
+
*
|
|
1543
|
+
*/
|
|
1544
|
+
get xsize(): number | undefined;
|
|
1545
|
+
/** If this is a finite collection, return true. */
|
|
1546
|
+
isFiniteCollection: boolean | undefined;
|
|
1547
|
+
/** If this is an empty collection, return true.
|
|
1548
|
+
*
|
|
1549
|
+
* An empty collection has a size of 0.
|
|
1550
|
+
*/
|
|
1551
|
+
isEmptyCollection: boolean | undefined;
|
|
1552
|
+
/** If this is an indexed collection, return the element at the specified
|
|
1553
|
+
* index. The first element is at index 1.
|
|
1189
1554
|
*
|
|
1190
1555
|
* If the index is negative, return the element at index `size() + index + 1`.
|
|
1191
1556
|
*
|
|
1557
|
+
* The last element is at index -1.
|
|
1558
|
+
*
|
|
1192
1559
|
*/
|
|
1193
1560
|
at(index: number): BoxedExpression | undefined;
|
|
1194
|
-
/** If this is a map
|
|
1561
|
+
/** If this is a keyed collection (map, record, tuple), return the value of
|
|
1562
|
+
* the corresponding key.
|
|
1195
1563
|
*
|
|
1196
1564
|
* If `key` is a `BoxedExpression`, it should be a string.
|
|
1197
1565
|
*
|
|
1198
1566
|
*/
|
|
1199
1567
|
get(key: string | BoxedExpression): BoxedExpression | undefined;
|
|
1200
1568
|
/**
|
|
1201
|
-
* If this is an
|
|
1202
|
-
* that matches the
|
|
1569
|
+
* If this is an indexed collection, return the index of the first element
|
|
1570
|
+
* that matches the predicate.
|
|
1571
|
+
*
|
|
1203
1572
|
*/
|
|
1204
|
-
|
|
1573
|
+
indexWhere(predicate: (element: BoxedExpression) => boolean): number | undefined;
|
|
1205
1574
|
}
|
|
1206
1575
|
/** A semi boxed expression is a MathJSON expression which can include some
|
|
1207
1576
|
* boxed terms.
|
|
@@ -1211,7 +1580,17 @@ export interface BoxedExpression {
|
|
|
1211
1580
|
*
|
|
1212
1581
|
* @category Boxed Expression
|
|
1213
1582
|
*/
|
|
1214
|
-
export type SemiBoxedExpression = number | bigint | string | BigNum |
|
|
1583
|
+
export type SemiBoxedExpression = number | bigint | string | BigNum | MathJsonNumberObject | MathJsonStringObject | MathJsonSymbolObject | MathJsonFunctionObject | MathJsonDictionaryObject | readonly [MathJsonSymbol, ...SemiBoxedExpression[]] | BoxedExpression;
|
|
1584
|
+
/** Interface for dictionary-like structures.
|
|
1585
|
+
* Use `isDictionary()` to check if an expression is a dictionary.
|
|
1586
|
+
*/
|
|
1587
|
+
export interface DictionaryInterface {
|
|
1588
|
+
get(key: string): BoxedExpression | undefined;
|
|
1589
|
+
has(key: string): boolean;
|
|
1590
|
+
get keys(): string[];
|
|
1591
|
+
get entries(): [string, BoxedExpression][];
|
|
1592
|
+
get values(): BoxedExpression[];
|
|
1593
|
+
}
|
|
1215
1594
|
/**
|
|
1216
1595
|
* These handlers compare two expressions.
|
|
1217
1596
|
*
|
|
@@ -1341,7 +1720,7 @@ export type ReplaceOptions = {
|
|
|
1341
1720
|
useVariations: boolean;
|
|
1342
1721
|
/**
|
|
1343
1722
|
* If `iterationLimit` > 1, the rules will be repeatedly applied
|
|
1344
|
-
* until no rules apply, up to `
|
|
1723
|
+
* until no rules apply, up to `iterationLimit` times.
|
|
1345
1724
|
*
|
|
1346
1725
|
* Note that if `once` is true, `iterationLimit` has no effect.
|
|
1347
1726
|
*
|
|
@@ -1357,49 +1736,57 @@ export type ReplaceOptions = {
|
|
|
1357
1736
|
};
|
|
1358
1737
|
/**
|
|
1359
1738
|
* 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')
|
|
1739
|
+
* (e.g. ∀ x ∈ ℝ), a value (x = 5) or both (π: value = 3.14... type = 'real').
|
|
1740
|
+
*
|
|
1361
1741
|
* @category Definitions
|
|
1362
1742
|
*/
|
|
1363
|
-
export type
|
|
1364
|
-
|
|
1743
|
+
export type ValueDefinition = BaseDefinition & {
|
|
1744
|
+
holdUntil: 'never' | 'evaluate' | 'N';
|
|
1745
|
+
type: Type | TypeString | BoxedType;
|
|
1365
1746
|
/** If true, the type is inferred, and could be adjusted later
|
|
1366
1747
|
* as more information becomes available or if the symbol is explicitly
|
|
1367
1748
|
* declared.
|
|
1368
1749
|
*/
|
|
1369
|
-
inferred
|
|
1750
|
+
inferred: boolean;
|
|
1370
1751
|
/** `value` can be a JS function since for some constants, such as
|
|
1371
1752
|
* `Pi`, the actual value depends on the `precision` setting of the
|
|
1372
1753
|
* `ComputeEngine` and possible other environment settings */
|
|
1373
|
-
value
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
collection?: Partial<CollectionHandlers>;
|
|
1754
|
+
value: LatexString | SemiBoxedExpression | ((ce: ComputeEngine) => BoxedExpression | null);
|
|
1755
|
+
eq: (a: BoxedExpression) => boolean | undefined;
|
|
1756
|
+
neq: (a: BoxedExpression) => boolean | undefined;
|
|
1757
|
+
cmp: (a: BoxedExpression) => '=' | '>' | '<' | undefined;
|
|
1758
|
+
collection: CollectionHandlers;
|
|
1379
1759
|
};
|
|
1380
1760
|
/**
|
|
1381
1761
|
* Definition record for a function.
|
|
1382
1762
|
* @category Definitions
|
|
1383
1763
|
*
|
|
1384
1764
|
*/
|
|
1385
|
-
export type
|
|
1765
|
+
export type OperatorDefinition = Partial<BaseDefinition> & Partial<OperatorDefinitionFlags> & {
|
|
1386
1766
|
/**
|
|
1387
|
-
* The function signature
|
|
1767
|
+
* The function signature, describing the type of the arguments and the
|
|
1768
|
+
* return type.
|
|
1388
1769
|
*
|
|
1389
1770
|
* If a `type` handler is provided, the return type of the function should
|
|
1390
1771
|
* be a subtype of the return type in the signature.
|
|
1391
1772
|
*
|
|
1392
1773
|
*/
|
|
1393
|
-
signature?: Type | TypeString;
|
|
1774
|
+
signature?: Type | TypeString | BoxedType;
|
|
1394
1775
|
/**
|
|
1395
|
-
* The
|
|
1776
|
+
* The type of the result (return type) based on the type of
|
|
1777
|
+
* the arguments.
|
|
1778
|
+
*
|
|
1779
|
+
* Should be a subtype of the type indicated by the signature.
|
|
1396
1780
|
*
|
|
1397
|
-
*
|
|
1781
|
+
* For example, if the signature is `(number) -> real`, the type of the
|
|
1782
|
+
* result could be `real` or `integer`, but not `complex`.
|
|
1398
1783
|
*
|
|
1784
|
+
* :::info[Note]
|
|
1399
1785
|
* Do not evaluate the arguments.
|
|
1400
1786
|
*
|
|
1401
|
-
*
|
|
1402
|
-
* result.
|
|
1787
|
+
* However, the type of the arguments can be used to determine the type of
|
|
1788
|
+
* the result.
|
|
1789
|
+
* :::
|
|
1403
1790
|
*
|
|
1404
1791
|
*/
|
|
1405
1792
|
type?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
@@ -1414,14 +1801,36 @@ export type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlag
|
|
|
1414
1801
|
*
|
|
1415
1802
|
* Do not evaluate the arguments.
|
|
1416
1803
|
*
|
|
1417
|
-
*
|
|
1804
|
+
* However, the type and sign of the arguments can be used to determine the
|
|
1805
|
+
* sign.
|
|
1418
1806
|
*
|
|
1419
1807
|
*/
|
|
1420
1808
|
sgn?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
1421
1809
|
engine: ComputeEngine;
|
|
1422
1810
|
}) => Sign | undefined;
|
|
1423
|
-
/**
|
|
1424
|
-
*
|
|
1811
|
+
/** The value of this expression is > 0, same as `isGreater(0)`
|
|
1812
|
+
*
|
|
1813
|
+
* @category Numeric Expression
|
|
1814
|
+
*/
|
|
1815
|
+
readonly isPositive?: boolean | undefined;
|
|
1816
|
+
/** The value of this expression is >= 0, same as `isGreaterEqual(0)`
|
|
1817
|
+
*
|
|
1818
|
+
* @category Numeric Expression
|
|
1819
|
+
*/
|
|
1820
|
+
readonly isNonNegative?: boolean | undefined;
|
|
1821
|
+
/** The value of this expression is < 0, same as `isLess(0)`
|
|
1822
|
+
*
|
|
1823
|
+
* @category Numeric Expression
|
|
1824
|
+
*/
|
|
1825
|
+
readonly isNegative?: boolean | undefined;
|
|
1826
|
+
/** The value of this expression is <= 0, same as `isLessEqual(0)`
|
|
1827
|
+
*
|
|
1828
|
+
* @category Numeric Expression
|
|
1829
|
+
*/
|
|
1830
|
+
readonly isNonPositive?: boolean | undefined;
|
|
1831
|
+
/** Return `true` if the function expression is even, `false` if it is odd
|
|
1832
|
+
* and `undefined` if it is neither (for example if it is not a number,
|
|
1833
|
+
* or if it is a complex number).
|
|
1425
1834
|
*/
|
|
1426
1835
|
even?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
1427
1836
|
engine: ComputeEngine;
|
|
@@ -1453,12 +1862,13 @@ export type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlag
|
|
|
1453
1862
|
* The arguments (`args`) may not be in canonical form. If necessary, they
|
|
1454
1863
|
* can be put in canonical form.
|
|
1455
1864
|
*
|
|
1456
|
-
* This handler should validate the type and number of the arguments
|
|
1865
|
+
* This handler should validate the type and number of the arguments
|
|
1866
|
+
* (arity).
|
|
1457
1867
|
*
|
|
1458
1868
|
* If a required argument is missing, it should be indicated with a
|
|
1459
1869
|
* `["Error", "'missing"]` expression. If more arguments than expected
|
|
1460
1870
|
* are present, this should be indicated with an
|
|
1461
|
-
* ["Error", "'unexpected-argument'"]` error expression
|
|
1871
|
+
* `["Error", "'unexpected-argument'"]` error expression
|
|
1462
1872
|
*
|
|
1463
1873
|
* If the type of an argument is not compatible, it should be indicated
|
|
1464
1874
|
* with an `incompatible-type` error.
|
|
@@ -1480,19 +1890,20 @@ export type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlag
|
|
|
1480
1890
|
*
|
|
1481
1891
|
* The result of the handler should be a canonical expression.
|
|
1482
1892
|
*
|
|
1483
|
-
* If the arguments do not match, they should be replaced with an
|
|
1484
|
-
* `["Error"]` expression. If the expression cannot be put in
|
|
1485
|
-
* the handler should return `null`.
|
|
1893
|
+
* If the arguments do not match, they should be replaced with an
|
|
1894
|
+
* appropriate `["Error"]` expression. If the expression cannot be put in
|
|
1895
|
+
* canonical form, the handler should return `null`.
|
|
1486
1896
|
*
|
|
1487
1897
|
*/
|
|
1488
1898
|
canonical?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
1489
1899
|
engine: ComputeEngine;
|
|
1900
|
+
scope: Scope | undefined;
|
|
1490
1901
|
}) => BoxedExpression | null;
|
|
1491
1902
|
/**
|
|
1492
1903
|
* Evaluate a function expression.
|
|
1493
1904
|
*
|
|
1494
|
-
*
|
|
1495
|
-
* `
|
|
1905
|
+
* When the handler is invoked, the arguments have been evaluated, except
|
|
1906
|
+
* if the `lazy` option is set to `true`.
|
|
1496
1907
|
*
|
|
1497
1908
|
* It is not necessary to further simplify or evaluate the arguments.
|
|
1498
1909
|
*
|
|
@@ -1501,19 +1912,15 @@ export type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlag
|
|
|
1501
1912
|
* number or a square root, rather than a floating point approximation.
|
|
1502
1913
|
* Use `ce.number()` to create the numeric value.
|
|
1503
1914
|
*
|
|
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
1915
|
* If the expression cannot be evaluated, due to the values, types, or
|
|
1509
|
-
* assumptions about its arguments,
|
|
1916
|
+
* assumptions about its arguments, return `undefined` or
|
|
1510
1917
|
* an `["Error"]` expression.
|
|
1511
1918
|
*/
|
|
1512
1919
|
evaluate?: ((ops: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
|
|
1513
1920
|
engine: ComputeEngine;
|
|
1514
1921
|
}) => BoxedExpression | undefined) | BoxedExpression;
|
|
1515
1922
|
/**
|
|
1516
|
-
* An
|
|
1923
|
+
* An asynchronous version of `evaluate`.
|
|
1517
1924
|
*
|
|
1518
1925
|
*/
|
|
1519
1926
|
evaluateAsync?: (ops: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
|
|
@@ -1526,28 +1933,44 @@ export type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlag
|
|
|
1526
1933
|
engine: ComputeEngine;
|
|
1527
1934
|
}) => BoxedExpression;
|
|
1528
1935
|
/** Return a compiled (optimized) expression. */
|
|
1529
|
-
|
|
1936
|
+
xcompile?: (expr: BoxedExpression) => CompiledExpression;
|
|
1530
1937
|
eq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
|
|
1531
1938
|
neq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
|
|
1532
|
-
collection?:
|
|
1939
|
+
collection?: CollectionHandlers;
|
|
1533
1940
|
};
|
|
1534
1941
|
/**
|
|
1942
|
+
* Metadata common to both symbols and functions.
|
|
1943
|
+
*
|
|
1535
1944
|
* @category Definitions
|
|
1536
1945
|
*
|
|
1537
1946
|
*/
|
|
1538
|
-
export
|
|
1539
|
-
/**
|
|
1540
|
-
|
|
1947
|
+
export interface BaseDefinition {
|
|
1948
|
+
/**
|
|
1949
|
+
* If a string, a short description, about one line long.
|
|
1950
|
+
*
|
|
1951
|
+
* Otherwise, a list of strings, each string a paragraph.
|
|
1952
|
+
*
|
|
1953
|
+
* May contain Markdown.
|
|
1954
|
+
*/
|
|
1955
|
+
description: string | string[];
|
|
1956
|
+
/** A list of examples of how to use this symbol or operator.
|
|
1957
|
+
*
|
|
1958
|
+
* Each example is a string, which can be a MathJSON expression or LaTeX, bracketed by `$` signs.
|
|
1959
|
+
* For example, `["Add", 1, 2]` or `$\\sin(\\pi/4)$`.
|
|
1960
|
+
*/
|
|
1961
|
+
examples: string | string[];
|
|
1541
1962
|
/** A URL pointing to more information about this symbol or operator. */
|
|
1542
|
-
url
|
|
1963
|
+
url: string;
|
|
1543
1964
|
/**
|
|
1544
1965
|
* A short string representing an entry in a wikibase.
|
|
1545
1966
|
*
|
|
1546
|
-
* For example `Q167` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
|
|
1967
|
+
* For example `"Q167"` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
|
|
1547
1968
|
* for the `Pi` constant.
|
|
1548
1969
|
*/
|
|
1549
|
-
wikidata
|
|
1550
|
-
|
|
1970
|
+
wikidata: string;
|
|
1971
|
+
/** If true, the value or type of the definition cannot be changed */
|
|
1972
|
+
readonly isConstant?: boolean;
|
|
1973
|
+
}
|
|
1551
1974
|
/** Options for `BoxedExpression.simplify()`
|
|
1552
1975
|
*
|
|
1553
1976
|
* @category Boxed Expression
|
|
@@ -1567,9 +1990,9 @@ export type SimplifyOptions = {
|
|
|
1567
1990
|
costFunction?: (expr: BoxedExpression) => number;
|
|
1568
1991
|
};
|
|
1569
1992
|
/**
|
|
1570
|
-
* A table mapping
|
|
1993
|
+
* A table mapping symbols to their definition.
|
|
1571
1994
|
*
|
|
1572
|
-
*
|
|
1995
|
+
* Symbols should be valid MathJSON symbols. In addition, the
|
|
1573
1996
|
* following rules are recommended:
|
|
1574
1997
|
*
|
|
1575
1998
|
* - Use only latin letters, digits and `-`: `/[a-zA-Z0-9-]+/`
|
|
@@ -1579,18 +2002,34 @@ export type SimplifyOptions = {
|
|
|
1579
2002
|
* @category Definitions
|
|
1580
2003
|
*
|
|
1581
2004
|
*/
|
|
1582
|
-
export type
|
|
1583
|
-
SymbolDefinition,
|
|
1584
|
-
FunctionDefinition,
|
|
1585
|
-
SemiBoxedExpression
|
|
1586
|
-
]>;
|
|
2005
|
+
export type SymbolDefinition = OneOf<[ValueDefinition, OperatorDefinition]>;
|
|
1587
2006
|
/**
|
|
1588
2007
|
* @category Definitions
|
|
1589
2008
|
*
|
|
1590
2009
|
*/
|
|
1591
|
-
export type
|
|
1592
|
-
[id: string]:
|
|
2010
|
+
export type SymbolDefinitions = Readonly<{
|
|
2011
|
+
[id: string]: Partial<SymbolDefinition>;
|
|
1593
2012
|
}>;
|
|
2013
|
+
/**
|
|
2014
|
+
* When a unitless value is passed to or returned from a trigonometric function,
|
|
2015
|
+
* the angular unit of the value.
|
|
2016
|
+
*
|
|
2017
|
+
* | Angular Unit | Description |
|
|
2018
|
+
* |:--------------|:-------------|
|
|
2019
|
+
* | `rad` | radians, 2π radians is a full circle |
|
|
2020
|
+
* | `deg` | degrees, 360 degrees is a full circle |
|
|
2021
|
+
* | `grad` | gradians, 400 gradians is a full circle |
|
|
2022
|
+
* | `turn` | turns, 1 turn is a full circle |
|
|
2023
|
+
*
|
|
2024
|
+
* To change the angular unit used by the Compute Engine, use:
|
|
2025
|
+
*
|
|
2026
|
+
* ```js
|
|
2027
|
+
* ce.angularUnit = 'deg';
|
|
2028
|
+
* ```
|
|
2029
|
+
*
|
|
2030
|
+
* @category Compute Engine
|
|
2031
|
+
*/
|
|
2032
|
+
export type AngularUnit = 'rad' | 'deg' | 'grad' | 'turn';
|
|
1594
2033
|
/** @category Numerics */
|
|
1595
2034
|
export type Sign =
|
|
1596
2035
|
/** The expression is equal to 0 */
|
|
@@ -1605,248 +2044,226 @@ export type Sign =
|
|
|
1605
2044
|
| 'non-positive'
|
|
1606
2045
|
/** The expression is not equal to 0 (possibly with an imaginary part) and isPositive, isNegative, isUnsigned are all false or undefined */
|
|
1607
2046
|
| '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
2047
|
/** The expression has an imaginary part or is NaN */
|
|
1621
2048
|
| 'unsigned';
|
|
1622
|
-
/**
|
|
1623
|
-
* When used in a `SymbolDefinition` or `Functiondefinition` these flags
|
|
1624
|
-
* provide additional information about the value of the symbol or function.
|
|
1625
|
-
*
|
|
1626
|
-
* If provided, they will override the value derived from
|
|
1627
|
-
* the symbol's value.
|
|
1628
|
-
*
|
|
1629
|
-
* @category Definitions
|
|
1630
|
-
*/
|
|
1631
|
-
export type NumericFlags = {
|
|
1632
|
-
sgn: Sign | undefined;
|
|
1633
|
-
even: boolean | undefined;
|
|
1634
|
-
odd: boolean | undefined;
|
|
1635
|
-
};
|
|
1636
2049
|
/**
|
|
1637
2050
|
* 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.
|
|
2051
|
+
* all collections, indexed or not.
|
|
1648
2052
|
*
|
|
1649
2053
|
* @category Definitions
|
|
1650
2054
|
*/
|
|
1651
|
-
export
|
|
2055
|
+
export interface BaseCollectionHandlers {
|
|
2056
|
+
/**
|
|
2057
|
+
* Return an iterator that iterates over the elements of the collection.
|
|
2058
|
+
*
|
|
2059
|
+
* The order in which the elements are returned is not defined. Requesting
|
|
2060
|
+
* two iterators on the same collection may return the elements in a
|
|
2061
|
+
* different order.
|
|
2062
|
+
*
|
|
2063
|
+
* @category Definitions
|
|
2064
|
+
*/
|
|
2065
|
+
iterator: (collection: BoxedExpression) => Iterator<BoxedExpression, undefined> | undefined;
|
|
1652
2066
|
/** Return the number of elements in the collection.
|
|
1653
2067
|
*
|
|
1654
|
-
* An empty collection has a
|
|
2068
|
+
* An empty collection has a count of 0.
|
|
2069
|
+
*/
|
|
2070
|
+
count: (collection: BoxedExpression) => number | undefined;
|
|
2071
|
+
/** Optional flag to quickly check if the collection is empty, without having to count exactly how may elements it has (useful for lazy evaluation). */
|
|
2072
|
+
isEmpty?: (collection: BoxedExpression) => boolean | undefined;
|
|
2073
|
+
/** Optional flag to quickly check if the collection is finite, without having to count exactly how many elements it has (useful for lazy evaluation). */
|
|
2074
|
+
isFinite?: (collection: BoxedExpression) => boolean | undefined;
|
|
2075
|
+
/** Return `true` if the collection is lazy, `false` otherwise.
|
|
2076
|
+
* If the collection is lazy, it means that the elements are not
|
|
2077
|
+
* computed until they are needed, for example when iterating over the
|
|
2078
|
+
* collection.
|
|
2079
|
+
*
|
|
2080
|
+
* Default: `true`
|
|
1655
2081
|
*/
|
|
1656
|
-
|
|
2082
|
+
isLazy?: (collection: BoxedExpression) => boolean;
|
|
1657
2083
|
/**
|
|
1658
|
-
* Return `true` if the target
|
|
1659
|
-
*
|
|
2084
|
+
* Return `true` if the target expression is in the collection,
|
|
2085
|
+
* `false` otherwise.
|
|
2086
|
+
*
|
|
2087
|
+
* Return `undefined` if the membership cannot be determined.
|
|
1660
2088
|
*/
|
|
1661
|
-
contains
|
|
1662
|
-
/**
|
|
1663
|
-
*
|
|
1664
|
-
*
|
|
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
|
|
2089
|
+
contains?: (collection: BoxedExpression, target: BoxedExpression) => boolean | undefined;
|
|
2090
|
+
/**
|
|
2091
|
+
* Return `true` if all the elements of `other` are in `collection`.
|
|
2092
|
+
* Both `collection` and `other` are collections.
|
|
1668
2093
|
*
|
|
1669
|
-
* If
|
|
2094
|
+
* If strict is `true`, the subset must be strict, that is, `collection` must
|
|
2095
|
+
* have more elements than `other`.
|
|
1670
2096
|
*
|
|
1671
|
-
*
|
|
2097
|
+
* Return `undefined` if the subset relation cannot be determined.
|
|
1672
2098
|
*/
|
|
1673
|
-
|
|
2099
|
+
subsetOf?: (collection: BoxedExpression, other: BoxedExpression, strict: boolean) => boolean | undefined;
|
|
2100
|
+
/** Return the sign of all the elements of the collection. */
|
|
2101
|
+
eltsgn?: (collection: BoxedExpression) => Sign | undefined;
|
|
2102
|
+
/** Return the widest type of all the elements in the collection */
|
|
2103
|
+
elttype?: (collection: BoxedExpression) => Type | undefined;
|
|
2104
|
+
}
|
|
2105
|
+
/**
|
|
2106
|
+
* These additional collection handlers are applicable to indexed
|
|
2107
|
+
* collections only.
|
|
2108
|
+
*
|
|
2109
|
+
* The elements of an indexed collection can be accessed by index, and
|
|
2110
|
+
* the order of the elements is defined.
|
|
2111
|
+
*
|
|
2112
|
+
* @category Definitions
|
|
2113
|
+
*/
|
|
2114
|
+
export interface IndexedCollectionHandlers {
|
|
1674
2115
|
/**
|
|
1675
2116
|
* Return the element at the specified index.
|
|
1676
2117
|
*
|
|
1677
2118
|
* The first element is `at(1)`, the last element is `at(-1)`.
|
|
1678
2119
|
*
|
|
1679
|
-
* If the index is <0, return the element at index `
|
|
2120
|
+
* If the index is <0, return the element at index `count() + index + 1`.
|
|
1680
2121
|
*
|
|
1681
|
-
* The index can also be a string for example for
|
|
1682
|
-
* is returned by the `keys()` handler.
|
|
2122
|
+
* The index can also be a string for example for records. The set of valid
|
|
2123
|
+
* keys is returned by the `keys()` handler.
|
|
1683
2124
|
*
|
|
1684
2125
|
* If the index is invalid, return `undefined`.
|
|
1685
2126
|
*/
|
|
1686
2127
|
at: (collection: BoxedExpression, index: number | string) => undefined | BoxedExpression;
|
|
1687
2128
|
/**
|
|
1688
|
-
*
|
|
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.
|
|
2129
|
+
* Return the index of the first element that matches the predicate.
|
|
1694
2130
|
*
|
|
1695
|
-
*
|
|
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.
|
|
2131
|
+
* If no element matches the predicate, return `undefined`.
|
|
1705
2132
|
*/
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
2133
|
+
indexWhere: (collection: BoxedExpression, predicate: (element: BoxedExpression) => boolean) => number | undefined;
|
|
2134
|
+
}
|
|
2135
|
+
/**
|
|
2136
|
+
* The collection handlers are the primitive operations that can be
|
|
2137
|
+
* performed on collections, such as lists, sets, tuples, etc...
|
|
2138
|
+
*
|
|
2139
|
+
* @category Definitions
|
|
2140
|
+
*/
|
|
2141
|
+
export type CollectionHandlers = BaseCollectionHandlers & Partial<IndexedCollectionHandlers>;
|
|
2142
|
+
/**
|
|
2143
|
+
*
|
|
2144
|
+
* The definition for a value, represented as a tagged object literal.
|
|
2145
|
+
* @category Definitions
|
|
2146
|
+
*
|
|
2147
|
+
*/
|
|
2148
|
+
export type TaggedValueDefinition = {
|
|
2149
|
+
value: BoxedValueDefinition;
|
|
1718
2150
|
};
|
|
1719
2151
|
/**
|
|
2152
|
+
*
|
|
2153
|
+
* The definition for an operator, represented as a tagged object literal.
|
|
2154
|
+
*
|
|
1720
2155
|
* @category Definitions
|
|
1721
2156
|
*
|
|
1722
2157
|
*/
|
|
1723
|
-
export
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
2158
|
+
export type TaggedOperatorDefinition = {
|
|
2159
|
+
operator: BoxedOperatorDefinition;
|
|
2160
|
+
};
|
|
2161
|
+
/**
|
|
2162
|
+
* A definition can be either a value or an operator.
|
|
2163
|
+
*
|
|
2164
|
+
* It is collected in a tagged object literal, instead of being a simple union
|
|
2165
|
+
* type, so that the type of the definition can be changed while keeping
|
|
2166
|
+
* references to the definition in bound expressions.
|
|
2167
|
+
*
|
|
2168
|
+
* @category Definitions
|
|
2169
|
+
*
|
|
2170
|
+
*/
|
|
2171
|
+
export type BoxedDefinition = TaggedValueDefinition | TaggedOperatorDefinition;
|
|
2172
|
+
/**
|
|
2173
|
+
* @category Definitions
|
|
2174
|
+
*
|
|
2175
|
+
*/
|
|
2176
|
+
export interface BoxedBaseDefinition extends Partial<BaseDefinition> {
|
|
1734
2177
|
/** If this is the definition of a collection, the set of primitive operations
|
|
1735
2178
|
* 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.
|
|
2179
|
+
* enumerating it, etc...).
|
|
1740
2180
|
*/
|
|
1741
|
-
|
|
2181
|
+
collection?: CollectionHandlers;
|
|
1742
2182
|
}
|
|
1743
2183
|
/**
|
|
1744
|
-
* @category Definitions
|
|
1745
2184
|
*
|
|
2185
|
+
* @category Definitions
|
|
1746
2186
|
*/
|
|
1747
|
-
export
|
|
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;
|
|
2187
|
+
export interface BoxedValueDefinition extends BoxedBaseDefinition {
|
|
1757
2188
|
/**
|
|
1758
|
-
|
|
1759
|
-
|
|
2189
|
+
* If the symbol has a value, it is held as indicated in the table below.
|
|
2190
|
+
* A green checkmark indicate that the symbol is substituted.
|
|
1760
2191
|
|
|
1761
|
-
|
|
2192
|
+
<div className="symbols-table">
|
|
1762
2193
|
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
2194
|
+
| Operation | `"never"` | `"evaluate"` | `"N"` |
|
|
2195
|
+
| :--- | :-----: | :----: | :---: |
|
|
2196
|
+
| `canonical()` | (X) | | |
|
|
2197
|
+
| `evaluate()` | (X) | (X) | |
|
|
2198
|
+
| `"N()"` | (X) | (X) | (X) |
|
|
1768
2199
|
|
|
1769
|
-
|
|
2200
|
+
</div>
|
|
1770
2201
|
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
2202
|
+
* Some examples:
|
|
2203
|
+
* - `ImaginaryUnit` has `holdUntil: 'never'`: it is substituted during canonicalization
|
|
2204
|
+
* - `x` has `holdUntil: 'evaluate'` (variables)
|
|
2205
|
+
* - `Pi` has `holdUntil: 'N'` (special numeric constant)
|
|
2206
|
+
*
|
|
2207
|
+
* **Default:** `evaluate`
|
|
2208
|
+
*/
|
|
1778
2209
|
holdUntil: 'never' | 'evaluate' | 'N';
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
set value(val: BoxedExpression | number | undefined);
|
|
1786
|
-
readonly isFunction: boolean;
|
|
1787
|
-
readonly isConstant: boolean;
|
|
2210
|
+
/** This is either the initial value of the symbol (i.e. when a new
|
|
2211
|
+
* evaluation context is created), or its constant value, if a constant.
|
|
2212
|
+
* Otherwise, the current value is tracked in the evaluation context.
|
|
2213
|
+
*
|
|
2214
|
+
*/
|
|
2215
|
+
readonly value: BoxedExpression | undefined;
|
|
1788
2216
|
eq?: (a: BoxedExpression) => boolean | undefined;
|
|
1789
2217
|
neq?: (a: BoxedExpression) => boolean | undefined;
|
|
1790
2218
|
cmp?: (a: BoxedExpression) => '=' | '>' | '<' | undefined;
|
|
2219
|
+
/**
|
|
2220
|
+
* True if the type has been inferred. An inferred type can be updated as
|
|
2221
|
+
* more information becomes available.
|
|
2222
|
+
*
|
|
2223
|
+
* A type that is not inferred, but has been set explicitly, cannot be updated.
|
|
2224
|
+
*/
|
|
1791
2225
|
inferredType: boolean;
|
|
1792
2226
|
type: BoxedType;
|
|
1793
2227
|
}
|
|
1794
2228
|
/**
|
|
1795
|
-
*
|
|
1796
|
-
*
|
|
1797
|
-
*
|
|
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.
|
|
1801
|
-
*
|
|
1802
|
-
* The scope stack is used to resolve symbols, and it is possible for
|
|
1803
|
-
* a scope to 'mask' definitions from previous scopes.
|
|
1804
|
-
*
|
|
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.
|
|
1807
|
-
*
|
|
1808
|
-
* @category Compute Engine
|
|
1809
|
-
*/
|
|
1810
|
-
export type Scope = Record<string, any>;
|
|
1811
|
-
/** Options for `BoxedExpression.evaluate()`
|
|
1812
|
-
*
|
|
1813
|
-
* @category Boxed Expression
|
|
1814
|
-
*/
|
|
1815
|
-
export type EvaluateOptions = {
|
|
1816
|
-
numericApproximation: boolean;
|
|
1817
|
-
signal: AbortSignal;
|
|
1818
|
-
};
|
|
1819
|
-
/**
|
|
1820
|
-
* A function definition can have some flags to indicate specific
|
|
1821
|
-
* properties of the function.
|
|
2229
|
+
* An operator definition can have some flags to indicate specific
|
|
2230
|
+
* properties of the operator.
|
|
1822
2231
|
* @category Definitions
|
|
1823
2232
|
*/
|
|
1824
|
-
export type
|
|
2233
|
+
export type OperatorDefinitionFlags = {
|
|
1825
2234
|
/**
|
|
1826
|
-
* If `true`, the arguments to this
|
|
2235
|
+
* If `true`, the arguments to this operator are not automatically
|
|
1827
2236
|
* evaluated. The default is `false` (the arguments are evaluated).
|
|
1828
2237
|
*
|
|
1829
|
-
* This can be useful for example for
|
|
1830
|
-
* expressions as arguments, such as `
|
|
2238
|
+
* This can be useful for example for operators that take symbolic
|
|
2239
|
+
* expressions as arguments, such as `Declare` or `Integrate`.
|
|
1831
2240
|
*
|
|
1832
|
-
* This is also useful for
|
|
2241
|
+
* This is also useful for operators that take an argument that is
|
|
1833
2242
|
* potentially an infinite collection.
|
|
1834
2243
|
*
|
|
1835
2244
|
* It will be up to the `evaluate()` handler to evaluate the arguments as
|
|
1836
|
-
* needed. This is
|
|
1837
|
-
* to
|
|
2245
|
+
* needed. This is convenient to pass symbolic expressions as arguments
|
|
2246
|
+
* to operators without having to explicitly use a `Hold` expression.
|
|
1838
2247
|
*
|
|
1839
2248
|
* This also applies to the `canonical()` handler.
|
|
1840
2249
|
*
|
|
1841
2250
|
*/
|
|
1842
2251
|
lazy: boolean;
|
|
1843
|
-
/**
|
|
2252
|
+
/**
|
|
2253
|
+
* If `true`, the operator requires a new lexical scope when canonicalized.
|
|
2254
|
+
* This will allow it to declare variables that are not visible outside
|
|
2255
|
+
* the function expression using the operator.
|
|
2256
|
+
*
|
|
2257
|
+
* **Default**: `false`
|
|
2258
|
+
*/
|
|
2259
|
+
scoped: boolean;
|
|
2260
|
+
/** If `true`, the operator is applied element by element to lists, matrices
|
|
1844
2261
|
* (`["List"]` or `["Tuple"]` expressions) and equations (relational
|
|
1845
2262
|
* operators).
|
|
1846
2263
|
*
|
|
1847
2264
|
* **Default**: `false`
|
|
1848
2265
|
*/
|
|
1849
|
-
|
|
2266
|
+
broadcastable: boolean;
|
|
1850
2267
|
/** If `true`, `["f", ["f", a], b]` simplifies to `["f", a, b]`
|
|
1851
2268
|
*
|
|
1852
2269
|
* **Default**: `false`
|
|
@@ -1867,10 +2284,10 @@ export type FunctionDefinitionFlags = {
|
|
|
1867
2284
|
*
|
|
1868
2285
|
*/
|
|
1869
2286
|
commutativeOrder: ((a: BoxedExpression, b: BoxedExpression) => number) | undefined;
|
|
1870
|
-
/** If `true`, when the
|
|
2287
|
+
/** If `true`, when the operator is univariate, `["f", ["Multiply", x, c]]`
|
|
1871
2288
|
* simplifies to `["Multiply", ["f", x], c]` where `c` is constant
|
|
1872
2289
|
*
|
|
1873
|
-
* When the
|
|
2290
|
+
* When the operator is multivariate, multiplicativity is considered only on
|
|
1874
2291
|
* the first argument: `["f", ["Multiply", x, y], z]` simplifies to
|
|
1875
2292
|
* `["Multiply", ["f", x, z], ["f", y, z]]`
|
|
1876
2293
|
*
|
|
@@ -1886,10 +2303,10 @@ export type FunctionDefinitionFlags = {
|
|
|
1886
2303
|
* **Default**: `false`
|
|
1887
2304
|
*/
|
|
1888
2305
|
involution: boolean;
|
|
1889
|
-
/** If `true`, the value of this
|
|
2306
|
+
/** If `true`, the value of this operator is always the same for a given
|
|
1890
2307
|
* set of arguments and it has no side effects.
|
|
1891
2308
|
*
|
|
1892
|
-
* An expression using this
|
|
2309
|
+
* An expression using this operator is pure if the operator and all its
|
|
1893
2310
|
* arguments are pure.
|
|
1894
2311
|
*
|
|
1895
2312
|
* For example `Sin` is pure, `Random` isn't.
|
|
@@ -1901,10 +2318,15 @@ export type FunctionDefinitionFlags = {
|
|
|
1901
2318
|
pure: boolean;
|
|
1902
2319
|
};
|
|
1903
2320
|
/**
|
|
2321
|
+
*
|
|
2322
|
+
* The definition includes information specific about an operator, such as
|
|
2323
|
+
* handlers to canonicalize or evaluate a function expression with this
|
|
2324
|
+
* operator.
|
|
2325
|
+
*
|
|
1904
2326
|
* @category Definitions
|
|
1905
2327
|
*
|
|
1906
2328
|
*/
|
|
1907
|
-
export
|
|
2329
|
+
export interface BoxedOperatorDefinition extends BoxedBaseDefinition, OperatorDefinitionFlags {
|
|
1908
2330
|
complexity: number;
|
|
1909
2331
|
/** If true, the signature was inferred from usage and may be modified
|
|
1910
2332
|
* as more information becomes available.
|
|
@@ -1936,6 +2358,7 @@ export type BoxedFunctionDefinition = BoxedBaseDefinition & FunctionDefinitionFl
|
|
|
1936
2358
|
neq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
|
|
1937
2359
|
canonical?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
1938
2360
|
engine: ComputeEngine;
|
|
2361
|
+
scope: Scope | undefined;
|
|
1939
2362
|
}) => BoxedExpression | null;
|
|
1940
2363
|
evaluate?: (ops: ReadonlyArray<BoxedExpression>, options: Partial<EvaluateOptions> & {
|
|
1941
2364
|
engine?: ComputeEngine;
|
|
@@ -1947,16 +2370,33 @@ export type BoxedFunctionDefinition = BoxedBaseDefinition & FunctionDefinitionFl
|
|
|
1947
2370
|
engine: ComputeEngine;
|
|
1948
2371
|
}) => BoxedExpression;
|
|
1949
2372
|
compile?: (expr: BoxedExpression) => CompiledExpression;
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
2373
|
+
/** @internal */
|
|
2374
|
+
update(def: OperatorDefinition): void;
|
|
2375
|
+
}
|
|
2376
|
+
/** @category Assumptions */
|
|
2377
|
+
export interface Assumption {
|
|
2378
|
+
isPositive: boolean | undefined;
|
|
2379
|
+
isNonNegative: boolean | undefined;
|
|
2380
|
+
isNegative: boolean | undefined;
|
|
2381
|
+
isNonPositive: boolean | undefined;
|
|
2382
|
+
isNumber: boolean | undefined;
|
|
2383
|
+
isInteger: boolean | undefined;
|
|
2384
|
+
isRational: boolean | undefined;
|
|
2385
|
+
isReal: boolean | undefined;
|
|
2386
|
+
isComplex: boolean | undefined;
|
|
2387
|
+
isImaginary: boolean | undefined;
|
|
2388
|
+
isFinite: boolean | undefined;
|
|
2389
|
+
isInfinite: boolean | undefined;
|
|
2390
|
+
isNaN: boolean | undefined;
|
|
2391
|
+
isZero: boolean | undefined;
|
|
2392
|
+
matches(t: BoxedType): boolean | undefined;
|
|
2393
|
+
isGreater(other: BoxedExpression): boolean | undefined;
|
|
2394
|
+
isGreaterEqual(other: BoxedExpression): boolean | undefined;
|
|
2395
|
+
isLess(other: BoxedExpression): boolean | undefined;
|
|
2396
|
+
isLessEqual(other: BoxedExpression): boolean | undefined;
|
|
2397
|
+
isEqual(other: BoxedExpression): boolean | undefined;
|
|
2398
|
+
toExpression(ce: ComputeEngine, x: MathJsonSymbol): BoxedExpression;
|
|
2399
|
+
}
|
|
1960
2400
|
/** @category Assumptions */
|
|
1961
2401
|
export interface ExpressionMapInterface<U> {
|
|
1962
2402
|
has(expr: BoxedExpression): boolean;
|
|
@@ -1969,24 +2409,6 @@ export interface ExpressionMapInterface<U> {
|
|
|
1969
2409
|
}
|
|
1970
2410
|
/** @category Assumptions */
|
|
1971
2411
|
export type AssumeResult = 'internal-error' | 'not-a-predicate' | 'contradiction' | 'tautology' | 'ok';
|
|
1972
|
-
/**
|
|
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
|
|
1980
|
-
*
|
|
1981
|
-
* @category Compute Engine
|
|
1982
|
-
*/
|
|
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
|
-
};
|
|
1990
2412
|
/**
|
|
1991
2413
|
* When provided, canonical forms are used to put an expression in a
|
|
1992
2414
|
* "standard" form.
|
|
@@ -1997,7 +2419,8 @@ export type RuntimeScope = Scope & {
|
|
|
1997
2419
|
*
|
|
1998
2420
|
* - `InvisibleOperator`: replace use of the `InvisibleOperator` with
|
|
1999
2421
|
* another operation, such as multiplication (i.e. `2x` or function
|
|
2000
|
-
* application (`f(x)`).
|
|
2422
|
+
* application (`f(x)`). Also replaces ['InvisibleOperator', real, imaginary] instances with
|
|
2423
|
+
* complex (imaginary) numbers.
|
|
2001
2424
|
* - `Number`: replace all numeric values with their
|
|
2002
2425
|
* canonical representation, for example, reduce
|
|
2003
2426
|
* rationals and replace complex numbers with no imaginary part with a real number.
|
|
@@ -2015,8 +2438,38 @@ export type RuntimeScope = Scope & {
|
|
|
2015
2438
|
export type CanonicalForm = 'InvisibleOperator' | 'Number' | 'Multiply' | 'Add' | 'Power' | 'Divide' | 'Flatten' | 'Order';
|
|
2016
2439
|
/** @category Boxed Expression */
|
|
2017
2440
|
export type CanonicalOptions = boolean | CanonicalForm | CanonicalForm[];
|
|
2441
|
+
/** Options for `BoxedExpression.evaluate()`
|
|
2442
|
+
*
|
|
2443
|
+
* @category Boxed Expression
|
|
2444
|
+
*/
|
|
2445
|
+
export type EvaluateOptions = {
|
|
2446
|
+
/**
|
|
2447
|
+
* If `true`, the evaluation will return a numeric approximation
|
|
2448
|
+
* of the expression, if possible.
|
|
2449
|
+
* If `false`, the evaluation will return an exact value, if possible.
|
|
2450
|
+
* Defaults to `false`.
|
|
2451
|
+
*/
|
|
2452
|
+
numericApproximation: boolean;
|
|
2453
|
+
/**
|
|
2454
|
+
* If `false`, and the result of the expression is a lazy collection,
|
|
2455
|
+
* the collection will not be evaluated and will remain lazy.
|
|
2456
|
+
*
|
|
2457
|
+
* If `true` and the expression is a finite lazy collection,
|
|
2458
|
+
* the collection will be evaluated and returned as a non-lazy collection.
|
|
2459
|
+
*
|
|
2460
|
+
* If an integer, the collection will be evaluated up to that many elements.
|
|
2461
|
+
*
|
|
2462
|
+
* If a pair of integers `[n,m]`, and the collection is finite, the first `n`
|
|
2463
|
+
* elements will be evaluated, and the last `m` elements will be evaluated.
|
|
2464
|
+
*
|
|
2465
|
+
* Defaults to `false`.
|
|
2466
|
+
*/
|
|
2467
|
+
materialization: boolean | number | [number, number];
|
|
2468
|
+
signal: AbortSignal;
|
|
2469
|
+
withArguments: Record<MathJsonSymbol, BoxedExpression>;
|
|
2470
|
+
};
|
|
2018
2471
|
/**
|
|
2019
|
-
* Metadata that can be associated with
|
|
2472
|
+
* Metadata that can be associated with an MathJSON expression.
|
|
2020
2473
|
*
|
|
2021
2474
|
* @category Boxed Expression
|
|
2022
2475
|
*/
|
|
@@ -2025,14 +2478,14 @@ export type Metadata = {
|
|
|
2025
2478
|
wikidata?: string | undefined;
|
|
2026
2479
|
};
|
|
2027
2480
|
/**
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2481
|
+
* A substitution describes the values of the wildcards in a pattern so that
|
|
2482
|
+
* the pattern is equal to a target expression.
|
|
2483
|
+
*
|
|
2484
|
+
* A substitution can also be considered a more constrained version of a
|
|
2485
|
+
* rule whose `match` is always a symbol.
|
|
2033
2486
|
|
|
2034
|
-
* @category Pattern Matching
|
|
2035
|
-
|
|
2487
|
+
* @category Pattern Matching
|
|
2488
|
+
*/
|
|
2036
2489
|
export type Substitution<T = SemiBoxedExpression> = {
|
|
2037
2490
|
[symbol: string]: T;
|
|
2038
2491
|
};
|
|
@@ -2110,6 +2563,8 @@ export type Rule = string | RuleFunction | {
|
|
|
2110
2563
|
condition?: LatexString | RuleConditionFunction;
|
|
2111
2564
|
useVariations?: boolean;
|
|
2112
2565
|
id?: string;
|
|
2566
|
+
onBeforeMatch?: (rule: Rule, expr: BoxedExpression) => void;
|
|
2567
|
+
onMatch?: (rule: Rule, expr: BoxedExpression, replace: BoxedExpression | RuleStep) => void;
|
|
2113
2568
|
};
|
|
2114
2569
|
/**
|
|
2115
2570
|
*
|
|
@@ -2128,6 +2583,8 @@ export type BoxedRule = {
|
|
|
2128
2583
|
condition: undefined | RuleConditionFunction;
|
|
2129
2584
|
useVariations?: boolean;
|
|
2130
2585
|
id?: string;
|
|
2586
|
+
onBeforeMatch?: (rule: Rule, expr: BoxedExpression) => void;
|
|
2587
|
+
onMatch?: (rule: Rule, expr: BoxedExpression, replace: BoxedExpression | RuleStep) => void;
|
|
2131
2588
|
};
|
|
2132
2589
|
/**
|
|
2133
2590
|
* To create a BoxedRuleSet use the `ce.rules()` method.
|
|
@@ -2139,15 +2596,77 @@ export type BoxedRule = {
|
|
|
2139
2596
|
export type BoxedRuleSet = {
|
|
2140
2597
|
rules: ReadonlyArray<BoxedRule>;
|
|
2141
2598
|
};
|
|
2142
|
-
/**
|
|
2143
|
-
|
|
2599
|
+
/**
|
|
2600
|
+
* The argument of `ce.assign()` is a value that can be assigned to a variable.
|
|
2601
|
+
* It can be a primitive value, a boxed expression, or a function that
|
|
2602
|
+
* takes a list of arguments and returns a boxed expression.
|
|
2603
|
+
* @category Compute Engine */
|
|
2604
|
+
export type AssignValue = boolean | number | bigint | SemiBoxedExpression | ((args: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
|
|
2144
2605
|
engine: ComputeEngine;
|
|
2145
2606
|
}) => BoxedExpression) | undefined;
|
|
2607
|
+
/**
|
|
2608
|
+
* A lexical scope is a table mapping symbols to their definitions. The
|
|
2609
|
+
* symbols are the names of the variables, unknowns and functions in the scope.
|
|
2610
|
+
*
|
|
2611
|
+
* The lexical scope is used to resolve the metadata about symbols, such as
|
|
2612
|
+
* their type, whether they are constant, etc...
|
|
2613
|
+
*
|
|
2614
|
+
* It does not resolve the values of the symbols, since those depend on the
|
|
2615
|
+
* evaluation context. For example, the local variables of a recursive function
|
|
2616
|
+
* will have the same lexical scope, but different values in each evaluation
|
|
2617
|
+
* context.
|
|
2618
|
+
*
|
|
2619
|
+
* @category Definitions
|
|
2620
|
+
*/
|
|
2621
|
+
export type Scope = {
|
|
2622
|
+
parent: Scope | null;
|
|
2623
|
+
bindings: Map<string, BoxedDefinition>;
|
|
2624
|
+
types?: Record<string, TypeReference>;
|
|
2625
|
+
};
|
|
2626
|
+
/**
|
|
2627
|
+
* An evaluation context is a set of bindings mapping symbols to their
|
|
2628
|
+
* values. It also includes a reference to the lexical scope of the
|
|
2629
|
+
* context, as well as a set of assumptions about the values of the
|
|
2630
|
+
* symbols.
|
|
2631
|
+
*
|
|
2632
|
+
*
|
|
2633
|
+
* Eval contexts are arranged in a stack structure. When a new context is
|
|
2634
|
+
* created, it is pushed on the top of the stack.
|
|
2635
|
+
*
|
|
2636
|
+
* A new eval context is created when a function expression that needs to track
|
|
2637
|
+
* its own local variables and named arguments is evaluated. This kind of
|
|
2638
|
+
* function is a "scoped" function, meaning that it has its own local variables
|
|
2639
|
+
* and named arguments.
|
|
2640
|
+
*
|
|
2641
|
+
* For example, the `Sum` function creates a new eval context to track the local
|
|
2642
|
+
* variable used as the index of the sum.
|
|
2643
|
+
*
|
|
2644
|
+
* The eval context stack is used to resolve the value of symbols.
|
|
2645
|
+
*
|
|
2646
|
+
* When a scoped recursive function is called, a new context is created for each
|
|
2647
|
+
* recursive call.
|
|
2648
|
+
*
|
|
2649
|
+
* In contrast, the lexical scope is used to resolve the metadata about
|
|
2650
|
+
* symbols, such as their type, whether they are constant, etc... A new
|
|
2651
|
+
* scope is not created for recursive calls, since the metadata
|
|
2652
|
+
* does not change, only the values of the symbols change.
|
|
2653
|
+
*
|
|
2654
|
+
* The name of the eval context is used to print a "stack trace" for
|
|
2655
|
+
* debugging.
|
|
2656
|
+
*
|
|
2657
|
+
* @category Compute Engine
|
|
2658
|
+
*/
|
|
2659
|
+
export type EvalContext = {
|
|
2660
|
+
lexicalScope: Scope;
|
|
2661
|
+
assumptions: ExpressionMapInterface<boolean>;
|
|
2662
|
+
values: Record<string, BoxedExpression | undefined>;
|
|
2663
|
+
name: undefined | string;
|
|
2664
|
+
};
|
|
2146
2665
|
/** @internal */
|
|
2147
2666
|
export interface ComputeEngine extends IBigNum {
|
|
2148
2667
|
latexDictionary: readonly LatexDictionaryEntry[];
|
|
2149
2668
|
/** @private */
|
|
2150
|
-
|
|
2669
|
+
_indexedLatexDictionary: IndexedLatexDictionary;
|
|
2151
2670
|
decimalSeparator: LatexString;
|
|
2152
2671
|
readonly True: BoxedExpression;
|
|
2153
2672
|
readonly False: BoxedExpression;
|
|
@@ -2158,6 +2677,7 @@ export interface ComputeEngine extends IBigNum {
|
|
|
2158
2677
|
readonly One: BoxedExpression;
|
|
2159
2678
|
readonly Half: BoxedExpression;
|
|
2160
2679
|
readonly NegativeOne: BoxedExpression;
|
|
2680
|
+
/** ImaginaryUnit */
|
|
2161
2681
|
readonly I: BoxedExpression;
|
|
2162
2682
|
readonly NaN: BoxedExpression;
|
|
2163
2683
|
readonly PositiveInfinity: BoxedExpression;
|
|
@@ -2177,34 +2697,22 @@ export interface ComputeEngine extends IBigNum {
|
|
|
2177
2697
|
readonly _BIGNUM_PI: BigNum;
|
|
2178
2698
|
/** @internal */
|
|
2179
2699
|
readonly _BIGNUM_NEGATIVE_ONE: BigNum;
|
|
2180
|
-
|
|
2181
|
-
|
|
2700
|
+
readonly context: EvalContext;
|
|
2701
|
+
contextStack: ReadonlyArray<EvalContext>;
|
|
2702
|
+
/** @internal */
|
|
2703
|
+
readonly _typeResolver: TypeResolver;
|
|
2182
2704
|
/** Absolute time beyond which evaluation should not proceed
|
|
2183
2705
|
* @internal
|
|
2184
2706
|
*/
|
|
2185
2707
|
_deadline?: number;
|
|
2186
|
-
/** Time remaining before _deadline
|
|
2187
|
-
|
|
2188
|
-
/** @private */
|
|
2189
|
-
generation: 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
|
-
*
|
|
2708
|
+
/** Time remaining before _deadline
|
|
2709
|
+
* @internal
|
|
2195
2710
|
*/
|
|
2711
|
+
_timeRemaining: number;
|
|
2712
|
+
/** @internal */
|
|
2713
|
+
_generation: number;
|
|
2196
2714
|
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
2715
|
iterationLimit: number;
|
|
2203
|
-
/** Signal `recursion-depth-exceeded` when the recursion depth for this
|
|
2204
|
-
* scope is exceeded.
|
|
2205
|
-
*
|
|
2206
|
-
* @experimental
|
|
2207
|
-
*/
|
|
2208
2716
|
recursionLimit: number;
|
|
2209
2717
|
chop(n: number): number;
|
|
2210
2718
|
chop(n: BigNum): BigNum | 0;
|
|
@@ -2213,14 +2721,6 @@ export interface ComputeEngine extends IBigNum {
|
|
|
2213
2721
|
complex: (a: number | Complex, b?: number) => Complex;
|
|
2214
2722
|
/** @internal */
|
|
2215
2723
|
_numericValue(value: number | bigint | OneOf<[BigNum | NumericValueData | ExactNumericValueData]>): NumericValue;
|
|
2216
|
-
/** If the precision is set to `machine`, floating point numbers
|
|
2217
|
-
* are represented internally as a 64-bit floating point number (as
|
|
2218
|
-
* per IEEE 754-2008), with a 52-bit mantissa, which gives about 15
|
|
2219
|
-
* digits of precision.
|
|
2220
|
-
*
|
|
2221
|
-
* If the precision is set to `auto`, the precision is set to 300 digits.
|
|
2222
|
-
*
|
|
2223
|
-
*/
|
|
2224
2724
|
set precision(p: number | 'machine' | 'auto');
|
|
2225
2725
|
get precision(): number;
|
|
2226
2726
|
tolerance: number;
|
|
@@ -2230,18 +2730,37 @@ export interface ComputeEngine extends IBigNum {
|
|
|
2230
2730
|
box(expr: NumericValue | SemiBoxedExpression, options?: {
|
|
2231
2731
|
canonical?: CanonicalOptions;
|
|
2232
2732
|
structural?: boolean;
|
|
2733
|
+
scope?: Scope;
|
|
2233
2734
|
}): BoxedExpression;
|
|
2234
2735
|
function(name: string, ops: ReadonlyArray<SemiBoxedExpression>, options?: {
|
|
2235
2736
|
metadata?: Metadata;
|
|
2236
2737
|
canonical?: CanonicalOptions;
|
|
2237
2738
|
structural?: boolean;
|
|
2739
|
+
scope?: Scope;
|
|
2740
|
+
}): BoxedExpression;
|
|
2741
|
+
/**
|
|
2742
|
+
* This is a primitive to create a boxed function.
|
|
2743
|
+
*
|
|
2744
|
+
* In general, consider using `ce.box()` or `ce.function()` or
|
|
2745
|
+
* `canonicalXXX()` instead.
|
|
2746
|
+
*
|
|
2747
|
+
* The caller must ensure that the arguments are in canonical form:
|
|
2748
|
+
* - arguments are `canonical()`
|
|
2749
|
+
* - arguments are sorted
|
|
2750
|
+
* - arguments are flattened and desequenced
|
|
2751
|
+
*
|
|
2752
|
+
* @internal
|
|
2753
|
+
*/
|
|
2754
|
+
_fn(name: string, ops: ReadonlyArray<BoxedExpression>, options?: {
|
|
2755
|
+
metadata?: Metadata;
|
|
2756
|
+
canonical?: boolean;
|
|
2757
|
+
scope?: Scope;
|
|
2238
2758
|
}): BoxedExpression;
|
|
2239
|
-
number(value: number | bigint | string | NumericValue |
|
|
2759
|
+
number(value: number | bigint | string | NumericValue | MathJsonNumberObject | BigNum | Complex | Rational, options?: {
|
|
2240
2760
|
metadata?: Metadata;
|
|
2241
2761
|
canonical?: CanonicalOptions;
|
|
2242
2762
|
}): BoxedExpression;
|
|
2243
2763
|
symbol(sym: string, options?: {
|
|
2244
|
-
metadata?: Metadata;
|
|
2245
2764
|
canonical?: CanonicalOptions;
|
|
2246
2765
|
}): BoxedExpression;
|
|
2247
2766
|
string(s: string, metadata?: Metadata): BoxedExpression;
|
|
@@ -2254,26 +2773,7 @@ export interface ComputeEngine extends IBigNum {
|
|
|
2254
2773
|
rules(rules: Rule | ReadonlyArray<Rule | BoxedRule> | BoxedRuleSet | undefined | null, options?: {
|
|
2255
2774
|
canonical?: boolean;
|
|
2256
2775
|
}): BoxedRuleSet;
|
|
2257
|
-
/**
|
|
2258
|
-
* Return a set of built-in rules.
|
|
2259
|
-
*/
|
|
2260
2776
|
getRuleSet(id?: 'harmonization' | 'solve-univariate' | 'standard-simplification'): BoxedRuleSet | undefined;
|
|
2261
|
-
/**
|
|
2262
|
-
* This is a primitive to create a boxed function.
|
|
2263
|
-
*
|
|
2264
|
-
* In general, consider using `ce.box()` or `ce.function()` or
|
|
2265
|
-
* `canonicalXXX()` instead.
|
|
2266
|
-
*
|
|
2267
|
-
* The caller must ensure that the arguments are in canonical form:
|
|
2268
|
-
* - arguments are `canonical()`
|
|
2269
|
-
* - arguments are sorted
|
|
2270
|
-
* - arguments are flattened and desequenced
|
|
2271
|
-
*
|
|
2272
|
-
* @internal
|
|
2273
|
-
*/
|
|
2274
|
-
_fn(name: string, ops: ReadonlyArray<BoxedExpression>, options?: Metadata & {
|
|
2275
|
-
canonical?: boolean;
|
|
2276
|
-
}): BoxedExpression;
|
|
2277
2777
|
parse(latex: null, options?: Partial<ParseLatexOptions> & {
|
|
2278
2778
|
canonical?: CanonicalOptions;
|
|
2279
2779
|
}): null;
|
|
@@ -2283,51 +2783,90 @@ export interface ComputeEngine extends IBigNum {
|
|
|
2283
2783
|
parse(latex: LatexString | null, options?: Partial<ParseLatexOptions> & {
|
|
2284
2784
|
canonical?: CanonicalOptions;
|
|
2285
2785
|
}): BoxedExpression | null;
|
|
2286
|
-
pushScope(scope?:
|
|
2287
|
-
popScope():
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2786
|
+
pushScope(scope?: Scope, name?: string): void;
|
|
2787
|
+
popScope(): void;
|
|
2788
|
+
/**
|
|
2789
|
+
*
|
|
2790
|
+
* When a new eval context is created, it has slots for the local variables
|
|
2791
|
+
* from the current lexical scope. It also copies the current set of
|
|
2792
|
+
* assumptions.
|
|
2793
|
+
*
|
|
2794
|
+
* Need a pointer to the current lexical scope (may have a scope chain without an evaluation context). Each lexical scope includes a pointer to the parent scope (it's a DAG).
|
|
2795
|
+
*
|
|
2796
|
+
* If a function is "scoped" (has a `scoped` flag), create a new lexical scope
|
|
2797
|
+
* when the function is canonicalized, store the scope with the function
|
|
2798
|
+
* definition (if the function has a lazy flag, and a canonical handler, it
|
|
2799
|
+
* can behave like a scoped function, but a scoped flag is convenient,
|
|
2800
|
+
* it would still evaluate the arguments).
|
|
2801
|
+
*
|
|
2802
|
+
* Note: if an expression is not canonical, evaluating it return itself.
|
|
2803
|
+
* This is important to support arguments that are just symbol names
|
|
2804
|
+
* (they are not canonicalized).
|
|
2805
|
+
*
|
|
2806
|
+
* When the function expression is evaluated, if it is "scoped", push the
|
|
2807
|
+
* scope associated with the function (maybe not?) and a matching eval
|
|
2808
|
+
* context, including all the symbols in the lexical scope (including
|
|
2809
|
+
* constants). Need some way to indicate that a symbol maps to an argument
|
|
2810
|
+
* (in value definition?).
|
|
2811
|
+
*
|
|
2812
|
+
* When searching the value of a symbol, start with the current
|
|
2813
|
+
* eval context, then the previous one.
|
|
2814
|
+
*
|
|
2815
|
+
* When looking for a definition, start with the lexical scope of the
|
|
2816
|
+
* current eval context, then the parent lexical context.
|
|
2817
|
+
*
|
|
2818
|
+
* @internal */
|
|
2819
|
+
_pushEvalContext(scope: Scope, name?: string): void;
|
|
2820
|
+
/** @internal */
|
|
2821
|
+
_popEvalContext(): void;
|
|
2822
|
+
/**
|
|
2823
|
+
* Temporarily sets the lexical scope to the provided scope, then
|
|
2824
|
+
* executes the function `f` in that scope and returns the result.
|
|
2825
|
+
* @internal */
|
|
2826
|
+
_inScope<T>(scope: Scope | undefined, f: () => T): T;
|
|
2827
|
+
/**
|
|
2828
|
+
* Use `ce.box(id)` instead
|
|
2829
|
+
* @internal */
|
|
2830
|
+
_getSymbolValue(id: MathJsonSymbol): BoxedExpression | undefined;
|
|
2831
|
+
/**
|
|
2832
|
+
* Use `ce.assign(id, value)` instead.
|
|
2833
|
+
* @internal */
|
|
2834
|
+
_setSymbolValue(id: MathJsonSymbol, value: BoxedExpression | boolean | number | undefined): void;
|
|
2835
|
+
/** A list of the function calls to the current evaluation context */
|
|
2836
|
+
trace: ReadonlyArray<string>;
|
|
2837
|
+
lookupContext(id: MathJsonSymbol): undefined | EvalContext;
|
|
2838
|
+
/** @internal */
|
|
2839
|
+
_swapContext(context: EvalContext): void;
|
|
2840
|
+
lookupDefinition(id: MathJsonSymbol): undefined | BoxedDefinition;
|
|
2294
2841
|
assign(ids: {
|
|
2295
|
-
[id:
|
|
2842
|
+
[id: MathJsonSymbol]: AssignValue;
|
|
2296
2843
|
}): ComputeEngine;
|
|
2297
|
-
assign(id:
|
|
2298
|
-
assign(arg1:
|
|
2299
|
-
[id:
|
|
2844
|
+
assign(id: MathJsonSymbol, value: AssignValue): ComputeEngine;
|
|
2845
|
+
assign(arg1: MathJsonSymbol | {
|
|
2846
|
+
[id: MathJsonSymbol]: AssignValue;
|
|
2300
2847
|
}, arg2?: AssignValue): ComputeEngine;
|
|
2301
|
-
|
|
2302
|
-
|
|
2848
|
+
declareType(name: string, type: Type, options?: {
|
|
2849
|
+
alias?: boolean;
|
|
2850
|
+
}): void;
|
|
2851
|
+
declare(symbols: {
|
|
2852
|
+
[id: MathJsonSymbol]: Type | TypeString | Partial<SymbolDefinition>;
|
|
2303
2853
|
}): ComputeEngine;
|
|
2304
|
-
declare(id:
|
|
2305
|
-
declare(arg1:
|
|
2306
|
-
[id:
|
|
2307
|
-
}, arg2?: Type |
|
|
2854
|
+
declare(id: MathJsonSymbol, def: Type | TypeString | Partial<SymbolDefinition>, scope?: Scope): ComputeEngine;
|
|
2855
|
+
declare(arg1: MathJsonSymbol | {
|
|
2856
|
+
[id: MathJsonSymbol]: Type | TypeString | Partial<SymbolDefinition>;
|
|
2857
|
+
}, arg2?: Type | TypeString | Partial<SymbolDefinition>, arg3?: Scope): ComputeEngine;
|
|
2308
2858
|
assume(predicate: BoxedExpression): AssumeResult;
|
|
2309
|
-
forget(symbol?:
|
|
2310
|
-
get assumptions(): ExpressionMapInterface<boolean>;
|
|
2859
|
+
forget(symbol?: MathJsonSymbol | MathJsonSymbol[]): void;
|
|
2311
2860
|
ask(pattern: BoxedExpression): BoxedSubstitution[];
|
|
2312
2861
|
verify(query: BoxedExpression): boolean;
|
|
2313
2862
|
/** @internal */
|
|
2314
|
-
|
|
2315
|
-
/** @internal */
|
|
2316
|
-
checkContinueExecution(): void;
|
|
2863
|
+
_shouldContinueExecution(): boolean;
|
|
2317
2864
|
/** @internal */
|
|
2318
|
-
|
|
2865
|
+
_checkContinueExecution(): void;
|
|
2319
2866
|
/** @internal */
|
|
2320
|
-
|
|
2867
|
+
_cache<T>(name: string, build: () => T, purge?: (t: T) => T | undefined): T;
|
|
2321
2868
|
/** @internal */
|
|
2322
|
-
|
|
2323
|
-
/** @internal */
|
|
2324
|
-
_register(expr: BoxedExpression): void;
|
|
2869
|
+
_reset(): void;
|
|
2325
2870
|
/** @internal */
|
|
2326
|
-
|
|
2327
|
-
}
|
|
2328
|
-
/** @internal */
|
|
2329
|
-
export interface ComputeEngineStats {
|
|
2330
|
-
symbols: Set<BoxedExpression>;
|
|
2331
|
-
expressions: null | Set<BoxedExpression>;
|
|
2332
|
-
highwaterMark: number;
|
|
2871
|
+
listenToConfigurationChange(tracker: ConfigurationChangeListener): () => void;
|
|
2333
2872
|
}
|