const bool V3SVrfIPDR::checkReachability2(const uint32_t& frame, const V3NetVec& cubeState, const bool& extend, const bool& notImportant) { if(heavy_debug && !notImportant){ cerr << "\n!!!!!!checkReachability2 frame : " << frame << " cube : "; printState(cubeState); cerr << endl; } assert (frame > 0); assert (frame < getPDRFrame()); const uint32_t& d = frame - 1; _pdrSvr[d]->assumeRelease(); // Assume cube' addCubeToSolver2(d, cubeState, 0); /*V3SSvrMiniSat * gg= (V3SSvrMiniSat *)_pdrSvr[d]; for (unsigned i = 0; i < 40; ++i){ cerr << i << " : " << gg->getVerifyData( i ,0 ) << endl; }*/ for (uint32_t i = 0; i < cubeState.size(); ++i) _pdrSvr[d]->assumeProperty(_pdrSvr[d]->getFormula(_handler->_latchMap->at(_decompDepth)[cubeState[i].id], 0), cubeState[i].cp); if (extend) { // Assume ~cube addCubeToSolver(d, cubeState, 0); V3SvrDataVec blockCube; blockCube.clear(); blockCube.reserve(cubeState.size()); size_t fId; for (uint32_t i = 0; i < cubeState.size(); ++i) { fId = _pdrSvr[d]->getFormula(_vrfNtk->getLatch(cubeState[i].id), 0); blockCube.push_back(cubeState[i].cp ? fId : _pdrSvr[d]->getNegFormula(fId)); } _pdrSvrData = _pdrSvr[d]->setImplyUnion(blockCube); assert (_pdrSvrData); _pdrSvr[d]->assumeProperty(_pdrSvrData); // Check Reachability by SAT Calling if (profileON()) _solveStat->start(); _pdrSvr[d]->simplify(); const bool result = _pdrSvr[d]->assump_solve(); if (profileON()) _solveStat->end(); _pdrSvr[d]->assertProperty(_pdrSvr[d]->getNegFormula(_pdrSvrData)); // Invalidate ~cube in future solving if(heavy_debug && !notImportant) cerr << "result: " << result << endl << endl; return result; } else { if (profileON()) _solveStat->start(); /*V3SSvrMiniSat * GG = (V3SSvrMiniSat *)_pdrSvr[d]; for (unsigned i = 0, s = GG->_assump.size(); i < s; ++i){ cout << var(GG->_assump[i]) << ":" << sign(GG->_assump[i]) << endl; }*/ _pdrSvr[d]->simplify(); const bool result = _pdrSvr[d]->assump_solve(); if (profileON()) _solveStat->end(); if(heavy_debug && !notImportant) cerr << "result: " << result << endl << endl; return result; } }
void V3VrfMPDR::addFrameInfoToSolver(const uint32_t& f) { assert (f); assert (f < _pdrFrame.size()); _pdrFrame[f]->setActivator(_pdrSvr->reserveFormula()); const V3MPDRCubeList& cubeList = _pdrFrame[f]->getCubeList(); V3SvrDataVec formula; formula.clear(); size_t fId; for (V3MPDRCubeList::const_reverse_iterator it = cubeList.rbegin(); it != cubeList.rend(); ++it) { addCubeToSolver((*it)->getState(), 0); formula.reserve(1 + (*it)->getState().size()); formula.push_back(_pdrSvr->getNegFormula(_pdrFrame[f]->getActivator())); for (uint32_t j = 0; j < (*it)->getState().size(); ++j) { fId = _pdrSvr->getFormula(_vrfNtk->getLatch((*it)->getState()[j].id), 0); formula.push_back((*it)->getState()[j].cp ? fId : _pdrSvr->getNegFormula(fId)); } _pdrSvr->assertProperty(_pdrSvr->setImplyUnion(formula)); formula.clear(); } }
void V3VrfMPDR::addBlockedCube(const V3MPDRTimedCube& cube) { assert (cube.first <= getPDRFrame()); assert (cube.second->getState().size()); // Push cube into corresponding frame that it should be blocked if (!_pdrFrame[cube.first]->pushCube(cube.second)) return; // Renders this cube to be blocked as frame activator is asserted const V3NetVec& state = cube.second->getState(); addCubeToSolver(state, 0); V3SvrDataVec formula; formula.clear(); formula.reserve(1 + state.size()); size_t fId; formula.push_back(_pdrSvr->getNegFormula(_pdrFrame[cube.first]->getActivator())); for (uint32_t i = 0; i < state.size(); ++i) { fId = _pdrSvr->getFormula(_vrfNtk->getLatch(state[i].id), 0); formula.push_back(state[i].cp ? fId : _pdrSvr->getNegFormula(fId)); ++_pdrPriority[state[i].id]; // Increase Signal Priority } _pdrSvr->assertProperty(_pdrSvr->setImplyUnion(formula)); // Share Invariants if (_sharedInv && (cube.first == getPDRFrame())) _sharedInv->updateInv(state); }
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()); }