--- /dev/null
+/********************* */\r
+/*! \file relevant_domain.cpp\r
+ ** \verbatim\r
+ ** Original author: Andrew Reynolds\r
+ ** Major contributors: Morgan Deters\r
+ ** Minor contributors (to current version): none\r
+ ** This file is part of the CVC4 project.\r
+ ** Copyright (c) 2009-2013 New York University and The University of Iowa\r
+ ** See the file COPYING in the top-level source directory for licensing\r
+ ** information.\endverbatim\r
+ **\r
+ ** \brief Implementation of relevant domain class\r
+ **/\r
+\r
+#include "theory/quantifiers_engine.h"\r
+#include "theory/quantifiers/relevant_domain.h"\r
+#include "theory/quantifiers/term_database.h"\r
+#include "theory/quantifiers/first_order_model.h"\r
+\r
+using namespace std;\r
+using namespace CVC4;\r
+using namespace CVC4::kind;\r
+using namespace CVC4::context;\r
+using namespace CVC4::theory;\r
+using namespace CVC4::theory::quantifiers;\r
+\r
+void RelevantDomain::RDomain::merge( RDomain * r ) {\r
+ Assert( !d_parent );\r
+ Assert( !r->d_parent );\r
+ d_parent = r;\r
+ for( unsigned i=0; i<d_terms.size(); i++ ){\r
+ r->addTerm( d_terms[i] );\r
+ }\r
+ d_terms.clear();\r
+}\r
+\r
+void RelevantDomain::RDomain::addTerm( Node t ) {\r
+ if( std::find( d_terms.begin(), d_terms.end(), t )==d_terms.end() ){\r
+ d_terms.push_back( t );\r
+ }\r
+}\r
+\r
+RelevantDomain::RDomain * RelevantDomain::RDomain::getParent() {\r
+ if( !d_parent ){\r
+ return this;\r
+ }else{\r
+ RDomain * p = d_parent->getParent();\r
+ d_parent = p;\r
+ return p;\r
+ }\r
+}\r
+\r
+void RelevantDomain::RDomain::removeRedundantTerms( FirstOrderModel * fm ) {\r
+ std::map< Node, Node > rterms;\r
+ for( unsigned i=0; i<d_terms.size(); i++ ){\r
+ Node r = d_terms[i];\r
+ if( !TermDb::hasInstConstAttr( d_terms[i] ) ){\r
+ r = fm->getRepresentative( d_terms[i] );\r
+ }\r
+ if( rterms.find( r )==rterms.end() ){\r
+ rterms[r] = d_terms[i];\r
+ }\r
+ }\r
+ d_terms.clear();\r
+ for( std::map< Node, Node >::iterator it = rterms.begin(); it != rterms.end(); ++it ){\r
+ d_terms.push_back( it->second );\r
+ }\r
+}\r
+\r
+\r
+\r
+RelevantDomain::RelevantDomain( QuantifiersEngine* qe, FirstOrderModel* m ) : d_qe( qe ), d_model( m ){\r
+\r
+}\r
+\r
+RelevantDomain::RDomain * RelevantDomain::getRDomain( Node n, int i ) {\r
+ if( d_rel_doms.find( n )==d_rel_doms.end() || d_rel_doms[n].find( i )==d_rel_doms[n].end() ){\r
+ d_rel_doms[n][i] = new RDomain;\r
+ d_rn_map[d_rel_doms[n][i]] = n;\r
+ d_ri_map[d_rel_doms[n][i]] = i;\r
+ }\r
+ return d_rel_doms[n][i]->getParent();\r
+}\r
+\r
+void RelevantDomain::compute(){\r
+ for( std::map< Node, std::map< int, RDomain * > >::iterator it = d_rel_doms.begin(); it != d_rel_doms.end(); ++it ){\r
+ for( std::map< int, RDomain * >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){\r
+ it2->second->reset();\r
+ }\r
+ }\r
+ for( int i=0; i<(int)d_model->getNumAssertedQuantifiers(); i++ ){\r
+ Node f = d_model->getAssertedQuantifier( i );\r
+ Node icf = d_qe->getTermDatabase()->getInstConstantBody( f );\r
+ Trace("rel-dom-debug") << "compute relevant domain for " << icf << std::endl;\r
+ computeRelevantDomain( icf, true, true );\r
+ }\r
+\r
+ Trace("rel-dom-debug") << "account for ground terms" << std::endl;\r
+ for( std::map< Node, std::vector< Node > >::iterator it = d_model->d_uf_terms.begin(); it != d_model->d_uf_terms.end(); ++it ){\r
+ Node op = it->first;\r
+ for( unsigned i=0; i<it->second.size(); i++ ){\r
+ Node n = it->second[i];\r
+ //if it is a non-redundant term\r
+ if( !n.getAttribute(NoMatchAttribute()) ){\r
+ for( unsigned j=0; j<n.getNumChildren(); j++ ){\r
+ RDomain * rf = getRDomain( op, j );\r
+ rf->addTerm( n[j] );\r
+ }\r
+ }\r
+ }\r
+ }\r
+ //print debug\r
+ for( std::map< Node, std::map< int, RDomain * > >::iterator it = d_rel_doms.begin(); it != d_rel_doms.end(); ++it ){\r
+ Trace("rel-dom") << "Relevant domain for " << it->first << " : " << std::endl;\r
+ for( std::map< int, RDomain * >::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 ){\r
+ Trace("rel-dom") << " " << it2->first << " : ";\r
+ RDomain * r = it2->second;\r
+ RDomain * rp = r->getParent();\r
+ if( r==rp ){\r
+ r->removeRedundantTerms( d_model );\r
+ for( unsigned i=0; i<r->d_terms.size(); i++ ){\r
+ Trace("rel-dom") << r->d_terms[i] << " ";\r
+ }\r
+ }else{\r
+ Trace("rel-dom") << "Dom( " << d_rn_map[rp] << ", " << d_ri_map[rp] << " ) ";\r
+ }\r
+ Trace("rel-dom") << std::endl;\r
+ }\r
+ }\r
+\r
+}\r
+\r
+void RelevantDomain::computeRelevantDomain( Node n, bool hasPol, bool pol ) {\r
+\r
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){\r
+ if( n.getKind()==APPLY_UF ){\r
+ RDomain * rf = getRDomain( n.getOperator(), i );\r
+ if( n[i].getKind()==INST_CONSTANT ){\r
+ Node q = d_qe->getTermDatabase()->getInstConstAttr( n[i] );\r
+ //merge the RDomains\r
+ unsigned id = n[i].getAttribute(InstVarNumAttribute());\r
+ Trace("rel-dom-debug") << n[i] << " is variable # " << id << " for " << q;\r
+ Trace("rel-dom-debug") << " with body : " << d_qe->getTermDatabase()->getInstConstantBody( q ) << std::endl;\r
+ RDomain * rq = getRDomain( q, id );\r
+ if( rf!=rq ){\r
+ rq->merge( rf );\r
+ }\r
+ }else{\r
+ //term to add\r
+ rf->addTerm( n[i] );\r
+ }\r
+ }\r
+\r
+ //TODO\r
+ if( n[i].getKind()!=FORALL ){\r
+ bool newHasPol = hasPol;\r
+ bool newPol = pol;\r
+ computeRelevantDomain( n[i], newHasPol, newPol );\r
+ }\r
+ }\r
+}\r
+\r
+Node RelevantDomain::getRelevantTerm( Node f, int i, Node r ) {\r
+ RDomain * rf = getRDomain( f, i );\r
+ Trace("rel-dom-debug") << "Get relevant domain " << rf << " " << r << std::endl;\r
+ if( !d_qe->getEqualityQuery()->getEngine()->hasTerm( r ) || rf->hasTerm( r ) ){\r
+ return r;\r
+ }else{\r
+ Node rr = d_model->getRepresentative( r );\r
+ eq::EqClassIterator eqc( rr, d_qe->getEqualityQuery()->getEngine() );\r
+ while( !eqc.isFinished() ){\r
+ Node en = (*eqc);\r
+ if( rf->hasTerm( en ) ){\r
+ return en;\r
+ }\r
+ ++eqc;\r
+ }\r
+ //otherwise, may be equal to some non-ground term\r
+\r
+ return r;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/********************* */\r
+/*! \file relevant_domain.h\r
+ ** \verbatim\r
+ ** Original author: Andrew Reynolds\r
+ ** Major contributors: Morgan Deters\r
+ ** Minor contributors (to current version): none\r
+ ** This file is part of the CVC4 project.\r
+ ** Copyright (c) 2009-2013 New York University and The University of Iowa\r
+ ** See the file COPYING in the top-level source directory for licensing\r
+ ** information.\endverbatim\r
+ **\r
+ ** \brief relevant domain class\r
+ **/\r
+\r
+#include "cvc4_private.h"\r
+\r
+#ifndef __CVC4__THEORY__QUANTIFIERS__RELEVANT_DOMAIN_H\r
+#define __CVC4__THEORY__QUANTIFIERS__RELEVANT_DOMAIN_H\r
+\r
+#include "theory/quantifiers/first_order_model.h"\r
+\r
+namespace CVC4 {\r
+namespace theory {\r
+namespace quantifiers {\r
+\r
+class RelevantDomain\r
+{\r
+private:\r
+ class RDomain\r
+ {\r
+ public:\r
+ RDomain() : d_parent( NULL ) {}\r
+ void reset() { d_parent = NULL; d_terms.clear(); }\r
+ RDomain * d_parent;\r
+ std::vector< Node > d_terms;\r
+ void merge( RDomain * r );\r
+ void addTerm( Node t );\r
+ RDomain * getParent();\r
+ void removeRedundantTerms( FirstOrderModel * fm );\r
+ bool hasTerm( Node n ) { return std::find( d_terms.begin(), d_terms.end(), n )!=d_terms.end(); }\r
+ };\r
+ std::map< Node, std::map< int, RDomain * > > d_rel_doms;\r
+ std::map< RDomain *, Node > d_rn_map;\r
+ std::map< RDomain *, int > d_ri_map;\r
+ RDomain * getRDomain( Node n, int i );\r
+ QuantifiersEngine* d_qe;\r
+ FirstOrderModel* d_model;\r
+ void computeRelevantDomain( Node n, bool hasPol, bool pol );\r
+public:\r
+ RelevantDomain( QuantifiersEngine* qe, FirstOrderModel* m );\r
+ virtual ~RelevantDomain(){}\r
+ //compute the relevant domain\r
+ void compute();\r
+\r
+ Node getRelevantTerm( Node f, int i, Node r );\r
+};/* class RelevantDomain */\r
+\r
+}/* CVC4::theory::quantifiers namespace */\r
+}/* CVC4::theory namespace */\r
+}/* CVC4 namespace */\r
+\r
+#endif /* __CVC4__THEORY__QUANTIFIERS__RELEVANT_DOMAIN_H */\r
sortId = d_qe->getTheoryEngine()->getSortInference()->getSortId( f, f[0][index] );
}
if( d_int_rep[sortId].find( r )==d_int_rep[sortId].end() ){
- std::vector< Node > eqc;
- getEquivalenceClass( r, eqc );
//find best selection for representative
Node r_best;
- int r_best_score = -1;
- for( size_t i=0; i<eqc.size(); i++ ){
- int score = getRepScore( eqc[i], f, index );
- if( optInternalRepSortInference() ){
- int e_sortId = d_qe->getTheoryEngine()->getSortInference()->getSortId( eqc[i]);
- if( score>=0 && e_sortId!=sortId ){
- score += 100;
+ if( options::fmfRelevantDomain() ){
+ Trace("internal-rep-debug") << "Consult relevant domain to mkRep " << r << std::endl;
+ r_best = d_qe->getModelEngine()->getRelevantDomain()->getRelevantTerm( f, index, r );
+ Trace("internal-rep-debug") << "Returned " << r_best << " " << r << std::endl;
+ }else{
+ std::vector< Node > eqc;
+ getEquivalenceClass( r, eqc );
+ int r_best_score = -1;
+ for( size_t i=0; i<eqc.size(); i++ ){
+ int score = getRepScore( eqc[i], f, index );
+ if( optInternalRepSortInference() ){
+ int e_sortId = d_qe->getTheoryEngine()->getSortInference()->getSortId( eqc[i]);
+ if( score>=0 && e_sortId!=sortId ){
+ score += 100;
+ }
+ }
+ //score prefers earliest use of this term as a representative
+ if( r_best.isNull() || ( score>=0 && ( r_best_score<0 || score<r_best_score ) ) ){
+ r_best = eqc[i];
+ r_best_score = score;
}
}
- //score prefers earliest use of this term as a representative
- if( r_best.isNull() || ( score>=0 && ( r_best_score<0 || score<r_best_score ) ) ){
- r_best = eqc[i];
- r_best_score = score;
+ //now, make sure that no other member of the class is an instance
+ if( !optInternalRepSortInference() ){
+ r_best = getInstance( r_best, eqc );
+ }
+ //store that this representative was chosen at this point
+ if( d_rep_score.find( r_best )==d_rep_score.end() ){
+ d_rep_score[ r_best ] = d_reset_count;
}
- }
- //now, make sure that no other member of the class is an instance
- if( !optInternalRepSortInference() ){
- r_best = getInstance( r_best, eqc );
- }
- //store that this representative was chosen at this point
- if( d_rep_score.find( r_best )==d_rep_score.end() ){
- d_rep_score[ r_best ] = d_reset_count;
}
d_int_rep[sortId][r] = r_best;
if( r_best!=a ){