void DepthFirstSearch::visit(TraceConcreteBranch *node) { // Concrete branches are basically ignored by this search. // If there are unexplored nodes as children of a concrete branch, then we ignore them and only search through children of symbolic branches. if(isImmediatelyUnexplored(node->getFalseBranch()) && isImmediatelyUnexplored(node->getTrueBranch())){ Log::fatal("Reached a branch where both branches are unexplored during search."); exit(1); }else if(isImmediatelyUnexplored(node->getFalseBranch())){ // Then we treat this node as a pass-through to the 'true' subtree node->getTrueBranch()->accept(this); }else if(isImmediatelyUnexplored(node->getTrueBranch())){ // Then we treat this node as a pass-through to the 'false' subtree node->getFalseBranch()->accept(this); }else{ // Both branches are explored, so we must search each in turn. mParentStack.push(SavedPosition(node, mCurrentDepth, mCurrentPC, mCurrentDomConstraints)); //mCurrentDepth++; // Do not increase depth for concrete branches. mPreviousParent = node; mPreviousDirection = false; // We are always taking the false branch to begin with. node->getFalseBranch()->accept(this); } }
void CObject::spatial_update (float eps_P, float eps_R) { // BOOL bUpdate=FALSE; if (PositionStack.empty()) { // Empty bUpdate = TRUE; PositionStack.push_back (SavedPosition()); PositionStack.back().dwTime = Device.dwTimeGlobal; PositionStack.back().vPosition = Position(); } else { if (PositionStack.back().vPosition.similar(Position(),eps_P)) { // Just update time PositionStack.back().dwTime = Device.dwTimeGlobal; } else { // Register _new_ record bUpdate = TRUE; if (PositionStack.size()<4) { PositionStack.push_back (SavedPosition()); } else { PositionStack[0] = PositionStack[1]; PositionStack[1] = PositionStack[2]; PositionStack[2] = PositionStack[3]; } PositionStack.back().dwTime = Device.dwTimeGlobal; PositionStack.back().vPosition = Position(); } } if (bUpdate) { spatial_move (); } else { if (spatial.node_ptr) { // Object registered! if (!fsimilar(Radius(),spatial.sphere.R,eps_R)) spatial_move(); else { Fvector C; Center (C); if (!C.similar(spatial.sphere.P,eps_P)) spatial_move(); } // else nothing to do :_) } } }
void DepthFirstSearch::visit(TraceSymbolicBranch *node) { // At a branch, we explore only the 'false' subtree. // Once we reach a leaf, the parent stack is used to return to branches and explore their 'true' children (see continueFromLeaf()). // This allows us to stop the search once we find a node we would like to explore. // The depth limit is also enforced here. if(mCurrentDepth < mDepthLimit){ mParentStack.push(SavedPosition(node, mCurrentDepth, mCurrentPC, mCurrentDomConstraints)); mCurrentDepth++; mPreviousParent = node; mPreviousDirection = false; mCurrentPC.append(PathBranch(node, false)); // We are always taking the false branch here. node->getFalseBranch()->accept(this); }else{ continueFromLeaf(); } }
void DepthFirstSearch::visit(TraceConcreteSummarisation *node) { // If this node has only one execution path then it is just an annotation and we pass over it. if(node->executions.length() == 1) { node->executions[0].second->accept(this); return; } // If there are multiple children, we must add this node to the parent stack so we can explore the rest. // The depth limit is ignored for concrete branches. if(node->executions.length() > 1) { mParentStack.push(SavedPosition(node, mCurrentDepth, mCurrentPC, mCurrentDomConstraints, 1)); node->executions[0].second->accept(this); // N.B. we do not update mPreviousParent or mPreviousDirection as these should not be used to refer to a // concrete summarisation. They are used when we find an unexplored node and attempt to explore it and then // need to work out where it used to be in the tree to see if we replaced it or not. Seeing as there must be a // true branch node after a concrete summary before we can see an unexplored node these are not necessary here. } }