Add support for cardinality constraints logic UFC. Add regressions in fmf/. Fix...
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Thu, 10 Apr 2014 15:31:47 +0000 (10:31 -0500)
committerAndrew Reynolds <andrew.j.reynolds@gmail.com>
Thu, 10 Apr 2014 15:33:24 +0000 (10:33 -0500)
27 files changed:
src/parser/smt1/smt1.h
src/smt/smt_engine.cpp
src/theory/datatypes/theory_datatypes.cpp
src/theory/logic_info.cpp
src/theory/logic_info.h
src/theory/quantifiers/first_order_model.cpp
src/theory/quantifiers/modes.cpp
src/theory/quantifiers/modes.h
src/theory/quantifiers/options
src/theory/quantifiers/options_handlers.h
src/theory/quantifiers/term_database.cpp
src/theory/uf/theory_uf.cpp
src/util/datatype.cpp
src/util/datatype.h
test/regress/regress0/bug512.smt2
test/regress/regress0/fmf/Arrow_Order-smtlib.778341.smt
test/regress/regress0/fmf/Makefile.am
test/regress/regress0/fmf/QEpres-uf.855035.smt
test/regress/regress0/fmf/fc-pigeonhole19.smt2 [new file with mode: 0755]
test/regress/regress0/fmf/fc-simple.smt2 [new file with mode: 0755]
test/regress/regress0/fmf/fc-unsat-pent.smt2 [new file with mode: 0755]
test/regress/regress0/fmf/fc-unsat-tot-2.smt2 [new file with mode: 0755]
test/regress/regress0/quantifiers/bug269.smt2
test/regress/regress0/quantifiers/burns13.smt2
test/regress/regress0/rewriterules/Makefile.am
test/regress/regress0/rewriterules/read5.smt2 [new file with mode: 0755]
test/regress/regress0/tptp/Makefile.am

index f96a4e81026351ab8d2f154deba427423c6363dd..c19b0f872a355400bf565711eb2834c67a736da2 100644 (file)
@@ -84,7 +84,8 @@ public:
     THEORY_REALS,
     THEORY_REALS_INTS,
     THEORY_STRINGS,
-    THEORY_QUANTIFIERS
+    THEORY_QUANTIFIERS,
+    THEORY_CARDINALITY_CONSTRAINT
   };
 
 private:
