ExpressionNode Addition::simplify(ExpressionNode& left, ExpressionNode& right) const { clog << "checkpoint addsimplify" << endl; //simplest case: at least one side is just 0 if (left.getType() == NUMBER && left.getValue().getInt() == 0) { return right; } else if (right.getType() == NUMBER && right.getValue().getInt() == 0) { return left; } // for each left term: for each right term: try adding stack <ExpressionNode*> leftNodeStack; ExpressionNode * currentLeftNode = &left; bool leftFinished = false; stack <ExpressionNode*> rightNodeStack; vector <ExpressionNode*> rightDeleteList; ExpressionNode * currentRightNode = &right; bool rightFinished = false; ExpressionNode newNode(&ADDITION); while (leftFinished == false) { clog << "looping left" << endl; if (currentLeftNode->getType() == OPERATION && currentLeftNode->getOperation() == &ADDITION) { if (currentLeftNode->getFirstChild() == 0) { throw ExpressionNode::WrongArityError(); } currentLeftNode = currentLeftNode->getFirstChild(); leftNodeStack.push(currentLeftNode); continue; } // leaf term on left tree: traverse right tree rightFinished = false; currentRightNode = &right; while (rightFinished == false) { clog << "looping right" << endl; if (currentRightNode->getType() == OPERATION && currentRightNode->getOperation() == &ADDITION) { if (currentRightNode->getFirstChild() == 0) { throw ExpressionNode::WrongArityError(); } currentRightNode = currentRightNode->getFirstChild(); rightNodeStack.push(currentRightNode); continue; } assert(currentLeftNode != 0); assert(currentRightNode !=0); clog << "checkpoint addsimplify: before isAddable(" << *currentLeftNode << ", " << *currentRightNode << ")"<< endl; // leaf terms on both sides: attempt adding if (isCompatible(*currentLeftNode, *currentRightNode)) { clog << "checkpoint addsimplify: after isAddable; " << endl; clog << *currentLeftNode << " " << *currentRightNode << endl; (*currentLeftNode) = addTerms(*currentLeftNode, *currentRightNode); clog << "checkpoint addsimplify: after addTerms; " << endl; clog << "currentLeftNode: " << *currentLeftNode << " RightNode:" << *currentRightNode << endl; clog << "left " << left << "right " << right << endl; if (currentRightNode == &right) { //entire right tree has been assimilated return left; } // try marking for deletion after right loop instead of removing rightDeleteList.push_back(currentRightNode); } while (true) { clog << "rightNodeStack: " << rightNodeStack.size() << endl; if (rightNodeStack.size() != 0) clog << "rightNodeStack.top(): " << *(rightNodeStack.top()) << endl; if (rightNodeStack.size() == 0) { rightFinished = true; break; } currentRightNode = rightNodeStack.top(); rightNodeStack.pop(); if (currentRightNode->getRight() != 0) { currentRightNode = currentRightNode->getRight(); rightNodeStack.push(currentRightNode); break; } } } // deleting marked rights for (vector<ExpressionNode*>::iterator it = rightDeleteList.begin(); it != rightDeleteList.end(); it++) { right.remove(*it); } rightDeleteList.clear(); clog << "here left: " << left << "right: " << right <<endl; //clog << "leftNodeStack: " << leftNodeStack.size() << endl; //if (leftNodeStack.size() > 0) //{ //clog << "leftNodeStack: " << *(leftNodeStack.top()) << endl; //} while (true) { if (leftNodeStack.size() == 0) { leftFinished = true; break; } currentLeftNode = leftNodeStack.top(); leftNodeStack.pop(); if (currentLeftNode->getRight() != 0) { currentLeftNode = currentLeftNode->getRight(); leftNodeStack.push(currentLeftNode); break; } } } //still some terms left on right newNode.appendChild(left); newNode.appendChild(right); return newNode; }
ExpressionNode Addition::simplify(ExpressionNode& left, ExpressionNode& right) { std::clog << "checkpoint addsimplify" << std::endl; //simplest case: at least one side is just 0 if (left.getType() == NUMBER && left.getValue().getInt() == 0) { return right; } else if (right.getType() == NUMBER && right.getValue().getInt() == 0) { return left; } // for each left term: for each right term: try adding std::stack <ExpressionNode*> leftNodeStack; ExpressionNode * currentLeftNode = &left; bool leftFinished = false; std::stack <ExpressionNode*> rightNodeStack; ExpressionNode * currentRightNode = &right; bool rightFinished = false; ExpressionNode * tempNodePtr; ExpressionNode newNode; while (leftFinished == false) { std::clog << "looping left" << std::endl; if (currentLeftNode->getType() == OPERATION && currentLeftNode->getOperation() == &ADDITION) { if (currentLeftNode->getFirstChild() == 0) { throw ExpressionNode::WrongArityError(); } currentLeftNode = currentLeftNode->getFirstChild(); leftNodeStack.push(currentLeftNode); continue; } // leaf term on left tree: traverse right tree while (rightFinished == false) { std::clog << "looping right" << std::endl; if (currentRightNode->getType() == OPERATION && currentRightNode->getOperation() == &ADDITION) { if (currentRightNode->getFirstChild() == 0) { throw ExpressionNode::WrongArityError(); } currentRightNode = currentRightNode->getFirstChild(); rightNodeStack.push(currentRightNode); continue; } std::clog << "checkpoint addsimplify: before isAddable; " << std::endl; // leaf terms on both sides: attempt adding if (isAddable(*currentLeftNode, *currentRightNode)) { std::clog << "checkpoint addsimplify: after isAddable; " << std::endl; std::clog << *currentLeftNode << " " << *currentRightNode << std::endl; std::clog << "add testrun: " << addTerms(*currentLeftNode, *currentRightNode); (*currentLeftNode).replace( addTerms(*currentLeftNode, *currentRightNode) ); std::clog << "checkpoint addsimplify: after addTerms; " << std::endl; if (currentRightNode == &right) { //entire right tree has been assimilated return left; } tempNodePtr = currentRightNode; currentRightNode = right.findParentOf(*currentRightNode); right.remove(*tempNodePtr); } while (true) { if (rightNodeStack.size() == 0) { rightFinished = true; break; } currentRightNode = rightNodeStack.top(); rightNodeStack.pop(); if (currentRightNode->getRight() != 0) { currentRightNode = currentRightNode->getRight(); rightNodeStack.push(currentRightNode); break; } } } while (true) { if (leftNodeStack.size() == 0) { leftFinished = true; break; } currentLeftNode = leftNodeStack.top(); leftNodeStack.pop(); if (currentLeftNode->getRight() != 0) { currentLeftNode = currentLeftNode->getRight(); leftNodeStack.push(currentLeftNode); break; } } } //still some terms left on right left.setRight(&right); newNode.init(&ADDITION, &left); return newNode; }