Пример #1
0
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;
}
Пример #2
0
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;
}