d_zero = NodeManager::currentNM()->mkConst( Rational( 0 ) );
d_one = NodeManager::currentNM()->mkConst( Rational( 1 ) );
d_true = NodeManager::currentNM()->mkConst( true );
+ d_is_nested_quant = false;
}
void CegInstantiator::computeProgVars( Node n ){
//collect all assertions from theory
for( context::CDList<Assertion>::const_iterator it = theory->facts_begin(); it != theory->facts_end(); ++ it) {
Node lit = (*it).assertion;
- d_curr_asserts[tid].push_back( lit );
- Trace("cbqi-proc-debug") << "...add : " << lit << std::endl;
+ Node atom = lit.getKind()==NOT ? lit[0] : lit;
+ if( d_is_nested_quant || std::find( d_ce_atoms.begin(), d_ce_atoms.end(), atom )!=d_ce_atoms.end() ){
+ d_curr_asserts[tid].push_back( lit );
+ Trace("cbqi-proc-debug") << "...add : " << lit << std::endl;
+ }else{
+ Trace("cbqi-proc") << "...do not consider literal " << tid << " : " << lit << " since it is not part of CE body." << std::endl;
+ }
if( lit.getKind()==EQUAL ){
std::map< Node, std::map< Node, Node > >::iterator itae = d_aux_eq.find( lit );
if( itae!=d_aux_eq.end() ){
subs_rhs.push_back( r );
}
+void CegInstantiator::collectCeAtoms( Node n, std::map< Node, bool >& visited ) {
+ if( n.getKind()==FORALL ){
+ d_is_nested_quant = true;
+ }else{
+ if( visited.find( n )==visited.end() ){
+ visited[n] = true;
+ if( TermDb::isBoolConnective( n.getKind() ) ){
+ for( unsigned i=0; i<n.getNumChildren(); i++ ){
+ collectCeAtoms( n[i], visited );
+ }
+ }else{
+ if( std::find( d_ce_atoms.begin(), d_ce_atoms.end(), n )==d_ce_atoms.end() ){
+ d_ce_atoms.push_back( n );
+ }
+ }
+ }
+ }
+}
+
void CegInstantiator::registerCounterexampleLemma( std::vector< Node >& lems, std::vector< Node >& ce_vars ) {
Assert( d_vars.empty() );
d_vars.insert( d_vars.end(), ce_vars.begin(), ce_vars.end() );
}
lems[i] = rlem;
}
+ //collect atoms from lem[0]: we will only do bounds coming from original body
+ d_is_nested_quant = false;
+ std::map< Node, bool > visited;
+ collectCeAtoms( lems[0], visited );
}
//old implementation
std::map< Node, std::map< Node, Node > > d_aux_eq;
//the CE variables
std::vector< Node > d_vars;
+ //atoms of the CE lemma
+ bool d_is_nested_quant;
+ std::vector< Node > d_ce_atoms;
private:
+ //collect atoms
+ void collectCeAtoms( Node n, std::map< Node, bool >& visited );
//for adding instantiations during check
void computeProgVars( Node n );
//solved form, involves substitution with coefficients
}
bool MatchGen::isHandledBoolConnective( TNode n ) {
- return n.getType().isBoolean() && ( n.getKind()==OR || n.getKind()==AND || n.getKind()==IFF || n.getKind()==ITE || n.getKind()==FORALL || n.getKind()==NOT );
+ return n.getType().isBoolean() && TermDb::isBoolConnective( n.getKind() );
}
bool MatchGen::isHandledUfTerm( TNode n ) {
k==BITVECTOR_PLUS || k==BITVECTOR_MULT || k==BITVECTOR_AND || k==BITVECTOR_OR || k==BITVECTOR_XOR || k==BITVECTOR_XNOR;
}
+bool TermDb::isBoolConnective( Kind k ) {
+ return k==OR || k==AND || k==IFF || k==ITE || k==FORALL || k==NOT;
+}
+
void TermDb::registerTrigger( theory::inst::Trigger* tr, Node op ){
if( std::find( d_op_triggers[op].begin(), d_op_triggers[op].end(), tr )==d_op_triggers[op].end() ){
d_op_triggers[op].push_back( tr );
static bool isAssoc( Kind k );
/** is comm */
static bool isComm( Kind k );
+ /** is bool connective */
+ static bool isBoolConnective( Kind k );
//for sygus
private:
}
void QuantifiersEngine::presolve() {
- Trace("quant-engine-debug") << "QuantifiersEngine : presolve " << std::endl;
+ Trace("quant-engine-proc") << "QuantifiersEngine : presolve " << std::endl;
for( unsigned i=0; i<d_modules.size(); i++ ){
d_modules[i]->presolve();
}
d_presolve = false;
//add all terms to database
if( options::incrementalSolving() ){
+ Trace("quant-engine-proc") << "Add presolve cache " << d_presolve_cache.size() << std::endl;
for( unsigned i=0; i<d_presolve_cache.size(); i++ ){
addTermToDatabase( d_presolve_cache[i], d_presolve_cache_wq[i], d_presolve_cache_wic[i] );
}
+ Trace("quant-engine-proc") << "Done add presolve cache " << std::endl;
}
}
//generate the phase requirements
d_phase_reqs[f] = new QuantPhaseReq( ceBody, true );
//also register it with the strong solver
- if( options::finiteModelFind() ){
- ((uf::TheoryUF*)d_te->theoryOf( THEORY_UF ))->getStrongSolver()->registerQuantifier( f );
- }
+ //if( options::finiteModelFind() ){
+ // ((uf::TheoryUF*)d_te->theoryOf( THEORY_UF ))->getStrongSolver()->registerQuantifier( f );
+ //}
d_quants[f] = true;
return true;
}
d_out->lemma(*i);
}
}
+ if( d_thss ){
+ d_thss->presolve();
+ }
Debug("uf") << "uf: end presolve()" << endl;
}
}
}
+void StrongSolverTheoryUF::SortModel::presolve() {
+ d_initialized = false;
+ d_aloc_cardinality = 0;
+}
+
void StrongSolverTheoryUF::SortModel::propagate( Theory::Effort level, OutputChannel* out ){
}
if( d_cardinality_assertions.find( cn )==d_cardinality_assertions.end() ){
Trace("uf-ss-dec") << "UFSS : Get next decision " << d_type << " " << i << std::endl;
return cn;
+ }else{
+ Trace("uf-ss-dec-debug") << " dec : " << cn << " already asserted " << d_cardinality_assertions[cn].get() << std::endl;
}
}
}
Trace("uf-ss-dec") << "UFSS : no decisions for " << d_type << "." << std::endl;
Trace("uf-ss-dec-debug") << " aloc_cardinality = " << d_aloc_cardinality << ", cardinality = " << d_cardinality << ", hasCard = " << d_hasCard << std::endl;
+ Assert( d_hasCard );
return Node::null();
}
if( !d_conflict ){
Trace("uf-ss-assert") << "Assert cardinality " << d_type << " " << c << " " << val << " level = ";
Trace("uf-ss-assert") << d_thss->getTheory()->d_valuation.getAssertionLevel() << std::endl;
+ Assert( c>0 );
Node cl = getCardinalityLiteral( c );
d_cardinality_assertions[ cl ] = val;
if( val ){
if( !d_hasCard ){
bool needsCard = true;
for( std::map< int, Node >::iterator it = d_cardinality_literal.begin(); it!=d_cardinality_literal.end(); ++it ){
- if( d_cardinality_assertions.find( it->second )==d_cardinality_assertions.end() ){
- Debug("fmf-card-debug") << "..does not need allocate because of " << it->second << std::endl;
- needsCard = false;
- break;
+ if( it->first<=d_aloc_cardinality.get() ){
+ if( d_cardinality_assertions.find( it->second )==d_cardinality_assertions.end() ){
+ Debug("fmf-card-debug") << "..does not need allocate because of " << it->second << std::endl;
+ needsCard = false;
+ break;
+ }
}
}
if( needsCard ){
}
}
+void StrongSolverTheoryUF::presolve() {
+ d_aloc_com_card.set( 0 );
+ for( std::map< TypeNode, SortModel* >::iterator it = d_rep_model.begin(); it != d_rep_model.end(); ++it ){
+ it->second->presolve();
+ it->second->initialize( d_out );
+ }
+}
+
/** propagate */
void StrongSolverTheoryUF::propagate( Theory::Effort level ){
//for( std::map< TypeNode, SortModel* >::iterator it = d_rep_model.begin(); it != d_rep_model.end(); ++it ){
}
}
-void StrongSolverTheoryUF::registerQuantifier( Node f ){
- Debug("uf-ss-register") << "Register quantifier " << f << std::endl;
+//void StrongSolverTheoryUF::registerQuantifier( Node f ){
+// Debug("uf-ss-register") << "Register quantifier " << f << std::endl;
//must ensure the quantifier does not quantify over arithmetic
//for( int i=0; i<(int)f[0].getNumChildren(); i++ ){
// TypeNode tn = f[0][i].getType();
// preRegisterType( tn, true );
//}
-}
+//}
StrongSolverTheoryUF::SortModel* StrongSolverTheoryUF::getSortModel( Node n ){
it = d_rep_model.find( tn );
}
if( it!=d_rep_model.end() ){
- //initialize the type if necessary
- //if( d_rep_model_init.find( tn )==d_rep_model_init.end() ){
- ////initialize the model
- //it->second->initialize( d_out );
- //d_rep_model_init[tn] = true;
- //}
return it->second;
+ }else{
+ return NULL;
}
- return NULL;
}
void StrongSolverTheoryUF::notifyRestart(){
bool areDisequal( Node a, Node b );
/** check */
void check( Theory::Effort level, OutputChannel* out );
+ /** presolve */
+ void presolve();
/** propagate */
void propagate( Theory::Effort level, OutputChannel* out );
/** get next decision request */
public:
/** check */
void check( Theory::Effort level );
+ /** presolve */
+ void presolve();
/** propagate */
void propagate( Theory::Effort level );
/** get next decision request */
/** preregister a term */
void preRegisterTerm( TNode n );
/** preregister a quantifier */
- void registerQuantifier( Node f );
+ //void registerQuantifier( Node f );
/** notify restart */
void notifyRestart();
public:
bug654-dd.smt2 \
bug-fmf-fun-skolem.smt2 \
bug674.smt2 \
- inc-double-u.smt2
+ inc-double-u.smt2 \
+ fmf-fun-dbu.smt2
TESTS = $(SMT_TESTS) $(SMT2_TESTS) $(CVC_TESTS) $(BUG_TESTS)
--- /dev/null
+; COMMAND-LINE: --incremental --fmf-fun --no-check-models
+(set-logic UFDTLIA)
+(set-option :produce-models true)
+(set-info :smt-lib-version 2.5)
+(declare-datatypes () ((List (Nil) (Cons (Cons$head Int) (Cons$tail List)))))
+(define-fun-rec all-z ((x List)) Bool (=> (is-Cons x) (and (= 0 (Cons$head x)) (all-z (Cons$tail x)))))
+(define-fun-rec len ((x List)) Int (ite (is-Nil x) 0 (+ 1 (len (Cons$tail x)))))
+(declare-fun root() List)
+; EXPECT: sat
+(assert (and (all-z root) (<= 1 (len root))))
+(check-sat)
+; EXPECT: sat
+(assert (= root (Cons 0 Nil)))
+(check-sat)
+
uminus_one.sy \
sygus-dt.sy \
dt-no-syntax.sy \
- list-head-x.sy
+ list-head-x.sy \
+ clock-inc-tuple.sy
# sygus tests currently taking too long for make regress
EXTRA_DIST = $(TESTS) \
--- /dev/null
+; EXPECT: unsat
+; COMMAND-LINE: --cegqi-si --no-dump-synth
+
+(set-logic ALL_SUPPORTED)
+(declare-var m Int)
+(declare-var s Int)
+(declare-var inc Int)
+(declare-datatypes () ( (tuple2 (tuple2 (_m Int) (_s Int))) ))
+
+(synth-fun x12 ((m Int) (s Int) (inc Int)) tuple2)
+(constraint (=>
+(and (>= m 0) (>= s 0) (< s 3) (> inc 0))
+(and (>= (_m (x12 m s inc)) 0) (>= (_s (x12 m s inc)) 0) (< (_s (x12 m s inc)) 3) (= (+ (* (_m (x12 m s inc)) 3) (_s (x12 m s inc))) (+ (+ (* m 3) s) inc)))))
+(check-synth)