Esempio n. 1
0
void TraceViewerDialog::visit(TraceSymbolicBranch *node)
{
    // This printer only works for straight-line traces, so we require branches that one side is alwyas "capped"
    // by a TraceUnexplored node immediately.

    ExpressionPrinter printer;
    node->getSymbolicCondition()->accept(&printer);

    if(isImmediatelyUnexplored(node->getFalseBranch())){
        // Took 'true' branch.

        mNodeList->addItem(QString("Branch: Condition: %1; Took true branch; Symbolic").arg(printer.getResult().data()));
        node->getTrueBranch()->accept(this);

    } else if(isImmediatelyUnexplored(node->getTrueBranch())){
        // Took 'false' branch.

        mNodeList->addItem(QString("Branch: Condition: %1; Took false branch; Symbolic").arg(printer.getResult().data()));
        node->getFalseBranch()->accept(this);

    } else {
        // Invalid branch node

        Log::fatal("Trace Display: reached an invalid branch node.");
        exit(1);
    }
}
Esempio n. 2
0
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);
    }
}
Esempio n. 3
0
void DepthFirstSearch::markNodeMissed()
{
    // This method can only be called once we have started a search.
    assert(mIsPreviousRun);

    // Replace the current node with TraceUnexploredMissed.
    if(mPreviousDirection){
        // Replace the true branch of mPreviousParent.
        assert(isImmediatelyUnexplored(mPreviousParent->getTrueBranch()));
        mPreviousParent->setTrueBranch(TraceUnexploredMissed::getInstance());
    }else{
        // Replace the false branch of mPreviousParent.
        assert(isImmediatelyUnexplored(mPreviousParent->getFalseBranch()));
        mPreviousParent->setFalseBranch(TraceUnexploredMissed::getInstance());
    }
}
Esempio n. 4
0
/**
 *  Selects an unexplored node from the tree to be explored next.
 *  Calculates the constraint [hopefully] leading to the unexplored node it has chosen.
 *  Returns true if an unexplored node was found (then the constraint can be retrieved with getTargetPC())
 *  and false when we reached the end of the tree.
 *  N.B. in this case there may still be unexplored areas in the following cases:
 *      * They were lower than the current search depth in the tree.
 *      * They were skipped (i.e. the first attempt to explore them failed).
 *      * A previously skipped node was explored "accidentally" by a later run.
 *
 *  TODO: I think this mehtod assumes there will be at least one branch above any unexplored node.
 *        This means we should only run it on a tree containing at least one trace for now.
 */
bool DepthFirstSearch::chooseNextTarget()
{
    TraceNodePtr current;

    // Check if we are starting a new search or continuing an old one.
    if(mIsPreviousRun){
        // Continue the search.
        
        // Check if the left/right (according to mPreviousDirection) child of mPreviousParent is still unexplored.
        // If so, skip it and search for the next unexplored node.
        // If not, we want to search the newly revealed area before continuing.
        // ASSUMPTION: if the true/false child of a branch eventually terminates in unexplored (without further branching) then it is immediately unexplored.

        if(mPreviousDirection){
            // We are interested in the 'true' branch of mPreviousParent.
            current = mPreviousParent->getTrueBranch();
        }else{
            // We are interested in the 'false' branch of mPreviousParent.
            current = mPreviousParent->getFalseBranch();
        }
        // The depth, PC, etc. are all already set from the previous call.


        if(isImmediatelyUnexplored(current)){
            // Then the previous run did not reach the intended target.
            // Use the same method as continueFromLeaf() to jump to the next node to be searched.
            // If the parent stack is empty here, then we have reached the end of the search.
            if(mParentStack.empty()){
                mFoundTarget = false;
                return deepenRestartAndChoose();
            }else{
                current = nextAfterLeaf();
            }
        }

    }else{
        // Strat a new search.
        current = mTree;
    }

    // Call the visitor to continue the search.
    current->accept(this);

    // Future runs should continue wherever we left off.
    mIsPreviousRun = true;

    // The visitor will set its own "output" in mCurrentPC.
    // This function returns whether we reached the end of the iteration or not.
    if(mFoundTarget) {
        mPreviousPassFoundTarget = true;
        return true;
    } else {
        // Attempt to increase the depth limit and restart, if possible.
        return deepenRestartAndChoose();
    }

}
Esempio n. 5
0
void TraceViewerDialog::visit(TraceConcreteBranch *node)
{
    // This printer only works for straight-line traces, so we require branches that one side is alwyas "capped"
    // by a TraceUnexplored node immediately.

    if(isImmediatelyUnexplored(node->getFalseBranch())){
        // Took 'true' branch.

        mNodeList->addItem("Branch: Took true branch;");
        node->getTrueBranch()->accept(this);

    } else if(isImmediatelyUnexplored(node->getTrueBranch())){
        // Took 'false' branch.

        mNodeList->addItem("Branch: Took false branch;");
        node->getFalseBranch()->accept(this);

    } else {
        // Invalid branch node

        Log::fatal("Trace Display: reached an invalid branch node.");
        exit(1);
    }
}
Esempio n. 6
0
bool DepthFirstSearch::overUnexploredNode()
{
    // This method can only be called once we have started a search.
    assert(mIsPreviousRun);

    // Use mPreviousParent and mPreviousDirection to find the "current" node again, as in chooseNextTarget().
    TraceNodePtr current;
    if(mPreviousDirection){
        current = mPreviousParent->getTrueBranch();
    }else{
        current = mPreviousParent->getFalseBranch();
    }

    return isImmediatelyUnexplored(current);
}