Пример #1
0
/**
 * Quantify local primary input and auxiliary variables.
 */
BDD BddTrAttachment::quantifyLocalInputs(
  vector<BDD>& conjuncts,
  const BDD& qcube,
  unsigned int limit,
  Options::Verbosity verbosity) const
{
  // A -1 means "not yet seen."
  // A -2 means "seen in more than one conjunct."
  vector<int> whereSeen(bddManager().ReadSize(),-1);
  for (vector<BDD>::size_type i = 0; i != conjuncts.size(); ++i) {
    vector<unsigned int> support = conjuncts[i].SupportIndices();
    for (vector<unsigned int>::const_iterator j = support.begin();
         j != support.end(); ++j) {
      if (whereSeen[*j] == -1)
        whereSeen[*j] = i;
      else
        whereSeen[*j] = -2;
    }
  }

  // Attempt quantification of variables seen exactly once, but
  // back off if this blows up the conjunct.
  vector<unsigned int> qvars = qcube.SupportIndices();
  BDD ret = bddManager().bddOne();
  for (vector<unsigned int>::size_type i = 0; i != qvars.size(); ++i) {
    unsigned int index = qvars[i];
    BDD bvar = bddManager().bddVar(qvars[i]);
    int ws = whereSeen[index];
    if (ws >= 0) {
      int currentLimit = conjuncts[ws].nodeCount();
      BDD tmp = conjuncts[ws].ExistAbstract(bvar, currentLimit);
      if (tmp && tmp.nodeCount() <= currentLimit) {
        conjuncts[ws] = tmp;
#if 0
        cout << "Eliminated local variable " << index 
             << " from conjunct " << ws << endl;
#endif
      } else {
#if 0
        cout << "Failed to eliminate local variable " << index 
             << " from conjunct " << ws << endl;
#endif
        ret &= bvar;
      }
    } else {
      ret &= bvar;
    }
  }
  assert(qcube <= ret);
  if (verbosity > Options::Terse)
    cout << "Number of clusters/nodes = " << conjuncts.size()
         << "/" << bddManager().SharingSize(conjuncts) << endl;

  return ret;

} // BddTrAttachment::quantifyLocalInputs
Пример #2
0
/**
 * Compose auxiliary functions recursively into a BDD.
 */
void BddTrAttachment::composeAuxiliaryFunctions(
  BddAttachment const * bat,
  BDD & f,
  unordered_map<int, ID> const & index2id)
{
  vector<unsigned int> support = f.SupportIndices();
  queue< vector<unsigned int> > q;
  q.push(support);
  while (!q.empty()) {
    vector<unsigned int> supp = q.front();
    q.pop();
    for (vector<unsigned int>::const_iterator j = supp.begin();
         j != supp.end(); ++j) {
      unordered_map<int,ID>::const_iterator cit = index2id.find(*j);
      if (cit != index2id.end()) {
        BDD g = bat->bdd(cit->second);
        BDD a = bddManager().bddVar(*j);
        f = f.AndAbstract(a.Xnor(g),a);
        vector<unsigned int> addSupp = g.SupportIndices();
        q.push(addSupp);
      }
    }
  }
}
Пример #3
0
/**
 * Eliminate auxiliary variables from output function.
 */
BDD BddTrAttachment::flattenOutput(
  const vector<BDD>& conjuncts,
  const BDD& wCube)
{
  vector<BDD> schedule;
  for (vector<BDD>::size_type i = 0; i != conjuncts.size(); ++i) {
    schedule.push_back(bddManager().bddOne());
  }

  // For each variable appearing in the conjuncts find the last
  // conjunct in which it appears.
  vector<int> lastSeen(bddManager().ReadSize(),-1);
  for (vector<BDD>::size_type i = 0; i != conjuncts.size(); ++i) {
    vector<unsigned int> support = conjuncts[i].SupportIndices();
    for (vector<unsigned int>::const_iterator j = support.begin();
         j != support.end(); ++j) {
      lastSeen[*j] = i;
    }
  }

  vector<unsigned int> wVars = wCube.SupportIndices();
#if 0
  printVector("wVars", wVars); // Diagnostic printout.
#endif
  for (vector<unsigned int>::size_type i = 0; i != wVars.size(); ++i) {
    unsigned int index = wVars[i];
    int ls = lastSeen[index];
    if (ls >= 0) {
      BDD var = bddManager().bddVar(index);
      schedule[ls] &= var;
    }
  }

  BDD ret = bddManager().bddOne();
  for (vector<BDD>::size_type i = 0; i != conjuncts.size(); ++i) {
    ret = ret.AndAbstract(conjuncts[i], schedule[i]);
  }
  return ret;

} // BddTrAttachment::flattenOutput
Пример #4
0
/**
 * Compute the quantification schedule for the primary inputs and the
 * auxiliary variables.
 */
void BddTrAttachment::computeSchedule(
  const vector<BDD>& conjuncts,
  const BDD& wCube)
{
  vector<BDD> fwSchedule, bwSchedule;
  for (vector<BDD>::size_type i = 0; i != conjuncts.size(); ++i) {
    fwSchedule.push_back(bddManager().bddOne());
    bwSchedule.push_back(bddManager().bddOne());
  }
  _prequantx = bddManager().bddOne();
  _prequanty = bddManager().bddOne();

  // For each variable appearing in the conjuncts find the last
  // conjunct in which it appears.
  vector<int> lastSeen(bddManager().ReadSize(),-1);
  for (vector<BDD>::size_type i = 0; i != conjuncts.size(); ++i) {
    vector<unsigned int> support = conjuncts[i].SupportIndices();
    for (vector<unsigned int>::const_iterator j = support.begin();
         j != support.end(); ++j) {
      lastSeen[*j] = i;
    }
  }

  vector<unsigned int> wVars = wCube.SupportIndices();
#if 0
  printVector("wVars", wVars); // Diagnostic printout.
#endif
  for (vector<unsigned int>::size_type i = 0; i != wVars.size(); ++i) {
    unsigned int index = wVars[i];
    int ls = lastSeen[index];
    if (ls >= 0) {
      BDD var = bddManager().bddVar(index);
      fwSchedule[ls] &= var;
      bwSchedule[ls] &= var;
    }
  }

  for (vector<BDD>::size_type i = 0; i != _xvars.size(); ++i) {
    unsigned int index = _xvars[i].NodeReadIndex();
    int ls = lastSeen[index];
    if (ls >= 0) {
      fwSchedule[ls] &= _xvars[i];
    } else {
      _prequantx &= _xvars[i];
    }
  }

  for (vector<BDD>::size_type i = 0; i != _yvars.size(); ++i) {
    unsigned int index = _yvars[i].NodeReadIndex();
    int ls = lastSeen[index];
    if (ls >= 0) {
      bwSchedule[ls] &= _yvars[i];
    } else {
      _prequanty &= _yvars[i];
    }
  }

  for (vector<BDD>::size_type i = 0; i != conjuncts.size(); ++i) {
    _tr.push_back(RelPart(conjuncts[i], fwSchedule[i], bwSchedule[i]));
  }

} // BddTrAttachment::computeSchedule
Пример #5
0
vector<BDD> BddTrAttachment::clusterConjuncts(
  vector<BDD>& conjuncts,
  const BDD& qcube,
  unsigned int limit,
  Options::Verbosity verbosity) const
{
  vector<BDD> clusters;
  if (conjuncts.size() == 0) {
    clusters.push_back(bddManager().bddOne());
    return clusters;
  }
  // Create records of occurrence of all variables in the conjuncts.
  // The variables that occur in no conjuncts end up with
  // earliest > latest.  For the others, we know the first and last
  // conjunct in which they occur.
  unsigned int numvars = bddManager().ReadSize();
  unsigned int nconjuncts = conjuncts.size();
  vector<VarRec> occurrence;
  occurrence.reserve(numvars);
  for (unsigned int i = 0; i != numvars; ++i) {
    occurrence.push_back(VarRec(i,nconjuncts,-1));
  }
  for (vector<BDD>::size_type i = 0; i != nconjuncts; ++i) {
    vector<unsigned int> support = conjuncts[i].SupportIndices();
    for (vector<unsigned int>::const_iterator j = support.begin();
         j != support.end(); ++j) {
      if (occurrence[*j].earliest() > (int) i)
        occurrence[*j].setEarliest((int) i);
      if (occurrence[*j].latest() < (int) i)
        occurrence[*j].setLatest((int) i);
    }
  }

  // Filter variables that are not candidates for quantification
  // and are not present in the conjuncts.
  vector<unsigned int> qvars = qcube.SupportIndices();
  unordered_set<unsigned int> qset(qvars.begin(), qvars.end());
  vector<VarRec> candidate;
  candidate.reserve(qvars.size());
  for (vector<VarRec>::const_iterator i = occurrence.begin();
       i != occurrence.end(); ++i) {
    if (qset.find(i->index()) != qset.end() &&
        i->earliest() <= i->latest())
      candidate.push_back(*i);
  }
  // Sort occurrence records according to latest occurrence
  // using earliest occurrence as tie breaker.
  stable_sort(candidate.begin(), candidate.end());
#if 0
  // Diagnostic printout.
  for (vector<VarRec>::const_iterator i = candidate.begin();
       i != candidate.end(); ++i) {
    cout << "Variable: " << i->index() << " ("
         << i->earliest() << "," << i->latest() << ")\n";
  }
#endif

  // We are now ready for clustering having collected the
  // information of which variables may be quantified when.
  // In the following, i points to the first conjunct in the cluster.
  // (Conjunct of highest index since we go backwards.)
  int i = conjuncts.size() - 1;
  BDD cluster = conjuncts[i];
  conjuncts.pop_back();
  // j points to the conjuncts that is being added to the cluster.
  int j = i - 1;
  // k points to the candidates for quantification
  vector<VarRec>::size_type k = 0;
  while (j >= 0) {
    reportBDD("conjunct", conjuncts[j], numvars, verbosity, Options::Informative);
    // Find variables that are local to cluster.  A variable is local to
    // the current cluster if its lifespan is entirely contained between
    // i and j.
    BDD qcube = bddManager().bddOne();
    while (k < candidate.size() && candidate[k].latest() > (int) i)
      k++;
    while (k < candidate.size() && candidate[k].earliest() >= (int) j) {
      qcube &= bddManager().bddVar(candidate[k].index());
      k++;
    }
    BDD tmp = cluster.AndAbstract(conjuncts[j], qcube, limit);
    if (tmp && (unsigned int) tmp.nodeCount() <= 2*limit) {
      cluster = tmp;
    } else {
      reportBDD("Cluster", cluster, numvars, verbosity, Options::Informative);
      clusters.push_back(cluster);
      i = j;
      cluster = conjuncts[i];
    }
    j--;
    conjuncts.pop_back();
  }
  reportBDD("Cluster", cluster, numvars, verbosity, Options::Informative);
  clusters.push_back(cluster);
  return clusters;

} // BddTrAttachment::clusterConjuncts