Example #1
0
int InstStrategyFreeVariable::process( Node f, Theory::Effort effort, int e ){
  if( e<5 ){
    return STATUS_UNFINISHED;
  }else{
    //first, try from relevant domain
    RelevantDomain * rd = d_quantEngine->getRelevantDomain();
    for( unsigned r=0; r<2; r++ ){
      if( rd || r==1 ){
        if( r==0 ){
          Trace("inst-alg") << "-> Relevant domain instantiate " << f << "..." << std::endl;
        }else{
          Trace("inst-alg") << "-> Guess instantiate " << f << "..." << std::endl;
        }
        rd->compute();
        unsigned final_max_i = 0;
        std::vector< unsigned > maxs;
        for(unsigned i=0; i<f[0].getNumChildren(); i++ ){
          unsigned ts;
          if( r==0 ){
            ts = rd->getRDomain( f, i )->d_terms.size();
          }else{
            ts = d_quantEngine->getTermDatabase()->d_type_map[f[0][i].getType()].size();
          }
          maxs.push_back( ts );
          Trace("inst-alg-rd") << "Variable " << i << " has " << ts << " in relevant domain." << std::endl;
          if( ts>final_max_i ){
            final_max_i = ts;
          }
        }
        Trace("inst-alg-rd") << "Will do " << final_max_i << " stages of instantiation." << std::endl;

        unsigned max_i = 0;
        bool success;
        while( max_i<=final_max_i ){
          Trace("inst-alg-rd") << "Try stage " << max_i << "..." << std::endl;
          std::vector< unsigned > childIndex;
          int index = 0;
          do {
            while( index>=0 && index<(int)f[0].getNumChildren() ){
              if( index==(int)childIndex.size() ){
                childIndex.push_back( -1 );
              }else{
                Assert( index==(int)(childIndex.size())-1 );
                unsigned nv = childIndex[index]+1;
                if( options::cbqi() ){
                  //skip inst constant nodes
                  while( nv<maxs[index] && nv<=max_i &&
                         r==1 && quantifiers::TermDb::hasInstConstAttr( d_quantEngine->getTermDatabase()->d_type_map[f[0][index].getType()][nv] ) ){
                    childIndex[index]++;
                    nv = childIndex[index]+1;
                  }
                }
                if( nv<maxs[index] && nv<=max_i ){
                  childIndex[index]++;
                  index++;
                }else{
                  childIndex.pop_back();
                  index--;
                }
              }
            }
            success = index>=0;
            if( success ){
              Trace("inst-alg-rd") << "Try instantiation..." << std::endl;
              index--;
              //try instantiation
              std::vector< Node > terms;
              for( unsigned i=0; i<f[0].getNumChildren(); i++ ){
                if( r==0 ){
                  terms.push_back( rd->getRDomain( f, i )->d_terms[childIndex[i]] );
                }else{
                  terms.push_back( d_quantEngine->getTermDatabase()->d_type_map[f[0][i].getType()][childIndex[i]] );
                }
              }
              if( d_quantEngine->addInstantiation( f, terms, false ) ){
                Trace("inst-alg-rd") << "Success!" << std::endl;
                ++(d_quantEngine->getInstantiationEngine()->d_statistics.d_instantiations_guess);
                return STATUS_UNKNOWN;
              }
            }
          }while( success );
          max_i++;
        }
      }
      if( r==0 ){
        if( d_guessed.find( f )==d_guessed.end() ){
          Trace("inst-alg") << "-> Guess instantiate " << f << "..." << std::endl;
          d_guessed[f] = true;
          InstMatch m( f );
          if( d_quantEngine->addInstantiation( f, m ) ){
            ++(d_quantEngine->getInstantiationEngine()->d_statistics.d_instantiations_guess);
            return STATUS_UNKNOWN;
          }
        }
      }
    }
    return STATUS_UNKNOWN;
  }
}
Example #2
0
void InstStrategyEnum::check(Theory::Effort e, QEffort quant_e)
{
  bool doCheck = false;
  bool fullEffort = false;
  if (options::fullSaturateInterleave())
  {
    // we only add when interleaved with other strategies
    doCheck = quant_e == QEFFORT_STANDARD && d_quantEngine->hasAddedLemma();
  }
  if (options::fullSaturateQuant() && !doCheck)
  {
    doCheck = quant_e == QEFFORT_LAST_CALL;
    fullEffort = !d_quantEngine->hasAddedLemma();
  }
  if (!doCheck)
  {
    return;
  }
  double clSet = 0;
  if (Trace.isOn("fs-engine"))
  {
    clSet = double(clock()) / double(CLOCKS_PER_SEC);
    Trace("fs-engine") << "---Full Saturation Round, effort = " << e << "---"
                       << std::endl;
  }
  unsigned rstart = options::fullSaturateQuantRd() ? 0 : 1;
  unsigned rend = fullEffort ? 1 : rstart;
  unsigned addedLemmas = 0;
  // First try in relevant domain of all quantified formulas, if no
  // instantiations exist, try arbitrary ground terms.
  // Notice that this stratification of effort levels makes it so that some
  // quantified formulas may not be instantiated (if they have no instances
  // at effort level r=0 but another quantified formula does). We prefer
  // this stratification since effort level r=1 may be highly expensive in the
  // case where we have a quantified formula with many entailed instances.
  FirstOrderModel* fm = d_quantEngine->getModel();
  RelevantDomain* rd = d_quantEngine->getRelevantDomain();
  unsigned nquant = fm->getNumAssertedQuantifiers();
  std::map<Node, bool> alreadyProc;
  for (unsigned r = rstart; r <= rend; r++)
  {
    if (rd || r > 0)
    {
      if (r == 0)
      {
        Trace("inst-alg") << "-> Relevant domain instantiate..." << std::endl;
        Trace("inst-alg-debug") << "Compute relevant domain..." << std::endl;
        rd->compute();
        Trace("inst-alg-debug") << "...finished" << std::endl;
      }
      else
      {
        Trace("inst-alg") << "-> Ground term instantiate..." << std::endl;
      }
      for (unsigned i = 0; i < nquant; i++)
      {
        Node q = fm->getAssertedQuantifier(i, true);
        bool doProcess = d_quantEngine->hasOwnership(q, this)
                         && fm->isQuantifierActive(q)
                         && alreadyProc.find(q) == alreadyProc.end();
        if (doProcess)
        {
          if (process(q, fullEffort, r == 0))
          {
            // don't need to mark this if we are not stratifying
            if (!options::fullSaturateStratify())
            {
              alreadyProc[q] = true;
            }
            // added lemma
            addedLemmas++;
            if (d_quantEngine->inConflict())
            {
              break;
            }
          }
        }
      }
      if (d_quantEngine->inConflict()
          || (addedLemmas > 0 && options::fullSaturateStratify()))
      {
        // we break if we are in conflict, or if we added any lemma at this
        // effort level and we stratify effort levels.
        break;
      }
    }
  }
  if (Trace.isOn("fs-engine"))
  {
    Trace("fs-engine") << "Added lemmas = " << addedLemmas << std::endl;
    double clSet2 = double(clock()) / double(CLOCKS_PER_SEC);
    Trace("fs-engine") << "Finished full saturation engine, time = "
                       << (clSet2 - clSet) << std::endl;
  }
}
Example #3
0
bool FullSaturation::process( Node f, bool fullEffort ){
  //first, try from relevant domain
  RelevantDomain * rd = d_quantEngine->getRelevantDomain();
  unsigned rstart = options::fullSaturateQuantRd() ? 0 : 1;
  unsigned rend = fullEffort ? 1 : rstart;
  for( unsigned r=rstart; r<=rend; r++ ){
    if( rd || r>0 ){
      if( r==0 ){
        Trace("inst-alg") << "-> Relevant domain instantiate " << f << "..." << std::endl;
      }else{
        Trace("inst-alg") << "-> Ground term instantiate " << f << "..." << std::endl;
      }
      rd->compute();
      unsigned final_max_i = 0;
      std::vector< unsigned > maxs;
      std::vector< bool > max_zero;
      bool has_zero = false;
      for(unsigned i=0; i<f[0].getNumChildren(); i++ ){
        unsigned ts;
        if( r==0 ){
          ts = rd->getRDomain( f, i )->d_terms.size();
        }else{
          ts = d_quantEngine->getTermDatabase()->getNumTypeGroundTerms( f[0][i].getType() );
        }
        max_zero.push_back( fullEffort && ts==0 );
        ts = ( fullEffort && ts==0 ) ? 1 : ts;
        Trace("inst-alg-rd") << "Variable " << i << " has " << ts << " in relevant domain." << std::endl;
        if( ts==0 ){
          has_zero = true;
          break;
        }else{
          maxs.push_back( ts );
          if( ts>final_max_i ){
            final_max_i = ts;
          }
        }
      }
      if( !has_zero ){
        std::vector< TypeNode > ftypes;
        for( unsigned i=0; i<f[0].getNumChildren(); i++ ){
          ftypes.push_back( f[0][i].getType() );
        }
      
        Trace("inst-alg-rd") << "Will do " << final_max_i << " stages of instantiation." << std::endl;
        unsigned max_i = 0;
        bool success;
        while( max_i<=final_max_i ){
          Trace("inst-alg-rd") << "Try stage " << max_i << "..." << std::endl;
          std::vector< unsigned > childIndex;
          int index = 0;
          do {
            while( index>=0 && index<(int)f[0].getNumChildren() ){
              if( index==(int)childIndex.size() ){
                childIndex.push_back( -1 );
              }else{
                Assert( index==(int)(childIndex.size())-1 );
                unsigned nv = childIndex[index]+1;
                if( options::cbqi() && r==1 && !max_zero[index] ){
                  //skip inst constant nodes
                  while( nv<maxs[index] && nv<=max_i &&
                          quantifiers::TermDb::hasInstConstAttr( d_quantEngine->getTermDatabase()->getTypeGroundTerm( ftypes[index], nv ) ) ){
                    nv++;
                  }
                }
                if( nv<maxs[index] && nv<=max_i ){
                  childIndex[index] = nv;
                  index++;
                }else{
                  childIndex.pop_back();
                  index--;
                }
              }
            }
            success = index>=0;
            if( success ){
              Trace("inst-alg-rd") << "Try instantiation { ";
              for( unsigned j=0; j<childIndex.size(); j++ ){
                Trace("inst-alg-rd") << childIndex[j] << " ";
              }
              Trace("inst-alg-rd") << "}" << std::endl;
              //try instantiation
              std::vector< Node > terms;
              for( unsigned i=0; i<f[0].getNumChildren(); i++ ){
                if( max_zero[i] ){
                  //no terms available, will report incomplete instantiation
                  terms.push_back( Node::null() );
                  Trace("inst-alg-rd") << "  null" << std::endl;
                }else if( r==0 ){
                  terms.push_back( rd->getRDomain( f, i )->d_terms[childIndex[i]] );
                  Trace("inst-alg-rd") << "  " << rd->getRDomain( f, i )->d_terms[childIndex[i]] << std::endl;
                }else{
                  terms.push_back( d_quantEngine->getTermDatabase()->getTypeGroundTerm( ftypes[i], childIndex[i] ) );
                  Trace("inst-alg-rd") << "  " << d_quantEngine->getTermDatabase()->getTypeGroundTerm( ftypes[i], childIndex[i] ) << std::endl;
                }
              }
              if( d_quantEngine->addInstantiation( f, terms ) ){
                Trace("inst-alg-rd") << "Success!" << std::endl;
                ++(d_quantEngine->d_statistics.d_instantiations_guess);
                return true;
              }else{
                index--;
              }
            }
          }while( success );
          max_i++;
        }
      }
    }
  }
  //term enumerator?
  return false;
}
Example #4
0
bool InstStrategyEnum::process(Node f, bool fullEffort, bool isRd)
{
  // ignore if constant true (rare case of non-standard quantifier whose body is
  // rewritten to true)
  if (f[1].isConst() && f[1].getConst<bool>())
  {
    return false;
  }
  RelevantDomain* rd = d_quantEngine->getRelevantDomain();
  unsigned final_max_i = 0;
  std::vector<unsigned> maxs;
  std::vector<bool> max_zero;
  bool has_zero = false;
  std::map<TypeNode, std::vector<Node> > term_db_list;
  std::vector<TypeNode> ftypes;
  TermDb* tdb = d_quantEngine->getTermDatabase();
  EqualityQuery* qy = d_quantEngine->getEqualityQuery();
  // iterate over substitutions for variables
  for (unsigned i = 0; i < f[0].getNumChildren(); i++)
  {
    TypeNode tn = f[0][i].getType();
    ftypes.push_back(tn);
    unsigned ts;
    if (isRd)
    {
      ts = rd->getRDomain(f, i)->d_terms.size();
    }
    else
    {
      ts = tdb->getNumTypeGroundTerms(tn);
      std::map<TypeNode, std::vector<Node> >::iterator ittd =
          term_db_list.find(tn);
      if (ittd == term_db_list.end())
      {
        std::map<Node, Node> reps_found;
        for (unsigned j = 0; j < ts; j++)
        {
          Node gt = tdb->getTypeGroundTerm(ftypes[i], j);
          if (!options::cbqi() || !quantifiers::TermUtil::hasInstConstAttr(gt))
          {
            Node rep = qy->getRepresentative(gt);
            if (reps_found.find(rep) == reps_found.end())
            {
              reps_found[rep] = gt;
              term_db_list[tn].push_back(gt);
            }
          }
        }
        ts = term_db_list[tn].size();
      }
      else
      {
        ts = ittd->second.size();
      }
    }
    // consider a default value if at full effort
    max_zero.push_back(fullEffort && ts == 0);
    ts = (fullEffort && ts == 0) ? 1 : ts;
    Trace("inst-alg-rd") << "Variable " << i << " has " << ts
                         << " in relevant domain." << std::endl;
    if (ts == 0)
    {
      has_zero = true;
      break;
    }
    maxs.push_back(ts);
    if (ts > final_max_i)
    {
      final_max_i = ts;
    }
  }
  if (!has_zero)
  {
    Trace("inst-alg-rd") << "Will do " << final_max_i
                         << " stages of instantiation." << std::endl;
    unsigned max_i = 0;
    bool success;
    Instantiate* ie = d_quantEngine->getInstantiate();
    while (max_i <= final_max_i)
    {
      Trace("inst-alg-rd") << "Try stage " << max_i << "..." << std::endl;
      std::vector<unsigned> childIndex;
      int index = 0;
      do
      {
        while (index >= 0 && index < (int)f[0].getNumChildren())
        {
          if (index == static_cast<int>(childIndex.size()))
          {
            childIndex.push_back(-1);
          }
          else
          {
            Assert(index == static_cast<int>(childIndex.size()) - 1);
            unsigned nv = childIndex[index] + 1;
            if (nv < maxs[index] && nv <= max_i)
            {
              childIndex[index] = nv;
              index++;
            }
            else
            {
              childIndex.pop_back();
              index--;
            }
          }
        }
        success = index >= 0;
        if (success)
        {
          if (Trace.isOn("inst-alg-rd"))
          {
            Trace("inst-alg-rd") << "Try instantiation { ";
            for (unsigned i : childIndex)
            {
              Trace("inst-alg-rd") << i << " ";
            }
            Trace("inst-alg-rd") << "}" << std::endl;
          }
          // try instantiation
          std::vector<Node> terms;
          for (unsigned i = 0, nchild = f[0].getNumChildren(); i < nchild; i++)
          {
            if (max_zero[i])
            {
              // no terms available, will report incomplete instantiation
              terms.push_back(Node::null());
              Trace("inst-alg-rd") << "  null" << std::endl;
            }
            else if (isRd)
            {
              terms.push_back(rd->getRDomain(f, i)->d_terms[childIndex[i]]);
              Trace("inst-alg-rd")
                  << "  " << rd->getRDomain(f, i)->d_terms[childIndex[i]]
                  << std::endl;
            }
            else
            {
              Assert(childIndex[i] < term_db_list[ftypes[i]].size());
              terms.push_back(term_db_list[ftypes[i]][childIndex[i]]);
              Trace("inst-alg-rd")
                  << "  " << term_db_list[ftypes[i]][childIndex[i]]
                  << std::endl;
            }
          }
          if (ie->addInstantiation(f, terms))
          {
            Trace("inst-alg-rd") << "Success!" << std::endl;
            ++(d_quantEngine->d_statistics.d_instantiations_guess);
            return true;
          }
          else
          {
            index--;
          }
        }
      } while (success);
      max_i++;
    }
  }
  // TODO : term enumerator instantiation?
  return false;
}