コード例 #1
0
ファイル: v3sVrfIPDR2.cpp プロジェクト: SillyDuck/V3
void
V3SVrfIPDR::generalizeSimulation2(const uint32_t& d, V3SIPDRCube* const cube, const V3SIPDRCube* const nextCube) {
   assert (d < _pdrSvr.size()); assert (cube); assert (nextCube);
   assert (nextCube == cube->getNextCube()); assert (_pdrSim);
   // Set Values for Simulator
   for (uint32_t i = 0; i < _vrfNtk->getInputSize(); ++i) {
      if (!_pdrSvr[d]->existVerifyData(_vrfNtk->getInput(i), 0)) _pdrSim->clearSource(_vrfNtk->getInput(i), true);
      else _pdrSim->setSource(_vrfNtk->getInput(i), _pdrSvr[d]->getDataValue(_vrfNtk->getInput(i), 0));
   }
   for (uint32_t i = 0; i < _vrfNtk->getLatchSize(); ++i) {
      if (!_pdrSvr[d]->existVerifyData(_vrfNtk->getLatch(i), 0)) _pdrSim->clearSource(_vrfNtk->getLatch(i), true);
      else _pdrSim->setSource(_vrfNtk->getLatch(i), _pdrSvr[d]->getDataValue(_vrfNtk->getLatch(i), 0));
   }
   _pdrSim->simulate();

   // Perform SAT Generalization
   if (_pdrBad != nextCube) _pdrGen->setTargetNets2(V3NetVec(), nextCube->getState(), _decompDepth);
   else {
      V3NetVec constrCube(1, nextCube->getState()[0]);
      assert (1 == nextCube->getState().size()); _pdrGen->setTargetNets(constrCube);
   }
   // Set Priority
   V3UI32Vec prioNets; prioNets.clear(); prioNets.reserve(_pdrPriority.size());
   for (uint32_t i = 0; i < _pdrPriority.size(); ++i) if (!_pdrPriority[i]) prioNets.push_back(i);
   for (uint32_t i = 0; i < _pdrPriority.size(); ++i) if ( _pdrPriority[i]) prioNets.push_back(i);
   //_pdrGen->_tem = true;
   _pdrGen->performSetXForNotCOIVars(false); _pdrGen->performXPropForExtensibleVars(prioNets,false);
   cube->setState(_pdrGen->getGeneralizationResult());
}
コード例 #2
0
ファイル: v3VrfBase.cpp プロジェクト: hschiang/V3
// 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);
   }
}
コード例 #3
0
ファイル: v3Formula.cpp プロジェクト: SillyDuck/V3
V3Formula::V3Formula(V3NtkHandler* const handler, const uint32_t& constrSize, const uint32_t& maxCard, const V3GateType& gateType, const uint32_t& noPIorFF) : _handler(handler) {
   assert (handler); assert (constrSize); assert (maxCard); assert (!(noPIorFF & ~3ul));
   assert (BV_AND == gateType || BV_OR == gateType || BV_XOR == gateType || BV_XNOR == gateType);
   // Collect Leaf Candidates
   V3Ntk* const ntk = handler->getNtk(); assert (ntk);
   V3NetVec leafId; leafId.clear(); leafId.reserve(ntk->getInputSize() + ntk->getInoutSize() + ntk->getLatchSize());
   if (!(1ul & noPIorFF)) {
      for (uint32_t i = 0; i < ntk->getInputSize(); ++i) 
         if (1 == ntk->getNetWidth(ntk->getInput(i))) leafId.push_back(ntk->getInput(i));
      for (uint32_t i = 0; i < ntk->getInoutSize(); ++i) 
         if (1 == ntk->getNetWidth(ntk->getInout(i))) leafId.push_back(ntk->getInout(i));
   }
   if (!(2ul & noPIorFF)) {
      for (uint32_t i = 0; i < ntk->getLatchSize(); ++i) 
         if (1 == ntk->getNetWidth(ntk->getLatch(i))) leafId.push_back(ntk->getLatch(i));
   }
   V3UI32Vec constrId; constrId.clear(); constrId.reserve(constrSize); _formula.clear();
   // Create Constraints
   for (uint32_t i = 0; i < constrSize; ++i) {
      const uint32_t startId = _formula.size();
      // Create Leaf Nodes
      for (uint32_t j = 0; j < maxCard; ++j) {
         if (j && !(rand() % maxCard)) break;
         const V3NetId id = (rand() % 5) ? leafId[rand() % leafId.size()] : ~leafId[rand() % leafId.size()];
         _formula.push_back(make_pair(V3_PI, V3InputVec())); _formula.back().second.push_back(V3NetType(id));
      }
      assert (startId < _formula.size());
      // Link Leaf Nodes with the Specified GateType
      for (uint32_t j = 0, k = _formula.size() - startId; j < k; ++j) {
         if (!j) constrId.push_back(startId + j);
         else {
            _formula.push_back(make_pair(gateType, V3InputVec()));
            _formula.back().second.push_back(constrId.back());
            _formula.back().second.push_back(startId + j);
            constrId.back() = _formula.size() - 1;
         }
      }
      assert ((1 + i) == constrId.size());
   }
   // Combine Constraints
   for (uint32_t i = 0; i < constrId.size(); ++i) {
      if (!i) _rootId = constrId[i];
      else {
         _formula.push_back(make_pair(BV_AND, V3InputVec()));
         _formula.back().second.push_back(_rootId);
         _formula.back().second.push_back(constrId[i]);
         _rootId = _formula.size() - 1;
      }
   }
}
コード例 #4
0
ファイル: v3VrfBase.cpp プロジェクト: hschiang/V3
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;
}
コード例 #5
0
ファイル: v3Formula.cpp プロジェクト: SillyDuck/V3
// Constructor for Random Formula
V3Formula::V3Formula(V3NtkHandler* const handler, const V3SimTraceVec& cexTrace, const double& strength) : _handler(handler) {
   assert (handler); assert (cexTrace.size()); assert (strength > 0 && strength <= 1.00);
   V3UI32Vec constrId; constrId.clear(); constrId.reserve(cexTrace.size()); _formula.clear();
   // Create Constraints
   V3Ntk* const ntk = handler->getNtk(); assert (ntk);
   for (uint32_t i = 0; i < cexTrace.size(); ++i) {
      const uint32_t startId = _formula.size(), end = 1 + (uint32_t)(strength * ntk->getLatchSize());
      assert (cexTrace[i].size()); assert (ntk->getLatchSize() == cexTrace[i].size());
      for (uint32_t j = 0; j < end; ++j) {
         const uint32_t index = rand() % cexTrace[i].size(); assert (1 == ntk->getNetWidth(ntk->getLatch(index)));
         const V3NetId id = ('0' == cexTrace[i][index][0]) ? ~(ntk->getLatch(index)) : ntk->getLatch(index);
         _formula.push_back(make_pair(V3_PI, V3InputVec())); _formula.back().second.push_back(V3NetType(id));
      }
      assert (startId <= _formula.size());
      // Conjunction of Leaf Nodes
      for (uint32_t j = 0, k = _formula.size() - startId; j < k; ++j) {
         if (!j) constrId.push_back(startId + j);
         else {
            _formula.push_back(make_pair(BV_AND, V3InputVec()));
            _formula.back().second.push_back(constrId.back());
            _formula.back().second.push_back(startId + j);
            constrId.back() = _formula.size() - 1;
         }
      }
   }
   // Disjunction of Constraints
   for (uint32_t i = 0; i < constrId.size(); ++i) {
      if (!i) _rootId = constrId[i];
      else {
         _formula.push_back(make_pair(BV_OR, V3InputVec()));
         _formula.back().second.push_back(_rootId);
         _formula.back().second.push_back(constrId[i]);
         _rootId = _formula.size() - 1;
      }
   }
}
コード例 #6
0
ファイル: v3TransCmd.cpp プロジェクト: SillyDuck/V3
//----------------------------------------------------------------------
// MITer NTk <(unsigned ntkId1)> <(unsigned ntkId2)>
//           [-Name <(string miterNtkName)>] [| -SEC | -CEC] [-Merge]
//----------------------------------------------------------------------
V3CmdExecStatus
V3MiterNtkCmd::exec(const string& option) {
   vector<string> options;
   V3CmdExec::lexOptions(option, options);

   uint32_t id1 = V3NtkUD, id2 = V3NtkUD;
   bool miterName = false, miterNameON = false;
   bool sec = false, cec = false, merge = false;
   string miterNtkName = ""; int temp;
   
   size_t n = options.size();
   for (size_t i = 0; i < n; ++i) {
      const string& token = options[i];
      if (v3StrNCmp("-Name", token, 2) == 0) {
         if (miterName) return V3CmdExec::errorOption(CMD_OPT_EXTRA, token);
         else miterName = miterNameON = true;
      }
      else if (v3StrNCmp("-SEC", token, 4) == 0) {
         if (sec || cec) return V3CmdExec::errorOption(CMD_OPT_EXTRA, token);
         else sec = true;
      }
      else if (v3StrNCmp("-CEC", token, 4) == 0) {
         if (sec || cec) return V3CmdExec::errorOption(CMD_OPT_EXTRA, token);
         else cec = true;
      }
      else if (v3StrNCmp("-Merge", token, 2) == 0) {
         if (merge) return V3CmdExec::errorOption(CMD_OPT_EXTRA, token);
         else merge = true;
      }
      else if (miterNameON) { miterNameON = false; miterNtkName = token; }
      else if (V3NtkUD == id1) {
         if (!v3Str2Int(token, temp)) return V3CmdExec::errorOption(CMD_OPT_ILLEGAL, "(unsigned ntkId1)");
         else if (temp < 0) return V3CmdExec::errorOption(CMD_OPT_ILLEGAL, "(unsigned ntkId1)");
         id1 = (uint32_t)temp;
      }
      else if (V3NtkUD == id2) {
         if (!v3Str2Int(token, temp)) return V3CmdExec::errorOption(CMD_OPT_ILLEGAL, "(unsigned ntkId2)");
         else if (temp < 0) return V3CmdExec::errorOption(CMD_OPT_ILLEGAL, "(unsigned ntkId2)");
         id2 = (uint32_t)temp;
      }
      else return V3CmdExec::errorOption(CMD_OPT_ILLEGAL, token);
   }

   if (V3NtkUD == id1) return V3CmdExec::errorOption(CMD_OPT_MISSING, "(unsigned ntkId1)");
   if (V3NtkUD == id2) return V3CmdExec::errorOption(CMD_OPT_MISSING, "(unsigned ntkId2)");
   if (miterNameON) return V3CmdExec::errorOption(CMD_OPT_MISSING, "(string miterNtkName)");

   V3NtkHandler* const handler = v3Handler.getCurHandler();
   if (handler) {
      if (id1 >= v3Handler.getHandlerCount()) 
         Msg(MSG_ERR) << "Network with id = " << id1 << " Does NOT Exist !!" << endl;
      else if (id2 >= v3Handler.getHandlerCount()) 
         Msg(MSG_ERR) << "Network with id = " << id2 << " Does NOT Exist !!" << endl;
      else {
         V3NtkHandler* const handler1 = v3Handler.getHandler(id1); assert (handler);
         V3NtkHandler* const handler2 = v3Handler.getHandler(id2); assert (handler);
         if (!(reportIncompatibleModule(handler1, handler2) || reportIncompatibleModule(handler1, handler2))) {
            if (!cec) {
               V3NtkMiter* const miterHandler = new V3NtkMiter(handler1, handler2, merge, miterNtkName);
               assert (miterHandler); v3Handler.pushAndSetCurHandler(miterHandler);
            }
            else {
               // Compute Name Mapping for Latches Between Two Networks
               if (handler1->getNtk()->getLatchSize() == handler2->getNtk()->getLatchSize()) {
                  V3Map<string, uint32_t>::Map nameMap; nameMap.clear();
                  for (uint32_t i = 0; i < handler2->getNtk()->getLatchSize(); ++i)
                     nameMap.insert(make_pair(handler2->getNetName(handler2->getNtk()->getLatch(i)), i));
                  if (handler2->getNtk()->getLatchSize() == nameMap.size()) {
                     V3Map<string, uint32_t>::Map::const_iterator it; V3UI32Vec latchMap;
                     latchMap.clear(); latchMap.reserve(handler1->getNtk()->getLatchSize());
                     for (uint32_t i = 0; i < nameMap.size(); ++i) {
                        it = nameMap.find(handler1->getNetName(handler1->getNtk()->getLatch(i)));
                        if ((nameMap.end() == it) || 
                            (handler1->getNtk()->getNetWidth(handler1->getNtk()->getLatch(i)) != 
                             handler2->getNtk()->getNetWidth(handler2->getNtk()->getLatch(it->second)))) break;
                        else latchMap.push_back(it->second);
                     }
                     if (handler1->getNtk()->getLatchSize() == latchMap.size()) {
                        V3NtkMiter* const miterHandler = 
                           new V3NtkMiter(handler1, handler2, latchMap, merge, miterNtkName);
                        assert (miterHandler); v3Handler.pushAndSetCurHandler(miterHandler);
                     }
                     else Msg(MSG_ERR) << "Unmapped Latch " << latchMap.size() 
                                       << " Found in Network " << id1 << " !!" << endl;
                  }
                  else Msg(MSG_ERR) << "Repeated or Missing Latch Names Exist !!" << endl;
               }
               else Msg(MSG_ERR) << "Number of Latches in Networks NOT Matched : " << id1 << "(" 
                                 << handler1->getNtk()->getLatchSize() << ") != " << id2 << "(" 
                                 << handler2->getNtk()->getLatchSize() << ") !!" << endl;
            }
         }
      }
   }
   else Msg(MSG_ERR) << "Empty Ntk !!" << endl;
   return CMD_EXEC_DONE;
}
コード例 #7
0
ファイル: v3NtkElaborate.cpp プロジェクト: SillyDuck/V3
const V3NetId
V3NtkElaborate::elaborateL2S(const V3NetId& id) {
   assert (_ntk); assert (_p2cMap.size()); assert (id.id < _ntk->getNetSize());
   assert (isMutable()); assert (_shadow.size() == _handler->getNtk()->getLatchSize());
   // Create L2S Data Members if NOT Exist
   V3BvNtk* const bvNtk = dynamic_cast<V3BvNtk*>(_ntk);
   V3InputVec inputs; inputs.clear(); inputs.reserve(4);
   if (V3NetUD == _saved || V3NetUD == _1stSave || V3NetUD == _inLoop) {
      assert (V3NetUD == _saved && V3NetUD == _1stSave && V3NetUD == _inLoop);
      _saved = _ntk->createNet(1);  // Create Latch (_saved) for "In the Loop"
      const V3NetId oracle = _ntk->createNet(1), inSaved = _ntk->createNet(1);
      inputs.push_back(~_saved); inputs.push_back(~oracle); _ntk->setInput(inSaved, inputs);
      _ntk->createGate((bvNtk ? BV_AND : AIG_NODE), inSaved); inputs.clear();
      inputs.push_back(~inSaved); inputs.push_back(0); _ntk->setInput(_saved, inputs);
      _ntk->createLatch(_saved); inputs.clear(); _ntk->createInput(oracle);
      _1stSave = _ntk->createNet(1);  // Create Net (_1stSave) for "Loop Start"
      inputs.push_back(oracle); inputs.push_back(~_saved); _ntk->setInput(_1stSave, inputs);
      _ntk->createGate((bvNtk ? BV_AND : AIG_NODE), _1stSave); inputs.clear();
      _inLoop = _ntk->createNet(1);  // Create Net (_inLoop) for "_1stSave || _saved"
      inputs.push_back(~_1stSave); inputs.push_back(~_saved); _ntk->setInput(_inLoop, inputs);
      _ntk->createGate((bvNtk ? BV_AND : AIG_NODE), _inLoop); inputs.clear(); _inLoop = ~_inLoop;
   }
   // Create Equivalence Logic and Shadow FF if NOT Exist
   V3NetId ffId; V3GateType type; V3UI32Vec newShadow; newShadow.clear();
   for (uint32_t i = 0; i < _shadow.size(); ++i) {
      ffId = _p2cMap[_handler->getNtk()->getLatch(i).id]; assert (V3_FF == _ntk->getGateType(ffId));
      if (V3NetUD == ffId || V3NetUD != _shadow[i]) continue; newShadow.push_back(i);
      // Create Net for Shadow FF
      _shadow[i] = _ntk->createNet(_ntk->getNetWidth(ffId)); assert (V3NetUD != _shadow[i]);
      V3NetId shadowMux = V3NetUD;  // Create Input MUX of Shadow FF
      if (bvNtk) {
         inputs.push_back(_shadow[i]); inputs.push_back(ffId); inputs.push_back(_1stSave);
         type = BV_MUX; shadowMux = elaborateBvGate(bvNtk, type, inputs, _netHash);
      }
      else {
         inputs.push_back(_1stSave); inputs.push_back(ffId);
         inputs.push_back(~_1stSave); inputs.push_back(_shadow[i]);
         type = AIG_NODE; shadowMux = elaborateAigAndOrAndGate(_ntk, inputs, _netHash);
      }
      // Create Shadow FF
      assert (V3NetUD != shadowMux); inputs.clear(); inputs.push_back(shadowMux);
      if (_ntk->getNetWidth(ffId) == 1) inputs.push_back(0);
      else {
         V3InputVec constInputs(1, bvNtk->hashV3ConstBitVec(v3Int2Str(_ntk->getNetWidth(ffId)) + "'d0"));
         type = BV_CONST; inputs.push_back(elaborateBvGate(bvNtk, type, constInputs, _netHash));
      }
      _ntk->setInput(_shadow[i], inputs); _ntk->createLatch(_shadow[i]); inputs.clear();
      // Create Equivalence Gate and Update _shadow
      if (bvNtk) {
         inputs.push_back(ffId); inputs.push_back(_shadow[i]); type = BV_EQUALITY;
         _shadow[i] = elaborateBvGate(bvNtk, type, inputs, _netHash);
      }
      else {
         inputs.push_back(ffId); inputs.push_back(_shadow[i]);
         inputs.push_back(~ffId); inputs.push_back(~_shadow[i]);
         _shadow[i] = elaborateAigAndOrAndGate(_ntk, inputs, _netHash);
      }
      assert (V3NetUD != _shadow[i]); assert (1 == _ntk->getNetWidth(_shadow[i])); inputs.clear();
   }
   // Create or Update Net (_looped) for "Loop Found" if NOT Exist
   if (V3NetUD == _looped) _looped = _saved;
   for (uint32_t i = 0; i < newShadow.size(); ++i) {
      assert (V3NetUD != _p2cMap[_handler->getNtk()->getLatch(i).id]); assert (V3NetUD != _shadow[i]);
      inputs.push_back(_looped); inputs.push_back(_shadow[i]);
      if (bvNtk) { type = BV_AND; _looped = elaborateBvGate(bvNtk, type, inputs, _netHash); }
      else { type = AIG_NODE; _looped = elaborateAigGate(_ntk, type, inputs, _netHash); }
      assert (V3NetUD != _looped); inputs.clear();
   }
   if (V3NetId::makeNetId(0) == ~id) return _looped;
   // Create Latch (pLatch) for Recording Existence of Violation to id
   const V3NetId pLatch = _ntk->createNet(1), in_pLatch = _ntk->createNet(1);
   inputs.push_back(~pLatch); inputs.push_back(id); _ntk->setInput(in_pLatch, inputs);
   _ntk->createGate((bvNtk ? BV_AND : AIG_NODE), in_pLatch); inputs.clear();
   inputs.push_back(~in_pLatch); inputs.push_back(0); _ntk->setInput(pLatch, inputs);
   _ntk->createLatch(pLatch); inputs.clear();
   // Create L2S Property Output (to Witness "_looped && in_pLatch")
   V3NetId pId = V3NetUD; inputs.push_back(_looped); inputs.push_back(in_pLatch);
   if (bvNtk) { type = BV_AND; pId = elaborateBvGate(bvNtk, type, inputs, _netHash); }
   else { type = AIG_NODE; pId = elaborateAigGate(_ntk, type, inputs, _netHash); }
   assert (V3NetUD != pId); inputs.clear(); return pId;
}