simplifyCore.js (8533B)
1 "use strict"; 2 3 Object.defineProperty(exports, "__esModule", { 4 value: true 5 }); 6 exports.createSimplifyCore = void 0; 7 8 var _is = require("../../utils/is.js"); 9 10 var _util = require("./simplify/util.js"); 11 12 var _factory = require("../../utils/factory.js"); 13 14 var name = 'simplifyCore'; 15 var dependencies = ['equal', 'isZero', 'add', 'subtract', 'multiply', 'divide', 'pow', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'ParenthesisNode', 'SymbolNode']; 16 var createSimplifyCore = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) { 17 var equal = _ref.equal, 18 isZero = _ref.isZero, 19 add = _ref.add, 20 subtract = _ref.subtract, 21 multiply = _ref.multiply, 22 divide = _ref.divide, 23 pow = _ref.pow, 24 AccessorNode = _ref.AccessorNode, 25 ArrayNode = _ref.ArrayNode, 26 ConstantNode = _ref.ConstantNode, 27 FunctionNode = _ref.FunctionNode, 28 IndexNode = _ref.IndexNode, 29 ObjectNode = _ref.ObjectNode, 30 OperatorNode = _ref.OperatorNode, 31 ParenthesisNode = _ref.ParenthesisNode, 32 SymbolNode = _ref.SymbolNode; 33 var node0 = new ConstantNode(0); 34 var node1 = new ConstantNode(1); 35 36 var _createUtil = (0, _util.createUtil)({ 37 FunctionNode: FunctionNode, 38 OperatorNode: OperatorNode, 39 SymbolNode: SymbolNode 40 }), 41 hasProperty = _createUtil.hasProperty, 42 isCommutative = _createUtil.isCommutative; 43 /** 44 * simplifyCore() performs single pass simplification suitable for 45 * applications requiring ultimate performance. In contrast, simplify() 46 * extends simplifyCore() with additional passes to provide deeper 47 * simplification. 48 * 49 * Syntax: 50 * 51 * simplifyCore(expr) 52 * 53 * Examples: 54 * 55 * const f = math.parse('2 * 1 * x ^ (2 - 1)') 56 * math.simpifyCore(f) // Node {2 * x} 57 * math.simplify('2 * 1 * x ^ (2 - 1)', [math.simplifyCore]) // Node {2 * x} 58 * 59 * See also: 60 * 61 * simplify, resolve, derivative 62 * 63 * @param {Node} node 64 * The expression to be simplified 65 * @param {Object} options 66 * Simplification options, as per simplify() 67 * @return {Node} Returns expression with basic simplifications applied 68 */ 69 70 71 function simplifyCore(node, options) { 72 var context = options ? options.context : undefined; 73 74 if (hasProperty(node, 'trivial', context)) { 75 // This node does nothing if it has only one argument, so if so, 76 // return that argument simplified 77 if ((0, _is.isFunctionNode)(node) && node.args.length === 1) { 78 return simplifyCore(node.args[0], options); 79 } // For other node types, we try the generic methods 80 81 82 var simpChild = false; 83 var childCount = 0; 84 node.forEach(function (c) { 85 ++childCount; 86 87 if (childCount === 1) { 88 simpChild = simplifyCore(c, options); 89 } 90 }); 91 92 if (childCount === 1) { 93 return simpChild; 94 } 95 } 96 97 if ((0, _is.isOperatorNode)(node) && node.isUnary()) { 98 var a0 = simplifyCore(node.args[0], options); 99 100 if (node.op === '-') { 101 // unary minus 102 if ((0, _is.isOperatorNode)(a0)) { 103 if (a0.isUnary() && a0.op === '-') { 104 return a0.args[0]; 105 } else if (a0.isBinary() && a0.fn === 'subtract') { 106 return new OperatorNode('-', 'subtract', [a0.args[1], a0.args[0]]); 107 } 108 } 109 110 return new OperatorNode(node.op, node.fn, [a0]); 111 } 112 } else if ((0, _is.isOperatorNode)(node) && node.isBinary()) { 113 var _a = simplifyCore(node.args[0], options); 114 115 var a1 = simplifyCore(node.args[1], options); 116 117 if (node.op === '+') { 118 if ((0, _is.isConstantNode)(_a)) { 119 if (isZero(_a.value)) { 120 return a1; 121 } else if ((0, _is.isConstantNode)(a1)) { 122 return new ConstantNode(add(_a.value, a1.value)); 123 } 124 } 125 126 if ((0, _is.isConstantNode)(a1) && isZero(a1.value)) { 127 return _a; 128 } 129 130 if ((0, _is.isOperatorNode)(a1) && a1.isUnary() && a1.op === '-') { 131 return new OperatorNode('-', 'subtract', [_a, a1.args[0]]); 132 } 133 134 return new OperatorNode(node.op, node.fn, a1 ? [_a, a1] : [_a]); 135 } else if (node.op === '-') { 136 if ((0, _is.isConstantNode)(_a) && a1) { 137 if ((0, _is.isConstantNode)(a1)) { 138 return new ConstantNode(subtract(_a.value, a1.value)); 139 } else if (isZero(_a.value)) { 140 return new OperatorNode('-', 'unaryMinus', [a1]); 141 } 142 } // if (node.fn === "subtract" && node.args.length === 2) { 143 144 145 if (node.fn === 'subtract') { 146 if ((0, _is.isConstantNode)(a1) && isZero(a1.value)) { 147 return _a; 148 } 149 150 if ((0, _is.isOperatorNode)(a1) && a1.isUnary() && a1.op === '-') { 151 return simplifyCore(new OperatorNode('+', 'add', [_a, a1.args[0]]), options); 152 } 153 154 return new OperatorNode(node.op, node.fn, [_a, a1]); 155 } 156 } else if (node.op === '*') { 157 if ((0, _is.isConstantNode)(_a)) { 158 if (isZero(_a.value)) { 159 return node0; 160 } else if (equal(_a.value, 1)) { 161 return a1; 162 } else if ((0, _is.isConstantNode)(a1)) { 163 return new ConstantNode(multiply(_a.value, a1.value)); 164 } 165 } 166 167 if ((0, _is.isConstantNode)(a1)) { 168 if (isZero(a1.value)) { 169 return node0; 170 } else if (equal(a1.value, 1)) { 171 return _a; 172 } else if ((0, _is.isOperatorNode)(_a) && _a.isBinary() && _a.op === node.op && isCommutative(node, context)) { 173 var a00 = _a.args[0]; 174 175 if ((0, _is.isConstantNode)(a00)) { 176 var a00a1 = new ConstantNode(multiply(a00.value, a1.value)); 177 return new OperatorNode(node.op, node.fn, [a00a1, _a.args[1]], node.implicit); // constants on left 178 } 179 } 180 181 if (isCommutative(node, context)) { 182 return new OperatorNode(node.op, node.fn, [a1, _a], node.implicit); // constants on left 183 } else { 184 return new OperatorNode(node.op, node.fn, [_a, a1], node.implicit); 185 } 186 } 187 188 return new OperatorNode(node.op, node.fn, [_a, a1], node.implicit); 189 } else if (node.op === '/') { 190 if ((0, _is.isConstantNode)(_a)) { 191 if (isZero(_a.value)) { 192 return node0; 193 } else if ((0, _is.isConstantNode)(a1) && (equal(a1.value, 1) || equal(a1.value, 2) || equal(a1.value, 4))) { 194 return new ConstantNode(divide(_a.value, a1.value)); 195 } 196 } 197 198 return new OperatorNode(node.op, node.fn, [_a, a1]); 199 } else if (node.op === '^') { 200 if ((0, _is.isConstantNode)(a1)) { 201 if (isZero(a1.value)) { 202 return node1; 203 } else if (equal(a1.value, 1)) { 204 return _a; 205 } else { 206 if ((0, _is.isConstantNode)(_a)) { 207 // fold constant 208 return new ConstantNode(pow(_a.value, a1.value)); 209 } else if ((0, _is.isOperatorNode)(_a) && _a.isBinary() && _a.op === '^') { 210 var a01 = _a.args[1]; 211 212 if ((0, _is.isConstantNode)(a01)) { 213 return new OperatorNode(node.op, node.fn, [_a.args[0], new ConstantNode(multiply(a01.value, a1.value))]); 214 } 215 } 216 } 217 } 218 } 219 220 return new OperatorNode(node.op, node.fn, [_a, a1]); 221 } else if ((0, _is.isFunctionNode)(node)) { 222 return new FunctionNode(simplifyCore(node.fn), node.args.map(function (n) { 223 return simplifyCore(n, options); 224 })); 225 } else if ((0, _is.isArrayNode)(node)) { 226 return new ArrayNode(node.items.map(function (n) { 227 return simplifyCore(n, options); 228 })); 229 } else if ((0, _is.isAccessorNode)(node)) { 230 return new AccessorNode(simplifyCore(node.object, options), simplifyCore(node.index, options)); 231 } else if ((0, _is.isIndexNode)(node)) { 232 return new IndexNode(node.dimensions.map(function (n) { 233 return simplifyCore(n, options); 234 })); 235 } else if ((0, _is.isObjectNode)(node)) { 236 var newProps = {}; 237 238 for (var prop in node.properties) { 239 newProps[prop] = simplifyCore(node.properties[prop], options); 240 } 241 242 return new ObjectNode(newProps); 243 } else {// cannot simplify 244 } 245 246 return node; 247 } 248 249 return simplifyCore; 250 }); 251 exports.createSimplifyCore = createSimplifyCore;