instantiation rounds quantifiers takes (>=1) before allowing theory combination to happen
option instWhenTcFirst --inst-when-tc-first bool :default true :read-write
allow theory combination to happen once initially, before quantifier strategies are run
+option quantModelEe --quant-model-ee bool :default false
+ use equality engine of model for last call effort
option instMaxLevel --inst-max-level=N int :read-write :default -1
maximum inst level of terms used to instantiate quantified formulas with (-1 == no limit, default)
option instNoEntail --inst-no-entail bool :read-write :default true
do not consider instances of quantified formulas that are currently entailed
+option instNoModelTrue --inst-no-model-true bool :read-write :default false
+ do not consider instances of quantified formulas that are currently true in model, if it is available
option instPropagate --inst-prop bool :read-write :default false
internal propagation for instantiations for selecting relevant instances
TNode nh = d_qe->getTermDatabase()->getEligibleTermInEqc( n );
if( !nh.isNull() ){
if( options::instMaxLevel()!=-1 || options::lteRestrictInstClosure() ){
- nh = d_qe->getEqualityQuery()->getInternalRepresentative( nh, d_f, d_index );
+ nh = d_qe->getInternalRepresentative( nh, d_f, d_index );
//don't consider this if already the instantiation is ineligible
if( !d_qe->getTermDatabase()->isTermEligibleForInstantiation( nh, d_f, false ) ){
nh = Node::null();
d_curr_eqc.clear();
d_curr_type_eqc.clear();
+ // must use master equality engine to avoid value instantiations
eq::EqualityEngine* ee = d_qe->getMasterEqualityEngine();
//to eliminate identified illegal terms
std::map< Node, Node > aux_subs;
/** get the equality engine associated with this query */
eq::EqualityEngine* EqualityQueryInstProp::getEngine() {
- return d_qe->getMasterEqualityEngine();
+ return d_qe->getActiveEqualityEngine();
}
/** get the equivalence class of a */
void LtePartialInst::reset() {
d_reps.clear();
- eq::EqualityEngine* ee = d_quantEngine->getMasterEqualityEngine();
+ eq::EqualityEngine* ee = d_quantEngine->getActiveEqualityEngine();
eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( ee );
while( !eqcs_i.isFinished() ){
TNode r = (*eqcs_i);
//Trace("model-engine-debug") << "Flattening representatives...." << std::endl;
//d_quantEngine->getEqualityQuery()->flattenRepresentatives( fm->d_rep_set.d_type_reps );
- //for debugging
+ //for debugging, setup
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-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 );
+ Node r = d_quantEngine->getInternalRepresentative( it->second[i], Node::null(), 0 );
Trace("model-engine-debug") << r << " ";
}
Trace("model-engine-debug") << std::endl;
}
eq::EqualityEngine * QuantifiersModule::getEqualityEngine() {
- return d_quantEngine->getMasterEqualityEngine();
+ return d_quantEngine->getActiveEqualityEngine();
}
bool QuantifiersModule::areEqual( TNode n1, TNode n2 ) {
void TermDb::computeArgReps( TNode n ) {
if( d_arg_reps.find( n )==d_arg_reps.end() ){
- eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
+ eq::EqualityEngine * ee = d_quantEngine->getActiveEqualityEngine();
for( unsigned j=0; j<n.getNumChildren(); j++ ){
TNode r = ee->hasTerm( n[j] ) ? ee->getRepresentative( n[j] ) : n[j];
d_arg_reps[n].push_back( r );
void TermDb::computeUfEqcTerms( TNode f ) {
if( d_func_map_eqc_trie.find( f )==d_func_map_eqc_trie.end() ){
d_func_map_eqc_trie[f].clear();
- eq::EqualityEngine * ee = d_quantEngine->getTheoryEngine()->getMasterEqualityEngine();
+ eq::EqualityEngine * ee = d_quantEngine->getActiveEqualityEngine();
for( unsigned i=0; i<d_op_map[f].size(); i++ ){
TNode n = d_op_map[f][i];
if( hasTermCurrent( n ) ){
d_op_nonred_count[ f ] = 0;
std::map< Node, std::vector< Node > >::iterator it = d_op_map.find( f );
if( it!=d_op_map.end() ){
- eq::EqualityEngine* ee = d_quantEngine->getMasterEqualityEngine();
+ eq::EqualityEngine* ee = d_quantEngine->getActiveEqualityEngine();
Trace("term-db-debug") << "Adding terms for operator " << f << std::endl;
unsigned congruentCount = 0;
unsigned nonCongruentCount = 0;
bool TermDb::inRelevantDomain( TNode f, unsigned i, TNode r ) {
computeUfTerms( f );
- Assert( d_quantEngine->getTheoryEngine()->getMasterEqualityEngine()->getRepresentative( r )==r );
+ Assert( !d_quantEngine->getActiveEqualityEngine()->hasTerm( r ) ||
+ d_quantEngine->getActiveEqualityEngine()->getRepresentative( r )==r );
std::map< Node, std::map< unsigned, std::vector< Node > > >::iterator it = d_func_map_rel_dom.find( f );
if( it != d_func_map_rel_dom.end() ){
std::map< unsigned, std::vector< Node > >::iterator it2 = it->second.find( i );
if( !useMode ){
return d_has_map.find( n )!=d_has_map.end();
}else{
- //return d_quantEngine->getMasterEqualityEngine()->hasTerm( n ); //some assertions are not sent to EE
+ //return d_quantEngine->getActiveEqualityEngine()->hasTerm( n ); //some assertions are not sent to EE
if( options::termDbMode()==TERM_DB_ALL ){
return true;
}else if( options::termDbMode()==TERM_DB_RELEVANT ){
std::map< Node, Node >::iterator it = d_term_elig_eqc.find( r );
if( it==d_term_elig_eqc.end() ){
Node h;
- eq::EqualityEngine* ee = d_quantEngine->getMasterEqualityEngine();
+ eq::EqualityEngine* ee = d_quantEngine->getActiveEqualityEngine();
eq::EqClassIterator eqc_i = eq::EqClassIterator( r, ee );
while( h.isNull() && !eqc_i.isFinished() ){
TNode n = (*eqc_i);
d_func_map_rel_dom.clear();
d_consistent_ee = true;
- eq::EqualityEngine* ee = d_quantEngine->getMasterEqualityEngine();
+ eq::EqualityEngine* ee = d_quantEngine->getActiveEqualityEngine();
//compute has map
if( options::termDbMode()==TERM_DB_RELEVANT || options::lteRestrictInstClosure() ){
d_has_map.clear();
using namespace CVC4::theory::quantifiers;
TheoryQuantifiers::TheoryQuantifiers(Context* c, context::UserContext* u, OutputChannel& out, Valuation valuation, const LogicInfo& logicInfo) :
- Theory(THEORY_QUANTIFIERS, c, u, out, valuation, logicInfo),
- d_masterEqualityEngine(0)
+ Theory(THEORY_QUANTIFIERS, c, u, out, valuation, logicInfo)
{
d_numInstantiations = 0;
d_baseDecLevel = -1;
}
void TheoryQuantifiers::setMasterEqualityEngine(eq::EqualityEngine* eq) {
- d_masterEqualityEngine = eq;
+
}
void TheoryQuantifiers::addSharedTerm(TNode t) {
/** number of instantiations */
int d_numInstantiations;
int d_baseDecLevel;
-
- eq::EqualityEngine* d_masterEqualityEngine;
-
private:
void computeCareGraph();
void shutdown() { }
std::string identify() const { return std::string("TheoryQuantifiers"); }
void setUserAttribute(const std::string& attr, Node n, std::vector<Node> node_values, std::string str_value);
- eq::EqualityEngine* getMasterEqualityEngine() { return d_masterEqualityEngine; }
bool ppDontRewriteSubterm(TNode atom) { return atom.getKind() == kind::FORALL || atom.getKind() == kind::EXISTS; }
private:
void assertUniversal( Node n );
d_curr_effort_level = QEFFORT_NONE;
d_conflict = false;
d_hasAddedLemma = false;
+ d_useModelEe = false;
//don't add true lemma
d_lemmas_produced_c[d_term_db->d_true] = true;
void QuantifiersEngine::check( Theory::Effort e ){
CodeTimer codeTimer(d_statistics.d_time);
- if( !getMasterEqualityEngine()->consistent() ){
+ d_useModelEe = options::quantModelEe() && ( e>=Theory::EFFORT_LAST_CALL );
+ // if we want to use the model's equality engine, build the model now
+ if( d_useModelEe && !d_model->isBuilt() ){
+ Trace("quant-engine-debug") << "Build the model." << std::endl;
+ if( !d_te->getModelBuilder()->buildModel( d_model ) ){
+ //we are done if model building was unsuccessful
+ flushLemmas();
+ if( d_hasAddedLemma ){
+ Trace("quant-engine-debug") << "...failed." << std::endl;
+ return;
+ }
+ }
+ }
+
+ if( !getActiveEqualityEngine()->consistent() ){
Trace("quant-engine-debug") << "Master equality engine not consistent, return." << std::endl;
return;
}
Trace("quant-engine-debug") << "Check modules that needed check..." << std::endl;
for( unsigned quant_e = QEFFORT_CONFLICT; quant_e<=QEFFORT_LAST_CALL; quant_e++ ){
d_curr_effort_level = quant_e;
- bool success = true;
//build the model if any module requested it
if( needsModelE==quant_e && !d_model->isBuilt() ){
// theory engine's model builder is quantifier engine's builder if it has one
Trace("quant-engine-debug") << "Build model..." << std::endl;
if( !d_te->getModelBuilder()->buildModel( d_model ) ){
//we are done if model building was unsuccessful
- Trace("quant-engine-debug") << "...failed." << std::endl;
- success = false;
+ Trace("quant-engine-debug") << "...added lemmas." << std::endl;
+ flushLemmas();
}
}
- if( success ){
+ if( !d_hasAddedLemma ){
//check each module
for( unsigned i=0; i<qm.size(); i++ ){
Trace("quant-engine-debug") << "Check " << qm[i]->identify().c_str() << " at effort " << quant_e << "..." << std::endl;
break;
}
}
+ //flush all current lemmas
+ flushLemmas();
}
- //flush all current lemmas
- flushLemmas();
//if we have added one, stop
if( d_hasAddedLemma ){
break;
}
if( mkRep ){
//pick the best possible representative for instantiation, based on past use and simplicity of term
- terms[i] = d_eq_query->getInternalRepresentative( terms[i], q, i );
+ terms[i] = getInternalRepresentative( terms[i], q, i );
}else{
//ensure the type is correct
terms[i] = quantifiers::TermDb::ensureType( terms[i], q[0][i].getType() );
//construct the lemma
Trace("inst-assert") << "(assert " << body << ")" << std::endl;
body = Rewriter::rewrite(body);
+
+ if( d_useModelEe && options::instNoModelTrue() ){
+ Node val_body = d_model->getValue( body );
+ if( val_body==d_term_db->d_true ){
+ Trace("inst-add-debug") << " --> True in model." << std::endl;
+ ++(d_statistics.d_inst_duplicate_model_true);
+ return false;
+ }
+ }
+
Node lem;
if( rlv_cond.empty() ){
lem = NodeManager::currentNM()->mkNode( kind::OR, q.negate(), body );
d_inst_duplicate("QuantifiersEngine::Duplicate_Inst", 0),
d_inst_duplicate_eq("QuantifiersEngine::Duplicate_Inst_Eq", 0),
d_inst_duplicate_ent("QuantifiersEngine::Duplicate_Inst_Entailed", 0),
+ d_inst_duplicate_model_true("QuantifiersEngine::Duplicate_Inst_Model_True", 0),
d_triggers("QuantifiersEngine::Triggers", 0),
d_simple_triggers("QuantifiersEngine::Triggers_Simple", 0),
d_multi_triggers("QuantifiersEngine::Triggers_Multi", 0),
smtStatisticsRegistry()->registerStat(&d_inst_duplicate);
smtStatisticsRegistry()->registerStat(&d_inst_duplicate_eq);
smtStatisticsRegistry()->registerStat(&d_inst_duplicate_ent);
+ smtStatisticsRegistry()->registerStat(&d_inst_duplicate_model_true);
smtStatisticsRegistry()->registerStat(&d_triggers);
smtStatisticsRegistry()->registerStat(&d_simple_triggers);
smtStatisticsRegistry()->registerStat(&d_multi_triggers);
smtStatisticsRegistry()->unregisterStat(&d_inst_duplicate);
smtStatisticsRegistry()->unregisterStat(&d_inst_duplicate_eq);
smtStatisticsRegistry()->unregisterStat(&d_inst_duplicate_ent);
+ smtStatisticsRegistry()->unregisterStat(&d_inst_duplicate_model_true);
smtStatisticsRegistry()->unregisterStat(&d_triggers);
smtStatisticsRegistry()->unregisterStat(&d_simple_triggers);
smtStatisticsRegistry()->unregisterStat(&d_multi_triggers);
}
eq::EqualityEngine* QuantifiersEngine::getMasterEqualityEngine(){
- return getTheoryEngine()->getMasterEqualityEngine();
+ return d_te->getMasterEqualityEngine();
+}
+
+eq::EqualityEngine* QuantifiersEngine::getActiveEqualityEngine() {
+ if( d_useModelEe ){
+ return d_model->d_equalityEngine;
+ }else{
+ return d_te->getMasterEqualityEngine();
+ }
+}
+
+Node QuantifiersEngine::getInternalRepresentative( Node a, Node q, int index ){
+ bool prevModelEe = d_useModelEe;
+ d_useModelEe = false;
+ Node ret = d_eq_query->getInternalRepresentative( a, q, index );
+ d_useModelEe = prevModelEe;
+ return ret;
}
void QuantifiersEngine::debugPrintEqualityEngine( const char * c ) {
- eq::EqualityEngine* ee = getMasterEqualityEngine();
+ eq::EqualityEngine* ee = getActiveEqualityEngine();
eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( ee );
std::map< TypeNode, int > typ_num;
while( !eqcs_i.isFinished() ){
}
eq::EqualityEngine* EqualityQueryQuantifiersEngine::getEngine(){
- return d_qe->getMasterEqualityEngine();
+ return d_qe->getActiveEqualityEngine();
}
void EqualityQueryQuantifiersEngine::getEquivalenceClass( Node a, std::vector< Node >& eqc ){
context::CDO< bool > d_conflict_c;
/** has added lemma this round */
bool d_hasAddedLemma;
+ /** whether to use model equality engine */
+ bool d_useModelEe;
private:
/** list of all quantifiers seen */
std::map< Node, bool > d_quants;
bool removeInstantiationInternal( Node q, std::vector< Node >& terms );
/** set instantiation level attr */
static void setInstantiationLevelAttr( Node n, Node qn, uint64_t level );
-public:
/** flush lemmas */
void flushLemmas();
+public:
/** get instantiation */
Node getInstantiation( Node q, std::vector< Node >& vars, std::vector< Node >& terms, bool doVts = false );
/** get instantiation */
void eqNotifyPostMerge(TNode t1, TNode t2);
void eqNotifyDisequal(TNode t1, TNode t2, TNode reason);
/** get the master equality engine */
- eq::EqualityEngine* getMasterEqualityEngine() ;
+ eq::EqualityEngine* getMasterEqualityEngine();
+ /** get the active equality engine */
+ eq::EqualityEngine* getActiveEqualityEngine();
/** debug print equality engine */
void debugPrintEqualityEngine( const char * c );
+ /** get internal representative */
+ Node getInternalRepresentative( Node a, Node q, int index );
public:
/** print instantiations */
void printInstantiations( std::ostream& out );
IntStat d_inst_duplicate;
IntStat d_inst_duplicate_eq;
IntStat d_inst_duplicate_ent;
+ IntStat d_inst_duplicate_model_true;
IntStat d_triggers;
IntStat d_simple_triggers;
IntStat d_multi_triggers;