UNPKG

mathsteps-experimental-fork

Version:

Step by step math solutions. Experimental Fork

149 lines (139 loc) 4.7 kB
import math from '../config.js'; import clone from '../newServices/nodeServices/clone.js'; import Node from '../node/index.js'; import simplify from './simplifyCore.js'; function applyRules(node, poolOfRules, options) { let rv = null; options = options || {}; // Possible improvement: catch many steps at once. const steps = simplify(node, poolOfRules, null, { ...options, stopOnFirstStep: true }); if (steps.length > 0) { const oneStep = steps[0]; if (oneStep.isMistake) oneStep.nodeAfter.isMistake = true; rv = { changeType: oneStep.ruleApplied.id, rootNode: oneStep.nodeAfter, mistakes: oneStep?.mistakes?.map(oneRes => ({ changeType: oneRes.ruleApplied.id, rootNode: oneRes.nodeAfter, isMistake: true })), isMistake: oneStep.isMistake, }; } return rv } // Make sure we store all constant nodes as bignumber to avoid fake unequals. function kemuNormalizeConstantNodes(node) { if (node == null) ; else if (node.type === 'ParenthesisNode') { // (...) - enter into node. node = kemuNormalizeConstantNodes(node.content); } else if (Node.Type.isConstant(node)) { // Constant node. Make sure we store value as bignumber. node.value = math.bignumber(node.value); } else if (Node.Type.isUnaryMinus(node) && Node.Type.isConstant(node.args[0])) { // Negative constant node. // Make sure we store value as bignumber. node = clone(node.args[0]); node.value = math.multiply(math.bignumber(node.value), -1); } else if (Node.Type.isFunction(node, 'nthRoot') && !node.args[1]) { // nthRoot(x, null) -> nthRoot(x, 2) node.args[0] = kemuNormalizeConstantNodes(node.args[0]); node.args[1] = Node.Creator.constant(2); } else if (Node.Type.isFunction(node, 'log10')) { // log10(x) -> logXY(10, x) node.fn.name = 'logXY'; node.args[1] = kemuNormalizeConstantNodes(node.args[0]); node.args[0] = Node.Creator.constant(10); } else if (Node.Type.isFunction(node, 'logE')) { // logE(x) -> logXY(e, x) node.fn.name = 'logXY'; node.args[1] = kemuNormalizeConstantNodes(node.args[0]); node.args[0] = Node.Creator.kemuCreateBuiltInConstant('e'); } else { // Non constant-node. Go on recurisively if possible. if (node.args) { node.args.forEach((childNode, idx) => { node.args[idx] = kemuNormalizeConstantNodes(childNode); }); } } return node } function _explodeNodeArgs(node, op) { // [2x, a, b] gives [2, x, a, b] let rv = []; node.args.forEach((oneArg) => { if (oneArg.op === op) rv = rv.concat(_explodeNodeArgs(oneArg, op)); else rv.push(oneArg); }); return rv } function kemuFlatten(node, options = { keepSubtraction: false }) { let rv = node; if (node.args) { // Flatten args recursively. node.args.forEach((oneChild, idx) => { node.args[idx] = kemuFlatten(oneChild); }); if (Node.Type.isOperator(node)) { switch (node.op) { case '*': case '+': { // Flatten nested multiply/add e.g. (3*x)*y =>3*x*y node.args = _explodeNodeArgs(node, node.op); break } case '-': { if (options.keepSubtraction) { break } // Convert a-b to a+(-b). const x = node.args[0]; const y = node.args[1]; const args = Node.Type.isOperator(x, '+') ? _explodeNodeArgs(x, '+') : [x]; const argsY = Node.Type.isOperator(y, '+') ? _explodeNodeArgs(y, '+') : [y]; // const ogNumberOfArgs = args.length // Possible improvement: Optimize it. argsY.forEach((item) => { args.push(Node.Creator.unaryMinus(item)); }); rv = Node.Creator.operator('+', args); // const argsAfterOgNumberOfArgs = args.slice(ogNumberOfArgs) // argsAfterOgNumberOfArgs.forEach((item) => { // item.wasInitiallySubtractedBy = myNodeToString(x) // }) break } } } } return rv } /* const deepIdx = 0 KEMU OLD function logEnter(msg) { if (process) process.stdout.write(`${' '.repeat(deepIdx * 2)}-> `) console.log.apply(console, arguments) deepIdx++ } function logLeave() { deepIdx-- if (process) process.stdout.write(`${' '.repeat(deepIdx * 2)}<- `) console.log.apply(console, arguments) } function log() { if (process) process.stdout.write(' '.repeat(deepIdx * 2)) console.log.apply(console, arguments) } */ export { applyRules, kemuFlatten, kemuNormalizeConstantNodes };