if(self.getAttribute(DatatypeUFiniteComputedAttr())) {
return self.getAttribute(DatatypeUFiniteAttr());
}
+ //start by assuming it is not
+ self.setAttribute(DatatypeUFiniteComputedAttr(), true);
+ self.setAttribute(DatatypeUFiniteAttr(), false);
for(const_iterator i = begin(), i_end = end(); i != i_end; ++i) {
if(! (*i).isUFinite()) {
- self.setAttribute(DatatypeUFiniteComputedAttr(), true);
- self.setAttribute(DatatypeUFiniteAttr(), false);
return false;
}
}
return self.getAttribute(DatatypeFiniteAttr());
}
for(const_iterator i = begin(), i_end = end(); i != i_end; ++i) {
- if(! SelectorType((*i).getSelector().getType()).getRangeType().getCardinality().isFinite()) {
+ if(! (*i).getRangeType().getCardinality().isFinite()) {
self.setAttribute(DatatypeFiniteComputedAttr(), true);
self.setAttribute(DatatypeFiniteAttr(), false);
return false;
if(self.getAttribute(DatatypeUFiniteComputedAttr())) {
return self.getAttribute(DatatypeUFiniteAttr());
}
+ bool success = true;
for(const_iterator i = begin(), i_end = end(); i != i_end; ++i) {
- Type t = SelectorType((*i).getSelector().getType()).getRangeType();
- if(!t.isSort() && !t.getCardinality().isFinite()) {
+ Type t = (*i).getRangeType();
+ if( t.isDatatype() ){
+ const Datatype& dt = ((DatatypeType)t).getDatatype();
+ if( !dt.isUFinite() ){
+ success = false;
+ }
+ }else if(!t.isSort() && !t.getCardinality().isFinite()) {
+ success = false;
+ }
+ if(!success ){
self.setAttribute(DatatypeUFiniteComputedAttr(), true);
self.setAttribute(DatatypeUFiniteAttr(), false);
return false;
}else{
int score = -1;
if( options::quantDynamicSplit()==quantifiers::QUANT_DSPLIT_MODE_AGG ){
- score = dt.isFinite() ? 1 : -1;
- }else if( options::quantDynamicSplit()==quantifiers::QUANT_DSPLIT_MODE_DEFAULT ){
+ score = dt.isUFinite() ? 1 : -1;
+ }else if( options::quantDynamicSplit()==quantifiers::QUANT_DSPLIT_MODE_DEFAULT ){
score = dt.isUFinite() ? 1 : -1;
}
- Trace("quant-dsplit-debug") << "Datatype " << dt.getName() << " is score " << score << std::endl;
+ Trace("quant-dsplit-debug") << "Datatype " << dt.getName() << " is score " << score << " (" << dt.isUFinite() << " " << dt.isFinite() << ")" << std::endl;
if( score>max_score ){
max_index = i;
max_score = score;
/* whether this module needs to check this round */
bool QuantDSplit::needsCheck( Theory::Effort e ) {
- return e>=Theory::EFFORT_FULL;
+ return e>=Theory::EFFORT_FULL && !d_quant_to_reduce.empty();
}
+
/* Call during quantifier engine's check */
void QuantDSplit::check( Theory::Effort e, unsigned quant_e ) {
- //flush lemmas ASAP (they are a reduction)
+ //add lemmas ASAP (they are a reduction)
if( quant_e==QuantifiersEngine::QEFFORT_CONFLICT ){
std::vector< Node > lemmas;
for(std::map< Node, int >::iterator it = d_quant_to_reduce.begin(); it != d_quant_to_reduce.end(); ++it) {
TNode svar = q[0][it->second];
TypeNode tn = svar.getType();
if( tn.isDatatype() ){
+ std::vector< Node > cons;
const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype();
for( unsigned j=0; j<dt.getNumConstructors(); j++ ){
std::vector< Node > vars;
if( !bvs_cmb.empty() ){
body = NodeManager::currentNM()->mkNode( kind::FORALL, NodeManager::currentNM()->mkNode( kind::BOUND_VAR_LIST, bvs_cmb ), body );
}
- disj.push_back( body );
+ cons.push_back( body );
}
+ Node conc = cons.size()==1 ? cons[0] : NodeManager::currentNM()->mkNode( kind::AND, cons );
+ disj.push_back( conc );
}else{
Assert( false );
}
Trace("quant-dsplit") << "QuantDSplit lemma : " << lemmas[i] << std::endl;
d_quantEngine->addLemma( lemmas[i], false );
}
+ d_quant_to_reduce.clear();
}
}
d_modules.push_back( d_lte_part_inst );
}
if( ( options::finiteModelFind() && options::quantDynamicSplit()!=quantifiers::QUANT_DSPLIT_MODE_NONE ) ||
- options::quantDynamicSplit()!=quantifiers::QUANT_DSPLIT_MODE_AGG ){
+ options::quantDynamicSplit()==quantifiers::QUANT_DSPLIT_MODE_AGG ){
d_qsplit = new quantifiers::QuantDSplit( this, c );
d_modules.push_back( d_qsplit );
}
}
bool usedModelBuilder = false;
- Trace("quant-engine-debug") << "Quantifiers Engine call to check, level = " << e << std::endl;
+ Trace("quant-engine-debug2") << "Quantifiers Engine call to check, level = " << e << ", needsCheck=" << needsCheck << std::endl;
if( needsCheck ){
- Trace("quant-engine") << "Quantifiers Engine check, level = " << e << std::endl;
if( Trace.isOn("quant-engine-debug") ){
+ Trace("quant-engine-debug") << "Quantifiers Engine check, level = " << e << std::endl;
Trace("quant-engine-debug") << " modules to check : ";
for( unsigned i=0; i<qm.size(); i++ ){
Trace("quant-engine-debug") << qm[i]->identify() << " ";
}
}
}
- Trace("quant-engine") << "Finished quantifiers engine check." << std::endl;
+ Trace("quant-engine-debug2") << "Finished quantifiers engine check." << std::endl;
}else{
- Trace("quant-engine") << "Quantifiers Engine does not need check." << std::endl;
+ Trace("quant-engine-debug2") << "Quantifiers Engine does not need check." << std::endl;
}
//SAT case
fmc_unsound_model.smt2 \
am-bad-model.cvc \
nun-0208-to.smt2 \
- datatypes-ufinite.smt2
+ datatypes-ufinite.smt2 \
+ datatypes-ufinite-nested.smt2
EXTRA_DIST = $(TESTS)
--- /dev/null
+; COMMAND-LINE: --finite-model-find
+; EXPECT: sat
+(set-logic ALL_SUPPORTED)
+(declare-sort U 0)
+(declare-fun a () U)
+(declare-fun b () U)
+(declare-fun c () U)
+(declare-fun d () U)
+(assert (distinct a b c))
+(declare-sort V 0)
+(declare-datatypes () ((ufin1 (cons1 (s11 U) (s13 ufin2))) (ufin2 (cons2 (s21 V) (s22 U)) (cons3))))
+(declare-fun P (ufin1 ufin2) Bool)
+(declare-fun Q (ufin1 ufin1) Bool)
+(assert (forall ((x ufin1) (y ufin2) (z ufin1)) (or (P x y) (Q x z))))
+(assert (not (P (cons1 a cons3) cons3)))
+(assert (not (Q (cons1 b cons3) (cons1 a cons3))))
+(check-sat)
(declare-fun d () U)
(assert (distinct a b c))
(declare-sort V 0)
-(declare-datatypes () ((ufin1 (cons1 (s11 U) (s12 U) (s13 U))) (ufin2 (cons2 (s21 V) (s22 U)) (cons3))))
+(declare-datatypes () ((ufin1 (cons1 (s11 U) (s12 U))) (ufin2 (cons2 (s21 V) (s22 U)) (cons3))))
(declare-fun P (ufin1 ufin2) Bool)
(declare-fun Q (ufin1 ufin1) Bool)
(assert (forall ((x ufin1) (y ufin2) (z ufin1)) (or (P x y) (Q x z))))
-(assert (not (P (cons1 a a a) cons3)))
-(assert (not (Q (cons1 a d a) (cons1 a b c))))
+(assert (not (P (cons1 a a) cons3)))
+(assert (not (Q (cons1 a d) (cons1 a b))))
(check-sat)