//#define ONE_SPLIT_REGION
//#define DISABLE_QUICK_CLIQUE_CHECKS
//#define COMBINE_REGIONS_SMALL_INTO_LARGE
+//#define LAZY_REL_EQC
using namespace std;
using namespace CVC4;
StrongSolverTheoryUF::SortModel::SortModel( Node n, context::Context* c, context::UserContext* u, StrongSolverTheoryUF* thss ) : d_type( n.getType() ),
d_thss( thss ), d_regions_index( c, 0 ), d_regions_map( c ), d_split_score( c ), d_disequalities_index( c, 0 ),
d_reps( c, 0 ), d_conflict( c, false ), d_cardinality( c, 1 ), d_aloc_cardinality( u, 0 ),
- d_cardinality_assertions( c ), d_hasCard( c, false ), d_maxNegCard( c, 0 ), d_initialized( u, false ){
+ d_cardinality_assertions( c ), d_hasCard( c, false ), d_maxNegCard( c, 0 ), d_initialized( u, false ), d_lemma_cache( u ){
d_cardinality_term = n;
//if( d_type.isSort() ){
// TypeEnumerator te(tn);
//add splitting lemma for cardinality constraint
Assert( !d_cardinality_term.isNull() );
Node lem = getCardinalityLiteral( d_aloc_cardinality );
- Trace("uf-ss-lemma") << "*** Cardinality split on : " << lem << std::endl;
lem = NodeManager::currentNM()->mkNode( OR, lem, lem.notNode() );
d_cardinality_lemma[ d_aloc_cardinality ] = lem;
//add as lemma to output channel
- out->lemma( lem );
+ if( doSendLemma( lem ) ){
+ Trace("uf-ss-lemma") << "*** Cardinality split on : " << lem << std::endl;
+ }
//require phase
out->requirePhase( d_cardinality_literal[ d_aloc_cardinality ], true );
//add the appropriate lemma, propagate as decision
if (!s.isNull() ){
//add lemma to output channel
Assert( s.getKind()==EQUAL );
- Trace("uf-ss-lemma") << "*** Split on " << s << std::endl;
Node ss = Rewriter::rewrite( s );
if( ss.getKind()!=EQUAL ){
Node b_t = NodeManager::currentNM()->mkConst( true );
//Trace("uf-ss-lemma") << s[0].getType() << " " << s[1].getType() << std::endl;
//Notice() << "*** Split on " << s << std::endl;
//split on the equality s
- out->split( ss );
- //tell the sat solver to explore the equals branch first
- out->requirePhase( ss, true );
- ++( d_thss->d_statistics.d_split_lemmas );
+ Node lem = NodeManager::currentNM()->mkNode( kind::OR, ss, ss.negate() );
+ if( doSendLemma( lem ) ){
+ Trace("uf-ss-lemma") << "*** Split on " << s << std::endl;
+ //tell the sat solver to explore the equals branch first
+ out->requirePhase( ss, true );
+ ++( d_thss->d_statistics.d_split_lemmas );
+ }
return 1;
}else{
return 0;
}
eqs.push_back( d_cardinality_literal[ d_cardinality ].notNode() );
Node lem = NodeManager::currentNM()->mkNode( OR, eqs );
- Trace("uf-ss-lemma") << "*** Add clique lemma " << lem << std::endl;
- ++( d_thss->d_statistics.d_clique_lemmas );
- out->lemma( lem );
+ if( doSendLemma( lem ) ){
+ Trace("uf-ss-lemma") << "*** Add clique lemma " << lem << std::endl;
+ ++( d_thss->d_statistics.d_clique_lemmas );
+ }
}else{
//found a clique
Debug("uf-ss-cliques") << "Found a clique (cardinality=" << d_cardinality << ") :" << std::endl;
//Assert( hasValue );
//Assert( value );
conflictNode = NodeManager::currentNM()->mkNode( IMPLIES, conflictNode, cardNode.notNode() );
- Trace("uf-ss-lemma") << "*** Add clique lemma " << conflictNode << std::endl;
- out->lemma( conflictNode );
- ++( d_thss->d_statistics.d_clique_lemmas );
+ if( doSendLemma( conflictNode ) ){
+ Trace("uf-ss-lemma") << "*** Add clique lemma " << conflictNode << std::endl;
+ ++( d_thss->d_statistics.d_clique_lemmas );
+ }
}
//DO_THIS: ensure that the same clique is not reported??? Check standard effort after assertDisequal can produce same clique.
}
void StrongSolverTheoryUF::SortModel::addClique( int c, std::vector< Node >& clique ) {
-
- if( d_clique_trie[c].add( clique ) ){
- d_cliques[ c ].push_back( clique );
- }
+ //if( d_clique_trie[c].add( clique ) ){
+ // d_cliques[ c ].push_back( clique );
+ //}
}
}
}
+bool StrongSolverTheoryUF::SortModel::doSendLemma( Node lem ) {
+ if( d_lemma_cache.find( lem )==d_lemma_cache.end() ){
+ d_lemma_cache[lem] = true;
+ d_thss->getOutputChannel().lemma( lem );
+ return true;
+ }else{
+ return false;
+ }
+}
+
void StrongSolverTheoryUF::SortModel::debugPrint( const char* c ){
Debug( c ) << "-- Conflict Find:" << std::endl;
Debug( c ) << "Number of reps = " << d_reps << std::endl;
}
/** new node */
-void StrongSolverTheoryUF::newEqClass( Node n ){
- SortModel* c = getSortModel( n );
+void StrongSolverTheoryUF::newEqClass( Node a ){
+ SortModel* c = getSortModel( a );
if( c ){
+#ifdef LAZY_REL_EQC
//do nothing
+#else
+ Trace("uf-ss-solver") << "StrongSolverTheoryUF: New eq class " << a << " : " << a.getType() << std::endl;
+ c->newEqClass( a );
+ if( options::ufssSymBreak() ){
+ d_sym_break->newEqClass( a );
+ }
+ Trace("uf-ss-solver") << "StrongSolverTheoryUF: Done New eq class." << std::endl;
+#endif
}
}
//TODO: ensure they are relevant
SortModel* c = getSortModel( a );
if( c ){
+#ifdef LAZY_REL_EQC
ensureEqc( c, a );
if( hasEqc( b ) ){
Trace("uf-ss-solver") << "StrongSolverTheoryUF: Merge " << a << " " << b << " : " << a.getType() << std::endl;
//c->assignEqClass( b, a );
d_rel_eqc[b] = true;
}
+#else
+ Trace("uf-ss-solver") << "StrongSolverTheoryUF: Merge " << a << " " << b << " : " << a.getType() << std::endl;
+ c->merge( a, b );
+ Trace("uf-ss-solver") << "StrongSolverTheoryUF: Done Merge." << std::endl;
+#endif
}else{
if( options::ufssDiseqPropagation() ){
d_deq_prop->merge(a, b);
void StrongSolverTheoryUF::assertDisequal( Node a, Node b, Node reason ){
SortModel* c = getSortModel( a );
if( c ){
+#ifdef LAZY_REL_EQC
ensureEqc( c, a );
ensureEqc( c, b );
+#endif
Trace("uf-ss-solver") << "StrongSolverTheoryUF: Assert disequal " << a << " " << b << " : " << a.getType() << std::endl;
//Assert( d_th->d_equalityEngine.getRepresentative( a )==a );
//Assert( d_th->d_equalityEngine.getRepresentative( b )==b );
/** assert a node */
void StrongSolverTheoryUF::assertNode( Node n, bool isDecision ){
Trace("uf-ss") << "Assert " << n << " " << isDecision << std::endl;
+#ifdef LAZY_REL_EQC
ensureEqcRec( n );
+#endif
bool polarity = n.getKind() != kind::NOT;
TNode lit = polarity ? n : n[0];
if( lit.getKind()==CARDINALITY_CONSTRAINT ){
d_com_card_literal[ d_aloc_com_card.get() ] = lem;
lem = NodeManager::currentNM()->mkNode( OR, lem, lem.notNode() );
//add as lemma to output channel
+ Trace("uf-ss-lemma") << "*** Combined cardinality split : " << lem << std::endl;
getOutputChannel().lemma( lem );
//require phase
getOutputChannel().requirePhase( d_com_card_literal[ d_aloc_com_card.get() ], true );