mathsteps-experimental-fork
Version:
Step by step math solutions. Experimental Fork
117 lines (112 loc) • 4.51 kB
JavaScript
'use strict';
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const config = require('../../config.js');
const index = require('../../node/index.js');
const Equation = require('../Equation.js');
const NODE_ZERO = index.default.Creator.constant(0);
const fParenX_EQ_C = {
id: 'fParenX_EQ_C',
pattern: 'f(x)=C',
solveFunction: (equation, EquationSolver) => {
// Apply common rules.
const poolOfRules = [
// Common rules.
{ l: 'EQ(fx^a , 0)', r: 'EQ(fx , 0)', id: 'remove_pow' },
{ l: 'EQ(fx1/fx , a2)', r: 'EQ(fx1 , a2 * fx)', id: 'mul_by_fx' },
{ l: 'EQ(a1/fx , a2)', r: 'EQ(a1 , a2 * fx)', id: 'mul_by_fx' },
];
equation.applyRules(poolOfRules, {
simplifyBeforeEachStepEnabled: false,
});
if (!equation.isSolved()) {
// Possible improvement: General fork mechanism in EquationSolver?
if (index.default.Type.isOperator(equation.left.node, '*')
&& index.default.Type.isZero(equation.right.node)) {
// Fork f1(x) * f2(x) * ... = 0 into separated equations:
// f1(x) = 0
// f2(x) = 0
// ...
const arrayOfChildEquations = [];
// Helper function to collect nested x*(y*z) factors.
// We want x*(y*z) = 0 gives three equations:
// x = 0
// y = 0
// z = 0
// Possible improvement: move to core code?
const _collectFactors = (node, cb) => {
if (index.default.Type.isOperator(node, '*')) {
// x * y ... - collect all factors from x and y recursively.
node.args.forEach((oneChild) => {
_collectFactors(oneChild, cb);
});
}
else {
// Not a multiply node.
// Collect factor as is.
cb(node);
}
};
// Collect child equations.
_collectFactors(equation.left.node, (node) => {
// Build another fn(x) = 0 equation.
// We want one equation per factor.
arrayOfChildEquations.push(new Equation({
leftNode: node,
rightNode: NODE_ZERO,
comparator: '=',
unknownVariable: equation.unknownVariable,
}));
});
// Fork parent equation into many children equations.
EquationSolver.forkEquation(equation, arrayOfChildEquations);
}
else if (index.default.Type.isOperator(equation.left.node, '^')
&& index.default.Type.isConstant(equation.left.node.args[1])
&& !index.default.Type.doesContainSymbol(equation.left.node.args[1])
&& !index.default.Type.doesContainSymbol(equation.right.node, equation.unknownVariable)) {
// f(x)^n = C
// Possible improvement: General substitution mechanism:
// Possible improvement: Example: (x+2)^4 = 1 <=> t^4 = 1
// Possible improvement: Move to rules table?
const fx = equation.left.node.args[0];
const n = equation.left.node.args[1];
const C = equation.right.node;
const nthRoot = index.default.Creator.nthRoot(C, n);
const arrayOfChildEquations = [];
if (config.default.unequal(config.default.mod(n.value, 2), 0)) {
// n is *NOT* divisible by 2.
// Perform nth-root on both sides.
// f(x)^n = C <=> f(x) = nthRoot(C, n)
arrayOfChildEquations.push(new Equation({
leftNode: fx,
rightNode: nthRoot,
comparator: '=',
unknownVariable: equation.unknownVariable,
}));
}
else {
// f(x)^2n = C
// n is divisible by 2.
// 2n exponent "kills" the sign under the power.
// There are two possible cases:
// 1. f(x) = - nthRoot(C, n)
// 2. f(x) = nthRoot(C, n)
arrayOfChildEquations.push(new Equation({
leftNode: fx,
rightNode: index.default.Creator.unaryMinus(nthRoot),
comparator: '=',
unknownVariable: equation.unknownVariable,
}));
arrayOfChildEquations.push(new Equation({
leftNode: fx,
rightNode: nthRoot,
comparator: '=',
unknownVariable: equation.unknownVariable,
}));
}
EquationSolver.forkEquation(equation, arrayOfChildEquations);
}
}
},
};
exports.fParenX_EQ_C = fParenX_EQ_C;