diff options
author | Morgan Deters <mdeters@gmail.com> | 2011-09-02 20:41:08 +0000 |
---|---|---|
committer | Morgan Deters <mdeters@gmail.com> | 2011-09-02 20:41:08 +0000 |
commit | 1d18e5ebed9a5b20ed6a8fe21d11842acf6fa7ea (patch) | |
tree | 7074f04453914bc377ff6aeb307dd17b82b76ff3 /src | |
parent | 74770f1071e6102795393cf65dd0c651038db6b4 (diff) |
Merge from my post-smtcomp branch. Includes:
Dumping infrastructure. Can dump preprocessed queries and clauses. Can
also dump queries (for testing with another solver) to see if any conflicts
are missed, T-propagations are missed, all lemmas are T-valid, etc. For a
full list of options see --dump=help.
CUDD building much cleaner.
Documentation and assertion fixes.
Printer improvements, printing of commands in language-defined way, etc.
Typechecker stuff in expr package now autogenerated, no need to manually
edit the expr package when adding a new theory.
CVC3 compatibility layer (builds as libcompat).
SWIG detection and language binding support (infrastructure).
Support for some Z3 extended commands (like datatypes) in SMT-LIBv2 mode
(when not in compliance mode).
Copyright and file headers regenerated.
Diffstat (limited to 'src')
271 files changed, 7088 insertions, 3564 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index de9aa0339..9ffe249ee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,10 +17,12 @@ AM_CPPFLAGS = \ -I@srcdir@/include -I@srcdir@ -I@builddir@ AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) -SUBDIRS = lib expr util context theory prop smt printer . parser main +SUBDIRS = lib expr util context theory prop smt printer bindings . parser compat main lib_LTLIBRARIES = libcvc4.la +if HAVE_CXXTESTGEN noinst_LTLIBRARIES = libcvc4_noinst.la +endif libcvc4_la_LDFLAGS = -version-info $(LIBCVC4_VERSION) @@ -57,10 +59,6 @@ EXTRA_DIST = \ include/cvc4_private.h \ include/cvc4_public.h -publicheaders = \ - include/cvc4_public.h \ - include/cvc4parser_public.h - subversion_versioninfo.cpp: svninfo $(AM_V_GEN)( \ if test -s svninfo; then \ @@ -87,16 +85,39 @@ svninfo: svninfo.tmp svninfo.tmp: $(AM_V_GEN)(cd "$(top_srcdir)" && svn info && echo "Modifications: `test -z \"\`svn status -q\`\" && echo false || echo true`") >"$@" 2>/dev/null || true -install-data-local: $(publicheaders) - $(mkinstalldirs) $(DESTDIR)$(prefix)$(includedir)/cvc4 - @for f in $(publicheaders); do \ - echo $(INSTALL_DATA) "$(srcdir)/$$f" "$(DESTDIR)$(prefix)$(includedir)/cvc4"; \ - $(INSTALL_DATA) "$(srcdir)/$$f" "$(DESTDIR)$(prefix)$(includedir)/cvc4"; \ +install-data-local: + (echo include/cvc4_public.h; \ + find * -name '*.h' | \ + xargs grep -l '^# *include *"cvc4.*_public\.h"'; \ + (cd "$(srcdir)" && find * -name '*.h' | \ + xargs grep -l '^# *include *"cvc4.*_public\.h"')) | \ + while read f; do \ + if expr "$$f" : ".*_\(template\|private\|test_utils\)\.h$$" &>/dev/null; then \ + continue; \ + fi; \ + d="$$(echo "$$f" | sed 's,^include/,,')"; \ + $(mkinstalldirs) "$$(dirname "$(DESTDIR)$(includedir)/cvc4/$$d")"; \ + if [ -e "$$f" ]; then \ + path="$$f"; \ + else \ + path="$(srcdir)/$$f"; \ + fi; \ + echo $(INSTALL_DATA) "$$path" "$(DESTDIR)$(includedir)/cvc4/$$d"; \ + $(INSTALL_DATA) "$$path" "$(DESTDIR)$(includedir)/cvc4/$$d"; \ done uninstall-local: - @for f in $(publicheaders); do \ - f=`echo "$$f" | sed 's,.*/,,'`; \ - rm -f "$(DESTDIR)$(prefix)$(includedir)/cvc4/$$f"; \ + -(echo include/cvc4_public.h; \ + find * -name '*.h' | \ + xargs grep -l '^# *include *"cvc4.*_public\.h"'; \ + (cd "$(srcdir)" && find * -name '*.h' | \ + xargs grep -l '^# *include *"cvc4.*_public\.h"')) | \ + while read f; do \ + if expr "$$f" : ".*_\(template\|private\|test_utils\)\.h$$" &>/dev/null; then \ + continue; \ + fi; \ + d="$$(echo "$$f" | sed 's,^include/,,')"; \ + rm -f "$(DESTDIR)$(includedir)/cvc4/$$d"; \ + rmdir -p "$$(dirname "$(DESTDIR)$(includedir)/cvc4/$$d")" 2>/dev/null; \ done - @rmdir "$(DESTDIR)$(prefix)$(includedir)/cvc4" + -rmdir "$(DESTDIR)$(includedir)/cvc4" diff --git a/src/bindings/Makefile b/src/bindings/Makefile new file mode 100644 index 000000000..419d3a1b4 --- /dev/null +++ b/src/bindings/Makefile @@ -0,0 +1,4 @@ +topdir = ../.. +srcdir = src/bindings + +include $(topdir)/Makefile.subdir diff --git a/src/bindings/Makefile.am b/src/bindings/Makefile.am new file mode 100644 index 000000000..cd314f957 --- /dev/null +++ b/src/bindings/Makefile.am @@ -0,0 +1,58 @@ +AM_CPPFLAGS = \ + -D__BUILDING_CVC4BINDINGSLIB \ + -I@srcdir@/../include -I@srcdir@/.. -I@builddir@/.. +AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN) + +lib_LTLIBRARIES = +if CVC4_LANGUAGE_BINDING_JAVA +lib_LTLIBRARIES += libcvc4bindings_java.la +endif +# cvc4bindings_csharp.so \ +# cvc4bindings_perl.so \ +# cvc4bindings_php.so \ +# cvc4bindings_python.so \ +# cvc4bindings_ocaml.so \ +# cvc4bindings_ruby.so \ +# cvc4bindings_tcl.so + +nodist_libcvc4bindings_java_la_SOURCES = java.cpp +#nodist_cvc4bindings_csharp_so_SOURCES = csharp.cpp +#nodist_cvc4bindings_perl_so_SOURCES = perl.cpp +#nodist_cvc4bindings_php_so_SOURCES = php.cpp +#nodist_cvc4bindings_python_so_SOURCES = python.cpp +#nodist_cvc4bindings_ocaml_so_SOURCES = ocaml.cpp +#nodist_cvc4bindings_ruby_so_SOURCES = ruby.cpp +#nodist_cvc4bindings_tcl_so_SOURCES = tcl.cpp + +BUILT_SOURCES = \ + java.cpp \ + csharp.cpp \ + perl.cpp \ + php.cpp \ + python.cpp \ + ocaml.cpp \ + ruby.cpp \ + tcl.cpp + +CLEANFILES = \ + $(BUILT_SOURCES) \ + cvc4.java \ + cvc4.cs \ + cvc4JNI.java \ + cvc4.php \ + cvc4PINVOKE.cs \ + cvc4.pm \ + cvc4.py \ + php_cvc4.h + +java.lo: java.cpp; $(LTCXXCOMPILE) $(JAVA_INCLUDES) -o $@ $< +java.cpp:: +csharp.cpp:: +perl.cpp:: +php.cpp:: +python.cpp:: +ocaml.cpp:: +ruby.cpp:: +tcl.cpp:: +$(patsubst %,%.cpp,$(filter-out c c++,$(CVC4_LANGUAGE_BINDINGS))):: %.cpp: @srcdir@/../smt/smt_engine.h + $(AM_V_GEN)$(SWIG) -w503 -I@srcdir@/../include -I@srcdir@/.. -I@builddir@/.. -module cvc4 -c++ -$(patsubst %.cpp,%,$@) -o $@ $< diff --git a/src/compat/Makefile b/src/compat/Makefile new file mode 100644 index 000000000..675bd8827 --- /dev/null +++ b/src/compat/Makefile @@ -0,0 +1,4 @@ +topdir = ../.. +srcdir = src/compat + +include $(topdir)/Makefile.subdir diff --git a/src/compat/Makefile.am b/src/compat/Makefile.am new file mode 100644 index 000000000..905eaa6c4 --- /dev/null +++ b/src/compat/Makefile.am @@ -0,0 +1,50 @@ +# LIBCVC4COMPAT_VERSION (-version-info) is in the form current:revision:age +# +# current - +# increment if interfaces have been added, removed or changed +# revision - +# increment if source code has changed +# set to zero if current is incremented +# age - +# increment if interfaces have been added +# set to zero if interfaces have been removed +# or changed +# +LIBCVC4COMPAT_VERSION = @CVC4_COMPAT_LIBRARY_VERSION@ + +AM_CPPFLAGS = \ + -D__BUILDING_CVC4COMPATLIB \ + -I@srcdir@/../include -I@srcdir@/.. -I@builddir@/.. $(ANTLR_INCLUDES) +AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) + +if CVC4_BUILD_LIBCOMPAT + +nobase_lib_LTLIBRARIES = libcvc4compat.la +if HAVE_CXXTESTGEN +noinst_LTLIBRARIES = libcvc4compat_noinst.la +endif + +libcvc4compat_la_LDFLAGS = \ + -version-info $(LIBCVC4COMPAT_VERSION) +libcvc4compat_noinst_la_LDFLAGS = + +libcvc4compat_la_LIBADD = \ + @builddir@/../lib/libreplacements.la +libcvc4compat_noinst_la_LIBADD = \ + @builddir@/../lib/libreplacements.la + +libcvc4compat_la_SOURCES = \ + cvc3_compat.h \ + cvc3_compat.cpp + +libcvc4compat_noinst_la_SOURCES = \ + cvc3_compat.h \ + cvc3_compat.cpp + +else + +EXTRA_DIST = \ + cvc3_compat.h \ + cvc3_compat.cpp + +endif diff --git a/src/compat/cvc3_compat.cpp b/src/compat/cvc3_compat.cpp new file mode 100644 index 000000000..99cf4e84b --- /dev/null +++ b/src/compat/cvc3_compat.cpp @@ -0,0 +1,1886 @@ +/********************* */ +/*! \file cvc3_compat.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief CVC3 compatibility layer for CVC4 + ** + ** CVC3 compatibility layer for CVC4. + **/ + +#include "compat/cvc3_compat.h" + +#include "expr/kind.h" +#include "expr/command.h" + +#include "util/rational.h" +#include "util/integer.h" +#include "util/bitvector.h" + +#include "parser/parser.h" +#include "parser/parser_builder.h" + +#include <iostream> +#include <string> +#include <sstream> + +using namespace std; + +namespace CVC3 { + +std::string int2string(int n) { + std::ostringstream ss; + ss << n; + return ss.str(); +} + +std::ostream& operator<<(std::ostream& out, CLFlagType clft) { + switch(clft) { + case CLFLAG_NULL: out << "CLFLAG_NULL"; + case CLFLAG_BOOL: out << "CLFLAG_BOOL"; + case CLFLAG_INT: out << "CLFLAG_INT"; + case CLFLAG_STRING: out << "CLFLAG_STRING"; + case CLFLAG_STRVEC: out << "CLFLAG_STRVEC"; + default: out << "CLFlagType!UNKNOWN"; + } + + return out; +} + +std::ostream& operator<<(std::ostream& out, QueryResult qr) { + switch(qr) { + case SATISFIABLE: out << "SATISFIABLE/INVALID"; break; + case UNSATISFIABLE: out << "VALID/UNSATISFIABLE"; break; + case ABORT: out << "ABORT"; break; + case UNKNOWN: out << "UNKNOWN"; break; + default: out << "QueryResult!UNKNOWN"; + } + + return out; +} + +std::ostream& operator<<(std::ostream& out, FormulaValue fv) { + switch(fv) { + case TRUE_VAL: out << "TRUE_VAL"; break; + case FALSE_VAL: out << "FALSE_VAL"; break; + case UNKNOWN_VAL: out << "UNKNOWN_VAL"; break; + default: out << "FormulaValue!UNKNOWN"; + } + + return out; +} + +std::ostream& operator<<(std::ostream& out, CVC3CardinalityKind c) { + switch(c) { + case CARD_FINITE: out << "CARD_FINITE"; break; + case CARD_INFINITE: out << "CARD_INFINITE"; break; + case CARD_UNKNOWN: out << "CARD_UNKNOWN"; break; + default: out << "CVC3CardinalityKind!UNKNOWN"; + } + + return out; +} + +static string toString(CLFlagType clft) { + stringstream sstr; + sstr << clft; + return sstr.str(); +} + +bool operator==(const Cardinality& c, CVC3CardinalityKind d) { + switch(d) { + case CARD_FINITE: + return c.isFinite(); + case CARD_INFINITE: + return c.isInfinite(); + case CARD_UNKNOWN: + return c.isUnknown(); + } + + Unhandled(d); +} + +bool operator==(CVC3CardinalityKind d, const Cardinality& c) { + return c == d; +} + +bool operator!=(const Cardinality& c, CVC3CardinalityKind d) { + return !(c == d); +} + +bool operator!=(CVC3CardinalityKind d, const Cardinality& c) { + return !(c == d); +} + +Type::Type() : + CVC4::Type() { +} + +Type::Type(const CVC4::Type& type) : + CVC4::Type(type) { +} + +Type::Type(const Type& type) : + CVC4::Type(type) { +} + +Expr Type::getExpr() const { + Unimplemented(); +} + +int Type::arity() const { + return isSort() ? CVC4::SortType(*this).getParamTypes().size() : 0; +} + +Type Type::operator[](int i) const { + return Type(CVC4::Type(CVC4::SortType(*this).getParamTypes()[i])); +} + +bool Type::isBool() const { + return isBoolean(); +} + +bool Type::isSubtype() const { + return false; +} + +Cardinality Type::card() const { + return getCardinality(); +} + +Expr Type::enumerateFinite(Unsigned n) const { + Unimplemented(); +} + +Unsigned Type::sizeFinite() const { + return getCardinality().getFiniteCardinality().getUnsignedLong(); +} + +Type Type::typeBool(ExprManager* em) { + return Type(CVC4::Type(em->booleanType())); +} + +Type Type::funType(const std::vector<Type>& typeDom, + const Type& typeRan) { + const vector<CVC4::Type>& dom = + *reinterpret_cast<const vector<CVC4::Type>*>(&typeDom); + return Type(typeRan.getExprManager()->mkFunctionType(dom, typeRan)); +} + +Type Type::funType(const Type& typeRan) const { + return Type(getExprManager()->mkFunctionType(*this, typeRan)); +} + +Expr::Expr() : CVC4::Expr() { +} + +Expr::Expr(const Expr& e) : CVC4::Expr(e) { +} + +Expr::Expr(const CVC4::Expr& e) : CVC4::Expr(e) { +} + +Expr Expr::eqExpr(const Expr& right) const { + return getEM()->mkExpr(CVC4::kind::EQUAL, *this, right); +} + +Expr Expr::notExpr() const { + return getEM()->mkExpr(CVC4::kind::NOT, *this); +} + +Expr Expr::negate() const { + // avoid double-negatives + return (getKind() == CVC4::kind::NOT) ? + (*this)[0] : + Expr(getEM()->mkExpr(CVC4::kind::NOT, *this)); +} + +Expr Expr::andExpr(const Expr& right) const { + return getEM()->mkExpr(CVC4::kind::AND, *this, right); +} + +Expr Expr::orExpr(const Expr& right) const { + return getEM()->mkExpr(CVC4::kind::OR, *this, right); +} + +Expr Expr::iteExpr(const Expr& thenpart, const Expr& elsepart) const { + return getEM()->mkExpr(CVC4::kind::ITE, *this, thenpart, elsepart); +} + +Expr Expr::iffExpr(const Expr& right) const { + return getEM()->mkExpr(CVC4::kind::IFF, *this, right); +} + +Expr Expr::impExpr(const Expr& right) const { + return getEM()->mkExpr(CVC4::kind::IMPLIES, *this, right); +} + +Expr Expr::xorExpr(const Expr& right) const { + return getEM()->mkExpr(CVC4::kind::XOR, *this, right); +} + +Expr Expr::substExpr(const std::vector<Expr>& oldTerms, + const std::vector<Expr>& newTerms) const { + const vector<CVC4::Expr>& o = + *reinterpret_cast<const vector<CVC4::Expr>*>(&oldTerms); + const vector<CVC4::Expr>& n = + *reinterpret_cast<const vector<CVC4::Expr>*>(&newTerms); + + return Expr(substitute(o, n)); +} + +Expr Expr::substExpr(const ExprHashMap<Expr>& oldToNew) const { + const hash_map<CVC4::Expr, CVC4::Expr, CVC4::ExprHashFunction>& o2n = + *reinterpret_cast<const hash_map<CVC4::Expr, CVC4::Expr, CVC4::ExprHashFunction>*>(&oldToNew); + + return Expr(substitute(o2n)); +} + +Expr Expr::operator!() const { + return notExpr(); +} + +Expr Expr::operator&&(const Expr& right) const { + return andExpr(right); +} + +Expr Expr::operator||(const Expr& right) const { + return orExpr(right); +} + +size_t Expr::hash(const Expr& e) { + return CVC4::ExprHashFunction()(e); +} + +size_t Expr::hash() const { + return CVC4::ExprHashFunction()(*this); +} + +bool Expr::isFalse() const { + return getKind() == CVC4::kind::CONST_BOOLEAN && !getConst<bool>(); +} + +bool Expr::isTrue() const { + return getKind() == CVC4::kind::CONST_BOOLEAN && getConst<bool>(); +} + +bool Expr::isBoolConst() const { + return getKind() == CVC4::kind::CONST_BOOLEAN; +} + +bool Expr::isVar() const { + return isVariable(); +} + +bool Expr::isEq() const { + return getKind() == CVC4::kind::EQUAL; +} + +bool Expr::isNot() const { + return getKind() == CVC4::kind::NOT; +} + +bool Expr::isAnd() const { + return getKind() == CVC4::kind::AND; +} + +bool Expr::isOr() const { + return getKind() == CVC4::kind::OR; +} + +bool Expr::isITE() const { + return getKind() == CVC4::kind::ITE; +} + +bool Expr::isIff() const { + return getKind() == CVC4::kind::IFF; +} + +bool Expr::isImpl() const { + return getKind() == CVC4::kind::IMPLIES; +} + +bool Expr::isXor() const { + return getKind() == CVC4::kind::XOR; +} + +bool Expr::isRational() const { + return getKind() == CVC4::kind::CONST_RATIONAL; +} + +bool Expr::isSkolem() const { + return getKind() == CVC4::kind::SKOLEM; +} + +std::vector< std::vector<Expr> > Expr::getTriggers() const { + return vector< vector<Expr> >(); +} + +ExprManager* Expr::getEM() const { + return getExprManager(); +} + +std::vector<Expr> Expr::getKids() const { + vector<CVC4::Expr> v = getChildren(); + return *reinterpret_cast<vector<Expr>*>(&v); +} + +ExprIndex Expr::getIndex() const { + return getId(); +} + +int Expr::arity() const { + return getNumChildren(); +} + +Expr Expr::unnegate() const { + return isNot() ? Expr((*this)[0]) : *this; +} + +bool Expr::isInitialized() const { + return !isNull(); +} + +Type Expr::getType() const { + return Type(this->CVC4::Expr::getType()); +} + +Type Expr::lookupType() const { + return getType(); +} + +Expr Expr::operator[](int i) const { + return Expr(this->CVC4::Expr::operator[](i)); +} + +CLFlag::CLFlag(bool b, const std::string& help, bool display) : + d_tp(CLFLAG_BOOL) { + d_data.b = b; +} + +CLFlag::CLFlag(int i, const std::string& help, bool display) : + d_tp(CLFLAG_INT) { + d_data.i = i; +} + +CLFlag::CLFlag(const std::string& s, const std::string& help, bool display) : + d_tp(CLFLAG_STRING) { + d_data.s = new string(s); +} + +CLFlag::CLFlag(const char* s, const std::string& help, bool display) : + d_tp(CLFLAG_STRING) { + d_data.s = new string(s); +} + +CLFlag::CLFlag(const std::vector<std::pair<std::string,bool> >& sv, + const std::string& help, bool display) : + d_tp(CLFLAG_STRVEC) { + d_data.sv = new vector<pair<string, bool> >(sv); +} + +CLFlag::CLFlag() : + d_tp(CLFLAG_NULL) { +} + +CLFlag::CLFlag(const CLFlag& f) : + d_tp(f.d_tp) { + switch(d_tp) { + case CLFLAG_STRING: + d_data.s = new string(*f.d_data.s); + break; + case CLFLAG_STRVEC: + d_data.sv = new vector<pair<string, bool> >(*f.d_data.sv); + break; + default: + d_data = f.d_data; + } +} + +CLFlag::~CLFlag() { + switch(d_tp) { + case CLFLAG_STRING: + delete d_data.s; + break; + case CLFLAG_STRVEC: + delete d_data.sv; + break; + default: + ; // nothing to do + } +} + +CLFlag& CLFlag::operator=(const CLFlag& f) { + if(this == &f) { + // self-assignment + return *this; + } + + // try to preserve the existing heap objects if possible + if(d_tp == f.d_tp) { + switch(d_tp) { + case CLFLAG_STRING: + *d_data.s = *f.d_data.s; + break; + case CLFLAG_STRVEC: + *d_data.sv = *f.d_data.sv; + break; + default: + d_data = f.d_data; + } + } else { + switch(d_tp) { + case CLFLAG_STRING: + delete d_data.s; + break; + case CLFLAG_STRVEC: + delete d_data.sv; + break; + default: + ; // nothing to do here + } + + switch(f.d_tp) { + case CLFLAG_STRING: + d_data.s = new string(*f.d_data.s); + break; + case CLFLAG_STRVEC: + d_data.sv = new vector<pair<string, bool> >(*f.d_data.sv); + break; + default: + d_data = f.d_data; + } + } + d_tp = f.d_tp; + return *this; +} + +CLFlag& CLFlag::operator=(bool b) { + CheckArgument(d_tp == CLFLAG_BOOL, this); + d_data.b = b; + return *this; +} + +CLFlag& CLFlag::operator=(int i) { + CheckArgument(d_tp == CLFLAG_INT, this); + d_data.i = i; + return *this; +} + +CLFlag& CLFlag::operator=(const std::string& s) { + CheckArgument(d_tp == CLFLAG_STRING, this); + *d_data.s = s; + return *this; +} + +CLFlag& CLFlag::operator=(const char* s) { + CheckArgument(d_tp == CLFLAG_STRING, this); + *d_data.s = s; + return *this; +} + +CLFlag& CLFlag::operator=(const std::pair<std::string, bool>& p) { + CheckArgument(d_tp == CLFLAG_STRVEC, this); + d_data.sv->push_back(p); + return *this; +} + +CLFlag& CLFlag::operator=(const std::vector<std::pair<std::string, bool> >& sv) { + CheckArgument(d_tp == CLFLAG_STRVEC, this); + *d_data.sv = sv; + return *this; +} + +CLFlagType CLFlag::getType() const { + return d_tp; +} + +bool CLFlag::modified() const { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +bool CLFlag::display() const { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +const bool& CLFlag::getBool() const { + CheckArgument(d_tp == CLFLAG_BOOL, this); + return d_data.b; +} + +const int& CLFlag::getInt() const { + CheckArgument(d_tp == CLFLAG_INT, this); + return d_data.i; +} + +const std::string& CLFlag::getString() const { + CheckArgument(d_tp == CLFLAG_STRING, this); + return *d_data.s; +} + +const std::vector<std::pair<std::string, bool> >& CLFlag::getStrVec() const { + CheckArgument(d_tp == CLFLAG_STRVEC, this); + return *d_data.sv; +} + +const std::string& CLFlag::getHelp() const { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void CLFlags::addFlag(const std::string& name, const CLFlag& f) { + d_map[name] = f; +} + +size_t CLFlags::countFlags(const std::string& name) const { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +size_t CLFlags::countFlags(const std::string& name, + std::vector<std::string>& names) const { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +const CLFlag& CLFlags::getFlag(const std::string& name) const { + FlagMap::const_iterator i = d_map.find(name); + CheckArgument(i != d_map.end(), name, "No command-line flag by that name, or not supported."); + return (*i).second; +} + +const CLFlag& CLFlags::operator[](const std::string& name) const { + return getFlag(name); +} + +void CLFlags::setFlag(const std::string& name, const CLFlag& f) { + FlagMap::iterator i = d_map.find(name); + CheckArgument(i != d_map.end(), name, "No command-line flag by that name, or not supported."); + CheckArgument((*i).second.getType() == f.getType(), f, + "Command-line flag `%s' has type %s, but caller tried to set to a %s.", + name.c_str(), + toString((*i).second.getType()).c_str(), + toString(f.getType()).c_str()); + (*i).second = f; +} + +void CLFlags::setFlag(const std::string& name, bool b) { + FlagMap::iterator i = d_map.find(name); + CheckArgument(i != d_map.end(), name, "No command-line flag by that name, or not supported."); + (*i).second = b; +} + +void CLFlags::setFlag(const std::string& name, int i) { + FlagMap::iterator it = d_map.find(name); + CheckArgument(it != d_map.end(), name, "No command-line flag by that name, or not supported."); + (*it).second = i; +} + +void CLFlags::setFlag(const std::string& name, const std::string& s) { + FlagMap::iterator i = d_map.find(name); + CheckArgument(i != d_map.end(), name, "No command-line flag by that name, or not supported."); + (*i).second = s; +} + +void CLFlags::setFlag(const std::string& name, const char* s) { + FlagMap::iterator i = d_map.find(name); + CheckArgument(i != d_map.end(), name, "No command-line flag by that name, or not supported."); + (*i).second = s; +} + +void CLFlags::setFlag(const std::string& name, const std::pair<std::string, bool>& p) { + FlagMap::iterator i = d_map.find(name); + CheckArgument(i != d_map.end(), name, "No command-line flag by that name, or not supported."); + (*i).second = p; +} + +void CLFlags::setFlag(const std::string& name, + const std::vector<std::pair<std::string, bool> >& sv) { + FlagMap::iterator i = d_map.find(name); + CheckArgument(i != d_map.end(), name, "No command-line flag by that name, or not supported."); + (*i).second = sv; +} + +ValidityChecker::ValidityChecker() : + d_clflags(new CLFlags()), + d_em(), + d_smt(&d_em) { +} + +ValidityChecker::ValidityChecker(const CLFlags& clflags) : + d_clflags(new CLFlags(clflags)), + d_em(), + d_smt(&d_em) { +} + +ValidityChecker::~ValidityChecker() { + delete d_clflags; +} + +CLFlags& ValidityChecker::getFlags() const { + return *d_clflags; +} + +void ValidityChecker::reprocessFlags() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +CLFlags ValidityChecker::createFlags() { + CLFlags flags; + + // We expect the user to type cvc3 -h to get help, which will set + // the "help" flag to false; that's why it's initially true. + + // Overall system control flags + flags.addFlag("timeout", CLFlag(0, "Kill cvc3 process after given number of seconds (0==no limit)")); + flags.addFlag("stimeout", CLFlag(0, "Set time resource limit in tenths of seconds for a query(0==no limit)")); + flags.addFlag("resource", CLFlag(0, "Set finite resource limit (0==no limit)")); + flags.addFlag("mm", CLFlag("chunks", "Memory manager (chunks, malloc)")); + + // Information printing flags + flags.addFlag("help",CLFlag(true, "print usage information and exit")); + flags.addFlag("unsupported",CLFlag(true, "print usage for old/unsupported/experimental options")); + flags.addFlag("version",CLFlag(true, "print version information and exit")); + flags.addFlag("interactive", CLFlag(false, "Interactive mode")); + flags.addFlag("stats", CLFlag(false, "Print run-time statistics")); + flags.addFlag("seed", CLFlag(1, "Set the seed for random sequence")); + flags.addFlag("printResults", CLFlag(true, "Print results of interactive commands.")); + flags.addFlag("dump-log", CLFlag("", "Dump API call log in CVC3 input " + "format to given file " + "(off when file name is \"\")")); + flags.addFlag("parse-only", CLFlag(false,"Parse the input, then exit.")); + + //Translation related flags + flags.addFlag("expResult", CLFlag("", "For smtlib translation. Give the expected result", false)); + flags.addFlag("category", CLFlag("unknown", "For smtlib translation. Give the category", false)); + flags.addFlag("translate", CLFlag(false, "Produce a complete translation from " + "the input language to output language. ")); + flags.addFlag("real2int", CLFlag(false, "When translating, convert reals to integers.", false)); + flags.addFlag("convertArith", CLFlag(false, "When translating, try to rewrite arith terms into smt-lib subset", false)); + flags.addFlag("convert2diff", CLFlag("", "When translating, try to force into difference logic. Legal values are int and real.", false)); + flags.addFlag("iteLiftArith", CLFlag(false, "For translation. If true, ite's are lifted out of arith exprs.", false)); + flags.addFlag("convertArray", CLFlag(false, "For translation. If true, arrays are converted to uninterpreted functions if possible.", false)); + flags.addFlag("combineAssump", CLFlag(false, "For translation. If true, assumptions are combined into the query.", false)); + flags.addFlag("convert2array", CLFlag(false, "For translation. If true, try to convert to array-only theory", false)); + flags.addFlag("convertToBV",CLFlag(0, "For translation. Set to nonzero to convert ints to bv's of that length", false)); + flags.addFlag("convert-eq-iff",CLFlag(false, "Convert equality on Boolean expressions to iff.", false)); + flags.addFlag("preSimplify",CLFlag(false, "Simplify each assertion or query before translating it", false)); + flags.addFlag("dump-tcc", CLFlag(false, "Compute and dump TCC only")); + flags.addFlag("trans-skip-pp", CLFlag(false, "Skip preprocess step in translation module", false)); + flags.addFlag("trans-skip-difficulty", CLFlag(false, "Leave out difficulty attribute during translation to SMT v2.0", false)); + flags.addFlag("promote", CLFlag(true, "Promote undefined logic combinations to defined logic combinations during translation to SMT", false)); + + // Parser related flags + flags.addFlag("old-func-syntax",CLFlag(false, "Enable parsing of old-style function syntax", false)); + + // Pretty-printing related flags + flags.addFlag("dagify-exprs", + CLFlag(true, "Print expressions with sharing as DAGs")); + flags.addFlag("lang", CLFlag("presentation", "Input language " + "(presentation, smt, smt2, internal)")); + flags.addFlag("output-lang", CLFlag("", "Output language " + "(presentation, smtlib, simplify, internal, lisp, tptp, spass)")); + flags.addFlag("indent", CLFlag(false, "Print expressions with indentation")); + flags.addFlag("width", CLFlag(80, "Suggested line width for printing")); + flags.addFlag("print-depth", CLFlag(-1, "Max. depth to print expressions ")); + flags.addFlag("print-assump", CLFlag(false, "Print assumptions in Theorems ")); + + // Search Engine (SAT) related flags + flags.addFlag("sat",CLFlag("minisat", "choose a SAT solver to use " + "(sat, minisat)")); + flags.addFlag("de",CLFlag("dfs", "choose a decision engine to use " + "(dfs, sat)")); + + // Proofs and Assumptions + flags.addFlag("proofs", CLFlag(false, "Produce proofs")); + flags.addFlag("check-proofs", CLFlag(false, "Check proofs on-the-fly")); + flags.addFlag("minimizeClauses", CLFlag(false, "Use brute-force minimization of clauses", false)); + flags.addFlag("dynack", CLFlag(false, "Use dynamic Ackermannization", false)); + flags.addFlag("smart-clauses", CLFlag(true, "Learn multiple clauses per conflict")); + // Core framework switches + flags.addFlag("tcc", CLFlag(false, "Check TCCs for each ASSERT and QUERY")); + flags.addFlag("cnf", CLFlag(true, "Convert top-level Boolean formulas to CNF", false)); + flags.addFlag("ignore-cnf-vars", CLFlag(false, "Do not split on aux. CNF vars (with +cnf)", false)); + flags.addFlag("orig-formula", CLFlag(false, "Preserve the original formula with +cnf (for splitter heuristics)", false)); + flags.addFlag("liftITE", CLFlag(false, "Eagerly lift all ITE exprs")); + flags.addFlag("iflift", CLFlag(false, "Translate if-then-else terms to CNF (with +cnf)", false)); + flags.addFlag("circuit", CLFlag(false, "With +cnf, use circuit propagation", false)); + flags.addFlag("un-ite-ify", CLFlag(false, "Unconvert ITE expressions", false)); + flags.addFlag("ite-cond-simp", + CLFlag(false, "Replace ITE condition by TRUE/FALSE in subexprs", false)); + flags.addFlag("preprocess", CLFlag(true, "Preprocess queries")); + flags.addFlag("pp-pushneg", CLFlag(false, "Push negation in preprocessor")); + flags.addFlag("pp-bryant", CLFlag(false, "Enable Bryant algorithm for UF", false)); + flags.addFlag("pp-budget", CLFlag(0, "Budget for new preprocessing step", false)); + flags.addFlag("pp-care", CLFlag(true, "Enable care-set preprocessing step", false)); + flags.addFlag("simp-and", CLFlag(false, "Rewrite x&y to x&y[x/true]", false)); + flags.addFlag("simp-or", CLFlag(false, "Rewrite x|y to x|y[x/false]", false)); + flags.addFlag("pp-batch", CLFlag(false, "Ignore assumptions until query, then process all at once")); + + // Negate the query when translate into tptp + flags.addFlag("negate-query", CLFlag(true, "Negate the query when translate into TPTP format"));; + + // Concrete model generation (counterexamples) flags + flags.addFlag("counterexample", CLFlag(false, "Dump counterexample if formula is invalid or satisfiable")); + flags.addFlag("model", CLFlag(false, "Dump model if formula is invalid or satisfiable")); + flags.addFlag("unknown-check-model", CLFlag(false, "Try to generate model if formula is unknown")); + flags.addFlag("applications", CLFlag(true, "Add relevant function applications and array accesses to the concrete countermodel")); + // Debugging flags (only for the debug build) + // #ifdef _CVC3_DEBUG_MODE + vector<pair<string,bool> > sv; + flags.addFlag("trace", CLFlag(sv, "Tracing. Multiple flags add up.")); + flags.addFlag("dump-trace", CLFlag("", "Dump debugging trace to " + "given file (off when file name is \"\")")); + // #endif + // DP-specific flags + + // Arithmetic + flags.addFlag("arith-new",CLFlag(false, "Use new arithmetic dp", false)); + flags.addFlag("arith3",CLFlag(false, "Use old arithmetic dp that works well with combined theories", false)); + flags.addFlag("var-order", + CLFlag(false, "Use simple variable order in arith", false)); + flags.addFlag("ineq-delay", CLFlag(0, "Accumulate this many inequalities before processing (-1 for don't process until necessary)")); + + flags.addFlag("nonlinear-sign-split", CLFlag(true, "Whether to split on the signs of nontrivial nonlinear terms")); + + flags.addFlag("grayshadow-threshold", CLFlag(-1, "Ignore gray shadows bigger than this (makes solver incomplete)")); + flags.addFlag("pathlength-threshold", CLFlag(-1, "Ignore gray shadows bigger than this (makes solver incomplete)")); + + // Arrays + flags.addFlag("liftReadIte", CLFlag(true, "Lift read of ite")); + + //for LFSC stuff, disable Tseitin CNF conversion, by Yeting + flags.addFlag("cnf-formula", CLFlag(false, "The input must be in CNF. This option automatically enables '-de sat' and disable preprocess")); + + //for LFSC print out, by Yeting + //flags.addFlag("lfsc", CLFlag(false, "the input is already in CNF. This option automatically enables -de sat and disable -preprocess")); + + // for LFSC print, allows different modes by Liana + flags.addFlag("lfsc-mode", + CLFlag(0, "lfsc mode 0: off, 1:normal, 2:cvc3-mimic etc.")); + + + // Quantifiers + flags.addFlag("max-quant-inst", CLFlag(200, "The maximum number of" + " naive instantiations")); + + flags.addFlag("quant-new", + CLFlag(true, "If this option is false, only naive instantiation is called")); + + flags.addFlag("quant-lazy", CLFlag(false, "Instantiate lazily", false)); + + flags.addFlag("quant-sem-match", + CLFlag(false, "Attempt to match semantically when instantiating", false)); + +// flags.addFlag("quant-const-match", +// CLFlag(true, "When matching semantically, only match with constants", false)); + + flags.addFlag("quant-complete-inst", + CLFlag(false, "Try complete instantiation heuristic. +pp-batch will be automatically enabled")); + + flags.addFlag("quant-max-IL", + CLFlag(100, "The maximum Instantiation Level allowed")); + + flags.addFlag("quant-inst-lcache", + CLFlag(true, "Cache instantiations")); + + flags.addFlag("quant-inst-gcache", + CLFlag(false, "Cache instantiations", false)); + + flags.addFlag("quant-inst-tcache", + CLFlag(false, "Cache instantiations", false)); + + + flags.addFlag("quant-inst-true", + CLFlag(true, "Ignore true instantiations")); + + flags.addFlag("quant-pullvar", + CLFlag(false, "Pull out vars", false)); + + flags.addFlag("quant-score", + CLFlag(true, "Use instantiation level")); + + flags.addFlag("quant-polarity", + CLFlag(false, "Use polarity ", false)); + + flags.addFlag("quant-eqnew", + CLFlag(true, "Use new equality matching")); + + flags.addFlag("quant-max-score", + CLFlag(0, "Maximum initial dynamic score")); + + flags.addFlag("quant-trans3", + CLFlag(true, "Use trans heuristic")); + + flags.addFlag("quant-trans2", + CLFlag(true, "Use trans2 heuristic")); + + flags.addFlag("quant-naive-num", + CLFlag(1000, "Maximum number to call naive instantiation")); + + flags.addFlag("quant-naive-inst", + CLFlag(true, "Use naive instantiation")); + + flags.addFlag("quant-man-trig", + CLFlag(true, "Use manual triggers")); + + flags.addFlag("quant-gfact", + CLFlag(false, "Send facts to core directly", false)); + + flags.addFlag("quant-glimit", + CLFlag(1000, "Limit for gfacts", false)); + + flags.addFlag("print-var-type", //by yeting, as requested by Sascha Boehme for proofs + CLFlag(false, "Print types for bound variables")); + + // Bitvectors + flags.addFlag("bv32-flag", + CLFlag(false, "assume that all bitvectors are 32bits with no overflow", false)); + + // Uninterpreted Functions + flags.addFlag("trans-closure", + CLFlag(false,"enables transitive closure of binary relations", false)); + + // Datatypes + flags.addFlag("dt-smartsplits", + CLFlag(true, "enables smart splitting in datatype theory", false)); + flags.addFlag("dt-lazy", + CLFlag(false, "lazy splitting on datatypes", false)); + + return flags; +} + +ValidityChecker* ValidityChecker::create(const CLFlags& flags) { + return new ValidityChecker(flags); +} + +ValidityChecker* ValidityChecker::create() { + return new ValidityChecker(createFlags()); +} + +Type ValidityChecker::boolType() { + return d_em.booleanType(); +} + +Type ValidityChecker::realType() { + return d_em.realType(); +} + +Type ValidityChecker::intType() { + return d_em.integerType(); +} + +Type ValidityChecker::subrangeType(const Expr& l, const Expr& r) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::subtypeType(const Expr& pred, const Expr& witness) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::tupleType(const Type& type0, const Type& type1) { + vector<CVC4::Type> types; + types.push_back(type0); + types.push_back(type1); + return d_em.mkTupleType(types); +} + +Type ValidityChecker::tupleType(const Type& type0, const Type& type1, const Type& type2) { + vector<CVC4::Type> types; + types.push_back(type0); + types.push_back(type1); + types.push_back(type2); + return d_em.mkTupleType(types); +} + +Type ValidityChecker::tupleType(const std::vector<Type>& types) { + const vector<CVC4::Type>& v = + *reinterpret_cast<const vector<CVC4::Type>*>(&types); + return Type(d_em.mkTupleType(v)); +} + +Type ValidityChecker::recordType(const std::string& field, const Type& type) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::recordType(const std::string& field0, const Type& type0, + const std::string& field1, const Type& type1) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::recordType(const std::string& field0, const Type& type0, + const std::string& field1, const Type& type1, + const std::string& field2, const Type& type2) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::recordType(const std::vector<std::string>& fields, + const std::vector<Type>& types) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::dataType(const std::string& name, + const std::string& constructor, + const std::vector<std::string>& selectors, + const std::vector<Expr>& types) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::dataType(const std::string& name, + const std::vector<std::string>& constructors, + const std::vector<std::vector<std::string> >& selectors, + const std::vector<std::vector<Expr> >& types) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::dataType(const std::vector<std::string>& names, + const std::vector<std::vector<std::string> >& constructors, + const std::vector<std::vector<std::vector<std::string> > >& selectors, + const std::vector<std::vector<std::vector<Expr> > >& types, + std::vector<Type>& returnTypes) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::arrayType(const Type& typeIndex, const Type& typeData) { + return d_em.mkArrayType(typeIndex, typeData); +} + +Type ValidityChecker::bitvecType(int n) { + CheckArgument(n >= 0, n, "cannot construct a bitvector type of negative size"); + return d_em.mkBitVectorType(n); +} + +Type ValidityChecker::funType(const Type& typeDom, const Type& typeRan) { + return d_em.mkFunctionType(typeDom, typeRan); +} + +Type ValidityChecker::funType(const std::vector<Type>& typeDom, const Type& typeRan) { + const vector<CVC4::Type>& dom = + *reinterpret_cast<const vector<CVC4::Type>*>(&typeDom); + return Type(d_em.mkFunctionType(dom, typeRan)); +} + +Type ValidityChecker::createType(const std::string& typeName) { + return d_em.mkSort(typeName); +} + +Type ValidityChecker::createType(const std::string& typeName, const Type& def) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::lookupType(const std::string& typeName) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +ExprManager* ValidityChecker::getEM() { + return &d_em; +} + +Expr ValidityChecker::varExpr(const std::string& name, const Type& type) { + return d_em.mkVar(name, type); +} + +Expr ValidityChecker::varExpr(const std::string& name, const Type& type, + const Expr& def) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::lookupVar(const std::string& name, Type* type) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::getType(const Expr& e) { + return d_em.getType(e); +} + +Type ValidityChecker::getBaseType(const Expr& e) { + Type t = d_em.getType(e); + return t.isInteger() ? Type(d_em.realType()) : t; +} + +Type ValidityChecker::getBaseType(const Type& t) { + return t.isInteger() ? Type(d_em.realType()) : t; +} + +Expr ValidityChecker::getTypePred(const Type&t, const Expr& e) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::stringExpr(const std::string& str) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::idExpr(const std::string& name) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::listExpr(const std::vector<Expr>& kids) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::listExpr(const Expr& e1) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::listExpr(const Expr& e1, const Expr& e2) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::listExpr(const Expr& e1, const Expr& e2, const Expr& e3) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::listExpr(const std::string& op, + const std::vector<Expr>& kids) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::listExpr(const std::string& op, const Expr& e1) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::listExpr(const std::string& op, const Expr& e1, + const Expr& e2) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::listExpr(const std::string& op, const Expr& e1, + const Expr& e2, const Expr& e3) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::printExpr(const Expr& e) { + printExpr(e, Message()); +} + +void ValidityChecker::printExpr(const Expr& e, std::ostream& os) { + Expr::setdepth::Scope sd(os, -1); + Expr::printtypes::Scope pt(os, false); + Expr::setlanguage::Scope sl(os, d_em.getOptions()->outputLanguage); + os << e; +} + +Expr ValidityChecker::parseExpr(const Expr& e) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::parseType(const Expr& e) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::importExpr(const Expr& e) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Type ValidityChecker::importType(const Type& t) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::cmdsFromString(const std::string& s, InputLanguage lang) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::exprFromString(const std::string& e) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::trueExpr() { + return d_em.mkConst(true); +} + +Expr ValidityChecker::falseExpr() { + return d_em.mkConst(false); +} + +Expr ValidityChecker::notExpr(const Expr& child) { + return d_em.mkExpr(CVC4::kind::NOT, child); +} + +Expr ValidityChecker::andExpr(const Expr& left, const Expr& right) { + return d_em.mkExpr(CVC4::kind::AND, left, right); +} + +Expr ValidityChecker::andExpr(const std::vector<Expr>& children) { + const vector<CVC4::Expr>& v = + *reinterpret_cast<const vector<CVC4::Expr>*>(&children); + return d_em.mkExpr(CVC4::kind::AND, v); +} + +Expr ValidityChecker::orExpr(const Expr& left, const Expr& right) { + return d_em.mkExpr(CVC4::kind::OR, left, right); +} + +Expr ValidityChecker::orExpr(const std::vector<Expr>& children) { + const vector<CVC4::Expr>& v = + *reinterpret_cast<const vector<CVC4::Expr>*>(&children); + return d_em.mkExpr(CVC4::kind::OR, v); +} + +Expr ValidityChecker::impliesExpr(const Expr& hyp, const Expr& conc) { + return d_em.mkExpr(CVC4::kind::IMPLIES, hyp, conc); +} + +Expr ValidityChecker::iffExpr(const Expr& left, const Expr& right) { + return d_em.mkExpr(CVC4::kind::IFF, left, right); +} + +Expr ValidityChecker::eqExpr(const Expr& child0, const Expr& child1) { + return d_em.mkExpr(CVC4::kind::EQUAL, child0, child1); +} + +Expr ValidityChecker::iteExpr(const Expr& ifpart, const Expr& thenpart, + const Expr& elsepart) { + return d_em.mkExpr(CVC4::kind::ITE, ifpart, thenpart, elsepart); +} + +Expr ValidityChecker::distinctExpr(const std::vector<Expr>& children) { + const vector<CVC4::Expr>& v = + *reinterpret_cast<const vector<CVC4::Expr>*>(&children); + return d_em.mkExpr(CVC4::kind::DISTINCT, v); +} + +Op ValidityChecker::createOp(const std::string& name, const Type& type) { + return d_em.mkVar(name, type); +} + +Op ValidityChecker::createOp(const std::string& name, const Type& type, + const Expr& def) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Op ValidityChecker::lookupOp(const std::string& name, Type* type) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::funExpr(const Op& op, const Expr& child) { + return d_em.mkExpr(CVC4::kind::APPLY_UF, op, child); +} + +Expr ValidityChecker::funExpr(const Op& op, const Expr& left, const Expr& right) { + return d_em.mkExpr(CVC4::kind::APPLY_UF, op, left, right); +} + +Expr ValidityChecker::funExpr(const Op& op, const Expr& child0, + const Expr& child1, const Expr& child2) { + return d_em.mkExpr(CVC4::kind::APPLY_UF, op, child0, child1, child2); +} + +Expr ValidityChecker::funExpr(const Op& op, const std::vector<Expr>& children) { + vector<CVC4::Expr> opkids; + opkids.push_back(op); + opkids.insert(opkids.end(), children.begin(), children.end()); + return d_em.mkExpr(CVC4::kind::APPLY_UF, opkids); +} + +bool ValidityChecker::addPairToArithOrder(const Expr& smaller, const Expr& bigger) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::ratExpr(int n, int d) { + return d_em.mkConst(Rational(n, d)); +} + +Expr ValidityChecker::ratExpr(const std::string& n, const std::string& d, int base) { + return d_em.mkConst(Rational(n + '/' + d, base)); +} + +Expr ValidityChecker::ratExpr(const std::string& n, int base) { + return d_em.mkConst(Rational(n, base)); +} + +Expr ValidityChecker::uminusExpr(const Expr& child) { + return d_em.mkExpr(CVC4::kind::UMINUS, child); +} + +Expr ValidityChecker::plusExpr(const Expr& left, const Expr& right) { + return d_em.mkExpr(CVC4::kind::PLUS, left, right); +} + +Expr ValidityChecker::plusExpr(const std::vector<Expr>& children) { + const vector<CVC4::Expr>& v = + *reinterpret_cast<const vector<CVC4::Expr>*>(&children); + return d_em.mkExpr(CVC4::kind::PLUS, v); +} + +Expr ValidityChecker::minusExpr(const Expr& left, const Expr& right) { + return d_em.mkExpr(CVC4::kind::MINUS, left, right); +} + +Expr ValidityChecker::multExpr(const Expr& left, const Expr& right) { + return d_em.mkExpr(CVC4::kind::MULT, left, right); +} + +Expr ValidityChecker::powExpr(const Expr& x, const Expr& n) { + return d_em.mkExpr(CVC4::kind::POW, x, n); +} + +Expr ValidityChecker::divideExpr(const Expr& numerator, + const Expr& denominator) { + return d_em.mkExpr(CVC4::kind::DIVISION, numerator, denominator); +} + +Expr ValidityChecker::ltExpr(const Expr& left, const Expr& right) { + return d_em.mkExpr(CVC4::kind::LT, left, right); +} + +Expr ValidityChecker::leExpr(const Expr& left, const Expr& right) { + return d_em.mkExpr(CVC4::kind::LEQ, left, right); +} + +Expr ValidityChecker::gtExpr(const Expr& left, const Expr& right) { + return d_em.mkExpr(CVC4::kind::GT, left, right); +} + +Expr ValidityChecker::geExpr(const Expr& left, const Expr& right) { + return d_em.mkExpr(CVC4::kind::GEQ, left, right); +} + +Expr ValidityChecker::recordExpr(const std::string& field, const Expr& expr) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::recordExpr(const std::string& field0, const Expr& expr0, + const std::string& field1, const Expr& expr1) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::recordExpr(const std::string& field0, const Expr& expr0, + const std::string& field1, const Expr& expr1, + const std::string& field2, const Expr& expr2) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::recordExpr(const std::vector<std::string>& fields, + const std::vector<Expr>& exprs) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::recSelectExpr(const Expr& record, const std::string& field) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::recUpdateExpr(const Expr& record, const std::string& field, + const Expr& newValue) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::readExpr(const Expr& array, const Expr& index) { + return d_em.mkExpr(CVC4::kind::SELECT, array, index); +} + +Expr ValidityChecker::writeExpr(const Expr& array, const Expr& index, + const Expr& newValue) { + return d_em.mkExpr(CVC4::kind::STORE, array, index, newValue); +} + +Expr ValidityChecker::newBVConstExpr(const std::string& s, int base) { + return d_em.mkConst(CVC4::BitVector(s, base)); +} + +Expr ValidityChecker::newBVConstExpr(const std::vector<bool>& bits) { + Integer value = 0; + for(vector<bool>::const_iterator i = bits.begin(); i != bits.end(); ++i) { + value *= 2; + value += *i ? 1 : 0; + } + return d_em.mkConst(CVC4::BitVector(bits.size(), value)); +} + +Expr ValidityChecker::newBVConstExpr(const Rational& r, int len) { + // implementation based on CVC3's TheoryBitvector::newBVConstExpr() + + CheckArgument(r.getDenominator() == 1, r, "ValidityChecker::newBVConstExpr: " + "not an integer: `%s'", r.toString().c_str()); + CheckArgument(len > 0, len, "ValidityChecker::newBVConstExpr: " + "len = %d", len); + + string s(r.toString(2)); + size_t strsize = s.size(); + size_t length = len; + Expr res; + if(length > 0 && length != strsize) { + //either (length > strsize) or (length < strsize) + if(length < strsize) { + s = s.substr(strsize - length, length); + } else { + string zeros(""); + for(size_t i = 0, pad = length - strsize; i < pad; ++i) + zeros += "0"; + s = zeros + s; + } + } + + return newBVConstExpr(s, 2); +} + +Expr ValidityChecker::newConcatExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only concat a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only concat a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_CONCAT, t1, t2); +} + +Expr ValidityChecker::newConcatExpr(const std::vector<Expr>& kids) { + const vector<CVC4::Expr>& v = + *reinterpret_cast<const vector<CVC4::Expr>*>(&kids); + return d_em.mkExpr(CVC4::kind::BITVECTOR_CONCAT, v); +} + +Expr ValidityChecker::newBVExtractExpr(const Expr& e, int hi, int low) { + CheckArgument(e.getType().isBitVector(), e, "can only bvextract from a bitvector, not a `%s'", e.getType().toString().c_str()); + CheckArgument(hi >= low, hi, "extraction [%d:%d] is bad; possibly inverted?", hi, low); + CheckArgument(low >= 0, low, "extraction [%d:%d] is bad (negative)", hi, low); + CheckArgument(CVC4::BitVectorType(e.getType()).getSize() > unsigned(hi), hi, "bitvector is of size %u, extraction [%d:%d] is off-the-end", CVC4::BitVectorType(e.getType()).getSize(), hi, low); + return d_em.mkExpr(CVC4::kind::BITVECTOR_EXTRACT, + d_em.mkConst(CVC4::BitVectorExtract(hi, low)), e); +} + +Expr ValidityChecker::newBVNegExpr(const Expr& t1) { + // CVC3's BVNEG => SMT-LIBv2 bvnot + CheckArgument(t1.getType().isBitVector(), t1, "can only bvneg a bitvector, not a `%s'", t1.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_NOT, t1); +} + +Expr ValidityChecker::newBVAndExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvand a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvand a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_AND, t1, t2); +} + +Expr ValidityChecker::newBVAndExpr(const std::vector<Expr>& kids) { + // BVAND is not N-ary + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::newBVOrExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvor a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvor a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_OR, t1, t2); +} + +Expr ValidityChecker::newBVOrExpr(const std::vector<Expr>& kids) { + // BVOR is not N-ary + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::newBVXorExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvxor a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvxor a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_XOR, t1, t2); +} + +Expr ValidityChecker::newBVXorExpr(const std::vector<Expr>& kids) { + // BVXOR is not N-ary + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::newBVXnorExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvxnor a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvxnor a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_XNOR, t1, t2); +} + +Expr ValidityChecker::newBVXnorExpr(const std::vector<Expr>& kids) { + // BVXNOR is not N-ary + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::newBVNandExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvnand a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvnand a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_NAND, t1, t2); +} + +Expr ValidityChecker::newBVNorExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvnor a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvnor a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_NOR, t1, t2); +} + +Expr ValidityChecker::newBVCompExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvcomp a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvcomp a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_COMP, t1, t2); +} + +Expr ValidityChecker::newBVLTExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvlt a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvlt a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_ULT, t1, t2); +} + +Expr ValidityChecker::newBVLEExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvle a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvle a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_ULE, t1, t2); +} + +Expr ValidityChecker::newBVSLTExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvslt a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvslt a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_SLT, t1, t2); +} + +Expr ValidityChecker::newBVSLEExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvsle a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvsle a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_SLE, t1, t2); +} + +Expr ValidityChecker::newSXExpr(const Expr& t1, int len) { + CheckArgument(t1.getType().isBitVector(), t1, "can only sx a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(len >= 0, len, "must sx by a positive integer"); + CheckArgument(unsigned(len) >= CVC4::BitVectorType(t1.getType()).getSize(), len, "cannot sx by something smaller than the bitvector (%d < %u)", len, CVC4::BitVectorType(t1.getType()).getSize()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_SIGN_EXTEND, + d_em.mkConst(CVC4::BitVectorSignExtend(len)), t1); +} + +Expr ValidityChecker::newBVUminusExpr(const Expr& t1) { + // CVC3's BVUMINUS => SMT-LIBv2 bvneg + CheckArgument(t1.getType().isBitVector(), t1, "can only bvuminus a bitvector, not a `%s'", t1.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_NEG, t1); +} + +Expr ValidityChecker::newBVSubExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvsub a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvsub by a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_SUB, t1, t2); +} + +Expr ValidityChecker::newBVPlusExpr(int numbits, const std::vector<Expr>& k) { + // BVPLUS is not N-ary + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::newBVPlusExpr(int numbits, const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvplus a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvplus a bitvector, not a `%s'", t2.getType().toString().c_str()); + Expr e = d_em.mkExpr(CVC4::kind::BITVECTOR_PLUS, t1, t2); + unsigned size = CVC4::BitVectorType(e.getType()).getSize(); + CheckArgument(numbits > 0, numbits, + "argument must be positive integer, not %u", numbits); + CheckArgument(unsigned(numbits) == size, numbits, + "argument must match computed size of bitvector sum: " + "passed size == %u, computed size == %u", numbits, size); + return e; +} + +Expr ValidityChecker::newBVMultExpr(int numbits, const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvmult a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvmult by a bitvector, not a `%s'", t2.getType().toString().c_str()); + Expr e = d_em.mkExpr(CVC4::kind::BITVECTOR_MULT, t1, t2); + unsigned size = CVC4::BitVectorType(e.getType()).getSize(); + CheckArgument(numbits > 0, numbits, + "argument must be positive integer, not %u", numbits); + CheckArgument(unsigned(numbits) == size, numbits, + "argument must match computed size of bitvector product: " + "passed size == %u, computed size == %u", numbits, size); + return e; +} + +Expr ValidityChecker::newBVUDivExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvudiv a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvudiv by a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_UDIV, t1, t2); +} + +Expr ValidityChecker::newBVURemExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvurem a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvurem by a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_UREM, t1, t2); +} + +Expr ValidityChecker::newBVSDivExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvsdiv a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvsdiv by a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_SDIV, t1, t2); +} + +Expr ValidityChecker::newBVSRemExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvsrem a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvsrem by a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_SREM, t1, t2); +} + +Expr ValidityChecker::newBVSModExpr(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only bvsmod a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only bvsmod by a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_SMOD, t1, t2); +} + +Expr ValidityChecker::newFixedLeftShiftExpr(const Expr& t1, int r) { + CheckArgument(t1.getType().isBitVector(), t1, "can only left-shift a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(r >= 0, r, "left shift amount must be >= 0 (you passed %d)", r); + // Defined in: + // http://www.cs.nyu.edu/acsys/cvc3/doc/user_doc.html#user_doc_pres_lang_expr_bit + return d_em.mkExpr(CVC4::kind::BITVECTOR_CONCAT, t1, d_em.mkConst(CVC4::BitVector(r))); +} + +Expr ValidityChecker::newFixedConstWidthLeftShiftExpr(const Expr& t1, int r) { + CheckArgument(t1.getType().isBitVector(), t1, "can only right-shift a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(r >= 0, r, "const-width left shift amount must be >= 0 (you passed %d)", r); + // just turn it into a BVSHL + return d_em.mkExpr(CVC4::kind::BITVECTOR_SHL, t1, d_em.mkConst(CVC4::BitVector(CVC4::BitVectorType(t1.getType()).getSize(), unsigned(r)))); +} + +Expr ValidityChecker::newFixedRightShiftExpr(const Expr& t1, int r) { + CheckArgument(t1.getType().isBitVector(), t1, "can only right-shift a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(r >= 0, r, "right shift amount must be >= 0 (you passed %d)", r); + // Defined in: + // http://www.cs.nyu.edu/acsys/cvc3/doc/user_doc.html#user_doc_pres_lang_expr_bit + // Should be equivalent to a BVLSHR; just turn it into that. + return d_em.mkExpr(CVC4::kind::BITVECTOR_LSHR, t1, d_em.mkConst(CVC4::BitVector(CVC4::BitVectorType(t1.getType()).getSize(), unsigned(r)))); +} + +Expr ValidityChecker::newBVSHL(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only right-shift a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only right-shift by a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_SHL, t1, t2); +} + +Expr ValidityChecker::newBVLSHR(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only right-shift a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only right-shift by a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_LSHR, t1, t2); +} + +Expr ValidityChecker::newBVASHR(const Expr& t1, const Expr& t2) { + CheckArgument(t1.getType().isBitVector(), t1, "can only right-shift a bitvector, not a `%s'", t1.getType().toString().c_str()); + CheckArgument(t2.getType().isBitVector(), t2, "can only right-shift by a bitvector, not a `%s'", t2.getType().toString().c_str()); + return d_em.mkExpr(CVC4::kind::BITVECTOR_ASHR, t1, t2); +} + +Rational ValidityChecker::computeBVConst(const Expr& e) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::tupleExpr(const std::vector<Expr>& exprs) { + const vector<CVC4::Expr>& v = + *reinterpret_cast<const vector<CVC4::Expr>*>(&exprs); + return d_em.mkExpr(CVC4::kind::TUPLE, v); +} + +Expr ValidityChecker::tupleSelectExpr(const Expr& tuple, int index) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::tupleUpdateExpr(const Expr& tuple, int index, + const Expr& newValue) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::datatypeConsExpr(const std::string& constructor, const std::vector<Expr>& args) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::datatypeSelExpr(const std::string& selector, const Expr& arg) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::datatypeTestExpr(const std::string& constructor, const Expr& arg) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::boundVarExpr(const std::string& name, const std::string& uid, + const Type& type) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::forallExpr(const std::vector<Expr>& vars, const Expr& body) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::forallExpr(const std::vector<Expr>& vars, const Expr& body, + const Expr& trigger) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::forallExpr(const std::vector<Expr>& vars, const Expr& body, + const std::vector<Expr>& triggers) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::forallExpr(const std::vector<Expr>& vars, const Expr& body, + const std::vector<std::vector<Expr> >& triggers) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::setTriggers(const Expr& e, const std::vector<std::vector<Expr> > & triggers) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::setTriggers(const Expr& e, const std::vector<Expr>& triggers) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::setTrigger(const Expr& e, const Expr& trigger) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::setMultiTrigger(const Expr& e, const std::vector<Expr>& multiTrigger) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::existsExpr(const std::vector<Expr>& vars, const Expr& body) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Op ValidityChecker::lambdaExpr(const std::vector<Expr>& vars, const Expr& body) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Op ValidityChecker::transClosure(const Op& op) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::simulateExpr(const Expr& f, const Expr& s0, + const std::vector<Expr>& inputs, + const Expr& n) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::setResourceLimit(unsigned limit) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::setTimeLimit(unsigned limit) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::assertFormula(const Expr& e) { + d_smt.assertFormula(CVC4::BoolExpr(e)); +} + +void ValidityChecker::registerAtom(const Expr& e) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::getImpliedLiteral() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::simplify(const Expr& e) { + return d_smt.simplify(e); +} + +static QueryResult cvc4resultToCvc3result(CVC4::Result r) { + switch(r.isSat()) { + case CVC4::Result::SAT: + return SATISFIABLE; + case CVC4::Result::UNSAT: + return UNSATISFIABLE; + default: + ; + } + + switch(r.isValid()) { + case CVC4::Result::VALID: + return VALID; + case CVC4::Result::INVALID: + return INVALID; + default: + return UNKNOWN; + } +} + +QueryResult ValidityChecker::query(const Expr& e) { + return cvc4resultToCvc3result(d_smt.query(CVC4::BoolExpr(e))); +} + +QueryResult ValidityChecker::checkUnsat(const Expr& e) { + return cvc4resultToCvc3result(d_smt.checkSat(CVC4::BoolExpr(e))); +} + +QueryResult ValidityChecker::checkContinue() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +QueryResult ValidityChecker::restart(const Expr& e) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::returnFromCheck() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::getUserAssumptions(std::vector<Expr>& assumptions) { + CheckArgument(assumptions.empty(), assumptions, "assumptions arg must be empty"); + vector<CVC4::Expr> v = d_smt.getAssertions(); + assumptions.swap(*reinterpret_cast<vector<Expr>*>(&v)); +} + +void ValidityChecker::getInternalAssumptions(std::vector<Expr>& assumptions) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::getAssumptions(std::vector<Expr>& assumptions) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::getAssumptionsUsed(std::vector<Expr>& assumptions) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::getProofQuery() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::getCounterExample(std::vector<Expr>& assumptions, + bool inOrder) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::getConcreteModel(ExprMap<Expr>& m) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +QueryResult ValidityChecker::tryModelGeneration() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +FormulaValue ValidityChecker::value(const Expr& e) { + CheckArgument(e.getType() == d_em.booleanType(), e, "argument must be a formula"); + return d_smt.getValue(e).getConst<bool>() ? TRUE_VAL : FALSE_VAL; +} + +bool ValidityChecker::inconsistent(std::vector<Expr>& assumptions) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +bool ValidityChecker::inconsistent() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +bool ValidityChecker::incomplete() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +bool ValidityChecker::incomplete(std::vector<std::string>& reasons) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Proof ValidityChecker::getProof() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::getTCC() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::getAssumptionsTCC(std::vector<Expr>& assumptions) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Proof ValidityChecker::getProofTCC() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Expr ValidityChecker::getClosure() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Proof ValidityChecker::getProofClosure() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +int ValidityChecker::stackLevel() { + return d_smt.getStackLevel(); +} + +void ValidityChecker::push() { + d_smt.push(); +} + +void ValidityChecker::pop() { + d_smt.pop(); +} + +void ValidityChecker::popto(int stackLevel) { + CheckArgument(stackLevel >= 0, stackLevel, + "Cannot pop to a negative stack level %u", stackLevel); + CheckArgument(unsigned(stackLevel) <= d_smt.getStackLevel(), stackLevel, + "Cannot pop to a level higher than the current one! " + "At level %u, user requested level %d", + d_smt.getStackLevel(), stackLevel); + while(unsigned(stackLevel) < d_smt.getStackLevel()) { + pop(); + } +} + +int ValidityChecker::scopeLevel() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::pushScope() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::popScope() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::poptoScope(int scopeLevel) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +Context* ValidityChecker::getCurrentContext() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::reset() { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +void ValidityChecker::logAnnotation(const Expr& annot) { + Unimplemented("This CVC3 compatibility function not yet implemented (sorry!)"); +} + +static void doCommands(CVC4::parser::Parser* parser, CVC4::SmtEngine& smt, CVC4::Options& opts) { + while(CVC4::Command* cmd = parser->nextCommand()) { + if(opts.verbosity >= 0) { + cmd->invoke(&smt, *opts.out); + } else { + cmd->invoke(&smt); + } + delete cmd; + } +} + +void ValidityChecker::loadFile(const std::string& fileName, + InputLanguage lang, + bool interactive, + bool calledFromParser) { + CVC4::Options opts = *d_em.getOptions(); + opts.inputLanguage = lang; + opts.interactive = interactive; + CVC4::parser::ParserBuilder parserBuilder(&d_em, fileName, opts); + CVC4::parser::Parser* parser = parserBuilder.build(); + doCommands(parser, d_smt, opts); + delete parser; +} + +void ValidityChecker::loadFile(std::istream& is, + InputLanguage lang, + bool interactive) { + CVC4::Options opts = *d_em.getOptions(); + opts.inputLanguage = lang; + opts.interactive = interactive; + CVC4::parser::ParserBuilder parserBuilder(&d_em, "[stream]", opts); + CVC4::parser::Parser* parser = parserBuilder.withStreamInput(is).build(); + doCommands(parser, d_smt, opts); + delete parser; +} + +Statistics& ValidityChecker::getStatistics() { + return *d_smt.getStatisticsRegistry(); +} + +void ValidityChecker::printStatistics() { + Message() << d_smt.getStatisticsRegistry(); +} + +}/* CVC3 namespace */ diff --git a/src/compat/cvc3_compat.h b/src/compat/cvc3_compat.h new file mode 100644 index 000000000..36c5c0f6a --- /dev/null +++ b/src/compat/cvc3_compat.h @@ -0,0 +1,1465 @@ +/********************* */ +/*! \file cvc3_compat.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief CVC3 compatibility layer for CVC4 + ** + ** CVC3 compatibility layer for CVC4. This version was derived from + ** the following CVS revisions of the following files in CVC3. If + ** those files have a later revision, then this file might be out of + ** date. + ** + ** src/include/vc.h 1.36 + ** src/include/expr.h 1.39 + ** src/include/command_line_flags.h 1.3 + ** src/include/queryresult.h 1.2 + ** src/include/formula_value.h 1.1 + **/ + +#include "cvc4_public.h" + +#ifndef __CVC4__CVC3_COMPAT_H +#define __CVC4__CVC3_COMPAT_H + +// keep the CVC3 include guard also +#if defined(_cvc3__include__vc_h_) || \ + defined(_cvc3__expr_h_) || \ + defined(_cvc3__command_line_flags_h_) || \ + defined(_cvc3__include__queryresult_h_) || \ + defined(_cvc3__include__formula_value_h_) + +#error "A CVC3 header file was included before CVC4's cvc3_compat.h header. Please include cvc3_compat.h rather than any CVC3 headers." + +#else + +// define these so the files are skipped if the user #includes them too +#define _cvc3__expr_h_ +#define _cvc3__include__vc_h_ +#define _cvc3__command_line_flags_h_ +#define _cvc3__include__queryresult_h_ +#define _cvc3__include__formula_value_h_ + +#include "expr/expr_manager.h" +#include "expr/expr.h" +#include "expr/type.h" + +#include "smt/smt_engine.h" + +#include "util/rational.h" +#include "util/integer.h" + +#include "util/exception.h" +#include "util/hash.h" + +#include <stdlib.h> +#include <map> +#include <utility> + +// some #defines that CVC3 exported to userspace :( +#ifdef CVC4_DEBUG +# define DebugAssert(cond, ...) Assert(cond, "CVC3-style assertion failed"); +# define IF_DEBUG(x) x +#else +# define DebugAssert(...) +# define IF_DEBUG(x) +#endif +#define FatalAssert(cond, ...) AlwaysAssert(cond, "CVC3-style assertion failed"); + +//class CInterface; + +namespace CVC3 { + +std::string int2string(int n); + +//! Different types of command line flags +typedef enum { + CLFLAG_NULL, + CLFLAG_BOOL, + CLFLAG_INT, + CLFLAG_STRING, + CLFLAG_STRVEC //!< Vector of pair<string, bool> +} CLFlagType; + +std::ostream& operator<<(std::ostream& out, CLFlagType clft); + +/*! + Class CLFlag (for Command Line Flag) + + Author: Sergey Berezin + + Date: Fri May 30 14:10:48 2003 + + This class implements a data structure to hold a value of a single + command line flag. +*/ +class CLFlag { + //! Type of the argument + CLFlagType d_tp; + //! The argument + union { + bool b; + int i; + std::string* s; + std::vector<std::pair<std::string,bool> >* sv; + } d_data; + +public: + + //! Constructor for a boolean flag + CLFlag(bool b, const std::string& help, bool display = true); + //! Constructor for an integer flag + CLFlag(int i, const std::string& help, bool display = true); + //! Constructor for a string flag + CLFlag(const std::string& s, const std::string& help, bool display = true); + //! Constructor for a string flag from char* + CLFlag(const char* s, const std::string& help, bool display = true); + //! Constructor for a vector flag + CLFlag(const std::vector<std::pair<std::string,bool> >& sv, + const std::string& help, bool display = true); + //! Default constructor + CLFlag(); + //! Copy constructor + CLFlag(const CLFlag& f); + //! Destructor + ~CLFlag(); + + //! Assignment from another flag + CLFlag& operator=(const CLFlag& f); + //! Assignment of a boolean value + /*! The flag must already have the right type */ + CLFlag& operator=(bool b); + //! Assignment of an integer value + /*! The flag must already have the right type */ + CLFlag& operator=(int i); + //! Assignment of a string value + /*! The flag must already have a string type. */ + CLFlag& operator=(const std::string& s); + //! Assignment of an string value from char* + /*! The flag must already have a string type. */ + CLFlag& operator=(const char* s); + //! Assignment of a string value with a boolean tag to a vector flag + /*! The flag must already have a vector type. The pair of + <string,bool> will be appended to the vector. */ + CLFlag& operator=(const std::pair<std::string,bool>& p); + //! Assignment of a vector value + /*! The flag must already have a vector type. */ + CLFlag& operator=(const std::vector<std::pair<std::string,bool> >& sv); + + // Accessor methods + //! Return the type of the flag + CLFlagType getType() const; + /*! @brief Return true if the flag was modified from the default + value (e.g. set on the command line) */ + bool modified() const; + //! Return true if flag should be displayed in regular help + bool display() const; + + // The value accessors return a reference. For the system-wide + // flags, this reference will remain valid throughout the run of the + // program, even if the flag's value changes. So, the reference can + // be cached, and the value can be checked directly (which is more + // efficient). + const bool& getBool() const; + + const int& getInt() const; + + const std::string& getString() const; + + const std::vector<std::pair<std::string,bool> >& getStrVec() const; + + const std::string& getHelp() const; + +};/* class CLFlag */ + +/////////////////////////////////////////////////////////////////////// +// Class CLFlag (for Command Line Flag) +// +// Author: Sergey Berezin +// Date: Fri May 30 14:10:48 2003 +// +// Database of command line flags. +/////////////////////////////////////////////////////////////////////// + +class CLFlags { + typedef std::map<std::string, CLFlag> FlagMap; + FlagMap d_map; + +public: + // Public methods + // Add a new flag. The name must be a complete flag name. + void addFlag(const std::string& name, const CLFlag& f); + // Count how many flags match the name prefix + size_t countFlags(const std::string& name) const; + // Match the name prefix and add all the matching names to the vector + size_t countFlags(const std::string& name, + std::vector<std::string>& names) const; + // Retrieve an existing flag. The 'name' must be a full name of an + // existing flag. + const CLFlag& getFlag(const std::string& name) const; + + const CLFlag& operator[](const std::string& name) const; + + // Setting the flag to a new value, but preserving the help string. + // The 'name' prefix must uniquely resolve to an existing flag. + void setFlag(const std::string& name, const CLFlag& f); + + // Variants of setFlag for all the types + void setFlag(const std::string& name, bool b); + void setFlag(const std::string& name, int i); + void setFlag(const std::string& name, const std::string& s); + void setFlag(const std::string& name, const char* s); + void setFlag(const std::string& name, const std::pair<std::string, bool>& p); + void setFlag(const std::string& name, + const std::vector<std::pair<std::string, bool> >& sv); + +};/* class CLFlags */ + +class Context; +class Proof {}; + +using CVC4::ExprManager; +using CVC4::InputLanguage; +using CVC4::Rational; +using CVC4::Integer; +using CVC4::Exception; +using CVC4::Cardinality; +using namespace CVC4::kind; + +typedef size_t ExprIndex; +typedef CVC4::TypeCheckingException TypecheckException; +typedef size_t Unsigned; + +static const int READ = ::CVC4::kind::SELECT; +static const int WRITE = ::CVC4::kind::STORE; + +// CVC4 has a more sophisticated Cardinality type; +// but we can support comparison against CVC3's more +// coarse-grained Cardinality. +enum CVC3CardinalityKind { + CARD_FINITE, + CARD_INFINITE, + CARD_UNKNOWN +};/* enum CVC3CardinalityKind */ + +std::ostream& operator<<(std::ostream& out, CVC3CardinalityKind c); + +bool operator==(const Cardinality& c, CVC3CardinalityKind d); +bool operator==(CVC3CardinalityKind d, const Cardinality& c); +bool operator!=(const Cardinality& c, CVC3CardinalityKind d); +bool operator!=(CVC3CardinalityKind d, const Cardinality& c); + +class Expr; + +template <class T> +class ExprMap : public std::map<Expr, T> { +};/* class ExprMap<T> */ + +template <class T> +class ExprHashMap : public std::hash_map<Expr, T, CVC4::ExprHashFunction> { +public: + void insert(Expr a, Expr b); +};/* class ExprHashMap<T> */ + +class Type : public CVC4::Type { +public: + Type(); + Type(const CVC4::Type& type); + Type(const Type& type); + Expr getExpr() const; + + // Reasoning about children + int arity() const; + Type operator[](int i) const; + + // Core testers + bool isBool() const; + bool isSubtype() const; + //! Return cardinality of type + Cardinality card() const; + //! Return nth (starting with 0) element in a finite type + /*! Returns NULL Expr if unable to compute nth element + */ + Expr enumerateFinite(Unsigned n) const; + //! Return size of a finite type; returns 0 if size cannot be determined + Unsigned sizeFinite() const; + + // Core constructors + static Type typeBool(ExprManager* em); + static Type funType(const std::vector<Type>& typeDom, const Type& typeRan); + Type funType(const Type& typeRan) const; + +};/* class CVC3::Type */ + +/** + * Expr class for CVC3 compatibility layer. + * + * This class is identical to (and convertible to/from) a CVC4 Expr, + * except that a few additional functions are supported to provide + * naming compatibility with CVC3. + */ +class Expr : public CVC4::Expr { +public: + Expr(); + Expr(const Expr& e); + Expr(const CVC4::Expr& e); + + // Compound expression constructors + Expr eqExpr(const Expr& right) const; + Expr notExpr() const; + Expr negate() const; // avoid double-negatives + Expr andExpr(const Expr& right) const; + Expr orExpr(const Expr& right) const; + Expr iteExpr(const Expr& thenpart, const Expr& elsepart) const; + Expr iffExpr(const Expr& right) const; + Expr impExpr(const Expr& right) const; + Expr xorExpr(const Expr& right) const; + + Expr substExpr(const std::vector<Expr>& oldTerms, + const std::vector<Expr>& newTerms) const; + Expr substExpr(const ExprHashMap<Expr>& oldToNew) const; + + Expr operator!() const; + Expr operator&&(const Expr& right) const; + Expr operator||(const Expr& right) const; + + static size_t hash(const Expr& e); + + size_t hash() const; + + // Core expression testers + + bool isFalse() const; + bool isTrue() const; + bool isBoolConst() const; + bool isVar() const; + + bool isEq() const; + bool isNot() const; + bool isAnd() const; + bool isOr() const; + bool isITE() const; + bool isIff() const; + bool isImpl() const; + bool isXor() const; + + bool isRational() const; + bool isSkolem() const; + + //! Get the manual triggers of the closure Expr + std::vector< std::vector<Expr> > getTriggers() const; + + // Get the expression manager. The expression must be non-null. + ExprManager* getEM() const; + + // Return a ref to the vector of children. + std::vector<Expr> getKids() const; + + // Get the index field + ExprIndex getIndex() const; + + // Return the number of children. Note, that an application of a + // user-defined function has the arity of that function (the number + // of arguments), and the function name itself is part of the + // operator. + int arity() const; + + // Return the ith child. As with arity, it's also the ith argument + // in function application. + Expr operator[](int i) const; + + //! Remove leading NOT if any + Expr unnegate() const; + + // Check if Expr is not Null + bool isInitialized() const; + + //! Get the type. Recursively compute if necessary + Type getType() const; + //! Look up the current type. Do not recursively compute (i.e. may be NULL) + Type lookupType() const; + +};/* class CVC3::Expr */ + +typedef Expr Op; +typedef CVC4::StatisticsRegistry Statistics; + +#define PRESENTATION_LANG ::CVC4::language::input::LANG_CVC4 +#define SMTLIB_LANG ::CVC4::language::input::LANG_SMTLIB +#define SMTLIB_V2_LANG ::CVC4::language::input::LANG_SMTLIB_V2 +#define AST_LANG ::CVC4::language::input::LANG_AST + +/*****************************************************************************/ +/* + * Type for result of queries. VALID and UNSATISFIABLE are treated as + * equivalent, as are SATISFIABLE and INVALID. + */ +/*****************************************************************************/ +typedef enum QueryResult { + SATISFIABLE = 0, + INVALID = 0, + VALID = 1, + UNSATISFIABLE = 1, + ABORT, + UNKNOWN +} QueryResult; + +std::ostream& operator<<(std::ostream& out, QueryResult qr); + +/*****************************************************************************/ +/* + * Type for truth value of formulas. + */ +/*****************************************************************************/ +typedef enum FormulaValue { + TRUE_VAL, + FALSE_VAL, + UNKNOWN_VAL +} FormulaValue; + +std::ostream& operator<<(std::ostream& out, FormulaValue fv); + +/*****************************************************************************/ +/*! + *\class ValidityChecker + *\brief CVC3 API (compatibility layer for CVC4) + * + * All terms and formulas are represented as expressions using the Expr class. + * The notion of a context is also important. A context is a "background" set + * of formulas which are assumed to be true or false. Formulas can be added to + * the context explicitly, using assertFormula, or they may be added as part of + * processing a query command. At any time, the current set of formulas making + * up the context can be retrieved using getAssumptions. + */ +/*****************************************************************************/ +class CVC4_PUBLIC ValidityChecker { + + CLFlags* d_clflags; + CVC4::ExprManager d_em; + CVC4::SmtEngine d_smt; + + ValidityChecker(const CLFlags& clflags); + +public: + //! Constructor + ValidityChecker(); + //! Destructor + virtual ~ValidityChecker(); + + //! Return the set of command-line flags + /*! The flags are returned by reference, and if modified, will have an + immediate effect on the subsequent commands. Note that not all flags will + have such an effect; some flags are used only at initialization time (like + "sat"), and therefore, will not take effect if modified after + ValidityChecker is created. + */ + virtual CLFlags& getFlags() const; + //! Force reprocessing of all flags + virtual void reprocessFlags(); + + /***************************************************************************/ + /* + * Static methods + */ + /***************************************************************************/ + + //! Create the set of command line flags with default values; + /*! + \return the set of flags by value + */ + static CLFlags createFlags(); + //! Create an instance of ValidityChecker + /*! + \param flags is the set of command line flags. + */ + static ValidityChecker* create(const CLFlags& flags); + //! Create an instance of ValidityChecker using default flag values. + static ValidityChecker* create(); + + /***************************************************************************/ + /*! + *\name Type-related methods + * Methods for creating and looking up types + *\sa class Type + *@{ + */ + /***************************************************************************/ + + // Basic types + virtual Type boolType(); //!< Create type BOOLEAN + + virtual Type realType(); //!< Create type REAL + + virtual Type intType(); //!< Create type INT + + //! Create a subrange type [l..r] + /*! l and r can be Null; l=Null represents minus infinity, r=Null is + * plus infinity. + */ + virtual Type subrangeType(const Expr& l, const Expr& r); + + //! Creates a subtype defined by the given predicate + /*! + * \param pred is a predicate taking one argument of type T and returning + * Boolean. The resulting type is a subtype of T whose elements x are those + * satisfying the predicate pred(x). + * + * \param witness is an expression of type T for which pred holds (if a Null + * expression is passed as a witness, cvc will try to prove \f$\exists x. pred(x))\f$. + * if the witness check fails, a TypecheckException is thrown. + */ + virtual Type subtypeType(const Expr& pred, const Expr& witness); + + // Tuple types + //! 2-element tuple + virtual Type tupleType(const Type& type0, const Type& type1); + + //! 3-element tuple + virtual Type tupleType(const Type& type0, const Type& type1, + const Type& type2); + //! n-element tuple (from a vector of types) + virtual Type tupleType(const std::vector<Type>& types); + + // Record types + //! 1-element record + virtual Type recordType(const std::string& field, const Type& type); + + //! 2-element record + /*! Fields will be sorted automatically */ + virtual Type recordType(const std::string& field0, const Type& type0, + const std::string& field1, const Type& type1); + //! 3-element record + /*! Fields will be sorted automatically */ + virtual Type recordType(const std::string& field0, const Type& type0, + const std::string& field1, const Type& type1, + const std::string& field2, const Type& type2); + //! n-element record (fields and types must be of the same length) + /*! Fields will be sorted automatically */ + virtual Type recordType(const std::vector<std::string>& fields, + const std::vector<Type>& types); + + // Datatypes + + //! Single datatype, single constructor + /*! The types are either type exressions (obtained from a type with + * getExpr()) or string expressions containing the name of (one of) the + * dataType(s) being defined. */ + virtual Type dataType(const std::string& name, + const std::string& constructor, + const std::vector<std::string>& selectors, + const std::vector<Expr>& types); + + //! Single datatype, multiple constructors + /*! The types are either type exressions (obtained from a type with + * getExpr()) or string expressions containing the name of (one of) the + * dataType(s) being defined. */ + virtual Type dataType(const std::string& name, + const std::vector<std::string>& constructors, + const std::vector<std::vector<std::string> >& selectors, + const std::vector<std::vector<Expr> >& types); + + //! Multiple datatypes + /*! The types are either type exressions (obtained from a type with + * getExpr()) or string expressions containing the name of (one of) the + * dataType(s) being defined. */ + virtual void dataType(const std::vector<std::string>& names, + const std::vector<std::vector<std::string> >& constructors, + const std::vector<std::vector<std::vector<std::string> > >& selectors, + const std::vector<std::vector<std::vector<Expr> > >& types, + std::vector<Type>& returnTypes); + + //! Create an array type (ARRAY typeIndex OF typeData) + virtual Type arrayType(const Type& typeIndex, const Type& typeData); + + //! Create a bitvector type of length n + virtual Type bitvecType(int n); + + //! Create a function type typeDom -> typeRan + virtual Type funType(const Type& typeDom, const Type& typeRan); + + //! Create a function type (t1,t2,...,tn) -> typeRan + virtual Type funType(const std::vector<Type>& typeDom, const Type& typeRan); + + //! Create named user-defined uninterpreted type + virtual Type createType(const std::string& typeName); + + //! Create named user-defined interpreted type (type abbreviation) + virtual Type createType(const std::string& typeName, const Type& def); + + //! Lookup a user-defined (uninterpreted) type by name. Returns Null if none. + virtual Type lookupType(const std::string& typeName); + + /*@}*/ // End of Type-related methods + + /***************************************************************************/ + /*! + *\name General Expr methods + *\sa class Expr + *\sa class ExprManager + *@{ + */ + /***************************************************************************/ + + //! Return the ExprManager + virtual ExprManager* getEM(); + + //! Create a variable with a given name and type + /*! + \param name is the name of the variable + \param type is its type. The type cannot be a function type. + \return an Expr representation of a new variable + */ + virtual Expr varExpr(const std::string& name, const Type& type); + + //! Create a variable with a given name, type, and value + virtual Expr varExpr(const std::string& name, const Type& type, + const Expr& def); + + //! Get the variable associated with a name, and its type + /*! + \param name is the variable name + \param type is where the type value is returned + + \return a variable by the name. If there is no such Expr, a NULL \ + Expr is returned. + */ + virtual Expr lookupVar(const std::string& name, Type* type); + + //! Get the type of the Expr. + virtual Type getType(const Expr& e); + + //! Get the largest supertype of the Expr. + virtual Type getBaseType(const Expr& e); + + //! Get the largest supertype of the Type. + virtual Type getBaseType(const Type& t); + + //! Get the subtype predicate + virtual Expr getTypePred(const Type&t, const Expr& e); + + //! Create a string Expr + virtual Expr stringExpr(const std::string& str); + + //! Create an ID Expr + virtual Expr idExpr(const std::string& name); + + //! Create a list Expr + /*! Intermediate representation for DP-specific expressions. + * Normally, the first element of the list is a string Expr + * representing an operator, and the rest of the list are the + * arguments. For example, + * + * kids.push_back(vc->stringExpr("PLUS")); + * kids.push_back(x); // x and y are previously created Exprs + * kids.push_back(y); + * Expr lst = vc->listExpr(kids); + * + * Or, alternatively (using its overloaded version): + * + * Expr lst = vc->listExpr("PLUS", x, y); + * + * or + * + * vector<Expr> summands; + * summands.push_back(x); summands.push_back(y); ... + * Expr lst = vc->listExpr("PLUS", summands); + */ + virtual Expr listExpr(const std::vector<Expr>& kids); + + //! Overloaded version of listExpr with one argument + virtual Expr listExpr(const Expr& e1); + + //! Overloaded version of listExpr with two arguments + virtual Expr listExpr(const Expr& e1, const Expr& e2); + + //! Overloaded version of listExpr with three arguments + virtual Expr listExpr(const Expr& e1, const Expr& e2, const Expr& e3); + + //! Overloaded version of listExpr with string operator and many arguments + virtual Expr listExpr(const std::string& op, + const std::vector<Expr>& kids); + + //! Overloaded version of listExpr with string operator and one argument + virtual Expr listExpr(const std::string& op, const Expr& e1); + + //! Overloaded version of listExpr with string operator and two arguments + virtual Expr listExpr(const std::string& op, const Expr& e1, + const Expr& e2); + + //! Overloaded version of listExpr with string operator and three arguments + virtual Expr listExpr(const std::string& op, const Expr& e1, + const Expr& e2, const Expr& e3); + + //! Prints e to the standard output + virtual void printExpr(const Expr& e); + + //! Prints e to the given ostream + virtual void printExpr(const Expr& e, std::ostream& os); + + //! Parse an expression using a Theory-specific parser + virtual Expr parseExpr(const Expr& e); + + //! Parse a type expression using a Theory-specific parser + virtual Type parseType(const Expr& e); + + //! Import the Expr from another instance of ValidityChecker + /*! When expressions need to be passed among several instances of + * ValidityChecker, they need to be explicitly imported into the + * corresponding instance using this method. The return result is + * an identical expression that belongs to the current instance of + * ValidityChecker, and can be safely used as part of more complex + * expressions from the same instance. + */ + virtual Expr importExpr(const Expr& e); + + //! Import the Type from another instance of ValidityChecker + /*! \sa getType() */ + virtual Type importType(const Type& t); + + //! Parse a sequence of commands from a presentation language string + virtual void cmdsFromString(const std::string& s, + InputLanguage lang = PRESENTATION_LANG); + + //! Parse an expression from a presentation language string + virtual Expr exprFromString(const std::string& e); + + /*@}*/ // End of General Expr Methods + + /***************************************************************************/ + /*! + *\name Core expression methods + * Methods for manipulating core expressions + * + * Except for equality and ite, the children provided as arguments must be of + * type Boolean. + *@{ + */ + /***************************************************************************/ + + //! Return TRUE Expr + virtual Expr trueExpr(); + + //! Return FALSE Expr + virtual Expr falseExpr(); + + //! Create negation + virtual Expr notExpr(const Expr& child); + + //! Create 2-element conjunction + virtual Expr andExpr(const Expr& left, const Expr& right); + + //! Create n-element conjunction + virtual Expr andExpr(const std::vector<Expr>& children); + + //! Create 2-element disjunction + virtual Expr orExpr(const Expr& left, const Expr& right); + + //! Create n-element disjunction + virtual Expr orExpr(const std::vector<Expr>& children); + + //! Create Boolean implication + virtual Expr impliesExpr(const Expr& hyp, const Expr& conc); + + //! Create left IFF right (boolean equivalence) + virtual Expr iffExpr(const Expr& left, const Expr& right); + + //! Create an equality expression. + /*! + The two children must have the same type, and cannot be of type + Boolean. + */ + virtual Expr eqExpr(const Expr& child0, const Expr& child1); + + //! Create IF ifpart THEN thenpart ELSE elsepart ENDIF + /*! + \param ifpart must be of type Boolean. + \param thenpart and \param elsepart must have the same type, which will + also be the type of the ite expression. + */ + virtual Expr iteExpr(const Expr& ifpart, const Expr& thenpart, + const Expr& elsepart); + + /** + * Create an expression asserting that all the children are different. + * @param children the children to be asserted different + */ + virtual Expr distinctExpr(const std::vector<Expr>& children); + + /*@}*/ // End of Core expression methods + + /***************************************************************************/ + /*! + *\name User-defined (uninterpreted) function methods + * Methods for manipulating uninterpreted function expressions + *@{ + */ + /***************************************************************************/ + + //! Create a named uninterpreted function with a given type + /*! + \param name is the new function's name (as ID Expr) + \param type is a function type ( [range -> domain] ) + */ + virtual Op createOp(const std::string& name, const Type& type); + + //! Create a named user-defined function with a given type + virtual Op createOp(const std::string& name, const Type& type, + const Expr& def); + + //! Get the Op associated with a name, and its type + /*! + \param name is the operator name + \param type is where the type value is returned + + \return an Op by the name. If there is no such Op, a NULL \ + Op is returned. + */ + virtual Op lookupOp(const std::string& name, Type* type); + + //! Unary function application (op must be of function type) + virtual Expr funExpr(const Op& op, const Expr& child); + + //! Binary function application (op must be of function type) + virtual Expr funExpr(const Op& op, const Expr& left, const Expr& right); + + //! Ternary function application (op must be of function type) + virtual Expr funExpr(const Op& op, const Expr& child0, + const Expr& child1, const Expr& child2); + + //! n-ary function application (op must be of function type) + virtual Expr funExpr(const Op& op, const std::vector<Expr>& children); + + /*@}*/ // End of User-defined (uninterpreted) function methods + + /***************************************************************************/ + /*! + *\name Arithmetic expression methods + * Methods for manipulating arithmetic expressions + * + * These functions create arithmetic expressions. The children provided + * as arguments must be of type Real. + *@{ + */ + /***************************************************************************/ + + /*! + * Add the pair of variables to the variable ordering for aritmetic solving. + * Terms that are not arithmetic will be ignored. + * \param smaller the smaller variable + * \param bigger the bigger variable + */ + virtual bool addPairToArithOrder(const Expr& smaller, const Expr& bigger); + + //! Create a rational number with numerator n and denominator d. + /*! + \param n the numerator + \param d the denominator, cannot be 0. + */ + virtual Expr ratExpr(int n, int d = 1); + + //! Create a rational number with numerator n and denominator d. + /*! + Here n and d are given as strings. They are converted to + arbitrary-precision integers according to the given base. + */ + virtual Expr ratExpr(const std::string& n, const std::string& d, int base); + + //! Create a rational from a single string. + /*! + \param n can be a string containing an integer, a pair of integers + "nnn/ddd", or a number in the fixed or floating point format. + \param base is the base in which to interpret the string. + */ + virtual Expr ratExpr(const std::string& n, int base = 10); + + //! Unary minus. + virtual Expr uminusExpr(const Expr& child); + + //! Create 2-element sum (left + right) + virtual Expr plusExpr(const Expr& left, const Expr& right); + + //! Create n-element sum + virtual Expr plusExpr(const std::vector<Expr>& children); + + //! Make a difference (left - right) + virtual Expr minusExpr(const Expr& left, const Expr& right); + + //! Create a product (left * right) + virtual Expr multExpr(const Expr& left, const Expr& right); + + //! Create a power expression (x ^ n); n must be integer + virtual Expr powExpr(const Expr& x, const Expr& n); + + //! Create expression x / y + virtual Expr divideExpr(const Expr& numerator, const Expr& denominator); + + //! Create (left < right) + virtual Expr ltExpr(const Expr& left, const Expr& right); + + //! Create (left <= right) + virtual Expr leExpr(const Expr& left, const Expr& right); + + //! Create (left > right) + virtual Expr gtExpr(const Expr& left, const Expr& right); + + //! Create (left >= right) + virtual Expr geExpr(const Expr& left, const Expr& right); + + /*@}*/ // End of Arithmetic expression methods + + /***************************************************************************/ + /*! + *\name Record expression methods + * Methods for manipulating record expressions + *@{ + */ + /***************************************************************************/ + + //! Create a 1-element record value (# field := expr #) + /*! Fields will be sorted automatically */ + virtual Expr recordExpr(const std::string& field, const Expr& expr); + + //! Create a 2-element record value (# field0 := expr0, field1 := expr1 #) + /*! Fields will be sorted automatically */ + virtual Expr recordExpr(const std::string& field0, const Expr& expr0, + const std::string& field1, const Expr& expr1); + + //! Create a 3-element record value (# field_i := expr_i #) + /*! Fields will be sorted automatically */ + virtual Expr recordExpr(const std::string& field0, const Expr& expr0, + const std::string& field1, const Expr& expr1, + const std::string& field2, const Expr& expr2); + + //! Create an n-element record value (# field_i := expr_i #) + /*! + * \param fields + * \param exprs must be the same length as fields + * + * Fields will be sorted automatically + */ + virtual Expr recordExpr(const std::vector<std::string>& fields, + const std::vector<Expr>& exprs); + + //! Create record.field (field selection) + /*! Create an expression representing the selection of a field from + a record. */ + virtual Expr recSelectExpr(const Expr& record, const std::string& field); + + //! Record update; equivalent to "record WITH .field := newValue" + /*! Notice the `.' before field in the presentation language (and + the comment above); this is to distinguish it from datatype + update. + */ + virtual Expr recUpdateExpr(const Expr& record, const std::string& field, + const Expr& newValue); + + /*@}*/ // End of Record expression methods + + /***************************************************************************/ + /*! + *\name Array expression methods + * Methods for manipulating array expressions + *@{ + */ + /***************************************************************************/ + + //! Create an expression array[index] (array access) + /*! Create an expression for the value of array at the given index */ + virtual Expr readExpr(const Expr& array, const Expr& index); + + //! Array update; equivalent to "array WITH index := newValue" + virtual Expr writeExpr(const Expr& array, const Expr& index, + const Expr& newValue); + + /*@}*/ // End of Array expression methods + + /***************************************************************************/ + /*! + *\name Bitvector expression methods + * Methods for manipulating bitvector expressions + *@{ + */ + /***************************************************************************/ + + // Bitvector constants + // From a string of digits in a given base + virtual Expr newBVConstExpr(const std::string& s, int base = 2); + // From a vector of bools + virtual Expr newBVConstExpr(const std::vector<bool>& bits); + // From a rational: bitvector is of length 'len', or the min. needed length when len=0. + virtual Expr newBVConstExpr(const Rational& r, int len = 0); + + // Concat and extract + virtual Expr newConcatExpr(const Expr& t1, const Expr& t2); + virtual Expr newConcatExpr(const std::vector<Expr>& kids); + virtual Expr newBVExtractExpr(const Expr& e, int hi, int low); + + // Bitwise Boolean operators: Negation, And, Nand, Or, Nor, Xor, Xnor + virtual Expr newBVNegExpr(const Expr& t1); + + virtual Expr newBVAndExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVAndExpr(const std::vector<Expr>& kids); + + virtual Expr newBVOrExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVOrExpr(const std::vector<Expr>& kids); + + virtual Expr newBVXorExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVXorExpr(const std::vector<Expr>& kids); + + virtual Expr newBVXnorExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVXnorExpr(const std::vector<Expr>& kids); + + virtual Expr newBVNandExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVNorExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVCompExpr(const Expr& t1, const Expr& t2); + + // Unsigned bitvector inequalities + virtual Expr newBVLTExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVLEExpr(const Expr& t1, const Expr& t2); + + // Signed bitvector inequalities + virtual Expr newBVSLTExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVSLEExpr(const Expr& t1, const Expr& t2); + + // Sign-extend t1 to a total of len bits + virtual Expr newSXExpr(const Expr& t1, int len); + + // Bitvector arithmetic: unary minus, plus, subtract, multiply + virtual Expr newBVUminusExpr(const Expr& t1); + virtual Expr newBVSubExpr(const Expr& t1, const Expr& t2); + //! 'numbits' is the number of bits in the result + virtual Expr newBVPlusExpr(int numbits, const std::vector<Expr>& k); + virtual Expr newBVPlusExpr(int numbits, const Expr& t1, const Expr& t2); + virtual Expr newBVMultExpr(int numbits, + const Expr& t1, const Expr& t2); + + virtual Expr newBVUDivExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVURemExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVSDivExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVSRemExpr(const Expr& t1, const Expr& t2); + virtual Expr newBVSModExpr(const Expr& t1, const Expr& t2); + + // Left shift by r bits: result is old size + r bits + virtual Expr newFixedLeftShiftExpr(const Expr& t1, int r); + // Left shift by r bits: result is same size as t1 + virtual Expr newFixedConstWidthLeftShiftExpr(const Expr& t1, int r); + // Logical right shift by r bits: result is same size as t1 + virtual Expr newFixedRightShiftExpr(const Expr& t1, int r); + // Left shift with shift parameter an arbitrary bit-vector expr + virtual Expr newBVSHL(const Expr& t1, const Expr& t2); + // Logical right shift with shift parameter an arbitrary bit-vector expr + virtual Expr newBVLSHR(const Expr& t1, const Expr& t2); + // Arithmetic right shift with shift parameter an arbitrary bit-vector expr + virtual Expr newBVASHR(const Expr& t1, const Expr& t2); + // Get value of BV Constant + virtual Rational computeBVConst(const Expr& e); + + /*@}*/ // End of Bitvector expression methods + + /***************************************************************************/ + /*! + *\name Other expression methods + * Methods for manipulating other kinds of expressions + *@{ + */ + /***************************************************************************/ + + //! Tuple expression + virtual Expr tupleExpr(const std::vector<Expr>& exprs); + + //! Tuple select; equivalent to "tuple.n", where n is an numeral (e.g. tup.5) + virtual Expr tupleSelectExpr(const Expr& tuple, int index); + + //! Tuple update; equivalent to "tuple WITH index := newValue" + virtual Expr tupleUpdateExpr(const Expr& tuple, int index, + const Expr& newValue); + + //! Datatype constructor expression + virtual Expr datatypeConsExpr(const std::string& constructor, const std::vector<Expr>& args); + + //! Datatype selector expression + virtual Expr datatypeSelExpr(const std::string& selector, const Expr& arg); + + //! Datatype tester expression + virtual Expr datatypeTestExpr(const std::string& constructor, const Expr& arg); + + //! Create a bound variable with a given name, unique ID (uid) and type + /*! + \param name is the name of the variable + \param uid is the unique ID (a string), which must be unique for + each variable + \param type is its type. The type cannot be a function type. + \return an Expr representation of a new variable + */ + virtual Expr boundVarExpr(const std::string& name, + const std::string& uid, + const Type& type); + + //! Universal quantifier + virtual Expr forallExpr(const std::vector<Expr>& vars, const Expr& body); + //! Universal quantifier with a trigger + virtual Expr forallExpr(const std::vector<Expr>& vars, const Expr& body, + const Expr& trigger); + //! Universal quantifier with a set of triggers. + virtual Expr forallExpr(const std::vector<Expr>& vars, const Expr& body, + const std::vector<Expr>& triggers); + //! Universal quantifier with a set of multi-triggers. + virtual Expr forallExpr(const std::vector<Expr>& vars, const Expr& body, + const std::vector<std::vector<Expr> >& triggers); + + //! Set triggers for quantifier instantiation + /*! + * \param e the expression for which triggers are being set. + * \param triggers Each item in triggers is a vector of Expr containing one + * or more patterns. A pattern is a term or Atomic predicate sub-expression + * of e. A vector containing more than one pattern is treated as a + * multi-trigger. Patterns will be matched in the order they occur in + * the vector. + */ + virtual void setTriggers(const Expr& e, const std::vector<std::vector<Expr> > & triggers); + //! Set triggers for quantifier instantiation (no multi-triggers) + virtual void setTriggers(const Expr& e, const std::vector<Expr>& triggers); + //! Set a single trigger for quantifier instantiation + virtual void setTrigger(const Expr& e, const Expr& trigger); + //! Set a single multi-trigger for quantifier instantiation + virtual void setMultiTrigger(const Expr& e, const std::vector<Expr>& multiTrigger); + + //! Existential quantifier + virtual Expr existsExpr(const std::vector<Expr>& vars, const Expr& body); + + //! Lambda-expression + virtual Op lambdaExpr(const std::vector<Expr>& vars, const Expr& body); + + //! Transitive closure of a binary predicate + virtual Op transClosure(const Op& op); + + //! Symbolic simulation expression + /*! + * \param f is the next state function (LAMBDA-expression) + * \param s0 is the initial state + * \param inputs is the vector of LAMBDA-expressions representing + * the sequences of inputs to f + * \param n is a constant, the number of cycles to run the simulation. + */ + virtual Expr simulateExpr(const Expr& f, const Expr& s0, + const std::vector<Expr>& inputs, + const Expr& n); + + /*@}*/ // End of Other expression methods + + /***************************************************************************/ + /*! + *\name Validity checking methods + * Methods related to validity checking + * + * This group includes methods for asserting formulas, checking + * validity in the given logical context, manipulating the scope + * level of the context, etc. + *@{ + */ + /***************************************************************************/ + + //! Set the resource limit (0==unlimited, 1==exhausted). + /*! Currently, the limit is the total number of processed facts. */ + virtual void setResourceLimit(unsigned limit); + + //! Set a time limit in tenth of a second, + /*! counting the cpu time used by the current process from now on. + * Currently, when the limit is reached, cvc3 tries to quickly + * terminate, probably with the status unknown. + */ + virtual void setTimeLimit(unsigned limit); + + //! Assert a new formula in the current context. + /*! This creates the assumption e |- e. The formula must have Boolean type. + */ + virtual void assertFormula(const Expr& e); + + //! Register an atomic formula of interest. + /*! Registered atoms are tracked by the decision procedures. If one of them + is deduced to be true or false, it is added to a list of implied literals. + Implied literals can be retrieved with the getImpliedLiteral function */ + virtual void registerAtom(const Expr& e); + + //! Return next literal implied by last assertion. Null Expr if none. + /*! Returned literals are either registered atomic formulas or their negation + */ + virtual Expr getImpliedLiteral(); + + //! Simplify e with respect to the current context + virtual Expr simplify(const Expr& e); + + //! Check validity of e in the current context. + /*! If it returns VALID, the scope and context are the same + * as when called. If it returns INVALID, the context will be one which + * falsifies the query. If it returns UNKNOWN, the context will falsify the + * query, but the context may be inconsistent. Finally, if it returns + * ABORT, the context will be one which satisfies as much as possible. + * + * \param e is the queried formula + */ + virtual QueryResult query(const Expr& e); + + //! Check satisfiability of the expr in the current context. + /*! Equivalent to query(!e) */ + virtual QueryResult checkUnsat(const Expr& e); + + //! Get the next model + /*! This method should only be called after a query which returns + INVALID. Its return values are as for query(). */ + virtual QueryResult checkContinue(); + + //! Restart the most recent query with e as an additional assertion. + /*! This method should only be called after a query which returns + INVALID. Its return values are as for query(). */ + virtual QueryResult restart(const Expr& e); + + //! Returns to context immediately before last invalid query. + /*! This method should only be called after a query which returns false. + */ + virtual void returnFromCheck(); + + //! Get assumptions made by the user in this and all previous contexts. + /*! User assumptions are created either by calls to assertFormula or by a + * call to query. In the latter case, the negated query is added as an + * assumption. + * \param assumptions should be empty on entry. + */ + virtual void getUserAssumptions(std::vector<Expr>& assumptions); + + //! Get assumptions made internally in this and all previous contexts. + /*! Internal assumptions are literals assumed by the sat solver. + * \param assumptions should be empty on entry. + */ + virtual void getInternalAssumptions(std::vector<Expr>& assumptions); + + //! Get all assumptions made in this and all previous contexts. + /*! \param assumptions should be empty on entry. + */ + virtual void getAssumptions(std::vector<Expr>& assumptions); + + //! Returns the set of assumptions used in the proof of queried formula. + /*! It returns a subset of getAssumptions(). If the last query was false + * or there has not yet been a query, it does nothing. + * NOTE: this functionality is not supported yet + * \param assumptions should be empty on entry. + */ + virtual void getAssumptionsUsed(std::vector<Expr>& assumptions); + + virtual Expr getProofQuery(); + + + //! Return the internal assumptions that make the queried formula false. + /*! This method should only be called after a query which returns + false. It will try to return the simplest possible subset of + the internal assumptions sufficient to make the queried expression + false. + \param assumptions should be empty on entry. + \param inOrder if true, returns the assumptions in the order they + were made. This is slightly more expensive than inOrder = false. + */ + virtual void getCounterExample(std::vector<Expr>& assumptions, + bool inOrder=true); + + //! Will assign concrete values to all user created variables + /*! This function should only be called after a query which return false. + */ + virtual void getConcreteModel(ExprMap<Expr> & m); + + //! If the result of the last query was UNKNOWN try to actually build the model + //! to verify the result. + /*! This function should only be called after a query which return unknown. + */ + virtual QueryResult tryModelGeneration(); + + //:ALEX: returns the current truth value of a formula + // returns UNKNOWN_VAL if e is not associated + // with a boolean variable in the SAT module, + // i.e. if its value can not determined without search. + virtual FormulaValue value(const Expr& e); + + //! Returns true if the current context is inconsistent. + /*! Also returns a minimal set of assertions used to determine the + inconsistency. + \param assumptions should be empty on entry. + */ + virtual bool inconsistent(std::vector<Expr>& assumptions); + + //! Returns true if the current context is inconsistent. + virtual bool inconsistent(); + + //! Returns true if the invalid result from last query() is imprecise + /*! + * Some decision procedures in CVC are incomplete (quantifier + * elimination, non-linear arithmetic, etc.). If any incomplete + * features were used during the last query(), and the result is + * "invalid" (query() returns false), then this result is + * inconclusive. It means that the system gave up the search for + * contradiction at some point. + */ + virtual bool incomplete(); + + //! Returns true if the invalid result from last query() is imprecise + /*! + * \sa incomplete() + * + * The argument is filled with the reasons for incompleteness (they + * are intended to be shown to the end user). + */ + virtual bool incomplete(std::vector<std::string>& reasons); + + //! Returns the proof term for the last proven query + /*! If there has not been a successful query, it should return a NULL proof + */ + virtual Proof getProof(); + + //! Returns the TCC of the last assumption or query + /*! Returns Null if no assumptions or queries were performed. */ + virtual Expr getTCC(); + + //! Return the set of assumptions used in the proof of the last TCC + virtual void getAssumptionsTCC(std::vector<Expr>& assumptions); + + //! Returns the proof of TCC of the last assumption or query + /*! Returns Null if no assumptions or queries were performed. */ + virtual Proof getProofTCC(); + + //! After successful query, return its closure |- Gamma => phi + /*! Turn a valid query Gamma |- phi into an implication + * |- Gamma => phi. + * + * Returns Null if last query was invalid. + */ + virtual Expr getClosure(); + + //! Construct a proof of the query closure |- Gamma => phi + /*! Returns Null if last query was Invalid. */ + virtual Proof getProofClosure(); + + /*@}*/ // End of Validity checking methods + + /***************************************************************************/ + /*! + *\name Context methods + * Methods for manipulating contexts + * + * Contexts support stack-based push and pop. There are two + * separate notions of the current context stack. stackLevel(), push(), + * pop(), and popto() work with the user-level notion of the stack. + * + * scopeLevel(), pushScope(), popScope(), and poptoScope() work with + * the internal stack which is more fine-grained than the user + * stack. + * + * Do not use the scope methods unless you know what you are doing. + * *@{ + */ + /***************************************************************************/ + + //! Returns the current stack level. Initial level is 0. + virtual int stackLevel(); + + //! Checkpoint the current context and increase the scope level + virtual void push(); + + //! Restore the current context to its state at the last checkpoint + virtual void pop(); + + //! Restore the current context to the given stackLevel. + /*! + \param stackLevel should be greater than or equal to 0 and less + than or equal to the current scope level. + */ + virtual void popto(int stackLevel); + + //! Returns the current scope level. Initially, the scope level is 1. + virtual int scopeLevel(); + + /*! @brief Checkpoint the current context and increase the + * <strong>internal</strong> scope level. Do not use unless you + * know what you're doing! + */ + virtual void pushScope(); + + /*! @brief Restore the current context to its state at the last + * <strong>internal</strong> checkpoint. Do not use unless you know + * what you're doing! + */ + virtual void popScope(); + + //! Restore the current context to the given scopeLevel. + /*! + \param scopeLevel should be less than or equal to the current scope level. + + If scopeLevel is less than 1, then the current context is reset + and the scope level is set to 1. + */ + virtual void poptoScope(int scopeLevel); + + //! Get the current context + virtual Context* getCurrentContext(); + + //! Destroy and recreate validity checker: resets everything except for flags + virtual void reset(); + + //! Add an annotation to the current script - prints annot when translating + virtual void logAnnotation(const Expr& annot); + + /*@}*/ // End of Context methods + + /***************************************************************************/ + /*! + *\name Reading files + * Methods for reading external files + *@{ + */ + /***************************************************************************/ + + //! Read and execute the commands from a file given by name ("" means stdin) + virtual void loadFile(const std::string& fileName, + InputLanguage lang = PRESENTATION_LANG, + bool interactive = false, + bool calledFromParser = false); + + //! Read and execute the commands from a stream + virtual void loadFile(std::istream& is, + InputLanguage lang = PRESENTATION_LANG, + bool interactive = false); + + /*@}*/ // End of methods for reading files + + /***************************************************************************/ + /*! + *\name Reporting Statistics + * Methods for collecting and reporting run-time statistics + *@{ + */ + /***************************************************************************/ + + //! Get statistics object + virtual Statistics& getStatistics(); + + //! Print collected statistics to stdout + virtual void printStatistics(); + + /*@}*/ // End of Statistics Methods + +};/* class ValidityChecker */ + +template <class T> +void ExprHashMap<T>::insert(Expr a, Expr b) { + (*this)[a] = b; +} + +}/* CVC3 namespace */ + +#endif /* _cvc3__include__vc_h_ */ +#endif /* __CVC4__CVC3_COMPAT_H */ diff --git a/src/context/Makefile.am b/src/context/Makefile.am index 9e349a06b..ca5772d7c 100644 --- a/src/context/Makefile.am +++ b/src/context/Makefile.am @@ -18,4 +18,8 @@ libcontext_la_SOURCES = \ cdmap_forward.h \ cdset.h \ cdset_forward.h \ - cdvector.h + cdcirclist.h \ + cdcirclist_forward.h \ + cdvector.h \ + stacking_map.h \ + stacking_vector.h diff --git a/src/context/cdcirclist.h b/src/context/cdcirclist.h new file mode 100644 index 000000000..cc6b60217 --- /dev/null +++ b/src/context/cdcirclist.h @@ -0,0 +1,418 @@ +/********************* */ +/*! \file cdcirclist.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief Context-dependent circular list class + ** + ** Context-dependent circular list class. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__CONTEXT__CDCIRCLIST_H +#define __CVC4__CONTEXT__CDCIRCLIST_H + +#include <iterator> +#include <memory> +#include <string> +#include <sstream> + +#include "context/context.h" +#include "context/context_mm.h" +#include "context/cdcirclist_forward.h" +#include "context/cdo.h" +#include "util/Assert.h" + +namespace CVC4 { +namespace context { + +// CDO for pointers in particular, adds * and -> operators +template <class T> +class CDPtr : public CDO<T*> { + typedef CDO<T*> super; + + // private copy ctor + CDPtr(const CDPtr<T>& cdptr) : + super(cdptr) { + } + +public: + + CDPtr(Context* context, T* data = NULL) : + super(context, data) { + } + + CDPtr(bool allocatedInCMM, Context* context, T* data = NULL) : + super(allocatedInCMM, context, data) { + } + + // undesirable to put this here, since CDO<> does it already (?) + virtual ~CDPtr() throw(AssertionException) { this->destroy(); } + + virtual ContextObj* save(ContextMemoryManager* pCMM) { + Debug("context") << "save cdptr " << this << " (value " << super::get() << ")"; + ContextObj* p = new(pCMM) CDPtr<T>(*this); + Debug("context") << " to " << p << std::endl; + return p; + } + + virtual void restore(ContextObj* pContextObj) { + Debug("context") << "restore cdptr " << this << " (using " << pContextObj << ") from " << super::get(); + this->super::restore(pContextObj); + Debug("context") << " to " << super::get() << std::endl; + } + + CDPtr<T>& operator=(T* data) { + Debug("context") << "set " << this << " from " << super::get(); + super::set(data); + Debug("context") << " to " << super::get() << std::endl; + return *this; + } + // assignment is just like using the underlying ptr + CDPtr<T>& operator=(const CDPtr<T>& cdptr) { + return *this = cdptr.get(); + } + + T& operator*() { return *super::get(); } + T* operator->() { return super::get(); } + const T& operator*() const { return *super::get(); } + const T* operator->() const { return super::get(); } +};/* class CDPtr<T> */ + + +/** + * Class representing a single link in a CDCircList<>. + * + * The underlying T object is immutable, only the structure of the + * list is mutable, so only that's backtracked. + */ +template <class T, class AllocatorT> +class CDCircElement { + typedef CDCircElement<T, AllocatorT> elt_t; + const T d_t; + CDPtr<elt_t> d_prev; + CDPtr<elt_t> d_next; + friend class CDCircList<T, AllocatorT>; +public: + CDCircElement(Context* context, const T& t, + elt_t* prev = NULL, elt_t* next = NULL) : + d_t(t), + d_prev(true, context, prev), + d_next(true, context, next) { + } + + CDPtr<elt_t>& next() { return d_next; } + CDPtr<elt_t>& prev() { return d_prev; } + elt_t* next() const { return d_next; } + elt_t* prev() const { return d_prev; } + T element() const { return d_t; } +};/* class CDCircElement<> */ + + +/** + * Generic context-dependent circular list. Items themselves are not + * context dependent, only the forward and backward links. This + * allows two lists to be spliced together in constant time (see + * concat()). The list *structure* is mutable (things can be spliced + * in, removed, added, the list can be cleared, etc.) in a + * context-dependent manner, but the list items are immutable. To + * replace an item A in the list with B, A must be removed and + * B added in the same location. + */ +template <class T, class AllocatorT> +class CDCircList : public ContextObj { +public: + + /** List carrier element type */ + typedef CDCircElement<T, AllocatorT> elt_t; + /** The value type with which this CDCircList<> was instantiated. */ + typedef T value_type; + /** The allocator type with which this CDCircList<> was instantiated. */ + typedef AllocatorT Allocator; + +private: + + /** Head element of the circular list */ + CDPtr<elt_t> d_head; + /** The context with which we're associated */ + Context* d_context; + /** Our allocator */ + typename Allocator::template rebind< CDCircElement<T, AllocatorT> >::other d_allocator; + +public: + + CDCircList(Context* context, const Allocator& alloc = Allocator()) : + ContextObj(context), + d_head(context, NULL), + d_context(context), + d_allocator(alloc) { + } + + CDCircList(bool allocatedInCMM, Context* context, const Allocator& alloc = Allocator()) : + ContextObj(allocatedInCMM, context), + d_head(allocatedInCMM, context, NULL), + d_context(context), + d_allocator(alloc) { + Debug("cdcirclist") << "head " << &d_head << " in cmm ? " << allocatedInCMM << std::endl; + } + + ~CDCircList() throw(AssertionException) { + // by context contract, call destroy() here + destroy(); + } + + void clear() { + d_head = NULL; + } + + bool empty() const { + return d_head == NULL; + } + + CDPtr<elt_t>& head() { + return d_head; + } + + CDPtr<elt_t>& tail() { + return empty() ? d_head : d_head->d_prev; + } + + const elt_t* head() const { + return d_head; + } + + const elt_t* tail() const { + return empty() ? d_head : d_head->d_prev; + } + + T front() const { + Assert(! empty()); + return head()->element(); + } + + T back() const { + Assert(! empty()); + return tail()->element(); + } + + void push_back(const T& t) { + if(Debug.isOn("cdcirclist:paranoid")) { + debugCheck(); + } + // FIXME LEAK! (should alloc in CMM, no?) + elt_t* x = d_allocator.allocate(1); + if(empty()) { + // zero-element case + new(x) elt_t(d_context, t, x, x); + d_head = x; + } else { + // N-element case + new(x) elt_t(d_context, t, d_head->d_prev, d_head); + d_head->d_prev->d_next = x; + d_head->d_prev = x; + } + } + + /** + * Concatenate two lists. This modifies both: afterward, the two + * lists might have different heads, but they will have the same + * elements in the same (circular) order. + */ + void concat(CDCircList<T, AllocatorT>& l) { + Assert(this != &l, "cannot concat a list with itself"); + + if(d_head == NULL) { + d_head = l.d_head; + return; + } else if(l.d_head == NULL) { + l.d_head = d_head; + return; + } + + // splice together the two circular lists + CDPtr<elt_t> &l1head = head(), &l2head = l.head(); + CDPtr<elt_t> &l1tail = tail(), &l2tail = l.tail(); + // l2tail will change underneath us in what's below (because it's + // the same as l2head->prev()), so we have to keep a regular + // pointer to it + elt_t* oldl2tail = l2tail; + + Debug("cdcirclist") << "concat1 " << this << " " << &l << std::endl; + l1tail->next() = l2head; + Debug("cdcirclist") << "concat2" << std::endl; + l2head->prev() = l1tail; + + Debug("cdcirclist") << "concat3" << std::endl; + oldl2tail->next() = l1head; + Debug("cdcirclist") << "concat4" << std::endl; + l1head->prev() = oldl2tail; + Debug("cdcirclist") << "concat5" << std::endl; + } + + class iterator { + const CDCircList<T, AllocatorT>* d_list; + const elt_t* d_current; + friend class CDCircList<T, AllocatorT>; + public: + iterator(const CDCircList<T, AllocatorT>* list, const elt_t* first) : + d_list(list), + d_current(first) { + } + iterator(const iterator& other) : + d_list(other.d_list), + d_current(other.d_current) { + } + + bool operator==(const iterator& other) const { + return d_list == other.d_list && d_current == other.d_current; + } + bool operator!=(const iterator& other) const { + return !(*this == other); + } + iterator& operator++() { + Assert(d_current != NULL, "iterator already off the end"); + if(d_current == d_list->tail()) { + d_current = NULL; + } else { + d_current = d_current->next(); + } + return *this; + } + iterator operator++(int) { + const elt_t* old = d_current; + ++*this; + return iterator(d_list, old); + } + iterator& operator--() { + // undefined to go off the beginning, but don't have a check for that + if(d_current == NULL) { + d_current = d_list->tail(); + } else { + d_current = d_current->prev(); + } + return *this; + } + iterator operator--(int) { + const elt_t* old = d_current; + --*this; + return iterator(d_list, old); + } + T operator*() { + Assert(d_current != NULL, "iterator already off the end"); + return d_current->element(); + } + };/* class CDCircList<>::iterator */ + + // list elements are immutable + typedef iterator const_iterator; + + iterator begin() { + if(Debug.isOn("cdcirclist:paranoid")) { + debugCheck(); + } + return iterator(this, head()); + } + + iterator end() { + if(Debug.isOn("cdcirclist:paranoid")) { + debugCheck(); + } + return iterator(this, NULL); + } + + const_iterator begin() const { + return const_iterator(this, head()); + } + + const_iterator end() const { + return const_iterator(this, NULL); + } + + iterator erase(iterator pos) { + Assert(pos.d_current != NULL); + if(pos.d_current->prev() == pos.d_current) { + // one-elt list + d_head = NULL; + return iterator(this, NULL); + } else { + // N-elt list + if(pos.d_current == d_head) { + // removing list head + elt_t *pHead = head(), *pTail = tail(); + pTail->next() = pHead->next(); + pHead->next()->prev() = pTail; + d_head = pHead->next(); + return iterator(this, d_head); + // can't free old head, because of backtracking + } else { + // not removing list head + const elt_t *elt = pos.d_current; + elt_t *prev = pos.d_current->prev(); + prev->next() = elt->next(); + elt->next()->prev() = prev; + return iterator(this, elt->next()); + // can't free elt, because of backtracking + } + } + } + +private: + + // do not permit copy/assignment + CDCircList(const CDCircList<T, AllocatorT>&) CVC4_UNUSED; + CDCircList<T, AllocatorT>& operator=(const CDCircList<T, AllocatorT>&) CVC4_UNUSED; + +public: + /** Check internal structure and invariants of the list */ + void debugCheck() const { + elt_t* p = d_head; + Debug("cdcirclist") << "this is " << this << std::endl; + if(p == NULL) { + Debug("cdcirclist") << "head[" << &d_head << "] is NULL : " << d_context->getLevel() << std::endl; + // empty list + return; + } + Debug("cdcirclist") << "head[" << &d_head << "] is " << p << " next " << p->d_next << " prev " << p->d_prev << " : " << d_context->getLevel() << std::endl;//p->d_t << std::endl; + do { + elt_t* p_last = p; + p = p->d_next; + if(p == NULL) { + Debug("cdcirclist") << "****** ERROR ON LINE ABOVE, next == NULL ******" << std::endl; + break; + } + Debug("cdcirclist") << " p is " << p << " next " << p->d_next << " prev " << p->d_prev << " : " << std::endl;//p->d_t << std::endl; + if(p->d_prev != p_last) { + Debug("cdcirclist") << "****** ERROR ON LINE ABOVE, prev != last ******" << std::endl; + } + //Assert(p->d_prev == p_last); + Assert(p != NULL); + } while(p != d_head); + } + +private: + + // Nothing to save; the elements take care of themselves + virtual ContextObj* save(ContextMemoryManager* pCMM) { + Unreachable(); + } + + // Similarly, nothing to restore + virtual void restore(ContextObj* data) { + Unreachable(); + } + +};/* class CDCircList<> */ + +}/* CVC4::context namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__CONTEXT__CDCIRCLIST_H */ diff --git a/src/context/cdcirclist_forward.h b/src/context/cdcirclist_forward.h new file mode 100644 index 000000000..56a39e96f --- /dev/null +++ b/src/context/cdcirclist_forward.h @@ -0,0 +1,45 @@ +/********************* */ +/*! \file cdcirclist_forward.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief This is a forward declaration header to declare the + ** CDCircList<> template + ** + ** This is a forward declaration header to declare the CDCircList<> + ** template. It's useful if you want to forward-declare CDCircList<> + ** without including the full cdcirclist.h header, for example, in a + ** public header context, or to keep compile times low when only a + ** forward declaration is needed. + **/ + +#include "cvc4_public.h" + +#ifndef __CVC4__CONTEXT__CDCIRCLIST_FORWARD_H +#define __CVC4__CONTEXT__CDCIRCLIST_FORWARD_H + +#include <memory> + +namespace __gnu_cxx { + template <class Key> struct hash; +}/* __gnu_cxx namespace */ + +namespace CVC4 { + namespace context { + template <class T> + class ContextMemoryAllocator; + + template <class T, class Allocator = ContextMemoryAllocator<T> > + class CDCircList; + }/* CVC4::context namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__CONTEXT__CDCIRCLIST_FORWARD_H */ diff --git a/src/context/cdlist.h b/src/context/cdlist.h index c999ecadb..dea9f8be7 100644 --- a/src/context/cdlist.h +++ b/src/context/cdlist.h @@ -3,17 +3,18 @@ ** \verbatim ** Original author: mdeters ** Major contributors: none - ** Minor contributors (to current version): barrett, taking + ** Minor contributors (to current version): taking ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim ** - ** \brief Context-dependent list class. + ** \brief Context-dependent list class (only supports append) ** - ** Context-dependent list class. + ** Context-dependent list class. This list only supports appending + ** to the list; on backtrack, the list is simply shortened. **/ #include "cvc4_private.h" diff --git a/src/context/cdlist_context_memory.h b/src/context/cdlist_context_memory.h index 45a44756d..fcb51fe20 100644 --- a/src/context/cdlist_context_memory.h +++ b/src/context/cdlist_context_memory.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/context/cdlist_forward.h b/src/context/cdlist_forward.h index a1e50c7c8..90c439085 100644 --- a/src/context/cdlist_forward.h +++ b/src/context/cdlist_forward.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/context/cdmap.h b/src/context/cdmap.h index c71459835..3ac99f729 100644 --- a/src/context/cdmap.h +++ b/src/context/cdmap.h @@ -5,7 +5,7 @@ ** Major contributors: none ** Minor contributors (to current version): taking, dejan ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/context/cdmap_forward.h b/src/context/cdmap_forward.h index 214d9e700..331d6a93e 100644 --- a/src/context/cdmap_forward.h +++ b/src/context/cdmap_forward.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/context/cdo.h b/src/context/cdo.h index f4c4a7e29..025e8e337 100644 --- a/src/context/cdo.h +++ b/src/context/cdo.h @@ -5,7 +5,7 @@ ** Major contributors: none ** Minor contributors (to current version): barrett ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 @@ -40,13 +40,29 @@ class CDO : public ContextObj { */ T d_data; +protected: + + /** + * Copy constructor - it's private to ensure it is only used by save(). + * Basic CDO objects, cannot be copied-they have to be unique. + */ + CDO(const CDO<T>& cdo) : ContextObj(cdo), d_data(cdo.d_data) {} + + /** + * operator= for CDO is private to ensure CDO object is not copied. + */ + CDO<T>& operator=(const CDO<T>& cdo) CVC4_UNUSED; + /** * Implementation of mandatory ContextObj method save: simply copies the * current data to a copy using the copy constructor. Memory is allocated * using the ContextMemoryManager. */ virtual ContextObj* save(ContextMemoryManager* pCMM) { - return new(pCMM) CDO<T>(*this); + Debug("context") << "save cdo " << this << " (value " << get() << ")"; + ContextObj* p = new(pCMM) CDO<T>(*this); + Debug("context") << " to " << p << std::endl; + return p; } /** @@ -54,20 +70,11 @@ class CDO : public ContextObj { * saved data back from the saved copy using operator= for T. */ virtual void restore(ContextObj* pContextObj) { + //Debug("context") << "restore cdo " << this << " from " << get(); d_data = ((CDO<T>*) pContextObj)->d_data; + //Debug("context") << " to " << get() << std::endl; } - /** - * Copy constructor - it's private to ensure it is only used by save(). - * Basic CDO objects, cannot be copied-they have to be unique. - */ - CDO(const CDO<T>& cdo) : ContextObj(cdo), d_data(cdo.d_data) {} - - /** - * operator= for CDO is private to ensure CDO object is not copied. - */ - CDO<T>& operator=(const CDO<T>& cdo); - public: /** @@ -75,7 +82,8 @@ public: * value of d_data. */ CDO(Context* context) : - ContextObj(context) { + ContextObj(context), + d_data(T()) { } /** @@ -90,7 +98,8 @@ public: * allocating contextual objects with non-standard allocators." */ CDO(bool allocatedInCMM, Context* context) : - ContextObj(allocatedInCMM, context) { + ContextObj(allocatedInCMM, context), + d_data(T()) { } /** @@ -100,7 +109,8 @@ public: * is assigned by the default constructor for T */ CDO(Context* context, const T& data) : - ContextObj(context) { + ContextObj(context), + d_data(T()) { makeCurrent(); d_data = data; } @@ -119,7 +129,8 @@ public: * allocating contextual objects with non-standard allocators." */ CDO(bool allocatedInCMM, Context* context, const T& data) : - ContextObj(allocatedInCMM, context) { + ContextObj(allocatedInCMM, context), + d_data(T()) { makeCurrent(); d_data = data; } diff --git a/src/context/cdset.h b/src/context/cdset.h index 268c3127b..8699d9cf4 100644 --- a/src/context/cdset.h +++ b/src/context/cdset.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/context/cdset_forward.h b/src/context/cdset_forward.h index af3c6f85c..2339552a6 100644 --- a/src/context/cdset_forward.h +++ b/src/context/cdset_forward.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/context/cdvector.h b/src/context/cdvector.h index cb86d5c4d..49d1b67e9 100644 --- a/src/context/cdvector.h +++ b/src/context/cdvector.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/context/context.cpp b/src/context/context.cpp index 9b40e9780..2b220d5b4 100644 --- a/src/context/context.cpp +++ b/src/context/context.cpp @@ -5,7 +5,7 @@ ** Major contributors: barrett ** 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) + ** Copyright (c) 2009, 2010, 2011 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 @@ -78,8 +78,10 @@ void Context::pop() { // Notify the (pre-pop) ContextNotifyObj objects ContextNotifyObj* pCNO = d_pCNOpre; while(pCNO != NULL) { + // pre-store the "next" pointer in case pCNO deletes itself on notify() + ContextNotifyObj* next = pCNO->d_pCNOnext; pCNO->notify(); - pCNO = pCNO->d_pCNOnext; + pCNO = next; } // Grab the top Scope @@ -97,8 +99,10 @@ void Context::pop() { // Notify the (post-pop) ContextNotifyObj objects pCNO = d_pCNOpost; while(pCNO != NULL) { + // pre-store the "next" pointer in case pCNO deletes itself on notify() + ContextNotifyObj* next = pCNO->d_pCNOnext; pCNO->notify(); - pCNO = pCNO->d_pCNOnext; + pCNO = next; } Trace("pushpop") << std::string(2 * getLevel(), ' ') << "} Pop [to " @@ -135,6 +139,7 @@ void Context::addNotifyObjPost(ContextNotifyObj* pCNO) { void ContextObj::update() throw(AssertionException) { Debug("context") << "before update(" << this << "):" << std::endl + << "context is " << getContext() << std::endl << *getContext() << std::endl; // Call save() to save the information in the current object @@ -203,6 +208,7 @@ ContextObj* ContextObj::restoreAndContinue() throw(AssertionException) { // Assert(d_pScope == d_pScope->getContext()->getBottomScope(), // "Expected bottom scope"); + Debug("context") << "NULL restore object! " << this << std::endl; pContextObjNext = d_pContextObjNext; // Nothing else to do @@ -261,22 +267,28 @@ void ContextObj::destroy() throw(AssertionException) { ContextObj::ContextObj(Context* pContext) : - d_pContextObjRestore(NULL) { + d_pScope(NULL), + d_pContextObjRestore(NULL), + d_pContextObjNext(NULL), + d_ppContextObjPrev(NULL) { Assert(pContext != NULL, "NULL context pointer"); - Debug("context") << "create new ContextObj(" << this << ")" << std::endl; + Debug("context") << "create new ContextObj(" << this << " inCMM=false)" << std::endl; d_pScope = pContext->getBottomScope(); d_pScope->addToChain(this); } ContextObj::ContextObj(bool allocatedInCMM, Context* pContext) : - d_pContextObjRestore(NULL) { + d_pScope(NULL), + d_pContextObjRestore(NULL), + d_pContextObjNext(NULL), + d_ppContextObjPrev(NULL) { Assert(pContext != NULL, "NULL context pointer"); - Debug("context") << "create new ContextObj(" << this << ")" << std::endl; + Debug("context") << "create new ContextObj(" << this << " inCMM=" << allocatedInCMM << ")" << std::endl; if(allocatedInCMM) { d_pScope = pContext->getTopScope(); } else { @@ -326,12 +338,15 @@ std::ostream& operator<<(std::ostream& out, std::ostream& operator<<(std::ostream& out, const Scope& scope) throw(AssertionException) { - out << "Scope " << scope.d_level << ":"; + out << "Scope " << scope.d_level << " [" << &scope << "]:"; ContextObj* pContextObj = scope.d_pContextObjList; Assert(pContextObj == NULL || pContextObj->prev() == &scope.d_pContextObjList); while(pContextObj != NULL) { out << " <--> " << pContextObj; + if(pContextObj->d_pScope != &scope) { + out << " XXX bad scope" << std::endl; + } Assert(pContextObj->d_pScope == &scope); Assert(pContextObj->next() == NULL || pContextObj->next()->prev() == &pContextObj->next()); diff --git a/src/context/context.h b/src/context/context.h index 34107ef29..1e69964a0 100644 --- a/src/context/context.h +++ b/src/context/context.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: mdeters ** Major contributors: barrett - ** Minor contributors (to current version): taking, dejan + ** Minor contributors (to current version): dejan, taking ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/context/context_mm.cpp b/src/context/context_mm.cpp index fde69a149..aea2fe9c2 100644 --- a/src/context/context_mm.cpp +++ b/src/context/context_mm.cpp @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/context/context_mm.h b/src/context/context_mm.h index 56ef7ab59..66db21424 100644 --- a/src/context/context_mm.h +++ b/src/context/context_mm.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 @@ -161,10 +161,11 @@ public: }; ContextMemoryAllocator(ContextMemoryManager* mm) throw() : d_mm(mm) {} - ContextMemoryAllocator(const ContextMemoryAllocator& alloc) throw() : d_mm(alloc.d_mm) {} + template <class U> + ContextMemoryAllocator(const ContextMemoryAllocator<U>& alloc) throw() : d_mm(alloc.getCMM()) {} ~ContextMemoryAllocator() throw() {} - ContextMemoryManager* getCMM() { return d_mm; } + ContextMemoryManager* getCMM() const { return d_mm; } T* address(T& v) const { return &v; } T const* address(T const& v) const { return &v; } size_t max_size() const throw() { diff --git a/src/context/stacking_map.h b/src/context/stacking_map.h new file mode 100644 index 000000000..2dec1845c --- /dev/null +++ b/src/context/stacking_map.h @@ -0,0 +1,162 @@ +/********************* */ +/*! \file stacking_map.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief Backtrackable map using an undo stack + ** + ** Backtrackable map using an undo stack rather than storing items in + ** a CDMap<>. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__CONTEXT__STACKING_MAP_H +#define __CVC4__CONTEXT__STACKING_MAP_H + +#include <utility> +#include <vector> +#include <ext/hash_map> + +#include "expr/node.h" +#include "context/cdo.h" + +namespace CVC4 { +namespace context { + +template <class T> +struct StackingMapArgType { + typedef T argtype; +};/* struct StackingMapArgType<T> */ + +template <> +struct StackingMapArgType<Node> { + typedef TNode argtype; +};/* struct StackingMapArgType<Node> */ + + +template <class KeyType, class ValueType, class KeyHash> +struct StackingMapRestoreValue { + typedef typename StackingMapArgType<KeyType>::argtype ArgType; + static void restore(__gnu_cxx::hash_map<KeyType, ValueType, KeyHash>& map, const ArgType& k, const ValueType& v) { + map[k] = v; + } +};/* struct StackingMapRestoreValue<KeyType, ValueType, KeyHash> */ + +template <class KeyType, class KeyHash> +struct StackingMapRestoreValue<KeyType, Node, KeyHash> { + typedef typename StackingMapArgType<KeyType>::argtype ArgType; + static void restore(__gnu_cxx::hash_map<KeyType, Node, KeyHash>& map, const ArgType& k, TNode v) { + if(v.isNull()) { + map.erase(k); + } else { + map[k] = v; + } + } +};/* struct StackingMapRestoreValue<KeyType, Node, KeyHash> */ + +template <class KeyType, class KeyHash> +struct StackingMapRestoreValue<KeyType, TNode, KeyHash> { + typedef typename StackingMapArgType<KeyType>::argtype ArgType; + static void restore(__gnu_cxx::hash_map<KeyType, TNode, KeyHash>& map, const ArgType& k, TNode v) { + if(v.isNull()) { + map.erase(k); + } else { + map[k] = v; + } + } +};/* struct StackingMapRestoreValue<KeyType, TNode, KeyHash> */ + + +template <class KeyType, class ValueType, class KeyHash> +class StackingMap : context::ContextNotifyObj { + /** Our underlying map type. */ + typedef __gnu_cxx::hash_map<KeyType, ValueType, KeyHash> MapType; + + /** + * The type for arguments being passed in. It's the same as + * KeyType, unless KeyType is Node, then it's TNode for efficiency. + */ + typedef typename StackingMapArgType<KeyType>::argtype ArgType; + + /** Our map of keys to their values. */ + MapType d_map; + + /** Our undo stack for changes made to d_map. */ + std::vector<std::pair<ArgType, ValueType> > d_trace; + + /** Our current offset in the d_trace stack (context-dependent). */ + context::CDO<size_t> d_offset; + +public: + typedef typename MapType::const_iterator const_iterator; + + StackingMap(context::Context* ctxt) : + context::ContextNotifyObj(ctxt), + d_offset(ctxt, 0) { + } + + ~StackingMap() throw() { } + + const_iterator find(ArgType n) const { return d_map.find(n); } + const_iterator end() const { return d_map.end(); } + + /** + * Return a key's value in the key-value map. If n is not a key in + * the map, this function returns a default-constructed value. + */ + ValueType operator[](ArgType n) const { + const_iterator it = find(n); + if(it == end()) { + return ValueType(); + } else { + return (*it).second; + } + } + //ValueType& operator[](ArgType n) { return d_map[n]; }// not permitted--bypasses set() logic + + /** + * Set the value in the key-value map for Node n to newValue. + */ + void set(ArgType n, const ValueType& newValue); + + /** + * Called by the Context when a pop occurs. Cancels everything to the + * current context level. Overrides ContextNotifyObj::notify(). + */ + void notify(); + +};/* class StackingMap<> */ + +template <class KeyType, class ValueType, class KeyHash> +void StackingMap<KeyType, ValueType, KeyHash>::set(ArgType n, const ValueType& newValue) { + Trace("sm") << "SM setting " << n << " : " << newValue << " @ " << d_trace.size() << std::endl; + ValueType& ref = d_map[n]; + d_trace.push_back(std::make_pair(n, ValueType(ref))); + d_offset = d_trace.size(); + ref = newValue; +} + +template <class KeyType, class ValueType, class KeyHash> +void StackingMap<KeyType, ValueType, KeyHash>::notify() { + Trace("sm") << "SM cancelling : " << d_offset << " < " << d_trace.size() << " ?" << std::endl; + while(d_offset < d_trace.size()) { + std::pair<ArgType, ValueType> p = d_trace.back(); + StackingMapRestoreValue<KeyType, ValueType, KeyHash>::restore(d_map, p.first, p.second); + d_trace.pop_back(); + } + Trace("sm") << "SM cancelling finished." << std::endl; +} + +}/* CVC4::context namespace */ +}/* CVC4 namespace */ + +#endif /*__CVC4__CONTEXT__STACKING_MAP_H */ diff --git a/src/context/stacking_vector.h b/src/context/stacking_vector.h new file mode 100644 index 000000000..9987731d4 --- /dev/null +++ b/src/context/stacking_vector.h @@ -0,0 +1,116 @@ +/********************* */ +/*! \file stacking_vector.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief Backtrackable vector using an undo stack + ** + ** Backtrackable vector using an undo stack rather than storing items in + ** a CDVector<>. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__CONTEXT__STACKING_VECTOR_H +#define __CVC4__CONTEXT__STACKING_VECTOR_H + +#include <utility> +#include <vector> + +#include "context/cdo.h" + +namespace CVC4 { +namespace context { + +template <class T> +class StackingVector : context::ContextNotifyObj { + /** Our underlying map type. */ + typedef std::vector<T> VectorType; + + /** Our map of indices to their values. */ + VectorType d_map; + + /** Our undo stack for changes made to d_map. */ + std::vector<std::pair<size_t, T> > d_trace; + + /** Our current offset in the d_trace stack (context-dependent). */ + context::CDO<size_t> d_offset; + +public: + typedef typename VectorType::const_iterator const_iterator; + + StackingVector(context::Context* ctxt) : + context::ContextNotifyObj(ctxt), + d_offset(ctxt, 0) { + } + + ~StackingVector() throw() { } + + /** + * Return a value from the vector. If n is not a key in + * the map, this function returns a default-constructed T. + */ + T operator[](size_t n) const { + return n < d_map.size() ? d_map[n] : T(); + } + //T& operator[](ArgType n) { return d_map[n]; }// not permitted--bypasses set() logic + + /** + * Set the value in the key-value map for Node n to newValue. + */ + void set(size_t n, const T& newValue); + + /** + * Return the current size of the vector. Note that once a certain + * size is achieved, the size never goes down again, although the + * elements off the old end of the vector will be replaced with + * default-constructed T values. + */ + size_t size() const { + return d_map.size(); + } + + /** + * Called by the Context when a pop occurs. Cancels everything to the + * current context level. Overrides ContextNotifyObj::notify(). + */ + void notify(); + +};/* class StackingVector<> */ + +template <class T> +void StackingVector<T>::set(size_t n, const T& newValue) { + Trace("sv") << "SV setting " << n << " : " << newValue << " @ " << d_trace.size() << std::endl; + if(n >= d_map.size()) { + d_map.resize(n + 1); + } + T& ref = d_map[n]; + d_trace.push_back(std::make_pair(n, T(ref))); + d_offset = d_trace.size(); + ref = newValue; +} + +template <class T> +void StackingVector<T>::notify() { + Trace("sv") << "SV cancelling : " << d_offset << " < " << d_trace.size() << " ?" << std::endl; + while(d_offset < d_trace.size()) { + std::pair<size_t, T> p = d_trace.back(); + Trace("sv") << "SV cancelling: " << p.first << " back to " << p.second << std::endl; + d_map[p.first] = p.second; + d_trace.pop_back(); + } + Trace("sv") << "SV cancelling finished." << std::endl; +} + +}/* CVC4::context namespace */ +}/* CVC4 namespace */ + +#endif /*__CVC4__CONTEXT__STACKING_VECTOR_H */ diff --git a/src/expr/Makefile.am b/src/expr/Makefile.am index 352647642..738604f90 100644 --- a/src/expr/Makefile.am +++ b/src/expr/Makefile.am @@ -16,6 +16,7 @@ libexpr_la_SOURCES = \ type.cpp \ node_value.h \ node_manager.h \ + type_checker.h \ attribute.h \ attribute_internals.h \ attribute.cpp \ @@ -37,7 +38,8 @@ nodist_libexpr_la_SOURCES = \ expr.h \ expr.cpp \ expr_manager.h \ - expr_manager.cpp + expr_manager.cpp \ + type_checker.cpp EXTRA_DIST = \ kind_template.h \ @@ -47,6 +49,7 @@ EXTRA_DIST = \ expr_manager_template.cpp \ expr_template.h \ expr_template.cpp \ + type_checker_template.cpp \ mkkind \ mkmetakind \ mkexpr @@ -59,6 +62,7 @@ BUILT_SOURCES = \ expr.cpp \ expr_manager.h \ expr_manager.cpp \ + type_checker.cpp \ $(top_builddir)/src/theory/.subdirs CLEANFILES = \ @@ -68,6 +72,7 @@ CLEANFILES = \ expr.cpp \ expr_manager.h \ expr_manager.cpp \ + type_checker.cpp \ $(top_builddir)/src/theory/.subdirs include @top_srcdir@/src/theory/Makefile.subdirs @@ -127,3 +132,11 @@ expr_manager.cpp: expr_manager_template.cpp mkexpr @top_builddir@/src/theory/.su $< \ `cat @top_builddir@/src/theory/.subdirs` \ > $@) || (rm -f $@ && exit 1) + +type_checker.cpp: type_checker_template.cpp mkexpr @top_builddir@/src/theory/.subdirs @top_srcdir@/src/theory/*/kinds + $(AM_V_at)chmod +x @srcdir@/mkexpr + $(AM_V_at)$(am__mv) $@ $@~ 2>/dev/null || true + $(AM_V_GEN)(@srcdir@/mkexpr \ + $< \ + `cat @top_builddir@/src/theory/.subdirs` \ + > $@) || (rm -f $@ && exit 1) diff --git a/src/expr/attribute.cpp b/src/expr/attribute.cpp index 85c0fe528..d58173454 100644 --- a/src/expr/attribute.cpp +++ b/src/expr/attribute.cpp @@ -5,7 +5,7 @@ ** Major contributors: dejan ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/expr/attribute.h b/src/expr/attribute.h index 9b21184d0..3da3799be 100644 --- a/src/expr/attribute.h +++ b/src/expr/attribute.h @@ -5,7 +5,7 @@ ** Major contributors: dejan ** Minor contributors (to current version): cconway, taking ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/expr/command.cpp b/src/expr/command.cpp index 2783e8eaa..5fb4d1fbd 100644 --- a/src/expr/command.cpp +++ b/src/expr/command.cpp @@ -78,6 +78,10 @@ EmptyCommand::EmptyCommand(std::string name) : d_name(name) { } +std::string EmptyCommand::getName() const { + return d_name; +} + void EmptyCommand::invoke(SmtEngine* smtEngine) { /* empty commands have no implementation */ } @@ -88,6 +92,10 @@ AssertCommand::AssertCommand(const BoolExpr& e) : d_expr(e) { } +BoolExpr AssertCommand::getExpr() const { + return d_expr; +} + void AssertCommand::invoke(SmtEngine* smtEngine) { smtEngine->assertFormula(d_expr); } @@ -106,10 +114,18 @@ void PopCommand::invoke(SmtEngine* smtEngine) { /* class CheckSatCommand */ +CheckSatCommand::CheckSatCommand() : + d_expr() { +} + CheckSatCommand::CheckSatCommand(const BoolExpr& expr) : d_expr(expr) { } +BoolExpr CheckSatCommand::getExpr() const { + return d_expr; +} + void CheckSatCommand::invoke(SmtEngine* smtEngine) { d_result = smtEngine->checkSat(d_expr); } @@ -128,6 +144,10 @@ QueryCommand::QueryCommand(const BoolExpr& e) : d_expr(e) { } +BoolExpr QueryCommand::getExpr() const { + return d_expr; +} + void QueryCommand::invoke(SmtEngine* smtEngine) { d_result = smtEngine->query(d_expr); } @@ -145,6 +165,23 @@ void QueryCommand::printResult(std::ostream& out) const { QuitCommand::QuitCommand() { } +void QuitCommand::invoke(SmtEngine* smtEngine) { + Dump("benchmark") << *this; +} + +/* class CommentCommand */ + +CommentCommand::CommentCommand(std::string comment) : d_comment(comment) { +} + +std::string CommentCommand::getComment() const { + return d_comment; +} + +void CommentCommand::invoke(SmtEngine* smtEngine) { + Dump("benchmark") << *this; +} + /* class CommandSequence */ CommandSequence::CommandSequence() : @@ -175,51 +212,150 @@ void CommandSequence::invoke(SmtEngine* smtEngine, std::ostream& out) { } } -/* class DeclarationCommand */ +CommandSequence::const_iterator CommandSequence::begin() const { + return d_commandSequence.begin(); +} + +CommandSequence::const_iterator CommandSequence::end() const { + return d_commandSequence.end(); +} + +CommandSequence::iterator CommandSequence::begin() { + return d_commandSequence.begin(); +} + +CommandSequence::iterator CommandSequence::end() { + return d_commandSequence.end(); +} + +/* class DeclarationSequenceCommand */ + +/* class DeclarationDefinitionCommand */ + +DeclarationDefinitionCommand::DeclarationDefinitionCommand(const std::string& id) : + d_symbol(id) { +} + +std::string DeclarationDefinitionCommand::getSymbol() const { + return d_symbol; +} + +/* class DeclareFunctionCommand */ + +DeclareFunctionCommand::DeclareFunctionCommand(const std::string& id, Type t) : + DeclarationDefinitionCommand(id), + d_type(t) { +} + +Type DeclareFunctionCommand::getType() const { + return d_type; +} + +void DeclareFunctionCommand::invoke(SmtEngine* smtEngine) { + Dump("declarations") << *this << endl; +} + +/* class DeclareTypeCommand */ + +DeclareTypeCommand::DeclareTypeCommand(const std::string& id, size_t arity, Type t) : + DeclarationDefinitionCommand(id), + d_arity(arity), + d_type(t) { +} + +size_t DeclareTypeCommand::getArity() const { + return d_arity; +} + +Type DeclareTypeCommand::getType() const { + return d_type; +} + +void DeclareTypeCommand::invoke(SmtEngine* smtEngine) { + Dump("declarations") << *this << endl; +} + +/* class DefineTypeCommand */ -DeclarationCommand::DeclarationCommand(const std::string& id, Type t) : +DefineTypeCommand::DefineTypeCommand(const std::string& id, + Type t) : + DeclarationDefinitionCommand(id), + d_params(), d_type(t) { - d_declaredSymbols.push_back(id); } -DeclarationCommand::DeclarationCommand(const std::vector<std::string>& ids, Type t) : - d_declaredSymbols(ids), +DefineTypeCommand::DefineTypeCommand(const std::string& id, + const std::vector<Type>& params, + Type t) : + DeclarationDefinitionCommand(id), + d_params(params), d_type(t) { } -const std::vector<std::string>& DeclarationCommand::getDeclaredSymbols() const { - return d_declaredSymbols; +const std::vector<Type>& DefineTypeCommand::getParameters() const { + return d_params; } -Type DeclarationCommand::getDeclaredType() const { +Type DefineTypeCommand::getType() const { return d_type; } +void DefineTypeCommand::invoke(SmtEngine* smtEngine) { + Dump("declarations") << *this << endl; +} + /* class DefineFunctionCommand */ -DefineFunctionCommand::DefineFunctionCommand(Expr func, +DefineFunctionCommand::DefineFunctionCommand(const std::string& id, + Expr func, + Expr formula) : + DeclarationDefinitionCommand(id), + d_func(func), + d_formals(), + d_formula(formula) { +} + +DefineFunctionCommand::DefineFunctionCommand(const std::string& id, + Expr func, const std::vector<Expr>& formals, Expr formula) : + DeclarationDefinitionCommand(id), d_func(func), d_formals(formals), d_formula(formula) { } +Expr DefineFunctionCommand::getFunction() const { + return d_func; +} + +const std::vector<Expr>& DefineFunctionCommand::getFormals() const { + return d_formals; +} + +Expr DefineFunctionCommand::getFormula() const { + return d_formula; +} + void DefineFunctionCommand::invoke(SmtEngine* smtEngine) { - smtEngine->defineFunction(d_func, d_formals, d_formula); + Dump("declarations") << *this << endl; + if(!d_func.isNull()) { + smtEngine->defineFunction(d_func, d_formals, d_formula); + } } -/* class DefineFunctionCommand */ +/* class DefineNamedFunctionCommand */ -DefineNamedFunctionCommand::DefineNamedFunctionCommand(Expr func, +DefineNamedFunctionCommand::DefineNamedFunctionCommand(const std::string& id, + Expr func, const std::vector<Expr>& formals, Expr formula) : - DefineFunctionCommand(func, formals, formula) { + DefineFunctionCommand(id, func, formals, formula) { } void DefineNamedFunctionCommand::invoke(SmtEngine* smtEngine) { this->DefineFunctionCommand::invoke(smtEngine); - if(d_func.getType().isBoolean()) { + if(!d_func.isNull() && d_func.getType().isBoolean()) { smtEngine->addToAssignment(d_func.getExprManager()->mkExpr(kind::APPLY, d_func)); } @@ -231,6 +367,10 @@ SimplifyCommand::SimplifyCommand(Expr term) : d_term(term) { } +Expr SimplifyCommand::getTerm() const { + return d_term; +} + void SimplifyCommand::invoke(SmtEngine* smtEngine) { d_result = smtEngine->simplify(d_term); } @@ -249,6 +389,10 @@ GetValueCommand::GetValueCommand(Expr term) : d_term(term) { } +Expr GetValueCommand::getTerm() const { + return d_term; +} + void GetValueCommand::invoke(SmtEngine* smtEngine) { d_result = d_term.getExprManager()->mkExpr(kind::TUPLE, d_term, smtEngine->getValue(d_term)); @@ -305,6 +449,10 @@ SetBenchmarkStatusCommand::SetBenchmarkStatusCommand(BenchmarkStatus status) : d_status(status) { } +BenchmarkStatus SetBenchmarkStatusCommand::getStatus() const { + return d_status; +} + void SetBenchmarkStatusCommand::invoke(SmtEngine* smtEngine) { stringstream ss; ss << d_status; @@ -326,6 +474,10 @@ SetBenchmarkLogicCommand::SetBenchmarkLogicCommand(std::string logic) : d_logic(logic) { } +std::string SetBenchmarkLogicCommand::getLogic() const { + return d_logic; +} + void SetBenchmarkLogicCommand::invoke(SmtEngine* smtEngine) { try { smtEngine->setLogic(d_logic); @@ -337,11 +489,19 @@ void SetBenchmarkLogicCommand::invoke(SmtEngine* smtEngine) { /* class SetInfoCommand */ -SetInfoCommand::SetInfoCommand(std::string flag, SExpr& sexpr) : +SetInfoCommand::SetInfoCommand(std::string flag, const SExpr& sexpr) : d_flag(flag), d_sexpr(sexpr) { } +std::string SetInfoCommand::getFlag() const { + return d_flag; +} + +SExpr SetInfoCommand::getSExpr() const { + return d_sexpr; +} + void SetInfoCommand::invoke(SmtEngine* smtEngine) { try { smtEngine->setInfo(d_flag, d_sexpr); @@ -369,6 +529,10 @@ GetInfoCommand::GetInfoCommand(std::string flag) : d_flag(flag) { } +std::string GetInfoCommand::getFlag() const { + return d_flag; +} + void GetInfoCommand::invoke(SmtEngine* smtEngine) { try { stringstream ss; @@ -391,11 +555,19 @@ void GetInfoCommand::printResult(std::ostream& out) const { /* class SetOptionCommand */ -SetOptionCommand::SetOptionCommand(std::string flag, SExpr& sexpr) : +SetOptionCommand::SetOptionCommand(std::string flag, const SExpr& sexpr) : d_flag(flag), d_sexpr(sexpr) { } +std::string SetOptionCommand::getFlag() const { + return d_flag; +} + +SExpr SetOptionCommand::getSExpr() const { + return d_sexpr; +} + void SetOptionCommand::invoke(SmtEngine* smtEngine) { try { smtEngine->setOption(d_flag, d_sexpr); @@ -423,6 +595,10 @@ GetOptionCommand::GetOptionCommand(std::string flag) : d_flag(flag) { } +std::string GetOptionCommand::getFlag() const { + return d_flag; +} + void GetOptionCommand::invoke(SmtEngine* smtEngine) { try { d_result = smtEngine->getOption(d_flag).getValue(); @@ -446,17 +622,19 @@ void GetOptionCommand::printResult(std::ostream& out) const { DatatypeDeclarationCommand::DatatypeDeclarationCommand(const DatatypeType& datatype) : d_datatypes() { d_datatypes.push_back(datatype); - Debug("datatypes") << "Create datatype command." << endl; } DatatypeDeclarationCommand::DatatypeDeclarationCommand(const std::vector<DatatypeType>& datatypes) : d_datatypes(datatypes) { - Debug("datatypes") << "Create datatype command." << endl; +} + +const std::vector<DatatypeType>& +DatatypeDeclarationCommand::getDatatypes() const { + return d_datatypes; } void DatatypeDeclarationCommand::invoke(SmtEngine* smtEngine) { - Debug("datatypes") << "Invoke datatype command." << endl; - //smtEngine->addDatatypeDefinitions(d_datatype); + Dump("declarations") << *this << endl; } /* output stream insertion operator for benchmark statuses */ diff --git a/src/expr/command.h b/src/expr/command.h index 50d382038..5cf4f6fa0 100644 --- a/src/expr/command.h +++ b/src/expr/command.h @@ -2,8 +2,8 @@ /*! \file command.h ** \verbatim ** Original author: mdeters - ** Major contributors: dejan - ** Minor contributors (to current version): cconway + ** Major contributors: none + ** Minor contributors (to current version): cconway, dejan ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -59,26 +59,31 @@ std::ostream& operator<<(std::ostream& out, class CVC4_PUBLIC Command { public: + virtual ~Command() {} + virtual void invoke(SmtEngine* smtEngine) = 0; virtual void invoke(SmtEngine* smtEngine, std::ostream& out); - virtual ~Command() {}; + virtual void toStream(std::ostream& out, int toDepth = -1, bool types = false, OutputLanguage language = language::output::LANG_AST) const; + std::string toString() const; + virtual void printResult(std::ostream& out) const; + };/* class Command */ /** - * EmptyCommands (and its subclasses) are the residue of a command - * after the parser handles them (and there's nothing left to do). + * EmptyCommands are the residue of a command after the parser handles + * them (and there's nothing left to do). */ class CVC4_PUBLIC EmptyCommand : public Command { protected: std::string d_name; public: EmptyCommand(std::string name = ""); + std::string getName() const; void invoke(SmtEngine* smtEngine); - std::string getName() const { return d_name; } };/* class EmptyCommand */ class CVC4_PUBLIC AssertCommand : public Command { @@ -86,8 +91,8 @@ protected: BoolExpr d_expr; public: AssertCommand(const BoolExpr& e); + BoolExpr getExpr() const; void invoke(SmtEngine* smtEngine); - BoolExpr getExpr() const { return d_expr; } };/* class AssertCommand */ class CVC4_PUBLIC PushCommand : public Command { @@ -100,30 +105,59 @@ public: void invoke(SmtEngine* smtEngine); };/* class PopCommand */ -class CVC4_PUBLIC DeclarationCommand : public EmptyCommand { +class CVC4_PUBLIC DeclarationDefinitionCommand : public Command { +protected: + std::string d_symbol; +public: + DeclarationDefinitionCommand(const std::string& id); + std::string getSymbol() const; +};/* class DeclarationDefinitionCommand */ + +class CVC4_PUBLIC DeclareFunctionCommand : public DeclarationDefinitionCommand { +protected: + Type d_type; +public: + DeclareFunctionCommand(const std::string& id, Type type); + Type getType() const; + void invoke(SmtEngine* smtEngine); +};/* class DeclareFunctionCommand */ + +class CVC4_PUBLIC DeclareTypeCommand : public DeclarationDefinitionCommand { +protected: + size_t d_arity; + Type d_type; +public: + DeclareTypeCommand(const std::string& id, size_t arity, Type t); + size_t getArity() const; + Type getType() const; + void invoke(SmtEngine* smtEngine); +};/* class DeclareTypeCommand */ + +class CVC4_PUBLIC DefineTypeCommand : public DeclarationDefinitionCommand { protected: - std::vector<std::string> d_declaredSymbols; + std::vector<Type> d_params; Type d_type; public: - DeclarationCommand(const std::string& id, Type t); - DeclarationCommand(const std::vector<std::string>& ids, Type t); - const std::vector<std::string>& getDeclaredSymbols() const; - Type getDeclaredType() const; -};/* class DeclarationCommand */ + DefineTypeCommand(const std::string& id, Type t); + DefineTypeCommand(const std::string& id, const std::vector<Type>& params, Type t); + const std::vector<Type>& getParameters() const; + Type getType() const; + void invoke(SmtEngine* smtEngine); +};/* class DefineTypeCommand */ -class CVC4_PUBLIC DefineFunctionCommand : public Command { +class CVC4_PUBLIC DefineFunctionCommand : public DeclarationDefinitionCommand { protected: Expr d_func; std::vector<Expr> d_formals; Expr d_formula; public: - DefineFunctionCommand(Expr func, - const std::vector<Expr>& formals, - Expr formula); + DefineFunctionCommand(const std::string& id, Expr func, Expr formula); + DefineFunctionCommand(const std::string& id, Expr func, + const std::vector<Expr>& formals, Expr formula); + Expr getFunction() const; + const std::vector<Expr>& getFormals() const; + Expr getFormula() const; void invoke(SmtEngine* smtEngine); - Expr getFunction() const { return d_func; } - const std::vector<Expr>& getFormals() const { return d_formals; } - Expr getFormula() const { return d_formula; } };/* class DefineFunctionCommand */ /** @@ -133,9 +167,8 @@ public: */ class CVC4_PUBLIC DefineNamedFunctionCommand : public DefineFunctionCommand { public: - DefineNamedFunctionCommand(Expr func, - const std::vector<Expr>& formals, - Expr formula); + DefineNamedFunctionCommand(const std::string& id, Expr func, + const std::vector<Expr>& formals, Expr formula); void invoke(SmtEngine* smtEngine); };/* class DefineNamedFunctionCommand */ @@ -144,9 +177,10 @@ protected: BoolExpr d_expr; Result d_result; public: + CheckSatCommand(); CheckSatCommand(const BoolExpr& expr); + BoolExpr getExpr() const; void invoke(SmtEngine* smtEngine); - BoolExpr getExpr() const { return d_expr; } Result getResult() const; void printResult(std::ostream& out) const; };/* class CheckSatCommand */ @@ -157,8 +191,8 @@ protected: Result d_result; public: QueryCommand(const BoolExpr& e); + BoolExpr getExpr() const; void invoke(SmtEngine* smtEngine); - BoolExpr getExpr() const { return d_expr; } Result getResult() const; void printResult(std::ostream& out) const; };/* class QueryCommand */ @@ -170,8 +204,8 @@ protected: Expr d_result; public: SimplifyCommand(Expr term); + Expr getTerm() const; void invoke(SmtEngine* smtEngine); - Expr getTerm() const { return d_term; } Expr getResult() const; void printResult(std::ostream& out) const; };/* class SimplifyCommand */ @@ -182,8 +216,8 @@ protected: Expr d_result; public: GetValueCommand(Expr term); + Expr getTerm() const; void invoke(SmtEngine* smtEngine); - Expr getTerm() const { return d_term; } Expr getResult() const; void printResult(std::ostream& out) const; };/* class GetValueCommand */ @@ -214,8 +248,8 @@ protected: BenchmarkStatus d_status; public: SetBenchmarkStatusCommand(BenchmarkStatus status); + BenchmarkStatus getStatus() const; void invoke(SmtEngine* smtEngine); - BenchmarkStatus getStatus() const { return d_status; } };/* class SetBenchmarkStatusCommand */ class CVC4_PUBLIC SetBenchmarkLogicCommand : public Command { @@ -224,8 +258,8 @@ protected: std::string d_logic; public: SetBenchmarkLogicCommand(std::string logic); + std::string getLogic() const; void invoke(SmtEngine* smtEngine); - std::string getLogic() const { return d_logic; } };/* class SetBenchmarkLogicCommand */ class CVC4_PUBLIC SetInfoCommand : public Command { @@ -234,10 +268,10 @@ protected: SExpr d_sexpr; std::string d_result; public: - SetInfoCommand(std::string flag, SExpr& sexpr); + SetInfoCommand(std::string flag, const SExpr& sexpr); + std::string getFlag() const; + SExpr getSExpr() const; void invoke(SmtEngine* smtEngine); - std::string getFlag() const { return d_flag; } - SExpr getSExpr() const { return d_sexpr; } std::string getResult() const; void printResult(std::ostream& out) const; };/* class SetInfoCommand */ @@ -248,8 +282,8 @@ protected: std::string d_result; public: GetInfoCommand(std::string flag); + std::string getFlag() const; void invoke(SmtEngine* smtEngine); - std::string getFlag() const { return d_flag; } std::string getResult() const; void printResult(std::ostream& out) const; };/* class GetInfoCommand */ @@ -260,10 +294,10 @@ protected: SExpr d_sexpr; std::string d_result; public: - SetOptionCommand(std::string flag, SExpr& sexpr); + SetOptionCommand(std::string flag, const SExpr& sexpr); + std::string getFlag() const; + SExpr getSExpr() const; void invoke(SmtEngine* smtEngine); - std::string getFlag() const { return d_flag; } - SExpr getSExpr() const { return d_sexpr; } std::string getResult() const; void printResult(std::ostream& out) const; };/* class SetOptionCommand */ @@ -274,8 +308,8 @@ protected: std::string d_result; public: GetOptionCommand(std::string flag); + std::string getFlag() const; void invoke(SmtEngine* smtEngine); - std::string getFlag() const { return d_flag; } std::string getResult() const; void printResult(std::ostream& out) const; };/* class GetOptionCommand */ @@ -286,15 +320,24 @@ private: public: DatatypeDeclarationCommand(const DatatypeType& datatype); DatatypeDeclarationCommand(const std::vector<DatatypeType>& datatypes); + const std::vector<DatatypeType>& getDatatypes() const; void invoke(SmtEngine* smtEngine); - const std::vector<DatatypeType>& getDatatypes() const { return d_datatypes; } };/* class DatatypeDeclarationCommand */ -class CVC4_PUBLIC QuitCommand : public EmptyCommand { +class CVC4_PUBLIC QuitCommand : public Command { public: QuitCommand(); + void invoke(SmtEngine* smtEngine); };/* class QuitCommand */ +class CVC4_PUBLIC CommentCommand : public Command { + std::string d_comment; +public: + CommentCommand(std::string comment); + std::string getComment() const; + void invoke(SmtEngine* smtEngine); +};/* class CommentCommand */ + class CVC4_PUBLIC CommandSequence : public Command { private: /** All the commands to be executed (in sequence) */ @@ -304,20 +347,27 @@ private: public: CommandSequence(); ~CommandSequence(); + + void addCommand(Command* cmd); + void invoke(SmtEngine* smtEngine); void invoke(SmtEngine* smtEngine, std::ostream& out); - void addCommand(Command* cmd); typedef std::vector<Command*>::iterator iterator; typedef std::vector<Command*>::const_iterator const_iterator; - const_iterator begin() const { return d_commandSequence.begin(); } - const_iterator end() const { return d_commandSequence.end(); } + const_iterator begin() const; + const_iterator end() const; + + iterator begin(); + iterator end(); - iterator begin() { return d_commandSequence.begin(); } - iterator end() { return d_commandSequence.end(); } };/* class CommandSequence */ +class CVC4_PUBLIC DeclarationSequence : public CommandSequence { +public: +};/* class DeclarationSequence */ + }/* CVC4 namespace */ #endif /* __CVC4__COMMAND_H */ diff --git a/src/expr/convenience_node_builders.h b/src/expr/convenience_node_builders.h index 655accde3..451250e52 100644 --- a/src/expr/convenience_node_builders.h +++ b/src/expr/convenience_node_builders.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/expr/declaration_scope.cpp b/src/expr/declaration_scope.cpp index ae91efa68..37c709b6a 100644 --- a/src/expr/declaration_scope.cpp +++ b/src/expr/declaration_scope.cpp @@ -3,7 +3,7 @@ ** \verbatim ** Original author: cconway ** Major contributors: mdeters - ** Minor contributors (to current version): dejan + ** Minor contributors (to current version): dejan, ajreynol ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/expr/declaration_scope.h b/src/expr/declaration_scope.h index d695a3bf8..4bce5e1be 100644 --- a/src/expr/declaration_scope.h +++ b/src/expr/declaration_scope.h @@ -3,7 +3,7 @@ ** \verbatim ** Original author: cconway ** Major contributors: mdeters - ** Minor contributors (to current version): none + ** Minor contributors (to current version): ajreynol ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/expr/expr_manager_template.cpp b/src/expr/expr_manager_template.cpp index 038f58f95..f013c1644 100644 --- a/src/expr/expr_manager_template.cpp +++ b/src/expr/expr_manager_template.cpp @@ -3,7 +3,7 @@ ** \verbatim ** Original author: dejan ** Major contributors: cconway, mdeters - ** Minor contributors (to current version): none + ** Minor contributors (to current version): ajreynol ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -116,6 +116,10 @@ ExprManager::~ExprManager() { delete d_ctxt; } +const Options* ExprManager::getOptions() const { + return d_nodeManager->getOptions(); +} + BooleanType ExprManager::booleanType() const { NodeManagerScope nms(d_nodeManager); return BooleanType(Type(d_nodeManager, new TypeNode(d_nodeManager->booleanType()))); diff --git a/src/expr/expr_manager_template.h b/src/expr/expr_manager_template.h index eb67277a1..2828ae381 100644 --- a/src/expr/expr_manager_template.h +++ b/src/expr/expr_manager_template.h @@ -3,7 +3,7 @@ ** \verbatim ** Original author: dejan ** Major contributors: mdeters - ** Minor contributors (to current version): taking, cconway + ** Minor contributors (to current version): ajreynol, taking, cconway ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -114,6 +114,9 @@ public: */ ~ExprManager(); + /** Get this node manager's options */ + const Options* getOptions() const; + /** Get the type for booleans */ BooleanType booleanType() const; diff --git a/src/expr/expr_stream.h b/src/expr/expr_stream.h index a6b99fb73..990ce9982 100644 --- a/src/expr/expr_stream.h +++ b/src/expr/expr_stream.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/expr/expr_template.cpp b/src/expr/expr_template.cpp index 7c2d02809..619fd5280 100644 --- a/src/expr/expr_template.cpp +++ b/src/expr/expr_template.cpp @@ -21,15 +21,19 @@ #include "expr/expr_manager_scope.h" #include "util/Assert.h" +#include <iterator> +#include <utility> + ${includes} // This is a hack, but an important one: if there's an error, the // compiler directs the user to the template file instead of the // generated one. We don't want the user to modify the generated one, // since it'll get overwritten on a later build. -#line 31 "${template}" +#line 34 "${template}" using namespace CVC4::kind; +using namespace std; namespace CVC4 { @@ -73,7 +77,7 @@ TypeCheckingException::~TypeCheckingException() throw () { } void TypeCheckingException::toStream(std::ostream& os) const { - os << "Error type-checking " << d_expr << ": " << d_msg << std::endl << *d_expr; + os << "Error type-checking " << d_expr << ": " << d_msg << endl << *d_expr; } Expr TypeCheckingException::getExpression() const { @@ -208,6 +212,59 @@ Type Expr::getType(bool check) const throw (TypeCheckingException) { return d_exprManager->getType(*this, check); } +Expr Expr::substitute(Expr e, Expr replacement) const { + return Expr(d_exprManager, new Node(d_node->substitute(TNode(*e.d_node), TNode(*replacement.d_node)))); +} + +template <class Iterator> +class NodeIteratorAdaptor : public std::iterator<std::input_iterator_tag, Node> { + Iterator d_iterator; +public: + NodeIteratorAdaptor(Iterator i) : d_iterator(i) { + } + NodeIteratorAdaptor& operator++() { ++d_iterator; return *this; } + NodeIteratorAdaptor operator++(int) { NodeIteratorAdaptor i(d_iterator); ++d_iterator; return i; } + bool operator==(NodeIteratorAdaptor i) { return d_iterator == i.d_iterator; } + bool operator!=(NodeIteratorAdaptor i) { return !(*this == i); } + Node operator*() { return Node::fromExpr(*d_iterator); } +};/* class NodeIteratorAdaptor */ + +template <class Iterator> +static inline NodeIteratorAdaptor<Iterator> mkNodeIteratorAdaptor(Iterator i) { + return NodeIteratorAdaptor<Iterator>(i); +} + +Expr Expr::substitute(const std::vector<Expr> exes, + const std::vector<Expr>& replacements) const { + return Expr(d_exprManager, + new Node(d_node->substitute(mkNodeIteratorAdaptor(exes.begin()), + mkNodeIteratorAdaptor(exes.end()), + mkNodeIteratorAdaptor(replacements.begin()), + mkNodeIteratorAdaptor(replacements.end())))); +} + +template <class Iterator> +class NodePairIteratorAdaptor : public std::iterator<std::input_iterator_tag, pair<Node, Node> > { + Iterator d_iterator; +public: + NodePairIteratorAdaptor(Iterator i) : d_iterator(i) { + } + NodePairIteratorAdaptor& operator++() { ++d_iterator; return *this; } + NodePairIteratorAdaptor operator++(int) { NodePairIteratorAdaptor i(d_iterator); ++d_iterator; return i; } + bool operator==(NodePairIteratorAdaptor i) { return d_iterator == i.d_iterator; } + bool operator!=(NodePairIteratorAdaptor i) { return !(*this == i); } + pair<Node, Node> operator*() { return make_pair(Node::fromExpr((*d_iterator).first), Node::fromExpr((*d_iterator).second)); } +};/* class NodePairIteratorAdaptor */ + +template <class Iterator> +static inline NodePairIteratorAdaptor<Iterator> mkNodePairIteratorAdaptor(Iterator i) { + return NodePairIteratorAdaptor<Iterator>(i); +} + +Expr Expr::substitute(const std::hash_map<Expr, Expr, ExprHashFunction> map) const { + return Expr(d_exprManager, new Node(d_node->substitute(mkNodePairIteratorAdaptor(map.begin()), mkNodePairIteratorAdaptor(map.end())))); +} + Expr::const_iterator::const_iterator() : d_iterator(NULL) { } @@ -280,6 +337,12 @@ Expr::operator bool() const { return !isNull(); } +bool Expr::isVariable() const { + ExprManagerScope ems(*this); + Assert(d_node != NULL, "Unexpected NULL expression pointer!"); + return d_node->getMetaKind() == kind::metakind::VARIABLE; +} + bool Expr::isConst() const { ExprManagerScope ems(*this); Assert(d_node != NULL, "Unexpected NULL expression pointer!"); diff --git a/src/expr/expr_template.h b/src/expr/expr_template.h index bffb37ddb..e95e434fe 100644 --- a/src/expr/expr_template.h +++ b/src/expr/expr_template.h @@ -35,12 +35,13 @@ ${includes} #include "util/exception.h" #include "util/language.h" +#include "util/hash.h" // This is a hack, but an important one: if there's an error, the // compiler directs the user to the template file instead of the // generated one. We don't want the user to modify the generated one, // since it'll get overwritten on a later build. -#line 44 "${template}" +#line 45 "${template}" namespace CVC4 { @@ -121,6 +122,11 @@ std::ostream& operator<<(std::ostream& out, */ std::ostream& operator<<(std::ostream& out, const Expr& e) CVC4_PUBLIC; +// for hash_maps, hash_sets.. +struct ExprHashFunction { + size_t operator()(CVC4::Expr e) const; +};/* struct ExprHashFunction */ + /** * Class encapsulating CVC4 expressions and methods for constructing new * expressions. @@ -344,6 +350,22 @@ public: Type getType(bool check = false) const throw (TypeCheckingException); /** + * Substitute "replacement" in for "e". + */ + Expr substitute(Expr e, Expr replacement) const; + + /** + * Substitute "replacements" in for "exes". + */ + Expr substitute(const std::vector<Expr> exes, + const std::vector<Expr>& replacements) const; + + /** + * Substitute pairs of (ex,replacement) from the given map. + */ + Expr substitute(const std::hash_map<Expr, Expr, ExprHashFunction> map) const; + + /** * Returns the string representation of the expression. * @return a string representation of the expression */ @@ -365,18 +387,28 @@ public: /** * Check if this is a null expression. + * * @return true if a null expression */ bool isNull() const; /** * Check if this is a null expression. + * * @return true if NOT a null expression */ operator bool() const; /** + * Check if this is an expression representing a variable. + * + * @return true if a variable expression + */ + bool isVariable() const; + + /** * Check if this is an expression representing a constant. + * * @return true if a constant expression */ bool isConst() const; @@ -541,7 +573,7 @@ public: /** * Make a Boolean if-then-else expression using this expression as the - * condition, and given the then and else parts + * condition, and given the then and else parts. * @param then_e the then branch expression * @param else_e the else branch expression * @return the if-then-else expression @@ -550,13 +582,14 @@ public: /** * Make a term if-then-else expression using this expression as the - * condition, and given the then and else parts + * condition, and given the then and else parts. * @param then_e the then branch expression * @param else_e the else branch expression * @return the if-then-else expression */ Expr iteExpr(const Expr& then_e, const Expr& else_e) const; -}; + +};/* class BoolExpr */ namespace expr { @@ -791,7 +824,7 @@ public: ${getConst_instantiations} -#line 795 "${template}" +#line 828 "${template}" namespace expr { @@ -839,12 +872,9 @@ inline std::ostream& operator<<(std::ostream& out, ExprSetLanguage l) { }/* CVC4::expr namespace */ -// for hash_maps, hash_sets.. -struct ExprHashFunction { - size_t operator()(CVC4::Expr e) const { - return (size_t) e.getId(); - } -};/* struct ExprHashFunction */ +inline size_t ExprHashFunction::operator()(CVC4::Expr e) const { + return (size_t) e.getId(); +} }/* CVC4 namespace */ diff --git a/src/expr/kind_map.h b/src/expr/kind_map.h index a02339e5e..974bd6791 100644 --- a/src/expr/kind_map.h +++ b/src/expr/kind_map.h @@ -1,7 +1,7 @@ /********************* */ /*! \file kind_map.h ** \verbatim - ** Original author: mdeters + ** Original author: dejan ** Major contributors: none ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. diff --git a/src/expr/metakind_template.h b/src/expr/metakind_template.h index 5f9aa6619..a954a7f70 100644 --- a/src/expr/metakind_template.h +++ b/src/expr/metakind_template.h @@ -5,7 +5,7 @@ ** Major contributors: none ** Minor contributors (to current version): dejan ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/expr/mkexpr b/src/expr/mkexpr index 479ef6d11..69f7019ab 100755 --- a/src/expr/mkexpr +++ b/src/expr/mkexpr @@ -107,6 +107,25 @@ function endtheory { seen_endtheory=true } +function typechecker { + # typechecker header + lineno=${BASH_LINENO[0]} + check_theory_seen + typechecker_includes="${typechecker_includes} +#include \"$1\"" +} + +function typerule { + # typerule OPERATOR typechecking-class + lineno=${BASH_LINENO[0]} + check_theory_seen + typerules="${typerules} + case kind::$1: + typeNode = $2::computeType(nodeManager, n, check); + break; +" +} + function sort { # sort TYPE cardinality [well-founded ground-term header | not-well-founded] ["comment"] lineno=${BASH_LINENO[0]} @@ -225,6 +244,8 @@ for var in \ getConst_implementations \ mkConst_instantiations \ mkConst_implementations \ + typechecker_includes \ + typerules \ ; do eval text="\${text//\\\$\\{$var\\}/\${$var}}" done diff --git a/src/expr/mkkind b/src/expr/mkkind index 47d02863e..abb238f1a 100755 --- a/src/expr/mkkind +++ b/src/expr/mkkind @@ -118,6 +118,18 @@ function endtheory { seen_endtheory=true } +function typechecker { + # typechecker header + lineno=${BASH_LINENO[0]} + check_theory_seen +} + +function typerule { + # typerule OPERATOR typechecking-class + lineno=${BASH_LINENO[0]} + check_theory_seen +} + function rewriter { # properties prop* lineno=${BASH_LINENO[0]} diff --git a/src/expr/mkmetakind b/src/expr/mkmetakind index 46a69dee5..d84691e14 100755 --- a/src/expr/mkmetakind +++ b/src/expr/mkmetakind @@ -93,6 +93,18 @@ function endtheory { seen_endtheory=true } +function typechecker { + # typechecker header + lineno=${BASH_LINENO[0]} + check_theory_seen +} + +function typerule { + # typerule OPERATOR typechecking-class + lineno=${BASH_LINENO[0]} + check_theory_seen +} + function rewriter { # rewriter class header lineno=${BASH_LINENO[0]} diff --git a/src/expr/node.h b/src/expr/node.h index f501dba21..0f4b55d4a 100644 --- a/src/expr/node.h +++ b/src/expr/node.h @@ -28,6 +28,8 @@ #include <string> #include <iostream> #include <utility> +#include <algorithm> +#include <functional> #include <stdint.h> #include "expr/type.h" @@ -832,16 +834,23 @@ public: */ inline bool hasSubterm(NodeTemplate<false> t, bool strict = false) const; - NodeTemplate<true> eqNode(const NodeTemplate& right) const; + template <bool ref_count2> + NodeTemplate<true> eqNode(const NodeTemplate<ref_count2>& right) const; NodeTemplate<true> notNode() const; - NodeTemplate<true> andNode(const NodeTemplate& right) const; - NodeTemplate<true> orNode(const NodeTemplate& right) const; - NodeTemplate<true> iteNode(const NodeTemplate& thenpart, - const NodeTemplate& elsepart) const; - NodeTemplate<true> iffNode(const NodeTemplate& right) const; - NodeTemplate<true> impNode(const NodeTemplate& right) const; - NodeTemplate<true> xorNode(const NodeTemplate& right) const; + template <bool ref_count2> + NodeTemplate<true> andNode(const NodeTemplate<ref_count2>& right) const; + template <bool ref_count2> + NodeTemplate<true> orNode(const NodeTemplate<ref_count2>& right) const; + template <bool ref_count2, bool ref_count3> + NodeTemplate<true> iteNode(const NodeTemplate<ref_count2>& thenpart, + const NodeTemplate<ref_count3>& elsepart) const; + template <bool ref_count2> + NodeTemplate<true> iffNode(const NodeTemplate<ref_count2>& right) const; + template <bool ref_count2> + NodeTemplate<true> impNode(const NodeTemplate<ref_count2>& right) const; + template <bool ref_count2> + NodeTemplate<true> xorNode(const NodeTemplate<ref_count2>& right) const; };/* class NodeTemplate<ref_count> */ @@ -1085,8 +1094,9 @@ operator=(const NodeTemplate<!ref_count>& e) { } template <bool ref_count> +template <bool ref_count2> NodeTemplate<true> -NodeTemplate<ref_count>::eqNode(const NodeTemplate<ref_count>& right) const { +NodeTemplate<ref_count>::eqNode(const NodeTemplate<ref_count2>& right) const { assertTNodeNotExpired(); return NodeManager::currentNM()->mkNode(kind::EQUAL, *this, right); } @@ -1098,44 +1108,50 @@ NodeTemplate<true> NodeTemplate<ref_count>::notNode() const { } template <bool ref_count> +template <bool ref_count2> NodeTemplate<true> -NodeTemplate<ref_count>::andNode(const NodeTemplate<ref_count>& right) const { +NodeTemplate<ref_count>::andNode(const NodeTemplate<ref_count2>& right) const { assertTNodeNotExpired(); return NodeManager::currentNM()->mkNode(kind::AND, *this, right); } template <bool ref_count> +template <bool ref_count2> NodeTemplate<true> -NodeTemplate<ref_count>::orNode(const NodeTemplate<ref_count>& right) const { +NodeTemplate<ref_count>::orNode(const NodeTemplate<ref_count2>& right) const { assertTNodeNotExpired(); return NodeManager::currentNM()->mkNode(kind::OR, *this, right); } template <bool ref_count> +template <bool ref_count2, bool ref_count3> NodeTemplate<true> -NodeTemplate<ref_count>::iteNode(const NodeTemplate<ref_count>& thenpart, - const NodeTemplate<ref_count>& elsepart) const { +NodeTemplate<ref_count>::iteNode(const NodeTemplate<ref_count2>& thenpart, + const NodeTemplate<ref_count3>& elsepart) const { assertTNodeNotExpired(); return NodeManager::currentNM()->mkNode(kind::ITE, *this, thenpart, elsepart); } template <bool ref_count> +template <bool ref_count2> NodeTemplate<true> -NodeTemplate<ref_count>::iffNode(const NodeTemplate<ref_count>& right) const { +NodeTemplate<ref_count>::iffNode(const NodeTemplate<ref_count2>& right) const { assertTNodeNotExpired(); return NodeManager::currentNM()->mkNode(kind::IFF, *this, right); } template <bool ref_count> +template <bool ref_count2> NodeTemplate<true> -NodeTemplate<ref_count>::impNode(const NodeTemplate<ref_count>& right) const { +NodeTemplate<ref_count>::impNode(const NodeTemplate<ref_count2>& right) const { assertTNodeNotExpired(); return NodeManager::currentNM()->mkNode(kind::IMPLIES, *this, right); } template <bool ref_count> +template <bool ref_count2> NodeTemplate<true> -NodeTemplate<ref_count>::xorNode(const NodeTemplate<ref_count>& right) const { +NodeTemplate<ref_count>::xorNode(const NodeTemplate<ref_count2>& right) const { assertTNodeNotExpired(); return NodeManager::currentNM()->mkNode(kind::XOR, *this, right); } @@ -1273,11 +1289,13 @@ NodeTemplate<ref_count>::substitute(Iterator1 nodesBegin, } // otherwise compute - Assert( nodesEnd - nodesBegin == replacementsEnd - replacementsBegin, + Assert( std::distance(nodesBegin, nodesEnd) == std::distance(replacementsBegin, replacementsEnd), "Substitution iterator ranges must be equal size" ); - Iterator1 j = find(nodesBegin, nodesEnd, *this); + Iterator1 j = find(nodesBegin, nodesEnd, TNode(*this)); if(j != nodesEnd) { - Node n = *(replacementsBegin + (j - nodesBegin)); + Iterator2 b = replacementsBegin; + std::advance(b, std::distance(nodesBegin, j)); + Node n = *b; cache[*this] = n; return n; } else if(getNumChildren() == 0) { diff --git a/src/expr/node_builder.h b/src/expr/node_builder.h index 156d14299..2cb2527b2 100644 --- a/src/expr/node_builder.h +++ b/src/expr/node_builder.h @@ -5,7 +5,7 @@ ** Major contributors: dejan ** Minor contributors (to current version): taking, cconway ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/expr/node_manager.cpp b/src/expr/node_manager.cpp index ce3db4a40..3b4d8ac66 100644 --- a/src/expr/node_manager.cpp +++ b/src/expr/node_manager.cpp @@ -18,21 +18,15 @@ ** Reviewed by Chris Conway, Apr 5 2010 (bug #65). **/ -#include "node_manager.h" - -#include "theory/builtin/theory_builtin_type_rules.h" -#include "theory/booleans/theory_bool_type_rules.h" -#include "theory/uf/theory_uf_type_rules.h" -#include "theory/arith/theory_arith_type_rules.h" -#include "theory/arrays/theory_arrays_type_rules.h" -#include "theory/bv/theory_bv_type_rules.h" -#include "theory/datatypes/theory_datatypes_type_rules.h" +#include "expr/node_manager.h" #include "util/Assert.h" #include "util/options.h" #include "util/stats.h" #include "util/tls.h" +#include "expr/type_checker.h" + #include <algorithm> #include <stack> #include <ext/hash_set> @@ -241,234 +235,6 @@ void NodeManager::reclaimZombies() { } }/* NodeManager::reclaimZombies() */ -TypeNode NodeManager::computeType(TNode n, bool check) - throw (TypeCheckingExceptionPrivate, AssertionException) { - TypeNode typeNode; - - // Infer the type - switch(n.getKind()) { - case kind::VARIABLE: - typeNode = getAttribute(n, TypeAttr()); - break; - case kind::SKOLEM: - typeNode = getAttribute(n, TypeAttr()); - break; - case kind::BUILTIN: - typeNode = builtinOperatorType(); - break; - case kind::SORT_TYPE: - typeNode = kindType(); - break; - case kind::APPLY: - typeNode = CVC4::theory::builtin::ApplyTypeRule::computeType(this, n, check); - break; - case kind::EQUAL: - typeNode = CVC4::theory::builtin::EqualityTypeRule::computeType(this, n, check); - break; - case kind::DISTINCT: - typeNode = CVC4::theory::builtin::DistinctTypeRule::computeType(this, n, check); - break; - case kind::TUPLE: - typeNode = CVC4::theory::builtin::TupleTypeRule::computeType(this, n, check); - break; - case kind::CONST_BOOLEAN: - typeNode = CVC4::theory::boolean::BooleanTypeRule::computeType(this, n, check); - break; - case kind::NOT: - typeNode = CVC4::theory::boolean::BooleanTypeRule::computeType(this, n, check); - break; - case kind::AND: - typeNode = CVC4::theory::boolean::BooleanTypeRule::computeType(this, n, check); - break; - case kind::IFF: - typeNode = CVC4::theory::boolean::BooleanTypeRule::computeType(this, n, check); - break; - case kind::IMPLIES: - typeNode = CVC4::theory::boolean::BooleanTypeRule::computeType(this, n, check); - break; - case kind::OR: - typeNode = CVC4::theory::boolean::BooleanTypeRule::computeType(this, n, check); - break; - case kind::XOR: - typeNode = CVC4::theory::boolean::BooleanTypeRule::computeType(this, n, check); - break; - case kind::ITE: - typeNode = CVC4::theory::boolean::IteTypeRule::computeType(this, n, check); - break; - case kind::APPLY_UF: - typeNode = CVC4::theory::uf::UfTypeRule::computeType(this, n, check); - break; - case kind::PLUS: - typeNode = CVC4::theory::arith::ArithOperatorTypeRule::computeType(this, n, check); - break; - case kind::MULT: - typeNode = CVC4::theory::arith::ArithOperatorTypeRule::computeType(this, n, check); - break; - case kind::MINUS: - typeNode = CVC4::theory::arith::ArithOperatorTypeRule::computeType(this, n, check); - break; - case kind::UMINUS: - typeNode = CVC4::theory::arith::ArithOperatorTypeRule::computeType(this, n, check); - break; - case kind::DIVISION: - typeNode = CVC4::theory::arith::ArithOperatorTypeRule::computeType(this, n, check); - break; - case kind::CONST_RATIONAL: - typeNode = CVC4::theory::arith::ArithConstantTypeRule::computeType(this, n, check); - break; - case kind::CONST_INTEGER: - typeNode = CVC4::theory::arith::ArithConstantTypeRule::computeType(this, n, check); - break; - case kind::LT: - typeNode = CVC4::theory::arith::ArithPredicateTypeRule::computeType(this, n, check); - break; - case kind::LEQ: - typeNode = CVC4::theory::arith::ArithPredicateTypeRule::computeType(this, n, check); - break; - case kind::GT: - typeNode = CVC4::theory::arith::ArithPredicateTypeRule::computeType(this, n, check); - break; - case kind::GEQ: - typeNode = CVC4::theory::arith::ArithPredicateTypeRule::computeType(this, n, check); - break; - case kind::SELECT: - typeNode = CVC4::theory::arrays::ArraySelectTypeRule::computeType(this, n, check); - break; - case kind::STORE: - typeNode = CVC4::theory::arrays::ArrayStoreTypeRule::computeType(this, n, check); - break; - case kind::CONST_BITVECTOR: - typeNode = CVC4::theory::bv::BitVectorConstantTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_AND: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_OR: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_XOR: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_NOT: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_NAND: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_NOR: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_XNOR: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_COMP: - typeNode = CVC4::theory::bv::BitVectorCompRule::computeType(this, n, check); - break; - case kind::BITVECTOR_MULT: - typeNode = CVC4::theory::bv::BitVectorArithRule::computeType(this, n, check); - break; - case kind::BITVECTOR_PLUS: - typeNode = CVC4::theory::bv::BitVectorArithRule::computeType(this, n, check); - break; - case kind::BITVECTOR_SUB: - typeNode = CVC4::theory::bv::BitVectorArithRule::computeType(this, n, check); - break; - case kind::BITVECTOR_NEG: - typeNode = CVC4::theory::bv::BitVectorArithRule::computeType(this, n, check); - break; - case kind::BITVECTOR_UDIV: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_UREM: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_SDIV: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_SREM: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_SMOD: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_SHL: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_LSHR: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_ASHR: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_ROTATE_LEFT: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_ROTATE_RIGHT: - typeNode = CVC4::theory::bv::BitVectorFixedWidthTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_ULT: - typeNode = CVC4::theory::bv::BitVectorPredicateTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_ULE: - typeNode = CVC4::theory::bv::BitVectorPredicateTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_UGT: - typeNode = CVC4::theory::bv::BitVectorPredicateTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_UGE: - typeNode = CVC4::theory::bv::BitVectorPredicateTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_SLT: - typeNode = CVC4::theory::bv::BitVectorPredicateTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_SLE: - typeNode = CVC4::theory::bv::BitVectorPredicateTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_SGT: - typeNode = CVC4::theory::bv::BitVectorPredicateTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_SGE: - typeNode = CVC4::theory::bv::BitVectorPredicateTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_EXTRACT: - typeNode = CVC4::theory::bv::BitVectorExtractTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_CONCAT: - typeNode = CVC4::theory::bv::BitVectorConcatRule::computeType(this, n, check); - break; - case kind::BITVECTOR_REPEAT: - typeNode = CVC4::theory::bv::BitVectorRepeatTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_ZERO_EXTEND: - typeNode = CVC4::theory::bv::BitVectorExtendTypeRule::computeType(this, n, check); - break; - case kind::BITVECTOR_SIGN_EXTEND: - typeNode = CVC4::theory::bv::BitVectorExtendTypeRule::computeType(this, n, check); - break; - case kind::APPLY_CONSTRUCTOR: - typeNode = CVC4::theory::datatypes::DatatypeConstructorTypeRule::computeType(this, n, check); - break; - case kind::APPLY_SELECTOR: - typeNode = CVC4::theory::datatypes::DatatypeSelectorTypeRule::computeType(this, n, check); - break; - case kind::APPLY_TESTER: - typeNode = CVC4::theory::datatypes::DatatypeTesterTypeRule::computeType(this, n, check); - break; - case kind::APPLY_TYPE_ASCRIPTION: - typeNode = CVC4::theory::datatypes::DatatypeAscriptionTypeRule::computeType(this, n, check); - break; - default: - Debug("getType") << "FAILURE" << std::endl; - Unhandled(n.getKind()); - } - - setAttribute(n, TypeAttr(), typeNode); - setAttribute(n, TypeCheckedAttr(), - check || getAttribute(n, TypeCheckedAttr())); - - return typeNode; -} - TypeNode NodeManager::getType(TNode n, bool check) throw (TypeCheckingExceptionPrivate, AssertionException) { // Many theories' type checkers call Node::getType() directly. @@ -510,7 +276,7 @@ TypeNode NodeManager::getType(TNode n, bool check) if( readyToCompute ) { /* All the children have types, time to compute */ - typeNode = computeType(m, check); + typeNode = TypeChecker::computeType(this, m, check); worklist.pop(); } } // end while @@ -520,7 +286,7 @@ TypeNode NodeManager::getType(TNode n, bool check) } else if( !hasType || needsCheck ) { /* We can compute the type top-down, without worrying about deep recursion. */ - typeNode = computeType(n, check); + typeNode = TypeChecker::computeType(this, n, check); } /* The type should be have been computed and stored. */ diff --git a/src/expr/node_manager.h b/src/expr/node_manager.h index 0ac215f1e..6adcb62a9 100644 --- a/src/expr/node_manager.h +++ b/src/expr/node_manager.h @@ -11,7 +11,7 @@ ** See the file COPYING in the top-level source directory for licensing ** information.\endverbatim ** - ** \brief A manager for Nodes. + ** \brief A manager for Nodes ** ** A manager for Nodes. ** @@ -48,6 +48,8 @@ class StatisticsRegistry; namespace expr { +class TypeChecker; + // Definition of an attribute for the variable name. // TODO: hide this attribute behind a NodeManager interface. namespace attr { @@ -64,6 +66,7 @@ class NodeManager { template <unsigned nchild_thresh> friend class CVC4::NodeBuilder; friend class NodeManagerScope; friend class expr::NodeValue; + friend class expr::TypeChecker; /** Predicate for use with STL algorithms */ struct NodeValueReferenceCountNonZero { @@ -250,9 +253,6 @@ class NodeManager { // undefined private copy constructor (disallow copy) NodeManager(const NodeManager&) CVC4_UNDEFINED; - TypeNode computeType(TNode n, bool check = false) - throw (TypeCheckingExceptionPrivate, AssertionException); - void init(); public: diff --git a/src/expr/node_self_iterator.h b/src/expr/node_self_iterator.h index c38243b0a..37c28ab07 100644 --- a/src/expr/node_self_iterator.h +++ b/src/expr/node_self_iterator.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/expr/node_value.cpp b/src/expr/node_value.cpp index 666462875..5fe48b01d 100644 --- a/src/expr/node_value.cpp +++ b/src/expr/node_value.cpp @@ -2,10 +2,10 @@ /*! \file node_value.cpp ** \verbatim ** Original author: mdeters - ** Major contributors: none - ** Minor contributors (to current version): dejan + ** Major contributors: dejan + ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/expr/node_value.h b/src/expr/node_value.h index 2c11b58d5..71aa37926 100644 --- a/src/expr/node_value.h +++ b/src/expr/node_value.h @@ -2,10 +2,10 @@ /*! \file node_value.h ** \verbatim ** Original author: mdeters - ** Major contributors: dejan - ** Minor contributors (to current version): cconway, taking + ** Major contributors: none + ** Minor contributors (to current version): cconway, taking, dejan ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/expr/type.cpp b/src/expr/type.cpp index e162065b0..28bcb460f 100644 --- a/src/expr/type.cpp +++ b/src/expr/type.cpp @@ -3,7 +3,7 @@ ** \verbatim ** Original author: cconway ** Major contributors: dejan, mdeters - ** Minor contributors (to current version): none + ** Minor contributors (to current version): ajreynol ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/expr/type.h b/src/expr/type.h index a63ca6cf0..5bff8d12a 100644 --- a/src/expr/type.h +++ b/src/expr/type.h @@ -2,8 +2,8 @@ /*! \file type.h ** \verbatim ** Original author: cconway - ** Major contributors: mdeters, dejan - ** Minor contributors (to current version): none + ** Major contributors: dejan, mdeters + ** Minor contributors (to current version): ajreynol ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -397,7 +397,7 @@ class CVC4_PUBLIC BooleanType : public Type { public: /** Construct from the base type */ - BooleanType(const Type& type) throw(AssertionException); + BooleanType(const Type& type = Type()) throw(AssertionException); };/* class BooleanType */ /** @@ -408,7 +408,7 @@ class CVC4_PUBLIC IntegerType : public Type { public: /** Construct from the base type */ - IntegerType(const Type& type) throw(AssertionException); + IntegerType(const Type& type = Type()) throw(AssertionException); };/* class IntegerType */ /** @@ -419,7 +419,7 @@ class CVC4_PUBLIC RealType : public Type { public: /** Construct from the base type */ - RealType(const Type& type) throw(AssertionException); + RealType(const Type& type = Type()) throw(AssertionException); };/* class RealType */ /** @@ -441,7 +441,7 @@ class CVC4_PUBLIC FunctionType : public Type { public: /** Construct from the base type */ - FunctionType(const Type& type) throw(AssertionException); + FunctionType(const Type& type = Type()) throw(AssertionException); /** Get the argument types */ std::vector<Type> getArgTypes() const; @@ -458,7 +458,7 @@ class CVC4_PUBLIC TupleType : public Type { public: /** Construct from the base type */ - TupleType(const Type& type) throw(AssertionException); + TupleType(const Type& type = Type()) throw(AssertionException); /** Get the constituent types */ std::vector<Type> getTypes() const; @@ -472,7 +472,7 @@ class CVC4_PUBLIC ArrayType : public Type { public: /** Construct from the base type */ - ArrayType(const Type& type) throw(AssertionException); + ArrayType(const Type& type = Type()) throw(AssertionException); /** Get the index type */ Type getIndexType() const; @@ -489,7 +489,7 @@ class CVC4_PUBLIC SortType : public Type { public: /** Construct from the base type */ - SortType(const Type& type) throw(AssertionException); + SortType(const Type& type = Type()) throw(AssertionException); /** Get the name of the sort */ std::string getName() const; @@ -510,7 +510,7 @@ class CVC4_PUBLIC SortConstructorType : public Type { public: /** Construct from the base type */ - SortConstructorType(const Type& type) throw(AssertionException); + SortConstructorType(const Type& type = Type()) throw(AssertionException); /** Get the name of the sort constructor */ std::string getName() const; @@ -530,7 +530,7 @@ class CVC4_PUBLIC KindType : public Type { public: /** Construct from the base type */ - KindType(const Type& type) throw(AssertionException); + KindType(const Type& type = Type()) throw(AssertionException); };/* class KindType */ /** @@ -541,7 +541,7 @@ class CVC4_PUBLIC BitVectorType : public Type { public: /** Construct from the base type */ - BitVectorType(const Type& type) throw(AssertionException); + BitVectorType(const Type& type = Type()) throw(AssertionException); /** * Returns the size of the bit-vector type. @@ -559,7 +559,7 @@ class CVC4_PUBLIC DatatypeType : public Type { public: /** Construct from the base type */ - DatatypeType(const Type& type) throw(AssertionException); + DatatypeType(const Type& type = Type()) throw(AssertionException); /** Get the underlying datatype */ const Datatype& getDatatype() const; @@ -599,7 +599,7 @@ class CVC4_PUBLIC ConstructorType : public Type { public: /** Construct from the base type */ - ConstructorType(const Type& type) throw(AssertionException); + ConstructorType(const Type& type = Type()) throw(AssertionException); /** Get the range type */ DatatypeType getRangeType() const; @@ -621,7 +621,7 @@ class CVC4_PUBLIC SelectorType : public Type { public: /** Construct from the base type */ - SelectorType(const Type& type) throw(AssertionException); + SelectorType(const Type& type = Type()) throw(AssertionException); /** Get the domain type for this selector (the datatype type) */ DatatypeType getDomain() const; @@ -639,7 +639,7 @@ class CVC4_PUBLIC TesterType : public Type { public: /** Construct from the base type */ - TesterType(const Type& type) throw(AssertionException); + TesterType(const Type& type = Type()) throw(AssertionException); /** Get the type that this tester tests (the datatype type) */ DatatypeType getDomain() const; diff --git a/src/expr/type_checker.h b/src/expr/type_checker.h new file mode 100644 index 000000000..0c8093469 --- /dev/null +++ b/src/expr/type_checker.h @@ -0,0 +1,40 @@ +/********************* */ +/*! \file type_checker.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: cconway, dejan + ** Minor contributors (to current version): acsys, taking + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief A type checker + ** + ** A type checker. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__EXPR__TYPE_CHECKER_H +#define __CVC4__EXPR__TYPE_CHECKER_H + +#include "expr/node.h" + +namespace CVC4 { +namespace expr { + +class TypeChecker { +public: + + static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check = false) + throw (TypeCheckingExceptionPrivate, AssertionException); + +};/* class TypeChecker */ + +}/* CVC4::expr namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__EXPR__TYPE_CHECKER_H */ diff --git a/src/expr/type_checker_template.cpp b/src/expr/type_checker_template.cpp new file mode 100644 index 000000000..2791376b5 --- /dev/null +++ b/src/expr/type_checker_template.cpp @@ -0,0 +1,66 @@ +/********************* */ +/*! \file type_checker_template.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief TypeChecker implementation + ** + ** TypeChecker implementation. + **/ + +#line 20 "${template}" + +#include "expr/type_checker.h" +#include "expr/node_manager.h" + +${typechecker_includes} + +#line 27 "${template}" + +namespace CVC4 { +namespace expr { + +TypeNode TypeChecker::computeType(NodeManager* nodeManager, TNode n, bool check) + throw (TypeCheckingExceptionPrivate, AssertionException) { + TypeNode typeNode; + + // Infer the type + switch(n.getKind()) { + case kind::VARIABLE: + case kind::SKOLEM: + typeNode = nodeManager->getAttribute(n, NodeManager::TypeAttr()); + break; + case kind::BUILTIN: + typeNode = nodeManager->builtinOperatorType(); + break; + case kind::SORT_TYPE: + typeNode = nodeManager->kindType(); + break; + +${typerules} + +#line 51 "${template}" + + default: + Debug("getType") << "FAILURE" << std::endl; + Unhandled(n.getKind()); + } + + nodeManager->setAttribute(n, NodeManager::TypeAttr(), typeNode); + nodeManager->setAttribute(n, NodeManager::TypeCheckedAttr(), + check || nodeManager->getAttribute(n, NodeManager::TypeCheckedAttr())); + + return typeNode; + +}/* TypeChecker::computeType */ + +}/* CVC4::expr namespace */ +}/* CVC4 namespace */ diff --git a/src/expr/type_node.cpp b/src/expr/type_node.cpp index 76a084204..51d86904a 100644 --- a/src/expr/type_node.cpp +++ b/src/expr/type_node.cpp @@ -2,8 +2,8 @@ /*! \file type_node.cpp ** \verbatim ** Original author: dejan - ** Major contributors: none - ** Minor contributors (to current version): none + ** Major contributors: mdeters + ** Minor contributors (to current version): taking, ajreynol ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/expr/type_node.h b/src/expr/type_node.h index 3f4e52d36..25af3aae6 100644 --- a/src/expr/type_node.h +++ b/src/expr/type_node.h @@ -3,7 +3,7 @@ ** \verbatim ** Original author: dejan ** Major contributors: mdeters - ** Minor contributors (to current version): taking + ** Minor contributors (to current version): taking, ajreynol ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/include/cvc4_private.h b/src/include/cvc4_private.h index ea9c8371f..11d4a2ea9 100644 --- a/src/include/cvc4_private.h +++ b/src/include/cvc4_private.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/include/cvc4_public.h b/src/include/cvc4_public.h index 1e26699ec..6dec72736 100644 --- a/src/include/cvc4_public.h +++ b/src/include/cvc4_public.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 @@ -71,12 +71,14 @@ # define CVC4_NORETURN __attribute__ ((__noreturn__)) # define CVC4_CONST_FUNCTION __attribute__ ((__const__)) # define CVC4_PURE_FUNCTION __attribute__ ((__pure__)) +# define CVC4_DEPRECATED __attribute__ ((__deprecated__)) # define CVC4_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) #else /* ! __GNUC__ */ # define CVC4_UNUSED # define CVC4_NORETURN # define CVC4_CONST_FUNCTION # define CVC4_PURE_FUNCTION +# define CVC4_DEPRECATED # define CVC4_WARN_UNUSED_RESULT #endif /* __GNUC__ */ diff --git a/src/include/cvc4parser_private.h b/src/include/cvc4parser_private.h index cfd4405e6..bb4354178 100644 --- a/src/include/cvc4parser_private.h +++ b/src/include/cvc4parser_private.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/include/cvc4parser_public.h b/src/include/cvc4parser_public.h index a60d281bb..e86356942 100644 --- a/src/include/cvc4parser_public.h +++ b/src/include/cvc4parser_public.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/lib/clock_gettime.c b/src/lib/clock_gettime.c index 97c8f28a8..0d888fa8e 100644 --- a/src/lib/clock_gettime.c +++ b/src/lib/clock_gettime.c @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/lib/replacements.h b/src/lib/replacements.h index a0a9475f4..ee2ffc2dd 100644 --- a/src/lib/replacements.h +++ b/src/lib/replacements.h @@ -16,8 +16,6 @@ ** Common header for replacement function sources. **/ -#include "cvc4_public.h" - #ifndef __CVC4__LIB__REPLACEMENTS_H #define __CVC4__LIB__REPLACEMENTS_H diff --git a/src/main/interactive_shell.cpp b/src/main/interactive_shell.cpp index 707fc0ef3..8f1d54a3a 100644 --- a/src/main/interactive_shell.cpp +++ b/src/main/interactive_shell.cpp @@ -2,8 +2,8 @@ /*! \file interactive_shell.cpp ** \verbatim ** Original author: cconway - ** Major contributors: none - ** Minor contributors (to current version): mdeters + ** Major contributors: mdeters + ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -237,11 +237,14 @@ Command* InteractiveShell::readCommand() { break; } else { #if HAVE_LIBREADLINE - DeclarationCommand* dcmd = - dynamic_cast<DeclarationCommand*>(cmd); - if(dcmd != NULL) { - const vector<string>& ids = dcmd->getDeclaredSymbols(); - s_declarations.insert(ids.begin(), ids.end()); + if(dynamic_cast<DeclareFunctionCommand*>(cmd) != NULL) { + s_declarations.insert(dynamic_cast<DeclareFunctionCommand*>(cmd)->getSymbol()); + } else if(dynamic_cast<DefineFunctionCommand*>(cmd) != NULL) { + s_declarations.insert(dynamic_cast<DeclareFunctionCommand*>(cmd)->getSymbol()); + } else if(dynamic_cast<DeclareTypeCommand*>(cmd) != NULL) { + s_declarations.insert(dynamic_cast<DeclareFunctionCommand*>(cmd)->getSymbol()); + } else if(dynamic_cast<DefineTypeCommand*>(cmd) != NULL) { + s_declarations.insert(dynamic_cast<DeclareFunctionCommand*>(cmd)->getSymbol()); } #endif /* HAVE_LIBREADLINE */ } diff --git a/src/main/interactive_shell.h b/src/main/interactive_shell.h index 4fa2d6e96..f6852b95b 100644 --- a/src/main/interactive_shell.h +++ b/src/main/interactive_shell.h @@ -2,7 +2,7 @@ /*! \file interactive_shell.h ** \verbatim ** Original author: cconway - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/main/main.cpp b/src/main/main.cpp index 1423befb6..ef19e1604 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -183,6 +183,7 @@ int runCvc4(int argc, char* argv[]) { Chat.setStream(CVC4::null_os); Message.setStream(CVC4::null_os); Warning.setStream(CVC4::null_os); + Dump.setStream(CVC4::null_os); } else { if(options.verbosity < 2) { Chat.setStream(CVC4::null_os); @@ -228,7 +229,10 @@ int runCvc4(int argc, char* argv[]) { } } - OutputLanguage outLang = language::toOutputLanguage(options.inputLanguage); + if(options.outputLanguage == language::output::LANG_AUTO) { + options.outputLanguage = language::toOutputLanguage(options.inputLanguage); + } + // Determine which messages to show based on smtcomp_mode and verbosity if(Configuration::isMuzzledBuild()) { Debug.setStream(CVC4::null_os); @@ -237,6 +241,7 @@ int runCvc4(int argc, char* argv[]) { Chat.setStream(CVC4::null_os); Message.setStream(CVC4::null_os); Warning.setStream(CVC4::null_os); + Dump.setStream(CVC4::null_os); } else { if(options.verbosity < 2) { Chat.setStream(CVC4::null_os); @@ -249,12 +254,15 @@ int runCvc4(int argc, char* argv[]) { Warning.setStream(CVC4::null_os); } - Debug.getStream() << Expr::setlanguage(outLang); - Trace.getStream() << Expr::setlanguage(outLang); - Notice.getStream() << Expr::setlanguage(outLang); - Chat.getStream() << Expr::setlanguage(outLang); - Message.getStream() << Expr::setlanguage(outLang); - Warning.getStream() << Expr::setlanguage(outLang); + Debug.getStream() << Expr::setlanguage(options.outputLanguage); + Trace.getStream() << Expr::setlanguage(options.outputLanguage); + Notice.getStream() << Expr::setlanguage(options.outputLanguage); + Chat.getStream() << Expr::setlanguage(options.outputLanguage); + Message.getStream() << Expr::setlanguage(options.outputLanguage); + Warning.getStream() << Expr::setlanguage(options.outputLanguage); + Dump.getStream() << Expr::setlanguage(options.outputLanguage) + << Expr::setdepth(-1) + << Expr::printtypes(false); } Parser* replayParser = NULL; @@ -271,7 +279,7 @@ int runCvc4(int argc, char* argv[]) { options.replayStream = new Parser::ExprStream(replayParser); } if( options.replayLog != NULL ) { - *options.replayLog << Expr::setlanguage(outLang) << Expr::setdepth(-1); + *options.replayLog << Expr::setlanguage(options.outputLanguage) << Expr::setdepth(-1); } // Parse and execute commands until we are done @@ -296,8 +304,7 @@ int runCvc4(int argc, char* argv[]) { delete cmd; } } else { - ParserBuilder parserBuilder = - ParserBuilder(&exprMgr, filename, options); + ParserBuilder parserBuilder(&exprMgr, filename, options); if( inputFromStdin ) { parserBuilder.withStreamInput(cin); diff --git a/src/main/main.h b/src/main/main.h index e472b43f1..1771198f4 100644 --- a/src/main/main.h +++ b/src/main/main.h @@ -3,7 +3,7 @@ ** \verbatim ** Original author: mdeters ** Major contributors: none - ** Minor contributors (to current version): dejan, barrett + ** Minor contributors (to current version): cconway ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/main/usage.h b/src/main/usage.h index 5ad96aea6..c11a2b73e 100644 --- a/src/main/usage.h +++ b/src/main/usage.h @@ -5,7 +5,7 @@ ** Major contributors: none ** Minor contributors (to current version): cconway ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/main/util.cpp b/src/main/util.cpp index bf42025a0..255d84205 100644 --- a/src/main/util.cpp +++ b/src/main/util.cpp @@ -3,9 +3,9 @@ ** \verbatim ** Original author: mdeters ** Major contributors: none - ** Minor contributors (to current version): acsys + ** Minor contributors (to current version): acsys, cconway ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/Makefile.am b/src/parser/Makefile.am index 2b90da502..f1802c6c5 100644 --- a/src/parser/Makefile.am +++ b/src/parser/Makefile.am @@ -20,7 +20,9 @@ AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) SUBDIRS = smt smt2 cvc nobase_lib_LTLIBRARIES = libcvc4parser.la +if HAVE_CXXTESTGEN noinst_LTLIBRARIES = libcvc4parser_noinst.la +endif libcvc4parser_la_LDFLAGS = $(ANTLR_LDFLAGS) \ -version-info $(LIBCVC4PARSER_VERSION) diff --git a/src/parser/antlr_input.cpp b/src/parser/antlr_input.cpp index 74157acd7..c51d4b8c3 100644 --- a/src/parser/antlr_input.cpp +++ b/src/parser/antlr_input.cpp @@ -5,7 +5,7 @@ ** Major contributors: none ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/antlr_input.h b/src/parser/antlr_input.h index 4ae063266..913dd8013 100644 --- a/src/parser/antlr_input.h +++ b/src/parser/antlr_input.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: cconway ** Major contributors: none - ** Minor contributors (to current version): mdeters, dejan + ** Minor contributors (to current version): dejan, mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/bounded_token_factory.cpp b/src/parser/bounded_token_factory.cpp index 5f42f0f29..71b8849e5 100644 --- a/src/parser/bounded_token_factory.cpp +++ b/src/parser/bounded_token_factory.cpp @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/bounded_token_factory.h b/src/parser/bounded_token_factory.h index 4d510c9e3..84697fd3e 100644 --- a/src/parser/bounded_token_factory.h +++ b/src/parser/bounded_token_factory.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/cvc/Cvc.g b/src/parser/cvc/Cvc.g index 75a59c6e0..1f817350c 100644 --- a/src/parser/cvc/Cvc.g +++ b/src/parser/cvc/Cvc.g @@ -3,7 +3,7 @@ ** \verbatim ** Original author: cconway ** Major contributors: mdeters - ** Minor contributors (to current version): dejan + ** Minor contributors (to current version): dejan, ajreynol ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -64,6 +64,7 @@ tokens { PRINT_TYPE_TOK = 'PRINT_TYPE'; CALL_TOK = 'CALL'; ECHO_TOK = 'ECHO'; + EXIT_TOK = 'EXIT'; INCLUDE_TOK = 'INCLUDE'; DUMP_PROOF_TOK = 'DUMP_PROOF'; DUMP_ASSUMPTIONS_TOK = 'DUMP_ASSUMPTIONS'; @@ -84,7 +85,6 @@ tokens { AND_TOK = 'AND'; BOOLEAN_TOK = 'BOOLEAN'; - ECHO_TOK = 'ECHO'; ELSEIF_TOK = 'ELSIF'; ELSE_TOK = 'ELSE'; ENDIF_TOK = 'ENDIF'; @@ -448,38 +448,39 @@ namespace CVC4 { /** * This class is just here to get around an unfortunate bit of Antlr. * We use strings below as return values from rules, which require - * them to be constructible by a uintptr_t. So we derive the string + * them to be constructible by a void*. So we derive the string * class to provide just such a conversion. */ class myString : public std::string { public: myString(const std::string& s) : std::string(s) {} - myString(uintptr_t) : std::string() {} + myString(void*) : std::string() {} myString() : std::string() {} };/* class myString */ /** - * Just exists to give us the uintptr_t construction that + * Just exists to give us the void* construction that * ANTLR requires. */ class mySubrangeBound : public CVC4::SubrangeBound { public: mySubrangeBound() : CVC4::SubrangeBound() {} - mySubrangeBound(uintptr_t) : CVC4::SubrangeBound() {} + mySubrangeBound(void*) : CVC4::SubrangeBound() {} mySubrangeBound(const Integer& i) : CVC4::SubrangeBound(i) {} mySubrangeBound(const SubrangeBound& b) : CVC4::SubrangeBound(b) {} };/* class mySubrangeBound */ /** - * Just exists to give us the uintptr_t construction that + * Just exists to give us the void* construction that * ANTLR requires. */ struct myExpr : public CVC4::Expr { myExpr() : CVC4::Expr() {} - myExpr(uintptr_t) : CVC4::Expr() {} + myExpr(void*) : CVC4::Expr() {} myExpr(const Expr& e) : CVC4::Expr(e) {} myExpr(const myExpr& e) : CVC4::Expr(e) {} };/* struct myExpr */ + }/* CVC4::parser::cvc namespace */ }/* CVC4::parser namespace */ }/* CVC4 namespace */ @@ -532,7 +533,7 @@ using namespace CVC4::parser; * Parses an expression. * @return the parsed expression */ -parseExpr returns [CVC4::parser::cvc::myExpr expr] +parseExpr returns [CVC4::Expr expr = CVC4::Expr()] : formula[expr] | EOF ; @@ -541,7 +542,7 @@ parseExpr returns [CVC4::parser::cvc::myExpr expr] * Parses a command (the whole benchmark) * @return the command of the benchmark */ -parseCommand returns [CVC4::Command* cmd] +parseCommand returns [CVC4::Command* cmd = NULL] : c=command { $cmd = c; } | EOF { $cmd = NULL; } ; @@ -580,7 +581,6 @@ mainCommand[CVC4::Command*& cmd] std::vector<CVC4::Datatype> dts; Debug("parser-extra") << "command: " << AntlrInput::tokenText(LT(1)) << std::endl; std::string s; - k = 0; } /* our bread & butter */ : ASSERT_TOK formula[f] { cmd = new AssertCommand(f); } @@ -696,6 +696,9 @@ mainCommand[CVC4::Command*& cmd] | { Message() << std::endl; } ) + | EXIT_TOK + { cmd = new QuitCommand(); } + | INCLUDE_TOK ( ( str[s] | IDENTIFIER { s = AntlrInput::tokenText($IDENTIFIER); } ) { UNSUPPORTED("INCLUDE command"); } @@ -752,15 +755,15 @@ toplevelDeclaration[CVC4::Command*& cmd] Debug("parser-extra") << "declaration: " << AntlrInput::tokenText(LT(1)) << std::endl; } : identifierList[ids,CHECK_NONE,SYM_VARIABLE] COLON - ( declareVariables[t,ids,true] { cmd = new DeclarationCommand(ids, t); } - | declareTypes[ids] { cmd = new DeclarationCommand(ids, EXPR_MANAGER->kindType()); } ) + ( declareVariables[cmd,t,ids,true] + | declareTypes[cmd,ids] ) ; /** * A bound variable declaration. */ boundVarDecl[std::vector<std::string>& ids, CVC4::Type& t] - : identifierList[ids,CHECK_NONE,SYM_VARIABLE] COLON declareVariables[t,ids,false] + : identifierList[ids,CHECK_NONE,SYM_VARIABLE] COLON declareVariables[*(Command**)NULL,t,ids,false] ; /** @@ -808,13 +811,14 @@ boundVarDeclReturn[std::vector<CVC4::Expr>& terms, * because type declarations are always top-level, except for * type-lets, which don't use this rule. */ -declareTypes[const std::vector<std::string>& idList] +declareTypes[CVC4::Command*& cmd, const std::vector<std::string>& idList] @init { Type t; } /* A sort declaration (e.g., "T : TYPE") */ : TYPE_TOK - { for(std::vector<std::string>::const_iterator i = idList.begin(); + { DeclarationSequence* seq = new DeclarationSequence(); + for(std::vector<std::string>::const_iterator i = idList.begin(); i != idList.end(); ++i) { // Don't allow a type variable to clash with a previously @@ -822,8 +826,11 @@ declareTypes[const std::vector<std::string>& idList] // non-type variable can clash unambiguously. Break from CVC3 // behavior here. PARSER_STATE->checkDeclaration(*i, CHECK_UNDECLARED, SYM_SORT); + Type sort = PARSER_STATE->mkSort(*i); + Command* decl = new DeclareTypeCommand(*i, 0, sort); + seq->addCommand(decl); } - PARSER_STATE->mkSorts(idList); + cmd = seq; } /* A type alias "T : TYPE = foo..." */ @@ -843,16 +850,20 @@ declareTypes[const std::vector<std::string>& idList] * re-declared if topLevel is true (CVC allows re-declaration if the * types are compatible---if they aren't compatible, an error is * thrown). Also if topLevel is true, variable definitions are - * permitted. + * permitted and "cmd" is output. */ -declareVariables[CVC4::Type& t, const std::vector<std::string>& idList, bool topLevel] +declareVariables[CVC4::Command*& cmd, CVC4::Type& t, const std::vector<std::string>& idList, bool topLevel] @init { Expr f; Debug("parser-extra") << "declType: " << AntlrInput::tokenText(LT(1)) << std::endl; } /* A variable declaration (or definition) */ : type[t,CHECK_DECLARED] ( EQUAL_TOK formula[f] )? - { if(f.isNull()) { + { DeclarationSequence* seq = NULL; + if(topLevel) { + cmd = seq = new DeclarationSequence(); + } + if(f.isNull()) { Debug("parser") << "working on " << idList.front() << " : " << t << std::endl; // CVC language allows redeclaration of variables if types are the same for(std::vector<std::string>::const_iterator i = idList.begin(), @@ -877,6 +888,10 @@ declareVariables[CVC4::Type& t, const std::vector<std::string>& idList, bool top } else { Debug("parser") << " " << *i << " not declared" << std::endl; PARSER_STATE->mkVar(*i, t); + if(topLevel) { + Command* decl = new DeclareFunctionCommand(*i, t); + seq->addCommand(decl); + } } } } else { @@ -892,6 +907,8 @@ declareVariables[CVC4::Type& t, const std::vector<std::string>& idList, bool top ++i) { PARSER_STATE->checkDeclaration(*i, CHECK_UNDECLARED, SYM_VARIABLE); PARSER_STATE->defineFunction(*i, f); + Command* decl = new DefineFunctionCommand(*i, Expr(), f); + seq->addCommand(decl); } } } @@ -1007,10 +1024,10 @@ restrictedTypePossiblyFunctionLHS[CVC4::Type& t, /* named types */ : identifier[id,check,SYM_SORT] parameterization[check,types]? - { + { if(check == CHECK_DECLARED || PARSER_STATE->isDeclared(id, SYM_SORT)) { - Debug("parser-param") << "param: getSort " << id << " " << types.size() << " " << PARSER_STATE->getArity( id ) + Debug("parser-param") << "param: getSort " << id << " " << types.size() << " " << PARSER_STATE->getArity( id ) << " " << PARSER_STATE->isDeclared(id, SYM_SORT) << std::endl; if( types.size()>0 ){ t = PARSER_STATE->getSort(id, types); @@ -1024,7 +1041,7 @@ restrictedTypePossiblyFunctionLHS[CVC4::Type& t, }else{ t = PARSER_STATE->mkUnresolvedTypeConstructor(id,types); t = SortConstructorType(t).instantiate( types ); - Debug("parser-param") << "param: make unres param type " << id << " " << types.size() << " " + Debug("parser-param") << "param: make unres param type " << id << " " << types.size() << " " << PARSER_STATE->getArity( id ) << std::endl; } } @@ -1095,7 +1112,7 @@ restrictedTypePossiblyFunctionLHS[CVC4::Type& t, } ; -parameterization[CVC4::parser::DeclarationCheck check, +parameterization[CVC4::parser::DeclarationCheck check, std::vector<CVC4::Type>& params] @init { Type t; @@ -1146,7 +1163,7 @@ formula[CVC4::Expr& f] ; morecomparisons[std::vector<CVC4::Expr>& expressions, - std::vector<unsigned>& operators] returns [size_t i] + std::vector<unsigned>& operators] returns [size_t i = 0] @init { unsigned op; Expr f; @@ -1165,10 +1182,7 @@ morecomparisons[std::vector<CVC4::Expr>& expressions, ; /** Matches 0 or more NOTs. */ -nots returns [size_t n] -@init { - $n = 0; -} +nots returns [size_t n = 0] : ( NOT_TOK { ++$n; } )* ; @@ -1208,8 +1222,9 @@ prefixFormula[CVC4::Expr& f] RPAREN COLON formula[f] { PARSER_STATE->popScope(); Type t = EXPR_MANAGER->mkFunctionType(types, f.getType()); - Expr func = PARSER_STATE->mkAnonymousFunction("lambda", t); - Command* cmd = new DefineFunctionCommand(func, terms, f); + std::string name = "lambda"; + Expr func = PARSER_STATE->mkAnonymousFunction(name, t); + Command* cmd = new DefineFunctionCommand(name, func, terms, f); PARSER_STATE->preemptCommand(cmd); f = func; } @@ -1735,17 +1750,18 @@ datatypeDef[std::vector<CVC4::Datatype>& datatypes] Type t; std::vector< Type > params; } - /* This really needs to be CHECK_NONE, or mutually-recursive datatypes - * won't work, because this type will already be "defined" as an - * unresolved type; don't worry, we check below. */ + /* This really needs to be CHECK_NONE, or mutually-recursive + * datatypes won't work, because this type will already be + * "defined" as an unresolved type; don't worry, we check + * below. */ : identifier[id,CHECK_NONE,SYM_SORT] { PARSER_STATE->pushScope(); } - ( LBRACKET identifier[id2,CHECK_UNDECLARED,SYM_SORT] { + ( LBRACKET identifier[id2,CHECK_UNDECLARED,SYM_SORT] { t = PARSER_STATE->mkSort(id2); - params.push_back( t ); + params.push_back( t ); } - ( COMMA identifier[id2,CHECK_UNDECLARED,SYM_SORT] { + ( COMMA identifier[id2,CHECK_UNDECLARED,SYM_SORT] { t = PARSER_STATE->mkSort(id2); - params.push_back( t ); } + params.push_back( t ); } )* RBRACKET )? { datatypes.push_back(Datatype(id,params)); @@ -1768,8 +1784,7 @@ constructorDef[CVC4::Datatype& type] CVC4::Datatype::Constructor* ctor = NULL; } : identifier[id,CHECK_UNDECLARED,SYM_SORT] - { - // make the tester + { // make the tester std::string testerId("is_"); testerId.append(id); PARSER_STATE->checkDeclaration(testerId, CHECK_UNDECLARED, SYM_SORT); @@ -1826,7 +1841,7 @@ DECIMAL_LITERAL * in the BVPLUS/BVMINUS/BVMULT rules where $INTEGER_LITERAL was * returning a reference to the wrong token?! */ -numeral returns [unsigned k] +numeral returns [unsigned k = 0] : INTEGER_LITERAL { $k = AntlrInput::tokenToUnsigned($INTEGER_LITERAL); } ; @@ -1834,7 +1849,7 @@ numeral returns [unsigned k] /** * Similar to numeral but for arbitrary-precision, signed integer. */ -integer returns [CVC4::Integer k] +integer returns [CVC4::Integer k = 0] : INTEGER_LITERAL { $k = AntlrInput::tokenToInteger($INTEGER_LITERAL); } | MINUS_TOK INTEGER_LITERAL diff --git a/src/parser/cvc/cvc_input.cpp b/src/parser/cvc/cvc_input.cpp index 541ac0eac..d91a13bee 100644 --- a/src/parser/cvc/cvc_input.cpp +++ b/src/parser/cvc/cvc_input.cpp @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/cvc/cvc_input.h b/src/parser/cvc/cvc_input.h index efe0a522f..9a1f24fde 100644 --- a/src/parser/cvc/cvc_input.h +++ b/src/parser/cvc/cvc_input.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/input.cpp b/src/parser/input.cpp index 36e96516f..27b207342 100644 --- a/src/parser/input.cpp +++ b/src/parser/input.cpp @@ -5,7 +5,7 @@ ** Major contributors: mdeters, cconway ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/memory_mapped_input_buffer.cpp b/src/parser/memory_mapped_input_buffer.cpp index aad5aaec0..dad38c913 100644 --- a/src/parser/memory_mapped_input_buffer.cpp +++ b/src/parser/memory_mapped_input_buffer.cpp @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/memory_mapped_input_buffer.h b/src/parser/memory_mapped_input_buffer.h index 18618a090..ccbe04059 100644 --- a/src/parser/memory_mapped_input_buffer.h +++ b/src/parser/memory_mapped_input_buffer.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 78e70572a..3f2ec107a 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -3,7 +3,7 @@ ** \verbatim ** Original author: dejan ** Major contributors: cconway, mdeters - ** Minor contributors (to current version): none + ** Minor contributors (to current version): ajreynol ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -227,15 +227,6 @@ Parser::mkSortConstructor(const std::string& name, size_t arity) { return type; } -std::vector<SortType> -Parser::mkSorts(const std::vector<std::string>& names) { - std::vector<SortType> types; - for(unsigned i = 0; i < names.size(); ++i) { - types.push_back(mkSort(names[i])); - } - return types; -} - SortType Parser::mkUnresolvedType(const std::string& name) { SortType unresolved = mkSort(name); d_unresolved.insert(unresolved); @@ -243,7 +234,7 @@ SortType Parser::mkUnresolvedType(const std::string& name) { } SortConstructorType -Parser::mkUnresolvedTypeConstructor(const std::string& name, +Parser::mkUnresolvedTypeConstructor(const std::string& name, size_t arity) { SortConstructorType unresolved = mkSortConstructor(name,arity); d_unresolved.insert(unresolved); @@ -251,7 +242,7 @@ Parser::mkUnresolvedTypeConstructor(const std::string& name, } SortConstructorType -Parser::mkUnresolvedTypeConstructor(const std::string& name, +Parser::mkUnresolvedTypeConstructor(const std::string& name, const std::vector<Type>& params) { Debug("parser") << "newSortConstructor(P)(" << name << ", " << params.size() << ")" << std::endl; @@ -356,13 +347,15 @@ void Parser::checkDeclaration(const std::string& varName, switch(check) { case CHECK_DECLARED: if( !isDeclared(varName, type) ) { - parseError("Symbol " + varName + " not declared as a " + (type == SYM_VARIABLE ? "variable" : "type")); + parseError("Symbol " + varName + " not declared as a " + + (type == SYM_VARIABLE ? "variable" : "type")); } break; case CHECK_UNDECLARED: if( isDeclared(varName, type) ) { - parseError("Symbol " + varName + " previously declared as a " + (type == SYM_VARIABLE ? "variable" : "type")); + parseError("Symbol " + varName + " previously declared as a " + + (type == SYM_VARIABLE ? "variable" : "type")); } break; diff --git a/src/parser/parser.h b/src/parser/parser.h index b2f76b39d..5ce016b85 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -3,7 +3,7 @@ ** \verbatim ** Original author: cconway ** Major contributors: mdeters - ** Minor contributors (to current version): dejan + ** Minor contributors (to current version): dejan, ajreynol ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -368,11 +368,6 @@ public: SortConstructorType mkSortConstructor(const std::string& name, size_t arity); /** - * Creates new sorts with the given names (all of arity 0). - */ - std::vector<SortType> mkSorts(const std::vector<std::string>& names); - - /** * Creates a new "unresolved type," used only during parsing. */ SortType mkUnresolvedType(const std::string& name); diff --git a/src/parser/smt/Smt.g b/src/parser/smt/Smt.g index 2a3a79125..da20c68a2 100644 --- a/src/parser/smt/Smt.g +++ b/src/parser/smt/Smt.g @@ -2,7 +2,7 @@ /*! \file Smt.g ** \verbatim ** Original author: cconway - ** Major contributors: mdeters, dejan + ** Major contributors: dejan, mdeters ** Minor contributors (to current version): taking ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) @@ -143,7 +143,7 @@ parseExpr returns [CVC4::parser::smt::myExpr expr] * Parses a command (the whole benchmark) * @return the command of the benchmark */ -parseCommand returns [CVC4::Command* cmd] +parseCommand returns [CVC4::Command* cmd = NULL] : b = benchmark { $cmd = b; } ; @@ -151,7 +151,7 @@ parseCommand returns [CVC4::Command* cmd] * Matches the whole SMT-LIB benchmark. * @return the sequence command containing the whole problem */ -benchmark returns [CVC4::Command* cmd] +benchmark returns [CVC4::Command* cmd = NULL] : LPAREN_TOK BENCHMARK_TOK IDENTIFIER c = benchAttributes RPAREN_TOK { $cmd = c; } | EOF { $cmd = 0; } @@ -162,7 +162,7 @@ benchmark returns [CVC4::Command* cmd] * command sequence. * @return the command sequence */ -benchAttributes returns [CVC4::CommandSequence* cmd_seq] +benchAttributes returns [CVC4::CommandSequence* cmd_seq = NULL] @init { cmd_seq = new CommandSequence(); } @@ -174,26 +174,42 @@ benchAttributes returns [CVC4::CommandSequence* cmd_seq] * a corresponding command * @return a command corresponding to the attribute */ -benchAttribute returns [CVC4::Command* smt_command] +benchAttribute returns [CVC4::Command* smt_command = NULL] @declarations { std::string name; BenchmarkStatus b_status; Expr expr; + Command* c; } : LOGIC_TOK identifier[name,CHECK_NONE,SYM_VARIABLE] - { PARSER_STATE->setLogic(name); - smt_command = new SetBenchmarkLogicCommand(name); } + { PARSER_STATE->preemptCommand(new SetBenchmarkLogicCommand(name)); + PARSER_STATE->setLogic(name); + smt_command = new EmptyCommand(); + } | ASSUMPTION_TOK annotatedFormula[expr] - { smt_command = new AssertCommand(expr); } + { smt_command = new AssertCommand(expr); } | FORMULA_TOK annotatedFormula[expr] { smt_command = new CheckSatCommand(expr); } | STATUS_TOK status[b_status] { smt_command = new SetBenchmarkStatusCommand(b_status); } - | EXTRAFUNS_TOK LPAREN_TOK (functionDeclaration)+ RPAREN_TOK - | EXTRAPREDS_TOK LPAREN_TOK (predicateDeclaration)+ RPAREN_TOK - | EXTRASORTS_TOK LPAREN_TOK sortDeclaration+ RPAREN_TOK + | EXTRAFUNS_TOK LPAREN_TOK + ( { smt_command = new CommandSequence(); } + functionDeclaration[c] + { ((CommandSequence*) smt_command)->addCommand(c); } + )+ RPAREN_TOK + | EXTRAPREDS_TOK LPAREN_TOK + ( { smt_command = new CommandSequence(); } + predicateDeclaration[c] + { ((CommandSequence*) smt_command)->addCommand(c); } + )+ RPAREN_TOK + | EXTRASORTS_TOK LPAREN_TOK + ( { smt_command = new CommandSequence(); } + sortDeclaration[c] + { ((CommandSequence*) smt_command)->addCommand(c); } + )+ RPAREN_TOK | NOTES_TOK STRING_LITERAL - | annotation + { smt_command = new CommentCommand(AntlrInput::tokenText($STRING_LITERAL)); } + | annotation[smt_command] ; /** @@ -417,11 +433,12 @@ functionSymbol[CVC4::Expr& fun] /** * Matches an attribute name from the input (:attribute_name). */ -attribute +attribute[std::string& s] : ATTR_IDENTIFIER + { s = AntlrInput::tokenText($ATTR_IDENTIFIER); } ; -functionDeclaration +functionDeclaration[CVC4::Command*& smt_command] @declarations { std::string name; std::vector<Type> sorts; @@ -435,13 +452,15 @@ functionDeclaration } else { t = EXPR_MANAGER->mkFunctionType(sorts); } - PARSER_STATE->mkVar(name, t); } + PARSER_STATE->mkVar(name, t); + smt_command = new DeclareFunctionCommand(name, t); + } ; /** * Matches the declaration of a predicate and declares it */ -predicateDeclaration +predicateDeclaration[CVC4::Command*& smt_command] @declarations { std::string name; std::vector<Type> p_sorts; @@ -453,16 +472,20 @@ predicateDeclaration } else { t = EXPR_MANAGER->mkPredicateType(p_sorts); } - PARSER_STATE->mkVar(name, t); } + PARSER_STATE->mkVar(name, t); + smt_command = new DeclareFunctionCommand(name, t); + } ; -sortDeclaration +sortDeclaration[CVC4::Command*& smt_command] @declarations { std::string name; } : sortName[name,CHECK_UNDECLARED] { Debug("parser") << "sort decl: '" << name << "'" << std::endl; - PARSER_STATE->mkSort(name); } + Type type = PARSER_STATE->mkSort(name); + smt_command = new DeclareTypeCommand(name, 0, type); + } ; /** @@ -503,8 +526,19 @@ status[ CVC4::BenchmarkStatus& status ] /** * Matches an annotation, which is an attribute name, with an optional user */ -annotation - : attribute (USER_VALUE)? +annotation[CVC4::Command*& smt_command] +@init { + std::string key; + smt_command = NULL; +} + : attribute[key] + ( USER_VALUE + { smt_command = new SetInfoCommand(key, AntlrInput::tokenText($USER_VALUE)); } + )? + { if(smt_command == NULL) { + smt_command = new EmptyCommand(std::string("annotation: ") + key); + } + } ; /** @@ -676,21 +710,20 @@ FLET_IDENTIFIER ; /** - * Matches the value of user-defined annotations or attributes. The only constraint imposed on a user-defined value is that it start with - * an open brace and end with closed brace. + * Matches the value of user-defined annotations or attributes. The + * only constraint imposed on a user-defined value is that it start + * with an open brace and end with closed brace. */ USER_VALUE - : '{' - ( '\\{' | '\\}' | ~('{' | '}') )* - '}' + : '{' ( '\\{' | '\\}' | ~('{' | '}') )* '}' ; - /** * Matches and skips whitespace in the input. */ WHITESPACE - : (' ' | '\t' | '\f' | '\r' | '\n')+ { SKIP();; } + : (' ' | '\t' | '\f' | '\r' | '\n')+ + { SKIP(); } ; /** @@ -716,7 +749,8 @@ STRING_LITERAL * Matches the comments and ignores them */ COMMENT - : ';' (~('\n' | '\r'))* { SKIP();; } + : ';' (~('\n' | '\r'))* + { SKIP(); } ; diff --git a/src/parser/smt/smt.cpp b/src/parser/smt/smt.cpp index a8dabeffe..a6e716b77 100644 --- a/src/parser/smt/smt.cpp +++ b/src/parser/smt/smt.cpp @@ -2,8 +2,8 @@ /*! \file smt.cpp ** \verbatim ** Original author: cconway - ** Major contributors: none - ** Minor contributors (to current version): dejan, mdeters + ** Major contributors: mdeters + ** Minor contributors (to current version): dejan ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -20,6 +20,7 @@ namespace std { } #include "expr/type.h" +#include "expr/command.h" #include "parser/parser.h" #include "parser/smt/smt.h" @@ -80,6 +81,10 @@ void Smt::addTheory(Theory theory) { case THEORY_ARRAYS_EX: { Type indexType = mkSort("Index"); Type elementType = mkSort("Element"); + DeclarationSequence* seq = new DeclarationSequence(); + seq->addCommand(new DeclareTypeCommand("Index", 0, indexType)); + seq->addCommand(new DeclareTypeCommand("Element", 0, elementType)); + preemptCommand(seq); defineType("Array", getExprManager()->mkArrayType(indexType,elementType)); @@ -88,9 +93,11 @@ void Smt::addTheory(Theory theory) { break; } - case THEORY_EMPTY: - mkSort("U"); + case THEORY_EMPTY: { + Type sort = mkSort("U"); + preemptCommand(new DeclareTypeCommand("U", 0, sort)); break; + } case THEORY_REALS_INTS: defineType("Real", getExprManager()->realType()); diff --git a/src/parser/smt/smt.h b/src/parser/smt/smt.h index 98ebf6410..11a30c2fc 100644 --- a/src/parser/smt/smt.h +++ b/src/parser/smt/smt.h @@ -2,8 +2,8 @@ /*! \file smt.h ** \verbatim ** Original author: cconway - ** Major contributors: none - ** Minor contributors (to current version): mdeters + ** Major contributors: mdeters + ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/parser/smt/smt_input.cpp b/src/parser/smt/smt_input.cpp index d062683d3..d368339f5 100644 --- a/src/parser/smt/smt_input.cpp +++ b/src/parser/smt/smt_input.cpp @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/smt/smt_input.h b/src/parser/smt/smt_input.h index 2fb037f06..b976a3b6a 100644 --- a/src/parser/smt/smt_input.h +++ b/src/parser/smt/smt_input.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g index 091e6c93c..5ae04adea 100644 --- a/src/parser/smt2/Smt2.g +++ b/src/parser/smt2/Smt2.g @@ -143,7 +143,7 @@ parseExpr returns [CVC4::parser::smt2::myExpr expr] * Parses a command * @return the parsed command, or NULL if we've reached the end of the input */ -parseCommand returns [CVC4::Command* cmd] +parseCommand returns [CVC4::Command* cmd = NULL] : LPAREN_TOK c = command RPAREN_TOK { $cmd = c; } | EOF { $cmd = 0; } ; @@ -151,7 +151,7 @@ parseCommand returns [CVC4::Command* cmd] /** * Parse the internal portion of the command, ignoring the surrounding parentheses. */ -command returns [CVC4::Command* cmd] +command returns [CVC4::Command* cmd = NULL] @declarations { std::string name; std::vector<std::string> names; @@ -192,11 +192,11 @@ command returns [CVC4::Command* cmd] << "' arity=" << n << std::endl; unsigned arity = AntlrInput::tokenToUnsigned(n); if(arity == 0) { - PARSER_STATE->mkSort(name); - $cmd = new DeclarationCommand(name, EXPR_MANAGER->kindType()); + Type type = PARSER_STATE->mkSort(name); + $cmd = new DeclareTypeCommand(name, 0, type); } else { - PARSER_STATE->mkSortConstructor(name, arity); - $cmd = new DeclarationCommand(name, EXPR_MANAGER->kindType()); + Type type = PARSER_STATE->mkSortConstructor(name, arity); + $cmd = new DeclareTypeCommand(name, arity, type); } } | /* sort definition */ @@ -216,7 +216,7 @@ command returns [CVC4::Command* cmd] // Do NOT call mkSort, since that creates a new sort! // This name is not its own distinct sort, it's an alias. PARSER_STATE->defineParameterizedType(name, sorts, t); - $cmd = new EmptyCommand; + $cmd = new DefineTypeCommand(name, sorts, t); } | /* function declaration */ DECLARE_FUN_TOK symbol[name,CHECK_UNDECLARED,SYM_VARIABLE] @@ -227,7 +227,7 @@ command returns [CVC4::Command* cmd] t = EXPR_MANAGER->mkFunctionType(sorts, t); } PARSER_STATE->mkVar(name, t); - $cmd = new DeclarationCommand(name,t); } + $cmd = new DeclareFunctionCommand(name, t); } | /* function definition */ DEFINE_FUN_TOK symbol[name,CHECK_UNDECLARED,SYM_VARIABLE] LPAREN_TOK sortedVarList[sortedVarNames] RPAREN_TOK @@ -259,10 +259,16 @@ command returns [CVC4::Command* cmd] // must not be extended with the name itself; no recursion // permitted) Expr func = PARSER_STATE->mkFunction(name, t); - $cmd = new DefineFunctionCommand(func, terms, expr); + $cmd = new DefineFunctionCommand(name, func, terms, expr); } | /* value query */ - GET_VALUE_TOK LPAREN_TOK termList[terms,expr] RPAREN_TOK + ( GET_VALUE_TOK | + EVAL_TOK + { if(PARSER_STATE->strictModeEnabled()) { + PARSER_STATE->parseError("Strict compliance mode doesn't recognize \"eval\". Maybe you want (get-value...)?"); + } + } ) + LPAREN_TOK termList[terms,expr] RPAREN_TOK { if(terms.size() == 1) { $cmd = new GetValueCommand(terms[0]); } else { @@ -289,36 +295,86 @@ command returns [CVC4::Command* cmd] GET_ASSERTIONS_TOK { cmd = new GetAssertionsCommand; } | /* push */ - PUSH_TOK k=INTEGER_LITERAL - { unsigned n = AntlrInput::tokenToUnsigned(k); - if(n == 0) { - cmd = new EmptyCommand; - } else if(n == 1) { - cmd = new PushCommand; - } else { - CommandSequence* seq = new CommandSequence; - do { - seq->addCommand(new PushCommand); - } while(--n > 0); - cmd = seq; + PUSH_TOK + ( k=INTEGER_LITERAL + { unsigned n = AntlrInput::tokenToUnsigned(k); + if(n == 0) { + cmd = new EmptyCommand; + } else if(n == 1) { + cmd = new PushCommand; + } else { + CommandSequence* seq = new CommandSequence; + do { + seq->addCommand(new PushCommand); + } while(--n > 0); + cmd = seq; + } } - } - | POP_TOK k=INTEGER_LITERAL - { unsigned n = AntlrInput::tokenToUnsigned(k); - if(n == 0) { - cmd = new EmptyCommand; - } else if(n == 1) { - cmd = new PopCommand; - } else { - CommandSequence* seq = new CommandSequence; - do { - seq->addCommand(new PopCommand); - } while(--n > 0); - cmd = seq; + | { if(PARSER_STATE->strictModeEnabled()) { + PARSER_STATE->parseError("Strict compliance mode demands an integer to be provided to PUSH. Maybe you want (push 1)?"); + } else { + cmd = new PushCommand; + } + } ) + | POP_TOK + ( k=INTEGER_LITERAL + { unsigned n = AntlrInput::tokenToUnsigned(k); + if(n == 0) { + cmd = new EmptyCommand; + } else if(n == 1) { + cmd = new PopCommand; + } else { + CommandSequence* seq = new CommandSequence; + do { + seq->addCommand(new PopCommand); + } while(--n > 0); + cmd = seq; + } } - } + | { if(PARSER_STATE->strictModeEnabled()) { + PARSER_STATE->parseError("Strict compliance mode demands an integer to be provided to POP. Maybe you want (pop 1)?"); + } else { + cmd = new PopCommand; + } + } ) | EXIT_TOK { cmd = new QuitCommand; } + + /* CVC4-extended SMT-LIBv2 commands */ + | extendedCommand[cmd] + { if(PARSER_STATE->strictModeEnabled()) { + PARSER_STATE->parseError("Extended commands are not permitted while operating in strict compliance mode."); + } + } + ; + +extendedCommand[CVC4::Command*& cmd] +@declarations { + std::vector<CVC4::Datatype> dts; + Expr e; +} + /* Z3's extended SMT-LIBv2 set of commands syntax */ + : DECLARE_DATATYPES_TOK + { /* open a scope to keep the UnresolvedTypes contained */ + PARSER_STATE->pushScope(); } + LPAREN_TOK ( LPAREN_TOK datatypeDef[dts] RPAREN_TOK )+ RPAREN_TOK + { PARSER_STATE->popScope(); + cmd = new DatatypeDeclarationCommand(PARSER_STATE->mkMutualDatatypeTypes(dts)); } + + + | DECLARE_SORTS_TOK + | DECLARE_FUNS_TOK + | DECLARE_PREDS_TOK + | DEFINE_TOK + | DEFINE_SORTS_TOK + | DECLARE_CONST_TOK + + | SIMPLIFY_TOK term[e] + { cmd = new SimplifyCommand(e); } + | ECHO_TOK + ( STRING_LITERAL + { Message() << AntlrInput::tokenText($STRING_LITERAL) << std::endl; } + | { Message() << std::endl; } ) ; symbolicExpr[CVC4::SExpr& sexpr] @@ -441,7 +497,7 @@ term[CVC4::Expr& expr] Expr func = PARSER_STATE->mkFunction(name, expr.getType()); // bind name to expr with define-fun Command* c = - new DefineNamedFunctionCommand(func, std::vector<Expr>(), expr); + new DefineNamedFunctionCommand(name, func, std::vector<Expr>(), expr); PARSER_STATE->preemptCommand(c); } else { std::stringstream ss; @@ -716,6 +772,73 @@ nonemptyNumeralList[std::vector<uint64_t>& numerals] )+ ; +/** + * Parses a datatype definition + */ +datatypeDef[std::vector<CVC4::Datatype>& datatypes] +@init { + std::string id, id2; + Type t; + std::vector< Type > params; +} + /* This really needs to be CHECK_NONE, or mutually-recursive + * datatypes won't work, because this type will already be + * "defined" as an unresolved type; don't worry, we check + * below. */ + : symbol[id,CHECK_NONE,SYM_SORT] { PARSER_STATE->pushScope(); } + ( '[' symbol[id2,CHECK_UNDECLARED,SYM_SORT] { + t = PARSER_STATE->mkSort(id2); + params.push_back( t ); + } + ( symbol[id2,CHECK_UNDECLARED,SYM_SORT] { + t = PARSER_STATE->mkSort(id2); + params.push_back( t ); } + )* ']' + )? + { datatypes.push_back(Datatype(id,params)); + if(!PARSER_STATE->isUnresolvedType(id)) { + // if not unresolved, must be undeclared + PARSER_STATE->checkDeclaration(id, CHECK_UNDECLARED, SYM_SORT); + } + } + ( LPAREN_TOK constructorDef[datatypes.back()] RPAREN_TOK )+ + { PARSER_STATE->popScope(); } + ; + +/** + * Parses a constructor defintion for type + */ +constructorDef[CVC4::Datatype& type] +@init { + std::string id; + CVC4::Datatype::Constructor* ctor = NULL; +} + : symbol[id,CHECK_UNDECLARED,SYM_SORT] + { // make the tester + std::string testerId("is_"); + testerId.append(id); + PARSER_STATE->checkDeclaration(testerId, CHECK_UNDECLARED, SYM_SORT); + ctor = new CVC4::Datatype::Constructor(id, testerId); + } + ( LPAREN_TOK selector[*ctor] RPAREN_TOK )* + { // make the constructor + type.addConstructor(*ctor); + Debug("parser-idt") << "constructor: " << id.c_str() << std::endl; + delete ctor; + } + ; + +selector[CVC4::Datatype::Constructor& ctor] +@init { + std::string id; + Type t, t2; +} + : symbol[id,CHECK_UNDECLARED,SYM_SORT] sortSymbol[t] + { ctor.addArg(id, t); + Debug("parser-idt") << "selector: " << id.c_str() << std::endl; + } + ; + // Base SMT-LIB tokens ASSERT_TOK : 'assert'; CHECKSAT_TOK : 'check-sat'; @@ -741,6 +864,18 @@ GET_OPTION_TOK : 'get-option'; PUSH_TOK : 'push'; POP_TOK : 'pop'; +// extended commands +DECLARE_DATATYPES_TOK : 'declare-datatypes'; +DECLARE_SORTS_TOK : 'declare-sorts'; +DECLARE_FUNS_TOK : 'declare-funs'; +DECLARE_PREDS_TOK : 'declare-preds'; +DEFINE_TOK : 'define'; +DEFINE_SORTS_TOK : 'define-sorts'; +DECLARE_CONST_TOK : 'declare-const'; +SIMPLIFY_TOK : 'simplify'; +EVAL_TOK : 'eval'; +ECHO_TOK : 'echo'; + // operators (NOTE: theory symbols go here) AMPERSAND_TOK : '&'; AND_TOK : 'and'; @@ -759,7 +894,6 @@ MINUS_TOK : '-'; NOT_TOK : 'not'; OR_TOK : 'or'; PERCENT_TOK : '%'; -PIPE_TOK : '|'; PLUS_TOK : '+'; POUND_TOK : '#'; SELECT_TOK : 'select'; diff --git a/src/parser/smt2/smt2_input.cpp b/src/parser/smt2/smt2_input.cpp index 9a349785c..acd0e17f6 100644 --- a/src/parser/smt2/smt2_input.cpp +++ b/src/parser/smt2/smt2_input.cpp @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/parser/smt2/smt2_input.h b/src/parser/smt2/smt2_input.h index 04fe48fe1..05a62c30d 100644 --- a/src/parser/smt2/smt2_input.h +++ b/src/parser/smt2/smt2_input.h @@ -2,10 +2,10 @@ /*! \file smt2_input.h ** \verbatim ** Original author: cconway - ** Major contributors: none - ** Minor contributors (to current version): mdeters + ** Major contributors: mdeters + ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/printer/ast/ast_printer.cpp b/src/printer/ast/ast_printer.cpp index 5863ded9f..082765765 100644 --- a/src/printer/ast/ast_printer.cpp +++ b/src/printer/ast/ast_printer.cpp @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 @@ -112,9 +112,12 @@ void AstPrinter::toStream(std::ostream& out, const Command* c, tryToStream<CheckSatCommand>(out, c) || tryToStream<QueryCommand>(out, c) || tryToStream<QuitCommand>(out, c) || + tryToStream<DeclarationSequence>(out, c) || tryToStream<CommandSequence>(out, c) || - tryToStream<DeclarationCommand>(out, c) || + tryToStream<DeclareFunctionCommand>(out, c) || tryToStream<DefineFunctionCommand>(out, c) || + tryToStream<DeclareTypeCommand>(out, c) || + tryToStream<DefineTypeCommand>(out, c) || tryToStream<DefineNamedFunctionCommand>(out, c) || tryToStream<SimplifyCommand>(out, c) || tryToStream<GetValueCommand>(out, c) || @@ -126,7 +129,8 @@ void AstPrinter::toStream(std::ostream& out, const Command* c, tryToStream<GetInfoCommand>(out, c) || tryToStream<SetOptionCommand>(out, c) || tryToStream<GetOptionCommand>(out, c) || - tryToStream<DatatypeDeclarationCommand>(out, c)) { + tryToStream<DatatypeDeclarationCommand>(out, c) || + tryToStream<CommentCommand>(out, c)) { return; } @@ -167,6 +171,16 @@ static void toStream(std::ostream& out, const QuitCommand* c) { out << "Quit()"; } +static void toStream(std::ostream& out, const DeclarationSequence* c) { + out << "DeclarationSequence[" << endl; + for(CommandSequence::const_iterator i = c->begin(); + i != c->end(); + ++i) { + out << *i << endl; + } + out << "]"; +} + static void toStream(std::ostream& out, const CommandSequence* c) { out << "CommandSequence[" << endl; for(CommandSequence::const_iterator i = c->begin(); @@ -177,13 +191,8 @@ static void toStream(std::ostream& out, const CommandSequence* c) { out << "]"; } -static void toStream(std::ostream& out, const DeclarationCommand* c) { - const vector<string>& declaredSymbols = c->getDeclaredSymbols(); - out << "Declare(["; - copy( declaredSymbols.begin(), declaredSymbols.end() - 1, - ostream_iterator<string>(out, ", ") ); - out << declaredSymbols.back(); - out << "])"; +static void toStream(std::ostream& out, const DeclareFunctionCommand* c) { + out << "Declare(" << c->getSymbol() << "," << c->getType() << ")"; } static void toStream(std::ostream& out, const DefineFunctionCommand* c) { @@ -199,6 +208,22 @@ static void toStream(std::ostream& out, const DefineFunctionCommand* c) { out << "], << " << formula << " >> )"; } +static void toStream(std::ostream& out, const DeclareTypeCommand* c) { + out << "DeclareType(" << c->getSymbol() << "," << c->getArity() << "," + << c->getType() << ")"; +} + +static void toStream(std::ostream& out, const DefineTypeCommand* c) { + const vector<Type>& params = c->getParameters(); + out << "DefineType(" << c->getSymbol() << ",["; + if(params.size() > 0) { + copy( params.begin(), params.end() - 1, + ostream_iterator<Type>(out, ", ") ); + out << params.back(); + } + out << "]," << c->getType() << ")"; +} + static void toStream(std::ostream& out, const DefineNamedFunctionCommand* c) { out << "DefineNamedFunction( "; toStream(out, static_cast<const DefineFunctionCommand*>(c)); @@ -252,6 +277,10 @@ static void toStream(std::ostream& out, const DatatypeDeclarationCommand* c) { out << "])"; } +static void toStream(std::ostream& out, const CommentCommand* c) { + out << "CommentCommand([" << c->getComment() << "])"; +} + template <class T> static bool tryToStream(std::ostream& out, const Command* c) { if(typeid(*c) == typeid(T)) { diff --git a/src/printer/ast/ast_printer.h b/src/printer/ast/ast_printer.h index ddc3c50b8..69c39915b 100644 --- a/src/printer/ast/ast_printer.h +++ b/src/printer/ast/ast_printer.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/printer/cvc/cvc_printer.cpp b/src/printer/cvc/cvc_printer.cpp index 8e089a8a3..0f3d635bd 100644 --- a/src/printer/cvc/cvc_printer.cpp +++ b/src/printer/cvc/cvc_printer.cpp @@ -28,6 +28,7 @@ #include <typeinfo> #include <algorithm> #include <iterator> +#include <stack> using namespace std; @@ -172,6 +173,15 @@ void CvcPrinter::toStream(std::ostream& out, TNode n, return; } else if(n.getMetaKind() == kind::metakind::PARAMETERIZED) { switch(n.getKind()) { + case kind::SORT_TYPE: { + std::string name; + if(n.getAttribute(expr::VarNameAttr(), name)) { + out << name; + } else { + goto default_case; + } + break; + } case kind::BITVECTOR_EXTRACT: out << n[0] << n.getOperator().getConst<BitVectorExtract>(); break; @@ -192,6 +202,7 @@ void CvcPrinter::toStream(std::ostream& out, TNode n, break; default: + default_case: out << n.getOperator(); if(n.getNumChildren() > 0) { out << '('; @@ -231,9 +242,24 @@ void CvcPrinter::toStream(std::ostream& out, TNode n, case kind::SELECT: out << n[0] << '[' << n[1] << ']'; break; - case kind::STORE: - out << n[0] << " WITH [" << n[1] << "] = " << n[2]; + case kind::STORE: { + stack<TNode> stk; + stk.push(n); + while(stk.top()[0].getKind() == kind::STORE) { + stk.push(stk.top()[0]); + } + out << '('; + TNode x = stk.top(); + out << x[0] << " WITH [" << x[1] << "] := " << x[2]; + stk.pop(); + while(!stk.empty()) { + x = stk.top(); + out << ", [" << x[1] << "] := " << x[2]; + stk.pop(); + } + out << ')'; break; + } case kind::TUPLE_TYPE: out << '['; @@ -301,7 +327,9 @@ void CvcPrinter::toStream(std::ostream& out, TNode n, // infix binary operator out << '(' << n[0] << ' ' << n.getOperator() << ' ' << n[1] << ')'; } else if(n.getKind() == kind::AND || - n.getKind() == kind::OR) { + n.getKind() == kind::OR || + n.getKind() == kind::PLUS || + n.getKind() == kind::MULT) { // infix N-ary operator TNode::iterator i = n.begin(); out << '(' << *i++; @@ -347,9 +375,12 @@ void CvcPrinter::toStream(std::ostream& out, const Command* c, tryToStream<CheckSatCommand>(out, c) || tryToStream<QueryCommand>(out, c) || tryToStream<QuitCommand>(out, c) || + tryToStream<DeclarationSequence>(out, c) || tryToStream<CommandSequence>(out, c) || - tryToStream<DeclarationCommand>(out, c) || + tryToStream<DeclareFunctionCommand>(out, c) || tryToStream<DefineFunctionCommand>(out, c) || + tryToStream<DeclareTypeCommand>(out, c) || + tryToStream<DefineTypeCommand>(out, c) || tryToStream<DefineNamedFunctionCommand>(out, c) || tryToStream<SimplifyCommand>(out, c) || tryToStream<GetValueCommand>(out, c) || @@ -361,7 +392,8 @@ void CvcPrinter::toStream(std::ostream& out, const Command* c, tryToStream<GetInfoCommand>(out, c) || tryToStream<SetOptionCommand>(out, c) || tryToStream<GetOptionCommand>(out, c) || - tryToStream<DatatypeDeclarationCommand>(out, c)) { + tryToStream<DatatypeDeclarationCommand>(out, c) || + tryToStream<CommentCommand>(out, c)) { return; } @@ -385,16 +417,22 @@ static void toStream(std::ostream& out, const CheckSatCommand* c) { BoolExpr e = c->getExpr(); if(!e.isNull()) { out << "CHECKSAT " << e << ";"; + } else { + out << "CHECKSAT;"; } - out << "CHECKSAT;"; } static void toStream(std::ostream& out, const QueryCommand* c) { - out << "QUERY " << c->getExpr() << ";"; + BoolExpr e = c->getExpr(); + if(!e.isNull()) { + out << "QUERY " << e << ";"; + } else { + out << "QUERY TRUE;"; + } } static void toStream(std::ostream& out, const QuitCommand* c) { - Unhandled("quit command"); + //out << "EXIT;"; } static void toStream(std::ostream& out, const CommandSequence* c) { @@ -405,14 +443,22 @@ static void toStream(std::ostream& out, const CommandSequence* c) { } } -static void toStream(std::ostream& out, const DeclarationCommand* c) { - const vector<string>& declaredSymbols = c->getDeclaredSymbols(); - Type declaredType = c->getDeclaredType(); - Assert(declaredSymbols.size() > 0); - copy( declaredSymbols.begin(), declaredSymbols.end() - 1, - ostream_iterator<string>(out, ", ") ); - out << declaredSymbols.back(); - out << " : " << declaredType << ";"; +static void toStream(std::ostream& out, const DeclarationSequence* c) { + DeclarationSequence::const_iterator i = c->begin(); + for(;;) { + DeclarationDefinitionCommand* dd = + static_cast<DeclarationDefinitionCommand*>(*i++); + if(i != c->end()) { + out << dd->getSymbol() << ", "; + } else { + out << *dd; + break; + } + } +} + +static void toStream(std::ostream& out, const DeclareFunctionCommand* c) { + out << c->getSymbol() << " : " << c->getType() << ";"; } static void toStream(std::ostream& out, const DefineFunctionCommand* c) { @@ -430,6 +476,22 @@ static void toStream(std::ostream& out, const DefineFunctionCommand* c) { out << "): " << formula << ";"; } +static void toStream(std::ostream& out, const DeclareTypeCommand* c) { + if(c->getArity() > 0) { + Unhandled("Don't know how to print parameterized type declaration " + "in CVC language:\n%s", c->toString().c_str()); + } + out << c->getSymbol() << " : TYPE;"; +} + +static void toStream(std::ostream& out, const DefineTypeCommand* c) { + if(c->getParameters().size() > 0) { + Unhandled("Don't know how to print parameterized type definition " + "in CVC language:\n%s", c->toString().c_str()); + } + out << c->getSymbol() << " : TYPE = " << c->getType() << ";"; +} + static void toStream(std::ostream& out, const DefineNamedFunctionCommand* c) { toStream(out, static_cast<const DefineFunctionCommand*>(c)); } @@ -484,6 +546,10 @@ static void toStream(std::ostream& out, const DatatypeDeclarationCommand* c) { } } +static void toStream(std::ostream& out, const CommentCommand* c) { + out << "% " << c->getComment(); +} + template <class T> static bool tryToStream(std::ostream& out, const Command* c) { if(typeid(*c) == typeid(T)) { diff --git a/src/printer/cvc/cvc_printer.h b/src/printer/cvc/cvc_printer.h index d794c82e8..fd478dbe5 100644 --- a/src/printer/cvc/cvc_printer.h +++ b/src/printer/cvc/cvc_printer.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/printer/printer.cpp b/src/printer/printer.cpp index ca5935bec..6714d355e 100644 --- a/src/printer/printer.cpp +++ b/src/printer/printer.cpp @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/printer/printer.h b/src/printer/printer.h index eae2fc48f..7294ab231 100644 --- a/src/printer/printer.h +++ b/src/printer/printer.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/printer/smt/smt_printer.cpp b/src/printer/smt/smt_printer.cpp index de22a04c1..ed7f8febf 100644 --- a/src/printer/smt/smt_printer.cpp +++ b/src/printer/smt/smt_printer.cpp @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/printer/smt/smt_printer.h b/src/printer/smt/smt_printer.h index 058a6b18c..14d6c09e1 100644 --- a/src/printer/smt/smt_printer.h +++ b/src/printer/smt/smt_printer.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/printer/smt2/smt2_printer.cpp b/src/printer/smt2/smt2_printer.cpp index 5ce571904..5758b1101 100644 --- a/src/printer/smt2/smt2_printer.cpp +++ b/src/printer/smt2/smt2_printer.cpp @@ -23,6 +23,8 @@ #include <string> #include <typeinfo> +#include "util/boolean_simplification.h" + using namespace std; namespace CVC4 { @@ -64,6 +66,17 @@ void Smt2Printer::toStream(std::ostream& out, TNode n, // constant if(n.getMetaKind() == kind::metakind::CONSTANT) { switch(n.getKind()) { + case kind::TYPE_CONSTANT: + switch(n.getConst<TypeConstant>()) { + case BOOLEAN_TYPE: out << "Boolean"; break; + case REAL_TYPE: out << "Real"; break; + case INTEGER_TYPE: out << "Int"; break; + default: + // fall back on whatever operator<< does on underlying type; we + // might luck out and be SMT-LIB v2 compliant + kind::metakind::NodeValueConstPrinter::toStream(out, n); + } + break; case kind::BITVECTOR_TYPE: out << "(_ BitVec " << n.getConst<BitVectorSize>().size << ")"; break; @@ -91,11 +104,20 @@ void Smt2Printer::toStream(std::ostream& out, TNode n, return; } + if(n.getKind() == kind::SORT_TYPE) { + std::string name; + if(n.getAttribute(expr::VarNameAttr(), name)) { + out << name; + return; + } + } + bool stillNeedToPrintParams = true; // operator out << '('; switch(n.getKind()) { // builtin theory + case kind::APPLY: break; case kind::EQUAL: out << "= "; break; case kind::DISTINCT: out << "distinct "; break; case kind::TUPLE: break; @@ -111,7 +133,6 @@ void Smt2Printer::toStream(std::ostream& out, TNode n, // uf theory case kind::APPLY_UF: break; - case kind::SORT_TYPE: break; // arith theory case kind::PLUS: out << "+ "; break; @@ -127,6 +148,7 @@ void Smt2Printer::toStream(std::ostream& out, TNode n, // arrays theory case kind::SELECT: out << "select "; break; case kind::STORE: out << "store "; break; + case kind::ARRAY_TYPE: out << "Array "; break; // bv theory case kind::BITVECTOR_CONCAT: out << "concat "; break; @@ -253,8 +275,10 @@ void Smt2Printer::toStream(std::ostream& out, const Command* c, tryToStream<QueryCommand>(out, c) || tryToStream<QuitCommand>(out, c) || tryToStream<CommandSequence>(out, c) || - tryToStream<DeclarationCommand>(out, c) || + tryToStream<DeclareFunctionCommand>(out, c) || tryToStream<DefineFunctionCommand>(out, c) || + tryToStream<DeclareTypeCommand>(out, c) || + tryToStream<DefineTypeCommand>(out, c) || tryToStream<DefineNamedFunctionCommand>(out, c) || tryToStream<SimplifyCommand>(out, c) || tryToStream<GetValueCommand>(out, c) || @@ -266,7 +290,8 @@ void Smt2Printer::toStream(std::ostream& out, const Command* c, tryToStream<GetInfoCommand>(out, c) || tryToStream<SetOptionCommand>(out, c) || tryToStream<GetOptionCommand>(out, c) || - tryToStream<DatatypeDeclarationCommand>(out, c)) { + tryToStream<DatatypeDeclarationCommand>(out, c) || + tryToStream<CommentCommand>(out, c)) { return; } @@ -289,13 +314,25 @@ static void toStream(std::ostream& out, const PopCommand* c) { static void toStream(std::ostream& out, const CheckSatCommand* c) { BoolExpr e = c->getExpr(); if(!e.isNull()) { - out << "(assert " << e << ")"; + out << PushCommand() << endl + << AssertCommand(e) << endl + << CheckSatCommand() << endl + << PopCommand() << endl; + } else { + out << "(check-sat)"; } - out << "(check-sat)"; } static void toStream(std::ostream& out, const QueryCommand* c) { - Unhandled("query command"); + BoolExpr e = c->getExpr(); + if(!e.isNull()) { + out << PushCommand() << endl + << AssertCommand(BooleanSimplification::negate(e)) << endl + << CheckSatCommand() << endl + << PopCommand() << endl; + } else { + out << "(check-sat)"; + } } static void toStream(std::ostream& out, const QuitCommand* c) { @@ -310,26 +347,21 @@ static void toStream(std::ostream& out, const CommandSequence* c) { } } -static void toStream(std::ostream& out, const DeclarationCommand* c) { - const vector<string>& declaredSymbols = c->getDeclaredSymbols(); - Type declaredType = c->getDeclaredType(); - for(vector<string>::const_iterator i = declaredSymbols.begin(); - i != declaredSymbols.end(); - ++i) { - if(declaredType.isFunction()) { - FunctionType ft = declaredType; - out << "(declare-fun " << *i << " ("; - const vector<Type> argTypes = ft.getArgTypes(); - if(argTypes.size() > 0) { - copy( argTypes.begin(), argTypes.end() - 1, - ostream_iterator<Type>(out, " ") ); - out << argTypes.back(); - } - out << ") " << ft.getRangeType() << ")"; - } else { - out << "(declare-fun " << *i << " () " << declaredType << ")"; +static void toStream(std::ostream& out, const DeclareFunctionCommand* c) { + Type type = c->getType(); + out << "(declare-fun " << c->getSymbol() << " ("; + if(type.isFunction()) { + FunctionType ft = type; + const vector<Type> argTypes = ft.getArgTypes(); + if(argTypes.size() > 0) { + copy( argTypes.begin(), argTypes.end() - 1, + ostream_iterator<Type>(out, " ") ); + out << argTypes.back(); } + type = ft.getRangeType(); } + + out << ") " << type << ")"; } static void toStream(std::ostream& out, const DefineFunctionCommand* c) { @@ -337,14 +369,34 @@ static void toStream(std::ostream& out, const DefineFunctionCommand* c) { const vector<Expr>& formals = c->getFormals(); Expr formula = c->getFormula(); out << "(define-fun " << func << " ("; - for(vector<Expr>::const_iterator i = formals.begin(); - i != formals.end(); - ++i) { + vector<Expr>::const_iterator i = formals.begin(); + for(;;) { out << "(" << (*i) << " " << (*i).getType() << ")"; + ++i; + if(i != formals.end()) { + out << " "; + } else { + break; + } } out << ") " << FunctionType(func.getType()).getRangeType() << " " << formula << ")"; } +static void toStream(std::ostream& out, const DeclareTypeCommand* c) { + out << "(declare-sort " << c->getSymbol() << " " << c->getArity() << ")"; +} + +static void toStream(std::ostream& out, const DefineTypeCommand* c) { + const vector<Type>& params = c->getParameters(); + out << "(define-sort " << c->getSymbol() << " ("; + if(params.size() > 0) { + copy( params.begin(), params.end() - 1, + ostream_iterator<Type>(out, " ") ); + out << params.back(); + } + out << ") " << c->getType() << ")"; +} + static void toStream(std::ostream& out, const DefineNamedFunctionCommand* c) { out << "DefineNamedFunction( "; toStream(out, static_cast<const DefineFunctionCommand*>(c)); @@ -406,6 +458,10 @@ static void toStream(std::ostream& out, const DatatypeDeclarationCommand* c) { Unhandled("datatype declaration command"); } +static void toStream(std::ostream& out, const CommentCommand* c) { + out << "(set-info :notes \"" << c->getComment() << "\")"; +} + template <class T> static bool tryToStream(std::ostream& out, const Command* c) { if(typeid(*c) == typeid(T)) { diff --git a/src/printer/smt2/smt2_printer.h b/src/printer/smt2/smt2_printer.h index 4bae8a2e1..2086370ae 100644 --- a/src/printer/smt2/smt2_printer.h +++ b/src/printer/smt2/smt2_printer.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/prop/cnf_stream.cpp b/src/prop/cnf_stream.cpp index 9797e4c67..5b8e4c3f3 100644 --- a/src/prop/cnf_stream.cpp +++ b/src/prop/cnf_stream.cpp @@ -2,8 +2,8 @@ /*! \file cnf_stream.cpp ** \verbatim ** Original author: taking - ** Major contributors: dejan - ** Minor contributors (to current version): cconway, mdeters + ** Major contributors: mdeters, dejan + ** Minor contributors (to current version): cconway ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -18,13 +18,15 @@ ** of given an equisatisfiable stream of assertions to PropEngine. **/ -#include "sat.h" +#include "prop/sat.h" #include "prop/cnf_stream.h" #include "prop/prop_engine.h" #include "theory/theory_engine.h" #include "expr/node.h" #include "util/Assert.h" #include "util/output.h" +#include "expr/command.h" +#include "expr/expr.h" #include <queue> @@ -57,6 +59,21 @@ TseitinCnfStream::TseitinCnfStream(SatInputInterface* satSolver, theory::Registr void CnfStream::assertClause(TNode node, SatClause& c) { Debug("cnf") << "Inserting into stream " << c << endl; + if(Dump.isOn("clauses")) { + if(Message.isOn()) { + if(c.size() == 1) { + Message() << AssertCommand(BoolExpr(getNode(c[0]).toExpr())) << endl; + } else { + Assert(c.size() > 1); + NodeBuilder<> b(kind::OR); + for(int i = 0; i < c.size(); ++i) { + b << getNode(c[i]); + } + Node n = b; + Message() << AssertCommand(BoolExpr(n.toExpr())) << endl; + } + } + } d_satSolver->addClause(c, d_removable); } @@ -114,7 +131,8 @@ SatLiteral CnfStream::newLiteral(TNode node, bool theoryLiteral) { // If it's a theory literal, need to store it for back queries if ( theoryLiteral || - ( CVC4_USE_REPLAY && Options::current()->replayLog != NULL ) ) { + ( CVC4_USE_REPLAY && Options::current()->replayLog != NULL ) || + Dump.isOn("clauses") ) { d_nodeCache[lit] = node; d_nodeCache[~lit] = node.notNode(); } @@ -580,6 +598,15 @@ void TseitinCnfStream::convertAndAssert(TNode node, bool removable, bool negated void TseitinCnfStream::convertAndAssert(TNode node, bool negated) { Debug("cnf") << "convertAndAssert(" << node << ", negated = " << (negated ? "true" : "false") << ")" << endl; + + if(hasLiteral(node)) { + Debug("cnf") << "==> fortunate literal detected!" << endl; + ++d_fortunateLiterals; + SatLiteral lit = getLiteral(node); + //d_satSolver->renewVar(lit); + assertClause(node, negated ? ~lit : lit); + } + switch(node.getKind()) { case AND: convertAndAssertAnd(node, negated); diff --git a/src/prop/cnf_stream.h b/src/prop/cnf_stream.h index fd0ab6291..ecb0fd2fb 100644 --- a/src/prop/cnf_stream.h +++ b/src/prop/cnf_stream.h @@ -3,7 +3,7 @@ ** \verbatim ** Original author: taking ** Major contributors: mdeters, dejan - ** Minor contributors (to current version): cconway + ** Minor contributors (to current version): barrett, cconway ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -77,6 +77,24 @@ protected: /** Top level nodes that we translated */ std::vector<TNode> d_translationTrail; + /** + * How many literals were already mapped at the top-level when we + * tried to convertAndAssert() something. This + * achieves early detection of units and leads to fewer + * clauses. It's motivated by the following pattern: + * + * ASSERT BIG FORMULA => x + * (and then later...) + * ASSERT BIG FORMULA + * + * With the first assert, BIG FORMULA is clausified, and a literal + * is assigned for the top level so that the final clause for the + * implication is "lit => x". But without "fortunate literal + * detection," when BIG FORMULA is later asserted, it is clausified + * separately, and "lit" is never asserted as a unit clause. + */ + KEEP_STATISTIC(IntStat, d_fortunateLiterals, "prop::CnfStream::fortunateLiterals", 0); + /** Remove nots from the node */ TNode stripNot(TNode node) { while (node.getKind() == kind::NOT) { diff --git a/src/prop/minisat/Makefile.am b/src/prop/minisat/Makefile.am index 3e844ef79..6e003c248 100644 --- a/src/prop/minisat/Makefile.am +++ b/src/prop/minisat/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = \ -D__BUILDING_CVC4LIB \ -D __STDC_LIMIT_MACROS \ - -D __STDC_FORMAT_MACROS \ + -D __STDC_FORMAT_MACROS \ -I@srcdir@/ -I@srcdir@/../.. -I@builddir@/../.. -I@srcdir@/../../include AM_CXXFLAGS = -Wall -Wno-parentheses -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) diff --git a/src/prop/minisat/core/Solver.cc b/src/prop/minisat/core/Solver.cc index 711379519..e160e1ef5 100644 --- a/src/prop/minisat/core/Solver.cc +++ b/src/prop/minisat/core/Solver.cc @@ -20,9 +20,14 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include <math.h> +#include <iostream> + #include "mtl/Sort.h" #include "core/Solver.h" + #include "prop/sat.h" +#include "util/output.h" +#include "expr/command.h" using namespace Minisat; using namespace CVC4; @@ -287,10 +292,16 @@ bool Solver::satisfied(const Clause& c) const { // Revert to the state at given level (keeping all assignment at 'level' but not beyond). // void Solver::cancelUntil(int level) { + Debug("minisat") << "minisat::cancelUntil(" << level << std::endl; + if (decisionLevel() > level){ // Pop the SMT context - for (int l = trail_lim.size() - level; l > 0; --l) + for (int l = trail_lim.size() - level; l > 0; --l) { context->pop(); + if(Dump.isOn("state")) { + Dump("state") << PopCommand() << std::endl; + } + } for (int c = trail.size()-1; c >= trail_lim[level]; c--){ Var x = var(trail[c]); assigns [x] = l_Undef; diff --git a/src/prop/minisat/core/Solver.h b/src/prop/minisat/core/Solver.h index 4c6e98a2e..8e5e05b1c 100644 --- a/src/prop/minisat/core/Solver.h +++ b/src/prop/minisat/core/Solver.h @@ -23,6 +23,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "cvc4_private.h" +#include <iostream> + #include "mtl/Vec.h" #include "mtl/Heap.h" #include "mtl/Alg.h" @@ -31,12 +33,14 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "context/context.h" #include "theory/theory.h" +#include "util/output.h" +#include "expr/command.h" namespace CVC4 { namespace prop { class SatSolver; -} -} +}/* CVC4::prop namespace */ +}/* CVC4 namespace */ namespace Minisat { @@ -441,7 +445,7 @@ inline bool Solver::addClause (Lit p, bool removable) inline bool Solver::addClause (Lit p, Lit q, bool removable) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp, removable); } inline bool Solver::addClause (Lit p, Lit q, Lit r, bool removable) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp, removable); } inline bool Solver::locked (const Clause& c) const { return value(c[0]) == l_True && isPropagatedBy(var(c[0]), c); } -inline void Solver::newDecisionLevel() { trail_lim.push(trail.size()); context->push(); } +inline void Solver::newDecisionLevel() { trail_lim.push(trail.size()); context->push(); if(Dump.isOn("state")) { Dump("state") << CVC4::PushCommand() << std::endl; } } inline int Solver::decisionLevel () const { return trail_lim.size(); } inline uint32_t Solver::abstractLevel (Var x) const { return 1 << (level(x) & 31); } @@ -495,6 +499,6 @@ inline void Solver::toDimacs (const char* file, Lit p, Lit q, Lit r){ ve //================================================================================================= -} +}/* Minisat namespace */ #endif diff --git a/src/prop/prop_engine.cpp b/src/prop/prop_engine.cpp index 046e4ef7e..c8e4083b1 100644 --- a/src/prop/prop_engine.cpp +++ b/src/prop/prop_engine.cpp @@ -2,8 +2,8 @@ /*! \file prop_engine.cpp ** \verbatim ** Original author: mdeters - ** Major contributors: taking, cconway, dejan - ** Minor contributors (to current version): none + ** Major contributors: dejan + ** Minor contributors (to current version): barrett, taking, cconway ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -90,14 +90,10 @@ void PropEngine::assertLemma(TNode node, bool negated, bool removable) { //Assert(d_inCheckSat, "Sat solver should be in solve()!"); Debug("prop::lemmas") << "assertLemma(" << node << ")" << endl; - if(Options::current()->preprocessOnly) { - if(Message.isOn()) { - // If "preprocess only" mode is in effect, the lemmas we get - // here are due to theory reasoning during preprocessing. So - // push the lemma to the Message() stream. - expr::ExprSetDepth::Scope sdScope(Message.getStream(), -1); - Message() << AssertCommand(BoolExpr(node.toExpr())) << endl; - } + if(!d_inCheckSat && Dump.isOn("learned")) { + Dump("learned") << AssertCommand(BoolExpr(node.toExpr())) << endl; + } else if(Dump.isOn("lemmas")) { + Dump("lemmas") << AssertCommand(BoolExpr(node.toExpr())) << endl; } //TODO This comment is now false diff --git a/src/prop/prop_engine.h b/src/prop/prop_engine.h index 599439987..af7067130 100644 --- a/src/prop/prop_engine.h +++ b/src/prop/prop_engine.h @@ -3,18 +3,18 @@ ** \verbatim ** Original author: mdeters ** Major contributors: taking, dejan - ** Minor contributors (to current version): cconway + ** Minor contributors (to current version): cconway, barrett ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim ** - ** \brief The PropEngine (proposiitonal engine); main interface point - ** between CVC4's SMT infrastructure and the SAT solver. + ** \brief The PropEngine (propositional engine); main interface point + ** between CVC4's SMT infrastructure and the SAT solver ** - ** The PropEngine (proposiitonal engine); main interface point + ** The PropEngine (propositional engine); main interface point ** between CVC4's SMT infrastructure and the SAT solver. **/ @@ -118,6 +118,7 @@ public: * Return true if node has an associated SAT literal */ bool isSatLiteral(TNode node); + /** * Check if the node has a value and return it if yes. */ diff --git a/src/prop/sat.cpp b/src/prop/sat.cpp index a7eced6f2..8bda0fd1e 100644 --- a/src/prop/sat.cpp +++ b/src/prop/sat.cpp @@ -2,7 +2,7 @@ /*! \file sat.cpp ** \verbatim ** Original author: cconway - ** Major contributors: dejan, mdeters, taking + ** Major contributors: dejan, taking, mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/smt/bad_option_exception.h b/src/smt/bad_option_exception.h index 13e5d96d0..8fafb952e 100644 --- a/src/smt/bad_option_exception.h +++ b/src/smt/bad_option_exception.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/smt/modal_exception.h b/src/smt/modal_exception.h index c5c0f6ab2..de0565aa1 100644 --- a/src/smt/modal_exception.h +++ b/src/smt/modal_exception.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/smt/no_such_function_exception.h b/src/smt/no_such_function_exception.h index 0a5f2889c..615f6ab2b 100644 --- a/src/smt/no_such_function_exception.h +++ b/src/smt/no_such_function_exception.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp index dcfa43424..3f1111879 100644 --- a/src/smt/smt_engine.cpp +++ b/src/smt/smt_engine.cpp @@ -70,7 +70,7 @@ namespace smt { */ class DefinedFunction { Node d_func; - std::vector<Node> d_formals; + vector<Node> d_formals; Node d_formula; public: DefinedFunction() {} @@ -114,7 +114,7 @@ class SmtEnginePrivate { theory::SubstitutionMap d_topLevelSubstitutions; /** - * Runs the nonslausal solver and tries to solve all the assigned + * Runs the nonclausal solver and tries to solve all the assigned * theory literals. */ void nonClausalSimplify(); @@ -215,6 +215,9 @@ SmtEngine::SmtEngine(ExprManager* em) throw(AssertionException) : } void SmtEngine::shutdown() { + if(Dump.isOn("benchmark")) { + Dump("benchmark") << QuitCommand() << endl; + } d_propEngine->shutdown(); d_theoryEngine->shutdown(); } @@ -248,6 +251,9 @@ void SmtEngine::setLogic(const std::string& s) throw(ModalException) { if(d_logic != "") { throw ModalException("logic already set"); } + if(Dump.isOn("benchmark")) { + Dump("benchmark") << SetBenchmarkLogicCommand(s) << endl; + } d_logic = s; d_theoryEngine->setLogic(s); @@ -259,7 +265,10 @@ void SmtEngine::setLogic(const std::string& s) throw(ModalException) { void SmtEngine::setInfo(const std::string& key, const SExpr& value) throw(BadOptionException, ModalException) { - Debug("smt") << "SMT setInfo(" << key << ", " << value << ")" << endl; + Trace("smt") << "SMT setInfo(" << key << ", " << value << ")" << endl; + if(Dump.isOn("benchmark")) { + Dump("benchmark") << SetInfoCommand(key, value) << endl; + } if(key == ":name" || key == ":source" || key == ":category" || @@ -285,7 +294,7 @@ void SmtEngine::setInfo(const std::string& key, const SExpr& value) SExpr SmtEngine::getInfo(const std::string& key) const throw(BadOptionException) { - Debug("smt") << "SMT getInfo(" << key << ")" << endl; + Trace("smt") << "SMT getInfo(" << key << ")" << endl; if(key == ":all-statistics") { vector<SExpr> stats; for(StatisticsRegistry::const_iterator i = StatisticsRegistry::begin(); @@ -323,7 +332,10 @@ SExpr SmtEngine::getInfo(const std::string& key) const void SmtEngine::setOption(const std::string& key, const SExpr& value) throw(BadOptionException, ModalException) { - Debug("smt") << "SMT setOption(" << key << ", " << value << ")" << endl; + Trace("smt") << "SMT setOption(" << key << ", " << value << ")" << endl; + if(Dump.isOn("benchmark")) { + Dump("benchmark") << SetOptionCommand(key, value) << endl; + } if(key == ":print-success") { throw BadOptionException(); @@ -362,7 +374,10 @@ void SmtEngine::setOption(const std::string& key, const SExpr& value) SExpr SmtEngine::getOption(const std::string& key) const throw(BadOptionException) { - Debug("smt") << "SMT getOption(" << key << ")" << endl; + Trace("smt") << "SMT getOption(" << key << ")" << endl; + if(Dump.isOn("benchmark")) { + Dump("benchmark") << GetOptionCommand(key) << endl; + } if(key == ":print-success") { return SExpr("true"); } else if(key == ":expand-definitions") { @@ -393,9 +408,21 @@ SExpr SmtEngine::getOption(const std::string& key) const void SmtEngine::defineFunction(Expr func, const std::vector<Expr>& formals, Expr formula) { - Debug("smt") << "SMT defineFunction(" << func << ")" << endl; + Trace("smt") << "SMT defineFunction(" << func << ")" << endl; + /* + if(Dump.isOn("declarations")) { + stringstream ss; + ss << Expr::setlanguage(Expr::setlanguage::getLanguage(Dump("declarations"))) + << func; + Dump("declarations") << DefineFunctionCommand(ss.str(), func, formals, formula) + << endl; + } + */ NodeManagerScope nms(d_nodeManager); - Type formulaType = formula.getType(Options::current()->typeChecking);// type check body + + // type check body + Type formulaType = formula.getType(Options::current()->typeChecking); + Type funcType = func.getType(); Type rangeType = funcType.isFunction() ? FunctionType(funcType).getRangeType() : funcType; @@ -501,7 +528,7 @@ Node SmtEnginePrivate::expandDefinitions(TNode n, hash_map<TNode, Node, TNodeHas void SmtEnginePrivate::removeITEs() { - Debug("simplify") << "SmtEnginePrivate::removeITEs()" << std::endl; + Trace("simplify") << "SmtEnginePrivate::removeITEs()" << endl; // Remove all of the ITE occurances and normalize RemoveITE::run(d_assertionsToCheck); @@ -514,7 +541,7 @@ void SmtEnginePrivate::staticLearning() { TimerStat::CodeTimer staticLearningTimer(d_smt.d_staticLearningTime); - Debug("simplify") << "SmtEnginePrivate::staticLearning()" << std::endl; + Trace("simplify") << "SmtEnginePrivate::staticLearning()" << endl; for (unsigned i = 0; i < d_assertionsToCheck.size(); ++ i) { @@ -533,28 +560,32 @@ void SmtEnginePrivate::nonClausalSimplify() { TimerStat::CodeTimer nonclauselTimer(d_smt.d_nonclausalSimplificationTime); - Debug("simplify") << "SmtEnginePrivate::nonClausalSimplify()" << std::endl; + Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify()" << endl; // Apply the substitutions we already have, and normalize - Debug("simplify") << "SmtEnginePrivate::nonClausalSimplify(): applying substitutions" << std::endl; + Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify(): " + << "applying substitutions" << endl; for (unsigned i = 0; i < d_assertionsToPreprocess.size(); ++ i) { - d_assertionsToPreprocess[i] = theory::Rewriter::rewrite(d_topLevelSubstitutions.apply(d_assertionsToPreprocess[i])); + d_assertionsToPreprocess[i] = + theory::Rewriter::rewrite(d_topLevelSubstitutions.apply(d_assertionsToPreprocess[i])); } d_nonClausalLearnedLiterals.clear(); - bool goNuts = Options::current()->simplificationStyle == Options::AGGRESSIVE_SIMPLIFICATION_STYLE; - booleans::CircuitPropagator propagator(d_nonClausalLearnedLiterals, true, true, goNuts); + booleans::CircuitPropagator propagator(d_nonClausalLearnedLiterals, true, true); // Assert all the assertions to the propagator - Debug("simplify") << "SmtEnginePrivate::nonClausalSimplify(): asserting to propagator" << std::endl; + Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify(): " + << "asserting to propagator" << endl; for (unsigned i = 0; i < d_assertionsToPreprocess.size(); ++ i) { propagator.assert(d_assertionsToPreprocess[i]); } - Debug("simplify") << "SmtEnginePrivate::nonClausalSimplify(): propagating" << std::endl; + Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify(): " + << "propagating" << endl; if (propagator.propagate()) { // If in conflict, just return false - Debug("simplify") << "SmtEnginePrivate::nonClausalSimplify(): conflict in non-clausal propagation" << std::endl; + Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify(): " + << "conflict in non-clausal propagation" << endl; d_assertionsToCheck.push_back(NodeManager::currentNM()->mkConst<bool>(false)); return; } else { @@ -562,7 +593,8 @@ void SmtEnginePrivate::nonClausalSimplify() { unsigned j = 0; for(unsigned i = 0, i_end = d_nonClausalLearnedLiterals.size(); i < i_end; ++ i) { // Simplify the literal we learned wrt previous substitutions - Node learnedLiteral = theory::Rewriter::rewrite(d_topLevelSubstitutions.apply(d_nonClausalLearnedLiterals[i])); + Node learnedLiteral = + theory::Rewriter::rewrite(d_topLevelSubstitutions.apply(d_nonClausalLearnedLiterals[i])); // It might just simplify to a constant if (learnedLiteral.isConst()) { if (learnedLiteral.getConst<bool>()) { @@ -570,23 +602,30 @@ void SmtEnginePrivate::nonClausalSimplify() { continue; } else { // If the learned literal simplifies to false, we're in conflict - Debug("simplify") << "SmtEnginePrivate::nonClausalSimplify(): conflict with " << d_nonClausalLearnedLiterals[i] << std::endl; + Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify(): " + << "conflict with " + << d_nonClausalLearnedLiterals[i] << endl; d_assertionsToCheck.push_back(NodeManager::currentNM()->mkConst<bool>(false)); return; } } // Solve it with the corresponding theory - Debug("simplify") << "SmtEnginePrivate::nonClausalSimplify(): solving " << learnedLiteral << std::endl; - Theory::SolveStatus solveStatus = d_smt.d_theoryEngine->solve(learnedLiteral, d_topLevelSubstitutions); + Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify(): " + << "solving " << learnedLiteral << endl; + Theory::SolveStatus solveStatus = + d_smt.d_theoryEngine->solve(learnedLiteral, d_topLevelSubstitutions); switch (solveStatus) { case Theory::SOLVE_STATUS_CONFLICT: // If in conflict, we return false - Debug("simplify") << "SmtEnginePrivate::nonClausalSimplify(): conflict while solving " << learnedLiteral << std::endl; + Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify(): " + << "conflict while solving " + << learnedLiteral << endl; d_assertionsToCheck.push_back(NodeManager::currentNM()->mkConst<bool>(false)); return; case Theory::SOLVE_STATUS_SOLVED: // The literal should rewrite to true - Debug("simplify") << "SmtEnginePrivate::nonClausalSimplify(): solved " << learnedLiteral << std::endl; + Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify(): " + << "solved " << learnedLiteral << endl; Assert(theory::Rewriter::rewrite(d_topLevelSubstitutions.apply(learnedLiteral)).isConst()); break; default: @@ -601,38 +640,53 @@ void SmtEnginePrivate::nonClausalSimplify() { for (unsigned i = 0; i < d_nonClausalLearnedLiterals.size(); ++ i) { d_assertionsToCheck.push_back(theory::Rewriter::rewrite(d_topLevelSubstitutions.apply(d_nonClausalLearnedLiterals[i]))); - Debug("simplify") << "SmtEnginePrivate::nonClausalSimplify(): non-clausal learned : " << d_assertionsToCheck.back() << std::endl; + Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify(): " + << "non-clausal learned : " + << d_assertionsToCheck.back() << endl; } d_nonClausalLearnedLiterals.clear(); for (unsigned i = 0; i < d_assertionsToPreprocess.size(); ++ i) { d_assertionsToCheck.push_back(theory::Rewriter::rewrite(d_topLevelSubstitutions.apply(d_assertionsToPreprocess[i]))); - Debug("simplify") << "SmtEnginePrivate::nonClausalSimplify(): non-clausal preprocessed: " << d_assertionsToCheck.back() << std::endl; + Trace("simplify") << "SmtEnginePrivate::nonClausalSimplify(): " + << "non-clausal preprocessed: " + << d_assertionsToCheck.back() << endl; } d_assertionsToPreprocess.clear(); } -void SmtEnginePrivate::simplifyAssertions() throw(NoSuchFunctionException, AssertionException) { +void SmtEnginePrivate::simplifyAssertions() + throw(NoSuchFunctionException, AssertionException) { try { - Debug("simplify") << "SmtEnginePrivate::simplify()" << std::endl; + Trace("simplify") << "SmtEnginePrivate::simplify()" << endl; if(!Options::current()->lazyDefinitionExpansion) { - Debug("simplify") << "SmtEnginePrivate::simplify(): expanding definitions" << std::endl; + Trace("simplify") << "SmtEnginePrivate::simplify(): expanding definitions" << endl; TimerStat::CodeTimer codeTimer(d_smt.d_definitionExpansionTime); hash_map<TNode, Node, TNodeHashFunction> cache; for (unsigned i = 0; i < d_assertionsToPreprocess.size(); ++ i) { - d_assertionsToPreprocess[i] = expandDefinitions(d_assertionsToPreprocess[i], cache); + d_assertionsToPreprocess[i] = + expandDefinitions(d_assertionsToPreprocess[i], cache); } } - // Perform the non-clausal simplification - Debug("simplify") << "SmtEnginePrivate::simplify(): performing non-clausal simplification" << std::endl; - nonClausalSimplify(); + if(Options::current()->simplificationMode != Options::SIMPLIFICATION_MODE_NONE) { + // Perform non-clausal simplification + Trace("simplify") << "SmtEnginePrivate::simplify(): " + << "performing non-clausal simplification" << endl; + nonClausalSimplify(); + } else { + Assert(d_assertionsToCheck.empty()); + d_assertionsToCheck.swap(d_assertionsToPreprocess); + } - // Perform static learning - Debug("simplify") << "SmtEnginePrivate::simplify(): performing static learning" << std::endl; - staticLearning(); + if(Options::current()->doStaticLearning) { + // Perform static learning + Trace("simplify") << "SmtEnginePrivate::simplify(): " + << "performing static learning" << endl; + staticLearning(); + } // Remove ITEs removeITEs(); @@ -652,38 +706,34 @@ void SmtEnginePrivate::simplifyAssertions() throw(NoSuchFunctionException, Asser } Result SmtEngine::check() { - Debug("smt") << "SmtEngine::check()" << endl; + Trace("smt") << "SmtEngine::check()" << endl; // make sure the prop layer has all assertions - Debug("smt") << "SmtEngine::check(): processing assertion" << endl; + Trace("smt") << "SmtEngine::check(): processing assertion" << endl; d_private->processAssertions(); - Debug("smt") << "SmtEngine::check(): running check" << endl; + Trace("smt") << "SmtEngine::check(): running check" << endl; return d_propEngine->checkSat(); } Result SmtEngine::quickCheck() { - Debug("smt") << "SMT quickCheck()" << endl; + Trace("smt") << "SMT quickCheck()" << endl; return Result(Result::VALIDITY_UNKNOWN, Result::REQUIRES_FULL_CHECK); } void SmtEnginePrivate::processAssertions() { - Debug("smt") << "SmtEnginePrivate::processAssertions()" << endl; + Trace("smt") << "SmtEnginePrivate::processAssertions()" << endl; // Simplify the assertions simplifyAssertions(); - if(Options::current()->preprocessOnly) { - if(Message.isOn()) { - // Push the formula to the Message() stream - for (unsigned i = 0; i < d_assertionsToCheck.size(); ++ i) { - expr::ExprSetDepth::Scope sdScope(Message.getStream(), -1); - Message() << AssertCommand(BoolExpr(d_assertionsToCheck[i].toExpr())) << endl; - } + if(Dump.isOn("assertions")) { + // Push the simplified assertions to the dump output stream + for (unsigned i = 0; i < d_assertionsToCheck.size(); ++ i) { + Dump("assertions") + << AssertCommand(BoolExpr(d_assertionsToCheck[i].toExpr())) << endl; } - // We still call into SAT below so that we can output theory - // contributions that come from presolve(). } // Push the formula to SAT @@ -693,9 +743,10 @@ void SmtEnginePrivate::processAssertions() { d_assertionsToCheck.clear(); } -void SmtEnginePrivate::addFormula(TNode n) throw(NoSuchFunctionException, AssertionException) { +void SmtEnginePrivate::addFormula(TNode n) + throw(NoSuchFunctionException, AssertionException) { - Debug("smt") << "SmtEnginePrivate::addFormula(" << n << ")" << endl; + Trace("smt") << "SmtEnginePrivate::addFormula(" << n << ")" << endl; // Add the normalized formula to the queue d_assertionsToPreprocess.push_back(theory::Rewriter::rewrite(n)); @@ -721,32 +772,44 @@ void SmtEngine::ensureBoolean(const BoolExpr& e) { Result SmtEngine::checkSat(const BoolExpr& e) { - Assert(e.getExprManager() == d_exprManager); + Assert(e.isNull() || e.getExprManager() == d_exprManager); NodeManagerScope nms(d_nodeManager); - Debug("smt") << "SmtEngine::checkSat(" << e << ")" << endl; + Trace("smt") << "SmtEngine::checkSat(" << e << ")" << endl; if(d_queryMade && !Options::current()->incrementalSolving) { - throw ModalException("Cannot make multiple queries unless incremental solving is enabled (try --incremental)"); + throw ModalException("Cannot make multiple queries unless " + "incremental solving is enabled " + "(try --incremental)"); } - // Enuser that the expression is Boolean - ensureBoolean(e); + // Ensure that the expression is type-checked at this point, and Boolean + if(!e.isNull()) { + ensureBoolean(e); + } // Push the context internalPush(); - // Add the + // Note that a query has been made d_queryMade = true; // Add the formula - d_problemExtended = true; - d_private->addFormula(e.getNode()); + if(!e.isNull()) { + d_problemExtended = true; + d_private->addFormula(e.getNode()); + } // Run the check Result r = check().asSatisfiabilityResult(); + // Dump the query if requested + if(Dump.isOn("benchmark")) { + // the expr already got dumped out if assertion-dumping is on + Dump("benchmark") << CheckSatCommand() << endl; + } + // Pop the context internalPop(); @@ -755,36 +818,65 @@ Result SmtEngine::checkSat(const BoolExpr& e) { d_problemExtended = false; - Debug("smt") << "SmtEngine::checkSat(" << e << ") => " << r << endl; + Trace("smt") << "SmtEngine::checkSat(" << e << ") => " << r << endl; return r; } Result SmtEngine::query(const BoolExpr& e) { + + Assert(!e.isNull()); Assert(e.getExprManager() == d_exprManager); + NodeManagerScope nms(d_nodeManager); - Debug("smt") << "SMT query(" << e << ")" << endl; + + Trace("smt") << "SMT query(" << e << ")" << endl; + if(d_queryMade && !Options::current()->incrementalSolving) { throw ModalException("Cannot make multiple queries unless " "incremental solving is enabled " "(try --incremental)"); } - d_queryMade = true; - ensureBoolean(e);// ensure expr is type-checked at this point + + // Ensure that the expression is type-checked at this point, and Boolean + ensureBoolean(e); + + // Push the context internalPush(); + + // Note that a query has been made + d_queryMade = true; + + // Add the formula + d_problemExtended = true; d_private->addFormula(e.getNode().notNode()); + + // Run the check Result r = check().asValidityResult(); + + // Dump the query if requested + if(Dump.isOn("benchmark")) { + // the expr already got dumped out if assertion-dumping is on + Dump("benchmark") << CheckSatCommand() << endl; + } + + // Pop the context internalPop(); + + // Remember the status d_status = r; + d_problemExtended = false; - Debug("smt") << "SMT query(" << e << ") ==> " << r << endl; + + Trace("smt") << "SMT query(" << e << ") ==> " << r << endl; + return r; } Result SmtEngine::assertFormula(const BoolExpr& e) { Assert(e.getExprManager() == d_exprManager); NodeManagerScope nms(d_nodeManager); - Debug("smt") << "SmtEngine::assertFormula(" << e << ")" << endl; + Trace("smt") << "SmtEngine::assertFormula(" << e << ")" << endl; ensureBoolean(e); if(d_assertionList != NULL) { d_assertionList->push_back(e); @@ -799,7 +891,10 @@ Expr SmtEngine::simplify(const Expr& e) { if( Options::current()->typeChecking ) { e.getType(true);// ensure expr is type-checked at this point } - Debug("smt") << "SMT simplify(" << e << ")" << endl; + Trace("smt") << "SMT simplify(" << e << ")" << endl; + if(Dump.isOn("benchmark")) { + Dump("benchmark") << SimplifyCommand(e) << endl; + } return d_private->applySubstitutions(e).toExpr(); } @@ -807,8 +902,14 @@ Expr SmtEngine::getValue(const Expr& e) throw(ModalException, AssertionException) { Assert(e.getExprManager() == d_exprManager); NodeManagerScope nms(d_nodeManager); - Type type = e.getType(Options::current()->typeChecking);// ensure expr is type-checked at this point - Debug("smt") << "SMT getValue(" << e << ")" << endl; + + // ensure expr is type-checked at this point + Type type = e.getType(Options::current()->typeChecking); + + Trace("smt") << "SMT getValue(" << e << ")" << endl; + if(Dump.isOn("benchmark")) { + Dump("benchmark") << GetValueCommand(e) << endl; + } if(!Options::current()->produceModels) { const char* msg = "Cannot get value when produce-models options is off."; @@ -831,7 +932,7 @@ Expr SmtEngine::getValue(const Expr& e) // Normalize for the theories Node n = theory::Rewriter::rewrite(e.getNode()); - Debug("smt") << "--- getting value of " << n << endl; + Trace("smt") << "--- getting value of " << n << endl; Node resultNode = d_theoryEngine->getValue(n); // type-check the result we got @@ -867,7 +968,10 @@ bool SmtEngine::addToAssignment(const Expr& e) throw(AssertionException) { } SExpr SmtEngine::getAssignment() throw(ModalException, AssertionException) { - Debug("smt") << "SMT getAssignment()" << endl; + Trace("smt") << "SMT getAssignment()" << endl; + if(Dump.isOn("benchmark")) { + Dump("benchmark") << GetAssignmentCommand() << endl; + } if(!Options::current()->produceAssignments) { const char* msg = "Cannot get the current assignment when " @@ -898,7 +1002,7 @@ SExpr SmtEngine::getAssignment() throw(ModalException, AssertionException) { // Normalize Node n = theory::Rewriter::rewrite(*i); - Debug("smt") << "--- getting value of " << n << endl; + Trace("smt") << "--- getting value of " << n << endl; Node resultNode = d_theoryEngine->getValue(n); // type-check the result we got @@ -920,8 +1024,11 @@ SExpr SmtEngine::getAssignment() throw(ModalException, AssertionException) { vector<Expr> SmtEngine::getAssertions() throw(ModalException, AssertionException) { + if(Dump.isOn("benchmark")) { + Dump("benchmark") << GetAssertionsCommand() << endl; + } NodeManagerScope nms(d_nodeManager); - Debug("smt") << "SMT getAssertions()" << endl; + Trace("smt") << "SMT getAssertions()" << endl; if(!Options::current()->interactive) { const char* msg = "Cannot query the current assertion list when not in interactive mode."; @@ -931,21 +1038,33 @@ vector<Expr> SmtEngine::getAssertions() return vector<Expr>(d_assertionList->begin(), d_assertionList->end()); } +size_t SmtEngine::getStackLevel() const { + NodeManagerScope nms(d_nodeManager); + Trace("smt") << "SMT getStackLevel()" << endl; + return d_context->getLevel(); +} + void SmtEngine::push() { NodeManagerScope nms(d_nodeManager); - Debug("smt") << "SMT push()" << endl; + Trace("smt") << "SMT push()" << endl; + if(Dump.isOn("benchmark")) { + Dump("benchmark") << PushCommand() << endl; + } if(!Options::current()->incrementalSolving) { throw ModalException("Cannot push when not solving incrementally (use --incremental)"); } d_userLevels.push_back(d_userContext->getLevel()); internalPush(); - Debug("userpushpop") << "SmtEngine: pushed to level " + Trace("userpushpop") << "SmtEngine: pushed to level " << d_userContext->getLevel() << endl; } void SmtEngine::pop() { NodeManagerScope nms(d_nodeManager); - Debug("smt") << "SMT pop()" << endl; + Trace("smt") << "SMT pop()" << endl; + if(Dump.isOn("benchmark")) { + Dump("benchmark") << PopCommand() << endl; + } if(!Options::current()->incrementalSolving) { throw ModalException("Cannot pop when not solving incrementally (use --incremental)"); } @@ -955,21 +1074,23 @@ void SmtEngine::pop() { } d_userLevels.pop_back(); - Debug("userpushpop") << "SmtEngine: popped to level " + Trace("userpushpop") << "SmtEngine: popped to level " << d_userContext->getLevel() << endl; // FIXME: should we reset d_status here? // SMT-LIBv2 spec seems to imply no, but it would make sense to.. } void SmtEngine::internalPop() { - Debug("smt") << "internalPop()" << endl; + Trace("smt") << "internalPop()" << endl; d_propEngine->pop(); d_userContext->pop(); } void SmtEngine::internalPush() { - Debug("smt") << "internalPush()" << endl; - // TODO: this is the right thing to do, but needs serious thinking to keep completeness + Trace("smt") << "internalPush()" << endl; + // TODO: this is the right thing to do, but needs serious thinking + // to keep completeness + // // d_private->processAssertions(); d_userContext->push(); d_propEngine->push(); diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h index 81bd5cb47..698f9ba2e 100644 --- a/src/smt/smt_engine.h +++ b/src/smt/smt_engine.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: mdeters ** Major contributors: dejan - ** Minor contributors (to current version): none + ** Minor contributors (to current version): cconway ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 @@ -23,6 +23,26 @@ #include <vector> +#if SWIG +%include "cvc4_public.h" +%include "util/rational.h" +%include "util/exception.h" +%include "expr/kind.h" +%include "util/integer.h" +%include "util/cardinality.h" +%include "util/sexpr.h" +%include "util/language.h" +%include "expr/type.h" +%include "expr/expr.h" +%include "expr/expr_manager.h" +%{ +#include "util/integer.h" +#include "expr/expr_manager.h" +#include "expr/type.h" +#include "expr/expr.h" +%} +#endif + #include "context/cdlist_forward.h" #include "context/cdmap_forward.h" #include "context/cdset_forward.h" @@ -253,16 +273,17 @@ public: Result assertFormula(const BoolExpr& e); /** - * Add a formula to the current context and call check(). Returns - * true iff consistent. + * Check validity of an expression with respect to the current set + * of assertions by asserting the query expression's negation and + * calling check(). Returns valid, invalid, or unknown result. */ Result query(const BoolExpr& e); /** - * Add a formula to the current context and call check(). Returns - * true iff consistent. + * Assert a formula (if provided) to the current context and call + * check(). Returns sat, unsat, or unknown result. */ - Result checkSat(const BoolExpr& e); + Result checkSat(const BoolExpr& e = BoolExpr()); /** * Simplify a formula without doing "much" work. Does not involve @@ -307,6 +328,11 @@ public: std::vector<Expr> getAssertions() throw(ModalException, AssertionException); /** + * Get the current context level. + */ + size_t getStackLevel() const; + + /** * Push a user-level context. */ void push(); diff --git a/src/theory/arith/arith_priority_queue.cpp b/src/theory/arith/arith_priority_queue.cpp index 872c25e3b..3b1f5f395 100644 --- a/src/theory/arith/arith_priority_queue.cpp +++ b/src/theory/arith/arith_priority_queue.cpp @@ -1,3 +1,22 @@ +/********************* */ +/*! \file arith_priority_queue.cpp + ** \verbatim + ** Original author: taking + ** Major contributors: none + ** Minor contributors (to current version): mdeters + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + #include "theory/arith/arith_priority_queue.h" diff --git a/src/theory/arith/arith_priority_queue.h b/src/theory/arith/arith_priority_queue.h index f912d7753..1e7e3460b 100644 --- a/src/theory/arith/arith_priority_queue.h +++ b/src/theory/arith/arith_priority_queue.h @@ -1,3 +1,22 @@ +/********************* */ +/*! \file arith_priority_queue.h + ** \verbatim + ** Original author: taking + ** Major contributors: none + ** Minor contributors (to current version): mdeters + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + #include "cvc4_private.h" diff --git a/src/theory/arith/arith_prop_manager.cpp b/src/theory/arith/arith_prop_manager.cpp index 7f38c74a7..d1fce5b90 100644 --- a/src/theory/arith/arith_prop_manager.cpp +++ b/src/theory/arith/arith_prop_manager.cpp @@ -1,3 +1,22 @@ +/********************* */ +/*! \file arith_prop_manager.cpp + ** \verbatim + ** Original author: taking + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + #include "theory/arith/arith_prop_manager.h" diff --git a/src/theory/arith/arith_prop_manager.h b/src/theory/arith/arith_prop_manager.h index 39bcb7477..82f58c7a0 100644 --- a/src/theory/arith/arith_prop_manager.h +++ b/src/theory/arith/arith_prop_manager.h @@ -1,3 +1,22 @@ +/********************* */ +/*! \file arith_prop_manager.h + ** \verbatim + ** Original author: taking + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + #include "cvc4_private.h" #ifndef __CVC4__THEORY__ARITH__ARITH_PROP_MANAGER_H diff --git a/src/theory/arith/arith_rewriter.cpp b/src/theory/arith/arith_rewriter.cpp index 8d12e78fe..66223b479 100644 --- a/src/theory/arith/arith_rewriter.cpp +++ b/src/theory/arith/arith_rewriter.cpp @@ -2,8 +2,8 @@ /*! \file arith_rewriter.cpp ** \verbatim ** Original author: taking - ** Major contributors: dejan - ** Minor contributors (to current version): mdeters + ** Major contributors: none + ** Minor contributors (to current version): mdeters, dejan ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/theory/arith/arith_static_learner.h b/src/theory/arith/arith_static_learner.h index c58778215..03402a6f1 100644 --- a/src/theory/arith/arith_static_learner.h +++ b/src/theory/arith/arith_static_learner.h @@ -2,8 +2,8 @@ /*! \file arith_static_learner.h ** \verbatim ** Original author: taking - ** Major contributors: none - ** Minor contributors (to current version): none + ** Major contributors: mdeters + ** Minor contributors (to current version): dejan ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/theory/arith/arith_utilities.h b/src/theory/arith/arith_utilities.h index 2dee26be4..3a1135f74 100644 --- a/src/theory/arith/arith_utilities.h +++ b/src/theory/arith/arith_utilities.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: taking ** Major contributors: none - ** Minor contributors (to current version): mdeters + ** Minor contributors (to current version): dejan, mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/atom_database.cpp b/src/theory/arith/atom_database.cpp index 5c3519435..774d0eb22 100644 --- a/src/theory/arith/atom_database.cpp +++ b/src/theory/arith/atom_database.cpp @@ -3,9 +3,9 @@ ** \verbatim ** Original author: taking ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/atom_database.h b/src/theory/arith/atom_database.h index 25020977a..af7068ada 100644 --- a/src/theory/arith/atom_database.h +++ b/src/theory/arith/atom_database.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: taking ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/delta_rational.cpp b/src/theory/arith/delta_rational.cpp index d0e4ed1f4..c5c5c629b 100644 --- a/src/theory/arith/delta_rational.cpp +++ b/src/theory/arith/delta_rational.cpp @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/delta_rational.h b/src/theory/arith/delta_rational.h index c70d26db5..c8a5e39a7 100644 --- a/src/theory/arith/delta_rational.h +++ b/src/theory/arith/delta_rational.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/kinds b/src/theory/arith/kinds index db47062bb..bf5ea24c1 100644 --- a/src/theory/arith/kinds +++ b/src/theory/arith/kinds @@ -5,6 +5,7 @@ # theory THEORY_ARITH ::CVC4::theory::arith::TheoryArith "theory/arith/theory_arith.h" +typechecker "theory/arith/theory_arith_type_rules.h" properties stable-infinite properties check propagate staticLearning presolve notifyRestart @@ -17,6 +18,7 @@ operator MULT 2: "arithmetic multiplication" operator MINUS 2 "arithmetic binary subtraction operator" operator UMINUS 1 "arithmetic unary negation" operator DIVISION 2 "arithmetic division" +operator POW 2 "arithmetic power" sort REAL_TYPE \ Cardinality::REALS \ @@ -58,4 +60,19 @@ operator LEQ 2 "less than or equal, x <= y" operator GT 2 "greater than, x > y" operator GEQ 2 "greater than or equal, x >= y" +typerule PLUS ::CVC4::theory::arith::ArithOperatorTypeRule +typerule MULT ::CVC4::theory::arith::ArithOperatorTypeRule +typerule MINUS ::CVC4::theory::arith::ArithOperatorTypeRule +typerule UMINUS ::CVC4::theory::arith::ArithOperatorTypeRule +typerule DIVISION ::CVC4::theory::arith::ArithOperatorTypeRule +typerule POW ::CVC4::theory::arith::ArithOperatorTypeRule + +typerule CONST_RATIONAL ::CVC4::theory::arith::ArithConstantTypeRule +typerule CONST_INTEGER ::CVC4::theory::arith::ArithConstantTypeRule + +typerule LT ::CVC4::theory::arith::ArithPredicateTypeRule +typerule LEQ ::CVC4::theory::arith::ArithPredicateTypeRule +typerule GT ::CVC4::theory::arith::ArithPredicateTypeRule +typerule GEQ ::CVC4::theory::arith::ArithPredicateTypeRule + endtheory diff --git a/src/theory/arith/normal_form.cpp b/src/theory/arith/normal_form.cpp index b529a8077..e7df14df7 100644 --- a/src/theory/arith/normal_form.cpp +++ b/src/theory/arith/normal_form.cpp @@ -3,9 +3,9 @@ ** \verbatim ** Original author: taking ** Major contributors: mdeters - ** Minor contributors (to current version): none + ** Minor contributors (to current version): dejan ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/normal_form.h b/src/theory/arith/normal_form.h index d6e79318d..6e2d706cc 100644 --- a/src/theory/arith/normal_form.h +++ b/src/theory/arith/normal_form.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: taking ** Major contributors: mdeters - ** Minor contributors (to current version): none + ** Minor contributors (to current version): dejan ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/ordered_set.h b/src/theory/arith/ordered_set.h index e44ba8687..c126ab568 100644 --- a/src/theory/arith/ordered_set.h +++ b/src/theory/arith/ordered_set.h @@ -1,3 +1,22 @@ +/********************* */ +/*! \file ordered_set.h + ** \verbatim + ** Original author: taking + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + #include <map> #include <set> #include "expr/kind.h" diff --git a/src/theory/arith/partial_model.cpp b/src/theory/arith/partial_model.cpp index 3cd8ed926..ed8f837d1 100644 --- a/src/theory/arith/partial_model.cpp +++ b/src/theory/arith/partial_model.cpp @@ -5,7 +5,7 @@ ** Major contributors: none ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/partial_model.h b/src/theory/arith/partial_model.h index f07e524aa..aa333046b 100644 --- a/src/theory/arith/partial_model.h +++ b/src/theory/arith/partial_model.h @@ -5,7 +5,7 @@ ** Major contributors: none ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/simplex.cpp b/src/theory/arith/simplex.cpp index 3e2d90674..77e7e1060 100644 --- a/src/theory/arith/simplex.cpp +++ b/src/theory/arith/simplex.cpp @@ -1,3 +1,22 @@ +/********************* */ +/*! \file simplex.cpp + ** \verbatim + ** Original author: taking + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + #include "theory/arith/simplex.h" diff --git a/src/theory/arith/simplex.h b/src/theory/arith/simplex.h index b3f43baf1..04b4ca784 100644 --- a/src/theory/arith/simplex.h +++ b/src/theory/arith/simplex.h @@ -1,3 +1,22 @@ +/********************* */ +/*! \file simplex.h + ** \verbatim + ** Original author: taking + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + #include "cvc4_private.h" diff --git a/src/theory/arith/tableau.cpp b/src/theory/arith/tableau.cpp index b432416bd..ef3206650 100644 --- a/src/theory/arith/tableau.cpp +++ b/src/theory/arith/tableau.cpp @@ -3,9 +3,9 @@ ** \verbatim ** Original author: taking ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/tableau.h b/src/theory/arith/tableau.h index e14436f8c..3da3d68a5 100644 --- a/src/theory/arith/tableau.h +++ b/src/theory/arith/tableau.h @@ -2,10 +2,10 @@ /*! \file tableau.h ** \verbatim ** Original author: taking - ** Major contributors: mdeters - ** Minor contributors (to current version): dejan + ** Major contributors: none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/theory_arith.cpp b/src/theory/arith/theory_arith.cpp index 2664aaac3..4369c6de0 100644 --- a/src/theory/arith/theory_arith.cpp +++ b/src/theory/arith/theory_arith.cpp @@ -2,10 +2,10 @@ /*! \file theory_arith.cpp ** \verbatim ** Original author: taking - ** Major contributors: none - ** Minor contributors (to current version): barrett, dejan, mdeters + ** Major contributors: mdeters, dejan + ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/theory_arith.h b/src/theory/arith/theory_arith.h index 7e14f6b06..2e85659e4 100644 --- a/src/theory/arith/theory_arith.h +++ b/src/theory/arith/theory_arith.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: mdeters ** Major contributors: taking - ** Minor contributors (to current version): barrett + ** Minor contributors (to current version): dejan ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arith/theory_arith_type_rules.h b/src/theory/arith/theory_arith_type_rules.h index 8bfd2aef6..9c69ec684 100644 --- a/src/theory/arith/theory_arith_type_rules.h +++ b/src/theory/arith/theory_arith_type_rules.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters, cconway ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arrays/array_info.cpp b/src/theory/arrays/array_info.cpp index 5a836fdc2..1e06621b4 100644 --- a/src/theory/arrays/array_info.cpp +++ b/src/theory/arrays/array_info.cpp @@ -3,9 +3,9 @@ ** \verbatim ** Original author: lianah ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arrays/array_info.h b/src/theory/arrays/array_info.h index ce3f015b5..fcc45bbd5 100644 --- a/src/theory/arrays/array_info.h +++ b/src/theory/arrays/array_info.h @@ -1,3 +1,22 @@ +/********************* */ +/*! \file array_info.h + ** \verbatim + ** Original author: lianah + ** Major contributors: none + ** Minor contributors (to current version): mdeters + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + /*! \file array_info.h ** \verbatim ** Original author: lianah diff --git a/src/theory/arrays/kinds b/src/theory/arrays/kinds index 30242db30..2f4bc7313 100644 --- a/src/theory/arrays/kinds +++ b/src/theory/arrays/kinds @@ -5,6 +5,7 @@ # theory THEORY_ARRAY ::CVC4::theory::arrays::TheoryArrays "theory/arrays/theory_arrays.h" +typechecker "theory/arrays/theory_arrays_type_rules.h" properties polite stable-infinite properties check propagate presolve @@ -23,4 +24,7 @@ operator SELECT 2 "array select" # store a i e is a[i] <= e operator STORE 3 "array store" +typerule SELECT ::CVC4::theory::arrays::ArraySelectTypeRule +typerule STORE ::CVC4::theory::arrays::ArrayStoreTypeRule + endtheory diff --git a/src/theory/arrays/static_fact_manager.cpp b/src/theory/arrays/static_fact_manager.cpp index 1e135514a..dfa32418f 100644 --- a/src/theory/arrays/static_fact_manager.cpp +++ b/src/theory/arrays/static_fact_manager.cpp @@ -1,11 +1,11 @@ /********************* */ /*! \file static_fact_manager.cpp ** \verbatim - ** Original author: mdeters + ** Original author: barrett ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arrays/static_fact_manager.h b/src/theory/arrays/static_fact_manager.h index de487f97c..5e1ba27a3 100644 --- a/src/theory/arrays/static_fact_manager.h +++ b/src/theory/arrays/static_fact_manager.h @@ -1,11 +1,11 @@ /********************* */ /*! \file static_fact_manager.h ** \verbatim - ** Original author: mdeters + ** Original author: barrett ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arrays/theory_arrays.cpp b/src/theory/arrays/theory_arrays.cpp index 888a98a45..6985aaea8 100644 --- a/src/theory/arrays/theory_arrays.cpp +++ b/src/theory/arrays/theory_arrays.cpp @@ -2,8 +2,8 @@ /*! \file theory_arrays.cpp ** \verbatim ** Original author: barrett - ** Major contributors: none - ** Minor contributors (to current version): mdeters + ** Major contributors: mdeters + ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -22,6 +22,7 @@ #include "expr/kind.h" #include <map> #include "theory/rewriter.h" +#include "expr/command.h" using namespace std; using namespace CVC4; @@ -689,7 +690,7 @@ void TheoryArrays::appendToDiseqList(TNode of, TNode eq) { * Iterates through the indices of a and stores of b and checks if any new * Row lemmas need to be instantiated. */ -bool TheoryArrays::isRedundandRowLemma(TNode a, TNode b, TNode i, TNode j) { +bool TheoryArrays::isRedundantRowLemma(TNode a, TNode b, TNode i, TNode j) { Assert(a.getType().isArray()); Assert(b.getType().isArray()); @@ -984,7 +985,7 @@ void TheoryArrays::checkRowLemmas(TNode a, TNode b) { TNode j = store[1]; TNode c = store[0]; - if( !isRedundandRowLemma(store, c, j, i)){ + if( !isRedundantRowLemma(store, c, j, i)){ //&&!propagateFromRow(store, c, j, i)) { queueRowLemma(store, c, j, i); } @@ -1004,7 +1005,7 @@ void TheoryArrays::checkRowLemmas(TNode a, TNode b) { TNode c = store[0]; if ( isNonLinear(c) - &&!isRedundandRowLemma(store, c, j, i)){ + &&!isRedundantRowLemma(store, c, j, i)){ //&&!propagateFromRow(store, c, j, i)) { queueRowLemma(store, c, j, i); } @@ -1066,7 +1067,7 @@ void TheoryArrays::checkRowForIndex(TNode i, TNode a) { Assert(store.getKind()==kind::STORE); TNode j = store[1]; //Trace("arrays-lem")<<"Arrays::checkRowForIndex ("<<store<<", "<<store[0]<<", "<<j<<", "<<i<<")\n"; - if(!isRedundandRowLemma(store, store[0], j, i)) { + if(!isRedundantRowLemma(store, store[0], j, i)) { //Trace("arrays-lem")<<"Arrays::checkRowForIndex ("<<store<<", "<<store[0]<<", "<<j<<", "<<i<<")\n"; queueRowLemma(store, store[0], j, i); } @@ -1078,7 +1079,7 @@ void TheoryArrays::checkRowForIndex(TNode i, TNode a) { Assert(instore.getKind()==kind::STORE); TNode j = instore[1]; //Trace("arrays-lem")<<"Arrays::checkRowForIndex ("<<instore<<", "<<instore[0]<<", "<<j<<", "<<i<<")\n"; - if(!isRedundandRowLemma(instore, instore[0], j, i)) { + if(!isRedundantRowLemma(instore, instore[0], j, i)) { //Trace("arrays-lem")<<"Arrays::checkRowForIndex ("<<instore<<", "<<instore[0]<<", "<<j<<", "<<i<<")\n"; queueRowLemma(instore, instore[0], j, i); } @@ -1104,7 +1105,7 @@ void TheoryArrays::checkStore(TNode a) { for(; it!= js->end(); it++) { TNode j = *it; - if(!isRedundandRowLemma(a, b, i, j)) { + if(!isRedundantRowLemma(a, b, i, j)) { //Trace("arrays-lem")<<"Arrays::checkRowStore ("<<a<<", "<<b<<", "<<i<<", "<<j<<")\n"; queueRowLemma(a,b,i,j); } @@ -1141,7 +1142,17 @@ inline void TheoryArrays::addExtLemma(TNode a, TNode b) { && d_extAlreadyAdded.count(make_pair(b, a)) == 0) { NodeManager* nm = NodeManager::currentNM(); - Node k = nm->mkVar(a.getType()[0]); + TypeNode ixType = a.getType()[0]; + Node k = nm->mkVar(ixType); + if(Dump.isOn("declarations")) { + stringstream kss; + kss << Expr::setlanguage(Expr::setlanguage::getLanguage(Dump("declarations"))) << k; + string ks = kss.str(); + Dump("declarations") + << CommentCommand(ks + " is an extensional lemma index variable " + "from the theory of arrays") << endl + << DeclareFunctionCommand(ks, ixType.toType()) << endl; + } Node eq = nm->mkNode(kind::EQUAL, a, b); Node ak = nm->mkNode(kind::SELECT, a, k); Node bk = nm->mkNode(kind::SELECT, b, k); @@ -1154,7 +1165,7 @@ inline void TheoryArrays::addExtLemma(TNode a, TNode b) { ++d_numExt; return; } - Trace("arrays-cle")<<"Arrays::checkExtLemmas lemma already generated. \n"; + Trace("arrays-cle")<<"Arrays::checkExtLemmas lemma already generated. \n"; } diff --git a/src/theory/arrays/theory_arrays.h b/src/theory/arrays/theory_arrays.h index cf822cb65..37fffd2ec 100644 --- a/src/theory/arrays/theory_arrays.h +++ b/src/theory/arrays/theory_arrays.h @@ -2,10 +2,10 @@ /*! \file theory_arrays.h ** \verbatim ** Original author: mdeters - ** Major contributors: barrett - ** Minor contributors (to current version): none + ** Major contributors: none + ** Minor contributors (to current version): barrett ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 @@ -254,7 +254,7 @@ private: bool isAxiom(TNode lhs, TNode rhs); - bool isRedundandRowLemma(TNode a, TNode b, TNode i, TNode j); + bool isRedundantRowLemma(TNode a, TNode b, TNode i, TNode j); bool isRedundantInContext(TNode a, TNode b, TNode i, TNode j); diff --git a/src/theory/arrays/theory_arrays_rewriter.h b/src/theory/arrays/theory_arrays_rewriter.h index d7b37d8ba..8c1c16de2 100644 --- a/src/theory/arrays/theory_arrays_rewriter.h +++ b/src/theory/arrays/theory_arrays_rewriter.h @@ -2,7 +2,7 @@ /*! \file theory_arrays_rewriter.h ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: barrett, mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/arrays/union_find.cpp b/src/theory/arrays/union_find.cpp index b0f06b78e..57fd412e4 100644 --- a/src/theory/arrays/union_find.cpp +++ b/src/theory/arrays/union_find.cpp @@ -1,11 +1,11 @@ /********************* */ /*! \file union_find.cpp ** \verbatim - ** Original author: mdeters + ** Original author: lianah ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/arrays/union_find.h b/src/theory/arrays/union_find.h index 4a882806c..7ae85424d 100644 --- a/src/theory/arrays/union_find.h +++ b/src/theory/arrays/union_find.h @@ -1,11 +1,11 @@ /********************* */ /*! \file union_find.h ** \verbatim - ** Original author: mdeters + ** Original author: lianah ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/booleans/circuit_propagator.cpp b/src/theory/booleans/circuit_propagator.cpp index fd44ec13b..318fdecce 100644 --- a/src/theory/booleans/circuit_propagator.cpp +++ b/src/theory/booleans/circuit_propagator.cpp @@ -2,7 +2,7 @@ /*! \file circuit_propagator.cpp ** \verbatim ** Original author: mdeters - ** Major contributors: none + ** Major contributors: dejan ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) @@ -29,11 +29,11 @@ namespace CVC4 { namespace theory { namespace booleans { -void CircuitPropagator::assert(TNode assertion) +void CircuitPropagator::assert(TNode assertion) { if (assertion.getKind() == kind::AND) { for (unsigned i = 0; i < assertion.getNumChildren(); ++ i) { - assert(assertion[i]); + assert(assertion[i]); } } else { // Analyze the assertion for back-edges and all that diff --git a/src/theory/booleans/circuit_propagator.h b/src/theory/booleans/circuit_propagator.h index 73a5be0f8..9593f7735 100644 --- a/src/theory/booleans/circuit_propagator.h +++ b/src/theory/booleans/circuit_propagator.h @@ -2,7 +2,7 @@ /*! \file circuit_propagator.h ** \verbatim ** Original author: mdeters - ** Major contributors: none + ** Major contributors: dejan ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) @@ -189,20 +189,16 @@ private: bool d_forwardPropagation; /** Whether to perform backward propagation */ bool d_backwardPropagation; - /** Whether to perform expensive propagations */ - bool d_expensivePropagation; public: /** * Construct a new CircuitPropagator with the given atoms and backEdges. */ - CircuitPropagator(std::vector<Node>& outLearnedLiterals, bool enableForward = true, bool enableBackward = true, bool enableExpensive = true) : + CircuitPropagator(std::vector<Node>& outLearnedLiterals, bool enableForward = true, bool enableBackward = true) : d_conflict(false), d_learnedLiterals(outLearnedLiterals), d_forwardPropagation(enableForward), - d_backwardPropagation(enableBackward), - d_expensivePropagation(enableExpensive) - { + d_backwardPropagation(enableBackward) { } /** Assert for propagation */ diff --git a/src/theory/booleans/kinds b/src/theory/booleans/kinds index d540d57f5..5580418e5 100644 --- a/src/theory/booleans/kinds +++ b/src/theory/booleans/kinds @@ -5,6 +5,7 @@ # theory THEORY_BOOL ::CVC4::theory::booleans::TheoryBool "theory/booleans/theory_bool.h" +typechecker "theory/booleans/theory_bool_type_rules.h" properties finite @@ -31,4 +32,14 @@ operator OR 2: "logical or" operator XOR 2 "exclusive or" operator ITE 3 "if-then-else" +typerule CONST_BOOLEAN ::CVC4::theory::boolean::BooleanTypeRule + +typerule NOT ::CVC4::theory::boolean::BooleanTypeRule +typerule AND ::CVC4::theory::boolean::BooleanTypeRule +typerule IFF ::CVC4::theory::boolean::BooleanTypeRule +typerule IMPLIES ::CVC4::theory::boolean::BooleanTypeRule +typerule OR ::CVC4::theory::boolean::BooleanTypeRule +typerule XOR ::CVC4::theory::boolean::BooleanTypeRule +typerule ITE ::CVC4::theory::boolean::IteTypeRule + endtheory diff --git a/src/theory/booleans/theory_bool.cpp b/src/theory/booleans/theory_bool.cpp index 01185281a..2be1dac55 100644 --- a/src/theory/booleans/theory_bool.cpp +++ b/src/theory/booleans/theory_bool.cpp @@ -2,7 +2,7 @@ /*! \file theory_bool.cpp ** \verbatim ** Original author: mdeters - ** Major contributors: none + ** Major contributors: dejan ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/booleans/theory_bool.h b/src/theory/booleans/theory_bool.h index ce9938b10..d53337fa7 100644 --- a/src/theory/booleans/theory_bool.h +++ b/src/theory/booleans/theory_bool.h @@ -2,8 +2,8 @@ /*! \file theory_bool.h ** \verbatim ** Original author: mdeters - ** Major contributors: taking - ** Minor contributors (to current version): barrett + ** Major contributors: none + ** Minor contributors (to current version): dejan ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/theory/booleans/theory_bool_rewriter.cpp b/src/theory/booleans/theory_bool_rewriter.cpp index d2693268f..4f41d2fa5 100644 --- a/src/theory/booleans/theory_bool_rewriter.cpp +++ b/src/theory/booleans/theory_bool_rewriter.cpp @@ -2,7 +2,7 @@ /*! \file theory_bool_rewriter.cpp ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters, barrett ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/booleans/theory_bool_rewriter.h b/src/theory/booleans/theory_bool_rewriter.h index 4a23249d4..6771f775c 100644 --- a/src/theory/booleans/theory_bool_rewriter.h +++ b/src/theory/booleans/theory_bool_rewriter.h @@ -2,7 +2,7 @@ /*! \file theory_bool_rewriter.h ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/booleans/theory_bool_type_rules.h b/src/theory/booleans/theory_bool_type_rules.h index 09030d331..e6c3e0f54 100644 --- a/src/theory/booleans/theory_bool_type_rules.h +++ b/src/theory/booleans/theory_bool_type_rules.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters, cconway ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/builtin/kinds b/src/theory/builtin/kinds index d170469e0..83a372726 100644 --- a/src/theory/builtin/kinds +++ b/src/theory/builtin/kinds @@ -36,7 +36,6 @@ # check the theory supports the check() function # propagate the theory supports propagate() (and explain()) # staticLearning the theory supports staticLearning() -# registerTerm the theory supports registerTerm() # notifyRestart the theory supports notifyRestart() # presolve the theory supports presolve() # @@ -59,6 +58,12 @@ # future, so if possible, do not rely on them being called (and # implement them as a no-op). # +# typechecker header +# +# Declare that this theory's typechecker class is defined in the +# given header. (#include'd by the TypeChecker class in the expr +# package.) +# # variable K ["comment"] # # This declares a kind K that has no operator (it's conceptually a @@ -122,6 +127,19 @@ # For consistency, constants taking a non-void payload should # start with "CONST_", but this is not enforced. # +# typerule K typechecker-class +# +# Declares that a (previously-declared) kind K is typechecked by +# the typechecker-class. This class should be defined by the +# header given to the "typechecker" command, above. The +# typechecker-class is used this way by the main TypeChecker code: +# +# typechecker-class::computeType(NodeManager* nm, TNode n, bool check) +# +# It returns TypeNode. It should compute the type of n and return it, +# and if "check" is true, should actually perform type checking instead +# of simply type computation. +# # sort K cardinality [well-founded ground-term header | not-well-founded] ["comment"] # # This creates a kind K that represents a sort (a "type constant"). @@ -217,6 +235,7 @@ # theory THEORY_BUILTIN ::CVC4::theory::builtin::TheoryBuiltin "theory/builtin/theory_builtin.h" +typechecker "theory/builtin/theory_builtin_type_rules.h" properties stable-infinite @@ -282,4 +301,9 @@ well-founded TUPLE_TYPE \ "::CVC4::theory::builtin::TupleProperties::mkGroundTerm(%TYPE%)" \ "theory/builtin/theory_builtin_type_rules.h" +typerule APPLY ::CVC4::theory::builtin::ApplyTypeRule +typerule EQUAL ::CVC4::theory::builtin::EqualityTypeRule +typerule DISTINCT ::CVC4::theory::builtin::DistinctTypeRule +typerule TUPLE ::CVC4::theory::builtin::TupleTypeRule + endtheory diff --git a/src/theory/builtin/theory_builtin.cpp b/src/theory/builtin/theory_builtin.cpp index 1c779bd79..e955539d5 100644 --- a/src/theory/builtin/theory_builtin.cpp +++ b/src/theory/builtin/theory_builtin.cpp @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/builtin/theory_builtin.h b/src/theory/builtin/theory_builtin.h index 4e62401ff..5c3c70443 100644 --- a/src/theory/builtin/theory_builtin.h +++ b/src/theory/builtin/theory_builtin.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: mdeters ** Major contributors: none - ** Minor contributors (to current version): barrett + ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/builtin/theory_builtin_rewriter.cpp b/src/theory/builtin/theory_builtin_rewriter.cpp index b71d66c03..f62140263 100644 --- a/src/theory/builtin/theory_builtin_rewriter.cpp +++ b/src/theory/builtin/theory_builtin_rewriter.cpp @@ -2,7 +2,7 @@ /*! \file theory_builtin_rewriter.cpp ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/builtin/theory_builtin_type_rules.h b/src/theory/builtin/theory_builtin_type_rules.h index 3bfb7fdc5..ce06b4259 100644 --- a/src/theory/builtin/theory_builtin_type_rules.h +++ b/src/theory/builtin/theory_builtin_type_rules.h @@ -5,7 +5,7 @@ ** Major contributors: cconway, mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/bv/cd_set_collection.h b/src/theory/bv/cd_set_collection.h index 30e4e47ec..ba9d104a1 100644 --- a/src/theory/bv/cd_set_collection.h +++ b/src/theory/bv/cd_set_collection.h @@ -1,3 +1,22 @@ +/********************* */ +/*! \file cd_set_collection.h + ** \verbatim + ** Original author: dejan + ** Major contributors: none + ** Minor contributors (to current version): mdeters + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + /* * set_collection.h * diff --git a/src/theory/bv/equality_engine.cpp b/src/theory/bv/equality_engine.cpp index fa0650506..ee4e9903c 100644 --- a/src/theory/bv/equality_engine.cpp +++ b/src/theory/bv/equality_engine.cpp @@ -2,10 +2,10 @@ /*! \file equality_engine.cpp ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/bv/equality_engine.h b/src/theory/bv/equality_engine.h index 31a4bfd27..558fd2b7b 100644 --- a/src/theory/bv/equality_engine.h +++ b/src/theory/bv/equality_engine.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: dejan ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/bv/kinds b/src/theory/bv/kinds index d10e32ee0..d502c5ecb 100644 --- a/src/theory/bv/kinds +++ b/src/theory/bv/kinds @@ -5,6 +5,7 @@ # theory THEORY_BV ::CVC4::theory::bv::TheoryBV "theory/bv/theory_bv.h" +typechecker "theory/bv/theory_bv_type_rules.h" properties finite properties check propagate @@ -99,4 +100,47 @@ parameterized BITVECTOR_SIGN_EXTEND BITVECTOR_SIGN_EXTEND_OP 1 "bit-vector sign- parameterized BITVECTOR_ROTATE_LEFT BITVECTOR_ROTATE_LEFT_OP 1 "bit-vector rotate left" parameterized BITVECTOR_ROTATE_RIGHT BITVECTOR_ROTATE_RIGHT_OP 1 "bit-vector rotate right" +typerule CONST_BITVECTOR ::CVC4::theory::bv::BitVectorConstantTypeRule + +typerule BITVECTOR_AND ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_OR ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_XOR ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_NOT ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_NAND ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_NOR ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_XNOR ::CVC4::theory::bv::BitVectorFixedWidthTypeRule + +typerule BITVECTOR_COMP ::CVC4::theory::bv::BitVectorCompRule + +typerule BITVECTOR_MULT ::CVC4::theory::bv::BitVectorArithRule +typerule BITVECTOR_PLUS ::CVC4::theory::bv::BitVectorArithRule +typerule BITVECTOR_SUB ::CVC4::theory::bv::BitVectorArithRule +typerule BITVECTOR_NEG ::CVC4::theory::bv::BitVectorArithRule + +typerule BITVECTOR_UDIV ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_UREM ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_SDIV ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_SREM ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_SMOD ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_SHL ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_LSHR ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_ASHR ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_ROTATE_LEFT ::CVC4::theory::bv::BitVectorFixedWidthTypeRule +typerule BITVECTOR_ROTATE_RIGHT ::CVC4::theory::bv::BitVectorFixedWidthTypeRule + +typerule BITVECTOR_ULT ::CVC4::theory::bv::BitVectorPredicateTypeRule +typerule BITVECTOR_ULE ::CVC4::theory::bv::BitVectorPredicateTypeRule +typerule BITVECTOR_UGT ::CVC4::theory::bv::BitVectorPredicateTypeRule +typerule BITVECTOR_UGE ::CVC4::theory::bv::BitVectorPredicateTypeRule +typerule BITVECTOR_SLT ::CVC4::theory::bv::BitVectorPredicateTypeRule +typerule BITVECTOR_SLE ::CVC4::theory::bv::BitVectorPredicateTypeRule +typerule BITVECTOR_SGT ::CVC4::theory::bv::BitVectorPredicateTypeRule +typerule BITVECTOR_SGE ::CVC4::theory::bv::BitVectorPredicateTypeRule + +typerule BITVECTOR_EXTRACT ::CVC4::theory::bv::BitVectorExtractTypeRule +typerule BITVECTOR_CONCAT ::CVC4::theory::bv::BitVectorConcatRule +typerule BITVECTOR_REPEAT ::CVC4::theory::bv::BitVectorRepeatTypeRule +typerule BITVECTOR_ZERO_EXTEND ::CVC4::theory::bv::BitVectorExtendTypeRule +typerule BITVECTOR_SIGN_EXTEND ::CVC4::theory::bv::BitVectorExtendTypeRule + endtheory diff --git a/src/theory/bv/slice_manager.h b/src/theory/bv/slice_manager.h index 4fb11f105..9e0b09f2f 100644 --- a/src/theory/bv/slice_manager.h +++ b/src/theory/bv/slice_manager.h @@ -1,3 +1,22 @@ +/********************* */ +/*! \file slice_manager.h + ** \verbatim + ** Original author: dejan + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + /* * slice_manager.h * diff --git a/src/theory/bv/theory_bv.cpp b/src/theory/bv/theory_bv.cpp index 593274281..c1fa692b9 100644 --- a/src/theory/bv/theory_bv.cpp +++ b/src/theory/bv/theory_bv.cpp @@ -2,10 +2,10 @@ /*! \file theory_bv.cpp ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/bv/theory_bv.h b/src/theory/bv/theory_bv.h index 27fadce0b..5c6797e76 100644 --- a/src/theory/bv/theory_bv.h +++ b/src/theory/bv/theory_bv.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: mdeters ** Major contributors: dejan - ** Minor contributors (to current version): barrett + ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/bv/theory_bv_rewrite_rules.h b/src/theory/bv/theory_bv_rewrite_rules.h index b66fef0a9..68f75847f 100644 --- a/src/theory/bv/theory_bv_rewrite_rules.h +++ b/src/theory/bv/theory_bv_rewrite_rules.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: dejan ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/bv/theory_bv_rewrite_rules_core.h b/src/theory/bv/theory_bv_rewrite_rules_core.h index e94388754..b1541fa4a 100644 --- a/src/theory/bv/theory_bv_rewrite_rules_core.h +++ b/src/theory/bv/theory_bv_rewrite_rules_core.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: dejan ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/bv/theory_bv_rewriter.cpp b/src/theory/bv/theory_bv_rewriter.cpp index 5bcbdf746..a232ad33b 100644 --- a/src/theory/bv/theory_bv_rewriter.cpp +++ b/src/theory/bv/theory_bv_rewriter.cpp @@ -2,7 +2,7 @@ /*! \file theory_bv_rewriter.cpp ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/bv/theory_bv_rewriter.h b/src/theory/bv/theory_bv_rewriter.h index 7af5b4496..20da74ce8 100644 --- a/src/theory/bv/theory_bv_rewriter.h +++ b/src/theory/bv/theory_bv_rewriter.h @@ -2,7 +2,7 @@ /*! \file theory_bv_rewriter.h ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/bv/theory_bv_type_rules.h b/src/theory/bv/theory_bv_type_rules.h index 613df47f3..926ceb767 100644 --- a/src/theory/bv/theory_bv_type_rules.h +++ b/src/theory/bv/theory_bv_type_rules.h @@ -2,10 +2,10 @@ /*! \file theory_bv_type_rules.h ** \verbatim ** Original author: dejan - ** Major contributors: cconway - ** Minor contributors (to current version): mdeters + ** Major contributors: mdeters, cconway + ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/bv/theory_bv_utils.h b/src/theory/bv/theory_bv_utils.h index a3135f077..fc4fbf834 100644 --- a/src/theory/bv/theory_bv_utils.h +++ b/src/theory/bv/theory_bv_utils.h @@ -2,10 +2,10 @@ /*! \file theory_bv_utils.h ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/datatypes/datatypes_rewriter.h b/src/theory/datatypes/datatypes_rewriter.h index b4ff7e135..14f05d14c 100644 --- a/src/theory/datatypes/datatypes_rewriter.h +++ b/src/theory/datatypes/datatypes_rewriter.h @@ -1,8 +1,8 @@ /********************* */ /*! \file datatypes_rewriter.h ** \verbatim - ** Original author: ajreynol - ** Major contributors: mdeters + ** Original author: mdeters + ** Major contributors: ajreynol ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/datatypes/explanation_manager.cpp b/src/theory/datatypes/explanation_manager.cpp index 10ee9bf64..6107e7f2c 100644 --- a/src/theory/datatypes/explanation_manager.cpp +++ b/src/theory/datatypes/explanation_manager.cpp @@ -1,3 +1,22 @@ +/********************* */ +/*! \file explanation_manager.cpp + ** \verbatim + ** Original author: ajreynol + ** Major contributors: none + ** Minor contributors (to current version): mdeters + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 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.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + #include "theory/datatypes/explanation_manager.h" using namespace std; diff --git a/src/theory/datatypes/kinds b/src/theory/datatypes/kinds index 47896b1e0..e90712129 100644 --- a/src/theory/datatypes/kinds +++ b/src/theory/datatypes/kinds @@ -5,6 +5,7 @@ # theory THEORY_DATATYPES ::CVC4::theory::datatypes::TheoryDatatypes "theory/datatypes/theory_datatypes.h" +typechecker "theory/datatypes/theory_datatypes_type_rules.h" properties check presolve @@ -70,4 +71,9 @@ constant ASCRIPTION_TYPE \ "util/ascription_type.h" \ "a type parameter for type ascription" +typerule APPLY_CONSTRUCTOR ::CVC4::theory::datatypes::DatatypeConstructorTypeRule +typerule APPLY_SELECTOR ::CVC4::theory::datatypes::DatatypeSelectorTypeRule +typerule APPLY_TESTER ::CVC4::theory::datatypes::DatatypeTesterTypeRule +typerule APPLY_TYPE_ASCRIPTION ::CVC4::theory::datatypes::DatatypeAscriptionTypeRule + endtheory diff --git a/src/theory/datatypes/theory_datatypes.cpp b/src/theory/datatypes/theory_datatypes.cpp index 6aed9e9fa..7c474a811 100644 --- a/src/theory/datatypes/theory_datatypes.cpp +++ b/src/theory/datatypes/theory_datatypes.cpp @@ -2,8 +2,8 @@ /*! \file theory_datatypes.cpp ** \verbatim ** Original author: ajreynol - ** Major contributors: mdeters - ** Minor contributors (to current version): none + ** Major contributors: none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/theory/datatypes/theory_datatypes.h b/src/theory/datatypes/theory_datatypes.h index 1b9e357ed..d91e9e7f4 100644 --- a/src/theory/datatypes/theory_datatypes.h +++ b/src/theory/datatypes/theory_datatypes.h @@ -3,7 +3,7 @@ ** \verbatim ** Original author: ajreynol ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/theory/datatypes/theory_datatypes_type_rules.h b/src/theory/datatypes/theory_datatypes_type_rules.h index 578de69a2..347bc16b3 100644 --- a/src/theory/datatypes/theory_datatypes_type_rules.h +++ b/src/theory/datatypes/theory_datatypes_type_rules.h @@ -2,7 +2,7 @@ /*! \file theory_datatypes_type_rules.h ** \verbatim ** Original author: ajreynol - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/datatypes/union_find.cpp b/src/theory/datatypes/union_find.cpp index e56c9f282..eacc4e798 100644 --- a/src/theory/datatypes/union_find.cpp +++ b/src/theory/datatypes/union_find.cpp @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/datatypes/union_find.h b/src/theory/datatypes/union_find.h index 31b18e7e9..51d1d85bc 100644 --- a/src/theory/datatypes/union_find.h +++ b/src/theory/datatypes/union_find.h @@ -3,9 +3,9 @@ ** \verbatim ** Original author: ajreynol ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/interrupted.h b/src/theory/interrupted.h index d8a54b1e4..0796f3cb0 100644 --- a/src/theory/interrupted.h +++ b/src/theory/interrupted.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/mkrewriter b/src/theory/mkrewriter index ec659d0bb..395317045 100755 --- a/src/theory/mkrewriter +++ b/src/theory/mkrewriter @@ -94,6 +94,18 @@ function endtheory { seen_endtheory=true } +function typechecker { + # typechecker header + lineno=${BASH_LINENO[0]} + check_theory_seen +} + +function typerule { + # typerule OPERATOR typechecking-class + lineno=${BASH_LINENO[0]} + check_theory_seen +} + function rewriter { # rewriter class header class="$1" diff --git a/src/theory/mktheorytraits b/src/theory/mktheorytraits index 538ffb25f..852b29711 100755 --- a/src/theory/mktheorytraits +++ b/src/theory/mktheorytraits @@ -43,7 +43,6 @@ theory_for_each_macro="#define CVC4_FOR_EACH_THEORY \\ theory_has_check="false" theory_has_propagate="false" theory_has_staticLearning="false" -theory_has_registerTerm="false" theory_has_notifyRestart="false" theory_has_presolve="false" @@ -130,7 +129,6 @@ struct TheoryTraits<${theory_id}> { static const bool hasCheck = ${theory_has_check}; static const bool hasPropagate = ${theory_has_propagate}; static const bool hasStaticLearning = ${theory_has_staticLearning}; - static const bool hasRegisterTerm = ${theory_has_registerTerm}; static const bool hasNotifyRestart = ${theory_has_notifyRestart}; static const bool hasPresolve = ${theory_has_presolve}; };/* struct TheoryTraits<${theory_id}> */ @@ -139,7 +137,7 @@ struct TheoryTraits<${theory_id}> { # warnings about theory content and properties dir="$(dirname "$kf")/../../" if [ -e "$dir/$theory_header" ]; then - for function in check propagate staticLearning registerTerm notifyRestart presolve; do + for function in check propagate staticLearning notifyRestart presolve; do if eval "\$theory_has_$function"; then grep '\<'"$function"' *\((\|;\)' "$dir/$theory_header" | grep -vq '^ */\(/\|\*\)' || echo "$kf: warning: $theory_class has property \"$function\" in its kinds file but doesn't appear to declare the function" >&2 @@ -155,7 +153,6 @@ struct TheoryTraits<${theory_id}> { theory_has_check="false" theory_has_propagate="false" theory_has_staticLearning="false" - theory_has_registerTerm="false" theory_has_notifyRestart="false" theory_has_presolve="false" @@ -172,6 +169,17 @@ struct TheoryTraits<${theory_id}> { lineno=${BASH_LINENO[0]} } +function typechecker { + # typechecker header + lineno=${BASH_LINENO[0]} + check_theory_seen +} + +function typerule { + # typerule OPERATOR typechecking-class + lineno=${BASH_LINENO[0]} + check_theory_seen +} function properties { # properties property* @@ -188,7 +196,6 @@ function properties { propagate) theory_has_propagate="true";; staticLearning) theory_has_staticLearning="true";; presolve) theory_has_presolve="true";; - registerTerm) theory_has_registerTerm="true";; notifyRestart) theory_has_notifyRestart="true";; *) echo "$kf:$lineno: error: unknown theory property \"$property\"" >&2; exit 1;; esac diff --git a/src/theory/output_channel.h b/src/theory/output_channel.h index d82e628c1..bf928cb62 100644 --- a/src/theory/output_channel.h +++ b/src/theory/output_channel.h @@ -2,10 +2,10 @@ /*! \file output_channel.h ** \verbatim ** Original author: mdeters - ** Major contributors: taking - ** Minor contributors (to current version): barrett + ** Major contributors: none + ** Minor contributors (to current version): taking, barrett ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/rewriter.cpp b/src/theory/rewriter.cpp index bb42a5ec7..f6aa75bbd 100644 --- a/src/theory/rewriter.cpp +++ b/src/theory/rewriter.cpp @@ -2,7 +2,7 @@ /*! \file rewriter.cpp ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/rewriter.h b/src/theory/rewriter.h index 884d0af72..f1a0e2b30 100644 --- a/src/theory/rewriter.h +++ b/src/theory/rewriter.h @@ -2,7 +2,7 @@ /*! \file rewriter.h ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/rewriter_attributes.h b/src/theory/rewriter_attributes.h index a2b2d06b7..c958abb68 100644 --- a/src/theory/rewriter_attributes.h +++ b/src/theory/rewriter_attributes.h @@ -2,7 +2,7 @@ /*! \file rewriter_attributes.h ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/rewriter_tables_template.h b/src/theory/rewriter_tables_template.h index cbbff95c1..34204ec2d 100644 --- a/src/theory/rewriter_tables_template.h +++ b/src/theory/rewriter_tables_template.h @@ -2,7 +2,7 @@ /*! \file rewriter_tables_template.h ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/shared_data.cpp b/src/theory/shared_data.cpp index 50e916832..3e89dec7e 100644 --- a/src/theory/shared_data.cpp +++ b/src/theory/shared_data.cpp @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/shared_data.h b/src/theory/shared_data.h index 181508c54..7d6a9ebd2 100644 --- a/src/theory/shared_data.h +++ b/src/theory/shared_data.h @@ -2,10 +2,10 @@ /*! \file shared_data.h ** \verbatim ** Original author: barrett - ** Major contributors: none + ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/shared_term_manager.cpp b/src/theory/shared_term_manager.cpp index 03afa984e..20f7a82f1 100644 --- a/src/theory/shared_term_manager.cpp +++ b/src/theory/shared_term_manager.cpp @@ -3,9 +3,9 @@ ** \verbatim ** Original author: barrett ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/shared_term_manager.h b/src/theory/shared_term_manager.h index 7263ac93a..faea8d687 100644 --- a/src/theory/shared_term_manager.h +++ b/src/theory/shared_term_manager.h @@ -2,10 +2,10 @@ /*! \file shared_term_manager.h ** \verbatim ** Original author: barrett - ** Major contributors: none + ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/substitutions.cpp b/src/theory/substitutions.cpp index 76551bc18..88e5b3dba 100644 --- a/src/theory/substitutions.cpp +++ b/src/theory/substitutions.cpp @@ -1,7 +1,7 @@ /********************* */ /*! \file substitutions.cpp ** \verbatim - ** Original author: mdeters + ** Original author: dejan ** Major contributors: none ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. diff --git a/src/theory/substitutions.h b/src/theory/substitutions.h index f59c17dc0..849c8f166 100644 --- a/src/theory/substitutions.h +++ b/src/theory/substitutions.h @@ -2,7 +2,7 @@ /*! \file substitutions.h ** \verbatim ** Original author: mdeters - ** Major contributors: none + ** Major contributors: dejan ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/theory.cpp b/src/theory/theory.cpp index 576e0188b..b772d9d23 100644 --- a/src/theory/theory.cpp +++ b/src/theory/theory.cpp @@ -5,7 +5,7 @@ ** Major contributors: taking ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/theory.h b/src/theory/theory.h index 62a8cb4d6..a1d62ca04 100644 --- a/src/theory/theory.h +++ b/src/theory/theory.h @@ -23,6 +23,7 @@ #include "expr/node.h" #include "expr/attribute.h" +#include "expr/command.h" #include "theory/valuation.h" #include "theory/substitutions.h" #include "theory/output_channel.h" @@ -125,10 +126,9 @@ protected: Valuation d_valuation; /** - * Returns the next atom in the assertFact() queue. Guarantees that - * registerTerm() has been called on the theory specific subterms. + * Returns the next atom in the assertFact() queue. * - * @return the next atom in the assertFact() queue. + * @return the next atom in the assertFact() queue */ TNode get() { Assert( !done(), "Theory::get() called with assertion queue empty!" ); @@ -136,7 +136,11 @@ protected: d_wasSharedTermFact = false; d_factsHead = d_factsHead + 1; Trace("theory") << "Theory::get() => " << fact - << " (" << d_facts.size() - d_factsHead << " left)" << std::endl; + << " (" << d_facts.size() - d_factsHead << " left)" + << std::endl; + if(Dump.isOn("state")) { + Dump("state") << AssertCommand(fact.toExpr()) << std::endl; + } return fact; } diff --git a/src/theory/theory_engine.cpp b/src/theory/theory_engine.cpp index e604c45df..040582c9f 100644 --- a/src/theory/theory_engine.cpp +++ b/src/theory/theory_engine.cpp @@ -2,8 +2,8 @@ /*! \file theory_engine.cpp ** \verbatim ** Original author: mdeters - ** Major contributors: taking, barrett, dejan - ** Minor contributors (to current version): cconway + ** Major contributors: barrett, dejan + ** Minor contributors (to current version): cconway, taking ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -37,18 +37,18 @@ using namespace std; using namespace CVC4; using namespace CVC4::theory; -/** Tag for the "preregisterTerm()-has-benn-called" flag on nodes */ -struct PreRegisteredAttrTag {}; -/** The "preregisterTerm()-has-been-called" flag on Nodes */ -typedef expr::Attribute<PreRegisteredAttrTag, Theory::Set> PreRegisteredAttr; - TheoryEngine::TheoryEngine(context::Context* ctxt) : d_propEngine(NULL), d_context(ctxt), d_activeTheories(0), + d_atomPreprocessingCache(), + d_possiblePropagations(), + d_hasPropagated(ctxt), d_theoryOut(this, ctxt), + d_sharedTermManager(NULL), d_hasShutDown(false), d_incomplete(ctxt, false), + d_logic(""), d_statistics(), d_preRegistrationVisitor(*this, ctxt) { @@ -87,6 +87,10 @@ struct preregister_stack_element { };/* struct preprocess_stack_element */ void TheoryEngine::preRegister(TNode preprocessed) { + if(Dump.isOn("missed-t-propagations")) { + d_possiblePropagations.push_back(preprocessed); + } + NodeVisitor<PreRegisterVisitor>::run(d_preRegistrationVisitor, preprocessed); } @@ -112,8 +116,14 @@ void TheoryEngine::check(theory::Theory::Effort effort) { // Do the checking try { CVC4_FOR_EACH_THEORY; + + if(Dump.isOn("missed-t-conflicts")) { + Dump("missed-t-conflicts") + << CommentCommand("Completeness check for T-conflicts; expect sat") << endl + << CheckSatCommand() << endl; + } } catch(const theory::Interrupted&) { - Trace("theory") << "TheoryEngine::check() => conflict" << std::endl; + Trace("theory") << "TheoryEngine::check() => conflict" << endl; } } @@ -124,11 +134,54 @@ void TheoryEngine::propagate() { #endif #define CVC4_FOR_EACH_THEORY_STATEMENT(THEORY) \ if (theory::TheoryTraits<THEORY>::hasPropagate && isActive(THEORY)) { \ - reinterpret_cast<theory::TheoryTraits<THEORY>::theory_class*>(d_theoryTable[THEORY])->propagate(theory::Theory::FULL_EFFORT); \ + reinterpret_cast<theory::TheoryTraits<THEORY>::theory_class*>(d_theoryTable[THEORY])->propagate(theory::Theory::FULL_EFFORT); \ } // Propagate for each theory using the statement above CVC4_FOR_EACH_THEORY; + + if(Dump.isOn("missed-t-propagations")) { + for(vector<TNode>::iterator i = d_possiblePropagations.begin(); + i != d_possiblePropagations.end(); + ++i) { + if(d_hasPropagated.find(*i) == d_hasPropagated.end()) { + Dump("missed-t-propagations") + << CommentCommand("Completeness check for T-propagations; expect invalid") << endl + << QueryCommand((*i).toExpr()) << endl; + } + } + } +} + +Node TheoryEngine::getExplanation(TNode node, theory::Theory* theory) { + theory->explain(node); + if(Dump.isOn("t-explanations")) { + Dump("t-explanations") + << CommentCommand(string("theory explanation from ") + + theory->identify() + ": expect valid") << endl + << QueryCommand(d_theoryOut.d_explanationNode.get().impNode(node).toExpr()) + << endl; + } + Assert(properExplanation(node, d_theoryOut.d_explanationNode.get())); + return d_theoryOut.d_explanationNode; +} + +bool TheoryEngine::properConflict(TNode conflict) const { + Assert(!conflict.isNull()); +#warning fixme + return true; +} + +bool TheoryEngine::properPropagation(TNode lit) const { + Assert(!lit.isNull()); +#warning fixme + return true; +} + +bool TheoryEngine::properExplanation(TNode node, TNode expl) const { + Assert(!node.isNull() && !expl.isNull()); +#warning fixme + return true; } Node TheoryEngine::getValue(TNode node) { @@ -212,11 +265,27 @@ void TheoryEngine::staticLearning(TNode in, NodeBuilder<>& learned) { CVC4_FOR_EACH_THEORY; } +void TheoryEngine::shutdown() { + // Set this first; if a Theory shutdown() throws an exception, + // at least the destruction of the TheoryEngine won't confound + // matters. + d_hasShutDown = true; + + // Shutdown all the theories + for(unsigned theoryId = 0; theoryId < theory::THEORY_LAST; ++theoryId) { + if(d_theoryTable[theoryId]) { + d_theoryTable[theoryId]->shutdown(); + } + } + + theory::Rewriter::shutdown(); +} + theory::Theory::SolveStatus TheoryEngine::solve(TNode literal, SubstitutionMap& substitionOut) { TNode atom = literal.getKind() == kind::NOT ? literal[0] : literal; - Trace("theory") << "TheoryEngine::solve(" << literal << "): solving with " << theoryOf(atom)->getId() << std::endl; + Trace("theory") << "TheoryEngine::solve(" << literal << "): solving with " << theoryOf(atom)->getId() << endl; Theory::SolveStatus solveStatus = theoryOf(atom)->solve(literal, substitionOut); - Trace("theory") << "TheoryEngine::solve(" << literal << ") => " << solveStatus << std::endl; + Trace("theory") << "TheoryEngine::solve(" << literal << ") => " << solveStatus << endl; return solveStatus; } @@ -230,9 +299,9 @@ struct preprocess_stack_element { Node TheoryEngine::preprocess(TNode assertion) { - Trace("theory") << "TheoryEngine::preprocess(" << assertion << ")" << std::endl; + Trace("theory") << "TheoryEngine::preprocess(" << assertion << ")" << endl; - // Do a topological sort of the subexpressions and substitute them + // Do a topological sort of the subexpressions and substitute them vector<preprocess_stack_element> toVisit; toVisit.push_back(assertion); @@ -242,7 +311,7 @@ Node TheoryEngine::preprocess(TNode assertion) { preprocess_stack_element& stackHead = toVisit.back(); TNode current = stackHead.node; - Debug("theory::internal") << "TheoryEngine::preprocess(" << assertion << "): processing " << current << std::endl; + Debug("theory::internal") << "TheoryEngine::preprocess(" << assertion << "): processing " << current << endl; // If node already in the cache we're done, pop from the stack NodeMap::iterator find = d_atomPreprocessingCache.find(current); @@ -270,7 +339,7 @@ Node TheoryEngine::preprocess(TNode assertion) { } // Mark the substitution and continue Node result = builder; - Debug("theory::internal") << "TheoryEngine::preprocess(" << assertion << "): setting " << current << " -> " << result << std::endl; + Debug("theory::internal") << "TheoryEngine::preprocess(" << assertion << "): setting " << current << " -> " << result << endl; d_atomPreprocessingCache[current] = result; toVisit.pop_back(); } else { @@ -287,7 +356,7 @@ Node TheoryEngine::preprocess(TNode assertion) { } } else { // No children, so we're done - Debug("substitution::internal") << "SubstitutionMap::internalSubstitute(" << assertion << "): setting " << current << " -> " << current << std::endl; + Debug("substitution::internal") << "SubstitutionMap::internalSubstitute(" << assertion << "): setting " << current << " -> " << current << endl; d_atomPreprocessingCache[current] = current; toVisit.pop_back(); } diff --git a/src/theory/theory_engine.h b/src/theory/theory_engine.h index 2107bcb66..815a79a5a 100644 --- a/src/theory/theory_engine.h +++ b/src/theory/theory_engine.h @@ -2,8 +2,8 @@ /*! \file theory_engine.h ** \verbatim ** Original author: mdeters - ** Major contributors: taking, dejan - ** Minor contributors (to current version): cconway, barrett + ** Major contributors: dejan + ** Minor contributors (to current version): cconway, barrett, taking ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -26,7 +26,9 @@ #include <utility> #include "expr/node.h" +#include "expr/command.h" #include "prop/prop_engine.h" +#include "context/cdset.h" #include "theory/shared_term_manager.h" #include "theory/theory.h" #include "theory/substitutions.h" @@ -77,6 +79,19 @@ class TheoryEngine { NodeMap d_atomPreprocessingCache; /** + * Used for "missed-t-propagations" dumping mode only. A set of all + * theory-propagable literals. + */ + std::vector<TNode> d_possiblePropagations; + + /** + * Used for "missed-t-propagations" dumping mode only. A + * context-dependent set of those theory-propagable literals that + * have been propagated. + */ + context::CDSet<TNode, TNodeHashFunction> d_hasPropagated; + + /** * An output channel for Theory that passes messages * back to a TheoryEngine. */ @@ -122,13 +137,16 @@ class TheoryEngine { d_explanationNode(context) { } - void newFact(TNode n); - void conflict(TNode conflictNode, bool safe) throw(theory::Interrupted, AssertionException) { Trace("theory") << "EngineOutputChannel::conflict(" << conflictNode << ")" << std::endl; d_inConflict = true; + if(Dump.isOn("t-conflicts")) { + Dump("t-conflicts") << CommentCommand("theory conflict: expect unsat") << std::endl + << CheckSatCommand(conflictNode.toExpr()) << std::endl; + } + Assert(d_engine->properConflict(conflictNode)); ++(d_engine->d_statistics.d_statConflicts); // Construct the lemma (note that no CNF caching should happen as all the literals already exists) @@ -144,6 +162,15 @@ class TheoryEngine { throw(theory::Interrupted, AssertionException) { Trace("theory") << "EngineOutputChannel::propagate(" << lit << ")" << std::endl; + if(Dump.isOn("t-propagations")) { + Dump("t-propagations") + << CommentCommand("negation of theory propagation: expect valid") << std::endl + << QueryCommand(lit.toExpr()) << std::endl; + } + if(Dump.isOn("missed-t-propagations")) { + d_engine->d_hasPropagated.insert(lit); + } + Assert(d_engine->properPropagation(lit)); d_propagatedLiterals.push_back(lit); ++(d_engine->d_statistics.d_statPropagate); } @@ -152,6 +179,10 @@ class TheoryEngine { throw(theory::Interrupted, TypeCheckingExceptionPrivate, AssertionException) { Trace("theory") << "EngineOutputChannel::lemma(" << node << ")" << std::endl; + if(Dump.isOn("t-lemmas")) { + Dump("t-lemmas") << CommentCommand("theory lemma: expect valid") << std::endl + << QueryCommand(node.toExpr()) << std::endl; + } ++(d_engine->d_statistics.d_statLemma); d_engine->newLemma(node, false, removable); @@ -161,12 +192,12 @@ class TheoryEngine { throw(theory::Interrupted, AssertionException) { Trace("theory") << "EngineOutputChannel::explanation(" << explanationNode << ")" << std::endl; + // handle dumping of explanations elsewhere.. d_explanationNode = explanationNode; ++(d_engine->d_statistics.d_statExplanation); } - void setIncomplete() - throw(theory::Interrupted, AssertionException) { + void setIncomplete() throw(theory::Interrupted, AssertionException) { d_engine->d_incomplete = true; } };/* class EngineOutputChannel */ @@ -177,12 +208,6 @@ class TheoryEngine { SharedTermManager* d_sharedTermManager; /** - * Whether or not theory registration is on. May not be safe to - * turn off with some theories. - */ - bool d_theoryRegistration; - - /** * Debugging flag to ensure that shutdown() is called before the * destructor. */ @@ -224,14 +249,15 @@ public: * there is another theory it will be deleted. */ template <class TheoryClass> - void addTheory() { + inline void addTheory() { TheoryClass* theory = new TheoryClass(d_context, d_theoryOut, theory::Valuation(this)); d_theoryTable[theory->getId()] = theory; d_sharedTermManager->registerTheory(static_cast<TheoryClass*>(theory)); } /** - * Set's the logic (smt-lib format). All theory specific setup/hacks should go in here. + * Sets the logic (SMT-LIB format). All theory specific setup/hacks + * should go in here. */ void setLogic(std::string logic); @@ -239,7 +265,7 @@ public: return d_sharedTermManager; } - void setPropEngine(prop::PropEngine* propEngine) { + inline void setPropEngine(prop::PropEngine* propEngine) { Assert(d_propEngine == NULL); d_propEngine = propEngine; } @@ -247,7 +273,7 @@ public: /** * Get a pointer to the underlying propositional engine. */ - prop::PropEngine* getPropEngine() const { + inline prop::PropEngine* getPropEngine() const { return d_propEngine; } @@ -260,7 +286,7 @@ public: /** * Return whether or not we are incomplete (in the current context). */ - bool isIncomplete() { + inline bool isIncomplete() { return d_incomplete; } @@ -269,21 +295,7 @@ public: * destruction. It is important because there are destruction * ordering issues between PropEngine and Theory. */ - void shutdown() { - // Set this first; if a Theory shutdown() throws an exception, - // at least the destruction of the TheoryEngine won't confound - // matters. - d_hasShutDown = true; - - // Shutdown all the theories - for(unsigned theoryId = 0; theoryId < theory::THEORY_LAST; ++theoryId) { - if(d_theoryTable[theoryId]) { - d_theoryTable[theoryId]->shutdown(); - } - } - - theory::Rewriter::shutdown(); - } + void shutdown(); /** * Get the theory associated to a given Node. @@ -367,7 +379,7 @@ public: return d_theoryOut.d_propagatedLiterals; } - void clearPropagatedLiterals() { + inline void clearPropagatedLiterals() { d_theoryOut.d_propagatedLiterals.clear(); } @@ -384,16 +396,25 @@ public: void propagate(); - inline Node getExplanation(TNode node, theory::Theory* theory) { - theory->explain(node); - return d_theoryOut.d_explanationNode; - } + Node getExplanation(TNode node, theory::Theory* theory); + + bool properConflict(TNode conflict) const; + bool properPropagation(TNode lit) const; + bool properExplanation(TNode node, TNode expl) const; inline Node getExplanation(TNode node) { d_theoryOut.d_explanationNode = Node::null(); TNode atom = node.getKind() == kind::NOT ? node[0] : node; theoryOf(atom)->explain(node); Assert(!d_theoryOut.d_explanationNode.get().isNull()); + if(Dump.isOn("t-explanations")) { + Dump("t-explanations") + << CommentCommand(std::string("theory explanation from ") + + theoryOf(atom)->identify() + ": expect valid") << std::endl + << QueryCommand(d_theoryOut.d_explanationNode.get().impNode(node).toExpr()) + << std::endl; + } + Assert(properExplanation(node, d_theoryOut.d_explanationNode.get())); return d_theoryOut.d_explanationNode; } diff --git a/src/theory/theory_test_utils.h b/src/theory/theory_test_utils.h index 0b377fb11..ec2405295 100644 --- a/src/theory/theory_test_utils.h +++ b/src/theory/theory_test_utils.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/theory_traits_template.h b/src/theory/theory_traits_template.h index 525c06b3c..bbf13b425 100644 --- a/src/theory/theory_traits_template.h +++ b/src/theory/theory_traits_template.h @@ -2,7 +2,7 @@ /*! \file theory_traits_template.h ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/uf/Makefile.am b/src/theory/uf/Makefile.am index fc0f32927..f25e50ec9 100644 --- a/src/theory/uf/Makefile.am +++ b/src/theory/uf/Makefile.am @@ -5,10 +5,6 @@ AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) noinst_LTLIBRARIES = libuf.la -# force automake to link using g++ -nodist_EXTRA_libuf_la_SOURCES = \ - dummy.cpp - libuf_la_SOURCES = \ theory_uf.h \ theory_uf.cpp \ @@ -19,10 +15,4 @@ libuf_la_SOURCES = \ symmetry_breaker.h \ symmetry_breaker.cpp -libuf_la_LIBADD = \ - @builddir@/tim/libuftim.la \ - @builddir@/morgan/libufmorgan.la - -SUBDIRS = tim morgan - EXTRA_DIST = kinds diff --git a/src/theory/uf/equality_engine.h b/src/theory/uf/equality_engine.h index 4f3879560..ba607526f 100644 --- a/src/theory/uf/equality_engine.h +++ b/src/theory/uf/equality_engine.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/uf/equality_engine_impl.h b/src/theory/uf/equality_engine_impl.h index 1dd9963f7..bea6ff9a9 100644 --- a/src/theory/uf/equality_engine_impl.h +++ b/src/theory/uf/equality_engine_impl.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/uf/kinds b/src/theory/uf/kinds index 6cec23385..1f8643330 100644 --- a/src/theory/uf/kinds +++ b/src/theory/uf/kinds @@ -5,11 +5,14 @@ # theory THEORY_UF ::CVC4::theory::uf::TheoryUF "theory/uf/theory_uf.h" +typechecker "theory/uf/theory_uf_type_rules.h" properties stable-infinite -properties check propagate staticLearning presolve notifyRestart +properties check propagate staticLearning presolve rewriter ::CVC4::theory::uf::TheoryUfRewriter "theory/uf/theory_uf_rewriter.h" parameterized APPLY_UF VARIABLE 1: "uninterpreted function application" +typerule APPLY_UF ::CVC4::theory::uf::UfTypeRule + endtheory diff --git a/src/theory/uf/morgan/Makefile b/src/theory/uf/morgan/Makefile deleted file mode 100644 index 4f6767bdd..000000000 --- a/src/theory/uf/morgan/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -topdir = ../../../.. -srcdir = src/theory/uf/morgan - -include $(topdir)/Makefile.subdir diff --git a/src/theory/uf/morgan/Makefile.am b/src/theory/uf/morgan/Makefile.am deleted file mode 100644 index 886178a6f..000000000 --- a/src/theory/uf/morgan/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -AM_CPPFLAGS = \ - -D__BUILDING_CVC4LIB \ - -I@srcdir@/../../../include -I@srcdir@/../../.. -I@builddir@/../../.. -AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) - -noinst_LTLIBRARIES = libufmorgan.la - -libufmorgan_la_SOURCES = \ - theory_uf_morgan.h \ - theory_uf_morgan.cpp \ - union_find.h \ - union_find.cpp \ - stacking_map.h \ - stacking_map.cpp - -EXTRA_DIST = diff --git a/src/theory/uf/morgan/stacking_map.cpp b/src/theory/uf/morgan/stacking_map.cpp deleted file mode 100644 index 16a85e71b..000000000 --- a/src/theory/uf/morgan/stacking_map.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/********************* */ -/*! \file stacking_map.cpp - ** \verbatim - ** 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.\endverbatim - ** - ** \brief Backtrackable map using an undo stack - ** - ** Backtrackable map using an undo stack rather than storing items in - ** a CDMap<>. - **/ - -#include <iostream> - -#include "theory/uf/morgan/stacking_map.h" -#include "util/Assert.h" -#include "expr/node.h" - -using namespace std; - -namespace CVC4 { -namespace theory { -namespace uf { -namespace morgan { - -template <class NodeType, class NodeHash> -TNode StackingMap<NodeType, NodeHash>::find(TNode n) const { - typename MapType::const_iterator i = d_map.find(n); - if(i == d_map.end()) { - return TNode(); - } else { - return (*i).second; - } -} - -template <class NodeType, class NodeHash> -void StackingMap<NodeType, NodeHash>::set(TNode n, TNode newValue) { - Trace("ufsm") << "UFSM setting " << n << " : " << newValue << " @ " << d_trace.size() << endl; - NodeType& ref = d_map[n]; - d_trace.push_back(make_pair(n, TNode(ref))); - d_offset = d_trace.size(); - ref = newValue; -} - -template <class NodeType, class NodeHash> -void StackingMap<NodeType, NodeHash>::notify() { - Trace("ufsm") << "UFSM cancelling : " << d_offset << " < " << d_trace.size() << " ?" << endl; - while(d_offset < d_trace.size()) { - pair<TNode, TNode> p = d_trace.back(); - if(p.second.isNull()) { - d_map.erase(p.first); - Trace("ufsm") << "UFSM " << d_trace.size() << " erasing " << p.first << endl; - } else { - d_map[p.first] = p.second; - Trace("ufsm") << "UFSM " << d_trace.size() << " replacing " << p << endl; - } - d_trace.pop_back(); - } - Trace("ufufsm") << "UFSM cancelling finished." << endl; -} - -// The following declarations allow us to put functions in the .cpp file -// instead of the header, since we know which instantiations are needed. - -template TNode StackingMap<Node, NodeHashFunction>::find(TNode n) const; -template void StackingMap<Node, NodeHashFunction>::set(TNode n, TNode newValue); -template void StackingMap<Node, NodeHashFunction>::notify(); - -template TNode StackingMap<TNode, TNodeHashFunction>::find(TNode n) const; -template void StackingMap<TNode, TNodeHashFunction>::set(TNode n, TNode newValue); -template void StackingMap<TNode, TNodeHashFunction>::notify(); - -}/* CVC4::theory::uf::morgan namespace */ -}/* CVC4::theory::uf namespace */ -}/* CVC4::theory namespace */ -}/* CVC4 namespace */ diff --git a/src/theory/uf/morgan/stacking_map.h b/src/theory/uf/morgan/stacking_map.h deleted file mode 100644 index c54acc363..000000000 --- a/src/theory/uf/morgan/stacking_map.h +++ /dev/null @@ -1,91 +0,0 @@ -/********************* */ -/*! \file stacking_map.h - ** \verbatim - ** 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.\endverbatim - ** - ** \brief Backtrackable map using an undo stack - ** - ** Backtrackable map using an undo stack rather than storing items in - ** a CDMap<>. - **/ - -#include "cvc4_private.h" - -#ifndef __CVC4__THEORY__UF__MORGAN__STACKING_MAP_H -#define __CVC4__THEORY__UF__MORGAN__STACKING_MAP_H - -#include <utility> -#include <vector> -#include <ext/hash_map> - -#include "expr/node.h" -#include "context/cdo.h" - -namespace CVC4 { - -namespace context { - class Context; -}/* CVC4::context namespace */ - -namespace theory { -namespace uf { -namespace morgan { - -// NodeType \in { Node, TNode } -template <class NodeType, class NodeHash> -class StackingMap : context::ContextNotifyObj { - /** Our underlying map type. */ - typedef __gnu_cxx::hash_map<NodeType, NodeType, NodeHash> MapType; - - /** - * Our map of Nodes to their values. - */ - MapType d_map; - - /** Our undo stack for changes made to d_map. */ - std::vector<std::pair<TNode, TNode> > d_trace; - - /** Our current offset in the d_trace stack (context-dependent). */ - context::CDO<size_t> d_offset; - -public: - StackingMap(context::Context* ctxt) : - context::ContextNotifyObj(ctxt), - d_offset(ctxt, 0) { - } - - ~StackingMap() throw() { } - - /** - * Return a Node's value in the key-value map. If n is not a key in - * the map, this function returns TNode::null(). - */ - TNode find(TNode n) const; - - /** - * Set the value in the key-value map for Node n to newValue. - */ - void set(TNode n, TNode newValue); - - /** - * Called by the Context when a pop occurs. Cancels everything to the - * current context level. Overrides ContextNotifyObj::notify(). - */ - void notify(); - -};/* class StackingMap<> */ - -}/* CVC4::theory::uf::morgan namespace */ -}/* CVC4::theory::uf namespace */ -}/* CVC4::theory namespace */ -}/* CVC4 namespace */ - -#endif /*__CVC4__THEORY__UF__MORGAN__STACKING_MAP_H */ diff --git a/src/theory/uf/morgan/theory_uf_morgan.cpp b/src/theory/uf/morgan/theory_uf_morgan.cpp deleted file mode 100644 index 01bab53ac..000000000 --- a/src/theory/uf/morgan/theory_uf_morgan.cpp +++ /dev/null @@ -1,751 +0,0 @@ -/********************* */ -/*! \file theory_uf_morgan.cpp - ** \verbatim - ** Original author: taking - ** Major contributors: mdeters - ** 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.\endverbatim - ** - ** \brief Implementation of the theory of uninterpreted functions. - ** - ** Implementation of the theory of uninterpreted functions. - **/ - -#include "theory/uf/morgan/theory_uf_morgan.h" -#include "theory/valuation.h" -#include "expr/kind.h" -#include "util/congruence_closure.h" -#include "theory/uf/symmetry_breaker.h" - -#include <map> - -using namespace std; - -using namespace CVC4; -using namespace CVC4::context; -using namespace CVC4::theory; -using namespace CVC4::theory::uf; -using namespace CVC4::theory::uf::morgan; - -TheoryUFMorgan::TheoryUFMorgan(Context* ctxt, OutputChannel& out, Valuation valuation) : - TheoryUF(ctxt, out, valuation), - d_assertions(ctxt), - d_ccChannel(this), - d_cc(ctxt, &d_ccChannel), - d_unionFind(ctxt), - d_disequalities(ctxt), - d_equalities(ctxt), - d_conflict(), - d_trueNode(), - d_falseNode(), - d_trueEqFalseNode(), - d_ccExplanationLength("theory::uf::morgan::cc::averageExplanationLength", - d_cc.getExplanationLength()), - d_ccNewSkolemVars("theory::uf::morgan::cc::newSkolemVariables", - d_cc.getNewSkolemVars()) { - - StatisticsRegistry::registerStat(&d_ccExplanationLength); - StatisticsRegistry::registerStat(&d_ccNewSkolemVars); - - NodeManager* nm = NodeManager::currentNM(); - TypeNode boolType = nm->booleanType(); - d_trueNode = nm->mkVar("TRUE_UF", boolType); - d_falseNode = nm->mkVar("FALSE_UF", boolType); - d_trueEqFalseNode = nm->mkNode(kind::IFF, d_trueNode, d_falseNode); - addDisequality(d_trueEqFalseNode); - d_cc.addTerm(d_trueNode); - d_cc.addTerm(d_falseNode); -} - -TheoryUFMorgan::~TheoryUFMorgan() { - d_trueNode = Node::null(); - d_falseNode = Node::null(); - d_trueEqFalseNode = Node::null(); - - StatisticsRegistry::unregisterStat(&d_ccExplanationLength); - StatisticsRegistry::unregisterStat(&d_ccNewSkolemVars); -} - -void TheoryUFMorgan::preRegisterTerm(TNode n) { - Debug("uf") << "uf: preRegisterTerm(" << n << ")" << endl; - if(n.getKind() == kind::EQUAL || n.getKind() == kind::IFF) { - registerEqualityForPropagation(n); - } -} - -void TheoryUFMorgan::registerTerm(TNode n) { - Debug("uf") << "uf: registerTerm(" << n << ")" << endl; -} - -Node TheoryUFMorgan::constructConflict(TNode diseq) { - Debug("uf") << "uf: begin constructConflict()" << endl; - Debug("uf") << "uf: using diseq == " << diseq << endl; - - Node explanation = d_cc.explain(diseq[0], diseq[1]); - - NodeBuilder<> nb(kind::AND); - if(explanation.getKind() == kind::AND) { - for(TNode::iterator i = TNode(explanation).begin(); - i != TNode(explanation).end(); - ++i) { - TNode n = *i; - Assert(n.getKind() == kind::EQUAL || - n.getKind() == kind::IFF); - Assert(n[0] != d_trueNode && - n[0] != d_falseNode); - if(n[1] == d_trueNode) { - nb << n[0]; - } else if(n[1] == d_falseNode) { - nb << n[0].notNode(); - } else { - nb << n; - } - } - } else { - Assert(explanation.getKind() == kind::EQUAL || - explanation.getKind() == kind::IFF); - Assert(explanation[0] != d_trueNode && - explanation[0] != d_falseNode); - if(explanation[1] == d_trueNode) { - nb << explanation[0]; - } else if(explanation[1] == d_falseNode) { - nb << explanation[0].notNode(); - } else { - nb << explanation; - } - } - if(diseq != d_trueEqFalseNode) { - nb << diseq.notNode(); - } - - // by construction this should be true - Assert(nb.getNumChildren() > 1); - - Node conflict = nb; - Debug("uf") << "conflict constructed : " << conflict << endl; - - Debug("uf") << "uf: ending constructConflict()" << endl; - - return conflict; -} - -void TheoryUFMorgan::notifyCongruent(TNode a, TNode b) { - Debug("uf") << "uf: notified of merge " << a << endl - << " and " << b << endl; - if(!d_conflict.isNull()) { - // if already a conflict, we don't care - return; - } - - merge(a, b); -} - -void TheoryUFMorgan::merge(TNode a, TNode b) { - Assert(d_conflict.isNull()); - - // make "a" the one with shorter diseqList - EqLists::iterator deq_ia = d_disequalities.find(a); - EqLists::iterator deq_ib = d_disequalities.find(b); - if(deq_ia != d_disequalities.end()) { - if(deq_ib == d_disequalities.end() || - (*deq_ia).second->size() > (*deq_ib).second->size()) { - TNode tmp = a; - a = b; - b = tmp; - Debug("uf") << " swapping to make a shorter diseqList" << endl; - } - } - a = find(a); - b = find(b); - Debug("uf") << "uf: uf reps are " << a << endl - << " and " << b << endl; - - if(a == b) { - return; - } - - // should have already found such a conflict - Assert(find(d_trueNode) != find(d_falseNode)); - - d_unionFind.setCanon(a, b); - - EqLists::iterator deq_i = d_disequalities.find(a); - // a set of other trees we are already disequal to, and their - // (TNode) equalities (for optimizations below) - map<TNode, TNode> alreadyDiseqs; - if(deq_i != d_disequalities.end()) { - EqLists::iterator deq_ib = d_disequalities.find(b); - if(deq_ib != d_disequalities.end()) { - EqList* deq = (*deq_ib).second; - for(EqList::const_iterator j = deq->begin(); j != deq->end(); ++j) { - TNode deqn = *j; - TNode s = deqn[0]; - TNode t = deqn[1]; - TNode sp = find(s); - TNode tp = find(t); - Assert(sp == b || tp == b); - if(sp == b) { - alreadyDiseqs[tp] = deqn; - } else { - alreadyDiseqs[sp] = deqn; - } - } - } - - EqList* deq = (*deq_i).second; - if(Debug.isOn("uf")) { - Debug("uf") << "a == " << a << endl; - Debug("uf") << "size of deq(a) is " << deq->size() << endl; - } - for(EqList::const_iterator j = deq->begin(); j != deq->end(); ++j) { - Debug("uf") << " deq(a) ==> " << *j << endl; - TNode deqn = *j; - Assert(deqn.getKind() == kind::EQUAL || - deqn.getKind() == kind::IFF); - TNode s = deqn[0]; - TNode t = deqn[1]; - if(Debug.isOn("uf")) { - Debug("uf") << " s ==> " << s << endl - << " t ==> " << t << endl - << " find(s) ==> " << debugFind(s) << endl - << " find(t) ==> " << debugFind(t) << endl; - } - TNode sp = find(s); - TNode tp = find(t); - if(sp == tp) { - d_conflict = deqn; - return; - } - Assert(sp == b || tp == b); - // optimization: don't put redundant diseq's in the list - if(sp == b) { - if(alreadyDiseqs.find(tp) == alreadyDiseqs.end()) { - appendToDiseqList(b, deqn); - alreadyDiseqs[tp] = deqn; - } - } else { - if(alreadyDiseqs.find(sp) == alreadyDiseqs.end()) { - appendToDiseqList(b, deqn); - alreadyDiseqs[sp] = deqn; - } - } - } - Debug("uf") << "end diseq-list." << endl; - } - - // Note that at this point, alreadyDiseqs contains everything we're - // disequal to, and the attendant disequality - - // FIXME these could be "remembered" and then done in propagation (?) -// EqLists::iterator eq_i = d_equalities.find(a); -// if(eq_i != d_equalities.end()) { -// EqList* eq = (*eq_i).second; -// if(Debug.isOn("uf")) { -// Debug("uf") << "a == " << a << endl; -// Debug("uf") << "size of eq(a) is " << eq->size() << endl; -// } -// for(EqList::const_iterator j = eq->begin(); j != eq->end(); ++j) { -// Debug("uf") << " eq(a) ==> " << *j << endl; -// TNode eqn = *j; -// Assert(eqn.getKind() == kind::EQUAL || -// eqn.getKind() == kind::IFF); -// TNode s = eqn[0]; -// TNode t = eqn[1]; -// if(Debug.isOn("uf")) { -// Debug("uf") << " s ==> " << s << endl -// << " t ==> " << t << endl -// << " find(s) ==> " << debugFind(s) << endl -// << " find(t) ==> " << debugFind(t) << endl; -// } -// TNode sp = find(s); -// TNode tp = find(t); -// if(sp == tp) { -// // propagation of equality -// Debug("uf:prop") << " uf-propagating " << eqn << endl; -// ++d_propagations; -// d_out->propagate(eqn); -// } else { -// Assert(sp == b || tp == b); -// appendToEqList(b, eqn); -// if(sp == b) { -// map<TNode, TNode>::const_iterator k = alreadyDiseqs.find(tp); -// if(k != alreadyDiseqs.end()) { -// // propagation of disequality -// // FIXME: this will propagate the same disequality on every -// // subsequent merge, won't it?? -// Node deqn = (*k).second.notNode(); -// Debug("uf:prop") << " uf-propagating " << deqn << endl; -// ++d_propagations; -// d_out->propagate(deqn); -// } -// } else { -// map<TNode, TNode>::const_iterator k = alreadyDiseqs.find(sp); -// if(k != alreadyDiseqs.end()) { -// // propagation of disequality -// // FIXME: this will propagate the same disequality on every -// // subsequent merge, won't it?? -// Node deqn = (*k).second.notNode(); -// Debug("uf:prop") << " uf-propagating " << deqn << endl; -// ++d_propagations; -// d_out->propagate(deqn); -// } -// } -// } -// } -// Debug("uf") << "end eq-list." << endl; -// } -} - -void TheoryUFMorgan::appendToDiseqList(TNode of, TNode eq) { - Debug("uf") << "appending " << eq << endl - << " to diseq list of " << of << endl; - Assert(eq.getKind() == kind::EQUAL || - eq.getKind() == kind::IFF); - Assert(of == debugFind(of)); - EqLists::iterator deq_i = d_disequalities.find(of); - EqList* deq; - if(deq_i == d_disequalities.end()) { - deq = new(getContext()->getCMM()) EqList(true, getContext(), false, - ContextMemoryAllocator<TNode>(getContext()->getCMM())); - d_disequalities.insertDataFromContextMemory(of, deq); - } else { - deq = (*deq_i).second; - } - deq->push_back(eq); - if(Debug.isOn("uf")) { - Debug("uf") << " size is now " << deq->size() << endl; - } -} - -void TheoryUFMorgan::appendToEqList(TNode of, TNode eq) { - Debug("uf") << "appending " << eq << endl - << " to eq list of " << of << endl; - Assert(eq.getKind() == kind::EQUAL || - eq.getKind() == kind::IFF); - Assert(of == debugFind(of)); - EqLists::iterator eq_i = d_equalities.find(of); - EqList* eql; - if(eq_i == d_equalities.end()) { - eql = new(getContext()->getCMM()) EqList(true, getContext(), false, - ContextMemoryAllocator<TNode>(getContext()->getCMM())); - d_equalities.insertDataFromContextMemory(of, eql); - } else { - eql = (*eq_i).second; - } - eql->push_back(eq); - if(Debug.isOn("uf")) { - Debug("uf") << " size is now " << eql->size() << endl; - } -} - -void TheoryUFMorgan::addDisequality(TNode eq) { - Assert(eq.getKind() == kind::EQUAL || - eq.getKind() == kind::IFF); - - TNode a = eq[0]; - TNode b = eq[1]; - - appendToDiseqList(find(a), eq); - appendToDiseqList(find(b), eq); -} - -void TheoryUFMorgan::registerEqualityForPropagation(TNode eq) { - // should NOT be in search at this point, this must be called during - // preregistration - - // FIXME with lemmas on demand, this could miss future propagations, - // since we are not necessarily at context level 0, but are updating - // context-sensitive structures. - - Assert(eq.getKind() == kind::EQUAL || - eq.getKind() == kind::IFF); - - TNode a = eq[0]; - TNode b = eq[1]; - - appendToEqList(find(a), eq); - appendToEqList(find(b), eq); -} - -void TheoryUFMorgan::check(Effort level) { - TimerStat::CodeTimer codeTimer(d_checkTimer); - - Debug("uf") << "uf: begin check(" << level << ")" << endl; - - while(!done()) { - Assert(d_conflict.isNull()); - - Node assertion = get(); - - //d_activeAssertions.push_back(assertion); - - Debug("uf") << "uf check(): " << assertion << endl; - - switch(assertion.getKind()) { - case kind::EQUAL: - case kind::IFF: - d_cc.addEquality(assertion); - if(!d_conflict.isNull()) { - Node conflict = constructConflict(d_conflict); - d_conflict = Node::null(); - ++d_conflicts; - d_out->conflict(conflict, false); - return; - } - merge(assertion[0], assertion[1]); - break; - case kind::APPLY_UF: - { // predicate - - // assert it's a predicate - Assert(assertion.getOperator().getType().getRangeType().isBoolean()); - - Node eq = NodeManager::currentNM()->mkNode(kind::IFF, - assertion, d_trueNode); - d_cc.addTerm(assertion); - d_cc.addEquality(eq); - - if(!d_conflict.isNull()) { - Node conflict = constructConflict(d_conflict); - d_conflict = Node::null(); - ++d_conflicts; - d_out->conflict(conflict, false); - return; - } - - if(Debug.isOn("uf")) { - Debug("uf") << "true == false ? " - << (find(d_trueNode) == find(d_falseNode)) << endl; - } - - Assert(find(d_trueNode) != find(d_falseNode)); - - merge(eq[0], eq[1]); - } - break; - case kind::NOT: - if(assertion[0].getKind() == kind::EQUAL || - assertion[0].getKind() == kind::IFF) { - Node a = assertion[0][0]; - Node b = assertion[0][1]; - - addDisequality(assertion[0]); - - d_cc.addTerm(a); - d_cc.addTerm(b); - - if(Debug.isOn("uf")) { - Debug("uf") << " a ==> " << a << endl - << " b ==> " << b << endl - << " find(a) ==> " << debugFind(a) << endl - << " find(b) ==> " << debugFind(b) << endl; - } - - // There are two ways to get a conflict here. - if(!d_conflict.isNull()) { - // We get a conflict this way if we weren't watching a, b - // before and we were just now notified (via - // notifyCongruent()) when we called addTerm() above that - // they are congruent. We make this a separate case (even - // though the check in the "else if.." below would also - // catch it, so that we can clear out d_conflict. - Node conflict = constructConflict(d_conflict); - d_conflict = Node::null(); - ++d_conflicts; - d_out->conflict(conflict, false); - return; - } else if(find(a) == find(b)) { - // We get a conflict this way if we WERE previously watching - // a, b and were notified previously (via notifyCongruent()) - // that they were congruent. - Node conflict = constructConflict(assertion[0]); - ++d_conflicts; - d_out->conflict(conflict, false); - return; - } - - // If we get this far, there should be nothing conflicting due - // to this disequality. - Assert(!d_cc.areCongruent(a, b)); - } else { - // negation of a predicate - Assert(assertion[0].getKind() == kind::APPLY_UF); - - // assert it's a predicate - Assert(assertion[0].getOperator().getType().getRangeType().isBoolean()); - - Node eq = NodeManager::currentNM()->mkNode(kind::IFF, - assertion[0], d_falseNode); - d_cc.addTerm(assertion[0]); - d_cc.addEquality(eq); - - if(!d_conflict.isNull()) { - Node conflict = constructConflict(d_conflict); - d_conflict = Node::null(); - ++d_conflicts; - d_out->conflict(conflict, false); - return; - } - - if(Debug.isOn("uf")) { - Debug("uf") << "true == false ? " - << (find(d_trueNode) == find(d_falseNode)) << endl; - } - - Assert(find(d_trueNode) != find(d_falseNode)); - - merge(eq[0], eq[1]); - } - break; - default: - Unhandled(assertion.getKind()); - } - - /* - if(Debug.isOn("uf")) { - dump(); - } - */ - } - Assert(d_conflict.isNull()); - Debug("uf") << "uf check() done = " << (done() ? "true" : "false") - << endl; - - /* - for(CDList<Node>::const_iterator diseqIter = d_disequality.begin(); - diseqIter != d_disequality.end(); - ++diseqIter) { - - TNode left = (*diseqIter)[0]; - TNode right = (*diseqIter)[1]; - if(Debug.isOn("uf")) { - Debug("uf") << "testing left: " << left << endl - << " right: " << right << endl - << " find(L): " << debugFind(left) << endl - << " find(R): " << debugFind(right) << endl - << " areCong: " << d_cc.areCongruent(left, right) - << endl; - } - Assert((debugFind(left) == debugFind(right)) == - d_cc.areCongruent(left, right)); - } - */ - - Debug("uf") << "uf: end check(" << level << ")" << endl; -} - -void TheoryUFMorgan::propagate(Effort level) { - TimerStat::CodeTimer codeTimer(d_propagateTimer); - - Debug("uf") << "uf: begin propagate(" << level << ")" << endl; - // propagation is done in check(), for now - // FIXME need to find a slick way to propagate predicates - Debug("uf") << "uf: end propagate(" << level << ")" << endl; -} - -void TheoryUFMorgan::explain(TNode n) { - TimerStat::CodeTimer codeTimer(d_explainTimer); - - Debug("uf") << "uf: begin explain([" << n << "])" << endl; - Unimplemented(); - Debug("uf") << "uf: end explain([" << n << "])" << endl; -} - -void TheoryUFMorgan::presolve() { - TimerStat::CodeTimer codeTimer(d_presolveTimer); - - Debug("uf") << "uf: begin presolve()" << endl; - if(Options::current()->ufSymmetryBreaker) { - vector<Node> newClauses; - d_symb.apply(newClauses); - for(vector<Node>::const_iterator i = newClauses.begin(); - i != newClauses.end(); - ++i) { - d_out->lemma(*i); - } - } - Debug("uf") << "uf: end presolve()" << endl; -} - -void TheoryUFMorgan::notifyRestart() { - Debug("uf") << "uf: begin notifyDecisionLevelZero()" << endl; - Debug("uf") << "uf: end notifyDecisionLevelZero()" << endl; -} - -Node TheoryUFMorgan::getValue(TNode n) { - NodeManager* nodeManager = NodeManager::currentNM(); - - switch(n.getKind()) { - - case kind::VARIABLE: - case kind::APPLY_UF: - if(n.getType().isBoolean()) { - if(d_cc.areCongruent(d_trueNode, n)) { - return nodeManager->mkConst(true); - } else if(d_cc.areCongruent(d_falseNode, n)) { - return nodeManager->mkConst(false); - } - } - return d_cc.normalize(n); - - case kind::EQUAL: // 2 args - return nodeManager-> - mkConst( d_valuation.getValue(n[0]) == d_valuation.getValue(n[1]) ); - - default: - Unhandled(n.getKind()); - } -} - -void TheoryUFMorgan::staticLearning(TNode n, NodeBuilder<>& learned) { - TimerStat::CodeTimer codeTimer(d_staticLearningTimer); - - vector<TNode> workList; - workList.push_back(n); - __gnu_cxx::hash_set<TNode, TNodeHashFunction> processed; - - while(!workList.empty()) { - n = workList.back(); - - bool unprocessedChildren = false; - for(TNode::iterator i = n.begin(), iend = n.end(); i != iend; ++i) { - if(processed.find(*i) == processed.end()) { - // unprocessed child - workList.push_back(*i); - unprocessedChildren = true; - } - } - - if(unprocessedChildren) { - continue; - } - - workList.pop_back(); - // has node n been processed in the meantime ? - if(processed.find(n) != processed.end()) { - continue; - } - processed.insert(n); - - // == DIAMONDS == - - Debug("diamonds") << "===================== looking at" << endl - << n << endl; - - // binary OR of binary ANDs of EQUALities - if(n.getKind() == kind::OR && n.getNumChildren() == 2 && - n[0].getKind() == kind::AND && n[0].getNumChildren() == 2 && - n[1].getKind() == kind::AND && n[1].getNumChildren() == 2 && - (n[0][0].getKind() == kind::EQUAL || n[0][0].getKind() == kind::IFF) && - (n[0][1].getKind() == kind::EQUAL || n[0][1].getKind() == kind::IFF) && - (n[1][0].getKind() == kind::EQUAL || n[1][0].getKind() == kind::IFF) && - (n[1][1].getKind() == kind::EQUAL || n[1][1].getKind() == kind::IFF)) { - // now we have (a = b && c = d) || (e = f && g = h) - - Debug("diamonds") << "has form of a diamond!" << endl; - - TNode - a = n[0][0][0], b = n[0][0][1], - c = n[0][1][0], d = n[0][1][1], - e = n[1][0][0], f = n[1][0][1], - g = n[1][1][0], h = n[1][1][1]; - - // test that one of {a, b} = one of {c, d}, and make "b" the - // shared node (i.e. put in the form (a = b && b = d)) - // note we don't actually care about the shared ones, so the - // "swaps" below are one-sided, ignoring b and c - if(a == c) { - a = b; - } else if(a == d) { - a = b; - d = c; - } else if(b == c) { - // nothing to do - } else if(b == d) { - d = c; - } else { - // condition not satisfied - Debug("diamonds") << "+ A fails" << endl; - continue; - } - - Debug("diamonds") << "+ A holds" << endl; - - // same: one of {e, f} = one of {g, h}, and make "f" the - // shared node (i.e. put in the form (e = f && f = h)) - if(e == g) { - e = f; - } else if(e == h) { - e = f; - h = g; - } else if(f == g) { - // nothing to do - } else if(f == h) { - h = g; - } else { - // condition not satisfied - Debug("diamonds") << "+ B fails" << endl; - continue; - } - - Debug("diamonds") << "+ B holds" << endl; - - // now we have (a = b && b = d) || (e = f && f = h) - // test that {a, d} == {e, h} - if( (a == e && d == h) || - (a == h && d == e) ) { - // learn: n implies a == d - Debug("diamonds") << "+ C holds" << endl; - Node newEquality = a.getType().isBoolean() ? a.iffNode(d) : a.eqNode(d); - Debug("diamonds") << " ==> " << newEquality << endl; - learned << n.impNode(newEquality); - } else { - Debug("diamonds") << "+ C fails" << endl; - } - } - } - - if(Options::current()->ufSymmetryBreaker) { - d_symb.assertFormula(n); - } -} - -/* -void TheoryUFMorgan::dump() { - if(!Debug.isOn("uf")) { - return; - } - Debug("uf") << "============== THEORY_UF ==============" << endl; - Debug("uf") << "Active assertions list:" << endl; - for(context::CDList<Node>::const_iterator i = d_activeAssertions.begin(); - i != d_activeAssertions.end(); - ++i) { - Debug("uf") << " " << *i << endl; - } - Debug("uf") << "Congruence union-find:" << endl; - for(UnionFind::const_iterator i = d_unionFind.begin(); - i != d_unionFind.end(); - ++i) { - Debug("uf") << " " << (*i).first << " ==> " << (*i).second - << endl; - } - Debug("uf") << "Disequality lists:" << endl; - for(EqLists::const_iterator i = d_disequalities.begin(); - i != d_disequalities.end(); - ++i) { - Debug("uf") << " " << (*i).first << ":" << endl; - EqList* dl = (*i).second; - for(EqList::const_iterator j = dl->begin(); - j != dl->end(); - ++j) { - Debug("uf") << " " << *j << endl; - } - } - Debug("uf") << "=======================================" << endl; -} -*/ diff --git a/src/theory/uf/morgan/theory_uf_morgan.h b/src/theory/uf/morgan/theory_uf_morgan.h deleted file mode 100644 index e801f383e..000000000 --- a/src/theory/uf/morgan/theory_uf_morgan.h +++ /dev/null @@ -1,267 +0,0 @@ -/********************* */ -/*! \file theory_uf_morgan.h - ** \verbatim - ** Original author: taking - ** Major contributors: mdeters - ** 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.\endverbatim - ** - ** \brief Implementation of the theory of uninterpreted functions with - ** equality - ** - ** Implementation of the theory of uninterpreted functions with equality, - ** based on CVC4's congruence closure module (which is in turn based on - ** the Nieuwenhuis and Oliveras paper, Fast Congruence Closure and - ** Extensions. - **/ - -#include "cvc4_private.h" - -#ifndef __CVC4__THEORY__UF__MORGAN__THEORY_UF_MORGAN_H -#define __CVC4__THEORY__UF__MORGAN__THEORY_UF_MORGAN_H - -#include "expr/node.h" -#include "expr/attribute.h" - -#include "theory/theory.h" -#include "theory/uf/theory_uf.h" -#include "theory/uf/morgan/union_find.h" -#include "theory/uf/symmetry_breaker.h" - -#include "context/context.h" -#include "context/context_mm.h" -#include "context/cdlist.h" -#include "util/congruence_closure.h" - -namespace CVC4 { -namespace theory { -namespace uf { -namespace morgan { - -class TheoryUFMorgan : public TheoryUF { - -private: - - class CongruenceChannel { - TheoryUFMorgan* d_uf; - - public: - CongruenceChannel(TheoryUFMorgan* uf) : d_uf(uf) {} - void notifyCongruent(TNode a, TNode b) { - d_uf->notifyCongruent(a, b); - } - };/* class CongruenceChannel */ - friend class CongruenceChannel; - - /** - * List of all of the non-negated literals from the assertion queue. - * This is used only for conflict generation. - * This differs from pending as the program generates new equalities that - * are not in this list. - * This will probably be phased out in future version. - */ - context::CDList<Node> d_assertions; - - SymmetryBreaker d_symb; - - /** - * Our channel connected to the congruence closure module. - */ - CongruenceChannel d_ccChannel; - - /** - * Instance of the congruence closure module. - */ - CongruenceClosure<CongruenceChannel, CongruenceOperator<kind::APPLY_UF> > d_cc; - - /** - * Our union find for equalities. - */ - UnionFind<TNode, TNodeHashFunction> d_unionFind; - - typedef context::CDList<TNode, context::ContextMemoryAllocator<TNode> > EqList; - typedef context::CDMap<Node, EqList*, NodeHashFunction> EqLists; - - /** List of all disequalities this theory has seen. */ - EqLists d_disequalities; - - /** List of all (potential) equalities to be propagated. */ - EqLists d_equalities; - - Node d_conflict; - - Node d_trueNode, d_falseNode, d_trueEqFalseNode; - - // === STATISTICS === - /** time spent in check() */ - KEEP_STATISTIC(TimerStat, - d_checkTimer, - "theory::uf::morgan::checkTime"); - /** time spent in propagate() */ - KEEP_STATISTIC(TimerStat, - d_propagateTimer, - "theory::uf::morgan::propagateTime"); - - /** time spent in explain() */ - KEEP_STATISTIC(TimerStat, - d_explainTimer, - "theory::uf::morgan::explainTime"); - /** time spent in staticLearning() */ - KEEP_STATISTIC(TimerStat, - d_staticLearningTimer, - "theory::uf::morgan::staticLearningTime"); - /** time spent in presolve() */ - KEEP_STATISTIC(TimerStat, - d_presolveTimer, - "theory::uf::morgan::presolveTime"); - /** number of UF conflicts */ - KEEP_STATISTIC(IntStat, - d_conflicts, - "theory::uf::morgan::conflicts", 0); - /** number of UF propagations */ - KEEP_STATISTIC(IntStat, - d_propagations, - "theory::uf::morgan::propagations", 0); - /** CC module expl length */ - WrappedStat<AverageStat> d_ccExplanationLength; - /** CC module # skolem vars */ - WrappedStat<IntStat> d_ccNewSkolemVars; - -public: - - /** Constructs a new instance of TheoryUF w.r.t. the provided context.*/ - TheoryUFMorgan(context::Context* ctxt, OutputChannel& out, Valuation valuation); - - /** Destructor for UF theory, cleans up memory and statistics. */ - ~TheoryUFMorgan(); - - /** - * Registers a previously unseen [in this context] node n. - * For TheoryUF, this sets up and maintains invaraints about - * equivalence class data-structures. - * - * Overloads a void registerTerm(TNode n); from theory.h. - * See theory/theory.h for more information about this method. - */ - void registerTerm(TNode n); - - /** - * Currently this does nothing. - * - * Overloads a void preRegisterTerm(TNode n); from theory.h. - * See theory/theory.h for more information about this method. - */ - void preRegisterTerm(TNode n); - - /** - * Checks whether the set of literals provided to the theory is consistent. - * - * If this is called at any effort level, it computes the congruence closure - * of all of the positive literals in the context. - * - * If this is called at full effort it checks if any of the negative literals - * are inconsistent with the congruence closure. - * - * Overloads void check(Effort level); from theory.h. - * See theory/theory.h for more information about this method. - */ - void check(Effort level); - - /** - * Propagates theory literals. - * - * Overloads void propagate(Effort level); from theory.h. - * See theory/theory.h for more information about this method. - */ - void propagate(Effort level); - - /** - * Explains a previously theory-propagated literal. - * - * Overloads void explain(TNode n, Effort level); from theory.h. - * See theory/theory.h for more information about this method. - */ - void explain(TNode n); - - /** - * The theory should only add (via .operator<< or .append()) to the - * "learned" builder. It is a conjunction to add to the formula at - * the top-level and may contain other theories' contributions. - */ - void staticLearning(TNode in, NodeBuilder<>& learned); - - /** - * A Theory is called with presolve exactly one time per user - * check-sat. presolve() is called after preregistration, - * rewriting, and Boolean propagation, (other theories' - * propagation?), but the notified Theory has not yet had its - * check() or propagate() method called. A Theory may empty its - * assertFact() queue using get(). A Theory can raise conflicts, - * add lemmas, and propagate literals during presolve(). - */ - void presolve(); - - /** - * Notification sent to the Theory when the search restarts. - */ - void notifyRestart(); - - /** - * Gets a theory value. - * - * Overloads Node getValue(TNode n); from theory.h. - * See theory/theory.h for more information about this method. - */ - Node getValue(TNode n); - - std::string identify() const { return std::string("TheoryUFMorgan"); } - -private: - - /** Constructs a conflict from an inconsistent disequality. */ - Node constructConflict(TNode diseq); - - inline TNode find(TNode a); - inline TNode debugFind(TNode a) const; - - void appendToDiseqList(TNode of, TNode eq); - void appendToEqList(TNode of, TNode eq); - void addDisequality(TNode eq); - void registerEqualityForPropagation(TNode eq); - - /** - * Receives a notification from the congruence closure module that - * two nodes have been merged into the same congruence class. - */ - void notifyCongruent(TNode a, TNode b); - - /** - * Internally handle a congruence, whether generated by the CC - * module or from a theory check(). Merges the classes from a and b - * and looks for a conflict. If there is one, sets d_conflict. - */ - void merge(TNode a, TNode b); - - void dump(); - -};/* class TheoryUFMorgan */ - -inline TNode TheoryUFMorgan::find(TNode a) { - return d_unionFind.find(a); -} - -inline TNode TheoryUFMorgan::debugFind(TNode a) const { - return d_unionFind.debugFind(a); -} - -}/* CVC4::theory::uf::morgan namespace */ -}/* CVC4::theory::uf namespace */ -}/* CVC4::theory namespace */ -}/* CVC4 namespace */ - -#endif /* __CVC4__THEORY__UF__MORGAN__THEORY_UF_MORGAN_H */ diff --git a/src/theory/uf/morgan/union_find.cpp b/src/theory/uf/morgan/union_find.cpp deleted file mode 100644 index 135320707..000000000 --- a/src/theory/uf/morgan/union_find.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/********************* */ -/*! \file union_find.cpp - ** \verbatim - ** 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.\endverbatim - ** - ** \brief Path-compressing, backtrackable union-find using an undo - ** stack - ** - ** Path-compressing, backtrackable union-find using an undo stack - ** rather than storing items in a CDMap<>. - **/ - -#include <iostream> - -#include "theory/uf/morgan/union_find.h" -#include "util/Assert.h" -#include "expr/node.h" - -using namespace std; - -namespace CVC4 { -namespace theory { -namespace uf { -namespace morgan { - -template <class NodeType, class NodeHash> -void UnionFind<NodeType, NodeHash>::notify() { - Trace("ufuf") << "UFUF cancelling : " << d_offset << " < " << d_trace.size() << " ?" << endl; - while(d_offset < d_trace.size()) { - pair<TNode, TNode> p = d_trace.back(); - if(p.second.isNull()) { - d_map.erase(p.first); - Trace("ufuf") << "UFUF " << d_trace.size() << " erasing " << p.first << endl; - } else { - d_map[p.first] = p.second; - Trace("ufuf") << "UFUF " << d_trace.size() << " replacing " << p << endl; - } - d_trace.pop_back(); - } - Trace("ufuf") << "UFUF cancelling finished." << endl; -} - -// The following declarations allow us to put functions in the .cpp file -// instead of the header, since we know which instantiations are needed. - -template void UnionFind<Node, NodeHashFunction>::notify(); - -template void UnionFind<TNode, TNodeHashFunction>::notify(); - -}/* CVC4::theory::uf::morgan namespace */ -}/* CVC4::theory::uf namespace */ -}/* CVC4::theory namespace */ -}/* CVC4 namespace */ diff --git a/src/theory/uf/morgan/union_find.h b/src/theory/uf/morgan/union_find.h deleted file mode 100644 index 794d7452c..000000000 --- a/src/theory/uf/morgan/union_find.h +++ /dev/null @@ -1,148 +0,0 @@ -/********************* */ -/*! \file union_find.h - ** \verbatim - ** 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.\endverbatim - ** - ** \brief Path-compressing, backtrackable union-find using an undo - ** stack - ** - ** Path-compressing, backtrackable union-find using an undo stack - ** rather than storing items in a CDMap<>. - **/ - -#include "cvc4_private.h" - -#ifndef __CVC4__THEORY__UF__MORGAN__UNION_FIND_H -#define __CVC4__THEORY__UF__MORGAN__UNION_FIND_H - -#include <utility> -#include <vector> -#include <ext/hash_map> - -#include "expr/node.h" -#include "context/cdo.h" - -namespace CVC4 { - -namespace context { - class Context; -}/* CVC4::context namespace */ - -namespace theory { -namespace uf { -namespace morgan { - -// NodeType \in { Node, TNode } -template <class NodeType, class NodeHash> -class UnionFind : context::ContextNotifyObj { - /** Our underlying map type. */ - typedef __gnu_cxx::hash_map<NodeType, NodeType, NodeHash> MapType; - - /** - * Our map of Nodes to their canonical representatives. - * If a Node is not present in the map, it is its own - * representative. - */ - MapType d_map; - - /** Our undo stack for changes made to d_map. */ - std::vector<std::pair<TNode, TNode> > d_trace; - - /** Our current offset in the d_trace stack (context-dependent). */ - context::CDO<size_t> d_offset; - -public: - UnionFind(context::Context* ctxt) : - context::ContextNotifyObj(ctxt), - d_offset(ctxt, 0) { - } - - ~UnionFind() throw() { } - - /** - * Return a Node's union-find representative, doing path compression. - */ - inline TNode find(TNode n); - - /** - * Return a Node's union-find representative, NOT doing path compression. - * This is useful for Assert() statements, debug checking, and similar - * things that you do NOT want to mutate the structure. - */ - inline TNode debugFind(TNode n) const; - - /** - * Set the canonical representative of n to newParent. They should BOTH - * be their own canonical representatives on entry to this funciton. - */ - inline void setCanon(TNode n, TNode newParent); - - /** - * Called by the Context when a pop occurs. Cancels everything to the - * current context level. Overrides ContextNotifyObj::notify(). - */ - void notify(); - -};/* class UnionFind<> */ - -template <class NodeType, class NodeHash> -inline TNode UnionFind<NodeType, NodeHash>::debugFind(TNode n) const { - typename MapType::const_iterator i = d_map.find(n); - if(i == d_map.end()) { - return n; - } else { - return debugFind((*i).second); - } -} - -template <class NodeType, class NodeHash> -inline TNode UnionFind<NodeType, NodeHash>::find(TNode n) { - Trace("ufuf") << "UFUF find of " << n << std::endl; - typename MapType::iterator i = d_map.find(n); - if(i == d_map.end()) { - Trace("ufuf") << "UFUF it is rep" << std::endl; - return n; - } else { - Trace("ufuf") << "UFUF not rep: par is " << (*i).second << std::endl; - std::pair<TNode, TNode> pr = *i; - // our iterator is invalidated by the recursive call to find(), - // since it mutates the map - TNode p = find(pr.second); - if(p == pr.second) { - return p; - } - d_trace.push_back(std::make_pair(n, pr.second)); - d_offset = d_trace.size(); - Trace("ufuf") << "UFUF setting canon of " << n << " : " << p << " @ " << d_trace.size() << std::endl; - pr.second = p; - d_map.insert(pr); - return p; - } -} - -template <class NodeType, class NodeHash> -inline void UnionFind<NodeType, NodeHash>::setCanon(TNode n, TNode newParent) { - Assert(d_map.find(n) == d_map.end()); - Assert(d_map.find(newParent) == d_map.end()); - if(n != newParent) { - Trace("ufuf") << "UFUF setting canon of " << n << " : " << newParent << " @ " << d_trace.size() << std::endl; - d_map[n] = newParent; - d_trace.push_back(std::make_pair(n, TNode::null())); - d_offset = d_trace.size(); - } -} - -}/* CVC4::theory::uf::morgan namespace */ -}/* CVC4::theory::uf namespace */ -}/* CVC4::theory namespace */ -}/* CVC4 namespace */ - -#endif /*__CVC4__THEORY__UF__MORGAN__UNION_FIND_H */ diff --git a/src/theory/uf/theory_uf.cpp b/src/theory/uf/theory_uf.cpp index 3c8d59d08..401c18203 100644 --- a/src/theory/uf/theory_uf.cpp +++ b/src/theory/uf/theory_uf.cpp @@ -2,10 +2,10 @@ /*! \file theory_uf.cpp ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/uf/theory_uf.h b/src/theory/uf/theory_uf.h index de8e70a49..1f4c2372f 100644 --- a/src/theory/uf/theory_uf.h +++ b/src/theory/uf/theory_uf.h @@ -1,11 +1,11 @@ /********************* */ /*! \file theory_uf.h ** \verbatim - ** Original author: dejan - ** Major contributors: none + ** Original author: mdeters + ** Major contributors: dejan ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/uf/theory_uf_rewriter.h b/src/theory/uf/theory_uf_rewriter.h index ee88df126..e1aba2c95 100644 --- a/src/theory/uf/theory_uf_rewriter.h +++ b/src/theory/uf/theory_uf_rewriter.h @@ -2,7 +2,7 @@ /*! \file theory_uf_rewriter.h ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/theory/uf/theory_uf_type_rules.h b/src/theory/uf/theory_uf_type_rules.h index 7a4bf721f..927a31e01 100644 --- a/src/theory/uf/theory_uf_type_rules.h +++ b/src/theory/uf/theory_uf_type_rules.h @@ -5,7 +5,7 @@ ** Major contributors: cconway, mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/theory/uf/tim/Makefile b/src/theory/uf/tim/Makefile deleted file mode 100644 index e1db2cbf9..000000000 --- a/src/theory/uf/tim/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -topdir = ../../../.. -srcdir = src/theory/uf/tim - -include $(topdir)/Makefile.subdir diff --git a/src/theory/uf/tim/Makefile.am b/src/theory/uf/tim/Makefile.am deleted file mode 100644 index 647783885..000000000 --- a/src/theory/uf/tim/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -AM_CPPFLAGS = \ - -D__BUILDING_CVC4LIB \ - -I@srcdir@/../../../include -I@srcdir@/../../.. -I@builddir@/../../.. -AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) - -noinst_LTLIBRARIES = libuftim.la - -libuftim_la_SOURCES = \ - ecdata.h \ - ecdata.cpp \ - theory_uf_tim.h \ - theory_uf_tim.cpp - -EXTRA_DIST = diff --git a/src/theory/uf/tim/ecdata.cpp b/src/theory/uf/tim/ecdata.cpp deleted file mode 100644 index 52a110ff2..000000000 --- a/src/theory/uf/tim/ecdata.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/********************* */ -/*! \file ecdata.cpp - ** \verbatim - ** Original author: taking - ** Major contributors: mdeters - ** 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.\endverbatim - ** - ** \brief Implementation of equivalence class data for UF theory. - ** - ** Implementation of equivalence class data for UF theory. This is a - ** context-dependent object. - **/ - -#include "theory/uf/tim/ecdata.h" - -using namespace CVC4; -using namespace CVC4::context; -using namespace CVC4::theory; -using namespace CVC4::theory::uf; -using namespace CVC4::theory::uf::tim; - -ECData::ECData(Context * context, TNode n) : - ContextObj(context), - d_find(this), - d_rep(n), - d_watchListSize(0), - d_first(NULL), - d_last(NULL) { -} - -bool ECData::isClassRep() { - return this == this->d_find; -} - -void ECData::addPredecessor(TNode n) { - Assert(isClassRep()); - - makeCurrent(); - - Link * newPred = new(getCMM()) Link(getContext(), n, d_first); - d_first = newPred; - if(d_last == NULL) { - d_last = newPred; - } - - ++d_watchListSize; -} - -ContextObj* ECData::save(ContextMemoryManager* pCMM) { - return new(pCMM) ECData(*this); -} - -void ECData::restore(ContextObj* pContextObj) { - ECData* data = (ECData*)pContextObj; - d_find = data->d_find; - d_first = data->d_first; - d_last = data->d_last; - d_rep = data->d_rep; - d_watchListSize = data->d_watchListSize; -} - -Node ECData::getRep() { - return d_rep; -} - -unsigned ECData::getWatchListSize() { - return d_watchListSize; -} - -void ECData::setFind(ECData * ec) { - makeCurrent(); - d_find = ec; -} - -ECData* ECData::getFind() { - return d_find; -} - -Link* ECData::getFirst() { - return d_first; -} - -void ECData::takeOverDescendantWatchList(ECData* nslave, ECData* nmaster) { - Assert(nslave != nmaster); - Assert(nslave->getFind() == nmaster); - - nmaster->makeCurrent(); - - nmaster->d_watchListSize += nslave->d_watchListSize; - - if(nmaster->d_first == NULL) { - nmaster->d_first = nslave->d_first; - nmaster->d_last = nslave->d_last; - } else if(nslave->d_first != NULL) { - Link* currLast = nmaster->d_last; - currLast->d_next = nslave->d_first; - nmaster->d_last = nslave->d_last; - } -} diff --git a/src/theory/uf/tim/ecdata.h b/src/theory/uf/tim/ecdata.h deleted file mode 100644 index 5e72f0042..000000000 --- a/src/theory/uf/tim/ecdata.h +++ /dev/null @@ -1,261 +0,0 @@ -/********************* */ -/*! \file ecdata.h - ** \verbatim - ** Original author: taking - ** Major contributors: mdeters - ** 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.\endverbatim - ** - ** \brief Context dependent equivalence class datastructure for nodes. - ** - ** Context dependent equivalence class datastructure for nodes. - ** Currently keeps a context dependent watch list. - **/ - -#include "cvc4_private.h" - -#ifndef __CVC4__THEORY__UF__TIM__ECDATA_H -#define __CVC4__THEORY__UF__TIM__ECDATA_H - -#include "expr/node.h" -#include "context/context.h" -#include "context/cdo.h" -#include "context/context_mm.h" - -namespace CVC4 { -namespace theory { -namespace uf { -namespace tim { - -/** - * Link is a context dependent linked list of nodes. - * Link is intended to be allocated in a Context's memory manager. - * The next pointer of the list is context dependent, but the node being - * pointed to is fixed for the life of the Link. - * - * Clients of Link are intended not to modify the node that is being pointed - * to in good faith. This may change in the future. - */ -struct Link { - /** - * Pointer to the next element in linked list. - * This is context dependent. - */ - context::CDO<Link*> d_next; - - /** - * Link is supposed to be allocated in a region of a - * ContextMemoryManager. In order to avoid having to decrement the - * ref count at deletion time, it is preferrable for the user of - * Link to maintain the invariant that data will survival for the - * entire scope of the TNode. - */ - TNode d_data; - - /** - * Creates a new Link w.r.t. a context for the node n. - * An optional parameter is to specify the next element in the link. - */ - Link(context::Context* context, TNode n, Link* l = NULL) : - d_next(true, context, l), - d_data(n) { - Debug("context") << "Link: " << this - << " so cdo is " << &d_next << std::endl; - } - - /** - * Allocates a new Link in the region for the provided ContextMemoryManager. - * This allows for cheap cleanup on pop. - */ - static void* operator new(size_t size, context::ContextMemoryManager* pCMM) { - return pCMM->newData(size); - } - -private: - - /** - * The destructor isn't actually defined. This declaration keeps - * the compiler from creating (wastefully) a default definition, and - * ensures that we get a link error if someone uses Link in a way - * that requires destruction. Objects of class Link should always - * be allocated in a ContextMemoryManager, which doesn't call - * destructors. - */ - ~Link() throw(); - - /** - * Just like the destructor, this is not defined. This ensures no - * one tries to create a Link on the heap. - */ - static void* operator new(size_t size); - -};/* struct Link */ - - -/** - * ECData is a equivalence class object that is context dependent. - * It is developed in order to support the congruence closure algorithm - * in TheoryUF, and is not intended to be used outside of that package. - * - * ECData maintains: - * - find pointer for the equivalence class (disjoint set forest) - * - the node that represents the equivalence class. - * - maintains a predecessorlist/watchlist - * - * ECData does not have support for the canonical find and union operators - * for disjoint set forests. Instead it only provides access to the find - * pointer. The implementation of find is ccFind in TheoryUF. - * union is broken into 2 phases: - * 1) setting the find point with setFind - * 2) taking over the watch list of the other node. - * This is a technical requirement for the implementation of TheoryUF. - * (See ccUnion in TheoryUF for more information.) - * - * The intended paradigm for iterating over the watch list of ec is: - * for(Link* i = ec->getFirst(); i != NULL; i = i->next ); - * - * See also ECAttr() in theory_uf.h, and theory_uf.cpp where the codde that uses - * ECData lives. - */ -class ECData : public context::ContextObj { -private: - /** - * This is the standard disjoint set forest find pointer. - * - * Why an ECData pointer instead of a node? - * This was chosen to be a ECData pointer in order to shortcut at least one - * table every time the find pointer is examined. - */ - ECData* d_find; - - /** - * This is pointer back to the node that represents this equivalence class. - * - * The following invariant should be maintained: - * (n.getAttribute(ECAttr()))->rep == n - * i.e. rep is equal to the node that maps to the ECData using ECAttr. - * - * Tricky part: This needs to be a TNode, not a Node. - * Suppose that rep were a hard link. - * When a node n maps to an ECData via the ECAttr() there will be a hard - * link back to n in the ECData. The attribute does not do garbage collection - * until the node gets garbage collected, which does not happen until its - * ref count drops to 0. So because of this cycle neither the node and - * the ECData will never get garbage collected. - * So this needs to be a soft link. - */ - TNode d_rep; - - // Watch list data structures follow - - /** - * Maintains watch list size for more efficient merging. - */ - unsigned d_watchListSize; - - /** - * Pointer to the beginning of the watchlist. - * This value is NULL iff the watch list is empty. - */ - Link* d_first; - - /** - * Pointer to the end of the watch-list. - * This is maintained in order to constant time list merging. - * (This does not give any asymptotic improve as this is currently always - * preceeded by an O(|watchlist|) operation.) - * This value is NULL iff the watch list is empty. - */ - Link* d_last; - - /** Context-dependent operation: save this ECData */ - context::ContextObj* save(context::ContextMemoryManager* pCMM); - - /** Context-dependent operation: restore this ECData */ - void restore(context::ContextObj* pContextObj); - -public: - /** - * Returns true if this ECData object is the current representative of - * the equivalence class. - */ - bool isClassRep(); - - /** - * Adds a node to the watch list of the equivalence class. Does - * context-dependent memory allocation in the Context with which - * this ECData was created. - * - * @param n the node to be added. - * @pre isClassRep() == true - */ - void addPredecessor(TNode n); - - /** - * Creates a EQ with the representative n - * @param context the context to associate with this ecdata. - * This is required as ECData is context dependent - * @param n the node that corresponds to this ECData - */ - ECData(context::Context* context, TNode n); - - /** Destructor for ECDatas */ - ~ECData() { - Debug("ufgc") << "Calling ECData destructor" << std::endl; - destroy(); - } - - /** - * An ECData takes over the watch list of another ECData. - * This is the second step in the union operator for ECData. - * This should be called after nslave->setFind(nmaster); - * After this is done nslave's watch list should never be accessed by - * getLast() or getFirst() - */ - static void takeOverDescendantWatchList(ECData * nslave, ECData * nmaster); - - /** - * Returns the representative of this ECData. - */ - Node getRep(); - - /** - * Returns the size of the equivalence class. - */ - unsigned getWatchListSize(); - - /** - * Returns a pointer the first member of the watch list. - */ - Link* getFirst(); - - - /** - * Returns the find pointer of the ECData. - * If isClassRep(), then getFind() == this - */ - ECData* getFind(); - - /** - * Sets the find pointer of the equivalence class to be another ECData object. - * - * @pre isClassRep() == true - * @pre ec->isClassRep() == true - * @post isClassRep() == false - * @post ec->isClassRep() == true - */ - void setFind(ECData * ec); - -};/* class ECData */ - -}/* CVC4::theory::uf::tim namespace */ -}/* CVC4::theory::uf namespace */ -}/* CVC4::theory namespace */ -}/* CVC4 namespace */ - -#endif /* __CVC4__THEORY__UF__TIM__ECDATA_H */ diff --git a/src/theory/uf/tim/theory_uf_tim.cpp b/src/theory/uf/tim/theory_uf_tim.cpp deleted file mode 100644 index ae37dfe99..000000000 --- a/src/theory/uf/tim/theory_uf_tim.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/********************* */ -/*! \file theory_uf_tim.cpp - ** \verbatim - ** Original author: taking - ** Major contributors: mdeters - ** Minor contributors (to current version): dejan - ** 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.\endverbatim - ** - ** \brief Implementation of the theory of uninterpreted functions. - ** - ** Implementation of the theory of uninterpreted functions. - **/ - -#include "theory/uf/tim/theory_uf_tim.h" -#include "theory/uf/tim/ecdata.h" -#include "expr/kind.h" - -using namespace CVC4; -using namespace CVC4::kind; -using namespace CVC4::context; -using namespace CVC4::theory; -using namespace CVC4::theory::uf; -using namespace CVC4::theory::uf::tim; - -TheoryUFTim::TheoryUFTim(Context* c, OutputChannel& out, Valuation valuation) : - TheoryUF(c, out, valuation), - d_assertions(c), - d_pending(c), - d_currentPendingIdx(c,0), - d_disequality(c), - d_registered(c) { - Warning() << "NOTE:" << std::endl - << "NOTE: currently the 'Tim' UF solver is broken," << std::endl - << "NOTE: since its registerTerm() function is never" << std::endl - << "NOTE: called." << std::endl - << "NOTE:" << std::endl; -} - -TheoryUFTim::~TheoryUFTim() { -} - -void TheoryUFTim::preRegisterTerm(TNode n) { - Debug("uf") << "uf: begin preRegisterTerm(" << n << ")" << std::endl; - Debug("uf") << "uf: end preRegisterTerm(" << n << ")" << std::endl; -} - -void TheoryUFTim::registerTerm(TNode n) { - - Debug("uf") << "uf: begin registerTerm(" << n << ")" << std::endl; - - d_registered.push_back(n); - - ECData* 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, - * then it must be the case that this attribute was created in a previous - * and no longer valid context. Because of this we have to reregister the - * predecessors lists. - * Also we do not have to worry about duplicates because all of the Link* - * setup before are removed when the context n was setup in was popped out - * of. All we are going to do here are sanity checks. - */ - - /* - * Consider the following chain of events: - * 1) registerTerm(n) is called on node n where n : f(m) in context level X, - * 2) A new ECData is created on the heap, ecN, - * 3) n is added to the predessecor list of m in context level X, - * 4) We pop out of X, - * 5) n is removed from the predessecor list of m because this is context - * dependent, the Link* will be destroyed and pointers to the Link - * structs in the ECData objects will be updated. - * 6) registerTerm(n) is called on node n in context level Y, - * 7) If n.hasAttribute(ECAttr(), &ecN), then ecN is still around, - * but the predecessor list is not - * - * The above assumes that the code is working correctly. - */ - Assert(ecN->getFirst() == NULL, - "Equivalence class data exists for the node being registered. " - "Expected getFirst() == NULL. " - "This data is either already in use or was not properly maintained " - "during backtracking"); - /*Assert(ecN->getLast() == NULL, - "Equivalence class data exists for the node being registered. " - "Expected getLast() == NULL. " - "This data is either already in use or was not properly maintained " - "during backtracking.");*/ - Assert(ecN->isClassRep(), - "Equivalence class data exists for the node being registered. " - "Expected isClassRep() to be true. " - "This data is either already in use or was not properly maintained " - "during backtracking"); - Assert(ecN->getWatchListSize() == 0, - "Equivalence class data exists for the node being registered. " - "Expected getWatchListSize() == 0. " - "This data is either already in use or was not properly maintained " - "during backtracking"); - } else { - //The attribute does not exist, so it is created and set - ecN = new (true) ECData(getContext(), n); - n.setAttribute(ECAttr(), ecN); - } - - /* If the node is an APPLY_UF, we need to add it to the predecessor list - * of its children. - */ - if(n.getKind() == APPLY_UF) { - TNode::iterator cIter = n.begin(); - - for(; cIter != n.end(); ++cIter) { - TNode child = *cIter; - - /* Because this can be called after nodes have been merged, we need - * to lookup the representative in the UnionFind datastructure. - */ - ECData* ecChild = ccFind(child.getAttribute(ECAttr())); - - /* 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)) { - Node pend = n.eqNode(Px->d_data); - d_pending.push_back(pend); - } - } - - ecChild->addPredecessor(n); - } - } - Debug("uf") << "uf: end registerTerm(" << n << ")" << std::endl; - -} - -bool TheoryUFTim::sameCongruenceClass(TNode x, TNode y) { - return - ccFind(x.getAttribute(ECAttr())) == - ccFind(y.getAttribute(ECAttr())); -} - -bool TheoryUFTim::equiv(TNode x, TNode y) { - Assert(x.getKind() == kind::APPLY_UF); - Assert(y.getKind() == kind::APPLY_UF); - - if(x.getNumChildren() != y.getNumChildren()) { - return false; - } - - 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()) { - - if(!sameCongruenceClass(*xIter, *yIter)) { - return false; - } - - ++xIter; - ++yIter; - } - return true; -} - -/* This is a very basic, but *obviously correct* find implementation - * of the classic find algorithm. - * TODO after we have done some more testing: - * 1) Add path compression. This is dependent on changes to ccUnion as - * many better algorithms use eager path compression. - * 2) Elminate recursion. - */ -ECData* TheoryUFTim::ccFind(ECData * x) { - if(x->getFind() == x) { - return x; - } else { - return ccFind(x->getFind()); - } - /* Slightly better Find w/ path compression and no recursion*/ - /* - ECData* start; - ECData* next = x; - while(x != x->getFind()) x=x->getRep(); - while( (start = next) != x) { - next = start->getFind(); - start->setFind(x); - } - return x; - */ -} - -void TheoryUFTim::ccUnion(ECData* ecX, ECData* ecY) { - ECData* nslave; - ECData* nmaster; - - if(ecX->getWatchListSize() <= ecY->getWatchListSize()) { - nslave = ecX; - nmaster = ecY; - } 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)) { - Node pendingEq = (Px->d_data).eqNode(Py->d_data); - d_pending.push_back(pendingEq); - } - } - } - - ECData::takeOverDescendantWatchList(nslave, nmaster); -} - -void TheoryUFTim::merge() { - while(d_currentPendingIdx < d_pending.size() ) { - Node assertion = d_pending[d_currentPendingIdx]; - d_currentPendingIdx = d_currentPendingIdx + 1; - - TNode x = assertion[0]; - TNode y = assertion[1]; - - ECData* tmpX = x.getAttribute(ECAttr()); - ECData* tmpY = y.getAttribute(ECAttr()); - - ECData* ecX = ccFind(tmpX); - ECData* ecY = ccFind(tmpY); - if(ecX == ecY) - continue; - - Debug("uf") << "merging equivalence classes for " << std::endl; - Debug("uf") << "left equivalence class :" << (ecX->getRep()) << std::endl; - Debug("uf") << "right equivalence class :" << (ecY->getRep()) << std::endl; - Debug("uf") << std::endl; - - ccUnion(ecX, ecY); - } -} - -Node TheoryUFTim::constructConflict(TNode diseq) { - Debug("uf") << "uf: begin constructConflict()" << std::endl; - - NodeBuilder<> nb(kind::AND); - nb << diseq; - for(unsigned i = 0; i < d_assertions.size(); ++i) { - nb << d_assertions[i]; - } - - Assert(nb.getNumChildren() > 0); - Node conflict = nb.getNumChildren() == 1 ? nb[0] : nb; - - Debug("uf") << "conflict constructed : " << conflict << std::endl; - - Debug("uf") << "uf: ending constructConflict()" << std::endl; - - return conflict; -} - -void TheoryUFTim::check(Effort level) { - - Debug("uf") << "uf: begin check(" << level << ")" << std::endl; - - while(!done()) { - Node assertion = get(); - Debug("uf") << "TheoryUFTim::check(): " << assertion << std::endl; - - switch(assertion.getKind()) { - case EQUAL: - d_assertions.push_back(assertion); - d_pending.push_back(assertion); - merge(); - break; - case NOT: - Assert(assertion[0].getKind() == EQUAL, - "predicates not supported in this UF implementation"); - d_disequality.push_back(assertion[0]); - break; - case APPLY_UF: - Unhandled("predicates not supported in this UF implementation"); - default: - Unhandled(assertion.getKind()); - } - - Debug("uf") << "TheoryUFTim::check(): done = " << (done() ? "true" : "false") << std::endl; - } - - //Make sure all outstanding merges are completed. - if(d_currentPendingIdx < d_pending.size()) { - merge(); - } - - if(standardEffortOrMore(level)) { - for(CDList<Node>::const_iterator diseqIter = d_disequality.begin(); - diseqIter != d_disequality.end(); - ++diseqIter) { - - TNode left = (*diseqIter)[0]; - TNode right = (*diseqIter)[1]; - if(sameCongruenceClass(left, right)) { - Node remakeNeq = (*diseqIter).notNode(); - Node conflict = constructConflict(remakeNeq); - d_out->conflict(conflict, false); - return; - } - } - } - - Debug("uf") << "uf: end check(" << level << ")" << std::endl; -} diff --git a/src/theory/uf/tim/theory_uf_tim.h b/src/theory/uf/tim/theory_uf_tim.h deleted file mode 100644 index 70c60728f..000000000 --- a/src/theory/uf/tim/theory_uf_tim.h +++ /dev/null @@ -1,225 +0,0 @@ -/********************* */ -/*! \file theory_uf_tim.h - ** \verbatim - ** Original author: taking - ** Major contributors: mdeters - ** 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.\endverbatim - ** - ** \brief This is a basic implementation of the Theory of Uninterpreted Functions - ** with Equality. - ** - ** This is a basic implementation of the Theory of Uninterpreted Functions - ** with Equality. It is based on the Nelson-Oppen algorithm given in - ** "Fast Decision Procedures Based on Congruence Closure" - ** (http://portal.acm.org/ft_gateway.cfm?id=322198&type=pdf) - ** This has been extended to work in a context-dependent way. - ** This interacts heavily with the data-structures given in ecdata.h . - **/ - -#include "cvc4_private.h" - -#ifndef __CVC4__THEORY__UF__TIM__THEORY_UF_TIM_H -#define __CVC4__THEORY__UF__TIM__THEORY_UF_TIM_H - -#include "expr/node.h" -#include "expr/attribute.h" - -#include "theory/theory.h" - -#include "context/context.h" -#include "context/cdo.h" -#include "context/cdlist.h" -#include "theory/uf/theory_uf.h" -#include "theory/uf/tim/ecdata.h" - -namespace CVC4 { -namespace theory { -namespace uf { -namespace tim { - -class TheoryUFTim : public TheoryUF { - -private: - - /** - * List of all of the non-negated literals from the assertion queue. - * This is used only for conflict generation. - * This differs from pending as the program generates new equalities that - * are not in this list. - * This will probably be phased out in future version. - */ - context::CDList<Node> d_assertions; - - /** - * List of pending equivalence class merges. - * - * Tricky part: - * Must keep a hard link because new equality terms are created and appended - * to this list. - */ - context::CDList<Node> d_pending; - - /** Index of the next pending equality to merge. */ - context::CDO<unsigned> d_currentPendingIdx; - - /** List of all disequalities this theory has seen. */ - context::CDList<Node> d_disequality; - - /** - * List of all of the terms that are registered in the current context. - * When registerTerm is called on a term we want to guarentee that there - * is a hard link to the term for the duration of the context in which - * register term is called. - * This invariant is enough for us to use soft links where we want is the - * current implementation as well as making ECAttr() not context dependent. - * Soft links used both in ECData, and Link. - */ - context::CDList<Node> d_registered; - -public: - - /** Constructs a new instance of TheoryUF w.r.t. the provided context.*/ - TheoryUFTim(context::Context* c, OutputChannel& out, Valuation valuation); - - /** Destructor for the TheoryUF object. */ - ~TheoryUFTim(); - - /** - * Registers a previously unseen [in this context] node n. - * For TheoryUF, this sets up and maintains invaraints about - * equivalence class data-structures. - * - * Overloads a void registerTerm(TNode n); from theory.h. - * See theory/theory.h for more information about this method. - */ - void registerTerm(TNode n); - - /** - * Currently this does nothing. - * - * Overloads a void preRegisterTerm(TNode n); from theory.h. - * See theory/theory.h for more information about this method. - */ - void preRegisterTerm(TNode n); - - /** - * Checks whether the set of literals provided to the theory is consistent. - * - * If this is called at any effort level, it computes the congruence closure - * of all of the positive literals in the context. - * - * If this is called at full effort it checks if any of the negative literals - * are inconsistent with the congruence closure. - * - * Overloads void check(Effort level); from theory.h. - * See theory/theory.h for more information about this method. - */ - void check(Effort level); - - void presolve() { - // do nothing - } - - /** - * Propagates theory literals. Currently does nothing. - * - * Overloads void propagate(Effort level); from theory.h. - * See theory/theory.h for more information about this method. - */ - void propagate(Effort level) {} - - /** - * Explains a previously reported conflict. Currently does nothing. - * - * Overloads void explain(TNode n, Effort level); from theory.h. - * See theory/theory.h for more information about this method. - */ - void explain(TNode n) {} - - /** - * Get a theory value. - * - * Overloads Node getValue(TNode n); from theory.h. - * See theory/theory.h for more information about this method. - */ - Node getValue(TNode n) { - Unimplemented("TheoryUFTim doesn't support model generation"); - } - - std::string identify() const { return std::string("TheoryUFTim"); } - -private: - /** - * Checks whether 2 nodes are already in the same equivalence class tree. - * This should only be used internally, and it should only be called when - * the only thing done with the equivalence classes is an equality check. - * - * @returns true iff ccFind(x) == ccFind(y); - */ - bool sameCongruenceClass(TNode x, TNode y); - - /** - * Checks whether Node x and Node y are currently congruent - * using the equivalence class data structures. - * @returns true iff - * |x| = n = |y| and - * x.getOperator() == y.getOperator() and - * forall 1 <= i < n : ccFind(x[i]) == ccFind(y[i]) - */ - bool equiv(TNode x, TNode y); - - /** - * Merges 2 equivalence classes, checks wether any predecessors need to - * be set equal to complete congruence closure. - * The class with the smaller class size will be merged. - * @pre ecX->isClassRep() - * @pre ecY->isClassRep() - */ - void ccUnion(ECData* ecX, ECData* ecY); - - /** - * Returns the representative of the equivalence class. - * May modify the find pointers associated with equivalence classes. - */ - ECData* ccFind(ECData* x); - - /** Performs Congruence Closure to reflect the new additions to d_pending. */ - void merge(); - - /** Constructs a conflict from an inconsistent disequality. */ - Node constructConflict(TNode diseq); - -};/* class TheoryUFTim */ - - -/** - * Cleanup function for ECData. This will be used for called whenever - * a ECAttr is being destructed. - */ -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 ECAttrTag {}; - -/** - * ECAttr is the attribute that maps a node to an equivalence class. - */ -typedef expr::Attribute<ECAttrTag, ECData*, ECCleanupStrategy> ECAttr; - -}/* CVC4::theory::uf::tim namespace */ -}/* CVC4::theory::uf namespace */ -}/* CVC4::theory namespace */ -}/* CVC4 namespace */ - -#endif /* __CVC4__THEORY__UF__TIM__THEORY_UF_TIM_H */ diff --git a/src/theory/valuation.cpp b/src/theory/valuation.cpp index 5002c8a59..9375998f9 100644 --- a/src/theory/valuation.cpp +++ b/src/theory/valuation.cpp @@ -2,8 +2,8 @@ /*! \file valuation.cpp ** \verbatim ** Original author: mdeters - ** Major contributors: none - ** Minor contributors (to current version): none + ** Major contributors: taking + ** Minor contributors (to current version): barrett, dejan ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -31,16 +31,12 @@ bool Valuation::isSatLiteral(TNode n) const { return d_engine->getPropEngine()->isSatLiteral(n); } -bool Valuation::hasSatValue(TNode n, bool& value) const { - return d_engine->getPropEngine()->hasValue(n, value); -} - -Node Valuation::getSatValue(TNode n) const{ +Node Valuation::getSatValue(TNode n) const { if(n.getKind() == kind::NOT) { Node atomRes = d_engine->getPropEngine()->getValue(n[0]); - if(atomRes.getKind() == kind::CONST_BOOLEAN){ + if(atomRes.getKind() == kind::CONST_BOOLEAN) { return NodeManager::currentNM()->mkConst(!atomRes.getConst<bool>()); - }else{ + } else { Assert(atomRes.isNull()); return atomRes; } @@ -49,5 +45,9 @@ Node Valuation::getSatValue(TNode n) const{ } } +bool Valuation::hasSatValue(TNode n, bool& value) const { + return d_engine->getPropEngine()->hasValue(n, value); +} + }/* CVC4::theory namespace */ }/* CVC4 namespace */ diff --git a/src/theory/valuation.h b/src/theory/valuation.h index 58615f481..f819eff9d 100644 --- a/src/theory/valuation.h +++ b/src/theory/valuation.h @@ -3,7 +3,7 @@ ** \verbatim ** Original author: mdeters ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): taking, barrett, dejan ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -57,7 +57,15 @@ public: Node getSatValue(TNode n) const; /** - * Returns true if the node has a sat value. If yes value is set to it's value. + * Returns true if the node has a current SAT assignment. If yes, the + * argument "value" is set to its value. + * + * This is only permitted if n is a theory atom that has an associated + * SAT literal. + * + * @return true if the literal has a current assignment, and returns the + * value in the "value" argument; otherwise false and the "value" + * argument is unmodified. */ bool hasSatValue(TNode n, bool& value) const; diff --git a/src/util/Assert.cpp b/src/util/Assert.cpp index ea0b26248..54d95ced0 100644 --- a/src/util/Assert.cpp +++ b/src/util/Assert.cpp @@ -5,7 +5,7 @@ ** Major contributors: none ** Minor contributors (to current version): acsys ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/Assert.h b/src/util/Assert.h index e38a3f9cf..3334de4a0 100644 --- a/src/util/Assert.h +++ b/src/util/Assert.h @@ -235,9 +235,7 @@ public: #ifdef CVC4_DEBUG -#ifdef CVC4_DEBUG extern CVC4_THREADLOCAL_PUBLIC(const char*) s_debugLastException; -#endif /* CVC4_DEBUG */ /** * Special assertion failure handling in debug mode; in non-debug @@ -259,9 +257,9 @@ void debugAssertionFailed(const AssertionException& thisException, do { \ if(EXPECT_FALSE( ! (cond) )) { \ /* save the last assertion failure */ \ - const char* lastException = s_debugLastException; \ - CVC4::AssertionException exception(#cond, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg); \ - CVC4::debugAssertionFailed(exception, lastException); \ + const char* lastException = ::CVC4::s_debugLastException; \ + ::CVC4::AssertionException exception(#cond, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg); \ + ::CVC4::debugAssertionFailed(exception, lastException); \ } \ } while(0) @@ -271,27 +269,27 @@ void debugAssertionFailed(const AssertionException& thisException, # define AlwaysAssert(cond, msg...) \ do { \ if(EXPECT_FALSE( ! (cond) )) { \ - throw CVC4::AssertionException(#cond, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg); \ + throw ::CVC4::AssertionException(#cond, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg); \ } \ } while(0) #endif /* CVC4_DEBUG */ #define Unreachable(msg...) \ - throw CVC4::UnreachableCodeException(__PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) + throw ::CVC4::UnreachableCodeException(__PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) #define Unhandled(msg...) \ - throw CVC4::UnhandledCaseException(__PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) + throw ::CVC4::UnhandledCaseException(__PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) #define Unimplemented(msg...) \ - throw CVC4::UnimplementedOperationException(__PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) + throw ::CVC4::UnimplementedOperationException(__PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) #define InternalError(msg...) \ - throw CVC4::InternalErrorException(__PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) + throw ::CVC4::InternalErrorException(__PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) #define IllegalArgument(arg, msg...) \ - throw CVC4::IllegalArgumentException(#arg, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) + throw ::CVC4::IllegalArgumentException(#arg, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) #define CheckArgument(cond, arg, msg...) \ AlwaysAssertArgument(cond, arg, ## msg) #define AlwaysAssertArgument(cond, arg, msg...) \ do { \ if(EXPECT_FALSE( ! (cond) )) { \ - throw CVC4::IllegalArgumentException(#cond, #arg, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg); \ + throw ::CVC4::IllegalArgumentException(#cond, #arg, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg); \ } \ } while(0) diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 61ff27c08..f371a4d72 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -8,7 +8,7 @@ noinst_LTLIBRARIES = libutil.la libutilcudd.la # libutilcudd.la is a separate library so that we can pass separate # compiler flags libutilcudd_la_CPPFLAGS = $(CPPFLAGS) $(AM_CPPFLAGS) @CUDD_CPPFLAGS@ -libutilcudd_la_LIBADD = @CUDD_LDFLAGS@ +libutilcudd_la_LIBADD = @CUDD_LDFLAGS@ @CUDD_LIBS@ # Do not list built sources (like integer.h, rational.h, and tls.h) here! # Rather, list them under BUILT_SOURCES, and their .in versions under diff --git a/src/util/array.h b/src/util/array.h index c00cfdaa3..22605922b 100644 --- a/src/util/array.h +++ b/src/util/array.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/backtrackable.h b/src/util/backtrackable.h index 418172235..c5c6b1399 100644 --- a/src/util/backtrackable.h +++ b/src/util/backtrackable.h @@ -2,10 +2,10 @@ /*! \file backtrackable.h ** \verbatim ** Original author: lianah - ** Major contributors: none + ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/bitvector.h b/src/util/bitvector.h index ade08164b..f05ebaf17 100644 --- a/src/util/bitvector.h +++ b/src/util/bitvector.h @@ -2,7 +2,7 @@ /*! \file bitvector.h ** \verbatim ** Original author: dejan - ** Major contributors: mdeters, cconway + ** Major contributors: cconway, mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/util/bool.h b/src/util/bool.h index d2a29c8d5..15d46b5d1 100644 --- a/src/util/bool.h +++ b/src/util/bool.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/boolean_simplification.cpp b/src/util/boolean_simplification.cpp index 92534bfd4..862f1e5fc 100644 --- a/src/util/boolean_simplification.cpp +++ b/src/util/boolean_simplification.cpp @@ -1,7 +1,7 @@ /********************* */ /*! \file boolean_simplification.cpp ** \verbatim - ** Original author: taking + ** Original author: mdeters ** Major contributors: none ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. diff --git a/src/util/boolean_simplification.h b/src/util/boolean_simplification.h index c2da8af5b..b3dffa475 100644 --- a/src/util/boolean_simplification.h +++ b/src/util/boolean_simplification.h @@ -2,7 +2,7 @@ /*! \file boolean_simplification.h ** \verbatim ** Original author: taking - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) @@ -198,6 +198,16 @@ public: } /** + * Negates an Expr, doing all the double-negation elimination that's + * possible. + * + * @param e the Expr to negate (cannot be the null Expr) + */ + static Expr negate(Expr e) throw(AssertionException) { + return negate(Node::fromExpr(e)).toExpr(); + } + + /** * Simplify an OR, AND, or IMPLIES. This function is the identity * for all other kinds. */ diff --git a/src/util/cardinality.h b/src/util/cardinality.h index e7f86c80e..6985ae38e 100644 --- a/src/util/cardinality.h +++ b/src/util/cardinality.h @@ -22,6 +22,11 @@ #ifndef __CVC4__CARDINALITY_H #define __CVC4__CARDINALITY_H +#if SWIG +%include "util/integer.h" +%include "util/Assert.h" +#endif /* SWIG */ + #include <iostream> #include <utility> @@ -140,6 +145,11 @@ public: return d_card > 0; } + /** Returns true iff this cardinality is infinite. */ + bool isInfinite() const throw() { + return d_card < 0; + } + /** * Returns true iff this cardinality is finite or countably * infinite. diff --git a/src/util/configuration.cpp b/src/util/configuration.cpp index aa3e6bf6b..c13b63e3f 100644 --- a/src/util/configuration.cpp +++ b/src/util/configuration.cpp @@ -49,6 +49,10 @@ bool Configuration::isTracingBuild() { return IS_TRACING_BUILD; } +bool Configuration::isDumpingBuild() { + return IS_DUMPING_BUILD; +} + bool Configuration::isMuzzledBuild() { return IS_MUZZLED_BUILD; } @@ -89,7 +93,11 @@ unsigned Configuration::getVersionRelease() { return CVC4_RELEASE; } -string Configuration::about() { +std::string Configuration::getVersionExtra() { + return CVC4_EXTRAVERSION; +} + +std::string Configuration::about() { return CVC4_ABOUT_STRING; } diff --git a/src/util/configuration.h b/src/util/configuration.h index 31a2ca3d4..cb207298c 100644 --- a/src/util/configuration.h +++ b/src/util/configuration.h @@ -53,6 +53,8 @@ public: static bool isTracingBuild(); + static bool isDumpingBuild(); + static bool isMuzzledBuild(); static bool isAssertionBuild(); @@ -73,6 +75,8 @@ public: static unsigned getVersionRelease(); + static std::string getVersionExtra(); + static std::string about(); static bool isBuiltWithGmp(); diff --git a/src/util/configuration_private.h b/src/util/configuration_private.h index 0421273ca..13347d970 100644 --- a/src/util/configuration_private.h +++ b/src/util/configuration_private.h @@ -49,6 +49,12 @@ namespace CVC4 { # define IS_TRACING_BUILD false #endif /* CVC4_TRACING */ +#ifdef CVC4_DUMPING +# define IS_DUMPING_BUILD true +#else /* CVC4_DUMPING */ +# define IS_DUMPING_BUILD false +#endif /* CVC4_DUMPING */ + #ifdef CVC4_MUZZLE # define IS_MUZZLED_BUILD true #else /* CVC4_MUZZLE */ diff --git a/src/util/congruence_closure.cpp b/src/util/congruence_closure.cpp index 9ce902b2a..14315ac5a 100644 --- a/src/util/congruence_closure.cpp +++ b/src/util/congruence_closure.cpp @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/congruence_closure.h b/src/util/congruence_closure.h index 83f6d15c0..4e690ec16 100644 --- a/src/util/congruence_closure.h +++ b/src/util/congruence_closure.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 @@ -34,7 +34,7 @@ #include "context/cdset.h" #include "context/cdlist_context_memory.h" #include "util/exception.h" -#include "theory/uf/morgan/stacking_map.h" +#include "context/stacking_map.h" #include "util/stats.h" namespace CVC4 { @@ -66,11 +66,11 @@ struct CongruenceOperator { typedef Tail_ Tail; };/* class CongruenceOperator<> */ -#define CONGRUENCE_OPERATORS_1(kind1) CongruenceOperator<kind1, EndOfCongruenceOpList> -#define CONGRUENCE_OPERATORS_2(kind1, kind2) CongruenceOperator<kind1, CONGRUENCE_OPERATORS_1(kind2)> -#define CONGRUENCE_OPERATORS_3(kind1, kind2, kind3) CongruenceOperator<kind1, CONGRUENCE_OPERATORS_2(kind2, kind3)> -#define CONGRUENCE_OPERATORS_4(kind1, kind2, kind3, kind4) CongruenceOperator<kind1, CONGRUENCE_OPERATORS_3(kind2, kind3, kind4)> -#define CONGRUENCE_OPERATORS_5(kind1, kind2, kind3, kind4, kind5) CongruenceOperator<kind1, CONGRUENCE_OPERATORS_4(kind2, kind3, kind4, kind5)> +#define CONGRUENCE_OPERATORS_1(kind1) ::CVC4::CongruenceOperator<kind1, ::CVC4::EndOfCongruenceOpList> +#define CONGRUENCE_OPERATORS_2(kind1, kind2) ::CVC4::CongruenceOperator<kind1, CONGRUENCE_OPERATORS_1(kind2)> +#define CONGRUENCE_OPERATORS_3(kind1, kind2, kind3) ::CVC4::CongruenceOperator<kind1, CONGRUENCE_OPERATORS_2(kind2, kind3)> +#define CONGRUENCE_OPERATORS_4(kind1, kind2, kind3, kind4) ::CVC4::CongruenceOperator<kind1, CONGRUENCE_OPERATORS_3(kind2, kind3, kind4)> +#define CONGRUENCE_OPERATORS_5(kind1, kind2, kind3, kind4, kind5) ::CVC4::CongruenceOperator<kind1, CONGRUENCE_OPERATORS_4(kind2, kind3, kind4, kind5)> /** * Returns true if the kind k is registered as a congruence operator @@ -139,7 +139,7 @@ class CongruenceClosure { OutputChannel* d_out; // typedef all of these so that iterators are easy to define - typedef theory::uf::morgan::StackingMap<Node, NodeHashFunction> RepresentativeMap; + typedef context::StackingMap<Node, Node, NodeHashFunction> RepresentativeMap; typedef context::CDList<TNode, context::ContextMemoryAllocator<TNode> > ClassList; typedef context::CDMap<Node, ClassList*, NodeHashFunction> ClassLists; typedef context::CDList<TNode, context::ContextMemoryAllocator<TNode> > UseList; @@ -270,6 +270,7 @@ private: if(i == d_eqMap.end()) { ++d_newSkolemVars; Node v = NodeManager::currentNM()->mkSkolem(t.getType()); + Debug("cc") << "CC made skolem " << v << std::endl; addEq(NodeManager::currentNM()->mkNode(t.getType().isBoolean() ? kind::IFF : kind::EQUAL, t, v), TNode::null()); d_added.insert(v); d_eqMap[t] = v; @@ -333,7 +334,7 @@ private: * Find the EC representative for a term t in the current context. */ inline TNode find(TNode t) const throw(AssertionException) { - TNode rep1 = d_representative.find(t); + TNode rep1 = d_representative[t]; return rep1.isNull() ? t : rep1; } @@ -1088,7 +1089,6 @@ std::ostream& operator<<(std::ostream& out, return out; } - }/* CVC4 namespace */ #endif /* __CVC4__UTIL__CONGRUENCE_CLOSURE_H */ diff --git a/src/util/datatype.cpp b/src/util/datatype.cpp index 926f31847..93651f1a9 100644 --- a/src/util/datatype.cpp +++ b/src/util/datatype.cpp @@ -2,7 +2,7 @@ /*! \file datatype.cpp ** \verbatim ** Original author: mdeters - ** Major contributors: none + ** Major contributors: ajreynol ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/util/datatype.h b/src/util/datatype.h index 477b16f66..c64f420dd 100644 --- a/src/util/datatype.h +++ b/src/util/datatype.h @@ -3,7 +3,7 @@ ** \verbatim ** Original author: mdeters ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): ajreynol ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences diff --git a/src/util/debug.h b/src/util/debug.h index 402c5bed4..ad2dbc2dd 100644 --- a/src/util/debug.h +++ b/src/util/debug.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/decision_engine.cpp b/src/util/decision_engine.cpp index 7641472f8..46807b1f9 100644 --- a/src/util/decision_engine.cpp +++ b/src/util/decision_engine.cpp @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/decision_engine.h b/src/util/decision_engine.h index 3eee8aeb6..1c2bd3ef7 100644 --- a/src/util/decision_engine.h +++ b/src/util/decision_engine.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/dynamic_array.h b/src/util/dynamic_array.h index c0a8cf260..2c8b842e4 100644 --- a/src/util/dynamic_array.h +++ b/src/util/dynamic_array.h @@ -2,10 +2,10 @@ /*! \file dynamic_array.h ** \verbatim ** Original author: taking - ** Major contributors: none + ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 @@ -17,11 +17,10 @@ ** \todo document this file **/ - #include "cvc4_private.h" -#ifndef __CVC4__UTIL__DYNAMICARRAY_H -#define __CVC4__UTIL__DYNAMICARRAY_H +#ifndef __CVC4__UTIL__DYNAMIC_ARRAY_H +#define __CVC4__UTIL__DYNAMIC_ARRAY_H #include "util/Assert.h" @@ -29,14 +28,14 @@ namespace CVC4 { template <class T> class DynamicArray { -private: +protected: T* d_arr; unsigned d_size; unsigned d_allocated; bool d_callDestructor; - void grow(){ + void grow() { bool empty = (d_arr == NULL); d_allocated = empty ? 15 : d_allocated * 2 + 1; unsigned allocSize = sizeof(T) * d_allocated; @@ -48,14 +47,14 @@ private: } public: - DynamicArray(bool deallocate = false): + DynamicArray(bool callDestructor = false) : d_arr(NULL), d_size(0), d_allocated(0), - d_callDestructor(deallocate){ + d_callDestructor(callDestructor) { } - ~DynamicArray(){ + virtual ~DynamicArray() { if(d_callDestructor) { for(unsigned i = 0; i < d_size; ++i) { d_arr[i].~T(); @@ -83,12 +82,17 @@ public: ++d_size; } + const T& operator[](unsigned i) const { + Assert(i < d_size, "index out of bounds in DynamicArray::operator[]"); + return d_arr[i]; + } + T& operator[](unsigned i) { Assert(i < d_size, "index out of bounds in DynamicArray::operator[]"); return d_arr[i]; } - const T& back() const{ + const T& back() const { Assert(d_size > 0, "DynamicArray::back() called on empty list"); return d_arr[d_size - 1]; } @@ -96,12 +100,53 @@ public: void pop_back() { Assert(d_size > 0, "DynamicArray::back() called on empty list"); --d_size; - if(d_callDestructor){ - d_arr[d_size].~T();; + if(d_callDestructor) { + d_arr[d_size].~T(); + } + } + + typedef T* iterator; + typedef const T* const_iterator; + + iterator begin() { return d_arr; } + iterator end() { return d_arr + d_size; } + const_iterator begin() const { return d_arr; } + const_iterator end() const { return d_arr + d_size; } + +};/* class DynamicArray<T> */ + +template <class T, class Ctor = T> +class DynamicGrowingArray : public DynamicArray<T> { + Ctor d_ctor; + +public: + DynamicGrowingArray(bool callDestructor, const Ctor& c) : + DynamicArray<T>(callDestructor), + d_ctor(c) { + } + + DynamicGrowingArray(bool callDestructor = false) : + DynamicArray<T>(callDestructor), + d_ctor() { + } + + T& operator[](unsigned i) { + while(this->d_allocated <= i) { + this->grow(); + } + while(this->d_size <= i) { + ::new((void*)(this->d_arr + this->d_size)) T(d_ctor); + ++this->d_size; } + return this->d_arr[i]; + } + + const T& operator[](unsigned i) const { + Assert(this->d_size > i); + return this->d_arr[i]; } -};/* CVC4::DynamicArray */ +};/* CVC4::DynamicGrowingArray */ }/* CVC4 namespace */ -#endif /* __CVC4__UTIL__DYNAMICARRAY_H */ +#endif /* __CVC4__UTIL__DYNAMIC_ARRAY_H */ diff --git a/src/util/gmp_util.h b/src/util/gmp_util.h index 87102e644..7d2badbfe 100644 --- a/src/util/gmp_util.h +++ b/src/util/gmp_util.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** Minor contributors (to current version): taking ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/hash.h b/src/util/hash.h index cca60ce76..10211970f 100644 --- a/src/util/hash.h +++ b/src/util/hash.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** Minor contributors (to current version): taking ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/integer.h.in b/src/util/integer.h.in index 7e1b9a1aa..b2973081d 100644 --- a/src/util/integer.h.in +++ b/src/util/integer.h.in @@ -11,7 +11,7 @@ ** See the file COPYING in the top-level source directory for licensing ** information.\endverbatim ** - ** \brief A multiprecision integer constant. + ** \brief A multiprecision integer constant ** ** A multiprecision integer constant. **/ @@ -26,8 +26,14 @@ #ifdef CVC4_CLN_IMP # include "util/integer_cln_imp.h" +# if SWIG + %include "util/integer_cln_imp.h" +# endif /* SWIG */ #endif /* CVC4_CLN_IMP */ #ifdef CVC4_GMP_IMP # include "util/integer_gmp_imp.h" +# if SWIG + %include "util/integer_gmp_imp.h" +# endif /* SWIG */ #endif /* CVC4_GMP_IMP */ diff --git a/src/util/integer_cln_imp.h b/src/util/integer_cln_imp.h index 664027cdc..a7de8c75e 100644 --- a/src/util/integer_cln_imp.h +++ b/src/util/integer_cln_imp.h @@ -2,10 +2,10 @@ /*! \file integer_cln_imp.h ** \verbatim ** Original author: taking - ** Major contributors: none - ** Minor contributors (to current version): mdeters, dejan + ** Major contributors: mdeters + ** Minor contributors (to current version): dejan ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/integer_gmp_imp.h b/src/util/integer_gmp_imp.h index 60cee3937..237114d24 100644 --- a/src/util/integer_gmp_imp.h +++ b/src/util/integer_gmp_imp.h @@ -2,10 +2,10 @@ /*! \file integer_gmp_imp.h ** \verbatim ** Original author: taking - ** Major contributors: none - ** Minor contributors (to current version): dejan, mdeters + ** Major contributors: mdeters + ** Minor contributors (to current version): dejan ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/ite_removal.cpp b/src/util/ite_removal.cpp index e9c5122b3..bd5048040 100644 --- a/src/util/ite_removal.cpp +++ b/src/util/ite_removal.cpp @@ -2,7 +2,7 @@ /*! \file ite_removal.cpp ** \verbatim ** Original author: dejan - ** Major contributors: none + ** Major contributors: mdeters ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) @@ -11,20 +11,22 @@ ** See the file COPYING in the top-level source directory for licensing ** information.\endverbatim ** - ** \brief Representation of cardinality + ** \brief Removal of term ITEs ** - ** Simple class to represent a cardinality; used by the CVC4 type system - ** give the cardinality of sorts. + ** Removal of term ITEs. **/ #include <vector> #include "util/ite_removal.h" #include "theory/rewriter.h" +#include "expr/command.h" using namespace CVC4; using namespace std; +namespace CVC4 { + struct IteRewriteAttrTag {}; typedef expr::Attribute<IteRewriteAttrTag, Node> IteRewriteAttr; @@ -34,8 +36,7 @@ void RemoveITE::run(std::vector<Node>& output) { } } -Node RemoveITE::run(TNode node, std::vector<Node>& output) -{ +Node RemoveITE::run(TNode node, std::vector<Node>& output) { // Current node Debug("ite") << "removeITEs(" << node << ")" << endl; @@ -54,8 +55,18 @@ Node RemoveITE::run(TNode node, std::vector<Node>& output) // Make the skolem to represent the ITE Node skolem = nodeManager->mkVar(nodeType); + if(Dump.isOn("declarations")) { + stringstream kss; + kss << Expr::setlanguage(Expr::setlanguage::getLanguage(Dump("declarations"))) << skolem; + string ks = kss.str(); + Dump("declarations") << CommentCommand(ks + " is a variable introduced due to term-level ITE removal") << endl + << DeclareFunctionCommand(ks, nodeType.toType()) << endl; + } + // The new assertion - Node newAssertion = nodeManager->mkNode(kind::ITE, node[0], skolem.eqNode(node[1]), skolem.eqNode(node[2])); + Node newAssertion = + nodeManager->mkNode(kind::ITE, node[0], skolem.eqNode(node[1]), + skolem.eqNode(node[2])); Debug("ite") << "removeITEs(" << node << ") => " << newAssertion << endl; // Attach the skolem @@ -91,4 +102,6 @@ Node RemoveITE::run(TNode node, std::vector<Node>& output) nodeManager->setAttribute(node, IteRewriteAttr(), Node::null()); return node; } -}; +} + +}/* CVC4 namespace */ diff --git a/src/util/ite_removal.h b/src/util/ite_removal.h index b286665cc..d68c6d933 100644 --- a/src/util/ite_removal.h +++ b/src/util/ite_removal.h @@ -1,9 +1,9 @@ /********************* */ /*! \file ite_removal.h ** \verbatim - ** Original author: mdeters + ** Original author: dejan ** Major contributors: none - ** Minor contributors (to current version): none + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -11,10 +11,9 @@ ** See the file COPYING in the top-level source directory for licensing ** information.\endverbatim ** - ** \brief Representation of cardinality + ** \brief Removal of term ITEs ** - ** Simple class to represent a cardinality; used by the CVC4 type system - ** give the cardinality of sorts. + ** Removal of term ITEs. **/ #pragma once @@ -38,7 +37,6 @@ public: */ static Node run(TNode node, std::vector<Node>& additionalAssertions); -}; +};/* class RemoveTTE */ - -} +}/* CVC4 namespace */ diff --git a/src/util/language.h b/src/util/language.h index dbda6a315..d3405e35b 100644 --- a/src/util/language.h +++ b/src/util/language.h @@ -86,6 +86,9 @@ namespace output { enum CVC4_PUBLIC Language { // SPECIAL "NON-LANGUAGE" LANGUAGES HAVE ENUM VALUE < 0 + /** Match the output language to the input language */ + LANG_AUTO = -1, + // COMMON INPUT AND OUTPUT LANGUAGES HAVE ENUM VALUES IN [0,9] // AND SHOULD CORRESPOND IN PLACEMENT WITH INPUTLANGUAGE // diff --git a/src/util/matcher.h b/src/util/matcher.h index 5dc511bc2..6daceb8fd 100644 --- a/src/util/matcher.h +++ b/src/util/matcher.h @@ -1,8 +1,8 @@ /********************* */ /*! \file matcher.h ** \verbatim - ** Original author: ajreynol - ** Major contributors: none + ** Original author: mdeters + ** Major contributors: ajreynol ** Minor contributors (to current version): none ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) diff --git a/src/util/ntuple.h b/src/util/ntuple.h index 4c9a033a1..4f8b73945 100644 --- a/src/util/ntuple.h +++ b/src/util/ntuple.h @@ -30,6 +30,11 @@ public: T1 first; T2 second; T3 third; + triple(const T1& t1, const T2& t2, const T3& t3) : + first(t1), + second(t2), + third(t3) { + } };/* class triple<> */ template <class T1, class T2, class T3> @@ -45,9 +50,12 @@ public: T2 second; T3 third; T4 fourth; - quad(const T1& t1, const T2& t2, const T3& t3, const T4& t4) - : first(t1), second(t2), third(t3), fourth(t4) - { } + quad(const T1& t1, const T2& t2, const T3& t3, const T4& t4) : + first(t1), + second(t2), + third(t3), + fourth(t4) { + } };/* class quad<> */ template <class T1, class T2, class T3, class T4> diff --git a/src/util/options.cpp b/src/util/options.cpp index 9bceee931..7e6011352 100644 --- a/src/util/options.cpp +++ b/src/util/options.cpp @@ -2,7 +2,7 @@ /*! \file options.cpp ** \verbatim ** Original author: mdeters - ** Major contributors: taking, cconway + ** Major contributors: cconway, taking ** Minor contributors (to current version): barrett, dejan ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) @@ -62,15 +62,16 @@ Options::Options() : err(&std::cerr), verbosity(0), inputLanguage(language::input::LANG_AUTO), - uf_implementation(MORGAN), + outputLanguage(language::output::LANG_AUTO), parseOnly(false), + preprocessOnly(false), semanticChecks(DO_SEMANTIC_CHECKS_BY_DEFAULT), theoryRegistration(true), memoryMap(false), strictParsing(false), lazyDefinitionExpansion(false), simplificationMode(SIMPLIFICATION_MODE_BATCH), - simplificationStyle(NO_SIMPLIFICATION_STYLE), + doStaticLearning(true), interactive(false), interactiveSetByUser(false), segvNoSpin(false), @@ -95,10 +96,13 @@ Options::Options() : static const string optionsDescription = "\ --lang | -L force input language (default is `auto'; see --lang help)\n\ + --output-lang force output language (default is `auto'; see --lang help)\n\ --version | -V identify this CVC4 binary\n\ --help | -h this command line reference\n\ --parse-only exit after parsing input\n\ - --preprocess-only exit after parsing preprocessing input (and dump preprocessed assertions, unless -q)\n\ + --preprocess-only exit after preprocessing (useful with --stats or --dump)\n\ + --dump=MODE dump preprocessed assertions, T-propagations, etc., see --dump=help\n\ + --dump-to=FILE all dumping goes to FILE (instead of stdout)\n\ --mmap memory map file input\n\ --show-config show CVC4 static configuration\n\ --segv-nospin don't spin on segfault waiting for gdb\n\ @@ -115,13 +119,13 @@ static const string optionsDescription = "\ --stats give statistics on exit\n\ --default-expr-depth=N print exprs to depth N (0 == default, -1 == no limit)\n\ --print-expr-types print types with variables when printing exprs\n\ - --uf=morgan|tim select uninterpreted function theory implementation\n\ --interactive run interactively\n\ --no-interactive do not run interactively\n\ --produce-models support the get-value command\n\ --produce-assignments support the get-assignment command\n\ --lazy-definition-expansion expand define-fun lazily\n\ --simplification=MODE choose simplification mode, see --simplification=help\n\ + --no-static-learning turn off static learning (e.g. diamond-breaking)\n\ --replay=file replay decisions from file\n\ --replay-log=file log decisions and propagations to file\n\ --pivot-rule=RULE change the pivot rule (see --pivot-rule help)\n\ @@ -140,6 +144,13 @@ Languages currently supported as arguments to the -L / --lang option:\n\ pl | cvc4 CVC4 presentation language\n\ smt | smtlib SMT-LIB format 1.2\n\ smt2 | smtlib2 SMT-LIB format 2.0\n\ +\n\ +Languages currently supported as arguments to the --output-lang option:\n\ + auto match the output language to the input language\n\ + pl | cvc4 CVC4 presentation language\n\ + smt | smtlib SMT-LIB format 1.2\n\ + smt2 | smtlib2 SMT-LIB format 2.0\n\ + ast internal format (simple syntax-tree language)\n\ "; static const string simplificationHelp = "\ @@ -154,18 +165,74 @@ incremental\n\ + run nonclausal simplification and clausal propagation at each ASSERT\n\ (and at CHECKSAT/QUERY/SUBTYPE)\n\ \n\ -You can also specify the level of aggressiveness for the simplification\n\ -(by repeating the --simplification option):\n\ +none\n\ ++ do not perform nonclausal simplification\n\ +"; + +static const string dumpHelp = "\ +Dump modes currently supported by the --dump option:\n\ \n\ -toplevel (default)\n\ -+ apply toplevel simplifications (things known true/false at outer level\n\ - only)\n\ +benchmark\n\ ++ Dump the benchmark structure (set-logic, push/pop, queries, etc.), but\n\ + does not include any declarations or assertions. Implied by all following\n\ + modes.\n\ \n\ -aggressive\n\ -+ do aggressive, local simplification across the entire formula\n\ +declarations\n\ ++ Dump declarations. Implied by all following modes.\n\ \n\ -none\n\ -+ do not perform nonclausal simplification\n\ +assertions\n\ ++ Output the assertions after non-clausal simplification and static\n\ + learning phases, but before presolve-time T-lemmas arrive. If\n\ + non-clausal simplification and static learning are off\n\ + (--simplification=none --no-static-learning), the output\n\ + will closely resemble the input (with term-level ITEs removed).\n\ +\n\ +learned\n\ ++ Output the assertions after non-clausal simplification, static\n\ + learning, and presolve-time T-lemmas. This should include all eager\n\ + T-lemmas (in the form provided by the theory, which my or may not be\n\ + clausal). Also includes level-0 BCP done by Minisat.\n\ +\n\ +clauses\n\ ++ Do all the preprocessing outlined above, and dump the CNF-converted\n\ + output\n\ +\n\ +state\n\ ++ Dump all contextual assertions (e.g., SAT decisions, propagations..).\n\ + Implied by all \"stateful\" modes below and conflicts with all\n\ + non-stateful modes below.\n\ +\n\ +t-conflicts [non-stateful]\n\ ++ Output correctness queries for all theory conflicts\n\ +\n\ +missed-t-conflicts [stateful]\n\ ++ Output completeness queries for theory conflicts\n\ +\n\ +t-propagations [stateful]\n\ ++ Output correctness queries for all theory propagations\n\ +\n\ +missed-t-propagations [stateful]\n\ ++ Output completeness queries for theory propagations (LARGE and EXPENSIVE)\n\ +\n\ +t-lemmas [non-stateful]\n\ ++ Output correctness queries for all theory lemmas\n\ +\n\ +t-explanations [non-stateful]\n\ ++ Output correctness queries for all theory explanations\n\ +\n\ +Dump modes can be combined with multiple uses of --dump. Generally you want\n\ +one from the assertions category (either asertions, learned, or clauses), and\n\ +perhaps one or more stateful or non-stateful modes for checking correctness\n\ +and completeness of decision procedure implementations. Stateful modes dump\n\ +the contextual assertions made by the core solver (all decisions and propagations\n\ +as assertions; that affects the validity of the resulting correctness and\n\ +completeness queries, so of course stateful and non-stateful modes cannot\n\ +be mixed in the same run.\n\ +\n\ +The --output-language option controls the language used for dumping, and\n\ +this allows you to connect CVC4 to another solver implementation via a UNIX\n\ +pipe to perform on-line checking. The --dump-to option can be used to dump\n\ +to a file.\n\ "; string Options::getDescription() const { @@ -192,8 +259,11 @@ enum OptionValue { SMTCOMP = 256, /* avoid clashing with char options */ STATS, SEGV_NOSPIN, + OUTPUT_LANGUAGE, PARSE_ONLY, PREPROCESS_ONLY, + DUMP, + DUMP_TO, NO_CHECKING, NO_THEORY_REGISTRATION, USE_MMAP, @@ -204,6 +274,7 @@ enum OptionValue { UF_THEORY, LAZY_DEFINITION_EXPANSION, SIMPLIFICATION_MODE, + NO_STATIC_LEARNING, INTERACTIVE, NO_INTERACTIVE, PRODUCE_MODELS, @@ -263,8 +334,11 @@ static struct option cmdlineOptions[] = { { "version" , no_argument , NULL, 'V' }, { "about" , no_argument , NULL, 'V' }, { "lang" , required_argument, NULL, 'L' }, + { "output-lang", required_argument, NULL, OUTPUT_LANGUAGE }, { "parse-only" , no_argument , NULL, PARSE_ONLY }, - { "preprocess-only", no_argument , NULL, PREPROCESS_ONLY }, + { "preprocess-only", no_argument , NULL, PREPROCESS_ONLY }, + { "dump" , required_argument, NULL, DUMP }, + { "dump-to" , required_argument, NULL, DUMP_TO }, { "mmap" , no_argument , NULL, USE_MMAP }, { "strict-parsing", no_argument , NULL, STRICT_PARSING }, { "default-expr-depth", required_argument, NULL, DEFAULT_EXPR_DEPTH }, @@ -272,6 +346,7 @@ static struct option cmdlineOptions[] = { { "uf" , required_argument, NULL, UF_THEORY }, { "lazy-definition-expansion", no_argument, NULL, LAZY_DEFINITION_EXPANSION }, { "simplification", required_argument, NULL, SIMPLIFICATION_MODE }, + { "no-static-learning", no_argument, NULL, NO_STATIC_LEARNING }, { "interactive", no_argument , NULL, INTERACTIVE }, { "no-interactive", no_argument , NULL, NO_INTERACTIVE }, { "produce-models", no_argument , NULL, PRODUCE_MODELS }, @@ -371,6 +446,32 @@ throw(OptionException) { languageHelp = true; break; + case OUTPUT_LANGUAGE: + if(!strcmp(optarg, "cvc4") || !strcmp(optarg, "pl")) { + outputLanguage = language::output::LANG_CVC4; + break; + } else if(!strcmp(optarg, "smtlib") || !strcmp(optarg, "smt")) { + outputLanguage = language::output::LANG_SMTLIB; + break; + } else if(!strcmp(optarg, "smtlib2") || !strcmp(optarg, "smt2")) { + outputLanguage = language::output::LANG_SMTLIB_V2; + break; + } else if(!strcmp(optarg, "ast")) { + outputLanguage = language::output::LANG_AST; + break; + } else if(!strcmp(optarg, "auto")) { + outputLanguage = language::output::LANG_AUTO; + break; + } + + if(strcmp(optarg, "help")) { + throw OptionException(string("unknown language for --output-lang: `") + + optarg + "'. Try --output-lang help."); + } + + languageHelp = true; + break; + case 't': Trace.on(optarg); break; @@ -396,6 +497,87 @@ throw(OptionException) { preprocessOnly = true; break; + case DUMP: { +#ifdef CVC4_DUMPING + char* tokstr = optarg; + char* toksave; + while((optarg = strtok_r(tokstr, ",", &toksave)) != NULL) { + tokstr = NULL; + if(!strcmp(optarg, "benchmark")) { + } else if(!strcmp(optarg, "declarations")) { + } else if(!strcmp(optarg, "assertions")) { + } else if(!strcmp(optarg, "learned")) { + } else if(!strcmp(optarg, "clauses")) { + } else if(!strcmp(optarg, "t-conflicts") || + !strcmp(optarg, "t-lemmas") || + !strcmp(optarg, "t-explanations")) { + // These are "non-state-dumping" modes. If state (SAT decisions, + // propagations, etc.) is dumped, it will interfere with the validity + // of these generated queries. + if(Dump.isOn("state")) { + throw OptionException(string("dump option `") + optarg + + "' conflicts with a previous, " + "state-dumping dump option. You cannot " + "mix stateful and non-stateful dumping modes; " + "see --dump help."); + } else { + Dump.on("no-permit-state"); + } + } else if(!strcmp(optarg, "state") || + !strcmp(optarg, "missed-t-conflicts") || + !strcmp(optarg, "t-propagations") || + !strcmp(optarg, "missed-t-propagations")) { + // These are "state-dumping" modes. If state (SAT decisions, + // propagations, etc.) is not dumped, it will interfere with the + // validity of these generated queries. + if(Dump.isOn("no-permit-state")) { + throw OptionException(string("dump option `") + optarg + + "' conflicts with a previous, " + "non-state-dumping dump option. You cannot " + "mix stateful and non-stateful dumping modes; " + "see --dump help."); + } else { + Dump.on("state"); + } + } else if(!strcmp(optarg, "help")) { + puts(dumpHelp.c_str()); + exit(1); + } else { + throw OptionException(string("unknown option for --dump: `") + + optarg + "'. Try --dump help."); + } + + Dump.on(optarg); + Dump.on("benchmark"); + if(strcmp(optarg, "benchmark")) { + Dump.on("declarations"); + } + } +#else /* CVC4_DUMPING */ + throw OptionException("The dumping feature was disabled in this build of CVC4."); +#endif /* CVC4_DUMPING */ + break; + } + + case DUMP_TO: { +#ifdef CVC4_DUMPING + if(optarg == NULL || *optarg == '\0') { + throw OptionException(string("Bad file name for --dump-to")); + } else if(!strcmp(optarg, "-")) { + Dump.setStream(DumpC::dump_cout); + } else { + ostream* dumpTo = new ofstream(optarg, ofstream::out | ofstream::trunc); + if(!*dumpTo) { + throw OptionException(string("Cannot open dump-to file (maybe it exists): `") + optarg + "'"); + } + Dump.setStream(*dumpTo); + } +#else /* CVC4_DUMPING */ + throw OptionException("The dumping feature was disabled in this build of CVC4."); +#endif /* CVC4_DUMPING */ + } + break; + case NO_THEORY_REGISTRATION: theoryRegistration = false; break; @@ -437,24 +619,6 @@ throw(OptionException) { } break; - case UF_THEORY: - { - if(!strcmp(optarg, "tim")) { - uf_implementation = Options::TIM; - } else if(!strcmp(optarg, "morgan")) { - uf_implementation = Options::MORGAN; - } else if(!strcmp(optarg, "help")) { - printf("UF implementations available:\n"); - printf(" tim\n"); - printf(" morgan\n"); - exit(1); - } else { - throw OptionException(string("unknown option for --uf: `") + - optarg + "'. Try --uf help."); - } - } - break; - case LAZY_DEFINITION_EXPANSION: lazyDefinitionExpansion = true; break; @@ -464,12 +628,8 @@ throw(OptionException) { simplificationMode = SIMPLIFICATION_MODE_BATCH; } else if(!strcmp(optarg, "incremental")) { simplificationMode = SIMPLIFICATION_MODE_INCREMENTAL; - } else if(!strcmp(optarg, "aggressive")) { - simplificationStyle = AGGRESSIVE_SIMPLIFICATION_STYLE; - } else if(!strcmp(optarg, "toplevel")) { - simplificationStyle = TOPLEVEL_SIMPLIFICATION_STYLE; } else if(!strcmp(optarg, "none")) { - simplificationStyle = NO_SIMPLIFICATION_STYLE; + simplificationMode = SIMPLIFICATION_MODE_NONE; } else if(!strcmp(optarg, "help")) { puts(simplificationHelp.c_str()); exit(1); @@ -479,6 +639,10 @@ throw(OptionException) { } break; + case NO_STATIC_LEARNING: + doStaticLearning = false; + break; + case INTERACTIVE: interactive = true; interactiveSetByUser = true; @@ -622,6 +786,7 @@ throw(OptionException) { printf("statistics : %s\n", Configuration::isStatisticsBuild() ? "yes" : "no"); printf("replay : %s\n", Configuration::isReplayBuild() ? "yes" : "no"); printf("tracing : %s\n", Configuration::isTracingBuild() ? "yes" : "no"); + printf("dumping : %s\n", Configuration::isDumpingBuild() ? "yes" : "no"); printf("muzzled : %s\n", Configuration::isMuzzledBuild() ? "yes" : "no"); printf("assertions : %s\n", Configuration::isAssertionBuild() ? "yes" : "no"); printf("coverage : %s\n", Configuration::isCoverageBuild() ? "yes" : "no"); diff --git a/src/util/options.h b/src/util/options.h index ce2bc71e7..c4e115b08 100644 --- a/src/util/options.h +++ b/src/util/options.h @@ -2,8 +2,8 @@ /*! \file options.h ** \verbatim ** Original author: mdeters - ** Major contributors: cconway - ** Minor contributors (to current version): dejan, taking + ** Major contributors: taking, cconway + ** Minor contributors (to current version): dejan ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -71,11 +71,8 @@ struct CVC4_PUBLIC Options { /** The input language */ InputLanguage inputLanguage; - /** Enumeration of UF implementation choices */ - typedef enum { TIM, MORGAN } UfImplementation; - - /** Which implementation of uninterpreted function theory to use */ - UfImplementation uf_implementation; + /** The output language */ + OutputLanguage outputLanguage; /** Should we print the help message? */ bool help; @@ -112,21 +109,16 @@ struct CVC4_PUBLIC Options { /** Simplify the assertions as they come in */ SIMPLIFICATION_MODE_INCREMENTAL, /** Simplify the assertions all together once a check is requested */ - SIMPLIFICATION_MODE_BATCH + SIMPLIFICATION_MODE_BATCH, + /** Don't do simplification */ + SIMPLIFICATION_MODE_NONE } SimplificationMode; - /** When to perform nonclausal simplifications. */ + /** When/whether to perform nonclausal simplifications. */ SimplificationMode simplificationMode; - /** Enumeration of simplification styles (how much to simplify). */ - typedef enum { - AGGRESSIVE_SIMPLIFICATION_STYLE, - TOPLEVEL_SIMPLIFICATION_STYLE, - NO_SIMPLIFICATION_STYLE - } SimplificationStyle; - - /** Style of nonclausal simplifications to perform. */ - SimplificationStyle simplificationStyle; + /** Whether to perform the static learning pass. */ + bool doStaticLearning; /** Whether we're in interactive mode or not */ bool interactive; @@ -229,34 +221,18 @@ struct CVC4_PUBLIC Options { };/* struct Options */ inline std::ostream& operator<<(std::ostream& out, - Options::UfImplementation uf) CVC4_PUBLIC; - -inline std::ostream& operator<<(std::ostream& out, - Options::UfImplementation uf) { - switch(uf) { - case Options::TIM: - out << "TIM"; - break; - case Options::MORGAN: - out << "MORGAN"; - break; - default: - out << "UfImplementation:UNKNOWN![" << unsigned(uf) << "]"; - } - - return out; -} - -inline std::ostream& operator<<(std::ostream& out, Options::SimplificationMode mode) CVC4_PUBLIC; inline std::ostream& operator<<(std::ostream& out, Options::SimplificationMode mode) { switch(mode) { + case Options::SIMPLIFICATION_MODE_INCREMENTAL: + out << "SIMPLIFICATION_MODE_INCREMENTAL"; + break; case Options::SIMPLIFICATION_MODE_BATCH: out << "SIMPLIFICATION_MODE_BATCH"; break; - case Options::SIMPLIFICATION_MODE_INCREMENTAL: - out << "SIMPLIFICATION_MODE_INCREMENTAL"; + case Options::SIMPLIFICATION_MODE_NONE: + out << "SIMPLIFICATION_MODE_NONE"; break; default: out << "SimplificationMode:UNKNOWN![" << unsigned(mode) << "]"; diff --git a/src/util/output.cpp b/src/util/output.cpp index 29de4c360..3823f7be6 100644 --- a/src/util/output.cpp +++ b/src/util/output.cpp @@ -40,6 +40,8 @@ MessageC MessageChannel CVC4_PUBLIC (&cout); NoticeC NoticeChannel CVC4_PUBLIC (&cout); ChatC ChatChannel CVC4_PUBLIC (&cout); TraceC TraceChannel CVC4_PUBLIC (&cout); +std::ostream DumpC::dump_cout(cout.rdbuf());// copy cout stream buffer +DumpC DumpChannel CVC4_PUBLIC (&DumpC::dump_cout); #ifndef CVC4_MUZZLE @@ -155,6 +157,40 @@ int TraceC::printf(std::string tag, const char* fmt, ...) { # endif /* CVC4_TRACING */ +# ifdef CVC4_DUMPING + +int DumpC::printf(const char* tag, const char* fmt, ...) { + if(d_tags.find(string(tag)) == d_tags.end()) { + return 0; + } + + // chop off output after 1024 bytes + char buf[1024]; + va_list vl; + va_start(vl, fmt); + int retval = vsnprintf(buf, sizeof(buf), fmt, vl); + va_end(vl); + *d_os << buf; + return retval; +} + +int DumpC::printf(std::string tag, const char* fmt, ...) { + if(d_tags.find(tag) == d_tags.end()) { + return 0; + } + + // chop off output after 1024 bytes + char buf[1024]; + va_list vl; + va_start(vl, fmt); + int retval = vsnprintf(buf, sizeof(buf), fmt, vl); + va_end(vl); + *d_os << buf; + return retval; +} + +# endif /* CVC4_DUMPING */ + #endif /* ! CVC4_MUZZLE */ }/* CVC4 namespace */ diff --git a/src/util/output.h b/src/util/output.h index 6d0f27f2a..e096ff028 100644 --- a/src/util/output.h +++ b/src/util/output.h @@ -3,7 +3,7 @@ ** \verbatim ** Original author: mdeters ** Major contributors: none - ** Minor contributors (to current version): cconway, taking, dejan + ** Minor contributors (to current version): taking, dejan ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences @@ -190,6 +190,7 @@ public: bool on (std::string tag) { d_tags.insert(tag); return true; } bool off(const char* tag) { d_tags.erase (std::string(tag)); return false; } bool off(std::string tag) { d_tags.erase (tag); return false; } + bool off() { d_tags.clear(); return false; } bool isOn(const char* tag) { return d_tags.find(std::string(tag)) != d_tags.end(); } bool isOn(std::string tag) { return d_tags.find(tag) != d_tags.end(); } @@ -297,6 +298,7 @@ public: bool on (std::string tag) { d_tags.insert(tag); return true; } bool off(const char* tag) { d_tags.erase (std::string(tag)); return false; } bool off(std::string tag) { d_tags.erase (tag); return false; } + bool off() { d_tags.clear(); return false; } bool isOn(const char* tag) { return d_tags.find(std::string(tag)) != d_tags.end(); } bool isOn(std::string tag) { return d_tags.find(tag) != d_tags.end(); } @@ -305,6 +307,51 @@ public: std::ostream& getStream() { return *d_os; } };/* class TraceC */ +/** The dump output class */ +class CVC4_PUBLIC DumpC { + std::set<std::string> d_tags; + std::ostream* d_os; + +public: + /** + * A copy of cout for use by the dumper. This is important because + * it has different settings (e.g., the expr printing depth is always + * unlimited). */ + static std::ostream dump_cout; + + explicit DumpC(std::ostream* os) : d_os(os) {} + + int printf(const char* tag, const char* fmt, ...) __attribute__ ((format(printf, 3, 4))); + int printf(std::string tag, const char* fmt, ...) __attribute__ ((format(printf, 3, 4))); + + CVC4ostream operator()(const char* tag) { + if(!d_tags.empty() && d_tags.find(std::string(tag)) != d_tags.end()) { + return CVC4ostream(d_os); + } else { + return CVC4ostream(); + } + } + CVC4ostream operator()(std::string tag) { + if(!d_tags.empty() && d_tags.find(tag) != d_tags.end()) { + return CVC4ostream(d_os); + } else { + return CVC4ostream(); + } + } + + bool on (const char* tag) { d_tags.insert(std::string(tag)); return true; } + bool on (std::string tag) { d_tags.insert(tag); return true; } + bool off(const char* tag) { d_tags.erase (std::string(tag)); return false; } + bool off(std::string tag) { d_tags.erase (tag); return false; } + bool off() { d_tags.clear(); return false; } + + bool isOn(const char* tag) { return d_tags.find(std::string(tag)) != d_tags.end(); } + bool isOn(std::string tag) { return d_tags.find(tag) != d_tags.end(); } + + std::ostream& setStream(std::ostream& os) { d_os = &os; return os; } + std::ostream& getStream() { return *d_os; } +};/* class DumpC */ + /** The debug output singleton */ extern DebugC DebugChannel CVC4_PUBLIC; /** The warning output singleton */ @@ -317,6 +364,8 @@ extern NoticeC NoticeChannel CVC4_PUBLIC; extern ChatC ChatChannel CVC4_PUBLIC; /** The trace output singleton */ extern TraceC TraceChannel CVC4_PUBLIC; +/** The dump output singleton */ +extern DumpC DumpChannel CVC4_PUBLIC; #ifdef CVC4_MUZZLE @@ -326,6 +375,7 @@ extern TraceC TraceChannel CVC4_PUBLIC; # define Notice ::CVC4::__cvc4_true() ? ::CVC4::nullCvc4Stream : ::CVC4::NoticeChannel # define Chat ::CVC4::__cvc4_true() ? ::CVC4::nullCvc4Stream : ::CVC4::ChatChannel # define Trace ::CVC4::__cvc4_true() ? ::CVC4::nullCvc4Stream : ::CVC4::TraceChannel +# define Dump ::CVC4::__cvc4_true() ? ::CVC4::nullCvc4Stream : ::CVC4::DumpChannel inline int DebugC::printf(const char* tag, const char* fmt, ...) { return 0; } inline int DebugC::printf(std::string tag, const char* fmt, ...) { return 0; } @@ -335,6 +385,8 @@ inline int NoticeC::printf(const char* fmt, ...) { return 0; } inline int ChatC::printf(const char* fmt, ...) { return 0; } inline int TraceC::printf(const char* tag, const char* fmt, ...) { return 0; } inline int TraceC::printf(std::string tag, const char* fmt, ...) { return 0; } +inline int DumpC::printf(const char* tag, const char* fmt, ...) { return 0; } +inline int DumpC::printf(std::string tag, const char* fmt, ...) { return 0; } #else /* CVC4_MUZZLE */ @@ -356,6 +408,13 @@ inline int DebugC::printf(std::string tag, const char* fmt, ...) { return 0; } inline int TraceC::printf(const char* tag, const char* fmt, ...) { return 0; } inline int TraceC::printf(std::string tag, const char* fmt, ...) { return 0; } # endif /* CVC4_TRACING */ +# ifdef CVC4_DUMPING +# define Dump ::CVC4::DumpChannel +# else /* CVC4_DUMPING */ +# define Dump ::CVC4::__cvc4_true() ? ::CVC4::nullCvc4Stream : ::CVC4::DumpChannel +inline int DumpC::printf(const char* tag, const char* fmt, ...) { return 0; } +inline int DumpC::printf(std::string tag, const char* fmt, ...) { return 0; } +# endif /* CVC4_DUMPING */ #endif /* CVC4_MUZZLE */ diff --git a/src/util/rational.h.in b/src/util/rational.h.in index 88c488290..17c1e31fc 100644 --- a/src/util/rational.h.in +++ b/src/util/rational.h.in @@ -11,9 +11,9 @@ ** See the file COPYING in the top-level source directory for licensing ** information.\endverbatim ** - ** \brief Multi-precision rational constants. + ** \brief A multi-precision rational constant ** - ** Multi-precision rational constants. + ** A multi-precision rational constant. **/ // this is used to avoid a public header dependence on cvc4autoconfig.h @@ -26,8 +26,14 @@ #ifdef CVC4_CLN_IMP # include "util/rational_cln_imp.h" +# if SWIG + %include "util/rational_cln_imp.h" +# endif /* SWIG */ #endif /* CVC4_CLN_IMP */ #ifdef CVC4_GMP_IMP # include "util/rational_gmp_imp.h" +# if SWIG + %include "util/rational_gmp_imp.h" +# endif /* SWIG */ #endif /* CVC4_GMP_IMP */ diff --git a/src/util/rational_cln_imp.cpp b/src/util/rational_cln_imp.cpp index 057100d10..22e3a7ad1 100644 --- a/src/util/rational_cln_imp.cpp +++ b/src/util/rational_cln_imp.cpp @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/rational_cln_imp.h b/src/util/rational_cln_imp.h index b97484ff1..a883500f9 100644 --- a/src/util/rational_cln_imp.h +++ b/src/util/rational_cln_imp.h @@ -5,7 +5,7 @@ ** Major contributors: none ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/rational_gmp_imp.cpp b/src/util/rational_gmp_imp.cpp index 5921b8fd3..b26172d66 100644 --- a/src/util/rational_gmp_imp.cpp +++ b/src/util/rational_gmp_imp.cpp @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/rational_gmp_imp.h b/src/util/rational_gmp_imp.h index 167e0fc22..b97965169 100644 --- a/src/util/rational_gmp_imp.h +++ b/src/util/rational_gmp_imp.h @@ -5,7 +5,7 @@ ** Major contributors: none ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/result.cpp b/src/util/result.cpp index 8e1db27c4..8a2bcf3b2 100644 --- a/src/util/result.cpp +++ b/src/util/result.cpp @@ -1,11 +1,11 @@ /********************* */ -/*! \file result.h +/*! \file result.cpp ** \verbatim ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/result.h b/src/util/result.h index 7da1dc0b7..c4733eab9 100644 --- a/src/util/result.h +++ b/src/util/result.h @@ -5,7 +5,7 @@ ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/sexpr.h b/src/util/sexpr.h index 376a8a224..63ce23874 100644 --- a/src/util/sexpr.h +++ b/src/util/sexpr.h @@ -2,10 +2,10 @@ /*! \file sexpr.h ** \verbatim ** Original author: cconway - ** Major contributors: none - ** Minor contributors (to current version): mdeters + ** Major contributors: mdeters + ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/stats.cpp b/src/util/stats.cpp index 70d486ff6..474d8fa7a 100644 --- a/src/util/stats.cpp +++ b/src/util/stats.cpp @@ -2,10 +2,10 @@ /*! \file stats.cpp ** \verbatim ** Original author: taking - ** Major contributors: none - ** Minor contributors (to current version): mdeters + ** Major contributors: mdeters + ** 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) + ** Copyright (c) 2009, 2010, 2011 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 @@ -20,6 +20,13 @@ #include "util/stats.h" #include "expr/node_manager.h" #include "expr/expr_manager_scope.h" +#include "lib/clock_gettime.h" + +#ifdef CVC4_STATISTICS_ON +# define __CVC4_USE_STATISTICS true +#else +# define __CVC4_USE_STATISTICS false +#endif using namespace CVC4; @@ -67,6 +74,24 @@ StatisticsRegistry::const_iterator StatisticsRegistry::end() { return NodeManager::currentNM()->getStatisticsRegistry()->d_registeredStats.end(); }/* StatisticsRegistry::end() */ +void TimerStat::start() { + if(__CVC4_USE_STATISTICS) { + AlwaysAssert(!d_running); + clock_gettime(CLOCK_MONOTONIC, &d_start); + d_running = true; + } +}/* TimerStat::start() */ + +void TimerStat::stop() { + if(__CVC4_USE_STATISTICS) { + AlwaysAssert(d_running); + ::timespec end; + clock_gettime(CLOCK_MONOTONIC, &end); + d_data += end - d_start; + d_running = false; + } +}/* TimerStat::stop() */ + RegisterStatistic::RegisterStatistic(ExprManager& em, Stat* stat) : d_em(&em), d_stat(stat) { ExprManagerScope ems(*d_em); diff --git a/src/util/stats.h b/src/util/stats.h index a94733595..7d3e33a6f 100644 --- a/src/util/stats.h +++ b/src/util/stats.h @@ -5,7 +5,7 @@ ** Major contributors: mdeters ** 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) + ** Copyright (c) 2009, 2010, 2011 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 @@ -32,7 +32,6 @@ #include <vector> #include "util/Assert.h" -#include "lib/clock_gettime.h" namespace CVC4 { @@ -702,27 +701,13 @@ public: } /** Start the timer. */ - void start() { - if(__CVC4_USE_STATISTICS) { - AlwaysAssert(!d_running); - clock_gettime(CLOCK_MONOTONIC, &d_start); - d_running = true; - } - } + void start(); /** * Stop the timer and update the statistic value with the * accumulated time. */ - void stop() { - if(__CVC4_USE_STATISTICS) { - AlwaysAssert(d_running); - ::timespec end; - clock_gettime(CLOCK_MONOTONIC, &end); - d_data += end - d_start; - d_running = false; - } - } + void stop(); };/* class TimerStat */ diff --git a/src/util/trans_closure.cpp b/src/util/trans_closure.cpp index 61c48fa8d..5d772b576 100644 --- a/src/util/trans_closure.cpp +++ b/src/util/trans_closure.cpp @@ -2,10 +2,10 @@ /*! \file trans_closure.cpp ** \verbatim ** Original author: barrett - ** Major contributors: none + ** Major contributors: ajreynol ** 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) + ** Copyright (c) 2009, 2010, 2011 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 diff --git a/src/util/trans_closure.h b/src/util/trans_closure.h index 951a32a63..ef04d7af5 100644 --- a/src/util/trans_closure.h +++ b/src/util/trans_closure.h @@ -2,8 +2,8 @@ /*! \file trans_closure.h ** \verbatim ** Original author: barrett - ** Major contributors: none - ** Minor contributors (to current version): none + ** Major contributors: ajreynol + ** Minor contributors (to current version): mdeters ** This file is part of the CVC4 prototype. ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) ** Courant Institute of Mathematical Sciences |