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
|
@@ -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,6 +112,19 @@ 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)
|
|
@@ -140,12 +133,28 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
140
133
|
* An optional `options` argument can be passed as last argument of `simplify`.
|
|
141
134
|
* Currently available options (defaults in parentheses):
|
|
142
135
|
* - `consoleDebug` (false): whether to write the expression being simplified
|
|
143
|
-
|
|
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.)
|
|
144
153
|
* - `exactFractions` (true): whether to try to convert all constants to
|
|
145
|
-
|
|
154
|
+
* exact rational numbers.
|
|
146
155
|
* - `fractionsLimit` (10000): when `exactFractions` is true, constants will
|
|
147
|
-
|
|
148
|
-
|
|
156
|
+
* be expressed as fractions only when both numerator and denominator
|
|
157
|
+
* are smaller than `fractionsLimit`.
|
|
149
158
|
*
|
|
150
159
|
* Syntax:
|
|
151
160
|
*
|
|
@@ -168,7 +177,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
168
177
|
*
|
|
169
178
|
* See also:
|
|
170
179
|
*
|
|
171
|
-
* derivative, parse,
|
|
180
|
+
* simplifyCore, derivative, evaluate, parse, rationalize, resolve
|
|
172
181
|
*
|
|
173
182
|
* @param {Node | string} expr
|
|
174
183
|
* The expression to be simplified
|
|
@@ -217,7 +226,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
217
226
|
},
|
|
218
227
|
'Node, Array, Map, Object': function NodeArrayMapObject(expr, rules, scope, options) {
|
|
219
228
|
var debug = options.consoleDebug;
|
|
220
|
-
rules = _buildRules(rules);
|
|
229
|
+
rules = _buildRules(rules, options.context);
|
|
221
230
|
var res = resolve(expr, scope);
|
|
222
231
|
res = removeParens(res);
|
|
223
232
|
var visited = {};
|
|
@@ -239,8 +248,8 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
239
248
|
res = rules[i](res, options);
|
|
240
249
|
if (debug) rulestr = rules[i].name;
|
|
241
250
|
} else {
|
|
242
|
-
flatten(res);
|
|
243
|
-
res = applyRule(res, rules[i]);
|
|
251
|
+
flatten(res, options.context);
|
|
252
|
+
res = applyRule(res, rules[i], options.context);
|
|
244
253
|
|
|
245
254
|
if (debug) {
|
|
246
255
|
rulestr = "".concat(rules[i].l.toString(), " -> ").concat(rules[i].r.toString());
|
|
@@ -257,8 +266,12 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
257
266
|
laststr = newstr;
|
|
258
267
|
}
|
|
259
268
|
}
|
|
269
|
+
/* Use left-heavy binary tree internally,
|
|
270
|
+
* since custom rule functions may expect it
|
|
271
|
+
*/
|
|
260
272
|
|
|
261
|
-
|
|
273
|
+
|
|
274
|
+
unflattenl(res, options.context);
|
|
262
275
|
}
|
|
263
276
|
|
|
264
277
|
str = res.toString({
|
|
@@ -269,8 +282,9 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
269
282
|
return res;
|
|
270
283
|
}
|
|
271
284
|
});
|
|
272
|
-
simplify.
|
|
273
|
-
simplify.
|
|
285
|
+
simplify.defaultContext = defaultContext;
|
|
286
|
+
simplify.realContext = realContext;
|
|
287
|
+
simplify.positiveContext = positiveContext;
|
|
274
288
|
|
|
275
289
|
function removeParens(node) {
|
|
276
290
|
return node.transform(function (node, path, parent) {
|
|
@@ -280,8 +294,8 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
280
294
|
|
|
281
295
|
|
|
282
296
|
var SUPPORTED_CONSTANTS = {
|
|
283
|
-
|
|
284
|
-
|
|
297
|
+
true: true,
|
|
298
|
+
false: true,
|
|
285
299
|
e: true,
|
|
286
300
|
i: true,
|
|
287
301
|
Infinity: true,
|
|
@@ -322,41 +336,155 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
322
336
|
// Note initially we tend constants to the right because like-term
|
|
323
337
|
// collection prefers the left, and we would rather collect nonconstants
|
|
324
338
|
{
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
{
|
|
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
|
+
}, {
|
|
333
391
|
l: '-v',
|
|
334
392
|
r: 'v * (-1)'
|
|
335
|
-
},
|
|
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
|
+
{
|
|
336
400
|
l: 'n/n1^n2',
|
|
337
401
|
r: 'n*n1^-n2'
|
|
338
402
|
}, // temporarily replace 'divide' so we can further flatten the 'multiply' operator
|
|
339
403
|
{
|
|
340
404
|
l: 'n/n1',
|
|
341
405
|
r: 'n*n1^-1'
|
|
342
|
-
},
|
|
406
|
+
}, {
|
|
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
|
+
}
|
|
420
|
+
}, // expand nested exponentiation
|
|
343
421
|
{
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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
|
|
347
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
|
+
}, {
|
|
348
456
|
l: 'n*n',
|
|
349
457
|
r: 'n^2'
|
|
350
458
|
}, {
|
|
351
|
-
|
|
352
|
-
|
|
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
|
+
|
|
353
466
|
}, {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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
|
|
357
480
|
{
|
|
358
|
-
|
|
359
|
-
|
|
481
|
+
s: 'n+n -> 2*n',
|
|
482
|
+
assuming: {
|
|
483
|
+
add: {
|
|
484
|
+
total: true
|
|
485
|
+
}
|
|
486
|
+
} // 2 = 1 + 1 needs to exist
|
|
487
|
+
|
|
360
488
|
}, {
|
|
361
489
|
l: 'n+-n',
|
|
362
490
|
r: '0'
|
|
@@ -369,33 +497,91 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
369
497
|
r: 'n3*(n1+n2)'
|
|
370
498
|
}, // All sub-monomials tried there.
|
|
371
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
|
+
}, {
|
|
372
535
|
l: 'n*c + c',
|
|
373
536
|
r: '(n+1)*c'
|
|
374
|
-
},
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
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')
|
|
383
546
|
{
|
|
384
|
-
|
|
385
|
-
|
|
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
|
+
}
|
|
386
564
|
}, // final ordering of constants
|
|
387
565
|
{
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
566
|
+
s: 'c+v -> v+c',
|
|
567
|
+
assuming: {
|
|
568
|
+
add: {
|
|
569
|
+
commutative: true
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
imposeContext: {
|
|
391
573
|
add: {
|
|
392
574
|
commutative: false
|
|
393
575
|
}
|
|
394
576
|
}
|
|
395
577
|
}, {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
578
|
+
s: 'v*c -> c*v',
|
|
579
|
+
assuming: {
|
|
580
|
+
multiply: {
|
|
581
|
+
commutative: true
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
imposeContext: {
|
|
399
585
|
multiply: {
|
|
400
586
|
commutative: false
|
|
401
587
|
}
|
|
@@ -407,36 +593,127 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
407
593
|
r: 'n-n1'
|
|
408
594
|
}, // undo replace 'subtract'
|
|
409
595
|
{
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
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
|
+
|
|
416
604
|
}, {
|
|
417
|
-
|
|
418
|
-
|
|
605
|
+
s: 'n*n1^-n2 -> n/n1^n2',
|
|
606
|
+
assuming: {
|
|
607
|
+
multiply: {
|
|
608
|
+
commutative: true
|
|
609
|
+
}
|
|
610
|
+
} // o.w. / not conventional
|
|
611
|
+
|
|
419
612
|
}, {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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
|
|
423
624
|
{
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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)' },
|
|
428
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
|
|
429
645
|
{
|
|
430
646
|
l: '1*n',
|
|
431
|
-
r: 'n'
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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
|
+
}
|
|
436
660
|
}, {
|
|
437
661
|
l: 'n1/(-n2)',
|
|
438
662
|
r: '-n1/n2'
|
|
439
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
|
+
}
|
|
440
717
|
/**
|
|
441
718
|
* Parse the string array of rules into nodes
|
|
442
719
|
*
|
|
@@ -454,60 +731,26 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
454
731
|
* 'n1 * c1 -> c1 * n1'
|
|
455
732
|
*/
|
|
456
733
|
|
|
457
|
-
|
|
734
|
+
|
|
735
|
+
function _buildRules(rules, context) {
|
|
458
736
|
// Array of rules to be used to simplify expressions
|
|
459
737
|
var ruleSet = [];
|
|
460
738
|
|
|
461
739
|
for (var i = 0; i < rules.length; i++) {
|
|
462
740
|
var rule = rules[i];
|
|
463
741
|
var newRule = void 0;
|
|
464
|
-
var ruleType = (0, _typeof2
|
|
742
|
+
var ruleType = (0, _typeof2.default)(rule);
|
|
465
743
|
|
|
466
744
|
switch (ruleType) {
|
|
467
745
|
case 'string':
|
|
468
|
-
{
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
if (lr.length === 2) {
|
|
472
|
-
rule = {
|
|
473
|
-
l: lr[0],
|
|
474
|
-
r: lr[1]
|
|
475
|
-
};
|
|
476
|
-
} else {
|
|
477
|
-
throw SyntaxError('Could not parse rule: ' + rule);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
746
|
+
rule = {
|
|
747
|
+
s: rule
|
|
748
|
+
};
|
|
480
749
|
|
|
481
750
|
/* falls through */
|
|
482
751
|
|
|
483
752
|
case 'object':
|
|
484
|
-
newRule =
|
|
485
|
-
l: removeParens(parse(rule.l)),
|
|
486
|
-
r: removeParens(parse(rule.r))
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
if (rule.context) {
|
|
490
|
-
newRule.context = rule.context;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
if (rule.evaluate) {
|
|
494
|
-
newRule.evaluate = parse(rule.evaluate);
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
if (isAssociative(newRule.l)) {
|
|
498
|
-
var makeNode = createMakeNodeFunction(newRule.l);
|
|
499
|
-
|
|
500
|
-
var expandsym = _getExpandPlaceholderSymbol();
|
|
501
|
-
|
|
502
|
-
newRule.expanded = {};
|
|
503
|
-
newRule.expanded.l = makeNode([newRule.l.clone(), expandsym]); // Push the expandsym into the deepest possible branch.
|
|
504
|
-
// This helps to match the newRule against nodes returned from getSplits() later on.
|
|
505
|
-
|
|
506
|
-
flatten(newRule.expanded.l);
|
|
507
|
-
unflattenr(newRule.expanded.l);
|
|
508
|
-
newRule.expanded.r = makeNode([newRule.r, expandsym]);
|
|
509
|
-
}
|
|
510
|
-
|
|
753
|
+
newRule = _canonicalizeRule(rule, context);
|
|
511
754
|
break;
|
|
512
755
|
|
|
513
756
|
case 'function':
|
|
@@ -532,90 +775,155 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
532
775
|
return new SymbolNode('_p' + _lastsym++);
|
|
533
776
|
}
|
|
534
777
|
|
|
535
|
-
function mapRule(nodes, rule) {
|
|
778
|
+
function mapRule(nodes, rule, context) {
|
|
779
|
+
var resNodes = nodes;
|
|
780
|
+
|
|
536
781
|
if (nodes) {
|
|
537
782
|
for (var i = 0; i < nodes.length; ++i) {
|
|
538
|
-
|
|
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
|
+
}
|
|
539
792
|
}
|
|
540
793
|
}
|
|
794
|
+
|
|
795
|
+
return resNodes;
|
|
541
796
|
}
|
|
542
797
|
/**
|
|
543
798
|
* Returns a simplfied form of node, or the original node if no simplification was possible.
|
|
544
799
|
*
|
|
545
800
|
* @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} node
|
|
801
|
+
* @param {Object | Function} rule
|
|
802
|
+
* @param {Object} context -- information about assumed properties of operators
|
|
546
803
|
* @return {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} The simplified form of `expr`, or the original node if no simplification was possible.
|
|
547
804
|
*/
|
|
548
805
|
|
|
549
806
|
|
|
550
|
-
|
|
551
|
-
'
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
} else if (res instanceof ParenthesisNode) {
|
|
561
|
-
if (res.content) {
|
|
562
|
-
res.content = applyRule(res.content, rule);
|
|
563
|
-
}
|
|
564
|
-
} else if (res instanceof ArrayNode) {
|
|
565
|
-
mapRule(res.items, rule);
|
|
566
|
-
} else if (res instanceof AccessorNode) {
|
|
567
|
-
if (res.object) {
|
|
568
|
-
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
|
+
}
|
|
569
817
|
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
570
820
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
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);
|
|
579
840
|
}
|
|
580
|
-
}
|
|
841
|
+
}
|
|
842
|
+
} else if (res instanceof ArrayNode) {
|
|
843
|
+
var newItems = mapRule(res.items, rule, context);
|
|
581
844
|
|
|
845
|
+
if (newItems !== res.items) {
|
|
846
|
+
res = new ArrayNode(newItems);
|
|
847
|
+
}
|
|
848
|
+
} else if (res instanceof AccessorNode) {
|
|
849
|
+
var newObj = res.object;
|
|
582
850
|
|
|
583
|
-
|
|
851
|
+
if (res.object) {
|
|
852
|
+
newObj = applyRule(res.object, rule, context);
|
|
853
|
+
}
|
|
584
854
|
|
|
585
|
-
var
|
|
586
|
-
// 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;
|
|
587
856
|
|
|
857
|
+
if (res.index) {
|
|
858
|
+
newIndex = applyRule(res.index, rule, context);
|
|
859
|
+
}
|
|
588
860
|
|
|
589
|
-
if (
|
|
590
|
-
|
|
591
|
-
matches = _ruleMatch(rule.expanded.l, res)[0];
|
|
861
|
+
if (newObj !== res.object || newIndex !== res.index) {
|
|
862
|
+
res = new AccessorNode(newObj, newIndex);
|
|
592
863
|
}
|
|
864
|
+
} else if (res instanceof IndexNode) {
|
|
865
|
+
var newDims = mapRule(res.dimensions, rule, context);
|
|
593
866
|
|
|
594
|
-
if (
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
867
|
+
if (newDims !== res.dimensions) {
|
|
868
|
+
res = new IndexNode(newDims);
|
|
869
|
+
}
|
|
870
|
+
} else if (res instanceof ObjectNode) {
|
|
871
|
+
var changed = false;
|
|
872
|
+
var newProps = {};
|
|
600
873
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
} // 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);
|
|
604
876
|
|
|
877
|
+
if (newProps[prop] !== res.properties[prop]) {
|
|
878
|
+
changed = true;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
605
881
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
return matches.placeholders[node.name].clone();
|
|
609
|
-
} else {
|
|
610
|
-
return node;
|
|
611
|
-
}
|
|
612
|
-
}); // const after = res.toString({parenthesis: 'all'})
|
|
613
|
-
// console.log('Simplified ' + before + ' to ' + after)
|
|
882
|
+
if (changed) {
|
|
883
|
+
res = new ObjectNode(newProps);
|
|
614
884
|
}
|
|
885
|
+
} // Try to match a rule against this node
|
|
615
886
|
|
|
616
|
-
|
|
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];
|
|
617
897
|
}
|
|
618
|
-
|
|
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
|
+
}
|
|
619
927
|
/**
|
|
620
928
|
* Get (binary) combinations of a flattened binary node
|
|
621
929
|
* e.g. +(node1, node2, node3) -> [
|
|
@@ -625,6 +933,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
625
933
|
*
|
|
626
934
|
*/
|
|
627
935
|
|
|
936
|
+
|
|
628
937
|
function getSplits(node, context) {
|
|
629
938
|
var res = [];
|
|
630
939
|
var right, rightArgs;
|
|
@@ -638,9 +947,18 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
638
947
|
res.push(makeNode([node.args[i], right]));
|
|
639
948
|
}
|
|
640
949
|
} else {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
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
|
+
}
|
|
644
962
|
}
|
|
645
963
|
|
|
646
964
|
return res;
|
|
@@ -743,15 +1061,19 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
743
1061
|
*
|
|
744
1062
|
* @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} rule
|
|
745
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.
|
|
746
1068
|
* @return {Object} Information about the match, if it exists.
|
|
747
1069
|
*/
|
|
748
1070
|
|
|
749
1071
|
|
|
750
|
-
function _ruleMatch(rule, node, isSplit) {
|
|
1072
|
+
function _ruleMatch(rule, node, context, isSplit) {
|
|
751
1073
|
// console.log('Entering _ruleMatch(' + JSON.stringify(rule) + ', ' + JSON.stringify(node) + ')')
|
|
752
1074
|
// console.log('rule = ' + rule)
|
|
753
1075
|
// console.log('node = ' + node)
|
|
754
|
-
// console.log('Entering _ruleMatch('
|
|
1076
|
+
// console.log('Entering _ruleMatch(', rule.toString({parenthesis:'all'}), ', ', node.toString({parenthesis:'all'}), ', ', context, ')')
|
|
755
1077
|
var res = [{
|
|
756
1078
|
placeholders: {}
|
|
757
1079
|
}];
|
|
@@ -769,32 +1091,65 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
|
|
|
769
1091
|
} // rule and node match. Search the children of rule and node.
|
|
770
1092
|
|
|
771
1093
|
|
|
772
|
-
if (node.args.length === 1 && rule.args.length === 1 || !isAssociative(node) && node.args.length === rule.args.length || isSplit) {
|
|
773
|
-
// 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
|
|
774
1097
|
var childMatches = [];
|
|
775
1098
|
|
|
776
1099
|
for (var i = 0; i < rule.args.length; i++) {
|
|
777
|
-
var childMatch = _ruleMatch(rule.args[i], node.args[i]);
|
|
1100
|
+
var childMatch = _ruleMatch(rule.args[i], node.args[i], context);
|
|
778
1101
|
|
|
779
1102
|
if (childMatch.length === 0) {
|
|
780
1103
|
// Child did not match, so stop searching immediately
|
|
781
|
-
|
|
1104
|
+
break;
|
|
782
1105
|
} // The child matched, so add the information returned from the child to our result
|
|
783
1106
|
|
|
784
1107
|
|
|
785
1108
|
childMatches.push(childMatch);
|
|
786
1109
|
}
|
|
787
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
|
+
|
|
788
1143
|
res = mergeChildMatches(childMatches);
|
|
789
1144
|
} else if (node.args.length >= 2 && rule.args.length === 2) {
|
|
790
1145
|
// node is flattened, rule is not
|
|
791
1146
|
// Associative operators/functions can be split in different ways so we check if the rule matches each
|
|
792
1147
|
// them and return their union.
|
|
793
|
-
var splits = getSplits(node,
|
|
1148
|
+
var splits = getSplits(node, context);
|
|
794
1149
|
var splitMatches = [];
|
|
795
1150
|
|
|
796
|
-
for (var
|
|
797
|
-
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
|
|
798
1153
|
|
|
799
1154
|
|
|
800
1155
|
splitMatches = splitMatches.concat(matchSet);
|