예제 #1
0
/**
 * Cluster conjuncts to produce a partitioned transition relation.
 *
 * Conjuncts larger than limit are rejected (unless they are
 * singletons).
 */
vector<BDD> BddTrAttachment::clusterConjunctsOld(
  vector<BDD>& conjuncts,
  unsigned int limit,
  Options::Verbosity verbosity,
  int nvars) const
{
  vector<BDD> clusters;
  if (conjuncts.size() == 0) {
    clusters.push_back(bddManager().bddOne());
    return clusters;
  }
  vector<BDD>::const_reverse_iterator it = conjuncts.rbegin();
  BDD cluster = *it++;
  conjuncts.pop_back();
  while (it != conjuncts.rend()) {
    reportBDD("conjunct", *it, nvars, verbosity, Options::Informative);
    BDD tmp = cluster.And(*it,limit);
    if (tmp && (unsigned int) tmp.nodeCount() <= 2*limit) {
      cluster = tmp;
    } else {
      reportBDD("Cluster", cluster, nvars, verbosity, Options::Informative);
      clusters.push_back(cluster);
      cluster = *it;
    }
    ++it;
    conjuncts.pop_back();
  }
  reportBDD("Cluster", cluster, nvars, verbosity, Options::Informative);
  clusters.push_back(cluster);
  return clusters;

} // BddTrAttachment::clusterConjunctsOld
예제 #2
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
예제 #3
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