mathjs 10.1.0 → 10.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HISTORY.md +38 -0
- package/docs/expressions/algebra.md +27 -0
- package/docs/expressions/syntax.md +31 -2
- package/docs/reference/functions/abs.md +6 -0
- package/docs/reference/functions/acos.md +6 -0
- package/docs/reference/functions/acosh.md +6 -0
- package/docs/reference/functions/acot.md +6 -0
- package/docs/reference/functions/acoth.md +6 -0
- package/docs/reference/functions/acsc.md +6 -0
- package/docs/reference/functions/acsch.md +6 -0
- package/docs/reference/functions/add.md +6 -0
- package/docs/reference/functions/and.md +6 -0
- package/docs/reference/functions/apply.md +6 -0
- package/docs/reference/functions/arg.md +6 -0
- package/docs/reference/functions/asec.md +6 -0
- package/docs/reference/functions/asech.md +6 -0
- package/docs/reference/functions/asin.md +6 -0
- package/docs/reference/functions/asinh.md +6 -0
- package/docs/reference/functions/atan.md +6 -0
- package/docs/reference/functions/atan2.md +6 -0
- package/docs/reference/functions/atanh.md +6 -0
- package/docs/reference/functions/bellNumbers.md +6 -0
- package/docs/reference/functions/bin.md +6 -0
- package/docs/reference/functions/bitAnd.md +6 -0
- package/docs/reference/functions/bitNot.md +6 -0
- package/docs/reference/functions/bitOr.md +6 -0
- package/docs/reference/functions/bitXor.md +6 -0
- package/docs/reference/functions/catalan.md +6 -0
- package/docs/reference/functions/cbrt.md +6 -0
- package/docs/reference/functions/ceil.md +6 -0
- package/docs/reference/functions/clone.md +6 -0
- package/docs/reference/functions/column.md +6 -0
- package/docs/reference/functions/combinations.md +6 -0
- package/docs/reference/functions/combinationsWithRep.md +6 -0
- package/docs/reference/functions/compare.md +6 -0
- package/docs/reference/functions/compareNatural.md +6 -0
- package/docs/reference/functions/compareText.md +6 -0
- package/docs/reference/functions/compile.md +6 -0
- package/docs/reference/functions/composition.md +6 -0
- package/docs/reference/functions/concat.md +6 -0
- package/docs/reference/functions/conj.md +6 -0
- package/docs/reference/functions/cos.md +6 -0
- package/docs/reference/functions/cosh.md +6 -0
- package/docs/reference/functions/cot.md +6 -0
- package/docs/reference/functions/coth.md +6 -0
- package/docs/reference/functions/count.md +6 -0
- package/docs/reference/functions/cross.md +6 -0
- package/docs/reference/functions/csc.md +6 -0
- package/docs/reference/functions/csch.md +6 -0
- package/docs/reference/functions/ctranspose.md +6 -0
- package/docs/reference/functions/cube.md +6 -0
- package/docs/reference/functions/deepEqual.md +6 -0
- package/docs/reference/functions/derivative.md +6 -0
- package/docs/reference/functions/det.md +6 -0
- package/docs/reference/functions/diag.md +6 -0
- package/docs/reference/functions/diff.md +6 -0
- package/docs/reference/functions/distance.md +6 -0
- package/docs/reference/functions/divide.md +6 -0
- package/docs/reference/functions/dot.md +6 -0
- package/docs/reference/functions/dotDivide.md +6 -0
- package/docs/reference/functions/dotMultiply.md +6 -0
- package/docs/reference/functions/dotPow.md +6 -0
- package/docs/reference/functions/eigs.md +6 -0
- package/docs/reference/functions/equal.md +6 -0
- package/docs/reference/functions/equalText.md +6 -0
- package/docs/reference/functions/erf.md +6 -0
- package/docs/reference/functions/evaluate.md +6 -0
- package/docs/reference/functions/exp.md +6 -0
- package/docs/reference/functions/expm.md +6 -0
- package/docs/reference/functions/expm1.md +6 -0
- package/docs/reference/functions/factorial.md +6 -0
- package/docs/reference/functions/filter.md +6 -0
- package/docs/reference/functions/fix.md +6 -0
- package/docs/reference/functions/flatten.md +6 -0
- package/docs/reference/functions/floor.md +6 -0
- package/docs/reference/functions/forEach.md +6 -0
- package/docs/reference/functions/format.md +6 -0
- package/docs/reference/functions/gamma.md +6 -0
- package/docs/reference/functions/gcd.md +6 -0
- package/docs/reference/functions/getMatrixDataType.md +6 -0
- package/docs/reference/functions/hasNumericValue.md +6 -0
- package/docs/reference/functions/help.md +6 -0
- package/docs/reference/functions/hex.md +6 -0
- package/docs/reference/functions/hypot.md +6 -0
- package/docs/reference/functions/identity.md +6 -0
- package/docs/reference/functions/im.md +6 -0
- package/docs/reference/functions/intersect.md +6 -0
- package/docs/reference/functions/inv.md +6 -0
- package/docs/reference/functions/invmod.md +6 -0
- package/docs/reference/functions/isInteger.md +6 -0
- package/docs/reference/functions/isNaN.md +6 -0
- package/docs/reference/functions/isNegative.md +6 -0
- package/docs/reference/functions/isNumeric.md +6 -0
- package/docs/reference/functions/isPositive.md +6 -0
- package/docs/reference/functions/isPrime.md +6 -0
- package/docs/reference/functions/isZero.md +6 -0
- package/docs/reference/functions/kldivergence.md +6 -0
- package/docs/reference/functions/kron.md +6 -0
- package/docs/reference/functions/larger.md +6 -0
- package/docs/reference/functions/largerEq.md +6 -0
- package/docs/reference/functions/lcm.md +6 -0
- package/docs/reference/functions/leafCount.md +52 -0
- package/docs/reference/functions/leftShift.md +6 -0
- package/docs/reference/functions/log.md +6 -0
- package/docs/reference/functions/log10.md +6 -0
- package/docs/reference/functions/log1p.md +6 -0
- package/docs/reference/functions/log2.md +6 -0
- package/docs/reference/functions/lsolve.md +6 -0
- package/docs/reference/functions/lsolveAll.md +6 -0
- package/docs/reference/functions/lup.md +6 -0
- package/docs/reference/functions/lusolve.md +6 -0
- package/docs/reference/functions/mad.md +6 -0
- package/docs/reference/functions/map.md +28 -5
- package/docs/reference/functions/matrixFromColumns.md +6 -0
- package/docs/reference/functions/matrixFromFunction.md +6 -0
- package/docs/reference/functions/matrixFromRows.md +6 -0
- package/docs/reference/functions/max.md +6 -0
- package/docs/reference/functions/mean.md +6 -0
- package/docs/reference/functions/median.md +6 -0
- package/docs/reference/functions/min.md +6 -0
- package/docs/reference/functions/mod.md +6 -0
- package/docs/reference/functions/mode.md +6 -0
- package/docs/reference/functions/multinomial.md +6 -0
- package/docs/reference/functions/multiply.md +6 -0
- package/docs/reference/functions/norm.md +6 -0
- package/docs/reference/functions/not.md +6 -0
- package/docs/reference/functions/nthRoot.md +6 -0
- package/docs/reference/functions/nthRoots.md +6 -0
- package/docs/reference/functions/numeric.md +6 -0
- package/docs/reference/functions/oct.md +6 -0
- package/docs/reference/functions/ones.md +6 -0
- package/docs/reference/functions/or.md +6 -0
- package/docs/reference/functions/parser.md +6 -0
- package/docs/reference/functions/partitionSelect.md +6 -0
- package/docs/reference/functions/permutations.md +6 -0
- package/docs/reference/functions/pickRandom.md +6 -0
- package/docs/reference/functions/pow.md +6 -0
- package/docs/reference/functions/print.md +6 -0
- package/docs/reference/functions/prod.md +6 -0
- package/docs/reference/functions/qr.md +6 -0
- package/docs/reference/functions/quantileSeq.md +6 -0
- package/docs/reference/functions/random.md +6 -0
- package/docs/reference/functions/randomInt.md +6 -0
- package/docs/reference/functions/range.md +6 -0
- package/docs/reference/functions/rationalize.md +7 -1
- package/docs/reference/functions/re.md +6 -0
- package/docs/reference/functions/reshape.md +7 -0
- package/docs/reference/functions/resize.md +6 -0
- package/docs/reference/functions/resolve.md +46 -0
- package/docs/reference/functions/rightArithShift.md +6 -0
- package/docs/reference/functions/rightLogShift.md +6 -0
- package/docs/reference/functions/rotate.md +6 -0
- package/docs/reference/functions/rotationMatrix.md +6 -0
- package/docs/reference/functions/round.md +6 -0
- package/docs/reference/functions/row.md +6 -0
- package/docs/reference/functions/sec.md +6 -0
- package/docs/reference/functions/sech.md +6 -0
- package/docs/reference/functions/setCartesian.md +6 -0
- package/docs/reference/functions/setDifference.md +6 -0
- package/docs/reference/functions/setDistinct.md +6 -0
- package/docs/reference/functions/setIntersect.md +6 -0
- package/docs/reference/functions/setIsSubset.md +6 -0
- package/docs/reference/functions/setMultiplicity.md +6 -0
- package/docs/reference/functions/setPowerset.md +6 -0
- package/docs/reference/functions/setSize.md +6 -0
- package/docs/reference/functions/setSymDifference.md +6 -0
- package/docs/reference/functions/setUnion.md +6 -0
- package/docs/reference/functions/sign.md +6 -0
- package/docs/reference/functions/simplify.md +47 -7
- package/docs/reference/functions/simplifyCore.md +50 -0
- package/docs/reference/functions/sin.md +6 -0
- package/docs/reference/functions/sinh.md +6 -0
- package/docs/reference/functions/size.md +6 -0
- package/docs/reference/functions/slu.md +6 -0
- package/docs/reference/functions/smaller.md +6 -0
- package/docs/reference/functions/smallerEq.md +6 -0
- package/docs/reference/functions/sort.md +6 -0
- package/docs/reference/functions/sqrt.md +6 -0
- package/docs/reference/functions/sqrtm.md +6 -0
- package/docs/reference/functions/square.md +6 -0
- package/docs/reference/functions/squeeze.md +6 -0
- package/docs/reference/functions/std.md +6 -0
- package/docs/reference/functions/stirlingS2.md +6 -0
- package/docs/reference/functions/subset.md +16 -2
- package/docs/reference/functions/subtract.md +6 -0
- package/docs/reference/functions/sum.md +6 -0
- package/docs/reference/functions/symbolicEqual.md +62 -0
- package/docs/reference/functions/tan.md +6 -0
- package/docs/reference/functions/tanh.md +6 -0
- package/docs/reference/functions/to.md +6 -0
- package/docs/reference/functions/trace.md +6 -0
- package/docs/reference/functions/transpose.md +6 -0
- package/docs/reference/functions/typeOf.md +6 -0
- package/docs/reference/functions/unaryMinus.md +6 -0
- package/docs/reference/functions/unaryPlus.md +6 -0
- package/docs/reference/functions/unequal.md +6 -0
- package/docs/reference/functions/usolve.md +6 -0
- package/docs/reference/functions/usolveAll.md +6 -0
- package/docs/reference/functions/variance.md +6 -0
- package/docs/reference/functions/xgcd.md +6 -0
- package/docs/reference/functions/xor.md +6 -0
- package/docs/reference/functions/zeros.md +6 -0
- package/docs/reference/functions.md +5 -1
- package/lib/browser/math.js +6 -6
- package/lib/browser/math.js.map +1 -1
- package/lib/cjs/core/create.js +4 -4
- package/lib/cjs/core/function/import.js +3 -3
- package/lib/cjs/core/function/typed.js +2 -2
- package/lib/cjs/defaultInstance.js +3 -3
- package/lib/cjs/entry/allFactoriesAny.js +1 -1
- package/lib/cjs/entry/allFactoriesNumber.js +1 -1
- package/lib/cjs/entry/configReadonly.js +1 -1
- package/lib/cjs/entry/dependenciesAny/dependenciesLeafCount.generated.js +23 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesRationalize.generated.js +3 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesResolve.generated.js +32 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesSimplify.generated.js +6 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesSimplifyCore.generated.js +65 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesSymbolicEqual.generated.js +29 -0
- package/lib/cjs/entry/dependenciesAny.generated.js +32 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesRationalize.generated.js +3 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesResolve.generated.js +32 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesSimplify.generated.js +6 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesSimplifyCore.generated.js +65 -0
- package/lib/cjs/entry/dependenciesNumber.generated.js +16 -0
- package/lib/cjs/entry/impureFunctionsAny.generated.js +80 -34
- package/lib/cjs/entry/impureFunctionsNumber.generated.js +96 -64
- package/lib/cjs/entry/pureFunctionsAny.generated.js +62 -64
- package/lib/cjs/entry/pureFunctionsNumber.generated.js +46 -48
- package/lib/cjs/expression/Help.js +4 -0
- package/lib/cjs/expression/Parser.js +1 -1
- package/lib/cjs/expression/embeddedDocs/core/typed.js +1 -1
- package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +247 -235
- package/lib/cjs/expression/embeddedDocs/function/algebra/leafCount.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/algebra/resolve.js +16 -0
- package/lib/cjs/expression/embeddedDocs/function/algebra/simplify.js +1 -1
- package/lib/cjs/expression/embeddedDocs/function/algebra/simplifyCore.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/algebra/symbolicEqual.js +15 -0
- package/lib/cjs/expression/embeddedDocs/function/matrix/subset.js +2 -2
- package/lib/cjs/expression/node/FunctionNode.js +80 -61
- package/lib/cjs/expression/node/IndexNode.js +1 -1
- package/lib/cjs/expression/node/Node.js +3 -3
- package/lib/cjs/expression/node/ObjectNode.js +1 -1
- package/lib/cjs/expression/node/utils/access.js +1 -1
- package/lib/cjs/expression/node/utils/assign.js +1 -1
- package/lib/cjs/expression/parse.js +13 -13
- package/lib/cjs/factoriesAny.js +32 -0
- package/lib/cjs/factoriesNumber.js +16 -0
- package/lib/cjs/function/algebra/decomposition/qr.js +1 -1
- package/lib/cjs/function/algebra/leafCount.js +66 -0
- package/lib/cjs/function/algebra/rationalize.js +24 -41
- package/lib/cjs/function/algebra/resolve.js +106 -0
- package/lib/cjs/function/algebra/simplify/simplifyConstant.js +5 -5
- package/lib/cjs/function/algebra/simplify/util.js +171 -33
- package/lib/cjs/function/algebra/simplify.js +588 -211
- package/lib/cjs/function/algebra/{simplify/simplifyCore.js → simplifyCore.js} +67 -43
- package/lib/cjs/function/algebra/solver/lsolveAll.js +2 -2
- package/lib/cjs/function/algebra/solver/usolveAll.js +2 -2
- package/lib/cjs/function/algebra/symbolicEqual.js +88 -0
- package/lib/cjs/function/arithmetic/ceil.js +3 -3
- package/lib/cjs/function/arithmetic/floor.js +3 -3
- package/lib/cjs/function/arithmetic/invmod.js +1 -1
- package/lib/cjs/function/arithmetic/norm.js +1 -1
- package/lib/cjs/function/arithmetic/round.js +1 -1
- package/lib/cjs/function/matrix/eigs/complexEigs.js +13 -11
- package/lib/cjs/function/matrix/map.js +53 -15
- package/lib/cjs/function/matrix/matrixFromColumns.js +1 -1
- package/lib/cjs/function/matrix/matrixFromRows.js +1 -1
- package/lib/cjs/function/matrix/subset.js +15 -5
- package/lib/cjs/function/probability/util/seededRNG.js +2 -2
- package/lib/cjs/function/relational/compareNatural.js +6 -6
- package/lib/cjs/header.js +2 -2
- package/lib/cjs/plain/bignumber/index.js +1 -1
- package/lib/cjs/plain/number/combinations.js +18 -6
- package/lib/cjs/type/bignumber/BigNumber.js +2 -2
- package/lib/cjs/type/bignumber/function/bignumber.js +1 -1
- package/lib/cjs/type/boolean.js +2 -2
- package/lib/cjs/type/complex/Complex.js +14 -14
- package/lib/cjs/type/complex/function/complex.js +1 -1
- package/lib/cjs/type/fraction/Fraction.js +6 -6
- package/lib/cjs/type/fraction/function/fraction.js +1 -1
- package/lib/cjs/type/matrix/DenseMatrix.js +5 -5
- package/lib/cjs/type/matrix/SparseMatrix.js +2 -2
- package/lib/cjs/type/number.js +1 -1
- package/lib/cjs/type/string.js +2 -2
- package/lib/cjs/type/unit/Unit.js +8 -8
- package/lib/cjs/utils/customs.js +2 -2
- package/lib/cjs/utils/emitter.js +1 -1
- package/lib/cjs/utils/function.js +2 -2
- package/lib/cjs/utils/is.js +6 -6
- package/lib/cjs/utils/latex.js +3 -3
- package/lib/cjs/utils/lruQueue.js +1 -1
- package/lib/cjs/utils/map.js +3 -3
- package/lib/cjs/utils/object.js +2 -2
- package/lib/cjs/utils/snapshot.js +7 -7
- package/lib/cjs/utils/string.js +2 -2
- package/lib/cjs/version.js +1 -1
- package/lib/esm/entry/dependenciesAny/dependenciesLeafCount.generated.js +12 -0
- package/lib/esm/entry/dependenciesAny/dependenciesRationalize.generated.js +2 -0
- package/lib/esm/entry/dependenciesAny/dependenciesResolve.generated.js +18 -0
- package/lib/esm/entry/dependenciesAny/dependenciesSimplify.generated.js +4 -0
- package/lib/esm/entry/dependenciesAny/dependenciesSimplifyCore.generated.js +40 -0
- package/lib/esm/entry/dependenciesAny/dependenciesSymbolicEqual.generated.js +16 -0
- package/lib/esm/entry/dependenciesAny.generated.js +4 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesRationalize.generated.js +2 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesResolve.generated.js +18 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesSimplify.generated.js +4 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesSimplifyCore.generated.js +40 -0
- package/lib/esm/entry/dependenciesNumber.generated.js +2 -0
- package/lib/esm/entry/impureFunctionsAny.generated.js +69 -27
- package/lib/esm/entry/impureFunctionsNumber.generated.js +83 -53
- package/lib/esm/entry/pureFunctionsAny.generated.js +49 -49
- package/lib/esm/entry/pureFunctionsNumber.generated.js +32 -32
- package/lib/esm/expression/Help.js +4 -0
- package/lib/esm/expression/embeddedDocs/core/typed.js +1 -1
- package/lib/esm/expression/embeddedDocs/embeddedDocs.js +220 -212
- package/lib/esm/expression/embeddedDocs/function/algebra/leafCount.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/algebra/resolve.js +9 -0
- package/lib/esm/expression/embeddedDocs/function/algebra/simplify.js +1 -1
- package/lib/esm/expression/embeddedDocs/function/algebra/simplifyCore.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/algebra/symbolicEqual.js +8 -0
- package/lib/esm/expression/embeddedDocs/function/matrix/subset.js +2 -2
- package/lib/esm/expression/node/FunctionNode.js +70 -53
- package/lib/esm/factoriesAny.js +4 -0
- package/lib/esm/factoriesNumber.js +2 -0
- package/lib/esm/function/algebra/leafCount.js +59 -0
- package/lib/esm/function/algebra/rationalize.js +24 -40
- package/lib/esm/function/algebra/resolve.js +95 -0
- package/lib/esm/function/algebra/simplify/simplifyConstant.js +3 -3
- package/lib/esm/function/algebra/simplify/util.js +170 -34
- package/lib/esm/function/algebra/simplify.js +583 -206
- package/lib/esm/function/algebra/{simplify/simplifyCore.js → simplifyCore.js} +60 -44
- package/lib/esm/function/algebra/symbolicEqual.js +80 -0
- package/lib/esm/function/matrix/eigs/complexEigs.js +8 -6
- package/lib/esm/function/matrix/map.js +53 -15
- package/lib/esm/function/matrix/subset.js +15 -5
- package/lib/esm/plain/number/combinations.js +18 -6
- package/lib/esm/version.js +1 -1
- package/package.json +20 -15
- package/types/index.d.ts +52 -10
- package/lib/cjs/function/algebra/simplify/resolve.js +0 -76
- package/lib/esm/function/algebra/simplify/resolve.js +0 -67
|
@@ -15,18 +15,14 @@ var _factory = require("../../utils/factory.js");
|
|
|
15
15
|
|
|
16
16
|
var _util = require("./simplify/util.js");
|
|
17
17
|
|
|
18
|
-
var _simplifyCore = require("./simplify/simplifyCore.js");
|
|
19
|
-
|
|
20
18
|
var _simplifyConstant = require("./simplify/simplifyConstant.js");
|
|
21
19
|
|
|
22
|
-
var _resolve = require("./simplify/resolve.js");
|
|
23
|
-
|
|
24
20
|
var _object = require("../../utils/object.js");
|
|
25
21
|
|
|
26
22
|
var _map = require("../../utils/map.js");
|
|
27
23
|
|
|
28
24
|
var name = 'simplify';
|
|
29
|
-
var dependencies = ['config', 'typed', 'parse', 'add', 'subtract', 'multiply', 'divide', 'pow', 'isZero', 'equal', '?fraction', '?bignumber', 'mathWithTransform', 'matrix', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'ParenthesisNode', 'SymbolNode'];
|
|
25
|
+
var dependencies = ['config', 'typed', 'parse', 'add', 'subtract', 'multiply', 'divide', 'pow', 'isZero', 'equal', 'resolve', 'simplifyCore', '?fraction', '?bignumber', 'mathWithTransform', 'matrix', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'ParenthesisNode', 'SymbolNode'];
|
|
30
26
|
var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
|
|
31
27
|
var config = _ref.config,
|
|
32
28
|
typed = _ref.typed,
|
|
@@ -38,6 +34,8 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
38
34
|
pow = _ref.pow,
|
|
39
35
|
isZero = _ref.isZero,
|
|
40
36
|
equal = _ref.equal,
|
|
37
|
+
resolve = _ref.resolve,
|
|
38
|
+
simplifyCore = _ref.simplifyCore,
|
|
41
39
|
fraction = _ref.fraction,
|
|
42
40
|
bignumber = _ref.bignumber,
|
|
43
41
|
mathWithTransform = _ref.mathWithTransform,
|
|
@@ -67,41 +65,23 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
67
65
|
OperatorNode: OperatorNode,
|
|
68
66
|
SymbolNode: SymbolNode
|
|
69
67
|
});
|
|
70
|
-
var simplifyCore = (0, _simplifyCore.createSimplifyCore)({
|
|
71
|
-
equal: equal,
|
|
72
|
-
isZero: isZero,
|
|
73
|
-
add: add,
|
|
74
|
-
subtract: subtract,
|
|
75
|
-
multiply: multiply,
|
|
76
|
-
divide: divide,
|
|
77
|
-
pow: pow,
|
|
78
|
-
AccessorNode: AccessorNode,
|
|
79
|
-
ArrayNode: ArrayNode,
|
|
80
|
-
ConstantNode: ConstantNode,
|
|
81
|
-
FunctionNode: FunctionNode,
|
|
82
|
-
IndexNode: IndexNode,
|
|
83
|
-
ObjectNode: ObjectNode,
|
|
84
|
-
OperatorNode: OperatorNode,
|
|
85
|
-
ParenthesisNode: ParenthesisNode
|
|
86
|
-
});
|
|
87
|
-
var resolve = (0, _resolve.createResolve)({
|
|
88
|
-
parse: parse,
|
|
89
|
-
FunctionNode: FunctionNode,
|
|
90
|
-
OperatorNode: OperatorNode,
|
|
91
|
-
ParenthesisNode: ParenthesisNode
|
|
92
|
-
});
|
|
93
68
|
|
|
94
69
|
var _createUtil = (0, _util.createUtil)({
|
|
95
70
|
FunctionNode: FunctionNode,
|
|
96
71
|
OperatorNode: OperatorNode,
|
|
97
72
|
SymbolNode: SymbolNode
|
|
98
73
|
}),
|
|
74
|
+
hasProperty = _createUtil.hasProperty,
|
|
99
75
|
isCommutative = _createUtil.isCommutative,
|
|
100
76
|
isAssociative = _createUtil.isAssociative,
|
|
77
|
+
mergeContext = _createUtil.mergeContext,
|
|
101
78
|
flatten = _createUtil.flatten,
|
|
102
79
|
unflattenr = _createUtil.unflattenr,
|
|
103
80
|
unflattenl = _createUtil.unflattenl,
|
|
104
|
-
createMakeNodeFunction = _createUtil.createMakeNodeFunction
|
|
81
|
+
createMakeNodeFunction = _createUtil.createMakeNodeFunction,
|
|
82
|
+
defaultContext = _createUtil.defaultContext,
|
|
83
|
+
realContext = _createUtil.realContext,
|
|
84
|
+
positiveContext = _createUtil.positiveContext;
|
|
105
85
|
/**
|
|
106
86
|
* Simplify an expression tree.
|
|
107
87
|
*
|
|
@@ -132,17 +112,49 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
132
112
|
* The default list of rules is exposed on the function as `simplify.rules`
|
|
133
113
|
* and can be used as a basis to built a set of custom rules.
|
|
134
114
|
*
|
|
115
|
+
* To specify a rule as a string, separate the left and right pattern by '->'
|
|
116
|
+
* When specifying a rule as an object, the following keys are meaningful:
|
|
117
|
+
* - l - the left pattern
|
|
118
|
+
* - r - the right pattern
|
|
119
|
+
* - s - in lieu of l and r, the string form that is broken at -> to give them
|
|
120
|
+
* - repeat - whether to repeat this rule until the expression stabilizes
|
|
121
|
+
* - assuming - gives a context object, as in the 'context' option to
|
|
122
|
+
* simplify. Every property in the context object must match the current
|
|
123
|
+
* context in order, or else the rule will not be applied.
|
|
124
|
+
* - imposeContext - gives a context object, as in the 'context' option to
|
|
125
|
+
* simplify. Any settings specified will override the incoming context
|
|
126
|
+
* for all matches of this rule.
|
|
127
|
+
*
|
|
135
128
|
* For more details on the theory, see:
|
|
136
129
|
*
|
|
137
130
|
* - [Strategies for simplifying math expressions (Stackoverflow)](https://stackoverflow.com/questions/7540227/strategies-for-simplifying-math-expressions)
|
|
138
131
|
* - [Symbolic computation - Simplification (Wikipedia)](https://en.wikipedia.org/wiki/Symbolic_computation#Simplification)
|
|
139
132
|
*
|
|
140
133
|
* An optional `options` argument can be passed as last argument of `simplify`.
|
|
141
|
-
*
|
|
142
|
-
* - `
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
134
|
+
* Currently available options (defaults in parentheses):
|
|
135
|
+
* - `consoleDebug` (false): whether to write the expression being simplified
|
|
136
|
+
* and any changes to it, along with the rule responsible, to console
|
|
137
|
+
* - `context` (simplify.defaultContext): an object giving properties of
|
|
138
|
+
* each operator, which determine what simplifications are allowed. The
|
|
139
|
+
* currently meaningful properties are commutative, associative,
|
|
140
|
+
* total (whether the operation is defined for all arguments), and
|
|
141
|
+
* trivial (whether the operation applied to a single argument leaves
|
|
142
|
+
* that argument unchanged). The default context is very permissive and
|
|
143
|
+
* allows almost all simplifications. Only properties differing from
|
|
144
|
+
* the default need to be specified; the default context is used as a
|
|
145
|
+
* fallback. Additional contexts `simplify.realContext` and
|
|
146
|
+
* `simplify.positiveContext` are supplied to cause simplify to perform
|
|
147
|
+
* just simplifications guaranteed to preserve all values of the expression
|
|
148
|
+
* assuming all variables and subexpressions are real numbers or
|
|
149
|
+
* positive real numbers, respectively. (Note that these are in some cases
|
|
150
|
+
* more restrictive than the default context; for example, the default
|
|
151
|
+
* context will allow `x/x` to simplify to 1, whereas
|
|
152
|
+
* `simplify.realContext` will not, as `0/0` is not equal to 1.)
|
|
153
|
+
* - `exactFractions` (true): whether to try to convert all constants to
|
|
154
|
+
* exact rational numbers.
|
|
155
|
+
* - `fractionsLimit` (10000): when `exactFractions` is true, constants will
|
|
156
|
+
* be expressed as fractions only when both numerator and denominator
|
|
157
|
+
* are smaller than `fractionsLimit`.
|
|
146
158
|
*
|
|
147
159
|
* Syntax:
|
|
148
160
|
*
|
|
@@ -165,7 +177,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
165
177
|
*
|
|
166
178
|
* See also:
|
|
167
179
|
*
|
|
168
|
-
* derivative, parse,
|
|
180
|
+
* simplifyCore, derivative, evaluate, parse, rationalize, resolve
|
|
169
181
|
*
|
|
170
182
|
* @param {Node | string} expr
|
|
171
183
|
* The expression to be simplified
|
|
@@ -213,7 +225,8 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
213
225
|
return this(expr, rules, (0, _map.createMap)(scope), options);
|
|
214
226
|
},
|
|
215
227
|
'Node, Array, Map, Object': function NodeArrayMapObject(expr, rules, scope, options) {
|
|
216
|
-
|
|
228
|
+
var debug = options.consoleDebug;
|
|
229
|
+
rules = _buildRules(rules, options.context);
|
|
217
230
|
var res = resolve(expr, scope);
|
|
218
231
|
res = removeParens(res);
|
|
219
232
|
var visited = {};
|
|
@@ -225,15 +238,40 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
225
238
|
visited[str] = true;
|
|
226
239
|
_lastsym = 0; // counter for placeholder symbols
|
|
227
240
|
|
|
241
|
+
var laststr = str;
|
|
242
|
+
if (debug) console.log('Working on: ', str);
|
|
243
|
+
|
|
228
244
|
for (var i = 0; i < rules.length; i++) {
|
|
245
|
+
var rulestr = '';
|
|
246
|
+
|
|
229
247
|
if (typeof rules[i] === 'function') {
|
|
230
248
|
res = rules[i](res, options);
|
|
249
|
+
if (debug) rulestr = rules[i].name;
|
|
231
250
|
} else {
|
|
232
|
-
flatten(res);
|
|
233
|
-
res = applyRule(res, rules[i]);
|
|
251
|
+
flatten(res, options.context);
|
|
252
|
+
res = applyRule(res, rules[i], options.context);
|
|
253
|
+
|
|
254
|
+
if (debug) {
|
|
255
|
+
rulestr = "".concat(rules[i].l.toString(), " -> ").concat(rules[i].r.toString());
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (debug) {
|
|
260
|
+
var newstr = res.toString({
|
|
261
|
+
parenthesis: 'all'
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
if (newstr !== laststr) {
|
|
265
|
+
console.log('Applying', rulestr, 'produced', newstr);
|
|
266
|
+
laststr = newstr;
|
|
267
|
+
}
|
|
234
268
|
}
|
|
269
|
+
/* Use left-heavy binary tree internally,
|
|
270
|
+
* since custom rule functions may expect it
|
|
271
|
+
*/
|
|
235
272
|
|
|
236
|
-
|
|
273
|
+
|
|
274
|
+
unflattenl(res, options.context);
|
|
237
275
|
}
|
|
238
276
|
|
|
239
277
|
str = res.toString({
|
|
@@ -244,8 +282,9 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
244
282
|
return res;
|
|
245
283
|
}
|
|
246
284
|
});
|
|
247
|
-
simplify.
|
|
248
|
-
simplify.
|
|
285
|
+
simplify.defaultContext = defaultContext;
|
|
286
|
+
simplify.realContext = realContext;
|
|
287
|
+
simplify.positiveContext = positiveContext;
|
|
249
288
|
|
|
250
289
|
function removeParens(node) {
|
|
251
290
|
return node.transform(function (node, path, parent) {
|
|
@@ -255,8 +294,8 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
255
294
|
|
|
256
295
|
|
|
257
296
|
var SUPPORTED_CONSTANTS = {
|
|
258
|
-
|
|
259
|
-
|
|
297
|
+
true: true,
|
|
298
|
+
false: true,
|
|
260
299
|
e: true,
|
|
261
300
|
i: true,
|
|
262
301
|
Infinity: true,
|
|
@@ -297,52 +336,155 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
297
336
|
// Note initially we tend constants to the right because like-term
|
|
298
337
|
// collection prefers the left, and we would rather collect nonconstants
|
|
299
338
|
{
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
{
|
|
339
|
+
s: 'n-n1 -> n+-n1',
|
|
340
|
+
// temporarily replace 'subtract' so we can further flatten the 'add' operator
|
|
341
|
+
assuming: {
|
|
342
|
+
subtract: {
|
|
343
|
+
total: true
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}, {
|
|
347
|
+
s: 'n-n -> 0',
|
|
348
|
+
// partial alternative when we can't always subtract
|
|
349
|
+
assuming: {
|
|
350
|
+
subtract: {
|
|
351
|
+
total: false
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}, {
|
|
355
|
+
s: '-(c*v) -> v * (-c)',
|
|
356
|
+
// make non-constant terms positive
|
|
357
|
+
assuming: {
|
|
358
|
+
multiply: {
|
|
359
|
+
commutative: true
|
|
360
|
+
},
|
|
361
|
+
subtract: {
|
|
362
|
+
total: true
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}, {
|
|
366
|
+
s: '-(c*v) -> (-c) * v',
|
|
367
|
+
// non-commutative version, part 1
|
|
368
|
+
assuming: {
|
|
369
|
+
multiply: {
|
|
370
|
+
commutative: false
|
|
371
|
+
},
|
|
372
|
+
subtract: {
|
|
373
|
+
total: true
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}, {
|
|
377
|
+
s: '-(v*c) -> v * (-c)',
|
|
378
|
+
// non-commutative version, part 2
|
|
379
|
+
assuming: {
|
|
380
|
+
multiply: {
|
|
381
|
+
commutative: false
|
|
382
|
+
},
|
|
383
|
+
subtract: {
|
|
384
|
+
total: true
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}, {
|
|
388
|
+
l: '-(n1/n2)',
|
|
389
|
+
r: '-n1/n2'
|
|
390
|
+
}, {
|
|
308
391
|
l: '-v',
|
|
309
392
|
r: 'v * (-1)'
|
|
310
|
-
},
|
|
393
|
+
}, // finish making non-constant terms positive
|
|
394
|
+
{
|
|
395
|
+
l: '(n1 + n2)*(-1)',
|
|
396
|
+
r: 'n1*(-1) + n2*(-1)',
|
|
397
|
+
repeat: true
|
|
398
|
+
}, // expand negations to achieve as much sign cancellation as possible
|
|
399
|
+
{
|
|
311
400
|
l: 'n/n1^n2',
|
|
312
401
|
r: 'n*n1^-n2'
|
|
313
402
|
}, // temporarily replace 'divide' so we can further flatten the 'multiply' operator
|
|
314
403
|
{
|
|
315
404
|
l: 'n/n1',
|
|
316
405
|
r: 'n*n1^-1'
|
|
317
|
-
}, // remove parenthesis in the case of negating a quantity
|
|
318
|
-
{
|
|
319
|
-
l: 'n1 + (n2 + n3)*(-1)',
|
|
320
|
-
r: 'n1 + n2*(-1) + n3*(-1)'
|
|
321
|
-
}, // subsume resulting -1 into constants where possible
|
|
322
|
-
{
|
|
323
|
-
l: '(-1) * c',
|
|
324
|
-
r: '-c'
|
|
325
406
|
}, {
|
|
326
|
-
|
|
327
|
-
|
|
407
|
+
s: '(n1*n2)^n3 -> n1^n3 * n2^n3',
|
|
408
|
+
assuming: {
|
|
409
|
+
multiply: {
|
|
410
|
+
commutative: true
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}, {
|
|
414
|
+
s: '(n1*n2)^(-1) -> n2^(-1) * n1^(-1)',
|
|
415
|
+
assuming: {
|
|
416
|
+
multiply: {
|
|
417
|
+
commutative: false
|
|
418
|
+
}
|
|
419
|
+
}
|
|
328
420
|
}, // expand nested exponentiation
|
|
329
421
|
{
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
422
|
+
s: '(n ^ n1) ^ n2 -> n ^ (n1 * n2)',
|
|
423
|
+
assuming: {
|
|
424
|
+
divide: {
|
|
425
|
+
total: true
|
|
426
|
+
}
|
|
427
|
+
} // 1/(1/n) = n needs 1/n to exist
|
|
428
|
+
|
|
429
|
+
}, // collect like factors; into a sum, only do this for nonconstants
|
|
333
430
|
{
|
|
431
|
+
l: ' v * ( v * n1 + n2)',
|
|
432
|
+
r: 'v^2 * n1 + v * n2'
|
|
433
|
+
}, {
|
|
434
|
+
s: ' v * (v^n4 * n1 + n2) -> v^(1+n4) * n1 + v * n2',
|
|
435
|
+
assuming: {
|
|
436
|
+
divide: {
|
|
437
|
+
total: true
|
|
438
|
+
}
|
|
439
|
+
} // v*1/v = v^(1+-1) needs 1/v
|
|
440
|
+
|
|
441
|
+
}, {
|
|
442
|
+
s: 'v^n3 * ( v * n1 + n2) -> v^(n3+1) * n1 + v^n3 * n2',
|
|
443
|
+
assuming: {
|
|
444
|
+
divide: {
|
|
445
|
+
total: true
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}, {
|
|
449
|
+
s: 'v^n3 * (v^n4 * n1 + n2) -> v^(n3+n4) * n1 + v^n3 * n2',
|
|
450
|
+
assuming: {
|
|
451
|
+
divide: {
|
|
452
|
+
total: true
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}, {
|
|
334
456
|
l: 'n*n',
|
|
335
457
|
r: 'n^2'
|
|
336
458
|
}, {
|
|
337
|
-
|
|
338
|
-
|
|
459
|
+
s: 'n * n^n1 -> n^(n1+1)',
|
|
460
|
+
assuming: {
|
|
461
|
+
divide: {
|
|
462
|
+
total: true
|
|
463
|
+
}
|
|
464
|
+
} // n*1/n = n^(-1+1) needs 1/n
|
|
465
|
+
|
|
339
466
|
}, {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
467
|
+
s: 'n^n1 * n^n2 -> n^(n1+n2)',
|
|
468
|
+
assuming: {
|
|
469
|
+
divide: {
|
|
470
|
+
total: true
|
|
471
|
+
}
|
|
472
|
+
} // ditto for n^2*1/n^2
|
|
473
|
+
|
|
474
|
+
}, // Unfortunately, to deal with more complicated cancellations, it
|
|
475
|
+
// becomes necessary to simplify constants twice per pass. It's not
|
|
476
|
+
// terribly expensive compared to matching rules, so this should not
|
|
477
|
+
// pose a performance problem.
|
|
478
|
+
simplifyConstant, // First: before collecting like terms
|
|
479
|
+
// collect like terms
|
|
343
480
|
{
|
|
344
|
-
|
|
345
|
-
|
|
481
|
+
s: 'n+n -> 2*n',
|
|
482
|
+
assuming: {
|
|
483
|
+
add: {
|
|
484
|
+
total: true
|
|
485
|
+
}
|
|
486
|
+
} // 2 = 1 + 1 needs to exist
|
|
487
|
+
|
|
346
488
|
}, {
|
|
347
489
|
l: 'n+-n',
|
|
348
490
|
r: '0'
|
|
@@ -355,25 +497,91 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
355
497
|
r: 'n3*(n1+n2)'
|
|
356
498
|
}, // All sub-monomials tried there.
|
|
357
499
|
{
|
|
500
|
+
l: 'n3^(-n4)*n1 + n3 * n2',
|
|
501
|
+
r: 'n3^(-n4)*(n1 + n3^(n4+1) *n2)'
|
|
502
|
+
}, {
|
|
503
|
+
l: 'n3^(-n4)*n1 + n3^n5 * n2',
|
|
504
|
+
r: 'n3^(-n4)*(n1 + n3^(n4+n5)*n2)'
|
|
505
|
+
}, {
|
|
506
|
+
s: 'n*v + v -> (n+1)*v',
|
|
507
|
+
// noncommutative additional cases
|
|
508
|
+
assuming: {
|
|
509
|
+
multiply: {
|
|
510
|
+
commutative: false
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}, {
|
|
514
|
+
s: 'n1*n3 + n2*n3 -> (n1+n2)*n3',
|
|
515
|
+
assuming: {
|
|
516
|
+
multiply: {
|
|
517
|
+
commutative: false
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}, {
|
|
521
|
+
s: 'n1*n3^(-n4) + n2 * n3 -> (n1 + n2*n3^(n4 + 1))*n3^(-n4)',
|
|
522
|
+
assuming: {
|
|
523
|
+
multiply: {
|
|
524
|
+
commutative: false
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}, {
|
|
528
|
+
s: 'n1*n3^(-n4) + n2 * n3^n5 -> (n1 + n2*n3^(n4 + n5))*n3^(-n4)',
|
|
529
|
+
assuming: {
|
|
530
|
+
multiply: {
|
|
531
|
+
commutative: false
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}, {
|
|
358
535
|
l: 'n*c + c',
|
|
359
536
|
r: '(n+1)*c'
|
|
360
|
-
},
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
537
|
+
}, {
|
|
538
|
+
s: 'c*n + c -> c*(n+1)',
|
|
539
|
+
assuming: {
|
|
540
|
+
multiply: {
|
|
541
|
+
commutative: false
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}, simplifyConstant, // Second: before returning expressions to "standard form"
|
|
545
|
+
// make factors positive (and undo 'make non-constant terms positive')
|
|
365
546
|
{
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
547
|
+
s: '(-n)*n1 -> -(n*n1)',
|
|
548
|
+
assuming: {
|
|
549
|
+
subtract: {
|
|
550
|
+
total: true
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}, {
|
|
554
|
+
s: 'n1*(-n) -> -(n1*n)',
|
|
555
|
+
// in case * non-commutative
|
|
556
|
+
assuming: {
|
|
557
|
+
subtract: {
|
|
558
|
+
total: true
|
|
559
|
+
},
|
|
560
|
+
multiply: {
|
|
561
|
+
commutative: false
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}, // final ordering of constants
|
|
565
|
+
{
|
|
566
|
+
s: 'c+v -> v+c',
|
|
567
|
+
assuming: {
|
|
568
|
+
add: {
|
|
569
|
+
commutative: true
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
imposeContext: {
|
|
369
573
|
add: {
|
|
370
574
|
commutative: false
|
|
371
575
|
}
|
|
372
576
|
}
|
|
373
577
|
}, {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
578
|
+
s: 'v*c -> c*v',
|
|
579
|
+
assuming: {
|
|
580
|
+
multiply: {
|
|
581
|
+
commutative: true
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
imposeContext: {
|
|
377
585
|
multiply: {
|
|
378
586
|
commutative: false
|
|
379
587
|
}
|
|
@@ -385,36 +593,127 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
385
593
|
r: 'n-n1'
|
|
386
594
|
}, // undo replace 'subtract'
|
|
387
595
|
{
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
596
|
+
s: 'n*(n1^-1) -> n/n1',
|
|
597
|
+
// undo replace 'divide'; for * commutative
|
|
598
|
+
assuming: {
|
|
599
|
+
multiply: {
|
|
600
|
+
commutative: true
|
|
601
|
+
}
|
|
602
|
+
} // o.w. / not conventional
|
|
603
|
+
|
|
394
604
|
}, {
|
|
395
|
-
|
|
396
|
-
|
|
605
|
+
s: 'n*n1^-n2 -> n/n1^n2',
|
|
606
|
+
assuming: {
|
|
607
|
+
multiply: {
|
|
608
|
+
commutative: true
|
|
609
|
+
}
|
|
610
|
+
} // o.w. / not conventional
|
|
611
|
+
|
|
397
612
|
}, {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
613
|
+
s: 'n^-1 -> 1/n',
|
|
614
|
+
assuming: {
|
|
615
|
+
multiply: {
|
|
616
|
+
commutative: true
|
|
617
|
+
}
|
|
618
|
+
} // o.w. / not conventional
|
|
619
|
+
|
|
620
|
+
}, {
|
|
621
|
+
l: 'n^1',
|
|
622
|
+
r: 'n'
|
|
623
|
+
}, // can be produced by power cancellation
|
|
401
624
|
{
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
625
|
+
s: 'n*(n1/n2) -> (n*n1)/n2',
|
|
626
|
+
// '*' before '/'
|
|
627
|
+
assuming: {
|
|
628
|
+
multiply: {
|
|
629
|
+
associative: true
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}, {
|
|
633
|
+
s: 'n-(n1+n2) -> n-n1-n2',
|
|
634
|
+
// '-' before '+'
|
|
635
|
+
assuming: {
|
|
636
|
+
addition: {
|
|
637
|
+
associative: true,
|
|
638
|
+
commutative: true
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}, // { l: '(n1/n2)/n3', r: 'n1/(n2*n3)' },
|
|
406
642
|
// { l: '(n*n1)/(n*n2)', r: 'n1/n2' },
|
|
643
|
+
// simplifyConstant can leave an extra factor of 1, which can always
|
|
644
|
+
// be eliminated, since the identity always commutes
|
|
407
645
|
{
|
|
408
646
|
l: '1*n',
|
|
409
|
-
r: 'n'
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
647
|
+
r: 'n',
|
|
648
|
+
imposeContext: {
|
|
649
|
+
multiply: {
|
|
650
|
+
commutative: true
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}, {
|
|
654
|
+
s: 'n1/(n2/n3) -> (n1*n3)/n2',
|
|
655
|
+
assuming: {
|
|
656
|
+
multiply: {
|
|
657
|
+
associative: true
|
|
658
|
+
}
|
|
659
|
+
}
|
|
414
660
|
}, {
|
|
415
661
|
l: 'n1/(-n2)',
|
|
416
662
|
r: '-n1/n2'
|
|
417
663
|
}];
|
|
664
|
+
/**
|
|
665
|
+
* Takes any rule object as allowed by the specification in simplify
|
|
666
|
+
* and puts it in a standard form used by applyRule
|
|
667
|
+
*/
|
|
668
|
+
|
|
669
|
+
function _canonicalizeRule(ruleObject, context) {
|
|
670
|
+
var newRule = {};
|
|
671
|
+
|
|
672
|
+
if (ruleObject.s) {
|
|
673
|
+
var lr = ruleObject.s.split('->');
|
|
674
|
+
|
|
675
|
+
if (lr.length === 2) {
|
|
676
|
+
newRule.l = lr[0];
|
|
677
|
+
newRule.r = lr[1];
|
|
678
|
+
} else {
|
|
679
|
+
throw SyntaxError('Could not parse rule: ' + ruleObject.s);
|
|
680
|
+
}
|
|
681
|
+
} else {
|
|
682
|
+
newRule.l = ruleObject.l;
|
|
683
|
+
newRule.r = ruleObject.r;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
newRule.l = removeParens(parse(newRule.l));
|
|
687
|
+
newRule.r = removeParens(parse(newRule.r));
|
|
688
|
+
|
|
689
|
+
for (var _i = 0, _arr = ['imposeContext', 'repeat', 'assuming']; _i < _arr.length; _i++) {
|
|
690
|
+
var prop = _arr[_i];
|
|
691
|
+
|
|
692
|
+
if (prop in ruleObject) {
|
|
693
|
+
newRule[prop] = ruleObject[prop];
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
if (ruleObject.evaluate) {
|
|
698
|
+
newRule.evaluate = parse(ruleObject.evaluate);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
if (isAssociative(newRule.l, context)) {
|
|
702
|
+
var makeNode = createMakeNodeFunction(newRule.l);
|
|
703
|
+
|
|
704
|
+
var expandsym = _getExpandPlaceholderSymbol();
|
|
705
|
+
|
|
706
|
+
newRule.expanded = {};
|
|
707
|
+
newRule.expanded.l = makeNode([newRule.l.clone(), expandsym]); // Push the expandsym into the deepest possible branch.
|
|
708
|
+
// This helps to match the newRule against nodes returned from getSplits() later on.
|
|
709
|
+
|
|
710
|
+
flatten(newRule.expanded.l, context);
|
|
711
|
+
unflattenr(newRule.expanded.l, context);
|
|
712
|
+
newRule.expanded.r = makeNode([newRule.r, expandsym]);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
return newRule;
|
|
716
|
+
}
|
|
418
717
|
/**
|
|
419
718
|
* Parse the string array of rules into nodes
|
|
420
719
|
*
|
|
@@ -432,60 +731,26 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
432
731
|
* 'n1 * c1 -> c1 * n1'
|
|
433
732
|
*/
|
|
434
733
|
|
|
435
|
-
|
|
734
|
+
|
|
735
|
+
function _buildRules(rules, context) {
|
|
436
736
|
// Array of rules to be used to simplify expressions
|
|
437
737
|
var ruleSet = [];
|
|
438
738
|
|
|
439
739
|
for (var i = 0; i < rules.length; i++) {
|
|
440
740
|
var rule = rules[i];
|
|
441
741
|
var newRule = void 0;
|
|
442
|
-
var ruleType = (0, _typeof2
|
|
742
|
+
var ruleType = (0, _typeof2.default)(rule);
|
|
443
743
|
|
|
444
744
|
switch (ruleType) {
|
|
445
745
|
case 'string':
|
|
446
|
-
{
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
if (lr.length === 2) {
|
|
450
|
-
rule = {
|
|
451
|
-
l: lr[0],
|
|
452
|
-
r: lr[1]
|
|
453
|
-
};
|
|
454
|
-
} else {
|
|
455
|
-
throw SyntaxError('Could not parse rule: ' + rule);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
746
|
+
rule = {
|
|
747
|
+
s: rule
|
|
748
|
+
};
|
|
458
749
|
|
|
459
750
|
/* falls through */
|
|
460
751
|
|
|
461
752
|
case 'object':
|
|
462
|
-
newRule =
|
|
463
|
-
l: removeParens(parse(rule.l)),
|
|
464
|
-
r: removeParens(parse(rule.r))
|
|
465
|
-
};
|
|
466
|
-
|
|
467
|
-
if (rule.context) {
|
|
468
|
-
newRule.context = rule.context;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
if (rule.evaluate) {
|
|
472
|
-
newRule.evaluate = parse(rule.evaluate);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
if (isAssociative(newRule.l)) {
|
|
476
|
-
var makeNode = createMakeNodeFunction(newRule.l);
|
|
477
|
-
|
|
478
|
-
var expandsym = _getExpandPlaceholderSymbol();
|
|
479
|
-
|
|
480
|
-
newRule.expanded = {};
|
|
481
|
-
newRule.expanded.l = makeNode([newRule.l.clone(), expandsym]); // Push the expandsym into the deepest possible branch.
|
|
482
|
-
// This helps to match the newRule against nodes returned from getSplits() later on.
|
|
483
|
-
|
|
484
|
-
flatten(newRule.expanded.l);
|
|
485
|
-
unflattenr(newRule.expanded.l);
|
|
486
|
-
newRule.expanded.r = makeNode([newRule.r, expandsym]);
|
|
487
|
-
}
|
|
488
|
-
|
|
753
|
+
newRule = _canonicalizeRule(rule, context);
|
|
489
754
|
break;
|
|
490
755
|
|
|
491
756
|
case 'function':
|
|
@@ -510,90 +775,155 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
510
775
|
return new SymbolNode('_p' + _lastsym++);
|
|
511
776
|
}
|
|
512
777
|
|
|
513
|
-
function mapRule(nodes, rule) {
|
|
778
|
+
function mapRule(nodes, rule, context) {
|
|
779
|
+
var resNodes = nodes;
|
|
780
|
+
|
|
514
781
|
if (nodes) {
|
|
515
782
|
for (var i = 0; i < nodes.length; ++i) {
|
|
516
|
-
|
|
783
|
+
var newNode = applyRule(nodes[i], rule, context);
|
|
784
|
+
|
|
785
|
+
if (newNode !== nodes[i]) {
|
|
786
|
+
if (resNodes === nodes) {
|
|
787
|
+
resNodes = nodes.slice();
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
resNodes[i] = newNode;
|
|
791
|
+
}
|
|
517
792
|
}
|
|
518
793
|
}
|
|
794
|
+
|
|
795
|
+
return resNodes;
|
|
519
796
|
}
|
|
520
797
|
/**
|
|
521
798
|
* Returns a simplfied form of node, or the original node if no simplification was possible.
|
|
522
799
|
*
|
|
523
800
|
* @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} node
|
|
801
|
+
* @param {Object | Function} rule
|
|
802
|
+
* @param {Object} context -- information about assumed properties of operators
|
|
524
803
|
* @return {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} The simplified form of `expr`, or the original node if no simplification was possible.
|
|
525
804
|
*/
|
|
526
805
|
|
|
527
806
|
|
|
528
|
-
|
|
529
|
-
'
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
} else if (res instanceof ParenthesisNode) {
|
|
539
|
-
if (res.content) {
|
|
540
|
-
res.content = applyRule(res.content, rule);
|
|
541
|
-
}
|
|
542
|
-
} else if (res instanceof ArrayNode) {
|
|
543
|
-
mapRule(res.items, rule);
|
|
544
|
-
} else if (res instanceof AccessorNode) {
|
|
545
|
-
if (res.object) {
|
|
546
|
-
res.object = applyRule(res.object, rule);
|
|
807
|
+
function applyRule(node, rule, context) {
|
|
808
|
+
// console.log('Entering applyRule("', rule.l.toString({parenthesis:'all'}), '->', rule.r.toString({parenthesis:'all'}), '",', node.toString({parenthesis:'all'}),')')
|
|
809
|
+
// check that the assumptions for this rule are satisfied by the current
|
|
810
|
+
// context:
|
|
811
|
+
if (rule.assuming) {
|
|
812
|
+
for (var symbol in rule.assuming) {
|
|
813
|
+
for (var property in rule.assuming[symbol]) {
|
|
814
|
+
if (hasProperty(symbol, property, context) !== rule.assuming[symbol][property]) {
|
|
815
|
+
return node;
|
|
816
|
+
}
|
|
547
817
|
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
548
820
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
821
|
+
var mergedContext = mergeContext(rule.imposeContext, context); // Do not clone node unless we find a match
|
|
822
|
+
|
|
823
|
+
var res = node; // First replace our child nodes with their simplified versions
|
|
824
|
+
// If a child could not be simplified, applying the rule to it
|
|
825
|
+
// will have no effect since the node is returned unchanged
|
|
826
|
+
|
|
827
|
+
if (res instanceof OperatorNode || res instanceof FunctionNode) {
|
|
828
|
+
var newArgs = mapRule(res.args, rule, context);
|
|
829
|
+
|
|
830
|
+
if (newArgs !== res.args) {
|
|
831
|
+
res = res.clone();
|
|
832
|
+
res.args = newArgs;
|
|
833
|
+
}
|
|
834
|
+
} else if (res instanceof ParenthesisNode) {
|
|
835
|
+
if (res.content) {
|
|
836
|
+
var newContent = applyRule(res.content, rule, context);
|
|
837
|
+
|
|
838
|
+
if (newContent !== res.content) {
|
|
839
|
+
res = new ParenthesisNode(newContent);
|
|
557
840
|
}
|
|
558
|
-
}
|
|
841
|
+
}
|
|
842
|
+
} else if (res instanceof ArrayNode) {
|
|
843
|
+
var newItems = mapRule(res.items, rule, context);
|
|
559
844
|
|
|
845
|
+
if (newItems !== res.items) {
|
|
846
|
+
res = new ArrayNode(newItems);
|
|
847
|
+
}
|
|
848
|
+
} else if (res instanceof AccessorNode) {
|
|
849
|
+
var newObj = res.object;
|
|
560
850
|
|
|
561
|
-
|
|
851
|
+
if (res.object) {
|
|
852
|
+
newObj = applyRule(res.object, rule, context);
|
|
853
|
+
}
|
|
562
854
|
|
|
563
|
-
var
|
|
564
|
-
// This allows us to match rules like 'n+n' to the expression '(1+x)+x' or even 'x+1+x' if the operator is commutative.
|
|
855
|
+
var newIndex = res.index;
|
|
565
856
|
|
|
857
|
+
if (res.index) {
|
|
858
|
+
newIndex = applyRule(res.index, rule, context);
|
|
859
|
+
}
|
|
566
860
|
|
|
567
|
-
if (
|
|
568
|
-
|
|
569
|
-
matches = _ruleMatch(rule.expanded.l, res)[0];
|
|
861
|
+
if (newObj !== res.object || newIndex !== res.index) {
|
|
862
|
+
res = new AccessorNode(newObj, newIndex);
|
|
570
863
|
}
|
|
864
|
+
} else if (res instanceof IndexNode) {
|
|
865
|
+
var newDims = mapRule(res.dimensions, rule, context);
|
|
571
866
|
|
|
572
|
-
if (
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
867
|
+
if (newDims !== res.dimensions) {
|
|
868
|
+
res = new IndexNode(newDims);
|
|
869
|
+
}
|
|
870
|
+
} else if (res instanceof ObjectNode) {
|
|
871
|
+
var changed = false;
|
|
872
|
+
var newProps = {};
|
|
578
873
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
} // Replace placeholders with their respective nodes without traversing deeper into the replaced nodes
|
|
874
|
+
for (var prop in res.properties) {
|
|
875
|
+
newProps[prop] = applyRule(res.properties[prop], rule, context);
|
|
582
876
|
|
|
877
|
+
if (newProps[prop] !== res.properties[prop]) {
|
|
878
|
+
changed = true;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
583
881
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
return matches.placeholders[node.name].clone();
|
|
587
|
-
} else {
|
|
588
|
-
return node;
|
|
589
|
-
}
|
|
590
|
-
}); // const after = res.toString({parenthesis: 'all'})
|
|
591
|
-
// console.log('Simplified ' + before + ' to ' + after)
|
|
882
|
+
if (changed) {
|
|
883
|
+
res = new ObjectNode(newProps);
|
|
592
884
|
}
|
|
885
|
+
} // Try to match a rule against this node
|
|
593
886
|
|
|
594
|
-
|
|
887
|
+
|
|
888
|
+
var repl = rule.r;
|
|
889
|
+
|
|
890
|
+
var matches = _ruleMatch(rule.l, res, mergedContext)[0]; // If the rule is associative operator, we can try matching it while allowing additional terms.
|
|
891
|
+
// This allows us to match rules like 'n+n' to the expression '(1+x)+x' or even 'x+1+x' if the operator is commutative.
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
if (!matches && rule.expanded) {
|
|
895
|
+
repl = rule.expanded.r;
|
|
896
|
+
matches = _ruleMatch(rule.expanded.l, res, mergedContext)[0];
|
|
595
897
|
}
|
|
596
|
-
|
|
898
|
+
|
|
899
|
+
if (matches) {
|
|
900
|
+
// const before = res.toString({parenthesis: 'all'})
|
|
901
|
+
// Create a new node by cloning the rhs of the matched rule
|
|
902
|
+
// we keep any implicit multiplication state if relevant
|
|
903
|
+
var implicit = res.implicit;
|
|
904
|
+
res = repl.clone();
|
|
905
|
+
|
|
906
|
+
if (implicit && 'implicit' in repl) {
|
|
907
|
+
res.implicit = true;
|
|
908
|
+
} // Replace placeholders with their respective nodes without traversing deeper into the replaced nodes
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
res = res.transform(function (node) {
|
|
912
|
+
if (node.isSymbolNode && (0, _object.hasOwnProperty)(matches.placeholders, node.name)) {
|
|
913
|
+
return matches.placeholders[node.name].clone();
|
|
914
|
+
} else {
|
|
915
|
+
return node;
|
|
916
|
+
}
|
|
917
|
+
}); // const after = res.toString({parenthesis: 'all'})
|
|
918
|
+
// console.log('Simplified ' + before + ' to ' + after)
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
if (rule.repeat && res !== node) {
|
|
922
|
+
res = applyRule(res, rule, context);
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
return res;
|
|
926
|
+
}
|
|
597
927
|
/**
|
|
598
928
|
* Get (binary) combinations of a flattened binary node
|
|
599
929
|
* e.g. +(node1, node2, node3) -> [
|
|
@@ -603,6 +933,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
603
933
|
*
|
|
604
934
|
*/
|
|
605
935
|
|
|
936
|
+
|
|
606
937
|
function getSplits(node, context) {
|
|
607
938
|
var res = [];
|
|
608
939
|
var right, rightArgs;
|
|
@@ -616,9 +947,18 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
616
947
|
res.push(makeNode([node.args[i], right]));
|
|
617
948
|
}
|
|
618
949
|
} else {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
950
|
+
// Keep order, but try all parenthesizations
|
|
951
|
+
for (var _i2 = 1; _i2 < node.args.length; _i2++) {
|
|
952
|
+
var left = node.args[0];
|
|
953
|
+
|
|
954
|
+
if (_i2 > 1) {
|
|
955
|
+
left = makeNode(node.args.slice(0, _i2));
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
rightArgs = node.args.slice(_i2);
|
|
959
|
+
right = rightArgs.length === 1 ? rightArgs[0] : makeNode(rightArgs);
|
|
960
|
+
res.push(makeNode([left, right]));
|
|
961
|
+
}
|
|
622
962
|
}
|
|
623
963
|
|
|
624
964
|
return res;
|
|
@@ -721,15 +1061,19 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
721
1061
|
*
|
|
722
1062
|
* @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} rule
|
|
723
1063
|
* @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} node
|
|
1064
|
+
* @param {Object} context -- provides assumed properties of operators
|
|
1065
|
+
* @param {Boolean} isSplit -- whether we are in process of splitting an
|
|
1066
|
+
* n-ary operator node into possible binary combinations.
|
|
1067
|
+
* Defaults to false.
|
|
724
1068
|
* @return {Object} Information about the match, if it exists.
|
|
725
1069
|
*/
|
|
726
1070
|
|
|
727
1071
|
|
|
728
|
-
function _ruleMatch(rule, node, isSplit) {
|
|
1072
|
+
function _ruleMatch(rule, node, context, isSplit) {
|
|
729
1073
|
// console.log('Entering _ruleMatch(' + JSON.stringify(rule) + ', ' + JSON.stringify(node) + ')')
|
|
730
1074
|
// console.log('rule = ' + rule)
|
|
731
1075
|
// console.log('node = ' + node)
|
|
732
|
-
// console.log('Entering _ruleMatch('
|
|
1076
|
+
// console.log('Entering _ruleMatch(', rule.toString({parenthesis:'all'}), ', ', node.toString({parenthesis:'all'}), ', ', context, ')')
|
|
733
1077
|
var res = [{
|
|
734
1078
|
placeholders: {}
|
|
735
1079
|
}];
|
|
@@ -747,32 +1091,65 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
747
1091
|
} // rule and node match. Search the children of rule and node.
|
|
748
1092
|
|
|
749
1093
|
|
|
750
|
-
if (node.args.length === 1 && rule.args.length === 1 || !isAssociative(node) && node.args.length === rule.args.length || isSplit) {
|
|
751
|
-
// Expect non-associative operators to match exactly
|
|
1094
|
+
if (node.args.length === 1 && rule.args.length === 1 || !isAssociative(node, context) && node.args.length === rule.args.length || isSplit) {
|
|
1095
|
+
// Expect non-associative operators to match exactly,
|
|
1096
|
+
// except in any order if operator is commutative
|
|
752
1097
|
var childMatches = [];
|
|
753
1098
|
|
|
754
1099
|
for (var i = 0; i < rule.args.length; i++) {
|
|
755
|
-
var childMatch = _ruleMatch(rule.args[i], node.args[i]);
|
|
1100
|
+
var childMatch = _ruleMatch(rule.args[i], node.args[i], context);
|
|
756
1101
|
|
|
757
1102
|
if (childMatch.length === 0) {
|
|
758
1103
|
// Child did not match, so stop searching immediately
|
|
759
|
-
|
|
1104
|
+
break;
|
|
760
1105
|
} // The child matched, so add the information returned from the child to our result
|
|
761
1106
|
|
|
762
1107
|
|
|
763
1108
|
childMatches.push(childMatch);
|
|
764
1109
|
}
|
|
765
1110
|
|
|
1111
|
+
if (childMatches.length !== rule.args.length) {
|
|
1112
|
+
if (!isCommutative(node, context) || // exact match in order needed
|
|
1113
|
+
rule.args.length === 1) {
|
|
1114
|
+
// nothing to commute
|
|
1115
|
+
return [];
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
if (rule.args.length > 2) {
|
|
1119
|
+
/* Need to generate all permutations and try them.
|
|
1120
|
+
* It's a bit complicated, and unlikely to come up since there
|
|
1121
|
+
* are very few ternary or higher operators. So punt for now.
|
|
1122
|
+
*/
|
|
1123
|
+
throw new Error('permuting >2 commutative non-associative rule arguments not yet implemented');
|
|
1124
|
+
}
|
|
1125
|
+
/* Exactly two arguments, try them reversed */
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
var leftMatch = _ruleMatch(rule.args[0], node.args[1], context);
|
|
1129
|
+
|
|
1130
|
+
if (leftMatch.length === 0) {
|
|
1131
|
+
return [];
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
var rightMatch = _ruleMatch(rule.args[1], node.args[0], context);
|
|
1135
|
+
|
|
1136
|
+
if (rightMatch.length === 0) {
|
|
1137
|
+
return [];
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
childMatches = [leftMatch, rightMatch];
|
|
1141
|
+
}
|
|
1142
|
+
|
|
766
1143
|
res = mergeChildMatches(childMatches);
|
|
767
1144
|
} else if (node.args.length >= 2 && rule.args.length === 2) {
|
|
768
1145
|
// node is flattened, rule is not
|
|
769
1146
|
// Associative operators/functions can be split in different ways so we check if the rule matches each
|
|
770
1147
|
// them and return their union.
|
|
771
|
-
var splits = getSplits(node,
|
|
1148
|
+
var splits = getSplits(node, context);
|
|
772
1149
|
var splitMatches = [];
|
|
773
1150
|
|
|
774
|
-
for (var
|
|
775
|
-
var matchSet = _ruleMatch(rule, splits[
|
|
1151
|
+
for (var _i3 = 0; _i3 < splits.length; _i3++) {
|
|
1152
|
+
var matchSet = _ruleMatch(rule, splits[_i3], context, true); // recursing at the same tree depth here
|
|
776
1153
|
|
|
777
1154
|
|
|
778
1155
|
splitMatches = splitMatches.concat(matchSet);
|