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 ) ){
+ uf::StrongSolverTheoryUF * ufss = ((uf::TheoryUF*)d_quantEngine->getTheoryEngine()->theoryOf( THEORY_UF ))->getStrongSolver();
+ if( !ufss || ufss->debugModel( fm ) ){
Trace("model-engine-debug") << "Check model..." << std::endl;
d_incomplete_check = false;
//print debug
Trace("quant-engine-debug") << "Done resetting all modules." << std::endl;
if( e==Theory::EFFORT_LAST_CALL ){
- //if effort is last call, try to minimize model first
- if( options::finiteModelFind() ){
- //first, check if we can minimize the model further FIXME: remove?
- if( !((uf::TheoryUF*)getTheoryEngine()->theoryOf( THEORY_UF ))->getStrongSolver()->minimize() ){
- return;
- }
+ //if effort is last call, try to minimize model first FIXME: remove?
+ uf::StrongSolverTheoryUF * ufss = ((uf::TheoryUF*)getTheoryEngine()->theoryOf( THEORY_UF ))->getStrongSolver();
+ if( ufss && !ufss->minimize() ){
+ return;
}
++(d_statistics.d_instantiation_rounds_lc);
}else if( e==Theory::EFFORT_FULL ){
always use simple clique lemmas for uf strong solver
option ufssDiseqPropagation --uf-ss-deq-prop bool :default false
eagerly propagate disequalities for uf strong solver
-option ufssMinimalModel /--disable-uf-ss-min-model bool :default true
- disable finding a minimal model in uf strong solver
+option ufssMode --uf-ss=MODE CVC4::theory::uf::UfssMode :default CVC4::theory::uf::UF_SS_FULL :include "theory/uf/options_handlers.h" :handler CVC4::theory::uf::stringToUfssMode :handler-include "theory/uf/options_handlers.h"
+ mode of operation for uf strong solver.
option ufssCliqueSplits --uf-ss-clique-splits bool :default false
use cliques instead of splitting on demand to shrink model
/*! \file options_handlers.h
** \verbatim
** Original author: Morgan Deters
- ** Major contributors: none
+ ** Major contributors: Andrew Reynolds
** Minor contributors (to current version): none
** This file is part of the CVC4 project.
** Copyright (c) 2009-2014 New York University and The University of Iowa
namespace CVC4 {
namespace theory {
namespace uf {
+
+typedef enum {
+ /** default, use uf strong solver to find minimal models for uninterpreted sorts */
+ UF_SS_FULL,
+ /** use uf strong solver to shrink model sizes, but do no enforce minimality */
+ UF_SS_NO_MINIMAL,
+ /** do not use uf strong solver */
+ UF_SS_NONE,
+} UfssMode;
+
+static const std::string ufssModeHelp = "\
+UF strong solver options currently supported by the --uf-ss option:\n\
+\n\
+full \n\
++ Default, use uf strong solver to find minimal models for uninterpreted sorts.\n\
+\n\
+no-minimal \n\
++ Use uf strong solver to shrink model sizes, but do no enforce minimality.\n\
+\n\
+none \n\
++ Do not use uf strong solver to shrink model sizes. \n\
+\n\
+";
+
+inline UfssMode stringToUfssMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) {
+ if(optarg == "default" || optarg == "full" ) {
+ return UF_SS_FULL;
+ } else if(optarg == "no-minimal") {
+ return UF_SS_NO_MINIMAL;
+ } else if(optarg == "none") {
+ return UF_SS_NONE;
+ } else if(optarg == "help") {
+ puts(ufssModeHelp.c_str());
+ exit(1);
+ } else {
+ throw OptionException(std::string("unknown option for --uf-ss: `") +
+ optarg + "'. Try --uf-ss help.");
+ }
+}
}/* CVC4::theory::uf namespace */
}/* CVC4::theory namespace */
void TheoryUF::finishInit() {
// initialize the strong solver
- if (options::finiteModelFind()) {
+ if (options::finiteModelFind() && options::ufssMode()!=UF_SS_NONE) {
d_thss = new StrongSolverTheoryUF(getSatContext(), getUserContext(), *d_out, this);
}
}
return false;
}
-
-void StrongSolverTheoryUF::SortModel::Region::getRepresentatives( std::vector< Node >& reps ){
- for( std::map< Node, RegionNodeInfo* >::iterator it = d_nodes.begin(); it != d_nodes.end(); ++it ){
- RegionNodeInfo* rni = it->second;
- if( rni->d_valid ){
- reps.push_back( it->first );
- }
- }
-}
-
void StrongSolverTheoryUF::SortModel::Region::getNumExternalDisequalities( std::map< Node, int >& num_ext_disequalities ){
for( std::map< Node, RegionNodeInfo* >::iterator it = d_nodes.begin(); it != d_nodes.end(); ++it ){
RegionNodeInfo* rni = it->second;
if( d_regions[i]->d_valid ){
std::vector< Node > clique;
if( d_regions[i]->check( level, d_cardinality, clique ) ){
- if( options::ufssMinimalModel() ){
+ if( options::ufssMode()==UF_SS_FULL ){
//add clique lemma
addCliqueLemma( clique, out );
return;
if( d_regions[i]->d_valid ){
int fcr = forceCombineRegion( i, false );
Trace("uf-ss-debug") << "Combined regions " << i << " " << fcr << std::endl;
- if( options::ufssMinimalModel() || fcr!=-1 ){
+ if( options::ufssMode()==UF_SS_FULL || fcr!=-1 ){
recheck = true;
break;
}
//now check if region is in conflict
std::vector< Node > clique;
if( d_regions[ri]->check( Theory::EFFORT_STANDARD, d_cardinality, clique ) ){
- if( options::ufssMinimalModel() ){
+ if( options::ufssMode()==UF_SS_FULL ){
//explain clique
addCliqueLemma( clique, &d_thss->getOutputChannel() );
}
}
Assert( s!=Node::null() );
}else{
- if( !options::ufssMinimalModel() ){
+ if( options::ufssMode()!=UF_SS_FULL ){
//since candidate clique is not reported, we may need to find splits manually
for ( std::map< Node, Region::RegionNodeInfo* >::iterator it = r->d_nodes.begin(); it != r->d_nodes.end(); ++it ){
if ( it->second->d_valid ){
return count;
}
-void StrongSolverTheoryUF::SortModel::getRepresentatives( std::vector< Node >& reps ){
- for( int i=0; i<(int)d_regions_index; i++ ){
- //should not have multiple regions at this point
- //if( foundRegion ){
- // Assert( !d_regions[i]->d_valid );
- //}
- if( d_regions[i]->d_valid ){
- //this is the only valid region
- d_regions[i]->getRepresentatives( reps );
- }
- }
-}
-
Node StrongSolverTheoryUF::SortModel::getCardinalityLiteral( int c ) {
if( d_cardinality_literal.find( c )==d_cardinality_literal.end() ){
d_cardinality_literal[c] = NodeManager::currentNM()->mkNode( CARDINALITY_CONSTRAINT, d_cardinality_term,
void StrongSolverTheoryUF::check( Theory::Effort level ){
if( !d_conflict ){
Trace("uf-ss-solver") << "StrongSolverTheoryUF: check " << level << std::endl;
- if( level==Theory::EFFORT_FULL ){
+ if( level==Theory::EFFORT_FULL && Debug.isOn( "uf-ss-debug" ) ){
debugPrint( "uf-ss-debug" );
}
for( std::map< TypeNode, SortModel* >::iterator it = d_rep_model.begin(); it != d_rep_model.end(); ++it ){
return -1;
}
-/*
-void StrongSolverTheoryUF::getRepresentatives( Node n, std::vector< Node >& reps ){
- SortModel* c = getSortModel( n );
- if( c ){
- c->getRepresentatives( reps );
- if( (int)reps.size()!=c->getCardinality() ){
- Trace("uf-ss-warn") << "Sort " << n.getType() << " has cardinality " << c->getCardinality();
- Trace("uf-ss-warn") << ", but provided " << reps.size() << " representatives!!!" << std::endl;
- }
- }
-}
-*/
-
bool StrongSolverTheoryUF::minimize( TheoryModel* m ){
for( std::map< TypeNode, SortModel* >::iterator it = d_rep_model.begin(); it != d_rep_model.end(); ++it ){
if( !it->second->minimize( d_out, m ) ){
bool getMustCombine( int cardinality );
/** has splits */
bool hasSplits() { return d_splitsSize>0; }
- /** get representatives */
- void getRepresentatives( std::vector< Node >& reps );
/** get external disequalities */
void getNumExternalDisequalities( std::map< Node, int >& num_ext_disequalities );
public:
bool isConflict() { return d_conflict; }
/** get cardinality */
int getCardinality() { return d_cardinality; }
- /** get representatives */
- void getRepresentatives( std::vector< Node >& reps );
/** has cardinality */
bool hasCardinalityAsserted() { return d_hasCard; }
/** get cardinality term */
int getCardinality( Node n );
/** get cardinality for type */
int getCardinality( TypeNode tn );
- /** get representatives */
- //void getRepresentatives( Node n, std::vector< Node >& reps );
/** minimize */
bool minimize( TheoryModel* m = NULL );