V3MPDRCube* const V3VrfMPDR::recursiveBlockCube(V3MPDRCube* const badCube) { // Create a Queue for Blocking Cubes V3BucketList<V3MPDRCube*> badQueue(getPDRFrame()); assert (badCube); badQueue.add(getPDRDepth(), badCube); // Block Cubes from the Queue V3MPDRTimedCube baseCube, generalizedCube; while (badQueue.pop(baseCube.first, baseCube.second)) { assert (baseCube.first < getPDRFrame()); if (!baseCube.first) { // Clear All Cubes in badQueue before Return V3Set<const V3MPDRCube*>::Set traceCubes; traceCubes.clear(); const V3MPDRCube* traceCube = baseCube.second; while (true) { traceCubes.insert(traceCube); if (_pdrBad == traceCube) break; traceCube = traceCube->getNextCube(); } while (badQueue.pop(generalizedCube.first, generalizedCube.second)) { if (traceCubes.end() == traceCubes.find(generalizedCube.second)) delete generalizedCube.second; } return baseCube.second; // A Cube cannot be blocked by R0 --> Cex } if (!isBlocked(baseCube)) { assert (!existInitial(baseCube.second->getState())); // Check Reachability : SAT (R ^ ~cube ^ T ^ cube') if (checkReachability(baseCube.first, baseCube.second->getState())) { // SAT, Not Blocked Yet if (profileON()) _ternaryStat->start(); generalizedCube.second = extractModel(baseCube.second, baseCube.first - 1); if (profileON()) _ternaryStat->end(); badQueue.add(baseCube.first - 1, generalizedCube.second); // This Cube should be blocked in previous frame badQueue.add(baseCube.first, baseCube.second); // This Cube has not yet been blocked (postpone to future) } else { // UNSAT, Blocked bool satGen = true; while (true) { if (profileON()) _generalStat->start(); generalizedCube.first = baseCube.first; generalizedCube.second = new V3MPDRCube(*(baseCube.second)); generalization(generalizedCube); // Generalization if (profileON()) _generalStat->end(); addBlockedCube(generalizedCube); // Record this Cube that is bad and to be blocked // I found Niklas Een has modified the original IWLS paper and alter the line below // However, I suggest the alteration restricts PDR (i.e. fold-free) and does not help if (satGen && (baseCube.first < getPDRDepth()) && (generalizedCube.first < getPDRFrame())) badQueue.add(baseCube.first + 1, baseCube.second); //if ((baseCube.first < getPDRDepth()) && (generalizedCube.first < getPDRDepth())) // badQueue.add(generalizedCube.first + 1, baseCube.second); if (!isForwardSATGen() || getPDRDepth() <= generalizedCube.first) break; baseCube.second = forwardModel(generalizedCube.second); if (!baseCube.second) break; baseCube.first = baseCube.first + 1; satGen = false; if (checkReachability(baseCube.first, baseCube.second->getState())) break; } } } //else delete baseCube.second; } return 0; }
void V3VrfMPDR::recycleSolver() { // Initialize Solver assert (!_pdrActCount); initializeSolver(); // Initialize Frames _pdrFrame[0]->setActivator(_pdrSvr->setImplyInit()); for (uint32_t i = 1; i < _pdrFrame.size(); ++i) addFrameInfoToSolver(i); // Check Shared Invariants if (_sharedInv) { V3NetTable sharedInv; _sharedInv->getInv(sharedInv); for (uint32_t i = 0; i < sharedInv.size(); ++i) { V3MPDRCube* const inv = new V3MPDRCube(0); assert (inv); inv->setState(sharedInv[i]); addBlockedCube(make_pair(getPDRFrame(), inv)); } } _pdrSvr->simplify(); }
V3SIPDRCube* const V3SVrfIPDR::recursiveBlockCube2(V3SIPDRCube* const badCube) { //unfolding_depth uint32_t d = _decompDepth; //cerr << "_decompDepth : " << d << endl; if(heavy_debug) cerr << "\n\n\nrecursiveBlockCube2\n"; // Create a Queue for Blocking Cubes V3BucketList<V3SIPDRCube*> badQueue(getPDRFrame()); assert (badCube); badQueue.add(getPDRDepth(), badCube); vector<uint32_t> v; for (unsigned i = 0; i <= getPDRDepth(); ++i){ v.push_back(0); } // Block Cubes from the Queue V3SIPDRTimedCube baseCube, generalizedCube; while (badQueue.pop(baseCube.first, baseCube.second)) { v[baseCube.first]++; if(heavy_debug){ cerr << "\nPoped: baseCube frame: " << baseCube.first << ", cube: "; printState( baseCube.second->getState() ); } assert (baseCube.first < getPDRFrame()); if (!baseCube.first) { // Clear All Cubes in badQueue before Return V3Set<const V3SIPDRCube*>::Set traceCubes; traceCubes.clear(); const V3SIPDRCube* traceCube = baseCube.second; while (true) { traceCubes.insert(traceCube); if (_pdrBad == traceCube) break; traceCube = traceCube->getNextCube(); } while (badQueue.pop(generalizedCube.first, generalizedCube.second)) { if (traceCubes.end() == traceCubes.find(generalizedCube.second)) delete generalizedCube.second; } return baseCube.second; // A Cube cannot be blocked by R0 --> Cex } if (!isBlocked(baseCube)) { assert (!existInitial2(baseCube.second->getState())); // Check Reachability : SAT (R ^ ~cube ^ T ^ cube') if( baseCube.first >= d && v[baseCube.first] > 10){ //if( false ){ if(checkReachability2(baseCube.first - d + 1, baseCube.second->getState(),false)){ if(heavy_debug){ cerr << "SAT, generalizing... Frame before gen:" << baseCube.first << " Cube before gen:"; printState(baseCube.second->getState()); } if (profileON()) _ternaryStat->start(); generalizedCube.second = extractModel2(baseCube.first - d, baseCube.second); if (profileON()) _ternaryStat->end(); if(heavy_debug){ cerr << "SAT, pushing to queue, Frame after gen:" << baseCube.first-d << " Cube after gen:"; printState(generalizedCube.second->getState()); } badQueue.add(baseCube.first - d, generalizedCube.second); // This Cube should be blocked in previous frame badQueue.add(baseCube.first, baseCube.second); // This Cube has not yet been blocked (postpone to future) //cout << "WOW" << endl; continue; } } if (checkReachability(baseCube.first, baseCube.second->getState())) { // SAT, Not Blocked Yet if(heavy_debug){ cerr << "SAT, generalizing... Frame before gen:" << baseCube.first << " Cube before gen:"; printState(baseCube.second->getState()); } if (profileON()) _ternaryStat->start(); generalizedCube.second = extractModel(baseCube.first - 1, baseCube.second); if (profileON()) _ternaryStat->end(); if(heavy_debug){ cerr << "SAT, pushing to queue, Frame after gen:" << baseCube.first-1 << " Cube after gen:"; printState(generalizedCube.second->getState()); } badQueue.add(baseCube.first - 1, generalizedCube.second); // This Cube should be blocked in previous frame badQueue.add(baseCube.first, baseCube.second); // This Cube has not yet been blocked (postpone to future) } else { // UNSAT, Blocked if (profileON()) _generalStat->start(); generalizedCube.first = baseCube.first; generalizedCube.second = new V3SIPDRCube(*(baseCube.second)); generalization2(generalizedCube); // Generalization if (profileON()) _generalStat->end(); addBlockedCube(generalizedCube); // Record this Cube that is bad and to be blocked if ((baseCube.first < getPDRDepth()) && (generalizedCube.first < getPDRFrame())) badQueue.add(baseCube.first + 1, baseCube.second); } } } return 0; }
const bool V3VrfMPDR::propagateCubes() { if (profileON()) _propagateStat->start(); // Check Each Frame if some Cubes can be Further Propagated for (uint32_t i = 1; i < getPDRDepth(); ++i) { const V3MPDRCubeList& cubeList = _pdrFrame[i]->getCubeList(); #ifdef V3_MPDR_USE_PROPAGATE_BACKWARD // Backward Version (Check from rbegin() to rend()) uint32_t candidates = 1; V3MPDRCubeList::const_iterator it; while (candidates <= cubeList.size()) { it = cubeList.begin(); for (uint32_t j = candidates; j < cubeList.size(); ++j) ++it; #else // Forward Version (Check from begin() to end()) V3MPDRCubeList::const_iterator it = cubeList.begin(); while (it != cubeList.end()) { #endif // Check if this cube can be pushed forward (closer to All Frame) if (!checkReachability(i + 1, (*it)->getState(), false)) { V3MPDRTimedCube cube = make_pair(i + 1, new V3MPDRCube(*(*it))); // Remove Cubes in the Next Frame that can be Subsumed by the cube removeFromProof(cube); _pdrFrame[i + 1]->removeSubsumed(cube.second); // Remove cubes in this frame that can be subsumed by the cube _pdrFrame[i]->removeSubsumed(cube.second, ++it); // Block this cube again at higher frames addBlockedCube(cube); } else { // Remove cubes in this frame that can be subsumed by the cube _pdrFrame[i]->removeSubsumed(*it, it); #ifdef V3_MPDR_USE_PROPAGATE_BACKWARD // Backward Version (Check from rbegin() to rend()) ++candidates; #else // Forward Version (Check from begin() to end()) ++it; #endif } } // Check if Any Remaining Cubes in this Frame can be Subsumed _pdrFrame[i]->removeSelfSubsumed(); /* // Debug : Check Real Containment for (uint32_t j = i + 1; j < _pdrFrame.size(); ++j) { it = _pdrFrame[j]->getCubeList().begin(); while (it != _pdrFrame[j]->getCubeList().end()) { assert (!checkReachability(i, (*it)->getState())); ++it; } } */ // Check Inductive Invariant if (!_pdrFrame[i]->getCubeList().size()) { if (profileON()) _propagateStat->end(); return true; } } // Check if Any Remaining Cubes in the Latest Frame can be Subsumed _pdrFrame[getPDRDepth()]->removeSelfSubsumed(); //_pdrFrame[getPDRFrame()]->removeSelfSubsumed(); /* // Debug : Check Real Containment for (uint32_t j = getPDRDepth() + 1; j < _pdrFrame.size(); ++j) { V3MPDRCubeList::const_iterator it = _pdrFrame[j]->getCubeList().begin(); while (it != _pdrFrame[j]->getCubeList().end()) { assert (!checkReachability(getPDRDepth(), (*it)->getState())); ++it; } } */ if (profileON()) _propagateStat->end(); return false; } #else const bool V3VrfMPDR::propagateCubes() { if (profileON()) _propagateStat->start(); // Check Each Frame if some Cubes can be Further Propagated for (uint32_t i = 1; i < getPDRDepth(); ++i) { const V3MPDRCubeList& cubeList = _pdrFrame[i]->getCubeList(); #ifdef V3_MPDR_USE_PROPAGATE_BACKWARD // Backward Version (Check from rbegin() to rend()) uint32_t candidates = 1; V3MPDRCubeList::const_iterator it; while (candidates <= cubeList.size()) { it = cubeList.begin(); for (uint32_t j = candidates; j < cubeList.size(); ++j) ++it; #else // Forward Version (Check from begin() to end()) V3MPDRCubeList::const_iterator it = cubeList.begin(); while (it != cubeList.end()) { #endif // Check if this cube can be pushed forward (closer to All Frame) if (!checkReachability(i + 1, (*it)->getState(), false)) { V3MPDRTimedCube cube = make_pair(i + 1, new V3MPDRCube(*(*it))); // Block this cube again at higher frames removeFromProof(cube); addBlockedCube(cube); // Remove blocked cubes in lower frames that can be subsumed by the cube for (uint32_t j = 1; j < i; ++j) _pdrFrame[j]->removeSubsumed(cube.second); // Remove Cubes in this Frame that can be Subsumed by the cube _pdrFrame[i]->removeSubsumed(cube.second, ++it); // NOTE: Need not to recover iterator after subsumption (set.erase) // the iterator it will point to the next candidate } else { // Remove blocked cubes in lower frames that can be subsumed by the cube for (uint32_t j = 1; j < i; ++j) _pdrFrame[j]->removeSubsumed(*it); #ifdef V3_MPDR_USE_PROPAGATE_BACKWARD // Backward Version (Check from rbegin() to rend()) ++candidates; #else // Forward Version (Check from begin() to end()) ++it; #endif } } // Check if Any Remaining Cubes in this Frame can be Subsumed _pdrFrame[i]->removeSelfSubsumed(); // Check Inductive Invariant for (uint32_t j = 1; j <= i; ++j) { if (!_pdrFrame[j]->getCubeList().size()) { if (profileON()) _propagateStat->end(); return true; } } } // Check if Any Remaining Cubes in these Frames can be Subsumed _pdrFrame[getPDRDepth()]->removeSelfSubsumed(); _pdrFrame[getPDRFrame()]->removeSelfSubsumed(); if (profileON()) _propagateStat->end(); return false; } #endif // PDR Auxiliary Functions const bool V3VrfMPDR::checkReachability(const uint32_t& frame, const V3NetVec& cubeState, const bool& extend) { assert (frame > 0); assert (frame <= getPDRFrame()); // Check if Recycle is Triggered if (!_pdrActCount) recycleSolver(); // Assume R _pdrSvr->assumeRelease(); assumeReachability((frame == getPDRFrame()) ? frame : frame - 1); // Assume cube' addCubeToSolver(cubeState, 1); for (uint32_t i = 0; i < cubeState.size(); ++i) _pdrSvr->assumeProperty(_pdrSvr->getFormula(_vrfNtk->getLatch(cubeState[i].id), 1), cubeState[i].cp); if (extend) { // Assume ~cube addCubeToSolver(cubeState, 0); V3SvrDataVec blockCube; blockCube.clear(); blockCube.reserve(cubeState.size()); size_t fId; for (uint32_t i = 0; i < cubeState.size(); ++i) { fId = _pdrSvr->getFormula(_vrfNtk->getLatch(cubeState[i].id), 0); blockCube.push_back(cubeState[i].cp ? fId : _pdrSvr->getNegFormula(fId)); } _pdrSvrData = _pdrSvr->setImplyUnion(blockCube); assert (_pdrSvrData); _pdrSvr->assumeProperty(_pdrSvrData); // Check Reachability by SAT Calling if (profileON()) _solveStat->start(); _pdrSvr->simplify(); const bool result = _pdrSvr->assump_solve(); if (profileON()) _solveStat->end(); _pdrSvr->assertProperty(_pdrSvr->getNegFormula(_pdrSvrData)); // Invalidate ~cube in future solving --_pdrActCount; return result; } else { if (profileON()) _solveStat->start(); _pdrSvr->simplify(); const bool result = _pdrSvr->assump_solve(); if (profileON()) _solveStat->end(); return result; } } const bool V3VrfMPDR::isBlocked(const V3MPDRTimedCube& timedCube) { // Check if cube has already been blocked by R (at specified frame) // Perform Subsumption Check : cube implies some C in R (at specified frame) for (uint32_t i = timedCube.first; i < _pdrFrame.size(); ++i) if (_pdrFrame[i]->subsumes(timedCube.second)) return true; ///* // Check by SAT _pdrSvr->assumeRelease(); assumeReachability(timedCube.first); const V3NetVec& state = timedCube.second->getState(); addCubeToSolver(state, 0); for (uint32_t i = 0; i < state.size(); ++i) _pdrSvr->assumeProperty(_pdrSvr->getFormula(_vrfNtk->getLatch(state[i].id), 0), state[i].cp); if (profileON()) _solveStat->start(); const bool result = _pdrSvr->assump_solve(); if (profileON()) _solveStat->end(); return !result; //*/ //return false; } const bool V3VrfMPDR::existInitial(const V3NetVec& state) { for (uint32_t i = 0; i < state.size(); ++i) { assert (state[i].id < _pdrInitConst.size()); assert (state[i].id < _pdrInitValue.size()); if (_pdrInitConst[state[i].id] && (_pdrInitValue[state[i].id] ^ state[i].cp)) return false; } return true; } void V3VrfMPDR::assumeReachability(const unsigned& k) { uint32_t i = _pdrFrame.size(); while (i-- > k) _pdrSvr->assumeProperty(_pdrFrame[i]->getActivator()); }
/* ---------------------------------------------------------------------------------------------------- *\ isIncKeepLastReachability(): If the last result is unsat, put the inductive invariant into the last frame. isIncContinueOnLastSolver(): Reset the solver. \* ---------------------------------------------------------------------------------------------------- */ void V3VrfMPDR::startVerify(const uint32_t& p) { vrfRestart: // Check Shared Results if (_sharedBound && V3NtkUD == _sharedBound->getBound(p)) return; // Clear Verification Results clearResult(p); if (profileON()) _totalStat->start(); // Consistency Check consistencyCheck(); assert (!_constr.size()); if (!reportUnsupportedInitialState()) return; // Initialize Backup Frames for (uint32_t i = 0; i < _pdrBackup.size(); ++i) delete _pdrBackup[i]; _pdrBackup.clear(); if (_pdrFrame.size()) { if (isIncKeepLastReachability()) { // Backup frames in the order: ..., 2, 1, INF assert (_pdrFrame.size() > 1); _pdrBackup.reserve(_pdrFrame.size() - 1); for (uint32_t i = _pdrFrame.size() - 2; i > 0; --i) _pdrBackup.push_back(_pdrFrame[i]); _pdrBackup.push_back(_pdrFrame.back()); delete _pdrFrame[0]; } else { for (uint32_t i = 0; i < _pdrFrame.size(); ++i) delete _pdrFrame[i]; } _pdrFrame.clear(); } // Initialize Other Members if (!isIncKeepLastReachability()) _pdrPriority.clear(); _pdrActCount = 0; if (_pdrBad) delete _pdrBad; _pdrBad = 0; if (_pdrGen) delete _pdrGen; _pdrGen = 0; if (dynamic_cast<V3BvNtk*>(_vrfNtk)) { _pdrGen = new V3AlgBvGeneralize(_handler); assert (_pdrGen); _pdrSim = dynamic_cast<V3AlgBvSimulate*>(_pdrGen); assert (_pdrSim); } else { _pdrGen = new V3AlgAigGeneralize(_handler); assert (_pdrGen); _pdrSim = dynamic_cast<V3AlgAigSimulate*>(_pdrGen); assert (_pdrSim); } V3NetVec simTargets(1, _vrfNtk->getOutput(p)); _pdrSim->reset(simTargets); // Initialize Pattern Input Size assert (p < _result.size()); assert (p < _vrfNtk->getOutputSize()); const V3NetId& pId = _vrfNtk->getOutput(p); assert (V3NetUD != pId); _pdrSize = _vrfNtk->getInputSize() + _vrfNtk->getInoutSize(); // Initialize Parameters const string flushSpace = string(100, ' '); uint32_t proved = V3NtkUD, fired = V3NtkUD; struct timeval inittime, curtime; gettimeofday(&inittime, NULL); // Initialize Signal Priority List if (_pdrPriority.size() != _vrfNtk->getLatchSize()) _pdrPriority.resize(_vrfNtk->getLatchSize(), 0); // Initialize Solver if (_pdrSvr && !isIncContinueOnLastSolver()) { delete _pdrSvr; _pdrSvr = 0; } initializeSolver(); // Initialize Bad Cube _pdrBad = new V3MPDRCube(0); assert (_pdrBad); _pdrBad->setState(V3NetVec(1, pId)); // Initialize Frame 0 if (_vrfNtk->getLatchSize()) _pdrFrame.push_back(new V3MPDRFrame(_pdrSvr->setImplyInit())); // R0 = I0 else _pdrFrame.push_back(new V3MPDRFrame(_pdrSvr->reserveFormula())); assert (_pdrFrame.back()->getActivator()); assert (_pdrFrame.size() == 1); // Initialize Frame INF if (_pdrBackup.size()) { _pdrFrame.push_back(_pdrBackup.back()); _pdrBackup.pop_back(); addFrameInfoToSolver(1); } else _pdrFrame.push_back(new V3MPDRFrame(_pdrSvr->reserveFormula())); assert (_pdrFrame.back()->getActivator()); assert (_pdrFrame.size() == 2); // Check Shared Invariants if (_sharedInv) { V3NetTable sharedInv; _sharedInv->getInv(sharedInv); for (uint32_t i = 0; i < sharedInv.size(); ++i) { V3MPDRCube* const inv = new V3MPDRCube(0); assert (inv); inv->setState(sharedInv[i]); addBlockedCube(make_pair(getPDRFrame(), inv)); } } // Continue on the Last Depth while (_pdrBackup.size() && (getIncLastDepthToKeepGoing() > getPDRFrame())) { _pdrFrame.push_back(_pdrFrame.back()); // Keep frame INF the last frame _pdrFrame[_pdrFrame.size() - 2] = _pdrBackup.back(); _pdrBackup.pop_back(); addFrameInfoToSolver(_pdrFrame.size() - 2); } // Start PDR Based Verification V3MPDRCube* badCube = 0; while (true) { // Check Time Bounds gettimeofday(&curtime, NULL); if (_maxTime < getTimeUsed(inittime, curtime)) break; // Check Shared Results if (_sharedBound && (V3NtkUD == _sharedBound->getBound(p))) break; // Check Shared Networks if (_sharedNtk) { V3NtkHandler* const sharedNtk = _sharedNtk->getNtk(_handler); if (sharedNtk) { setIncKeepLastReachability(true); setIncContinueOnLastSolver(false); setIncLastDepthToKeepGoing(getPDRDepth()); _handler = sharedNtk; _vrfNtk = sharedNtk->getNtk(); goto vrfRestart; } } // Find a Bad Cube as Initial Proof Obligation badCube = getInitialObligation(); // SAT(R ^ T ^ !p) if (!badCube) { if (!isIncKeepSilent() && intactON()) { if (!endLineON()) Msg(MSG_IFO) << "\r" + flushSpace + "\r"; Msg(MSG_IFO) << setw(3) << left << getPDRDepth() << " :"; const uint32_t j = (_pdrFrame.size() > 25) ? _pdrFrame.size() - 25 : 0; if (j) Msg(MSG_IFO) << " ..."; for (uint32_t i = j; i < _pdrFrame.size(); ++i) Msg(MSG_IFO) << " " << _pdrFrame[i]->getCubeList().size(); if (svrInfoON()) { Msg(MSG_IFO) << " ("; _pdrSvr->printInfo(); Msg(MSG_IFO) << ")"; } Msg(MSG_IFO) << endl; // Always Endline At the End of Each Frame } if (_sharedBound) _sharedBound->updateBound(p, getPDRFrame()); // Push New Frame _pdrFrame.push_back(_pdrFrame.back()); // Renders F Infinity to be the last in _pdrFrame if (_pdrBackup.size()) { _pdrFrame[_pdrFrame.size() - 2] = _pdrBackup.back(); _pdrBackup.pop_back(); addFrameInfoToSolver(_pdrFrame.size() - 2); } else _pdrFrame[_pdrFrame.size() - 2] = new V3MPDRFrame(_pdrSvr->reserveFormula()); // New Frame if (propagateCubes()) { proved = getPDRDepth(); break; } if (_maxDepth <= (getPDRFrame() - 1)) break; } else { badCube = recursiveBlockCube(badCube); if (badCube) { fired = getPDRDepth(); break; } // Interactively Show the Number of Bad Cubes in Frames if (!isIncKeepSilent() && intactON()) { if (!endLineON()) Msg(MSG_IFO) << "\r" + flushSpace + "\r"; Msg(MSG_IFO) << setw(3) << left << getPDRDepth() << " :"; const uint32_t j = (_pdrFrame.size() > 25) ? _pdrFrame.size() - 25 : 0; if (j) Msg(MSG_IFO) << " ..."; for (uint32_t i = j; i < _pdrFrame.size(); ++i) Msg(MSG_IFO) << " " << _pdrFrame[i]->getCubeList().size(); if (svrInfoON()) { Msg(MSG_IFO) << " ("; _pdrSvr->printInfo(); Msg(MSG_IFO) << ")"; } if (endLineON()) Msg(MSG_IFO) << endl; else Msg(MSG_IFO) << flush; } } } // Report Verification Result if (!isIncKeepSilent() && reportON()) { if (intactON()) { if (endLineON()) Msg(MSG_IFO) << endl; else Msg(MSG_IFO) << "\r" << flushSpace << "\r"; } if (V3NtkUD != proved) Msg(MSG_IFO) << "Inductive Invariant found at depth = " << ++proved; else if (V3NtkUD != fired) Msg(MSG_IFO) << "Counter-example found at depth = " << ++fired; else Msg(MSG_IFO) << "UNDECIDED at depth = " << _maxDepth; if (usageON()) { gettimeofday(&curtime, NULL); Msg(MSG_IFO) << " (time = " << setprecision(5) << getTimeUsed(inittime, curtime) << " sec)" << endl; } if (profileON()) { _totalStat->end(); Msg(MSG_IFO) << *_initSvrStat << endl; Msg(MSG_IFO) << *_solveStat << endl; Msg(MSG_IFO) << *_generalStat << endl; Msg(MSG_IFO) << *_propagateStat << endl; Msg(MSG_IFO) << *_ternaryStat << endl; Msg(MSG_IFO) << *_totalStat << endl; } } // Record CounterExample Trace or Invariant if (V3NtkUD != fired) { // Record Counter-Example // Compute PatternCount const V3MPDRCube* traceCube = badCube; assert (traceCube); assert (existInitial(traceCube->getState())); uint32_t patternCount = 0; while (_pdrBad != traceCube) { traceCube = traceCube->getNextCube(); ++patternCount; } V3CexTrace* const cex = new V3CexTrace(patternCount); assert (cex); _result[p].setCexTrace(cex); assert (_result[p].isCex()); // Set Pattern Value traceCube = badCube; assert (traceCube); assert (existInitial(traceCube->getState())); while (_pdrBad != traceCube) { if (_pdrSize) cex->pushData(traceCube->getInputData()); traceCube = traceCube->getNextCube(); assert (traceCube); } // Set Initial State Value if (_pdrInitValue.size()) { V3BitVecX initValue(_pdrInitValue.size()); for (uint32_t i = 0; i < badCube->getState().size(); ++i) { assert (initValue.size() > badCube->getState()[i].id); if (badCube->getState()[i].cp) initValue.set0(badCube->getState()[i].id); else initValue.set1(badCube->getState()[i].id); } for (uint32_t i = 0; i < _pdrInitValue.size(); ++i) if (_pdrInitConst[i]) { if (_pdrInitValue[i]) initValue.set0(i); else initValue.set1(i); } cex->setInit(initValue); } // Delete Cubes on the Trace const V3MPDRCube* lastCube; traceCube = badCube; while (_pdrBad != traceCube) { lastCube = traceCube->getNextCube(); delete traceCube; traceCube = lastCube; } // Check Common Results if (isIncVerifyUsingCurResult()) checkCommonCounterexample(p, *cex); } else if (V3NtkUD != proved) { // Record Inductive Invariant _result[p].setIndInv(_vrfNtk); assert (_result[p].isInv()); // Put the Inductive Invariant to Frame INF uint32_t f = 1; for (; f < getPDRDepth(); ++f) if (!_pdrFrame[f]->getCubeList().size()) break; assert (f < getPDRDepth()); for (uint32_t i = 1 + f; i < getPDRFrame(); ++i) { const V3MPDRCubeList& cubeList = _pdrFrame[i]->getCubeList(); V3MPDRCubeList::const_iterator it; for (it = cubeList.begin(); it != cubeList.end(); ++it) addBlockedCube(make_pair(getPDRFrame(), *it)); _pdrFrame[i]->clearCubeList(); delete _pdrFrame[i]; } // Remove Empty Frames _pdrFrame.back()->removeSelfSubsumed(); _pdrFrame[f] = _pdrFrame.back(); while ((1 + f) != _pdrFrame.size()) _pdrFrame.pop_back(); // Check Common Results if (isIncVerifyUsingCurResult()) { const V3MPDRCubeList& invCubeList = _pdrFrame.back()->getCubeList(); V3NetTable invList; invList.clear(); invList.reserve(invCubeList.size()); for (V3MPDRCubeList::const_iterator it = invCubeList.begin(); it != invCubeList.end(); ++it) invList.push_back((*it)->getState()); checkCommonProof(p, invList, false); } } }