예제 #1
0
void ModelEngine::check( Theory::Effort e ){
  if( e==Theory::EFFORT_LAST_CALL && !d_quantEngine->hasAddedLemma() ){
    int addedLemmas = 0;
    bool needsBuild = true;
    FirstOrderModel* fm = d_quantEngine->getModel();
    if( fm->getNumAssertedQuantifiers()>0 ){
      //the following will attempt to build a model and test that it satisfies all asserted universal quantifiers
      //quantifiers are initialized, we begin an instantiation round
      double clSet = 0;
      if( Trace.isOn("model-engine") ){
        clSet = double(clock())/double(CLOCKS_PER_SEC);
      }
      ++(d_statistics.d_inst_rounds);
      bool buildAtFullModel = d_builder->optBuildAtFullModel();
      needsBuild = !buildAtFullModel;
      //two effort levels: first try exhaustive instantiation without axioms, then with.
      int startEffort = ( !fm->isAxiomAsserted() || options::axiomInstMode()==AXIOM_INST_MODE_DEFAULT ) ? 1 : 0;
      for( int effort=startEffort; effort<2; effort++ ){
        // for effort = 0, we only instantiate non-axioms
        // for effort = 1, we instantiate everything
        if( addedLemmas==0 ){
          Trace("model-engine") << "---Model Engine Round---" << std::endl;
          //initialize the model
          Trace("model-engine-debug") << "Build model..." << std::endl;
          d_builder->d_considerAxioms = effort>=1;
          d_builder->d_addedLemmas = 0;
          d_builder->buildModel( fm, buildAtFullModel );
          addedLemmas += (int)d_builder->d_addedLemmas;
          //if builder has lemmas, add and return
          if( addedLemmas==0 ){
            Trace("model-engine-debug") << "Verify uf ss is minimal..." << std::endl;
            //let the strong solver verify that the model is minimal
            //for debugging, this will if there are terms in the model that the strong solver was not notified of
            if( ((uf::TheoryUF*)d_quantEngine->getTheoryEngine()->theoryOf( THEORY_UF ))->getStrongSolver()->debugModel( fm ) ){
              Trace("model-engine-debug") << "Check model..." << std::endl;
              d_incomplete_check = false;
              //print debug
              Debug("fmf-model-complete") << std::endl;
              debugPrint("fmf-model-complete");
              //successfully built an acceptable model, now check it
              addedLemmas += checkModel();
            }else{
              addedLemmas++;
            }
          }
        }
        if( addedLemmas==0 ){
          //if we have not added lemmas yet and axiomInstMode=trust, then we are done
          if( options::axiomInstMode()==AXIOM_INST_MODE_TRUST ){
            //we must return unknown if an axiom is asserted
            if( effort==0 ){
              d_incomplete_check = true;
            }
            break;
          }
        }
      }
      if( Trace.isOn("model-engine") ){
        double clSet2 = double(clock())/double(CLOCKS_PER_SEC);
        Trace("model-engine") << "Finished model engine, time = " << (clSet2-clSet) << std::endl;
      }
    }else{
      Trace("model-engine-debug") << "No quantified formulas asserted." << std::endl;
    }
    if( addedLemmas==0 ){
      Trace("model-engine-debug") << "No lemmas added, incomplete = " << d_incomplete_check << std::endl;
      //CVC4 will answer SAT or unknown
      Trace("fmf-consistent") << std::endl;
      debugPrint("fmf-consistent");
      if( options::produceModels() && needsBuild ){
        // finish building the model
        d_builder->buildModel( fm, true );
      }
      //if the check was incomplete, we must set incomplete flag
      if( d_incomplete_check ){
        d_quantEngine->getOutputChannel().setIncomplete();
      }
    }else{
      //otherwise, the search will continue
      d_quantEngine->flushLemmas( &d_quantEngine->getOutputChannel() );
    }
  }
}
예제 #2
0
int ModelEngine::checkModel(){
  FirstOrderModel* fm = d_quantEngine->getModel();

  //flatten the representatives
  //Trace("model-engine-debug") << "Flattening representatives...." << std::endl;
  //d_quantEngine->getEqualityQuery()->flattenRepresentatives( fm->d_rep_set.d_type_reps );

  //for debugging
  if( Trace.isOn("model-engine") || Trace.isOn("model-engine-debug") ){
    for( std::map< TypeNode, std::vector< Node > >::iterator it = fm->d_rep_set.d_type_reps.begin();
         it != fm->d_rep_set.d_type_reps.end(); ++it ){
      if( it->first.isSort() ){
        Trace("model-engine") << "Cardinality( " << it->first << " )" << " = " << it->second.size() << std::endl;
        if( Trace.isOn("model-engine-debug") ){
          Trace("model-engine-debug") << "   ";
          Node mbt = d_quantEngine->getTermDatabase()->getModelBasisTerm(it->first);
          for( size_t i=0; i<it->second.size(); i++ ){
            //Trace("model-engine-debug") << it->second[i] << "  ";
            Node r = d_quantEngine->getEqualityQuery()->getInternalRepresentative( it->second[i], Node::null(), 0 );
            Trace("model-engine-debug") << r << " ";
          }
          Trace("model-engine-debug") << std::endl;
          Trace("model-engine-debug") << "  Model basis term : " << mbt << std::endl;
        }
      }
    }
  }

  d_triedLemmas = 0;
  d_addedLemmas = 0;
  d_totalLemmas = 0;
  //for statistics
  for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
    Node f = fm->getAssertedQuantifier( i );
    int totalInst = 1;
    for( size_t i=0; i<f[0].getNumChildren(); i++ ){
      TypeNode tn = f[0][i].getType();
      if( fm->d_rep_set.hasType( tn ) ){
        totalInst = totalInst * (int)fm->d_rep_set.d_type_reps[ tn ].size();
      }
    }
    d_totalLemmas += totalInst;
  }

  Trace("model-engine-debug") << "Do exhaustive instantiation..." << std::endl;
  int e_max = options::mbqiMode()==MBQI_FMC || options::mbqiMode()==MBQI_FMC_INTERVAL ? 2 : ( options::mbqiMode()==MBQI_TRUST ? 0 : 1 );
  for( int e=0; e<e_max; e++) {
    if (d_addedLemmas==0) {
      for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
        Node f = fm->getAssertedQuantifier( i );
        //determine if we should check this quantifier
        if( d_builder->isQuantifierActive( f ) ){
          exhaustiveInstantiate( f, e );
          if( Trace.isOn("model-engine-warn") ){
            if( d_addedLemmas>10000 ){
              Debug("fmf-exit") << std::endl;
              debugPrint("fmf-exit");
              exit( 0 );
            }
          }
          if( optOneQuantPerRound() && d_addedLemmas>0 ){
            break;
          }
        }else{
          Trace("inst-fmf-ei") << "-> Inactive : " << f << std::endl;
        }
      }
    }
  }
  //print debug information
  Trace("model-engine-debug") << "Instantiate axioms : " << ( d_builder->d_considerAxioms ? "yes" : "no" ) << std::endl;
  Trace("model-engine") << "Added Lemmas = " << d_addedLemmas << " / " << d_triedLemmas << " / ";
  Trace("model-engine") << d_totalLemmas << std::endl;
  return d_addedLemmas;
}
예제 #3
0
int ModelEngine::checkModel(){
  FirstOrderModel* fm = d_quantEngine->getModel();
  //for debugging
  if( Trace.isOn("model-engine") || Trace.isOn("model-engine-debug") ){
    for( std::map< TypeNode, std::vector< Node > >::iterator it = fm->d_rep_set.d_type_reps.begin();
         it != fm->d_rep_set.d_type_reps.end(); ++it ){
      if( it->first.isSort() ){
        Trace("model-engine") << "Cardinality( " << it->first << " )" << " = " << it->second.size() << std::endl;
        Trace("model-engine-debug") << "   ";
        Node mbt = d_quantEngine->getTermDatabase()->getModelBasisTerm(it->first);
        for( size_t i=0; i<it->second.size(); i++ ){
          //Trace("model-engine-debug") << it->second[i] << "  ";
          Node r = ((EqualityQueryQuantifiersEngine*)d_quantEngine->getEqualityQuery())->getRepresentative( it->second[i] );
          Trace("model-engine-debug") << r << " ";
        }
        Trace("model-engine-debug") << std::endl;
        Trace("model-engine-debug") << "  Model basis term : " << mbt << std::endl;
      }
    }
  }
  //relevant domain?
  if( d_rel_dom ){
    d_rel_dom->compute();
  }

  d_triedLemmas = 0;
  d_addedLemmas = 0;
  d_totalLemmas = 0;
  //for statistics
  for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
    Node f = fm->getAssertedQuantifier( i );
    int totalInst = 1;
    for( size_t i=0; i<f[0].getNumChildren(); i++ ){
      TypeNode tn = f[0][i].getType();
      if( fm->d_rep_set.hasType( tn ) ){
        totalInst = totalInst * (int)fm->d_rep_set.d_type_reps[ tn ].size();
      }
    }
    d_totalLemmas += totalInst;
  }

  Trace("model-engine-debug") << "Do exhaustive instantiation..." << std::endl;
  int e_max = options::fmfFullModelCheck() && options::fmfModelBasedInst() ? 2 : 1;
  for( int e=0; e<e_max; e++) {
    if (d_addedLemmas==0) {
      for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
        Node f = fm->getAssertedQuantifier( i );
        //determine if we should check this quantifier
        if( d_builder->isQuantifierActive( f ) ){
          exhaustiveInstantiate( f, e );
          if( Trace.isOn("model-engine-warn") ){
            if( d_addedLemmas>10000 ){
              Debug("fmf-exit") << std::endl;
              debugPrint("fmf-exit");
              exit( 0 );
            }
          }
          if( optOneQuantPerRound() && d_addedLemmas>0 ){
            break;
          }
        }
      }
    }
  }
  //print debug information
  if( Trace.isOn("model-engine") ){
    Trace("model-engine") << "Instantiate axioms : " << ( d_builder->d_considerAxioms ? "yes" : "no" ) << std::endl;
    Trace("model-engine") << "Added Lemmas = " << d_addedLemmas << " / " << d_triedLemmas << " / ";
    Trace("model-engine") << d_totalLemmas << std::endl;
  }
  d_statistics.d_exh_inst_lemmas += d_addedLemmas;
  return d_addedLemmas;
}
예제 #4
0
int ModelEngine::checkModel( int checkOption ){
  int addedLemmas = 0;
  FirstOrderModel* fm = d_quantEngine->getModel();
  //for debugging
  if( Trace.isOn("model-engine") || Trace.isOn("model-engine-debug") ){
    for( std::map< TypeNode, std::vector< Node > >::iterator it = fm->d_rep_set.d_type_reps.begin();
         it != fm->d_rep_set.d_type_reps.end(); ++it ){
      if( it->first.isSort() ){
        Trace("model-engine") << "Cardinality( " << it->first << " )" << " = " << it->second.size() << std::endl;
        Trace("model-engine-debug") << "   ";
        for( size_t i=0; i<it->second.size(); i++ ){
          //Trace("model-engine-debug") << it->second[i] << "  ";
          Node r = ((EqualityQueryQuantifiersEngine*)d_quantEngine->getEqualityQuery())->getInternalRepresentative( it->second[i] );
          Trace("model-engine-debug") << r << " ";
        }
        Trace("model-engine-debug") << std::endl;
      }
    }
  }
  //compute the relevant domain if necessary
  if( optUseRelevantDomain() ){
    d_rel_domain.compute();
  }
  d_triedLemmas = 0;
  d_testLemmas = 0;
  d_relevantLemmas = 0;
  d_totalLemmas = 0;
  Trace("model-engine-debug") << "Do exhaustive instantiation..." << std::endl;
  for( int i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
    Node f = fm->getAssertedQuantifier( i );
    //keep track of total instantiations for statistics
    int totalInst = 1;
    for( size_t i=0; i<f[0].getNumChildren(); i++ ){
      TypeNode tn = f[0][i].getType();
      if( fm->d_rep_set.hasType( tn ) ){
        totalInst = totalInst * (int)fm->d_rep_set.d_type_reps[ tn ].size();
      }
    }
    d_totalLemmas += totalInst;
    //determine if we should check this quantifiers
    bool checkQuant = false;
    if( checkOption==check_model_full ){
      checkQuant = d_builder->isQuantifierActive( f );
    }else if( checkOption==check_model_no_inst_gen ){
      checkQuant = !d_builder->hasInstGen( f );
    }
    //if we need to consider this quantifier on this iteration
    if( checkQuant ){
      addedLemmas += exhaustiveInstantiate( f, optUseRelevantDomain() );
      if( Trace.isOn("model-engine-warn") ){
        if( addedLemmas>10000 ){
          Debug("fmf-exit") << std::endl;
          debugPrint("fmf-exit");
          exit( 0 );
        }
      }
      if( optOneQuantPerRound() && addedLemmas>0 ){
        break;
      }
    }
  }
  //print debug information
  if( Trace.isOn("model-engine") ){
    Trace("model-engine") << "Instantiate axioms : " << ( d_builder->d_considerAxioms ? "yes" : "no" ) << std::endl;
    Trace("model-engine") << "Added Lemmas = " << addedLemmas << " / " << d_triedLemmas << " / ";
    Trace("model-engine") << d_testLemmas << " / " << d_relevantLemmas << " / " << d_totalLemmas << std::endl;
  }
  d_statistics.d_exh_inst_lemmas += addedLemmas;
  return addedLemmas;
}
예제 #5
0
int ModelEngine::checkModel(){
  FirstOrderModel* fm = d_quantEngine->getModel();

  //flatten the representatives
  //Trace("model-engine-debug") << "Flattening representatives...." << std::endl;
  //d_quantEngine->getEqualityQuery()->flattenRepresentatives( fm->d_rep_set.d_type_reps );

  //for debugging
  if( Trace.isOn("model-engine") || Trace.isOn("model-engine-debug") ){
    for( std::map< TypeNode, std::vector< Node > >::iterator it = fm->d_rep_set.d_type_reps.begin();
         it != fm->d_rep_set.d_type_reps.end(); ++it ){
      if( it->first.isSort() ){
        Trace("model-engine") << "Cardinality( " << it->first << " )" << " = " << it->second.size() << std::endl;
        if( Trace.isOn("model-engine-debug") ){
          Trace("model-engine-debug") << "        Reps : ";
          for( size_t i=0; i<it->second.size(); i++ ){
            Trace("model-engine-debug") << it->second[i] << "  ";
          }
          Trace("model-engine-debug") << std::endl;
          Trace("model-engine-debug") << "   Term reps : ";
          for( size_t i=0; i<it->second.size(); i++ ){
            Node r = d_quantEngine->getEqualityQuery()->getInternalRepresentative( it->second[i], Node::null(), 0 );
            Trace("model-engine-debug") << r << " ";
          }
          Trace("model-engine-debug") << std::endl;
          Node mbt = d_quantEngine->getTermDatabase()->getModelBasisTerm(it->first);
          Trace("model-engine-debug") << "  Basis term : " << mbt << std::endl;
        }
      }
    }
  }

  d_triedLemmas = 0;
  d_addedLemmas = 0;
  d_totalLemmas = 0;
  //for statistics
  if( Trace.isOn("model-engine") ){
    for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
      Node f = fm->getAssertedQuantifier( i );
      int totalInst = 1;
      for( unsigned j=0; j<f[0].getNumChildren(); j++ ){
        TypeNode tn = f[0][j].getType();
        if( fm->d_rep_set.hasType( tn ) ){
          totalInst = totalInst * (int)fm->d_rep_set.d_type_reps[ tn ].size();
        }
      }
      d_totalLemmas += totalInst;
    }
  }

  Trace("model-engine-debug") << "Do exhaustive instantiation..." << std::endl;
  // FMC uses two sub-effort levels
  int e_max = options::mbqiMode()==MBQI_FMC || options::mbqiMode()==MBQI_FMC_INTERVAL ? 2 : ( options::mbqiMode()==MBQI_TRUST ? 0 : 1 );
  for( int e=0; e<e_max; e++) {
    for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ){
      Node f = fm->getAssertedQuantifier( i, true );
      Trace("fmf-exh-inst") << "-> Exhaustive instantiate " << f << ", effort = " << e << "..." << std::endl;
      //determine if we should check this quantifier
      if( considerQuantifiedFormula( f ) ){
        exhaustiveInstantiate( f, e );
        if( d_quantEngine->inConflict() || ( optOneQuantPerRound() && d_addedLemmas>0 ) ){
          break;
        }
      }else{
        Trace("fmf-exh-inst") << "-> Inactive : " << f << std::endl;
      }
    }
    if( d_addedLemmas>0 ){
      break;
    }else{
      Assert( !d_quantEngine->inConflict() );
    }
  }

  //print debug information
  if( d_quantEngine->inConflict() ){
    Trace("model-engine") << "Conflict, added lemmas = ";
  }else{
    Trace("model-engine") << "Added Lemmas = ";
  } 
  Trace("model-engine") << d_addedLemmas << " / " << d_triedLemmas << " / ";
  Trace("model-engine") << d_totalLemmas << std::endl;
  return d_addedLemmas;
}
예제 #6
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;
  }
}