index 8586bc9da5ee04e54db61172b928739e2eb9a239..36f9866f484b0154d09052d1dcdb7ad5a8170165 100644 (file)
@@ -1112,7 +1112,7 @@ void SmtEngine::setDefaults() {
   if(!options::decisionMode.wasSetByUser()) {
     decision::DecisionMode decMode =
       // ALL_SUPPORTED
-      d_logic.hasEverything() ? decision::DECISION_STRATEGY_INTERNAL :
+      d_logic.hasEverything() ? decision::DECISION_STRATEGY_JUSTIFICATION :
       ( // QF_BV
         (not d_logic.isQuantified() &&
           d_logic.isPure(THEORY_BV)
@@ -1153,9 +1153,7 @@ void SmtEngine::setDefaults() {
         // QF_LRA
         (not d_logic.isQuantified() &&
          d_logic.isPure(THEORY_ARITH) && d_logic.isLinear() && !d_logic.isDifferenceLogic() &&  !d_logic.areIntegersUsed()
-         ) ||
-        // Quantifiers
-        d_logic.isQuantified()
+         )
         ? true : false
       );
 
@@ -1172,12 +1170,17 @@ void SmtEngine::setDefaults() {
       options::instWhenMode.set( quantifiers::INST_WHEN_LAST_CALL );
     }
   }
-  if ( options::fmfBoundInt() ){
+  if( d_logic.hasCardinalityConstraints() ){
+    //must have finite model finding on
+    options::finiteModelFind.set( true );
+  }
+  if( options::fmfBoundInt() ){
     //must have finite model finding on
     options::finiteModelFind.set( true );
-    if( options::mbqiMode()!=quantifiers::MBQI_NONE &&
-        options::mbqiMode()!=quantifiers::MBQI_FMC &&
-        options::mbqiMode()!=quantifiers::MBQI_FMC_INTERVAL ){
+    if( ! options::mbqiMode.wasSetByUser() ||
+        ( options::mbqiMode()!=quantifiers::MBQI_NONE &&
+          options::mbqiMode()!=quantifiers::MBQI_FMC &&
+          options::mbqiMode()!=quantifiers::MBQI_FMC_INTERVAL ) ){
       //if bounded integers are set, use no MBQI by default
       options::mbqiMode.set( quantifiers::MBQI_NONE );
     }
index 0c6842222af1aae8409fd16b33cae41f12eea9b6..b00b4148d229ff404f0f606f64bb09d68e240e06 100644 (file)
@@ -889,14 +889,48 @@ void TheoryDatatypes::collectModelInfo( TheoryModel* m, bool fullModel ){
   Trace("dt-model") << std::endl;
   printModelDebug( "dt-model" );
   Trace("dt-model") << std::endl;
+
+  /*
+  bool eq_merged = false;
+  std::vector< Node > all_eqc;
+  eq::EqClassesIterator eqcs1_i = eq::EqClassesIterator( &d_equalityEngine );
+  while( !eqcs1_i.isFinished() ){
+    Node eqc = (*eqcs1_i);
+    all_eqc.push_back( eqc );
+    ++eqcs1_i;
+  }
+  //check if equivalence classes have merged
+  for( unsigned i=0; i<all_eqc.size(); i++ ){
+    for( unsigned j=(i+1); j<all_eqc.size(); j++ ){
+      if( m->areEqual( all_eqc[i], all_eqc[j] ) ){
+        Trace("dt-cmi") << "Pre-already forced equal : " << all_eqc[i] << " = " << all_eqc[j] << std::endl;
+        eq_merged = true;
+      }
+    }
+  }
+  Assert( !eq_merged );
+  */
+
+  //combine the equality engine
   m->assertEqualityEngine( &d_equalityEngine );
-/*
-  std::vector< TypeEnumerator > vec;
-  std::map< TypeNode, int > tes;
+
+  /*
+  //check again if equivalence classes have merged
+  for( unsigned i=0; i<all_eqc.size(); i++ ){
+    for( unsigned j=(i+1); j<all_eqc.size(); j++ ){
+      if( m->areEqual( all_eqc[i], all_eqc[j] ) ){
+        Trace("dt-cmi") << "Already forced equal : " << all_eqc[i] << " = " << all_eqc[j] << std::endl;
+        eq_merged = true;
+      }
+    }
+  }
+  Assert( !eq_merged );
   */
+
   //get all constructors
   eq::EqClassesIterator eqccs_i = eq::EqClassesIterator( &d_equalityEngine );
   std::vector< Node > cons;
+  std::vector< Node > nodes;
   while( !eqccs_i.isFinished() ){
     Node eqc = (*eqccs_i);
     //for all equivalence classes that are datatypes
@@ -904,28 +938,13 @@ void TheoryDatatypes::collectModelInfo( TheoryModel* m, bool fullModel ){
       EqcInfo* ei = getOrMakeEqcInfo( eqc );
       if( !ei->d_constructor.get().isNull() ){
         cons.push_back( ei->d_constructor.get() );
-      }
-    }
-    ++eqccs_i;
-  }
-
-  //must choose proper representatives
-  std::vector< Node > nodes;
-  eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( &d_equalityEngine );
-  while( !eqcs_i.isFinished() ){
-    Node eqc = (*eqcs_i);
-    //for all equivalence classes that are datatypes
-    if( DatatypesRewriter::isTermDatatype( eqc ) ){
-      EqcInfo* ei = getOrMakeEqcInfo( eqc );
-      if( !ei->d_constructor.get().isNull() ){
-        //specify that we should use the constructor as the representative
-        //m->assertRepresentative( ei->d_constructor.get() );
       }else{
         nodes.push_back( eqc );
       }
     }
-    ++eqcs_i;
+    ++eqccs_i;
   }
+
   unsigned index = 0;
   while( index<nodes.size() ){
     Node eqc = nodes[index];
@@ -972,44 +991,22 @@ void TheoryDatatypes::collectModelInfo( TheoryModel* m, bool fullModel ){
       }
       Trace("dt-cmi") << std::endl;
       /*
-      if( tes.find( eqc.getType() )==tes.end() ){
-        tes[eqc.getType()]=vec.size();
-        vec.push_back( TypeEnumerator( eqc.getType() ) );
-      }
-      bool success;
-      Node n;
-      do {
-        success = true;
-        Assert( !vec[tes[eqc.getType()]].isFinished() );
-        n = *vec[tes[eqc.getType()]];
-        ++vec[tes[eqc.getType()]];
-        Trace("dt-cmi-debug") << "Try " << n << "..." << std::endl;
-        //check if it is consistent with labels
-        size_t constructorIndex = Datatype::indexOf(n.getOperator().toExpr());
-        if( constructorIndex<pcons.size() && pcons[constructorIndex] ){
-          for( unsigned i=0; i<cons.size(); i++ ){
-            //check if it is modulo equality the same
-            if( cons[i].getOperator()==n.getOperator() ){
-              bool diff = false;
-              for( unsigned j=0; j<cons[i].getNumChildren(); j++ ){
-                if( !m->areEqual( cons[i][j], n[j] ) ){
-                  diff = true;
-                  break;
-                }
-              }
-              if( !diff ){
-                Trace("dt-cmi-debug") << "...Already equivalent modulo equality to " << cons[i] << std::endl;
-                success = false;
-                break;
-              }
-            }
-          }
-        }else{
-          Trace("dt-cmi-debug") << "...Not consistent with labels" << std::endl;
-          success = false;
+      std::map< int, std::map< int, bool > > sels;
+      Trace("dt-cmi") << "Existing selectors : ";
+      NodeListMap::iterator sel_i = d_selector_apps.find( eqc );
+      if( sel_i != d_selector_apps.end() ){
+        NodeList* sel = (*sel_i).second;
+        for( NodeList::const_iterator j = sel->begin(); j != sel->end(); j++ ){
+          Expr selectorExpr = (*j).getOperator().toExpr();
+          unsigned cindex = Datatype::cindexOf( selectorExpr );
+          unsigned index = Datatype::indexOf( selectorExpr );
+          sels[cindex][index] = true;
+          Trace("dt-cmi") << (*j) << " (" << cindex << ", " << index << ") ";
         }
-      }while( !success );
+      }
+      Trace("dt-cmi") << std::endl;
       */
+
       const Datatype& dt = ((DatatypeType)(eqc.getType()).toType()).getDatatype();
       for( unsigned r=0; r<2; r++ ){
         if( neqc.isNull() ){
@@ -1017,6 +1014,7 @@ void TheoryDatatypes::collectModelInfo( TheoryModel* m, bool fullModel ){
             if( pcons[i] && (r==1)==dt[ i ].isFinite() ){
               neqc = getInstantiateCons( eqc, dt, i, false, false );
               for( unsigned j=0; j<neqc.getNumChildren(); j++ ){
+                //if( sels[i].find( j )==sels[i].end() && DatatypesRewriter::isTermDatatype( neqc[j] ) ){
                 if( !d_equalityEngine.hasTerm( neqc[j] ) && DatatypesRewriter::isTermDatatype( neqc[j] ) ){
                   nodes.push_back( neqc[j] );
                 }
@@ -1030,6 +1028,24 @@ void TheoryDatatypes::collectModelInfo( TheoryModel* m, bool fullModel ){
     Assert( !neqc.isNull() );
     Trace("dt-cmi") << "Assign : " << neqc << std::endl;
     m->assertEquality( eqc, neqc, true );
+    /*
+    for( unsigned kk=0; kk<all_eqc.size(); kk++ ){
+      for( unsigned ll=(kk+1); ll<all_eqc.size(); ll++ ){
+        if( m->areEqual( all_eqc[kk], all_eqc[ll] ) ){
+          Trace("dt-cmi") << "Forced equal : " << kk << " " << ll << " : " << all_eqc[kk] << " = " << all_eqc[ll] << std::endl;
+          Node r = m->getRepresentative( all_eqc[kk] );
+          Trace("dt-cmi") << "  { ";
+          eq::EqClassIterator eqc_i = eq::EqClassIterator( r, m->d_equalityEngine );
+          while( !eqc_i.isFinished() ){
+            Trace("dt-cmi") << (*eqc_i) << " ";
+            ++eqc_i;
+          }
+          Trace("dt-cmi") << "} " << std::endl;
+        }
+        Assert( !m->areEqual( all_eqc[kk], all_eqc[ll] ) );
+      }
+    }
+    */
     //m->assertRepresentative( neqc );
     cons.push_back( neqc );
     ++index;
index c079eecf9ee1e5d8844a72d24c5a257bb36abfc1..78f4996b8ddaf728083844213984d5bd2dfb26bb 100644 (file)
@@ -37,6 +37,7 @@ LogicInfo::LogicInfo() :
   d_reals(true),
   d_linear(true),// for now, "everything enabled" doesn't include non-linear arith
   d_differenceLogic(false),
+  d_cardinalityConstraints(false),
   d_locked(false) {
 
   for(TheoryId id = THEORY_FIRST; id < THEORY_LAST; ++id) {
@@ -52,6 +53,7 @@ LogicInfo::LogicInfo(std::string logicString) throw(IllegalArgumentException) :
   d_reals(false),
   d_linear(false),
   d_differenceLogic(false),
+  d_cardinalityConstraints(false),
   d_locked(false) {
 
   setLogicString(logicString);
@@ -66,6 +68,7 @@ LogicInfo::LogicInfo(const char* logicString) throw(IllegalArgumentException) :
   d_reals(false),
   d_linear(false),
   d_differenceLogic(false),
+  d_cardinalityConstraints(false),
   d_locked(false) {
 
   setLogicString(logicString);
@@ -97,6 +100,9 @@ std::string LogicInfo::getLogicString() const {
         ss << "UF";
         ++seen;
       }
+      if( d_cardinalityConstraints ){
+        ss << "C";
+      }
       if(d_theories[THEORY_BV]) {
         ss << "BV";
         ++seen;
@@ -191,6 +197,10 @@ void LogicInfo::setLogicString(std::string logicString) throw(IllegalArgumentExc
         enableTheory(THEORY_UF);
         p += 2;
       }
+      if(!strncmp(p, "C", 1 )) {
+        d_cardinalityConstraints = true;
+        p += 1;
+      }
       // allow BV or DT in either order
       if(!strncmp(p, "BV", 2)) {
         enableTheory(THEORY_BV);
index a0777ae70a59fd5d24069c25dd0678b75aae82ac..1c4b69b15e66b257f14578e7e5f24007ce117151 100644 (file)
@@ -52,6 +52,7 @@ class CVC4_PUBLIC LogicInfo {
   bool d_reals; /**< are reals used in this logic? */
   bool d_linear; /**< linear-only arithmetic in this logic? */
   bool d_differenceLogic; /**< difference-only arithmetic in this logic? */
+  bool d_cardinalityConstraints; /**< cardinality constraints in this logic? */
 
   bool d_locked; /**< is this LogicInfo instance locked (and thus immutable)? */
 
@@ -175,6 +176,11 @@ public:
     CheckArgument(isTheoryEnabled(theory::THEORY_ARITH), *this, "Arithmetic not used in this LogicInfo; cannot ask whether it's difference logic");
     return d_differenceLogic;
   }
+  /** Does this logic allow cardinality constraints? */
+  bool hasCardinalityConstraints() const {
+    CheckArgument(d_locked, *this, "This LogicInfo isn't locked yet, and cannot be queried");
+    return d_cardinalityConstraints;
+  }
 
   // MUTATORS
 
index f3203da4bb1a9744d7fc116f965ad199bd1975f9..54be11b4482ef70bd39baa257e88ac94b3cf6f31 100644 (file)
@@ -656,6 +656,7 @@ Node FirstOrderModelFmc::getFunctionValue(Node op, const char* argPrefix ) {
       Node cond = d_models[op]->d_cond[i];
       std::vector< Node > children;
       for( unsigned j=0; j<cond.getNumChildren(); j++) {
+        TypeNode tn = vars[j].getType();
         if (isInterval(cond[j])){
           if( !isStar(cond[j][0]) ){
             children.push_back( NodeManager::currentNM()->mkNode( GEQ, vars[j], cond[j][0] ) );
@@ -663,7 +664,8 @@ Node FirstOrderModelFmc::getFunctionValue(Node op, const char* argPrefix ) {
           if( !isStar(cond[j][1]) ){
             children.push_back( NodeManager::currentNM()->mkNode( LT, vars[j], cond[j][1] ) );
           }
-        }else if (!isStar(cond[j])){
+        }else if ( !isStar(cond[j]) &&  //handle the case where there are 0 or 1 ground representatives of this type...
+                   d_rep_set.d_type_reps.find( tn )!=d_rep_set.d_type_reps.end() && d_rep_set.d_type_reps[ tn ].size()>1 ){
           Node c = getUsedRepresentative( cond[j] );
           children.push_back( NodeManager::currentNM()->mkNode( EQUAL, vars[j], c ) );
         }
@@ -673,6 +675,7 @@ Node FirstOrderModelFmc::getFunctionValue(Node op, const char* argPrefix ) {
       curr = NodeManager::currentNM()->mkNode( ITE, cc, v, curr );
     }
   }
+  Trace("fmc-model") << "Made " << curr << " for " << op << std::endl;
   curr = Rewriter::rewrite( curr );
   return NodeManager::currentNM()->mkNode(kind::LAMBDA, boundVarList, curr);
 }
index 10185914ef376c837d91d1709d32d97bfa5f6707..8bd97a8a74805ad8e1f6677e99f4dd13e793f092 100644 (file)
@@ -79,8 +79,8 @@ std::ostream& operator<<(std::ostream& out, theory::quantifiers::AxiomInstMode m
 
 std::ostream& operator<<(std::ostream& out, theory::quantifiers::MbqiMode mode) {
   switch(mode) {
-  case theory::quantifiers::MBQI_DEFAULT:
-    out << "MBQI_DEFAULT";
+  case theory::quantifiers::MBQI_GEN_EVAL:
+    out << "MBQI_GEN_EVAL";
     break;
   case theory::quantifiers::MBQI_NONE:
     out << "MBQI_NONE";
@@ -94,6 +94,9 @@ std::ostream& operator<<(std::ostream& out, theory::quantifiers::MbqiMode mode)
   case theory::quantifiers::MBQI_INTERVAL:
     out << "MBQI_INTERVAL";
     break;
+  case theory::quantifiers::MBQI_TRUST:
+    out << "MBQI_TRUST";
+    break;
   default:
     out << "MbqiMode!UNKNOWN";
   }
index 89e10b1759629c71b0190f783629a79daee89494..80534c8b053960d9464b9aaa95bccdb9b7b9de2c 100644 (file)
@@ -58,13 +58,13 @@ typedef enum {
 } AxiomInstMode;
 
 typedef enum {
-  /** default, mbqi from CADE 24 paper */
-  MBQI_DEFAULT,
+  /** mbqi from CADE 24 paper */
+  MBQI_GEN_EVAL,
   /** no mbqi */
   MBQI_NONE,
   /** implementation that mimics inst-gen */
   MBQI_INST_GEN,
-  /** mbqi from Section 5.4.2 of AJR thesis */
+  /** default, mbqi from Section 5.4.2 of AJR thesis */
   MBQI_FMC,
   /** mbqi with integer intervals */
   MBQI_FMC_INTERVAL,
index 0865f2c0b6b89597804ccd755785146aeaa9ee8a..b7f015f47d6f074d290fef3344efaae1df0e41ca 100644 (file)
@@ -71,7 +71,7 @@ option instWhenMode --inst-when=MODE CVC4::theory::quantifiers::InstWhenMode :de
 option eagerInstQuant --eager-inst-quant bool :default false
  apply quantifier instantiation eagerly
  
-option fullSaturateQuant --full-saturate-quant bool :default true
+option fullSaturateQuant --full-saturate-quant bool :default false
  when all other quantifier instantiation strategies fail, instantiate with ground terms from relevant domain, then arbitrary ground terms before answering unknown
 
 option literalMatchMode --literal-matching=MODE CVC4::theory::quantifiers::LiteralMatchMode :default CVC4::theory::quantifiers::LITERAL_MATCH_NONE :include "theory/quantifiers/modes.h" :handler CVC4::theory::quantifiers::stringToLiteralMatchMode :handler-include "theory/quantifiers/options_handlers.h" :predicate CVC4::theory::quantifiers::checkLiteralMatchMode :predicate-include "theory/quantifiers/options_handlers.h"
@@ -95,7 +95,7 @@ option internalReps /--disable-quant-internal-reps bool :default true
 option finiteModelFind finite-model-find --finite-model-find bool :default false :read-write
  use finite model finding heuristic for quantifier instantiation
 
-option mbqiMode --mbqi=MODE CVC4::theory::quantifiers::MbqiMode :read-write :default CVC4::theory::quantifiers::MBQI_DEFAULT :include "theory/quantifiers/modes.h" :handler CVC4::theory::quantifiers::stringToMbqiMode :handler-include "theory/quantifiers/options_handlers.h" :predicate CVC4::theory::quantifiers::checkMbqiMode :predicate-include "theory/quantifiers/options_handlers.h"
+option mbqiMode --mbqi=MODE CVC4::theory::quantifiers::MbqiMode :read-write :default CVC4::theory::quantifiers::MBQI_FMC :include "theory/quantifiers/modes.h" :handler CVC4::theory::quantifiers::stringToMbqiMode :handler-include "theory/quantifiers/options_handlers.h" :predicate CVC4::theory::quantifiers::checkMbqiMode :predicate-include "theory/quantifiers/options_handlers.h"
  choose mode for model-based quantifier instantiation
 option fmfOneInstPerRound --mbqi-one-inst-per-round bool :default false
  only add one instantiation per quantifier per round for mbqi
index e9c754d4a159e9e0aedb6b0a5a9c29d54b117d5d..164e9e6432f5f2039aeff078d0121835309f3afe 100644 (file)
@@ -82,8 +82,8 @@ static const std::string mbqiModeHelp = "\
 Model-based quantifier instantiation modes currently supported by the --mbqi option:\n\
 \n\
 default \n\
-+ Default, use model-based quantifier instantiation algorithm from CADE 24 finite\n\
-  model finding paper.\n\
++ Use algorithm from Section 5.4.2 of thesis Finite Model Finding in Satisfiability \n\
+  Modulo Theories.\n\
 \n\
 none \n\
 + Disable model-based quantifier instantiation.\n\
@@ -91,12 +91,12 @@ none \n\
 instgen \n\
 + Use instantiation algorithm that mimics Inst-Gen calculus. \n\
 \n\
-fmc \n\
-+ Use algorithm from Section 5.4.2 of thesis Finite Model Finding in Satisfiability \n\
-  Modulo Theories.\n\
+gen-ev \n\
++ Default, use model-based quantifier instantiation algorithm from CADE 24 finite\n\
+  model finding paper.\n\
 \n\
 fmc-interval \n\
-+ Same as fmc, but with intervals for models of integer functions.\n\
++ Same as default, but with intervals for models of integer functions.\n\
 \n\
 interval \n\
 + Use algorithm that abstracts domain elements as intervals. \n\
@@ -217,13 +217,13 @@ inline AxiomInstMode stringToAxiomInstMode(std::string option, std::string optar
 }
 
 inline MbqiMode stringToMbqiMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) {
-  if(optarg ==  "default") {
-    return MBQI_DEFAULT;
+  if(optarg ==  "gen-ev") {
+    return MBQI_GEN_EVAL;
   } else if(optarg ==  "none") {
     return MBQI_NONE;
   } else if(optarg ==  "instgen") {
     return MBQI_INST_GEN;
-  } else if(optarg ==  "fmc") {
+  } else if(optarg ==  "default" || optarg ==  "fmc") {
     return MBQI_FMC;
   } else if(optarg ==  "fmc-interval") {
     return MBQI_FMC_INTERVAL;
index ea1231e7a67589ed59e10bd9619389a9aedbdc9d..e6ee8f53b85afe6a82946e30ba26b20a81097c46 100644 (file)
@@ -81,7 +81,7 @@ Node TermDb::getOperator( Node n ) {
     }
     d_par_op_map[op][tn1][tn2] = n;
     return n;
-  }else if( n.getKind()==APPLY_UF ){
+  }else if( inst::Trigger::isAtomicTrigger( n ) ){
     return n.getOperator();
   }else{
     return Node::null();
index 9db32f894320f67a3bddd4ab2e7973b16f662613..57cf9001b4e82dac4b1aaf7db470c6cee84c9779 100644 (file)
@@ -101,7 +101,12 @@ void TheoryUF::check(Effort level) {
     if (atom.getKind() == kind::EQUAL) {
       d_equalityEngine.assertEquality(atom, polarity, fact);
     } else if (atom.getKind() == kind::CARDINALITY_CONSTRAINT || atom.getKind() == kind::COMBINED_CARDINALITY_CONSTRAINT) {
-      // do nothing
+      if( d_thss == NULL ){
+        std::stringstream ss;
+        ss << "Cardinality constraint " << atom << " was asserted, but the logic does not allow it." << std::endl;
+        ss << "Try using a logic containing \"UFC\"." << std::endl;
+        throw Exception( ss.str() );
+      }
     } else {
       d_equalityEngine.assertPredicate(atom, polarity, fact);
     }
index 8d70e4ffc48e9dd8838ad5f8912a8739a573e8bb..4d45d9148cab3608e78f396bc4ded713fb3bd253 100644 (file)
@@ -36,6 +36,7 @@ namespace CVC4 {
 namespace expr {
   namespace attr {
     struct DatatypeIndexTag {};
+    struct DatatypeConsIndexTag {};
     struct DatatypeFiniteTag {};
     struct DatatypeWellFoundedTag {};
     struct DatatypeFiniteComputedTag {};
@@ -45,6 +46,7 @@ namespace expr {
 }/* CVC4::expr namespace */
 
 typedef expr::Attribute<expr::attr::DatatypeIndexTag, uint64_t> DatatypeIndexAttr;
+typedef expr::Attribute<expr::attr::DatatypeConsIndexTag, uint64_t> DatatypeConsIndexAttr;
 typedef expr::Attribute<expr::attr::DatatypeFiniteTag, bool> DatatypeFiniteAttr;
 typedef expr::Attribute<expr::attr::DatatypeWellFoundedTag, bool> DatatypeWellFoundedAttr;
 typedef expr::Attribute<expr::attr::DatatypeFiniteComputedTag, bool> DatatypeFiniteComputedAttr;
@@ -81,6 +83,20 @@ size_t Datatype::indexOf(Expr item) {
   }
 }
 
+size_t Datatype::cindexOf(Expr item) {
+  ExprManagerScope ems(item);
+  CheckArgument(item.getType().isSelector(),
+                item,
+                "arg must be a datatype selector");
+  TNode n = Node::fromExpr(item);
+  if( item.getKind()==kind::APPLY_TYPE_ASCRIPTION ){
+    return cindexOf( item[0] );
+  }else{
+    Assert(n.hasAttribute(DatatypeConsIndexAttr()));
+    return n.getAttribute(DatatypeConsIndexAttr());
+  }
+}
+
 void Datatype::resolve(ExprManager* em,
                        const std::map<std::string, DatatypeType>& resolutions,
                        const std::vector<Type>& placeholders,
@@ -103,7 +119,7 @@ void Datatype::resolve(ExprManager* em,
   d_resolved = true;
   size_t index = 0;
   for(std::vector<DatatypeConstructor>::iterator i = d_constructors.begin(), i_end = d_constructors.end(); i != i_end; ++i) {
-    (*i).resolve(em, self, resolutions, placeholders, replacements, paramTypes, paramReplacements);
+    (*i).resolve(em, self, resolutions, placeholders, replacements, paramTypes, paramReplacements, index);
     Node::fromExpr((*i).d_constructor).setAttribute(DatatypeIndexAttr(), index);
     Node::fromExpr((*i).d_tester).setAttribute(DatatypeIndexAttr(), index++);
   }
@@ -401,7 +417,7 @@ void DatatypeConstructor::resolve(ExprManager* em, DatatypeType self,
                                   const std::vector<Type>& placeholders,
                                   const std::vector<Type>& replacements,
                                   const std::vector< SortConstructorType >& paramTypes,
-                                  const std::vector< DatatypeType >& paramReplacements)
+                                  const std::vector< DatatypeType >& paramReplacements, size_t cindex)
   throw(IllegalArgumentException, DatatypeResolutionException) {
 
   CheckArgument(em != NULL, em, "cannot resolve a Datatype with a NULL expression manager");
@@ -447,6 +463,7 @@ void DatatypeConstructor::resolve(ExprManager* em, DatatypeType self,
       }
       (*i).d_selector = nm->mkSkolem((*i).d_name, nm->mkSelectorType(selfTypeNode, TypeNode::fromType(range)), "is a selector", NodeManager::SKOLEM_EXACT_NAME | NodeManager::SKOLEM_NO_NOTIFY).toExpr();
     }
+    Node::fromExpr((*i).d_selector).setAttribute(DatatypeConsIndexAttr(), cindex);
     Node::fromExpr((*i).d_selector).setAttribute(DatatypeIndexAttr(), index++);
     (*i).d_resolved = true;
   }
index 99a303950d41a8c8589ea9e4ddedc53049cb557d..02e0b6be8636ac3c22f90ef5066d316eee48e95f 100644 (file)
@@ -191,7 +191,7 @@ private:
                const std::vector<Type>& placeholders,
                const std::vector<Type>& replacements,
                const std::vector< SortConstructorType >& paramTypes,
-               const std::vector< DatatypeType >& paramReplacements)
+               const std::vector< DatatypeType >& paramReplacements, size_t cindex)
     throw(IllegalArgumentException, DatatypeResolutionException);
   friend class Datatype;
 
@@ -434,6 +434,12 @@ public:
    */
   static size_t indexOf(Expr item) CVC4_PUBLIC;
 
+  /**
+   * Get the index of constructor corresponding to selector.  (Zero is
+   * always the first index.)
+   */
+  static size_t cindexOf(Expr item) CVC4_PUBLIC;
+
   /** The type for iterators over constructors. */
   typedef DatatypeConstructorIterator iterator;
   /** The (const) type for iterators over constructors. */
index b0c970f37496a8d5cea8fd76d470041ee5a095c3..1c8a0626a0b9ef4f14d64df30846173bb7a958a8 100644 (file)
@@ -1,6 +1,6 @@
 ; COMMAND-LINE: --tlimit-per 2500 -iq
 ; EXPECT: unknown
-; EXPECT: (:reason-unknown timeout)
+; EXPECT: (:reason-unknown incomplete)
 ; EXPECT: unsat
 (set-option :print-success false)
 (set-info :smt-lib-version 2.0)
index 536bc241fd295cb4e204e8abbc7e9bf15f150a69..f62f057e4b6a477f5633c41f5444d5ac0b6f5ec4 100644 (file)
@@ -1,4 +1,4 @@
-% COMMAND-LINE: --finite-model-find
+% COMMAND-LINE: --finite-model-find --mbqi=gen-ev
 % EXPECT: unsat
 (benchmark Isabelle
 :status sat
index b9a87231fbdbe28c6c2eb5df784170d25e2aedd5..395054d673bc558bcd61d7a58a636b0fdfcc0475 100644 (file)
@@ -23,18 +23,23 @@ TESTS =     \
        agree466.smt2 \
        ALG008-1.smt2 \
        german169.smt2 \
-       Hoare-z3.931718.smt \
        QEpres-uf.855035.smt \
        agree467.smt2 \
        Arrow_Order-smtlib.778341.smt \
        german73.smt2 \
        PUZ001+1.smt2 \
        refcount24.cvc.smt2 \
-       bug0909.smt2 \
-       fmf-bound-int.smt2
+       fmf-bound-int.smt2 \
+       fc-simple.smt2 \
+       fc-unsat-tot-2.smt2 \
+       fc-unsat-pent.smt2 \
+       fc-pigeonhole19.smt2
 
 EXTRA_DIST = $(TESTS)
 
+# disabled for now :
+# Hoare-z3.931718.smt bug0909.smt2
+
 #if CVC4_BUILD_PROFILE_COMPETITION
 #else
 #TESTS += \
index 980e5fd49ef540b2bd0bd8e0a16e129417eb4b4e..2945c8f4da9f66378a690e56e413c01baca2c72f 100644 (file)
@@ -1,4 +1,4 @@
-% COMMAND-LINE: --finite-model-find
+% COMMAND-LINE: --finite-model-find --mbqi=gen-ev
 % EXPECT: sat
 (benchmark Isabelle
 :status sat
diff --git a/test/regress/regress0/fmf/fc-pigeonhole19.smt2 b/test/regress/regress0/fmf/fc-pigeonhole19.smt2
new file mode 100755 (executable)
index 0000000..15c3668
--- /dev/null
@@ -0,0 +1,20 @@
+(set-logic UFC)\r
+(set-info :status unsat)\r
+\r
+(declare-sort P 0)\r
+(declare-sort H 0)\r
+\r
+(declare-fun p () P)\r
+(declare-fun h () H)\r
+\r
+; pigeonhole using native cardinality constraints\r
+(assert (fmf.card p 19))\r
+(assert (not (fmf.card p 18)))\r
+(assert (fmf.card h 18))\r
+(assert (not (fmf.card h 17)))\r
+\r
+; each pigeon has different holes\r
+(declare-fun f (P) H)\r
+(assert (forall ((p1 P) (p2 P)) (=> (not (= p1 p2)) (not (= (f p1) (f p2))))))\r
+\r
+(check-sat)
\ No newline at end of file
diff --git a/test/regress/regress0/fmf/fc-simple.smt2 b/test/regress/regress0/fmf/fc-simple.smt2
new file mode 100755 (executable)
index 0000000..d1fd230
--- /dev/null
@@ -0,0 +1,12 @@
+(set-logic QF_UFC)
+(set-info :status unsat)
+
+(declare-sort U 0)
+
+(declare-fun a () U)
+(declare-fun c () U)
+
+(assert (fmf.card c 2))
+(assert (not (fmf.card a 4)))
+
+(check-sat)
diff --git a/test/regress/regress0/fmf/fc-unsat-pent.smt2 b/test/regress/regress0/fmf/fc-unsat-pent.smt2
new file mode 100755 (executable)
index 0000000..f1721cb
--- /dev/null
@@ -0,0 +1,20 @@
+(set-logic QF_UFC)\r
+(set-info :status unsat)\r
+\r
+(declare-sort U 0)\r
+\r
+(declare-fun a () U)\r
+(declare-fun b () U)\r
+(declare-fun c () U)\r
+(declare-fun d () U)\r
+(declare-fun e () U)\r
+\r
+(assert (not (= a b)))\r
+(assert (not (= b c)))\r
+(assert (not (= c d)))\r
+(assert (not (= d e)))\r
+(assert (not (= e a)))\r
+\r
+(assert (fmf.card c 2))\r
+\r
+(check-sat)
\ No newline at end of file
diff --git a/test/regress/regress0/fmf/fc-unsat-tot-2.smt2 b/test/regress/regress0/fmf/fc-unsat-tot-2.smt2
new file mode 100755 (executable)
index 0000000..d946974
--- /dev/null
@@ -0,0 +1,14 @@
+(set-logic UFC)\r
+(set-info :status unsat)\r
+\r
+(declare-sort U 0)\r
+\r
+(declare-fun a () U)\r
+(declare-fun b () U)\r
+(declare-fun c () U)\r
+\r
+(assert (not (fmf.card a 2)))\r
+\r
+(assert (forall ((x U)) (or (= x a) (= x b))))\r
+\r
+(check-sat)
\ No newline at end of file
index 0d5aedbb3b220f1ecf605d4fed4beb4e673478c4..2e50030d1a5b7a15dd42045dc5c1082645e8f27d 100644 (file)
@@ -1,3 +1,5 @@
+; COMMAND-LINE: --full-saturate-quant
+; EXPECT: unsat
 (set-logic LRA)
 (set-info :status unsat)
 (declare-fun x4 () Real)
index ad970a2b299852bc5c14bcedc7ee4829a2fec6a9..3424c161ec8865e25e2f646461a8f8fdc0e2521c 100644 (file)
@@ -1,3 +1,5 @@
+; COMMAND-LINE: --full-saturate-quant --decision=internal
+; EXPECT: unsat
 (set-logic AUFLIA)
 (set-info :source | Burns mutual exclusion protocol. This is a benchmark of the haRVey theorem prover. It was translated to SMT-LIB by Leonardo  de Moura |)
 (set-info :smt-lib-version 2.0)
index 3a3a097bda94f14871424f3a20b947ac0651fd12..31f99905c8612bd7c0dd498f565f18216e33b49f 100644 (file)
@@ -23,16 +23,16 @@ MAKEFLAGS = -k
 # put it below in "TESTS +="
 TESTS =        \
        length_trick.smt2 \
-       length_trick2.smt2 \
        length_gen_020.smt2 \
        datatypes.smt2 \
        datatypes_sat.smt2 \
        reachability_back_to_the_future.smt2 \
        relation.smt2 \
        simulate_rewriting.smt2 \
-       native_arrays.smt2
+       native_arrays.smt2 \
+       read5.smt2
 
-# reachability_bbttf_eT_arrays.smt2 set_A_new_fast_tableau-base.smt2 set_A_new_fast_tableau-base_sat.smt2
+# length_trick2.smt2 reachability_bbttf_eT_arrays.smt2 set_A_new_fast_tableau-base.smt2 set_A_new_fast_tableau-base_sat.smt2
 
 EXTRA_DIST = $(TESTS)
 
diff --git a/test/regress/regress0/rewriterules/read5.smt2 b/test/regress/regress0/rewriterules/read5.smt2
new file mode 100755 (executable)
index 0000000..e66df7c
--- /dev/null
@@ -0,0 +1,35 @@
+(set-logic AUF)
+(set-info :source |
+Translated from old SVC processor verification benchmarks.  Contact Clark
+Barrett at barrett@cs.nyu.edu for more information.
+
+This benchmark was automatically translated into SMT-LIB format from
+CVC format using CVC Lite
+|)
+(set-info :smt-lib-version 2.0)
+(set-info :category "crafted")
+(set-info :status unsat)
+(declare-sort Index 0)
+(declare-sort Element 0)(declare-sort Arr 0)(declare-fun aselect (Arr Index) Element)(declare-fun astore (Arr Index Element) Arr)(declare-fun k (Arr Arr) Index)
+(declare-fun a () Index)
+(declare-fun aaa () Index)
+(declare-fun aa () Index)
+(declare-fun S () Arr)
+(declare-fun vvv () Element)
+(declare-fun v () Element)
+(declare-fun vv () Element)
+(declare-fun bbb () Index)
+(declare-fun www () Element)
+(declare-fun bb () Index)
+(declare-fun ww () Element)
+(declare-fun b () Index)
+(declare-fun w () Element)
+(declare-fun SS () Arr)
+(assert (let ((?v_3 (ite (= a aa) false true)) (?v_4 (ite (= aa aaa) false true)) (?v_1 (astore (astore (astore S a v) aa vv) aaa vvv)) (?v_0 (astore S aaa vvv)) (?v_2 (astore S aa vv))) (not (ite (ite (ite (ite (= a aaa) false true) (ite ?v_3 ?v_4 false) false) (ite (= (astore (astore ?v_0 a v) aa vv) ?v_1) (ite (= (astore (astore ?v_0 aa vv) a v) ?v_1) (ite (= (astore (astore ?v_2 a v) aaa vvv) ?v_1) (= (astore (astore ?v_2 aaa vvv) a v) ?v_1) false) false) false) true) (ite (ite (= ?v_1 (astore (astore (astore S bbb www) bb ww) b w)) (ite (ite ?v_3 (ite ?v_4 (ite (ite (= aa b) false true) (ite (ite (= aa bb) false true) (ite (= aa bbb) false true) false) false) false) false) (= (aselect S aa) vv) true) true) (ite (= S (astore SS a v)) (= S (astore SS a (aselect S a))) true) false) false))))
+; rewrite rule definition of arrays theory
+(assert (forall ((?x Arr) (?i Index) (?j Index) (?e Element)) (! (=> (not (= ?i ?j)) (= (aselect (astore ?x ?i ?e) ?j) (aselect ?x ?j))) :rewrite-rule)))
+(assert (forall ((?x Arr) (?i Index) (?e Element)) (! (=> true (= (aselect (astore ?x ?i ?e) ?i) ?e)) :rewrite-rule)))
+(assert (forall ((?x Arr) (?y Arr)) (! (=> (not (= ?x ?y)) (not (= (aselect ?x (k ?x ?y)) (aselect ?y (k ?x ?y))))) :rewrite-rule)))
+(assert (forall ((?x Arr) (?y Arr)) (! (! (=> true (or (= ?x ?y) (not (= ?x ?y)))) :pattern (?x)) :rewrite-rule)))
+(assert (forall ((?x Arr) (?i Index) (?j Index) (?e Element)) (! (! (=> true (or (= ?i ?j) (not (= ?i ?j)))) :pattern ((aselect (astore ?x ?i ?e) ?j))) :rewrite-rule)))(check-sat)
+(exit)
index e0c8a2b48c2fc7f6e522b69423afc50a8eb25cd2..e9274d2ee216aa86f20b5e211ebeb4a7c30b28a0 100644 (file)
@@ -35,7 +35,6 @@ TESTS =       \
        tff0.p \
        tff0-arith.p \
        ARI086$(equals)1.p \
-       BOO003-4.p \
        DAT001$(equals)1.p \
        KRS018+1.p \
        KRS063+1.p \
@@ -62,6 +61,7 @@ TEST_DEPS_DIST = \
 EXTRA_DIST = $(TESTS) \
        $(TEST_DEPS_DIST) \
        BOO027-1.p \
+       BOO003-4.p \
        MGT031-1.p \
        NLP114-1.p \
        SYN075+1.p