for( unsigned i=0; i<n.getNumChildren(); i++ ){
vec.push_back( 0 );
TypeNode tn = n[i].getType();
- if( TermDb::isClosedEnumerableType( tn ) ){
+ if( getTermDatabase()->isClosedEnumerableType( tn ) ){
types.push_back( tn );
}else{
return;
std::map< TypeNode, bool >::iterator it = d_may_complete.find( tn );
if( it==d_may_complete.end() ){
bool mc = false;
- if( !tn.isArray() && tn.getCardinality().isFinite() && !tn.getCardinality().isLargeFinite() ){
+ if( isClosedEnumerableType( tn ) && tn.getCardinality().isFinite() && !tn.getCardinality().isLargeFinite() ){
Node card = NodeManager::currentNM()->mkConst( Rational(tn.getCardinality().getFiniteCardinality()) );
Node oth = NodeManager::currentNM()->mkConst( Rational(1000) );
Node eq = NodeManager::currentNM()->mkNode( LEQ, card, oth );
}
bool TermDb::isClosedEnumerableType( TypeNode tn ) {
- return !tn.isArray() && !tn.isSort() && !tn.isCodatatype();
+ std::map< TypeNode, bool >::iterator it = d_typ_closed_enum.find( tn );
+ if( it==d_typ_closed_enum.end() ){
+ bool ret = true;
+ if( tn.isArray() || tn.isSort() || tn.isCodatatype() ){
+ ret = false;
+ }else{
+ //TODO: all subfields must be closed enumerable?
+ }
+ d_typ_closed_enum[tn] = ret;
+ return ret;
+ }else{
+ return it->second;
+ }
}
Node TermDb::getFreeVariableForInstConstant( Node n ){
//type enumerators
std::map< TypeNode, unsigned > d_typ_enum_map;
std::vector< TypeEnumerator > d_typ_enum;
+ // closed enumerable type cache
+ std::map< TypeNode, bool > d_typ_closed_enum;
public:
//get nth term for type
Node getEnumerateTerm( TypeNode tn, unsigned index );
//does this type have an enumerator that produces constants that are handled by ground theory solvers
- static bool isClosedEnumerableType( TypeNode tn );
+ bool isClosedEnumerableType( TypeNode tn );
//miscellaneous
public:
QuantifiersEngine::QuantifiersEngine(context::Context* c, context::UserContext* u, TheoryEngine* te):
d_te( te ),
-d_lemmas_produced_c(u){
+d_lemmas_produced_c(u),
+d_skolemized(u){
d_eq_query = new EqualityQueryQuantifiersEngine( this );
d_term_db = new quantifiers::TermDb( c, u, this );
d_tr_trie = new inst::TriggerTrie;
void QuantifiersEngine::printInstantiations( std::ostream& out ) {
bool printed = false;
- for( std::map< Node, bool >::iterator it = d_skolemized.begin(); it != d_skolemized.end(); ++it ){
+ for( BoolMap::iterator it = d_skolemized.begin(); it != d_skolemized.end(); ++it ){
+ Node q = (*it).first;
printed = true;
- out << "Skolem constants of " << it->first << " : " << std::endl;
+ out << "Skolem constants of " << q << " : " << std::endl;
out << " ( ";
- for( unsigned i=0; i<d_term_db->d_skolem_constants[it->first].size(); i++ ){
+ for( unsigned i=0; i<d_term_db->d_skolem_constants[q].size(); i++ ){
if( i>0 ){ out << ", "; }
- out << d_term_db->d_skolem_constants[it->first][i];
+ out << d_term_db->d_skolem_constants[q][i];
}
out << " )" << std::endl;
out << std::endl;
std::map< Node, inst::InstMatchTrie > d_inst_match_trie;
std::map< Node, inst::CDInstMatchTrie* > d_c_inst_match_trie;
/** quantifiers that have been skolemized */
- std::map< Node, bool > d_skolemized;
+ BoolMap d_skolemized;
/** term database */
quantifiers::TermDb* d_term_db;
/** all triggers will be stored in this trie */
return Node::null();
}
-//FIXME: need to ensure that theory enumerators exist for each sort
-Node TheoryModel::getNewDomainValue( TypeNode tn ){
- if( tn.isSort() ){
- return Node::null();
- }else{
- TypeEnumerator te(tn);
- while( !te.isFinished() ){
- Node r = *te;
- if(Debug.isOn("getNewDomainValue")) {
- Debug("getNewDomainValue") << "getNewDomainValue( " << tn << ")" << endl;
- Debug("getNewDomainValue") << "+ TypeEnumerator gave: " << r << endl;
- Debug("getNewDomainValue") << "+ d_type_reps are:";
- for(vector<Node>::const_iterator i = d_rep_set.d_type_reps[tn].begin();
- i != d_rep_set.d_type_reps[tn].end();
- ++i) {
- Debug("getNewDomainValue") << " " << *i;
- }
- Debug("getNewDomainValue") << endl;
- }
- if( std::find(d_rep_set.d_type_reps[tn].begin(), d_rep_set.d_type_reps[tn].end(), r) ==d_rep_set.d_type_reps[tn].end() ) {
- Debug("getNewDomainValue") << "+ it's new, so returning " << r << endl;
- return r;
- }
- ++te;
- }
- return Node::null();
- }
-}
-
/** add substitution */
void TheoryModel::addSubstitution( TNode x, TNode t, bool invalidateCache ){
if( !d_substitutions.hasSubstitution( x ) ){
* This function returns a term in d_rep_set.d_type_reps[tn] but not in exclude
*/
Node getDomainValue( TypeNode tn, std::vector< Node >& exclude );
- /** get new domain value
- * This function returns a constant term of type tn that is not in d_rep_set.d_type_reps[tn]
- * If it cannot find such a node, it returns null.
- */
- Node getNewDomainValue( TypeNode tn );
public:
/** Adds a substitution from x to t. */
void addSubstitution(TNode x, TNode t, bool invalidateCache = true);
quant-fun-proc.smt2 \
quant-fun-proc-unmacro.smt2 \
quant-fun-proc-unfd.smt2 \
- bug654-dd.smt2
+ bug654-dd.smt2 \
+ bug-fmf-fun-skolem.smt2
TESTS = $(SMT_TESTS) $(SMT2_TESTS) $(CVC_TESTS) $(BUG_TESTS)
--- /dev/null
+; COMMAND-LINE: --incremental --fmf-fun
+(set-logic ALL_SUPPORTED)
+(declare-datatypes () ((Lst (cons (head Int) (tail Lst)) (nil))))
+(define-fun-rec sum ((l Lst)) Int (ite (is-nil l) 0 (+ (head l) (sum (tail l)))))
+
+(declare-fun input () Int)
+(declare-fun p () Bool)
+(declare-fun acc () Lst)
+(assert (and (= acc (ite (>= input 0) (cons input nil) nil))
+ (= p (>= (sum acc) 0))))
+
+
+; EXPECT: unsat
+(push 1)
+(assert (not p))
+(check-sat)
+(pop 1)
+
+; EXPECT: unsat
+(push 1)
+(assert (not p))
+(check-sat)
+(pop 1)
+
+