mathjs 10.1.1 → 10.4.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 +43 -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/cumsum.md +57 -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 +7 -1
- 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 +43 -6
- 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 +8 -1
- 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 +6 -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/dependenciesCumSum.generated.js +26 -0
- package/lib/cjs/entry/dependenciesAny/dependenciesCumSumTransform.generated.js +26 -0
- 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 +48 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesCumSum.generated.js +26 -0
- package/lib/cjs/entry/dependenciesNumber/dependenciesCumSumTransform.generated.js +26 -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 +32 -0
- package/lib/cjs/entry/impureFunctionsAny.generated.js +85 -33
- package/lib/cjs/entry/impureFunctionsNumber.generated.js +102 -64
- package/lib/cjs/entry/pureFunctionsAny.generated.js +68 -64
- package/lib/cjs/entry/pureFunctionsNumber.generated.js +51 -47
- package/lib/cjs/expression/Help.js +4 -0
- package/lib/cjs/expression/Parser.js +1 -1
- package/lib/cjs/expression/embeddedDocs/construction/fraction.js +3 -3
- package/lib/cjs/expression/embeddedDocs/core/typed.js +1 -1
- package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +250 -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/embeddedDocs/function/statistics/cumsum.js +15 -0
- 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/expression/transform/cumsum.transform.js +57 -0
- package/lib/cjs/expression/transform/sum.transform.js +1 -1
- package/lib/cjs/factoriesAny.js +48 -0
- package/lib/cjs/factoriesNumber.js +33 -1
- 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 +562 -207
- package/lib/cjs/function/algebra/{simplify/simplifyCore.js → simplifyCore.js} +68 -44
- 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/function/statistics/cumsum.js +151 -0
- package/lib/cjs/function/statistics/sum.js +1 -1
- package/lib/cjs/function/string/format.js +1 -1
- 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 +21 -9
- 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/collection.js +3 -27
- 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/utils/switch.js +31 -0
- package/lib/cjs/version.js +1 -1
- package/lib/esm/entry/dependenciesAny/dependenciesCumSum.generated.js +14 -0
- package/lib/esm/entry/dependenciesAny/dependenciesCumSumTransform.generated.js +14 -0
- 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 +6 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesCumSum.generated.js +14 -0
- package/lib/esm/entry/dependenciesNumber/dependenciesCumSumTransform.generated.js +14 -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 +4 -0
- package/lib/esm/entry/impureFunctionsAny.generated.js +74 -26
- package/lib/esm/entry/impureFunctionsNumber.generated.js +89 -53
- package/lib/esm/entry/pureFunctionsAny.generated.js +54 -49
- package/lib/esm/entry/pureFunctionsNumber.generated.js +36 -31
- package/lib/esm/expression/Help.js +4 -0
- package/lib/esm/expression/embeddedDocs/construction/fraction.js +3 -3
- package/lib/esm/expression/embeddedDocs/core/typed.js +1 -1
- package/lib/esm/expression/embeddedDocs/embeddedDocs.js +222 -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/embeddedDocs/function/statistics/cumsum.js +8 -0
- package/lib/esm/expression/node/FunctionNode.js +70 -53
- package/lib/esm/expression/transform/cumsum.transform.js +48 -0
- package/lib/esm/expression/transform/sum.transform.js +1 -1
- package/lib/esm/factoriesAny.js +6 -0
- package/lib/esm/factoriesNumber.js +4 -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 +557 -202
- package/lib/esm/function/algebra/{simplify/simplifyCore.js → simplifyCore.js} +61 -45
- 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/function/statistics/cumsum.js +139 -0
- package/lib/esm/function/statistics/sum.js +1 -1
- package/lib/esm/function/string/format.js +1 -1
- package/lib/esm/plain/number/combinations.js +18 -6
- package/lib/esm/type/fraction/function/fraction.js +20 -8
- package/lib/esm/utils/collection.js +1 -26
- package/lib/esm/utils/switch.js +24 -0
- package/lib/esm/version.js +1 -1
- package/package.json +15 -10
- package/types/index.d.ts +155 -13
- package/lib/cjs/function/algebra/simplify/resolve.js +0 -76
- package/lib/esm/function/algebra/simplify/resolve.js +0 -67
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { isConstantNode, isParenthesisNode } from '../../utils/is.js';
|
|
2
2
|
import { factory } from '../../utils/factory.js';
|
|
3
3
|
import { createUtil } from './simplify/util.js';
|
|
4
|
-
import { createSimplifyCore } from './simplify/simplifyCore.js';
|
|
5
4
|
import { createSimplifyConstant } from './simplify/simplifyConstant.js';
|
|
6
|
-
import { createResolve } from './simplify/resolve.js';
|
|
7
5
|
import { hasOwnProperty } from '../../utils/object.js';
|
|
8
6
|
import { createEmptyMap, createMap } from '../../utils/map.js';
|
|
9
7
|
var name = 'simplify';
|
|
10
|
-
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'];
|
|
8
|
+
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'];
|
|
11
9
|
export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
12
10
|
var {
|
|
13
11
|
config,
|
|
@@ -20,6 +18,8 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
20
18
|
pow,
|
|
21
19
|
isZero,
|
|
22
20
|
equal,
|
|
21
|
+
resolve,
|
|
22
|
+
simplifyCore,
|
|
23
23
|
fraction,
|
|
24
24
|
bignumber,
|
|
25
25
|
mathWithTransform,
|
|
@@ -50,36 +50,18 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
50
50
|
OperatorNode,
|
|
51
51
|
SymbolNode
|
|
52
52
|
});
|
|
53
|
-
var simplifyCore = createSimplifyCore({
|
|
54
|
-
equal,
|
|
55
|
-
isZero,
|
|
56
|
-
add,
|
|
57
|
-
subtract,
|
|
58
|
-
multiply,
|
|
59
|
-
divide,
|
|
60
|
-
pow,
|
|
61
|
-
AccessorNode,
|
|
62
|
-
ArrayNode,
|
|
63
|
-
ConstantNode,
|
|
64
|
-
FunctionNode,
|
|
65
|
-
IndexNode,
|
|
66
|
-
ObjectNode,
|
|
67
|
-
OperatorNode,
|
|
68
|
-
ParenthesisNode
|
|
69
|
-
});
|
|
70
|
-
var resolve = createResolve({
|
|
71
|
-
parse,
|
|
72
|
-
FunctionNode,
|
|
73
|
-
OperatorNode,
|
|
74
|
-
ParenthesisNode
|
|
75
|
-
});
|
|
76
53
|
var {
|
|
54
|
+
hasProperty,
|
|
77
55
|
isCommutative,
|
|
78
56
|
isAssociative,
|
|
57
|
+
mergeContext,
|
|
79
58
|
flatten,
|
|
80
59
|
unflattenr,
|
|
81
60
|
unflattenl,
|
|
82
|
-
createMakeNodeFunction
|
|
61
|
+
createMakeNodeFunction,
|
|
62
|
+
defaultContext,
|
|
63
|
+
realContext,
|
|
64
|
+
positiveContext
|
|
83
65
|
} = createUtil({
|
|
84
66
|
FunctionNode,
|
|
85
67
|
OperatorNode,
|
|
@@ -115,6 +97,19 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
115
97
|
* The default list of rules is exposed on the function as `simplify.rules`
|
|
116
98
|
* and can be used as a basis to built a set of custom rules.
|
|
117
99
|
*
|
|
100
|
+
* To specify a rule as a string, separate the left and right pattern by '->'
|
|
101
|
+
* When specifying a rule as an object, the following keys are meaningful:
|
|
102
|
+
* - l - the left pattern
|
|
103
|
+
* - r - the right pattern
|
|
104
|
+
* - s - in lieu of l and r, the string form that is broken at -> to give them
|
|
105
|
+
* - repeat - whether to repeat this rule until the expression stabilizes
|
|
106
|
+
* - assuming - gives a context object, as in the 'context' option to
|
|
107
|
+
* simplify. Every property in the context object must match the current
|
|
108
|
+
* context in order, or else the rule will not be applied.
|
|
109
|
+
* - imposeContext - gives a context object, as in the 'context' option to
|
|
110
|
+
* simplify. Any settings specified will override the incoming context
|
|
111
|
+
* for all matches of this rule.
|
|
112
|
+
*
|
|
118
113
|
* For more details on the theory, see:
|
|
119
114
|
*
|
|
120
115
|
* - [Strategies for simplifying math expressions (Stackoverflow)](https://stackoverflow.com/questions/7540227/strategies-for-simplifying-math-expressions)
|
|
@@ -123,12 +118,28 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
123
118
|
* An optional `options` argument can be passed as last argument of `simplify`.
|
|
124
119
|
* Currently available options (defaults in parentheses):
|
|
125
120
|
* - `consoleDebug` (false): whether to write the expression being simplified
|
|
126
|
-
|
|
121
|
+
* and any changes to it, along with the rule responsible, to console
|
|
122
|
+
* - `context` (simplify.defaultContext): an object giving properties of
|
|
123
|
+
* each operator, which determine what simplifications are allowed. The
|
|
124
|
+
* currently meaningful properties are commutative, associative,
|
|
125
|
+
* total (whether the operation is defined for all arguments), and
|
|
126
|
+
* trivial (whether the operation applied to a single argument leaves
|
|
127
|
+
* that argument unchanged). The default context is very permissive and
|
|
128
|
+
* allows almost all simplifications. Only properties differing from
|
|
129
|
+
* the default need to be specified; the default context is used as a
|
|
130
|
+
* fallback. Additional contexts `simplify.realContext` and
|
|
131
|
+
* `simplify.positiveContext` are supplied to cause simplify to perform
|
|
132
|
+
* just simplifications guaranteed to preserve all values of the expression
|
|
133
|
+
* assuming all variables and subexpressions are real numbers or
|
|
134
|
+
* positive real numbers, respectively. (Note that these are in some cases
|
|
135
|
+
* more restrictive than the default context; for example, the default
|
|
136
|
+
* context will allow `x/x` to simplify to 1, whereas
|
|
137
|
+
* `simplify.realContext` will not, as `0/0` is not equal to 1.)
|
|
127
138
|
* - `exactFractions` (true): whether to try to convert all constants to
|
|
128
|
-
|
|
139
|
+
* exact rational numbers.
|
|
129
140
|
* - `fractionsLimit` (10000): when `exactFractions` is true, constants will
|
|
130
|
-
|
|
131
|
-
|
|
141
|
+
* be expressed as fractions only when both numerator and denominator
|
|
142
|
+
* are smaller than `fractionsLimit`.
|
|
132
143
|
*
|
|
133
144
|
* Syntax:
|
|
134
145
|
*
|
|
@@ -151,7 +162,7 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
151
162
|
*
|
|
152
163
|
* See also:
|
|
153
164
|
*
|
|
154
|
-
* derivative, parse,
|
|
165
|
+
* simplifyCore, derivative, evaluate, parse, rationalize, resolve
|
|
155
166
|
*
|
|
156
167
|
* @param {Node | string} expr
|
|
157
168
|
* The expression to be simplified
|
|
@@ -199,7 +210,7 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
199
210
|
},
|
|
200
211
|
'Node, Array, Map, Object': function NodeArrayMapObject(expr, rules, scope, options) {
|
|
201
212
|
var debug = options.consoleDebug;
|
|
202
|
-
rules = _buildRules(rules);
|
|
213
|
+
rules = _buildRules(rules, options.context);
|
|
203
214
|
var res = resolve(expr, scope);
|
|
204
215
|
res = removeParens(res);
|
|
205
216
|
var visited = {};
|
|
@@ -221,8 +232,8 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
221
232
|
res = rules[i](res, options);
|
|
222
233
|
if (debug) rulestr = rules[i].name;
|
|
223
234
|
} else {
|
|
224
|
-
flatten(res);
|
|
225
|
-
res = applyRule(res, rules[i]);
|
|
235
|
+
flatten(res, options.context);
|
|
236
|
+
res = applyRule(res, rules[i], options.context);
|
|
226
237
|
|
|
227
238
|
if (debug) {
|
|
228
239
|
rulestr = "".concat(rules[i].l.toString(), " -> ").concat(rules[i].r.toString());
|
|
@@ -239,8 +250,12 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
239
250
|
laststr = newstr;
|
|
240
251
|
}
|
|
241
252
|
}
|
|
253
|
+
/* Use left-heavy binary tree internally,
|
|
254
|
+
* since custom rule functions may expect it
|
|
255
|
+
*/
|
|
242
256
|
|
|
243
|
-
|
|
257
|
+
|
|
258
|
+
unflattenl(res, options.context);
|
|
244
259
|
}
|
|
245
260
|
|
|
246
261
|
str = res.toString({
|
|
@@ -251,8 +266,9 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
251
266
|
return res;
|
|
252
267
|
}
|
|
253
268
|
});
|
|
254
|
-
simplify.
|
|
255
|
-
simplify.
|
|
269
|
+
simplify.defaultContext = defaultContext;
|
|
270
|
+
simplify.realContext = realContext;
|
|
271
|
+
simplify.positiveContext = positiveContext;
|
|
256
272
|
|
|
257
273
|
function removeParens(node) {
|
|
258
274
|
return node.transform(function (node, path, parent) {
|
|
@@ -304,41 +320,155 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
304
320
|
// Note initially we tend constants to the right because like-term
|
|
305
321
|
// collection prefers the left, and we would rather collect nonconstants
|
|
306
322
|
{
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
{
|
|
323
|
+
s: 'n-n1 -> n+-n1',
|
|
324
|
+
// temporarily replace 'subtract' so we can further flatten the 'add' operator
|
|
325
|
+
assuming: {
|
|
326
|
+
subtract: {
|
|
327
|
+
total: true
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}, {
|
|
331
|
+
s: 'n-n -> 0',
|
|
332
|
+
// partial alternative when we can't always subtract
|
|
333
|
+
assuming: {
|
|
334
|
+
subtract: {
|
|
335
|
+
total: false
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}, {
|
|
339
|
+
s: '-(c*v) -> v * (-c)',
|
|
340
|
+
// make non-constant terms positive
|
|
341
|
+
assuming: {
|
|
342
|
+
multiply: {
|
|
343
|
+
commutative: true
|
|
344
|
+
},
|
|
345
|
+
subtract: {
|
|
346
|
+
total: true
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}, {
|
|
350
|
+
s: '-(c*v) -> (-c) * v',
|
|
351
|
+
// non-commutative version, part 1
|
|
352
|
+
assuming: {
|
|
353
|
+
multiply: {
|
|
354
|
+
commutative: false
|
|
355
|
+
},
|
|
356
|
+
subtract: {
|
|
357
|
+
total: true
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}, {
|
|
361
|
+
s: '-(v*c) -> v * (-c)',
|
|
362
|
+
// non-commutative version, part 2
|
|
363
|
+
assuming: {
|
|
364
|
+
multiply: {
|
|
365
|
+
commutative: false
|
|
366
|
+
},
|
|
367
|
+
subtract: {
|
|
368
|
+
total: true
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}, {
|
|
372
|
+
l: '-(n1/n2)',
|
|
373
|
+
r: '-n1/n2'
|
|
374
|
+
}, {
|
|
315
375
|
l: '-v',
|
|
316
376
|
r: 'v * (-1)'
|
|
317
|
-
},
|
|
377
|
+
}, // finish making non-constant terms positive
|
|
378
|
+
{
|
|
379
|
+
l: '(n1 + n2)*(-1)',
|
|
380
|
+
r: 'n1*(-1) + n2*(-1)',
|
|
381
|
+
repeat: true
|
|
382
|
+
}, // expand negations to achieve as much sign cancellation as possible
|
|
383
|
+
{
|
|
318
384
|
l: 'n/n1^n2',
|
|
319
385
|
r: 'n*n1^-n2'
|
|
320
386
|
}, // temporarily replace 'divide' so we can further flatten the 'multiply' operator
|
|
321
387
|
{
|
|
322
388
|
l: 'n/n1',
|
|
323
389
|
r: 'n*n1^-1'
|
|
324
|
-
},
|
|
390
|
+
}, {
|
|
391
|
+
s: '(n1*n2)^n3 -> n1^n3 * n2^n3',
|
|
392
|
+
assuming: {
|
|
393
|
+
multiply: {
|
|
394
|
+
commutative: true
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}, {
|
|
398
|
+
s: '(n1*n2)^(-1) -> n2^(-1) * n1^(-1)',
|
|
399
|
+
assuming: {
|
|
400
|
+
multiply: {
|
|
401
|
+
commutative: false
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}, // expand nested exponentiation
|
|
325
405
|
{
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
406
|
+
s: '(n ^ n1) ^ n2 -> n ^ (n1 * n2)',
|
|
407
|
+
assuming: {
|
|
408
|
+
divide: {
|
|
409
|
+
total: true
|
|
410
|
+
}
|
|
411
|
+
} // 1/(1/n) = n needs 1/n to exist
|
|
412
|
+
|
|
413
|
+
}, // collect like factors; into a sum, only do this for nonconstants
|
|
329
414
|
{
|
|
415
|
+
l: ' v * ( v * n1 + n2)',
|
|
416
|
+
r: 'v^2 * n1 + v * n2'
|
|
417
|
+
}, {
|
|
418
|
+
s: ' v * (v^n4 * n1 + n2) -> v^(1+n4) * n1 + v * n2',
|
|
419
|
+
assuming: {
|
|
420
|
+
divide: {
|
|
421
|
+
total: true
|
|
422
|
+
}
|
|
423
|
+
} // v*1/v = v^(1+-1) needs 1/v
|
|
424
|
+
|
|
425
|
+
}, {
|
|
426
|
+
s: 'v^n3 * ( v * n1 + n2) -> v^(n3+1) * n1 + v^n3 * n2',
|
|
427
|
+
assuming: {
|
|
428
|
+
divide: {
|
|
429
|
+
total: true
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}, {
|
|
433
|
+
s: 'v^n3 * (v^n4 * n1 + n2) -> v^(n3+n4) * n1 + v^n3 * n2',
|
|
434
|
+
assuming: {
|
|
435
|
+
divide: {
|
|
436
|
+
total: true
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}, {
|
|
330
440
|
l: 'n*n',
|
|
331
441
|
r: 'n^2'
|
|
332
442
|
}, {
|
|
333
|
-
|
|
334
|
-
|
|
443
|
+
s: 'n * n^n1 -> n^(n1+1)',
|
|
444
|
+
assuming: {
|
|
445
|
+
divide: {
|
|
446
|
+
total: true
|
|
447
|
+
}
|
|
448
|
+
} // n*1/n = n^(-1+1) needs 1/n
|
|
449
|
+
|
|
335
450
|
}, {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
451
|
+
s: 'n^n1 * n^n2 -> n^(n1+n2)',
|
|
452
|
+
assuming: {
|
|
453
|
+
divide: {
|
|
454
|
+
total: true
|
|
455
|
+
}
|
|
456
|
+
} // ditto for n^2*1/n^2
|
|
457
|
+
|
|
458
|
+
}, // Unfortunately, to deal with more complicated cancellations, it
|
|
459
|
+
// becomes necessary to simplify constants twice per pass. It's not
|
|
460
|
+
// terribly expensive compared to matching rules, so this should not
|
|
461
|
+
// pose a performance problem.
|
|
462
|
+
simplifyConstant, // First: before collecting like terms
|
|
463
|
+
// collect like terms
|
|
339
464
|
{
|
|
340
|
-
|
|
341
|
-
|
|
465
|
+
s: 'n+n -> 2*n',
|
|
466
|
+
assuming: {
|
|
467
|
+
add: {
|
|
468
|
+
total: true
|
|
469
|
+
}
|
|
470
|
+
} // 2 = 1 + 1 needs to exist
|
|
471
|
+
|
|
342
472
|
}, {
|
|
343
473
|
l: 'n+-n',
|
|
344
474
|
r: '0'
|
|
@@ -351,33 +481,91 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
351
481
|
r: 'n3*(n1+n2)'
|
|
352
482
|
}, // All sub-monomials tried there.
|
|
353
483
|
{
|
|
484
|
+
l: 'n3^(-n4)*n1 + n3 * n2',
|
|
485
|
+
r: 'n3^(-n4)*(n1 + n3^(n4+1) *n2)'
|
|
486
|
+
}, {
|
|
487
|
+
l: 'n3^(-n4)*n1 + n3^n5 * n2',
|
|
488
|
+
r: 'n3^(-n4)*(n1 + n3^(n4+n5)*n2)'
|
|
489
|
+
}, {
|
|
490
|
+
s: 'n*v + v -> (n+1)*v',
|
|
491
|
+
// noncommutative additional cases
|
|
492
|
+
assuming: {
|
|
493
|
+
multiply: {
|
|
494
|
+
commutative: false
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}, {
|
|
498
|
+
s: 'n1*n3 + n2*n3 -> (n1+n2)*n3',
|
|
499
|
+
assuming: {
|
|
500
|
+
multiply: {
|
|
501
|
+
commutative: false
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}, {
|
|
505
|
+
s: 'n1*n3^(-n4) + n2 * n3 -> (n1 + n2*n3^(n4 + 1))*n3^(-n4)',
|
|
506
|
+
assuming: {
|
|
507
|
+
multiply: {
|
|
508
|
+
commutative: false
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}, {
|
|
512
|
+
s: 'n1*n3^(-n4) + n2 * n3^n5 -> (n1 + n2*n3^(n4 + n5))*n3^(-n4)',
|
|
513
|
+
assuming: {
|
|
514
|
+
multiply: {
|
|
515
|
+
commutative: false
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}, {
|
|
354
519
|
l: 'n*c + c',
|
|
355
520
|
r: '(n+1)*c'
|
|
356
|
-
},
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
521
|
+
}, {
|
|
522
|
+
s: 'c*n + c -> c*(n+1)',
|
|
523
|
+
assuming: {
|
|
524
|
+
multiply: {
|
|
525
|
+
commutative: false
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}, simplifyConstant, // Second: before returning expressions to "standard form"
|
|
529
|
+
// make factors positive (and undo 'make non-constant terms positive')
|
|
365
530
|
{
|
|
366
|
-
|
|
367
|
-
|
|
531
|
+
s: '(-n)*n1 -> -(n*n1)',
|
|
532
|
+
assuming: {
|
|
533
|
+
subtract: {
|
|
534
|
+
total: true
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}, {
|
|
538
|
+
s: 'n1*(-n) -> -(n1*n)',
|
|
539
|
+
// in case * non-commutative
|
|
540
|
+
assuming: {
|
|
541
|
+
subtract: {
|
|
542
|
+
total: true
|
|
543
|
+
},
|
|
544
|
+
multiply: {
|
|
545
|
+
commutative: false
|
|
546
|
+
}
|
|
547
|
+
}
|
|
368
548
|
}, // final ordering of constants
|
|
369
549
|
{
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
550
|
+
s: 'c+v -> v+c',
|
|
551
|
+
assuming: {
|
|
552
|
+
add: {
|
|
553
|
+
commutative: true
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
imposeContext: {
|
|
373
557
|
add: {
|
|
374
558
|
commutative: false
|
|
375
559
|
}
|
|
376
560
|
}
|
|
377
561
|
}, {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
562
|
+
s: 'v*c -> c*v',
|
|
563
|
+
assuming: {
|
|
564
|
+
multiply: {
|
|
565
|
+
commutative: true
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
imposeContext: {
|
|
381
569
|
multiply: {
|
|
382
570
|
commutative: false
|
|
383
571
|
}
|
|
@@ -389,36 +577,125 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
389
577
|
r: 'n-n1'
|
|
390
578
|
}, // undo replace 'subtract'
|
|
391
579
|
{
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
580
|
+
s: 'n*(n1^-1) -> n/n1',
|
|
581
|
+
// undo replace 'divide'; for * commutative
|
|
582
|
+
assuming: {
|
|
583
|
+
multiply: {
|
|
584
|
+
commutative: true
|
|
585
|
+
}
|
|
586
|
+
} // o.w. / not conventional
|
|
587
|
+
|
|
398
588
|
}, {
|
|
399
|
-
|
|
400
|
-
|
|
589
|
+
s: 'n*n1^-n2 -> n/n1^n2',
|
|
590
|
+
assuming: {
|
|
591
|
+
multiply: {
|
|
592
|
+
commutative: true
|
|
593
|
+
}
|
|
594
|
+
} // o.w. / not conventional
|
|
595
|
+
|
|
401
596
|
}, {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
597
|
+
s: 'n^-1 -> 1/n',
|
|
598
|
+
assuming: {
|
|
599
|
+
multiply: {
|
|
600
|
+
commutative: true
|
|
601
|
+
}
|
|
602
|
+
} // o.w. / not conventional
|
|
603
|
+
|
|
604
|
+
}, {
|
|
605
|
+
l: 'n^1',
|
|
606
|
+
r: 'n'
|
|
607
|
+
}, // can be produced by power cancellation
|
|
405
608
|
{
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
609
|
+
s: 'n*(n1/n2) -> (n*n1)/n2',
|
|
610
|
+
// '*' before '/'
|
|
611
|
+
assuming: {
|
|
612
|
+
multiply: {
|
|
613
|
+
associative: true
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}, {
|
|
617
|
+
s: 'n-(n1+n2) -> n-n1-n2',
|
|
618
|
+
// '-' before '+'
|
|
619
|
+
assuming: {
|
|
620
|
+
addition: {
|
|
621
|
+
associative: true,
|
|
622
|
+
commutative: true
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}, // { l: '(n1/n2)/n3', r: 'n1/(n2*n3)' },
|
|
410
626
|
// { l: '(n*n1)/(n*n2)', r: 'n1/n2' },
|
|
627
|
+
// simplifyConstant can leave an extra factor of 1, which can always
|
|
628
|
+
// be eliminated, since the identity always commutes
|
|
411
629
|
{
|
|
412
630
|
l: '1*n',
|
|
413
|
-
r: 'n'
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
631
|
+
r: 'n',
|
|
632
|
+
imposeContext: {
|
|
633
|
+
multiply: {
|
|
634
|
+
commutative: true
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
}, {
|
|
638
|
+
s: 'n1/(n2/n3) -> (n1*n3)/n2',
|
|
639
|
+
assuming: {
|
|
640
|
+
multiply: {
|
|
641
|
+
associative: true
|
|
642
|
+
}
|
|
643
|
+
}
|
|
418
644
|
}, {
|
|
419
645
|
l: 'n1/(-n2)',
|
|
420
646
|
r: '-n1/n2'
|
|
421
647
|
}];
|
|
648
|
+
/**
|
|
649
|
+
* Takes any rule object as allowed by the specification in simplify
|
|
650
|
+
* and puts it in a standard form used by applyRule
|
|
651
|
+
*/
|
|
652
|
+
|
|
653
|
+
function _canonicalizeRule(ruleObject, context) {
|
|
654
|
+
var newRule = {};
|
|
655
|
+
|
|
656
|
+
if (ruleObject.s) {
|
|
657
|
+
var lr = ruleObject.s.split('->');
|
|
658
|
+
|
|
659
|
+
if (lr.length === 2) {
|
|
660
|
+
newRule.l = lr[0];
|
|
661
|
+
newRule.r = lr[1];
|
|
662
|
+
} else {
|
|
663
|
+
throw SyntaxError('Could not parse rule: ' + ruleObject.s);
|
|
664
|
+
}
|
|
665
|
+
} else {
|
|
666
|
+
newRule.l = ruleObject.l;
|
|
667
|
+
newRule.r = ruleObject.r;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
newRule.l = removeParens(parse(newRule.l));
|
|
671
|
+
newRule.r = removeParens(parse(newRule.r));
|
|
672
|
+
|
|
673
|
+
for (var prop of ['imposeContext', 'repeat', 'assuming']) {
|
|
674
|
+
if (prop in ruleObject) {
|
|
675
|
+
newRule[prop] = ruleObject[prop];
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
if (ruleObject.evaluate) {
|
|
680
|
+
newRule.evaluate = parse(ruleObject.evaluate);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
if (isAssociative(newRule.l, context)) {
|
|
684
|
+
var makeNode = createMakeNodeFunction(newRule.l);
|
|
685
|
+
|
|
686
|
+
var expandsym = _getExpandPlaceholderSymbol();
|
|
687
|
+
|
|
688
|
+
newRule.expanded = {};
|
|
689
|
+
newRule.expanded.l = makeNode([newRule.l.clone(), expandsym]); // Push the expandsym into the deepest possible branch.
|
|
690
|
+
// This helps to match the newRule against nodes returned from getSplits() later on.
|
|
691
|
+
|
|
692
|
+
flatten(newRule.expanded.l, context);
|
|
693
|
+
unflattenr(newRule.expanded.l, context);
|
|
694
|
+
newRule.expanded.r = makeNode([newRule.r, expandsym]);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
return newRule;
|
|
698
|
+
}
|
|
422
699
|
/**
|
|
423
700
|
* Parse the string array of rules into nodes
|
|
424
701
|
*
|
|
@@ -436,7 +713,8 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
436
713
|
* 'n1 * c1 -> c1 * n1'
|
|
437
714
|
*/
|
|
438
715
|
|
|
439
|
-
|
|
716
|
+
|
|
717
|
+
function _buildRules(rules, context) {
|
|
440
718
|
// Array of rules to be used to simplify expressions
|
|
441
719
|
var ruleSet = [];
|
|
442
720
|
|
|
@@ -447,49 +725,14 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
447
725
|
|
|
448
726
|
switch (ruleType) {
|
|
449
727
|
case 'string':
|
|
450
|
-
{
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
if (lr.length === 2) {
|
|
454
|
-
rule = {
|
|
455
|
-
l: lr[0],
|
|
456
|
-
r: lr[1]
|
|
457
|
-
};
|
|
458
|
-
} else {
|
|
459
|
-
throw SyntaxError('Could not parse rule: ' + rule);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
728
|
+
rule = {
|
|
729
|
+
s: rule
|
|
730
|
+
};
|
|
462
731
|
|
|
463
732
|
/* falls through */
|
|
464
733
|
|
|
465
734
|
case 'object':
|
|
466
|
-
newRule =
|
|
467
|
-
l: removeParens(parse(rule.l)),
|
|
468
|
-
r: removeParens(parse(rule.r))
|
|
469
|
-
};
|
|
470
|
-
|
|
471
|
-
if (rule.context) {
|
|
472
|
-
newRule.context = rule.context;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
if (rule.evaluate) {
|
|
476
|
-
newRule.evaluate = parse(rule.evaluate);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
if (isAssociative(newRule.l)) {
|
|
480
|
-
var makeNode = createMakeNodeFunction(newRule.l);
|
|
481
|
-
|
|
482
|
-
var expandsym = _getExpandPlaceholderSymbol();
|
|
483
|
-
|
|
484
|
-
newRule.expanded = {};
|
|
485
|
-
newRule.expanded.l = makeNode([newRule.l.clone(), expandsym]); // Push the expandsym into the deepest possible branch.
|
|
486
|
-
// This helps to match the newRule against nodes returned from getSplits() later on.
|
|
487
|
-
|
|
488
|
-
flatten(newRule.expanded.l);
|
|
489
|
-
unflattenr(newRule.expanded.l);
|
|
490
|
-
newRule.expanded.r = makeNode([newRule.r, expandsym]);
|
|
491
|
-
}
|
|
492
|
-
|
|
735
|
+
newRule = _canonicalizeRule(rule, context);
|
|
493
736
|
break;
|
|
494
737
|
|
|
495
738
|
case 'function':
|
|
@@ -514,90 +757,155 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
514
757
|
return new SymbolNode('_p' + _lastsym++);
|
|
515
758
|
}
|
|
516
759
|
|
|
517
|
-
function mapRule(nodes, rule) {
|
|
760
|
+
function mapRule(nodes, rule, context) {
|
|
761
|
+
var resNodes = nodes;
|
|
762
|
+
|
|
518
763
|
if (nodes) {
|
|
519
764
|
for (var i = 0; i < nodes.length; ++i) {
|
|
520
|
-
|
|
765
|
+
var newNode = applyRule(nodes[i], rule, context);
|
|
766
|
+
|
|
767
|
+
if (newNode !== nodes[i]) {
|
|
768
|
+
if (resNodes === nodes) {
|
|
769
|
+
resNodes = nodes.slice();
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
resNodes[i] = newNode;
|
|
773
|
+
}
|
|
521
774
|
}
|
|
522
775
|
}
|
|
776
|
+
|
|
777
|
+
return resNodes;
|
|
523
778
|
}
|
|
524
779
|
/**
|
|
525
780
|
* Returns a simplfied form of node, or the original node if no simplification was possible.
|
|
526
781
|
*
|
|
527
782
|
* @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} node
|
|
783
|
+
* @param {Object | Function} rule
|
|
784
|
+
* @param {Object} context -- information about assumed properties of operators
|
|
528
785
|
* @return {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} The simplified form of `expr`, or the original node if no simplification was possible.
|
|
529
786
|
*/
|
|
530
787
|
|
|
531
788
|
|
|
532
|
-
|
|
533
|
-
'
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
} else if (res instanceof ParenthesisNode) {
|
|
543
|
-
if (res.content) {
|
|
544
|
-
res.content = applyRule(res.content, rule);
|
|
545
|
-
}
|
|
546
|
-
} else if (res instanceof ArrayNode) {
|
|
547
|
-
mapRule(res.items, rule);
|
|
548
|
-
} else if (res instanceof AccessorNode) {
|
|
549
|
-
if (res.object) {
|
|
550
|
-
res.object = applyRule(res.object, rule);
|
|
789
|
+
function applyRule(node, rule, context) {
|
|
790
|
+
// console.log('Entering applyRule("', rule.l.toString({parenthesis:'all'}), '->', rule.r.toString({parenthesis:'all'}), '",', node.toString({parenthesis:'all'}),')')
|
|
791
|
+
// check that the assumptions for this rule are satisfied by the current
|
|
792
|
+
// context:
|
|
793
|
+
if (rule.assuming) {
|
|
794
|
+
for (var symbol in rule.assuming) {
|
|
795
|
+
for (var property in rule.assuming[symbol]) {
|
|
796
|
+
if (hasProperty(symbol, property, context) !== rule.assuming[symbol][property]) {
|
|
797
|
+
return node;
|
|
798
|
+
}
|
|
551
799
|
}
|
|
800
|
+
}
|
|
801
|
+
}
|
|
552
802
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
803
|
+
var mergedContext = mergeContext(rule.imposeContext, context); // Do not clone node unless we find a match
|
|
804
|
+
|
|
805
|
+
var res = node; // First replace our child nodes with their simplified versions
|
|
806
|
+
// If a child could not be simplified, applying the rule to it
|
|
807
|
+
// will have no effect since the node is returned unchanged
|
|
808
|
+
|
|
809
|
+
if (res instanceof OperatorNode || res instanceof FunctionNode) {
|
|
810
|
+
var newArgs = mapRule(res.args, rule, context);
|
|
811
|
+
|
|
812
|
+
if (newArgs !== res.args) {
|
|
813
|
+
res = res.clone();
|
|
814
|
+
res.args = newArgs;
|
|
815
|
+
}
|
|
816
|
+
} else if (res instanceof ParenthesisNode) {
|
|
817
|
+
if (res.content) {
|
|
818
|
+
var newContent = applyRule(res.content, rule, context);
|
|
819
|
+
|
|
820
|
+
if (newContent !== res.content) {
|
|
821
|
+
res = new ParenthesisNode(newContent);
|
|
561
822
|
}
|
|
562
|
-
}
|
|
823
|
+
}
|
|
824
|
+
} else if (res instanceof ArrayNode) {
|
|
825
|
+
var newItems = mapRule(res.items, rule, context);
|
|
563
826
|
|
|
827
|
+
if (newItems !== res.items) {
|
|
828
|
+
res = new ArrayNode(newItems);
|
|
829
|
+
}
|
|
830
|
+
} else if (res instanceof AccessorNode) {
|
|
831
|
+
var newObj = res.object;
|
|
564
832
|
|
|
565
|
-
|
|
833
|
+
if (res.object) {
|
|
834
|
+
newObj = applyRule(res.object, rule, context);
|
|
835
|
+
}
|
|
566
836
|
|
|
567
|
-
var
|
|
568
|
-
// 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.
|
|
837
|
+
var newIndex = res.index;
|
|
569
838
|
|
|
839
|
+
if (res.index) {
|
|
840
|
+
newIndex = applyRule(res.index, rule, context);
|
|
841
|
+
}
|
|
570
842
|
|
|
571
|
-
if (
|
|
572
|
-
|
|
573
|
-
matches = _ruleMatch(rule.expanded.l, res)[0];
|
|
843
|
+
if (newObj !== res.object || newIndex !== res.index) {
|
|
844
|
+
res = new AccessorNode(newObj, newIndex);
|
|
574
845
|
}
|
|
846
|
+
} else if (res instanceof IndexNode) {
|
|
847
|
+
var newDims = mapRule(res.dimensions, rule, context);
|
|
575
848
|
|
|
576
|
-
if (
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
849
|
+
if (newDims !== res.dimensions) {
|
|
850
|
+
res = new IndexNode(newDims);
|
|
851
|
+
}
|
|
852
|
+
} else if (res instanceof ObjectNode) {
|
|
853
|
+
var changed = false;
|
|
854
|
+
var newProps = {};
|
|
582
855
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
} // Replace placeholders with their respective nodes without traversing deeper into the replaced nodes
|
|
856
|
+
for (var prop in res.properties) {
|
|
857
|
+
newProps[prop] = applyRule(res.properties[prop], rule, context);
|
|
586
858
|
|
|
859
|
+
if (newProps[prop] !== res.properties[prop]) {
|
|
860
|
+
changed = true;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
587
863
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
return matches.placeholders[node.name].clone();
|
|
591
|
-
} else {
|
|
592
|
-
return node;
|
|
593
|
-
}
|
|
594
|
-
}); // const after = res.toString({parenthesis: 'all'})
|
|
595
|
-
// console.log('Simplified ' + before + ' to ' + after)
|
|
864
|
+
if (changed) {
|
|
865
|
+
res = new ObjectNode(newProps);
|
|
596
866
|
}
|
|
867
|
+
} // Try to match a rule against this node
|
|
597
868
|
|
|
598
|
-
|
|
869
|
+
|
|
870
|
+
var repl = rule.r;
|
|
871
|
+
|
|
872
|
+
var matches = _ruleMatch(rule.l, res, mergedContext)[0]; // If the rule is associative operator, we can try matching it while allowing additional terms.
|
|
873
|
+
// 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.
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
if (!matches && rule.expanded) {
|
|
877
|
+
repl = rule.expanded.r;
|
|
878
|
+
matches = _ruleMatch(rule.expanded.l, res, mergedContext)[0];
|
|
599
879
|
}
|
|
600
|
-
|
|
880
|
+
|
|
881
|
+
if (matches) {
|
|
882
|
+
// const before = res.toString({parenthesis: 'all'})
|
|
883
|
+
// Create a new node by cloning the rhs of the matched rule
|
|
884
|
+
// we keep any implicit multiplication state if relevant
|
|
885
|
+
var implicit = res.implicit;
|
|
886
|
+
res = repl.clone();
|
|
887
|
+
|
|
888
|
+
if (implicit && 'implicit' in repl) {
|
|
889
|
+
res.implicit = true;
|
|
890
|
+
} // Replace placeholders with their respective nodes without traversing deeper into the replaced nodes
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
res = res.transform(function (node) {
|
|
894
|
+
if (node.isSymbolNode && hasOwnProperty(matches.placeholders, node.name)) {
|
|
895
|
+
return matches.placeholders[node.name].clone();
|
|
896
|
+
} else {
|
|
897
|
+
return node;
|
|
898
|
+
}
|
|
899
|
+
}); // const after = res.toString({parenthesis: 'all'})
|
|
900
|
+
// console.log('Simplified ' + before + ' to ' + after)
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
if (rule.repeat && res !== node) {
|
|
904
|
+
res = applyRule(res, rule, context);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
return res;
|
|
908
|
+
}
|
|
601
909
|
/**
|
|
602
910
|
* Get (binary) combinations of a flattened binary node
|
|
603
911
|
* e.g. +(node1, node2, node3) -> [
|
|
@@ -607,6 +915,7 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
607
915
|
*
|
|
608
916
|
*/
|
|
609
917
|
|
|
918
|
+
|
|
610
919
|
function getSplits(node, context) {
|
|
611
920
|
var res = [];
|
|
612
921
|
var right, rightArgs;
|
|
@@ -620,9 +929,18 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
620
929
|
res.push(makeNode([node.args[i], right]));
|
|
621
930
|
}
|
|
622
931
|
} else {
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
932
|
+
// Keep order, but try all parenthesizations
|
|
933
|
+
for (var _i = 1; _i < node.args.length; _i++) {
|
|
934
|
+
var left = node.args[0];
|
|
935
|
+
|
|
936
|
+
if (_i > 1) {
|
|
937
|
+
left = makeNode(node.args.slice(0, _i));
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
rightArgs = node.args.slice(_i);
|
|
941
|
+
right = rightArgs.length === 1 ? rightArgs[0] : makeNode(rightArgs);
|
|
942
|
+
res.push(makeNode([left, right]));
|
|
943
|
+
}
|
|
626
944
|
}
|
|
627
945
|
|
|
628
946
|
return res;
|
|
@@ -725,15 +1043,19 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
725
1043
|
*
|
|
726
1044
|
* @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} rule
|
|
727
1045
|
* @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} node
|
|
1046
|
+
* @param {Object} context -- provides assumed properties of operators
|
|
1047
|
+
* @param {Boolean} isSplit -- whether we are in process of splitting an
|
|
1048
|
+
* n-ary operator node into possible binary combinations.
|
|
1049
|
+
* Defaults to false.
|
|
728
1050
|
* @return {Object} Information about the match, if it exists.
|
|
729
1051
|
*/
|
|
730
1052
|
|
|
731
1053
|
|
|
732
|
-
function _ruleMatch(rule, node, isSplit) {
|
|
1054
|
+
function _ruleMatch(rule, node, context, isSplit) {
|
|
733
1055
|
// console.log('Entering _ruleMatch(' + JSON.stringify(rule) + ', ' + JSON.stringify(node) + ')')
|
|
734
1056
|
// console.log('rule = ' + rule)
|
|
735
1057
|
// console.log('node = ' + node)
|
|
736
|
-
// console.log('Entering _ruleMatch('
|
|
1058
|
+
// console.log('Entering _ruleMatch(', rule.toString({parenthesis:'all'}), ', ', node.toString({parenthesis:'all'}), ', ', context, ')')
|
|
737
1059
|
var res = [{
|
|
738
1060
|
placeholders: {}
|
|
739
1061
|
}];
|
|
@@ -751,32 +1073,65 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
|
|
|
751
1073
|
} // rule and node match. Search the children of rule and node.
|
|
752
1074
|
|
|
753
1075
|
|
|
754
|
-
if (node.args.length === 1 && rule.args.length === 1 || !isAssociative(node) && node.args.length === rule.args.length || isSplit) {
|
|
755
|
-
// Expect non-associative operators to match exactly
|
|
1076
|
+
if (node.args.length === 1 && rule.args.length === 1 || !isAssociative(node, context) && node.args.length === rule.args.length || isSplit) {
|
|
1077
|
+
// Expect non-associative operators to match exactly,
|
|
1078
|
+
// except in any order if operator is commutative
|
|
756
1079
|
var childMatches = [];
|
|
757
1080
|
|
|
758
1081
|
for (var i = 0; i < rule.args.length; i++) {
|
|
759
|
-
var childMatch = _ruleMatch(rule.args[i], node.args[i]);
|
|
1082
|
+
var childMatch = _ruleMatch(rule.args[i], node.args[i], context);
|
|
760
1083
|
|
|
761
1084
|
if (childMatch.length === 0) {
|
|
762
1085
|
// Child did not match, so stop searching immediately
|
|
763
|
-
|
|
1086
|
+
break;
|
|
764
1087
|
} // The child matched, so add the information returned from the child to our result
|
|
765
1088
|
|
|
766
1089
|
|
|
767
1090
|
childMatches.push(childMatch);
|
|
768
1091
|
}
|
|
769
1092
|
|
|
1093
|
+
if (childMatches.length !== rule.args.length) {
|
|
1094
|
+
if (!isCommutative(node, context) || // exact match in order needed
|
|
1095
|
+
rule.args.length === 1) {
|
|
1096
|
+
// nothing to commute
|
|
1097
|
+
return [];
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
if (rule.args.length > 2) {
|
|
1101
|
+
/* Need to generate all permutations and try them.
|
|
1102
|
+
* It's a bit complicated, and unlikely to come up since there
|
|
1103
|
+
* are very few ternary or higher operators. So punt for now.
|
|
1104
|
+
*/
|
|
1105
|
+
throw new Error('permuting >2 commutative non-associative rule arguments not yet implemented');
|
|
1106
|
+
}
|
|
1107
|
+
/* Exactly two arguments, try them reversed */
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
var leftMatch = _ruleMatch(rule.args[0], node.args[1], context);
|
|
1111
|
+
|
|
1112
|
+
if (leftMatch.length === 0) {
|
|
1113
|
+
return [];
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
var rightMatch = _ruleMatch(rule.args[1], node.args[0], context);
|
|
1117
|
+
|
|
1118
|
+
if (rightMatch.length === 0) {
|
|
1119
|
+
return [];
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
childMatches = [leftMatch, rightMatch];
|
|
1123
|
+
}
|
|
1124
|
+
|
|
770
1125
|
res = mergeChildMatches(childMatches);
|
|
771
1126
|
} else if (node.args.length >= 2 && rule.args.length === 2) {
|
|
772
1127
|
// node is flattened, rule is not
|
|
773
1128
|
// Associative operators/functions can be split in different ways so we check if the rule matches each
|
|
774
1129
|
// them and return their union.
|
|
775
|
-
var splits = getSplits(node,
|
|
1130
|
+
var splits = getSplits(node, context);
|
|
776
1131
|
var splitMatches = [];
|
|
777
1132
|
|
|
778
|
-
for (var
|
|
779
|
-
var matchSet = _ruleMatch(rule, splits[
|
|
1133
|
+
for (var _i2 = 0; _i2 < splits.length; _i2++) {
|
|
1134
|
+
var matchSet = _ruleMatch(rule, splits[_i2], context, true); // recursing at the same tree depth here
|
|
780
1135
|
|
|
781
1136
|
|
|
782
1137
|
splitMatches = splitMatches.concat(matchSet);
|