diff --git a/lib/node/Term.js b/lib/node/Term.js index 34bb04ae..21f5694b 100644 --- a/lib/node/Term.js +++ b/lib/node/Term.js @@ -114,7 +114,7 @@ Term.parseNode = function(node, baseNodeFunc, onlyImplicitMultiplication) { throw Error('Expected two arguments to *'); } const coeffNode = node.args[0]; - if (!NodeType.isConstantOrConstantFraction(coeffNode)) { + if (!NodeType.isConstantOrConstantFraction(coeffNode, true)) { throw Error('Expected coefficient to be constant or fraction of ' + 'constants term, got ' + coeffNode); } diff --git a/lib/node/Type.js b/lib/node/Type.js index c1d6bd96..c3cdeaa1 100644 --- a/lib/node/Type.js +++ b/lib/node/Type.js @@ -78,6 +78,16 @@ NodeType.isConstantOrConstantFraction = function(node, allowUnaryMinus=false) { } }; +NodeType.isOverallConstant = function (node) { + if (NodeType.isConstantOrConstantFraction(node, true)) { + return true + } else if (NodeType.isUnaryMinus(node)) { + return NodeType.isOverallConstant(node.args[0]) + } else if (NodeType.isParenthesis(node)) { + return NodeType.isOverallConstant(node.content) + } +} + NodeType.isIntegerFraction = function(node, allowUnaryMinus=false) { if (!NodeType.isConstantFraction(node, allowUnaryMinus)) { return false; diff --git a/lib/solveEquation/stepThrough.js b/lib/solveEquation/stepThrough.js index 40c1474c..744db20e 100644 --- a/lib/solveEquation/stepThrough.js +++ b/lib/solveEquation/stepThrough.js @@ -257,11 +257,10 @@ function solveConstantEquation(equation, debug, steps=[]) { // If the left or right side didn't have any steps, unnecessary parens // might not have been removed, so do that now. - equation.leftNode = removeUnnecessaryParens(equation.leftNode); - equation.rightNode = removeUnnecessaryParens(equation.rightNode); + equation.leftNode = removeUnnecessaryParens(equation.leftNode, true); + equation.rightNode = removeUnnecessaryParens(equation.rightNode, true); - if (!Node.Type.isConstantOrConstantFraction(equation.leftNode, true) || - !Node.Type.isConstantOrConstantFraction(equation.rightNode, true)) { + if (!Node.Type.isOverallConstant(equation.leftNode) || !Node.Type.isOverallConstant(equation.rightNode)) { throw Error('Expected both nodes to be constants, instead got: ' + equation.ascii()); } diff --git a/lib/util/flattenOperands.js b/lib/util/flattenOperands.js index 8e5c0343..8aa63d1a 100644 --- a/lib/util/flattenOperands.js +++ b/lib/util/flattenOperands.js @@ -86,7 +86,9 @@ function flattenOperands(node) { return node; } else if (Node.Type.isUnaryMinus(node)) { - const arg = flattenOperands(node.args[0]); + // since arg is changed when it is negated, clone it before negation to avoid + // modifiying original reference + const arg = flattenOperands(node.args[0].cloneDeep()); const flattenedNode = Negative.negate(arg, true); if (node.changeGroup) { flattenedNode.changeGroup = node.changeGroup; diff --git a/lib/util/removeUnnecessaryParens.js b/lib/util/removeUnnecessaryParens.js index 3bbf796d..3d3c1447 100644 --- a/lib/util/removeUnnecessaryParens.js +++ b/lib/util/removeUnnecessaryParens.js @@ -37,8 +37,7 @@ function removeUnnecessaryParensSearch(node) { return node; } else if (Node.Type.isUnaryMinus(node)) { - const content = node.args[0]; - node.args[0] = removeUnnecessaryParensSearch(content); + node.args[0] = removeUnnecessaryParensSearch(node.args[0]) return node; } else { diff --git a/test/solveEquation/solveEquation.test.js b/test/solveEquation/solveEquation.test.js index 251179fe..2d0eb4c0 100644 --- a/test/solveEquation/solveEquation.test.js +++ b/test/solveEquation/solveEquation.test.js @@ -99,7 +99,9 @@ describe('solveEquation for =', function () { ['((x)/(4))=4', 'x = 16'], ['(2x-12)=(x+4)', 'x = 16'], ['x+y=x+y', '0 = 0'], - ['y + 2x = 14 + y', 'x = 7'] + ['y + 2x = 14 + y', 'x = 7'], + ['-(x/2) = 4', 'x = -8'], + ['-((1)/(3)) = ((-1)/(3))', '-(1/3) = -1/3'] // TODO: fix these cases, fail because lack of factoring support, for complex #s, // for taking the sqrt of both sides, etc // ['(x + y) (y + 2) = 0', 'y = -y'], diff --git a/test/util/removeUnnecessaryParens.test.js b/test/util/removeUnnecessaryParens.test.js index 9d7520ab..72f772a1 100644 --- a/test/util/removeUnnecessaryParens.test.js +++ b/test/util/removeUnnecessaryParens.test.js @@ -17,6 +17,7 @@ describe('removeUnnecessaryParens', function () { ['x + (12)', 'x + 12'], ['x + (y)', 'x + y'], ['x + -(y)', 'x - y'], + ['((((1))))', '1'], ['((3 - 5)) * x', '(3 - 5) * x'], ['((3 - 5)) * x', '(3 - 5) * x'], ['(((-5)))', '-5'],