// Functions for Checking Common Results void V3VrfBase::checkCommonCounterexample(const uint32_t& p, const V3CexTrace& cex) { assert (_result[p].isCex()); assert (cex.getTraceSize()); // Collect Unsolved Properties V3UI32Vec unsolved; unsolved.clear(); unsolved.reserve(_result.size()); for (uint32_t i = 0; i < _result.size(); ++i) if (!(_result[i].isCex() || _result[i].isInv())) unsolved.push_back(i); if (!unsolved.size()) return; assert (!_constr.size()); V3UI32Vec firedIndex, firedDepth; firedIndex.clear(); firedDepth.clear(); // Check Same Property const V3NetId pId = _vrfNtk->getOutput(p); for (uint32_t i = 0; i < unsolved.size(); ++i) { if (pId != _vrfNtk->getOutput(unsolved[i])) continue; firedIndex.push_back(unsolved[i]); firedDepth.push_back(cex.getTraceSize()); unsolved.erase(unsolved.begin() + i); --i; } // Create Simulator V3AlgSimulate* simulator = 0; V3BitVecX pattern; if (dynamic_cast<V3BvNtk*>(_vrfNtk)) simulator = new V3AlgBvSimulate(_handler); else simulator = new V3AlgAigSimulate(_handler); assert (simulator); // For each time-frame, set pattern from counter-example for (uint32_t i = 0, k; i < cex.getTraceSize(); ++i) { if (!unsolved.size()) break; // Update FF Next State Values simulator->updateNextStateValue(); // Set Initial State Values if (!i && cex.getInit()) { V3BitVecX* const initValue = cex.getInit(); k = 0; for (uint32_t j = 0; j < _vrfNtk->getLatchSize(); ++j, ++k) simulator->setSource(_vrfNtk->getLatch(j), initValue->bv_slice(k, k)); } // Set PI Values if (cex.getTraceDataSize()) pattern = cex.getData(i); k = 0; for (uint32_t j = 0; j < _vrfNtk->getInputSize(); ++j, ++k) simulator->setSource(_vrfNtk->getInput(j), pattern.bv_slice(k, k)); for (uint32_t j = 0; j < _vrfNtk->getInoutSize(); ++j, ++k) simulator->setSource(_vrfNtk->getInout(j), pattern.bv_slice(k, k)); // Simulate Ntk for a Cycle simulator->simulate(); // Check Property Assertion for (uint32_t j = 0; j < unsolved.size(); ++j) { if ('1' == simulator->getSimValue(_vrfNtk->getOutput(unsolved[j])).bv_slice(0, 0)[0]) { firedIndex.push_back(unsolved[j]); firedDepth.push_back(1 + i); unsolved.erase(unsolved.begin() + j); --j; } } } delete simulator; simulator = 0; assert (firedIndex.size() == firedDepth.size()); // Set Sub-Traces for Cex to Fired Properties for (uint32_t i = 0; i < firedIndex.size(); ++i) { V3CexTrace* const subTrace = new V3CexTrace(firedDepth[i]); assert (subTrace); if (cex.getTraceDataSize()) for (uint32_t j = 0; j < firedDepth[i]; ++j) subTrace->pushData(cex.getData(j)); if (cex.getInit()) subTrace->setInit(*(cex.getInit())); _result[firedIndex[i]].setCexTrace(subTrace); } }
void V3VrfBase::checkCommonProof(const uint32_t& p, const V3NetTable& invList, const bool& checkInitial) { assert (_result[p].isInv()); // Collect Unsolved Properties V3UI32Vec unsolved; unsolved.clear(); unsolved.reserve(_result.size()); for (uint32_t i = 0; i < _result.size(); ++i) if (!(_result[i].isCex() || _result[i].isInv())) unsolved.push_back(i); // Check Same Property const V3NetId pId = _vrfNtk->getOutput(p); for (uint32_t i = 0; i < unsolved.size(); ++i) { if (pId != _vrfNtk->getOutput(unsolved[i])) continue; _result[unsolved[i]].setIndInv(_vrfNtk); unsolved.erase(unsolved.begin() + i); --i; } if (!unsolved.size()) return; assert (!_constr.size()); // Create Solver V3SvrBase* const solver = allocSolver(getSolver(), _vrfNtk); assert (solver); V3SvrDataVec formula; formula.clear(); V3NetId id; uint32_t d = 0; // Set Inductive Invariant for (uint32_t i = 0; i < invList.size(); ++i) { formula.clear(); formula.reserve(invList[i].size()); for (uint32_t j = 0; j < invList[i].size(); ++j) { id = invList[i][j]; assert (_vrfNtk->getLatchSize() > id.id); assert (!d); if (!solver->existVerifyData(_vrfNtk->getLatch(id.id), d)) solver->addBoundedVerifyData(_vrfNtk->getLatch(id.id), d); assert (solver->existVerifyData(_vrfNtk->getLatch(id.id), d)); formula.push_back(solver->getFormula(_vrfNtk->getLatch(id.id), 0, d)); if (!id.cp) formula.back() = solver->getNegFormula(formula.back()); } solver->assertImplyUnion(formula); } if (checkInitial) { solver->assumeRelease(); solver->assumeInit(); if (solver->assump_solve()) { delete solver; return; } } // Check if the bad State Signal is Inconsistent with the Inductive Invariant for (uint32_t i = 0, j = 0; i < unsolved.size(); ++i) { solver->assumeRelease(); assert (!d); if (!solver->existVerifyData(_vrfNtk->getOutput(unsolved[i]), d)) solver->addBoundedVerifyData(_vrfNtk->getOutput(unsolved[i]), d); assert (solver->existVerifyData(_vrfNtk->getOutput(unsolved[i]), d)); solver->assumeProperty(_vrfNtk->getOutput(unsolved[i]), false, d); if (!solver->assump_solve()) { _result[unsolved[i]].setIndInv(_vrfNtk); j = 0; } else if (++j > 100) break; // Avoid Spending Too Much Effort on the Check } delete solver; }