summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/context/cdlist.h10
-rw-r--r--src/context/cdqueue.h10
-rw-r--r--src/context/cdtrail_queue.h6
-rw-r--r--src/prop/cryptominisat/MTRand/Makefile.in141
-rw-r--r--src/prop/cryptominisat/Makefile.in369
-rw-r--r--src/prop/cryptominisat/Solver/Makefile.in198
-rw-r--r--src/prop/cryptominisat/man/Makefile.in141
-rw-r--r--src/prop/cryptominisat/mtl/Makefile.in141
-rw-r--r--src/smt/smt_engine.cpp3
-rw-r--r--src/theory/arith/Makefile.am8
-rw-r--r--src/theory/arith/arith_prop_manager.cpp173
-rw-r--r--src/theory/arith/arith_prop_manager.h184
-rw-r--r--src/theory/arith/arith_rewriter.cpp34
-rw-r--r--src/theory/arith/arith_rewriter.h1
-rw-r--r--src/theory/arith/arith_static_learner.cpp2
-rw-r--r--src/theory/arith/arith_utilities.h127
-rw-r--r--src/theory/arith/arithvar.h12
-rw-r--r--src/theory/arith/arithvar_set.h38
-rw-r--r--src/theory/arith/atom_database.cpp542
-rw-r--r--src/theory/arith/atom_database.h165
-rw-r--r--src/theory/arith/constraint.cpp1130
-rw-r--r--src/theory/arith/constraint.h837
-rw-r--r--src/theory/arith/constraint_forward.h42
-rw-r--r--src/theory/arith/delta_rational.h12
-rw-r--r--src/theory/arith/difference_manager.cpp169
-rw-r--r--src/theory/arith/difference_manager.h117
-rw-r--r--src/theory/arith/dio_solver.cpp28
-rw-r--r--src/theory/arith/dio_solver.h18
-rw-r--r--src/theory/arith/linear_equality.cpp47
-rw-r--r--src/theory/arith/linear_equality.h13
-rw-r--r--src/theory/arith/normal_form.cpp1132
-rw-r--r--src/theory/arith/normal_form.h460
-rw-r--r--src/theory/arith/ordered_set.h116
-rw-r--r--src/theory/arith/partial_model.cpp208
-rw-r--r--src/theory/arith/partial_model.h107
-rw-r--r--src/theory/arith/simplex.cpp137
-rw-r--r--src/theory/arith/simplex.h52
-rw-r--r--src/theory/arith/tableau.cpp1
-rw-r--r--src/theory/arith/theory_arith.cpp849
-rw-r--r--src/theory/arith/theory_arith.h88
-rw-r--r--src/theory/theory.cpp5
-rw-r--r--src/theory/theory.h1
-rw-r--r--src/util/integer_cln_imp.h12
-rw-r--r--src/util/integer_gmp_imp.h12
-rw-r--r--src/util/options.cpp8
-rw-r--r--src/util/options.h12
-rw-r--r--src/util/rational_cln_imp.h8
-rw-r--r--src/util/rational_gmp_imp.h8
48 files changed, 4764 insertions, 3170 deletions
diff --git a/src/context/cdlist.h b/src/context/cdlist.h
index c22d617b0..9d7709589 100644
--- a/src/context/cdlist.h
+++ b/src/context/cdlist.h
@@ -384,6 +384,16 @@ public:
/** Prefix decrement */
const_iterator& operator--() { --d_it; return *this; }
+ /** operator+ */
+ const_iterator operator+(long signed int off) const {
+ return const_iterator(d_it + off);
+ }
+
+ /** operator+ */
+ const_iterator operator+(long unsigned int off) const {
+ return const_iterator(d_it + off);
+ }
+
// Postfix operations on iterators: requires a Proxy object to
// hold the intermediate value for dereferencing
class Proxy {
diff --git a/src/context/cdqueue.h b/src/context/cdqueue.h
index d8f6c42f1..b43217cfe 100644
--- a/src/context/cdqueue.h
+++ b/src/context/cdqueue.h
@@ -151,6 +151,16 @@ public:
return ParentType::d_list[ParentType::d_size - 1];
}
+ typedef typename ParentType::const_iterator const_iterator;
+
+ const_iterator begin() const {
+ return ParentType::begin() + d_iter;
+ }
+
+ const_iterator end() const {
+ return ParentType::end();
+ }
+
};/* class CDQueue<> */
}/* CVC4::context namespace */
diff --git a/src/context/cdtrail_queue.h b/src/context/cdtrail_queue.h
index 3f6887d29..94d758ced 100644
--- a/src/context/cdtrail_queue.h
+++ b/src/context/cdtrail_queue.h
@@ -80,11 +80,15 @@ public:
d_iter = d_iter + 1;
}
- const T& operator[](size_t index){
+ const T& operator[](size_t index) const{
Assert(index < d_list.size());
return d_list[index];
}
+ size_t size() const{
+ return d_list.size();
+ }
+
};/* class CDTrailQueue<> */
}/* CVC4::context namespace */
diff --git a/src/prop/cryptominisat/MTRand/Makefile.in b/src/prop/cryptominisat/MTRand/Makefile.in
index 1693a70f2..8cc478cdf 100644
--- a/src/prop/cryptominisat/MTRand/Makefile.in
+++ b/src/prop/cryptominisat/MTRand/Makefile.in
@@ -34,36 +34,17 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
-subdir = src/prop/cryptominisat/MTRand
+subdir = MTRand
DIST_COMMON = $(pkgincludesub_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/config/antlr.m4 \
- $(top_srcdir)/config/ax_prog_doxygen.m4 \
- $(top_srcdir)/config/ax_tls.m4 \
- $(top_srcdir)/config/bindings.m4 $(top_srcdir)/config/boost.m4 \
- $(top_srcdir)/config/cudd.m4 $(top_srcdir)/config/cvc4.m4 \
- $(top_srcdir)/config/gcc_version.m4 \
- $(top_srcdir)/config/libtool.m4 \
- $(top_srcdir)/config/ltoptions.m4 \
- $(top_srcdir)/config/ltsugar.m4 \
- $(top_srcdir)/config/ltversion.m4 \
- $(top_srcdir)/config/lt~obsolete.m4 \
- $(top_srcdir)/config/pkg.m4 $(top_srcdir)/config/readline.m4 \
- $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/cvc4autoconfig.h
+CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
-am__v_GEN_0 = @echo " GEN " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
-am__v_at_0 = @
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -94,128 +75,54 @@ CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-ANTLR = @ANTLR@
-ANTLR_HOME = @ANTLR_HOME@
-ANTLR_INCLUDES = @ANTLR_INCLUDES@
-ANTLR_LDFLAGS = @ANTLR_LDFLAGS@
AR = @AR@
-AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
-BOOST_LDPATH = @BOOST_LDPATH@
-BOOST_ROOT = @BOOST_ROOT@
-BOOST_THREAD_LDFLAGS = @BOOST_THREAD_LDFLAGS@
-BOOST_THREAD_LDPATH = @BOOST_THREAD_LDPATH@
-BOOST_THREAD_LIBS = @BOOST_THREAD_LIBS@
-BUILDING_SHARED = @BUILDING_SHARED@
-BUILDING_STATIC = @BUILDING_STATIC@
-CAMLP4O = @CAMLP4O@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
-CLN_CFLAGS = @CLN_CFLAGS@
-CLN_LIBS = @CLN_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CSHARP_CPPFLAGS = @CSHARP_CPPFLAGS@
-CUDD_CPPFLAGS = @CUDD_CPPFLAGS@
-CUDD_LDFLAGS = @CUDD_LDFLAGS@
-CUDD_LIBS = @CUDD_LIBS@
-CVC4_BINDINGS_LIBRARY_VERSION = @CVC4_BINDINGS_LIBRARY_VERSION@
-CVC4_BUILD_LIBCOMPAT = @CVC4_BUILD_LIBCOMPAT@
-CVC4_COMPAT_LIBRARY_VERSION = @CVC4_COMPAT_LIBRARY_VERSION@
-CVC4_HAS_THREADS = @CVC4_HAS_THREADS@
-CVC4_LANGUAGE_BINDINGS = @CVC4_LANGUAGE_BINDINGS@
-CVC4_LIBRARY_VERSION = @CVC4_LIBRARY_VERSION@
-CVC4_PARSER_LIBRARY_VERSION = @CVC4_PARSER_LIBRARY_VERSION@
-CVC4_TLS = @CVC4_TLS@
-CVC4_TLS_SUPPORTED = @CVC4_TLS_SUPPORTED@
-CVC4_USE_CLN_IMP = @CVC4_USE_CLN_IMP@
-CVC4_USE_GMP_IMP = @CVC4_USE_GMP_IMP@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
-CXXTEST = @CXXTEST@
-CXXTESTGEN = @CXXTESTGEN@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
-DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
DLLTOOL = @DLLTOOL@
-DOXYGEN_EXTRACT_PRIVATE = @DOXYGEN_EXTRACT_PRIVATE@
-DOXYGEN_EXTRACT_STATIC = @DOXYGEN_EXTRACT_STATIC@
-DOXYGEN_PAPER_SIZE = @DOXYGEN_PAPER_SIZE@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
-DX_CONFIG = @DX_CONFIG@
-DX_DOCDIR = @DX_DOCDIR@
-DX_DOT = @DX_DOT@
-DX_DOXYGEN = @DX_DOXYGEN@
-DX_DVIPS = @DX_DVIPS@
-DX_EGREP = @DX_EGREP@
-DX_ENV = @DX_ENV@
-DX_FLAG_DX_CURRENT_FEATURE = @DX_FLAG_DX_CURRENT_FEATURE@
-DX_FLAG_chi = @DX_FLAG_chi@
-DX_FLAG_chm = @DX_FLAG_chm@
-DX_FLAG_doc = @DX_FLAG_doc@
-DX_FLAG_dot = @DX_FLAG_dot@
-DX_FLAG_html = @DX_FLAG_html@
-DX_FLAG_man = @DX_FLAG_man@
-DX_FLAG_pdf = @DX_FLAG_pdf@
-DX_FLAG_ps = @DX_FLAG_ps@
-DX_FLAG_rtf = @DX_FLAG_rtf@
-DX_FLAG_xml = @DX_FLAG_xml@
-DX_HHC = @DX_HHC@
-DX_LATEX = @DX_LATEX@
-DX_MAKEINDEX = @DX_MAKEINDEX@
-DX_PDFLATEX = @DX_PDFLATEX@
-DX_PERL = @DX_PERL@
-DX_PROJECT = @DX_PROJECT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
-FLAG_VISIBILITY_HIDDEN = @FLAG_VISIBILITY_HIDDEN@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-JAR = @JAR@
-JAVA = @JAVA@
-JAVAC = @JAVAC@
-JAVAH = @JAVAH@
-JAVA_CPPFLAGS = @JAVA_CPPFLAGS@
LD = @LD@
LDFLAGS = @LDFLAGS@
-LFSC = @LFSC@
-LFSCARGS = @LFSCARGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
-MAN_DATE = @MAN_DATE@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OCAMLC = @OCAMLC@
-OCAMLFIND = @OCAMLFIND@
-OCAMLMKTOP = @OCAMLMKTOP@
+OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
@@ -226,33 +133,12 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PERL_CPPFLAGS = @PERL_CPPFLAGS@
-PHP_CPPFLAGS = @PHP_CPPFLAGS@
-PKG_CONFIG = @PKG_CONFIG@
-PYTHON = @PYTHON@
-PYTHON_CONFIG = @PYTHON_CONFIG@
-PYTHON_CXXFLAGS = @PYTHON_CXXFLAGS@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_INCLUDE = @PYTHON_INCLUDE@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
-READLINE_LIBS = @READLINE_LIBS@
-RUBY_CPPFLAGS = @RUBY_CPPFLAGS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
-STATIC_BINARY = @STATIC_BINARY@
STRIP = @STRIP@
-SWIG = @SWIG@
-TCL_CPPFLAGS = @TCL_CPPFLAGS@
-TEST_CPPFLAGS = @TEST_CPPFLAGS@
-TEST_CXXFLAGS = @TEST_CXXFLAGS@
-TEST_LDFLAGS = @TEST_LDFLAGS@
VERSION = @VERSION@
-WNO_CONVERSION_NULL = @WNO_CONVERSION_NULL@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
@@ -292,26 +178,17 @@ libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
-mk_include = @mk_include@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
-pkgpyexecdir = @pkgpyexecdir@
-pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
-pyexecdir = @pyexecdir@
-pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@@ -320,7 +197,7 @@ pkgincludesub_HEADERS = MersenneTwister.h
all: all-am
.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -329,9 +206,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/prop/cryptominisat/MTRand/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu MTRand/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/prop/cryptominisat/MTRand/Makefile
+ $(AUTOMAKE) --gnu MTRand/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -345,9 +222,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
diff --git a/src/prop/cryptominisat/Makefile.in b/src/prop/cryptominisat/Makefile.in
index a6806f0b4..2d9ee8bf8 100644
--- a/src/prop/cryptominisat/Makefile.in
+++ b/src/prop/cryptominisat/Makefile.in
@@ -33,37 +33,21 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
-subdir = src/prop/cryptominisat
-DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
- AUTHORS INSTALL NEWS TODO config.guess config.sub depcomp \
- install-sh ltmain.sh missing
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(top_srcdir)/configure AUTHORS INSTALL NEWS TODO config.guess \
+ config.sub depcomp install-sh ltmain.sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/config/antlr.m4 \
- $(top_srcdir)/config/ax_prog_doxygen.m4 \
- $(top_srcdir)/config/ax_tls.m4 \
- $(top_srcdir)/config/bindings.m4 $(top_srcdir)/config/boost.m4 \
- $(top_srcdir)/config/cudd.m4 $(top_srcdir)/config/cvc4.m4 \
- $(top_srcdir)/config/gcc_version.m4 \
- $(top_srcdir)/config/libtool.m4 \
- $(top_srcdir)/config/ltoptions.m4 \
- $(top_srcdir)/config/ltsugar.m4 \
- $(top_srcdir)/config/ltversion.m4 \
- $(top_srcdir)/config/lt~obsolete.m4 \
- $(top_srcdir)/config/pkg.m4 $(top_srcdir)/config/readline.m4 \
- $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/cvc4autoconfig.h
+CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
-am__v_GEN_0 = @echo " GEN " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
-am__v_at_0 = @
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
@@ -77,11 +61,17 @@ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
- distdir
+ distdir dist dist-all distcheck
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d "$(distdir)" \
+ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr "$(distdir)"; }; }
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
@@ -107,130 +97,60 @@ am__relativize = \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-ANTLR = @ANTLR@
-ANTLR_HOME = @ANTLR_HOME@
-ANTLR_INCLUDES = @ANTLR_INCLUDES@
-ANTLR_LDFLAGS = @ANTLR_LDFLAGS@
AR = @AR@
-AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
-BOOST_LDPATH = @BOOST_LDPATH@
-BOOST_ROOT = @BOOST_ROOT@
-BOOST_THREAD_LDFLAGS = @BOOST_THREAD_LDFLAGS@
-BOOST_THREAD_LDPATH = @BOOST_THREAD_LDPATH@
-BOOST_THREAD_LIBS = @BOOST_THREAD_LIBS@
-BUILDING_SHARED = @BUILDING_SHARED@
-BUILDING_STATIC = @BUILDING_STATIC@
-CAMLP4O = @CAMLP4O@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
-CLN_CFLAGS = @CLN_CFLAGS@
-CLN_LIBS = @CLN_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CSHARP_CPPFLAGS = @CSHARP_CPPFLAGS@
-CUDD_CPPFLAGS = @CUDD_CPPFLAGS@
-CUDD_LDFLAGS = @CUDD_LDFLAGS@
-CUDD_LIBS = @CUDD_LIBS@
-CVC4_BINDINGS_LIBRARY_VERSION = @CVC4_BINDINGS_LIBRARY_VERSION@
-CVC4_BUILD_LIBCOMPAT = @CVC4_BUILD_LIBCOMPAT@
-CVC4_COMPAT_LIBRARY_VERSION = @CVC4_COMPAT_LIBRARY_VERSION@
-CVC4_HAS_THREADS = @CVC4_HAS_THREADS@
-CVC4_LANGUAGE_BINDINGS = @CVC4_LANGUAGE_BINDINGS@
-CVC4_LIBRARY_VERSION = @CVC4_LIBRARY_VERSION@
-CVC4_PARSER_LIBRARY_VERSION = @CVC4_PARSER_LIBRARY_VERSION@
-CVC4_TLS = @CVC4_TLS@
-CVC4_TLS_SUPPORTED = @CVC4_TLS_SUPPORTED@
-CVC4_USE_CLN_IMP = @CVC4_USE_CLN_IMP@
-CVC4_USE_GMP_IMP = @CVC4_USE_GMP_IMP@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
-CXXTEST = @CXXTEST@
-CXXTESTGEN = @CXXTESTGEN@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
-DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
DLLTOOL = @DLLTOOL@
-DOXYGEN_EXTRACT_PRIVATE = @DOXYGEN_EXTRACT_PRIVATE@
-DOXYGEN_EXTRACT_STATIC = @DOXYGEN_EXTRACT_STATIC@
-DOXYGEN_PAPER_SIZE = @DOXYGEN_PAPER_SIZE@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
-DX_CONFIG = @DX_CONFIG@
-DX_DOCDIR = @DX_DOCDIR@
-DX_DOT = @DX_DOT@
-DX_DOXYGEN = @DX_DOXYGEN@
-DX_DVIPS = @DX_DVIPS@
-DX_EGREP = @DX_EGREP@
-DX_ENV = @DX_ENV@
-DX_FLAG_DX_CURRENT_FEATURE = @DX_FLAG_DX_CURRENT_FEATURE@
-DX_FLAG_chi = @DX_FLAG_chi@
-DX_FLAG_chm = @DX_FLAG_chm@
-DX_FLAG_doc = @DX_FLAG_doc@
-DX_FLAG_dot = @DX_FLAG_dot@
-DX_FLAG_html = @DX_FLAG_html@
-DX_FLAG_man = @DX_FLAG_man@
-DX_FLAG_pdf = @DX_FLAG_pdf@
-DX_FLAG_ps = @DX_FLAG_ps@
-DX_FLAG_rtf = @DX_FLAG_rtf@
-DX_FLAG_xml = @DX_FLAG_xml@
-DX_HHC = @DX_HHC@
-DX_LATEX = @DX_LATEX@
-DX_MAKEINDEX = @DX_MAKEINDEX@
-DX_PDFLATEX = @DX_PDFLATEX@
-DX_PERL = @DX_PERL@
-DX_PROJECT = @DX_PROJECT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
-FLAG_VISIBILITY_HIDDEN = @FLAG_VISIBILITY_HIDDEN@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-JAR = @JAR@
-JAVA = @JAVA@
-JAVAC = @JAVAC@
-JAVAH = @JAVAH@
-JAVA_CPPFLAGS = @JAVA_CPPFLAGS@
LD = @LD@
LDFLAGS = @LDFLAGS@
-LFSC = @LFSC@
-LFSCARGS = @LFSCARGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
-MAN_DATE = @MAN_DATE@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OCAMLC = @OCAMLC@
-OCAMLFIND = @OCAMLFIND@
-OCAMLMKTOP = @OCAMLMKTOP@
+OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
@@ -241,33 +161,12 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PERL_CPPFLAGS = @PERL_CPPFLAGS@
-PHP_CPPFLAGS = @PHP_CPPFLAGS@
-PKG_CONFIG = @PKG_CONFIG@
-PYTHON = @PYTHON@
-PYTHON_CONFIG = @PYTHON_CONFIG@
-PYTHON_CXXFLAGS = @PYTHON_CXXFLAGS@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_INCLUDE = @PYTHON_INCLUDE@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
-READLINE_LIBS = @READLINE_LIBS@
-RUBY_CPPFLAGS = @RUBY_CPPFLAGS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
-STATIC_BINARY = @STATIC_BINARY@
STRIP = @STRIP@
-SWIG = @SWIG@
-TCL_CPPFLAGS = @TCL_CPPFLAGS@
-TEST_CPPFLAGS = @TEST_CPPFLAGS@
-TEST_CXXFLAGS = @TEST_CXXFLAGS@
-TEST_LDFLAGS = @TEST_LDFLAGS@
VERSION = @VERSION@
-WNO_CONVERSION_NULL = @WNO_CONVERSION_NULL@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
@@ -307,26 +206,17 @@ libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
-mk_include = @mk_include@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
-pkgpyexecdir = @pkgpyexecdir@
-pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
-pyexecdir = @pyexecdir@
-pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@@ -339,46 +229,71 @@ SUBDIRS = Solver mtl MTRand man
EXTRA_DIST = HOWTO_VisualCpp HOWTO_MinGW32 \
LICENSE-GPL LICENSE-MIT TODO
-all: all-recursive
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/prop/cryptominisat/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/prop/cryptominisat/Makefile
+ $(AUTOMAKE) --foreign Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
*) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+ $(SHELL) ./config.status --recheck
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(top_srcdir)/configure: $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
+distclean-libtool:
+ -rm -f libtool config.lt
+
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
@@ -459,7 +374,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
mkid -fID $$unique
tags: TAGS
-TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
@@ -476,7 +391,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
@@ -494,9 +409,9 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
fi; \
fi
ctags: CTAGS
-CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
@@ -515,6 +430,8 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@@ -572,9 +489,124 @@ distdir: $(DISTFILES)
|| exit 1; \
fi; \
done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @$(am__cd) '$(distuninstallcheck_dir)' \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
check-am: all-am
check: check-recursive
-all-am: Makefile all-local
+all-am: Makefile config.h all-local
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
@@ -607,8 +639,10 @@ clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
-distclean-am: clean-am distclean-generic distclean-tags
+distclean-am: clean-am distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags
dvi: dvi-recursive
@@ -651,6 +685,8 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@@ -668,22 +704,25 @@ ps-am:
uninstall-am:
-.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
- install-am install-strip tags-recursive
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
+ ctags-recursive install-am install-strip tags-recursive
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
- all all-am all-local check check-am clean clean-generic \
- clean-libtool ctags ctags-recursive distclean \
- distclean-generic distclean-libtool distclean-tags distdir dvi \
- dvi-am html html-am info info-am install install-am \
- install-data install-data-am install-dvi install-dvi-am \
- install-exec install-exec-am install-html install-html-am \
- install-info install-info-am install-man install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs installdirs-am \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags tags-recursive uninstall uninstall-am
+ all all-am all-local am--refresh check check-am clean \
+ clean-generic clean-libtool ctags ctags-recursive dist \
+ dist-all dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ \
+ dist-xz dist-zip distcheck distclean distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags distcleancheck \
+ distdir distuninstallcheck dvi dvi-am html html-am info \
+ info-am install install-am install-data install-data-am \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am
all-local: Solver
diff --git a/src/prop/cryptominisat/Solver/Makefile.in b/src/prop/cryptominisat/Solver/Makefile.in
index 02344edd7..dd524fba2 100644
--- a/src/prop/cryptominisat/Solver/Makefile.in
+++ b/src/prop/cryptominisat/Solver/Makefile.in
@@ -36,29 +36,16 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
bin_PROGRAMS = cryptominisat$(EXEEXT)
-subdir = src/prop/cryptominisat/Solver
+subdir = Solver
DIST_COMMON = $(pkgincludesub_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/config/antlr.m4 \
- $(top_srcdir)/config/ax_prog_doxygen.m4 \
- $(top_srcdir)/config/ax_tls.m4 \
- $(top_srcdir)/config/bindings.m4 $(top_srcdir)/config/boost.m4 \
- $(top_srcdir)/config/cudd.m4 $(top_srcdir)/config/cvc4.m4 \
- $(top_srcdir)/config/gcc_version.m4 \
- $(top_srcdir)/config/libtool.m4 \
- $(top_srcdir)/config/ltoptions.m4 \
- $(top_srcdir)/config/ltsugar.m4 \
- $(top_srcdir)/config/ltversion.m4 \
- $(top_srcdir)/config/lt~obsolete.m4 \
- $(top_srcdir)/config/pkg.m4 $(top_srcdir)/config/readline.m4 \
- $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/cvc4autoconfig.h
+CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -94,47 +81,29 @@ am_libcryptominisat_la_OBJECTS = ClauseCleaner.lo FailedLitSearcher.lo \
ClauseVivifier.lo CompleteDetachReattacher.lo DimacsParser.lo \
OnlyNonLearntBins.lo SolverConf.lo DataSync.lo BothCache.lo
libcryptominisat_la_OBJECTS = $(am_libcryptominisat_la_OBJECTS)
-AM_V_lt = $(am__v_lt_$(V))
-am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
-am__v_lt_0 = --silent
-libcryptominisat_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
- $(AM_CXXFLAGS) $(CXXFLAGS) $(libcryptominisat_la_LDFLAGS) \
- $(LDFLAGS) -o $@
+libcryptominisat_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(libcryptominisat_la_LDFLAGS) $(LDFLAGS) -o $@
PROGRAMS = $(bin_PROGRAMS)
am_cryptominisat_OBJECTS = Main.$(OBJEXT)
cryptominisat_OBJECTS = $(am_cryptominisat_OBJECTS)
cryptominisat_DEPENDENCIES = libcryptominisat.la
-cryptominisat_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
- $(AM_CXXFLAGS) $(CXXFLAGS) $(cryptominisat_LDFLAGS) $(LDFLAGS) \
- -o $@
+cryptominisat_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(cryptominisat_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
- $(AM_CXXFLAGS) $(CXXFLAGS)
-AM_V_CXX = $(am__v_CXX_$(V))
-am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY))
-am__v_CXX_0 = @echo " CXX " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
-am__v_at_0 = @
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
- $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CXXLD = $(am__v_CXXLD_$(V))
-am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY))
-am__v_CXXLD_0 = @echo " CXXLD " $@;
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
-am__v_GEN_0 = @echo " GEN " $@;
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
SOURCES = $(libcryptominisat_la_SOURCES) $(cryptominisat_SOURCES)
DIST_SOURCES = $(libcryptominisat_la_SOURCES) $(cryptominisat_SOURCES)
HEADERS = $(pkgincludesub_HEADERS)
@@ -143,128 +112,54 @@ CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-ANTLR = @ANTLR@
-ANTLR_HOME = @ANTLR_HOME@
-ANTLR_INCLUDES = @ANTLR_INCLUDES@
-ANTLR_LDFLAGS = @ANTLR_LDFLAGS@
AR = @AR@
-AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
-BOOST_LDPATH = @BOOST_LDPATH@
-BOOST_ROOT = @BOOST_ROOT@
-BOOST_THREAD_LDFLAGS = @BOOST_THREAD_LDFLAGS@
-BOOST_THREAD_LDPATH = @BOOST_THREAD_LDPATH@
-BOOST_THREAD_LIBS = @BOOST_THREAD_LIBS@
-BUILDING_SHARED = @BUILDING_SHARED@
-BUILDING_STATIC = @BUILDING_STATIC@
-CAMLP4O = @CAMLP4O@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
-CLN_CFLAGS = @CLN_CFLAGS@
-CLN_LIBS = @CLN_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CSHARP_CPPFLAGS = @CSHARP_CPPFLAGS@
-CUDD_CPPFLAGS = @CUDD_CPPFLAGS@
-CUDD_LDFLAGS = @CUDD_LDFLAGS@
-CUDD_LIBS = @CUDD_LIBS@
-CVC4_BINDINGS_LIBRARY_VERSION = @CVC4_BINDINGS_LIBRARY_VERSION@
-CVC4_BUILD_LIBCOMPAT = @CVC4_BUILD_LIBCOMPAT@
-CVC4_COMPAT_LIBRARY_VERSION = @CVC4_COMPAT_LIBRARY_VERSION@
-CVC4_HAS_THREADS = @CVC4_HAS_THREADS@
-CVC4_LANGUAGE_BINDINGS = @CVC4_LANGUAGE_BINDINGS@
-CVC4_LIBRARY_VERSION = @CVC4_LIBRARY_VERSION@
-CVC4_PARSER_LIBRARY_VERSION = @CVC4_PARSER_LIBRARY_VERSION@
-CVC4_TLS = @CVC4_TLS@
-CVC4_TLS_SUPPORTED = @CVC4_TLS_SUPPORTED@
-CVC4_USE_CLN_IMP = @CVC4_USE_CLN_IMP@
-CVC4_USE_GMP_IMP = @CVC4_USE_GMP_IMP@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
-CXXTEST = @CXXTEST@
-CXXTESTGEN = @CXXTESTGEN@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
-DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
DLLTOOL = @DLLTOOL@
-DOXYGEN_EXTRACT_PRIVATE = @DOXYGEN_EXTRACT_PRIVATE@
-DOXYGEN_EXTRACT_STATIC = @DOXYGEN_EXTRACT_STATIC@
-DOXYGEN_PAPER_SIZE = @DOXYGEN_PAPER_SIZE@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
-DX_CONFIG = @DX_CONFIG@
-DX_DOCDIR = @DX_DOCDIR@
-DX_DOT = @DX_DOT@
-DX_DOXYGEN = @DX_DOXYGEN@
-DX_DVIPS = @DX_DVIPS@
-DX_EGREP = @DX_EGREP@
-DX_ENV = @DX_ENV@
-DX_FLAG_DX_CURRENT_FEATURE = @DX_FLAG_DX_CURRENT_FEATURE@
-DX_FLAG_chi = @DX_FLAG_chi@
-DX_FLAG_chm = @DX_FLAG_chm@
-DX_FLAG_doc = @DX_FLAG_doc@
-DX_FLAG_dot = @DX_FLAG_dot@
-DX_FLAG_html = @DX_FLAG_html@
-DX_FLAG_man = @DX_FLAG_man@
-DX_FLAG_pdf = @DX_FLAG_pdf@
-DX_FLAG_ps = @DX_FLAG_ps@
-DX_FLAG_rtf = @DX_FLAG_rtf@
-DX_FLAG_xml = @DX_FLAG_xml@
-DX_HHC = @DX_HHC@
-DX_LATEX = @DX_LATEX@
-DX_MAKEINDEX = @DX_MAKEINDEX@
-DX_PDFLATEX = @DX_PDFLATEX@
-DX_PERL = @DX_PERL@
-DX_PROJECT = @DX_PROJECT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
-FLAG_VISIBILITY_HIDDEN = @FLAG_VISIBILITY_HIDDEN@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-JAR = @JAR@
-JAVA = @JAVA@
-JAVAC = @JAVAC@
-JAVAH = @JAVAH@
-JAVA_CPPFLAGS = @JAVA_CPPFLAGS@
LD = @LD@
LDFLAGS = @LDFLAGS@
-LFSC = @LFSC@
-LFSCARGS = @LFSCARGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
-MAN_DATE = @MAN_DATE@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OCAMLC = @OCAMLC@
-OCAMLFIND = @OCAMLFIND@
-OCAMLMKTOP = @OCAMLMKTOP@
+OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
@@ -275,33 +170,12 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PERL_CPPFLAGS = @PERL_CPPFLAGS@
-PHP_CPPFLAGS = @PHP_CPPFLAGS@
-PKG_CONFIG = @PKG_CONFIG@
-PYTHON = @PYTHON@
-PYTHON_CONFIG = @PYTHON_CONFIG@
-PYTHON_CXXFLAGS = @PYTHON_CXXFLAGS@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_INCLUDE = @PYTHON_INCLUDE@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
-READLINE_LIBS = @READLINE_LIBS@
-RUBY_CPPFLAGS = @RUBY_CPPFLAGS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
-STATIC_BINARY = @STATIC_BINARY@
STRIP = @STRIP@
-SWIG = @SWIG@
-TCL_CPPFLAGS = @TCL_CPPFLAGS@
-TEST_CPPFLAGS = @TEST_CPPFLAGS@
-TEST_CXXFLAGS = @TEST_CXXFLAGS@
-TEST_LDFLAGS = @TEST_LDFLAGS@
VERSION = @VERSION@
-WNO_CONVERSION_NULL = @WNO_CONVERSION_NULL@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
@@ -341,26 +215,17 @@ libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
-mk_include = @mk_include@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
-pkgpyexecdir = @pkgpyexecdir@
-pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
-pyexecdir = @pyexecdir@
-pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@@ -398,7 +263,7 @@ all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -407,9 +272,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/prop/cryptominisat/Solver/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Solver/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/prop/cryptominisat/Solver/Makefile
+ $(AUTOMAKE) --gnu Solver/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -423,9 +288,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@@ -460,7 +325,7 @@ clean-libLTLIBRARIES:
rm -f "$${dir}/so_locations"; \
done
libcryptominisat.la: $(libcryptominisat_la_OBJECTS) $(libcryptominisat_la_DEPENDENCIES)
- $(AM_V_CXXLD)$(libcryptominisat_la_LINK) -rpath $(libdir) $(libcryptominisat_la_OBJECTS) $(libcryptominisat_la_LIBADD) $(LIBS)
+ $(libcryptominisat_la_LINK) -rpath $(libdir) $(libcryptominisat_la_OBJECTS) $(libcryptominisat_la_LIBADD) $(LIBS)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@@ -506,7 +371,7 @@ clean-binPROGRAMS:
rm -f $$list
cryptominisat$(EXEEXT): $(cryptominisat_OBJECTS) $(cryptominisat_DEPENDENCIES)
@rm -f cryptominisat$(EXEEXT)
- $(AM_V_CXXLD)$(cryptominisat_LINK) $(cryptominisat_OBJECTS) $(cryptominisat_LDADD) $(LIBS)
+ $(cryptominisat_LINK) $(cryptominisat_OBJECTS) $(cryptominisat_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -541,25 +406,22 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XorSubsumer.Plo@am__quote@
.cpp.o:
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
diff --git a/src/prop/cryptominisat/man/Makefile.in b/src/prop/cryptominisat/man/Makefile.in
index 7dc705cf1..5542511eb 100644
--- a/src/prop/cryptominisat/man/Makefile.in
+++ b/src/prop/cryptominisat/man/Makefile.in
@@ -33,35 +33,16 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
-subdir = src/prop/cryptominisat/man
+subdir = man
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/config/antlr.m4 \
- $(top_srcdir)/config/ax_prog_doxygen.m4 \
- $(top_srcdir)/config/ax_tls.m4 \
- $(top_srcdir)/config/bindings.m4 $(top_srcdir)/config/boost.m4 \
- $(top_srcdir)/config/cudd.m4 $(top_srcdir)/config/cvc4.m4 \
- $(top_srcdir)/config/gcc_version.m4 \
- $(top_srcdir)/config/libtool.m4 \
- $(top_srcdir)/config/ltoptions.m4 \
- $(top_srcdir)/config/ltsugar.m4 \
- $(top_srcdir)/config/ltversion.m4 \
- $(top_srcdir)/config/lt~obsolete.m4 \
- $(top_srcdir)/config/pkg.m4 $(top_srcdir)/config/readline.m4 \
- $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/cvc4autoconfig.h
+CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
-am__v_GEN_0 = @echo " GEN " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
-am__v_at_0 = @
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -92,128 +73,54 @@ MANS = $(man_MANS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-ANTLR = @ANTLR@
-ANTLR_HOME = @ANTLR_HOME@
-ANTLR_INCLUDES = @ANTLR_INCLUDES@
-ANTLR_LDFLAGS = @ANTLR_LDFLAGS@
AR = @AR@
-AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
-BOOST_LDPATH = @BOOST_LDPATH@
-BOOST_ROOT = @BOOST_ROOT@
-BOOST_THREAD_LDFLAGS = @BOOST_THREAD_LDFLAGS@
-BOOST_THREAD_LDPATH = @BOOST_THREAD_LDPATH@
-BOOST_THREAD_LIBS = @BOOST_THREAD_LIBS@
-BUILDING_SHARED = @BUILDING_SHARED@
-BUILDING_STATIC = @BUILDING_STATIC@
-CAMLP4O = @CAMLP4O@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
-CLN_CFLAGS = @CLN_CFLAGS@
-CLN_LIBS = @CLN_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CSHARP_CPPFLAGS = @CSHARP_CPPFLAGS@
-CUDD_CPPFLAGS = @CUDD_CPPFLAGS@
-CUDD_LDFLAGS = @CUDD_LDFLAGS@
-CUDD_LIBS = @CUDD_LIBS@
-CVC4_BINDINGS_LIBRARY_VERSION = @CVC4_BINDINGS_LIBRARY_VERSION@
-CVC4_BUILD_LIBCOMPAT = @CVC4_BUILD_LIBCOMPAT@
-CVC4_COMPAT_LIBRARY_VERSION = @CVC4_COMPAT_LIBRARY_VERSION@
-CVC4_HAS_THREADS = @CVC4_HAS_THREADS@
-CVC4_LANGUAGE_BINDINGS = @CVC4_LANGUAGE_BINDINGS@
-CVC4_LIBRARY_VERSION = @CVC4_LIBRARY_VERSION@
-CVC4_PARSER_LIBRARY_VERSION = @CVC4_PARSER_LIBRARY_VERSION@
-CVC4_TLS = @CVC4_TLS@
-CVC4_TLS_SUPPORTED = @CVC4_TLS_SUPPORTED@
-CVC4_USE_CLN_IMP = @CVC4_USE_CLN_IMP@
-CVC4_USE_GMP_IMP = @CVC4_USE_GMP_IMP@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
-CXXTEST = @CXXTEST@
-CXXTESTGEN = @CXXTESTGEN@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
-DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
DLLTOOL = @DLLTOOL@
-DOXYGEN_EXTRACT_PRIVATE = @DOXYGEN_EXTRACT_PRIVATE@
-DOXYGEN_EXTRACT_STATIC = @DOXYGEN_EXTRACT_STATIC@
-DOXYGEN_PAPER_SIZE = @DOXYGEN_PAPER_SIZE@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
-DX_CONFIG = @DX_CONFIG@
-DX_DOCDIR = @DX_DOCDIR@
-DX_DOT = @DX_DOT@
-DX_DOXYGEN = @DX_DOXYGEN@
-DX_DVIPS = @DX_DVIPS@
-DX_EGREP = @DX_EGREP@
-DX_ENV = @DX_ENV@
-DX_FLAG_DX_CURRENT_FEATURE = @DX_FLAG_DX_CURRENT_FEATURE@
-DX_FLAG_chi = @DX_FLAG_chi@
-DX_FLAG_chm = @DX_FLAG_chm@
-DX_FLAG_doc = @DX_FLAG_doc@
-DX_FLAG_dot = @DX_FLAG_dot@
-DX_FLAG_html = @DX_FLAG_html@
-DX_FLAG_man = @DX_FLAG_man@
-DX_FLAG_pdf = @DX_FLAG_pdf@
-DX_FLAG_ps = @DX_FLAG_ps@
-DX_FLAG_rtf = @DX_FLAG_rtf@
-DX_FLAG_xml = @DX_FLAG_xml@
-DX_HHC = @DX_HHC@
-DX_LATEX = @DX_LATEX@
-DX_MAKEINDEX = @DX_MAKEINDEX@
-DX_PDFLATEX = @DX_PDFLATEX@
-DX_PERL = @DX_PERL@
-DX_PROJECT = @DX_PROJECT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
-FLAG_VISIBILITY_HIDDEN = @FLAG_VISIBILITY_HIDDEN@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-JAR = @JAR@
-JAVA = @JAVA@
-JAVAC = @JAVAC@
-JAVAH = @JAVAH@
-JAVA_CPPFLAGS = @JAVA_CPPFLAGS@
LD = @LD@
LDFLAGS = @LDFLAGS@
-LFSC = @LFSC@
-LFSCARGS = @LFSCARGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
-MAN_DATE = @MAN_DATE@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OCAMLC = @OCAMLC@
-OCAMLFIND = @OCAMLFIND@
-OCAMLMKTOP = @OCAMLMKTOP@
+OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
@@ -224,33 +131,12 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PERL_CPPFLAGS = @PERL_CPPFLAGS@
-PHP_CPPFLAGS = @PHP_CPPFLAGS@
-PKG_CONFIG = @PKG_CONFIG@
-PYTHON = @PYTHON@
-PYTHON_CONFIG = @PYTHON_CONFIG@
-PYTHON_CXXFLAGS = @PYTHON_CXXFLAGS@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_INCLUDE = @PYTHON_INCLUDE@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
-READLINE_LIBS = @READLINE_LIBS@
-RUBY_CPPFLAGS = @RUBY_CPPFLAGS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
-STATIC_BINARY = @STATIC_BINARY@
STRIP = @STRIP@
-SWIG = @SWIG@
-TCL_CPPFLAGS = @TCL_CPPFLAGS@
-TEST_CPPFLAGS = @TEST_CPPFLAGS@
-TEST_CXXFLAGS = @TEST_CXXFLAGS@
-TEST_LDFLAGS = @TEST_LDFLAGS@
VERSION = @VERSION@
-WNO_CONVERSION_NULL = @WNO_CONVERSION_NULL@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
@@ -290,26 +176,17 @@ libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
-mk_include = @mk_include@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
-pkgpyexecdir = @pkgpyexecdir@
-pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
-pyexecdir = @pyexecdir@
-pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@@ -318,7 +195,7 @@ EXTRA_DIST = $(man_MANS)
all: all-am
.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -327,9 +204,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/prop/cryptominisat/man/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/prop/cryptominisat/man/Makefile
+ $(AUTOMAKE) --gnu man/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -343,9 +220,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
diff --git a/src/prop/cryptominisat/mtl/Makefile.in b/src/prop/cryptominisat/mtl/Makefile.in
index 7d8c8ce1b..eb9b73e19 100644
--- a/src/prop/cryptominisat/mtl/Makefile.in
+++ b/src/prop/cryptominisat/mtl/Makefile.in
@@ -34,36 +34,17 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-target_triplet = @target@
-subdir = src/prop/cryptominisat/mtl
+subdir = mtl
DIST_COMMON = $(pkgincludesub_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/config/antlr.m4 \
- $(top_srcdir)/config/ax_prog_doxygen.m4 \
- $(top_srcdir)/config/ax_tls.m4 \
- $(top_srcdir)/config/bindings.m4 $(top_srcdir)/config/boost.m4 \
- $(top_srcdir)/config/cudd.m4 $(top_srcdir)/config/cvc4.m4 \
- $(top_srcdir)/config/gcc_version.m4 \
- $(top_srcdir)/config/libtool.m4 \
- $(top_srcdir)/config/ltoptions.m4 \
- $(top_srcdir)/config/ltsugar.m4 \
- $(top_srcdir)/config/ltversion.m4 \
- $(top_srcdir)/config/lt~obsolete.m4 \
- $(top_srcdir)/config/pkg.m4 $(top_srcdir)/config/readline.m4 \
- $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/cvc4autoconfig.h
+CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
-am__v_GEN_0 = @echo " GEN " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
-am__v_at_0 = @
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -94,128 +75,54 @@ CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-ANTLR = @ANTLR@
-ANTLR_HOME = @ANTLR_HOME@
-ANTLR_INCLUDES = @ANTLR_INCLUDES@
-ANTLR_LDFLAGS = @ANTLR_LDFLAGS@
AR = @AR@
-AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
-BOOST_LDPATH = @BOOST_LDPATH@
-BOOST_ROOT = @BOOST_ROOT@
-BOOST_THREAD_LDFLAGS = @BOOST_THREAD_LDFLAGS@
-BOOST_THREAD_LDPATH = @BOOST_THREAD_LDPATH@
-BOOST_THREAD_LIBS = @BOOST_THREAD_LIBS@
-BUILDING_SHARED = @BUILDING_SHARED@
-BUILDING_STATIC = @BUILDING_STATIC@
-CAMLP4O = @CAMLP4O@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
-CLN_CFLAGS = @CLN_CFLAGS@
-CLN_LIBS = @CLN_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CSHARP_CPPFLAGS = @CSHARP_CPPFLAGS@
-CUDD_CPPFLAGS = @CUDD_CPPFLAGS@
-CUDD_LDFLAGS = @CUDD_LDFLAGS@
-CUDD_LIBS = @CUDD_LIBS@
-CVC4_BINDINGS_LIBRARY_VERSION = @CVC4_BINDINGS_LIBRARY_VERSION@
-CVC4_BUILD_LIBCOMPAT = @CVC4_BUILD_LIBCOMPAT@
-CVC4_COMPAT_LIBRARY_VERSION = @CVC4_COMPAT_LIBRARY_VERSION@
-CVC4_HAS_THREADS = @CVC4_HAS_THREADS@
-CVC4_LANGUAGE_BINDINGS = @CVC4_LANGUAGE_BINDINGS@
-CVC4_LIBRARY_VERSION = @CVC4_LIBRARY_VERSION@
-CVC4_PARSER_LIBRARY_VERSION = @CVC4_PARSER_LIBRARY_VERSION@
-CVC4_TLS = @CVC4_TLS@
-CVC4_TLS_SUPPORTED = @CVC4_TLS_SUPPORTED@
-CVC4_USE_CLN_IMP = @CVC4_USE_CLN_IMP@
-CVC4_USE_GMP_IMP = @CVC4_USE_GMP_IMP@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
-CXXTEST = @CXXTEST@
-CXXTESTGEN = @CXXTESTGEN@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
-DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
DLLTOOL = @DLLTOOL@
-DOXYGEN_EXTRACT_PRIVATE = @DOXYGEN_EXTRACT_PRIVATE@
-DOXYGEN_EXTRACT_STATIC = @DOXYGEN_EXTRACT_STATIC@
-DOXYGEN_PAPER_SIZE = @DOXYGEN_PAPER_SIZE@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
-DX_CONFIG = @DX_CONFIG@
-DX_DOCDIR = @DX_DOCDIR@
-DX_DOT = @DX_DOT@
-DX_DOXYGEN = @DX_DOXYGEN@
-DX_DVIPS = @DX_DVIPS@
-DX_EGREP = @DX_EGREP@
-DX_ENV = @DX_ENV@
-DX_FLAG_DX_CURRENT_FEATURE = @DX_FLAG_DX_CURRENT_FEATURE@
-DX_FLAG_chi = @DX_FLAG_chi@
-DX_FLAG_chm = @DX_FLAG_chm@
-DX_FLAG_doc = @DX_FLAG_doc@
-DX_FLAG_dot = @DX_FLAG_dot@
-DX_FLAG_html = @DX_FLAG_html@
-DX_FLAG_man = @DX_FLAG_man@
-DX_FLAG_pdf = @DX_FLAG_pdf@
-DX_FLAG_ps = @DX_FLAG_ps@
-DX_FLAG_rtf = @DX_FLAG_rtf@
-DX_FLAG_xml = @DX_FLAG_xml@
-DX_HHC = @DX_HHC@
-DX_LATEX = @DX_LATEX@
-DX_MAKEINDEX = @DX_MAKEINDEX@
-DX_PDFLATEX = @DX_PDFLATEX@
-DX_PERL = @DX_PERL@
-DX_PROJECT = @DX_PROJECT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
-FLAG_VISIBILITY_HIDDEN = @FLAG_VISIBILITY_HIDDEN@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-JAR = @JAR@
-JAVA = @JAVA@
-JAVAC = @JAVAC@
-JAVAH = @JAVAH@
-JAVA_CPPFLAGS = @JAVA_CPPFLAGS@
LD = @LD@
LDFLAGS = @LDFLAGS@
-LFSC = @LFSC@
-LFSCARGS = @LFSCARGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
-MAN_DATE = @MAN_DATE@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
-OCAMLC = @OCAMLC@
-OCAMLFIND = @OCAMLFIND@
-OCAMLMKTOP = @OCAMLMKTOP@
+OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
@@ -226,33 +133,12 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PERL_CPPFLAGS = @PERL_CPPFLAGS@
-PHP_CPPFLAGS = @PHP_CPPFLAGS@
-PKG_CONFIG = @PKG_CONFIG@
-PYTHON = @PYTHON@
-PYTHON_CONFIG = @PYTHON_CONFIG@
-PYTHON_CXXFLAGS = @PYTHON_CXXFLAGS@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_INCLUDE = @PYTHON_INCLUDE@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
-READLINE_LIBS = @READLINE_LIBS@
-RUBY_CPPFLAGS = @RUBY_CPPFLAGS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
-STATIC_BINARY = @STATIC_BINARY@
STRIP = @STRIP@
-SWIG = @SWIG@
-TCL_CPPFLAGS = @TCL_CPPFLAGS@
-TEST_CPPFLAGS = @TEST_CPPFLAGS@
-TEST_CXXFLAGS = @TEST_CXXFLAGS@
-TEST_LDFLAGS = @TEST_LDFLAGS@
VERSION = @VERSION@
-WNO_CONVERSION_NULL = @WNO_CONVERSION_NULL@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
@@ -292,26 +178,17 @@ libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
-mk_include = @mk_include@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
-pkgpyexecdir = @pkgpyexecdir@
-pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
-pyexecdir = @pyexecdir@
-pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
-target = @target@
target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@@ -320,7 +197,7 @@ pkgincludesub_HEADERS = Alg.h Heap.h Vec.h
all: all-am
.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -329,9 +206,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/prop/cryptominisat/mtl/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu mtl/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/prop/cryptominisat/mtl/Makefile
+ $(AUTOMAKE) --gnu mtl/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -345,9 +222,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index e73af60e9..97407a425 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -291,6 +291,9 @@ SmtEngine::SmtEngine(ExprManager* em) throw(AssertionException) :
setTimeLimit(Options::current()->cumulativeMillisecondLimit, true);
}
+
+ d_propEngine->assertFormula(NodeManager::currentNM()->mkConst<bool>(true));
+ d_propEngine->assertFormula(NodeManager::currentNM()->mkConst<bool>(false).notNode());
}
void SmtEngine::shutdown() {
diff --git a/src/theory/arith/Makefile.am b/src/theory/arith/Makefile.am
index 4cff4a782..b97a6f384 100644
--- a/src/theory/arith/Makefile.am
+++ b/src/theory/arith/Makefile.am
@@ -12,11 +12,10 @@ libarith_la_SOURCES = \
arith_rewriter.cpp \
arith_static_learner.h \
arith_static_learner.cpp \
- arith_prop_manager.h \
- arith_prop_manager.cpp \
arithvar_node_map.h \
- atom_database.h \
- atom_database.cpp \
+ constraint_forward.h \
+ constraint.h \
+ constraint.cpp \
difference_manager.h \
difference_manager.cpp \
normal_form.h\
@@ -28,7 +27,6 @@ libarith_la_SOURCES = \
partial_model.cpp \
linear_equality.h \
linear_equality.cpp \
- ordered_set.h \
arithvar_set.h \
tableau.h \
tableau.cpp \
diff --git a/src/theory/arith/arith_prop_manager.cpp b/src/theory/arith/arith_prop_manager.cpp
deleted file mode 100644
index dc9b0ddb9..000000000
--- a/src/theory/arith/arith_prop_manager.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/********************* */
-/*! \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"
-
-#include "theory/arith/arith_utilities.h"
-#include "context/context.h"
-#include "context/cdlist.h"
-#include "context/cdhashmap.h"
-#include "context/cdo.h"
-
-using namespace CVC4::kind;
-using namespace std;
-
-
-namespace CVC4 {
-namespace theory {
-namespace arith {
-
-bool ArithPropManager::isAsserted(TNode n) const{
- Node satValue = d_valuation.getSatValue(n);
- if(satValue.isNull()){
- return false;
- }else{
- //Assert(satValue.getConst<bool>());
- return true;
- }
-}
-
-
-Node ArithPropManager::strictlyWeakerAssertedUpperBound(ArithVar v, const DeltaRational& b) const{
- Node bound = boundAsNode(true, v, b);
-
- Assert(b.getInfinitesimalPart() <= 0);
- bool largeEpsilon = (b.getInfinitesimalPart() < -1);
-
- Node weaker = bound;
- do {
- if(largeEpsilon){
- weaker = d_atomDatabase.getBestImpliedUpperBound(weaker);
- largeEpsilon = false;
- }else{
- weaker = d_atomDatabase.getWeakerImpliedUpperBound(weaker);
- }
- }while(!weaker.isNull() && !isAsserted(weaker));
- return weaker;
-}
-
-Node ArithPropManager::strictlyWeakerAssertedLowerBound(ArithVar v, const DeltaRational& b) const{
- Debug("ArithPropManager") << "strictlyWeakerAssertedLowerBound" << endl;
- Node bound = boundAsNode(false, v, b);
-
- Assert(b.getInfinitesimalPart() >= 0);
- bool largeEpsilon = (b.getInfinitesimalPart() > 1);
-
- Node weaker = bound;
- Debug("ArithPropManager") << bound << b << endl;
- do {
- if(largeEpsilon){
- weaker = d_atomDatabase.getBestImpliedLowerBound(weaker);
- largeEpsilon = false;
- }else{
- weaker = d_atomDatabase.getWeakerImpliedLowerBound(weaker);
- }
- }while(!weaker.isNull() && !isAsserted(weaker));
- Debug("ArithPropManager") << "res: " << weaker << endl;
- return weaker;
-}
-
-Node ArithPropManager::getBestImpliedLowerBound(ArithVar v, const DeltaRational& b) const{
- Node bound = boundAsNode(false, v, b);
- return d_atomDatabase.getBestImpliedLowerBound(bound);
-}
-Node ArithPropManager::getBestImpliedUpperBound(ArithVar v, const DeltaRational& b) const{
- Node bound = boundAsNode(true, v, b);
- return d_atomDatabase.getBestImpliedUpperBound(bound);
-}
-
-Node ArithPropManager::boundAsNode(bool upperbound, ArithVar var, const DeltaRational& b) const {
- Assert((!upperbound) || (b.getInfinitesimalPart() <= 0) );
- Assert(upperbound || (b.getInfinitesimalPart() >= 0) );
-
- Node varAsNode = d_arithvarNodeMap.asNode(var);
- Kind kind;
- bool negate;
- if(upperbound){
- negate = b.getInfinitesimalPart() < 0;
- kind = negate ? GEQ : LEQ;
- } else{
- negate = b.getInfinitesimalPart() > 0;
- kind = negate ? LEQ : GEQ;
- }
-
- Node righthand = mkRationalNode(b.getNoninfinitesimalPart());
- Node bAsNode = NodeBuilder<2>(kind) << varAsNode << righthand;
-
- if(negate){
- bAsNode = NodeBuilder<1>(NOT) << bAsNode;
- }
-
- return bAsNode;
-}
-
-bool ArithPropManager::propagateArithVar(bool upperbound, ArithVar var, const DeltaRational& b, TNode reason){
- bool success = false;
-
- ++d_statistics.d_propagateArithVarCalls;
-
- Node bAsNode = boundAsNode(upperbound, var ,b);
-
- Node bestImplied = upperbound ?
- d_atomDatabase.getBestImpliedUpperBound(bAsNode):
- d_atomDatabase.getBestImpliedLowerBound(bAsNode);
-
- Debug("ArithPropManager") << upperbound <<","<< var <<","<< b <<","<< reason << endl
- << bestImplied << endl;
-
- if(!bestImplied.isNull()){
- bool asserted = isAsserted(bestImplied);
-
- if( !asserted && !isPropagated(bestImplied)){
- propagate(bestImplied, reason, false);
- ++d_statistics.d_addedPropagation;
- success = true;
- }else if(!asserted){
- ++d_statistics.d_alreadyPropagatedNode;
- }else if(!isPropagated(bestImplied)){
- ++d_statistics.d_alreadySetSatLiteral;
- }
- }
- return success;
-}
-
-ArithPropManager::Statistics::Statistics():
- d_propagateArithVarCalls("arith::prop-manager::propagateArithVarCalls",0),
- d_addedPropagation("arith::prop-manager::addedPropagation",0),
- d_alreadySetSatLiteral("arith::prop-manager::alreadySetSatLiteral",0),
- d_alreadyPropagatedNode("arith::prop-manager::alreadyPropagatedNode",0)
-{
- StatisticsRegistry::registerStat(&d_propagateArithVarCalls);
- StatisticsRegistry::registerStat(&d_alreadySetSatLiteral);
- StatisticsRegistry::registerStat(&d_alreadyPropagatedNode);
- StatisticsRegistry::registerStat(&d_addedPropagation);
-}
-
-ArithPropManager::Statistics::~Statistics()
-{
- StatisticsRegistry::unregisterStat(&d_propagateArithVarCalls);
- StatisticsRegistry::unregisterStat(&d_alreadySetSatLiteral);
- StatisticsRegistry::unregisterStat(&d_alreadyPropagatedNode);
- StatisticsRegistry::unregisterStat(&d_addedPropagation);
-}
-
-}; /* namesapce arith */
-}; /* namespace theory */
-}; /* namespace CVC4 */
diff --git a/src/theory/arith/arith_prop_manager.h b/src/theory/arith/arith_prop_manager.h
deleted file mode 100644
index 900a0ed58..000000000
--- a/src/theory/arith/arith_prop_manager.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/********************* */
-/*! \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
-#define __CVC4__THEORY__ARITH__ARITH_PROP_MANAGER_H
-
-#include "theory/valuation.h"
-#include "theory/arith/arithvar.h"
-#include "theory/arith/arithvar_node_map.h"
-#include "theory/arith/atom_database.h"
-#include "theory/arith/delta_rational.h"
-#include "context/context.h"
-#include "context/cdlist.h"
-#include "context/cdhashmap.h"
-#include "context/cdo.h"
-#include "theory/rewriter.h"
-#include "util/stats.h"
-
-namespace CVC4 {
-namespace theory {
-namespace arith {
-
-class PropManager {
-public:
- struct PropUnit {
- // consequent <= antecedent
- // i.e. the antecedent is the explanation of the consequent.
- Node consequent;
- Node antecedent;
- bool flag;
- PropUnit(Node c, Node a, bool f) :
- consequent(c), antecedent(a), flag(f)
- {}
- };
-
-private:
- context::CDList<PropUnit> d_propagated;
- context::CDO<uint32_t> d_propagatedPos;
-
- /* This maps the node a theory engine will request on an explain call to
- * to its corresponding PropUnit.
- * This is node is potentially both the consequent or Rewriter::rewrite(consequent).
- */
- typedef context::CDHashMap<Node, size_t, NodeHashFunction> ExplainMap;
- ExplainMap d_explanationMap;
-
- size_t getIndex(TNode n) const {
- Assert(isPropagated(n));
- return (*(d_explanationMap.find(n))).second;
- }
-
-public:
-
- PropManager(context::Context* c):
- d_propagated(c),
- d_propagatedPos(c, 0),
- d_explanationMap(c)
- { }
-
- const PropUnit& getUnit(TNode n) const {
- return d_propagated[getIndex(n)];
- }
-
- bool isPropagated(TNode n) const {
- return d_explanationMap.find(n) != d_explanationMap.end();
- }
-
- bool isFlagged(TNode n) const {
- return getUnit(n).flag;
- }
-
- void propagate(TNode n, Node reason, bool flag) {
- Assert(!isPropagated(n));
-
- if(flag){
- Node rewritten = Rewriter::rewrite(n);
- d_explanationMap.insert(rewritten, d_propagated.size());
- }else{
- //If !flag, then the rewriter is idempotent on n.
- Assert(Rewriter::rewrite(n) == n);
- }
- d_explanationMap.insert(n, d_propagated.size());
- d_propagated.push_back(PropUnit(n, reason, flag));
-
- Debug("ArithPropManager") << n << std::endl << "<="<< reason<< std::endl;
- }
-
- bool hasMorePropagations() const {
- return d_propagatedPos < d_propagated.size();
- }
-
- const PropUnit& getNextPropagation() {
- Assert(hasMorePropagations());
- const PropUnit& prop = d_propagated[d_propagatedPos];
- d_propagatedPos = d_propagatedPos + 1;
- return prop;
- }
-
- TNode explain(TNode n) const {
- return getUnit(n).antecedent;
- }
-
-};/* class PropManager */
-
-class ArithPropManager : public PropManager {
-private:
- const ArithVarNodeMap& d_arithvarNodeMap;
- const ArithAtomDatabase& d_atomDatabase;
- Valuation d_valuation;
-
-public:
- ArithPropManager(context::Context* c,
- const ArithVarNodeMap& map,
- const ArithAtomDatabase& db,
- Valuation v):
- PropManager(c), d_arithvarNodeMap(map), d_atomDatabase(db), d_valuation(v)
- {}
-
- /**
- * Returns true if the node has a value in sat solver in the current context.
- * In debug mode this fails an Assert() if the node has a negative assignment.
- */
- bool isAsserted(TNode n) const;
-
- /** Returns true if a bound was added. */
- bool propagateArithVar(bool upperbound, ArithVar var, const DeltaRational& b, TNode reason);
-
- Node boundAsNode(bool upperbound, ArithVar var, const DeltaRational& b) const;
-
- Node strictlyWeakerLowerBound(TNode n) const{
- return d_atomDatabase.getWeakerImpliedLowerBound(n);
- }
- Node strictlyWeakerUpperBound(TNode n) const{
- return d_atomDatabase.getWeakerImpliedUpperBound(n);
- }
-
- Node strictlyWeakerAssertedUpperBound(ArithVar v, const DeltaRational& b) const;
-
- Node strictlyWeakerAssertedLowerBound(ArithVar v, const DeltaRational& b) const;
-
- Node getBestImpliedLowerBound(ArithVar v, const DeltaRational& b) const;
- Node getBestImpliedUpperBound(ArithVar v, const DeltaRational& b) const;
-
- bool containsLiteral(TNode n) const {
- return d_atomDatabase.containsLiteral(n);
- }
-
-private:
- class Statistics {
- public:
- IntStat d_propagateArithVarCalls;
- IntStat d_addedPropagation;
- IntStat d_alreadySetSatLiteral;
- IntStat d_alreadyPropagatedNode;
-
- Statistics();
- ~Statistics();
- };
- Statistics d_statistics;
-};
-
-}/* CVC4::theory::arith namespace */
-}/* CVC4::theory namespace */
-}/* CVC4 namespace */
-
-#endif /* __CVC4__THEORY__ARITH__ARITH_PROP_MANAGER_H */
diff --git a/src/theory/arith/arith_rewriter.cpp b/src/theory/arith/arith_rewriter.cpp
index 30568c3ca..863eb5c31 100644
--- a/src/theory/arith/arith_rewriter.cpp
+++ b/src/theory/arith/arith_rewriter.cpp
@@ -204,34 +204,30 @@ RewriteResponse ArithRewriter::postRewriteMult(TNode t){
return RewriteResponse(REWRITE_DONE, res.getNode());
}
-RewriteResponse ArithRewriter::postRewriteAtomConstantRHS(TNode t){
- TNode left = t[0];
- TNode right = t[1];
+// RewriteResponse ArithRewriter::postRewriteAtomConstantRHS(TNode t){
+// TNode left = t[0];
+// TNode right = t[1];
- Comparison cmp = Comparison::mkNormalComparison(t.getKind(), Polynomial::parsePolynomial(left), Constant(right));
+// Polynomial pLeft = Polynomial::parsePolynomial(left);
+
- Assert(cmp.isNormalForm());
- return RewriteResponse(REWRITE_DONE, cmp.getNode());
-}
+// Comparison cmp = Comparison::mkComparison(t.getKind(), Polynomial::parsePolynomial(left), Constant(right));
+
+// Assert(cmp.isNormalForm());
+// return RewriteResponse(REWRITE_DONE, cmp.getNode());
+// }
RewriteResponse ArithRewriter::postRewriteAtom(TNode atom){
// left |><| right
TNode left = atom[0];
TNode right = atom[1];
- if(right.getMetaKind() == kind::metakind::CONSTANT){
- return postRewriteAtomConstantRHS(atom);
- }else{
- Polynomial pleft = Polynomial::parsePolynomial(left);
- Polynomial pright = Polynomial::parsePolynomial(right);
-
- Polynomial diff = pleft - pright;
-
- Constant cZero = Constant::mkConstant(Rational(0));
- Node reduction = NodeManager::currentNM()->mkNode(atom.getKind(), diff.getNode(), cZero.getNode());
+ Polynomial pleft = Polynomial::parsePolynomial(left);
+ Polynomial pright = Polynomial::parsePolynomial(right);
- return postRewriteAtomConstantRHS(reduction);
- }
+ Comparison cmp = Comparison::mkComparison(atom.getKind(), pleft, pright);
+ Assert(cmp.isNormalForm());
+ return RewriteResponse(REWRITE_DONE, cmp.getNode());
}
RewriteResponse ArithRewriter::preRewriteAtom(TNode atom){
diff --git a/src/theory/arith/arith_rewriter.h b/src/theory/arith/arith_rewriter.h
index 07c009b2e..748ed8686 100644
--- a/src/theory/arith/arith_rewriter.h
+++ b/src/theory/arith/arith_rewriter.h
@@ -66,7 +66,6 @@ private:
static RewriteResponse preRewriteAtom(TNode t);
static RewriteResponse postRewriteAtom(TNode t);
- static RewriteResponse postRewriteAtomConstantRHS(TNode t);
static bool isAtom(TNode n);
diff --git a/src/theory/arith/arith_static_learner.cpp b/src/theory/arith/arith_static_learner.cpp
index 2f4f6e32b..8ecc3abdc 100644
--- a/src/theory/arith/arith_static_learner.cpp
+++ b/src/theory/arith/arith_static_learner.cpp
@@ -261,7 +261,7 @@ void ArithStaticLearner::iteMinMax(TNode n, NodeBuilder<>& learned){
Assert(isRelationOperator(n[0].getKind()));
TNode c = n[0];
- Kind k = simplifiedKind(c);
+ Kind k = oldSimplifiedKind(c);
TNode t = n[1];
TNode e = n[2];
TNode cleft = (c.getKind() == NOT) ? c[0][0] : c[0];
diff --git a/src/theory/arith/arith_utilities.h b/src/theory/arith/arith_utilities.h
index a5d94ec40..af32c3f87 100644
--- a/src/theory/arith/arith_utilities.h
+++ b/src/theory/arith/arith_utilities.h
@@ -168,17 +168,17 @@ inline int deltaCoeff(Kind k){
* - (NOT (GT left right)) -> LEQ
* If none of these match, it returns UNDEFINED_KIND.
*/
- inline Kind simplifiedKind(TNode assertion){
- switch(assertion.getKind()){
+ inline Kind oldSimplifiedKind(TNode literal){
+ switch(literal.getKind()){
case kind::LT:
case kind::GT:
case kind::LEQ:
case kind::GEQ:
case kind::EQUAL:
- return assertion.getKind();
+ return literal.getKind();
case kind::NOT:
{
- TNode atom = assertion[0];
+ TNode atom = literal[0];
switch(atom.getKind()){
case kind::LEQ: //(not (LEQ x c)) <=> (GT x c)
return kind::GT;
@@ -201,57 +201,58 @@ inline int deltaCoeff(Kind k){
}
}
-template <bool selectLeft>
-inline TNode getSide(TNode assertion, Kind simpleKind){
- switch(simpleKind){
- case kind::LT:
- case kind::GT:
- case kind::DISTINCT:
- return selectLeft ? (assertion[0])[0] : (assertion[0])[1];
- case kind::LEQ:
- case kind::GEQ:
- case kind::EQUAL:
- return selectLeft ? assertion[0] : assertion[1];
- default:
- Unreachable();
- return TNode::null();
- }
-}
-
-inline DeltaRational determineRightConstant(TNode assertion, Kind simpleKind){
- TNode right = getSide<false>(assertion, simpleKind);
-
- Assert(right.getKind() == kind::CONST_RATIONAL);
- const Rational& noninf = right.getConst<Rational>();
- Rational inf = Rational(Integer(deltaCoeff(simpleKind)));
- return DeltaRational(noninf, inf);
-}
-
-inline DeltaRational asDeltaRational(TNode n){
- Kind simp = simplifiedKind(n);
- return determineRightConstant(n, simp);
-}
-
- /**
- * Takes two nodes with exactly 2 children,
- * the second child of both are of kind CONST_RATIONAL,
- * and compares value of the two children.
- * This is for comparing inequality nodes.
- * RightHandRationalLT((<= x 50), (< x 75)) == true
- */
-struct RightHandRationalLT
-{
- bool operator()(TNode s1, TNode s2) const
- {
- TNode rh1 = s1[1];
- TNode rh2 = s2[1];
- const Rational& c1 = rh1.getConst<Rational>();
- const Rational& c2 = rh2.getConst<Rational>();
- int cmpRes = c1.cmp(c2);
- return cmpRes < 0;
- }
-};
+// template <bool selectLeft>
+// inline TNode getSide(TNode assertion, Kind simpleKind){
+// switch(simpleKind){
+// case kind::LT:
+// case kind::GT:
+// case kind::DISTINCT:
+// return selectLeft ? (assertion[0])[0] : (assertion[0])[1];
+// case kind::LEQ:
+// case kind::GEQ:
+// case kind::EQUAL:
+// return selectLeft ? assertion[0] : assertion[1];
+// default:
+// Unreachable();
+// return TNode::null();
+// }
+// }
+
+// inline DeltaRational determineRightConstant(TNode assertion, Kind simpleKind){
+// TNode right = getSide<false>(assertion, simpleKind);
+
+// Assert(right.getKind() == kind::CONST_RATIONAL);
+// const Rational& noninf = right.getConst<Rational>();
+
+// Rational inf = Rational(Integer(deltaCoeff(simpleKind)));
+// return DeltaRational(noninf, inf);
+// }
+
+// inline DeltaRational asDeltaRational(TNode n){
+// Kind simp = simplifiedKind(n);
+// return determineRightConstant(n, simp);
+// }
+
+// /**
+// * Takes two nodes with exactly 2 children,
+// * the second child of both are of kind CONST_RATIONAL,
+// * and compares value of the two children.
+// * This is for comparing inequality nodes.
+// * RightHandRationalLT((<= x 50), (< x 75)) == true
+// */
+// struct RightHandRationalLT
+// {
+// bool operator()(TNode s1, TNode s2) const
+// {
+// TNode rh1 = s1[1];
+// TNode rh2 = s2[1];
+// const Rational& c1 = rh1.getConst<Rational>();
+// const Rational& c2 = rh2.getConst<Rational>();
+// int cmpRes = c1.cmp(c2);
+// return cmpRes < 0;
+// }
+// };
inline Node negateConjunctionAsClause(TNode conjunction){
Assert(conjunction.getKind() == kind::AND);
@@ -278,6 +279,24 @@ inline Node maybeUnaryConvert(NodeBuilder<>& builder){
}
}
+inline void flattenAnd(Node n, std::vector<TNode>& out){
+ Assert(n.getKind() == kind::AND);
+ for(Node::iterator i=n.begin(), i_end=n.end(); i != i_end; ++i){
+ Node curr = *i;
+ if(curr.getKind() == kind::AND){
+ flattenAnd(curr, out);
+ }else{
+ out.push_back(curr);
+ }
+ }
+}
+
+inline Node flattenAnd(Node n){
+ std::vector<TNode> out;
+ flattenAnd(n, out);
+ return NodeManager::currentNM()->mkNode(kind::AND, out);
+}
+
}; /* namesapce arith */
}; /* namespace theory */
}; /* namespace CVC4 */
diff --git a/src/theory/arith/arithvar.h b/src/theory/arith/arithvar.h
index 52dc9fd6a..432f9f0c2 100644
--- a/src/theory/arith/arithvar.h
+++ b/src/theory/arith/arithvar.h
@@ -47,7 +47,17 @@ typedef __gnu_cxx::hash_map<ArithVar, Node> ArithVarToNodeMap;
*/
class ArithVarCallBack {
public:
- virtual void callback(ArithVar x) = 0;
+ virtual void operator()(ArithVar x) = 0;
+};
+
+class TNodeCallBack {
+public:
+ virtual void operator()(TNode n) = 0;
+};
+
+class NodeCallBack {
+public:
+ virtual void operator()(Node n) = 0;
};
}; /* namesapce arith */
diff --git a/src/theory/arith/arithvar_set.h b/src/theory/arith/arithvar_set.h
index b502849fd..b9ae48b16 100644
--- a/src/theory/arith/arithvar_set.h
+++ b/src/theory/arith/arithvar_set.h
@@ -322,43 +322,27 @@ public:
class CDArithVarSet {
private:
- class RemoveIntWrapper{
- private:
- ArithVar d_var;
- ArithVarCallBack& d_onDestruction;
-
- public:
- RemoveIntWrapper(ArithVar v, ArithVarCallBack& onDestruction):
- d_var(v), d_onDestruction(onDestruction)
- {}
-
- ~RemoveIntWrapper(){
- d_onDestruction.callback(d_var);
- }
- };
-
- std::vector<bool> d_set;
- context::CDList<RemoveIntWrapper> d_list;
-
- class OnDestruction : public ArithVarCallBack {
+ class RemoveIntCleanup {
private:
std::vector<bool>& d_set;
public:
- OnDestruction(std::vector<bool>& set):
- d_set(set)
+ RemoveIntCleanup(std::vector<bool>& set)
+ : d_set(set)
{}
- void callback(ArithVar x){
- Assert(x < d_set.size());
+ void operator()(ArithVar* p){
+ ArithVar x = *p;
+ Assert(d_set[x]);
d_set[x] = false;
}
};
- OnDestruction d_callback;
+ std::vector<bool> d_set;
+ context::CDList<ArithVar, RemoveIntCleanup> d_list;
public:
- CDArithVarSet(context::Context* c) :
- d_list(c), d_callback(d_set)
+ CDArithVarSet(context::Context* c)
+ : d_set(), d_list(c, true, RemoveIntCleanup(d_set))
{ }
/** This cannot be const as garbage collection is done lazily. */
@@ -375,7 +359,7 @@ public:
if(x >= d_set.size()){
d_set.resize(x+1, false);
}
- d_list.push_back(RemoveIntWrapper(x, d_callback));
+ d_list.push_back(x);
d_set[x] = true;
}
};
diff --git a/src/theory/arith/atom_database.cpp b/src/theory/arith/atom_database.cpp
deleted file mode 100644
index 3476eb8f5..000000000
--- a/src/theory/arith/atom_database.cpp
+++ /dev/null
@@ -1,542 +0,0 @@
-/********************* */
-/*! \file atom_database.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/atom_database.h"
-#include "theory/arith/arith_utilities.h"
-
-#include <list>
-
-using namespace std;
-using namespace CVC4::kind;
-
-namespace CVC4 {
-namespace theory {
-namespace arith {
-
-ArithAtomDatabase::ArithAtomDatabase(context::Context* cxt, OutputChannel& out) :
- d_arithOut(out), d_setsMap()
-{ }
-
-bool ArithAtomDatabase::leftIsSetup(TNode left) const{
- return d_setsMap.find(left) != d_setsMap.end();
-}
-
-const ArithAtomDatabase::VariablesSets& ArithAtomDatabase::getVariablesSets(TNode left) const{
- Assert(leftIsSetup(left));
- NodeToSetsMap::const_iterator i = d_setsMap.find(left);
- return i->second;
-}
-ArithAtomDatabase::VariablesSets& ArithAtomDatabase::getVariablesSets(TNode left){
- Assert(leftIsSetup(left));
- NodeToSetsMap::iterator i = d_setsMap.find(left);
- return i->second;
-}
-EqualValueSet& ArithAtomDatabase::getEqualValueSet(TNode left){
- Assert(leftIsSetup(left));
- return getVariablesSets(left).d_eqValueSet;
-}
-
-const EqualValueSet& ArithAtomDatabase::getEqualValueSet(TNode left) const{
- Assert(leftIsSetup(left));
- return getVariablesSets(left).d_eqValueSet;
-}
-
-BoundValueSet& ArithAtomDatabase::getBoundValueSet(TNode left){
- Assert(leftIsSetup(left));
- return getVariablesSets(left).d_boundValueSet;
-}
-
-const BoundValueSet& ArithAtomDatabase::getBoundValueSet(TNode left) const{
- Assert(leftIsSetup(left));
- return getVariablesSets(left).d_boundValueSet;
-}
-
-bool ArithAtomDatabase::hasAnyAtoms(TNode v) const{
- Assert(!leftIsSetup(v)
- || !(getEqualValueSet(v)).empty()
- || !(getBoundValueSet(v)).empty());
-
- return leftIsSetup(v);
-}
-
-void ArithAtomDatabase::setupLefthand(TNode left){
- Assert(!leftIsSetup(left));
-
- d_setsMap[left] = VariablesSets();
-}
-
-bool ArithAtomDatabase::containsLiteral(TNode lit) const{
- switch(lit.getKind()){
- case NOT: return containsAtom(lit[0]);
- default: return containsAtom(lit);
- }
-}
-
-bool ArithAtomDatabase::containsAtom(TNode atom) const{
- switch(atom.getKind()){
- case EQUAL: return containsEquality(atom);
- case LEQ: return containsLeq(atom);
- case GEQ: return containsGeq(atom);
- default:
- Unreachable();
- }
-}
-
-bool ArithAtomDatabase::containsEquality(TNode atom) const{
- TNode left = atom[0];
- const EqualValueSet& eqSet = getEqualValueSet(left);
- return eqSet.find(atom) != eqSet.end();
-}
-
-bool ArithAtomDatabase::containsLeq(TNode atom) const{
- TNode left = atom[0];
- const Rational& value = rightHandRational(atom);
-
- const BoundValueSet& bvSet = getBoundValueSet(left);
- BoundValueSet::const_iterator i = bvSet.find(value);
- if(i == bvSet.end()){
- return false;
- }else{
- const BoundValueEntry& entry = i->second;
- return entry.hasLeq();
- }
-}
-
-bool ArithAtomDatabase::containsGeq(TNode atom) const{
- TNode left = atom[0];
- const Rational& value = rightHandRational(atom);
-
- const BoundValueSet& bvSet = getBoundValueSet(left);
- BoundValueSet::const_iterator i = bvSet.find(value);
- if(i == bvSet.end()){
- return false;
- }else{
- const BoundValueEntry& entry = i->second;
- return entry.hasGeq();
- }
-}
-
-void ArithAtomDatabase::addAtom(TNode atom){
- TNode left = atom[0];
- TNode right = atom[1];
-
- if(!leftIsSetup(left)){
- setupLefthand(left);
- }
-
- const Rational& value = rightHandRational(atom);
-
- switch(atom.getKind()){
- case EQUAL:
- {
- Assert(!containsEquality(atom));
- addImplicationsUsingEqualityAndEqualityValues(atom);
- addImplicationsUsingEqualityAndBoundValues(atom);
-
- pair<EqualValueSet::iterator, bool> res = getEqualValueSet(left).insert(atom);
- Assert(res.second);
- break;
- }
- case LEQ:
- {
- addImplicationsUsingLeqAndEqualityValues(atom);
- addImplicationsUsingLeqAndBoundValues(atom);
-
- BoundValueSet& bvSet = getBoundValueSet(left);
- if(hasBoundValueEntry(atom)){
- BoundValueSet::iterator i = bvSet.find(value);
- BoundValueEntry& inSet = i->second;
- inSet.addLeq(atom);
- }else{
- bvSet.insert(make_pair(value, BoundValueEntry::mkFromLeq(atom)));
- }
- break;
- }
- case GEQ:
- {
- addImplicationsUsingGeqAndEqualityValues(atom);
- addImplicationsUsingGeqAndBoundValues(atom);
-
- BoundValueSet& bvSet = getBoundValueSet(left);
- if(hasBoundValueEntry(atom)){
- BoundValueSet::iterator i = bvSet.find(value);
- BoundValueEntry& inSet = i->second;
- inSet.addGeq(atom);
- }else{
- bvSet.insert(make_pair(value, BoundValueEntry::mkFromGeq(atom)));
- }
- break;
- }
- default:
- Unreachable();
- }
-}
-
-bool ArithAtomDatabase::hasBoundValueEntry(TNode atom){
- TNode left = atom[0];
- const Rational& value = rightHandRational(atom);
- BoundValueSet& bvSet = getBoundValueSet(left);
- return bvSet.find(value) != bvSet.end();
-}
-
-bool rightHandRationalIsEqual(TNode a, TNode b){
- TNode secondA = a[1];
- TNode secondB = b[1];
-
- const Rational& qA = secondA.getConst<Rational>();
- const Rational& qB = secondB.getConst<Rational>();
-
- return qA == qB;
-}
-
-
-bool rightHandRationalIsLT(TNode a, TNode b){
- //This version is sticking around because it is easier to read!
- return RightHandRationalLT()(a,b);
-}
-
-void ArithAtomDatabase::addImplicationsUsingEqualityAndEqualityValues(TNode atom){
- Assert(atom.getKind() == EQUAL);
- TNode left = atom[0];
- EqualValueSet& eqSet = getEqualValueSet(left);
-
- Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
-
- for(EqualValueSet::iterator eqIter = eqSet.begin(), endIter = eqSet.end();
- eqIter != endIter; ++eqIter){
- TNode eq = *eqIter;
- Assert(eq != atom);
- addImplication(eq, negation);
- }
-}
-
-// if weaker, do not return an equivalent node
-// if strict, get the strongest bound implied by (< x value)
-// if !strict, get the strongest bound implied by (<= x value)
-Node getUpperBound(const BoundValueSet& bvSet, const Rational& value, bool strict, bool weaker){
- BoundValueSet::const_iterator bv = bvSet.lower_bound(value);
- if(bv == bvSet.end()){
- return Node::null();
- }
-
- if((bv->second).getValue() == value){
- const BoundValueEntry& entry = bv->second;
- if(strict && entry.hasGeq() && !weaker){
- return NodeBuilder<1>(NOT) << entry.getGeq();
- }else if(entry.hasLeq() && (strict || !weaker)){
- return entry.getLeq();
- }
- }
- ++bv;
- if(bv == bvSet.end()){
- return Node::null();
- }
- Assert(bv->second.getValue() > value);
- const BoundValueEntry& entry = bv->second;
- if(entry.hasGeq()){
- return NodeBuilder<1>(NOT) << entry.getGeq();
- }else{
- Assert(entry.hasLeq());
- return entry.getLeq();
- }
-}
-
-
-
-
-// if weaker, do not return an equivalent node
-// if strict, get the strongest bound implied by (> x value)
-// if !strict, get the strongest bound implied by (>= x value)
-Node getLowerBound(const BoundValueSet& bvSet, const Rational& value, bool strict, bool weaker){
- static int time = 0;
- ++time;
-
- if(bvSet.empty()){
- return Node::null();
- }
- Debug("getLowerBound") << "getLowerBound" << bvSet.size() << " " << value << " " << strict << weaker << endl;
-
- BoundValueSet::const_iterator bv = bvSet.lower_bound(value);
- if(bv == bvSet.end()){
- Debug("getLowerBound") << "got end " << value << " " << (bvSet.rbegin()->second).getValue() << endl;
- Assert(value > (bvSet.rbegin()->second).getValue());
- }else{
- Debug("getLowerBound") << value << ", " << bv->second.getValue() << endl;
- Assert(value <= bv->second.getValue());
- }
-
- if(bv != bvSet.end() && (bv->second).getValue() == value){
- const BoundValueEntry& entry = bv->second;
- Debug("getLowerBound") << entry.hasLeq() << entry.hasGeq() << endl;
- if(strict && entry.hasLeq() && !weaker){
- return NodeBuilder<1>(NOT) << entry.getLeq();
- }else if(entry.hasGeq() && (strict || !weaker)){
- return entry.getGeq();
- }
- }
- if(bv == bvSet.begin()){
- return Node::null();
- }else{
- --bv;
- // (and (>= x v) (>= v v')) then (> x v')
- Assert(bv->second.getValue() < value);
- const BoundValueEntry& entry = bv->second;
- if(entry.hasLeq()){
- return NodeBuilder<1>(NOT) << entry.getLeq();
- }else{
- Assert(entry.hasGeq());
- return entry.getGeq();
- }
- }
-}
-
-void ArithAtomDatabase::addImplicationsUsingEqualityAndBoundValues(TNode atom){
- Assert(atom.getKind() == EQUAL);
- Node left = atom[0];
-
- const Rational& value = rightHandRational(atom);
-
- BoundValueSet& bvSet = getBoundValueSet(left);
- Node ub = getUpperBound(bvSet, value, false, false);
- Node lb = getLowerBound(bvSet, value, false, false);
-
- if(!ub.isNull()){
- addImplication(atom, ub);
- }
-
- if(!lb.isNull()){
- addImplication(atom, lb);
- }
-}
-
-void ArithAtomDatabase::addImplicationsUsingLeqAndBoundValues(TNode atom)
-{
- Assert(atom.getKind() == LEQ);
- Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
-
- Node ub = getImpliedUpperBoundUsingLeq(atom, false);
- Node lb = getImpliedLowerBoundUsingGT(negation, false);
-
- if(!ub.isNull()){
- addImplication(atom, ub);
- }
-
- if(!lb.isNull()){
- addImplication(negation, lb);
- }
-}
-
-void ArithAtomDatabase::addImplicationsUsingLeqAndEqualityValues(TNode atom) {
- Assert(atom.getKind() == LEQ);
- Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
-
- TNode left = atom[0];
- EqualValueSet& eqSet = getEqualValueSet(left);
-
- //TODO Improve this later
- for(EqualValueSet::iterator eqIter = eqSet.begin(); eqIter != eqSet.end(); ++eqIter){
- TNode eq = *eqIter;
- if(rightHandRationalIsEqual(atom, eq)){
- // (x = b' /\ b = b') => x <= b
- addImplication(eq, atom);
- }else if(rightHandRationalIsLT(atom, eq)){
- // (x = b' /\ b' > b) => x > b
- addImplication(eq, negation);
- }else{
- // (x = b' /\ b' < b) => x <= b
- addImplication(eq, atom);
- }
- }
-}
-
-
-void ArithAtomDatabase::addImplicationsUsingGeqAndBoundValues(TNode atom){
- Assert(atom.getKind() == GEQ);
- Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
-
- Node lb = getImpliedLowerBoundUsingGeq(atom, false); //What is implied by (>= left value)
- Node ub = getImpliedUpperBoundUsingLT(negation, false);
-
- if(!lb.isNull()){
- addImplication(atom, lb);
- }
-
- if(!ub.isNull()){
- addImplication(negation, ub);
- }
-}
-void ArithAtomDatabase::addImplicationsUsingGeqAndEqualityValues(TNode atom){
-
- Assert(atom.getKind() == GEQ);
- Node negation = NodeManager::currentNM()->mkNode(NOT, atom);
- Node left = atom[0];
- EqualValueSet& eqSet = getEqualValueSet(left);
-
- //TODO Improve this later
- for(EqualValueSet::iterator eqIter = eqSet.begin(); eqIter != eqSet.end(); ++eqIter){
- TNode eq = *eqIter;
- if(rightHandRationalIsEqual(atom, eq)){
- // (x = b' /\ b = b') => x >= b
- addImplication(eq, atom);
- }else if(rightHandRationalIsLT(eq, atom)){
- // (x = b' /\ b' < b) => x < b
- addImplication(eq, negation);
- }else{
- // (x = b' /\ b' > b) => x >= b
- addImplication(eq, atom);
- }
- }
-}
-
-void ArithAtomDatabase::addImplication(TNode a, TNode b){
- Node imp = NodeBuilder<2>(IMPLIES) << a << b;
-
- Debug("arith::unate") << "ArithAtomDatabase::addImplication"
- << "(" << a << ", " << b <<")" << endl;
-
- d_arithOut.lemma(imp);
-}
-
-
-Node ArithAtomDatabase::getImpliedUpperBoundUsingLeq(TNode leq, bool weaker) const {
- Assert(leq.getKind() == LEQ);
- Node left = leq[0];
-
- if(!leftIsSetup(left)) return Node::null();
-
- const Rational& value = rightHandRational(leq);
- const BoundValueSet& bvSet = getBoundValueSet(left);
-
- Node ub = getUpperBound(bvSet, value, false, weaker);
- return ub;
-}
-
-Node ArithAtomDatabase::getImpliedUpperBoundUsingLT(TNode lt, bool weaker) const {
- Assert(lt.getKind() == NOT && lt[0].getKind() == GEQ);
- Node atom = lt[0];
- Node left = atom[0];
-
- if(!leftIsSetup(left)) return Node::null();
-
- const Rational& value = rightHandRational(atom);
- const BoundValueSet& bvSet = getBoundValueSet(left);
-
- return getUpperBound(bvSet, value, true, weaker);
-}
-
-Node ArithAtomDatabase::getBestImpliedUpperBound(TNode upperBound) const {
- Node result = Node::null();
- if(upperBound.getKind() == LEQ ){
- result = getImpliedUpperBoundUsingLeq(upperBound, false);
- }else if(upperBound.getKind() == NOT && upperBound[0].getKind() == GEQ){
- result = getImpliedUpperBoundUsingLT(upperBound, false);
- }else if(upperBound.getKind() == LT){
- Node geq = NodeBuilder<2>(GEQ) << upperBound[0] << upperBound[1];
- Node lt = NodeBuilder<1>(NOT) << geq;
- result = getImpliedUpperBoundUsingLT(lt, false);
- }else{
- Unreachable();
- }
-
- Debug("arith::unate") << upperBound <<" -> " << result << std::endl;
- return result;
-}
-
-Node ArithAtomDatabase::getWeakerImpliedUpperBound(TNode upperBound) const {
- Node result = Node::null();
- if(upperBound.getKind() == LEQ ){
- result = getImpliedUpperBoundUsingLeq(upperBound, true);
- }else if(upperBound.getKind() == NOT && upperBound[0].getKind() == GEQ){
- result = getImpliedUpperBoundUsingLT(upperBound, true);
- }else if(upperBound.getKind() == LT){
- Node geq = NodeBuilder<2>(GEQ) << upperBound[0] << upperBound[1];
- Node lt = NodeBuilder<1>(NOT) << geq;
- result = getImpliedUpperBoundUsingLT(lt, true);
- }else{
- Unreachable();
- }
- Assert(upperBound != result);
- Debug("arith::unate") << upperBound <<" -> " << result << std::endl;
- return result;
-}
-
-Node ArithAtomDatabase::getImpliedLowerBoundUsingGT(TNode gt, bool weaker) const {
- Assert(gt.getKind() == NOT && gt[0].getKind() == LEQ);
- Node atom = gt[0];
- Node left = atom[0];
-
- if(!leftIsSetup(left)) return Node::null();
-
- const Rational& value = rightHandRational(atom);
- const BoundValueSet& bvSet = getBoundValueSet(left);
-
- return getLowerBound(bvSet, value, true, weaker);
-}
-
-Node ArithAtomDatabase::getImpliedLowerBoundUsingGeq(TNode geq, bool weaker) const {
- Assert(geq.getKind() == GEQ);
- Node left = geq[0];
-
- if(!leftIsSetup(left)) return Node::null();
-
- const Rational& value = rightHandRational(geq);
- const BoundValueSet& bvSet = getBoundValueSet(left);
-
- return getLowerBound(bvSet, value, false, weaker);
-}
-
-Node ArithAtomDatabase::getBestImpliedLowerBound(TNode lowerBound) const {
- Node result = Node::null();
- if(lowerBound.getKind() == GEQ ){
- result = getImpliedLowerBoundUsingGeq(lowerBound, false);
- }else if(lowerBound.getKind() == NOT && lowerBound[0].getKind() == LEQ){
- result = getImpliedLowerBoundUsingGT(lowerBound, false);
- }else if(lowerBound.getKind() == GT){
- Node leq = NodeBuilder<2>(LEQ)<<lowerBound[0]<< lowerBound[1];
- Node gt = NodeBuilder<1>(NOT) << leq;
- result = getImpliedLowerBoundUsingGT(gt, false);
- }else{
- Unreachable();
- }
- Debug("arith::unate") << lowerBound <<" -> " << result << std::endl;
- return result;
-}
-
-Node ArithAtomDatabase::getWeakerImpliedLowerBound(TNode lowerBound) const {
- Node result = Node::null();
- if(lowerBound.getKind() == GEQ ){
- result = getImpliedLowerBoundUsingGeq(lowerBound, true);
- }else if(lowerBound.getKind() == NOT && lowerBound[0].getKind() == LEQ){
- result = getImpliedLowerBoundUsingGT(lowerBound, true);
- }else if(lowerBound.getKind() == GT){
- Node leq = NodeBuilder<2>(LEQ)<<lowerBound[0]<< lowerBound[1];
- Node gt = NodeBuilder<1>(NOT) << leq;
- result = getImpliedLowerBoundUsingGT(gt, true);
- }else{
- Unreachable();
- }
- Assert(result != lowerBound);
-
- Debug("arith::unate") << lowerBound <<" -> " << result << std::endl;
- return result;
-}
-
-}; /* namesapce arith */
-}; /* namespace theory */
-}; /* namespace CVC4 */
diff --git a/src/theory/arith/atom_database.h b/src/theory/arith/atom_database.h
deleted file mode 100644
index 4da8d7975..000000000
--- a/src/theory/arith/atom_database.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/********************* */
-/*! \file atom_database.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 ArithAtomDatabase keeps a database of the arithmetic atoms.
- ** Importantly, ArithAtomDatabase also handles unate propagations,
- ** i.e. it constructs implications of the form
- ** "if x < c and c < b, then x < b" (where c and b are constants).
- **
- ** ArithAtomDatabase detects unate implications amongst the atoms
- ** associated with the theory of arithmetic and informs the SAT solver of the
- ** implication. A unate implication is an implication of the form:
- ** "if x < c and c < b, then x < b" (where c and b are constants).
- ** Unate implications are always 2-SAT clauses.
- ** ArithAtomDatabase sends the implications to the SAT solver in an
- ** online fashion.
- ** This means that atoms may be added during solving or before.
- **
- ** ArithAtomDatabase maintains sorted lists containing all atoms associated
- ** for each unique left hand side, the "x" in the inequality "x < c".
- ** The lists are sorted by the value of the right hand side which must be a
- ** rational constant.
- **
- ** ArithAtomDatabase tries to send out a minimal number of additional
- ** lemmas per atom added. Let (x < a), (x < b), (x < c) be arithmetic atoms s.t.
- ** a < b < c.
- ** If the the order of adding the atoms is (x < a), (x < b), and (x < c), then
- ** then set of all lemmas added is:
- ** {(=> (x<a) (x < b)), (=> (x<b) (x < c))}
- ** If the order is changed to (x < a), (x < c), and (x < b), then
- ** the final set of implications emitted is:
- ** {(=> (x<a) (x < c)), (=> (x<a) (x < b)), (=> (x<b) (x < c))}
- **
- ** \todo document this file
- **/
-
-
-
-#include "cvc4_private.h"
-
-#ifndef __CVC4__THEORY__ARITH__ARITH_ATOM_DATABASE_H
-#define __CVC4__THEORY__ARITH__ARITH_ATOM_DATABASE_H
-
-#include "expr/node.h"
-#include "context/context.h"
-
-#include "theory/output_channel.h"
-#include "theory/arith/ordered_set.h"
-
-#include <ext/hash_map>
-
-namespace CVC4 {
-namespace theory {
-namespace arith {
-
-class ArithAtomDatabase {
-private:
- /**
- * OutputChannel for the theory of arithmetic.
- * The propagator uses this to pass implications back to the SAT solver.
- */
- OutputChannel& d_arithOut;
-
- struct VariablesSets {
- BoundValueSet d_boundValueSet;
- EqualValueSet d_eqValueSet;
- };
-
- typedef __gnu_cxx::hash_map<TNode, VariablesSets, NodeHashFunction> NodeToSetsMap;
- NodeToSetsMap d_setsMap;
-
-public:
- ArithAtomDatabase(context::Context* cxt, OutputChannel& arith);
-
- /**
- * Adds an atom to the propagator.
- * Any resulting lemmas will be output via d_arithOut.
- */
- void addAtom(TNode atom);
-
- /** Returns true if v has been added as a left hand side in an atom */
- bool hasAnyAtoms(TNode v) const;
-
- bool containsLiteral(TNode lit) const;
- bool containsAtom(TNode atom) const;
- bool containsEquality(TNode atom) const;
- bool containsLeq(TNode atom) const;
- bool containsGeq(TNode atom) const;
-
- /** Check to make sure an lhs has been properly set-up. */
- bool leftIsSetup(TNode left) const;
-
-private:
-
- VariablesSets& getVariablesSets(TNode left);
- BoundValueSet& getBoundValueSet(TNode left);
- EqualValueSet& getEqualValueSet(TNode left);
-
- const VariablesSets& getVariablesSets(TNode left) const;
- const BoundValueSet& getBoundValueSet(TNode left) const;
- const EqualValueSet& getEqualValueSet(TNode left) const;
-
- /** Sends an implication (=> a b) to the PropEngine via d_arithOut. */
- void addImplication(TNode a, TNode b);
-
- /** Initializes the lists associated with a unique lhs. */
- void setupLefthand(TNode left);
-
-
- /**
- * The addImplicationsUsingKAndJList(...)
- * functions are the work horses of the unate part of ArithAtomDatabase.
- * These take an atom of the kind K that has just been added
- * to its associated list, and the ordered list of Js associated with the lhs,
- * and uses these to deduce unate implications.
- * (K and J vary over EQUAL, LEQ, and GEQ.)
- *
- * Input:
- * atom - the atom being inserted of kind K
- * Jset - the list of atoms of kind J associated with the lhs.
- *
- * Unfortunately, these tend to be an absolute bear to read because
- * of all of the special casing and C++ iterator manipulation required.
- */
-
- void addImplicationsUsingEqualityAndEqualityValues(TNode eq);
- void addImplicationsUsingEqualityAndBoundValues(TNode eq);
-
- void addImplicationsUsingLeqAndEqualityValues(TNode leq);
- void addImplicationsUsingLeqAndBoundValues(TNode leq);
-
- void addImplicationsUsingGeqAndEqualityValues(TNode geq);
- void addImplicationsUsingGeqAndBoundValues(TNode geq);
-
- bool hasBoundValueEntry(TNode n);
-
- Node getImpliedUpperBoundUsingLeq(TNode leq, bool weaker) const;
- Node getImpliedUpperBoundUsingLT(TNode lt, bool weaker) const;
-
- Node getImpliedLowerBoundUsingGeq(TNode geq, bool weaker) const;
- Node getImpliedLowerBoundUsingGT(TNode gt, bool weaker) const;
-
-public:
- Node getBestImpliedUpperBound(TNode upperBound) const;
- Node getBestImpliedLowerBound(TNode lowerBound) const;
-
-
- Node getWeakerImpliedUpperBound(TNode upperBound) const;
- Node getWeakerImpliedLowerBound(TNode lowerBound) const;
-};
-
-}/* CVC4::theory::arith namespace */
-}/* CVC4::theory namespace */
-}/* CVC4 namespace */
-
-#endif /* __CVC4__THEORY__ARITH__ARITH_ATOM_DATABASE_H */
diff --git a/src/theory/arith/constraint.cpp b/src/theory/arith/constraint.cpp
new file mode 100644
index 000000000..f78ecdddf
--- /dev/null
+++ b/src/theory/arith/constraint.cpp
@@ -0,0 +1,1130 @@
+
+#include "cvc4_private.h"
+#include "theory/arith/constraint.h"
+#include "theory/arith/arith_utilities.h"
+#include "theory/arith/normal_form.h"
+
+#include <ostream>
+#include <algorithm>
+
+using namespace std;
+using namespace CVC4::kind;
+
+namespace CVC4 {
+namespace theory {
+namespace arith {
+
+/** Given a simplifiedKind this returns the corresponding ConstraintType. */
+//ConstraintType constraintTypeOfLiteral(Kind k);
+ConstraintType constraintTypeOfComparison(const Comparison& cmp){
+ Kind k = cmp.comparisonKind();
+ switch(k){
+ case LT:
+ case LEQ:
+ {
+ Polynomial l = cmp.getLeft();
+ if(l.leadingCoefficientIsPositive()){ // (< x c)
+ return UpperBound;
+ }else{
+ return LowerBound; // (< (-x) c)
+ }
+ }
+ case GT:
+ case GEQ:
+ {
+ Polynomial l = cmp.getLeft();
+ if(l.leadingCoefficientIsPositive()){
+ return LowerBound; // (> x c)
+ }else{
+ return UpperBound; // (> (-x) c)
+ }
+ }
+ case EQUAL:
+ return Equality;
+ case DISTINCT:
+ return Disequality;
+ default:
+ Unhandled(k);
+ }
+}
+
+ConstraintValue::ConstraintValue(ArithVar x, ConstraintType t, const DeltaRational& v)
+ : d_variable(x),
+ d_type(t),
+ d_value(v),
+ d_database(NULL),
+ d_literal(Node::null()),
+ d_negation(NullConstraint),
+ d_canBePropagated(false),
+ d_assertionOrder(AssertionOrderSentinel),
+ d_proof(ProofIdSentinel),
+ d_split(false),
+ d_variablePosition()
+{
+ Assert(!initialized());
+}
+
+
+std::ostream& operator<<(std::ostream& o, const Constraint c){
+ return o << *c;
+}
+
+std::ostream& operator<<(std::ostream& o, const ConstraintType t){
+ switch(t){
+ case LowerBound:
+ return o << ">=";
+ case UpperBound:
+ return o << "<=";
+ case Equality:
+ return o << "=";
+ case Disequality:
+ return o << "!=";
+ default:
+ Unreachable();
+ }
+}
+
+std::ostream& operator<<(std::ostream& o, const ConstraintValue& c){
+ o << c.getVariable() << ' ' << c.getType() << ' ' << c.getValue();
+ if(c.hasLiteral()){
+ o << "(node " << c.getLiteral() << ')';
+ }
+ return o;
+}
+
+std::ostream& operator<<(std::ostream& o, const ValueCollection& vc){
+ o << "{";
+ bool pending = false;
+ if(vc.hasEquality()){
+ o << "eq: " << vc.getEquality();
+ pending = true;
+ }
+ if(vc.hasLowerBound()){
+ if(pending){
+ o << ", ";
+ }
+ o << "lb: " << vc.getLowerBound();
+ pending = true;
+ }
+ if(vc.hasUpperBound()){
+ if(pending){
+ o << ", ";
+ }
+ o << "ub: " << vc.getUpperBound();
+ pending = true;
+ }
+ if(vc.hasDisequality()){
+ if(pending){
+ o << ", ";
+ }
+ o << "de: " << vc.getDisequality();
+ }
+ return o << "}";
+}
+
+void ConstraintValue::debugPrint() const {
+ cout << *this << endl;
+}
+
+void ValueCollection::push_into(std::vector<Constraint>& vec) const {
+ Debug("arith::constraint") << "push_into " << *this << endl;
+ if(hasEquality()){
+ vec.push_back(d_equality);
+ }
+ if(hasLowerBound()){
+ vec.push_back(d_lowerBound);
+ }
+ if(hasUpperBound()){
+ vec.push_back(d_upperBound);
+ }
+ if(hasDisequality()){
+ vec.push_back(d_disequality);
+ }
+}
+
+ValueCollection ValueCollection::mkFromConstraint(Constraint c){
+ ValueCollection ret;
+ Assert(ret.empty());
+ switch(c->getType()){
+ case LowerBound:
+ ret.d_lowerBound = c;
+ break;
+ case UpperBound:
+ ret.d_upperBound = c;
+ break;
+ case Equality:
+ ret.d_equality = c;
+ break;
+ case Disequality:
+ ret.d_disequality = c;
+ break;
+ default:
+ Unreachable();
+ }
+ return ret;
+}
+
+bool ValueCollection::hasConstraintOfType(ConstraintType t) const{
+ switch(t){
+ case LowerBound:
+ return hasLowerBound();
+ case UpperBound:
+ return hasUpperBound();
+ case Equality:
+ return hasEquality();
+ case Disequality:
+ return hasDisequality();
+ default:
+ Unreachable();
+ }
+}
+
+ArithVar ValueCollection::getVariable() const{
+ Assert(!empty());
+ return nonNull()->getVariable();
+}
+
+const DeltaRational& ValueCollection::getValue() const{
+ Assert(!empty());
+ return nonNull()->getValue();
+}
+
+void ValueCollection::add(Constraint c){
+ Assert(c != NullConstraint);
+
+ Assert(empty() || getVariable() == c->getVariable());
+ Assert(empty() || getValue() == c->getValue());
+
+ switch(c->getType()){
+ case LowerBound:
+ Assert(!hasLowerBound());
+ d_lowerBound = c;
+ break;
+ case Equality:
+ Assert(!hasEquality());
+ d_equality = c;
+ break;
+ case UpperBound:
+ Assert(!hasUpperBound());
+ d_upperBound = c;
+ break;
+ case Disequality:
+ Assert(!hasDisequality());
+ d_disequality = c;
+ break;
+ default:
+ Unreachable();
+ }
+}
+
+Constraint ValueCollection::getConstraintOfType(ConstraintType t) const{
+ switch(t){
+ case LowerBound:
+ Assert(hasLowerBound());
+ return d_lowerBound;
+ case Equality:
+ Assert(hasEquality());
+ return d_equality;
+ case UpperBound:
+ Assert(hasUpperBound());
+ return d_upperBound;
+ case Disequality:
+ Assert(hasDisequality());
+ return d_disequality;
+ default:
+ Unreachable();
+ }
+}
+
+void ValueCollection::remove(ConstraintType t){
+ switch(t){
+ case LowerBound:
+ Assert(hasLowerBound());
+ d_lowerBound = NullConstraint;
+ break;
+ case Equality:
+ Assert(hasEquality());
+ d_equality = NullConstraint;
+ break;
+ case UpperBound:
+ Assert(hasUpperBound());
+ d_upperBound = NullConstraint;
+ break;
+ case Disequality:
+ Assert(hasDisequality());
+ d_disequality = NullConstraint;
+ break;
+ default:
+ Unreachable();
+ }
+}
+
+bool ValueCollection::empty() const{
+ return
+ !(hasLowerBound() ||
+ hasUpperBound() ||
+ hasEquality() ||
+ hasDisequality());
+}
+
+Constraint ValueCollection::nonNull() const{
+ //This can be optimized by caching, but this is not necessary yet!
+ /* "Premature optimization is the root of all evil." */
+ if(hasLowerBound()){
+ return d_lowerBound;
+ }else if(hasUpperBound()){
+ return d_upperBound;
+ }else if(hasEquality()){
+ return d_equality;
+ }else if(hasDisequality()){
+ return d_disequality;
+ }else{
+ return NullConstraint;
+ }
+}
+
+bool ConstraintValue::initialized() const {
+ return d_database != NULL;
+}
+
+void ConstraintValue::initialize(ConstraintDatabase* db, SortedConstraintMapIterator v, Constraint negation){
+ Assert(!initialized());
+ d_database = db;
+ d_variablePosition = v;
+ d_negation = negation;
+}
+
+ConstraintValue::~ConstraintValue() {
+ Assert(safeToGarbageCollect());
+
+ if(initialized()){
+ ValueCollection& vc = d_variablePosition->second;
+ Debug("arith::constraint") << "removing" << vc << endl;
+
+ vc.remove(getType());
+
+ if(vc.empty()){
+ Debug("arith::constraint") << "erasing" << vc << endl;
+ SortedConstraintMap& perVariable = d_database->getVariableSCM(getVariable());
+ perVariable.erase(d_variablePosition);
+ }
+
+ if(hasLiteral()){
+ d_database->d_nodetoConstraintMap.erase(getLiteral());
+ }
+ }
+}
+
+const ValueCollection& ConstraintValue::getValueCollection() const{
+ return d_variablePosition->second;
+}
+
+Constraint ConstraintValue::getCeiling() {
+ Debug("getCeiling") << "ConstraintValue::getCeiling on " << *this << endl;
+ Assert(getValue().getInfinitesimalPart().sgn() > 0);
+
+ DeltaRational ceiling(getValue().ceiling());
+
+#warning "Optimize via the iterator"
+ return d_database->getConstraint(getVariable(), getType(), ceiling);
+}
+
+Constraint ConstraintValue::getFloor() {
+ Assert(getValue().getInfinitesimalPart().sgn() < 0);
+
+ DeltaRational floor(Rational(getValue().floor()));
+
+#warning "Optimize via the iterator"
+ return d_database->getConstraint(getVariable(), getType(), floor);
+}
+
+void ConstraintValue::setCanBePropagated() {
+ Assert(!canBePropagated());
+ d_database->pushCanBePropagatedWatch(this);
+}
+
+void ConstraintValue::setAssertedToTheTheory() {
+ Assert(hasLiteral());
+ Assert(!assertedToTheTheory());
+ Assert(!d_negation->assertedToTheTheory());
+ d_database->pushAssertionOrderWatch(this);
+}
+
+bool ConstraintValue::isSelfExplaining() const {
+ return d_proof == d_database->d_selfExplainingProof;
+}
+
+bool ConstraintValue::hasEqualityEngineProof() const {
+ return d_proof == d_database->d_equalityEngineProof;
+}
+
+bool ConstraintValue::sanityChecking(Node n) const {
+ Comparison cmp = Comparison::parseNormalForm(n);
+ Kind k = cmp.comparisonKind();
+ Polynomial pleft = cmp.normalizedVariablePart();
+ Assert(k == EQUAL || k == DISTINCT || pleft.leadingCoefficientIsPositive());
+ Assert(k != EQUAL || Monomial::isMember(n[0]));
+ Assert(k != DISTINCT || Monomial::isMember(n[0][0]));
+
+ TNode left = pleft.getNode();
+ DeltaRational right = cmp.normalizedDeltaRational();
+
+ const ArithVarNodeMap& av2node = d_database->getArithVarNodeMap();
+
+ Debug("nf::tmp") << cmp.getNode() << endl;
+ Debug("nf::tmp") << k << endl;
+ Debug("nf::tmp") << pleft.getNode() << endl;
+ Debug("nf::tmp") << left << endl;
+ Debug("nf::tmp") << right << endl;
+ Debug("nf::tmp") << getValue() << endl;
+ Debug("nf::tmp") << av2node.hasArithVar(left) << endl;
+ Debug("nf::tmp") << av2node.asArithVar(left) << endl;
+ Debug("nf::tmp") << getVariable() << endl;
+
+
+ if(av2node.hasArithVar(left) &&
+ av2node.asArithVar(left) == getVariable() &&
+ getValue() == right){
+ switch(getType()){
+ case LowerBound:
+ case UpperBound:
+ //Be overapproximate
+ return k == GT || k == GEQ ||k == LT || k == LEQ;
+ case Equality:
+ return k == EQUAL;
+ case Disequality:
+ return k == DISTINCT;
+ default:
+ Unreachable();
+ }
+ }else{
+ return false;
+ }
+}
+
+Constraint ConstraintValue::makeNegation(ArithVar v, ConstraintType t, const DeltaRational& r){
+ switch(t){
+ case LowerBound:
+ {
+ Assert(r.infinitesimalSgn() >= 0);
+ if(r.infinitesimalSgn() > 0){
+ Assert(r.getInfinitesimalPart() == 1);
+ // make (not (v > r)), which is (v <= r)
+ DeltaRational dropInf(r.getNoninfinitesimalPart(), 0);
+ return new ConstraintValue(v, UpperBound, dropInf);
+ }else{
+ Assert(r.infinitesimalSgn() == 0);
+ // make (not (v >= r)), which is (v < r)
+ DeltaRational addInf(r.getNoninfinitesimalPart(), -1);
+ return new ConstraintValue(v, UpperBound, addInf);
+ }
+ }
+ case UpperBound:
+ {
+ Assert(r.infinitesimalSgn() <= 0);
+ if(r.infinitesimalSgn() < 0){
+ Assert(r.getInfinitesimalPart() == -1);
+ // make (not (v < r)), which is (v >= r)
+ DeltaRational dropInf(r.getNoninfinitesimalPart(), 0);
+ return new ConstraintValue(v, LowerBound, dropInf);
+ }else{
+ Assert(r.infinitesimalSgn() == 0);
+ // make (not (v <= r)), which is (v > r)
+ DeltaRational addInf(r.getNoninfinitesimalPart(), 1);
+ return new ConstraintValue(v, LowerBound, addInf);
+ }
+ }
+ case Equality:
+ return new ConstraintValue(v, Disequality, r);
+ case Disequality:
+ return new ConstraintValue(v, Equality, r);
+ default:
+ Unreachable();
+ return NullConstraint;
+ }
+}
+
+ConstraintDatabase::ConstraintDatabase(context::Context* satContext, context::Context* userContext, const ArithVarNodeMap& av2nodeMap,
+ DifferenceManager& dm)
+ : d_varDatabases(),
+ d_toPropagate(satContext),
+ d_proofs(satContext, false),
+ d_watches(new Watches(satContext, userContext)),
+ d_av2nodeMap(av2nodeMap),
+ d_differenceManager(dm),
+ d_satContext(satContext),
+ d_satAllocationLevel(d_satContext->getLevel())
+{
+ d_selfExplainingProof = d_proofs.size();
+ d_proofs.push_back(NullConstraint);
+
+ d_equalityEngineProof = d_proofs.size();
+ d_proofs.push_back(NullConstraint);
+}
+
+Constraint ConstraintDatabase::getConstraint(ArithVar v, ConstraintType t, const DeltaRational& r){
+ //This must always return a constraint.
+
+ SortedConstraintMap& scm = getVariableSCM(v);
+ pair<SortedConstraintMapIterator, bool> insertAttempt;
+ insertAttempt = scm.insert(make_pair(r, ValueCollection()));
+
+ SortedConstraintMapIterator pos = insertAttempt.first;
+ ValueCollection& vc = pos->second;
+ if(vc.hasConstraintOfType(t)){
+ return vc.getConstraintOfType(t);
+ }else{
+ Constraint c = new ConstraintValue(v, t, r);
+ Constraint negC = ConstraintValue::makeNegation(v, t, r);
+
+ SortedConstraintMapIterator negPos;
+ if(t == Equality || t == Disequality){
+ negPos = pos;
+ }else{
+ pair<SortedConstraintMapIterator, bool> negInsertAttempt;
+ negInsertAttempt = scm.insert(make_pair(negC->getValue(), ValueCollection()));
+ Assert(negInsertAttempt.second);
+ negPos = negInsertAttempt.first;
+ }
+
+ c->initialize(this, pos, negC);
+ negC->initialize(this, negPos, c);
+
+ vc.add(c);
+ negPos->second.add(negC);
+
+ return c;
+ }
+}
+bool ConstraintDatabase::emptyDatabase(const std::vector<PerVariableDatabase>& vec){
+ std::vector<PerVariableDatabase>::const_iterator first = vec.begin();
+ std::vector<PerVariableDatabase>::const_iterator last = vec.end();
+ return std::find_if(first, last, PerVariableDatabase::IsEmpty) == last;
+}
+
+ConstraintDatabase::~ConstraintDatabase(){
+ Assert(d_satAllocationLevel <= d_satContext->getLevel());
+
+ delete d_watches;
+
+ std::vector<Constraint> constraintList;
+
+ while(!d_varDatabases.empty()){
+ PerVariableDatabase* back = d_varDatabases.back();
+
+ SortedConstraintMap& scm = back->d_constraints;
+ SortedConstraintMapIterator i = scm.begin(), i_end = scm.end();
+ for(; i != i_end; ++i){
+ (i->second).push_into(constraintList);
+ }
+ while(!constraintList.empty()){
+ Constraint c = constraintList.back();
+ constraintList.pop_back();
+ delete c;
+ }
+ Assert(scm.empty());
+ d_varDatabases.pop_back();
+ delete back;
+ }
+
+ Assert(d_nodetoConstraintMap.empty());
+}
+
+void ConstraintDatabase::addVariable(ArithVar v){
+ Assert(v == d_varDatabases.size());
+ d_varDatabases.push_back(new PerVariableDatabase(v));
+}
+
+bool ConstraintValue::safeToGarbageCollect() const{
+ return !isSplit()
+ && !canBePropagated()
+ && !hasProof()
+ && !assertedToTheTheory();
+}
+
+Node ConstraintValue::split(){
+ Assert(isEquality() || isDisequality());
+
+ bool isEq = isEquality();
+
+ Constraint eq = isEq ? this : d_negation;
+ Constraint diseq = isEq ? d_negation : this;
+
+ TNode eqNode = eq->getLiteral();
+ Assert(eqNode.getKind() == kind::EQUAL);
+ TNode lhs = eqNode[0];
+ TNode rhs = eqNode[1];
+
+ Node ltNode = NodeBuilder<2>(kind::LT) << lhs << rhs;
+ Node gtNode = NodeBuilder<2>(kind::GT) << lhs << rhs;
+
+ Node lemma = NodeBuilder<3>(OR) << eqNode << ltNode << gtNode;
+
+
+ eq->d_database->pushSplitWatch(eq);
+ diseq->d_database->pushSplitWatch(diseq);
+
+ return lemma;
+}
+
+bool ConstraintDatabase::hasLiteral(TNode literal) const {
+ return lookup(literal) != NullConstraint;
+}
+
+// Constraint ConstraintDatabase::addLiteral(TNode literal){
+// Assert(!hasLiteral(literal));
+// bool isNot = (literal.getKind() == NOT);
+// TNode atom = isNot ? literal[0] : literal;
+
+// Constraint atomC = addAtom(atom);
+
+// return isNot ? atomC->d_negation : atomC;
+// }
+
+// Constraint ConstraintDatabase::allocateConstraintForComparison(ArithVar v, const Comparison cmp){
+// Debug("arith::constraint") << "allocateConstraintForLiteral(" << v << ", "<< cmp <<")" << endl;
+// Kind kind = cmp.comparisonKind();
+// ConstraintType type = constraintTypeOfLiteral(kind);
+
+// DeltaRational dr = cmp.getDeltaRational();
+// return new ConstraintValue(v, type, dr);
+// }
+
+Constraint ConstraintDatabase::addLiteral(TNode literal){
+ Assert(!hasLiteral(literal));
+ bool isNot = (literal.getKind() == NOT);
+ Node atomNode = (isNot ? literal[0] : literal);
+ Node negationNode = atomNode.notNode();
+
+ Assert(!hasLiteral(atomNode));
+ Assert(!hasLiteral(negationNode));
+ Comparison posCmp = Comparison::parseNormalForm(atomNode);
+
+ ConstraintType posType = constraintTypeOfComparison(posCmp);
+
+ Polynomial nvp = posCmp.normalizedVariablePart();
+ Debug("nf::tmp") << "here " << nvp.getNode() << " " << endl;
+ ArithVar v = d_av2nodeMap.asArithVar(nvp.getNode());
+
+ DeltaRational posDR = posCmp.normalizedDeltaRational();
+
+ Constraint posC = new ConstraintValue(v, posType, posDR);
+
+ Debug("arith::constraint") << "addliteral( literal ->" << literal << ")" << endl;
+ Debug("arith::constraint") << "addliteral( posC ->" << posC << ")" << endl;
+
+ SortedConstraintMap& scm = getVariableSCM(posC->getVariable());
+ pair<SortedConstraintMapIterator, bool> insertAttempt;
+ insertAttempt = scm.insert(make_pair(posC->getValue(), ValueCollection()));
+
+ SortedConstraintMapIterator posI = insertAttempt.first;
+ // If the attempt succeeds, i points to a new empty ValueCollection
+ // If the attempt fails, i points to a pre-existing ValueCollection
+
+ if(posI->second.hasConstraintOfType(posC->getType())){
+ //This is the situation where the Constraint exists, but
+ //the literal has not been associated with it.
+ Constraint hit = posI->second.getConstraintOfType(posC->getType());
+ Debug("arith::constraint") << "hit " << hit << endl;
+ Debug("arith::constraint") << "posC " << posC << endl;
+
+ delete posC;
+
+ hit->setLiteral(atomNode);
+ hit->getNegation()->setLiteral(negationNode);
+ return isNot ? hit->getNegation(): hit;
+ }else{
+ Comparison negCmp = Comparison::parseNormalForm(negationNode);
+
+ ConstraintType negType = constraintTypeOfComparison(negCmp);
+ DeltaRational negDR = negCmp.normalizedDeltaRational();
+
+ Constraint negC = new ConstraintValue(v, negType, negDR);
+
+ SortedConstraintMapIterator negI;
+
+ if(posC->isEquality()){
+ negI = posI;
+ }else{
+ Assert(posC->isLowerBound() || posC->isUpperBound());
+
+ pair<SortedConstraintMapIterator, bool> negInsertAttempt;
+ negInsertAttempt = scm.insert(make_pair(negC->getValue(), ValueCollection()));
+
+ Debug("nf::tmp") << "sdhjfgdhjkldfgljkhdfg" << endl;
+ Debug("nf::tmp") << negC << endl;
+ Debug("nf::tmp") << negC->getValue() << endl;
+
+ //This should always succeed as the DeltaRational for the negation is unique!
+ Assert(negInsertAttempt.second);
+
+ negI = negInsertAttempt.first;
+ }
+
+ (posI->second).add(posC);
+ (negI->second).add(negC);
+
+ posC->initialize(this, posI, negC);
+ negC->initialize(this, negI, posC);
+
+ posC->setLiteral(atomNode);
+ negC->setLiteral(negationNode);
+
+ return isNot ? negC : posC;
+ }
+}
+
+// ConstraintType constraintTypeOfLiteral(Kind k){
+// switch(k){
+// case LT:
+// case LEQ:
+// return UpperBound;
+// case GT:
+// case GEQ:
+// return LowerBound;
+// case EQUAL:
+// return Equality;
+// case DISTINCT:
+// return Disequality;
+// default:
+// Unreachable();
+// }
+// }
+
+Constraint ConstraintDatabase::lookup(TNode literal) const{
+ NodetoConstraintMap::const_iterator iter = d_nodetoConstraintMap.find(literal);
+ if(iter == d_nodetoConstraintMap.end()){
+ return NullConstraint;
+ }else{
+ return iter->second;
+ }
+}
+
+void ConstraintValue::selfExplaining(){
+ markAsTrue();
+}
+
+void ConstraintValue::propagate(){
+ Assert(hasProof());
+ Assert(canBePropagated());
+ Assert(!assertedToTheTheory());
+ Assert(!isSelfExplaining());
+
+ d_database->d_toPropagate.push(this);
+}
+
+void ConstraintValue::propagate(Constraint a){
+ Assert(!hasProof());
+ Assert(canBePropagated());
+
+ markAsTrue(a);
+ propagate();
+}
+
+void ConstraintValue::propagate(Constraint a, Constraint b){
+ Assert(!hasProof());
+ Assert(canBePropagated());
+
+ markAsTrue(a, b);
+ propagate();
+}
+
+void ConstraintValue::propagate(const std::vector<Constraint>& b){
+ Assert(!hasProof());
+ Assert(canBePropagated());
+
+ markAsTrue(b);
+ propagate();
+}
+
+void ConstraintValue::impliedBy(Constraint a){
+ Assert(!isTrue());
+ Assert(!getNegation()->isTrue());
+
+ markAsTrue(a);
+ if(canBePropagated()){
+ propagate();
+ }
+}
+
+void ConstraintValue::impliedBy(Constraint a, Constraint b){
+ Assert(!isTrue());
+ Assert(!getNegation()->isTrue());
+
+ markAsTrue(a, b);
+ if(canBePropagated()){
+ propagate();
+ }
+}
+
+void ConstraintValue::impliedBy(const std::vector<Constraint>& b){
+ Assert(!isTrue());
+ Assert(!getNegation()->isTrue());
+
+ markAsTrue(b);
+ if(canBePropagated()){
+ propagate();
+ }
+}
+
+void ConstraintValue::setEqualityEngineProof(){
+ Assert(truthIsUnknown());
+ Assert(hasLiteral());
+ d_database->pushProofWatch(this, d_database->d_equalityEngineProof);
+}
+
+void ConstraintValue::markAsTrue(){
+ Assert(truthIsUnknown());
+ Assert(hasLiteral());
+ Assert(assertedToTheTheory());
+ d_database->pushProofWatch(this, d_database->d_selfExplainingProof);
+}
+
+void ConstraintValue::markAsTrue(Constraint imp){
+ Assert(truthIsUnknown());
+ Assert(imp->hasProof());
+
+ d_database->d_proofs.push_back(NullConstraint);
+ d_database->d_proofs.push_back(imp);
+ ProofId proof = d_database->d_proofs.size() - 1;
+ d_database->pushProofWatch(this, proof);
+}
+
+void ConstraintValue::markAsTrue(Constraint impA, Constraint impB){
+ Assert(truthIsUnknown());
+ Assert(impA->hasProof());
+ Assert(impB->hasProof());
+
+ d_database->d_proofs.push_back(NullConstraint);
+ d_database->d_proofs.push_back(impA);
+ d_database->d_proofs.push_back(impB);
+ ProofId proof = d_database->d_proofs.size() - 1;
+
+ d_database->pushProofWatch(this, proof);
+}
+
+void ConstraintValue::markAsTrue(const vector<Constraint>& a){
+ Assert(truthIsUnknown());
+ Assert(a.size() >= 1);
+ d_database->d_proofs.push_back(NullConstraint);
+ for(vector<Constraint>::const_iterator i = a.begin(), end = a.end(); i != end; ++i){
+ Constraint c_i = *i;
+ Assert(c_i->hasProof());
+ d_database->d_proofs.push_back(c_i);
+ }
+
+ ProofId proof = d_database->d_proofs.size() - 1;
+
+ d_database->pushProofWatch(this, proof);
+}
+
+SortedConstraintMap& ConstraintValue::constraintSet() const{
+ Assert(d_database->variableDatabaseIsSetup(d_variable));
+ return (d_database->d_varDatabases[d_variable])->d_constraints;
+}
+
+bool ConstraintValue::proofIsEmpty() const{
+ Assert(hasProof());
+ bool result = d_database->d_proofs[d_proof] == NullConstraint;
+ Assert((!result) || isSelfExplaining() || hasEqualityEngineProof());
+ return result;
+}
+
+void ConstraintValue::explainBefore(NodeBuilder<>& nb, AssertionOrder order) const{
+ Assert(hasProof());
+ Assert(!isSelfExplaining() || assertedToTheTheory());
+
+ if(assertedBefore(order)){
+ nb << getLiteral();
+ }else if(hasEqualityEngineProof()){
+ d_database->eeExplain(this, nb);
+ }else{
+ Assert(!isSelfExplaining());
+ ProofId p = d_proof;
+ Constraint antecedent = d_database->d_proofs[p];
+
+ for(; antecedent != NullConstraint; antecedent = d_database->d_proofs[--p] ){
+ antecedent->explainBefore(nb, order);
+ }
+ }
+}
+Node ConstraintValue::explainBefore(AssertionOrder order) const{
+ Assert(hasProof());
+ Assert(!isSelfExplaining() || assertedBefore(order));
+ if(assertedBefore(order)){
+ return getLiteral();
+ }else if(hasEqualityEngineProof()){
+ return d_database->eeExplain(this);
+ }else{
+ Assert(!proofIsEmpty());
+ //Force the selection of the layer above if the node is assertedToTheTheory()!
+ if(d_database->d_proofs[d_proof-1] == NullConstraint){
+ Constraint antecedent = d_database->d_proofs[d_proof];
+ return antecedent->explainBefore(order);
+ }else{
+ NodeBuilder<> nb(kind::AND);
+ Assert(!isSelfExplaining());
+
+ ProofId p = d_proof;
+ Constraint antecedent = d_database->d_proofs[p];
+ for(; antecedent != NullConstraint; antecedent = d_database->d_proofs[--p] ){
+ antecedent->explainBefore(nb, order);
+ }
+ return nb;
+ }
+ }
+}
+
+Node ConstraintValue::explainConflict(Constraint a, Constraint b){
+ NodeBuilder<> nb(kind::AND);
+ a->explainForConflict(nb);
+ b->explainForConflict(nb);
+ return nb;
+}
+
+Node ConstraintValue::explainConflict(Constraint a, Constraint b, Constraint c){
+ NodeBuilder<> nb(kind::AND);
+ a->explainForConflict(nb);
+ b->explainForConflict(nb);
+ c->explainForConflict(nb);
+ return nb;
+}
+
+Constraint ConstraintValue::getStrictlyWeakerLowerBound(bool hasLiteral, bool asserted) const {
+ Assert(initialized());
+ Assert(!asserted || hasLiteral);
+
+ SortedConstraintMapConstIterator i = d_variablePosition;
+ const SortedConstraintMap& scm = constraintSet();
+ SortedConstraintMapConstIterator i_begin = scm.begin();
+ while(i != i_begin){
+ --i;
+ const ValueCollection& vc = i->second;
+ if(vc.hasLowerBound()){
+ Constraint weaker = vc.getLowerBound();
+
+ // asserted -> hasLiteral
+ // hasLiteral -> weaker->hasLiteral()
+ // asserted -> weaker->assertedToTheTheory()
+ if((!hasLiteral || (weaker->hasLiteral())) &&
+ (!asserted || ( weaker->assertedToTheTheory()))){
+ return weaker;
+ }
+ }
+ }
+ return NullConstraint;
+}
+
+Constraint ConstraintValue::getStrictlyWeakerUpperBound(bool hasLiteral, bool asserted) const {
+ SortedConstraintMapConstIterator i = d_variablePosition;
+ const SortedConstraintMap& scm = constraintSet();
+ SortedConstraintMapConstIterator i_end = scm.end();
+
+ ++i;
+ for(; i != i_end; ++i){
+ const ValueCollection& vc = i->second;
+ if(vc.hasUpperBound()){
+ Constraint weaker = vc.getUpperBound();
+ if((!hasLiteral || (weaker->hasLiteral())) &&
+ (!asserted || ( weaker->assertedToTheTheory()))){
+ return weaker;
+ }
+ }
+ }
+
+ return NullConstraint;
+}
+
+Constraint ConstraintDatabase::getBestImpliedBound(ArithVar v, ConstraintType t, const DeltaRational& r) const {
+ Assert(variableDatabaseIsSetup(v));
+ Assert(t == UpperBound || t == LowerBound);
+
+ SortedConstraintMap& scm = getVariableSCM(v);
+ if(t == UpperBound){
+ SortedConstraintMapConstIterator i = scm.lower_bound(r);
+ SortedConstraintMapConstIterator i_end = scm.end();
+ Assert(i == i_end || r <= i->first);
+ for(; i != i_end; i++){
+ Assert(r <= i->first);
+ const ValueCollection& vc = i->second;
+ if(vc.hasUpperBound()){
+ return vc.getUpperBound();
+ }
+ }
+ return NullConstraint;
+ }else{
+ Assert(t == LowerBound);
+ if(scm.empty()){
+ return NullConstraint;
+ }else{
+ SortedConstraintMapConstIterator i = scm.lower_bound(r);
+ SortedConstraintMapConstIterator i_begin = scm.begin();
+ SortedConstraintMapConstIterator i_end = scm.end();
+ Assert(i == i_end || r <= i->first);
+
+ int fdj = 0;
+
+ if(i == i_end){
+ --i;
+ Debug("getBestImpliedBound") << fdj++ << " " << r << " " << i->first << endl;
+ }else if( (i->first) > r){
+ if(i == i_begin){
+ return NullConstraint;
+ }else{
+ --i;
+ Debug("getBestImpliedBound") << fdj++ << " " << r << " " << i->first << endl;
+ }
+ }
+
+ do{
+ Debug("getBestImpliedBound") << fdj++ << " " << r << " " << i->first << endl;
+ Assert(r >= i->first);
+ const ValueCollection& vc = i->second;
+
+ if(vc.hasLowerBound()){
+ return vc.getLowerBound();
+ }
+
+ if(i == i_begin){
+ break;
+ }else{
+ --i;
+ }
+ }while(true);
+ return NullConstraint;
+ }
+ }
+}
+Node ConstraintDatabase::eeExplain(const ConstraintValue* const c) const{
+ Assert(c->hasLiteral());
+ return d_differenceManager.explain(c->getLiteral());
+}
+
+void ConstraintDatabase::eeExplain(const ConstraintValue* const c, NodeBuilder<>& nb) const{
+ Assert(c->hasLiteral());
+ d_differenceManager.explain(c->getLiteral(), nb);
+}
+
+bool ConstraintDatabase::variableDatabaseIsSetup(ArithVar v) const {
+ return v < d_varDatabases.size();
+}
+
+
+ConstraintDatabase::Watches::Watches(context::Context* satContext, context::Context* userContext):
+ d_proofWatches(satContext),
+ d_canBePropagatedWatches(satContext),
+ d_assertionOrderWatches(satContext),
+ d_splitWatches(userContext)
+{}
+
+
+void ConstraintValue::setLiteral(Node n) {
+ Assert(!hasLiteral());
+ Assert(sanityChecking(n));
+ d_literal = n;
+ NodetoConstraintMap& map = d_database->d_nodetoConstraintMap;
+ Assert(map.find(n) == map.end());
+ map.insert(make_pair(d_literal, this));
+}
+
+void implies(std::vector<Node>& out, Constraint a, Constraint b){
+ Node la = a->getLiteral();
+ Node lb = b->getLiteral();
+
+ Node neg_la = (la.getKind() == kind::NOT)? la[0] : la.notNode();
+
+ Assert(lb != neg_la);
+ Node orderOr = (lb < neg_la) ? lb.orNode(neg_la) : neg_la.orNode(lb);
+ out.push_back(orderOr);
+}
+
+void mutuallyExclusive(std::vector<Node>& out, Constraint a, Constraint b){
+ Node la = a->getLiteral();
+ Node lb = b->getLiteral();
+
+ Node neg_la = (la.getKind() == kind::NOT)? la[0] : la.notNode();
+ Node neg_lb = (lb.getKind() == kind::NOT)? lb[0] : lb.notNode();
+
+ Assert(neg_la != neg_lb);
+ Node orderOr = (neg_la < neg_lb) ? neg_la.orNode(neg_lb) : neg_lb.orNode(neg_la);
+ out.push_back(orderOr);
+}
+
+void ConstraintDatabase::outputAllUnateLemmas(std::vector<Node>& out, ArithVar v) const{
+ SortedConstraintMap& scm = getVariableSCM(v);
+
+ SortedConstraintMapConstIterator outer;
+ SortedConstraintMapConstIterator scm_end = scm.end();
+
+ vector<Constraint> equalities;
+ for(outer = scm.begin(); outer != scm_end; ++outer){
+ const ValueCollection& vc = outer->second;
+ if(vc.hasEquality()){
+ Constraint eq = vc.getEquality();
+ if(eq->hasLiteral()){
+ equalities.push_back(eq);
+ }
+ }
+ }
+
+ Constraint prev = NullConstraint;
+ //get transitive unates
+ //Only lower bounds or upperbounds should be done.
+ for(outer = scm.begin(); outer != scm_end; ++outer){
+ const ValueCollection& vc = outer->second;
+
+ if(vc.hasUpperBound()){
+ Constraint ub = vc.getUpperBound();
+ if(ub->hasLiteral()){
+ if(prev != NullConstraint){
+ implies(out, prev, ub);
+ }
+ prev = ub;
+ }
+ }
+ }
+ vector<Constraint>::const_iterator i, j, eq_end = equalities.end();
+ for(i = equalities.begin(); i != eq_end; ++i){
+ Constraint at_i = *i;
+ for(j= i + 1; j != eq_end; ++j){
+ Constraint at_j = *j;
+
+ mutuallyExclusive(out, at_i, at_j);
+ }
+ }
+
+ for(i = equalities.begin(); i != eq_end; ++i){
+ Constraint eq = *i;
+ const ValueCollection& vc = eq->getValueCollection();
+ Assert(vc.hasEquality() && vc.getEquality()->hasLiteral());
+
+ bool hasLB = vc.hasLowerBound() && vc.getLowerBound()->hasLiteral();
+ bool hasUB = vc.hasUpperBound() && vc.getUpperBound()->hasLiteral();
+
+ Constraint lb = hasLB ?
+ vc.getLowerBound() : eq->getStrictlyWeakerLowerBound(true, false);
+ Constraint ub = hasUB ?
+ vc.getUpperBound() : eq->getStrictlyWeakerUpperBound(true, false);
+
+ if(hasUB && hasLB && !eq->isSplit()){
+ out.push_back(eq->split());
+ }
+ if(lb != NullConstraint){
+ implies(out, eq, lb);
+ }
+ if(ub != NullConstraint){
+ implies(out, eq, ub);
+ }
+ }
+ }
+
+void ConstraintDatabase::outputAllUnateLemmas(std::vector<Node>& lemmas) const{
+ for(ArithVar v = 0, N = d_varDatabases.size(); v < N; ++v){
+ outputAllUnateLemmas(lemmas, v);
+ }
+}
+
+
+}/* arith namespace */
+}/* theory namespace */
+}/* CVC4 namespace */
diff --git a/src/theory/arith/constraint.h b/src/theory/arith/constraint.h
new file mode 100644
index 000000000..e1939159b
--- /dev/null
+++ b/src/theory/arith/constraint.h
@@ -0,0 +1,837 @@
+/********************* */
+/*! \file constraint.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 Defines Constraint and ConstraintDatabase which is the internal representation of variables in arithmetic
+ **
+ ** This file defines Constraint and ConstraintDatabase.
+ ** A Constraint is the internal representation of literals in TheoryArithmetic.
+ ** Constraints are fundamentally a triple:
+ ** - ArithVar associated with the constraint,
+ ** - a DeltaRational value,
+ ** - and a ConstraintType.
+ **
+ ** Literals:
+ ** The constraint may also keep track of a node corresponding to the
+ ** Constraint.
+ ** This can be accessed by getLiteral() in O(1) if it has been set.
+ ** This node must be in normal form and may be used for communication with
+ ** the TheoryEngine.
+ **
+ ** In addition, Constraints keep track of the following:
+ ** - A Constrain that is the negation of the Constraint.
+ ** - An iterator into a set of Constraints for the ArithVar sorted by
+ ** DeltaRational value.
+ ** - A context dependent internal proof of the node that can be used for
+ ** explanations.
+ ** - Whether an equality/disequality has been split in the user context via a
+ ** lemma.
+ ** - Whether a constraint, be be used in explanations sent to the context
+ **
+ ** Looking up constraints:
+ ** - All of the Constraints with associated nodes in the ConstraintDatabase can
+ ** be accessed via a single hashtable lookup until the Constraint is removed.
+ ** - Nodes that have not been associated to a constraints can be
+ ** inserted/associated to existing nodes in O(log n) time.
+ **
+ ** Implications:
+ ** - A Constraint can be used to find unate implications.
+ ** - A unate implication is an implication based purely on the ArithVar matching
+ ** and the DeltaRational value.
+ ** (implies (<= x c) (<= x d)) given c <= d
+ ** - This is done using the iterator into the sorted set of constraints.
+ ** - Given a tight constraint and previous tightest constraint, this will
+ ** efficiently propagate internally.
+ **
+ ** Additing and Removing Constraints
+ ** - Adding Constraints takes O(log n) time where n is the number of
+ ** constraints associated with the ArithVar.
+ ** - Removing Constraints takes O(1) time.
+ **
+ ** Internals:
+ ** - Constraints are pointers to ConstraintValues.
+ ** - Undefined Constraints are NullConstraint.
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__ARITH__CONSTRAINT_H
+#define __CVC4__THEORY__ARITH__CONSTRAINT_H
+
+#include "expr/node.h"
+
+#include "context/context.h"
+#include "context/cdlist.h"
+#include "context/cdqueue.h"
+
+#include "theory/arith/arithvar.h"
+#include "theory/arith/arithvar_node_map.h"
+#include "theory/arith/delta_rational.h"
+
+#include "theory/arith/difference_manager.h"
+
+#include "theory/arith/constraint_forward.h"
+
+#include <vector>
+#include <list>
+#include <set>
+#include <ext/hash_map>
+
+namespace CVC4 {
+namespace theory {
+namespace arith {
+
+/**
+ * The types of constraints.
+ * The convex constraints are the constraints are LowerBound, Equality,
+ * and UpperBound.
+ */
+enum ConstraintType {LowerBound, Equality, UpperBound, Disequality};
+
+
+typedef context::CDList<Constraint> CDConstraintList;
+
+typedef __gnu_cxx::hash_map<Node, Constraint, NodeHashFunction> NodetoConstraintMap;
+
+typedef size_t ProofId;
+static ProofId ProofIdSentinel = std::numeric_limits<ProofId>::max();
+
+typedef size_t AssertionOrder;
+static AssertionOrder AssertionOrderSentinel = std::numeric_limits<AssertionOrder>::max();
+
+/**
+ * A ValueCollection binds together convex constraints that have the same
+ * DeltaRational value.
+ */
+class ValueCollection {
+private:
+
+ Constraint d_lowerBound;
+ Constraint d_upperBound;
+ Constraint d_equality;
+ Constraint d_disequality;
+
+public:
+ ValueCollection()
+ : d_lowerBound(NullConstraint),
+ d_upperBound(NullConstraint),
+ d_equality(NullConstraint),
+ d_disequality(NullConstraint)
+ {}
+
+ static ValueCollection mkFromConstraint(Constraint c);
+
+ bool hasLowerBound() const{
+ return d_lowerBound != NullConstraint;
+ }
+ bool hasUpperBound() const{
+ return d_upperBound != NullConstraint;
+ }
+ bool hasEquality() const{
+ return d_equality != NullConstraint;
+ }
+ bool hasDisequality() const {
+ return d_disequality != NullConstraint;
+ }
+
+ bool hasConstraintOfType(ConstraintType t) const;
+
+ Constraint getLowerBound() const {
+ Assert(hasLowerBound());
+ return d_lowerBound;
+ }
+ Constraint getUpperBound() const {
+ Assert(hasUpperBound());
+ return d_upperBound;
+ }
+ Constraint getEquality() const {
+ Assert(hasEquality());
+ return d_equality;
+ }
+ Constraint getDisequality() const {
+ Assert(hasDisequality());
+ return d_disequality;
+ }
+
+ Constraint getConstraintOfType(ConstraintType t) const;
+
+ /** Returns true if any of the constraints are non-null. */
+ bool empty() const;
+
+ /**
+ * Remove the constraint of the type t from the collection.
+ * Returns true if the ValueCollection is now empty.
+ * If true is returned, d_value is now NULL.
+ */
+ void remove(ConstraintType t);
+
+ /**
+ * Adds a constraint to the set.
+ * The collection must not have a constraint of that type already.
+ */
+ void add(Constraint c);
+
+ void push_into(std::vector<Constraint>& vec) const;
+
+ Constraint nonNull() const;
+
+ ArithVar getVariable() const;
+ const DeltaRational& getValue() const;
+};
+
+/**
+ * A Map of ValueCollections sorted by the associated DeltaRational values.
+ *
+ * Discussion:
+ * While it is more natural to consider this a set, this cannot be a set as in
+ * sets the type of both iterator and const_iterator in sets are
+ * "constant iterators". We require iterators that dereference to
+ * ValueCollection&.
+ *
+ * See:
+ * http://gcc.gnu.org/onlinedocs/libstdc++/ext/lwg-defects.html#103
+ */
+typedef std::map<DeltaRational, ValueCollection> SortedConstraintMap;
+typedef SortedConstraintMap::iterator SortedConstraintMapIterator;
+typedef SortedConstraintMap::const_iterator SortedConstraintMapConstIterator;
+
+/** A Pair associating a variables and a Sorted ConstraintSet. */
+struct PerVariableDatabase{
+ ArithVar d_var;
+ SortedConstraintMap d_constraints;
+
+ // x ? c_1, x ? c_2, x ? c_3, ...
+ // where ? is a non-empty subset of {lb, ub, eq}
+ // c_1 < c_2 < c_3 < ...
+
+ PerVariableDatabase(ArithVar v) : d_var(v), d_constraints() {}
+
+ bool empty() const {
+ return d_constraints.empty();
+ }
+
+ static bool IsEmpty(const PerVariableDatabase& p){
+ return p.empty();
+ }
+};
+
+class ConstraintValue {
+private:
+ /** The ArithVar associated with the constraint. */
+ const ArithVar d_variable;
+
+ /** The type of the Constraint. */
+ const ConstraintType d_type;
+
+ /** The DeltaRational value with the constraint. */
+ const DeltaRational d_value;
+
+ /** A pointer to the associated database for the Constraint. */
+ ConstraintDatabase * d_database;
+
+ /**
+ * The node to be communicated with the TheoryEngine.
+ *
+ * This is not context dependent, but may be set once.
+ *
+ * This must be set if the constraint canbePropgated().
+ * This must be set if the constraint assertedToTheTheory().
+ * Otherwise, this may be null().
+ */
+ Node d_literal;
+
+ /** Pointer to the negation of the Constraint. */
+ Constraint d_negation;
+
+ /**
+ * This is true if the associated node can be propagated.
+ *
+ * This should be enabled if the node has been preregistered.
+ *
+ * Sat Context Dependent.
+ * This is initially false.
+ */
+ bool d_canBePropagated;
+
+ /**
+ * This is the order the constraint was asserted to the theory.
+ * If this has been set, the node can be used in conflicts.
+ * If this is c.d_assertedOrder < d.d_assertedOrder, then c can be used in the
+ * explanation of d.
+ *
+ * This should be set after the literal is dequeued by Theory::get().
+ *
+ * Sat Context Dependent.
+ * This is initially AssertionOrderSentinel.
+ */
+ AssertionOrder d_assertionOrder;
+
+ /**
+ * This points at the proof for the constraint in the current context.
+ *
+ * Sat Context Dependent.
+ * This is initially ProofIdSentinel.
+ */
+ ProofId d_proof;
+
+ /**
+ * True if the equality has been split.
+ * Only meaningful if ContraintType == Equality.
+ *
+ * User Context Dependent.
+ * This is initially false.
+ */
+ bool d_split;
+
+ /**
+ * Position in sorted constraint set for the variable.
+ * Unset if d_type is Disequality.
+ */
+ SortedConstraintMapIterator d_variablePosition;
+
+ friend class ConstraintDatabase;
+
+ /**
+ * This begins construction of a minimal constraint.
+ *
+ * This should only be called by ConstraintDatabase.
+ *
+ * Because of circular dependencies a Constraint is not fully valid until
+ * initialize has been called on it.
+ */
+ ConstraintValue(ArithVar x, ConstraintType t, const DeltaRational& v);
+
+ /**
+ * Destructor for a constraint.
+ * This should only be called if safeToGarbageCollect() is true.
+ */
+ ~ConstraintValue();
+
+ bool initialized() const;
+
+ /**
+ * This initializes the fields that cannot be set in the constructor due to
+ * circular dependencies.
+ */
+ void initialize(ConstraintDatabase* db, SortedConstraintMapIterator v, Constraint negation);
+
+ class ProofCleanup {
+ public:
+ inline void operator()(Constraint* p){
+ Constraint constraint = *p;
+ Assert(constraint->d_proof != ProofIdSentinel);
+ constraint->d_proof = ProofIdSentinel;
+ }
+ };
+
+ class CanBePropagatedCleanup {
+ public:
+ inline void operator()(Constraint* p){
+ Constraint constraint = *p;
+ Assert(constraint->d_canBePropagated);
+ constraint->d_canBePropagated = false;
+ }
+ };
+
+ class AssertionOrderCleanup {
+ public:
+ inline void operator()(Constraint* p){
+ Constraint constraint = *p;
+ Assert(constraint->assertedToTheTheory());
+ constraint->d_assertionOrder = AssertionOrderSentinel;
+ Assert(!constraint->assertedToTheTheory());
+ }
+ };
+
+ class SplitCleanup {
+ public:
+ inline void operator()(Constraint* p){
+ Constraint constraint = *p;
+ Assert(constraint->d_split);
+ constraint->d_split = false;
+ }
+ };
+
+ /** Returns true if the node is safe to garbage collect. */
+ bool safeToGarbageCollect() const;
+
+ /**
+ * Returns true if the node correctly corresponds to the constraint that is
+ * being set.
+ */
+ bool sanityChecking(Node n) const;
+
+ /** Returns a reference to the map for d_variable. */
+ SortedConstraintMap& constraintSet() const;
+
+public:
+
+ ConstraintType getType() const {
+ return d_type;
+ }
+
+ ArithVar getVariable() const {
+ return d_variable;
+ }
+
+ const DeltaRational& getValue() const {
+ return d_value;
+ }
+
+ Constraint getNegation() const {
+ return d_negation;
+ }
+
+ bool isEquality() const{
+ return d_type == Equality;
+ }
+ bool isDisequality() const{
+ return d_type == Disequality;
+ }
+ bool isLowerBound() const{
+ return d_type == LowerBound;
+ }
+ bool isUpperBound() const{
+ return d_type == UpperBound;
+ }
+
+ bool isSplit() const {
+ return d_split;
+ }
+
+ /**
+ * Splits the node in the user context.
+ * Returns a lemma that is assumed to be true fro the rest of the user context.
+ * Constraint must be an equality or disequality.
+ */
+ Node split();
+
+ bool canBePropagated() const {
+ return d_canBePropagated;
+ }
+ void setCanBePropagated();
+
+ /**
+ * Light wrapper for calling setCanBePropagated(),
+ * on this and this-d_negation.
+ */
+ void setPreregistered(){
+ setCanBePropagated();
+ d_negation->setCanBePropagated();
+ }
+
+ bool assertedToTheTheory() const {
+ return d_assertionOrder < AssertionOrderSentinel;
+ }
+
+ bool assertedBefore(AssertionOrder time) const {
+ return d_assertionOrder < time;
+ }
+
+
+ void setAssertedToTheTheory();
+
+
+ bool hasLiteral() const {
+ return !d_literal.isNull();
+ }
+
+ void setLiteral(Node n);
+
+ Node getLiteral() const {
+ Assert(hasLiteral());
+ return d_literal;
+ }
+
+ /**
+ * Set the node as selfExplaining().
+ * The node must be assertedToTheTheory().
+ */
+ void selfExplaining();
+
+ /** Returns true if the node is selfExplaining.*/
+ bool isSelfExplaining() const;
+
+ /**
+ * Set the constraint to be a EqualityEngine proof.
+ */
+ void setEqualityEngineProof();
+ bool hasEqualityEngineProof() const;
+
+ /**
+ * Returns a explanation of the constraint that is appropriate for conflicts.
+ *
+ * This is not appropraite for propagation!
+ *
+ * This is the minimum fringe of the implication tree s.t.
+ * every constraint is assertedToTheTheory() or hasEqualityEngineProof().
+ */
+ Node explainForConflict() const{
+ return explainBefore(AssertionOrderSentinel);
+ }
+
+ /**
+ * Writes an explanation of a constraint into the node builder.
+ * Pushes back an explanation that is acceptable to send to the sat solver.
+ * nb is assumed to be an AND.
+ *
+ * This is the minimum fringe of the implication tree s.t.
+ * every constraint is assertedToTheTheory() or hasEqualityEngineProof().
+ *
+ * This is not appropraite for propagation!
+ * Use explainForPropagation() instead.
+ */
+ void explainForConflict(NodeBuilder<>& nb) const{
+ explainBefore(nb, AssertionOrderSentinel);
+ }
+
+ /** Utility function built from explainForConflict. */
+ static Node explainConflict(Constraint a, Constraint b);
+ static Node explainConflict(Constraint a, Constraint b, Constraint c);
+
+ /**
+ * Returns an explanation of a propagation by the ConstraintDatabase.
+ * The constraint must have a proof.
+ * The constraint cannot be selfExplaining().
+ *
+ * This is the minimum fringe of the implication tree (excluding the constraint itself)
+ * s.t. every constraint is assertedToTheTheory() or hasEqualityEngineProof().
+ */
+ Node explainForPropagation() const {
+ Assert(hasProof());
+ Assert(!isSelfExplaining());
+ return explainBefore(d_assertionOrder);
+ }
+
+private:
+ Node explainBefore(AssertionOrder order) const;
+
+ /**
+ * Returns an explanation of that was assertedBefore(order).
+ * The constraint must have a proof.
+ * The constraint cannot be selfExplaining().
+ *
+ * This is the minimum fringe of the implication tree
+ * s.t. every constraint is assertedBefore(order) or hasEqualityEngineProof().
+ */
+ void explainBefore(NodeBuilder<>& nb, AssertionOrder order) const;
+
+public:
+ bool hasProof() const {
+ return d_proof != ProofIdSentinel;
+ }
+ bool negationHasProof() const {
+ return d_negation->hasProof();
+ }
+
+ bool truthIsUnknown() const {
+ return !hasProof() && !negationHasProof();
+ }
+
+ bool isTrue() const {
+ return hasProof();
+ }
+
+ Constraint getCeiling();
+
+ Constraint getFloor();
+
+
+ static Constraint makeNegation(ArithVar v, ConstraintType t, const DeltaRational& r);
+
+ const ValueCollection& getValueCollection() const;
+
+
+ Constraint getStrictlyWeakerUpperBound(bool hasLiteral, bool mustBeAsserted) const;
+ Constraint getStrictlyWeakerLowerBound(bool hasLiteral, bool mustBeAsserted) const;
+
+ /**
+ * Marks the node as having a proof a.
+ * Adds the node the database's propagation queue.
+ *
+ * Preconditions:
+ * canBePropagated()
+ * !assertedToTheTheory()
+ */
+ void propagate(Constraint a);
+ void propagate(Constraint a, Constraint b);
+ void propagate(const std::vector<Constraint>& b);
+ /**
+ * The only restriction is that this is not known be true.
+ * This propgates if there is a node.
+ */
+ void impliedBy(Constraint a);
+ void impliedBy(Constraint a, Constraint b);
+ void impliedBy(const std::vector<Constraint>& b);
+
+
+ /** The node must have a proof already and be eligible for propagation! */
+ void propagate();
+
+private:
+ /**
+ * Marks the node as having a proof and being selfExplaining.
+ * Neither the node nor its negation can have a proof.
+ * This is internal!
+ */
+ void markAsTrue();
+ /**
+ * Marks the node as having a proof a.
+ * This is safe if the node does not have
+ */
+ void markAsTrue(Constraint a);
+
+ void markAsTrue(Constraint a, Constraint b);
+ void markAsTrue(const std::vector<Constraint>& b);
+
+public:
+
+
+private:
+
+ void debugPrint() const;
+
+ /**
+ * The proof of the node is empty.
+ * The proof must be a special proof. Either
+ * isSelfExplaining() or
+ * hasEqualityEngineProof()
+ */
+ bool proofIsEmpty() const;
+
+}; /* class ConstraintValue */
+
+std::ostream& operator<<(std::ostream& o, const ConstraintValue& c);
+std::ostream& operator<<(std::ostream& o, const Constraint c);
+std::ostream& operator<<(std::ostream& o, const ConstraintType t);
+std::ostream& operator<<(std::ostream& o, const ValueCollection& c);
+
+
+
+class ConstraintDatabase {
+private:
+ /**
+ * The map from ArithVars to their unique databases.
+ * When the vector changes size, we cannot allow the maps to move so this
+ * is a vector of pointers.
+ */
+ std::vector<PerVariableDatabase*> d_varDatabases;
+
+ SortedConstraintMap& getVariableSCM(ArithVar v) const{
+ Assert(variableDatabaseIsSetup(v));
+ return d_varDatabases[v]->d_constraints;
+ }
+
+ /** Maps literals to constraints.*/
+ NodetoConstraintMap d_nodetoConstraintMap;
+
+ /**
+ * A queue of propagated constraints.
+ *
+ * As Constraint are pointers, the elements of the queue do not require destruction.
+ */
+ context::CDQueue<Constraint> d_toPropagate;
+
+ /**
+ * Proof Lists.
+ * Proofs are lists of valid constraints terminated by the first smaller
+ * sentinel value in the proof list.
+ * The proof at p in d_proofs[p] of length n is
+ * (NullConstraint, d_proofs[p-(n-1)], ... , d_proofs[p-1], d_proofs[p])
+ * The proof at p corresponds to the conjunction:
+ * (and x_i)
+ *
+ * So the proof of a Constraint c corresponds to the horn clause:
+ * (implies (and x_i) c)
+ * where (and x_i) is the proof at c.d_proofs.
+ *
+ * Constraints are pointers so this list is designed not to require any
+ * destruction.
+ */
+ CDConstraintList d_proofs;
+
+ /**
+ * This is a special proof for marking that nodes are their own explanation
+ * from the perspective of the theory.
+ * These must always be asserted to the theory.
+ *
+ * This proof is always a member of the list.
+ */
+ ProofId d_selfExplainingProof;
+
+ /**
+ * Marks a node as being proved by the equality engine.
+ * The equality engine will be asked for the explanation of such nodes.
+ *
+ * This is a special proof that is always a member of the list.
+ */
+ ProofId d_equalityEngineProof;
+
+ typedef context::CDList<Constraint, ConstraintValue::ProofCleanup> ProofCleanupList;
+ typedef context::CDList<Constraint, ConstraintValue::CanBePropagatedCleanup> CBPList;
+ typedef context::CDList<Constraint, ConstraintValue::AssertionOrderCleanup> AOList;
+ typedef context::CDList<Constraint, ConstraintValue::SplitCleanup> SplitList;
+
+ /**
+ * The watch lists are collected together as they need to be garbage collected
+ * carefully.
+ */
+ struct Watches{
+ /**
+ * Contains the exact list of atoms that have a proof.
+ */
+ ProofCleanupList d_proofWatches;
+
+ /**
+ * Contains the exact list of constraints that can be used for propagation.
+ */
+ CBPList d_canBePropagatedWatches;
+
+ /**
+ * Contains the exact list of constraints that have been asserted to the theory.
+ */
+ AOList d_assertionOrderWatches;
+
+
+ /**
+ * Contains the exact list of atoms that have been preregistered.
+ * This is a pointer as it must be destroyed before the elements of
+ * d_varDatabases.
+ */
+ SplitList d_splitWatches;
+ Watches(context::Context* satContext, context::Context* userContext);
+ };
+ Watches* d_watches;
+
+ void pushSplitWatch(Constraint c){
+ Assert(!c->d_split);
+ c->d_split = true;
+ d_watches->d_splitWatches.push_back(c);
+ }
+
+ void pushCanBePropagatedWatch(Constraint c){
+ Assert(!c->d_canBePropagated);
+ c->d_canBePropagated = true;
+ d_watches->d_canBePropagatedWatches.push_back(c);
+ }
+
+ void pushAssertionOrderWatch(Constraint c){
+ Assert(!c->assertedToTheTheory());
+ c->d_assertionOrder = d_watches->d_assertionOrderWatches.size();
+ d_watches->d_assertionOrderWatches.push_back(c);
+ }
+
+ void pushProofWatch(Constraint c, ProofId pid){
+ Assert(c->d_proof == ProofIdSentinel);
+ c->d_proof = pid;
+ d_watches->d_proofWatches.push_back(c);
+ }
+
+ /** Returns true if all of the entries of the vector are empty. */
+ static bool emptyDatabase(const std::vector<PerVariableDatabase>& vec);
+
+ /** Map from nodes to arithvars. */
+ const ArithVarNodeMap& d_av2nodeMap;
+
+ const ArithVarNodeMap& getArithVarNodeMap() const{
+ return d_av2nodeMap;
+ }
+
+ DifferenceManager& d_differenceManager;
+
+ //Constraint allocateConstraintForLiteral(ArithVar v, Node literal);
+
+ const context::Context * const d_satContext;
+ const int d_satAllocationLevel;
+
+ friend class ConstraintValue;
+
+public:
+
+ ConstraintDatabase( context::Context* satContext,
+ context::Context* userContext,
+ const ArithVarNodeMap& av2nodeMap,
+ DifferenceManager& dm);
+
+ ~ConstraintDatabase();
+
+ Constraint addLiteral(TNode lit);
+ //Constraint addAtom(TNode atom);
+
+ /**
+ * If hasLiteral() is true, returns the constraint.
+ * Otherwise, returns NullConstraint.
+ */
+ Constraint lookup(TNode literal) const;
+
+ /**
+ * Returns true if the literal has been added to the database.
+ * This is a hash table lookup.
+ * It does not look in the database for an equivalent corresponding constraint.
+ */
+ bool hasLiteral(TNode literal) const;
+
+ bool hasMorePropagations() const{
+ return !d_toPropagate.empty();
+ }
+
+ Constraint nextPropagation(){
+ Assert(hasMorePropagations());
+
+ Constraint p = d_toPropagate.front();
+ d_toPropagate.pop();
+
+ return p;
+ }
+
+ void addVariable(ArithVar v);
+ bool variableDatabaseIsSetup(ArithVar v) const;
+
+ Node eeExplain(ConstConstraint c) const;
+ void eeExplain(ConstConstraint c, NodeBuilder<>& nb) const;
+
+ /**
+ * Returns a constraint with the variable v, the constraint type t, and a value
+ * dominated by r (explained below) if such a constraint exists in the database.
+ * If no such constraint exists, NullConstraint is returned.
+ *
+ * t must be either UpperBound or LowerBound.
+ * The returned value v is dominatated:
+ * If t is UpperBound, r <= v
+ * If t is LowerBound, r >= v
+ */
+ Constraint getBestImpliedBound(ArithVar v, ConstraintType t, const DeltaRational& r) const;
+
+ /**
+ * Returns a constraint with the variable v, the constraint type t and the value r.
+ * If there is such a constraint in the database already, it is returned.
+ * If there is no such constraint, this constraint is added to the database.
+ *
+ */
+ Constraint getConstraint(ArithVar v, ConstraintType t, const DeltaRational& r);
+
+
+ /**
+ * Outputs a minimal set of unate implications on the output channel
+ * for all variables.
+ */
+ void outputAllUnateLemmas(std::vector<Node>& lemmas) const;
+
+ void outputAllUnateLemmas(std::vector<Node>& lemmas, ArithVar v) const;
+
+}; /* ConstraintDatabase */
+
+}/* CVC4::theory::arith namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__ARITH__CONSTRAINT_H */
diff --git a/src/theory/arith/constraint_forward.h b/src/theory/arith/constraint_forward.h
new file mode 100644
index 000000000..dd0c1f2f6
--- /dev/null
+++ b/src/theory/arith/constraint_forward.h
@@ -0,0 +1,42 @@
+/********************* */
+/*! \file constraint_forward.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 Forward declarations of the ConstraintValue and ConstraintDatabase classes.
+ **
+ ** This is the forward declarations of the ConstraintValue and ConstraintDatabase
+ ** and the typedef for Constraint. This is used to break circular dependencies and
+ ** minimize interaction between header files.
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__ARITH__CONSTRAINT_FORWARD_H
+#define __CVC4__THEORY__ARITH__CONSTRAINT_FORWARD_H
+
+namespace CVC4 {
+namespace theory {
+namespace arith {
+
+class ConstraintValue;
+typedef ConstraintValue* Constraint;
+typedef const ConstraintValue* const ConstConstraint;
+
+static const Constraint NullConstraint = NULL;
+
+class ConstraintDatabase;
+
+}/* CVC4::theory::arith namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__ARITH__CONSTRAINT_FORWARD_H */
diff --git a/src/theory/arith/delta_rational.h b/src/theory/arith/delta_rational.h
index a46dde1cf..12110fab4 100644
--- a/src/theory/arith/delta_rational.h
+++ b/src/theory/arith/delta_rational.h
@@ -55,14 +55,18 @@ public:
}
int sgn() const {
- int x = getNoninfinitesimalPart().sgn();
- if(x == 0){
- return getInfinitesimalPart().sgn();
+ int s = getNoninfinitesimalPart().sgn();
+ if(s == 0){
+ return infinitesimalSgn();
}else{
- return x;
+ return s;
}
}
+ int infinitesimalSgn() const {
+ return getInfinitesimalPart().sgn();
+ }
+
int cmp(const DeltaRational& other) const{
int cmp = c.cmp(other.c);
if(cmp == 0){
diff --git a/src/theory/arith/difference_manager.cpp b/src/theory/arith/difference_manager.cpp
index b67240d4c..70588bc16 100644
--- a/src/theory/arith/difference_manager.cpp
+++ b/src/theory/arith/difference_manager.cpp
@@ -1,23 +1,131 @@
#include "theory/arith/difference_manager.h"
#include "theory/uf/equality_engine_impl.h"
+#include "theory/arith/constraint.h"
+#include "theory/arith/arith_utilities.h"
+
namespace CVC4 {
namespace theory {
namespace arith {
-DifferenceManager::DifferenceManager(context::Context* c, PropManager& pm)
- : d_literalsQueue(c),
- d_queue(pm),
+DifferenceManager::DifferenceManager(context::Context* c, ConstraintDatabase& cd, TNodeCallBack& setup)
+ : d_conflict(c),
+ d_literalsQueue(c),
+ d_propagatations(c),
+ d_explanationMap(c),
+ d_constraintDatabase(cd),
+ d_setupLiteral(setup),
d_notify(*this),
d_ee(d_notify, c, "theory::arith::DifferenceManager"),
d_false(NodeManager::currentNM()->mkConst<bool>(false)),
d_hasSharedTerms(c, false)
{}
-void DifferenceManager::propagate(TNode x){
+void DifferenceManager::differenceIsZero(Constraint lb, Constraint ub){
+ Assert(lb->isLowerBound());
+ Assert(ub->isUpperBound());
+ Assert(lb->getVariable() == ub->getVariable());
+ Assert(lb->getValue().sgn() == 0);
+ Assert(ub->getValue().sgn() == 0);
+
+ ArithVar s = lb->getVariable();
+ Node reason = ConstraintValue::explainConflict(lb,ub);
+
+ assertLiteral(true, s, reason);
+}
+
+void DifferenceManager::differenceIsZero(Constraint eq){
+ Assert(eq->isEquality());
+ Assert(eq->getValue().sgn() == 0);
+
+ ArithVar s = eq->getVariable();
+
+ //Explain for conflict is correct as these proofs are generated and stored eagerly
+ //These will be safe for propagation later as well
+ Node reason = eq->explainForConflict();
+
+ assertLiteral(true, s, reason);
+}
+
+void DifferenceManager::differenceCannotBeZero(Constraint c){
+ ArithVar s = c->getVariable();
+
+ //Explain for conflict is correct as these proofs are generated and stored eagerly
+ //These will be safe for propagation later as well
+ Node reason = c->explainForConflict();
+ assertLiteral(false, s, reason);
+}
+
+
+bool DifferenceManager::propagate(TNode x){
Debug("arith::differenceManager")<< "DifferenceManager::propagate("<<x<<")"<<std::endl;
+ if(inConflict()){
+ return true;
+ }
+
+ Node rewritten = Rewriter::rewrite(x);
+
+ //Need to still propagate this!
+ if(rewritten.getKind() == kind::CONST_BOOLEAN){
+ pushBack(x);
+ }
- d_queue.propagate(x, explain(x), true);
+ Assert(rewritten.getKind() != kind::CONST_BOOLEAN);
+
+ Constraint c = d_constraintDatabase.lookup(rewritten);
+ if(c == NullConstraint){
+ //using setup as there may not be a corresponding difference literal yet
+ d_setupLiteral(rewritten);
+ c = d_constraintDatabase.lookup(rewritten);
+ Assert(c != NullConstraint);
+ //c = d_constraintDatabase.addLiteral(rewritten);
+ }
+
+ Debug("arith::differenceManager")<< "x is "
+ << c->hasProof() << " "
+ << (x == rewritten) << " "
+ << c->canBePropagated() << " "
+ << c->negationHasProof() << std::endl;
+
+ if(c->negationHasProof()){
+ Node expC = explainInternal(x);
+ Node neg = c->getNegation()->explainForConflict();
+ Node conf = expC.andNode(neg);
+ Node final = flattenAnd(conf);
+
+ d_conflict.set(final);
+ Debug("arith::differenceManager") << "differenceManager found a conflict " << final << std::endl;
+ return false;
+ }
+
+ // Cases for propagation
+ // C : c has a proof
+ // S : x == rewritten
+ // P : c can be propagated
+ //
+ // CSP
+ // 000 : propagate x, and mark C it as being explained
+ // 001 : propagate x, and propagate c after marking it as being explained
+ // 01* : propagate x, mark c but do not propagate c
+ // 10* : propagate x, do not mark c and do not propagate c
+ // 11* : drop the constraint, do not propagate x or c
+
+ if(!c->hasProof() && x != rewritten){
+ pushBack(x, rewritten);
+
+ c->setEqualityEngineProof();
+ if(c->canBePropagated() && !c->assertedToTheTheory()){
+ c->propagate();
+ }
+ }else if(!c->hasProof() && x == rewritten){
+ pushBack(x, rewritten);
+ c->setEqualityEngineProof();
+ }else if(c->hasProof() && x != rewritten){
+ pushBack(x, rewritten);
+ }else{
+ Assert(c->hasProof() && x == rewritten);
+ }
+ return true;
}
void DifferenceManager::explain(TNode literal, std::vector<TNode>& assumptions) {
@@ -37,33 +145,44 @@ void DifferenceManager::explain(TNode literal, std::vector<TNode>& assumptions)
d_ee.explainEquality(lhs, rhs, assumptions);
}
-Node mkAnd(const std::vector<TNode>& conjunctions) {
- Assert(conjunctions.size() > 0);
+void DifferenceManager::enqueueIntoNB(const std::set<TNode> s, NodeBuilder<>& nb){
+ std::set<TNode>::const_iterator it = s.begin();
+ std::set<TNode>::const_iterator it_end = s.end();
+ for(; it != it_end; ++it) {
+ nb << *it;
+ }
+}
- std::set<TNode> all;
- all.insert(conjunctions.begin(), conjunctions.end());
+Node DifferenceManager::explainInternal(TNode internal){
+ std::vector<TNode> assumptions;
+ explain(internal, assumptions);
- if (all.size() == 1) {
- // All the same, or just one
- return conjunctions[0];
- }
+ std::set<TNode> assumptionSet;
+ assumptionSet.insert(assumptions.begin(), assumptions.end());
- NodeBuilder<> conjunction(kind::AND);
- std::set<TNode>::const_iterator it = all.begin();
- std::set<TNode>::const_iterator it_end = all.end();
- while (it != it_end) {
- conjunction << *it;
- ++ it;
+ if (assumptionSet.size() == 1) {
+ // All the same, or just one
+ return assumptions[0];
+ }else{
+ NodeBuilder<> conjunction(kind::AND);
+ enqueueIntoNB(assumptionSet, conjunction);
+ return conjunction;
}
-
- return conjunction;
+}
+Node DifferenceManager::explain(TNode external){
+ Node internal = externalToInternal(external);
+ return explainInternal(internal);
}
+void DifferenceManager::explain(TNode external, NodeBuilder<>& out){
+ Node internal = externalToInternal(external);
-Node DifferenceManager::explain(TNode lit){
std::vector<TNode> assumptions;
- explain(lit, assumptions);
- return mkAnd(assumptions);
+ explain(internal, assumptions);
+ std::set<TNode> assumptionSet;
+ assumptionSet.insert(assumptions.begin(), assumptions.end());
+
+ enqueueIntoNB(assumptionSet, out);
}
void DifferenceManager::addDifference(ArithVar s, Node x, Node y){
@@ -90,7 +209,7 @@ void DifferenceManager::addAssertionToEqualityEngine(bool eq, ArithVar s, TNode
void DifferenceManager::dequeueLiterals(){
Assert(d_hasSharedTerms);
- while(!d_literalsQueue.empty()){
+ while(!d_literalsQueue.empty() && !inConflict()){
const LiteralsQueueElem& front = d_literalsQueue.front();
d_literalsQueue.dequeue();
diff --git a/src/theory/arith/difference_manager.h b/src/theory/arith/difference_manager.h
index c6e7f314d..7862a6b31 100644
--- a/src/theory/arith/difference_manager.h
+++ b/src/theory/arith/difference_manager.h
@@ -6,20 +6,52 @@
#define __CVC4__THEORY__ARITH__DIFFERENCE_MANAGER_H
#include "theory/arith/arithvar.h"
+#include "theory/arith/constraint_forward.h"
#include "theory/uf/equality_engine.h"
#include "context/cdo.h"
#include "context/cdlist.h"
#include "context/context.h"
#include "context/cdtrail_queue.h"
#include "util/stats.h"
-#include "theory/arith/arith_prop_manager.h"
namespace CVC4 {
namespace theory {
namespace arith {
+/**
+ * This implements a CDMaybe.
+ * This has either been set in the context or it has not.
+ * T must have a default constructor and support assignment.
+ */
+template <class T>
+class CDMaybe {
+private:
+ typedef std::pair<bool, T> BoolTPair;
+ context::CDO<BoolTPair> d_data;
+
+public:
+ CDMaybe(context::Context* c) : d_data(c, std::make_pair(false, T()))
+ {}
+
+ bool isSet() const {
+ return d_data.get().first;
+ }
+
+ void set(const T& d){
+ Assert(!isSet());
+ d_data.set(std::make_pair(true, d));
+ }
+
+ const T& get() const{
+ Assert(isSet());
+ return d_data.get().second;
+ }
+};
+
class DifferenceManager {
private:
+ CDMaybe<Node> d_conflict;
+
struct Difference {
bool isSlack;
TNode x;
@@ -40,8 +72,7 @@ private:
bool notify(TNode propagation) {
Debug("arith::differences") << "DifferenceNotifyClass::notify(" << propagation << ")" << std::endl;
// Just forward to dm
- d_dm.propagate(propagation);
- return true;
+ return d_dm.propagate(propagation);
}
void notify(TNode t1, TNode t2) {
@@ -63,13 +94,69 @@ private:
/** Stores the queue of assertions. This keeps the Node backing the reasons */
context::CDTrailQueue<LiteralsQueueElem> d_literalsQueue;
- PropManager& d_queue;
+ //PropManager& d_queue;
+
+ /** Store the propagations. */
+ context::CDTrailQueue<Node> d_propagatations;
+
+ /* This maps the node a theory engine will request on an explain call to
+ * to its corresponding PropUnit.
+ * This is node is potentially both the propagation or Rewriter::rewrite(propagation).
+ */
+ typedef context::CDHashMap<Node, size_t, NodeHashFunction> ExplainMap;
+ ExplainMap d_explanationMap;
+
+ ConstraintDatabase& d_constraintDatabase;
+ TNodeCallBack& d_setupLiteral;
+
+public:
+
+ bool inConflict() const{
+ return d_conflict.isSet();
+ };
+ Node conflict() const{
+ Assert(inConflict());
+ return d_conflict.get();
+ }
+
+ bool hasMorePropagations() const {
+ return !d_propagatations.empty();
+ }
+
+ const Node getNextPropagation() {
+ Assert(hasMorePropagations());
+ Node prop = d_propagatations.front();
+ d_propagatations.dequeue();
+ return prop;
+ }
+
+ bool canExplain(TNode n) const {
+ return d_explanationMap.find(n) != d_explanationMap.end();
+ }
+
+private:
+ Node externalToInternal(TNode n) const{
+ Assert(canExplain(n));
+ size_t pos = (*(d_explanationMap.find(n))).second;
+ return d_propagatations[pos];
+ }
+
+ void pushBack(TNode n){
+ d_explanationMap.insert(n, d_propagatations.size());
+ d_propagatations.enqueue(n);
+ }
+
+ void pushBack(TNode n, TNode r){
+ d_explanationMap.insert(r, d_propagatations.size());
+ d_explanationMap.insert(n, d_propagatations.size());
+ d_propagatations.enqueue(n);
+ }
DifferenceNotifyClass d_notify;
theory::uf::EqualityEngine<DifferenceNotifyClass> d_ee;
- void propagate(TNode x);
+ bool propagate(TNode x);
void explain(TNode literal, std::vector<TNode>& assumptions);
Node d_false;
@@ -96,11 +183,16 @@ private:
void enableSharedTerms();
void dequeueLiterals();
+ void enqueueIntoNB(const std::set<TNode> all, NodeBuilder<>& nb);
+
+ Node explainInternal(TNode internal);
+
public:
- DifferenceManager(context::Context*, PropManager&);
+ DifferenceManager(context::Context* satContext, ConstraintDatabase&, TNodeCallBack&);
Node explain(TNode literal);
+ void explain(TNode lit, NodeBuilder<>& out);
void addDifference(ArithVar s, Node x, Node y);
@@ -112,13 +204,14 @@ public:
}
}
- void differenceIsZero(ArithVar s, TNode reason){
- assertLiteral(true, s, reason);
- }
+ /** Assert an equality. */
+ void differenceIsZero(Constraint eq);
- void differenceCannotBeZero(ArithVar s, TNode reason){
- assertLiteral(false, s, reason);
- }
+ /** Assert a conjunction from lb and ub. */
+ void differenceIsZero(Constraint lb, Constraint ub);
+
+ /** Assert that the value cannot be zero. */
+ void differenceCannotBeZero(Constraint c);
void addSharedTerm(Node x);
};/* class DifferenceManager */
diff --git a/src/theory/arith/dio_solver.cpp b/src/theory/arith/dio_solver.cpp
index 1e47d6cdd..1b3a5cac7 100644
--- a/src/theory/arith/dio_solver.cpp
+++ b/src/theory/arith/dio_solver.cpp
@@ -76,6 +76,22 @@ DioSolver::Statistics::~Statistics(){
StatisticsRegistry::unregisterStat(&d_cutTimer);
}
+bool DioSolver::queueConditions(TrailIndex t){
+ /* debugPrintTrail(t); */
+ Debug("queueConditions") << !inConflict() << std::endl;
+ Debug("queueConditions") << gcdIsOne(t) << std::endl;
+ Debug("queueConditions") << !debugAnySubstitionApplies(t) << std::endl;
+ Debug("queueConditions") << !triviallySat(t) << std::endl;
+ Debug("queueConditions") << !triviallyUnsat(t) << std::endl;
+
+ return
+ !inConflict() &&
+ gcdIsOne(t) &&
+ !debugAnySubstitionApplies(t) &&
+ !triviallySat(t) &&
+ !triviallyUnsat(t);
+}
+
size_t DioSolver::allocateVariableInPool() {
Assert(d_lastUsedVariable <= d_variablePool.size());
if(d_lastUsedVariable == d_variablePool.size()){
@@ -125,9 +141,10 @@ bool DioSolver::acceptableOriginalNodes(Node n){
}else if(k == kind::AND){
Node ub = n[0];
Node lb = n[1];
- Kind kub = simplifiedKind(ub);
- Kind klb = simplifiedKind(lb);
- return (kub == kind::LEQ || kub==kind::LT) && (klb == kind::GEQ || klb == kind::GT);
+ Kind kub = Comparison::comparisonKind(ub);
+ Kind klb = Comparison::comparisonKind(lb);
+ Debug("nf::tmp") << n << endl;
+ return (kub == kind::GEQ || kub==kind::LT) && (klb == kind::GEQ || klb == kind::LT);
}else{
return false;
}
@@ -135,11 +152,11 @@ bool DioSolver::acceptableOriginalNodes(Node n){
void DioSolver::pushInputConstraint(const Comparison& eq, Node reason){
Assert(!debugEqualityInInputEquations(reason));
- Assert(eq.isIntegral());
+ Assert(eq.debugIsIntegral());
Assert(eq.getNode().getKind() == kind::EQUAL);
Assert(acceptableOriginalNodes(reason));
- SumPair sp = SumPair::comparisonToSumPair(eq);
+ SumPair sp = eq.toSumPair();
uint32_t length = sp.maxLength();
if(length > d_maxInputCoefficientLength){
d_maxInputCoefficientLength = length;
@@ -573,7 +590,6 @@ DioSolver::TrailIndex DioSolver::applyAllSubstitutionsToIndex(DioSolver::TrailIn
bool DioSolver::debugSubstitutionApplies(DioSolver::SubIndex si, DioSolver::TrailIndex ti){
Variable var = d_subs[si].d_eliminated;
- TrailIndex subIndex = d_subs[si].d_constraint;
const SumPair& curr = d_trail[ti].d_eq;
Polynomial vsum = curr.getPolynomial();
diff --git a/src/theory/arith/dio_solver.h b/src/theory/arith/dio_solver.h
index 677040615..c5a0f534f 100644
--- a/src/theory/arith/dio_solver.h
+++ b/src/theory/arith/dio_solver.h
@@ -338,22 +338,8 @@ private:
/** Returns true if the queue of nodes to process is empty. */
bool queueEmpty() const;
- bool queueConditions(TrailIndex t){
- /* debugPrintTrail(t); */
-
- /* std::cout << !inConflict() << std::endl; */
- /* std::cout << gcdIsOne(t) << std::endl; */
- /* std::cout << !debugAnySubstitionApplies(t) << std::endl; */
- /* std::cout << !triviallySat(t) << std::endl; */
- /* std::cout << !triviallyUnsat(t) << std::endl; */
-
- return
- !inConflict() &&
- gcdIsOne(t) &&
- !debugAnySubstitionApplies(t) &&
- !triviallySat(t) &&
- !triviallyUnsat(t);
- }
+ bool queueConditions(TrailIndex t);
+
void pushToQueueBack(TrailIndex t){
Assert(queueConditions(t));
diff --git a/src/theory/arith/linear_equality.cpp b/src/theory/arith/linear_equality.cpp
index c84e61285..ca7cd69c4 100644
--- a/src/theory/arith/linear_equality.cpp
+++ b/src/theory/arith/linear_equality.cpp
@@ -26,8 +26,8 @@ namespace theory {
namespace arith {
/* Explicitly instatiate this function. */
-template void LinearEqualityModule::explainNonbasics<true>(ArithVar basic, NodeBuilder<>& output);
-template void LinearEqualityModule::explainNonbasics<false>(ArithVar basic, NodeBuilder<>& output);
+template void LinearEqualityModule::propagateNonbasics<true>(ArithVar basic, Constraint c);
+template void LinearEqualityModule::propagateNonbasics<false>(ArithVar basic, Constraint c);
LinearEqualityModule::Statistics::Statistics():
d_statPivots("theory::arith::pivots",0),
@@ -71,7 +71,7 @@ void LinearEqualityModule::update(ArithVar x_i, const DeltaRational& v){
DeltaRational nAssignment = assignment+(diff * a_ji);
d_partialModel.setAssignment(x_j, nAssignment);
- d_basicVariableUpdates.callback(x_j);
+ d_basicVariableUpdates(x_j);
}
d_partialModel.setAssignment(x_i, v);
@@ -119,7 +119,7 @@ void LinearEqualityModule::pivotAndUpdate(ArithVar x_i, ArithVar x_j, DeltaRatio
DeltaRational nextAssignment = d_partialModel.getAssignment(x_k) + (theta * a_kj);
d_partialModel.setAssignment(x_k, nextAssignment);
- d_basicVariableUpdates.callback(x_k);
+ d_basicVariableUpdates(x_k);
}
}
@@ -131,7 +131,7 @@ void LinearEqualityModule::pivotAndUpdate(ArithVar x_i, ArithVar x_j, DeltaRatio
//(d_statistics.d_avgNumRowsNotContainingOnPivot).addEntry(difference);
d_tableau.pivot(x_i, x_j);
- d_basicVariableUpdates.callback(x_j);
+ d_basicVariableUpdates(x_j);
if(Debug.isOn("tableau")){
d_tableau.printTableau();
@@ -255,12 +255,17 @@ bool LinearEqualityModule::hasBounds(ArithVar basic, bool upperBound){
}
template <bool upperBound>
-void LinearEqualityModule::explainNonbasics(ArithVar basic, NodeBuilder<>& output){
+void LinearEqualityModule::propagateNonbasics(ArithVar basic, Constraint c){
Assert(d_tableau.isBasic(basic));
+ Assert(c->getVariable() == basic);
+ Assert(!c->assertedToTheTheory());
+ Assert(c->canBePropagated());
+ Assert(!c->hasProof());
Debug("arith::explainNonbasics") << "LinearEqualityModule::explainNonbasics("
<< basic <<") start" << endl;
+ vector<Constraint> bounds;
Tableau::RowIterator iter = d_tableau.rowIterator(basic);
for(; !iter.atEnd(); ++iter){
@@ -269,30 +274,42 @@ void LinearEqualityModule::explainNonbasics(ArithVar basic, NodeBuilder<>& outpu
if(nonbasic == basic) continue;
const Rational& a_ij = entry.getCoefficient();
- TNode bound = TNode::null();
int sgn = a_ij.sgn();
Assert(sgn != 0);
+ Constraint bound = NullConstraint;
if(upperBound){
if(sgn < 0){
- bound = d_partialModel.getLowerConstraint(nonbasic);
+ bound = d_partialModel.getLowerBoundConstraint(nonbasic);
+ //d_partialModel.explainLowerBound(nonbasic, output);
+ //bound = d_partialModel.explainLowerBound(nonbasic);
}else{
Assert(sgn > 0);
- bound = d_partialModel.getUpperConstraint(nonbasic);
+ bound = d_partialModel.getUpperBoundConstraint(nonbasic);
+ //d_partialModel.explainUpperBound(nonbasic, output);
+ //bound = d_partialModel.explainUpperBound(nonbasic);
}
}else{
if(sgn < 0){
- bound = d_partialModel.getUpperConstraint(nonbasic);
+ bound = d_partialModel.getUpperBoundConstraint(nonbasic);
+ //d_partialModel.explainUpperBound(nonbasic, output);
+ //bound = d_partialModel.explainUpperBound(nonbasic);
}else{
Assert(sgn > 0);
- bound = d_partialModel.getLowerConstraint(nonbasic);
+ bound = d_partialModel.getLowerBoundConstraint(nonbasic);
+ //d_partialModel.explainLowerBound(nonbasic, output);
+ //bound = d_partialModel.explainLowerBound(nonbasic);
}
}
- Assert(!bound.isNull());
- Debug("arith::explainNonbasics") << "\t" << nonbasic << " " << sgn << " " << bound
- << endl;
- output << bound;
+ Assert(bound != NullConstraint);
+ Debug("arith::explainNonbasics") << "explainNonbasics" << bound << " for " << c << endl;
+ bounds.push_back(bound);
+ //Assert(!bound.isNull());
+ // Debug("arith::explainNonbasics") << "\t" << nonbasic << " " << sgn << " " << bound
+ // << endl;
+ // output << bound;
}
+ c->propagate(bounds);
Debug("arith::explainNonbasics") << "LinearEqualityModule::explainNonbasics("
<< basic << ") done" << endl;
}
diff --git a/src/theory/arith/linear_equality.h b/src/theory/arith/linear_equality.h
index 4d1d917b3..b5d439769 100644
--- a/src/theory/arith/linear_equality.h
+++ b/src/theory/arith/linear_equality.h
@@ -36,6 +36,7 @@
#include "theory/arith/arithvar.h"
#include "theory/arith/partial_model.h"
#include "theory/arith/tableau.h"
+#include "theory/arith/constraint.h"
#include "util/stats.h"
@@ -101,14 +102,16 @@ private:
* of the basic variable basic, using the non-basic variables in the row.
*/
template <bool upperBound>
- void explainNonbasics(ArithVar basic, NodeBuilder<>& output);
+ void propagateNonbasics(ArithVar basic, Constraint c);
public:
- void explainNonbasicsLowerBound(ArithVar basic, NodeBuilder<>& output){
- explainNonbasics<false>(basic, output);
+ void propagateNonbasicsLowerBound(ArithVar basic, Constraint c){
+ Assert(c->isLowerBound());
+ propagateNonbasics<false>(basic, c);
}
- void explainNonbasicsUpperBound(ArithVar basic, NodeBuilder<>& output){
- explainNonbasics<true>(basic, output);
+ void propagateNonbasicsUpperBound(ArithVar basic, Constraint c){
+ Assert(c->isUpperBound());
+ propagateNonbasics<true>(basic, c);
}
/**
diff --git a/src/theory/arith/normal_form.cpp b/src/theory/arith/normal_form.cpp
index 31cd8cd70..6f8a46236 100644
--- a/src/theory/arith/normal_form.cpp
+++ b/src/theory/arith/normal_form.cpp
@@ -18,6 +18,7 @@
**/
#include "theory/arith/normal_form.h"
+#include "theory/arith/arith_utilities.h"
#include <list>
using namespace std;
@@ -122,15 +123,25 @@ Monomial Monomial::parseMonomial(Node n) {
return Monomial(VarList::parseVarList(n));
}
}
-Monomial Monomial::operator*(const Constant& c) const {
- if(c.isZero()){
+Monomial Monomial::operator*(const Rational& q) const {
+ if(q.isZero()){
return mkZero();
}else{
- Constant newConstant = this->getConstant() * c;
+ Constant newConstant = this->getConstant() * q;
return Monomial::mkMonomial(newConstant, getVarList());
}
}
+Monomial Monomial::operator*(const Constant& c) const {
+ return (*this) * c.getValue();
+ // if(c.isZero()){
+ // return mkZero();
+ // }else{
+ // Constant newConstant = this->getConstant() * c;
+ // return Monomial::mkMonomial(newConstant, getVarList());
+ // }
+}
+
Monomial Monomial::operator*(const Monomial& mono) const {
Constant newConstant = this->getConstant() * mono.getConstant();
VarList newVL = this->getVarList() * mono.getVarList();
@@ -188,15 +199,15 @@ Polynomial Polynomial::operator-(const Polynomial& vl) const {
return *this + (vl*negOne);
}
-Polynomial Polynomial::operator*(const Constant& c) const{
- if(c.isZero()){
+Polynomial Polynomial::operator*(const Rational& q) const{
+ if(q.isZero()){
return Polynomial::mkZero();
- }else if(c.isOne()){
+ }else if(q.isOne()){
return *this;
}else{
std::vector<Monomial> newMonos;
for(iterator i = this->begin(), end = this->end(); i != end; ++i) {
- newMonos.push_back((*i)*c);
+ newMonos.push_back((*i)*q);
}
Assert(Monomial::isStrictlySorted(newMonos));
@@ -204,6 +215,23 @@ Polynomial Polynomial::operator*(const Constant& c) const{
}
}
+Polynomial Polynomial::operator*(const Constant& c) const{
+ return (*this) * c.getValue();
+ // if(c.isZero()){
+ // return Polynomial::mkZero();
+ // }else if(c.isOne()){
+ // return *this;
+ // }else{
+ // std::vector<Monomial> newMonos;
+ // for(iterator i = this->begin(), end = this->end(); i != end; ++i) {
+ // newMonos.push_back((*i)*c);
+ // }
+
+ // Assert(Monomial::isStrictlySorted(newMonos));
+ // return Polynomial::mkPolynomial(newMonos);
+ // }
+}
+
Polynomial Polynomial::operator*(const Monomial& mono) const {
if(mono.isZero()) {
return Polynomial(mono); //Don't multiply by zero
@@ -248,10 +276,29 @@ Monomial Polynomial::selectAbsMinimum() const {
return min;
}
+bool Polynomial::leadingCoefficientIsAbsOne() const {
+ return getHead().absCoefficientIsOne();
+}
+bool Polynomial::leadingCoefficientIsPositive() const {
+ return getHead().getConstant().isPositive();
+}
+
+bool Polynomial::denominatorLCMIsOne() const {
+ return denominatorLCM().isOne();
+}
+
+bool Polynomial::numeratorGCDIsOne() const {
+ return gcd().isOne();
+}
+
Integer Polynomial::gcd() const {
+ Assert(isIntegral());
+ return numeratorGCD();
+}
+
+Integer Polynomial::numeratorGCD() const {
//We'll use the standardization that gcd(0, 0) = 0
//So that the gcd of the zero polynomial is gcd{0} = 0
- Assert(isIntegral());
iterator i=begin(), e=end();
Assert(i!=e);
@@ -273,355 +320,918 @@ Integer Polynomial::denominatorLCM() const {
return tmp;
}
+
+Constant Polynomial::getCoefficient(const VarList& vl) const{
+ //TODO improve to binary search...
+ for(iterator iter=begin(), myend=end(); iter != myend; ++iter){
+ Monomial m = *iter;
+ VarList curr = m.getVarList();
+ if(curr == vl){
+ return m.getConstant();
+ }
+ }
+ return Constant::mkConstant(0);
+}
+
+Node Polynomial::computeQR(const Polynomial& p, const Integer& div){
+ Assert(p.isIntegral());
+ std::vector<Monomial> q_vec, r_vec;
+ Integer tmp_q, tmp_r;
+ for(iterator iter = p.begin(), pend = p.end(); iter != pend; ++iter){
+ Monomial curr = *iter;
+ VarList vl = curr.getVarList();
+ Constant c = curr.getConstant();
+
+ const Integer& a = c.getValue().getNumerator();
+ Integer::floorQR(tmp_q, tmp_r, a, div);
+ Constant q=Constant::mkConstant(tmp_q);
+ Constant r=Constant::mkConstant(tmp_r);
+ if(!q.isZero()){
+ q_vec.push_back(Monomial::mkMonomial(q, vl));
+ }
+ if(!r.isZero()){
+ r_vec.push_back(Monomial::mkMonomial(r, vl));
+ }
+ }
+
+ Polynomial p_q = Polynomial::mkPolynomial(q_vec);
+ Polynomial p_r = Polynomial::mkPolynomial(r_vec);
+
+ return NodeManager::currentNM()->mkNode(kind::PLUS, p_q.getNode(), p_r.getNode());
+}
+
+
+Monomial Polynomial::minimumVariableMonomial() const{
+ Assert(!isConstant());
+ if(singleton()){
+ return getHead();
+ }else{
+ iterator i = begin();
+ Monomial first = *i;
+ if( first.isConstant() ){
+ ++i;
+ Assert(i != end());
+ return *i;
+ }else{
+ return first;
+ }
+ }
+}
+
+bool Polynomial::variableMonomialAreStrictlyGreater(const Monomial& m) const{
+ if(isConstant()){
+ return true;
+ }else{
+ Monomial minimum = minimumVariableMonomial();
+ Debug("nf::tmp") << "minimum " << minimum.getNode() << endl;
+ Debug("nf::tmp") << "m " << m.getNode() << endl;
+ return m < minimum;
+ }
+}
+
+Node SumPair::computeQR(const SumPair& sp, const Integer& div){
+ Assert(sp.isIntegral());
+
+ const Integer& constant = sp.getConstant().getValue().getNumerator();
+
+ Integer constant_q, constant_r;
+ Integer::floorQR(constant_q, constant_r, constant, div);
+
+ Node p_qr = Polynomial::computeQR(sp.getPolynomial(), div);
+ Assert(p_qr.getKind() == kind::PLUS);
+ Assert(p_qr.getNumChildren() == 2);
+
+ Polynomial p_q = Polynomial::parsePolynomial(p_qr[0]);
+ Polynomial p_r = Polynomial::parsePolynomial(p_qr[1]);
+
+ SumPair sp_q(p_q, Constant::mkConstant(constant_q));
+ SumPair sp_r(p_r, Constant::mkConstant(constant_r));
+
+ return NodeManager::currentNM()->mkNode(kind::PLUS, sp_q.getNode(), sp_r.getNode());
+}
+
+SumPair SumPair::mkSumPair(const Polynomial& p){
+ if(p.isConstant()){
+ Constant leadingConstant = p.getHead().getConstant();
+ return SumPair(Polynomial::mkZero(), leadingConstant);
+ }else if(p.containsConstant()){
+ Assert(!p.singleton());
+ return SumPair(p.getTail(), p.getHead().getConstant());
+ }else{
+ return SumPair(p, Constant::mkZero());
+ }
+}
+
+Comparison::Comparison(TNode n)
+ : NodeWrapper(n)
+{
+ Assert(isNormalForm());
+}
+
+
+
+SumPair Comparison::toSumPair() const {
+ Kind cmpKind = comparisonKind();
+ switch(cmpKind){
+ case kind::LT:
+ case kind::LEQ:
+ case kind::GT:
+ case kind::GEQ:
+ {
+ TNode lit = getNode();
+ TNode atom = (cmpKind == kind::LT || cmpKind == kind::LEQ) ? lit[0] : lit;
+ Polynomial p = Polynomial::parsePolynomial(atom[0]);
+ Constant c = Constant::mkConstant(atom[1]);
+ if(p.leadingCoefficientIsPositive()){
+ return SumPair(p, -c);
+ }else{
+ return SumPair(-p, c);
+ }
+ }
+ case kind::EQUAL:
+ case kind::DISTINCT:
+ {
+ Polynomial left = getLeft();
+ Polynomial right = getRight();
+ Debug("nf::tmp") << "left: " << left.getNode() << endl;
+ Debug("nf::tmp") << "right: " << right.getNode() << endl;
+ if(right.isConstant()){
+ return SumPair(left, -right.getHead().getConstant());
+ }else if(right.containsConstant()){
+ Assert(!right.singleton());
+
+ Polynomial noConstant = right.getTail();
+ return SumPair(left - noConstant, -right.getHead().getConstant());
+ }else{
+ return SumPair(left - right, Constant::mkZero());
+ }
+ }
+ default:
+ Unhandled(cmpKind);
+ }
+}
+
+Polynomial Comparison::normalizedVariablePart() const {
+ Kind cmpKind = comparisonKind();
+ switch(cmpKind){
+ case kind::LT:
+ case kind::LEQ:
+ case kind::GT:
+ case kind::GEQ:
+ {
+ TNode lit = getNode();
+ TNode atom = (cmpKind == kind::LT || cmpKind == kind::LEQ) ? lit[0] : lit;
+ Polynomial p = Polynomial::parsePolynomial(atom[0]);
+ if(p.leadingCoefficientIsPositive()){
+ return p;
+ }else{
+ return -p;
+ }
+ }
+ case kind::EQUAL:
+ case kind::DISTINCT:
+ {
+ Polynomial left = getLeft();
+ Polynomial right = getRight();
+ if(right.isConstant()){
+ return left;
+ }else if(right.containsConstant()){
+ Polynomial noConstant = right.getTail();
+ return left - noConstant;
+ }else{
+ return left - right;
+ }
+ }
+ default:
+ Unhandled(cmpKind);
+ }
+}
+
+DeltaRational Comparison::normalizedDeltaRational() const {
+ Kind cmpKind = comparisonKind();
+ int delta = deltaCoeff(cmpKind);
+ switch(cmpKind){
+ case kind::LT:
+ case kind::LEQ:
+ case kind::GT:
+ case kind::GEQ:
+ {
+ Node lit = getNode();
+ Node atom = (cmpKind == kind::LT || cmpKind == kind::LEQ) ? lit[0] : lit;
+ Polynomial left = Polynomial::parsePolynomial(atom[0]);
+ const Rational& q = atom[1].getConst<Rational>();
+ if(left.leadingCoefficientIsPositive()){
+ return DeltaRational(q, delta);
+ }else{
+ return DeltaRational(-q, -delta);
+ }
+ }
+ case kind::EQUAL:
+ case kind::DISTINCT:
+ {
+ Monomial firstRight = getRight().getHead();
+ if(firstRight.isConstant()){
+ return DeltaRational(firstRight.getConstant().getValue(), 0);
+ }else{
+ return DeltaRational(0, 0);
+ }
+ }
+ default:
+ Unhandled(cmpKind);
+ }
+}
+
+Comparison Comparison::parseNormalForm(TNode n) {
+ Comparison result(n);
+ Assert(result.isNormalForm());
+ return result;
+}
+
Node Comparison::toNode(Kind k, const Polynomial& l, const Constant& r) {
Assert(isRelationOperator(k));
switch(k) {
case kind::GEQ:
+ case kind::GT:
+ return NodeManager::currentNM()->mkNode(k, l.getNode(), r.getNode());
+ default:
+ Unhandled(k);
+ }
+}
+
+Node Comparison::toNode(Kind k, const Polynomial& l, const Polynomial& r) {
+ Assert(isRelationOperator(k));
+ switch(k) {
+ case kind::GEQ:
case kind::EQUAL:
+ case kind::GT:
+ return NodeManager::currentNM()->mkNode(k, l.getNode(), r.getNode());
case kind::LEQ:
- return NodeManager::currentNM()->mkNode(k, l.getNode(),r.getNode());
+ return toNode(kind::GEQ, r, l).notNode();
case kind::LT:
- return NodeManager::currentNM()->mkNode(kind::NOT, toNode(kind::GEQ,l,r));
- case kind::GT:
- return NodeManager::currentNM()->mkNode(kind::NOT, toNode(kind::LEQ,l,r));
+ return toNode(kind::GT, r, l).notNode();
+ case kind::DISTINCT:
+ return toNode(kind::EQUAL, r, l).notNode();
default:
Unreachable();
}
}
-Comparison Comparison::parseNormalForm(TNode n) {
- if(n.getKind() == kind::CONST_BOOLEAN) {
- return Comparison(n.getConst<bool>());
- } else {
- bool negated = n.getKind() == kind::NOT;
- Node relation = negated ? n[0] : n;
- Assert( !negated ||
- relation.getKind() == kind::LEQ ||
- relation.getKind() == kind::GEQ);
-
- Polynomial left = Polynomial::parsePolynomial(relation[0]);
- Constant right(relation[1]);
-
- Kind newOperator = relation.getKind();
- if(negated) {
- if(newOperator == kind::LEQ) {
- newOperator = kind::GT;
- } else {
- newOperator = kind::LT;
- }
- }
- return Comparison(n, newOperator, left, right);
+bool Comparison::rightIsConstant() const {
+ if(getNode().getKind() == kind::NOT){
+ return getNode()[0][1].getKind() == kind::CONST_RATIONAL;
+ }else{
+ return getNode()[1].getKind() == kind::CONST_RATIONAL;
}
}
-bool Comparison::pbComparison(Kind k, TNode left, const Rational& right, bool& result) {
- AssertArgument(left.getType().isPseudoboolean(), left);
- switch(k) {
+Polynomial Comparison::getLeft() const {
+ TNode left;
+ Kind k = comparisonKind();
+ switch(k){
case kind::LT:
- if(right > 1) {
- result = true;
- return true;
- } else if(right <= 0) {
- result = false;
- return true;
- }
- break;
case kind::LEQ:
- if(right >= 1) {
- result = true;
- return true;
- } else if(right < 0) {
- result = false;
- return true;
- }
+ case kind::DISTINCT:
+ left = getNode()[0][0];
break;
case kind::EQUAL:
- if(right != 0 && right != 1) {
- result = false;
- return true;
- }
- break;
+ case kind::GT:
case kind::GEQ:
- if(right > 1) {
- result = false;
- return true;
- } else if(right <= 0) {
- result = true;
- return true;
- }
+ left = getNode()[0];
+ break;
+ default:
+ Unhandled(k);
+ }
+ return Polynomial::parsePolynomial(left);
+}
+
+Polynomial Comparison::getRight() const {
+ TNode right;
+ Kind k = comparisonKind();
+ switch(k){
+ case kind::LT:
+ case kind::LEQ:
+ case kind::DISTINCT:
+ right = getNode()[0][1];
break;
+ case kind::EQUAL:
case kind::GT:
- if(right >= 1) {
- result = false;
- return true;
- } else if(right < 0) {
- result = true;
- return true;
- }
+ case kind::GEQ:
+ right = getNode()[1];
break;
default:
- CheckArgument(false, k, "Bad comparison operator ?!");
+ Unhandled(k);
}
-
- return false;
+ return Polynomial::parsePolynomial(right);
}
-// Comparison Comparison::mkComparison(Kind k, const Polynomial& left, const Constant& right) {
-// Assert(isRelationOperator(k));
-// if(left.isConstant()) {
-// const Rational& lConst = left.getNode().getConst<Rational>();
-// const Rational& rConst = right.getNode().getConst<Rational>();
-// bool res = evaluateConstantPredicate(k, lConst, rConst);
-// return Comparison(res);
-// }
-
-// if(left.getNode().getType().isPseudoboolean()) {
-// bool result;
-// if(pbComparison(k, left.getNode(), right.getNode().getConst<Rational>(), result)) {
-// return Comparison(result);
-// }
-// }
+// Polynomial Comparison::getLeft() const {
+// Node n = getNode();
+// Node left = (n.getKind() == kind::NOT ? n[0]: n)[0];
+// return Polynomial::parsePolynomial(left);
+// }
-// return Comparison(toNode(k, left, right), k, left, right);
+// Polynomial Comparison::getRight() const {
+// Node n = getNode();
+// Node right = (n.getKind() == kind::NOT ? n[0]: n)[1];
+// return Polynomial::parsePolynomial(right);
// }
-Comparison Comparison::mkComparison(Kind k, const Polynomial& left, const Constant& right) {
- Assert(isRelationOperator(k));
- return Comparison(toNode(k, left, right), k, left, right);
+bool Comparison::isNormalForm() const {
+ Node n = getNode();
+ Kind cmpKind = comparisonKind(n);
+ Debug("nf::tmp") << "isNormalForm " << n << " " << cmpKind << endl;
+ switch(cmpKind){
+ case kind::CONST_BOOLEAN:
+ return true;
+ case kind::GT:
+ return isNormalGT();
+ case kind::GEQ:
+ return isNormalGEQ();
+ case kind::EQUAL:
+ return isNormalEquality();
+ case kind::LT:
+ return isNormalLT();
+ case kind::LEQ:
+ return isNormalLEQ();
+ case kind::DISTINCT:
+ return isNormalDistinct();
+ default:
+ return false;
+ }
}
-Comparison Comparison::addConstant(const Constant& constant) const {
- Assert(!isBoolean());
- Monomial mono(constant);
- Polynomial constAsPoly( mono );
- Polynomial newLeft = getLeft() + constAsPoly;
- Constant newRight = getRight() + constant;
- return mkComparison(oper, newLeft, newRight);
+/** This must be (> qpolynomial constant) */
+bool Comparison::isNormalGT() const {
+ Node n = getNode();
+ Assert(n.getKind() == kind::GT);
+ if(!rightIsConstant()){
+ return false;
+ }else{
+ Polynomial left = getLeft();
+ if(left.containsConstant()){
+ return false;
+ }else if(!left.leadingCoefficientIsAbsOne()){
+ return false;
+ }else{
+ return !left.isIntegral();
+ }
+ }
}
-bool Comparison::constantInLefthand() const{
- return getLeft().containsConstant();
+/** This must be (not (> qpolynomial constant)) */
+bool Comparison::isNormalLEQ() const {
+ Node n = getNode();
+ Debug("nf::tmp") << "isNormalLEQ " << n << endl;
+ Assert(n.getKind() == kind::NOT);
+ Assert(n[0].getKind() == kind::GT);
+ if(!rightIsConstant()){
+ return false;
+ }else{
+ Polynomial left = getLeft();
+ if(left.containsConstant()){
+ return false;
+ }else if(!left.leadingCoefficientIsAbsOne()){
+ return false;
+ }else{
+ return !left.isIntegral();
+ }
+ }
}
-Comparison Comparison::cancelLefthandConstant() const {
- if(constantInLefthand()){
- Monomial constantHead = getLeft().getHead();
- Assert(constantHead.isConstant());
- Constant constant = constantHead.getConstant();
- Constant negativeConstantHead = -constant;
- return addConstant(negativeConstantHead);
+/** This must be (>= qpolynomial constant) or (>= zpolynomial constant) */
+bool Comparison::isNormalGEQ() const {
+ Node n = getNode();
+ Assert(n.getKind() == kind::GEQ);
+
+ Debug("nf::tmp") << "isNormalGEQ " << n << " " << rightIsConstant() << endl;
+
+ if(!rightIsConstant()){
+ return false;
}else{
- return *this;
+ Polynomial left = getLeft();
+ if(left.containsConstant()){
+ return false;
+ }else{
+ if(left.isIntegral()){
+ return left.denominatorLCMIsOne() && left.numeratorGCDIsOne();
+ }else{
+ Debug("nf::tmp") << "imme sdfhkdjfh "<< left.leadingCoefficientIsAbsOne() << endl;
+ return left.leadingCoefficientIsAbsOne();
+ }
+ }
}
}
-Comparison Comparison::multiplyConstant(const Constant& constant) const {
- Assert(!isBoolean());
- Kind newOper = (constant.getValue() < 0) ? reverseRelationKind(oper) : oper;
+/** This must be (not (>= qpolynomial constant)) or (not (>= zpolynomial constant)) */
+bool Comparison::isNormalLT() const {
+ Node n = getNode();
+ Assert(n.getKind() == kind::NOT);
+ Assert(n[0].getKind() == kind::GEQ);
- return mkComparison(newOper, left*Monomial(constant), right*constant);
+ if(!rightIsConstant()){
+ return false;
+ }else{
+ Polynomial left = getLeft();
+ if(left.containsConstant()){
+ return false;
+ }else{
+ if(left.isIntegral()){
+ return left.denominatorLCMIsOne() && left.numeratorGCDIsOne();
+ }else{
+ return left.leadingCoefficientIsAbsOne();
+ }
+ }
+ }
}
-Integer Comparison::denominatorLCM() const {
- // Get the coefficients to be all integers.
- Integer leftDenominatorLCM = left.denominatorLCM();
- Integer rightDenominator = right.getValue().getDenominator();
- Integer denominatorLCM = leftDenominatorLCM.lcm(rightDenominator);
- Assert(denominatorLCM.sgn() > 0);
- return denominatorLCM;
-}
-Comparison Comparison::multiplyByDenominatorLCM() const{
- return multiplyConstant(Constant::mkConstant(denominatorLCM()));
-}
+bool Comparison::isNormalEqualityOrDisequality() const {
+ Polynomial pleft = getLeft();
-Comparison Comparison::normalizeLeadingCoefficientPositive() const {
- if(getLeft().getHead().getConstant().isNegative()){
- return multiplyConstant(Constant::mkConstant(-1));
+ if(pleft.numMonomials() == 1){
+ Monomial mleft = pleft.getHead();
+ if(mleft.isConstant()){
+ return false;
+ }else{
+ Polynomial pright = getRight();
+ if(allIntegralVariables()){
+ const Rational& lcoeff = mleft.getConstant().getValue();
+ if(pright.isConstant()){
+ return pright.isIntegral() && lcoeff.isOne();
+ }
+ Polynomial varRight = pright.containsConstant() ? pright.getTail() : pright;
+ if(lcoeff.sgn() <= 0){
+ return false;
+ }else{
+ Integer lcm = lcoeff.getDenominator().lcm(varRight.denominatorLCM());
+ Integer g = lcoeff.getNumerator().gcd(varRight.numeratorGCD());
+ Debug("nf::tmp") << lcm << " " << g << endl;
+ if(!lcm.isOne()){
+ return false;
+ }else if(!g.isOne()){
+ return false;
+ }else{
+ Monomial absMinRight = varRight.selectAbsMinimum();
+ Debug("nf::tmp") << mleft.getNode() << " " << absMinRight.getNode() << endl;
+ if( mleft.absLessThan(absMinRight) ){
+ return true;
+ }else{
+ return (!absMinRight.absLessThan(mleft)) && mleft < absMinRight;
+ }
+ }
+ }
+ }else{
+ if(mleft.coefficientIsOne()){
+ Debug("nf::tmp")
+ << "dfklj " << mleft.getNode() << endl
+ << pright.getNode() << endl
+ << pright.variableMonomialAreStrictlyGreater(mleft)
+ << endl;
+ return pright.variableMonomialAreStrictlyGreater(mleft);
+ }else{
+ return false;
+ }
+ }
+ }
}else{
- return *this;
+ return false;
}
}
-bool Comparison::isIntegral() const {
- return getRight().isIntegral() && getLeft().isIntegral();
+/** This must be (= qvarlist qpolynomial) or (= zmonomial zpolynomial)*/
+bool Comparison::isNormalEquality() const {
+ Assert(getNode().getKind() == kind::EQUAL);
+
+ return isNormalEqualityOrDisequality();
}
-bool Comparison::isConstant() const {
- return getLeft().isConstant();
+/**
+ * This must be (not (= qvarlist qpolynomial)) or
+ * (not (= zmonomial zpolynomial)).
+ */
+bool Comparison::isNormalDistinct() const {
+ Assert(getNode().getKind() == kind::NOT);
+ Assert(getNode()[0].getKind() == kind::EQUAL);
+
+ return isNormalEqualityOrDisequality();
}
-Comparison Comparison::evaluateConstant() const {
- Assert(left.isConstant());
- const Rational& rConst = getRight().getValue();
- const Rational& lConst = getLeft().getHead().getConstant().getValue();
- bool res = evaluateConstantPredicate(getKind(), lConst, rConst);
- return Comparison(res);
+Node Comparison::mkRatEquality(const Polynomial& p){
+ Assert(!p.isConstant());
+ Assert(!p.allIntegralVariables());
+
+ Monomial minimalVList = p.minimumVariableMonomial();
+ Constant coeffInv = -(minimalVList.getConstant().inverse());
+
+ Polynomial newRight = (p - minimalVList) * coeffInv;
+ Polynomial newLeft(minimalVList.getVarList());
+
+ return toNode(kind::EQUAL, newLeft, newRight);
}
-Comparison Comparison::divideByLefthandGCD() const {
- Assert(isIntegral());
+Node Comparison::mkRatInequality(Kind k, const Polynomial& p){
+ Assert(k == kind::GEQ || k == kind::GT);
+ Assert(!p.isConstant());
+ Assert(!p.allIntegralVariables());
+
+ SumPair sp = SumPair::mkSumPair(p);
+ Polynomial left = sp.getPolynomial();
+ Constant right = - sp.getConstant();
+
+ Monomial minimalVList = left.getHead();
+ Assert(!minimalVList.isConstant());
+
+ Constant coeffInv = minimalVList.getConstant().inverse().abs();
+ Polynomial newLeft = left * coeffInv;
+ Constant newRight = right * (coeffInv);
+
+ return toNode(k, newLeft, newRight);
+}
+
+Node Comparison::mkIntInequality(Kind k, const Polynomial& p){
+ Assert(kind::GT == k || kind::GEQ == k);
+ Assert(!p.isConstant());
+ Assert(p.allIntegralVariables());
+
+ SumPair sp = SumPair::mkSumPair(p);
+ Polynomial left = sp.getPolynomial();
+ Rational right = - (sp.getConstant().getValue());
+
+ Monomial m = left.getHead();
+ Assert(!m.isConstant());
+
+ Integer lcm = left.denominatorLCM();
+ Integer g = left.numeratorGCD();
+ Rational mult(lcm,g);
- Integer zr = getRight().getValue().getNumerator();
- Integer gcd = getLeft().gcd();
- Polynomial newLeft = getLeft().exactDivide(gcd);
+ Polynomial newLeft = left * mult;
+ Rational rightMult = right * mult;
- Constant newRight = Constant::mkConstant(Rational(zr,gcd));
- return mkComparison(getKind(), newLeft, newRight);
+
+ if(rightMult.isIntegral()){
+ if(k == kind::GT){
+ // (> p z)
+ // (>= p (+ z 1))
+ Constant rightMultPlusOne = Constant::mkConstant(rightMult + 1);
+ return toNode(kind::GEQ, newLeft, rightMultPlusOne);
+ }else{
+ Constant newRight = Constant::mkConstant(rightMult);
+ return toNode(kind::GEQ, newLeft, newRight);
+ }
+ }else{
+ //(>= l (/ n d))
+ //(>= l (ceil (/ n d)))
+ //This also hold for GT as (ceil (/ n d)) > (/ n d)
+ Integer ceilr = rightMult.ceiling();
+ Constant ceilRight = Constant::mkConstant(ceilr);
+ return toNode(kind::GEQ, newLeft, ceilRight);
+ }
}
-Comparison Comparison::divideByLeadingCoefficient() const {
- //Handle the rational/mixed case
- Monomial head = getLeft().getHead();
- Constant leadingCoefficient = head.getConstant();
- Assert(!leadingCoefficient.isZero());
+Node Comparison::mkIntEquality(const Polynomial& p){
+ Assert(!p.isConstant());
+ Assert(p.allIntegralVariables());
+
+ SumPair sp = SumPair::mkSumPair(p);
+ Polynomial varPart = sp.getPolynomial();
+ Constant constPart = sp.getConstant();
+
+ Integer lcm = varPart.denominatorLCM();
+ Integer g = varPart.numeratorGCD();
+ Constant mult = Constant::mkConstant(Rational(lcm,g));
- Constant inverse = leadingCoefficient.inverse();
+ Constant constMult = constPart * mult;
- return multiplyConstant(inverse);
+ if(constMult.isIntegral()){
+ Polynomial varPartMult = varPart * mult;
+
+ Monomial m = varPartMult.selectAbsMinimum();
+ bool mIsPositive = m.getConstant().isPositive();
+
+ Polynomial noM = (varPartMult + (- m)) + Polynomial(constMult);
+
+ // m + noM = 0
+ Polynomial newRight = mIsPositive ? -noM : noM;
+ Polynomial newLeft = mIsPositive ? m : -m;
+
+ Assert(newRight.isIntegral());
+ return toNode(kind::EQUAL, newLeft, newRight);
+ }else{
+ return mkBoolNode(false);
+ }
}
-Comparison Comparison::tightenIntegralConstraint() const {
- Assert(getLeft().isIntegral());
+Comparison Comparison::mkComparison(Kind k, const Polynomial& l, const Polynomial& r){
- if(getRight().isIntegral()){
- return *this;
+ //Make this special case fast for sharing!
+ if((k == kind::EQUAL || k == kind::DISTINCT) && l.isVarList() && r.isVarList()){
+ VarList vLeft = l.asVarList();
+ VarList vRight = r.asVarList();
+
+ if(vLeft == vRight){
+ return Comparison(k == kind::EQUAL);
+ }else{
+ Node eqNode = vLeft < vRight ? toNode( kind::EQUAL, l, r) : toNode( kind::EQUAL, r, l);
+ Node forK = (k == kind::DISTINCT) ? eqNode.notNode() : eqNode;
+ return Comparison(forK);
+ }
+ }
+
+ //General case
+ Polynomial diff = l - r;
+ if(diff.isConstant()){
+ bool res = evaluateConstantPredicate(k, diff.asConstant(), Rational(0));
+ return Comparison(res);
}else{
- switch(getKind()){
+ Node result = Node::null();
+ bool isInteger = diff.allIntegralVariables();
+ switch(k){
case kind::EQUAL:
- //If the gcd of the left hand side does not cleanly divide the right hand side,
- //this is unsatisfiable in the theory of Integers.
- return Comparison(false);
- case kind::GEQ:
- case kind::GT:
+ result = isInteger ? mkIntEquality(diff) : mkRatEquality(diff);
+ break;
+ case kind::DISTINCT:
{
- //(>= l (/ n d))
- //(>= l (ceil (/ n d)))
- //This also hold for GT as (ceil (/ n d)) > (/ n d)
- Integer ceilr = getRight().getValue().ceiling();
- Constant newRight = Constant::mkConstant(ceilr);
- return Comparison(toNode(kind::GEQ, getLeft(), newRight),kind::GEQ, getLeft(),newRight);
+ Node eq = isInteger ? mkIntEquality(diff) : mkRatEquality(diff);
+ result = eq.notNode();
}
+ break;
case kind::LEQ:
case kind::LT:
{
- //(<= l (/ n d))
- //(<= l (floor (/ n d)))
- //This also hold for LT as (floor (/ n d)) < (/ n d)
- Integer floor = getRight().getValue().floor();
- Constant newRight = Constant::mkConstant(floor);
- return Comparison(toNode(kind::LEQ, getLeft(), newRight),kind::LEQ, getLeft(),newRight);
+ Polynomial neg = - diff;
+ Kind negKind = (k == kind::LEQ ? kind::GEQ : kind::GT);
+ result = isInteger ?
+ mkIntInequality(negKind, neg) : mkRatInequality(negKind, neg);
}
+ break;
+ case kind::GEQ:
+ case kind::GT:
+ result = isInteger ?
+ mkIntInequality(k, diff) : mkRatInequality(k, diff);
+ break;
default:
- Unreachable();
+ Unhandled(k);
+ }
+ Assert(!result.isNull());
+ if(result.getKind() == kind::NOT && result[0].getKind() == kind::CONST_BOOLEAN){
+ return Comparison(!(result[0].getConst<bool>()));
+ }else{
+ Comparison cmp(result);
+ Assert(cmp.isNormalForm());
+ return cmp;
}
}
}
-bool Comparison::isIntegerNormalForm() const{
- if(constantInLefthand()){ return false; }
- else if(getLeft().getHead().getConstant().isNegative()){ return false; }
- else if(!isIntegral()){ return false; }
- else {
- return getLeft().gcd() == 1;
- }
-}
-bool Comparison::isMixedNormalForm() const {
- if(constantInLefthand()){ return false; }
- else if(allIntegralVariables()) { return false; }
- else{
- return getLeft().getHead().getConstant().getValue() == 1;
- }
-}
+// Comparison Comparison::normalize(Comparison c) {
+// if(c.isConstant()){
+// return c.evaluateConstant();
+// }else{
+// Comparison c0 = c.constantInLefthand() ? c.cancelLefthandConstant() : c;
+// Comparison c1 = c0.normalizeLeadingCoefficientPositive();
+// if(c1.allIntegralVariables()){
+// //All Integer Variable Case
+// Comparison integer0 = c1.multiplyByDenominatorLCM();
+// Comparison integer1 = integer0.divideByLefthandGCD();
+// Comparison integer2 = integer1.tightenIntegralConstraint();
+// Assert(integer2.isBoolean() || integer2.isIntegerNormalForm());
+// return integer2;
+// }else{
+// //Mixed case
+// Comparison mixed = c1.divideByLeadingCoefficient();
+// Assert(mixed.isMixedNormalForm());
+// return mixed;
+// }
+// }
+// }
-Comparison Comparison::normalize(Comparison c) {
- if(c.isConstant()){
- return c.evaluateConstant();
- }else{
- Comparison c0 = c.constantInLefthand() ? c.cancelLefthandConstant() : c;
- Comparison c1 = c0.normalizeLeadingCoefficientPositive();
- if(c1.allIntegralVariables()){
- //All Integer Variable Case
- Comparison integer0 = c1.multiplyByDenominatorLCM();
- Comparison integer1 = integer0.divideByLefthandGCD();
- Comparison integer2 = integer1.tightenIntegralConstraint();
- Assert(integer2.isBoolean() || integer2.isIntegerNormalForm());
- return integer2;
- }else{
- //Mixed case
- Comparison mixed = c1.divideByLeadingCoefficient();
- Assert(mixed.isMixedNormalForm());
- return mixed;
- }
- }
+bool Comparison::isBoolean() const {
+ return getNode().getKind() == kind::CONST_BOOLEAN;
}
-Comparison Comparison::mkNormalComparison(Kind k, const Polynomial& left, const Constant& right) {
- Comparison cmp = mkComparison(k,left,right);
- Comparison normalized = cmp.normalize(cmp);
- Assert(normalized.isNormalForm());
- return normalized;
+
+bool Comparison::debugIsIntegral() const{
+ return getLeft().isIntegral() && getRight().isIntegral();
}
-Node Polynomial::computeQR(const Polynomial& p, const Integer& div){
- Assert(p.isIntegral());
- std::vector<Monomial> q_vec, r_vec;
- Integer tmp_q, tmp_r;
- for(iterator iter = p.begin(), pend = p.end(); iter != pend; ++iter){
- Monomial curr = *iter;
- VarList vl = curr.getVarList();
- Constant c = curr.getConstant();
+// Comparison Comparison::mkComparison(Kind k, const Polynomial& left, const Constant& right) {
+// Assert(isRelationOperator(k));
+// if(left.isConstant()) {
+// const Rational& lConst = left.getNode().getConst<Rational>();
+// const Rational& rConst = right.getNode().getConst<Rational>();
+// bool res = evaluateConstantPredicate(k, lConst, rConst);
+// return Comparison(res);
+// }
- const Integer& a = c.getValue().getNumerator();
- Integer::floorQR(tmp_q, tmp_r, a, div);
- Constant q=Constant::mkConstant(tmp_q);
- Constant r=Constant::mkConstant(tmp_r);
- if(!q.isZero()){
- q_vec.push_back(Monomial::mkMonomial(q, vl));
- }
- if(!r.isZero()){
- r_vec.push_back(Monomial::mkMonomial(r, vl));
- }
- }
+// if(left.getNode().getType().isPseudoboolean()) {
+// bool result;
+// if(pbComparison(k, left.getNode(), right.getNode().getConst<Rational>(), result)) {
+// return Comparison(result);
+// }
+// }
- Polynomial p_q = Polynomial::mkPolynomial(q_vec);
- Polynomial p_r = Polynomial::mkPolynomial(r_vec);
+// return Comparison(toNode(k, left, right), k, left, right);
+// }
- return NodeManager::currentNM()->mkNode(kind::PLUS, p_q.getNode(), p_r.getNode());
-}
+// Comparison Comparison::mkComparison(Kind k, const Polynomial& left, const Polynomial& right) {
+// Assert(isRelationOperator(k));
+// return Comparison(toNode(k, left, right), k, left, right);
+// }
-Node SumPair::computeQR(const SumPair& sp, const Integer& div){
- Assert(sp.isIntegral());
- const Integer& constant = sp.getConstant().getValue().getNumerator();
+// bool Comparison::constantInLefthand() const{
+// return getLeft().containsConstant();
+// }
- Integer constant_q, constant_r;
- Integer::floorQR(constant_q, constant_r, constant, div);
+// Comparison Comparison::cancelLefthandConstant() const {
+// if(constantInLefthand()){
+// Monomial constantHead = getLeft().getHead();
+// Assert(constantHead.isConstant());
- Node p_qr = Polynomial::computeQR(sp.getPolynomial(), div);
- Assert(p_qr.getKind() == kind::PLUS);
- Assert(p_qr.getNumChildren() == 2);
+// Constant constant = constantHead.getConstant();
+// Constant negativeConstantHead = -constant;
+// return addConstant(negativeConstantHead);
+// }else{
+// return *this;
+// }
+// }
- Polynomial p_q = Polynomial::parsePolynomial(p_qr[0]);
- Polynomial p_r = Polynomial::parsePolynomial(p_qr[1]);
+// Integer OrderedPolynomialPair::denominatorLCM() const {
+// // Get the coefficients to be all integers.
+// Integer firstDenominatorLCM = getFirst().denominatorLCM();
+// Integer secondDenominatorLCM = getSecond().denominatorLCM();
+// Integer denominatorLCM = secondDenominatorLCM.lcm(secondDenominatorLCM);
+// Assert(denominatorLCM.sgn() > 0);
+// return denominatorLCM;
+// }
- SumPair sp_q(p_q, Constant::mkConstant(constant_q));
- SumPair sp_r(p_r, Constant::mkConstant(constant_r));
+// bool Comparison::isIntegral() const {
+// return getRight().isIntegral() && getLeft().isIntegral();
+// }
- return NodeManager::currentNM()->mkNode(kind::PLUS, sp_q.getNode(), sp_r.getNode());
-}
+// bool OrderedPolynomialPair::isConstant() const {
+// return getFirst().isConstant() && getSecond().isConstant();
+// }
-Constant Polynomial::getCoefficient(const VarList& vl) const{
- //TODO improve to binary search...
- for(iterator iter=begin(), myend=end(); iter != myend; ++iter){
- Monomial m = *iter;
- VarList curr = m.getVarList();
- if(curr == vl){
- return m.getConstant();
+// bool OrderedPolynomialPair::evaluateConstant(Kind k) const {
+// Assert(getFirst().isConstant());
+// Assert(getSecond().isConstant());
+
+// const Rational& firstConst = getFirst().asConstant();
+// const Rational& secondConst = getSecond().asConstant();
+
+// return evaluateConstantPredicate(k, firstConst, secondConst);
+// }
+
+// OrderedPolynomialPair OrderedPolynomialPair::divideByGCD() const {
+// Assert(isIntegral());
+
+// Integer fGcd = getFirst().gcd();
+// Integer sGcd = getSecond().gcd();
+
+// Integer gcd = fGcd.gcd(sGcd);
+// Polynomial newFirst = getFirst().exactDivide(gcd);
+// Polynomial newSecond = getSecond().exactDivide(gcd);
+
+// return OrderedPolynomialPair(newFirst, newSecond);
+// }
+
+// OrderedPolynomialPair OrderedPolynomialPair::divideByLeadingFirstCoefficient() const {
+// //Handle the rational/mixed case
+// Monomial head = getFirst().getHead();
+// Constant leadingCoefficient = head.getConstant();
+// Assert(!leadingCoefficient.isZero());
+
+// Constant inverse = leadingCoefficient.inverse();
+
+// return multiplyConstant(inverse);
+// }
+
+// OrderedPolynomialPair OrderedPolynomialPair::multiplyConstant(const Constant& c) const {
+// return OrderedPolynomialPair(getFirst() * c, getSecond() * c);
+// }
+
+// Comparison Comparison::divideByLeadingCoefficient() const {
+// //Handle the rational/mixed case
+// Monomial head = getLeft().getHead();
+// Constant leadingCoefficient = head.getConstant();
+// Assert(!leadingCoefficient.isZero());
+
+// Constant inverse = leadingCoefficient.inverse();
+
+// return multiplyConstant(inverse);
+// }
+
+
+
+// Comparison Comparison::tightenIntegralConstraint() const {
+// Assert(getLeft().isIntegral());
+
+// if(getRight().isIntegral()){
+// return *this;
+// }else{
+// switch(getKind()){
+// case kind::EQUAL:
+// //If the gcd of the left hand side does not cleanly divide the right hand side,
+// //this is unsatisfiable in the theory of Integers.
+// return Comparison(false);
+// case kind::GEQ:
+// case kind::GT:
+// {
+// //(>= l (/ n d))
+// //(>= l (ceil (/ n d)))
+// //This also hold for GT as (ceil (/ n d)) > (/ n d)
+// Integer ceilr = getRight().getValue().ceiling();
+// Constant newRight = Constant::mkConstant(ceilr);
+// return Comparison(toNode(kind::GEQ, getLeft(), newRight),kind::GEQ, getLeft(),newRight);
+// }
+// case kind::LEQ:
+// case kind::LT:
+// {
+// //(<= l (/ n d))
+// //(<= l (floor (/ n d)))
+// //This also hold for LT as (floor (/ n d)) < (/ n d)
+// Integer floor = getRight().getValue().floor();
+// Constant newRight = Constant::mkConstant(floor);
+// return Comparison(toNode(kind::LEQ, getLeft(), newRight),kind::LEQ, getLeft(),newRight);
+// }
+// default:
+// Unreachable();
+// }
+// }
+// }
+
+// bool Comparison::isIntegerNormalForm() const{
+// if(constantInLefthand()){ return false; }
+// else if(getLeft().getHead().getConstant().isNegative()){ return false; }
+// else if(!isIntegral()){ return false; }
+// else {
+// return getLeft().gcd() == 1;
+// }
+// }
+// bool Comparison::isMixedNormalForm() const {
+// if(constantInLefthand()){ return false; }
+// else if(allIntegralVariables()) { return false; }
+// else{
+// return getLeft().getHead().getConstant().getValue() == 1;
+// }
+// }
+
+// Comparison Comparison::normalize(Comparison c) {
+// if(c.isConstant()){
+// return c.evaluateConstant();
+// }else{
+// Comparison c0 = c.constantInLefthand() ? c.cancelLefthandConstant() : c;
+// Comparison c1 = c0.normalizeLeadingCoefficientPositive();
+// if(c1.allIntegralVariables()){
+// //All Integer Variable Case
+// Comparison integer0 = c1.multiplyByDenominatorLCM();
+// Comparison integer1 = integer0.divideByLefthandGCD();
+// Comparison integer2 = integer1.tightenIntegralConstraint();
+// Assert(integer2.isBoolean() || integer2.isIntegerNormalForm());
+// return integer2;
+// }else{
+// //Mixed case
+// Comparison mixed = c1.divideByLeadingCoefficient();
+// Assert(mixed.isMixedNormalForm());
+// return mixed;
+// }
+// }
+// }
+
+// Comparison Comparison::mkNormalComparison(Kind k, const Polynomial& left, const Constant& right) {
+// Comparison cmp = mkComparison(k,left,right);
+// Comparison normalized = cmp.normalize(cmp);
+// Assert(normalized.isNormalForm());
+// return normalized;
+// }
+
+
+Kind Comparison::comparisonKind(TNode literal){
+ switch(literal.getKind()){
+ case kind::CONST_BOOLEAN:
+ case kind::GT:
+ case kind::GEQ:
+ case kind::EQUAL:
+ return literal.getKind();
+ case kind::NOT:
+ {
+ TNode negatedAtom = literal[0];
+ switch(negatedAtom.getKind()){
+ case kind::GT: //(not (GT x c)) <=> (LEQ x c)
+ return kind::LEQ;
+ case kind::GEQ: //(not (GEQ x c)) <=> (LT x c)
+ return kind::LT;
+ case kind::EQUAL:
+ return kind::DISTINCT;
+ default:
+ return kind::UNDEFINED_KIND;
+ }
}
+ default:
+ return kind::UNDEFINED_KIND;
}
- return Constant::mkConstant(0);
}
} //namespace arith
diff --git a/src/theory/arith/normal_form.h b/src/theory/arith/normal_form.h
index a5e1e0cec..434be42a2 100644
--- a/src/theory/arith/normal_form.h
+++ b/src/theory/arith/normal_form.h
@@ -49,7 +49,7 @@ namespace arith {
*
* variable := n
* where
- * n.getMetaKind() == metakind::VARIABLE
+ * n.getMetaKind() == metakind::VARIABLE or is foreign
* n.getType() \in {Integer, Real}
*
* constant := n
@@ -71,24 +71,45 @@ namespace arith {
* isStrictlySorted monoOrder [monomial]
* forall (\x -> x != 0) [monomial]
*
- * rational_restricted_cmp := (|><| qpolynomial constant)
+ * rational_cmp := (|><| qpolynomial constant)
* where
- * |><| is GEQ, EQ, or EQ
+ * |><| is GEQ, or GT
* not (exists constantMonomial (monomialList qpolynomial))
* (exists realMonomial (monomialList qpolynomial))
- * monomialCoefficient (head (monomialList qpolynomial)) == 1
+ * abs(monomialCoefficient (head (monomialList qpolynomial))) == 1
*
- * integer_restricted_cmp := (|><| zpolynomial constant)
+ * integer_cmp := (<= zpolynomial constant)
* where
- * |><| is GEQ, EQ, or EQ
* not (exists constantMonomial (monomialList zpolynomial))
- * (forall integerMonomial (monomialList qpolynomial))
+ * (forall integerMonomial (monomialList zpolynomial))
+ * the gcd of all numerators of coefficients is 1
* the denominator of all coefficients and the constant is 1
+ *
+ * rational_eq := (= qvarlist qpolynomial)
+ * where
+ * let allMonomials = (cons qvarlist (monomialList zpolynomial))
+ * let variableMonomials = (drop constantMonomial allMonomials)
+ * isStrictlySorted variableMonomials
+ * exists realMonomial variableMonomials
+ * is not empty qvarlist
+ *
+ * integer_eq := (= zmonomial zpolynomial)
+ * where
+ * let allMonomials = (cons zmonomial (monomialList zpolynomial))
+ * let variableMonomials = (drop constantMonomial allMonomials)
+ * not (constantMonomial zmonomial)
+ * (forall integerMonomial allMonomials)
+ * isStrictlySorted variableMonomials
* the gcd of all numerators of coefficients is 1
+ * the denominator of all coefficients and the constant is 1
+ * the coefficient of monomial is positive
+ * the value of the coefficient of monomial is minimal in variableMonomials
*
* comparison := TRUE | FALSE
- * | rational_restricted_cmp | (not rational_restricted_cmp)
- * | integer_restricted_cmp | (not integer_restricted_cmp)
+ * | rational_cmp | (not rational_cmp)
+ * | rational_eq | (not rational_eq)
+ * | integer_cmp | (not integer_cmp)
+ * | integer_eq | (not integer_eq)
*
* Normal Form for terms := polynomial
* Normal Form for atoms := comparison
@@ -138,6 +159,15 @@ namespace arith {
* Section 3: Guard Conditions Misc.
*
*
+ * variable_order x y =
+ * if (meta_kind_variable x) and (meta_kind_variable y)
+ * then node_order x y
+ * else if (meta_kind_variable x)
+ * then false
+ * else if (meta_kind_variable y)
+ * then true
+ * else node_order x y
+ *
* var_list_len vl =
* match vl with
* variable -> 1
@@ -214,7 +244,27 @@ public:
return getNode().getType().isInteger();
}
- bool operator<(const Variable& v) const { return getNode() < v.getNode();}
+ bool isMetaKindVariable() const {
+ return getNode().getMetaKind() == kind::metakind::VARIABLE;
+ }
+
+ bool operator<(const Variable& v) const {
+ bool thisIsVariable = isMetaKindVariable();
+ bool vIsVariable = v.isMetaKindVariable();
+
+ if(thisIsVariable == vIsVariable){
+ bool thisIsInteger = isIntegral();
+ bool vIsInteger = v.isIntegral();
+ if(thisIsInteger == vIsInteger){
+ return getNode() < v.getNode();
+ }else{
+ return thisIsInteger && !vIsInteger;
+ }
+ }else{
+ return thisIsVariable && !vIsVariable;
+ }
+ }
+
bool operator==(const Variable& v) const { return getNode() == v.getNode();}
};/* class Variable */
@@ -240,6 +290,14 @@ public:
return Constant(mkRationalNode(rat));
}
+ static Constant mkZero() {
+ return mkConstant(Rational(0));
+ }
+
+ static Constant mkOne() {
+ return mkConstant(Rational(1));
+ }
+
const Rational& getValue() const {
return getNode().getConst<Rational>();
}
@@ -254,6 +312,10 @@ public:
bool isOne() const { return getValue() == 1; }
+ Constant operator*(const Rational& other) const {
+ return mkConstant(getValue() * other);
+ }
+
Constant operator*(const Constant& other) const {
return mkConstant(getValue() * other.getValue());
}
@@ -572,9 +634,18 @@ public:
return coefficientIsOne() || constant.getValue() == -1;
}
+ bool constantIsPositive() const {
+ return getConstant().isPositive();
+ }
+
+ Monomial operator*(const Rational& q) const;
Monomial operator*(const Constant& c) const;
Monomial operator*(const Monomial& mono) const;
+ Monomial operator-() const{
+ return (*this) * Rational(-1);
+ }
+
int cmp(const Monomial& mono) const {
return getVarList().cmp(mono.getVarList());
@@ -636,6 +707,8 @@ public:
};/* class Monomial */
+class SumPair;
+class Comparison;;
class Polynomial : public NodeWrapper {
private:
@@ -795,6 +868,9 @@ public:
return mkPolynomial(subrange);
}
+ Monomial minimumVariableMonomial() const;
+ bool variableMonomialAreStrictlyGreater(const Monomial& m) const;
+
void printList() const {
if(Debug.isOn("normal-form")){
Debug("normal-form") << "start list" << std::endl;
@@ -834,6 +910,12 @@ public:
*/
Monomial selectAbsMinimum() const;
+ /** Returns true if the absolute value of the head coefficient is one. */
+ bool leadingCoefficientIsAbsOne() const;
+ bool leadingCoefficientIsPositive() const;
+ bool denominatorLCMIsOne() const;
+ bool numeratorGCDIsOne() const;
+
/**
* Returns the Least Common Multiple of the denominators of the coefficients
* of the monomials.
@@ -841,6 +923,12 @@ public:
Integer denominatorLCM() const;
/**
+ * Returns the GCD of the numerators of the monomials.
+ * Requires this to be an isIntegral() polynomial.
+ */
+ Integer numeratorGCD() const;
+
+ /**
* Returns the GCD of the coefficients of the monomials.
* Requires this to be an isIntegral() polynomial.
*/
@@ -856,7 +944,11 @@ public:
Polynomial operator+(const Polynomial& vl) const;
Polynomial operator-(const Polynomial& vl) const;
+ Polynomial operator-() const{
+ return (*this) * Rational(-1);
+ }
+ Polynomial operator*(const Rational& q) const;
Polynomial operator*(const Constant& c) const;
Polynomial operator*(const Monomial& mono) const;
@@ -905,168 +997,31 @@ public:
return 1;
}
}
-};/* class Polynomial */
-
-
-class Comparison : public NodeWrapper {
-private:
- Kind oper;
- Polynomial left;
- Constant right;
-
- static Node toNode(Kind k, const Polynomial& l, const Constant& r);
-
- Comparison(TNode n, Kind k, const Polynomial& l, const Constant& r):
- NodeWrapper(n), oper(k), left(l), right(r)
- { }
-
- /**
- * Possibly simplify a comparison with a pseudoboolean-typed LHS. k
- * is one of LT, LEQ, EQUAL, GEQ, GT, and left must be PB-typed. If
- * possible, "left k right" is fully evaluated, "true" is returned,
- * and the result of the evaluation is returned in "result". If no
- * evaluation is possible, false is returned and "result" is
- * untouched.
- *
- * For example, pbComparison(kind::EQUAL, "x", 0.5, result) returns
- * true, and updates "result" to false, since pseudoboolean variable
- * "x" can never equal 0.5. pbComparison(kind::GEQ, "x", 1, result)
- * returns false, since "x" can be >= 1, but could also be less.
- */
- static bool pbComparison(Kind k, TNode left, const Rational& right, bool& result);
- Kind getKind() const { return oper; }
-
-public:
- Comparison(bool val) :
- NodeWrapper(NodeManager::currentNM()->mkConst(val)),
- oper(kind::CONST_BOOLEAN),
- left(Polynomial::mkZero()),
- right(Constant::mkConstant(0))
- { }
-
- Comparison(Kind k, const Polynomial& l, const Constant& r):
- NodeWrapper(toNode(k, l, r)), oper(k), left(l), right(r)
- {
- Assert(isRelationOperator(oper));
- Assert(!left.containsConstant());
- Assert(left.getHead().getConstant().isOne());
- }
-
- static Comparison mkComparison(Kind k, const Polynomial& left, const Constant& right);
-
- /**
- * Returns the left hand side of the comparison.
- * This is a polynomial that always contains all of the variables.
- */
- const Polynomial& getLeft() const { return left; }
-
- /**
- * Returns the right hand constatn of the comparison.
- * If in normal form, this is the only constant term.
- */
- const Constant& getRight() const { return right; }
-
- /** Returns true if the comparison is a boolean constant. */
- bool isBoolean() const {
- return (oper == kind::CONST_BOOLEAN);
- }
-
- /** Returns true if all of the variables are integers. */
- bool allIntegralVariables() const {
- return getLeft().allIntegralVariables();
+ const Rational& asConstant() const{
+ Assert(isConstant());
+ return getNode().getConst<Rational>();
+ //return getHead().getConstant().getValue();
}
- /**
- * Returns true if the comparison is either a boolean term,
- * in integer normal form or mixed normal form.
- */
- bool isNormalForm() const {
- if(isBoolean()) {
- return true;
- } else if(allIntegralVariables()) {
- return isIntegerNormalForm();
- } else{
- return isMixedNormalForm();
+ bool isVarList() const {
+ if(singleton()){
+ return VarList::isMember(getNode());
+ }else{
+ return false;
}
}
-private:
- /** Normal form check if at least one variable is real. */
- bool isMixedNormalForm() const;
-
- /** Normal form check is all variables are real.*/
- bool isIntegerNormalForm() const;
-
-public:
- /**
- * Returns true if the left hand side is the sum of a non-zero constant
- * and a polynomial.*/
- bool constantInLefthand() const;
-
- /**
- * Returns a polynomial that is equivalent to the original but does not contain
- * a constant in the top level sum on the left hand side.
- */
- Comparison cancelLefthandConstant() const;
-
-
- /** Returns true if the polynomial is a constant. */
- bool isConstant() const;
-
- /** Reduces a constant comparison to a boolean comaprison.*/
- Comparison evaluateConstant() const;
-
-
- /**
- * Returns true if all of the variables are integers, the coefficients are integers,
- * and the right hand coefficient is an integer.
- */
- bool isIntegral() const;
-
- /**
- * Returns the Least Common Multiple of the monomials
- * on the lefthand side and the constant on the right.
- */
- Integer denominatorLCM() const;
-
- /** Multiplies the comparison by the denominatorLCM(). */
- Comparison multiplyByDenominatorLCM() const;
-
- /** If the leading coefficient is negative, multiply by -1. */
- Comparison normalizeLeadingCoefficientPositive() const;
-
- /** Divides the Comaprison by the gcd of the lefthand.*/
- Comparison divideByLefthandGCD() const;
-
- /** Divides the Comparison by the leading coefficient. */
- Comparison divideByLeadingCoefficient() const;
-
- /**
- * If the left hand is integral and the right hand is not,
- * the comparison is tightened to the nearest integer.
- */
- Comparison tightenIntegralConstraint() const;
-
- Comparison addConstant(const Constant& constant) const;
-
- /* Multiply a non-boolean comparison by a constant term. */
- Comparison multiplyConstant(const Constant& constant) const;
-
- static Comparison parseNormalForm(TNode n);
-
- /* Returns a logically equivalent comparison in normal form. */
- static Comparison normalize(Comparison c);
+ VarList asVarList() const {
+ Assert(isVarList());
+ return getHead().getVarList();
+ }
- /** Makes a comparison that is in normal form. */
- static Comparison mkNormalComparison(Kind k, const Polynomial& left, const Constant& right);
+ friend class SumPair;
+ friend class Comparison;;
- inline static bool isNormalAtom(TNode n){
- Comparison parse = Comparison::parseNormalForm(n);
- return parse.isNormalForm();
- }
+};/* class Polynomial */
-};/* class Comparison */
/**
* SumPair is a utility class that extends polynomials for use in computations.
@@ -1147,6 +1102,8 @@ public:
return (*this) + (other * Constant::mkConstant(-1));
}
+ static SumPair mkSumPair(const Polynomial& p);
+
static SumPair mkSumPair(const Variable& var){
return SumPair(Polynomial::mkPolynomial(var));
}
@@ -1187,12 +1144,183 @@ public:
static Node computeQR(const SumPair& sp, const Integer& div);
+};/* class SumPair */
+
+/* class OrderedPolynomialPair { */
+/* private: */
+/* Polynomial d_first; */
+/* Polynomial d_second; */
+/* public: */
+/* OrderedPolynomialPair(const Polynomial& f, const Polynomial& s) */
+/* : d_first(f), */
+/* d_second(s) */
+/* {} */
+
+/* /\** Returns the first part of the pair. *\/ */
+/* const Polynomial& getFirst() const { */
+/* return d_first; */
+/* } */
+
+/* /\** Returns the second part of the pair. *\/ */
+/* const Polynomial& getSecond() const { */
+/* return d_second; */
+/* } */
+
+/* OrderedPolynomialPair operator*(const Constant& c) const; */
+/* OrderedPolynomialPair operator+(const Polynomial& p) const; */
+
+/* /\** Returns true if both of the polynomials are constant. *\/ */
+/* bool isConstant() const; */
+
+/* /\** */
+/* * Evaluates an isConstant() ordered pair as if */
+/* * (k getFirst() getRight()) */
+/* *\/ */
+/* bool evaluateConstant(Kind k) const; */
+
+/* /\** */
+/* * Returns the Least Common Multiple of the monomials */
+/* * on the lefthand side and the constant on the right. */
+/* *\/ */
+/* Integer denominatorLCM() const; */
+
+/* /\** Constructs a SumPair. *\/ */
+/* SumPair toSumPair() const; */
+
+
+/* OrderedPolynomialPair divideByGCD() const; */
+/* OrderedPolynomialPair multiplyConstant(const Constant& c) const; */
+
+/* /\** */
+/* * Returns true if all of the variables are integers, */
+/* * and the coefficients are integers. */
+/* *\/ */
+/* bool isIntegral() const; */
+
+/* /\** Returns true if all of the variables are integers. *\/ */
+/* bool allIntegralVariables() const { */
+/* return getFirst().allIntegralVariables() && getSecond().allIntegralVariables(); */
+/* } */
+/* }; */
+
+class Comparison : public NodeWrapper {
+private:
+
+ static Node toNode(Kind k, const Polynomial& l, const Constant& c);
+ static Node toNode(Kind k, const Polynomial& l, const Polynomial& r);
+
+ Comparison(TNode n);
+
+ /**
+ * Creates a node in normal form equivalent to (= l 0).
+ * All variables in l are integral.
+ */
+ static Node mkIntEquality(const Polynomial& l);
+
+ /**
+ * Creates a comparison equivalent to (k l 0).
+ * k is either GT or GEQ.
+ * All variables in l are integral.
+ */
+ static Node mkIntInequality(Kind k, const Polynomial& l);
- static SumPair comparisonToSumPair(const Comparison& cmp){
- return SumPair(cmp.getLeft(), - cmp.getRight());
+ /**
+ * Creates a node equivalent to (= l 0).
+ * It is not the case that all variables in l are integral.
+ */
+ static Node mkRatEquality(const Polynomial& l);
+
+ /**
+ * Creates a comparison equivalent to (k l 0).
+ * k is either GT or GEQ.
+ * It is not the case that all variables in l are integral.
+ */
+ static Node mkRatInequality(Kind k, const Polynomial& l);
+
+public:
+
+ Comparison(bool val) :
+ NodeWrapper(NodeManager::currentNM()->mkConst(val))
+ { }
+
+ /**
+ * Given a literal to TheoryArith return a single kind to
+ * to indicate its underlying structure.
+ * The function returns the following in each case:
+ * - (K left right) -> K where is either EQUAL, GT, or GEQ
+ * - (CONST_BOOLEAN b) -> CONST_BOOLEAN
+ * - (NOT (EQUAL left right)) -> DISTINCT
+ * - (NOT (GT left right)) -> LEQ
+ * - (NOT (GEQ left right)) -> LT
+ * If none of these match, it returns UNDEFINED_KIND.
+ */
+ static Kind comparisonKind(TNode literal);
+
+ Kind comparisonKind() const { return comparisonKind(getNode()); }
+
+ static Comparison mkComparison(Kind k, const Polynomial& l, const Polynomial& r);
+
+ /** Returns true if the comparison is a boolean constant. */
+ bool isBoolean() const;
+
+ /**
+ * Returns true if the comparison is either a boolean term,
+ * in integer normal form or mixed normal form.
+ */
+ bool isNormalForm() const;
+
+private:
+ bool isNormalGT() const;
+ bool isNormalGEQ() const;
+
+ bool isNormalLT() const;
+ bool isNormalLEQ() const;
+
+ bool isNormalEquality() const;
+ bool isNormalDistinct() const;
+ bool isNormalEqualityOrDisequality() const;
+
+ bool allIntegralVariables() const {
+ return getLeft().allIntegralVariables() && getRight().allIntegralVariables();
}
+ bool rightIsConstant() const;
-};/* class SumPair */
+public:
+ Polynomial getLeft() const;
+ Polynomial getRight() const;
+
+ /* /\** Normal form check if at least one variable is real. *\/ */
+ /* bool isMixedCompareNormalForm() const; */
+
+ /* /\** Normal form check if at least one variable is real. *\/ */
+ /* bool isMixedEqualsNormalForm() const; */
+
+ /* /\** Normal form check is all variables are integer.*\/ */
+ /* bool isIntegerCompareNormalForm() const; */
+
+ /* /\** Normal form check is all variables are integer.*\/ */
+ /* bool isIntegerEqualsNormalForm() const; */
+
+
+ /**
+ * Returns true if all of the variables are integers, the coefficients are integers,
+ * and the right hand coefficient is an integer.
+ */
+ bool debugIsIntegral() const;
+
+ static Comparison parseNormalForm(TNode n);
+
+ inline static bool isNormalAtom(TNode n){
+ Comparison parse = Comparison::parseNormalForm(n);
+ return parse.isNormalForm();
+ }
+
+ SumPair toSumPair() const;
+
+ Polynomial normalizedVariablePart() const;
+ DeltaRational normalizedDeltaRational() const;
+
+};/* class Comparison */
}/* CVC4::theory::arith namespace */
}/* CVC4::theory namespace */
diff --git a/src/theory/arith/ordered_set.h b/src/theory/arith/ordered_set.h
deleted file mode 100644
index 8887daa8d..000000000
--- a/src/theory/arith/ordered_set.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/********************* */
-/*! \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 "cvc4_private.h"
-
-#ifndef __CVC4__THEORY__ARITH__ORDERED_SET_H
-#define __CVC4__THEORY__ARITH__ORDERED_SET_H
-
-#include <map>
-#include <set>
-#include "expr/kind.h"
-#include "expr/node.h"
-#include "util/Assert.h"
-#include "theory/arith/arith_utilities.h"
-
-
-namespace CVC4 {
-namespace theory {
-namespace arith {
-
-inline const Rational& rightHandRational(TNode ineq){
- Assert(ineq.getKind() == kind::LEQ
- || ineq.getKind() == kind::GEQ
- || ineq.getKind() == kind::EQUAL);
- TNode righthand = ineq[1];
- Assert(righthand.getKind() == kind::CONST_RATIONAL);
- return righthand.getConst<Rational>();
-}
-
-class BoundValueEntry {
-private:
- const Rational& value;
- TNode d_leq, d_geq;
-
- BoundValueEntry(const Rational& v, TNode l, TNode g):
- value(v),
- d_leq(l),
- d_geq(g)
- {}
-
-public:
- Node getLeq() const{
- Assert(hasLeq());
- return d_leq;
- }
- Node getGeq() const{
- Assert(hasGeq());
- return d_geq;
- }
-
- static BoundValueEntry mkFromLeq(TNode leq){
- Assert(leq.getKind() == kind::LEQ);
- return BoundValueEntry(rightHandRational(leq), leq, TNode::null());
- }
-
- static BoundValueEntry mkFromGeq(TNode geq){
- Assert(geq.getKind() == kind::GEQ);
- return BoundValueEntry(rightHandRational(geq), TNode::null(), geq);
- }
-
- void addLeq(TNode leq){
- Assert(leq.getKind() == kind::LEQ);
- Assert(rightHandRational(leq) == getValue());
- // [MGD] With context-dependent pre-registration, we could get the
- // same one twice
- Assert(!hasLeq() || d_leq == leq);
- d_leq = leq;
- }
-
- void addGeq(TNode geq){
- Assert(geq.getKind() == kind::GEQ);
- Assert(rightHandRational(geq) == getValue());
- // [MGD] With context-dependent pre-registration, we could get the
- // same one twice
- Assert(!hasGeq() || d_geq == geq);
- d_geq = geq;
- }
-
- bool hasGeq() const { return d_geq != TNode::null(); }
- bool hasLeq() const { return d_leq != TNode::null(); }
-
-
- const Rational& getValue() const{
- return value;
- }
-
- bool operator<(const BoundValueEntry& other){
- return value < other.value;
- }
-};
-
-typedef std::map<Rational, BoundValueEntry> BoundValueSet;
-
-typedef std::set<TNode, RightHandRationalLT> EqualValueSet;
-
-}/* CVC4::theory::arith namespace */
-}/* CVC4::theory namespace */
-}/* CVC4 namespace */
-
-#endif /* __CVC4__THEORY__ARITH__ORDERED_SET_H */
diff --git a/src/theory/arith/partial_model.cpp b/src/theory/arith/partial_model.cpp
index 65b0083d9..32c9f6adc 100644
--- a/src/theory/arith/partial_model.cpp
+++ b/src/theory/arith/partial_model.cpp
@@ -20,6 +20,7 @@
#include "theory/arith/partial_model.h"
#include "util/output.h"
+#include "theory/arith/constraint.h"
using namespace std;
@@ -27,62 +28,26 @@ namespace CVC4 {
namespace theory {
namespace arith {
-
-
-bool ArithPartialModel::boundsAreEqual(ArithVar x){
+ArithPartialModel::ArithPartialModel(context::Context* c)
+ : d_mapSize(0),
+ d_hasSafeAssignment(),
+ d_assignment(),
+ d_safeAssignment(),
+ d_ubc(c),
+ d_lbc(c),
+ d_deltaIsSafe(false),
+ d_delta(-1,1),
+ d_history()
+{ }
+
+bool ArithPartialModel::boundsAreEqual(ArithVar x) const{
if(hasLowerBound(x) && hasUpperBound(x)){
- return d_upperBound[x] == d_lowerBound[x];
+ return getUpperBound(x) == getLowerBound(x);
}else{
return false;
}
}
-void ArithPartialModel::zeroDifferenceDetected(ArithVar x){
- Assert(d_dm.isDifferenceSlack(x));
- Assert(upperBoundIsZero(x));
- Assert(lowerBoundIsZero(x));
-
- Node lb = getLowerConstraint(x);
- Node ub = getUpperConstraint(x);
- Node reason = lb != ub ? lb.andNode(ub) : lb;
- d_dm.differenceIsZero(x, reason);
-}
-
-void ArithPartialModel::setUpperBound(ArithVar x, const DeltaRational& r){
- d_deltaIsSafe = false;
-
- Debug("partial_model") << "setUpperBound(" << x << "," << r << ")" << endl;
- d_hasHadABound[x] = true;
- d_upperBound.set(x,r);
-
- if(d_dm.isDifferenceSlack(x)){
- int sgn = r.sgn();
- if(sgn < 0){
- d_dm.differenceCannotBeZero(x, getUpperConstraint(x));
- }else if(sgn == 0 && lowerBoundIsZero(x)){
- zeroDifferenceDetected(x);
- }
- }
-}
-
-void ArithPartialModel::setLowerBound(ArithVar x, const DeltaRational& r){
- d_deltaIsSafe = false;
-
- Debug("partial_model") << "setLowerBound(" << x << "," << r << ")" << endl;
- d_hasHadABound[x] = true;
- d_lowerBound.set(x,r);
-
-
- if(d_dm.isDifferenceSlack(x)){
- int sgn = r.sgn();
- if(sgn > 0){
- d_dm.differenceCannotBeZero(x, getLowerConstraint(x));
- }else if(sgn == 0 && upperBoundIsZero(x)){
- zeroDifferenceDetected(x);
- }
- }
-}
-
void ArithPartialModel::setAssignment(ArithVar x, const DeltaRational& r){
Debug("partial_model") << "pm: updating the assignment to" << x
<< " now " << r <<endl;
@@ -114,14 +79,12 @@ void ArithPartialModel::setAssignment(ArithVar x, const DeltaRational& safe, con
}
bool ArithPartialModel::equalSizes(){
- return d_mapSize == d_hasHadABound.size() &&
+ return
d_mapSize == d_hasSafeAssignment.size() &&
d_mapSize == d_assignment.size() &&
d_mapSize == d_safeAssignment.size() &&
- d_mapSize == d_upperBound.size() &&
- d_mapSize == d_lowerBound.size() &&
- d_mapSize == d_upperConstraint.size() &&
- d_mapSize == d_lowerConstraint.size();
+ d_mapSize == d_ubc.size() &&
+ d_mapSize == d_lbc.size();
}
void ArithPartialModel::initialize(ArithVar x, const DeltaRational& r){
@@ -129,33 +92,27 @@ void ArithPartialModel::initialize(ArithVar x, const DeltaRational& r){
Assert(equalSizes());
++d_mapSize;
-
- d_hasHadABound.push_back( false );
-
d_hasSafeAssignment.push_back( false );
d_assignment.push_back( r );
d_safeAssignment.push_back( DeltaRational(0) );
- d_upperBound.push_back( DeltaRational(0) );
- d_lowerBound.push_back( DeltaRational(0) );
-
- d_upperConstraint.push_back( TNode::null() );
- d_lowerConstraint.push_back( TNode::null() );
+ d_ubc.push_back(NullConstraint);
+ d_lbc.push_back(NullConstraint);
}
/** Must know that the bound exists both calling this! */
-const DeltaRational& ArithPartialModel::getUpperBound(ArithVar x) {
+const DeltaRational& ArithPartialModel::getUpperBound(ArithVar x) const {
Assert(inMaps(x));
Assert(hasUpperBound(x));
- return d_upperBound[x];
+ return getUpperBoundConstraint(x)->getValue();
}
-const DeltaRational& ArithPartialModel::getLowerBound(ArithVar x) {
+const DeltaRational& ArithPartialModel::getLowerBound(ArithVar x) const {
Assert(inMaps(x));
Assert(hasLowerBound(x));
- return d_lowerBound[x];
+ return getLowerBoundConstraint(x)->getValue();
}
const DeltaRational& ArithPartialModel::getSafeAssignment(ArithVar x) const{
@@ -182,144 +139,93 @@ const DeltaRational& ArithPartialModel::getAssignment(ArithVar x) const{
}
-
-void ArithPartialModel::setLowerConstraint(ArithVar x, TNode constraint){
- Debug("partial_model") << "setLowerConstraint("
- << x << ":" << constraint << ")" << endl;
+void ArithPartialModel::setLowerBoundConstraint(Constraint c){
+ AssertArgument(c != NullConstraint, "Cannot set a lower bound to NullConstraint.");
+ AssertArgument(c->isEquality() || c->isLowerBound(),
+ "Constraint type must be set to an equality or UpperBound.");
+ ArithVar x = c->getVariable();
+ Debug("partial_model") << "setLowerBoundConstraint(" << x << ":" << c << ")" << endl;
Assert(inMaps(x));
- d_lowerConstraint.set(x,constraint);
+ Assert(greaterThanLowerBound(x, c->getValue()));
+ d_lbc.set(x, c);
}
-void ArithPartialModel::setUpperConstraint(ArithVar x, TNode constraint){
- Debug("partial_model") << "setUpperConstraint("
- << x << ":" << constraint << ")" << endl;
- Assert(inMaps(x));
- d_upperConstraint.set(x, constraint);
-}
+void ArithPartialModel::setUpperBoundConstraint(Constraint c){
+ AssertArgument(c != NullConstraint, "Cannot set a upper bound to NullConstraint.");
+ AssertArgument(c->isEquality() || c->isUpperBound(),
+ "Constraint type must be set to an equality or UpperBound.");
-TNode ArithPartialModel::getLowerConstraint(ArithVar x){
+ ArithVar x = c->getVariable();
+ Debug("partial_model") << "setUpperBoundConstraint(" << x << ":" << c << ")" << endl;
Assert(inMaps(x));
- Assert(hasLowerBound(x));
- return d_lowerConstraint[x];
-}
+ Assert(lessThanUpperBound(x, c->getValue()));
-TNode ArithPartialModel::getUpperConstraint(ArithVar x){
- Assert(inMaps(x));
- Assert(hasUpperBound(x));
- return d_upperConstraint[x];
+ d_ubc.set(x, c);
}
-int ArithPartialModel::cmpToLowerBound(ArithVar x, const DeltaRational& c){
+int ArithPartialModel::cmpToLowerBound(ArithVar x, const DeltaRational& c) const{
if(!hasLowerBound(x)){
// l = -\intfy
// ? c < -\infty |- _|_
return 1;
}else{
- return c.cmp(d_lowerBound[x]);
+ return c.cmp(getLowerBound(x));
}
}
-int ArithPartialModel::cmpToUpperBound(ArithVar x, const DeltaRational& c){
+int ArithPartialModel::cmpToUpperBound(ArithVar x, const DeltaRational& c) const{
if(!hasUpperBound(x)){
//u = \intfy
// ? c > \infty |- _|_
return -1;
}else{
- return c.cmp(d_upperBound[x]);
+ return c.cmp(getUpperBound(x));
}
}
-// bool ArithPartialModel::belowLowerBound(ArithVar x, const DeltaRational& c, bool strict){
-// if(!hasLowerBound(x)){
-// // l = -\intfy
-// // ? c < -\infty |- _|_
-// return false;
-// }
-// if(strict){
-// return c < d_lowerBound[x];
-// }else{
-// return c <= d_lowerBound[x];
-// }
-// }
-
-// bool ArithPartialModel::aboveUpperBound(ArithVar x, const DeltaRational& c, bool strict){
-// if(!hasUpperBound(x)){
-// // u = \intfy
-// // ? c > \infty |- _|_
-// return false;
-// }
-// if(strict){
-// return c > d_upperBound[x];
-// }else{
-// return c >= d_upperBound[x];
-// }
-// }
-
bool ArithPartialModel::equalsLowerBound(ArithVar x, const DeltaRational& c){
if(!hasLowerBound(x)){
return false;
}else{
- return c == d_lowerBound[x];
+ return c == getLowerBound(x);
}
}
bool ArithPartialModel::equalsUpperBound(ArithVar x, const DeltaRational& c){
if(!hasUpperBound(x)){
return false;
}else{
- return c == d_upperBound[x];
+ return c == getUpperBound(x);
}
}
-bool ArithPartialModel::hasEitherBound(ArithVar x){
+bool ArithPartialModel::hasEitherBound(ArithVar x) const{
return hasLowerBound(x) || hasUpperBound(x);
}
-bool ArithPartialModel::strictlyBelowUpperBound(ArithVar x){
+bool ArithPartialModel::strictlyBelowUpperBound(ArithVar x) const{
Assert(inMaps(x));
if(!hasUpperBound(x)){ // u = \infty
return true;
+ }else{
+ return d_assignment[x] < getUpperBound(x);
}
- return d_assignment[x] < d_upperBound[x];
}
-bool ArithPartialModel::strictlyAboveLowerBound(ArithVar x){
+bool ArithPartialModel::strictlyAboveLowerBound(ArithVar x) const{
Assert(inMaps(x));
if(!hasLowerBound(x)){ // l = -\infty
return true;
+ }else{
+ return getLowerBound(x) < d_assignment[x];
}
- return d_lowerBound[x] < d_assignment[x];
}
-// /**
-// * x <= u
-// * ? c < u
-// */
-// bool ArithPartialModel::strictlyBelowUpperBound(ArithVar x, const DeltaRational& c){
-// Assert(inMaps(x));
-// if(!hasUpperBound(x)){ // u = \infty
-// return true;
-// }
-// return c < d_upperBound[x];
-// }
-
-// /**
-// * x <= u
-// * ? c < u
-// */
-// bool ArithPartialModel::strictlyAboveLowerBound(ArithVar x, const DeltaRational& c){
-// Assert(inMaps(x));
-// if(!hasLowerBound(x)){ // l = -\infty
-// return true;
-// }
-// return d_lowerBound[x] < c;
-// }
-
-bool ArithPartialModel::assignmentIsConsistent(ArithVar x){
+bool ArithPartialModel::assignmentIsConsistent(ArithVar x) const{
const DeltaRational& beta = getAssignment(x);
//l_i <= beta(x_i) <= u_i
- return cmpToLowerBound(x,beta) >= 0 && cmpToUpperBound(x,beta) <= 0;
+ return greaterThanLowerBound(x,beta) && lessThanUpperBound(x,beta);
}
@@ -355,13 +261,13 @@ void ArithPartialModel::printModel(ArithVar x){
Debug("model") << "no lb ";
}else{
Debug("model") << getLowerBound(x) << " ";
- Debug("model") << getLowerConstraint(x) << " ";
+ Debug("model") << getLowerBoundConstraint(x) << " ";
}
if(!hasUpperBound(x)){
Debug("model") << "no ub ";
}else{
Debug("model") << getUpperBound(x) << " ";
- Debug("model") << getUpperConstraint(x) << " ";
+ Debug("model") << getUpperBoundConstraint(x) << " ";
}
}
diff --git a/src/theory/arith/partial_model.h b/src/theory/arith/partial_model.h
index 7e2211595..fc8423e36 100644
--- a/src/theory/arith/partial_model.h
+++ b/src/theory/arith/partial_model.h
@@ -19,16 +19,18 @@
#include "cvc4_private.h"
+#include "expr/node.h"
+
#include "context/context.h"
#include "context/cdvector.h"
+#include "context/cdo.h"
+
#include "theory/arith/arithvar.h"
#include "theory/arith/delta_rational.h"
-#include "expr/attribute.h"
-#include "expr/node.h"
+#include "theory/arith/constraint_forward.h"
-#include "theory/arith/difference_manager.h"
-#include <deque>
+#include <vector>
#ifndef __CVC4__THEORY__ARITH__PARTIAL_MODEL_H
#define __CVC4__THEORY__ARITH__PARTIAL_MODEL_H
@@ -41,19 +43,14 @@ class ArithPartialModel {
private:
unsigned d_mapSize;
- //Maps from ArithVar -> T
-
- std::vector<bool> d_hasHadABound;
+ //Maps from ArithVar -> T
std::vector<bool> d_hasSafeAssignment;
std::vector<DeltaRational> d_assignment;
std::vector<DeltaRational> d_safeAssignment;
- context::CDVector<DeltaRational> d_upperBound;
- context::CDVector<DeltaRational> d_lowerBound;
- context::CDVector<Node> d_upperConstraint;
- context::CDVector<Node> d_lowerConstraint;
-
+ context::CDVector<Constraint> d_ubc;
+ context::CDVector<Constraint> d_lbc;
bool d_deltaIsSafe;
Rational d_delta;
@@ -64,30 +61,20 @@ private:
typedef std::vector<ArithVar> HistoryList;
HistoryList d_history;
- DifferenceManager& d_dm;
public:
- ArithPartialModel(context::Context* c, DifferenceManager& dm):
- d_mapSize(0),
- d_hasHadABound(),
- d_hasSafeAssignment(),
- d_assignment(),
- d_safeAssignment(),
- d_upperBound(c),
- d_lowerBound(c),
- d_upperConstraint(c),
- d_lowerConstraint(c),
- d_deltaIsSafe(false),
- d_delta(-1,1),
- d_history(),
- d_dm(dm)
- { }
-
- void setLowerConstraint(ArithVar x, TNode constraint);
- void setUpperConstraint(ArithVar x, TNode constraint);
- TNode getLowerConstraint(ArithVar x);
- TNode getUpperConstraint(ArithVar x);
+ ArithPartialModel(context::Context* c);
+
+ void setLowerBoundConstraint(Constraint lb);
+ void setUpperBoundConstraint(Constraint ub);
+
+ inline Constraint getUpperBoundConstraint(ArithVar x) const{
+ return d_ubc[x];
+ }
+ inline Constraint getLowerBoundConstraint(ArithVar x) const{
+ return d_lbc[x];
+ }
/* Initializes a variable to a safe value.*/
@@ -112,14 +99,7 @@ public:
return hasUpperBound(x) && getUpperBound(x).sgn() == 0;
}
-private:
- void zeroDifferenceDetected(ArithVar x);
-
-public:
- bool boundsAreEqual(ArithVar x);
-
- void setUpperBound(ArithVar x, const DeltaRational& r);
- void setLowerBound(ArithVar x, const DeltaRational& r);
+ bool boundsAreEqual(ArithVar x) const;
/* Sets an unsafe variable assignment */
void setAssignment(ArithVar x, const DeltaRational& r);
@@ -127,8 +107,8 @@ public:
/** Must know that the bound exists before calling this! */
- const DeltaRational& getUpperBound(ArithVar x);
- const DeltaRational& getLowerBound(ArithVar x);
+ const DeltaRational& getUpperBound(ArithVar x) const;
+ const DeltaRational& getLowerBound(ArithVar x) const;
const DeltaRational& getAssignment(ArithVar x) const;
@@ -141,61 +121,60 @@ public:
* If lowerbound = - \infty:
* return 1
*/
- int cmpToLowerBound(ArithVar x, const DeltaRational& c);
+ int cmpToLowerBound(ArithVar x, const DeltaRational& c) const;
- inline bool strictlyLessThanLowerBound(ArithVar x, const DeltaRational& c){
+ inline bool strictlyLessThanLowerBound(ArithVar x, const DeltaRational& c) const{
return cmpToLowerBound(x, c) < 0;
}
- inline bool lessThanLowerBound(ArithVar x, const DeltaRational& c){
+ inline bool lessThanLowerBound(ArithVar x, const DeltaRational& c) const{
return cmpToLowerBound(x, c) <= 0;
}
- inline bool strictlyGreaterThanLowerBound(ArithVar x, const DeltaRational& c){
+ inline bool strictlyGreaterThanLowerBound(ArithVar x, const DeltaRational& c) const{
return cmpToLowerBound(x, c) > 0;
}
+ inline bool greaterThanLowerBound(ArithVar x, const DeltaRational& c) const{
+ return cmpToLowerBound(x, c) >= 0;
+ }
/**
* If upperbound < \infty:
* return getAssignment(x).cmp(getUpperBound(x))
* If upperbound = \infty:
* return -1
*/
- int cmpToUpperBound(ArithVar x, const DeltaRational& c);
+ int cmpToUpperBound(ArithVar x, const DeltaRational& c) const;
- inline bool strictlyLessThanUpperBound(ArithVar x, const DeltaRational& c){
+ inline bool strictlyLessThanUpperBound(ArithVar x, const DeltaRational& c) const{
return cmpToUpperBound(x, c) < 0;
}
- inline bool lessThanUpperBound(ArithVar x, const DeltaRational& c){
+ inline bool lessThanUpperBound(ArithVar x, const DeltaRational& c) const{
return cmpToUpperBound(x, c) <= 0;
}
- inline bool strictlyGreaterThanUpperBound(ArithVar x, const DeltaRational& c){
+ inline bool strictlyGreaterThanUpperBound(ArithVar x, const DeltaRational& c) const{
return cmpToUpperBound(x, c) > 0;
}
- inline bool greaterThanUpperBound(ArithVar x, const DeltaRational& c){
+ inline bool greaterThanUpperBound(ArithVar x, const DeltaRational& c) const{
return cmpToUpperBound(x, c) >= 0;
}
- bool strictlyBelowUpperBound(ArithVar x);
- bool strictlyAboveLowerBound(ArithVar x);
- bool assignmentIsConsistent(ArithVar x);
+ bool strictlyBelowUpperBound(ArithVar x) const;
+ bool strictlyAboveLowerBound(ArithVar x) const;
+ bool assignmentIsConsistent(ArithVar x) const;
void printModel(ArithVar x);
/** returns true iff x has both a lower and upper bound. */
- bool hasEitherBound(ArithVar x);
- inline bool hasLowerBound(ArithVar x){
- return !d_lowerConstraint[x].isNull();
+ bool hasEitherBound(ArithVar x) const;
+ inline bool hasLowerBound(ArithVar x) const{
+ return d_lbc[x] != NullConstraint;
}
- inline bool hasUpperBound(ArithVar x){
- return !d_upperConstraint[x].isNull();
- }
-
- bool hasEverHadABound(ArithVar var){
- return d_hasHadABound[var];
+ inline bool hasUpperBound(ArithVar x) const{
+ return d_ubc[x] != NullConstraint;
}
const Rational& getDelta(){
diff --git a/src/theory/arith/simplex.cpp b/src/theory/arith/simplex.cpp
index 7fce748dc..5837d4793 100644
--- a/src/theory/arith/simplex.cpp
+++ b/src/theory/arith/simplex.cpp
@@ -33,15 +33,13 @@ static const uint32_t NUM_CHECKS = 10;
static const bool CHECK_AFTER_PIVOT = true;
static const uint32_t VARORDER_CHECK_PERIOD = 200;
-SimplexDecisionProcedure::SimplexDecisionProcedure(ArithPropManager& propManager,
- LinearEqualityModule& linEq) :
+SimplexDecisionProcedure::SimplexDecisionProcedure(LinearEqualityModule& linEq, NodeCallBack& conflictChannel) :
d_linEq(linEq),
d_partialModel(d_linEq.getPartialModel()),
d_tableau(d_linEq.getTableau()),
d_queue(d_partialModel, d_tableau),
- d_propManager(propManager),
d_numVariables(0),
- d_delayedLemmas(),
+ d_conflictChannel(conflictChannel),
d_pivotsInRound(),
d_DELTA_ZERO(0,0)
{
@@ -77,7 +75,7 @@ SimplexDecisionProcedure::Statistics::Statistics():
d_weakeningSuccesses("theory::arith::weakening::success",0),
d_weakenings("theory::arith::weakening::total",0),
d_weakenTime("theory::arith::weakening::time"),
- d_delayedConflicts("theory::arith::delayedConflicts",0)
+ d_simplexConflicts("theory::arith::simplexConflicts",0)
{
StatisticsRegistry::registerStat(&d_statUpdateConflicts);
@@ -99,7 +97,7 @@ SimplexDecisionProcedure::Statistics::Statistics():
StatisticsRegistry::registerStat(&d_weakenings);
StatisticsRegistry::registerStat(&d_weakenTime);
- StatisticsRegistry::registerStat(&d_delayedConflicts);
+ StatisticsRegistry::registerStat(&d_simplexConflicts);
}
SimplexDecisionProcedure::Statistics::~Statistics(){
@@ -123,7 +121,7 @@ SimplexDecisionProcedure::Statistics::~Statistics(){
StatisticsRegistry::unregisterStat(&d_weakenings);
StatisticsRegistry::unregisterStat(&d_weakenTime);
- StatisticsRegistry::unregisterStat(&d_delayedConflicts);
+ StatisticsRegistry::unregisterStat(&d_simplexConflicts);
}
@@ -203,7 +201,7 @@ Node betterConflict(TNode x, TNode y){
else return y;
}
-Node SimplexDecisionProcedure::findConflictOnTheQueue(SearchPeriod type, bool returnFirst) {
+bool SimplexDecisionProcedure::findConflictOnTheQueue(SearchPeriod type) {
TimerStat::CodeTimer codeTimer(d_statistics.d_findConflictOnTheQueueTime);
switch(type){
@@ -215,7 +213,6 @@ Node SimplexDecisionProcedure::findConflictOnTheQueue(SearchPeriod type, bool re
}
bool success = false;
- Node firstConflict = Node::null();
ArithPriorityQueue::const_iterator i = d_queue.begin();
ArithPriorityQueue::const_iterator end = d_queue.end();
for(; i != end; ++i){
@@ -225,11 +222,7 @@ Node SimplexDecisionProcedure::findConflictOnTheQueue(SearchPeriod type, bool re
Node possibleConflict = checkBasicForConflict(x_i);
if(!possibleConflict.isNull()){
success = true;
- if(returnFirst && firstConflict.isNull()){
- firstConflict = possibleConflict;
- }else{
- delayConflictAsLemma(possibleConflict);
- }
+ reportConflict(possibleConflict);
}
}
}
@@ -242,13 +235,14 @@ Node SimplexDecisionProcedure::findConflictOnTheQueue(SearchPeriod type, bool re
case AfterVarOrderSearch: ++(d_statistics.d_successAfterVarOrderSearch); break;
}
}
- return firstConflict;
+ return success;
}
-Node SimplexDecisionProcedure::findModel(){
+bool SimplexDecisionProcedure::findModel(){
if(d_queue.empty()){
- return Node::null();
+ return false;
}
+ bool foundConflict = false;
static CVC4_THREADLOCAL(unsigned int) instance = 0;
instance = instance + 1;
@@ -256,45 +250,44 @@ Node SimplexDecisionProcedure::findModel(){
d_queue.transitionToDifferenceMode();
- Node possibleConflict = Node::null();
if(d_queue.size() > 1){
- possibleConflict = findConflictOnTheQueue(BeforeDiffSearch);
+ foundConflict = findConflictOnTheQueue(BeforeDiffSearch);
}
- if(possibleConflict.isNull()){
+ if(!foundConflict){
uint32_t numHueristicPivots = d_numVariables + 1;
uint32_t pivotsRemaining = numHueristicPivots;
uint32_t pivotsPerCheck = (numHueristicPivots/NUM_CHECKS) + (NUM_CHECKS-1);
while(!d_queue.empty() &&
- possibleConflict.isNull() &&
+ !foundConflict &&
pivotsRemaining > 0){
uint32_t pivotsToDo = min(pivotsPerCheck, pivotsRemaining);
- possibleConflict = searchForFeasibleSolution(pivotsToDo);
+ foundConflict = searchForFeasibleSolution(pivotsToDo);
pivotsRemaining -= pivotsToDo;
//Once every CHECK_PERIOD examine the entire queue for conflicts
- if(possibleConflict.isNull()){
- possibleConflict = findConflictOnTheQueue(DuringDiffSearch);
+ if(!foundConflict){
+ foundConflict = findConflictOnTheQueue(DuringDiffSearch);
}else{
- findConflictOnTheQueue(AfterDiffSearch, false);
+ findConflictOnTheQueue(AfterDiffSearch);
}
}
}
- if(!d_queue.empty() && possibleConflict.isNull()){
+ if(!d_queue.empty() && !foundConflict){
d_queue.transitionToVariableOrderMode();
- while(!d_queue.empty() && possibleConflict.isNull()){
- possibleConflict = searchForFeasibleSolution(VARORDER_CHECK_PERIOD);
+ while(!d_queue.empty() && !foundConflict){
+ foundConflict = searchForFeasibleSolution(VARORDER_CHECK_PERIOD);
//Once every CHECK_PERIOD examine the entire queue for conflicts
- if(possibleConflict.isNull()){
- possibleConflict = findConflictOnTheQueue(DuringVarOrderSearch);
- }else{
- findConflictOnTheQueue(AfterVarOrderSearch, false);
+ if(!foundConflict){
+ foundConflict = findConflictOnTheQueue(DuringVarOrderSearch);
+ } else{
+ findConflictOnTheQueue(AfterVarOrderSearch);
}
}
}
- Assert(!possibleConflict.isNull() || d_queue.empty());
+ Assert(foundConflict || d_queue.empty());
// Curiously the invariant that we always do a full check
// means that the assignment we can always empty these queues.
@@ -309,7 +302,7 @@ Node SimplexDecisionProcedure::findModel(){
Debug("arith::findModel") << "end findModel() " << instance << endl;
- return possibleConflict;
+ return foundConflict;
}
Node SimplexDecisionProcedure::checkBasicForConflict(ArithVar basic){
@@ -333,7 +326,7 @@ Node SimplexDecisionProcedure::checkBasicForConflict(ArithVar basic){
//corresponds to Check() in dM06
//template <SimplexDecisionProcedure::PreferenceFunction pf>
-Node SimplexDecisionProcedure::searchForFeasibleSolution(uint32_t remainingIterations){
+bool SimplexDecisionProcedure::searchForFeasibleSolution(uint32_t remainingIterations){
Debug("arith") << "searchForFeasibleSolution" << endl;
Assert(remainingIterations > 0);
@@ -344,7 +337,7 @@ Node SimplexDecisionProcedure::searchForFeasibleSolution(uint32_t remainingItera
Debug("arith::update::select") << "selectSmallestInconsistentVar()=" << x_i << endl;
if(x_i == ARITHVAR_SENTINEL){
Debug("arith_update") << "No inconsistent variables" << endl;
- return Node::null(); //sat
+ return false; //sat
}
--remainingIterations;
@@ -369,7 +362,9 @@ Node SimplexDecisionProcedure::searchForFeasibleSolution(uint32_t remainingItera
x_j = selectSlackUpperBound(x_i, pf);
if(x_j == ARITHVAR_SENTINEL ){
++(d_statistics.d_statUpdateConflicts);
- return generateConflictBelowLowerBound(x_i); //unsat
+ Node conflict = generateConflictBelowLowerBound(x_i); //unsat
+ reportConflict(conflict);
+ return true;
}
DeltaRational l_i = d_partialModel.getLowerBound(x_i);
d_linEq.pivotAndUpdate(x_i, x_j, l_i);
@@ -378,7 +373,9 @@ Node SimplexDecisionProcedure::searchForFeasibleSolution(uint32_t remainingItera
x_j = selectSlackLowerBound(x_i, pf);
if(x_j == ARITHVAR_SENTINEL ){
++(d_statistics.d_statUpdateConflicts);
- return generateConflictAboveUpperBound(x_i); //unsat
+ Node conflict = generateConflictAboveUpperBound(x_i); //unsat
+ reportConflict(conflict);
+ return true;
}
DeltaRational u_i = d_partialModel.getUpperBound(x_i);
d_linEq.pivotAndUpdate(x_i, x_j, u_i);
@@ -389,38 +386,50 @@ Node SimplexDecisionProcedure::searchForFeasibleSolution(uint32_t remainingItera
if(CHECK_AFTER_PIVOT){
Node possibleConflict = checkBasicForConflict(x_j);
if(!possibleConflict.isNull()){
- return possibleConflict;
+ reportConflict(possibleConflict);
+ return true; // unsat
}
}
}
Assert(remainingIterations == 0);
- return Node::null();
+ return false;
}
-TNode SimplexDecisionProcedure::weakestExplanation(bool aboveUpper, DeltaRational& surplus, ArithVar v, const Rational& coeff, bool& anyWeakening, ArithVar basic){
+Constraint SimplexDecisionProcedure::weakestExplanation(bool aboveUpper, DeltaRational& surplus, ArithVar v, const Rational& coeff, bool& anyWeakening, ArithVar basic){
int sgn = coeff.sgn();
bool ub = aboveUpper?(sgn < 0) : (sgn > 0);
- TNode exp = ub ?
- d_partialModel.getUpperConstraint(v) :
- d_partialModel.getLowerConstraint(v);
- DeltaRational bound = ub?
- d_partialModel.getUpperBound(v) :
- d_partialModel.getLowerBound(v);
+
+ Constraint c = ub ?
+ d_partialModel.getUpperBoundConstraint(v) :
+ d_partialModel.getLowerBoundConstraint(v);
+
+// #warning "revisit"
+// Node exp = ub ?
+// d_partialModel.explainUpperBound(v) :
+// d_partialModel.explainLowerBound(v);
bool weakened;
do{
+ const DeltaRational& bound = c->getValue();
+
weakened = false;
- Node weaker = ub?
- d_propManager.strictlyWeakerAssertedUpperBound(v, bound):
- d_propManager.strictlyWeakerAssertedLowerBound(v, bound);
+ Constraint weaker = ub?
+ c->getStrictlyWeakerUpperBound(true, true):
+ c->getStrictlyWeakerLowerBound(true, true);
+
+ // Node weaker = ub?
+ // d_propManager.strictlyWeakerAssertedUpperBound(v, bound):
+ // d_propManager.strictlyWeakerAssertedLowerBound(v, bound);
- if(!weaker.isNull()){
- DeltaRational weakerBound = asDeltaRational(weaker);
+ if(weaker != NullConstraint){
+ //if(!weaker.isNull()){
+ const DeltaRational& weakerBound = weaker->getValue();
+ //DeltaRational weakerBound = asDeltaRational(weaker);
DeltaRational diff = aboveUpper ? bound - weakerBound : weakerBound - bound;
//if var == basic,
@@ -438,24 +447,16 @@ TNode SimplexDecisionProcedure::weakestExplanation(bool aboveUpper, DeltaRationa
Debug("weak") << " basic: ";
}
Debug("weak") << " " << surplus << " "<< diff << endl
- << " " << bound << exp << endl
+ << " " << bound << c << endl
<< " " << weakerBound << weaker << endl;
- if(exp.getKind() == AND){
- Debug("weak") << "VICTORY" << endl;
- }
-
Assert(diff > d_DELTA_ZERO);
- exp = weaker;
- bound = weakerBound;
+ c = weaker;
}
}
}while(weakened);
- if(exp.getKind() == AND){
- Debug("weak") << "boo: " << exp << endl;
- }
- return exp;
+ return c;
}
Node SimplexDecisionProcedure::weakenConflict(bool aboveUpper, ArithVar basicVar){
@@ -479,7 +480,15 @@ Node SimplexDecisionProcedure::weakenConflict(bool aboveUpper, ArithVar basicVar
const TableauEntry& entry = *i;
ArithVar v = entry.getColVar();
const Rational& coeff = entry.getCoefficient();
- conflict << weakestExplanation(aboveUpper, surplus, v, coeff, anyWeakenings, basicVar);
+ bool weakening = false;
+ Constraint c = weakestExplanation(aboveUpper, surplus, v, coeff, weakening, basicVar);
+ Debug("weak") << "weak : " << weakening << " " << c->assertedToTheTheory()
+ << c << endl
+ << c->explainForConflict() << endl;
+ anyWeakenings = anyWeakenings || weakening;
+
+ Debug("weak") << "weak : " << c->explainForConflict() << endl;
+ c->explainForConflict(conflict);
}
++d_statistics.d_weakeningAttempts;
if(anyWeakenings){
diff --git a/src/theory/arith/simplex.h b/src/theory/arith/simplex.h
index 39c0bc20b..4e5ba3d9e 100644
--- a/src/theory/arith/simplex.h
+++ b/src/theory/arith/simplex.h
@@ -56,11 +56,11 @@
#include "theory/arith/delta_rational.h"
#include "theory/arith/tableau.h"
#include "theory/arith/partial_model.h"
-#include "theory/arith/arith_prop_manager.h"
#include "theory/arith/linear_equality.h"
-#include "util/options.h"
+#include "context/cdlist.h"
+#include "util/options.h"
#include "util/stats.h"
#include <queue>
@@ -91,13 +91,11 @@ private:
/** Contains a superset of the basic variables in violation of their bounds. */
ArithPriorityQueue d_queue;
- /** A link to the propagation manager. This is used to generate weaker conflicts. */
- ArithPropManager& d_propManager;
-
/** Number of variables in the system. This is used for tuning heuristics. */
ArithVar d_numVariables;
- std::queue<Node> d_delayedLemmas;
+ /** This is the call back channel for Simplex to report conflicts. */
+ NodeCallBack& d_conflictChannel;
/** Maps a variable to how many times they have been used as a pivot in the simplex search. */
ArithVarMultiset d_pivotsInRound;
@@ -106,8 +104,7 @@ private:
DeltaRational d_DELTA_ZERO;
public:
- SimplexDecisionProcedure(ArithPropManager& propManager,
- LinearEqualityModule& linEq);
+ SimplexDecisionProcedure(LinearEqualityModule& linEq, NodeCallBack& conflictChannel);
/**
* This must be called when the value of a basic variable may now voilate one
@@ -123,14 +120,15 @@ public:
* This is done by a simplex search through the possible bases of the tableau.
*
* If all of the variables can be made consistent with their bounds
- * Node::null() is returned. Otherwise a minimized conflict is returned.
+ * false is returned. Otherwise true is returned, and at least 1 conflict
+ * was reported on the conflictCallback passed to the Module.
*
* Tableau pivoting is performed so variables may switch from being basic to
* nonbasic and vice versa.
*
* Corresponds to the "check()" procedure in [Cav06].
*/
- Node findModel();
+ bool findModel();
private:
@@ -158,6 +156,7 @@ private:
* during the VarOrder stage of findModel.
*/
static ArithVar minColLength(const SimplexDecisionProcedure& simp, ArithVar x, ArithVar y);
+
/**
* minBoundAndRowCount is a PreferenceFunction for preferring a variable
* without an asserted bound over variables with an asserted bound.
@@ -173,11 +172,11 @@ private:
private:
- Node searchForFeasibleSolution(uint32_t maxIterations);
+ bool searchForFeasibleSolution(uint32_t maxIterations);
enum SearchPeriod {BeforeDiffSearch, DuringDiffSearch, AfterDiffSearch, DuringVarOrderSearch, AfterVarOrderSearch};
- Node findConflictOnTheQueue(SearchPeriod period, bool returnFirst = true);
+ bool findConflictOnTheQueue(SearchPeriod period);
/**
@@ -217,29 +216,12 @@ private:
public:
void increaseMax() {d_numVariables++;}
- /** Returns true if the simplex procedure has more delayed lemmas in its queue.*/
- bool hasMoreLemmas() const {
- return !d_delayedLemmas.empty();
- }
- /** Returns the next delayed lemmas on the queue.*/
- Node popLemma(){
- Assert(hasMoreLemmas());
- Node lemma = d_delayedLemmas.front();
- d_delayedLemmas.pop();
- return lemma;
- }
-
private:
- /** Adds a lemma to the queue. */
- void pushLemma(Node lemma){
- d_delayedLemmas.push(lemma);
- ++(d_statistics.d_delayedConflicts);
- }
- /** Adds a conflict as a lemma to the queue. */
- void delayConflictAsLemma(Node conflict){
- Node negatedConflict = negateConjunctionAsClause(conflict);
- pushLemma(negatedConflict);
+ /** Reports a conflict to on the output channel. */
+ void reportConflict(Node conflict){
+ d_conflictChannel(conflict);
+ ++(d_statistics.d_simplexConflicts);
}
template <bool above>
@@ -259,7 +241,7 @@ private:
Node checkBasicForConflict(ArithVar b);
Node weakenConflict(bool aboveUpper, ArithVar basicVar);
- TNode weakestExplanation(bool aboveUpper, DeltaRational& surplus, ArithVar v, const Rational& coeff, bool& anyWeakening, ArithVar basic);
+ Constraint weakestExplanation(bool aboveUpper, DeltaRational& surplus, ArithVar v, const Rational& coeff, bool& anyWeakening, ArithVar basic);
@@ -280,7 +262,7 @@ private:
TimerStat d_weakenTime;
- IntStat d_delayedConflicts;
+ IntStat d_simplexConflicts;
Statistics();
~Statistics();
diff --git a/src/theory/arith/tableau.cpp b/src/theory/arith/tableau.cpp
index ef3206650..567d8215e 100644
--- a/src/theory/arith/tableau.cpp
+++ b/src/theory/arith/tableau.cpp
@@ -78,7 +78,6 @@ void Tableau::pivot(ArithVar oldBasic, ArithVar newBasic){
Assert(!isBasic(newBasic));
Assert(mergeBufferIsEmpty());
- //cout << oldBasic << "," << newBasic << endl;
Debug("tableau") << "Tableau::pivot(" << oldBasic <<", " << newBasic <<")" << endl;
rowPivot(oldBasic, newBasic);
diff --git a/src/theory/arith/theory_arith.cpp b/src/theory/arith/theory_arith.cpp
index 3b29cbcd1..11a1a4a4a 100644
--- a/src/theory/arith/theory_arith.cpp
+++ b/src/theory/arith/theory_arith.cpp
@@ -23,14 +23,13 @@
#include "expr/node_builder.h"
#include "theory/valuation.h"
+#include "theory/rewriter.h"
#include "util/rational.h"
#include "util/integer.h"
#include "util/boolean_simplification.h"
-#include "theory/rewriter.h"
-
#include "theory/arith/arith_utilities.h"
#include "theory/arith/delta_rational.h"
#include "theory/arith/partial_model.h"
@@ -38,11 +37,9 @@
#include "theory/arith/arithvar_set.h"
#include "theory/arith/arith_rewriter.h"
-#include "theory/arith/atom_database.h"
-
+#include "theory/arith/constraint.h"
#include "theory/arith/theory_arith.h"
#include "theory/arith/normal_form.h"
-#include "theory/arith/arith_prop_manager.h"
#include <stdint.h>
@@ -59,12 +56,12 @@ const uint32_t RESET_START = 2;
TheoryArith::TheoryArith(context::Context* c, context::UserContext* u, OutputChannel& out, Valuation valuation) :
Theory(THEORY_ARITH, c, u, out, valuation),
d_hasDoneWorkSinceCut(false),
- d_atomsInContext(c),
d_learner(d_pbSubstitutions),
+ d_setupLiteralCallback(this),
d_nextIntegerCheckVar(0),
d_constantIntegerVariables(c),
- d_diseq(c),
- d_partialModel(c, d_differenceManager),
+ d_diseqQueue(c, false),
+ d_partialModel(c),
d_tableau(),
d_linEq(d_partialModel, d_tableau, d_basicVarModelUpdateCallBack),
d_diosolver(c),
@@ -73,10 +70,11 @@ TheoryArith::TheoryArith(context::Context* c, context::UserContext* u, OutputCha
d_rowHasBeenAdded(false),
d_tableauResetDensity(1.6),
d_tableauResetPeriod(10),
- d_atomDatabase(c, out),
- d_propManager(c, d_arithvarNodeMap, d_atomDatabase, valuation),
- d_differenceManager(c, d_propManager),
- d_simplex(d_propManager, d_linEq),
+ d_conflicts(c),
+ d_conflictCallBack(d_conflicts),
+ d_differenceManager(c, d_constraintDatabase, d_setupLiteralCallback),
+ d_simplex(d_linEq, d_conflictCallBack),
+ d_constraintDatabase(c, u, d_arithvarNodeMap, d_differenceManager),
d_basicVarModelUpdateCallBack(d_simplex),
d_DELTA_ZERO(0),
d_statistics()
@@ -152,13 +150,34 @@ TheoryArith::Statistics::~Statistics(){
StatisticsRegistry::unregisterStat(&d_boundPropagations);
}
+void TheoryArith::zeroDifferenceDetected(ArithVar x){
+ Assert(d_differenceManager.isDifferenceSlack(x));
+ Assert(d_partialModel.upperBoundIsZero(x));
+ Assert(d_partialModel.lowerBoundIsZero(x));
+
+ Constraint lb = d_partialModel.getLowerBoundConstraint(x);
+ Constraint ub = d_partialModel.getUpperBoundConstraint(x);
+
+ if(lb->isEquality()){
+ d_differenceManager.differenceIsZero(lb);
+ }else if(ub->isEquality()){
+ d_differenceManager.differenceIsZero(ub);
+ }else{
+ d_differenceManager.differenceIsZero(lb, ub);
+ }
+}
+
/* procedure AssertLower( x_i >= c_i ) */
-Node TheoryArith::AssertLower(ArithVar x_i, DeltaRational& c_i, TNode original){
+Node TheoryArith::AssertLower(Constraint constraint){
+ Assert(constraint != NullConstraint);
+ Assert(constraint->isLowerBound());
+
+ ArithVar x_i = constraint->getVariable();
+ const DeltaRational& c_i = constraint->getValue();
+
Debug("arith") << "AssertLower(" << x_i << " " << c_i << ")"<< std::endl;
- if(isInteger(x_i)){
- c_i = DeltaRational(c_i.ceiling());
- }
+ Assert(!isInteger(x_i) || c_i.isIntegral());
//TODO Relax to less than?
if(d_partialModel.lessThanLowerBound(x_i, c_i)){
@@ -167,9 +186,8 @@ Node TheoryArith::AssertLower(ArithVar x_i, DeltaRational& c_i, TNode original){
int cmpToUB = d_partialModel.cmpToUpperBound(x_i, c_i);
if(cmpToUB > 0){ // c_i < \lowerbound(x_i)
- Node ubc = d_partialModel.getUpperConstraint(x_i);
- Node conflict = NodeManager::currentNM()->mkNode(AND, ubc, original);
- //d_out->conflict(conflict);
+ Constraint ubc = d_partialModel.getUpperBoundConstraint(x_i);
+ Node conflict = ConstraintValue::explainConflict(ubc, constraint);
Debug("arith") << "AssertLower conflict " << conflict << endl;
++(d_statistics.d_statAssertLowerConflicts);
return conflict;
@@ -177,22 +195,36 @@ Node TheoryArith::AssertLower(ArithVar x_i, DeltaRational& c_i, TNode original){
if(isInteger(x_i)){
d_constantIntegerVariables.push_back(x_i);
}
- //check to make sure x_i != c_i has not been asserted
- Node left = d_arithvarNodeMap.asNode(x_i);
- // if lowerbound and upperbound are equal, then the infinitesimal must be 0
- Assert(c_i.getInfinitesimalPart().isZero());
- Node right = mkRationalNode(c_i.getNoninfinitesimalPart());
-
- Node diseq = left.eqNode(right).notNode();
- if (d_diseq.find(diseq) != d_diseq.end()) {
- Node ub = d_partialModel.getUpperConstraint(x_i);
- return disequalityConflict(diseq, ub , original);
+ const ValueCollection& vc = constraint->getValueCollection();
+ if(vc.hasDisequality()){
+ Assert(vc.hasEquality());
+ const Constraint eq = vc.getEquality();
+ const Constraint diseq = vc.getDisequality();
+ if(diseq->isTrue()){
+ const Constraint ub = vc.getUpperBound();
+ Node conflict = ConstraintValue::explainConflict(diseq, ub, constraint);
+
+ ++(d_statistics.d_statDisequalityConflicts);
+ Debug("eq") << " assert lower conflict " << conflict << endl;
+ return conflict;
+ }else if(!eq->isTrue()){
+ Debug("eq") << "lb == ub, propagate eq" << eq << endl;
+ eq->impliedBy(constraint, d_partialModel.getUpperBoundConstraint(x_i));
+ }
}
}
- d_partialModel.setLowerConstraint(x_i,original);
- d_partialModel.setLowerBound(x_i, c_i);
+ d_partialModel.setLowerBoundConstraint(constraint);
+
+ if(d_differenceManager.isDifferenceSlack(x_i)){
+ int sgn = c_i.sgn();
+ if(sgn > 0){
+ d_differenceManager.differenceCannotBeZero(constraint);
+ }else if(sgn == 0 && d_partialModel.upperBoundIsZero(x_i)){
+ zeroDifferenceDetected(x_i);
+ }
+ }
d_updatedBounds.softAdd(x_i);
@@ -210,12 +242,18 @@ Node TheoryArith::AssertLower(ArithVar x_i, DeltaRational& c_i, TNode original){
}
/* procedure AssertUpper( x_i <= c_i) */
-Node TheoryArith::AssertUpper(ArithVar x_i, DeltaRational& c_i, TNode original){
+Node TheoryArith::AssertUpper(Constraint constraint){
+ ArithVar x_i = constraint->getVariable();
+ const DeltaRational& c_i = constraint->getValue();
+
Debug("arith") << "AssertUpper(" << x_i << " " << c_i << ")"<< std::endl;
+ AssertArgument(constraint != NullConstraint,
+ "AssertUpper() called on a NullConstraint.");
+ Assert(constraint->isUpperBound());
- if(isInteger(x_i)){
- c_i = DeltaRational(c_i.floor());
- }
+ //Too strong because of rounding with integers
+ //Assert(!constraint->hasLiteral() || original == constraint->getLiteral());
+ Assert(!isInteger(x_i) || c_i.isIntegral());
Debug("arith") << "AssertUpper(" << x_i << " " << c_i << ")"<< std::endl;
@@ -226,8 +264,8 @@ Node TheoryArith::AssertUpper(ArithVar x_i, DeltaRational& c_i, TNode original){
// cmpToLb = \lowerbound(x_i).cmp(c_i)
int cmpToLB = d_partialModel.cmpToLowerBound(x_i, c_i);
if( cmpToLB < 0 ){ // \upperbound(x_i) < \lowerbound(x_i)
- Node lbc = d_partialModel.getLowerConstraint(x_i);
- Node conflict = NodeManager::currentNM()->mkNode(AND, lbc, original);
+ Constraint lbc = d_partialModel.getLowerBoundConstraint(x_i);
+ Node conflict = ConstraintValue::explainConflict(lbc, constraint);
Debug("arith") << "AssertUpper conflict " << conflict << endl;
++(d_statistics.d_statAssertUpperConflicts);
return conflict;
@@ -236,22 +274,34 @@ Node TheoryArith::AssertUpper(ArithVar x_i, DeltaRational& c_i, TNode original){
d_constantIntegerVariables.push_back(x_i);
}
- //check to make sure x_i != c_i has not been asserted
- Node left = d_arithvarNodeMap.asNode(x_i);
-
- // if lowerbound and upperbound are equal, then the infinitesimal must be 0
- Assert(c_i.getInfinitesimalPart().isZero());
- Node right = mkRationalNode(c_i.getNoninfinitesimalPart());
-
- Node diseq = left.eqNode(right).notNode();
- if (d_diseq.find(diseq) != d_diseq.end()) {
- Node lb = d_partialModel.getLowerConstraint(x_i);
- return disequalityConflict(diseq, lb , original);
+ const ValueCollection& vc = constraint->getValueCollection();
+ if(vc.hasDisequality()){
+ Assert(vc.hasEquality());
+ const Constraint diseq = vc.getDisequality();
+ const Constraint eq = vc.getEquality();
+ if(diseq->isTrue()){
+ const Constraint lb = vc.getLowerBound();
+ Node conflict = ConstraintValue::explainConflict(diseq, lb, constraint);
+ Debug("eq") << " assert upper conflict " << conflict << endl;
+ return conflict;
+ }else if(!eq->isTrue()){
+ Debug("eq") << "lb == ub, propagate eq" << eq << endl;
+ eq->impliedBy(constraint, d_partialModel.getLowerBoundConstraint(x_i));
+ }
}
+
}
- d_partialModel.setUpperConstraint(x_i,original);
- d_partialModel.setUpperBound(x_i, c_i);
+ d_partialModel.setUpperBoundConstraint(constraint);
+
+ if(d_differenceManager.isDifferenceSlack(x_i)){
+ int sgn = c_i.sgn();
+ if(sgn < 0){
+ d_differenceManager.differenceCannotBeZero(constraint);
+ }else if(sgn == 0 && d_partialModel.lowerBoundIsZero(x_i)){
+ zeroDifferenceDetected(x_i);
+ }
+ }
d_updatedBounds.softAdd(x_i);
@@ -269,11 +319,19 @@ Node TheoryArith::AssertUpper(ArithVar x_i, DeltaRational& c_i, TNode original){
}
-/* procedure AssertLower( x_i == c_i ) */
-Node TheoryArith::AssertEquality(ArithVar x_i, DeltaRational& c_i, TNode original){
+/* procedure AssertEquality( x_i == c_i ) */
+Node TheoryArith::AssertEquality(Constraint constraint){
+ AssertArgument(constraint != NullConstraint,
+ "AssertUpper() called on a NullConstraint.");
+
+ ArithVar x_i = constraint->getVariable();
+ const DeltaRational& c_i = constraint->getValue();
Debug("arith") << "AssertEquality(" << x_i << " " << c_i << ")"<< std::endl;
+ //Should be fine in integers
+ Assert(!isInteger(x_i) || c_i.isIntegral());
+
int cmpToLB = d_partialModel.cmpToLowerBound(x_i, c_i);
int cmpToUB = d_partialModel.cmpToUpperBound(x_i, c_i);
@@ -284,16 +342,16 @@ Node TheoryArith::AssertEquality(ArithVar x_i, DeltaRational& c_i, TNode origina
}
if(cmpToUB > 0){
- Node ubc = d_partialModel.getUpperConstraint(x_i);
- Node conflict = NodeManager::currentNM()->mkNode(AND, ubc, original);
- Debug("arith") << "AssertLower conflict " << conflict << endl;
+ Constraint ubc = d_partialModel.getUpperBoundConstraint(x_i);
+ Node conflict = ConstraintValue::explainConflict(ubc, constraint);
+ Debug("arith") << "AssertEquality conflicts with upper bound " << conflict << endl;
return conflict;
}
if(cmpToLB < 0){
- Node lbc = d_partialModel.getLowerConstraint(x_i);
- Node conflict = NodeManager::currentNM()->mkNode(AND, lbc, original);
- Debug("arith") << "AssertUpper conflict " << conflict << endl;
+ Constraint lbc = d_partialModel.getLowerBoundConstraint(x_i);
+ Node conflict = ConstraintValue::explainConflict(lbc, constraint);
+ Debug("arith") << "AssertEquality conflicts with lower bound" << conflict << endl;
return conflict;
}
@@ -309,11 +367,17 @@ Node TheoryArith::AssertEquality(ArithVar x_i, DeltaRational& c_i, TNode origina
// Don't bother to check whether x_i != c_i is in d_diseq
// The a and (not a) should never be on the fact queue
- d_partialModel.setLowerConstraint(x_i,original);
- d_partialModel.setLowerBound(x_i, c_i);
+ d_partialModel.setUpperBoundConstraint(constraint);
+ d_partialModel.setLowerBoundConstraint(constraint);
- d_partialModel.setUpperConstraint(x_i,original);
- d_partialModel.setUpperBound(x_i, c_i);
+ if(d_differenceManager.isDifferenceSlack(x_i)){
+ int sgn = c_i.sgn();
+ if(sgn == 0){
+ zeroDifferenceDetected(x_i);
+ }else{
+ d_differenceManager.differenceCannotBeZero(constraint);
+ }
+ }
d_updatedBounds.softAdd(x_i);
@@ -329,6 +393,72 @@ Node TheoryArith::AssertEquality(ArithVar x_i, DeltaRational& c_i, TNode origina
}
+/* procedure AssertDisequality( x_i != c_i ) */
+Node TheoryArith::AssertDisequality(Constraint constraint){
+
+ AssertArgument(constraint != NullConstraint,
+ "AssertUpper() called on a NullConstraint.");
+ ArithVar x_i = constraint->getVariable();
+ const DeltaRational& c_i = constraint->getValue();
+
+ Debug("arith") << "AssertDisequality(" << x_i << " " << c_i << ")"<< std::endl;
+
+ //Should be fine in integers
+ Assert(!isInteger(x_i) || c_i.isIntegral());
+
+ if(d_differenceManager.isDifferenceSlack(x_i)){
+ int sgn = c_i.sgn();
+ if(sgn == 0){
+ d_differenceManager.differenceCannotBeZero(constraint);
+ }
+ }
+
+ if(constraint->isSplit()){
+ Debug("eq") << "skipping already split " << constraint << endl;
+ return Node::null();
+ }
+
+ const ValueCollection& vc = constraint->getValueCollection();
+ if(vc.hasLowerBound() && vc.hasUpperBound()){
+ const Constraint lb = vc.getLowerBound();
+ const Constraint ub = vc.getUpperBound();
+ if(lb->isTrue() && ub->isTrue()){
+ //in conflict
+ Debug("eq") << "explaining" << endl;
+ ++(d_statistics.d_statDisequalityConflicts);
+ return ConstraintValue::explainConflict(constraint, lb, ub);
+ }else if(lb->isTrue()){
+ Debug("eq") << "propagate UpperBound " << constraint << lb << ub << endl;
+ const Constraint negUb = ub->getNegation();
+ if(!negUb->isTrue()){
+ negUb->impliedBy(constraint, lb);
+ }
+ }else if(ub->isTrue()){
+ Debug("eq") << "propagate LowerBound " << constraint << lb << ub << endl;
+ const Constraint negLb = lb->getNegation();
+ if(!negLb->isTrue()){
+ negLb->impliedBy(constraint, ub);
+ }
+ }
+ }
+
+
+ if(c_i == d_partialModel.getAssignment(x_i)){
+ Debug("eq") << "lemma now!" << endl;
+ d_out->lemma(constraint->split());
+ return Node::null();
+ }else if(d_partialModel.strictlyLessThanLowerBound(x_i, c_i)){
+ Debug("eq") << "can drop as less than lb" << constraint << endl;
+ }else if(d_partialModel.strictlyGreaterThanUpperBound(x_i, c_i)){
+ Debug("eq") << "can drop as less than ub" << constraint << endl;
+ }else{
+ Debug("eq") << "push back" << constraint << endl;
+ d_diseqQueue.push(constraint);
+ }
+ return Node::null();
+
+}
+
void TheoryArith::addSharedTerm(TNode n){
d_differenceManager.addSharedTerm(n);
if(!n.isConst() && !isSetup(n)){
@@ -360,10 +490,11 @@ Node TheoryArith::ppRewrite(TNode atom) {
Debug("pb") << "arith::preprocess() : after pb substitutions and rewriting: "
<< a << endl;
Debug("arith::preprocess") << "arith::preprocess() :"
- << "after pb substitutions and rewriting: " << a << endl;
+ << "after pb substitutions and rewriting: "
+ << a << endl;
}
- if (a.getKind() == kind::EQUAL) {
+ if (a.getKind() == kind::EQUAL && Options::current()->arithRewriteEq) {
Node leq = NodeBuilder<2>(kind::LEQ) << a[0] << a[1];
Node geq = NodeBuilder<2>(kind::GEQ) << a[0] << a[1];
Node rewritten = Rewriter::rewrite(leq.andNode(geq));
@@ -383,44 +514,61 @@ Theory::PPAssertStatus TheoryArith::ppAssert(TNode in, SubstitutionMap& outSubst
Rational minConstant = 0;
Node minMonomial;
Node minVar;
- unsigned nVars = 0;
if (in.getKind() == kind::EQUAL) {
- Assert(in[1].getKind() == kind::CONST_RATIONAL);
- // Find the variable with the smallest coefficient
- Polynomial p = Polynomial::parsePolynomial(in[0]);
- Polynomial::iterator it = p.begin(), it_end = p.end();
- for (; it != it_end; ++ it) {
- Monomial m = *it;
- // Skip the constant
- if (m.isConstant()) continue;
- // This is a ''variable''
- nVars ++;
- // Skip the non-linear stuff
- if (!m.getVarList().singleton()) continue;
- // Get the minimal one
- Rational constant = m.getConstant().getValue();
- Rational absSconstant = constant > 0 ? constant : -constant;
- if (minVar.isNull() || absSconstant < minConstant) {
- Node var = m.getVarList().getNode();
- if (var.getKind() == kind::VARIABLE) {
- minVar = var;
- minMonomial = m.getNode();
- minConstant = constant;
- }
+ Comparison cmp = Comparison::parseNormalForm(in);
+
+ Polynomial left = cmp.getLeft();
+ Polynomial right = cmp.getRight();
+
+ Monomial m = left.getHead();
+ if (m.getVarList().singleton()){
+ VarList vl = m.getVarList();
+ Node var = vl.getNode();
+ if (var.getKind() == kind::VARIABLE && !vl.isIntegral()) {
+ minVar = var;
}
}
+ //Assert(in[1].getKind() == kind::CONST_RATIONAL);
+ // Find the variable with the smallest coefficient
+ //Polynomial p = Polynomial::parsePolynomial(in[0]);
+
+ // Polynomial::iterator it = p.begin(), it_end = p.end();
+ // for (; it != it_end; ++ it) {
+ // Monomial m = *it;
+ // // Skip the constant
+ // if (m.isConstant()) continue;
+ // // This is a ''variable''
+ // nVars ++;
+ // // Skip the non-linear stuff
+ // if (!m.getVarList().singleton()) continue;
+ // // Get the minimal one
+ // Rational constant = m.getConstant().getValue();
+ // Rational absSconstant = constant > 0 ? constant : -constant;
+ // if (minVar.isNull() || absSconstant < minConstant) {
+ // Node var = m.getVarList().getNode();
+ // if (var.getKind() == kind::VARIABLE) {
+ // minVar = var;
+ // minMonomial = m.getNode();
+ // minConstant = constant;
+ // }
+ // }
+ //}
+
// Solve for variable
if (!minVar.isNull()) {
+ Polynomial right = cmp.getRight();
+ Node eliminateVar = right.getNode();
// ax + p = c -> (ax + p) -ax - c = -ax
- Node eliminateVar = NodeManager::currentNM()->mkNode(kind::MINUS, in[0], minMonomial);
- if (in[1].getConst<Rational>() != 0) {
- eliminateVar = NodeManager::currentNM()->mkNode(kind::MINUS, eliminateVar, in[1]);
- }
- // x = (p - ax - c) * -1/a
- eliminateVar = NodeManager::currentNM()->mkNode(kind::MULT, eliminateVar, mkRationalNode(- minConstant.inverse()));
- // Add the substitution if not recursive
- Node rewritten = Rewriter::rewrite(eliminateVar);
+ // Node eliminateVar = NodeManager::currentNM()->mkNode(kind::MINUS, in[0], minMonomial);
+ // if (in[1].getConst<Rational>() != 0) {
+ // eliminateVar = NodeManager::currentNM()->mkNode(kind::MINUS, eliminateVar, in[1]);
+ // }
+ // // x = (p - ax - c) * -1/a
+ // eliminateVar = NodeManager::currentNM()->mkNode(kind::MULT, eliminateVar, mkRationalNode(- minConstant.inverse()));
+ // // Add the substitution if not recursive
+ Node rewritten = eliminateVar;
+ Assert(rewritten == Rewriter::rewrite(eliminateVar));
if (!rewritten.hasSubterm(minVar)) {
Node elim = Rewriter::rewrite(eliminateVar);
if (!minVar.getType().isInteger() || elim.getType().isInteger()) {
@@ -584,21 +732,22 @@ void TheoryArith::setupPolynomial(const Polynomial& poly) {
*/
}
-void TheoryArith::setupAtom(TNode atom, bool addToDatabase) {
+void TheoryArith::setupAtom(TNode atom) {
Assert(isRelationOperator(atom.getKind()));
Assert(Comparison::isNormalAtom(atom));
Assert(!isSetup(atom));
+ Assert(!d_constraintDatabase.hasLiteral(atom));
- Node left = atom[0];
- if(!isSetup(left)){
- Polynomial poly = Polynomial::parsePolynomial(left);
- setupPolynomial(poly);
- }
+ Comparison cmp = Comparison::parseNormalForm(atom);
+ Polynomial nvp = cmp.normalizedVariablePart();
+ Assert(!nvp.isZero());
- if(addToDatabase){
- d_atomDatabase.addAtom(atom);
+ if(!isSetup(nvp.getNode())){
+ setupPolynomial(nvp);
}
+ d_constraintDatabase.addLiteral(atom);
+
markSetup(atom);
}
@@ -607,12 +756,17 @@ void TheoryArith::preRegisterTerm(TNode n) {
if(isRelationOperator(n.getKind())){
if(!isSetup(n)){
- setupAtom(n, Options::current()->arithPropagation);
+ setupAtom(n);
}
- addToContext(n);
+ Constraint c = d_constraintDatabase.lookup(n);
+ Assert(c != NullConstraint);
+
+ Debug("arith::preregister") << "setup constraint" << c << endl;
+ Assert(!c->canBePropagated());
+ c->setPreregistered();
}
- Debug("arith::preregister") << "end arith::preRegisterTerm(" << n <<")" << endl;
+ Debug("arith::preregister") << "end arith::preRegisterTerm("<< n <<")" << endl;
}
@@ -642,6 +796,8 @@ ArithVar TheoryArith::requestArithVar(TNode x, bool slack){
d_tableau.increaseSize();
+ d_constraintDatabase.addVariable(varX);
+
Debug("arith::arithvar") << x << " |-> " << varX << endl;
return varX;
@@ -698,20 +854,22 @@ void TheoryArith::setupInitialValue(ArithVar x){
Debug("arith") << "setupVariable("<<x<<")"<<std::endl;
}
-ArithVar TheoryArith::determineLeftVariable(TNode assertion, Kind simpleKind){
- TNode left = getSide<true>(assertion, simpleKind);
-
- return d_arithvarNodeMap.asArithVar(left);
+ArithVar TheoryArith::determineArithVar(const Polynomial& p) const{
+ Assert(!p.containsConstant());
+ Assert(p.getHead().constantIsPositive());
+ TNode n = p.getNode();
+ Debug("determineArithVar") << "determineArithVar(" << n << ")" << endl;
+ return d_arithvarNodeMap.asArithVar(n);
}
-
-Node TheoryArith::disequalityConflict(TNode eq, TNode lb, TNode ub){
- NodeBuilder<3> conflict(kind::AND);
- conflict << eq << lb << ub;
- ++(d_statistics.d_statDisequalityConflicts);
- return conflict;
+ArithVar TheoryArith::determineArithVar(TNode assertion) const{
+ Debug("determineArithVar") << "determineArithVar " << assertion << endl;
+ Comparison cmp = Comparison::parseNormalForm(assertion);
+ Polynomial variablePart = cmp.normalizedVariablePart();
+ return determineArithVar(variablePart);
}
+
bool TheoryArith::canSafelyAvoidEqualitySetup(TNode equality){
Assert(equality.getKind() == EQUAL);
return d_arithvarNodeMap.hasArithVar(equality[0]);
@@ -721,11 +879,11 @@ Comparison TheoryArith::mkIntegerEqualityFromAssignment(ArithVar v){
const DeltaRational& beta = d_partialModel.getAssignment(v);
Assert(beta.isIntegral());
- Constant betaAsConstant = Constant::mkConstant(beta.floor());
+ Polynomial betaAsPolynomial( Constant::mkConstant(beta.floor()) );
TNode var = d_arithvarNodeMap.asNode(v);
Polynomial varAsPolynomial = Polynomial::parsePolynomial(var);
- return Comparison::mkComparison(EQUAL, varAsPolynomial, betaAsConstant);
+ return Comparison::mkComparison(EQUAL, varAsPolynomial, betaAsPolynomial);
}
Node TheoryArith::dioCutting(){
@@ -755,12 +913,12 @@ Node TheoryArith::dioCutting(){
return Node::null();
}else{
Polynomial p = plane.getPolynomial();
- Constant c = plane.getConstant() * Constant::mkConstant(-1);
+ Polynomial c(plane.getConstant() * Constant::mkConstant(-1));
Integer gcd = p.gcd();
Assert(p.isIntegral());
Assert(c.isIntegral());
Assert(gcd > 1);
- Assert(!gcd.divides(c.getValue().getNumerator()));
+ Assert(!gcd.divides(c.asConstant().getNumerator()));
Comparison leq = Comparison::mkComparison(LEQ, p, c);
Comparison geq = Comparison::mkComparison(GEQ, p, c);
Node lemma = NodeManager::currentNM()->mkNode(OR, leq.getNode(), geq.getNode());
@@ -782,21 +940,17 @@ Node TheoryArith::callDioSolver(){
Assert(isInteger(v));
Assert(d_partialModel.boundsAreEqual(v));
- TNode lb = d_partialModel.getLowerConstraint(v);
- TNode ub = d_partialModel.getUpperConstraint(v);
+
+ Constraint lb = d_partialModel.getLowerBoundConstraint(v);
+ Constraint ub = d_partialModel.getUpperBoundConstraint(v);
Node orig = Node::null();
- if(lb == ub){
- Assert(lb.getKind() == EQUAL);
- orig = lb;
- }else if(lb.getKind() == EQUAL){
- orig = lb;
- }else if(ub.getKind() == EQUAL){
- orig = ub;
- }else{
- NodeBuilder<> nb(AND);
- nb << ub << lb;
- orig = nb;
+ if(lb->isEquality()){
+ orig = lb->explainForConflict();
+ }else if(ub->isEquality()){
+ orig = ub->explainForConflict();
+ }else {
+ orig = ConstraintValue::explainConflict(ub, lb);
}
Assert(d_partialModel.assignmentIsConsistent(v));
@@ -819,71 +973,124 @@ Node TheoryArith::callDioSolver(){
}
Node TheoryArith::assertionCases(TNode assertion){
- Kind simpleKind = simplifiedKind(assertion);
+ Constraint constraint = d_constraintDatabase.lookup(assertion);
+
+ Kind simpleKind = Comparison::comparisonKind(assertion);
Assert(simpleKind != UNDEFINED_KIND);
+ Assert(constraint != NullConstraint ||
+ simpleKind == EQUAL ||
+ simpleKind == DISTINCT );
if(simpleKind == EQUAL || simpleKind == DISTINCT){
Node eq = (simpleKind == DISTINCT) ? assertion[0] : assertion;
if(!isSetup(eq)){
//The previous code was equivalent to:
- setupAtom(eq, false);
- //We can try:
- //setupAtom(eq, true);
- addToContext(eq);
+ setupAtom(eq);
+ constraint = d_constraintDatabase.lookup(assertion);
+ }
+ }
+ Assert(constraint != NullConstraint);
+
+ if(constraint->negationHasProof()){
+ Constraint negation = constraint->getNegation();
+ if(negation->isSelfExplaining()){
+ if(Debug.isOn("whytheoryenginewhy")){
+ debugPrintFacts();
+ }
+ cout << "Theory engine is sending me both a literal and its negation?"
+ << "BOOOOOOOOOOOOOOOOOOOOOO!!!!"<< endl;
}
+ Debug("arith::eq") << constraint << endl;
+ Debug("arith::eq") << negation << endl;
+
+ NodeBuilder<> nb(kind::AND);
+ nb << assertion;
+ negation->explainForConflict(nb);
+ Node conflict = nb;
+ Debug("arith::eq") << "conflict" << conflict << endl;
+ return conflict;
}
+ Assert(!constraint->negationHasProof());
- ArithVar x_i = determineLeftVariable(assertion, simpleKind);
- DeltaRational c_i = determineRightConstant(assertion, simpleKind);
+ if(constraint->assertedToTheTheory()){
+ //Do nothing
+ return Node::null();
+ }
+ Assert(!constraint->assertedToTheTheory());
+ constraint->setAssertedToTheTheory();
- // bool tightened = false;
+ ArithVar x_i = constraint->getVariable();
+ //DeltaRational c_i = determineRightConstant(assertion, simpleKind);
- // //If the variable is an integer tighen the constraint.
- // if(isInteger(x_i)){
- // if(simpleKind == LT){
- // tightened = true;
- // c_i = DeltaRational(c_i.floor());
- // }else if(simpleKind == GT){
- // tightened = true;
- // c_i = DeltaRational(c_i.ceiling());
- // }
- // }
+ //Assert(constraint->getVariable() == determineLeftVariable(assertion, simpleKind));
+ //Assert(constraint->getValue() == determineRightConstant(assertion, simpleKind));
+ Assert(!constraint->hasLiteral() || constraint->getLiteral() == assertion);
Debug("arith::assertions") << "arith assertion @" << getContext()->getLevel()
<<"(" << assertion
<< " \\-> "
- << x_i<<" "<< simpleKind <<" "<< c_i << ")" << std::endl;
-
- switch(simpleKind){
- case LEQ:
- case LT:
- return AssertUpper(x_i, c_i, assertion);
- case GEQ:
- case GT:
- return AssertLower(x_i, c_i, assertion);
- case EQUAL:
- return AssertEquality(x_i, c_i, assertion);
- case DISTINCT:
- {
- d_diseq.insert(assertion);
- // Check if it conflicts with the the bounds
- TNode eq = assertion[0];
- Assert(eq.getKind() == kind::EQUAL);
- TNode lhs = eq[0];
- TNode rhs = eq[1];
- Assert(rhs.getKind() == CONST_RATIONAL);
- ArithVar lhsVar = determineLeftVariable(eq, kind::EQUAL);
- DeltaRational rhsValue = determineRightConstant(eq, kind::EQUAL);
- if (d_partialModel.hasLowerBound(lhsVar) &&
- d_partialModel.hasUpperBound(lhsVar) &&
- d_partialModel.getLowerBound(lhsVar) == rhsValue &&
- d_partialModel.getUpperBound(lhsVar) == rhsValue) {
- Node lb = d_partialModel.getLowerConstraint(lhsVar);
- Node ub = d_partialModel.getUpperConstraint(lhsVar);
- return disequalityConflict(assertion, lb, ub);
+ //<< determineLeftVariable(assertion, simpleKind)
+ <<" "<< simpleKind <<" "
+ //<< determineRightConstant(assertion, simpleKind)
+ << ")" << std::endl;
+
+
+ Debug("arith::constraint") << "arith constraint " << constraint << std::endl;
+
+ if(!constraint->hasProof()){
+ Debug("arith::constraint") << "marking as constraint as self explaining " << endl;
+ constraint->selfExplaining();
+ }else{
+ Debug("arith::constraint") << "already has proof: " << constraint->explainForConflict() << endl;
+ }
+
+ Assert(!isInteger(x_i) ||
+ simpleKind == EQUAL ||
+ simpleKind == DISTINCT ||
+ simpleKind == GEQ ||
+ simpleKind == LT);
+
+ switch(constraint->getType()){
+ case UpperBound:
+ if(simpleKind == LT && isInteger(x_i)){
+ Constraint floorConstraint = constraint->getFloor();
+ if(!floorConstraint->isTrue()){
+ if(floorConstraint->negationHasProof()){
+ return ConstraintValue::explainConflict(constraint, floorConstraint->getNegation());
+ }else{
+ floorConstraint->impliedBy(constraint);
+ }
}
+ //c_i = DeltaRational(c_i.floor());
+ //return AssertUpper(x_i, c_i, assertion, floorConstraint);
+ return AssertUpper(floorConstraint);
+ }else{
+ return AssertUpper(constraint);
}
- return Node::null();
+ //return AssertUpper(x_i, c_i, assertion, constraint);
+ case LowerBound:
+ if(simpleKind == LT && isInteger(x_i)){
+ Constraint ceilingConstraint = constraint->getCeiling();
+ if(!ceilingConstraint->isTrue()){
+ if(ceilingConstraint->negationHasProof()){
+
+ return ConstraintValue::explainConflict(constraint, ceilingConstraint->getNegation());
+ }
+ ceilingConstraint->impliedBy(constraint);
+ }
+ //c_i = DeltaRational(c_i.ceiling());
+ //return AssertLower(x_i, c_i, assertion, ceilingConstraint);
+ return AssertLower(ceilingConstraint);
+ }else{
+ return AssertLower(constraint);
+ }
+ //return AssertLower(x_i, c_i, assertion, constraint);
+ case Equality:
+ return AssertEquality(constraint);
+ //return AssertEquality(x_i, c_i, assertion, constraint);
+ case Disequality:
+ return AssertDisequality(constraint);
+ //return AssertDisequality(x_i, c_i, assertion, constraint);
default:
Unreachable();
return Node::null();
@@ -930,29 +1137,45 @@ void TheoryArith::check(Effort effortLevel){
d_out->conflict(possibleConflict);
return;
}
+ if(d_differenceManager.inConflict()){
+ Node c = d_differenceManager.conflict();
+ d_partialModel.revertAssignmentChanges();
+ Debug("arith::conflict") << "difference manager conflict " << c << endl;
+ clearUpdates();
+ d_out->conflict(c);
+ return;
+ }
}
+
if(Debug.isOn("arith::print_assertions")) {
debugPrintAssertions();
}
bool emmittedConflictOrSplit = false;
- Node possibleConflict = d_simplex.findModel();
- if(possibleConflict != Node::null()){
+ Assert(d_conflicts.empty());
+ bool foundConflict = d_simplex.findModel();
+ if(foundConflict){
d_partialModel.revertAssignmentChanges();
clearUpdates();
- Debug("arith::conflict") << "conflict " << possibleConflict << endl;
- d_out->conflict(possibleConflict);
+ Assert(!d_conflicts.empty());
+ for(size_t i = 0, i_end = d_conflicts.size(); i < i_end; ++i){
+ Node conflict = d_conflicts[i];
+ Debug("arith::conflict") << "d_conflicts[" << i << "] " << conflict << endl;
+ d_out->conflict(conflict);
+ }
emmittedConflictOrSplit = true;
}else{
d_partialModel.commitAssignmentChanges();
}
+
if(!emmittedConflictOrSplit && fullEffort(effortLevel)){
emmittedConflictOrSplit = splitDisequalities();
}
+ Node possibleConflict = Node::null();
if(!emmittedConflictOrSplit && fullEffort(effortLevel) && !hasIntegerModel()){
if(!emmittedConflictOrSplit && Options::current()->dioSolver){
@@ -1034,29 +1257,43 @@ Node TheoryArith::roundRobinBranch(){
bool TheoryArith::splitDisequalities(){
bool splitSomething = false;
- context::CDHashSet<Node, NodeHashFunction>::iterator it = d_diseq.begin();
- context::CDHashSet<Node, NodeHashFunction>::iterator it_end = d_diseq.end();
- for(; it != it_end; ++ it) {
- TNode eq = (*it)[0];
- Assert(eq.getKind() == kind::EQUAL);
- TNode lhs = eq[0];
- TNode rhs = eq[1];
- Assert(rhs.getKind() == CONST_RATIONAL);
- ArithVar lhsVar = determineLeftVariable(eq, kind::EQUAL);
- DeltaRational lhsValue = d_partialModel.getAssignment(lhsVar);
- DeltaRational rhsValue = determineRightConstant(eq, kind::EQUAL);
- if (lhsValue == rhsValue) {
- Debug("arith::lemma") << "Splitting on " << eq << endl;
- Debug("arith::lemma") << "LHS value = " << lhsValue << endl;
- Debug("arith::lemma") << "RHS value = " << rhsValue << endl;
- Node ltNode = NodeBuilder<2>(kind::LT) << lhs << rhs;
- Node gtNode = NodeBuilder<2>(kind::GT) << lhs << rhs;
- Node lemma = NodeBuilder<3>(OR) << eq << ltNode << gtNode;
- ++(d_statistics.d_statDisequalitySplits);
- d_out->lemma(lemma);
- splitSomething = true;
+ vector<Constraint> save;
+
+ while(!d_diseqQueue.empty()){
+ Constraint front = d_diseqQueue.front();
+ d_diseqQueue.pop();
+
+ if(front->isSplit()){
+ Debug("eq") << "split already" << endl;
+ }else{
+ Debug("eq") << "not split already" << endl;
+
+ ArithVar lhsVar = front->getVariable();
+
+ const DeltaRational& lhsValue = d_partialModel.getAssignment(lhsVar);
+ const DeltaRational& rhsValue = front->getValue();
+ if(lhsValue == rhsValue){
+ Debug("arith::lemma") << "Splitting on " << front << endl;
+ Debug("arith::lemma") << "LHS value = " << lhsValue << endl;
+ Debug("arith::lemma") << "RHS value = " << rhsValue << endl;
+ Node lemma = front->split();
+ ++(d_statistics.d_statDisequalitySplits);
+ d_out->lemma(lemma);
+ splitSomething = true;
+ }else if(d_partialModel.strictlyLessThanLowerBound(lhsVar, rhsValue)){
+ Debug("eq") << "can drop as less than lb" << front << endl;
+ }else if(d_partialModel.strictlyGreaterThanUpperBound(lhsVar, rhsValue)){
+ Debug("eq") << "can drop as greater than ub" << front << endl;
+ }else{
+ Debug("eq") << "save" << front << endl;
+ save.push_back(front);
+ }
}
}
+ vector<Constraint>::const_iterator i=save.begin(), i_end = save.end();
+ for(; i != i_end; ++i){
+ d_diseqQueue.push(*i);
+ }
return splitSomething;
}
@@ -1068,17 +1305,17 @@ void TheoryArith::debugPrintAssertions() {
Debug("arith::print_assertions") << "Assertions:" << endl;
for (ArithVar i = 0; i < d_variables.size(); ++ i) {
if (d_partialModel.hasLowerBound(i)) {
- Node lConstr = d_partialModel.getLowerConstraint(i);
+ Constraint lConstr = d_partialModel.getLowerBoundConstraint(i);
Debug("arith::print_assertions") << lConstr << endl;
}
if (d_partialModel.hasUpperBound(i)) {
- Node uConstr = d_partialModel.getUpperConstraint(i);
+ Constraint uConstr = d_partialModel.getUpperBoundConstraint(i);
Debug("arith::print_assertions") << uConstr << endl;
}
}
- context::CDHashSet<Node, NodeHashFunction>::iterator it = d_diseq.begin();
- context::CDHashSet<Node, NodeHashFunction>::iterator it_end = d_diseq.end();
+ context::CDQueue<Constraint>::const_iterator it = d_diseqQueue.begin();
+ context::CDQueue<Constraint>::const_iterator it_end = d_diseqQueue.end();
for(; it != it_end; ++ it) {
Debug("arith::print_assertions") << *it << endl;
}
@@ -1097,88 +1334,74 @@ void TheoryArith::debugPrintModel(){
}
Node TheoryArith::explain(TNode n) {
- Debug("arith::explain") << "explain @" << getContext()->getLevel() << ": " << n << endl;
- Assert(d_propManager.isPropagated(n));
- return d_propManager.explain(n);
-}
+ Debug("arith::explain") << "explain @" << getContext()->getLevel() << ": " << n << endl;
-void flattenAnd(Node n, std::vector<TNode>& out){
- Assert(n.getKind() == kind::AND);
- for(Node::iterator i=n.begin(), i_end=n.end(); i != i_end; ++i){
- Node curr = *i;
- if(curr.getKind() == kind::AND){
- flattenAnd(curr, out);
- }else{
- out.push_back(curr);
- }
+ Constraint c = d_constraintDatabase.lookup(n);
+ if(c != NullConstraint){
+ Assert(!c->isSelfExplaining());
+ Node exp = c->explainForPropagation();
+ Debug("arith::explain") << "constraint explanation" << n << ":" << exp << endl;
+ return exp;
+ }else{
+ Assert(d_differenceManager.canExplain(n));
+ Debug("arith::explain") << "dm explanation" << n << endl;
+ return d_differenceManager.explain(n);
}
}
-Node flattenAnd(Node n){
- std::vector<TNode> out;
- flattenAnd(n, out);
- return NodeManager::currentNM()->mkNode(kind::AND, out);
-}
void TheoryArith::propagate(Effort e) {
- bool propagated = false;
if(Options::current()->arithPropagation && hasAnyUpdates()){
propagateCandidates();
}else{
clearUpdates();
}
- while(d_propManager.hasMorePropagations()){
- const PropManager::PropUnit next = d_propManager.getNextPropagation();
- bool flag = next.flag;
- TNode toProp = next.consequent;
+ while(d_constraintDatabase.hasMorePropagations()){
+ Constraint c = d_constraintDatabase.nextPropagation();
- TNode atom = (toProp.getKind() == kind::NOT) ? toProp[0] : toProp;
+ if(c->negationHasProof()){
+ Node conflict = ConstraintValue::explainConflict(c, c->getNegation());
+ cout << "tears " << conflict << endl;
+ Debug("arith::prop") << "propagate conflict" << conflict << endl;
+ d_out->conflict(conflict);
+ return;
+ }else if(!c->assertedToTheTheory()){
- Debug("arith::propagate") << "propagate @" << getContext()->getLevel() <<" flag: "<< flag << " " << toProp << endl;
+ Node literal = c->getLiteral();
+ Debug("arith::prop") << "propagating @" << getContext()->getLevel() << " " << literal << endl;
- if(flag) {
- //Currently if the flag is set this came from an equality detected by the
- //equality engine in the the difference manager.
- if(toProp.getKind() == kind::EQUAL){
- Node normalized = Rewriter::rewrite(toProp);
- Node notNormalized = normalized.notNode();
+ d_out->propagate(literal);
+ }else{
+ Node literal = c->getLiteral();
+ Debug("arith::prop") << "already asserted to the theory " << literal << endl;
+ }
+ }
- if(d_diseq.find(notNormalized) == d_diseq.end()){
- d_out->propagate(toProp);
- propagated = true;
- }else{
- Node exp = d_differenceManager.explain(toProp);
- Node lp = flattenAnd(exp.andNode(notNormalized));
- Debug("arith::propagate") << "propagate conflict" << lp << endl;
- d_out->conflict(lp);
+ while(d_differenceManager.hasMorePropagations()){
+ TNode toProp = d_differenceManager.getNextPropagation();
- propagated = true;
- break;
- }
- }else{
- d_out->propagate(toProp);
- propagated = true;
- }
- }else if(inContextAtom(atom)){
- Node satValue = d_valuation.getSatValue(toProp);
- AlwaysAssert(satValue.isNull());
- propagated = true;
+ //Currently if the flag is set this came from an equality detected by the
+ //equality engine in the the difference manager.
+ Node normalized = Rewriter::rewrite(toProp);
+
+ Constraint constraint = d_constraintDatabase.lookup(normalized);
+ if(constraint == NullConstraint){
+ Debug("arith::prop") << "propagating on non-constraint? " << toProp << endl;
d_out->propagate(toProp);
+ }else if(constraint->negationHasProof()){
+ Node exp = d_differenceManager.explain(toProp);
+ Node notNormalized = normalized.getKind() == NOT ?
+ normalized[0] : normalized.notNode();
+ Node lp = flattenAnd(exp.andNode(notNormalized));
+ Debug("arith::prop") << "propagate conflict" << lp << endl;
+ d_out->conflict(lp);
+ return;
}else{
- //Not clear if this is a good time to do this or not...
- Debug("arith::propagate") << "Atom is not in context" << toProp << endl;
-#warning "enable remove atom in database"
- //d_atomDatabase.removeAtom(atom);
- }
- }
+ Debug("arith::prop") << "propagating still?" << toProp << endl;
- if(!propagated){
- //Opportunistically export previous conflicts
- while(d_simplex.hasMoreLemmas()){
- Node lemma = d_simplex.popLemma();
- d_out->lemma(lemma);
+ d_out->propagate(toProp);
}
}
}
@@ -1401,8 +1624,18 @@ void TheoryArith::presolve(){
callCount = callCount + 1;
}
+ if(Options::current()->arithPropagation ){
+ vector<Node> lemmas;
+ d_constraintDatabase.outputAllUnateLemmas(lemmas);
+ vector<Node>::const_iterator i = lemmas.begin(), i_end = lemmas.end();
+ for(; i != i_end; ++i){
+ Node lem = *i;
+ Debug("arith::oldprop") << " lemma lemma duck " <<lem << endl;
+ d_out->lemma(lem);
+ }
+ }
+
d_learner.clear();
- check(EFFORT_FULL);
}
EqualityStatus TheoryArith::getEqualityStatus(TNode a, TNode b) {
@@ -1423,27 +1656,71 @@ bool TheoryArith::propagateCandidateBound(ArithVar basic, bool upperBound){
if((upperBound && d_partialModel.strictlyLessThanUpperBound(basic, bound)) ||
(!upperBound && d_partialModel.strictlyGreaterThanLowerBound(basic, bound))){
- Node bestImplied = upperBound ?
- d_propManager.getBestImpliedUpperBound(basic, bound):
- d_propManager.getBestImpliedLowerBound(basic, bound);
- if(!bestImplied.isNull()){
- bool asserted = d_propManager.isAsserted(bestImplied);
- bool propagated = d_propManager.isPropagated(bestImplied);
- if( !asserted && !propagated){
+#warning "Policy point"
+ //We are only going to recreate the functionality for now.
+ //In the future this can be improved to generate a temporary constraint
+ //if none exists.
+ //Experiment with doing this everytime or only when the new constraint
+ //implies an unknown fact.
+
+ ConstraintType t = upperBound ? UpperBound : LowerBound;
+ Constraint bestImplied = d_constraintDatabase.getBestImpliedBound(basic, t, bound);
- NodeBuilder<> nb(kind::AND);
+ // Node bestImplied = upperBound ?
+ // d_apm.getBestImpliedUpperBound(basic, bound):
+ // d_apm.getBestImpliedLowerBound(basic, bound);
+
+ if(bestImplied != NullConstraint){
+ //This should be stronger
+ Assert(!upperBound || bound <= bestImplied->getValue());
+ Assert(!upperBound || d_partialModel.lessThanUpperBound(basic, bestImplied->getValue()));
+
+ Assert( upperBound || bound >= bestImplied->getValue());
+ Assert( upperBound || d_partialModel.greaterThanLowerBound(basic, bestImplied->getValue()));
+ //slightly changed
+
+ // Constraint c = d_constraintDatabase.lookup(bestImplied);
+ // Assert(c != NullConstraint);
+
+ bool assertedToTheTheory = bestImplied->assertedToTheTheory();
+ bool canBePropagated = bestImplied->canBePropagated();
+ bool hasProof = bestImplied->hasProof();
+
+ Debug("arith::prop") << "arith::prop" << basic
+ //<< " " << assertedValuation
+ << " " << assertedToTheTheory
+ << " " << canBePropagated
+ << " " << hasProof
+ << endl;
+
+ if(!assertedToTheTheory && canBePropagated && !hasProof ){
if(upperBound){
- d_linEq.explainNonbasicsUpperBound(basic, nb);
+ Assert(bestImplied != d_partialModel.getUpperBoundConstraint(basic));
+ d_linEq.propagateNonbasicsUpperBound(basic, bestImplied);
}else{
- d_linEq.explainNonbasicsLowerBound(basic, nb);
+ Assert(bestImplied != d_partialModel.getLowerBoundConstraint(basic));
+ d_linEq.propagateNonbasicsLowerBound(basic, bestImplied);
}
- Node explanation = nb;
- d_propManager.propagate(bestImplied, explanation, false);
return true;
- }else{
- Debug("arith::prop") << basic << " " << asserted << " " << propagated << endl;
}
+
+ // bool asserted = valuationIsAsserted(bestImplied);
+ // bool propagated = d_theRealPropManager.isPropagated(bestImplied);
+ // if( !asserted && !propagated){
+
+ // NodeBuilder<> nb(kind::AND);
+ // if(upperBound){
+ // d_linEq.explainNonbasicsUpperBound(basic, nb);
+ // }else{
+ // d_linEq.explainNonbasicsLowerBound(basic, nb);
+ // }
+ // Node explanation = nb;
+ // d_theRealPropManager.propagate(bestImplied, explanation, false);
+ // return true;
+ // }else{
+ // Debug("arith::prop") << basic << " " << asserted << " " << propagated << endl;
+ // }
}
}
return false;
diff --git a/src/theory/arith/theory_arith.h b/src/theory/arith/theory_arith.h
index 4f111d350..4a5c398bd 100644
--- a/src/theory/arith/theory_arith.h
+++ b/src/theory/arith/theory_arith.h
@@ -34,14 +34,14 @@
#include "theory/arith/arith_rewriter.h"
#include "theory/arith/partial_model.h"
#include "theory/arith/linear_equality.h"
-#include "theory/arith/atom_database.h"
#include "theory/arith/simplex.h"
#include "theory/arith/arith_static_learner.h"
-#include "theory/arith/arith_prop_manager.h"
#include "theory/arith/arithvar_node_map.h"
#include "theory/arith/dio_solver.h"
#include "theory/arith/difference_manager.h"
+#include "theory/arith/constraint.h"
+
#include "util/stats.h"
#include <vector>
@@ -66,24 +66,6 @@ private:
*/
bool d_hasDoneWorkSinceCut;
- /**
- * The set of atoms that are currently in the context.
- * This is exactly the union of preregistered atoms and
- * equalities from sharing.
- * This is used to reconstruct the rest of arithmetic.
- */
- CDNodeSet d_atomsInContext;
- bool inContextAtom(TNode atom){
- Assert(isRelationOperator(atom.getKind()));
- Assert(Comparison::isNormalAtom(atom));
- return d_atomsInContext.contains(atom);
- }
- void addToContext(TNode atom){
- Assert(isRelationOperator(atom.getKind()));
- Assert(Comparison::isNormalAtom(atom));
- d_atomsInContext.insert(atom);
- }
-
/** Static learner. */
ArithStaticLearner d_learner;
@@ -111,8 +93,20 @@ private:
void setupVariable(const Variable& x);
void setupVariableList(const VarList& vl);
void setupPolynomial(const Polynomial& poly);
- void setupAtom(TNode atom, bool addToDatabase);
+ void setupAtom(TNode atom);
+ class SetupLiteralCallBack : public TNodeCallBack {
+ private:
+ TheoryArith* d_arith;
+ public:
+ SetupLiteralCallBack(TheoryArith* ta) : d_arith(ta){}
+ void operator()(TNode lit){
+ TNode atom = (lit.getKind() == kind::NOT) ? lit[0] : lit;
+ if(!d_arith->isSetup(atom)){
+ d_arith->setupAtom(atom);
+ }
+ }
+ } d_setupLiteralCallback;
/**
* (For the moment) the type hierarchy goes as:
@@ -172,7 +166,9 @@ private:
/**
* List of all of the inequalities asserted in the current context.
*/
- context::CDHashSet<Node, NodeHashFunction> d_diseq;
+ //context::CDHashSet<Node, NodeHashFunction> d_diseq;
+ context::CDQueue<Constraint> d_diseqQueue;
+
/**
* Manages information about the assignment and upper and lower bounds on
@@ -222,6 +218,23 @@ private:
uint32_t d_tableauResetPeriod;
static const uint32_t s_TABLEAU_RESET_INCREMENT = 5;
+
+ /** This is only used by simplex at the moment. */
+ context::CDList<Node> d_conflicts;
+ class PushCallBack : public NodeCallBack {
+ private:
+ context::CDList<Node>& d_list;
+ public:
+ PushCallBack(context::CDList<Node>& l)
+ : d_list(l)
+ {}
+ void operator()(Node n){
+ d_list.push_back(n);
+ }
+ };
+ PushCallBack d_conflictCallBack;
+
+
/**
* A copy of the tableau immediately after removing variables
* without bounds in presolve().
@@ -232,10 +245,7 @@ private:
* The atom database keeps track of the atoms that have been preregistered.
* Used to add unate propagations.
*/
- ArithAtomDatabase d_atomDatabase;
-
- /** This manager keeps track of information needed to propagate. */
- ArithPropManager d_propManager;
+ //ArithAtomDatabase d_atomDatabase;
/** This keeps track of difference equalities. Mostly for sharing. */
DifferenceManager d_differenceManager;
@@ -243,6 +253,10 @@ private:
/** This implements the Simplex decision procedure. */
SimplexDecisionProcedure d_simplex;
+
+ /** The constraint database associated with the theory. */
+ ConstraintDatabase d_constraintDatabase;
+
/** Internal model value for the atom */
bool getDeltaAtomValue(TNode n);
@@ -291,7 +305,7 @@ private:
d_simplex(s)
{}
- void callback(ArithVar x){
+ void operator()(ArithVar x){
d_simplex.updateBasic(x);
}
};
@@ -305,10 +319,10 @@ private:
void propagateArithVar(bool upperbound, ArithVar var );
/**
- * Using the simpleKind return the ArithVar associated with the
- * left hand side of assertion.
+ * Using the simpleKind return the ArithVar associated with the assertion.
*/
- ArithVar determineLeftVariable(TNode assertion, Kind simpleKind);
+ ArithVar determineArithVar(const Polynomial& p) const;
+ ArithVar determineArithVar(TNode assertion) const;
/**
* Splits the disequalities in d_diseq that are violated using lemmas on demand.
@@ -317,6 +331,8 @@ private:
*/
bool splitDisequalities();
+ /** A Difference variable is known to be 0.*/
+ void zeroDifferenceDetected(ArithVar x);
/**
@@ -364,9 +380,10 @@ private:
* a node describing this conflict is returned.
* If this new bound is not in conflict, Node::null() is returned.
*/
- Node AssertLower(ArithVar x, DeltaRational& c, TNode orig);
- Node AssertUpper(ArithVar x, DeltaRational& c, TNode orig);
- Node AssertEquality(ArithVar x, DeltaRational& c, TNode orig);
+ Node AssertLower(Constraint constraint);
+ Node AssertUpper(Constraint constraint);
+ Node AssertEquality(Constraint constraint);
+ Node AssertDisequality(Constraint constraint);
/** Tracks the bounds that were updated in the current round. */
PermissiveBackArithVarSet d_updatedBounds;
@@ -401,11 +418,6 @@ private:
Node assertionCases(TNode assertion);
/**
- * This is used for reporting conflicts caused by disequalities during assertionCases.
- */
- Node disequalityConflict(TNode eq, TNode lb, TNode ub);
-
- /**
* Returns the basic variable with the shorted row containg a non-basic variable.
* If no such row exists, return ARITHVAR_SENTINEL.
*/
diff --git a/src/theory/theory.cpp b/src/theory/theory.cpp
index afd311bf2..cde65aa0f 100644
--- a/src/theory/theory.cpp
+++ b/src/theory/theory.cpp
@@ -83,5 +83,10 @@ void Theory::printFacts(std::ostream& os) const {
}
}
+void Theory::debugPrintFacts() const{
+ cout << "Theory::debugPrintFacts()" << endl;
+ printFacts(cout);
+}
+
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/theory.h b/src/theory/theory.h
index 28fdc8cbe..2b91da3b2 100644
--- a/src/theory/theory.h
+++ b/src/theory/theory.h
@@ -263,6 +263,7 @@ protected:
static TheoryId s_uninterpretedSortOwner;
void printFacts(std::ostream& os) const;
+ void debugPrintFacts() const;
public:
diff --git a/src/util/integer_cln_imp.h b/src/util/integer_cln_imp.h
index 9d67e8fba..d3e5c07ca 100644
--- a/src/util/integer_cln_imp.h
+++ b/src/util/integer_cln_imp.h
@@ -366,6 +366,18 @@ public:
return cln::cl_I_to_int(sgn);
}
+ bool isZero() const {
+ return cln::zerop(d_value);
+ }
+
+ bool isOne() const {
+ return d_value == 1;
+ }
+
+ bool isNegativeOne() const {
+ return d_value == -1;
+ }
+
//friend std::ostream& operator<<(std::ostream& os, const Integer& n);
long getLong() const {
diff --git a/src/util/integer_gmp_imp.h b/src/util/integer_gmp_imp.h
index ceb585852..74b4adad0 100644
--- a/src/util/integer_gmp_imp.h
+++ b/src/util/integer_gmp_imp.h
@@ -276,6 +276,18 @@ public:
return mpz_sgn(d_value.get_mpz_t());
}
+ bool isZero() const {
+ return sgn() == 0;
+ }
+
+ bool isOne() const {
+ return mpz_cmp_si(d_value.get_mpz_t(), 1) == 0;
+ }
+
+ bool isNegativeOne() const {
+ return mpz_cmp_si(d_value.get_mpz_t(), -1) == 0;
+ }
+
/**
* Raise this Integer to the power <code>exp</code>.
*
diff --git a/src/util/options.cpp b/src/util/options.cpp
index b6956a31b..b6a306ee0 100644
--- a/src/util/options.cpp
+++ b/src/util/options.cpp
@@ -110,6 +110,7 @@ Options::Options() :
ufSymmetryBreaker(false),
ufSymmetryBreakerSetByUser(false),
dioSolver(true),
+ arithRewriteEq(true),
lemmaOutputChannel(NULL),
lemmaInputChannel(NULL),
threads(2),// default should be 1 probably, but say 2 for now
@@ -183,6 +184,7 @@ Additional CVC4 options:\n\
--enable-symmetry-breaker turns on UF symmetry breaker (Deharbe et al., CADE 2011) [on by default only for QF_UF]\n\
--disable-symmetry-breaker turns off UF symmetry breaker\n\
--disable-dio-solver turns off Linear Diophantine Equation solver (Griggio, JSAT 2012)\n\
+ --disable-arith-rewrite-equalities turns off the preprocessing rewrite turning equalities into a conjunction of inequalities.\n \
--threads=N sets the number of solver threads\n\
--threadN=string configures thread N (0..#threads-1)\n\
--filter-lemma-length=N don't share lemmas strictly longer than N\n\
@@ -356,6 +358,7 @@ enum OptionValue {
ARITHMETIC_PIVOT_THRESHOLD,
ARITHMETIC_PROP_MAX_LENGTH,
ARITHMETIC_DIO_SOLVER,
+ ARITHMETIC_REWRITE_EQUALITIES,
ENABLE_SYMMETRY_BREAKER,
DISABLE_SYMMETRY_BREAKER,
PARALLEL_THREADS,
@@ -445,6 +448,7 @@ static struct option cmdlineOptions[] = {
{ "print-winner", no_argument , NULL, PRINT_WINNER },
{ "disable-arithmetic-propagation", no_argument, NULL, ARITHMETIC_PROPAGATION },
{ "disable-dio-solver", no_argument, NULL, ARITHMETIC_DIO_SOLVER },
+ { "disable-arith-rewrite-equalities", no_argument, NULL, ARITHMETIC_REWRITE_EQUALITIES },
{ "enable-symmetry-breaker", no_argument, NULL, ENABLE_SYMMETRY_BREAKER },
{ "disable-symmetry-breaker", no_argument, NULL, DISABLE_SYMMETRY_BREAKER },
{ "threads", required_argument, NULL, PARALLEL_THREADS },
@@ -796,6 +800,10 @@ throw(OptionException) {
dioSolver = false;
break;
+ case ARITHMETIC_REWRITE_EQUALITIES:
+ arithRewriteEq = false;
+ break;
+
case ENABLE_SYMMETRY_BREAKER:
ufSymmetryBreaker = true;
ufSymmetryBreakerSetByUser = true;
diff --git a/src/util/options.h b/src/util/options.h
index 4bf8b5b75..c7fbcd896 100644
--- a/src/util/options.h
+++ b/src/util/options.h
@@ -156,7 +156,7 @@ struct CVC4_PUBLIC Options {
/** Whether we produce proofs. */
bool proof;
-
+
/** Whether we support SmtEngine::getAssignment() for this run. */
bool produceAssignments;
@@ -195,7 +195,7 @@ struct CVC4_PUBLIC Options {
/** Variable activity decay factor for Minisat */
double satVarDecay;
-
+
/** Clause activity decay factor for Minisat */
double satClauseDecay;
@@ -238,6 +238,12 @@ struct CVC4_PUBLIC Options {
*/
bool dioSolver;
+ /**
+ * Whether to split (= x y) into (and (<= x y) (>= x y)) in
+ * arithmetic preprocessing.
+ */
+ bool arithRewriteEq;
+
/** The output channel to receive notfication events for new lemmas */
LemmaOutputChannel* lemmaOutputChannel;
LemmaInputChannel* lemmaInputChannel;
@@ -251,7 +257,7 @@ struct CVC4_PUBLIC Options {
/** Thread ID, for internal use in case of multi-threaded run */
int thread_id;
- /**
+ /**
* In multi-threaded setting print output of each thread at the
* end of run, separated by a divider ("----").
**/
diff --git a/src/util/rational_cln_imp.h b/src/util/rational_cln_imp.h
index 69eede0d6..c2da0e7ed 100644
--- a/src/util/rational_cln_imp.h
+++ b/src/util/rational_cln_imp.h
@@ -196,6 +196,14 @@ public:
return cln::zerop(d_value);
}
+ bool isOne() const {
+ return d_value == 1;
+ }
+
+ bool isNegativeOne() const {
+ return d_value == -1;
+ }
+
Rational abs() const {
if(sgn() < 0){
return -(*this);
diff --git a/src/util/rational_gmp_imp.h b/src/util/rational_gmp_imp.h
index 751c8f137..ef0720263 100644
--- a/src/util/rational_gmp_imp.h
+++ b/src/util/rational_gmp_imp.h
@@ -173,6 +173,14 @@ public:
return sgn() == 0;
}
+ bool isOne() const {
+ return mpq_cmp_si(d_value.get_mpq_t(), 1, 1) == 0;
+ }
+
+ bool isNegativeOne() const {
+ return mpq_cmp_si(d_value.get_mpq_t(), -1, 1) == 0;
+ }
+
Rational abs() const {
if(sgn() < 0){
return -(*this);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback