예제 #1
0
파일: TechMapCNF.cpp 프로젝트: graydon/iimc
  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]);
        }
      }
    }
  }