@cortex-js/compute-engine 0.32.0 → 0.32.1
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 +42905 -0
- package/dist/compute-engine.min.esm.js +125 -0
- package/dist/compute-engine.min.umd.js +127 -0
- package/dist/compute-engine.umd.js +42930 -0
- package/dist/math-json.esm.js +130 -0
- package/dist/math-json.min.esm.js +130 -0
- package/dist/math-json.min.umd.js +4 -0
- package/dist/math-json.umd.js +155 -0
- package/dist/types/common/ansi-codes.d.ts +41 -0
- package/dist/types/common/configuration-change.d.ts +28 -0
- package/dist/types/common/fuzzy-string-match.d.ts +2 -0
- package/dist/types/common/grapheme-splitter.d.ts +15 -0
- package/dist/types/common/interruptible.d.ts +20 -0
- package/dist/types/common/one-of.d.ts +10 -0
- package/dist/types/common/signals.d.ts +96 -0
- package/dist/types/common/type/ast-nodes.d.ts +146 -0
- package/dist/types/common/type/boxed-type.d.ts +30 -0
- package/dist/types/common/type/lexer.d.ts +51 -0
- package/dist/types/common/type/parse.d.ts +211 -0
- package/dist/types/common/type/parser.d.ts +45 -0
- package/dist/types/common/type/primitive.d.ts +10 -0
- package/dist/types/common/type/serialize.d.ts +2 -0
- package/dist/types/common/type/subtype.d.ts +6 -0
- package/dist/types/common/type/type-builder.d.ts +32 -0
- package/dist/types/common/type/types.d.ts +300 -0
- package/dist/types/common/type/utils.d.ts +36 -0
- package/dist/types/common/utils.d.ts +23 -0
- package/dist/types/compute-engine/assume.d.ts +26 -0
- package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +165 -0
- package/dist/types/compute-engine/boxed-expression/apply.d.ts +5 -0
- package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +16 -0
- package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +27 -0
- package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +38 -0
- package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +11 -0
- package/dist/types/compute-engine/boxed-expression/box.d.ts +47 -0
- package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +44 -0
- package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +136 -0
- package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +103 -0
- package/dist/types/compute-engine/boxed-expression/boxed-operator-definition.d.ts +53 -0
- package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +107 -0
- package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +27 -0
- package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +170 -0
- package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +83 -0
- package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +46 -0
- package/dist/types/compute-engine/boxed-expression/cache.d.ts +7 -0
- package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +5 -0
- package/dist/types/compute-engine/boxed-expression/canonical.d.ts +2 -0
- package/dist/types/compute-engine/boxed-expression/compare.d.ts +13 -0
- package/dist/types/compute-engine/boxed-expression/expand.d.ts +20 -0
- package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +12 -0
- package/dist/types/compute-engine/boxed-expression/factor.d.ts +10 -0
- package/dist/types/compute-engine/boxed-expression/flatten.d.ts +25 -0
- package/dist/types/compute-engine/boxed-expression/hold.d.ts +10 -0
- package/dist/types/compute-engine/boxed-expression/match.d.ts +41 -0
- package/dist/types/compute-engine/boxed-expression/negate.d.ts +11 -0
- package/dist/types/compute-engine/boxed-expression/numerics.d.ts +34 -0
- package/dist/types/compute-engine/boxed-expression/order.d.ts +71 -0
- package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +105 -0
- package/dist/types/compute-engine/boxed-expression/product.d.ts +66 -0
- package/dist/types/compute-engine/boxed-expression/rules.d.ts +129 -0
- package/dist/types/compute-engine/boxed-expression/serialize.d.ts +3 -0
- package/dist/types/compute-engine/boxed-expression/sgn.d.ts +46 -0
- package/dist/types/compute-engine/boxed-expression/simplify.d.ts +6 -0
- package/dist/types/compute-engine/boxed-expression/solve.d.ts +20 -0
- package/dist/types/compute-engine/boxed-expression/terms.d.ts +10 -0
- package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +9 -0
- package/dist/types/compute-engine/boxed-expression/utils.d.ts +64 -0
- package/dist/types/compute-engine/boxed-expression/validate.d.ts +58 -0
- package/dist/types/compute-engine/collection-utils.d.ts +35 -0
- package/dist/types/compute-engine/compilation/base-compiler.d.ts +31 -0
- package/dist/types/compute-engine/compilation/javascript-target.d.ts +68 -0
- package/dist/types/compute-engine/compilation/types.d.ts +83 -0
- package/dist/types/compute-engine/cost-function.d.ts +13 -0
- package/dist/types/compute-engine/function-utils.d.ts +120 -0
- package/dist/types/compute-engine/global-types.d.ts +2930 -0
- package/dist/types/compute-engine/index.d.ts +660 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +2 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +2 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +2 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +2 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +27 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +2 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +2 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +2 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +2 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +2 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +2 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +3 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +2 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +88 -0
- package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +21 -0
- package/dist/types/compute-engine/latex-syntax/parse.d.ts +316 -0
- package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +29 -0
- package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +10 -0
- package/dist/types/compute-engine/latex-syntax/serializer.d.ts +37 -0
- package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +18 -0
- package/dist/types/compute-engine/latex-syntax/types.d.ts +896 -0
- package/dist/types/compute-engine/latex-syntax/utils.d.ts +5 -0
- package/dist/types/compute-engine/library/arithmetic.d.ts +4 -0
- package/dist/types/compute-engine/library/calculus.d.ts +2 -0
- package/dist/types/compute-engine/library/collections.d.ts +27 -0
- package/dist/types/compute-engine/library/combinatorics.d.ts +2 -0
- package/dist/types/compute-engine/library/complex.d.ts +2 -0
- package/dist/types/compute-engine/library/control-structures.d.ts +2 -0
- package/dist/types/compute-engine/library/core.d.ts +2 -0
- package/dist/types/compute-engine/library/invisible-operator.d.ts +4 -0
- package/dist/types/compute-engine/library/library.d.ts +17 -0
- package/dist/types/compute-engine/library/linear-algebra.d.ts +2 -0
- package/dist/types/compute-engine/library/logic-analysis.d.ts +64 -0
- package/dist/types/compute-engine/library/logic-utils.d.ts +58 -0
- package/dist/types/compute-engine/library/logic.d.ts +7 -0
- package/dist/types/compute-engine/library/number-theory.d.ts +2 -0
- package/dist/types/compute-engine/library/polynomials.d.ts +2 -0
- package/dist/types/compute-engine/library/random-expression.d.ts +2 -0
- package/dist/types/compute-engine/library/relational-operator.d.ts +2 -0
- package/dist/types/compute-engine/library/sets.d.ts +2 -0
- package/dist/types/compute-engine/library/statistics.d.ts +2 -0
- package/dist/types/compute-engine/library/trigonometry.d.ts +2 -0
- package/dist/types/compute-engine/library/utils.d.ts +77 -0
- package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +57 -0
- package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +75 -0
- package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +56 -0
- package/dist/types/compute-engine/numeric-value/types.d.ts +116 -0
- package/dist/types/compute-engine/numerics/bigint.d.ts +2 -0
- package/dist/types/compute-engine/numerics/expression.d.ts +4 -0
- package/dist/types/compute-engine/numerics/interval.d.ts +12 -0
- package/dist/types/compute-engine/numerics/monte-carlo.d.ts +4 -0
- package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +18 -0
- package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +9 -0
- package/dist/types/compute-engine/numerics/numeric-complex.d.ts +3 -0
- package/dist/types/compute-engine/numerics/numeric.d.ts +60 -0
- package/dist/types/compute-engine/numerics/primes.d.ts +7 -0
- package/dist/types/compute-engine/numerics/rationals.d.ts +43 -0
- package/dist/types/compute-engine/numerics/richardson.d.ts +80 -0
- package/dist/types/compute-engine/numerics/special-functions.d.ts +28 -0
- package/dist/types/compute-engine/numerics/statistics.d.ts +24 -0
- package/dist/types/compute-engine/numerics/strings.d.ts +2 -0
- package/dist/types/compute-engine/numerics/types.d.ts +30 -0
- package/dist/types/compute-engine/symbolic/antiderivative.d.ts +3 -0
- package/dist/types/compute-engine/symbolic/derivative.d.ts +18 -0
- package/dist/types/compute-engine/symbolic/distribute.d.ts +5 -0
- package/dist/types/compute-engine/symbolic/simplify-product.d.ts +6 -0
- package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +27 -0
- package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +6 -0
- package/dist/types/compute-engine/tensor/tensor-fields.d.ts +128 -0
- package/dist/types/compute-engine/tensor/tensors.d.ts +93 -0
- package/dist/types/compute-engine/types.d.ts +8 -0
- package/dist/types/compute-engine.d.ts +3 -0
- package/dist/types/math-json/symbols.d.ts +11 -0
- package/dist/types/math-json/types.d.ts +122 -0
- package/dist/types/math-json/utils.d.ts +87 -0
- package/dist/types/math-json.d.ts +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,2930 @@
|
|
|
1
|
+
/* 0.32.1 */
|
|
2
|
+
import type { OneOf } from '../common/one-of';
|
|
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';
|
|
11
|
+
/** @category Compiling */
|
|
12
|
+
export type CompiledType = boolean | number | string | object;
|
|
13
|
+
/** @category Compiling */
|
|
14
|
+
export type JSSource = string;
|
|
15
|
+
/** @category Compiling */
|
|
16
|
+
export type CompiledExpression = {
|
|
17
|
+
evaluate?: (scope: {
|
|
18
|
+
[symbol: string]: BoxedExpression;
|
|
19
|
+
}) => number | BoxedExpression;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Map of `TensorDataType` to JavaScript type.
|
|
23
|
+
*
|
|
24
|
+
* @category Tensors */
|
|
25
|
+
export type DataTypeMap = {
|
|
26
|
+
float64: number;
|
|
27
|
+
float32: number;
|
|
28
|
+
int32: number;
|
|
29
|
+
uint8: number;
|
|
30
|
+
complex128: Complex;
|
|
31
|
+
complex64: Complex;
|
|
32
|
+
bool: boolean;
|
|
33
|
+
expression: BoxedExpression;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* The type of the cells in a tensor.
|
|
37
|
+
* @category Tensors */
|
|
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
|
+
}
|
|
52
|
+
/** @category Tensors */
|
|
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> {
|
|
92
|
+
dtype: DT;
|
|
93
|
+
shape: number[];
|
|
94
|
+
rank: number;
|
|
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;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* :::info[THEORY OF OPERATIONS]
|
|
133
|
+
*
|
|
134
|
+
* The `BoxedExpression` interface includes the methods and properties
|
|
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.
|
|
138
|
+
*
|
|
139
|
+
* When a property is not applicable to this `BoxedExpression` its value is
|
|
140
|
+
* `null`. For example `expr.symbol` for a `BoxedNumber` is `null`.
|
|
141
|
+
*
|
|
142
|
+
* This convention makes it convenient to manipulate expressions without
|
|
143
|
+
* having to check what kind of instance they are before manipulating them.
|
|
144
|
+
* :::
|
|
145
|
+
*
|
|
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.
|
|
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
|
+
* :::
|
|
197
|
+
*
|
|
198
|
+
* To create a boxed expression:
|
|
199
|
+
*
|
|
200
|
+
* ### `ce.box()` and `ce.parse()`
|
|
201
|
+
*
|
|
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:
|
|
210
|
+
* - the arguments are put in canonical form
|
|
211
|
+
* - the arguments of commutative functions are sorted
|
|
212
|
+
* - invisible operators are made explicit
|
|
213
|
+
* - a limited number of core simplifications are applied,
|
|
214
|
+
* for example rationals are reduced
|
|
215
|
+
* - sequences are flattened: `["Add", 1, ["Sequence", 2, 3]]` is
|
|
216
|
+
* transformed to `["Add", 1, 2, 3]`
|
|
217
|
+
* - associative functions are flattened: `["Add", 1, ["Add", 2, 3]]` is
|
|
218
|
+
* transformed to `["Add", 1, 2, 3]`
|
|
219
|
+
* - symbols are **not** replaced with their values (unless they have
|
|
220
|
+
* a `holdUntil` flag set to `never`).
|
|
221
|
+
*
|
|
222
|
+
* ### `ce.function()`
|
|
223
|
+
*
|
|
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
|
|
234
|
+
* internal calculations, although they may be used as part of the public
|
|
235
|
+
* API as well.
|
|
236
|
+
*
|
|
237
|
+
* - a runtime error is thrown if the expression is not canonical
|
|
238
|
+
* - the arguments are not evaluated
|
|
239
|
+
* - the canonical handler (of the corresponding operation) is not called
|
|
240
|
+
* - some additional simplifications over canonicalization are applied.
|
|
241
|
+
* For example number literals are combined.
|
|
242
|
+
* However, the result is exact, and no approximation is made. Use `.N()`
|
|
243
|
+
* to get an approximate value.
|
|
244
|
+
* This is equivalent to calling `simplify()` on the expression (but
|
|
245
|
+
* without simplifying the arguments).
|
|
246
|
+
* - sequences were already flattened as part of the canonicalization process
|
|
247
|
+
*
|
|
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.
|
|
252
|
+
*
|
|
253
|
+
* These methods are not equivalent to calling `expr.evaluate()` on the
|
|
254
|
+
* expression: evaluate will replace symbols with their values, and
|
|
255
|
+
* evaluate the expression.
|
|
256
|
+
*
|
|
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.
|
|
265
|
+
*
|
|
266
|
+
* ### `ce._fn()`
|
|
267
|
+
*
|
|
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.
|
|
270
|
+
*
|
|
271
|
+
* The arguments are not modified. The expression is not put in canonical
|
|
272
|
+
* form. The canonical handler is *not* called.
|
|
273
|
+
*
|
|
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.
|
|
277
|
+
*
|
|
278
|
+
*
|
|
279
|
+
*
|
|
280
|
+
* ### Canonical Handlers
|
|
281
|
+
*
|
|
282
|
+
* Canonical handlers are responsible for:
|
|
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.
|
|
289
|
+
* - flattening sequences
|
|
290
|
+
* - flattening arguments if the function is associative
|
|
291
|
+
* - sort the arguments (if the function is commutative)
|
|
292
|
+
* - calling `ce._fn()` to create a new function expression
|
|
293
|
+
*
|
|
294
|
+
* When the canonical handler is invoked, the arguments have been put in
|
|
295
|
+
* canonical form unless the `lazy` flag is set to `true`.
|
|
296
|
+
*
|
|
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.
|
|
301
|
+
*
|
|
302
|
+
* @category Boxed Expression
|
|
303
|
+
*
|
|
304
|
+
*/
|
|
305
|
+
export interface BoxedExpression {
|
|
306
|
+
/** @internal */
|
|
307
|
+
readonly hash: number;
|
|
308
|
+
/**
|
|
309
|
+
* The Compute Engine instance associated with this expression provides
|
|
310
|
+
* a context in which to interpret it, such as definition of symbols
|
|
311
|
+
* and functions.
|
|
312
|
+
*/
|
|
313
|
+
readonly engine: ComputeEngine;
|
|
314
|
+
/**
|
|
315
|
+
*
|
|
316
|
+
* Return a JavaScript primitive value for the expression, based on
|
|
317
|
+
* `Object.valueOf()`.
|
|
318
|
+
*
|
|
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.
|
|
322
|
+
*
|
|
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.
|
|
346
|
+
*
|
|
347
|
+
* @category Primitive Methods
|
|
348
|
+
*/
|
|
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()`.
|
|
355
|
+
*
|
|
356
|
+
* To get a LaTeX representation of the expression, use `expr.latex`.
|
|
357
|
+
*
|
|
358
|
+
* Note that lazy collections are eagerly evaluated.
|
|
359
|
+
*
|
|
360
|
+
* Used when coercing a `BoxedExpression` to a `String`.
|
|
361
|
+
*
|
|
362
|
+
* @category Primitive Methods
|
|
363
|
+
*/
|
|
364
|
+
toString(): string;
|
|
365
|
+
/** Serialize to a LaTeX string.
|
|
366
|
+
*
|
|
367
|
+
* Note that lazy collections are eagerly evaluated.
|
|
368
|
+
*
|
|
369
|
+
* Will ignore any LaTeX metadata.
|
|
370
|
+
*/
|
|
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
|
+
* :::
|
|
384
|
+
*
|
|
385
|
+
*/
|
|
386
|
+
get latex(): LatexString;
|
|
387
|
+
/** Used by `JSON.stringify()` to serialize this object to JSON.
|
|
388
|
+
*
|
|
389
|
+
* Method version of `expr.json`.
|
|
390
|
+
*
|
|
391
|
+
* Based on `Object.toJSON()`.
|
|
392
|
+
*
|
|
393
|
+
* Note that lazy collections are *not* eagerly evaluated.
|
|
394
|
+
*
|
|
395
|
+
* @category Primitive Methods
|
|
396
|
+
*/
|
|
397
|
+
toJSON(): Expression;
|
|
398
|
+
/** Serialize to a MathJSON expression with specified options */
|
|
399
|
+
toMathJson(options?: Readonly<Partial<JsonSerializationOptions>>): Expression;
|
|
400
|
+
/** MathJSON representation of this expression.
|
|
401
|
+
*
|
|
402
|
+
* This representation always use shorthands when possible. Metadata is not
|
|
403
|
+
* included.
|
|
404
|
+
*
|
|
405
|
+
* Numbers are converted to JavaScript numbers and may lose precision.
|
|
406
|
+
*
|
|
407
|
+
* The expression is represented exactly and no sugaring is applied. For
|
|
408
|
+
* example, `["Power", "x", 2]` is not represented as `["Square", "x"]`.
|
|
409
|
+
*
|
|
410
|
+
* For more control over the serialization, use `expr.toMathJson()`.
|
|
411
|
+
*
|
|
412
|
+
* Note that lazy collections are *not* eagerly evaluated.
|
|
413
|
+
*
|
|
414
|
+
* :::info[Note]
|
|
415
|
+
* Applicable to canonical and non-canonical expressions.
|
|
416
|
+
* :::
|
|
417
|
+
*
|
|
418
|
+
*/
|
|
419
|
+
readonly json: Expression;
|
|
420
|
+
/**
|
|
421
|
+
* Output to the console a string representation of the expression.
|
|
422
|
+
*
|
|
423
|
+
* Note that lazy collections are eagerly evaluated when printed.
|
|
424
|
+
*
|
|
425
|
+
*/
|
|
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.
|
|
438
|
+
*
|
|
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.
|
|
442
|
+
*
|
|
443
|
+
*/
|
|
444
|
+
get isStructural(): boolean;
|
|
445
|
+
/**
|
|
446
|
+
* Return the canonical form of this expression.
|
|
447
|
+
*
|
|
448
|
+
* If a function expression or symbol, they are first bound with a definition
|
|
449
|
+
* in the current scope.
|
|
450
|
+
*
|
|
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.
|
|
465
|
+
*
|
|
466
|
+
* :::info[Note]
|
|
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).
|
|
472
|
+
* :::
|
|
473
|
+
*
|
|
474
|
+
*/
|
|
475
|
+
get canonical(): BoxedExpression;
|
|
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.
|
|
492
|
+
*
|
|
493
|
+
* :::info[Note]
|
|
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.
|
|
498
|
+
* :::
|
|
499
|
+
*
|
|
500
|
+
*/
|
|
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.
|
|
519
|
+
*
|
|
520
|
+
* :::info[Note]
|
|
521
|
+
* Applicable to canonical expressions only
|
|
522
|
+
* :::
|
|
523
|
+
*/
|
|
524
|
+
readonly isPure: boolean;
|
|
525
|
+
/**
|
|
526
|
+
* `True` if evaluating this expression always returns the same value.
|
|
527
|
+
*
|
|
528
|
+
* If *true* and a function expression, implies that it is *pure* and
|
|
529
|
+
* that all of its arguments are constant.
|
|
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.
|
|
538
|
+
*/
|
|
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`.
|
|
544
|
+
*
|
|
545
|
+
* :::info[Note]
|
|
546
|
+
* Applicable to canonical and non-canonical expressions.
|
|
547
|
+
* :::
|
|
548
|
+
*
|
|
549
|
+
*/
|
|
550
|
+
readonly errors: ReadonlyArray<BoxedExpression>;
|
|
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
|
+
* ```
|
|
560
|
+
*
|
|
561
|
+
* :::info[Note]
|
|
562
|
+
* Applicable to canonical and non-canonical expressions.
|
|
563
|
+
* :::
|
|
564
|
+
*
|
|
565
|
+
*/
|
|
566
|
+
getSubexpressions(operator: string): ReadonlyArray<BoxedExpression>;
|
|
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
|
+
* ```
|
|
576
|
+
*
|
|
577
|
+
* :::info[Note]
|
|
578
|
+
* Applicable to canonical and non-canonical expressions.
|
|
579
|
+
* :::
|
|
580
|
+
*
|
|
581
|
+
*/
|
|
582
|
+
readonly subexpressions: ReadonlyArray<BoxedExpression>;
|
|
583
|
+
/**
|
|
584
|
+
*
|
|
585
|
+
* All the symbols in the expression, recursively
|
|
586
|
+
*
|
|
587
|
+
* ```js
|
|
588
|
+
* const expr = ce.parse('a + b * c + d');
|
|
589
|
+
* const symbols = expr.symbols;
|
|
590
|
+
* // -> ['a', 'b', 'c', 'd']
|
|
591
|
+
* ```
|
|
592
|
+
*
|
|
593
|
+
* :::info[Note]
|
|
594
|
+
* Applicable to canonical and non-canonical expressions.
|
|
595
|
+
* :::
|
|
596
|
+
*
|
|
597
|
+
*/
|
|
598
|
+
readonly symbols: ReadonlyArray<string>;
|
|
599
|
+
/**
|
|
600
|
+
* All the symbols used in the expression that do not have a value
|
|
601
|
+
* associated with them, i.e. they are declared but not defined.
|
|
602
|
+
*/
|
|
603
|
+
readonly unknowns: ReadonlyArray<string>;
|
|
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`.
|
|
609
|
+
*
|
|
610
|
+
* @category Numeric Expression
|
|
611
|
+
*
|
|
612
|
+
*/
|
|
613
|
+
readonly isNumberLiteral: boolean;
|
|
614
|
+
/**
|
|
615
|
+
* Return the value of this expression, if a number literal.
|
|
616
|
+
*
|
|
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.
|
|
620
|
+
*
|
|
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
|
|
630
|
+
*
|
|
631
|
+
*/
|
|
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`.
|
|
785
|
+
*
|
|
786
|
+
* :::info[Note]
|
|
787
|
+
* Applicable to canonical and non-canonical expressions.
|
|
788
|
+
* :::
|
|
789
|
+
*
|
|
790
|
+
* @category Symbol Expression
|
|
791
|
+
*
|
|
792
|
+
*/
|
|
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;
|
|
814
|
+
/**
|
|
815
|
+
* The name of the operator of the expression.
|
|
816
|
+
*
|
|
817
|
+
* For example, the name of the operator of `["Add", 2, 3]` is `"Add"`.
|
|
818
|
+
*
|
|
819
|
+
* A string literal has a `"String"` operator.
|
|
820
|
+
*
|
|
821
|
+
* A symbol has a `"Symbol"` operator.
|
|
822
|
+
*
|
|
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"`.
|
|
826
|
+
*
|
|
827
|
+
* @category Function Expression
|
|
828
|
+
*/
|
|
829
|
+
readonly operator: string;
|
|
830
|
+
/** The list of operands of the function.
|
|
831
|
+
*
|
|
832
|
+
* If the expression is not a function, return `null`.
|
|
833
|
+
*
|
|
834
|
+
* :::info[Note]
|
|
835
|
+
* Applicable to canonical and non-canonical expressions.
|
|
836
|
+
* :::
|
|
837
|
+
*
|
|
838
|
+
* @category Function Expression
|
|
839
|
+
*
|
|
840
|
+
*/
|
|
841
|
+
readonly ops: null | ReadonlyArray<BoxedExpression>;
|
|
842
|
+
/** If this expression is a function, the number of operands, otherwise 0.
|
|
843
|
+
*
|
|
844
|
+
* Note that a function can have 0 operands, so to check if this expression
|
|
845
|
+
* is a function, check if `this.ops !== null` instead.
|
|
846
|
+
*
|
|
847
|
+
* :::info[Note]
|
|
848
|
+
* Applicable to canonical and non-canonical expressions.
|
|
849
|
+
* :::
|
|
850
|
+
*
|
|
851
|
+
* @category Function Expression
|
|
852
|
+
*
|
|
853
|
+
*/
|
|
854
|
+
readonly nops: number;
|
|
855
|
+
/** First operand, i.e.`this.ops[0]`.
|
|
856
|
+
*
|
|
857
|
+
* If there is no first operand, return the symbol `Nothing`.
|
|
858
|
+
*
|
|
859
|
+
* :::info[Note]
|
|
860
|
+
* Applicable to canonical and non-canonical expressions.
|
|
861
|
+
* :::
|
|
862
|
+
*
|
|
863
|
+
* @category Function Expression
|
|
864
|
+
*
|
|
865
|
+
*
|
|
866
|
+
*/
|
|
867
|
+
readonly op1: BoxedExpression;
|
|
868
|
+
/** Second operand, i.e.`this.ops[1]`
|
|
869
|
+
*
|
|
870
|
+
* If there is no second operand, return the symbol `Nothing`.
|
|
871
|
+
*
|
|
872
|
+
* :::info[Note]
|
|
873
|
+
* Applicable to canonical and non-canonical expressions.
|
|
874
|
+
* :::
|
|
875
|
+
*
|
|
876
|
+
* @category Function Expression
|
|
877
|
+
*
|
|
878
|
+
*
|
|
879
|
+
*/
|
|
880
|
+
readonly op2: BoxedExpression;
|
|
881
|
+
/** Third operand, i.e. `this.ops[2]`
|
|
882
|
+
*
|
|
883
|
+
* If there is no third operand, return the symbol `Nothing`.
|
|
884
|
+
*
|
|
885
|
+
* :::info[Note]
|
|
886
|
+
* Applicable to canonical and non-canonical expressions.
|
|
887
|
+
* :::
|
|
888
|
+
*
|
|
889
|
+
* @category Function Expression
|
|
890
|
+
*
|
|
891
|
+
*
|
|
892
|
+
*/
|
|
893
|
+
readonly op3: BoxedExpression;
|
|
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.
|
|
897
|
+
*/
|
|
898
|
+
readonly isScoped: boolean;
|
|
899
|
+
/** If this expression has a local scope, return it. */
|
|
900
|
+
get localScope(): Scope | undefined;
|
|
901
|
+
/**
|
|
902
|
+
* Replace all the symbols in the expression as indicated.
|
|
903
|
+
*
|
|
904
|
+
* Note the same effect can be achieved with `this.replace()`, but
|
|
905
|
+
* using `this.subs()` is more efficient and simpler, but limited
|
|
906
|
+
* to replacing symbols.
|
|
907
|
+
*
|
|
908
|
+
* The result is bound to the current scope, not to `this.scope`.
|
|
909
|
+
*
|
|
910
|
+
* If `options.canonical` is not set, the result is canonical if `this`
|
|
911
|
+
* is canonical.
|
|
912
|
+
*
|
|
913
|
+
* :::info[Note]
|
|
914
|
+
* Applicable to canonical and non-canonical expressions.
|
|
915
|
+
*
|
|
916
|
+
* If this is a function, an empty substitution is given, and the computed value of `canonical`
|
|
917
|
+
* does not differ from that of this expr.: then a call this method is analagous to requesting a
|
|
918
|
+
* *clone*.
|
|
919
|
+
* :::
|
|
920
|
+
*
|
|
921
|
+
*/
|
|
922
|
+
subs(sub: Substitution, options?: {
|
|
923
|
+
canonical?: CanonicalOptions;
|
|
924
|
+
}): BoxedExpression;
|
|
925
|
+
/**
|
|
926
|
+
* Recursively replace all the subexpressions in the expression as indicated.
|
|
927
|
+
*
|
|
928
|
+
* To remove a subexpression, return an empty `["Sequence"]` expression.
|
|
929
|
+
*
|
|
930
|
+
* The `canonical` option is applied to each function subexpression after
|
|
931
|
+
* the substitution is applied.
|
|
932
|
+
*
|
|
933
|
+
* If no `options.canonical` is set, the result is canonical if `this`
|
|
934
|
+
* is canonical.
|
|
935
|
+
*
|
|
936
|
+
* **Default**: `{ canonical: this.isCanonical, recursive: true }`
|
|
937
|
+
*
|
|
938
|
+
* :::info[Note]
|
|
939
|
+
* Applicable to canonical and non-canonical expressions.
|
|
940
|
+
* :::
|
|
941
|
+
*/
|
|
942
|
+
map(fn: (expr: BoxedExpression) => BoxedExpression, options?: {
|
|
943
|
+
canonical: CanonicalOptions;
|
|
944
|
+
recursive?: boolean;
|
|
945
|
+
}): BoxedExpression;
|
|
946
|
+
/**
|
|
947
|
+
* Transform the expression by applying one or more replacement rules:
|
|
948
|
+
*
|
|
949
|
+
* - If the expression matches the `match` pattern and the `condition`
|
|
950
|
+
* predicate is true, replace it with the `replace` pattern.
|
|
951
|
+
*
|
|
952
|
+
* - If no rules apply, return `null`.
|
|
953
|
+
*
|
|
954
|
+
* See also `expr.subs()` for a simple substitution of symbols.
|
|
955
|
+
*
|
|
956
|
+
* Procedure for the determining the canonical-status of the input expression and replacements:
|
|
957
|
+
*
|
|
958
|
+
* - If `options.canonical` is set, the *entire expr.* is canonicalized to this degree: whether
|
|
959
|
+
* the replacement occurs at the top-level, or within/recursively.
|
|
960
|
+
*
|
|
961
|
+
* - If otherwise, the *direct replacement will be canonical* if either the 'replaced' expression
|
|
962
|
+
* is canonical, or the given replacement (- is a BoxedExpression and -) is canonical.
|
|
963
|
+
* Notably also, if this replacement takes place recursively (not at the top-level), then exprs.
|
|
964
|
+
* containing the replaced expr. will still however have their (previous) canonical-status
|
|
965
|
+
* *preserved*... unless this expr. was previously non-canonical, and *replacements have resulted
|
|
966
|
+
* in canonical operands*. In this case, an expr. meeting this criteria will be updated to
|
|
967
|
+
* canonical status. (Canonicalization is opportunistic here, in other words).
|
|
968
|
+
*
|
|
969
|
+
* :::info[Note]
|
|
970
|
+
* Applicable to canonical and non-canonical expressions.
|
|
971
|
+
*
|
|
972
|
+
* To match a specific symbol (not a wildcard pattern), the `match` must be
|
|
973
|
+
* a `BoxedExpression` (e.g., `{ match: ce.box('x'), replace: ... }`).
|
|
974
|
+
* For simple symbol substitution, consider using `subs()` instead.
|
|
975
|
+
* :::
|
|
976
|
+
*/
|
|
977
|
+
replace(rules: BoxedRuleSet | Rule | Rule[], options?: Partial<ReplaceOptions>): null | BoxedExpression;
|
|
978
|
+
/**
|
|
979
|
+
* True if the expression includes a symbol `v` or a function operator `v`.
|
|
980
|
+
*
|
|
981
|
+
* :::info[Note]
|
|
982
|
+
* Applicable to canonical and non-canonical expressions.
|
|
983
|
+
* :::
|
|
984
|
+
*/
|
|
985
|
+
has(v: string | string[]): boolean;
|
|
986
|
+
/** Structural/symbolic equality (weak equality).
|
|
987
|
+
*
|
|
988
|
+
* `ce.parse('1+x', {canonical: false}).isSame(ce.parse('x+1', {canonical: false}))` is `false`.
|
|
989
|
+
*
|
|
990
|
+
* See `expr.isEqual()` for mathematical equality.
|
|
991
|
+
*
|
|
992
|
+
* :::info[Note]
|
|
993
|
+
* Applicable to canonical and non-canonical expressions.
|
|
994
|
+
* :::
|
|
995
|
+
*
|
|
996
|
+
* @category Relational Operator
|
|
997
|
+
*/
|
|
998
|
+
isSame(rhs: BoxedExpression): boolean;
|
|
999
|
+
/**
|
|
1000
|
+
* Equivalent to `BoxedExpression.isSame()` but the argument can be
|
|
1001
|
+
* a JavaScript primitive. For example, `expr.is(2)` is equivalent to
|
|
1002
|
+
* `expr.isSame(ce.number(2))`.
|
|
1003
|
+
*
|
|
1004
|
+
* @category Primitive Methods
|
|
1005
|
+
*
|
|
1006
|
+
*/
|
|
1007
|
+
is(other: BoxedExpression | number | bigint | boolean | string): boolean;
|
|
1008
|
+
/**
|
|
1009
|
+
* If this expression matches `pattern`, return a substitution that makes
|
|
1010
|
+
* `pattern` equal to `this`. Otherwise return `null`.
|
|
1011
|
+
*
|
|
1012
|
+
* If `pattern` includes wildcards (symbols that start
|
|
1013
|
+
* with `_`), the substitution will include a prop for each matching named
|
|
1014
|
+
* wildcard.
|
|
1015
|
+
*
|
|
1016
|
+
* If this expression matches `pattern` but there are no named wildcards,
|
|
1017
|
+
* return the empty substitution, `{}`.
|
|
1018
|
+
*
|
|
1019
|
+
* Read more about [**patterns and rules**](/compute-engine/guides/patterns-and-rules/).
|
|
1020
|
+
*
|
|
1021
|
+
* :::info[Note]
|
|
1022
|
+
* Applicable to canonical and non-canonical expressions.
|
|
1023
|
+
* :::
|
|
1024
|
+
*
|
|
1025
|
+
*/
|
|
1026
|
+
match(pattern: BoxedExpression, options?: PatternMatchOptions): BoxedSubstitution | null;
|
|
1027
|
+
/** If this expression is a tensor, return the tensor data.
|
|
1028
|
+
* Otherwise, return `null`.
|
|
1029
|
+
*
|
|
1030
|
+
* :::info[Note]
|
|
1031
|
+
* Applicable to canonical and non-canonical expressions.
|
|
1032
|
+
* :::
|
|
1033
|
+
*
|
|
1034
|
+
* @category Tensor Expression
|
|
1035
|
+
*
|
|
1036
|
+
*/
|
|
1037
|
+
readonly tensor: null | Tensor<any>;
|
|
1038
|
+
/**
|
|
1039
|
+
*
|
|
1040
|
+
* The **shape** describes the **axes** of the expression, where each axis
|
|
1041
|
+
* represent a way to index the elements of the expression.
|
|
1042
|
+
*
|
|
1043
|
+
* When the expression is a scalar (number), the shape is `[]`.
|
|
1044
|
+
*
|
|
1045
|
+
* When the expression is a vector of length `n`, the shape is `[n]`.
|
|
1046
|
+
*
|
|
1047
|
+
* When the expression is a `n` by `m` matrix, the shape is `[n, m]`.
|
|
1048
|
+
*
|
|
1049
|
+
* @category Tensor Expression
|
|
1050
|
+
*
|
|
1051
|
+
*/
|
|
1052
|
+
readonly shape: number[];
|
|
1053
|
+
/**
|
|
1054
|
+
* The **rank** refers to the number of dimensions (or axes) of the
|
|
1055
|
+
* expression.
|
|
1056
|
+
*
|
|
1057
|
+
* Return 0 for a scalar, 1 for a vector, 2 for a matrix, > 2 for
|
|
1058
|
+
* a multidimensional matrix.
|
|
1059
|
+
*
|
|
1060
|
+
* The rank is equivalent to the length of `expr.shape`
|
|
1061
|
+
*
|
|
1062
|
+
* :::info[Note]
|
|
1063
|
+
* There are several definitions of rank in the literature.
|
|
1064
|
+
* For example, the row rank of a matrix is the number of linearly
|
|
1065
|
+
* independent rows. The rank can also refer to the number of non-zero
|
|
1066
|
+
* singular values of a matrix.
|
|
1067
|
+
* :::
|
|
1068
|
+
*
|
|
1069
|
+
* @category Tensor Expression
|
|
1070
|
+
* */
|
|
1071
|
+
readonly rank: number;
|
|
1072
|
+
/**
|
|
1073
|
+
*
|
|
1074
|
+
* The value of both expressions are compared.
|
|
1075
|
+
*
|
|
1076
|
+
* If the expressions cannot be compared, return `undefined`
|
|
1077
|
+
*
|
|
1078
|
+
* @category Relational Operator
|
|
1079
|
+
*/
|
|
1080
|
+
isLess(other: number | BoxedExpression): boolean | undefined;
|
|
1081
|
+
/**
|
|
1082
|
+
* The value of both expressions are compared.
|
|
1083
|
+
*
|
|
1084
|
+
* If the expressions cannot be compared, return `undefined`
|
|
1085
|
+
* @category Relational Operator
|
|
1086
|
+
*/
|
|
1087
|
+
isLessEqual(other: number | BoxedExpression): boolean | undefined;
|
|
1088
|
+
/**
|
|
1089
|
+
* The value of both expressions are compared.
|
|
1090
|
+
*
|
|
1091
|
+
* If the expressions cannot be compared, return `undefined`
|
|
1092
|
+
* @category Relational Operator
|
|
1093
|
+
*/
|
|
1094
|
+
isGreater(other: number | BoxedExpression): boolean | undefined;
|
|
1095
|
+
/**
|
|
1096
|
+
* The value of both expressions are compared.
|
|
1097
|
+
*
|
|
1098
|
+
* If the expressions cannot be compared, return `undefined`
|
|
1099
|
+
* @category Relational Operator
|
|
1100
|
+
*/
|
|
1101
|
+
isGreaterEqual(other: number | BoxedExpression): boolean | undefined;
|
|
1102
|
+
/**
|
|
1103
|
+
* If true, the value of this expression is "Not a Number".
|
|
1104
|
+
*
|
|
1105
|
+
* A value representing undefined result of computations, such as `0/0`,
|
|
1106
|
+
* as per the floating point format standard IEEE-754.
|
|
1107
|
+
*
|
|
1108
|
+
* Note that if `isNaN` is true, `isNumber` is also true (yes, `NaN` is a
|
|
1109
|
+
* number).
|
|
1110
|
+
*
|
|
1111
|
+
* @category Numeric Expression
|
|
1112
|
+
*
|
|
1113
|
+
*/
|
|
1114
|
+
readonly isNaN: boolean | undefined;
|
|
1115
|
+
/**
|
|
1116
|
+
* The numeric value of this expression is `±Infinity` or ComplexInfinity.
|
|
1117
|
+
*
|
|
1118
|
+
* @category Numeric Expression
|
|
1119
|
+
*/
|
|
1120
|
+
readonly isInfinity: boolean | undefined;
|
|
1121
|
+
/** This expression is a number, but not `±Infinity`, `ComplexInfinity` or
|
|
1122
|
+
* `NaN`
|
|
1123
|
+
*
|
|
1124
|
+
* @category Numeric Expression
|
|
1125
|
+
*/
|
|
1126
|
+
readonly isFinite: boolean | undefined;
|
|
1127
|
+
/**
|
|
1128
|
+
* Wikidata identifier.
|
|
1129
|
+
*
|
|
1130
|
+
* If not a canonical expression, return `undefined`.
|
|
1131
|
+
*
|
|
1132
|
+
*/
|
|
1133
|
+
readonly wikidata: string | undefined;
|
|
1134
|
+
/** An optional short description if a symbol or function expression.
|
|
1135
|
+
*
|
|
1136
|
+
* May include markdown. Each string is a paragraph.
|
|
1137
|
+
*
|
|
1138
|
+
* If not a canonical expression, return `undefined`.
|
|
1139
|
+
*
|
|
1140
|
+
*/
|
|
1141
|
+
readonly description: undefined | string[];
|
|
1142
|
+
/** An optional URL pointing to more information about the symbol or
|
|
1143
|
+
* function operator.
|
|
1144
|
+
*
|
|
1145
|
+
* If not a canonical expression, return `undefined`.
|
|
1146
|
+
*
|
|
1147
|
+
*/
|
|
1148
|
+
readonly url: string | undefined;
|
|
1149
|
+
/** Expressions with a higher complexity score are sorted
|
|
1150
|
+
* first in commutative functions
|
|
1151
|
+
*
|
|
1152
|
+
* If not a canonical expression, return `undefined`.
|
|
1153
|
+
*/
|
|
1154
|
+
readonly complexity: number | undefined;
|
|
1155
|
+
/**
|
|
1156
|
+
* For symbols and functions, a definition associated with the
|
|
1157
|
+
* expression. `this.baseDefinition` is the base class of symbol and function
|
|
1158
|
+
* definition.
|
|
1159
|
+
*
|
|
1160
|
+
* If not a canonical expression, return `undefined`.
|
|
1161
|
+
*
|
|
1162
|
+
*/
|
|
1163
|
+
readonly baseDefinition: BoxedBaseDefinition | undefined;
|
|
1164
|
+
/**
|
|
1165
|
+
* For function expressions, the definition of the operator associated with
|
|
1166
|
+
* the expression. For symbols, the definition of the symbol if it is an
|
|
1167
|
+
* operator, for example `"Sin"`.
|
|
1168
|
+
*
|
|
1169
|
+
* If not a canonical expression or not a function expression,
|
|
1170
|
+
* its value is `undefined`.
|
|
1171
|
+
*
|
|
1172
|
+
*/
|
|
1173
|
+
readonly operatorDefinition: BoxedOperatorDefinition | undefined;
|
|
1174
|
+
/**
|
|
1175
|
+
* For symbols, a definition associated with the expression, if it is
|
|
1176
|
+
* not an operator.
|
|
1177
|
+
*
|
|
1178
|
+
* If not a canonical expression, or not a value, its value is `undefined`.
|
|
1179
|
+
*
|
|
1180
|
+
*/
|
|
1181
|
+
readonly valueDefinition: BoxedValueDefinition | undefined;
|
|
1182
|
+
/**
|
|
1183
|
+
*
|
|
1184
|
+
* Infer the type of this expression.
|
|
1185
|
+
*
|
|
1186
|
+
* For symbols, inference may take place for undeclared symbols,
|
|
1187
|
+
* symbols with an `unknown` type, or symbols with an inferred type.
|
|
1188
|
+
*
|
|
1189
|
+
* Constant symbols always have a defined type, and will return `false`.
|
|
1190
|
+
*
|
|
1191
|
+
* For functions, inference only takes place if it has an *inferred
|
|
1192
|
+
* signature*.
|
|
1193
|
+
*
|
|
1194
|
+
*
|
|
1195
|
+
* For a successful inference, *narrows* the type for symbols,
|
|
1196
|
+
* and for functions, narrows the *(return) type*.
|
|
1197
|
+
*
|
|
1198
|
+
* Subsequent inferences can be made and will refine previous ones if valid.
|
|
1199
|
+
*
|
|
1200
|
+
* If the given type is incompatible with the declared or previously inferred
|
|
1201
|
+
* type, return `false`.
|
|
1202
|
+
*
|
|
1203
|
+
*
|
|
1204
|
+
* @internal
|
|
1205
|
+
*/
|
|
1206
|
+
infer(t: Type, inferenceMode?: 'narrow' | 'widen'): boolean;
|
|
1207
|
+
/**
|
|
1208
|
+
* Update the definition associated with this expression, using the
|
|
1209
|
+
* current scope (`ce.context`).
|
|
1210
|
+
*
|
|
1211
|
+
* @internal
|
|
1212
|
+
*/
|
|
1213
|
+
bind(): void;
|
|
1214
|
+
/**
|
|
1215
|
+
*
|
|
1216
|
+
* Reset the cached value associated with this expression.
|
|
1217
|
+
*
|
|
1218
|
+
* Use when the environment, for example the precision, has changed to
|
|
1219
|
+
* force the expression to be re-evaluated.
|
|
1220
|
+
*
|
|
1221
|
+
* @internal
|
|
1222
|
+
*/
|
|
1223
|
+
reset(): void;
|
|
1224
|
+
/**
|
|
1225
|
+
* Return a simpler form of this expression.
|
|
1226
|
+
*
|
|
1227
|
+
* A series of rewriting rules are applied repeatedly, until no more rules
|
|
1228
|
+
* apply.
|
|
1229
|
+
*
|
|
1230
|
+
* The values assigned to symbols and the assumptions about symbols may be
|
|
1231
|
+
* used, for example `expr.isInteger` or `expr.isPositive`.
|
|
1232
|
+
*
|
|
1233
|
+
* No calculations involving decimal numbers (numbers that are not
|
|
1234
|
+
* integers) are performed but exact calculations may be performed,
|
|
1235
|
+
* for example:
|
|
1236
|
+
*
|
|
1237
|
+
* $$ \sin(\frac{\pi}{4}) \longrightarrow \frac{\sqrt{2}}{2} $$.
|
|
1238
|
+
*
|
|
1239
|
+
* The result is canonical.
|
|
1240
|
+
*
|
|
1241
|
+
* To manipulate symbolically non-canonical expressions, use `expr.replace()`.
|
|
1242
|
+
*
|
|
1243
|
+
*/
|
|
1244
|
+
simplify(options?: Partial<SimplifyOptions>): BoxedExpression;
|
|
1245
|
+
/**
|
|
1246
|
+
* Expand the expression: distribute multiplications over additions,
|
|
1247
|
+
* and expand powers.
|
|
1248
|
+
*/
|
|
1249
|
+
expand(): BoxedExpression;
|
|
1250
|
+
/**
|
|
1251
|
+
* Return the value of the canonical form of this expression.
|
|
1252
|
+
*
|
|
1253
|
+
* A pure expression always returns the same value (provided that it
|
|
1254
|
+
* remains constant / values of sub-expressions or symbols do not change),
|
|
1255
|
+
* and has no side effects.
|
|
1256
|
+
*
|
|
1257
|
+
* Evaluating an impure expression may return a varying value, and may have
|
|
1258
|
+
* some side effects such as adjusting symbol assumptions.
|
|
1259
|
+
*
|
|
1260
|
+
* To perform approximate calculations, use `expr.N()` instead,
|
|
1261
|
+
* or call with `options.numericApproximation` to `true`.
|
|
1262
|
+
*
|
|
1263
|
+
* It is possible that the result of `expr.evaluate()` may be the same as
|
|
1264
|
+
* `expr.simplify()`.
|
|
1265
|
+
*
|
|
1266
|
+
* The result is in canonical form.
|
|
1267
|
+
*
|
|
1268
|
+
*/
|
|
1269
|
+
evaluate(options?: Partial<EvaluateOptions>): BoxedExpression;
|
|
1270
|
+
/** Asynchronous version of `evaluate()`.
|
|
1271
|
+
*
|
|
1272
|
+
* The `options` argument can include a `signal` property, which is an
|
|
1273
|
+
* `AbortSignal` object. If the signal is aborted, a `CancellationError` is thrown.
|
|
1274
|
+
*
|
|
1275
|
+
*/
|
|
1276
|
+
evaluateAsync(options?: Partial<EvaluateOptions>): Promise<BoxedExpression>;
|
|
1277
|
+
/** Return a numeric approximation of the canonical form of this expression.
|
|
1278
|
+
*
|
|
1279
|
+
* Any necessary calculations, including on decimal numbers (non-integers),
|
|
1280
|
+
* are performed.
|
|
1281
|
+
*
|
|
1282
|
+
* The calculations are performed according to the
|
|
1283
|
+
* `precision` property of the `ComputeEngine`.
|
|
1284
|
+
*
|
|
1285
|
+
* To only perform exact calculations, use `this.evaluate()` instead.
|
|
1286
|
+
*
|
|
1287
|
+
* If the function is not numeric, the result of `this.N()` is the same as
|
|
1288
|
+
* `this.evaluate()`.
|
|
1289
|
+
*
|
|
1290
|
+
* The result is in canonical form.
|
|
1291
|
+
*/
|
|
1292
|
+
N(): BoxedExpression;
|
|
1293
|
+
/**
|
|
1294
|
+
* Compile the expression to a JavaScript function.
|
|
1295
|
+
*
|
|
1296
|
+
* The function takes an object as argument, with the keys being the
|
|
1297
|
+
* symbols in the expression, and returns the value of the expression.
|
|
1298
|
+
*
|
|
1299
|
+
*
|
|
1300
|
+
* ```javascript
|
|
1301
|
+
* const expr = ce.parse("x^2 + y^2");
|
|
1302
|
+
* const f = expr.compile();
|
|
1303
|
+
* console.log(f({x: 2, y: 3}));
|
|
1304
|
+
* // -> 13
|
|
1305
|
+
* ```
|
|
1306
|
+
*
|
|
1307
|
+
* If the expression is a function literal, the function takes the
|
|
1308
|
+
* arguments of the function as arguments, and returns the value of the
|
|
1309
|
+
* expression.
|
|
1310
|
+
*
|
|
1311
|
+
* ```javascript
|
|
1312
|
+
* const expr = ce.parse("(x) \mapsto 2x");
|
|
1313
|
+
* const f = expr.compile();
|
|
1314
|
+
* console.log(f(42));
|
|
1315
|
+
* // -> 84
|
|
1316
|
+
* ```
|
|
1317
|
+
*
|
|
1318
|
+
* If the expression cannot be compiled, a JS function is returned that
|
|
1319
|
+
* falls back to the interpreting the expression, unless the
|
|
1320
|
+
* `options.fallback` is set to `false`. If it is set to `false`, the
|
|
1321
|
+
* function will throw an error if it cannot be compiled.
|
|
1322
|
+
*
|
|
1323
|
+
*/
|
|
1324
|
+
compile(options?: {
|
|
1325
|
+
to?: 'javascript' | 'wgsl' | 'python' | 'webassembly';
|
|
1326
|
+
functions?: Record<MathJsonSymbol, JSSource | ((...any: any[]) => any)>;
|
|
1327
|
+
vars?: Record<MathJsonSymbol, JSSource>;
|
|
1328
|
+
imports?: ((...any: any[]) => any)[];
|
|
1329
|
+
preamble?: string;
|
|
1330
|
+
fallback?: boolean;
|
|
1331
|
+
}): ((...args: any[]) => any) & {
|
|
1332
|
+
isCompiled?: boolean;
|
|
1333
|
+
};
|
|
1334
|
+
/**
|
|
1335
|
+
* If this is an equation, solve the equation for the variables in vars.
|
|
1336
|
+
* Otherwise, solve the equation `this = 0` for the variables in vars.
|
|
1337
|
+
*
|
|
1338
|
+
*
|
|
1339
|
+
* ```javascript
|
|
1340
|
+
* const expr = ce.parse("x^2 + 2*x + 1 = 0");
|
|
1341
|
+
* console.log(expr.solve("x"));
|
|
1342
|
+
* ```
|
|
1343
|
+
*
|
|
1344
|
+
*
|
|
1345
|
+
*/
|
|
1346
|
+
solve(vars?: Iterable<string> | string | BoxedExpression | Iterable<BoxedExpression>): null | ReadonlyArray<BoxedExpression>;
|
|
1347
|
+
/**
|
|
1348
|
+
* If this expression is a number literal, a string literal or a function
|
|
1349
|
+
* literal, return the expression.
|
|
1350
|
+
*
|
|
1351
|
+
* If the expression is a symbol, return the value of the symbol.
|
|
1352
|
+
*
|
|
1353
|
+
* Otherwise, the expression is a symbolic expression, including an unknown
|
|
1354
|
+
* symbol, i.e. a symbol with no value, return `undefined`.
|
|
1355
|
+
*
|
|
1356
|
+
*/
|
|
1357
|
+
get value(): BoxedExpression | undefined;
|
|
1358
|
+
/**
|
|
1359
|
+
* If the expression is a symbol, set the value of the symbol.
|
|
1360
|
+
*
|
|
1361
|
+
* Will throw a runtime error if either not a symbol, or a symbol with the
|
|
1362
|
+
* `constant` flag set to `true`.
|
|
1363
|
+
*
|
|
1364
|
+
* Setting the value of a symbol results in the forgetting of all assumptions
|
|
1365
|
+
* about it in the current scope.
|
|
1366
|
+
*
|
|
1367
|
+
*/
|
|
1368
|
+
set value(value: boolean | string | BigNum | OneOf<[
|
|
1369
|
+
{
|
|
1370
|
+
re: number;
|
|
1371
|
+
im: number;
|
|
1372
|
+
},
|
|
1373
|
+
{
|
|
1374
|
+
num: number;
|
|
1375
|
+
denom: number;
|
|
1376
|
+
},
|
|
1377
|
+
BoxedExpression
|
|
1378
|
+
]> | number[] | number | undefined);
|
|
1379
|
+
/**
|
|
1380
|
+
*
|
|
1381
|
+
* The type of the value of this expression.
|
|
1382
|
+
*
|
|
1383
|
+
* If a symbol the type of the value of the symbol.
|
|
1384
|
+
*
|
|
1385
|
+
* If a function expression, the type of the value of the function
|
|
1386
|
+
* (the result type).
|
|
1387
|
+
*
|
|
1388
|
+
* If a symbol with a `"function"` type (a function literal), returns the
|
|
1389
|
+
* signature.
|
|
1390
|
+
*
|
|
1391
|
+
* If not valid, return `"error"`.
|
|
1392
|
+
*
|
|
1393
|
+
* If the type is not known, return `"unknown"`.
|
|
1394
|
+
*
|
|
1395
|
+
* @category Type Properties
|
|
1396
|
+
*/
|
|
1397
|
+
get type(): BoxedType;
|
|
1398
|
+
set type(type: Type | TypeString | BoxedType);
|
|
1399
|
+
/** `true` if the value of this expression is a number.
|
|
1400
|
+
*
|
|
1401
|
+
*
|
|
1402
|
+
* Note that in a fateful twist of cosmic irony, `NaN` ("Not a Number")
|
|
1403
|
+
* **is** a number.
|
|
1404
|
+
*
|
|
1405
|
+
* If `isNumber` is `true`, this indicates that evaluating the expression
|
|
1406
|
+
* will return a number.
|
|
1407
|
+
*
|
|
1408
|
+
* This does not indicate that the expression is a number literal. To check
|
|
1409
|
+
* if the expression is a number literal, use `expr.isNumberLiteral`.
|
|
1410
|
+
*
|
|
1411
|
+
* For example, the expression `["Add", 1, "x"]` is a number if "x" is a
|
|
1412
|
+
* number and `expr.isNumber` is `true`, but `isNumberLiteral` is `false`.
|
|
1413
|
+
*
|
|
1414
|
+
* @category Type Properties
|
|
1415
|
+
*/
|
|
1416
|
+
readonly isNumber: boolean | undefined;
|
|
1417
|
+
/**
|
|
1418
|
+
*
|
|
1419
|
+
* The value of this expression is an element of the set ℤ: ...,-2, -1, 0, 1, 2...
|
|
1420
|
+
*
|
|
1421
|
+
* Note that ±∞ and NaN are not integers.
|
|
1422
|
+
*
|
|
1423
|
+
* @category Type Properties
|
|
1424
|
+
*
|
|
1425
|
+
*/
|
|
1426
|
+
readonly isInteger: boolean | undefined;
|
|
1427
|
+
/** The value of this expression is an element of the set ℚ, p/q with p ∈ ℕ, q ∈ ℤ ⃰ q >= 1
|
|
1428
|
+
*
|
|
1429
|
+
* Note that every integer is also a rational.
|
|
1430
|
+
*
|
|
1431
|
+
* This is equivalent to `this.type === "rational" || this.type === "integer"`
|
|
1432
|
+
*
|
|
1433
|
+
* Note that ±∞ and NaN are not rationals.
|
|
1434
|
+
*
|
|
1435
|
+
* @category Type Properties
|
|
1436
|
+
*
|
|
1437
|
+
*/
|
|
1438
|
+
readonly isRational: boolean | undefined;
|
|
1439
|
+
/**
|
|
1440
|
+
* The value of this expression is a real number.
|
|
1441
|
+
*
|
|
1442
|
+
* This is equivalent to `this.type === "rational" || this.type === "integer" || this.type === "real"`
|
|
1443
|
+
*
|
|
1444
|
+
* Note that ±∞ and NaN are not real numbers.
|
|
1445
|
+
*
|
|
1446
|
+
* @category Type Properties
|
|
1447
|
+
*/
|
|
1448
|
+
readonly isReal: boolean | undefined;
|
|
1449
|
+
/** Mathematical equality (strong equality), that is the value
|
|
1450
|
+
* of this expression and the value of `other` are numerically equal.
|
|
1451
|
+
*
|
|
1452
|
+
* Both expressions are evaluated and the result is compared numerically.
|
|
1453
|
+
*
|
|
1454
|
+
* Numbers whose difference is less than `engine.tolerance` are
|
|
1455
|
+
* considered equal. This tolerance is set when the `engine.precision` is
|
|
1456
|
+
* changed to be such that the last two digits are ignored.
|
|
1457
|
+
*
|
|
1458
|
+
* Evaluating the expressions may be expensive. Other options to consider
|
|
1459
|
+
* to compare two expressions include:
|
|
1460
|
+
* - `expr.isSame(other)` for a structural comparison which does not involve
|
|
1461
|
+
* evaluating the expressions.
|
|
1462
|
+
* - `expr.is(other)` for a comparison of a number literal
|
|
1463
|
+
*
|
|
1464
|
+
* **Examples**
|
|
1465
|
+
*
|
|
1466
|
+
* ```js
|
|
1467
|
+
* let expr = ce.parse('2 + 2');
|
|
1468
|
+
* console.log(expr.isEqual(4)); // true
|
|
1469
|
+
* console.log(expr.isSame(ce.parse(4))); // false
|
|
1470
|
+
* console.log(expr.is(4)); // false
|
|
1471
|
+
*
|
|
1472
|
+
* expr = ce.parse('4');
|
|
1473
|
+
* console.log(expr.isEqual(4)); // true
|
|
1474
|
+
* console.log(expr.isSame(ce.parse(4))); // true
|
|
1475
|
+
* console.log(expr.is(4)); // true (fastest)
|
|
1476
|
+
*
|
|
1477
|
+
* ```
|
|
1478
|
+
*
|
|
1479
|
+
* @category Relational Operator
|
|
1480
|
+
*/
|
|
1481
|
+
isEqual(other: number | BoxedExpression): boolean | undefined;
|
|
1482
|
+
/**
|
|
1483
|
+
* Is `true` if the expression is a collection.
|
|
1484
|
+
*
|
|
1485
|
+
* When `isCollection` is `true`, the expression:
|
|
1486
|
+
*
|
|
1487
|
+
* - has an `each()` method that returns a generator over the elements
|
|
1488
|
+
* of the collection.
|
|
1489
|
+
* - has a `size` property that returns the number of elements in the
|
|
1490
|
+
* collection.
|
|
1491
|
+
* - has a `contains(other)` method that returns `true` if the `other`
|
|
1492
|
+
* expression is in the collection.
|
|
1493
|
+
*
|
|
1494
|
+
*/
|
|
1495
|
+
isCollection: boolean;
|
|
1496
|
+
/**
|
|
1497
|
+
* Is `true` if this is an indexed collection, such as a list, a vector,
|
|
1498
|
+
* a matrix, a tuple, etc...
|
|
1499
|
+
*
|
|
1500
|
+
* The elements of an indexed collection can be accessed by a one-based
|
|
1501
|
+
* index.
|
|
1502
|
+
*
|
|
1503
|
+
* When `isIndexedCollection` is `true`, the expression:
|
|
1504
|
+
* - has an `each()`, `size()` and `contains(rhs)` methods
|
|
1505
|
+
* as for a collection.
|
|
1506
|
+
* - has an `at(index: number)` method that returns the element at the
|
|
1507
|
+
* specified index.
|
|
1508
|
+
* - has an `indexWhere(predicate: (element: BoxedExpression) => boolean)`
|
|
1509
|
+
* method that returns the index of the first element that matches the
|
|
1510
|
+
* predicate.
|
|
1511
|
+
*/
|
|
1512
|
+
isIndexedCollection: boolean;
|
|
1513
|
+
/**
|
|
1514
|
+
* False if not a collection, or if the elements of the collection
|
|
1515
|
+
* are not computed lazily.
|
|
1516
|
+
*
|
|
1517
|
+
* The elements of a lazy collection are computed on demand, when
|
|
1518
|
+
* iterating over the collection using `each()`.
|
|
1519
|
+
*
|
|
1520
|
+
* Use `ListFrom` and related functions to create eager collections from
|
|
1521
|
+
* lazy collections.
|
|
1522
|
+
*
|
|
1523
|
+
*/
|
|
1524
|
+
isLazyCollection: boolean;
|
|
1525
|
+
/**
|
|
1526
|
+
* If this is a collection, return an iterator over the elements of the
|
|
1527
|
+
* collection.
|
|
1528
|
+
*
|
|
1529
|
+
* ```js
|
|
1530
|
+
* const expr = ce.parse('[1, 2, 3, 4]');
|
|
1531
|
+
* for (const e of expr.each()) {
|
|
1532
|
+
* console.log(e);
|
|
1533
|
+
* }
|
|
1534
|
+
* ```
|
|
1535
|
+
*/
|
|
1536
|
+
each(): Generator<BoxedExpression>;
|
|
1537
|
+
/**
|
|
1538
|
+
* If this is a collection, return true if the `rhs` expression is in the
|
|
1539
|
+
* collection.
|
|
1540
|
+
*
|
|
1541
|
+
* Return `undefined` if the membership cannot be determined without
|
|
1542
|
+
* iterating over the collection.
|
|
1543
|
+
*/
|
|
1544
|
+
contains(rhs: BoxedExpression): boolean | undefined;
|
|
1545
|
+
/**
|
|
1546
|
+
* Check if this collection is a subset of another collection.
|
|
1547
|
+
*
|
|
1548
|
+
* @param other The other collection to check against.
|
|
1549
|
+
* @param strict If true, the subset relation is strict (i.e., proper subset).
|
|
1550
|
+
*/
|
|
1551
|
+
subsetOf(other: BoxedExpression, strict: boolean): boolean | undefined;
|
|
1552
|
+
/**
|
|
1553
|
+
* If this is a collection, return the number of elements in the collection.
|
|
1554
|
+
*
|
|
1555
|
+
* If the collection is infinite, return `Infinity`.
|
|
1556
|
+
*
|
|
1557
|
+
* If the number of elements cannot be determined, return `undefined`, for
|
|
1558
|
+
* example, if the collection is lazy and not finite and the size cannot
|
|
1559
|
+
* be determined without iterating over the collection.
|
|
1560
|
+
*
|
|
1561
|
+
*/
|
|
1562
|
+
get count(): number | undefined;
|
|
1563
|
+
/** If this is a finite collection, return true. */
|
|
1564
|
+
isFiniteCollection: boolean | undefined;
|
|
1565
|
+
/** If this is an empty collection, return true.
|
|
1566
|
+
*
|
|
1567
|
+
* An empty collection has a size of 0.
|
|
1568
|
+
*/
|
|
1569
|
+
isEmptyCollection: boolean | undefined;
|
|
1570
|
+
/** If this is an indexed collection, return the element at the specified
|
|
1571
|
+
* index. The first element is at index 1.
|
|
1572
|
+
*
|
|
1573
|
+
* If the index is negative, return the element at index `size() + index + 1`.
|
|
1574
|
+
*
|
|
1575
|
+
* The last element is at index -1.
|
|
1576
|
+
*
|
|
1577
|
+
*/
|
|
1578
|
+
at(index: number): BoxedExpression | undefined;
|
|
1579
|
+
/** If this is a keyed collection (map, record, tuple), return the value of
|
|
1580
|
+
* the corresponding key.
|
|
1581
|
+
*
|
|
1582
|
+
* If `key` is a `BoxedExpression`, it should be a string.
|
|
1583
|
+
*
|
|
1584
|
+
*/
|
|
1585
|
+
get(key: string | BoxedExpression): BoxedExpression | undefined;
|
|
1586
|
+
/**
|
|
1587
|
+
* If this is an indexed collection, return the index of the first element
|
|
1588
|
+
* that matches the predicate.
|
|
1589
|
+
*
|
|
1590
|
+
*/
|
|
1591
|
+
indexWhere(predicate: (element: BoxedExpression) => boolean): number | undefined;
|
|
1592
|
+
}
|
|
1593
|
+
/** A semi boxed expression is a MathJSON expression which can include some
|
|
1594
|
+
* boxed terms.
|
|
1595
|
+
*
|
|
1596
|
+
* This is convenient when creating new expressions from portions
|
|
1597
|
+
* of an existing `BoxedExpression` while avoiding unboxing and reboxing.
|
|
1598
|
+
*
|
|
1599
|
+
* @category Boxed Expression
|
|
1600
|
+
*/
|
|
1601
|
+
export type SemiBoxedExpression = number | bigint | string | BigNum | MathJsonNumberObject | MathJsonStringObject | MathJsonSymbolObject | MathJsonFunctionObject | MathJsonDictionaryObject | readonly [MathJsonSymbol, ...SemiBoxedExpression[]] | BoxedExpression;
|
|
1602
|
+
/** Interface for dictionary-like structures.
|
|
1603
|
+
* Use `isDictionary()` to check if an expression is a dictionary.
|
|
1604
|
+
*/
|
|
1605
|
+
export interface DictionaryInterface {
|
|
1606
|
+
get(key: string): BoxedExpression | undefined;
|
|
1607
|
+
has(key: string): boolean;
|
|
1608
|
+
get keys(): string[];
|
|
1609
|
+
get entries(): [string, BoxedExpression][];
|
|
1610
|
+
get values(): BoxedExpression[];
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* These handlers compare two expressions.
|
|
1614
|
+
*
|
|
1615
|
+
* If only one of the handlers is provided, the other is derived from it.
|
|
1616
|
+
*
|
|
1617
|
+
* Having both may be useful if comparing non-equality is faster than equality.
|
|
1618
|
+
*
|
|
1619
|
+
* @category Definitions
|
|
1620
|
+
*
|
|
1621
|
+
*/
|
|
1622
|
+
export interface EqHandlers {
|
|
1623
|
+
eq: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
|
|
1624
|
+
neq: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
|
|
1625
|
+
}
|
|
1626
|
+
/** @category Definitions */
|
|
1627
|
+
export type Hold = 'none' | 'all' | 'first' | 'rest' | 'last' | 'most';
|
|
1628
|
+
/**
|
|
1629
|
+
* Options to control the serialization to MathJSON when using `BoxedExpression.toMathJson()`.
|
|
1630
|
+
*
|
|
1631
|
+
* @category Serialization
|
|
1632
|
+
*/
|
|
1633
|
+
export type JsonSerializationOptions = {
|
|
1634
|
+
/** If true, the serialization applies some transformations to make
|
|
1635
|
+
* the JSON more readable. For example, `["Power", "x", 2]` is serialized
|
|
1636
|
+
* as `["Square", "x"]`.
|
|
1637
|
+
*/
|
|
1638
|
+
prettify: boolean;
|
|
1639
|
+
/** A list of space separated function names that should be excluded from
|
|
1640
|
+
* the JSON output.
|
|
1641
|
+
*
|
|
1642
|
+
* Those functions are replaced with an equivalent, for example, `Square` with
|
|
1643
|
+
* `Power`, etc...
|
|
1644
|
+
*
|
|
1645
|
+
* Possible values include `Sqrt`, `Root`, `Square`, `Exp`, `Subtract`,
|
|
1646
|
+
* `Rational`, `Complex`
|
|
1647
|
+
*
|
|
1648
|
+
* **Default**: `[]` (none)
|
|
1649
|
+
*/
|
|
1650
|
+
exclude: string[];
|
|
1651
|
+
/** A list of space separated keywords indicating which MathJSON expressions
|
|
1652
|
+
* can use a shorthand.
|
|
1653
|
+
*
|
|
1654
|
+
* **Default**: `["all"]`
|
|
1655
|
+
*/
|
|
1656
|
+
shorthands: ('all' | 'number' | 'symbol' | 'function' | 'string' | 'dictionary')[];
|
|
1657
|
+
/** A list of space separated keywords indicating which metadata should be
|
|
1658
|
+
* included in the MathJSON. If metadata is included, shorthand notation
|
|
1659
|
+
* is not used.
|
|
1660
|
+
*
|
|
1661
|
+
* **Default**: `[]` (none)
|
|
1662
|
+
*/
|
|
1663
|
+
metadata: ('all' | 'wikidata' | 'latex')[];
|
|
1664
|
+
/** If true, repeating decimals are detected and serialized accordingly
|
|
1665
|
+
* For example:
|
|
1666
|
+
* - `1.3333333333333333` \( \to \) `1.(3)`
|
|
1667
|
+
* - `0.142857142857142857142857142857142857142857142857142` \( \to \) `0.(1428571)`
|
|
1668
|
+
*
|
|
1669
|
+
* **Default**: `true`
|
|
1670
|
+
*/
|
|
1671
|
+
repeatingDecimal: boolean;
|
|
1672
|
+
/**
|
|
1673
|
+
* The maximum number of significant digits in serialized numbers.
|
|
1674
|
+
* - `"max"`: all availabe digits are serialized.
|
|
1675
|
+
* - `"auto"`: use the same precision as the compute engine.
|
|
1676
|
+
*
|
|
1677
|
+
* **Default**: `"auto"`
|
|
1678
|
+
*/
|
|
1679
|
+
fractionalDigits: 'auto' | 'max' | number;
|
|
1680
|
+
};
|
|
1681
|
+
/**
|
|
1682
|
+
* Control how a pattern is matched to an expression.
|
|
1683
|
+
*
|
|
1684
|
+
* ## Wildcards
|
|
1685
|
+
*
|
|
1686
|
+
* Patterns can include wildcards to match parts of expressions:
|
|
1687
|
+
*
|
|
1688
|
+
* - **Universal (`_` or `_name`)**: Matches exactly one element
|
|
1689
|
+
* - **Sequence (`__` or `__name`)**: Matches one or more elements
|
|
1690
|
+
* - **Optional Sequence (`___` or `___name`)**: Matches zero or more elements
|
|
1691
|
+
*
|
|
1692
|
+
* Named wildcards capture values in the returned substitution:
|
|
1693
|
+
* - `['Add', '_a', 1].match(['Add', 'x', 1])` → `{_a: 'x'}`
|
|
1694
|
+
* - `['Add', '__a'].match(['Add', 1, 2, 3])` → `{__a: [1, 2, 3]}`
|
|
1695
|
+
*
|
|
1696
|
+
* ## Options
|
|
1697
|
+
*
|
|
1698
|
+
* - `substitution`: if present, assumes these values for a subset of
|
|
1699
|
+
* named wildcards, and ensure that subsequent occurrence of the same
|
|
1700
|
+
* wildcard have the same value.
|
|
1701
|
+
* - `recursive`: if true, match recursively, otherwise match only the top
|
|
1702
|
+
* level.
|
|
1703
|
+
* - `useVariations`: if false, only match expressions that are structurally identical.
|
|
1704
|
+
* If true, match expressions that are structurally identical or equivalent.
|
|
1705
|
+
* For example, when true, `["Add", '_a', 2]` matches `2`, with `_a = 0`.
|
|
1706
|
+
* **Default**: `false`
|
|
1707
|
+
* - `matchPermutations`: if true (default), for commutative operators, try all
|
|
1708
|
+
* permutations of pattern operands. If false, match exact order only.
|
|
1709
|
+
*
|
|
1710
|
+
* @category Pattern Matching
|
|
1711
|
+
*
|
|
1712
|
+
*/
|
|
1713
|
+
export type PatternMatchOptions = {
|
|
1714
|
+
substitution?: BoxedSubstitution;
|
|
1715
|
+
recursive?: boolean;
|
|
1716
|
+
useVariations?: boolean;
|
|
1717
|
+
/**
|
|
1718
|
+
* If `true` (default), for commutative operators, try all permutations of
|
|
1719
|
+
* the pattern operands to find a match.
|
|
1720
|
+
*
|
|
1721
|
+
* If `false`, only match in the exact order given. This can be useful
|
|
1722
|
+
* when the pattern order is significant or for performance optimization
|
|
1723
|
+
* with large patterns.
|
|
1724
|
+
*/
|
|
1725
|
+
matchPermutations?: boolean;
|
|
1726
|
+
};
|
|
1727
|
+
/**
|
|
1728
|
+
* @category Boxed Expression
|
|
1729
|
+
*
|
|
1730
|
+
*/
|
|
1731
|
+
export type ReplaceOptions = {
|
|
1732
|
+
/**
|
|
1733
|
+
* If `true`, apply replacement rules to all sub-expressions.
|
|
1734
|
+
*
|
|
1735
|
+
* If `false`, only consider the top-level expression.
|
|
1736
|
+
*
|
|
1737
|
+
* **Default**: `false`
|
|
1738
|
+
*/
|
|
1739
|
+
recursive: boolean;
|
|
1740
|
+
/**
|
|
1741
|
+
* If `true`, stop after the first rule that matches.
|
|
1742
|
+
*
|
|
1743
|
+
* If `false`, apply all the remaining rules even after the first match.
|
|
1744
|
+
*
|
|
1745
|
+
* **Default**: `false`
|
|
1746
|
+
*/
|
|
1747
|
+
once: boolean;
|
|
1748
|
+
/**
|
|
1749
|
+
* If `true` the rule will use some equivalent variations to match.
|
|
1750
|
+
*
|
|
1751
|
+
* For example when `useVariations` is true:
|
|
1752
|
+
* - `x` matches `a + x` with a = 0
|
|
1753
|
+
* - `x` matches `ax` with a = 1
|
|
1754
|
+
* - etc...
|
|
1755
|
+
*
|
|
1756
|
+
* Setting this to `true` can save time by condensing multiple rules
|
|
1757
|
+
* into one. This can be particularly useful when describing equations
|
|
1758
|
+
* solutions. However, it can lead to infinite recursion and should be
|
|
1759
|
+
* used with caution.
|
|
1760
|
+
*
|
|
1761
|
+
*/
|
|
1762
|
+
useVariations: boolean;
|
|
1763
|
+
/**
|
|
1764
|
+
* If `true` (default), for commutative operators, try all permutations of
|
|
1765
|
+
* the pattern operands to find a match.
|
|
1766
|
+
*
|
|
1767
|
+
* If `false`, only match in the exact order given. This can be useful
|
|
1768
|
+
* when the pattern order is significant or for performance optimization
|
|
1769
|
+
* with large patterns.
|
|
1770
|
+
*
|
|
1771
|
+
* **Default**: `true`
|
|
1772
|
+
*/
|
|
1773
|
+
matchPermutations: boolean;
|
|
1774
|
+
/**
|
|
1775
|
+
* If `iterationLimit` > 1, the rules will be repeatedly applied
|
|
1776
|
+
* until no rules apply, up to `iterationLimit` times.
|
|
1777
|
+
*
|
|
1778
|
+
* Note that if `once` is true, `iterationLimit` has no effect.
|
|
1779
|
+
*
|
|
1780
|
+
* **Default**: `1`
|
|
1781
|
+
*/
|
|
1782
|
+
iterationLimit: number;
|
|
1783
|
+
/**
|
|
1784
|
+
* Indicate if the expression should be canonicalized after the replacement.
|
|
1785
|
+
* If not provided, the expression is canonicalized if the expression
|
|
1786
|
+
* that matched the pattern is canonical.
|
|
1787
|
+
*/
|
|
1788
|
+
canonical: CanonicalOptions;
|
|
1789
|
+
};
|
|
1790
|
+
/**
|
|
1791
|
+
* A bound symbol (i.e. one with an associated definition) has either a type
|
|
1792
|
+
* (e.g. ∀ x ∈ ℝ), a value (x = 5) or both (π: value = 3.14... type = 'real').
|
|
1793
|
+
*
|
|
1794
|
+
* @category Definitions
|
|
1795
|
+
*/
|
|
1796
|
+
export type ValueDefinition = BaseDefinition & {
|
|
1797
|
+
holdUntil: 'never' | 'evaluate' | 'N';
|
|
1798
|
+
type: Type | TypeString | BoxedType;
|
|
1799
|
+
/** If true, the type is inferred, and could be adjusted later
|
|
1800
|
+
* as more information becomes available or if the symbol is explicitly
|
|
1801
|
+
* declared.
|
|
1802
|
+
*/
|
|
1803
|
+
inferred: boolean;
|
|
1804
|
+
/** `value` can be a JS function since for some constants, such as
|
|
1805
|
+
* `Pi`, the actual value depends on the `precision` setting of the
|
|
1806
|
+
* `ComputeEngine` and possible other environment settings */
|
|
1807
|
+
value: LatexString | SemiBoxedExpression | ((ce: ComputeEngine) => BoxedExpression | null);
|
|
1808
|
+
eq: (a: BoxedExpression) => boolean | undefined;
|
|
1809
|
+
neq: (a: BoxedExpression) => boolean | undefined;
|
|
1810
|
+
cmp: (a: BoxedExpression) => '=' | '>' | '<' | undefined;
|
|
1811
|
+
collection: CollectionHandlers;
|
|
1812
|
+
};
|
|
1813
|
+
/**
|
|
1814
|
+
* Definition record for a function.
|
|
1815
|
+
* @category Definitions
|
|
1816
|
+
*
|
|
1817
|
+
*/
|
|
1818
|
+
export type OperatorDefinition = Partial<BaseDefinition> & Partial<OperatorDefinitionFlags> & {
|
|
1819
|
+
/**
|
|
1820
|
+
* The function signature, describing the type of the arguments and the
|
|
1821
|
+
* return type.
|
|
1822
|
+
*
|
|
1823
|
+
* If a `type` handler is provided, the return type of the function should
|
|
1824
|
+
* be a subtype of the return type in the signature.
|
|
1825
|
+
*
|
|
1826
|
+
*/
|
|
1827
|
+
signature?: Type | TypeString | BoxedType;
|
|
1828
|
+
/**
|
|
1829
|
+
* The type of the result (return type) based on the type of
|
|
1830
|
+
* the arguments.
|
|
1831
|
+
*
|
|
1832
|
+
* Should be a subtype of the type indicated by the signature.
|
|
1833
|
+
*
|
|
1834
|
+
* For example, if the signature is `(number) -> real`, the type of the
|
|
1835
|
+
* result could be `real` or `integer`, but not `complex`.
|
|
1836
|
+
*
|
|
1837
|
+
* :::info[Note]
|
|
1838
|
+
* Do not evaluate the arguments.
|
|
1839
|
+
*
|
|
1840
|
+
* However, the type of the arguments can be used to determine the type of
|
|
1841
|
+
* the result.
|
|
1842
|
+
* :::
|
|
1843
|
+
*
|
|
1844
|
+
*/
|
|
1845
|
+
type?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
1846
|
+
engine: ComputeEngine;
|
|
1847
|
+
}) => Type | TypeString | BoxedType | undefined;
|
|
1848
|
+
/** Return the sign of the function expression.
|
|
1849
|
+
*
|
|
1850
|
+
* If the sign cannot be determined, return `undefined`.
|
|
1851
|
+
*
|
|
1852
|
+
* When determining the sign, only literal values and the values of
|
|
1853
|
+
* symbols, if they are literals, should be considered.
|
|
1854
|
+
*
|
|
1855
|
+
* Do not evaluate the arguments.
|
|
1856
|
+
*
|
|
1857
|
+
* However, the type and sign of the arguments can be used to determine the
|
|
1858
|
+
* sign.
|
|
1859
|
+
*
|
|
1860
|
+
*/
|
|
1861
|
+
sgn?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
1862
|
+
engine: ComputeEngine;
|
|
1863
|
+
}) => Sign | undefined;
|
|
1864
|
+
/** The value of this expression is > 0, same as `isGreater(0)`
|
|
1865
|
+
*
|
|
1866
|
+
* @category Numeric Expression
|
|
1867
|
+
*/
|
|
1868
|
+
readonly isPositive?: boolean | undefined;
|
|
1869
|
+
/** The value of this expression is >= 0, same as `isGreaterEqual(0)`
|
|
1870
|
+
*
|
|
1871
|
+
* @category Numeric Expression
|
|
1872
|
+
*/
|
|
1873
|
+
readonly isNonNegative?: boolean | undefined;
|
|
1874
|
+
/** The value of this expression is < 0, same as `isLess(0)`
|
|
1875
|
+
*
|
|
1876
|
+
* @category Numeric Expression
|
|
1877
|
+
*/
|
|
1878
|
+
readonly isNegative?: boolean | undefined;
|
|
1879
|
+
/** The value of this expression is <= 0, same as `isLessEqual(0)`
|
|
1880
|
+
*
|
|
1881
|
+
* @category Numeric Expression
|
|
1882
|
+
*/
|
|
1883
|
+
readonly isNonPositive?: boolean | undefined;
|
|
1884
|
+
/** Return `true` if the function expression is even, `false` if it is odd
|
|
1885
|
+
* and `undefined` if it is neither (for example if it is not a number,
|
|
1886
|
+
* or if it is a complex number).
|
|
1887
|
+
*/
|
|
1888
|
+
even?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
1889
|
+
engine: ComputeEngine;
|
|
1890
|
+
}) => boolean | undefined;
|
|
1891
|
+
/**
|
|
1892
|
+
* A number used to order arguments.
|
|
1893
|
+
*
|
|
1894
|
+
* Argument with higher complexity are placed after arguments with
|
|
1895
|
+
* lower complexity when ordered canonically in commutative functions.
|
|
1896
|
+
*
|
|
1897
|
+
* - Additive functions: 1000-1999
|
|
1898
|
+
* - Multiplicative functions: 2000-2999
|
|
1899
|
+
* - Root and power functions: 3000-3999
|
|
1900
|
+
* - Log functions: 4000-4999
|
|
1901
|
+
* - Trigonometric functions: 5000-5999
|
|
1902
|
+
* - Hypertrigonometric functions: 6000-6999
|
|
1903
|
+
* - Special functions (factorial, Gamma, ...): 7000-7999
|
|
1904
|
+
* - Collections: 8000-8999
|
|
1905
|
+
* - Inert and styling: 9000-9999
|
|
1906
|
+
* - Logic: 10000-10999
|
|
1907
|
+
* - Relational: 11000-11999
|
|
1908
|
+
*
|
|
1909
|
+
* **Default**: 100,000
|
|
1910
|
+
*/
|
|
1911
|
+
complexity?: number;
|
|
1912
|
+
/**
|
|
1913
|
+
* Return the canonical form of the expression with the arguments `args`.
|
|
1914
|
+
*
|
|
1915
|
+
* The arguments (`args`) may not be in canonical form. If necessary, they
|
|
1916
|
+
* can be put in canonical form.
|
|
1917
|
+
*
|
|
1918
|
+
* This handler should validate the type and number of the arguments
|
|
1919
|
+
* (arity).
|
|
1920
|
+
*
|
|
1921
|
+
* If a required argument is missing, it should be indicated with a
|
|
1922
|
+
* `["Error", "'missing"]` expression. If more arguments than expected
|
|
1923
|
+
* are present, this should be indicated with an
|
|
1924
|
+
* `["Error", "'unexpected-argument'"]` error expression
|
|
1925
|
+
*
|
|
1926
|
+
* If the type of an argument is not compatible, it should be indicated
|
|
1927
|
+
* with an `incompatible-type` error.
|
|
1928
|
+
*
|
|
1929
|
+
* `["Sequence"]` expressions are not folded and need to be handled
|
|
1930
|
+
* explicitly.
|
|
1931
|
+
*
|
|
1932
|
+
* If the function is associative, idempotent or an involution,
|
|
1933
|
+
* this handler should account for it. Notably, if it is commutative, the
|
|
1934
|
+
* arguments should be sorted in canonical order.
|
|
1935
|
+
*
|
|
1936
|
+
*
|
|
1937
|
+
* Values of symbols should not be substituted, unless they have
|
|
1938
|
+
* a `holdUntil` attribute of `"never"`.
|
|
1939
|
+
*
|
|
1940
|
+
* The handler should not consider the value or any assumptions about any
|
|
1941
|
+
* of the arguments that are symbols or functions (i.e. `arg.isZero`,
|
|
1942
|
+
* `arg.isInteger`, etc...) since those may change over time.
|
|
1943
|
+
*
|
|
1944
|
+
* The result of the handler should be a canonical expression.
|
|
1945
|
+
*
|
|
1946
|
+
* If the arguments do not match, they should be replaced with an
|
|
1947
|
+
* appropriate `["Error"]` expression. If the expression cannot be put in
|
|
1948
|
+
* canonical form, the handler should return `null`.
|
|
1949
|
+
*
|
|
1950
|
+
*/
|
|
1951
|
+
canonical?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
1952
|
+
engine: ComputeEngine;
|
|
1953
|
+
scope: Scope | undefined;
|
|
1954
|
+
}) => BoxedExpression | null;
|
|
1955
|
+
/**
|
|
1956
|
+
* Evaluate a function expression.
|
|
1957
|
+
*
|
|
1958
|
+
* When the handler is invoked, the arguments have been evaluated, except
|
|
1959
|
+
* if the `lazy` option is set to `true`.
|
|
1960
|
+
*
|
|
1961
|
+
* It is not necessary to further simplify or evaluate the arguments.
|
|
1962
|
+
*
|
|
1963
|
+
* If performing numerical calculations and `options.numericalApproximation`
|
|
1964
|
+
* is `false` return an exact numeric value, for example return a rational
|
|
1965
|
+
* number or a square root, rather than a floating point approximation.
|
|
1966
|
+
* Use `ce.number()` to create the numeric value.
|
|
1967
|
+
*
|
|
1968
|
+
* If the expression cannot be evaluated, due to the values, types, or
|
|
1969
|
+
* assumptions about its arguments, return `undefined` or
|
|
1970
|
+
* an `["Error"]` expression.
|
|
1971
|
+
*/
|
|
1972
|
+
evaluate?: ((ops: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
|
|
1973
|
+
engine: ComputeEngine;
|
|
1974
|
+
}) => BoxedExpression | undefined) | BoxedExpression;
|
|
1975
|
+
/**
|
|
1976
|
+
* An asynchronous version of `evaluate`.
|
|
1977
|
+
*
|
|
1978
|
+
*/
|
|
1979
|
+
evaluateAsync?: (ops: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
|
|
1980
|
+
engine: ComputeEngine;
|
|
1981
|
+
}) => Promise<BoxedExpression | undefined>;
|
|
1982
|
+
/** Dimensional analysis
|
|
1983
|
+
* @experimental
|
|
1984
|
+
*/
|
|
1985
|
+
evalDimension?: (args: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
|
|
1986
|
+
engine: ComputeEngine;
|
|
1987
|
+
}) => BoxedExpression;
|
|
1988
|
+
/** Return a compiled (optimized) expression. */
|
|
1989
|
+
xcompile?: (expr: BoxedExpression) => CompiledExpression;
|
|
1990
|
+
eq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
|
|
1991
|
+
neq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
|
|
1992
|
+
collection?: CollectionHandlers;
|
|
1993
|
+
};
|
|
1994
|
+
/**
|
|
1995
|
+
* Metadata common to both symbols and functions.
|
|
1996
|
+
*
|
|
1997
|
+
* @category Definitions
|
|
1998
|
+
*
|
|
1999
|
+
*/
|
|
2000
|
+
export interface BaseDefinition {
|
|
2001
|
+
/**
|
|
2002
|
+
* If a string, a short description, about one line long.
|
|
2003
|
+
*
|
|
2004
|
+
* Otherwise, a list of strings, each string a paragraph.
|
|
2005
|
+
*
|
|
2006
|
+
* May contain Markdown.
|
|
2007
|
+
*/
|
|
2008
|
+
description: string | string[];
|
|
2009
|
+
/** A list of examples of how to use this symbol or operator.
|
|
2010
|
+
*
|
|
2011
|
+
* Each example is a string, which can be a MathJSON expression or LaTeX, bracketed by `$` signs.
|
|
2012
|
+
* For example, `["Add", 1, 2]` or `$\\sin(\\pi/4)$`.
|
|
2013
|
+
*/
|
|
2014
|
+
examples: string | string[];
|
|
2015
|
+
/** A URL pointing to more information about this symbol or operator. */
|
|
2016
|
+
url: string;
|
|
2017
|
+
/**
|
|
2018
|
+
* A short string representing an entry in a wikibase.
|
|
2019
|
+
*
|
|
2020
|
+
* For example `"Q167"` is the [wikidata entry](https://www.wikidata.org/wiki/Q167)
|
|
2021
|
+
* for the `Pi` constant.
|
|
2022
|
+
*/
|
|
2023
|
+
wikidata: string;
|
|
2024
|
+
/** If true, the value or type of the definition cannot be changed */
|
|
2025
|
+
readonly isConstant?: boolean;
|
|
2026
|
+
}
|
|
2027
|
+
/** Options for `BoxedExpression.simplify()`
|
|
2028
|
+
*
|
|
2029
|
+
* @category Boxed Expression
|
|
2030
|
+
*/
|
|
2031
|
+
export type SimplifyOptions = {
|
|
2032
|
+
/**
|
|
2033
|
+
* The set of rules to apply. If `null`, use no rules. If not provided,
|
|
2034
|
+
* use the default simplification rules.
|
|
2035
|
+
*/
|
|
2036
|
+
rules?: null | Rule | ReadonlyArray<BoxedRule | Rule> | BoxedRuleSet;
|
|
2037
|
+
/**
|
|
2038
|
+
* Use this cost function to determine if a simplification is worth it.
|
|
2039
|
+
*
|
|
2040
|
+
* If not provided, `ce.costFunction`, the cost function of the engine is
|
|
2041
|
+
* used.
|
|
2042
|
+
*/
|
|
2043
|
+
costFunction?: (expr: BoxedExpression) => number;
|
|
2044
|
+
};
|
|
2045
|
+
/**
|
|
2046
|
+
* A table mapping symbols to their definition.
|
|
2047
|
+
*
|
|
2048
|
+
* Symbols should be valid MathJSON symbols. In addition, the
|
|
2049
|
+
* following rules are recommended:
|
|
2050
|
+
*
|
|
2051
|
+
* - Use only latin letters, digits and `-`: `/[a-zA-Z0-9-]+/`
|
|
2052
|
+
* - The first character should be a letter: `/^[a-zA-Z]/`
|
|
2053
|
+
* - Functions and symbols exported from a library should start with an uppercase letter `/^[A-Z]/`
|
|
2054
|
+
*
|
|
2055
|
+
* @category Definitions
|
|
2056
|
+
*
|
|
2057
|
+
*/
|
|
2058
|
+
export type SymbolDefinition = OneOf<[ValueDefinition, OperatorDefinition]>;
|
|
2059
|
+
/**
|
|
2060
|
+
* @category Definitions
|
|
2061
|
+
*
|
|
2062
|
+
*/
|
|
2063
|
+
export type SymbolDefinitions = Readonly<{
|
|
2064
|
+
[id: string]: Partial<SymbolDefinition>;
|
|
2065
|
+
}>;
|
|
2066
|
+
/**
|
|
2067
|
+
* When a unitless value is passed to or returned from a trigonometric function,
|
|
2068
|
+
* the angular unit of the value.
|
|
2069
|
+
*
|
|
2070
|
+
* | Angular Unit | Description |
|
|
2071
|
+
* |:--------------|:-------------|
|
|
2072
|
+
* | `rad` | radians, 2π radians is a full circle |
|
|
2073
|
+
* | `deg` | degrees, 360 degrees is a full circle |
|
|
2074
|
+
* | `grad` | gradians, 400 gradians is a full circle |
|
|
2075
|
+
* | `turn` | turns, 1 turn is a full circle |
|
|
2076
|
+
*
|
|
2077
|
+
* To change the angular unit used by the Compute Engine, use:
|
|
2078
|
+
*
|
|
2079
|
+
* ```js
|
|
2080
|
+
* ce.angularUnit = 'deg';
|
|
2081
|
+
* ```
|
|
2082
|
+
*
|
|
2083
|
+
* @category Compute Engine
|
|
2084
|
+
*/
|
|
2085
|
+
export type AngularUnit = 'rad' | 'deg' | 'grad' | 'turn';
|
|
2086
|
+
/** @category Numerics */
|
|
2087
|
+
export type Sign =
|
|
2088
|
+
/** The expression is equal to 0 */
|
|
2089
|
+
'zero'
|
|
2090
|
+
/** The expression is > 0 */
|
|
2091
|
+
| 'positive'
|
|
2092
|
+
/** The expression is < 0 */
|
|
2093
|
+
| 'negative'
|
|
2094
|
+
/** The expression is >= 0 and isPositive is either false or undefined*/
|
|
2095
|
+
| 'non-negative'
|
|
2096
|
+
/** The expression is <= 0 and isNegative is either false or undefined*/
|
|
2097
|
+
| 'non-positive'
|
|
2098
|
+
/** The expression is not equal to 0 (possibly with an imaginary part) and isPositive, isNegative, isUnsigned are all false or undefined */
|
|
2099
|
+
| 'not-zero'
|
|
2100
|
+
/** The expression has an imaginary part or is NaN */
|
|
2101
|
+
| 'unsigned';
|
|
2102
|
+
/**
|
|
2103
|
+
* These handlers are the primitive operations that can be performed on
|
|
2104
|
+
* all collections, indexed or not.
|
|
2105
|
+
*
|
|
2106
|
+
* @category Definitions
|
|
2107
|
+
*/
|
|
2108
|
+
export interface BaseCollectionHandlers {
|
|
2109
|
+
/**
|
|
2110
|
+
* Return an iterator that iterates over the elements of the collection.
|
|
2111
|
+
*
|
|
2112
|
+
* The order in which the elements are returned is not defined. Requesting
|
|
2113
|
+
* two iterators on the same collection may return the elements in a
|
|
2114
|
+
* different order.
|
|
2115
|
+
*
|
|
2116
|
+
* @category Definitions
|
|
2117
|
+
*/
|
|
2118
|
+
iterator: (collection: BoxedExpression) => Iterator<BoxedExpression, undefined> | undefined;
|
|
2119
|
+
/** Return the number of elements in the collection.
|
|
2120
|
+
*
|
|
2121
|
+
* An empty collection has a count of 0.
|
|
2122
|
+
*/
|
|
2123
|
+
count: (collection: BoxedExpression) => number | undefined;
|
|
2124
|
+
/** Optional flag to quickly check if the collection is empty, without having to count exactly how may elements it has (useful for lazy evaluation). */
|
|
2125
|
+
isEmpty?: (collection: BoxedExpression) => boolean | undefined;
|
|
2126
|
+
/** Optional flag to quickly check if the collection is finite, without having to count exactly how many elements it has (useful for lazy evaluation). */
|
|
2127
|
+
isFinite?: (collection: BoxedExpression) => boolean | undefined;
|
|
2128
|
+
/** Return `true` if the collection is lazy, `false` otherwise.
|
|
2129
|
+
* If the collection is lazy, it means that the elements are not
|
|
2130
|
+
* computed until they are needed, for example when iterating over the
|
|
2131
|
+
* collection.
|
|
2132
|
+
*
|
|
2133
|
+
* Default: `true`
|
|
2134
|
+
*/
|
|
2135
|
+
isLazy?: (collection: BoxedExpression) => boolean;
|
|
2136
|
+
/**
|
|
2137
|
+
* Return `true` if the target expression is in the collection,
|
|
2138
|
+
* `false` otherwise.
|
|
2139
|
+
*
|
|
2140
|
+
* Return `undefined` if the membership cannot be determined.
|
|
2141
|
+
*/
|
|
2142
|
+
contains?: (collection: BoxedExpression, target: BoxedExpression) => boolean | undefined;
|
|
2143
|
+
/**
|
|
2144
|
+
* Return `true` if all the elements of `other` are in `collection`.
|
|
2145
|
+
* Both `collection` and `other` are collections.
|
|
2146
|
+
*
|
|
2147
|
+
* If strict is `true`, the subset must be strict, that is, `collection` must
|
|
2148
|
+
* have more elements than `other`.
|
|
2149
|
+
*
|
|
2150
|
+
* Return `undefined` if the subset relation cannot be determined.
|
|
2151
|
+
*/
|
|
2152
|
+
subsetOf?: (collection: BoxedExpression, other: BoxedExpression, strict: boolean) => boolean | undefined;
|
|
2153
|
+
/** Return the sign of all the elements of the collection. */
|
|
2154
|
+
eltsgn?: (collection: BoxedExpression) => Sign | undefined;
|
|
2155
|
+
/** Return the widest type of all the elements in the collection */
|
|
2156
|
+
elttype?: (collection: BoxedExpression) => Type | undefined;
|
|
2157
|
+
}
|
|
2158
|
+
/**
|
|
2159
|
+
* These additional collection handlers are applicable to indexed
|
|
2160
|
+
* collections only.
|
|
2161
|
+
*
|
|
2162
|
+
* The elements of an indexed collection can be accessed by index, and
|
|
2163
|
+
* the order of the elements is defined.
|
|
2164
|
+
*
|
|
2165
|
+
* @category Definitions
|
|
2166
|
+
*/
|
|
2167
|
+
export interface IndexedCollectionHandlers {
|
|
2168
|
+
/**
|
|
2169
|
+
* Return the element at the specified index.
|
|
2170
|
+
*
|
|
2171
|
+
* The first element is `at(1)`, the last element is `at(-1)`.
|
|
2172
|
+
*
|
|
2173
|
+
* If the index is <0, return the element at index `count() + index + 1`.
|
|
2174
|
+
*
|
|
2175
|
+
* The index can also be a string for example for records. The set of valid
|
|
2176
|
+
* keys is returned by the `keys()` handler.
|
|
2177
|
+
*
|
|
2178
|
+
* If the index is invalid, return `undefined`.
|
|
2179
|
+
*/
|
|
2180
|
+
at: (collection: BoxedExpression, index: number | string) => undefined | BoxedExpression;
|
|
2181
|
+
/**
|
|
2182
|
+
* Return the index of the first element that matches the predicate.
|
|
2183
|
+
*
|
|
2184
|
+
* If no element matches the predicate, return `undefined`.
|
|
2185
|
+
*/
|
|
2186
|
+
indexWhere: (collection: BoxedExpression, predicate: (element: BoxedExpression) => boolean) => number | undefined;
|
|
2187
|
+
}
|
|
2188
|
+
/**
|
|
2189
|
+
* The collection handlers are the primitive operations that can be
|
|
2190
|
+
* performed on collections, such as lists, sets, tuples, etc...
|
|
2191
|
+
*
|
|
2192
|
+
* @category Definitions
|
|
2193
|
+
*/
|
|
2194
|
+
export type CollectionHandlers = BaseCollectionHandlers & Partial<IndexedCollectionHandlers>;
|
|
2195
|
+
/**
|
|
2196
|
+
*
|
|
2197
|
+
* The definition for a value, represented as a tagged object literal.
|
|
2198
|
+
* @category Definitions
|
|
2199
|
+
*
|
|
2200
|
+
*/
|
|
2201
|
+
export type TaggedValueDefinition = {
|
|
2202
|
+
value: BoxedValueDefinition;
|
|
2203
|
+
};
|
|
2204
|
+
/**
|
|
2205
|
+
*
|
|
2206
|
+
* The definition for an operator, represented as a tagged object literal.
|
|
2207
|
+
*
|
|
2208
|
+
* @category Definitions
|
|
2209
|
+
*
|
|
2210
|
+
*/
|
|
2211
|
+
export type TaggedOperatorDefinition = {
|
|
2212
|
+
operator: BoxedOperatorDefinition;
|
|
2213
|
+
};
|
|
2214
|
+
/**
|
|
2215
|
+
* A definition can be either a value or an operator.
|
|
2216
|
+
*
|
|
2217
|
+
* It is collected in a tagged object literal, instead of being a simple union
|
|
2218
|
+
* type, so that the type of the definition can be changed while keeping
|
|
2219
|
+
* references to the definition in bound expressions.
|
|
2220
|
+
*
|
|
2221
|
+
* @category Definitions
|
|
2222
|
+
*
|
|
2223
|
+
*/
|
|
2224
|
+
export type BoxedDefinition = TaggedValueDefinition | TaggedOperatorDefinition;
|
|
2225
|
+
/**
|
|
2226
|
+
* @category Definitions
|
|
2227
|
+
*
|
|
2228
|
+
*/
|
|
2229
|
+
export interface BoxedBaseDefinition extends Partial<BaseDefinition> {
|
|
2230
|
+
/** If this is the definition of a collection, the set of primitive operations
|
|
2231
|
+
* that can be performed on this collection (counting the number of elements,
|
|
2232
|
+
* enumerating it, etc...).
|
|
2233
|
+
*/
|
|
2234
|
+
collection?: CollectionHandlers;
|
|
2235
|
+
}
|
|
2236
|
+
/**
|
|
2237
|
+
*
|
|
2238
|
+
* @category Definitions
|
|
2239
|
+
*/
|
|
2240
|
+
export interface BoxedValueDefinition extends BoxedBaseDefinition {
|
|
2241
|
+
/**
|
|
2242
|
+
* If the symbol has a value, it is held as indicated in the table below.
|
|
2243
|
+
* A green checkmark indicate that the symbol is substituted.
|
|
2244
|
+
|
|
2245
|
+
<div className="symbols-table">
|
|
2246
|
+
|
|
2247
|
+
| Operation | `"never"` | `"evaluate"` | `"N"` |
|
|
2248
|
+
| :--- | :-----: | :----: | :---: |
|
|
2249
|
+
| `canonical()` | (X) | | |
|
|
2250
|
+
| `evaluate()` | (X) | (X) | |
|
|
2251
|
+
| `"N()"` | (X) | (X) | (X) |
|
|
2252
|
+
|
|
2253
|
+
</div>
|
|
2254
|
+
|
|
2255
|
+
* Some examples:
|
|
2256
|
+
* - `ImaginaryUnit` has `holdUntil: 'never'`: it is substituted during canonicalization
|
|
2257
|
+
* - `x` has `holdUntil: 'evaluate'` (variables)
|
|
2258
|
+
* - `Pi` has `holdUntil: 'N'` (special numeric constant)
|
|
2259
|
+
*
|
|
2260
|
+
* **Default:** `evaluate`
|
|
2261
|
+
*/
|
|
2262
|
+
holdUntil: 'never' | 'evaluate' | 'N';
|
|
2263
|
+
/** This is either the initial value of the symbol (i.e. when a new
|
|
2264
|
+
* evaluation context is created), or its constant value, if a constant.
|
|
2265
|
+
* Otherwise, the current value is tracked in the evaluation context.
|
|
2266
|
+
*
|
|
2267
|
+
*/
|
|
2268
|
+
readonly value: BoxedExpression | undefined;
|
|
2269
|
+
eq?: (a: BoxedExpression) => boolean | undefined;
|
|
2270
|
+
neq?: (a: BoxedExpression) => boolean | undefined;
|
|
2271
|
+
cmp?: (a: BoxedExpression) => '=' | '>' | '<' | undefined;
|
|
2272
|
+
/**
|
|
2273
|
+
* True if the type has been inferred. An inferred type can be updated as
|
|
2274
|
+
* more information becomes available.
|
|
2275
|
+
*
|
|
2276
|
+
* A type that is not inferred, but has been set explicitly, cannot be updated.
|
|
2277
|
+
*/
|
|
2278
|
+
inferredType: boolean;
|
|
2279
|
+
type: BoxedType;
|
|
2280
|
+
}
|
|
2281
|
+
/**
|
|
2282
|
+
* An operator definition can have some flags to indicate specific
|
|
2283
|
+
* properties of the operator.
|
|
2284
|
+
* @category Definitions
|
|
2285
|
+
*/
|
|
2286
|
+
export type OperatorDefinitionFlags = {
|
|
2287
|
+
/**
|
|
2288
|
+
* If `true`, the arguments to this operator are not automatically
|
|
2289
|
+
* evaluated. The default is `false` (the arguments are evaluated).
|
|
2290
|
+
*
|
|
2291
|
+
* This can be useful for example for operators that take symbolic
|
|
2292
|
+
* expressions as arguments, such as `Declare` or `Integrate`.
|
|
2293
|
+
*
|
|
2294
|
+
* This is also useful for operators that take an argument that is
|
|
2295
|
+
* potentially an infinite collection.
|
|
2296
|
+
*
|
|
2297
|
+
* It will be up to the `evaluate()` handler to evaluate the arguments as
|
|
2298
|
+
* needed. This is convenient to pass symbolic expressions as arguments
|
|
2299
|
+
* to operators without having to explicitly use a `Hold` expression.
|
|
2300
|
+
*
|
|
2301
|
+
* This also applies to the `canonical()` handler.
|
|
2302
|
+
*
|
|
2303
|
+
*/
|
|
2304
|
+
lazy: boolean;
|
|
2305
|
+
/**
|
|
2306
|
+
* If `true`, the operator requires a new lexical scope when canonicalized.
|
|
2307
|
+
* This will allow it to declare variables that are not visible outside
|
|
2308
|
+
* the function expression using the operator.
|
|
2309
|
+
*
|
|
2310
|
+
* **Default**: `false`
|
|
2311
|
+
*/
|
|
2312
|
+
scoped: boolean;
|
|
2313
|
+
/** If `true`, the operator is applied element by element to lists, matrices
|
|
2314
|
+
* (`["List"]` or `["Tuple"]` expressions) and equations (relational
|
|
2315
|
+
* operators).
|
|
2316
|
+
*
|
|
2317
|
+
* **Default**: `false`
|
|
2318
|
+
*/
|
|
2319
|
+
broadcastable: boolean;
|
|
2320
|
+
/** If `true`, `["f", ["f", a], b]` simplifies to `["f", a, b]`
|
|
2321
|
+
*
|
|
2322
|
+
* **Default**: `false`
|
|
2323
|
+
*/
|
|
2324
|
+
associative: boolean;
|
|
2325
|
+
/** If `true`, `["f", a, b]` equals `["f", b, a]`. The canonical
|
|
2326
|
+
* version of the function will order the arguments.
|
|
2327
|
+
*
|
|
2328
|
+
* **Default**: `false`
|
|
2329
|
+
*/
|
|
2330
|
+
commutative: boolean;
|
|
2331
|
+
/**
|
|
2332
|
+
* If `commutative` is `true`, the order of the arguments is determined by
|
|
2333
|
+
* this function.
|
|
2334
|
+
*
|
|
2335
|
+
* If the function is not provided, the arguments are ordered by the
|
|
2336
|
+
* default order of the arguments.
|
|
2337
|
+
*
|
|
2338
|
+
*/
|
|
2339
|
+
commutativeOrder: ((a: BoxedExpression, b: BoxedExpression) => number) | undefined;
|
|
2340
|
+
/** If `true`, when the operator is univariate, `["f", ["Multiply", x, c]]`
|
|
2341
|
+
* simplifies to `["Multiply", ["f", x], c]` where `c` is constant
|
|
2342
|
+
*
|
|
2343
|
+
* When the operator is multivariate, multiplicativity is considered only on
|
|
2344
|
+
* the first argument: `["f", ["Multiply", x, y], z]` simplifies to
|
|
2345
|
+
* `["Multiply", ["f", x, z], ["f", y, z]]`
|
|
2346
|
+
*
|
|
2347
|
+
* Default: `false`
|
|
2348
|
+
*/
|
|
2349
|
+
/** If `true`, `["f", ["f", x]]` simplifies to `["f", x]`.
|
|
2350
|
+
*
|
|
2351
|
+
* **Default**: `false`
|
|
2352
|
+
*/
|
|
2353
|
+
idempotent: boolean;
|
|
2354
|
+
/** If `true`, `["f", ["f", x]]` simplifies to `x`.
|
|
2355
|
+
*
|
|
2356
|
+
* **Default**: `false`
|
|
2357
|
+
*/
|
|
2358
|
+
involution: boolean;
|
|
2359
|
+
/** If `true`, the value of this operator is always the same for a given
|
|
2360
|
+
* set of arguments and it has no side effects.
|
|
2361
|
+
*
|
|
2362
|
+
* An expression using this operator is pure if the operator and all its
|
|
2363
|
+
* arguments are pure.
|
|
2364
|
+
*
|
|
2365
|
+
* For example `Sin` is pure, `Random` isn't.
|
|
2366
|
+
*
|
|
2367
|
+
* This information may be used to cache the value of expressions.
|
|
2368
|
+
*
|
|
2369
|
+
* **Default:** `true`
|
|
2370
|
+
*/
|
|
2371
|
+
pure: boolean;
|
|
2372
|
+
};
|
|
2373
|
+
/**
|
|
2374
|
+
*
|
|
2375
|
+
* The definition includes information specific about an operator, such as
|
|
2376
|
+
* handlers to canonicalize or evaluate a function expression with this
|
|
2377
|
+
* operator.
|
|
2378
|
+
*
|
|
2379
|
+
* @category Definitions
|
|
2380
|
+
*
|
|
2381
|
+
*/
|
|
2382
|
+
export interface BoxedOperatorDefinition extends BoxedBaseDefinition, OperatorDefinitionFlags {
|
|
2383
|
+
complexity: number;
|
|
2384
|
+
/** If true, the signature was inferred from usage and may be modified
|
|
2385
|
+
* as more information becomes available.
|
|
2386
|
+
*/
|
|
2387
|
+
inferredSignature: boolean;
|
|
2388
|
+
/** The type of the arguments and return value of this function */
|
|
2389
|
+
signature: BoxedType;
|
|
2390
|
+
/** If present, this handler can be used to more precisely determine the
|
|
2391
|
+
* return type based on the type of the arguments. The arguments themselves
|
|
2392
|
+
* should *not* be evaluated, only their types should be used.
|
|
2393
|
+
*/
|
|
2394
|
+
type?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
2395
|
+
engine: ComputeEngine;
|
|
2396
|
+
}) => Type | TypeString | BoxedType | undefined;
|
|
2397
|
+
/** If present, this handler can be used to determine the sign of the
|
|
2398
|
+
* return value of the function, based on the sign and type of its
|
|
2399
|
+
* arguments.
|
|
2400
|
+
*
|
|
2401
|
+
* The arguments themselves should *not* be evaluated, only their types and
|
|
2402
|
+
* sign should be used.
|
|
2403
|
+
*
|
|
2404
|
+
* This can be used in some case for example to determine when certain
|
|
2405
|
+
* simplifications are valid.
|
|
2406
|
+
*/
|
|
2407
|
+
sgn?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
2408
|
+
engine: ComputeEngine;
|
|
2409
|
+
}) => Sign | undefined;
|
|
2410
|
+
eq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
|
|
2411
|
+
neq?: (a: BoxedExpression, b: BoxedExpression) => boolean | undefined;
|
|
2412
|
+
canonical?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
2413
|
+
engine: ComputeEngine;
|
|
2414
|
+
scope: Scope | undefined;
|
|
2415
|
+
}) => BoxedExpression | null;
|
|
2416
|
+
evaluate?: (ops: ReadonlyArray<BoxedExpression>, options: Partial<EvaluateOptions> & {
|
|
2417
|
+
engine?: ComputeEngine;
|
|
2418
|
+
}) => BoxedExpression | undefined;
|
|
2419
|
+
evaluateAsync?: (ops: ReadonlyArray<BoxedExpression>, options?: Partial<EvaluateOptions> & {
|
|
2420
|
+
engine?: ComputeEngine;
|
|
2421
|
+
}) => Promise<BoxedExpression | undefined>;
|
|
2422
|
+
evalDimension?: (ops: ReadonlyArray<BoxedExpression>, options: {
|
|
2423
|
+
engine: ComputeEngine;
|
|
2424
|
+
}) => BoxedExpression;
|
|
2425
|
+
compile?: (expr: BoxedExpression) => CompiledExpression;
|
|
2426
|
+
/** @internal */
|
|
2427
|
+
update(def: OperatorDefinition): void;
|
|
2428
|
+
}
|
|
2429
|
+
/** @category Assumptions */
|
|
2430
|
+
export interface Assumption {
|
|
2431
|
+
isPositive: boolean | undefined;
|
|
2432
|
+
isNonNegative: boolean | undefined;
|
|
2433
|
+
isNegative: boolean | undefined;
|
|
2434
|
+
isNonPositive: boolean | undefined;
|
|
2435
|
+
isNumber: boolean | undefined;
|
|
2436
|
+
isInteger: boolean | undefined;
|
|
2437
|
+
isRational: boolean | undefined;
|
|
2438
|
+
isReal: boolean | undefined;
|
|
2439
|
+
isComplex: boolean | undefined;
|
|
2440
|
+
isImaginary: boolean | undefined;
|
|
2441
|
+
isFinite: boolean | undefined;
|
|
2442
|
+
isInfinite: boolean | undefined;
|
|
2443
|
+
isNaN: boolean | undefined;
|
|
2444
|
+
isZero: boolean | undefined;
|
|
2445
|
+
matches(t: BoxedType): boolean | undefined;
|
|
2446
|
+
isGreater(other: BoxedExpression): boolean | undefined;
|
|
2447
|
+
isGreaterEqual(other: BoxedExpression): boolean | undefined;
|
|
2448
|
+
isLess(other: BoxedExpression): boolean | undefined;
|
|
2449
|
+
isLessEqual(other: BoxedExpression): boolean | undefined;
|
|
2450
|
+
isEqual(other: BoxedExpression): boolean | undefined;
|
|
2451
|
+
toExpression(ce: ComputeEngine, x: MathJsonSymbol): BoxedExpression;
|
|
2452
|
+
}
|
|
2453
|
+
/** @category Assumptions */
|
|
2454
|
+
export interface ExpressionMapInterface<U> {
|
|
2455
|
+
has(expr: BoxedExpression): boolean;
|
|
2456
|
+
get(expr: BoxedExpression): U | undefined;
|
|
2457
|
+
set(expr: BoxedExpression, value: U): void;
|
|
2458
|
+
delete(expr: BoxedExpression): void;
|
|
2459
|
+
clear(): void;
|
|
2460
|
+
[Symbol.iterator](): IterableIterator<[BoxedExpression, U]>;
|
|
2461
|
+
entries(): IterableIterator<[BoxedExpression, U]>;
|
|
2462
|
+
}
|
|
2463
|
+
/** @category Assumptions */
|
|
2464
|
+
export type AssumeResult = 'internal-error' | 'not-a-predicate' | 'contradiction' | 'tautology' | 'ok';
|
|
2465
|
+
/**
|
|
2466
|
+
* When provided, canonical forms are used to put an expression in a
|
|
2467
|
+
* "standard" form.
|
|
2468
|
+
*
|
|
2469
|
+
* Each canonical form applies some transformation to an expression. When
|
|
2470
|
+
* specified as an array, each transformation is done in the order in which
|
|
2471
|
+
* it was provided.
|
|
2472
|
+
*
|
|
2473
|
+
* - `InvisibleOperator`: replace use of the `InvisibleOperator` with
|
|
2474
|
+
* another operation, such as multiplication (i.e. `2x` or function
|
|
2475
|
+
* application (`f(x)`). Also replaces ['InvisibleOperator', real, imaginary] instances with
|
|
2476
|
+
* complex (imaginary) numbers.
|
|
2477
|
+
* - `Number`: replace all numeric values with their
|
|
2478
|
+
* canonical representation, for example, reduce
|
|
2479
|
+
* rationals and replace complex numbers with no imaginary part with a real number.
|
|
2480
|
+
* - `Multiply`: replace negation with multiplication by -1, remove 1 from multiplications, simplify signs (`-y \times -x` -> `x \times y`), complex numbers are promoted (['Multiply', 2, 'ImaginaryUnit'] -> `["Complex", 0, 2]`)
|
|
2481
|
+
* - `Add`: replace `Subtract` with `Add`, removes 0 in addition, promote complex numbers (["Add", "a", ["Complex", 0, "b"] -> `["Complex", "a", "b"]`)
|
|
2482
|
+
* - `Power`: simplify `Power` expression, for example, `x^{-1}` -> `\frac{1}{x}`, `x^0` -> `1`, `x^1` -> `x`, `1^x` -> `1`, `x^{\frac{1}{2}}` -> `\sqrt{x}`, `a^b^c` -> `a^{bc}`...
|
|
2483
|
+
* - `Divide`: replace with a `Rational` number if numerator and denominator are integers, simplify, e.g. `\frac{x}{1}` -> `x`...
|
|
2484
|
+
* - `Flatten`: remove any unnecessary `Delimiter` expression, and flatten any associative functions, for example `["Add", ["Add", "a", "b"], "c"]` -> `["Add", "a", "b", "c"]`
|
|
2485
|
+
* - `Order`: when applicable, sort the arguments in a specific order, for
|
|
2486
|
+
* example for addition and multiplication.
|
|
2487
|
+
*
|
|
2488
|
+
*
|
|
2489
|
+
* @category Boxed Expression
|
|
2490
|
+
*/
|
|
2491
|
+
export type CanonicalForm = 'InvisibleOperator' | 'Number' | 'Multiply' | 'Add' | 'Power' | 'Divide' | 'Flatten' | 'Order';
|
|
2492
|
+
/** @category Boxed Expression */
|
|
2493
|
+
export type CanonicalOptions = boolean | CanonicalForm | CanonicalForm[];
|
|
2494
|
+
/** Options for `BoxedExpression.evaluate()`
|
|
2495
|
+
*
|
|
2496
|
+
* @category Boxed Expression
|
|
2497
|
+
*/
|
|
2498
|
+
export type EvaluateOptions = {
|
|
2499
|
+
/**
|
|
2500
|
+
* If `true`, the evaluation will return a numeric approximation
|
|
2501
|
+
* of the expression, if possible.
|
|
2502
|
+
* If `false`, the evaluation will return an exact value, if possible.
|
|
2503
|
+
* Defaults to `false`.
|
|
2504
|
+
*/
|
|
2505
|
+
numericApproximation: boolean;
|
|
2506
|
+
/**
|
|
2507
|
+
* If `false`, and the result of the expression is a lazy collection,
|
|
2508
|
+
* the collection will not be evaluated and will remain lazy.
|
|
2509
|
+
*
|
|
2510
|
+
* If `true` and the expression is a finite lazy collection,
|
|
2511
|
+
* the collection will be evaluated and returned as a non-lazy collection.
|
|
2512
|
+
*
|
|
2513
|
+
* If an integer, the collection will be evaluated up to that many elements.
|
|
2514
|
+
*
|
|
2515
|
+
* If a pair of integers `[n,m]`, and the collection is finite, the first `n`
|
|
2516
|
+
* elements will be evaluated, and the last `m` elements will be evaluated.
|
|
2517
|
+
*
|
|
2518
|
+
* Defaults to `false`.
|
|
2519
|
+
*/
|
|
2520
|
+
materialization: boolean | number | [number, number];
|
|
2521
|
+
signal: AbortSignal;
|
|
2522
|
+
withArguments: Record<MathJsonSymbol, BoxedExpression>;
|
|
2523
|
+
};
|
|
2524
|
+
/**
|
|
2525
|
+
* Metadata that can be associated with an MathJSON expression.
|
|
2526
|
+
*
|
|
2527
|
+
* @category Boxed Expression
|
|
2528
|
+
*/
|
|
2529
|
+
export type Metadata = {
|
|
2530
|
+
latex?: string | undefined;
|
|
2531
|
+
wikidata?: string | undefined;
|
|
2532
|
+
};
|
|
2533
|
+
/**
|
|
2534
|
+
* A substitution describes the values of the wildcards in a pattern so that
|
|
2535
|
+
* the pattern is equal to a target expression.
|
|
2536
|
+
*
|
|
2537
|
+
* A substitution can also be considered a more constrained version of a
|
|
2538
|
+
* rule whose `match` is always a symbol.
|
|
2539
|
+
|
|
2540
|
+
* @category Pattern Matching
|
|
2541
|
+
*/
|
|
2542
|
+
export type Substitution<T = SemiBoxedExpression> = {
|
|
2543
|
+
[symbol: string]: T;
|
|
2544
|
+
};
|
|
2545
|
+
/**
|
|
2546
|
+
* @category Pattern Matching
|
|
2547
|
+
*
|
|
2548
|
+
*/
|
|
2549
|
+
export type BoxedSubstitution = Substitution<BoxedExpression>;
|
|
2550
|
+
/**
|
|
2551
|
+
* Given an expression and set of wildcards, return a new expression.
|
|
2552
|
+
*
|
|
2553
|
+
* For example:
|
|
2554
|
+
*
|
|
2555
|
+
* ```ts
|
|
2556
|
+
* {
|
|
2557
|
+
* match: '_x',
|
|
2558
|
+
* replace: (expr, {_x}) => { return ['Add', 1, _x] }
|
|
2559
|
+
* }
|
|
2560
|
+
* ```
|
|
2561
|
+
*
|
|
2562
|
+
* @category Rules */
|
|
2563
|
+
export type RuleReplaceFunction = (expr: BoxedExpression, wildcards: BoxedSubstitution) => BoxedExpression | undefined;
|
|
2564
|
+
/** @category Rules */
|
|
2565
|
+
export type RuleConditionFunction = (wildcards: BoxedSubstitution, ce: ComputeEngine) => boolean;
|
|
2566
|
+
/** @category Rules */
|
|
2567
|
+
export type RuleFunction = (expr: BoxedExpression) => undefined | BoxedExpression | RuleStep;
|
|
2568
|
+
/** @category Rules */
|
|
2569
|
+
export type RuleStep = {
|
|
2570
|
+
value: BoxedExpression;
|
|
2571
|
+
because: string;
|
|
2572
|
+
};
|
|
2573
|
+
/** @category Rules */
|
|
2574
|
+
export type RuleSteps = RuleStep[];
|
|
2575
|
+
/**
|
|
2576
|
+
* A rule describes how to modify an expression that matches a pattern `match`
|
|
2577
|
+
* into a new expression `replace`.
|
|
2578
|
+
*
|
|
2579
|
+
* - `x-1` \( \to \) `1-x`
|
|
2580
|
+
* - `(x+1)(x-1)` \( \to \) `x^2-1
|
|
2581
|
+
*
|
|
2582
|
+
* The patterns can be expressed as LaTeX strings or `SemiBoxedExpression`'s.
|
|
2583
|
+
* Alternatively, match/replace logic may be specified by a `RuleFunction`, allowing both custom
|
|
2584
|
+
* logic/conditions for the match, and either a *BoxedExpression* (or `RuleStep` if being
|
|
2585
|
+
* descriptive) for the replacement.
|
|
2586
|
+
*
|
|
2587
|
+
* As a shortcut, a rule can be defined as a LaTeX string: `x-1 -> 1-x`.
|
|
2588
|
+
* The expression to the left of `->` is the `match` and the expression to the
|
|
2589
|
+
* right is the `replace`. When using LaTeX strings, single character variables
|
|
2590
|
+
* are assumed to be wildcards. The rule LHS ('match') and RHS ('replace') may also be supplied
|
|
2591
|
+
* separately: in this case following the same rules.
|
|
2592
|
+
*
|
|
2593
|
+
* When using MathJSON expressions, anonymous wildcards (`_`) will match any
|
|
2594
|
+
* expression. Named wildcards (`_x`, `_a`, etc...) will match any expression
|
|
2595
|
+
* and bind the expression to the wildcard name.
|
|
2596
|
+
*
|
|
2597
|
+
* In addition the sequence wildcard (`__1`, `__a`, etc...) will match
|
|
2598
|
+
* a sequence of one or more expressions, and bind the sequence to the
|
|
2599
|
+
* wildcard name.
|
|
2600
|
+
*
|
|
2601
|
+
* Sequence wildcards are useful when the number of elements in the sequence
|
|
2602
|
+
* is not known in advance. For example, in a sum, the number of terms is
|
|
2603
|
+
* not known in advance. ["Add", 0, `__a`] will match two or more terms and
|
|
2604
|
+
* the `__a` wildcard will be a sequence of the matchign terms.
|
|
2605
|
+
*
|
|
2606
|
+
* If `exact` is false, the rule will match variants.
|
|
2607
|
+
*
|
|
2608
|
+
* For example 'x' will match 'a + x', 'x' will match 'ax', etc...
|
|
2609
|
+
*
|
|
2610
|
+
* For simplification rules, you generally want `exact` to be true, but
|
|
2611
|
+
* to solve equations, you want it to be false. Default to true.
|
|
2612
|
+
*
|
|
2613
|
+
* When set to false, infinite recursion is possible.
|
|
2614
|
+
*
|
|
2615
|
+
* @category Rules
|
|
2616
|
+
*/
|
|
2617
|
+
export type Rule = string | RuleFunction | {
|
|
2618
|
+
match?: LatexString | SemiBoxedExpression | BoxedExpression;
|
|
2619
|
+
replace: LatexString | SemiBoxedExpression | RuleReplaceFunction | RuleFunction;
|
|
2620
|
+
condition?: LatexString | RuleConditionFunction;
|
|
2621
|
+
useVariations?: boolean;
|
|
2622
|
+
id?: string;
|
|
2623
|
+
onBeforeMatch?: (rule: Rule, expr: BoxedExpression) => void;
|
|
2624
|
+
onMatch?: (rule: Rule, expr: BoxedExpression, replace: BoxedExpression | RuleStep) => void;
|
|
2625
|
+
};
|
|
2626
|
+
/**
|
|
2627
|
+
*
|
|
2628
|
+
* If the `match` property is `undefined`, all expressions match this rule
|
|
2629
|
+
* and `condition` should also be `undefined`. The `replace` property should
|
|
2630
|
+
* be a `BoxedExpression` or a `RuleFunction`, and further filtering can be
|
|
2631
|
+
* done in the `replace` function.
|
|
2632
|
+
*
|
|
2633
|
+
* @category Rules
|
|
2634
|
+
*/
|
|
2635
|
+
export type BoxedRule = {
|
|
2636
|
+
/** @internal */
|
|
2637
|
+
readonly _tag: 'boxed-rule';
|
|
2638
|
+
match: undefined | BoxedExpression;
|
|
2639
|
+
replace: BoxedExpression | RuleReplaceFunction | RuleFunction;
|
|
2640
|
+
condition: undefined | RuleConditionFunction;
|
|
2641
|
+
useVariations?: boolean;
|
|
2642
|
+
id?: string;
|
|
2643
|
+
onBeforeMatch?: (rule: Rule, expr: BoxedExpression) => void;
|
|
2644
|
+
onMatch?: (rule: Rule, expr: BoxedExpression, replace: BoxedExpression | RuleStep) => void;
|
|
2645
|
+
};
|
|
2646
|
+
/**
|
|
2647
|
+
* To create a BoxedRuleSet use the `ce.rules()` method.
|
|
2648
|
+
*
|
|
2649
|
+
* Do not create a `BoxedRuleSet` directly.
|
|
2650
|
+
*
|
|
2651
|
+
* @category Rules
|
|
2652
|
+
*/
|
|
2653
|
+
export type BoxedRuleSet = {
|
|
2654
|
+
rules: ReadonlyArray<BoxedRule>;
|
|
2655
|
+
};
|
|
2656
|
+
/**
|
|
2657
|
+
* The argument of `ce.assign()` is a value that can be assigned to a variable.
|
|
2658
|
+
* It can be a primitive value, a boxed expression, or a function that
|
|
2659
|
+
* takes a list of arguments and returns a boxed expression.
|
|
2660
|
+
* @category Compute Engine */
|
|
2661
|
+
export type AssignValue = boolean | number | bigint | SemiBoxedExpression | ((args: ReadonlyArray<BoxedExpression>, options: EvaluateOptions & {
|
|
2662
|
+
engine: ComputeEngine;
|
|
2663
|
+
}) => BoxedExpression) | undefined;
|
|
2664
|
+
/**
|
|
2665
|
+
* A lexical scope is a table mapping symbols to their definitions. The
|
|
2666
|
+
* symbols are the names of the variables, unknowns and functions in the scope.
|
|
2667
|
+
*
|
|
2668
|
+
* The lexical scope is used to resolve the metadata about symbols, such as
|
|
2669
|
+
* their type, whether they are constant, etc...
|
|
2670
|
+
*
|
|
2671
|
+
* It does not resolve the values of the symbols, since those depend on the
|
|
2672
|
+
* evaluation context. For example, the local variables of a recursive function
|
|
2673
|
+
* will have the same lexical scope, but different values in each evaluation
|
|
2674
|
+
* context.
|
|
2675
|
+
*
|
|
2676
|
+
* @category Definitions
|
|
2677
|
+
*/
|
|
2678
|
+
export type Scope = {
|
|
2679
|
+
parent: Scope | null;
|
|
2680
|
+
bindings: Map<string, BoxedDefinition>;
|
|
2681
|
+
types?: Record<string, TypeReference>;
|
|
2682
|
+
};
|
|
2683
|
+
/**
|
|
2684
|
+
* An evaluation context is a set of bindings mapping symbols to their
|
|
2685
|
+
* values. It also includes a reference to the lexical scope of the
|
|
2686
|
+
* context, as well as a set of assumptions about the values of the
|
|
2687
|
+
* symbols.
|
|
2688
|
+
*
|
|
2689
|
+
*
|
|
2690
|
+
* Eval contexts are arranged in a stack structure. When a new context is
|
|
2691
|
+
* created, it is pushed on the top of the stack.
|
|
2692
|
+
*
|
|
2693
|
+
* A new eval context is created when a function expression that needs to track
|
|
2694
|
+
* its own local variables and named arguments is evaluated. This kind of
|
|
2695
|
+
* function is a "scoped" function, meaning that it has its own local variables
|
|
2696
|
+
* and named arguments.
|
|
2697
|
+
*
|
|
2698
|
+
* For example, the `Sum` function creates a new eval context to track the local
|
|
2699
|
+
* variable used as the index of the sum.
|
|
2700
|
+
*
|
|
2701
|
+
* The eval context stack is used to resolve the value of symbols.
|
|
2702
|
+
*
|
|
2703
|
+
* When a scoped recursive function is called, a new context is created for each
|
|
2704
|
+
* recursive call.
|
|
2705
|
+
*
|
|
2706
|
+
* In contrast, the lexical scope is used to resolve the metadata about
|
|
2707
|
+
* symbols, such as their type, whether they are constant, etc... A new
|
|
2708
|
+
* scope is not created for recursive calls, since the metadata
|
|
2709
|
+
* does not change, only the values of the symbols change.
|
|
2710
|
+
*
|
|
2711
|
+
* The name of the eval context is used to print a "stack trace" for
|
|
2712
|
+
* debugging.
|
|
2713
|
+
*
|
|
2714
|
+
* @category Compute Engine
|
|
2715
|
+
*/
|
|
2716
|
+
export type EvalContext = {
|
|
2717
|
+
lexicalScope: Scope;
|
|
2718
|
+
assumptions: ExpressionMapInterface<boolean>;
|
|
2719
|
+
values: Record<string, BoxedExpression | undefined>;
|
|
2720
|
+
name: undefined | string;
|
|
2721
|
+
};
|
|
2722
|
+
/** @internal */
|
|
2723
|
+
export interface ComputeEngine extends IBigNum {
|
|
2724
|
+
latexDictionary: readonly LatexDictionaryEntry[];
|
|
2725
|
+
/** @private */
|
|
2726
|
+
_indexedLatexDictionary: IndexedLatexDictionary;
|
|
2727
|
+
decimalSeparator: LatexString;
|
|
2728
|
+
readonly True: BoxedExpression;
|
|
2729
|
+
readonly False: BoxedExpression;
|
|
2730
|
+
readonly Pi: BoxedExpression;
|
|
2731
|
+
readonly E: BoxedExpression;
|
|
2732
|
+
readonly Nothing: BoxedExpression;
|
|
2733
|
+
readonly Zero: BoxedExpression;
|
|
2734
|
+
readonly One: BoxedExpression;
|
|
2735
|
+
readonly Half: BoxedExpression;
|
|
2736
|
+
readonly NegativeOne: BoxedExpression;
|
|
2737
|
+
/** ImaginaryUnit */
|
|
2738
|
+
readonly I: BoxedExpression;
|
|
2739
|
+
readonly NaN: BoxedExpression;
|
|
2740
|
+
readonly PositiveInfinity: BoxedExpression;
|
|
2741
|
+
readonly NegativeInfinity: BoxedExpression;
|
|
2742
|
+
readonly ComplexInfinity: BoxedExpression;
|
|
2743
|
+
/** @internal */
|
|
2744
|
+
readonly _BIGNUM_NAN: BigNum;
|
|
2745
|
+
/** @internal */
|
|
2746
|
+
readonly _BIGNUM_ZERO: BigNum;
|
|
2747
|
+
/** @internal */
|
|
2748
|
+
readonly _BIGNUM_ONE: BigNum;
|
|
2749
|
+
/** @internal */
|
|
2750
|
+
readonly _BIGNUM_TWO: BigNum;
|
|
2751
|
+
/** @internal */
|
|
2752
|
+
readonly _BIGNUM_HALF: BigNum;
|
|
2753
|
+
/** @internal */
|
|
2754
|
+
readonly _BIGNUM_PI: BigNum;
|
|
2755
|
+
/** @internal */
|
|
2756
|
+
readonly _BIGNUM_NEGATIVE_ONE: BigNum;
|
|
2757
|
+
readonly context: EvalContext;
|
|
2758
|
+
contextStack: ReadonlyArray<EvalContext>;
|
|
2759
|
+
/** @internal */
|
|
2760
|
+
readonly _typeResolver: TypeResolver;
|
|
2761
|
+
/** Absolute time beyond which evaluation should not proceed
|
|
2762
|
+
* @internal
|
|
2763
|
+
*/
|
|
2764
|
+
_deadline?: number;
|
|
2765
|
+
/** Time remaining before _deadline
|
|
2766
|
+
* @internal
|
|
2767
|
+
*/
|
|
2768
|
+
_timeRemaining: number;
|
|
2769
|
+
/** @internal */
|
|
2770
|
+
_generation: number;
|
|
2771
|
+
timeLimit: number;
|
|
2772
|
+
iterationLimit: number;
|
|
2773
|
+
recursionLimit: number;
|
|
2774
|
+
chop(n: number): number;
|
|
2775
|
+
chop(n: BigNum): BigNum | 0;
|
|
2776
|
+
chop(n: number | BigNum): number | BigNum;
|
|
2777
|
+
bignum: (a: string | number | bigint | BigNum) => BigNum;
|
|
2778
|
+
complex: (a: number | Complex, b?: number) => Complex;
|
|
2779
|
+
/** @internal */
|
|
2780
|
+
_numericValue(value: number | bigint | OneOf<[BigNum | NumericValueData | ExactNumericValueData]>): NumericValue;
|
|
2781
|
+
set precision(p: number | 'machine' | 'auto');
|
|
2782
|
+
get precision(): number;
|
|
2783
|
+
tolerance: number;
|
|
2784
|
+
angularUnit: AngularUnit;
|
|
2785
|
+
costFunction: (expr: BoxedExpression) => number;
|
|
2786
|
+
strict: boolean;
|
|
2787
|
+
box(expr: NumericValue | SemiBoxedExpression, options?: {
|
|
2788
|
+
canonical?: CanonicalOptions;
|
|
2789
|
+
structural?: boolean;
|
|
2790
|
+
scope?: Scope;
|
|
2791
|
+
}): BoxedExpression;
|
|
2792
|
+
function(name: string, ops: ReadonlyArray<SemiBoxedExpression>, options?: {
|
|
2793
|
+
metadata?: Metadata;
|
|
2794
|
+
canonical?: CanonicalOptions;
|
|
2795
|
+
structural?: boolean;
|
|
2796
|
+
scope?: Scope;
|
|
2797
|
+
}): BoxedExpression;
|
|
2798
|
+
/**
|
|
2799
|
+
* This is a primitive to create a boxed function.
|
|
2800
|
+
*
|
|
2801
|
+
* In general, consider using `ce.box()` or `ce.function()` or
|
|
2802
|
+
* `canonicalXXX()` instead.
|
|
2803
|
+
*
|
|
2804
|
+
* The caller must ensure that the arguments are in canonical form:
|
|
2805
|
+
* - arguments are `canonical()`
|
|
2806
|
+
* - arguments are sorted
|
|
2807
|
+
* - arguments are flattened and desequenced
|
|
2808
|
+
*
|
|
2809
|
+
* @internal
|
|
2810
|
+
*/
|
|
2811
|
+
_fn(name: string, ops: ReadonlyArray<BoxedExpression>, options?: {
|
|
2812
|
+
metadata?: Metadata;
|
|
2813
|
+
canonical?: boolean;
|
|
2814
|
+
scope?: Scope;
|
|
2815
|
+
}): BoxedExpression;
|
|
2816
|
+
number(value: number | bigint | string | NumericValue | MathJsonNumberObject | BigNum | Complex | Rational, options?: {
|
|
2817
|
+
metadata?: Metadata;
|
|
2818
|
+
canonical?: CanonicalOptions;
|
|
2819
|
+
}): BoxedExpression;
|
|
2820
|
+
symbol(sym: string, options?: {
|
|
2821
|
+
canonical?: CanonicalOptions;
|
|
2822
|
+
metadata?: Metadata;
|
|
2823
|
+
}): BoxedExpression;
|
|
2824
|
+
string(s: string, metadata?: Metadata): BoxedExpression;
|
|
2825
|
+
error(message: string | string[], where?: string): BoxedExpression;
|
|
2826
|
+
typeError(expectedType: Type, actualType: undefined | Type | BoxedType, where?: SemiBoxedExpression): BoxedExpression;
|
|
2827
|
+
hold(expr: SemiBoxedExpression): BoxedExpression;
|
|
2828
|
+
tuple(...elements: ReadonlyArray<number>): BoxedExpression;
|
|
2829
|
+
tuple(...elements: ReadonlyArray<BoxedExpression>): BoxedExpression;
|
|
2830
|
+
type(type: Type | TypeString | BoxedType): BoxedType;
|
|
2831
|
+
rules(rules: Rule | ReadonlyArray<Rule | BoxedRule> | BoxedRuleSet | undefined | null, options?: {
|
|
2832
|
+
canonical?: boolean;
|
|
2833
|
+
}): BoxedRuleSet;
|
|
2834
|
+
getRuleSet(id?: 'harmonization' | 'solve-univariate' | 'standard-simplification'): BoxedRuleSet | undefined;
|
|
2835
|
+
parse(latex: null, options?: Partial<ParseLatexOptions> & {
|
|
2836
|
+
canonical?: CanonicalOptions;
|
|
2837
|
+
}): null;
|
|
2838
|
+
parse(latex: LatexString, options?: Partial<ParseLatexOptions> & {
|
|
2839
|
+
canonical?: CanonicalOptions;
|
|
2840
|
+
}): BoxedExpression;
|
|
2841
|
+
parse(latex: LatexString | null, options?: Partial<ParseLatexOptions> & {
|
|
2842
|
+
canonical?: CanonicalOptions;
|
|
2843
|
+
}): BoxedExpression | null;
|
|
2844
|
+
pushScope(scope?: Scope, name?: string): void;
|
|
2845
|
+
popScope(): void;
|
|
2846
|
+
/**
|
|
2847
|
+
*
|
|
2848
|
+
* When a new eval context is created, it has slots for the local variables
|
|
2849
|
+
* from the current lexical scope. It also copies the current set of
|
|
2850
|
+
* assumptions.
|
|
2851
|
+
*
|
|
2852
|
+
* 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).
|
|
2853
|
+
*
|
|
2854
|
+
* If a function is "scoped" (has a `scoped` flag), create a new lexical scope
|
|
2855
|
+
* when the function is canonicalized, store the scope with the function
|
|
2856
|
+
* definition (if the function has a lazy flag, and a canonical handler, it
|
|
2857
|
+
* can behave like a scoped function, but a scoped flag is convenient,
|
|
2858
|
+
* it would still evaluate the arguments).
|
|
2859
|
+
*
|
|
2860
|
+
* Note: if an expression is not canonical, evaluating it return itself.
|
|
2861
|
+
* This is important to support arguments that are just symbol names
|
|
2862
|
+
* (they are not canonicalized).
|
|
2863
|
+
*
|
|
2864
|
+
* When the function expression is evaluated, if it is "scoped", push the
|
|
2865
|
+
* scope associated with the function (maybe not?) and a matching eval
|
|
2866
|
+
* context, including all the symbols in the lexical scope (including
|
|
2867
|
+
* constants). Need some way to indicate that a symbol maps to an argument
|
|
2868
|
+
* (in value definition?).
|
|
2869
|
+
*
|
|
2870
|
+
* When searching the value of a symbol, start with the current
|
|
2871
|
+
* eval context, then the previous one.
|
|
2872
|
+
*
|
|
2873
|
+
* When looking for a definition, start with the lexical scope of the
|
|
2874
|
+
* current eval context, then the parent lexical context.
|
|
2875
|
+
*
|
|
2876
|
+
* @internal */
|
|
2877
|
+
_pushEvalContext(scope: Scope, name?: string): void;
|
|
2878
|
+
/** @internal */
|
|
2879
|
+
_popEvalContext(): void;
|
|
2880
|
+
/**
|
|
2881
|
+
* Temporarily sets the lexical scope to the provided scope, then
|
|
2882
|
+
* executes the function `f` in that scope and returns the result.
|
|
2883
|
+
* @internal */
|
|
2884
|
+
_inScope<T>(scope: Scope | undefined, f: () => T): T;
|
|
2885
|
+
/**
|
|
2886
|
+
* Use `ce.box(id)` instead
|
|
2887
|
+
* @internal */
|
|
2888
|
+
_getSymbolValue(id: MathJsonSymbol): BoxedExpression | undefined;
|
|
2889
|
+
/**
|
|
2890
|
+
* Use `ce.assign(id, value)` instead.
|
|
2891
|
+
* @internal */
|
|
2892
|
+
_setSymbolValue(id: MathJsonSymbol, value: BoxedExpression | boolean | number | undefined): void;
|
|
2893
|
+
/** A list of the function calls to the current evaluation context */
|
|
2894
|
+
trace: ReadonlyArray<string>;
|
|
2895
|
+
lookupContext(id: MathJsonSymbol): undefined | EvalContext;
|
|
2896
|
+
/** @internal */
|
|
2897
|
+
_swapContext(context: EvalContext): void;
|
|
2898
|
+
lookupDefinition(id: MathJsonSymbol): undefined | BoxedDefinition;
|
|
2899
|
+
assign(ids: {
|
|
2900
|
+
[id: MathJsonSymbol]: AssignValue;
|
|
2901
|
+
}): ComputeEngine;
|
|
2902
|
+
assign(id: MathJsonSymbol, value: AssignValue): ComputeEngine;
|
|
2903
|
+
assign(arg1: MathJsonSymbol | {
|
|
2904
|
+
[id: MathJsonSymbol]: AssignValue;
|
|
2905
|
+
}, arg2?: AssignValue): ComputeEngine;
|
|
2906
|
+
declareType(name: string, type: Type, options?: {
|
|
2907
|
+
alias?: boolean;
|
|
2908
|
+
}): void;
|
|
2909
|
+
declare(symbols: {
|
|
2910
|
+
[id: MathJsonSymbol]: Type | TypeString | Partial<SymbolDefinition>;
|
|
2911
|
+
}): ComputeEngine;
|
|
2912
|
+
declare(id: MathJsonSymbol, def: Type | TypeString | Partial<SymbolDefinition>, scope?: Scope): ComputeEngine;
|
|
2913
|
+
declare(arg1: MathJsonSymbol | {
|
|
2914
|
+
[id: MathJsonSymbol]: Type | TypeString | Partial<SymbolDefinition>;
|
|
2915
|
+
}, arg2?: Type | TypeString | Partial<SymbolDefinition>, arg3?: Scope): ComputeEngine;
|
|
2916
|
+
assume(predicate: BoxedExpression): AssumeResult;
|
|
2917
|
+
forget(symbol?: MathJsonSymbol | MathJsonSymbol[]): void;
|
|
2918
|
+
ask(pattern: BoxedExpression): BoxedSubstitution[];
|
|
2919
|
+
verify(query: BoxedExpression): boolean;
|
|
2920
|
+
/** @internal */
|
|
2921
|
+
_shouldContinueExecution(): boolean;
|
|
2922
|
+
/** @internal */
|
|
2923
|
+
_checkContinueExecution(): void;
|
|
2924
|
+
/** @internal */
|
|
2925
|
+
_cache<T>(name: string, build: () => T, purge?: (t: T) => T | undefined): T;
|
|
2926
|
+
/** @internal */
|
|
2927
|
+
_reset(): void;
|
|
2928
|
+
/** @internal */
|
|
2929
|
+
listenToConfigurationChange(tracker: ConfigurationChangeListener): () => void;
|
|
2930
|
+
}
|