void techMap(Options::Verbosity verbosity, const ::AIGAttachment& aigat, unsigned k, unsigned b, unsigned refinements, ::std::vector<ID>& outputs, ::Expr::Manager::View& v, ::std::vector< ::std::vector<ID> >& cnf, ::std::vector<ID>& roots, double timeOut, bool add_roots) { // convert outputs into AIG references ::std::vector< ::Opt::NodeRef> aig_outputs; for(unsigned outi = 0; outi < outputs.size(); ++outi) { ::Opt::IDRefMap::const_iterator fit = aigat.id2ref.find(outputs[outi]); assert(fit != aigat.id2ref.end()); aig_outputs.push_back(fit->second); } // make roots match the size of outputs roots.resize(aig_outputs.size()); // a place for AIG CNF ::std::vector< ::std::vector< ::Opt::NodeRef> > nrcnf; // do CNF generation techMap(verbosity, aigat, k, b, refinements, aig_outputs, nrcnf, timeOut, add_roots); // convert AIG CNF to Expr CNF typedef ::std::vector< ::std::vector< ::Opt::NodeRef> > aigcnf; std::map< ::Opt::NodeIndex, ID> newvars; cnf.resize(0); unsigned clause = 0; for(aigcnf::iterator i = nrcnf.begin(); i != nrcnf.end(); ++i, ++clause) { cnf.resize(cnf.size()+1); for(::std::vector< ::Opt::NodeRef>::iterator j = i->begin(); j != i->end(); ++j) { ID lit; if(*j == 0) { // map to false lit = v.bfalse(); } else if(*j == 1) { // map to true lit = v.btrue(); } else if(aigat.aig[ ::Opt::indexOf(*j)].isVar()) { // use existing inputs lit = aigat.ref2id.find(::Opt::refOf(::Opt::indexOf(*j), false))->second; if(::Opt::isNot(*j)) { // negate them if necessary lit = v.apply(::Expr::Not, lit); } } else { std::map< ::Opt::NodeIndex, ID>::iterator fj = newvars.find(::Opt::indexOf(*j)); if(fj == newvars.end()) { // create new variable ::std::stringstream s; s << "tmv" << *j; lit = v.newVar(s.str()); newvars[::Opt::indexOf(*j)] = lit; } else { // use existing var lit = fj->second; } if(::Opt::isNot(*j)) { lit = v.apply(::Expr::Not, lit); } } cnf[clause].push_back(lit); } } // fill in the roots vector unsigned j = 0; for(::std::vector< ::Opt::NodeRef>::iterator i = aig_outputs.begin(); i != aig_outputs.end(); ++i,++j) { if(*i == 0) { // map to false roots[j] = v.bfalse(); } else if(*i == 1) { // map to true roots[j] = v.btrue(); } else if(aigat.aig[ ::Opt::indexOf(*i)].isVar()) { // use existing input roots[j] = aigat.ref2id.find(::Opt::refOf(::Opt::indexOf(*i), false))->second; if(::Opt::isNot(*i)) { // negate as necessary roots[j] = v.apply(::Expr::Not, roots[j]); } } else { // use existing map std::map< ::Opt::NodeIndex, ID>::iterator fi = newvars.find(::Opt::indexOf(*i)); // it should be found assert(fi != newvars.end()); roots[j] = fi->second; if(::Opt::isNot(*i)) { // negate as necessary roots[j] = v.apply(::Expr::Not, roots[j]); } } } }