* Node::isAtomic() now looks at an "atomic" attribute of arguments
authorMorgan Deters <mdeters@gmail.com>
Sun, 4 Apr 2010 19:55:47 +0000 (19:55 +0000)
committerMorgan Deters <mdeters@gmail.com>
Sun, 4 Apr 2010 19:55:47 +0000 (19:55 +0000)
  instead of assuming it's atomic based on kind.  Atomicity is
  determined at node building time.  Fixes bug #81.  If this is
  determined to make node building too slow, we can allocate another
  attribute "AtomicHasBeenComputed" to lazily compute atomicity.

* TheoryImpl<> has gone away.  Theory implementations now derive from
  Theory directly and share a single RegisteredAttr attribute for term
  registration (which shouldn't overlap: every term is "owned" by
  exactly one Theory).  Fixes bug #79.

* Additional atomicity tests in ExprBlack unit test.

* More appropriate whitebox testing for attribute ID assignment
  (AttributeWhite unit test).

* Better (and more correct) assertion checking in NodeBuilderBlack.

* run-regression script now checks exit status against what's provided
  in "% EXIT: " gesture in .cvc input files, and stderr against
  "% EXPECT-ERROR: ".  These can be used to support intended failures.
  Fixes bug #84.  Also add "% EXIT: " gestures to all .cvc regressions
  in repository.

* Solved some "control reaches end of non-void function" warnings in
  src/parser/bounded_token_buffer.cpp by replacing
  "AlwaysAssert(false)" with "Unreachable()" (which is known
  statically to never return normally).

