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() ); } } }
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; }
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; }
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; }
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; }
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; } }