util.js (8554B)
1 "use strict"; 2 3 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); 4 5 Object.defineProperty(exports, "__esModule", { 6 value: true 7 }); 8 exports.createUtil = void 0; 9 10 var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); 11 12 var _is = require("../../../utils/is.js"); 13 14 var _factory = require("../../../utils/factory.js"); 15 16 var _object = require("../../../utils/object.js"); 17 18 function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } 19 20 function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } 21 22 var name = 'simplifyUtil'; 23 var dependencies = ['FunctionNode', 'OperatorNode', 'SymbolNode']; 24 var createUtil = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) { 25 var FunctionNode = _ref.FunctionNode, 26 OperatorNode = _ref.OperatorNode, 27 SymbolNode = _ref.SymbolNode; 28 // TODO commutative/associative properties rely on the arguments 29 // e.g. multiply is not commutative for matrices 30 // The properties should be calculated from an argument to simplify, or possibly something in math.config 31 // the other option is for typed() to specify a return type so that we can evaluate the type of arguments 32 33 /* So that properties of an operator fit on one line: */ 34 var T = true; 35 var F = false; 36 var defaultName = 'defaultF'; 37 var defaultContext = { 38 /* */ 39 add: { 40 trivial: T, 41 total: T, 42 commutative: T, 43 associative: T 44 }, 45 46 /**/ 47 unaryPlus: { 48 trivial: T, 49 total: T, 50 commutative: T, 51 associative: T 52 }, 53 54 /* */ 55 subtract: { 56 trivial: F, 57 total: T, 58 commutative: F, 59 associative: F 60 }, 61 62 /* */ 63 multiply: { 64 trivial: T, 65 total: T, 66 commutative: T, 67 associative: T 68 }, 69 70 /* */ 71 divide: { 72 trivial: F, 73 total: T, 74 commutative: F, 75 associative: F 76 }, 77 78 /* */ 79 paren: { 80 trivial: T, 81 total: T, 82 commutative: T, 83 associative: F 84 }, 85 86 /* */ 87 defaultF: { 88 trivial: F, 89 total: T, 90 commutative: F, 91 associative: F 92 } 93 }; 94 var realContext = { 95 divide: { 96 total: F 97 }, 98 log: { 99 total: F 100 } 101 }; 102 var positiveContext = { 103 subtract: { 104 total: F 105 }, 106 abs: { 107 trivial: T 108 }, 109 log: { 110 total: T 111 } 112 }; 113 114 function hasProperty(nodeOrName, property) { 115 var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultContext; 116 var name = defaultName; 117 118 if (typeof nodeOrName === 'string') { 119 name = nodeOrName; 120 } else if ((0, _is.isOperatorNode)(nodeOrName)) { 121 name = nodeOrName.fn.toString(); 122 } else if ((0, _is.isFunctionNode)(nodeOrName)) { 123 name = nodeOrName.name; 124 } else if ((0, _is.isParenthesisNode)(nodeOrName)) { 125 name = 'paren'; 126 } 127 128 if ((0, _object.hasOwnProperty)(context, name)) { 129 var properties = context[name]; 130 131 if ((0, _object.hasOwnProperty)(properties, property)) { 132 return properties[property]; 133 } 134 135 if ((0, _object.hasOwnProperty)(defaultContext, name)) { 136 return defaultContext[name][property]; 137 } 138 } 139 140 if ((0, _object.hasOwnProperty)(context, defaultName)) { 141 var _properties = context[defaultName]; 142 143 if ((0, _object.hasOwnProperty)(_properties, property)) { 144 return _properties[property]; 145 } 146 147 return defaultContext[defaultName][property]; 148 } 149 /* name not found in context and context has no global default */ 150 151 /* So use default context. */ 152 153 154 if ((0, _object.hasOwnProperty)(defaultContext, name)) { 155 var _properties2 = defaultContext[name]; 156 157 if ((0, _object.hasOwnProperty)(_properties2, property)) { 158 return _properties2[property]; 159 } 160 } 161 162 return defaultContext[defaultName][property]; 163 } 164 165 function isCommutative(node) { 166 var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultContext; 167 return hasProperty(node, 'commutative', context); 168 } 169 170 function isAssociative(node) { 171 var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultContext; 172 return hasProperty(node, 'associative', context); 173 } 174 /** 175 * Merge the given contexts, with primary overriding secondary 176 * wherever they might conflict 177 */ 178 179 180 function mergeContext(primary, secondary) { 181 var merged = _objectSpread({}, primary); 182 183 for (var prop in secondary) { 184 if ((0, _object.hasOwnProperty)(primary, prop)) { 185 merged[prop] = _objectSpread(_objectSpread({}, secondary[prop]), primary[prop]); 186 } else { 187 merged[prop] = secondary[prop]; 188 } 189 } 190 191 return merged; 192 } 193 /** 194 * Flatten all associative operators in an expression tree. 195 * Assumes parentheses have already been removed. 196 */ 197 198 199 function flatten(node, context) { 200 if (!node.args || node.args.length === 0) { 201 return node; 202 } 203 204 node.args = allChildren(node, context); 205 206 for (var i = 0; i < node.args.length; i++) { 207 flatten(node.args[i], context); 208 } 209 } 210 /** 211 * Get the children of a node as if it has been flattened. 212 * TODO implement for FunctionNodes 213 */ 214 215 216 function allChildren(node, context) { 217 var op; 218 var children = []; 219 220 var findChildren = function findChildren(node) { 221 for (var i = 0; i < node.args.length; i++) { 222 var child = node.args[i]; 223 224 if ((0, _is.isOperatorNode)(child) && op === child.op) { 225 findChildren(child); 226 } else { 227 children.push(child); 228 } 229 } 230 }; 231 232 if (isAssociative(node, context)) { 233 op = node.op; 234 findChildren(node); 235 return children; 236 } else { 237 return node.args; 238 } 239 } 240 /** 241 * Unflatten all flattened operators to a right-heavy binary tree. 242 */ 243 244 245 function unflattenr(node, context) { 246 if (!node.args || node.args.length === 0) { 247 return; 248 } 249 250 var makeNode = createMakeNodeFunction(node); 251 var l = node.args.length; 252 253 for (var i = 0; i < l; i++) { 254 unflattenr(node.args[i], context); 255 } 256 257 if (l > 2 && isAssociative(node, context)) { 258 var curnode = node.args.pop(); 259 260 while (node.args.length > 0) { 261 curnode = makeNode([node.args.pop(), curnode]); 262 } 263 264 node.args = curnode.args; 265 } 266 } 267 /** 268 * Unflatten all flattened operators to a left-heavy binary tree. 269 */ 270 271 272 function unflattenl(node, context) { 273 if (!node.args || node.args.length === 0) { 274 return; 275 } 276 277 var makeNode = createMakeNodeFunction(node); 278 var l = node.args.length; 279 280 for (var i = 0; i < l; i++) { 281 unflattenl(node.args[i], context); 282 } 283 284 if (l > 2 && isAssociative(node, context)) { 285 var curnode = node.args.shift(); 286 287 while (node.args.length > 0) { 288 curnode = makeNode([curnode, node.args.shift()]); 289 } 290 291 node.args = curnode.args; 292 } 293 } 294 295 function createMakeNodeFunction(node) { 296 if ((0, _is.isOperatorNode)(node)) { 297 return function (args) { 298 try { 299 return new OperatorNode(node.op, node.fn, args, node.implicit); 300 } catch (err) { 301 console.error(err); 302 return []; 303 } 304 }; 305 } else { 306 return function (args) { 307 return new FunctionNode(new SymbolNode(node.name), args); 308 }; 309 } 310 } 311 312 return { 313 createMakeNodeFunction: createMakeNodeFunction, 314 hasProperty: hasProperty, 315 isCommutative: isCommutative, 316 isAssociative: isAssociative, 317 mergeContext: mergeContext, 318 flatten: flatten, 319 allChildren: allChildren, 320 unflattenr: unflattenr, 321 unflattenl: unflattenl, 322 defaultContext: defaultContext, 323 realContext: realContext, 324 positiveContext: positiveContext 325 }; 326 }); 327 exports.createUtil = createUtil;