* Regression tests now use the cvc4 binary under
  builds/$(CURRENT_BUILD)/src/main instead of the one in bin/ which
  may not be properly installed yet at that point of the build.
  (Partially fixes bug #46.)

* -fvisibility=hidden is now included by configure.ac instead of each
   Makefile.am, which will make it easier to support platforms
   (e.g. cygwin) that do things a different way.

* TheoryUF code formatting.  (re: my code review bug #64)

* CDMap<> is leaking memory again, pending a fix for bug #85 in the
  context subsystem.  (To avoid serious errors, can't free context
  objects.)

* add ContextWhite unit test for bug #85 (though it's currently
  "defanged," awaiting the bugfix)

* Minor documentation, other cleanup.

113 files changed:
config/antlr.m4
configure.ac
src/Makefile.am
src/context/Makefile.am
src/context/cdmap.h
src/context/context.h
src/expr/Makefile.am
src/expr/metakind_template.h
src/expr/mkexpr
src/expr/mkmetakind
src/expr/node.h
src/expr/node_manager.h
src/main/main.cpp
src/parser/Makefile.am
src/parser/bounded_token_buffer.cpp
src/parser/cvc/Makefile.am
src/parser/smt/Makefile.am
src/prop/Makefile.am
src/prop/minisat/Makefile.am
src/smt/Makefile.am
src/theory/Makefile.am
src/theory/arith/Makefile.am
src/theory/arith/theory_arith.h
src/theory/arrays/Makefile.am
src/theory/arrays/theory_arrays.h
src/theory/booleans/Makefile.am
src/theory/booleans/theory_bool.h
src/theory/bv/Makefile.am
src/theory/bv/theory_bv.h
src/theory/theory.cpp
src/theory/theory.h
src/theory/uf/Makefile.am
src/theory/uf/theory_uf.cpp
src/theory/uf/theory_uf.h
src/util/Assert.cpp
src/util/Makefile.am
src/util/configuration.cpp
test/regress/regress0/Makefile.am
test/regress/regress0/boolean-prec.cvc
test/regress/regress0/boolean.cvc
test/regress/regress0/bug1.cvc
test/regress/regress0/bug32.cvc
test/regress/regress0/error.cvc [new file with mode: 0644]
test/regress/regress0/hole6.cvc
test/regress/regress0/logops.01.cvc
test/regress/regress0/logops.02.cvc
test/regress/regress0/logops.03.cvc
test/regress/regress0/logops.04.cvc
test/regress/regress0/logops.05.cvc
test/regress/regress0/precedence/Makefile.am
test/regress/regress0/precedence/and-not.cvc
test/regress/regress0/precedence/and-xor.cvc
test/regress/regress0/precedence/eq-fun.cvc
test/regress/regress0/precedence/iff-assoc.cvc
test/regress/regress0/precedence/iff-implies.cvc
test/regress/regress0/precedence/implies-assoc.cvc
test/regress/regress0/precedence/implies-iff.cvc
test/regress/regress0/precedence/implies-or.cvc
test/regress/regress0/precedence/not-and.cvc
test/regress/regress0/precedence/not-eq.cvc
test/regress/regress0/precedence/or-implies.cvc
test/regress/regress0/precedence/or-xor.cvc
test/regress/regress0/precedence/xor-and.cvc
test/regress/regress0/precedence/xor-assoc.cvc
test/regress/regress0/precedence/xor-or.cvc
test/regress/regress0/queries0.cvc
test/regress/regress0/simple.cvc
test/regress/regress0/smallcnf.cvc
test/regress/regress0/test11.cvc
test/regress/regress0/test12.cvc
test/regress/regress0/test9.cvc
test/regress/regress0/uf/Makefile.am
test/regress/regress0/uf/simple.01.cvc
test/regress/regress0/uf/simple.02.cvc
test/regress/regress0/uf/simple.03.cvc
test/regress/regress0/uf/simple.04.cvc
test/regress/regress0/uf20-03.cvc
test/regress/regress0/wiki.01.cvc
test/regress/regress0/wiki.02.cvc
test/regress/regress0/wiki.03.cvc
test/regress/regress0/wiki.04.cvc
test/regress/regress0/wiki.05.cvc
test/regress/regress0/wiki.06.cvc
test/regress/regress0/wiki.07.cvc
test/regress/regress0/wiki.08.cvc
test/regress/regress0/wiki.09.cvc
test/regress/regress0/wiki.10.cvc
test/regress/regress0/wiki.11.cvc
test/regress/regress0/wiki.12.cvc
test/regress/regress0/wiki.13.cvc
test/regress/regress0/wiki.14.cvc
test/regress/regress0/wiki.15.cvc
test/regress/regress0/wiki.16.cvc
test/regress/regress0/wiki.17.cvc
test/regress/regress0/wiki.18.cvc
test/regress/regress0/wiki.19.cvc
test/regress/regress0/wiki.20.cvc
test/regress/regress0/wiki.21.cvc
test/regress/regress1/Makefile.am
test/regress/regress1/hole7.cvc
test/regress/regress1/hole8.cvc
test/regress/regress2/Makefile.am
test/regress/regress2/hole9.cvc
test/regress/regress3/Makefile.am
test/regress/regress3/hole10.cvc
test/regress/run_regression
test/unit/Makefile.am
test/unit/context/cdmap_black.h
test/unit/context/context_white.h [new file with mode: 0644]
test/unit/expr/attribute_white.h
test/unit/expr/expr_black.h
test/unit/expr/node_builder_black.h
test/unit/theory/theory_black.h

index 64b554378aae2a72d010ffd1defddd3808b11b27..604d2f6bceeada608b409dbd0645a56397208f62 100644 (file)
@@ -26,10 +26,11 @@ AC_DEFUN([AC_PROG_ANTLR], [
 
 ##
 # Check the existence of the ANTLR3 C runtime library and headers
-# Will set ANTLR_INCLUDES and ANTLR_LIBS to the location of the ANTLR headers
-# and library respectively
+# Will set ANTLR_INCLUDES and ANTLR_LIBS to the location of the ANTLR
+# headers and library respectively
 ##
 AC_DEFUN([AC_LIB_ANTLR],[
+  AC_ARG_VAR(ANTLR_HOME, [path to libantlr3c installation])
 
   # Get the location of the ANTLR3 C includes and libraries
   AC_ARG_WITH(
index a80d1fee9c7a3b4bc6953c0a521959dcdf8c2217..7007ba47fc6426d728b5bbcd1c726e8363f3cdfa 100644 (file)
@@ -480,6 +480,9 @@ CXXFLAGS="${CXXFLAGS:+$CXXFLAGS }$CVC4CXXFLAGS -Wno-deprecated"
 CFLAGS="${CFLAGS:+$CFLAGS }$CVC4CFLAGS -Wno-deprecated"
 LDFLAGS="${LDFLAGS:+$LDFLAGS }$CVC4LDFLAGS"
 
+FLAG_VISIBILITY_HIDDEN='-fvisibility=hidden'
+AC_SUBST(FLAG_VISIBILITY_HIDDEN)
+
 # mk_include
 #
 # When automake scans Makefiles, it complains about non-standard make
index 17c8671635d88c7b941b5fc881952f9ee167d63e..593499c9b015599eb1d9355f04ca279edf690857 100644 (file)
@@ -15,7 +15,7 @@ LIBCVC4_VERSION = @CVC4_LIBRARY_VERSION@
 AM_CPPFLAGS =
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/include -I@srcdir@
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 SUBDIRS = expr util context theory prop smt . parser main
 
index 54accdd6e687a5c19674a93dd8e1df0d78b703da..85847e096e92d533081cdcf8c832da74a94ff8e2 100644 (file)
@@ -1,7 +1,7 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/../include -I@srcdir@/..
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 noinst_LTLIBRARIES = libcontext.la
 
index e9ae8337e8aafe4006583d1bdd8f2cc9b92ec960..d4de88daf24d45f50213d572398a9d65f2f767e0 100644 (file)
@@ -191,7 +191,8 @@ class CDMap : public ContextObj {
     for(typename std::vector<Element*>::iterator i = d_trash.begin();
         i != d_trash.end();
         ++i) {
-      (*i)->deleteSelf();
+      Debug("gc") << "emptyTrash(): " << *i << std::endl;
+      //(*i)->deleteSelf();
     }
     d_trash.clear();
   }
index 455169a62bb288b1fad7403ba56ad9b5c6b08041..0e2a9107fbb18cfba7ae42a3a6885d4a006d3384 100644 (file)
@@ -208,12 +208,12 @@ public:
   /**
    * Get the level of the current Scope
    */
-  int getLevel(void) const { return d_level; }
+  int getLevel() const { return d_level; }
 
   /**
    * Return true iff this Scope is the current top Scope
    */
-  bool isCurrent(void) const { return this == d_pContext->getTopScope(); }
+  bool isCurrent() const { return this == d_pContext->getTopScope(); }
 
   /**
    * When a ContextObj object is modified for the first time in this Scope, it
@@ -240,7 +240,7 @@ public:
   static void operator delete(void* pMem) {}
 
   //FIXME:  //! Check for memory leaks
-  //  void check(void);
+  //  void check();
 
 };/* class Scope */
 
index 76f6ef1a4652e791af3cdf9ca2dcd4de9142689d..1f5e403cc9c5baf338799e9df0b6704a0a282a7a 100644 (file)
@@ -1,7 +1,7 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/../include -I@srcdir@/..
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 noinst_LTLIBRARIES = libexpr.la
 
index 052458cbeaed2bf04887758a6a63fabd7c4476ad..96152d075da3668883be9490a940429348e3405d 100644 (file)
@@ -113,6 +113,9 @@ enum MetaKind_t {
 // individual MetaKind constants under kind::metakind::
 typedef ::CVC4::kind::metakind::MetaKind_t MetaKind;
 
+/**
+ * Get the metakind for a particular kind.
+ */
 static inline MetaKind metaKindOf(Kind k) {
   static const MetaKind metaKinds[] = {
     metakind::INVALID, /* NULL_EXPR */
@@ -123,15 +126,20 @@ ${metakind_kinds}
   return metaKinds[k];
 }/* metaKindOf(k) */
 
-static inline bool kindIsAtomic(Kind k) {
-  static const bool isAtomic[] = {
+/**
+ * Determine if a particular kind can be atomic or not.  Some kinds
+ * are never atomic (OR, NOT, ITE...), some can be atomic depending on
+ * their children (PLUS might have an ITE under it, for instance).
+ */
+static inline bool kindCanBeAtomic(Kind k) {
+  static const bool canBeAtomic[] = {
     false, /* NULL_EXPR */
-${metakind_isatomic}
+${metakind_canbeatomic}
     false /* LAST_KIND */
-  };/* isAtomic[] */
+  };/* canBeAtomic[] */
 
-  return isAtomic[k];
-}/* kindIsAtomic(k) */
+  return canBeAtomic[k];
+}/* kindCanBeAtomic(k) */
 
 }/* CVC4::kind namespace */
 
index 6508f81218f84f20fb465654d80af033b5bc2d16..f59388def1eb066af30606424ee81743305fb728 100755 (executable)
@@ -32,6 +32,23 @@ cat <<EOF
  ** for the CVC4 project.
  **/
 
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */
+
+/* Edit the template file instead:                     */
+/* $1 */
+
 EOF
 
 me=$(basename "$0")
index 3884f636a62ff247545730be340ae98cd0736f6e..b8dbc2dd6d0f8b629e2dc8d8c4b2db7826b82955 100755 (executable)
@@ -200,11 +200,11 @@ function register_metakind {
   nc=$3
 
   if [ $mk = NONATOMIC_OPERATOR ]; then
-    metakind_isatomic="${metakind_isatomic}    false, /* $k */
+    metakind_canbeatomic="${metakind_canbeatomic}    false, /* $k */
 ";
     mk=OPERATOR
   else
-    metakind_isatomic="${metakind_isatomic}    true, /* $k */
+    metakind_canbeatomic="${metakind_canbeatomic}    true, /* $k */
 ";
   fi
 
@@ -278,7 +278,7 @@ while [ $# -gt 0 ]; do
   metakind_kinds="${metakind_kinds}
     /* from $b */
 "
-  metakind_isatomic="${metakind_isatomic}
+  metakind_canbeatomic="${metakind_canbeatomic}
     /* from $b */
 "
   source "$kf"
@@ -293,7 +293,7 @@ text=$(cat "$template")
 for var in \
     metakind_includes \
     metakind_kinds \
-    metakind_isatomic \
+    metakind_canbeatomic \
     metakind_constantMaps \
     metakind_compares \
     metakind_constHashes \
index 6f6fdfb4d959d946428830c3f8e252cc5ae3e1a5..3a2aca571ce2f85417b18d0915315e9d0b7b8346 100644 (file)
@@ -587,8 +587,8 @@ template <bool ref_count>
 NodeTemplate<ref_count> NodeTemplate<ref_count>::s_null(&expr::NodeValue::s_null);
 
 template <bool ref_count>
-bool NodeTemplate<ref_count>::isAtomic() const {
-  return kind::kindIsAtomic(getKind());
+inline bool NodeTemplate<ref_count>::isAtomic() const {
+  return NodeManager::currentNM()->isAtomic(*this);
 }
 
 // FIXME: escape from type system convenient but is there a better
index 99b1471f900d0833bbca755c801dfbd4ea846ef0..71242f2e17cbabb58b49eaf8b8198b4c342d9b37 100644 (file)
 
 namespace CVC4 {
 
-class Type;
-
 namespace expr {
-namespace attr {
-
-struct VarName {};
-struct Type {};
 
+// Definition of an attribute for the variable name.
+// TODO: hide this attribute behind a NodeManager interface.
+namespace attr {
+  struct VarNameTag {};
 }/* CVC4::expr::attr namespace */
 
-typedef Attribute<attr::VarName, std::string> VarNameAttr;
-typedef ManagedAttribute<attr::Type, CVC4::Type*, attr::TypeCleanupStrategy> TypeAttr;
+typedef expr::Attribute<attr::VarNameTag, std::string> VarNameAttr;
 
 }/* CVC4::expr namespace */
 
@@ -125,6 +122,44 @@ class NodeManager {
     expr::NodeValue* child[N];
   };/* struct NodeManager::NVStorage<N> */
 
+  // attribute tags
+  struct TypeTag {};
+  struct AtomicTag {};
+
+  // NodeManager's attributes.  These aren't exposed outside of this
+  // class; use the getters.
+  typedef expr::ManagedAttribute<TypeTag,
+                                 CVC4::Type*,
+                                 expr::attr::TypeCleanupStrategy> TypeAttr;
+  typedef expr::Attribute<AtomicTag, bool> AtomicAttr;
+
+  /**
+   * Returns true if this node is atomic (has no more Boolean
+   * structure).  This is the NodeValue version for NodeManager's
+   * internal use.  There's a public version of this function below
+   * that takes a TNode.
+   * @param nv the node to check for atomicity
+   * @return true if atomic
+   */
+  inline bool isAtomic(expr::NodeValue* nv) const {
+    // The kindCanBeAtomic() and metakind checking are just optimizations
+    // (to avoid the hashtable lookup).  We assume that all nodes have
+    // the atomic attribute pre-computed and set at their time of
+    // creation.  This is because:
+    // (1) it's super cheap to do it bottom-up.
+    // (2) if we computed it lazily, we'd need a second attribute to
+    //     tell us whether we had computed it yet or not.
+    // The pre-computation and registration occurs in poolInsert().
+    AssertArgument(nv->getMetaKind() != kind::metakind::INVALID, *nv,
+                   "NodeManager::isAtomic() called on INVALID node (%s)",
+                   kind::kindToString(nv->getKind()).c_str());
+    return
+      nv->getMetaKind() == kind::metakind::VARIABLE ||
+      nv->getMetaKind() == kind::metakind::CONSTANT ||
+      ( kind::kindCanBeAtomic(nv->getKind()) &&
+        getAttribute(nv, AtomicAttr()) );
+  }
+
 public:
 
   NodeManager(context::Context* ctxt);
@@ -324,6 +359,15 @@ public:
    * TODO: Does this call compute the type if it's not already available?
    */
   inline Type* getType(TNode n) const;
+
+  /**
+   * Returns true if this node is atomic (has no more Boolean structure)
+   * @param n the node to check for atomicity
+   * @return true if atomic
+   */
+  inline bool isAtomic(TNode n) const {
+    return isAtomic(n.d_nv);
+  }
 };
 
 /**
@@ -476,7 +520,7 @@ inline Type* NodeManager::mkSort(const std::string& name) const {
 }
 
 inline Type* NodeManager::getType(TNode n) const {
-  return getAttribute(n, CVC4::expr::TypeAttr());
+  return getAttribute(n, TypeAttr());
 }
 
 inline expr::NodeValue* NodeManager::poolLookup(expr::NodeValue* nv) const {
@@ -492,6 +536,39 @@ inline void NodeManager::poolInsert(expr::NodeValue* nv) {
   Assert(d_nodeValuePool.find(nv) == d_nodeValuePool.end(),
          "NodeValue already in the pool!");
   d_nodeValuePool.insert(nv);// FIXME multithreading
+
+  switch(nv->getMetaKind()) {
+  case kind::metakind::INVALID:
+  case kind::metakind::VARIABLE:
+  case kind::metakind::CONSTANT:
+    // nothing to do (don't bother setting the attribute, isAtomic()
+    // on VARIABLEs and CONSTANTs is always true)
+    break;
+
+  case kind::metakind::OPERATOR:
+  case kind::metakind::PARAMETERIZED:
+    {
+      // register this NodeValue as atomic or not; use nv_begin/end
+      // because we need to consider the operator too in the case of
+      // PARAMETERIZED-metakinded nodes (i.e. APPLYs); they could have a
+      // buried ITE.
+
+      // assume it's atomic if its kind can be atomic, check children
+      // to see if that is actually true
+      bool atomic = kind::kindCanBeAtomic(nv->getKind());
+      if(atomic) {
+        for(expr::NodeValue::nv_iterator i = nv->nv_begin();
+            i != nv->nv_end();
+            ++i) {
+          if(!(atomic = isAtomic(*i))) {
+            break;
+          }
+        }
+      }
+
+      setAttribute(nv, AtomicAttr(), atomic);
+    }
+  }
 }
 
 inline void NodeManager::poolRemove(expr::NodeValue* nv) {
@@ -569,7 +646,7 @@ inline Node NodeManager::mkVar(Type* type, const std::string& name) {
 inline Node NodeManager::mkVar(Type* type) {
   Node n = mkVar();
   type->inc();// reference-count the type
-  n.setAttribute(expr::TypeAttr(), type);
+  n.setAttribute(TypeAttr(), type);
   return n;
 }
 
index b101036356dfaa91eb9f0f1a958782c52721aa9d..819f7695e87770aaef5ecb297e7a8784d95c934a 100644 (file)
@@ -58,25 +58,25 @@ int main(int argc, char* argv[]) {
     }
     cerr << "CVC4 Error:" << endl << e << endl;
     printf(usage, options.binary_name.c_str());
-    abort();
+    exit(1);
   } catch(Exception& e) {
     if(options.smtcomp_mode) {
       cout << "unknown" << endl;
     }
     cerr << "CVC4 Error:" << endl << e << endl;
-    abort();
+    exit(1);
   } catch(bad_alloc) {
     if(options.smtcomp_mode) {
       cout << "unknown" << endl;
     }
     cerr << "CVC4 ran out of memory." << endl;
-    abort();
+    exit(1);
   } catch(...) {
     if(options.smtcomp_mode) {
       cout << "unknown" << endl;
     }
     cerr << "CVC4 threw an exception of unknown type." << endl;
-    abort();
+    exit(1);
   }
 }
 
index 1aaf7ab691082f09aaf4a148700478887bbee798..dad8059f55d1345bf060785156974b38e9be18fc 100644 (file)
@@ -15,7 +15,7 @@ LIBCVC4PARSER_VERSION = @CVC4_PARSER_LIBRARY_VERSION@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4PARSERLIB \
        -I@srcdir@/../include -I@srcdir@/.. $(ANTLR_INCLUDES)
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 SUBDIRS = smt cvc
 
index 1418e8f3cca81ff8be272fcc2da7297cba96402d..29006b3438669ad0299dd01f48ac0e10033ed490 100644 (file)
@@ -281,13 +281,13 @@ dbgTokLT  (pANTLR3_TOKEN_STREAM ts, ANTLR3_INT32 k)
 static pANTLR3_COMMON_TOKEN
 LB(pANTLR3_COMMON_TOKEN_STREAM cts, ANTLR3_INT32 k)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 static pANTLR3_COMMON_TOKEN 
 get (pANTLR3_TOKEN_STREAM ts, ANTLR3_UINT32 i)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 static pANTLR3_TOKEN_SOURCE 
@@ -306,19 +306,19 @@ setTokenSource    (   pANTLR3_TOKEN_STREAM ts,
 static pANTLR3_STRING      
 toString    (pANTLR3_TOKEN_STREAM ts)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 static pANTLR3_STRING
 toStringSS(pANTLR3_TOKEN_STREAM ts, ANTLR3_UINT32 start, ANTLR3_UINT32 stop)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 static pANTLR3_STRING      
 toStringTT  (pANTLR3_TOKEN_STREAM ts, pANTLR3_COMMON_TOKEN start, pANTLR3_COMMON_TOKEN stop)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 /** Move the input pointer to the next incoming token.  The stream
@@ -395,13 +395,13 @@ discardOffChannel   (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_BOOLEAN dis
 static pANTLR3_VECTOR      
 getTokens   (pANTLR3_COMMON_TOKEN_STREAM tokenStream)
 {
-    AlwaysAssert(false);
+    Unreachable();
 }
 
 static pANTLR3_LIST        
 getTokenRange  (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }                                                   
 /** Given a start and stop index, return a List of all tokens in
  *  the token type BitSet.  Return null if no tokens were found.  This
@@ -410,19 +410,19 @@ getTokenRange     (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANT
 static pANTLR3_LIST        
 getTokensSet   (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, pANTLR3_BITSET types)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 static pANTLR3_LIST        
 getTokensList  (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, pANTLR3_LIST list)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 static pANTLR3_LIST        
 getTokensType  (pANTLR3_COMMON_TOKEN_STREAM tokenStream, ANTLR3_UINT32 start, ANTLR3_UINT32 stop, ANTLR3_UINT32 type)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 static ANTLR3_UINT32       
@@ -450,13 +450,13 @@ _LA  (pANTLR3_INT_STREAM is, ANTLR3_INT32 i)
 static ANTLR3_UINT32       
 dbgLA  (pANTLR3_INT_STREAM is, ANTLR3_INT32 i)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 static ANTLR3_MARKER
 mark   (pANTLR3_INT_STREAM is)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 /// As per mark() but with a call to tell the debugger we are doing this
@@ -464,7 +464,7 @@ mark        (pANTLR3_INT_STREAM is)
 static ANTLR3_MARKER
 dbgMark        (pANTLR3_INT_STREAM is)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 static void                
@@ -476,7 +476,7 @@ release     (pANTLR3_INT_STREAM is, ANTLR3_MARKER mark)
 static ANTLR3_UINT32       
 size   (pANTLR3_INT_STREAM is)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 static ANTLR3_MARKER   
@@ -496,33 +496,33 @@ tindex    (pANTLR3_INT_STREAM is)
 static void                
 dbgRewindLast  (pANTLR3_INT_STREAM is)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 static void                
 rewindLast     (pANTLR3_INT_STREAM is)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 static void                
 rewindStream   (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 static void                
 dbgRewindStream        (pANTLR3_INT_STREAM is, ANTLR3_MARKER marker)
 {
-   AlwaysAssert(false);
+   Unreachable();
 }
 
 static void                
 seek   (pANTLR3_INT_STREAM is, ANTLR3_MARKER index)
 {
-    AlwaysAssert(false);
+    Unreachable();
 }
 static void                
 dbgSeek        (pANTLR3_INT_STREAM is, ANTLR3_MARKER index)
 {
-  AlwaysAssert(false);
+  Unreachable();
 }
 
 static pANTLR3_COMMON_TOKEN nextToken(pBOUNDED_TOKEN_BUFFER buffer) {
index ade8d83e7fbe74cec7747d67e4d0310d20dbd0c2..08e6c4d5228906d5c93306603734909411d30530 100644 (file)
@@ -1,7 +1,7 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4PARSERLIB \
        -I@srcdir@/../../include -I@srcdir@/../.. $(ANTLR_INCLUDES)
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 # Compile generated C files using C++ compiler
 CC=$(CXX)
index f081f493fe0f56d72095eec11b68740d5d995a44..3ffe61b05083494e816092c5d68de5e3a28d094b 100644 (file)
@@ -1,7 +1,7 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4PARSERLIB \
        -I@srcdir@/../../include -I@srcdir@/../.. $(ANTLR_INCLUDES)
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 # Compile generated C files using C++ compiler
 AM_CFLAGS = $(AM_CXXFLAGS)
index fc0697edaf5add08f4744a49836e2c952e8a5b8e..357818b329ae7ce5d7c8c2c86541abb34929e459 100644 (file)
@@ -1,7 +1,7 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/../include -I@srcdir@/..
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 noinst_LTLIBRARIES = libprop.la
 
index 366cc34c8c565467b07abc6a54ef22b10e17a073..d68237d9be4be9a6d4e8a7bfa1671af38b7e1394 100644 (file)
@@ -1,7 +1,7 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/mtl -I@srcdir@/core -I@srcdir@/../.. -I@srcdir@/../../include
-AM_CXXFLAGS = -Wall -fvisibility=hidden -DNDEBUG
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN) -DNDEBUG
 
 noinst_LTLIBRARIES = libminisat.la
 libminisat_la_SOURCES = \
index a2da2c94902a64d1e49f3da41ef26c8bceb8aea6..889385d77c0e7b273b0e9953b525c220db0a2153 100644 (file)
@@ -1,7 +1,7 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/../include -I@srcdir@/..
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 noinst_LTLIBRARIES = libsmt.la
 
index 2891e64cf1980ba3b2716413fe2edfcaac613f7f..6b1854bfcb1a411c853de6568212b57a1052e99e 100644 (file)
@@ -1,7 +1,7 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/../include -I@srcdir@/..
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 noinst_LTLIBRARIES = libtheory.la
 
index 226d5af122d33b37411f6dca94a8421f4ad3b736..cb838f497e3a4e85a1ddb5ad37dd0b45a5301a7f 100644 (file)
@@ -1,12 +1,11 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/../../include -I@srcdir@/../..
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 noinst_LTLIBRARIES = libarith.la
 
 libarith_la_SOURCES = \
-       theory_def.h \
        theory_arith.h
 
 EXTRA_DIST = kinds
index 973651f7a224dd1fc3a0ac5493f38d93d813521f..d211cd37d51cbd66c11e7b3d1cfb7298221909eb 100644 (file)
@@ -25,10 +25,10 @@ namespace CVC4 {
 namespace theory {
 namespace arith {
 
-class TheoryArith : public TheoryImpl<TheoryArith> {
+class TheoryArith : public Theory {
 public:
   TheoryArith(context::Context* c, OutputChannel& out) :
-    TheoryImpl<TheoryArith>(c, out) {
+    Theory(c, out) {
   }
 
   void preRegisterTerm(TNode n) { Unimplemented(); }
index af3a28b3bfaf306577705af529be85c80d29d5e2..5d3514ddac76b73e6e009f950be5bb51dd918195 100644 (file)
@@ -1,12 +1,11 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/../../include -I@srcdir@/../..
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 noinst_LTLIBRARIES = libarrays.la
 
 libarrays_la_SOURCES = \
-       theory_def.h \
        theory_arrays.h
 
 EXTRA_DIST = kinds
index ec3b88ccdf0605db5494bc577c3460673de88d93..2f62aacd786ceda5442997f0b9643d1791220206 100644 (file)
@@ -25,10 +25,10 @@ namespace CVC4 {
 namespace theory {
 namespace arrays {
 
-class TheoryArrays : public TheoryImpl<TheoryArrays> {
+class TheoryArrays : public Theory {
 public:
   TheoryArrays(context::Context* c, OutputChannel& out) :
-    TheoryImpl<TheoryArrays>(c, out) {
+    Theory(c, out) {
   }
 
   void preRegisterTerm(TNode n) { Unimplemented(); }
index cbdf13add7f2ccd6cb0faaa962591f7690875482..69029963041daec8c6e72b34455b6a7703078f17 100644 (file)
@@ -1,12 +1,11 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/../../include -I@srcdir@/../..
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 noinst_LTLIBRARIES = libbooleans.la
 
 libbooleans_la_SOURCES = \
-       theory_def.h \
        theory_bool.h
 
 EXTRA_DIST = kinds
index 5196bb018c0041402b556cf46fcfaff28b91ae65..eb6e84c390f7bae07e7bf904f7d06a8b26b4756a 100644 (file)
@@ -25,10 +25,10 @@ namespace CVC4 {
 namespace theory {
 namespace booleans {
 
-class TheoryBool : public TheoryImpl<TheoryBool> {
+class TheoryBool : public Theory {
 public:
   TheoryBool(context::Context* c, OutputChannel& out) :
-    TheoryImpl<TheoryBool>(c, out) {
+    Theory(c, out) {
   }
 
   void preRegisterTerm(TNode n) { Unimplemented(); }
index 54622bf9a5c7c456f5a3df3c53a40cb30afe1ba3..d90472fd3ba25b3e6411dbb8514e2ca45c6eedb0 100644 (file)
@@ -1,12 +1,11 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/../../include -I@srcdir@/../..
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 noinst_LTLIBRARIES = libbv.la
 
 libbv_la_SOURCES = \
-       theory_def.h \
        theory_bv.h
 
 EXTRA_DIST = kinds
index fbb62545d1a637709eb423da4405949820d9965c..a859291a7a05523a0384fb3483e7ca646cacbf1c 100644 (file)
@@ -25,10 +25,10 @@ namespace CVC4 {
 namespace theory {
 namespace bv {
 
-class TheoryBV : public TheoryImpl<TheoryBV> {
+class TheoryBV : public Theory {
 public:
   TheoryBV(context::Context* c, OutputChannel& out) :
-    TheoryImpl<TheoryBV>(c, out) {
+    Theory(c, out) {
   }
 
   void preRegisterTerm(TNode n) { Unimplemented(); }
index 17a35f2edc65b93f0b6551ae0152f6eec6eb1477..d4bd717be45f1501d4904f18499b2c3ba98d1087 100644 (file)
@@ -23,5 +23,82 @@ using namespace std;
 namespace CVC4 {
 namespace theory {
 
+Node Theory::get() {
+  Assert( !d_facts.empty(),
+          "Theory::get() called with assertion queue empty!" );
+
+  Node fact = d_facts.front();
+  d_facts.pop_front();
+
+  Debug("theory") << "Theory::get() => " << fact
+                  << "(" << d_facts.size() << " left)" << std::endl;
+
+  if(! fact.getAttribute(RegisteredAttr())) {
+    std::list<TNode> toReg;
+    toReg.push_back(fact);
+
+    Debug("theory") << "Theory::get(): registering new atom" << std::endl;
+
+    /* Essentially this is doing a breadth-first numbering of
+     * non-registered subterms with children.  Any non-registered
+     * leaves are immediately registered. */
+    for(std::list<TNode>::iterator workp = toReg.begin();
+        workp != toReg.end();
+        ++workp) {
+
+      TNode n = *workp;
+
+      if(n.hasOperator()) {
+        TNode c = n.getOperator();
+
+        if(! c.getAttribute(RegisteredAttr())) {
+          if(c.getNumChildren() == 0) {
+            c.setAttribute(RegisteredAttr(), true);
+            registerTerm(c);
+          } else {
+            toReg.push_back(c);
+          }
+        }
+      }
+
+      for(TNode::iterator i = n.begin(); i != n.end(); ++i) {
+        TNode c = *i;
+
+        if(! c.getAttribute(RegisteredAttr())) {
+          if(c.getNumChildren() == 0) {
+            c.setAttribute(RegisteredAttr(), true);
+            registerTerm(c);
+          } else {
+            toReg.push_back(c);
+          }
+        }
+      }
+    }
+
+    /* Now register the list of terms in reverse order.  Between this
+     * and the above registration of leaves, this should ensure that
+     * all subterms in the entire tree were registered in
+     * reverse-topological order. */
+    for(std::list<TNode>::reverse_iterator i = toReg.rbegin();
+        i != toReg.rend();
+        ++i) {
+
+      TNode n = *i;
+
+      /* Note that a shared TNode in the DAG rooted at "fact" could
+       * appear twice on the list, so we have to avoid hitting it
+       * twice. */
+      // FIXME when ExprSets are online, use one of those to avoid
+      // duplicates in the above?
+      if(! n.getAttribute(RegisteredAttr())) {
+        n.setAttribute(RegisteredAttr(), true);
+        registerTerm(n);
+      }
+    }
+  }
+
+  return fact;
+}
+
 }/* CVC4::theory namespace */
 }/* CVC4 namespace */
index 4c3a43061e52866a3234bbd244bfc6eea3282f9b..2fcac86b02d7b9e2ae351f002fd651eb00e0bf7a 100644 (file)
@@ -38,35 +38,21 @@ namespace theory {
 struct RewriteCacheTag {};
 typedef expr::Attribute<RewriteCacheTag, TNode> RewriteCache;
 
-template <class T>
-class TheoryImpl;
-
 /**
  * Base class for T-solvers.  Abstract DPLL(T).
  *
  * This is essentially an interface class.  The TheoryEngine has
- * pointers to Theory.  But each individual theory implementation T
- * should inherit from TheoryImpl<T>, which specializes a few things
- * for that theory.
+ * pointers to Theory.  Note that only one specific Theory type (e.g.,
+ * TheoryUF) can exist per NodeManager, because of how the
+ * RegisteredAttr works.  (If you need multiple instances of the same
+ * theory, you'll have to write a multiplexed theory that dispatches
+ * all calls to them.)
  */
 class Theory {
 private:
 
-  template <class T>
-  friend class ::CVC4::theory::TheoryImpl;
-
   friend class ::CVC4::TheoryEngine;
 
-  /**
-   * Construct a Theory.
-   */
-  Theory(context::Context* ctxt, OutputChannel& out) throw() :
-    d_context(ctxt),
-    d_facts(),
-    d_factsResetter(*this),
-    d_out(&out) {
-  }
-
   /**
    * Disallow default construction.
    */
@@ -109,14 +95,24 @@ private:
 
 protected:
 
+  /**
+   * Construct a Theory.
+   */
+  Theory(context::Context* ctxt, OutputChannel& out) throw() :
+    d_context(ctxt),
+    d_facts(),
+    d_factsResetter(*this),
+    d_out(&out) {
+  }
+
   /**
    * This is called at shutdown time by the TheoryEngine, just before
    * destruction.  It is important because there are destruction
    * ordering issues between PropEngine and Theory (based on what
    * hard-links to Nodes are outstanding).  As the fact queue might be
    * nonempty, we ensure here that it's clear.  If you overload this,
-   * you must make an explicit call here to the Theory implementation
-   * of this function too.
+   * you must make an explicit call here to this->Theory::shutdown()
+   * too.
    */
   virtual void shutdown() {
     d_facts.clear();
@@ -158,6 +154,24 @@ protected:
     return n.getAttribute(RewriteCache());
   }
 
+  /** Tag for the "registerTerm()-has-been-called" flag on Nodes */
+  struct Registered {};
+  /** The "registerTerm()-has-been-called" flag on Nodes */
+  typedef CVC4::expr::CDAttribute<Registered, bool> RegisteredAttr;
+
+  /** Tag for the "preRegisterTerm()-has-been-called" flag on Nodes */
+  struct PreRegistered {};
+  /** The "preRegisterTerm()-has-been-called" flag on Nodes */
+  typedef CVC4::expr::Attribute<PreRegistered, bool> PreRegisteredAttr;
+
+  /**
+   * Returns the next atom in the assertFact() queue.  Guarantees that
+   * registerTerm() has been called on the theory specific subterms.
+   *
+   * @return the next atom in the assertFact() queue.
+   */
+  Node get();
+
 public:
 
   /**
@@ -308,133 +322,6 @@ protected:
 
 };/* class Theory */
 
-
-/**
- * Base class for T-solver implementations.  Each individual
- * implementation T of the Theory interface should inherit from
- * TheoryImpl<T>.  This class specializes some things for a particular
- * theory implementation.
- *
- * The problem with this is that Theory implementations cannot be
- * further subclassed without designing all non-children in the type
- * DAG to play the same trick as here (be template-polymorphic in their
- * most-derived child), linearizing the inheritance hierarchy (viewing
- * each instantiation separately).
- */
-template <class T>
-class TheoryImpl : public Theory {
-
-protected:
-
-  /**
-   * Construct a Theory.
-   */
-  TheoryImpl(context::Context* ctxt, OutputChannel& out) :
-    Theory(ctxt, out) {
-    /* FIXME: assert here that a TheoryImpl<T> doesn't already exist
-     * for this NodeManager??  If it does, we're hosed because they'll
-     * share per-theory node attributes. */
-  }
-
-  /** Tag for the "registerTerm()-has-been-called" flag on Nodes */
-  struct Registered {};
-  /** The "registerTerm()-has-been-called" flag on Nodes */
-  typedef CVC4::expr::CDAttribute<Registered, bool> RegisteredAttr;
-
-  /** Tag for the "preRegisterTerm()-has-been-called" flag on Nodes */
-  struct PreRegistered {};
-  /** The "preRegisterTerm()-has-been-called" flag on Nodes */
-  typedef CVC4::expr::Attribute<PreRegistered, bool> PreRegisteredAttr;
-
-  /**
-   * Returns the next atom in the assertFact() queue.  Guarantees that
-   * registerTerm() has been called on the theory specific subterms.
-   *
-   * @return the next atom in the assertFact() queue.
-   */
-  Node get();
-};/* class TheoryImpl<T> */
-
-template <class T>
-Node TheoryImpl<T>::get() {
-  Assert(typeid(*this) == typeid(T),
-         "Improper Theory inheritance chain detected.");
-
-  Assert( !d_facts.empty(),
-          "Theory::get() called with assertion queue empty!" );
-
-  Node fact = d_facts.front();
-  d_facts.pop_front();
-
-  Debug("theory") << "Theory::get() => " << fact << "(" << d_facts.size() << " left)" << std::endl;
-
-  if(! fact.getAttribute(RegisteredAttr())) {
-    std::list<TNode> toReg;
-    toReg.push_back(fact);
-
-    Debug("theory") << "Theory::get(): registering new atom" << std::endl;
-
-    /* Essentially this is doing a breadth-first numbering of
-     * non-registered subterms with children.  Any non-registered
-     * leaves are immediately registered. */
-    for(std::list<TNode>::iterator workp = toReg.begin();
-        workp != toReg.end();
-        ++workp) {
-
-      TNode n = *workp;
-
-      if(n.hasOperator()) {
-        TNode c = n.getOperator();
-
-        if(! c.getAttribute(RegisteredAttr())) {
-          if(c.getNumChildren() == 0) {
-            c.setAttribute(RegisteredAttr(), true);
-            registerTerm(c);
-          } else {
-            toReg.push_back(c);
-          }
-        }
-      }
-
-      for(TNode::iterator i = n.begin(); i != n.end(); ++i) {
-        TNode c = *i;
-
-        if(! c.getAttribute(RegisteredAttr())) {
-          if(c.getNumChildren() == 0) {
-            c.setAttribute(RegisteredAttr(), true);
-            registerTerm(c);
-          } else {
-            toReg.push_back(c);
-          }
-        }
-      }
-    }
-
-    /* Now register the list of terms in reverse order.  Between this
-     * and the above registration of leaves, this should ensure that
-     * all subterms in the entire tree were registered in
-     * reverse-topological order. */
-    for(std::list<TNode>::reverse_iterator i = toReg.rbegin();
-        i != toReg.rend();
-        ++i) {
-
-      TNode n = *i;
-
-      /* Note that a shared TNode in the DAG rooted at "fact" could
-       * appear twice on the list, so we have to avoid hitting it
-       * twice. */
-      // FIXME when ExprSets are online, use one of those to avoid
-      // duplicates in the above?
-      if(! n.getAttribute(RegisteredAttr())) {
-        n.setAttribute(RegisteredAttr(), true);
-        registerTerm(n);
-      }
-    }
-  }
-
-  return fact;
-}
-
 }/* CVC4::theory namespace */
 }/* CVC4 namespace */
 
index 156733c5ba138b68ea910faffb14ffaa6d0badcf..e0aa3a1df46f2e5fe213893938156810cf7e095b 100644 (file)
@@ -1,12 +1,11 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/../../include -I@srcdir@/../..
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 noinst_LTLIBRARIES = libuf.la
 
 libuf_la_SOURCES = \
-       theory_def.h \
        ecdata.h \
        ecdata.cpp \
        theory_uf.h \
index 3fe82b16c00f2e49ec5aa453bff667912c58acbc..f0d8b47e04cef72b74b1a29f48d1a2fc9031c90f 100644 (file)
  ** See the file COPYING in the top-level source directory for licensing
  ** information.
  **
- **
+ ** Implementation of the theory of uninterpreted functions.
  **/
 
-
 #include "theory/uf/theory_uf.h"
 #include "theory/uf/ecdata.h"
 #include "expr/kind.h"
@@ -24,37 +23,32 @@ using namespace CVC4::context;
 using namespace CVC4::theory;
 using namespace CVC4::theory::uf;
 
-
-
 TheoryUF::TheoryUF(Context* c, OutputChannel& out) :
-  TheoryImpl<TheoryUF>(c, out),
+  Theory(c, out),
   d_assertions(c),
   d_pending(c),
   d_currentPendingIdx(c,0),
   d_disequality(c),
-  d_registered(c)
-{}
+  d_registered(c) {
+}
 
-TheoryUF::~TheoryUF(){}
+TheoryUF::~TheoryUF() {
+}
 
-void TheoryUF::preRegisterTerm(TNode n){
+void TheoryUF::preRegisterTerm(TNode n) {
   Debug("uf") << "uf: begin preRegisterTerm(" << n << ")" << std::endl;
   Debug("uf") << "uf: end preRegisterTerm(" << n << ")" << std::endl;
 }
 
-void TheoryUF::registerTerm(TNode n){
+void TheoryUF::registerTerm(TNode n) {
 
   Debug("uf") << "uf: begin registerTerm(" << n << ")" << std::endl;
 
-
   d_registered.push_back(n);
 
-
-
-
   ECData* ecN;
 
-  if(n.getAttribute(ECAttr(), ecN)){
+  if(n.getAttribute(ECAttr(), ecN)) {
     /* registerTerm(n) is only called when a node has not been seen in the
      * current context.  ECAttr() is not a context-dependent attribute.
      * When n.hasAttribute(ECAttr(),...) is true on a registerTerm(n) call,
@@ -101,7 +95,7 @@ void TheoryUF::registerTerm(TNode n){
            "Expected getWatchListSize() == 0.  "
            "This data is either already in use or was not properly maintained "
            "during backtracking");
-  }else{
+  } else {
     //The attribute does not exist, so it is created and set
     ecN = new (true) ECData(getContext(), n);
     n.setAttribute(ECAttr(), ecN);
@@ -110,10 +104,10 @@ void TheoryUF::registerTerm(TNode n){
   /* If the node is an APPLY_UF, we need to add it to the predecessor list
    * of its children.
    */
-  if(n.getKind() == APPLY_UF){
+  if(n.getKind() == APPLY_UF) {
     TNode::iterator cIter = n.begin();
 
-    for(; cIter != n.end(); ++cIter){
+    for(; cIter != n.end(); ++cIter) {
       TNode child = *cIter;
 
       /* Because this can be called after nodes have been merged, we need
@@ -124,8 +118,8 @@ void TheoryUF::registerTerm(TNode n){
       /* Because this can be called after nodes have been merged we may need
        * to be merged with other predecessors of the equivalence class.
        */
-      for(Link* Px = ecChild->getFirst(); Px != NULL; Px = Px->d_next ){
-        if(equiv(n, Px->d_data)){
+      for(Link* Px = ecChild->getFirst(); Px != NULL; Px = Px->d_next ) {
+        if(equiv(n, Px->d_data)) {
           Node pend = n.eqNode(Px->d_data);
           d_pending.push_back(pend);
         }
@@ -138,30 +132,32 @@ void TheoryUF::registerTerm(TNode n){
 
 }
 
-bool TheoryUF::sameCongruenceClass(TNode x, TNode y){
+bool TheoryUF::sameCongruenceClass(TNode x, TNode y) {
   return
     ccFind(x.getAttribute(ECAttr())) ==
     ccFind(y.getAttribute(ECAttr()));
 }
 
-bool TheoryUF::equiv(TNode x, TNode y){
+bool TheoryUF::equiv(TNode x, TNode y) {
   Assert(x.getKind() == kind::APPLY_UF);
   Assert(y.getKind() == kind::APPLY_UF);
 
-  if(x.getNumChildren() != y.getNumChildren())
+  if(x.getNumChildren() != y.getNumChildren()) {
     return false;
+  }
 
-  if(x.getOperator() != y.getOperator())
+  if(x.getOperator() != y.getOperator()) {
     return false;
+  }
 
   // intentionally don't look at operator
 
   TNode::iterator xIter = x.begin();
   TNode::iterator yIter = y.begin();
 
-  while(xIter != x.end()){
+  while(xIter != x.end()) {
 
-    if(!sameCongruenceClass(*xIter, *yIter)){
+    if(!sameCongruenceClass(*xIter, *yIter)) {
       return false;
     }
 
@@ -178,10 +174,10 @@ bool TheoryUF::equiv(TNode x, TNode y){
  *    many better algorithms use eager path compression.
  * 2) Elminate recursion.
  */
-ECData* TheoryUF::ccFind(ECData * x){
-  if( x->getFind() == x)
+ECData* TheoryUF::ccFind(ECData * x) {
+  if(x->getFind() == x) {
     return x;
-  else{
+  } else {
     return ccFind(x->getFind());
   }
   /* Slightly better Find w/ path compression and no recursion*/
@@ -189,7 +185,7 @@ ECData* TheoryUF::ccFind(ECData * x){
     ECData* start;
     ECData* next = x;
     while(x != x->getFind()) x=x->getRep();
-    while( (start = next) != x){
+    while( (start = next) != x) {
       next = start->getFind();
       start->setFind(x);
     }
@@ -197,23 +193,23 @@ ECData* TheoryUF::ccFind(ECData * x){
   */
 }
 
-void TheoryUF::ccUnion(ECData* ecX, ECData* ecY){
+void TheoryUF::ccUnion(ECData* ecX, ECData* ecY) {
   ECData* nslave;
   ECData* nmaster;
 
-  if(ecX->getWatchListSize() <= ecY->getWatchListSize()){
+  if(ecX->getWatchListSize() <= ecY->getWatchListSize()) {
     nslave = ecX;
     nmaster = ecY;
-  }else{
+  } else {
     nslave = ecY;
     nmaster = ecX;
   }
 
   nslave->setFind(nmaster);
 
-  for(Link* Px = nmaster->getFirst(); Px != NULL; Px = Px->d_next ){
-    for(Link* Py = nslave->getFirst(); Py != NULL; Py = Py->d_next ){
-      if(equiv(Px->d_data,Py->d_data)){
+  for(Link* Px = nmaster->getFirst(); Px != NULL; Px = Px->d_next ) {
+    for(Link* Py = nslave->getFirst(); Py != NULL; Py = Py->d_next ) {
+      if(equiv(Px->d_data,Py->d_data)) {
         Node pendingEq = (Px->d_data).eqNode(Py->d_data);
         d_pending.push_back(pendingEq);
       }
@@ -223,7 +219,7 @@ void TheoryUF::ccUnion(ECData* ecX, ECData* ecY){
   ECData::takeOverDescendantWatchList(nslave, nmaster);
 }
 
-void TheoryUF::merge(){
+void TheoryUF::merge() {
   while(d_currentPendingIdx < d_pending.size() ) {
     Node assertion = d_pending[d_currentPendingIdx];
     d_currentPendingIdx = d_currentPendingIdx + 1;
@@ -248,7 +244,7 @@ void TheoryUF::merge(){
   }
 }
 
-Node TheoryUF::constructConflict(TNode diseq){
+Node TheoryUF::constructConflict(TNode diseq) {
   Debug("uf") << "uf: begin constructConflict()" << std::endl;
 
   NodeBuilder<> nb(kind::AND);
@@ -267,15 +263,15 @@ Node TheoryUF::constructConflict(TNode diseq){
   return conflict;
 }
 
-void TheoryUF::check(Effort level){
+void TheoryUF::check(Effort level) {
 
   Debug("uf") << "uf: begin check(" << level << ")" << std::endl;
 
-  while(!done()){
+  while(!done()) {
     Node assertion = get();
     Debug("uf") << "TheoryUF::check(): " << assertion << std::endl;
 
-    switch(assertion.getKind()){
+    switch(assertion.getKind()) {
     case EQUAL:
       d_assertions.push_back(assertion);
       d_pending.push_back(assertion);
@@ -292,18 +288,18 @@ void TheoryUF::check(Effort level){
   }
 
   //Make sure all outstanding merges are completed.
-  if(d_currentPendingIdx < d_pending.size()){
+  if(d_currentPendingIdx < d_pending.size()) {
     merge();
   }
 
-  if(fullEffort(level)){
+  if(fullEffort(level)) {
     for(CDList<Node>::const_iterator diseqIter = d_disequality.begin();
         diseqIter != d_disequality.end();
-        ++diseqIter){
+        ++diseqIter) {
 
       TNode left  = (*diseqIter)[0];
       TNode right = (*diseqIter)[1];
-      if(sameCongruenceClass(left, right)){
+      if(sameCongruenceClass(left, right)) {
         Node remakeNeq = (*diseqIter).notNode();
         Node conflict = constructConflict(remakeNeq);
         d_out->conflict(conflict, false);
@@ -313,5 +309,4 @@ void TheoryUF::check(Effort level){
   }
 
   Debug("uf") << "uf: end check(" << level << ")" << std::endl;
-
 }
index 8495e6c9c9310ce92ed0d212dab97081272ece01..5863a31fcd4cddd0cf8e822b48dcd0299206f4e9 100644 (file)
@@ -38,7 +38,7 @@ namespace CVC4 {
 namespace theory {
 namespace uf {
 
-class TheoryUF : public TheoryImpl<TheoryUF> {
+class TheoryUF : public Theory {
 
 private:
 
@@ -176,31 +176,30 @@ private:
   /** Constructs a conflict from an inconsistent disequality. */
   Node constructConflict(TNode diseq);
 
-};
+};/* class TheoryUF */
 
 
 /**
  * Cleanup function for ECData. This will be used for called whenever
  * a ECAttr is being destructed.
  */
-struct ECCleanupStrategy{
-  static void cleanup(ECData* ec){
+struct ECCleanupStrategy {
+  static void cleanup(ECData* ec) {
     Debug("ufgc") << "cleaning up ECData " << ec << "\n";
     ec->deleteSelf();
   }
-};
+};/* struct ECCleanupStrategy */
 
 /** Unique name to use for constructing ECAttr. */
-struct EquivClass;
+struct ECAttrTag {};
 
 /**
  * ECAttr is the attribute that maps a node to an equivalence class.
  */
-typedef expr::Attribute<EquivClass, ECData*, ECCleanupStrategy > ECAttr;
-
-} /* CVC4::theory::uf namespace */
-} /* CVC4::theory namespace */
-} /* CVC4 namespace */
+typedef expr::Attribute<ECAttrTag, ECData*, ECCleanupStrategy> ECAttr;
 
+}/* CVC4::theory::uf namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
 
 #endif /* __CVC4__THEORY__UF__THEORY_UF_H */
index 06be4ab7c5818577b3b6657c21f9cc9e68b7a0a4..1611f28d332811bcc65df37f9aec563e72ab016c 100644 (file)
@@ -70,8 +70,10 @@ void AssertionException::construct(const char* header, const char* extra,
   setMessage(string(buf));
 
 #ifdef CVC4_DEBUG
-  // we leak buf[] but only in debug mode with assertions failing
-  s_debugAssertionFailure = buf;
+  if(s_debugAssertionFailure == NULL) {
+    // we leak buf[] but only in debug mode with assertions failing
+    s_debugAssertionFailure = buf;
+  }
 #else /* CVC4_DEBUG */
   delete [] buf;
 #endif /* CVC4_DEBUG */
@@ -110,7 +112,9 @@ void AssertionException::construct(const char* header, const char* extra,
 
 #ifdef CVC4_DEBUG
   // we leak buf[] but only in debug mode with assertions failing
-  s_debugAssertionFailure = buf;
+  if(s_debugAssertionFailure == NULL) {
+    s_debugAssertionFailure = buf;
+  }
 #else /* CVC4_DEBUG */
   delete [] buf;
 #endif /* CVC4_DEBUG */
index 5e8dfd2a402f4d9a59e9888d5cdaeda71e76c7b1..6597c8b48a9bcaf26c8a066e4db192ba1aaa22a3 100644 (file)
@@ -1,7 +1,7 @@
 AM_CPPFLAGS = \
        -D__BUILDING_CVC4LIB \
        -I@srcdir@/../include -I@srcdir@/..
-AM_CXXFLAGS = -Wall -fvisibility=hidden
+AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN)
 
 noinst_LTLIBRARIES = libutil.la
 
index f4ce30968b2169bfe784f14f3f8e392902c162a1..5ed13a13999553ebbc49eee4be85013893a5c4d2 100644 (file)
@@ -94,7 +94,7 @@ string Configuration::about() {
 This is a pre-release of CVC4.\n\
 Copyright (C) 2009, 2010\n\
   The ACSys Group\n\
-  Courant Institute of Mathematical Sciences,\n\
+  Courant Institute of Mathematical Sciences\n\
   New York University\n\
   New York, NY  10012  USA\n");
 }
index eb07b22fb20e3cb2f8992d6d780473eb3ebf6dec..fe95ed7aa9949a3530f955e64348818446108bc6 100644 (file)
@@ -1,7 +1,9 @@
 SUBDIRS = precedence uf
 
-TESTS_ENVIRONMENT = @srcdir@/../run_regression @top_builddir@/../../bin/cvc4
+TESTS_ENVIRONMENT = @srcdir@/../run_regression @top_builddir@/src/main/cvc4
 TESTS =        \
+    error.cvc \
+    boolean-prec.cvc \
     distinct.smt \
     flet.smt \
     flet2.smt \
@@ -43,7 +45,7 @@ TESTS =       \
        wiki.19.cvc \
        wiki.20.cvc \
        wiki.21.cvc
-       
+
 # synonyms for "check"
 .PHONY: regress regress0 test
 regress regress0 test: check
index 4f84de94d2cd3b2aed647428ebebbd4bc7ce0819..d0205116cca3912827058239a61675b44d2fa725 100644 (file)
@@ -1,6 +1,7 @@
-% Expect: VALID
+% EXPECT: VALID
 % Simple test for right precedence of AND, <=>, NOT.
 
 A, B, C: BOOLEAN;
 
 QUERY (NOT A AND NOT B <=> C) <=> (((NOT A) AND (NOT B)) <=> C);
+% EXIT: 20
index 89afbe325e9104895540161897cf7b90a72d73c9..eeac40c9f99dabba0a81dfcd83f20cee8f8a0717 100644 (file)
@@ -804,3 +804,4 @@ a288 : BOOLEAN =
         ELSE FALSE
         ENDIF;
 QUERY a288;
+% EXIT: 20
index d3d936381b8b8144efd4782c5301f91717eef039..2b59638d1cb17ad4d1031378ff164cb3a34c3113 100644 (file)
@@ -6,3 +6,4 @@ ASSERT ((x > y) => f(x) > f (y));
 ASSERT (x = 3);
 ASSERT (y = 2);
 QUERY(f(x) > f (y));
+% EXIT: 20
index 8d113d78552c304c926d65c112cca94f6faa804d..c6d79a4ab02e946ba52a510ace1ec70a2e9d3095 100644 (file)
@@ -4,3 +4,4 @@ b:BOOLEAN;
 ASSERT(a);
 QUERY(a OR b);
 
+% EXIT: 20
diff --git a/test/regress/regress0/error.cvc b/test/regress/regress0/error.cvc
new file mode 100644 (file)
index 0000000..09a69e2
--- /dev/null
@@ -0,0 +1,4 @@
+% EXPECT-ERROR: CVC4 Error:
+% EXPECT-ERROR: Parse Error: Parser Error: error.cvc:3.9: Symbol BOOL not declared
+p : BOOL;
+% EXIT: 1
index bdd45b6d0499c5e7058f3812ea188cb74310e1d5..07bfa392cc0f82e28eb0fe0c3ae8e052f63283f1 100644 (file)
@@ -177,3 +177,4 @@ ASSERT x_42 OR x_41 OR x_40 OR x_39 OR x_38 OR x_37;
 
 
 QUERY FALSE;
+% EXIT: 20
index d947d1a277f4aea93b012e905c0f260e5d92b8f3..5348cf7e4760a6bed69f29c2b79a69d71e27f088 100644 (file)
@@ -1,3 +1,4 @@
 a, b, c: BOOLEAN;
 % EXPECT: VALID
 QUERY (a XOR b) <=> (NOT a AND b) OR (NOT b AND a);
+% EXIT: 20
index ba2d55b4fa5e467fc55cd79b8f8eb28ebfc3d355..4a8539faeca06fde24548600083c6603a7e0a4a3 100644 (file)
@@ -1,3 +1,4 @@
 a, b, c: BOOLEAN;
 % EXPECT: INVALID
 QUERY NOT c AND b;
+% EXIT: 10
index 85b23d2b0e3dc7991e097b00f4b01b3330eaf380..6b5f34613e672b1aec7a20e979f12d9314addc9a 100644 (file)
@@ -1,3 +1,4 @@
 a, b, c: BOOLEAN;
 % EXPECT: VALID
 QUERY (IF c THEN a ELSE b ENDIF) <=> ((c AND a) OR (NOT c AND b));
+% EXIT: 20
index a710965423440467560320f7e683305c84725a1a..6e7aa1f5eca43485ad8dcd0a62da7073a7e35577 100644 (file)
@@ -1,3 +1,4 @@
 a, b, c: BOOLEAN;
 % EXPECT: VALID
 QUERY (a => b) <=> (NOT a OR b);
+% EXIT: 20
index 19bbae5b458da3a384e723c94de91e8d7de8632f..14e2c887ab59e219c7b25019f8c3107289ee4f10 100644 (file)
@@ -2,3 +2,4 @@ a, b, c: BOOLEAN;
 % EXPECT: VALID
 QUERY TRUE XOR FALSE;
  
+% EXIT: 20
index 0b4fcd4a60bd17616a3e50ecbd106e9e02ccbd74..362ec70b6439f8ad60827ec3fdfde2789d772cf0 100644 (file)
@@ -1,4 +1,4 @@
-TESTS_ENVIRONMENT = @srcdir@/../../run_regression @top_builddir@/../../bin/cvc4
+TESTS_ENVIRONMENT = @srcdir@/../../run_regression @top_builddir@/src/main/cvc4
 TESTS = \
     iff-implies.cvc \
        implies-iff.cvc \
index d283ca881267adfa96a26201b04ccde6e58b911a..0de37db83c6bb5bbc7d65059087fac5457f4574f 100644 (file)
@@ -4,3 +4,4 @@
 A, B: BOOLEAN;
 
 QUERY (A AND NOT B) <=> (A AND (NOT B));
+% EXIT: 20
index c7268727ad7c38729bfc3e2e00b92dfa68522852..7b29bb95e9a5d5c9a7157c7c62f74fce5edd2bba 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (A AND B XOR C) <=> ((A AND B) XOR C);
+% EXIT: 20
index 43feeb1f82ea5cd9295149382dfde2811b18619f..e85b4a3e696c25861b1f719b12ce5f58f81b7348 100644 (file)
@@ -6,3 +6,4 @@ x , y: T;
 f : T -> T;
 
 QUERY (f(x) = f(y)) <=> ((f(x)) = (f(y)));
+% EXIT: 20
index 82e0cbc723010f1c37d23aab3dac9d7a0cc298b1..b92354753034eeeb2799cf6f032b318e4beb828f 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (A <=> B <=> C) <=> (A <=> (B <=> C));
+% EXIT: 20
index bebafce1451d7e9a591961f0d0813f71b3ce3502..0115fc3195ec30f181917280075e6989216336be 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (A <=> B => C) <=> ((A <=> (B => C)));
+% EXIT: 20
index c73616caf25bc78c2f64a40f9c3326dc896d644e..d465df3131378d240285076411d2e81d33397c54 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (A => B => C) <=> (A => (B => C));
+% EXIT: 20
index f44c4bc75e083e7871041123792e4359e12983e1..f8c813ceb7dc82fa66fe0db8476a83a3608dcaf5 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (A => B <=> C) <=> ((A => B) <=> C);
+% EXIT: 20
index 835da85702cecf4fd4041dd280b48567ca6cfedd..24edb4ecd1a06811d60a3e2b0d8d9b03846f26af 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (A => B OR C) <=> (A => (B OR C));
+% EXIT: 20
index 44c27af53ad83d34aecc65f420767c0cee2f338a..8c849a0d91406d82fab2a6d7481d4db379abc3ac 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (NOT A AND B) <=> ((NOT A) AND B);
+% EXIT: 20
index 1126926b8f263dc6b05de2cccbd7cc6ba3d8da05..16c812086da80b390bf8134b8d9fe1f78b75b84d 100644 (file)
@@ -4,3 +4,4 @@
 A, B: BOOLEAN;
 
 QUERY (NOT A = B) <=> (NOT (A = B));
+% EXIT: 20
index 3b336db5a27469d9e4fb3888267f1a08c5868481..d91f79dc84aa1f3d542d8be6f61ad5e08acf2c3f 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (A OR B => C) <=> ((A OR B) => C);
+% EXIT: 20
index 2198962c8eb2f0285762e345481a9899460c9528..47cc87c7648eb55054cb35b33c1e5f53c8a9f249 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (A OR B XOR C) <=> (A OR (B XOR C));
+% EXIT: 20
index ccdaeebad5e899f2a204edec6e2cf063fd15fa2d..ba3f48a7f48afb81458ae8061e748cd82aa476e9 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (A XOR B AND C) <=> (A XOR (B AND C));
+% EXIT: 20
index ffdb2c8c9c3fc2c194349053346fc9543283c743..27911332c3361dc5e4f9ab76fd15469b93e9d6d5 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (A XOR B XOR C) <=> ((A XOR B) XOR C);
+% EXIT: 20
index 959dec14efef54ca5d95ccb60b56299398d1a2cc..2b4436937c4441cb411eb168d86c67af4ddee086 100644 (file)
@@ -4,3 +4,4 @@
 A, B, C: BOOLEAN;
 
 QUERY (A XOR B OR C) <=> ((A XOR B) OR C);
+% EXIT: 20
index 36107e784844fb10a177120fded0096d3724fa35..fe6235981d6281ded08caae3dad5350bfa828fc5 100644 (file)
@@ -8,3 +8,4 @@ QUERY (a AND b) OR NOT (a AND b);
 % EXPECT: INVALID
 QUERY (a OR b);
 
+% EXIT: 10
index 21145b6e0e95cecf7c4878f61665125f5d1148ef..a0bff6c5af510e3541cb05600c30926803562c45 100644 (file)
@@ -5,3 +5,4 @@ ASSERT x3 OR x2;
 ASSERT x1 AND NOT x1;
 % EXPECT: VALID
 QUERY x2;
+% EXIT: 20
index 3a36b8c1e0956af63c52bbee8df6b36b8aa12539..fe17e0b53a647a184ae8782ccb06489e6816215f 100644 (file)
@@ -7,3 +7,4 @@ ASSERT a OR NOT b OR c;
 % EXPECT: INVALID
 QUERY FALSE;
 
+% EXIT: 10
index 6f0cac8fa4aae40fd5d7394ba21f57144f23f88f..2fa1e23ba4ee0518b1a87fc07e3fa9156ae458c2 100644 (file)
@@ -5,3 +5,4 @@ ASSERT NOT (x OR y);
 
 % EXPECT: VALID
 QUERY FALSE;
+% EXIT: 20
index 48966f53b2e0f1e950c729a687af8cc457e69aab..a3d63b49760c84a3e2697dd7168d8b4238f56aa9 100644 (file)
@@ -175,3 +175,4 @@ QUERY NOT P_10;
 POP;
 PUSH;
 QUERY FALSE;
+% EXIT: 20
index de6be2f545d17d8da450ead182dae5b57fb1bb6b..64c2011a4c973b8ae2c0ec0afa01fb0b4a1bc056 100644 (file)
@@ -2,3 +2,4 @@
 P,Q:BOOLEAN;
 ASSERT (P OR Q);
 QUERY (P OR Q);
+% EXIT: 20
index ec99fd45c546612490d31dd3526ade2755d3142e..802189f2b54ee752a01159762de9e50989b5ba15 100644 (file)
@@ -1,4 +1,4 @@
-TESTS_ENVIRONMENT = @srcdir@/../../run_regression @top_builddir@/../../bin/cvc4
+TESTS_ENVIRONMENT = @srcdir@/../../run_regression @top_builddir@/src/main/cvc4
 TESTS =        \
        euf_simp01.smt \
        euf_simp02.smt \
index f5d8c1033f76bbc6725d905c29c04202cc39e4b3..84b8b8a8d2a0570287b77a4924f181e2c9824c0b 100644 (file)
@@ -5,3 +5,4 @@ x, y: A;
 f: A -> B;
 QUERY (x = y => f(x) = f(y));
 
+% EXIT: 20
index 0ebc319ba18d7661be8fe8ef3a350e25cfa3bfbb..21d3e3cee1add89cba730ac5574875833e8d757a 100644 (file)
@@ -5,3 +5,4 @@ x, y: A;
 f: A -> B;
 QUERY (f(x) = f(y));
 
+% EXIT: 10
index 54948edb8c4226ab7b31889672267e05f505f5e8..476c6cd4a3743245aa2db72b8b5dfa3e27aab35b 100644 (file)
@@ -9,3 +9,4 @@ f: A -> B;
 ASSERT (x = a AND y = a) OR (x = b AND y = b);
 QUERY (f(x) = f(y));
 
+% EXIT: 20
index 58bb6fef158ab987ceee81d735d82a66a3944eca..c9675588d1beb51463aa7269d3d4a31a62b07488 100644 (file)
@@ -9,3 +9,4 @@ f: A -> B;
 ASSERT (x = a OR x = b) AND (y = b OR y = a);
 QUERY (f(x) = f(y));
 
+% EXIT: 10
index 74fdb11165c21779d8885f5e70c7db3287aa13d1..a44b028a234406c8761ecf36bd28aa972b9d3ee4 100644 (file)
@@ -113,3 +113,4 @@ ASSERT x_10 OR NOT x_11 OR x_16;
 
 
 QUERY FALSE;
+% EXIT: 10
index 57660b5a1df880dd8cac1743a35741522120b087..7b6835469722d5736d775ceb0b5155dfa6a45ca9 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a OR (b OR c) <=> (a OR b) OR c;
+% EXIT: 20
index baba459272ab944f765f9901581d19c5d1c09382..9fd4f8fb71f29dd2d67bb47ae3590cf78c831e9f 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a AND (b AND c) <=> (a AND b) AND c;
+% EXIT: 20
index 791cc45c8b6b8ff9628b33c7950a68eb4e9278b8..63c1029b431e2d3c15ea31a320fbcb371fa6e72e 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a OR b <=> b OR a;
+% EXIT: 20
index f0f73ce1f3a3705f31348125b2662b48769dfb10..77fa0059b5cc7a14834686fd8bbc821b75a1229a 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a AND b <=> b AND a;
+% EXIT: 20
index afb094dae40976023f1b60f29d1e9e3c1d31b1bc..cb7140bccf4abf26479837797c04c15acdce8d22 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a OR (a AND b) <=> a;
+% EXIT: 20
index 421bfbdfd5c9e6d6fac5368d1bf33844a883daef..6c69ca4bc7176fc6576fd94ca49751758e686b99 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a AND (a OR b) <=> a;
+% EXIT: 20
index a28cbf553edcaae7403e2ffdb277fa3ae70e1e4b..a0281d04b282d32f96dec5b5b595387de3bd6303 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a OR (b AND c) <=> (a OR b) AND (a OR c);
+% EXIT: 20
index 70fc5f430ee5d583c101843a37cdf5fd5df2c9d6..ddf0f328cc5ad2493f0f58990346d45447fe11ca 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a AND (b OR c) <=> (a AND b) OR (a AND c);
+% EXIT: 20
index d3118536d0395d39dd257754f0bcfd00901dc7b2..f97021910054314fef092902d03c2b70d64cdd2f 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a OR NOT a;
+% EXIT: 20
index 41a9bcd3f6c14db82a9880360529d6293fc12747..da8a1a9c358cbfd76c71890e87a19fc728c69920 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a AND NOT a <=> FALSE;
+% EXIT: 20
index e9c0b9cceccaadb9cd966860672d95025c927156..4d7c3c13059a15c8ddc048db72513ed6a280615a 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a OR a <=> a;
+% EXIT: 20
index d5e7bd77646704c46c2ec8734b9135377e18d5e9..c932892c802e3a139f79c497d39b897f39eb9e07 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a AND a <=> a;
+% EXIT: 20
index 2674ba47bf9482827b4edec41ddb6e6549c59a33..3ad4fd4abf410b46961f68e5c3b352647a493d0b 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a OR FALSE <=> a;
+% EXIT: 20
index 378b84dcd4036168f351874f60478636708f07b9..454cf442c70992b861451908c0b092afb04bd4bb 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a AND TRUE <=> a;
+% EXIT: 20
index ca51c46325b59f31b75785662b161cf4b0b2112c..81a13f7986b890399a98eebf583a06404ef59d8f 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a OR TRUE <=> TRUE;
+% EXIT: 20
index af47433f88a465d39a01715669f44ba0d50c7579..bd13faf11ae160126ff02c38719a4b01ffbf071d 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY a AND FALSE <=> FALSE;
+% EXIT: 20
index dc7e7a1c33bb5110d3fa62589ae868445bb07cf0..48949f89fb0aaca4c1a9208afb838d3d268d1d86 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY NOT FALSE <=> TRUE;
+% EXIT: 20
index 21a87f4b564582c5ab8550abefae7e9fb51278b3..8959d34a65a4b8d42380b978232aad1194bfb7ab 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY NOT TRUE <=> FALSE;
+% EXIT: 20
index c6081c200abc5616fb13947ed192acd79fe04fa3..11366526b9db5ce479020de19fbe031b6bd9408f 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY NOT (a OR b) <=> NOT a AND NOT b;
+% EXIT: 20
index 3bec9348be78721a022b7f1b65f817ebf4ad8159..5ef534bb0b3aa7209d3629b795fef55361cc8cc7 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY NOT (a AND b) <=> NOT a OR NOT b;
+% EXIT: 20
index e99ba2d68468b236d4abefa494ea77d31d4a2f5d..bcd7146fb9a8b4d4a69cbaa4c9c054e7280fa310 100644 (file)
@@ -2,3 +2,4 @@ a, b, c : BOOLEAN;
 
 % EXPECT: VALID
 QUERY NOT NOT a <=> a;
+% EXIT: 20
index 8a41e99a3f7072f74761273fa2367a0568ba8f11..9307a33a2fccaf6748ec1edb65e6c2653dbce2c0 100644 (file)
@@ -1,4 +1,4 @@
-TESTS_ENVIRONMENT = @srcdir@/../run_regression @top_builddir@/../../bin/cvc4
+TESTS_ENVIRONMENT = @srcdir@/../run_regression @top_builddir@/src/main/cvc4
 TESTS =        friedman_n4_i5.smt \
        hole7.cvc \
        hole8.cvc \
index 1bebf80497dd43df5bd48a3a3a69aed2ab179c9c..5ff290f6236f6c4eb1888d2b3e715ee4493f3d06 100644 (file)
@@ -262,3 +262,4 @@ ASSERT x_56 OR x_55 OR x_54 OR x_53 OR x_52 OR x_51 OR x_50;
 
 
 QUERY FALSE;
+% EXIT: 20
index 65942a27fdca918fc832112a775897e22d237d5b..d0f974619c3618c80e91ca10f77e502eb6d74976 100644 (file)
@@ -371,3 +371,4 @@ ASSERT x_72 OR x_71 OR x_70 OR x_69 OR x_68 OR x_67 OR x_66 OR x_65;
 
 
 QUERY FALSE;
+% EXIT: 20
index 2f72dd5e283b684192bb92a3e41ea13de6706649..710ee6b8e960d7056be63dfd1892c07531447c50 100644 (file)
@@ -1,4 +1,4 @@
-TESTS_ENVIRONMENT = @srcdir@/../run_regression @top_builddir@/../../bin/cvc4
+TESTS_ENVIRONMENT = @srcdir@/../run_regression @top_builddir@/src/main/cvc4
 TESTS =        bmc-galileo-8.smt \
        bmc-galileo-9.smt \
        bmc-ibm-10.smt \
index 93377ca0b7195effffabbb436ec24ca3986c0b5d..e631444d34cc4f3493c223f576293a46e656b087 100644 (file)
@@ -507,3 +507,4 @@ ASSERT x_90 OR x_89 OR x_88 OR x_87 OR x_86 OR x_85 OR x_84 OR x_83 OR x_82;
 
 
 QUERY FALSE;
+% EXIT: 20
index f0f46171cc8ef5c97ce1e1ed4cd7eb635cda0d0d..156fffb54f7e34617dc12255fb6008a94b8783ba 100644 (file)
@@ -1,4 +1,4 @@
-TESTS_ENVIRONMENT = @srcdir@/../run_regression @top_builddir@/../../bin/cvc4
+TESTS_ENVIRONMENT = @srcdir@/../run_regression @top_builddir@/src/main/cvc4
 TESTS =        C880mul.miter.shuffled-as.sat03-348.smt \
        comb2.shuffled-as.sat03-420.smt \
        hole10.cvc \
index 39c978b189b8326a9d8e9eac278b7f353a9532cb..661e3ef4b217d9708dbdc86597c3a72fceacec81 100644 (file)
@@ -673,3 +673,4 @@ ASSERT x_110 OR x_109 OR x_108 OR x_107 OR x_106 OR x_105 OR x_104 OR x_103 OR x
 
 
 QUERY FALSE;
+% EXIT: 20
index 2be776b3f629a326d3c7f27610517eb54ce85dd6..65ab6c31ac8b0b115892df5715c3fd4283854dd0 100755 (executable)
@@ -44,35 +44,68 @@ if expr "$benchmark" : '.*\.smt$' &>/dev/null; then
   fi
 elif expr "$benchmark" : '.*\.cvc$' &>/dev/null; then
   expected_output=`grep '^% EXPECT: ' "$benchmark" | sed 's,^% EXPECT: ,,'`
-  if [ -z "$expected_output" ]; then
-    error "cannot determine status of \`$benchmark'"
+  expected_error=`grep '^% EXPECT-ERROR: ' "$benchmark" | sed 's,^% EXPECT-ERROR: ,,'`
+  if [ -z "$expected_output" -a -z "$expected_error" ]; then
+    error "cannot determine expected output of \`$benchmark': " \
+          "please use \`% EXPECT:' and/or \`% EXPECT-ERROR:' gestures"
   fi
   expected_exit_status=`grep -m 1 '^% EXIT: ' "$benchmark" | sed 's,^% EXIT: ,,'`
+  if [ -z "$expected_exit_status" ]; then
+    error "cannot determine expected exit status of \`$benchmark': please use \`% EXIT:' gesture"
+  fi
 else
   error "benchmark \`$benchmark' must be *.cvc or *.smt"
 fi
 
-expfile=`mktemp -t cvc4_expected.XXXXXXXXXX`
-outfile=`mktemp -t cvc4_output.XXXXXXXXXX`
-echo "$expected_output" >"$expfile"
+expoutfile=`mktemp -t cvc4_expect_stdout.XXXXXXXXXX`
+experrfile=`mktemp -t cvc4_expect_stderr.XXXXXXXXXX`
+outfile=`mktemp -t cvc4_stdout.XXXXXXXXXX`
+errfile=`mktemp -t cvc4_stderr.XXXXXXXXXX`
+exitstatusfile=`mktemp -t cvc4_exitstatus.XXXXXXXXXX`
+if [ -z "$expected_output" ]; then
+  # in case expected stdout output is empty, make sure we don't differ
+  # by a newline, which we would if we echo "" >"$expoutfile"
+  touch "$expoutfile"
+else
+  echo "$expected_output" >"$expoutfile"
+fi
+if [ -z "$expected_error" ]; then
+  # in case expected stderr output is empty, make sure we don't differ
+  # by a newline, which we would if we echo "" >"$experrfile"
+  touch "$experrfile"
+else
+  echo "$expected_error" >"$experrfile"
+fi
 
-# echo "$cvc4" --segv-nospin "$benchmark"
-"$cvc4" --segv-nospin "$benchmark" > "$outfile"
+("$cvc4" --segv-nospin "$benchmark"; echo $? >"$exitstatusfile") > "$outfile" 2> "$errfile"
 
-diffs=`diff -u "$expfile" "$outfile"`
+diffs=`diff -u "$expoutfile" "$outfile"`
 diffexit=$?
-rm -f "$expfile"
+diffserr=`diff -u "$experrfile" "$errfile"`
+diffexiterr=$?
+exit_status=`cat "$exitstatusfile"`
+
+rm -f "$expoutfile"
+rm -f "$experrfile"
 rm -f "$outfile"
+rm -f "$errfile"
+rm -f "$exitstatusfile"
+
+exitcode=0
 if [ $diffexit -ne 0 ]; then
-  echo "$prog: error: differences between expected and actual output"
+  echo "$prog: error: differences between expected and actual output on stdout"
   echo "$diffs"
-  exit 1
+  exitcode=1
+fi
+if [ $diffexiterr -ne 0 ]; then
+  echo "$prog: error: differences between expected and actual output on stderr"
+  echo "$diffserr"
+  exitcode=1
 fi
 
-if [ -n "$expected_exit_status" ]; then
-  :
-  #if [ $exit_status != "$expected_exit_status" ]; then
-  #  error "expected exit status \`$expected_exit_status' but got \`$exit_status'"
-  #fi
+if [ "$exit_status" != "$expected_exit_status" ]; then
+  echo  "$prog: error: expected exit status \`$expected_exit_status' but got \`$exit_status'"
+  exitcode=1
 fi
 
+exit $exitcode
index 768a56a9b7e6b7fa5379d186588f975995c0589d..451100b59a2e079f3111704460199612e76c375f 100644 (file)
@@ -10,6 +10,7 @@ UNIT_TESTS = \
        expr/attribute_black \
        parser/parser_white \
        context/context_black \
+       context/context_white \
        context/context_mm_black \
        context/cdo_black \
        context/cdlist_black \
index 7040e4cc16c3096dc5dd777ce57ac6a713a4c368..262c66fe5883bebf8f3c94da0817fa8b292ca9ac 100644 (file)
@@ -30,6 +30,8 @@ public:
   void setUp() {
     d_context = new Context;
     //Debug.on("cdmap");
+    //Debug.on("gc");
+    //Debug.on("pushpop");
   }
 
   void tearDown() {
diff --git a/test/unit/context/context_white.h b/test/unit/context/context_white.h
new file mode 100644 (file)
index 0000000..3e0928b
--- /dev/null
@@ -0,0 +1,186 @@
+/*********************                                                        */
+/** context_white.h
+ ** Original author: mdeters
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009, 2010  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.
+ **
+ ** White box testing of CVC4::context::Context.
+ **/
+
+#include <cxxtest/TestSuite.h>
+
+#include "context/context.h"
+#include "context/cdo.h"
+#include "util/Assert.h"
+
+using namespace std;
+using namespace CVC4;
+using namespace CVC4::context;
+
+class ContextWhite : public CxxTest::TestSuite {
+private:
+
+  Context* d_context;
+
+public:
+
+  void setUp() {
+    d_context = new Context;
+  }
+
+  void tearDown() {
+    delete d_context;
+  }
+
+  void testContextSimple() {
+    Scope *s = d_context->getTopScope();
+
+    TS_ASSERT(s == d_context->getBottomScope());
+    TS_ASSERT(d_context->getLevel() == 0);
+    TS_ASSERT(d_context->d_scopeList.size() == 1);
+
+    TS_ASSERT(s->d_pContext == d_context);
+    TS_ASSERT(s->d_pCMM == d_context->d_pCMM);
+    TS_ASSERT(s->d_level == 0);
+    TS_ASSERT(s->d_pContextObjList == NULL);
+
+    CDO<int> a(d_context);
+
+    TS_ASSERT(s->d_pContext == d_context);
+    TS_ASSERT(s->d_pCMM == d_context->d_pCMM);
+    TS_ASSERT(s->d_level == 0);
+    TS_ASSERT(s->d_pContextObjList == &a);
+
+    TS_ASSERT(a.d_pScope == s);
+    TS_ASSERT(a.d_pContextObjRestore == NULL);
+    TS_ASSERT(a.d_pContextObjNext == NULL);
+    TS_ASSERT(a.d_ppContextObjPrev == &s->d_pContextObjList);
+
+    CDO<int> b(d_context);
+
+    TS_ASSERT(s->d_pContext == d_context);
+    TS_ASSERT(s->d_pCMM == d_context->d_pCMM);
+    TS_ASSERT(s->d_level == 0);
+    TS_ASSERT(s->d_pContextObjList == &b);
+
+    TS_ASSERT(a.d_pScope == s);
+    TS_ASSERT(a.d_pContextObjRestore == NULL);
+    TS_ASSERT(a.d_pContextObjNext == NULL);
+    TS_ASSERT(a.d_ppContextObjPrev == &b.d_pContextObjNext);
+
+    TS_ASSERT(b.d_pScope == s);
+    TS_ASSERT(b.d_pContextObjRestore == NULL);
+    TS_ASSERT(b.d_pContextObjNext == &a);
+    TS_ASSERT(b.d_ppContextObjPrev == &s->d_pContextObjList);
+
+    d_context->push();
+    Scope* t = d_context->getTopScope();
+    TS_ASSERT(s != t);
+
+    TS_ASSERT(s == d_context->getBottomScope());
+    TS_ASSERT(d_context->getLevel() == 1);
+    TS_ASSERT(d_context->d_scopeList.size() == 2);
+
+    TS_ASSERT(s->d_pContext == d_context);
+    TS_ASSERT(s->d_pCMM == d_context->d_pCMM);
+    TS_ASSERT(s->d_level == 0);
+    TS_ASSERT(s->d_pContextObjList == &b);
+
+    TS_ASSERT(t->d_pContext == d_context);
+    TS_ASSERT(t->d_pCMM == d_context->d_pCMM);
+    TS_ASSERT(t->d_level == 1);
+    TS_ASSERT(t->d_pContextObjList == NULL);
+
+    TS_ASSERT(a.d_pScope == s);
+    TS_ASSERT(a.d_pContextObjRestore == NULL);
+    TS_ASSERT(a.d_pContextObjNext == NULL);
+    TS_ASSERT(a.d_ppContextObjPrev == &b.d_pContextObjNext);
+
+    TS_ASSERT(b.d_pScope == s);
+    TS_ASSERT(b.d_pContextObjRestore == NULL);
+    TS_ASSERT(b.d_pContextObjNext == &a);
+    TS_ASSERT(b.d_ppContextObjPrev == &s->d_pContextObjList);
+
+    a = 5;
+
+    TS_ASSERT(t->d_pContext == d_context);
+    TS_ASSERT(t->d_pCMM == d_context->d_pCMM);
+    TS_ASSERT(t->d_level == 1);
+    TS_ASSERT(t->d_pContextObjList == &a);
+
+    TS_ASSERT(a.d_pScope == t);
+    TS_ASSERT(a.d_pContextObjRestore != NULL);
+    TS_ASSERT(a.d_pContextObjNext == NULL);
+    TS_ASSERT(a.d_ppContextObjPrev == &t->d_pContextObjList);
+
+    b = 3;
+
+    TS_ASSERT(t->d_pContext == d_context);
+    TS_ASSERT(t->d_pCMM == d_context->d_pCMM);
+    TS_ASSERT(t->d_level == 1);
+    TS_ASSERT(t->d_pContextObjList == &b);
+
+    TS_ASSERT(a.d_pScope == t);
+    TS_ASSERT(a.d_pContextObjRestore != NULL);
+    TS_ASSERT(a.d_pContextObjNext == NULL);
+    TS_ASSERT(a.d_ppContextObjPrev == &b.d_pContextObjNext);
+
+    TS_ASSERT(b.d_pScope == t);
+    TS_ASSERT(b.d_pContextObjRestore != NULL);
+    TS_ASSERT(b.d_pContextObjNext == &a);
+    TS_ASSERT(b.d_ppContextObjPrev == &t->d_pContextObjList);
+
+    d_context->push();
+    Scope* u = d_context->getTopScope();
+    TS_ASSERT(u != t);
+    TS_ASSERT(u != s);
+
+    CDO<int> c(d_context);
+    c = 4;
+
+    TS_ASSERT(c.d_pScope == u);
+    TS_ASSERT(c.d_pContextObjRestore != NULL);
+    TS_ASSERT(c.d_pContextObjNext == NULL);
+    TS_ASSERT(c.d_ppContextObjPrev == &u->d_pContextObjList);
+
+    d_context->pop();
+
+    TS_ASSERT(t->d_pContext == d_context);
+    TS_ASSERT(t->d_pCMM == d_context->d_pCMM);
+    TS_ASSERT(t->d_level == 1);
+    TS_ASSERT(t->d_pContextObjList == &b);
+
+    TS_ASSERT(a.d_pScope == t);
+    TS_ASSERT(a.d_pContextObjRestore != NULL);
+    TS_ASSERT(a.d_pContextObjNext == NULL);
+    TS_ASSERT(a.d_ppContextObjPrev == &b.d_pContextObjNext);
+
+    TS_ASSERT(b.d_pScope == t);
+    TS_ASSERT(b.d_pContextObjRestore != NULL);
+    TS_ASSERT(b.d_pContextObjNext == &a);
+    //TS_ASSERT(b.d_ppContextObjPrev == &t->d_pContextObjList);// THIS ONE FAILS
+
+    d_context->pop();
+
+    TS_ASSERT(s->d_pContext == d_context);
+    TS_ASSERT(s->d_pCMM == d_context->d_pCMM);
+    TS_ASSERT(s->d_level == 0);
+    //TS_ASSERT(s->d_pContextObjList == &b);// THIS ONE FAILS
+
+    TS_ASSERT(a.d_pScope == s);
+    TS_ASSERT(a.d_pContextObjRestore == NULL);
+    TS_ASSERT(a.d_pContextObjNext == NULL);
+    TS_ASSERT(a.d_ppContextObjPrev == &b.d_pContextObjNext);
+
+    TS_ASSERT(b.d_pScope == s);
+    TS_ASSERT(b.d_pContextObjRestore == NULL);
+    TS_ASSERT(b.d_pContextObjNext == &a);
+    TS_ASSERT(b.d_ppContextObjPrev == &s->d_pContextObjList);
+  }
+};
index fb18601a35fb6f56fadb5eb5eca6ed635d73bd04..64c768a13d68b81ee811d770f490f250f9326cf0 100644 (file)
 
 #include <string>
 
+#include "context/context.h"
 #include "expr/node_value.h"
 #include "expr/node_builder.h"
 #include "expr/node_manager.h"
-#include "expr/node.h"
 #include "expr/attribute.h"
-#include "context/context.h"
+#include "expr/node.h"
+#include "theory/theory.h"
+#include "theory/uf/theory_uf.h"
 #include "util/Assert.h"
 
 using namespace CVC4;
@@ -74,24 +76,73 @@ public:
   }
 
   void testAttributeIds() {
-    TS_ASSERT(VarNameAttr::s_id == 0);
-    TS_ASSERT(TestStringAttr1::s_id == 1);
-    TS_ASSERT(TestStringAttr2::s_id == 2);
-    TS_ASSERT((attr::LastAttributeId<string, false>::s_id == 3));
-
-    TS_ASSERT(TypeAttr::s_id == 0);
-    TS_ASSERT((attr::LastAttributeId<void*, false>::s_id == 1));
-
-    TS_ASSERT(TestFlag1::s_id == 0);
-    TS_ASSERT(TestFlag2::s_id == 1);
-    TS_ASSERT(TestFlag3::s_id == 2);
-    TS_ASSERT(TestFlag4::s_id == 3);
-    TS_ASSERT(TestFlag5::s_id == 4);
-    TS_ASSERT((attr::LastAttributeId<bool, false>::s_id == 5));
-  
-    TS_ASSERT(TestFlag1cd::s_id == 0);
-    TS_ASSERT(TestFlag2cd::s_id == 1);
-    TS_ASSERT((attr::LastAttributeId<bool, true>::s_id == 2));
+    // Test that IDs for (a subset of) attributes in the system are
+    // unique and that the LastAttributeId (which would be the next ID
+    // to assign) is greater than all attribute IDs.
+
+    // We used to check ID assignments explicitly.  However, between
+    // compilation modules, you don't get a strong guarantee
+    // (initialization order is somewhat implementation-specific, and
+    // anyway you'd have to change the tests anytime you add an
+    // attribute).  So we back off, and just test that they're unique
+    // and that the next ID to be assigned is strictly greater than
+    // those that have already been assigned.
+
+    unsigned lastId = attr::LastAttributeId<string, false>::s_id;
+    TS_ASSERT_LESS_THAN(VarNameAttr::s_id, lastId);
+    TS_ASSERT_LESS_THAN(TestStringAttr1::s_id, lastId);
+    TS_ASSERT_LESS_THAN(TestStringAttr2::s_id, lastId);
+
+    TS_ASSERT_DIFFERS(VarNameAttr::s_id, TestStringAttr1::s_id);
+    TS_ASSERT_DIFFERS(VarNameAttr::s_id, TestStringAttr2::s_id);
+    TS_ASSERT_DIFFERS(TestStringAttr1::s_id, TestStringAttr2::s_id);
+
+    lastId = attr::LastAttributeId<void*, false>::s_id;
+    TS_ASSERT_LESS_THAN(NodeManager::TypeAttr::s_id, lastId);
+    TS_ASSERT_LESS_THAN(theory::uf::ECAttr::s_id, lastId);
+    TS_ASSERT_DIFFERS(NodeManager::TypeAttr::s_id, theory::uf::ECAttr::s_id);
+
+    lastId = attr::LastAttributeId<bool, false>::s_id;
+    TS_ASSERT_LESS_THAN(NodeManager::AtomicAttr::s_id, lastId);
+    TS_ASSERT_LESS_THAN(theory::Theory::PreRegisteredAttr::s_id, lastId);
+    TS_ASSERT_LESS_THAN(TestFlag1::s_id, lastId);
+    TS_ASSERT_LESS_THAN(TestFlag2::s_id, lastId);
+    TS_ASSERT_LESS_THAN(TestFlag3::s_id, lastId);
+    TS_ASSERT_LESS_THAN(TestFlag4::s_id, lastId);
+    TS_ASSERT_LESS_THAN(TestFlag5::s_id, lastId);
+    TS_ASSERT_DIFFERS(NodeManager::AtomicAttr::s_id,
+                      theory::Theory::PreRegisteredAttr::s_id);
+    TS_ASSERT_DIFFERS(NodeManager::AtomicAttr::s_id, TestFlag1::s_id);
+    TS_ASSERT_DIFFERS(NodeManager::AtomicAttr::s_id, TestFlag2::s_id);
+    TS_ASSERT_DIFFERS(NodeManager::AtomicAttr::s_id, TestFlag3::s_id);
+    TS_ASSERT_DIFFERS(NodeManager::AtomicAttr::s_id, TestFlag4::s_id);
+    TS_ASSERT_DIFFERS(NodeManager::AtomicAttr::s_id, TestFlag5::s_id);
+    TS_ASSERT_DIFFERS(theory::Theory::PreRegisteredAttr::s_id, TestFlag1::s_id);
+    TS_ASSERT_DIFFERS(theory::Theory::PreRegisteredAttr::s_id, TestFlag2::s_id);
+    TS_ASSERT_DIFFERS(theory::Theory::PreRegisteredAttr::s_id, TestFlag3::s_id);
+    TS_ASSERT_DIFFERS(theory::Theory::PreRegisteredAttr::s_id, TestFlag4::s_id);
+    TS_ASSERT_DIFFERS(theory::Theory::PreRegisteredAttr::s_id, TestFlag5::s_id);
+    TS_ASSERT_DIFFERS(TestFlag1::s_id, TestFlag2::s_id);
+    TS_ASSERT_DIFFERS(TestFlag1::s_id, TestFlag3::s_id);
+    TS_ASSERT_DIFFERS(TestFlag1::s_id, TestFlag4::s_id);
+    TS_ASSERT_DIFFERS(TestFlag1::s_id, TestFlag5::s_id);
+    TS_ASSERT_DIFFERS(TestFlag2::s_id, TestFlag3::s_id);
+    TS_ASSERT_DIFFERS(TestFlag2::s_id, TestFlag4::s_id);
+    TS_ASSERT_DIFFERS(TestFlag2::s_id, TestFlag5::s_id);
+    TS_ASSERT_DIFFERS(TestFlag3::s_id, TestFlag4::s_id);
+    TS_ASSERT_DIFFERS(TestFlag3::s_id, TestFlag5::s_id);
+    TS_ASSERT_DIFFERS(TestFlag4::s_id, TestFlag5::s_id);
+
+    lastId = attr::LastAttributeId<bool, true>::s_id;
+    TS_ASSERT_LESS_THAN(theory::Theory::RegisteredAttr::s_id, lastId);
+    TS_ASSERT_LESS_THAN(TestFlag1cd::s_id, lastId);
+    TS_ASSERT_LESS_THAN(TestFlag2cd::s_id, lastId);
+    TS_ASSERT_DIFFERS(theory::Theory::RegisteredAttr::s_id, TestFlag1cd::s_id);
+    TS_ASSERT_DIFFERS(theory::Theory::RegisteredAttr::s_id, TestFlag2cd::s_id);
+    TS_ASSERT_DIFFERS(TestFlag1cd::s_id, TestFlag2cd::s_id);
+
+    lastId = attr::LastAttributeId<TNode, false>::s_id;
+    TS_ASSERT_LESS_THAN(theory::RewriteCache::s_id, lastId);
   }
 
   void testCDAttributes() {
index e253b4a24ba7474778d4d19fcccee50a637fd61d..03d4ba31c1df169cc168905a0fca1036cb851dca 100644 (file)
@@ -354,7 +354,9 @@ public:
     TS_ASSERT(mult->isAtomic());
     TS_ASSERT(plus->isAtomic());
     TS_ASSERT(d->isAtomic());
-    TS_ASSERT(!null->isAtomic());
+#ifdef CVC4_ASSERTIONS
+    TS_ASSERT_THROWS(null->isAtomic(), IllegalArgumentException);
+#endif /* CVC4_ASSERTIONS */
 
     TS_ASSERT(i1->isAtomic());
     TS_ASSERT(i2->isAtomic());
@@ -368,6 +370,12 @@ public:
     TS_ASSERT(!x.isAtomic());
     TS_ASSERT(!y.isAtomic());
     TS_ASSERT(!z.isAtomic());
+
+    Expr w1 = d_em->mkExpr(PLUS, d_em->mkExpr(ITE, z, *i1, *i2), *i2);
+    Expr w2 = d_em->mkExpr(PLUS, d_em->mkExpr(MULT, *i1, *i2), *i2);
+
+    TS_ASSERT(!w1.isAtomic());
+    TS_ASSERT(w2.isAtomic());
   }
 
   void testGetConst() {
index 81aa424f8a6a4a71f461aac34b196d43ac653130..2a7b3623eb76726d93cdfbe04c8e78da7041fd7f 100644 (file)
@@ -244,9 +244,9 @@ public:
 
     Node n = noKind;
 
-#ifdef CVC4_DEBUG
-    TS_ASSERT_THROWS_ANYTHING(noKind.getKind(););
-#endif
+#ifdef CVC4_ASSERTIONS
+    TS_ASSERT_THROWS(noKind.getKind(), AssertionException);
+#endif /* CVC4_ASSERTIONS */
 
     NodeBuilder<> spec(specKind);
     TS_ASSERT_EQUALS(spec.getKind(), specKind);
@@ -277,11 +277,11 @@ public:
     push_back(noKind, K);
     TS_ASSERT_EQUALS(noKind.getNumChildren(), K+K);
 
-#ifdef CVC4_DEBUG
+#ifdef CVC4_ASSERTIONS
     noKind << specKind;
     n = noKind;
-    TS_ASSERT_THROWS_ANYTHING( noKind.getNumChildren() );
-#endif
+    TS_ASSERT_THROWS( noKind.getNumChildren(), AssertionException );
+#endif /* CVC4_ASSERTIONS */
   }
 
   void testOperatorSquare() {
@@ -297,10 +297,10 @@ public:
     Node i_2 = d_nm->mkConst(true);
     Node i_K = d_nm->mkNode(NOT, i_0);
 
-#ifdef CVC4_DEBUG
-    TS_ASSERT_THROWS_ANYTHING(arr[-1];);
-    TS_ASSERT_THROWS_ANYTHING(arr[0];);
-#endif
+#ifdef CVC4_ASSERTIONS
+    TS_ASSERT_THROWS(arr[-1], AssertionException);
+    TS_ASSERT_THROWS(arr[0], AssertionException);
+#endif /* CVC4_ASSERTIONS */
 
     arr << i_0;
 
@@ -330,10 +330,10 @@ public:
     }
     TS_ASSERT_EQUALS(arr[K], i_K);
 
-#ifdef CVC4_DEBUG
+#ifdef CVC4_ASSERTIONS
     Node n = arr;
-    TS_ASSERT_THROWS_ANYTHING(arr[0]);
-#endif
+    TS_ASSERT_THROWS(arr[0], AssertionException);
+#endif /* CVC4_ASSERTIONS */
   }
 
   void testClear() {
@@ -469,6 +469,10 @@ public:
     Node p = d_nm->mkNode(PLUS, z, d_nm->mkNode(UMINUS, x), z);
     Node q = d_nm->mkNode(AND, x, z, d_nm->mkNode(NOT, y));
 
+#ifdef CVC4_ASSERTIONS
+    TS_ASSERT_THROWS(d_nm->mkNode(XOR, y, x, x), AssertionException);
+#endif /* CVC4_ASSERTIONS */
+
     NodeBuilder<> b;
 
     // test append(TNode)
index 427a22c9d8cd8e656b747c5244e9cfadc0a7089b..c6da4829100ed8fab28359a3dffc4139e29c2cd3 100644 (file)
@@ -82,13 +82,13 @@ public:
   }
 };
 
-class DummyTheory : public TheoryImpl<DummyTheory> {
+class DummyTheory : public Theory {
 public:
   set<Node> d_registered;
   vector<Node> d_getSequence;
 
   DummyTheory(Context* ctxt, OutputChannel& out) :
-    TheoryImpl<DummyTheory>(ctxt, out) {
+    Theory(ctxt, out) {
   }
 
   void registerTerm(TNode n) {