UNPKG

mathsteps-experimental-fork

Version:

Step by step math solutions. Experimental Fork

155 lines (143 loc) 5.05 kB
'use strict'; Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const config = require('../config.js'); const clone = require('../newServices/nodeServices/clone.js'); const index = require('../node/index.js'); const simplifyCore = require('./simplifyCore.js'); function applyRules(node, poolOfRules, options) { let rv = null; options = options || {}; // Possible improvement: catch many steps at once. const steps = simplifyCore(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 (index.default.Type.isConstant(node)) { // Constant node. Make sure we store value as bignumber. node.value = config.default.bignumber(node.value); } else if (index.default.Type.isUnaryMinus(node) && index.default.Type.isConstant(node.args[0])) { // Negative constant node. // Make sure we store value as bignumber. node = clone(node.args[0]); node.value = config.default.multiply(config.default.bignumber(node.value), -1); } else if (index.default.Type.isFunction(node, 'nthRoot') && !node.args[1]) { // nthRoot(x, null) -> nthRoot(x, 2) node.args[0] = kemuNormalizeConstantNodes(node.args[0]); node.args[1] = index.default.Creator.constant(2); } else if (index.default.Type.isFunction(node, 'log10')) { // log10(x) -> logXY(10, x) node.fn.name = 'logXY'; node.args[1] = kemuNormalizeConstantNodes(node.args[0]); node.args[0] = index.default.Creator.constant(10); } else if (index.default.Type.isFunction(node, 'logE')) { // logE(x) -> logXY(e, x) node.fn.name = 'logXY'; node.args[1] = kemuNormalizeConstantNodes(node.args[0]); node.args[0] = index.default.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 (index.default.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 = index.default.Type.isOperator(x, '+') ? _explodeNodeArgs(x, '+') : [x]; const argsY = index.default.Type.isOperator(y, '+') ? _explodeNodeArgs(y, '+') : [y]; // const ogNumberOfArgs = args.length // Possible improvement: Optimize it. argsY.forEach((item) => { args.push(index.default.Creator.unaryMinus(item)); }); rv = index.default.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) } */ exports.applyRules = applyRules; exports.kemuFlatten = kemuFlatten; exports.kemuNormalizeConstantNodes = kemuNormalizeConstantNodes;