mathjs 10.1.0 → 10.3.0

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