void InstGenProcess::calculateMatchesInterpreted( QuantifiersEngine* qe, Node f, InstMatch& curr, std::vector< Node >& terms, int argIndex ) { FirstOrderModel* fm = qe->getModel(); if( argIndex==(int)d_node.getNumChildren() ) { Node val; if( d_node.getNumChildren()==0 ) { val = d_node; } else if( d_node.getKind()==EQUAL ) { val = qe->getEqualityQuery()->areEqual( terms[0], terms[1] ) ? fm->d_true : fm->d_false; } else { val = NodeManager::currentNM()->mkNode( d_node.getKind(), terms ); val = Rewriter::rewrite( val ); } Trace("inst-gen-cm") << " - i-match : " << d_node << std::endl; Trace("inst-gen-cm") << " : " << val << std::endl; Trace("inst-gen-cm") << " : " << curr << std::endl; addMatchValue( qe, f, val, curr ); } else { if( d_children_map.find( argIndex )==d_children_map.end() ) { terms.push_back( fm->getRepresentative( d_node[argIndex] ) ); calculateMatchesInterpreted( qe, f, curr, terms, argIndex+1 ); terms.pop_back(); } else { for( int i=0; i<(int)d_children[ d_children_map[argIndex] ].getNumMatches(); i++ ) { InstMatch next( &curr ); if( d_children[ d_children_map[argIndex] ].getMatch( qe->getEqualityQuery(), i, next ) ) { terms.push_back( d_children[ d_children_map[argIndex] ].getMatchValue( i ) ); calculateMatchesInterpreted( qe, f, next, terms, argIndex+1 ); terms.pop_back(); } } } } }
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(); //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(){ 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; }
void QModelBuilderIG::processBuildModel( TheoryModel* m, bool fullModel ) { FirstOrderModel* f = (FirstOrderModel*)m; FirstOrderModelIG* fm = f->asFirstOrderModelIG(); Trace("model-engine-debug") << "Process build model, fullModel = " << fullModel << " " << optUseModel() << std::endl; if( fullModel ) { Assert( d_curr_model==fm ); //update models for( std::map< Node, uf::UfModelTree >::iterator it = fm->d_uf_model_tree.begin(); it != fm->d_uf_model_tree.end(); ++it ) { it->second.update( fm ); Trace("model-func") << "QModelBuilder: Make function value from tree " << it->first << std::endl; //construct function values fm->d_uf_models[ it->first ] = it->second.getFunctionValue( "$x" ); } TheoryEngineModelBuilder::processBuildModel( m, fullModel ); //mark that the model has been set fm->markModelSet(); //debug the model debugModel( fm ); } else { d_curr_model = fm; d_didInstGen = false; //reset the internal information reset( fm ); //only construct first order model if optUseModel() is true if( optUseModel() ) { Trace("model-engine-debug") << "Initializing " << fm->getNumAssertedQuantifiers() << " quantifiers..." << std::endl; //check if any quantifiers are un-initialized for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ) { Node f = fm->getAssertedQuantifier( i ); if( isQuantifierActive( f ) ) { int lems = initializeQuantifier( f, f ); d_statistics.d_init_inst_gen_lemmas += lems; d_addedLemmas += lems; if( d_qe->inConflict() ) { break; } } } if( d_addedLemmas>0 ) { Trace("model-engine") << "Initialize, Added Lemmas = " << d_addedLemmas << std::endl; } else { Assert( !d_qe->inConflict() ); //initialize model fm->initialize(); //analyze the functions Trace("model-engine-debug") << "Analyzing model..." << std::endl; analyzeModel( fm ); //analyze the quantifiers Trace("model-engine-debug") << "Analyzing quantifiers..." << std::endl; d_quant_sat.clear(); d_uf_prefs.clear(); for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ) { Node f = fm->getAssertedQuantifier( i ); if( isQuantifierActive( f ) ) { analyzeQuantifier( fm, f ); } } //if applicable, find exceptions to model via inst-gen if( options::fmfInstGen() ) { d_didInstGen = true; d_instGenMatches = 0; d_numQuantSat = 0; d_numQuantInstGen = 0; d_numQuantNoInstGen = 0; d_numQuantNoSelForm = 0; //now, see if we know that any exceptions via InstGen exist Trace("model-engine-debug") << "Perform InstGen techniques for quantifiers..." << std::endl; for( unsigned i=0; i<fm->getNumAssertedQuantifiers(); i++ ) { Node f = fm->getAssertedQuantifier( i ); if( isQuantifierActive( f ) ) { int lems = doInstGen( fm, f ); d_statistics.d_inst_gen_lemmas += lems; d_addedLemmas += lems; //temporary if( lems>0 ) { d_numQuantInstGen++; } else if( d_quant_sat.find( f )!=d_quant_sat.end() ) { d_numQuantSat++; } else if( hasInstGen( f ) ) { d_numQuantNoInstGen++; } else { d_numQuantNoSelForm++; } if( d_qe->inConflict() || ( options::fmfInstGenOneQuantPerRound() && lems>0 ) ) { break; } } else if( d_quant_sat.find( f )!=d_quant_sat.end() ) { d_numQuantSat++; } } Trace("model-engine-debug") << "Quantifiers sat/ig/n-ig/null " << d_numQuantSat << " / " << d_numQuantInstGen << " / "; Trace("model-engine-debug") << d_numQuantNoInstGen << " / " << d_numQuantNoSelForm << std::endl; Trace("model-engine-debug") << "Inst-gen # matches examined = " << d_instGenMatches << std::endl; if( Trace.isOn("model-engine") ) { if( d_addedLemmas>0 ) { Trace("model-engine") << "InstGen, added lemmas = " << d_addedLemmas << std::endl; } else { Trace("model-engine") << "No InstGen lemmas..." << std::endl; } } } //construct the model if necessary if( d_addedLemmas==0 ) { //if no immediate exceptions, build the model // this model will be an approximation that will need to be tested via exhaustive instantiation Trace("model-engine-debug") << "Building model..." << std::endl; //build model for UF for( std::map< Node, uf::UfModelTree >::iterator it = fm->d_uf_model_tree.begin(); it != fm->d_uf_model_tree.end(); ++it ) { Trace("model-engine-debug-uf") << "Building model for " << it->first << "..." << std::endl; constructModelUf( fm, it->first ); } /* //build model for arrays for( std::map< Node, arrays::ArrayModel >::iterator it = fm->d_array_model.begin(); it != fm->d_array_model.end(); ++it ){ //consult the model basis select term // i.e. the default value for array A is the value of select( A, e ), where e is the model basis term TypeNode tn = it->first.getType(); Node selModelBasis = NodeManager::currentNM()->mkNode( SELECT, it->first, fm->getTermDatabase()->getModelBasisTerm( tn[0] ) ); it->second.setDefaultValue( fm->getRepresentative( selModelBasis ) ); } */ Trace("model-engine-debug") << "Done building models." << std::endl; } } } } }
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; }
void AbsMbqiBuilder::processBuildModel(TheoryModel* m, bool fullModel) { Trace("ambqi-debug") << "process build model " << fullModel << std::endl; FirstOrderModel* f = (FirstOrderModel*)m; FirstOrderModelAbs* fm = f->asFirstOrderModelAbs(); if( fullModel ){ Trace("ambqi-model") << "Construct model representation..." << std::endl; //make function values for( std::map<Node, AbsDef * >::iterator it = fm->d_models.begin(); it != fm->d_models.end(); ++it ) { if( it->first.getType().getNumChildren()>1 ){ Trace("ambqi-model") << "Construct for " << it->first << "..." << std::endl; m->d_uf_models[ it->first ] = fm->getFunctionValue( it->first, "$x" ); } } TheoryEngineModelBuilder::processBuildModel( m, fullModel ); //mark that the model has been set fm->markModelSet(); //debug the model debugModel( fm ); }else{ fm->initialize(); //process representatives fm->d_rep_id.clear(); fm->d_domain.clear(); //initialize boolean sort TypeNode b = d_true.getType(); fm->d_rep_set.d_type_reps[b].clear(); fm->d_rep_set.d_type_reps[b].push_back( d_false ); fm->d_rep_set.d_type_reps[b].push_back( d_true ); fm->d_rep_id[d_false] = 0; fm->d_rep_id[d_true] = 1; //initialize unintpreted sorts Trace("ambqi-model") << std::endl << "Making representatives..." << std::endl; 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() ){ Assert( !it->second.empty() ); //set the domain fm->d_domain[it->first] = 0; Trace("ambqi-model") << "Representatives for " << it->first << " : " << std::endl; for( unsigned i=0; i<it->second.size(); i++ ){ if( i<32 ){ fm->d_domain[it->first] |= ( 1 << i ); } Trace("ambqi-model") << i << " : " << it->second[i] << std::endl; fm->d_rep_id[it->second[i]] = i; } if( it->second.size()>=32 ){ fm->d_domain.erase( it->first ); } } } Trace("ambqi-model") << std::endl << "Making function definitions..." << std::endl; //construct the models for functions for( std::map<Node, AbsDef * >::iterator it = fm->d_models.begin(); it != fm->d_models.end(); ++it ) { Node f = it->first; Trace("ambqi-model-debug") << "Building Model for " << f << std::endl; //reset the model it->second->clear(); //get all (non-redundant) f-applications std::vector< TNode > fapps; Trace("ambqi-model-debug") << "Initial terms: " << std::endl; for( size_t i=0; i<fm->d_uf_terms[f].size(); i++ ){ Node n = fm->d_uf_terms[f][i]; if( !n.getAttribute(NoMatchAttribute()) ){ Trace("ambqi-model-debug") << " " << n << " -> " << fm->getRepresentativeId( n ) << std::endl; fapps.push_back( n ); } } if( fapps.empty() ){ //choose arbitrary value Node mbt = d_qe->getTermDatabase()->getModelBasisOpTerm(f); Trace("ambqi-model-debug") << "Initial terms empty, add " << mbt << std::endl; fapps.push_back( mbt ); } bool fValid = true; for( unsigned i=0; i<fapps[0].getNumChildren(); i++ ){ if( fm->d_domain.find( fapps[0][i].getType() )==fm->d_domain.end() ){ Trace("ambqi-model") << "Interpretation of " << f << " is not valid."; Trace("ambqi-model") << " (domain for " << fapps[0][i].getType() << " is too large)." << std::endl; fValid = false; break; } } fm->d_models_valid[f] = fValid; if( fValid ){ //construct the ambqi model it->second->construct_func( fm, fapps ); Trace("ambqi-model-debug") << "Interpretation of " << f << " : " << std::endl; it->second->debugPrint("ambqi-model-debug", fm, fapps[0] ); Trace("ambqi-model-debug") << "Simplifying " << f << "..." << std::endl; it->second->simplify( fm, TNode::null(), fapps[0] ); Trace("ambqi-model") << "(Simplified) interpretation of " << f << " : " << std::endl; it->second->debugPrint("ambqi-model", fm, fapps[0] ); /* if( Debug.isOn("ambqi-model-debug") ){ for( size_t i=0; i<fm->d_uf_terms[f].size(); i++ ){ Node e = it->second->evaluate_n( fm, fm->d_uf_terms[f][i] ); Debug("ambqi-model-debug") << fm->d_uf_terms[f][i] << " evaluates to " << e << std::endl; Assert( fm->areEqual( e, fm->d_uf_terms[f][i] ) ); } } */ } } } }
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; } }