summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlianah <lianahady@gmail.com>2013-02-01 19:43:37 -0500
committerlianah <lianahady@gmail.com>2013-02-01 19:43:37 -0500
commit764bda53ed154495286d7ff117aa7182a8ce5f7b (patch)
treead0466a34055b19b1d91e0590415f7e93cee8f27 /src
parentf0988a89ecc0e5f2995dc8d390b5e9df2fa5421f (diff)
parent8c5e895525ec87ba0285c281b45144eab79b66f9 (diff)
merged master into branch
Diffstat (limited to 'src')
-rw-r--r--src/expr/attribute_internals.h2
-rw-r--r--src/expr/expr_manager_template.h2
-rw-r--r--src/expr/expr_template.h2
-rw-r--r--src/expr/kind_template.h2
-rw-r--r--src/expr/type.cpp127
-rw-r--r--src/expr/type.h121
-rw-r--r--src/include/cvc4_public.h14
-rw-r--r--src/lib/Makefile.am7
-rw-r--r--src/lib/clock_gettime.c34
-rw-r--r--src/lib/clock_gettime.h24
-rw-r--r--src/lib/ffs.c40
-rw-r--r--src/lib/ffs.h42
-rw-r--r--src/lib/strtok_r.c41
-rw-r--r--src/lib/strtok_r.h42
-rw-r--r--src/main/Makefile.am8
-rw-r--r--src/main/driver_unified.cpp1
-rw-r--r--src/main/util.cpp20
-rw-r--r--src/options/options.h2
-rw-r--r--src/options/options_template.cpp12
-rw-r--r--src/parser/antlr_input.cpp9
-rw-r--r--src/parser/memory_mapped_input_buffer.cpp17
-rw-r--r--src/parser/parser.cpp9
-rw-r--r--src/parser/parser.h6
-rw-r--r--src/parser/smt1/Smt1.g94
-rw-r--r--src/parser/smt2/Smt2.g43
-rw-r--r--src/parser/tptp/tptp.cpp2
-rw-r--r--src/printer/cvc/cvc_printer.cpp8
-rw-r--r--src/printer/smt2/smt2_printer.cpp9
-rw-r--r--src/printer/smt2/smt2_printer.h1
-rw-r--r--src/proof/proof_manager.cpp2
-rw-r--r--src/proof/proof_manager.h2
-rw-r--r--src/prop/bvminisat/core/Solver.cc2
-rw-r--r--src/prop/sat_solver.h3
-rw-r--r--src/smt/options_handlers.h1
-rw-r--r--src/smt/smt_engine.cpp37
-rw-r--r--src/smt/smt_engine.h4
-rw-r--r--src/theory/arith/arith_rewriter.cpp2
-rw-r--r--src/theory/arith/arith_static_learner.cpp13
-rw-r--r--src/theory/arith/arith_static_learner.h1
-rw-r--r--src/theory/arith/delta_rational.cpp12
-rw-r--r--src/theory/arith/delta_rational.h4
-rw-r--r--src/theory/arith/options9
-rw-r--r--src/theory/arith/partial_model.h2
-rw-r--r--src/theory/arith/theory_arith.cpp124
-rw-r--r--src/theory/arith/theory_arith.h5
-rw-r--r--src/theory/bv/bitblast_strategies.cpp22
-rw-r--r--src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h4
-rw-r--r--src/theory/bv/theory_bv_rewrite_rules_simplification.h4
-rw-r--r--src/theory/datatypes/options2
-rw-r--r--src/theory/datatypes/theory_datatypes.cpp87
-rw-r--r--src/theory/datatypes/theory_datatypes.h4
-rw-r--r--src/theory/datatypes/type_enumerator.h20
-rw-r--r--src/theory/model.cpp114
-rw-r--r--src/theory/quantifiers/first_order_model.cpp4
-rw-r--r--src/theory/quantifiers/first_order_model.h2
-rw-r--r--src/theory/quantifiers/inst_match.cpp82
-rw-r--r--src/theory/quantifiers/inst_match.h37
-rwxr-xr-xsrc/theory/quantifiers/inst_strategy_e_matching.h3
-rw-r--r--src/theory/quantifiers/instantiation_engine.cpp11
-rw-r--r--src/theory/quantifiers/options3
-rw-r--r--src/theory/quantifiers/quantifiers_attributes.cpp2
-rw-r--r--src/theory/quantifiers/quantifiers_attributes.h2
-rw-r--r--src/theory/quantifiers/theory_quantifiers.cpp12
-rw-r--r--src/theory/quantifiers/theory_quantifiers.h2
-rw-r--r--src/theory/quantifiers_engine.cpp27
-rw-r--r--src/theory/quantifiers_engine.h7
-rw-r--r--src/theory/rewriterules/theory_rewriterules.cpp2
-rw-r--r--src/theory/theory.h26
-rw-r--r--src/theory/theory_engine.cpp34
-rw-r--r--src/util/bitvector.h19
-rw-r--r--src/util/integer_cln_imp.h72
-rw-r--r--src/util/integer_gmp_imp.h79
-rw-r--r--src/util/node_visitor.h7
-rw-r--r--src/util/record.h2
-rw-r--r--src/util/statistics_registry.h11
75 files changed, 1102 insertions, 565 deletions
diff --git a/src/expr/attribute_internals.h b/src/expr/attribute_internals.h
index a085161bc..9a14caec5 100644
--- a/src/expr/attribute_internals.h
+++ b/src/expr/attribute_internals.h
@@ -752,7 +752,7 @@ public:
table_value_type table_value_type;
typedef attr::AttributeTraits<table_value_type, context_dep> traits;
uint64_t id = attr::LastAttributeId<table_value_type, context_dep>::s_id++;
- Assert(traits::cleanup.size() == id);// sanity check
+ //Assert(traits::cleanup.size() == id);// sanity check
traits::cleanup.push_back(attr::getCleanupStrategy<value_t,
CleanupStrategy>::fn);
return id;
diff --git a/src/expr/expr_manager_template.h b/src/expr/expr_manager_template.h
index b9cae9431..09018cbfd 100644
--- a/src/expr/expr_manager_template.h
+++ b/src/expr/expr_manager_template.h
@@ -43,7 +43,7 @@ class SmtEngine;
class NodeManager;
class Options;
class IntStat;
-class ExprManagerMapCollection;
+struct ExprManagerMapCollection;
class StatisticsRegistry;
namespace expr {
diff --git a/src/expr/expr_template.h b/src/expr/expr_template.h
index 442d29ac9..b353ec5dc 100644
--- a/src/expr/expr_template.h
+++ b/src/expr/expr_template.h
@@ -67,7 +67,7 @@ namespace prop {
class TheoryProxy;
}/* CVC4::prop namespace */
-class ExprManagerMapCollection;
+struct ExprManagerMapCollection;
struct ExprHashFunction;
diff --git a/src/expr/kind_template.h b/src/expr/kind_template.h
index 47504b0e4..0cab4e628 100644
--- a/src/expr/kind_template.h
+++ b/src/expr/kind_template.h
@@ -27,7 +27,7 @@
namespace CVC4 {
namespace kind {
-enum Kind_t {
+enum CVC4_PUBLIC Kind_t {
UNDEFINED_KIND = -1, /**< undefined */
NULL_EXPR, /**< Null kind */
${kind_decls}
diff --git a/src/expr/type.cpp b/src/expr/type.cpp
index cc52b11b9..4e95c0fe2 100644
--- a/src/expr/type.cpp
+++ b/src/expr/type.cpp
@@ -204,111 +204,48 @@ bool Type::isBoolean() const {
return d_typeNode->isBoolean();
}
-/** Cast to a Boolean type */
-Type::operator BooleanType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isBoolean(), this);
- return BooleanType(*this);
-}
-
/** Is this the integer type? */
bool Type::isInteger() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isInteger();
}
-/** Cast to a integer type */
-Type::operator IntegerType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isInteger(), this);
- return IntegerType(*this);
-}
-
/** Is this the real type? */
bool Type::isReal() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isReal();
}
-/** Cast to a real type */
-Type::operator RealType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isReal(), this);
- return RealType(*this);
-}
-
/** Is this the string type? */
bool Type::isString() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isString();
}
-/** Cast to a string type */
-Type::operator StringType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isString(), this);
- return StringType(*this);
-}
-
/** Is this the bit-vector type? */
bool Type::isBitVector() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isBitVector();
}
-/** Cast to a bit-vector type */
-Type::operator BitVectorType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isBitVector(), this);
- return BitVectorType(*this);
-}
-
-/** Cast to a Constructor type */
-Type::operator DatatypeType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isDatatype(), this);
- return DatatypeType(*this);
-}
-
/** Is this a datatype type? */
bool Type::isDatatype() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isDatatype() || d_typeNode->isParametricDatatype();
}
-/** Cast to a Constructor type */
-Type::operator ConstructorType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isConstructor(), this);
- return ConstructorType(*this);
-}
-
/** Is this the Constructor type? */
bool Type::isConstructor() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isConstructor();
}
-/** Cast to a Selector type */
-Type::operator SelectorType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isSelector(), this);
- return SelectorType(*this);
-}
-
/** Is this the Selector type? */
bool Type::isSelector() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isSelector();
}
-/** Cast to a Tester type */
-Type::operator TesterType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isTester(), this);
- return TesterType(*this);
-}
-
/** Is this the Tester type? */
bool Type::isTester() const {
NodeManagerScope nms(d_nodeManager);
@@ -330,64 +267,30 @@ bool Type::isPredicate() const {
return d_typeNode->isPredicate();
}
-/** Cast to a function type */
-Type::operator FunctionType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isFunction(), this);
- return FunctionType(*this);
-}
-
/** Is this a tuple type? */
bool Type::isTuple() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isTuple();
}
-/** Cast to a tuple type */
-Type::operator TupleType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isTuple(), this);
- return TupleType(*this);
-}
-
/** Is this a record type? */
bool Type::isRecord() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isRecord();
}
-/** Cast to a record type */
-Type::operator RecordType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isRecord(), this);
- return RecordType(*this);
-}
-
/** Is this a symbolic expression type? */
bool Type::isSExpr() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isSExpr();
}
-/** Cast to a symbolic expression type */
-Type::operator SExprType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isSExpr(), this);
- return SExprType(*this);
-}
-
/** Is this an array type? */
bool Type::isArray() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isArray();
}
-/** Cast to an array type */
-Type::operator ArrayType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- return ArrayType(*this);
-}
-
/** Is this a sort kind */
bool Type::isSort() const {
NodeManagerScope nms(d_nodeManager);
@@ -395,25 +298,11 @@ bool Type::isSort() const {
}
/** Cast to a sort type */
-Type::operator SortType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isSort(), this);
- return SortType(*this);
-}
-
-/** Is this a sort constructor kind */
bool Type::isSortConstructor() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isSortConstructor();
}
-/** Cast to a sort constructor type */
-Type::operator SortConstructorType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isSortConstructor(), this);
- return SortConstructorType(*this);
-}
-
/** Is this a predicate subtype */
/* - not in release 1.0
bool Type::isPredicateSubtype() const {
@@ -422,28 +311,12 @@ bool Type::isPredicateSubtype() const {
}
*/
-/** Cast to a predicate subtype */
-/* - not in release 1.0
-Type::operator PredicateSubtype() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isPredicateSubtype(), this);
- return PredicateSubtype(*this);
-}
-*/
-
/** Is this an integer subrange */
bool Type::isSubrange() const {
NodeManagerScope nms(d_nodeManager);
return d_typeNode->isSubrange();
}
-/** Cast to a predicate subtype */
-Type::operator SubrangeType() const throw(IllegalArgumentException) {
- NodeManagerScope nms(d_nodeManager);
- CheckArgument(isNull() || isSubrange(), this);
- return SubrangeType(*this);
-}
-
vector<Type> FunctionType::getArgTypes() const {
NodeManagerScope nms(d_nodeManager);
vector<Type> args;
diff --git a/src/expr/type.h b/src/expr/type.h
index 4223d71ab..ce6291cd8 100644
--- a/src/expr/type.h
+++ b/src/expr/type.h
@@ -30,15 +30,15 @@
namespace CVC4 {
class NodeManager;
-class ExprManager;
-class Expr;
+class CVC4_PUBLIC ExprManager;
+class CVC4_PUBLIC Expr;
class TypeNode;
-class ExprManagerMapCollection;
+struct CVC4_PUBLIC ExprManagerMapCollection;
-class SmtEngine;
+class CVC4_PUBLIC SmtEngine;
-class Datatype;
-class Record;
+class CVC4_PUBLIC Datatype;
+class CVC4_PUBLIC Record;
template <bool ref_count>
class NodeTemplate;
@@ -240,60 +240,30 @@ public:
bool isBoolean() const;
/**
- * Cast this type to a Boolean type
- * @return the BooleanType
- */
- operator BooleanType() const throw(IllegalArgumentException);
-
- /**
* Is this the integer type?
* @return true if the type is a integer type
*/
bool isInteger() const;
/**
- * Cast this type to a integer type
- * @return the IntegerType
- */
- operator IntegerType() const throw(IllegalArgumentException);
-
- /**
* Is this the real type?
* @return true if the type is a real type
*/
bool isReal() const;
/**
- * Cast this type to a real type
- * @return the RealType
- */
- operator RealType() const throw(IllegalArgumentException);
-
- /**
* Is this the string type?
* @return true if the type is the string type
*/
bool isString() const;
/**
- * Cast this type to a string type
- * @return the StringType
- */
- operator StringType() const throw(IllegalArgumentException);
-
- /**
* Is this the bit-vector type?
* @return true if the type is a bit-vector type
*/
bool isBitVector() const;
/**
- * Cast this type to a bit-vector type
- * @return the BitVectorType
- */
- operator BitVectorType() const throw(IllegalArgumentException);
-
- /**
* Is this a function type?
* @return true if the type is a function type
*/
@@ -307,132 +277,66 @@ public:
bool isPredicate() const;
/**
- * Cast this type to a function type
- * @return the FunctionType
- */
- operator FunctionType() const throw(IllegalArgumentException);
-
- /**
* Is this a tuple type?
* @return true if the type is a tuple type
*/
bool isTuple() const;
/**
- * Cast this type to a tuple type
- * @return the TupleType
- */
- operator TupleType() const throw(IllegalArgumentException);
-
- /**
* Is this a record type?
* @return true if the type is a record type
*/
bool isRecord() const;
/**
- * Cast this type to a record type
- * @return the RecordType
- */
- operator RecordType() const throw(IllegalArgumentException);
-
- /**
* Is this a symbolic expression type?
* @return true if the type is a symbolic expression type
*/
bool isSExpr() const;
/**
- * Cast this type to a symbolic expression type
- * @return the SExprType
- */
- operator SExprType() const throw(IllegalArgumentException);
-
- /**
* Is this an array type?
* @return true if the type is a array type
*/
bool isArray() const;
/**
- * Cast this type to an array type
- * @return the ArrayType
- */
- operator ArrayType() const throw(IllegalArgumentException);
-
- /**
* Is this a datatype type?
* @return true if the type is a datatype type
*/
bool isDatatype() const;
/**
- * Cast this type to a datatype type
- * @return the DatatypeType
- */
- operator DatatypeType() const throw(IllegalArgumentException);
-
- /**
* Is this a constructor type?
* @return true if the type is a constructor type
*/
bool isConstructor() const;
/**
- * Cast this type to a constructor type
- * @return the ConstructorType
- */
- operator ConstructorType() const throw(IllegalArgumentException);
-
- /**
* Is this a selector type?
* @return true if the type is a selector type
*/
bool isSelector() const;
/**
- * Cast this type to a selector type
- * @return the SelectorType
- */
- operator SelectorType() const throw(IllegalArgumentException);
-
- /**
* Is this a tester type?
* @return true if the type is a tester type
*/
bool isTester() const;
/**
- * Cast this type to a tester type
- * @return the TesterType
- */
- operator TesterType() const throw(IllegalArgumentException);
-
- /**
* Is this a sort kind?
* @return true if this is a sort kind
*/
bool isSort() const;
/**
- * Cast this type to a sort type
- * @return the sort type
- */
- operator SortType() const throw(IllegalArgumentException);
-
- /**
* Is this a sort constructor kind?
* @return true if this is a sort constructor kind
*/
bool isSortConstructor() const;
/**
- * Cast this type to a sort constructor type
- * @return the sort constructor type
- */
- operator SortConstructorType() const throw(IllegalArgumentException);
-
- /**
* Is this a predicate subtype?
* @return true if this is a predicate subtype
*/
@@ -440,25 +344,12 @@ public:
//bool isPredicateSubtype() const;
/**
- * Cast this type to a predicate subtype
- * @return the predicate subtype
- */
- // not in release 1.0
- //operator PredicateSubtype() const throw(IllegalArgumentException);
-
- /**
* Is this an integer subrange type?
* @return true if this is an integer subrange type
*/
bool isSubrange() const;
/**
- * Cast this type to an integer subrange type
- * @return the integer subrange type
- */
- operator SubrangeType() const throw(IllegalArgumentException);
-
- /**
* Outputs a string representation of this type to the stream.
* @param out the stream to output to
*/
diff --git a/src/include/cvc4_public.h b/src/include/cvc4_public.h
index 6c546a147..9993e5f18 100644
--- a/src/include/cvc4_public.h
+++ b/src/include/cvc4_public.h
@@ -22,19 +22,7 @@
#include <stdint.h>
#if defined _WIN32 || defined __CYGWIN__
-# ifdef BUILDING_DLL
-# ifdef __GNUC__
-# define CVC4_PUBLIC __attribute__((__dllexport__))
-# else /* ! __GNUC__ */
-# define CVC4_PUBLIC __declspec(dllexport)
-# endif /* __GNUC__ */
-# else /* BUILDING_DLL */
-# ifdef __GNUC__
-# define CVC4_PUBLIC __attribute__((__dllimport__))
-# else /* ! __GNUC__ */
-# define CVC4_PUBLIC __declspec(dllimport)
-# endif /* __GNUC__ */
-# endif /* BUILDING_DLL */
+# define CVC4_PUBLIC
#else /* !( defined _WIN32 || defined __CYGWIN__ ) */
# if __GNUC__ >= 4
# define CVC4_PUBLIC __attribute__ ((__visibility__("default")))
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index a6ea59e95..61f9e2d70 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -15,5 +15,8 @@ libreplacements_la_LIBADD = \
EXTRA_DIST = \
replacements.h \
clock_gettime.c \
- clock_gettime.h
-
+ clock_gettime.h \
+ strtok_r.c \
+ strtok_r.h \
+ ffs.c \
+ ffs.h
diff --git a/src/lib/clock_gettime.c b/src/lib/clock_gettime.c
index 77409c71a..054a8c112 100644
--- a/src/lib/clock_gettime.c
+++ b/src/lib/clock_gettime.c
@@ -18,25 +18,25 @@
#include "cvc4_private.h"
-#include <stdio.h>
-#include <errno.h>
-#include <time.h>
-
#include "lib/clock_gettime.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-#ifndef __APPLE__
-# warning This code assumes you're on Mac OS X, and you don't seem to be. You'll likely have problems.
-#endif /* __APPLE__ */
+#if !(defined(__APPLE__) || defined(__WIN32__))
+# warning "This code assumes you're on Mac OS X or Win32, and you don't seem to be. You'll likely have problems."
+#endif /* !(__APPLE__ || __WIN32__) */
+#ifdef __APPLE__
+
+#include <stdio.h>
+#include <errno.h>
#include <mach/mach_time.h>
static double s_clockconv = 0.0;
-long clock_gettime(clockid_t which_clock, struct timespec *tp) {
+long clock_gettime(clockid_t which_clock, struct timespec* tp) {
if( s_clockconv == 0.0 ) {
mach_timebase_info_data_t tb;
kern_return_t err = mach_timebase_info(&tb);
@@ -64,6 +64,24 @@ long clock_gettime(clockid_t which_clock, struct timespec *tp) {
return 0;
}
+#else /* else we're __WIN32__ */
+
+#include <time.h>
+#include <windows.h>
+
+long clock_gettime(clockid_t which_clock, struct timespec* tp) {
+ if(tp != NULL) {
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft);
+ uint64_t nanos = ((((uint64_t)ft.dwHighDateTime) << 32) | ft.dwLowDateTime) * 100;
+ tp->tv_sec = nanos / 1000000000ul;
+ tp->tv_nsec = nanos % 1000000000ul;
+ }
+ return 0;
+}
+
+#endif /* __APPLE__ / __WIN32__ */
+
#ifdef __cplusplus
}/* extern "C" */
#endif /* __cplusplus */
diff --git a/src/lib/clock_gettime.h b/src/lib/clock_gettime.h
index ac4ca1f85..6a8dd57ff 100644
--- a/src/lib/clock_gettime.h
+++ b/src/lib/clock_gettime.h
@@ -30,13 +30,34 @@
/* otherwise, we have to define it */
+#ifdef __WIN32__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct timespec {
+ uint64_t tv_sec;
+ int32_t tv_nsec;
+};/* struct timespec */
+
+#ifdef __cplusplus
+}/* extern "C" */
+#endif /* __cplusplus */
+
+#else /* ! __WIN32__ */
+
/* get timespec from <time.h> */
#include <time.h>
+#endif /* __WIN32__ */
+
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
+struct timespec;
+
typedef enum {
CLOCK_REALTIME,
CLOCK_MONOTONIC,
@@ -44,7 +65,7 @@ typedef enum {
CLOCK_MONOTONIC_HR
} clockid_t;
-long clock_gettime(clockid_t which_clock, struct timespec *tp);
+long clock_gettime(clockid_t which_clock, struct timespec* tp);
#ifdef __cplusplus
}/* extern "C" */
@@ -52,4 +73,3 @@ long clock_gettime(clockid_t which_clock, struct timespec *tp);
#endif /* HAVE_CLOCK_GETTIME */
#endif /*__CVC4__LIB__CLOCK_GETTIME_H */
-
diff --git a/src/lib/ffs.c b/src/lib/ffs.c
new file mode 100644
index 000000000..5c25211ce
--- /dev/null
+++ b/src/lib/ffs.c
@@ -0,0 +1,40 @@
+/********************* */
+/*! \file ffs.c
+ ** \verbatim
+ ** Original author: mdeters
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of CVC4.
+ ** Copyright (c) 2009-2013 New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Replacement for ffs() for systems without it (like Win32)
+ **
+ ** Replacement for ffs() for systems without it (like Win32).
+ **/
+
+#include "cvc4_private.h"
+
+#include "lib/ffs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int ffs(int i) {
+ long mask = 0x1;
+ int pos = 1;
+ while(pos <= sizeof(int) * 8) {
+ if((mask & i) != 0) {
+ return pos;
+ }
+ ++pos;
+ mask <<= 1;
+ }
+ return 0;
+}
+
+#ifdef __cplusplus
+}/* extern "C" */
+#endif /* __cplusplus */
diff --git a/src/lib/ffs.h b/src/lib/ffs.h
new file mode 100644
index 000000000..9b038d429
--- /dev/null
+++ b/src/lib/ffs.h
@@ -0,0 +1,42 @@
+/********************* */
+/*! \file ffs.h
+ ** \verbatim
+ ** Original author: mdeters
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of CVC4.
+ ** Copyright (c) 2009-2013 New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Replacement for ffs() for systems without it (like Win32)
+ **
+ ** Replacement for ffs() for systems without it (like Win32).
+ **/
+
+#include "cvc4_public.h"
+
+#ifndef __CVC4__LIB__FFS_H
+#define __CVC4__LIB__FFS_H
+
+#ifdef HAVE_FFS
+
+// available in strings.h
+#include <strings.h>
+
+#else /* ! HAVE_FFS */
+
+#include "lib/replacements.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int ffs(int i);
+
+#ifdef __cplusplus
+}/* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* HAVE_FFS */
+#endif /* __CVC4__LIB__FFS_H */
diff --git a/src/lib/strtok_r.c b/src/lib/strtok_r.c
new file mode 100644
index 000000000..b8df95359
--- /dev/null
+++ b/src/lib/strtok_r.c
@@ -0,0 +1,41 @@
+/********************* */
+/*! \file strtok_r.c
+ ** \verbatim
+ ** Original author: mdeters
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of CVC4.
+ ** Copyright (c) 2009-2013 New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Replacement for strtok_r() for systems without it (like Win32)
+ **
+ ** Replacement for strtok_r() for systems without it (like Win32).
+ **/
+
+#include "cvc4_private.h"
+
+#include "lib/strtok_r.h"
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+char* strtok_r(char *str, const char *delim, char **saveptr) {
+ if(str == NULL) {
+ char* retval = strtok(*saveptr, delim);
+ *saveptr = retval + strlen(retval) + 1;
+ return retval;
+ } else {
+ char* retval = strtok(str, delim);
+ *saveptr = retval + strlen(retval) + 1;
+ return retval;
+ }
+}
+
+#ifdef __cplusplus
+}/* extern "C" */
+#endif /* __cplusplus */
diff --git a/src/lib/strtok_r.h b/src/lib/strtok_r.h
new file mode 100644
index 000000000..6b3387e6b
--- /dev/null
+++ b/src/lib/strtok_r.h
@@ -0,0 +1,42 @@
+/********************* */
+/*! \file strtok_r.h
+ ** \verbatim
+ ** Original author: mdeters
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of CVC4.
+ ** Copyright (c) 2009-2013 New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Replacement for strtok_r() for systems without it (like Win32)
+ **
+ ** Replacement for strtok_r() for systems without it (like Win32).
+ **/
+
+#include "cvc4_public.h"
+
+#ifndef __CVC4__LIB__STRTOK_R_H
+#define __CVC4__LIB__STRTOK_R_H
+
+#ifdef HAVE_STRTOK_R
+
+// available in string.h
+#include <string.h>
+
+#else /* ! HAVE_STRTOK_R */
+
+#include "lib/replacements.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+char* strtok_r(char *str, const char *delim, char **saveptr);
+
+#ifdef __cplusplus
+}/* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* HAVE_STRTOK_R */
+#endif /* __CVC4__LIB__STRTOK_R_H */
diff --git a/src/main/Makefile.am b/src/main/Makefile.am
index 952951655..64a43eb02 100644
--- a/src/main/Makefile.am
+++ b/src/main/Makefile.am
@@ -41,9 +41,9 @@ pcvc4_LDADD += $(BOOST_THREAD_LIBS) -lpthread
pcvc4_LDADD += $(BOOST_THREAD_LDFLAGS)
if STATIC_BINARY
-pcvc4_LINK = $(CXXLINK) -all-static
+pcvc4_LINK = $(CXXLINK) -all-static $(pcvc4_LDFLAGS)
else
-pcvc4_LINK = $(CXXLINK)
+pcvc4_LINK = $(CXXLINK) $(pcvc4_LDFLAGS)
endif
endif
@@ -87,8 +87,8 @@ clean-local:
rm -f $(BUILT_SOURCES)
if STATIC_BINARY
-cvc4_LINK = $(CXXLINK) -all-static
+cvc4_LINK = $(CXXLINK) -all-static $(cvc4_LDFLAGS)
else
-cvc4_LINK = $(CXXLINK)
+cvc4_LINK = $(CXXLINK) $(cvc4_LDFLAGS)
endif
diff --git a/src/main/driver_unified.cpp b/src/main/driver_unified.cpp
index a9a7ef8c5..b429ad0c2 100644
--- a/src/main/driver_unified.cpp
+++ b/src/main/driver_unified.cpp
@@ -180,6 +180,7 @@ int runCvc4(int argc, char* argv[], Options& opts) {
// important even for muzzled builds (to get result output right)
*opts[options::out] << Expr::setlanguage(opts[options::outputLanguage]);
+ DumpChannel.getStream() << Expr::setlanguage(opts[options::outputLanguage]);
// Create the expression manager using appropriate options
# ifndef PORTFOLIO_BUILD
diff --git a/src/main/util.cpp b/src/main/util.cpp
index 5e7436580..9ade23630 100644
--- a/src/main/util.cpp
+++ b/src/main/util.cpp
@@ -19,10 +19,15 @@
#include <cerrno>
#include <exception>
#include <string.h>
+
+#ifndef __WIN32__
+
#include <signal.h>
#include <sys/resource.h>
#include <unistd.h>
+#endif /* __WIN32__ */
+
#include "util/exception.h"
#include "options/options.h"
#include "util/statistics.h"
@@ -44,9 +49,6 @@ namespace CVC4 {
namespace main {
-size_t cvc4StackSize;
-void* cvc4StackBase;
-
/**
* If true, will not spin on segfault even when CVC4_DEBUG is on.
* Useful for nightly regressions, noninteractive performance runs
@@ -54,6 +56,11 @@ void* cvc4StackBase;
*/
bool segvNoSpin = false;
+#ifndef __WIN32__
+
+size_t cvc4StackSize;
+void* cvc4StackBase;
+
/** Handler for SIGXCPU, i.e., timeout. */
void timeout_handler(int sig, siginfo_t* info, void*) {
fprintf(stderr, "CVC4 interrupted by timeout.\n");
@@ -144,10 +151,12 @@ void ill_handler(int sig, siginfo_t* info, void*) {
#endif /* CVC4_DEBUG */
}
+#endif /* __WIN32__ */
+
static terminate_handler default_terminator;
void cvc4unexpected() {
-#ifdef CVC4_DEBUG
+#if defined(CVC4_DEBUG) && !defined(__WIN32__)
fprintf(stderr, "\n"
"CVC4 threw an \"unexpected\" exception (one that wasn't properly "
"specified\nin the throws() specifier for the throwing function)."
@@ -204,6 +213,7 @@ void cvc4terminate() {
/** Initialize the driver. Sets signal handlers for SIGINT and SIGSEGV. */
void cvc4_init() throw(Exception) {
+#ifndef __WIN32__
stack_t ss;
ss.ss_sp = malloc(SIGSTKSZ);
if(ss.ss_sp == NULL) {
@@ -262,6 +272,8 @@ void cvc4_init() throw(Exception) {
throw Exception(string("sigaction(SIGILL) failure: ") + strerror(errno));
}
+#endif /* __WIN32__ */
+
set_unexpected(cvc4unexpected);
default_terminator = set_terminate(cvc4terminate);
}
diff --git a/src/options/options.h b/src/options/options.h
index 2d49765f3..5f17f5a5c 100644
--- a/src/options/options.h
+++ b/src/options/options.h
@@ -31,7 +31,7 @@
namespace CVC4 {
namespace options {
- class OptionsHolder;
+ struct OptionsHolder;
}/* CVC4::options namespace */
class ExprStream;
diff --git a/src/options/options_template.cpp b/src/options/options_template.cpp
index d7cd8813b..48834d803 100644
--- a/src/options/options_template.cpp
+++ b/src/options/options_template.cpp
@@ -356,7 +356,7 @@ std::vector<std::string> Options::parseOptions(int argc, char* main_argv[]) thro
// This can be = 1 in newer GNU getopt, but older (< 2007) require = 0.
optind = 0;
#if HAVE_DECL_OPTRESET
- optreset = 1; // on BSD getopt() (e.g. Mac OS), might also need this
+ optreset = 1; // on BSD getopt() (e.g. Mac OS), might need this
#endif /* HAVE_DECL_OPTRESET */
// find the base name of the program
@@ -386,7 +386,9 @@ std::vector<std::string> Options::parseOptions(int argc, char* main_argv[]) thro
Debug("preemptGetopt") << "top of loop, extra_optind == " << extra_optind << ", extra_argc == " << extra_argc << std::endl;
if((extra_optind == 0 ? 1 : extra_optind) < extra_argc) {
#if HAVE_DECL_OPTRESET
- optreset = 1; // on BSD getopt() (e.g. Mac OS), might also need this
+ if(optind_ref != &extra_optind) {
+ optreset = 1; // on BSD getopt() (e.g. Mac OS), might need this
+ }
#endif /* HAVE_DECL_OPTRESET */
old_optind = optind = extra_optind;
optind_ref = &extra_optind;
@@ -425,7 +427,9 @@ std::vector<std::string> Options::parseOptions(int argc, char* main_argv[]) thro
}
if(c == -1) {
#if HAVE_DECL_OPTRESET
- optreset = 1; // on BSD getopt() (e.g. Mac OS), might also need this
+ if(optind_ref != &main_optind) {
+ optreset = 1; // on BSD getopt() (e.g. Mac OS), might need this
+ }
#endif /* HAVE_DECL_OPTRESET */
old_optind = optind = main_optind;
optind_ref = &main_optind;
@@ -457,7 +461,7 @@ std::vector<std::string> Options::parseOptions(int argc, char* main_argv[]) thro
switch(c) {
${all_modules_option_handlers}
-#line 461 "${template}"
+#line 465 "${template}"
case ':':
// This can be a long or short option, and the way to get at the
diff --git a/src/parser/antlr_input.cpp b/src/parser/antlr_input.cpp
index 8987a7572..fbf2b8650 100644
--- a/src/parser/antlr_input.cpp
+++ b/src/parser/antlr_input.cpp
@@ -63,8 +63,13 @@ AntlrInputStream*
AntlrInputStream::newFileInputStream(const std::string& name,
bool useMmap)
throw (InputStreamException) {
+#ifdef _WIN32
+ if(useMmap) {
+ useMmap = false;
+ }
+#endif
pANTLR3_INPUT_STREAM input = NULL;
- if( useMmap ) {
+ if(useMmap) {
input = MemoryMappedInputBufferNew(name);
} else {
// libantlr3c v3.2 isn't source-compatible with v3.4
@@ -74,7 +79,7 @@ AntlrInputStream::newFileInputStream(const std::string& name,
input = antlr3FileStreamNew((pANTLR3_UINT8) name.c_str(), ANTLR3_ENC_8BIT);
#endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
}
- if( input == NULL ) {
+ if(input == NULL) {
throw InputStreamException("Couldn't open file: " + name);
}
return new AntlrInputStream( name, input );
diff --git a/src/parser/memory_mapped_input_buffer.cpp b/src/parser/memory_mapped_input_buffer.cpp
index 9f72ac51c..f110b1145 100644
--- a/src/parser/memory_mapped_input_buffer.cpp
+++ b/src/parser/memory_mapped_input_buffer.cpp
@@ -18,10 +18,15 @@
#include <stdio.h>
#include <stdint.h>
+#include <antlr3input.h>
+
+#ifndef _WIN32
+
#include <cerrno>
#include <sys/mman.h>
#include <sys/stat.h>
-#include <antlr3input.h>
+
+#endif /* _WIN32 */
#include "parser/memory_mapped_input_buffer.h"
#include "util/exception.h"
@@ -31,6 +36,14 @@ namespace parser {
extern "C" {
+#ifdef _WIN32
+
+pANTLR3_INPUT_STREAM MemoryMappedInputBufferNew(const std::string& filename) {
+ return 0;
+}
+
+#else /* ! _WIN32 */
+
static ANTLR3_UINT32
MemoryMapFile(pANTLR3_INPUT_STREAM input, const std::string& filename);
@@ -112,6 +125,8 @@ void UnmapFile(pANTLR3_INPUT_STREAM input) {
input->close(input);
}
+#endif /* _WIN32 */
+
}/* extern "C" */
}/* CVC4::parser namespace */
diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp
index 721dedc70..65d46220b 100644
--- a/src/parser/parser.cpp
+++ b/src/parser/parser.cpp
@@ -16,6 +16,7 @@
#include <iostream>
#include <fstream>
+#include <sstream>
#include <iterator>
#include <stdint.h>
#include <cassert>
@@ -500,6 +501,14 @@ Expr Parser::nextExpression() throw(ParserException) {
return result;
}
+void Parser::attributeNotSupported(const std::string& attr) {
+ if(d_attributesWarnedAbout.find(attr) == d_attributesWarnedAbout.end()) {
+ stringstream ss;
+ ss << "warning: Attribute " << attr << " not supported (ignoring this and all following uses)";
+ d_input->warning(ss.str());
+ d_attributesWarnedAbout.insert(attr);
+ }
+}
}/* CVC4::parser namespace */
}/* CVC4 namespace */
diff --git a/src/parser/parser.h b/src/parser/parser.h
index fc956b463..958c8a5b5 100644
--- a/src/parser/parser.h
+++ b/src/parser/parser.h
@@ -144,6 +144,9 @@ class CVC4_PUBLIC Parser {
/** The set of operators available in the current logic. */
std::set<Kind> d_logicOperators;
+ /** The set of attributes already warned about. */
+ std::set<std::string> d_attributesWarnedAbout;
+
/**
* The current set of unresolved types. We can get by with this NOT
* being on the scope, because we can only have one DATATYPE
@@ -451,6 +454,9 @@ public:
d_input->warning(msg);
}
+ /** Issue a warning to the user, but only once per attribute. */
+ void attributeNotSupported(const std::string& attr);
+
/** Raise a parse error with the given message. */
inline void parseError(const std::string& msg) throw(ParserException) {
d_input->parseError(msg);
diff --git a/src/parser/smt1/Smt1.g b/src/parser/smt1/Smt1.g
index 6dade9530..0f76baace 100644
--- a/src/parser/smt1/Smt1.g
+++ b/src/parser/smt1/Smt1.g
@@ -1,4 +1,3 @@
-/* ******************* */
/*! \file Smt1.g
** \verbatim
** Original author: cconway
@@ -235,10 +234,10 @@ annotatedFormula[CVC4::Expr& expr]
Expr op; /* Operator expression FIXME: move away kill it */
}
: /* a built-in operator application */
- LPAREN_TOK builtinOp[kind] annotatedFormulas[args,expr] RPAREN_TOK
+ LPAREN_TOK builtinOp[kind] annotatedFormulas[args,expr]
{ if((kind == CVC4::kind::AND || kind == CVC4::kind::OR) && args.size() == 1) {
/* Unary AND/OR can be replaced with the argument.
- It just so happens expr should already by the only argument. */
+ * It just so happens expr should already be the only argument. */
assert( expr == args[0] );
} else if( CVC4::kind::isAssociative(kind) &&
args.size() > EXPR_MANAGER->maxArity(kind) ) {
@@ -253,6 +252,7 @@ annotatedFormula[CVC4::Expr& expr]
expr = MK_EXPR(kind, args);
}
}
+ termAnnotation[expr]* RPAREN_TOK
| /* A quantifier */
LPAREN_TOK
@@ -261,12 +261,13 @@ annotatedFormula[CVC4::Expr& expr]
( LPAREN_TOK let_identifier[name,CHECK_NONE] t=sortSymbol RPAREN_TOK
{ args.push_back(PARSER_STATE->mkBoundVar(name, t)); }
)+
- annotatedFormula[expr] RPAREN_TOK
+ annotatedFormula[expr]
{ args2.push_back( MK_EXPR( kind::BOUND_VAR_LIST, args ) );
args2.push_back(expr);
expr = MK_EXPR(kind, args2);
- PARSER_STATE->popScope();
}
+ termAnnotation[expr]* RPAREN_TOK
+ { PARSER_STATE->popScope(); }
| /* A non-built-in function application */
@@ -275,9 +276,10 @@ annotatedFormula[CVC4::Expr& expr]
// { isFunction(LT(2)->getText()) }?
LPAREN_TOK
parameterizedOperator[op]
- annotatedFormulas[args,expr] RPAREN_TOK
+ annotatedFormulas[args,expr]
// TODO: check arity
{ expr = MK_EXPR(op,args); }
+ termAnnotation[expr]* RPAREN_TOK
| /* An ite expression */
LPAREN_TOK ITE_TOK
@@ -286,9 +288,9 @@ annotatedFormula[CVC4::Expr& expr]
annotatedFormula[expr]
{ args.push_back(expr); }
annotatedFormula[expr]
- { args.push_back(expr); }
- RPAREN_TOK
- { expr = MK_EXPR(CVC4::kind::ITE, args); }
+ { args.push_back(expr);
+ expr = MK_EXPR(CVC4::kind::ITE, args); }
+ termAnnotation[expr]* RPAREN_TOK
| /* a let/flet binding */
LPAREN_TOK
@@ -298,7 +300,7 @@ annotatedFormula[CVC4::Expr& expr]
{ PARSER_STATE->pushScope();
PARSER_STATE->defineVar(name,expr); }
annotatedFormula[expr]
- RPAREN_TOK
+ termAnnotation[expr]* RPAREN_TOK
{ PARSER_STATE->popScope(); }
/* constants */
@@ -310,7 +312,7 @@ annotatedFormula[CVC4::Expr& expr]
{ // FIXME: This doesn't work because an SMT rational is not a
// valid GMP rational string
expr = MK_CONST( AntlrInput::tokenToRational($RATIONAL_TOK) ); }
- | n = BITVECTOR_BV_CONST '[' size = NUMERAL_TOK ']'
+ | n = BITVECTOR_BV_CONST '[' size = NUMERAL_TOK ']'
{ expr = MK_CONST( AntlrInput::tokenToBitvector($n, $size) ); }
// NOTE: Theory constants go here
/* TODO: quantifiers, arithmetic constants */
@@ -320,7 +322,6 @@ annotatedFormula[CVC4::Expr& expr]
| let_identifier[name,CHECK_DECLARED]
| flet_identifier[name,CHECK_DECLARED] )
{ expr = PARSER_STATE->getVariable(name); }
-
;
/**
@@ -458,7 +459,7 @@ functionSymbol[CVC4::Expr& fun]
* Matches an attribute name from the input (:attribute_name).
*/
attribute[std::string& s]
- : ATTR_IDENTIFIER
+ : ATTR_IDENTIFIER
{ s = AntlrInput::tokenText($ATTR_IDENTIFIER); }
;
@@ -555,28 +556,56 @@ status[ CVC4::BenchmarkStatus& status ]
/**
* Matches an annotation, which is an attribute name, with an optional user
+ * value.
*/
annotation[CVC4::Command*& smt_command]
@init {
- std::string key;
+ std::string key, value;
smt_command = NULL;
+ std::vector<Expr> pats;
+ Expr pat;
}
- : attribute[key]
- ( USER_VALUE
- { std::string value = AntlrInput::tokenText($USER_VALUE);
- assert(*value.begin() == '{');
- assert(*value.rbegin() == '}');
- // trim whitespace
- value.erase(value.begin(), value.begin() + 1);
- value.erase(value.begin(), std::find_if(value.begin(), value.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
- value.erase(value.end() - 1);
- value.erase(std::find_if(value.rbegin(), value.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), value.end());
- smt_command = new SetInfoCommand(key.c_str() + 1, value); }
- )?
- { if(smt_command == NULL) {
- smt_command = new EmptyCommand(std::string("annotation: ") + key);
+ : PATTERN_ANNOTATION_BEGIN
+ { PARSER_STATE->warning(":pat not supported here; ignored"); }
+ annotatedFormulas[pats,pat] '}'
+ | attribute[key]
+ ( userValue[value]
+ { smt_command = new SetInfoCommand(key.c_str() + 1, value); }
+ | { smt_command = new EmptyCommand(std::string("annotation: ") + key); }
+ )
+ ;
+
+/**
+ * Matches an annotation, which is an attribute name, with an optional user
+ * value.
+ */
+termAnnotation[CVC4::Expr& expr]
+@init {
+ std::string key, value;
+ std::vector<Expr> pats;
+ Expr pat;
+}
+ : PATTERN_ANNOTATION_BEGIN annotatedFormulas[pats,pat] '}'
+ { if(expr.getKind() == kind::FORALL || expr.getKind() == kind::EXISTS) {
+ pat = MK_EXPR(kind::INST_PATTERN, pats);
+ if(expr.getNumChildren() == 3) {
+ // we have other user patterns attached to the quantifier
+ // already; add this one to the existing list
+ pats = expr[2].getChildren();
+ pats.push_back(pat);
+ expr = MK_EXPR(expr.getKind(), expr[0], expr[1], MK_EXPR(kind::INST_PATTERN_LIST, pats));
+ } else {
+ // this is the only user pattern for the quantifier
+ expr = MK_EXPR(expr.getKind(), expr[0], expr[1], MK_EXPR(kind::INST_PATTERN_LIST, pat));
+ }
+ } else {
+ PARSER_STATE->warning(":pat only supported on quantifiers");
}
}
+ | ':pat'
+ { PARSER_STATE->warning("expected an instantiation pattern after :pat"); }
+ | attribute[key] userValue[value]?
+ { PARSER_STATE->attributeNotSupported(key); }
;
/**
@@ -752,6 +781,15 @@ FLET_IDENTIFIER
* only constraint imposed on a user-defined value is that it start
* with an open brace and end with closed brace.
*/
+userValue[std::string& s]
+ : USER_VALUE
+ { s = AntlrInput::tokenText($USER_VALUE); }
+ ;
+
+PATTERN_ANNOTATION_BEGIN
+ : ':pat' (' ' | '\t' | '\f' | '\r' | '\n')* '{'
+ ;
+
USER_VALUE
: '{' ('\\{' | '\\}' | ~('{' | '}'))* '}'
;
diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g
index 87cf2083d..648666091 100644
--- a/src/parser/smt2/Smt2.g
+++ b/src/parser/smt2/Smt2.g
@@ -629,7 +629,7 @@ pattern[CVC4::Expr& expr]
}
;
-simpleSymbolicExpr[CVC4::SExpr& sexpr]
+simpleSymbolicExprNoKeyword[CVC4::SExpr& sexpr]
@declarations {
CVC4::Kind k;
std::string s;
@@ -647,6 +647,10 @@ simpleSymbolicExpr[CVC4::SExpr& sexpr]
ss << Expr::setlanguage(CVC4::language::output::LANG_SMTLIB_V2) << EXPR_MANAGER->mkConst(k);
sexpr = SExpr(ss.str());
}
+ ;
+
+simpleSymbolicExpr[CVC4::SExpr& sexpr]
+ : simpleSymbolicExprNoKeyword[sexpr]
| KEYWORD
{ sexpr = SExpr(AntlrInput::tokenText($KEYWORD)); }
;
@@ -715,8 +719,8 @@ term[CVC4::Expr& expr, CVC4::Expr& expr2]
expr = MK_EXPR(kind, args);
}
}
- | LPAREN_TOK AS_TOK term[f, f2] sortSymbol[type, CHECK_DECLARED] RPAREN_TOK
- {
+ | LPAREN_TOK AS_TOK term[f, f2] sortSymbol[type, CHECK_DECLARED] RPAREN_TOK
+ {
if(f.getKind() == CVC4::kind::APPLY_CONSTRUCTOR && type.isDatatype()) {
std::vector<CVC4::Expr> v;
Expr e = f.getOperator();
@@ -928,22 +932,31 @@ attribute[CVC4::Expr& expr,CVC4::Expr& retExpr, std::string& attr]
Expr patexpr;
std::vector<Expr> patexprs;
Expr e2;
+ bool hasValue = false;
}
-: KEYWORD
+ : KEYWORD ( simpleSymbolicExprNoKeyword[sexpr] { hasValue = true; } )?
{
attr = AntlrInput::tokenText($KEYWORD);
- //EXPR_MANAGER->setNamedAttribute( expr, attr );
- if( attr==":rewrite-rule" ){
- //do nothing
- } else if( attr==":axiom" || attr==":conjecture" ){
+ // EXPR_MANAGER->setNamedAttribute( expr, attr );
+ if(attr == ":rewrite-rule") {
+ if(hasValue) {
+ std::stringstream ss;
+ ss << "warning: Attribute " << attr << " does not take a value (ignoring)";
+ PARSER_STATE->warning(ss.str());
+ }
+ // do nothing
+ } else if(attr == ":axiom" || attr == ":conjecture") {
+ if(hasValue) {
+ std::stringstream ss;
+ ss << "warning: Attribute " << attr << " does not take a value (ignoring)";
+ PARSER_STATE->warning(ss.str());
+ }
std::string attr_name = attr;
attr_name.erase( attr_name.begin() );
Command* c = new SetUserAttributeCommand( attr_name, expr );
PARSER_STATE->preemptCommand(c);
} else {
- std::stringstream ss;
- ss << "Attribute `" << attr << "' not supported";
- PARSER_STATE->parseError(ss.str());
+ PARSER_STATE->attributeNotSupported(attr);
}
}
| ATTRIBUTE_PATTERN_TOK LPAREN_TOK ( term[patexpr, e2] { patexprs.push_back( patexpr ); } )+ RPAREN_TOK
@@ -951,6 +964,11 @@ attribute[CVC4::Expr& expr,CVC4::Expr& retExpr, std::string& attr]
attr = std::string(":pattern");
retExpr = MK_EXPR(kind::INST_PATTERN, patexprs);
}
+ | ATTRIBUTE_NO_PATTERN_TOK LPAREN_TOK term[patexpr, e2]+ RPAREN_TOK
+ {
+ attr = std::string(":no-pattern");
+ PARSER_STATE->attributeNotSupported(attr);
+ }
| ATTRIBUTE_NAMED_TOK symbolicExpr[sexpr]
{
attr = std::string(":named");
@@ -1098,7 +1116,7 @@ quantOp[CVC4::Kind& kind]
@init {
Debug("parser") << "quant: " << AntlrInput::tokenText(LT(1)) << std::endl;
}
- : EXISTS_TOK { $kind = CVC4::kind::EXISTS; }
+ : EXISTS_TOK { $kind = CVC4::kind::EXISTS; }
| FORALL_TOK { $kind = CVC4::kind::FORALL; }
;
@@ -1374,6 +1392,7 @@ SIMPLIFY_TOK : 'simplify';
// attributes
ATTRIBUTE_PATTERN_TOK : ':pattern';
+ATTRIBUTE_NO_PATTERN_TOK : ':no-pattern';
ATTRIBUTE_NAMED_TOK : ':named';
// operators (NOTE: theory symbols go here)
diff --git a/src/parser/tptp/tptp.cpp b/src/parser/tptp/tptp.cpp
index 89150142b..1e40ea63f 100644
--- a/src/parser/tptp/tptp.cpp
+++ b/src/parser/tptp/tptp.cpp
@@ -89,7 +89,7 @@ void Tptp::addTheory(Theory theory) {
/* The include are managed in the lexer but called in the parser */
-// Inspired by http://www.antlr.org/api/C/interop.html
+// Inspired by http://www.antlr3.org/api/C/interop.html
bool newInputStream(std::string fileName, pANTLR3_LEXER lexer){
Debug("parser") << "Including " << fileName << std::endl;
diff --git a/src/printer/cvc/cvc_printer.cpp b/src/printer/cvc/cvc_printer.cpp
index f0a936c97..e0d4656f4 100644
--- a/src/printer/cvc/cvc_printer.cpp
+++ b/src/printer/cvc/cvc_printer.cpp
@@ -493,9 +493,15 @@ void CvcPrinter::toStream(std::ostream& out, TNode n, int depth, bool types, boo
case kind::BITVECTOR_UDIV:
op << "BVUDIV";
break;
+ case kind::BITVECTOR_UDIV_TOTAL:
+ op << "BVUDIV_TOTAL";
+ break;
case kind::BITVECTOR_UREM:
op << "BVUREM";
break;
+ case kind::BITVECTOR_UREM_TOTAL:
+ op << "BVUREM_TOTAL";
+ break;
case kind::BITVECTOR_SDIV:
op << "BVSDIV";
break;
@@ -671,7 +677,7 @@ void CvcPrinter::toStream(std::ostream& out, TNode n, int depth, bool types, boo
toStream(out, n[1], depth, types, false);
out << ')';
// TODO: user patterns?
- break;
+ return;
case kind::INST_CONSTANT:
out << "INST_CONSTANT";
break;
diff --git a/src/printer/smt2/smt2_printer.cpp b/src/printer/smt2/smt2_printer.cpp
index 5985f38ef..000fd2fbf 100644
--- a/src/printer/smt2/smt2_printer.cpp
+++ b/src/printer/smt2/smt2_printer.cpp
@@ -254,7 +254,9 @@ void Smt2Printer::toStream(std::ostream& out, TNode n,
case kind::BITVECTOR_SUB: out << "bvsub "; break;
case kind::BITVECTOR_NEG: out << "bvneg "; break;
case kind::BITVECTOR_UDIV: out << "bvudiv "; break;
+ case kind::BITVECTOR_UDIV_TOTAL: out << "bvudiv_total "; break;
case kind::BITVECTOR_UREM: out << "bvurem "; break;
+ case kind::BITVECTOR_UREM_TOTAL: out << "bvurem_total "; break;
case kind::BITVECTOR_SDIV: out << "bvsdiv "; break;
case kind::BITVECTOR_SREM: out << "bvsrem "; break;
case kind::BITVECTOR_SMOD: out << "bvsmod "; break;
@@ -539,6 +541,13 @@ void Smt2Printer::toStream(std::ostream& out, const CommandStatus* s) const thro
}/* Smt2Printer::toStream(CommandStatus*) */
+void Smt2Printer::toStream(std::ostream& out, Model& m) const throw() {
+ out << "(model" << std::endl;
+ this->Printer::toStream(out, m);
+ out << ")" << std::endl;
+}
+
+
void Smt2Printer::toStream(std::ostream& out, Model& m, const Command* c) const throw() {
theory::TheoryModel& tm = (theory::TheoryModel&) m;
if(dynamic_cast<const DeclareTypeCommand*>(c) != NULL) {
diff --git a/src/printer/smt2/smt2_printer.h b/src/printer/smt2/smt2_printer.h
index c6d932457..32a0c94ba 100644
--- a/src/printer/smt2/smt2_printer.h
+++ b/src/printer/smt2/smt2_printer.h
@@ -30,6 +30,7 @@ namespace smt2 {
class Smt2Printer : public CVC4::Printer {
void toStream(std::ostream& out, TNode n, int toDepth, bool types) const throw();
void toStream(std::ostream& out, Model& m, const Command* c) const throw();
+ void toStream(std::ostream& out, Model& m) const throw();
public:
void toStream(std::ostream& out, TNode n, int toDepth, bool types, size_t dag) const throw();
void toStream(std::ostream& out, const Command* c, int toDepth, bool types, size_t dag) const throw();
diff --git a/src/proof/proof_manager.cpp b/src/proof/proof_manager.cpp
index d05fe24a7..c1351c6a2 100644
--- a/src/proof/proof_manager.cpp
+++ b/src/proof/proof_manager.cpp
@@ -26,7 +26,7 @@ namespace CVC4 {
bool ProofManager::isInitialized = false;
ProofManager* ProofManager::proofManager = NULL;
-ProofManager::ProofManager(ProofFormat format = LFSC):
+ProofManager::ProofManager(ProofFormat format):
d_satProof(NULL),
d_cnfProof(NULL),
d_format(format)
diff --git a/src/proof/proof_manager.h b/src/proof/proof_manager.h
index 3bfff1456..91eb2ed99 100644
--- a/src/proof/proof_manager.h
+++ b/src/proof/proof_manager.h
@@ -52,7 +52,7 @@ class ProofManager {
static ProofManager* proofManager;
static bool isInitialized;
- ProofManager(ProofFormat format);
+ ProofManager(ProofFormat format = LFSC);
public:
static ProofManager* currentPM();
diff --git a/src/prop/bvminisat/core/Solver.cc b/src/prop/bvminisat/core/Solver.cc
index 978ac8d7b..68969c78b 100644
--- a/src/prop/bvminisat/core/Solver.cc
+++ b/src/prop/bvminisat/core/Solver.cc
@@ -32,7 +32,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#include "theory/interrupted.h"
using namespace BVMinisat;
-namespace CVC4 {
+namespace BVMinisat {
#define OUTPUT_TAG "bvminisat: [a=" << assumptions.size() << ",l=" << decisionLevel() << "] "
diff --git a/src/prop/sat_solver.h b/src/prop/sat_solver.h
index e5d876b48..b4807b021 100644
--- a/src/prop/sat_solver.h
+++ b/src/prop/sat_solver.h
@@ -130,8 +130,6 @@ public:
};/* class DPLLSatSolverInterface */
-}/* CVC4::prop namespace */
-
inline std::ostream& operator <<(std::ostream& out, prop::SatLiteral lit) {
out << lit.toString();
return out;
@@ -167,6 +165,7 @@ inline std::ostream& operator <<(std::ostream& out, prop::SatValue val) {
return out;
}
+}/* CVC4::prop namespace */
}/* CVC4 namespace */
#endif /* __CVC4__PROP__SAT_MODULE_H */
diff --git a/src/smt/options_handlers.h b/src/smt/options_handlers.h
index a3065f29b..a0a6429a8 100644
--- a/src/smt/options_handlers.h
+++ b/src/smt/options_handlers.h
@@ -23,6 +23,7 @@
#include "util/dump.h"
#include "smt/modal_exception.h"
#include "smt/smt_engine.h"
+#include "lib/strtok_r.h"
#include <cerrno>
#include <cstring>
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index c82b7ca2c..1d98ce115 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -69,6 +69,7 @@
#include "theory/arrays/options.h"
#include "util/sort_inference.h"
#include "theory/quantifiers/macros.h"
+#include "theory/datatypes/options.h"
using namespace std;
using namespace CVC4;
@@ -631,6 +632,11 @@ void SmtEngine::finalOptionsAreSet() {
}
}
+ if(options::produceAssignments() && !options::produceModels()) {
+ Notice() << "SmtEngine: turning on produce-models to support produce-assignments" << std::endl;
+ setOption("produce-models", SExpr("true"));
+ }
+
if(! d_logic.isLocked()) {
// ensure that our heuristics are properly set up
setLogicInternal();
@@ -972,6 +978,13 @@ void SmtEngine::setLogicInternal() throw() {
setOption("check-models", SExpr("false"));
}
}
+
+ //datatypes theory should assign values to all datatypes terms if logic is quantified
+ if (d_logic.isQuantified() && d_logic.isTheoryEnabled(theory::THEORY_DATATYPES)) {
+ if( !options::dtForceAssignment.wasSetByUser() ){
+ options::dtForceAssignment.set(true);
+ }
+ }
}
void SmtEngine::setInfo(const std::string& key, const CVC4::SExpr& value)
@@ -2248,7 +2261,7 @@ void SmtEnginePrivate::processAssertions() {
collectSkolems((*pos).first, skolemSet, cache);
collectSkolems((*pos).second, skolemSet, cache);
}
-
+
// We need to ensure:
// 1. iteExpr has the form (ite cond (sk = t) (sk = e))
// 2. if some sk' in Sk appears in cond, t, or e, then sk' <_sk sk
@@ -2438,7 +2451,7 @@ Result SmtEngine::checkSat(const Expr& ex) throw(TypeCheckingException, ModalExc
Trace("smt") << "SmtEngine::checkSat(" << e << ") => " << r << endl;
// Check that SAT results generate a model correctly.
- if(options::checkModels()){
+ if(options::checkModels()) {
if(r.asSatisfiabilityResult().isSat() == Result::SAT ||
(r.isUnknown() && r.whyUnknown() == Result::INCOMPLETE) ){
checkModel(/* hard failure iff */ ! r.isUnknown());
@@ -2508,7 +2521,7 @@ Result SmtEngine::query(const Expr& ex) throw(TypeCheckingException, ModalExcept
Trace("smt") << "SMT query(" << e << ") ==> " << r << endl;
// Check that SAT results generate a model correctly.
- if(options::checkModels()){
+ if(options::checkModels()) {
if(r.asSatisfiabilityResult().isSat() == Result::SAT ||
(r.isUnknown() && r.whyUnknown() == Result::INCOMPLETE) ){
checkModel(/* hard failure iff */ ! r.isUnknown());
@@ -2705,20 +2718,22 @@ CVC4::SExpr SmtEngine::getAssignment() throw(ModalException) {
vector<SExpr> sexprs;
TypeNode boolType = d_nodeManager->booleanType();
+ TheoryModel* m = d_theoryEngine->getModel();
for(AssignmentSet::const_iterator i = d_assignments->begin(),
iend = d_assignments->end();
i != iend;
++i) {
Assert((*i).getType() == boolType);
- // Normalize
- Node n = Rewriter::rewrite(*i);
+ // Expand, then normalize
+ hash_map<Node, Node, NodeHashFunction> cache;
+ Node n = d_private->expandDefinitions(*i, cache);
+ n = Rewriter::rewrite(n);
Trace("smt") << "--- getting value of " << n << endl;
- TheoryModel* m = d_theoryEngine->getModel();
Node resultNode;
- if( m ){
- resultNode = m->getValue( n );
+ if(m != NULL) {
+ resultNode = m->getValue(n);
}
// type-check the result we got
@@ -2727,12 +2742,12 @@ CVC4::SExpr SmtEngine::getAssignment() throw(ModalException) {
vector<SExpr> v;
if((*i).getKind() == kind::APPLY) {
Assert((*i).getNumChildren() == 0);
- v.push_back((*i).getOperator().toString());
+ v.push_back(SExpr::Keyword((*i).getOperator().toString()));
} else {
Assert((*i).isVar());
- v.push_back((*i).toString());
+ v.push_back(SExpr::Keyword((*i).toString()));
}
- v.push_back(resultNode.toString());
+ v.push_back(SExpr::Keyword(resultNode.toString()));
sexprs.push_back(v);
}
return SExpr(sexprs);
diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h
index 3edcd6872..cdae68d96 100644
--- a/src/smt/smt_engine.h
+++ b/src/smt/smt_engine.h
@@ -47,7 +47,7 @@ namespace CVC4 {
template <bool ref_count> class NodeTemplate;
typedef NodeTemplate<true> Node;
typedef NodeTemplate<false> TNode;
-class NodeHashFunction;
+struct NodeHashFunction;
class Command;
class GetModelCommand;
@@ -77,7 +77,7 @@ namespace smt {
*/
class DefinedFunction;
- class SmtEngineStatistics;
+ struct SmtEngineStatistics;
class SmtEnginePrivate;
class SmtScope;
class BooleanTermConverter;
diff --git a/src/theory/arith/arith_rewriter.cpp b/src/theory/arith/arith_rewriter.cpp
index a367b8599..823b61df5 100644
--- a/src/theory/arith/arith_rewriter.cpp
+++ b/src/theory/arith/arith_rewriter.cpp
@@ -338,7 +338,7 @@ RewriteResponse ArithRewriter::rewriteIntsDivModTotal(TNode t, bool pre){
bool isDiv = (k == kind::INTS_DIVISION || k == kind::INTS_DIVISION_TOTAL);
- Integer result = isDiv ? ni.floorDivideQuotient(di) : ni.floorDivideRemainder(di);
+ Integer result = isDiv ? ni.euclidianDivideQuotient(di) : ni.euclidianDivideRemainder(di);
Node resultNode = mkRationalNode(Rational(result));
return RewriteResponse(REWRITE_DONE, resultNode);
diff --git a/src/theory/arith/arith_static_learner.cpp b/src/theory/arith/arith_static_learner.cpp
index 9ae7cd1c2..4ee176cf1 100644
--- a/src/theory/arith/arith_static_learner.cpp
+++ b/src/theory/arith/arith_static_learner.cpp
@@ -19,6 +19,7 @@
#include "theory/arith/arith_utilities.h"
#include "theory/arith/arith_static_learner.h"
+#include "theory/arith/options.h"
#include "util/propositional_query.h"
@@ -61,6 +62,13 @@ ArithStaticLearner::Statistics::~Statistics(){
StatisticsRegistry::unregisterStat(&d_avgNumMiplibtrickValues);
}
+void ArithStaticLearner::miplibTrickInsert(Node key, Node value){
+ if(options::arithMLTrick()){
+ d_miplibTrick.insert(key, value);
+ }
+}
+
+
void ArithStaticLearner::staticLearning(TNode n, NodeBuilder<>& learned){
vector<TNode> workList;
@@ -138,7 +146,8 @@ void ArithStaticLearner::process(TNode n, NodeBuilder<>& learned, const TNodeSet
TNode var = n[1][0];
Node current = (d_miplibTrick.find(var) == d_miplibTrick.end()) ?
mkBoolNode(false) : d_miplibTrick[var];
- d_miplibTrick.insert(var, n.orNode(current));
+
+ miplibTrickInsert(var, n.orNode(current));
Debug("arith::miplib") << "insert " << var << " const " << n << endl;
}
}
@@ -338,7 +347,7 @@ void ArithStaticLearner::postProcess(NodeBuilder<>& learned){
Result isTaut = PropositionalQuery::isTautology(possibleTaut);
if(isTaut == Result(Result::VALID)){
miplibTrick(var, values, learned);
- d_miplibTrick.insert(var, mkBoolNode(false));
+ miplibTrickInsert(var, mkBoolNode(false));
}
++keyIter;
}
diff --git a/src/theory/arith/arith_static_learner.h b/src/theory/arith/arith_static_learner.h
index 0de28c5ab..041ae6339 100644
--- a/src/theory/arith/arith_static_learner.h
+++ b/src/theory/arith/arith_static_learner.h
@@ -45,6 +45,7 @@ private:
// The domain is an implicit list OR(x, OR(y, ..., FALSE ))
// or FALSE
CDNodeToNodeListMap d_miplibTrick;
+ void miplibTrickInsert(Node key, Node value);
/**
* Map from a node to it's minimum and maximum.
diff --git a/src/theory/arith/delta_rational.cpp b/src/theory/arith/delta_rational.cpp
index a334e2c3d..39b99d625 100644
--- a/src/theory/arith/delta_rational.cpp
+++ b/src/theory/arith/delta_rational.cpp
@@ -83,23 +83,23 @@ DeltaRationalException::DeltaRationalException(const char* op, const DeltaRation
DeltaRationalException::~DeltaRationalException() throw () { }
-Integer DeltaRational::floorDivideQuotient(const DeltaRational& y) const throw(DeltaRationalException){
+Integer DeltaRational::euclidianDivideQuotient(const DeltaRational& y) const throw(DeltaRationalException){
if(isIntegral() && y.isIntegral()){
Integer ti = floor();
Integer yi = y.floor();
- return ti.floorDivideQuotient(yi);
+ return ti.euclidianDivideQuotient(yi);
}else{
- throw DeltaRationalException("floorDivideQuotient", *this, y);
+ throw DeltaRationalException("euclidianDivideQuotient", *this, y);
}
}
-Integer DeltaRational::floorDivideRemainder(const DeltaRational& y) const throw(DeltaRationalException){
+Integer DeltaRational::euclidianDivideRemainder(const DeltaRational& y) const throw(DeltaRationalException){
if(isIntegral() && y.isIntegral()){
Integer ti = floor();
Integer yi = y.floor();
- return ti.floorDivideRemainder(yi);
+ return ti.euclidianDivideRemainder(yi);
}else{
- throw DeltaRationalException("floorDivideRemainder", *this, y);
+ throw DeltaRationalException("euclidianDivideRemainder", *this, y);
}
}
diff --git a/src/theory/arith/delta_rational.h b/src/theory/arith/delta_rational.h
index dc4202f36..19a16d558 100644
--- a/src/theory/arith/delta_rational.h
+++ b/src/theory/arith/delta_rational.h
@@ -236,10 +236,10 @@ public:
}
/** Only well defined if both this and y are integral. */
- Integer floorDivideQuotient(const DeltaRational& y) const throw(DeltaRationalException);
+ Integer euclidianDivideQuotient(const DeltaRational& y) const throw(DeltaRationalException);
/** Only well defined if both this and y are integral. */
- Integer floorDivideRemainder(const DeltaRational& y) const throw(DeltaRationalException);
+ Integer euclidianDivideRemainder(const DeltaRational& y) const throw(DeltaRationalException);
std::string toString() const;
diff --git a/src/theory/arith/options b/src/theory/arith/options
index 38cf07251..719c826ae 100644
--- a/src/theory/arith/options
+++ b/src/theory/arith/options
@@ -51,4 +51,13 @@ option arithRewriteEq --enable-arith-rewrite-equalities/--disable-arith-rewrite-
turns on the preprocessing rewrite turning equalities into a conjunction of inequalities
/turns off the preprocessing rewrite turning equalities into a conjunction of inequalities
+option arithMLTrick --enable-miplib-trick/--disable-miplib-trick bool :default false :read-write
+ turns on the preprocessing step of attempting to infer bounds on miplib problems
+/turns off the preprocessing step of attempting to infer bounds on miplib problems
+
+option doCutAllBounded --enable-cut-all-bounded/--disable-cut-all-bounded bool :default false :read-write
+ turns on the integer solving step of periodically cutting all integer variables that have both upper and lower bounds
+/ turns off the integer solving step of periodically cutting all integer variables that have both upper and lower bounds
+
+
endmodule
diff --git a/src/theory/arith/partial_model.h b/src/theory/arith/partial_model.h
index 9a41d8d23..fdb4a8ffa 100644
--- a/src/theory/arith/partial_model.h
+++ b/src/theory/arith/partial_model.h
@@ -225,7 +225,7 @@ private:
bool equalSizes();
bool inMaps(ArithVar x) const{
- return 0 <= x && x < d_mapSize;
+ return x < d_mapSize;
}
};/* class ArithPartialModel */
diff --git a/src/theory/arith/theory_arith.cpp b/src/theory/arith/theory_arith.cpp
index f036e20fd..52f234129 100644
--- a/src/theory/arith/theory_arith.cpp
+++ b/src/theory/arith/theory_arith.cpp
@@ -88,6 +88,7 @@ TheoryArith::TheoryArith(context::Context* c, context::UserContext* u, OutputCha
d_deltaComputeCallback(this),
d_basicVarModelUpdateCallBack(d_simplex),
d_DELTA_ZERO(0),
+ d_fullCheckCounter(0),
d_statistics()
{
}
@@ -752,8 +753,8 @@ Theory::PPAssertStatus TheoryArith::ppAssert(TNode in, SubstitutionMap& outSubst
Assert(elim == Rewriter::rewrite(elim));
- static const unsigned MAX_SUB_SIZE = 20;
- if(false && right.size() > MAX_SUB_SIZE){
+ static const unsigned MAX_SUB_SIZE = 2;
+ if(right.size() > MAX_SUB_SIZE){
Debug("simplify") << "TheoryArith::solve(): did not substitute due to the right hand side containing too many terms: " << minVar << ":" << elim << endl;
Debug("simplify") << right.size() << endl;
}else if(elim.hasSubterm(minVar)){
@@ -1730,6 +1731,20 @@ void TheoryArith::check(Effort effortLevel){
}
Assert( d_currentPropagationList.empty());
+ if(!emmittedConflictOrSplit && fullEffort(effortLevel)){
+ ++d_fullCheckCounter;
+ }
+ static const int CUT_ALL_BOUNDED_PERIOD = 10;
+ if(!emmittedConflictOrSplit && fullEffort(effortLevel) &&
+ d_fullCheckCounter % CUT_ALL_BOUNDED_PERIOD == 1){
+ vector<Node> lemmas = cutAllBounded();
+ //output the lemmas
+ for(vector<Node>::const_iterator i = lemmas.begin(); i != lemmas.end(); ++i){
+ d_out->lemma(*i);
+ ++(d_statistics.d_externalBranchAndBounds);
+ }
+ emmittedConflictOrSplit = lemmas.size() > 0;
+ }
if(!emmittedConflictOrSplit && fullEffort(effortLevel)){
emmittedConflictOrSplit = splitDisequalities();
@@ -1776,6 +1791,55 @@ void TheoryArith::check(Effort effortLevel){
Debug("arith") << "TheoryArith::check end" << std::endl;
}
+Node TheoryArith::branchIntegerVariable(ArithVar x) const {
+ const DeltaRational& d = d_partialModel.getAssignment(x);
+ Assert(!d.isIntegral());
+ const Rational& r = d.getNoninfinitesimalPart();
+ const Rational& i = d.getInfinitesimalPart();
+ Trace("integers") << "integers: assignment to [[" << d_arithvarNodeMap.asNode(x) << "]] is " << r << "[" << i << "]" << endl;
+
+ Assert(! (r.getDenominator() == 1 && i.getNumerator() == 0));
+ Assert(!d.isIntegral());
+ TNode var = d_arithvarNodeMap.asNode(x);
+ Integer floor_d = d.floor();
+
+ Node ub = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::LEQ, var, mkRationalNode(floor_d)));
+ Node lb = ub.notNode();
+
+
+ Node lem = NodeManager::currentNM()->mkNode(kind::OR, ub, lb);
+ Trace("integers") << "integers: branch & bound: " << lem << endl;
+ if(d_valuation.isSatLiteral(lem[0])) {
+ Debug("integers") << " " << lem[0] << " == " << d_valuation.getSatValue(lem[0]) << endl;
+ } else {
+ Debug("integers") << " " << lem[0] << " is not assigned a SAT literal" << endl;
+ }
+ if(d_valuation.isSatLiteral(lem[1])) {
+ Debug("integers") << " " << lem[1] << " == " << d_valuation.getSatValue(lem[1]) << endl;
+ } else {
+ Debug("integers") << " " << lem[1] << " is not assigned a SAT literal" << endl;
+ }
+ return lem;
+}
+
+std::vector<Node> TheoryArith::cutAllBounded() const{
+ vector<Node> lemmas;
+ if(options::doCutAllBounded() && getNumberOfVariables() > 0){
+ for(ArithVar iter = 0; iter != getNumberOfVariables(); ++iter){
+ //Do not include slack variables
+ const DeltaRational& d = d_partialModel.getAssignment(iter);
+ if(isInteger(iter) && !isSlackVariable(iter) &&
+ d_partialModel.hasUpperBound(iter) &&
+ d_partialModel.hasLowerBound(iter) &&
+ !d.isIntegral()){
+ Node lem = branchIntegerVariable(iter);
+ lemmas.push_back(lem);
+ }
+ }
+ }
+ return lemmas;
+}
+
/** Returns true if the roundRobinBranching() issues a lemma. */
Node TheoryArith::roundRobinBranch(){
if(hasIntegerModel()){
@@ -1785,36 +1849,40 @@ Node TheoryArith::roundRobinBranch(){
Assert(isInteger(v));
Assert(!isSlackVariable(v));
+ return branchIntegerVariable(v);
- const DeltaRational& d = d_partialModel.getAssignment(v);
- const Rational& r = d.getNoninfinitesimalPart();
- const Rational& i = d.getInfinitesimalPart();
- Trace("integers") << "integers: assignment to [[" << d_arithvarNodeMap.asNode(v) << "]] is " << r << "[" << i << "]" << endl;
+ // Assert(isInteger(v));
+ // Assert(!isSlackVariable(v));
- Assert(! (r.getDenominator() == 1 && i.getNumerator() == 0));
- Assert(!d.isIntegral());
+ // const DeltaRational& d = d_partialModel.getAssignment(v);
+ // const Rational& r = d.getNoninfinitesimalPart();
+ // const Rational& i = d.getInfinitesimalPart();
+ // Trace("integers") << "integers: assignment to [[" << d_arithvarNodeMap.asNode(v) << "]] is " << r << "[" << i << "]" << endl;
- TNode var = d_arithvarNodeMap.asNode(v);
- Integer floor_d = d.floor();
- Integer ceil_d = d.ceiling();
+ // Assert(! (r.getDenominator() == 1 && i.getNumerator() == 0));
+ // Assert(!d.isIntegral());
- Node leq = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::LEQ, var, mkRationalNode(floor_d)));
- Node geq = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::GEQ, var, mkRationalNode(ceil_d)));
+ // TNode var = d_arithvarNodeMap.asNode(v);
+ // Integer floor_d = d.floor();
+ // Integer ceil_d = d.ceiling();
+ // Node leq = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::LEQ, var, mkRationalNode(floor_d)));
+ // Node geq = Rewriter::rewrite(NodeManager::currentNM()->mkNode(kind::GEQ, var, mkRationalNode(ceil_d)));
- Node lem = NodeManager::currentNM()->mkNode(kind::OR, leq, geq);
- Trace("integers") << "integers: branch & bound: " << lem << endl;
- if(d_valuation.isSatLiteral(lem[0])) {
- Debug("integers") << " " << lem[0] << " == " << d_valuation.getSatValue(lem[0]) << endl;
- } else {
- Debug("integers") << " " << lem[0] << " is not assigned a SAT literal" << endl;
- }
- if(d_valuation.isSatLiteral(lem[1])) {
- Debug("integers") << " " << lem[1] << " == " << d_valuation.getSatValue(lem[1]) << endl;
- } else {
- Debug("integers") << " " << lem[1] << " is not assigned a SAT literal" << endl;
- }
- return lem;
+
+ // Node lem = NodeManager::currentNM()->mkNode(kind::OR, leq, geq);
+ // Trace("integers") << "integers: branch & bound: " << lem << endl;
+ // if(d_valuation.isSatLiteral(lem[0])) {
+ // Debug("integers") << " " << lem[0] << " == " << d_valuation.getSatValue(lem[0]) << endl;
+ // } else {
+ // Debug("integers") << " " << lem[0] << " is not assigned a SAT literal" << endl;
+ // }
+ // if(d_valuation.isSatLiteral(lem[1])) {
+ // Debug("integers") << " " << lem[1] << " == " << d_valuation.getSatValue(lem[1]) << endl;
+ // } else {
+ // Debug("integers") << " " << lem[1] << " is not assigned a SAT literal" << endl;
+ // }
+ // return lem;
}
}
@@ -2060,10 +2128,10 @@ DeltaRational TheoryArith::getDeltaValue(TNode n) const throw (DeltaRationalExce
if(n.getKind() == kind::DIVISION_TOTAL){
res = numer / denom;
}else if(n.getKind() == kind::INTS_DIVISION_TOTAL){
- res = Rational(numer.floorDivideQuotient(denom));
+ res = Rational(numer.euclidianDivideQuotient(denom));
}else{
Assert(n.getKind() == kind::INTS_MODULUS_TOTAL);
- res = Rational(numer.floorDivideRemainder(denom));
+ res = Rational(numer.euclidianDivideRemainder(denom));
}
if(isSetup(n)){
ArithVar var = d_arithvarNodeMap.asArithVar(n);
diff --git a/src/theory/arith/theory_arith.h b/src/theory/arith/theory_arith.h
index 7d1150fb1..31f9bfcaf 100644
--- a/src/theory/arith/theory_arith.h
+++ b/src/theory/arith/theory_arith.h
@@ -537,6 +537,11 @@ private:
/** Debugging only routine. Prints the model. */
void debugPrintModel();
+ /** Counts the number of fullCheck calls to arithmetic. */
+ uint32_t d_fullCheckCounter;
+ std::vector<Node> cutAllBounded() const;
+ Node branchIntegerVariable(ArithVar x) const;
+
/** These fields are designed to be accessible to TheoryArith methods. */
class Statistics {
public:
diff --git a/src/theory/bv/bitblast_strategies.cpp b/src/theory/bv/bitblast_strategies.cpp
index bd76dd6d4..3ce9bcb44 100644
--- a/src/theory/bv/bitblast_strategies.cpp
+++ b/src/theory/bv/bitblast_strategies.cpp
@@ -648,6 +648,17 @@ void DefaultUdivBB (TNode node, Bits& q, Bitblaster* bb) {
Bits r;
uDivModRec(a, b, q, r, getSize(node));
+ // adding a special case for division by 0
+ std::vector<Node> iszero;
+ for (unsigned i = 0; i < b.size(); ++i) {
+ iszero.push_back(utils::mkNode(kind::IFF, b[i], utils::mkFalse()));
+ }
+ Node b_is_0 = utils::mkAnd(iszero);
+
+ for (unsigned i = 0; i < q.size(); ++i) {
+ q[i] = utils::mkNode(kind::ITE, b_is_0, utils::mkFalse(), q[i]);
+ r[i] = utils::mkNode(kind::ITE, b_is_0, utils::mkFalse(), r[i]);
+ }
// cache the remainder in case we need it later
Node remainder = mkNode(kind::BITVECTOR_UREM_TOTAL, node[0], node[1]);
@@ -664,6 +675,17 @@ void DefaultUremBB (TNode node, Bits& rem, Bitblaster* bb) {
Bits q;
uDivModRec(a, b, q, rem, getSize(node));
+ // adding a special case for division by 0
+ std::vector<Node> iszero;
+ for (unsigned i = 0; i < b.size(); ++i) {
+ iszero.push_back(utils::mkNode(kind::IFF, b[i], utils::mkFalse()));
+ }
+ Node b_is_0 = utils::mkAnd(iszero);
+
+ for (unsigned i = 0; i < q.size(); ++i) {
+ q[i] = utils::mkNode(kind::ITE, b_is_0, utils::mkFalse(), q[i]);
+ rem[i] = utils::mkNode(kind::ITE, b_is_0, utils::mkFalse(), rem[i]);
+ }
// cache the quotient in case we need it later
Node quotient = mkNode(kind::BITVECTOR_UDIV_TOTAL, node[0], node[1]);
diff --git a/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h b/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h
index 8b080d104..498378638 100644
--- a/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h
+++ b/src/theory/bv/theory_bv_rewrite_rules_constant_evaluation.h
@@ -207,7 +207,7 @@ Node RewriteRule<EvalUdiv>::apply(TNode node) {
BVDebug("bv-rewrite") << "RewriteRule<EvalUdiv>(" << node << ")" << std::endl;
BitVector a = node[0].getConst<BitVector>();
BitVector b = node[1].getConst<BitVector>();
- BitVector res = a.unsignedDiv(b);
+ BitVector res = a.unsignedDivTotal(b);
return utils::mkConst(res);
}
@@ -222,7 +222,7 @@ Node RewriteRule<EvalUrem>::apply(TNode node) {
BVDebug("bv-rewrite") << "RewriteRule<EvalUrem>(" << node << ")" << std::endl;
BitVector a = node[0].getConst<BitVector>();
BitVector b = node[1].getConst<BitVector>();
- BitVector res = a.unsignedRem(b);
+ BitVector res = a.unsignedRemTotal(b);
return utils::mkConst(res);
}
diff --git a/src/theory/bv/theory_bv_rewrite_rules_simplification.h b/src/theory/bv/theory_bv_rewrite_rules_simplification.h
index 23cd8381d..8bcc64414 100644
--- a/src/theory/bv/theory_bv_rewrite_rules_simplification.h
+++ b/src/theory/bv/theory_bv_rewrite_rules_simplification.h
@@ -430,10 +430,6 @@ Node RewriteRule<BitwiseNotOr>::apply(TNode node) {
template<> inline
bool RewriteRule<XorNot>::applies(TNode node) {
Unreachable();
- if (node.getKind() == kind::BITVECTOR_XOR &&
- node.getNumChildren() == 2 &&
- node[0].getKind() == kind::BITVECTOR_NOT &&
- node[1].getKind() == kind::BITVECTOR_NOT);
}
template<> inline
diff --git a/src/theory/datatypes/options b/src/theory/datatypes/options
index 45849858a..1daa30981 100644
--- a/src/theory/datatypes/options
+++ b/src/theory/datatypes/options
@@ -11,5 +11,7 @@ module DATATYPES "theory/datatypes/options.h" Datatypes theory
# cdr( nil ) has no set value.
expert-option dtRewriteErrorSel /--disable-dt-rewrite-error-sel bool :default true
disable rewriting incorrectly applied selectors to arbitrary ground term
+option dtForceAssignment /--dt-force-assignment bool :default false :read-write
+ force the datatypes solver to give specific values to all datatypes terms before answering sat
endmodule
diff --git a/src/theory/datatypes/theory_datatypes.cpp b/src/theory/datatypes/theory_datatypes.cpp
index e23d9deae..9e4f0de75 100644
--- a/src/theory/datatypes/theory_datatypes.cpp
+++ b/src/theory/datatypes/theory_datatypes.cpp
@@ -24,6 +24,7 @@
#include "theory/datatypes/theory_datatypes_type_rules.h"
#include "theory/model.h"
#include "smt/options.h"
+#include "theory/quantifiers/options.h"
#include <map>
@@ -45,7 +46,8 @@ TheoryDatatypes::TheoryDatatypes(Context* c, UserContext* u, OutputChannel& out,
d_equalityEngine(d_notify, c, "theory::datatypes::TheoryDatatypes"),
d_selector_apps( c ),
d_labels( c ),
- d_conflict( c, false ){
+ d_conflict( c, false ),
+ d_collectTermsCache( c ){
// The kinds we are treating as function application in congruence
d_equalityEngine.addFunctionKind(kind::APPLY_CONSTRUCTOR);
@@ -150,7 +152,7 @@ void TheoryDatatypes::check(Effort e) {
}
}
}
- if( !needSplit && mustSpecifyModel() ){
+ if( !needSplit && mustSpecifyAssignment() ){
//for the sake of termination, we must choose the constructor of a ground term
//NEED GUARENTEE: groundTerm should not contain any subterms of the same type
//** TODO: this is probably not good enough, actually need fair enumeration strategy
@@ -163,7 +165,7 @@ void TheoryDatatypes::check(Effort e) {
}
if( needSplit && consIndex!=-1 ) {
Node test = NodeManager::currentNM()->mkNode( APPLY_TESTER, Node::fromExpr( dt[consIndex].getTester() ), n );
- Trace("dt-split") << "*************Split for possible constructor " << test << " for " << n << endl;
+ Trace("dt-split") << "*************Split for possible constructor " << dt[consIndex] << " for " << n << endl;
test = Rewriter::rewrite( test );
NodeBuilder<> nb(kind::OR);
nb << test << test.notNode();
@@ -374,8 +376,13 @@ Node TheoryDatatypes::ppRewrite(TNode in) {
void TheoryDatatypes::addSharedTerm(TNode t) {
Debug("datatypes") << "TheoryDatatypes::addSharedTerm(): "
- << t << endl;
- d_equalityEngine.addTriggerTerm(t, THEORY_DATATYPES);
+ << t << " " << t.getType().isBoolean() << endl;
+ if( t.getType().isBoolean() ){
+ //d_equalityEngine.addTriggerPredicate(t, THEORY_DATATYPES);
+ }else{
+ d_equalityEngine.addTriggerTerm(t, THEORY_DATATYPES);
+ }
+ Debug("datatypes") << "TheoryDatatypes::addSharedTerm() finished" << std::endl;
}
/** propagate */
@@ -488,7 +495,7 @@ void TheoryDatatypes::merge( Node t1, Node t2 ){
Node unifEq = cons1.eqNode( cons2 );
for( int i=0; i<(int)cons1.getNumChildren(); i++ ) {
if( cons1[i]!=cons2[i] ){
- Node eq = cons1[i].eqNode( cons2[i] );
+ Node eq = cons1[i].getType().isBoolean() ? cons1[i].iffNode( cons2[i] ) : cons1[i].eqNode( cons2[i] );
d_pending.push_back( eq );
d_pending_exp[ eq ] = unifEq;
Trace("datatypes-infer") << "DtInfer : " << eq << " by " << unifEq << std::endl;
@@ -758,31 +765,34 @@ void TheoryDatatypes::collectModelInfo( TheoryModel* m, bool fullModel ){
void TheoryDatatypes::collectTerms( Node n ) {
- for( int i=0; i<(int)n.getNumChildren(); i++ ) {
- collectTerms( n[i] );
- }
- if( n.getKind() == APPLY_CONSTRUCTOR ){
- //we must take into account subterm relation when checking for cycles
+ if( d_collectTermsCache.find( n )==d_collectTermsCache.end() ){
+ d_collectTermsCache[n] = true;
for( int i=0; i<(int)n.getNumChildren(); i++ ) {
- Debug("datatypes-cycles") << "DtCyc: Subterm " << n << " -> " << n[i] << endl;
- bool result = d_cycle_check.addEdgeNode( n, n[i] );
- d_hasSeenCycle.set( d_hasSeenCycle.get() || result );
+ collectTerms( n[i] );
}
- }else if( n.getKind() == APPLY_SELECTOR ){
- if( d_selector_apps.find( n )==d_selector_apps.end() ){
- d_selector_apps[n] = false;
- //we must also record which selectors exist
- Debug("datatypes") << " Found selector " << n << endl;
- if (n.getType().isBoolean()) {
- d_equalityEngine.addTriggerPredicate( n );
- }else{
- d_equalityEngine.addTerm( n );
+ if( n.getKind() == APPLY_CONSTRUCTOR ){
+ //we must take into account subterm relation when checking for cycles
+ for( int i=0; i<(int)n.getNumChildren(); i++ ) {
+ Debug("datatypes-cycles") << "DtCyc: Subterm " << n << " -> " << n[i] << endl;
+ bool result = d_cycle_check.addEdgeNode( n, n[i] );
+ d_hasSeenCycle.set( d_hasSeenCycle.get() || result );
}
- Node rep = getRepresentative( n[0] );
- EqcInfo* eqc = getOrMakeEqcInfo( rep, true );
- if( !eqc->d_selectors ){
- eqc->d_selectors = true;
- instantiate( eqc, rep );
+ }else if( n.getKind() == APPLY_SELECTOR ){
+ if( d_selector_apps.find( n )==d_selector_apps.end() ){
+ d_selector_apps[n] = false;
+ //we must also record which selectors exist
+ Debug("datatypes") << " Found selector " << n << endl;
+ if (n.getType().isBoolean()) {
+ d_equalityEngine.addTriggerPredicate( n );
+ }else{
+ d_equalityEngine.addTerm( n );
+ }
+ Node rep = getRepresentative( n[0] );
+ EqcInfo* eqc = getOrMakeEqcInfo( rep, true );
+ if( !eqc->d_selectors ){
+ eqc->d_selectors = true;
+ instantiate( eqc, rep );
+ }
}
}
}
@@ -793,7 +803,7 @@ void TheoryDatatypes::processNewTerm( Node n ){
//see if it is rewritten to be something different
Node rn = Rewriter::rewrite( n );
if( rn!=n ){
- Node eq = rn.eqNode( n );
+ Node eq = n.getType().isBoolean() ? rn.iffNode( n ) : rn.eqNode( n );
d_pending.push_back( eq );
d_pending_exp[ eq ] = NodeManager::currentNM()->mkConst( true );
Trace("datatypes-infer") << "DtInfer : " << eq << ", trivial" << std::endl;
@@ -847,7 +857,7 @@ void TheoryDatatypes::collapseSelectors(){
Node sn = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR, op, cons );
Node s = Rewriter::rewrite( sn );
if( sn!=s ){
- Node eq = s.eqNode( sn );
+ Node eq = s.getType().isBoolean() ? s.iffNode( sn ) : s.eqNode( sn );
d_pending.push_back( eq );
d_pending_exp[ eq ] = NodeManager::currentNM()->mkConst( true );
Trace("datatypes-infer") << "DtInfer : " << eq << ", by rewrite" << std::endl;
@@ -879,7 +889,7 @@ void TheoryDatatypes::instantiate( EqcInfo* eqc, Node n ){
int index = getLabelIndex( eqc, n );
const Datatype& dt = ((DatatypeType)(tt.getType()).toType()).getDatatype();
//must be finite or have a selector
- if( eqc->d_selectors || dt[ index ].isFinite() || mustSpecifyModel() ){
+ if( eqc->d_selectors || dt[ index ].isFinite() || mustSpecifyAssignment() ){
//instantiate this equivalence class
eqc->d_inst = true;
Node tt_cons = getInstantiateCons( tt, dt, index );
@@ -963,9 +973,12 @@ bool TheoryDatatypes::searchForCycle( Node n, Node on,
return false;
}
-bool TheoryDatatypes::mustSpecifyModel(){
- return options::produceModels();
- //return options::finiteModelFind() || options::produceModels();
+bool TheoryDatatypes::mustSpecifyAssignment(){
+ //FIXME: the condition finiteModelFind is an over-approximation in this function
+ // we still may not want to specify assignments for datatypes that are truly infinite
+ // the fix for this is to correctly compute the cardinality for datatypes containing uninterpered sorts in fmf (i.e. by assuming they are finite)
+ return options::finiteModelFind() || options::produceModels() || options::dtForceAssignment();
+ //return options::produceModels();
//return false;
}
@@ -976,7 +989,7 @@ bool TheoryDatatypes::mustCommunicateFact( Node n, Node exp ){
// (3) Instantiate : is_C( t ) => t = C( sel_1( t ) ... sel_n( t ) )
//We may need to communicate (3) outwards if the conclusions involve other theories
Trace("dt-lemma-debug") << "Compute for " << exp << " => " << n << std::endl;
- if( n.getKind()==EQUAL && n[1].getKind()==APPLY_CONSTRUCTOR && exp.getKind()!=EQUAL ){
+ if( ( n.getKind()==EQUAL || n.getKind()==IFF) && n[1].getKind()==APPLY_CONSTRUCTOR && exp.getKind()!=EQUAL ){
bool addLemma = false;
#if 1
const Datatype& dt = ((DatatypeType)(n[1].getType()).toType()).getDatatype();
@@ -993,13 +1006,15 @@ bool TheoryDatatypes::mustCommunicateFact( Node n, Node exp ){
//check if we have already added this lemma
if( std::find( d_inst_lemmas[ n[0] ].begin(), d_inst_lemmas[ n[0] ].end(), n[1] )==d_inst_lemmas[ n[0] ].end() ){
d_inst_lemmas[ n[0] ].push_back( n[1] );
+ Trace("dt-lemma-debug") << "Communicate " << n << std::endl;
return true;
}else{
+ Trace("dt-lemma-debug") << "Already communicated " << n << std::endl;
return false;
}
}
- Trace("dt-lemma-debug") << "Do not need to communicate " << n << std::endl;
}
+ Trace("dt-lemma-debug") << "Do not need to communicate " << n << std::endl;
return false;
}
diff --git a/src/theory/datatypes/theory_datatypes.h b/src/theory/datatypes/theory_datatypes.h
index 90d82e255..46212ccbf 100644
--- a/src/theory/datatypes/theory_datatypes.h
+++ b/src/theory/datatypes/theory_datatypes.h
@@ -156,6 +156,8 @@ private:
context::CDO<bool> d_conflict;
/** The conflict node */
Node d_conflictNode;
+ /** cache for which terms we have called collectTerms(...) on */
+ BoolMap d_collectTermsCache;
/** pending assertions/merges */
std::vector< Node > d_pending;
std::map< Node, Node > d_pending_exp;
@@ -234,7 +236,7 @@ private:
* This returns true when the datatypes theory is expected to specify the constructor
* type for all equivalence classes.
*/
- bool mustSpecifyModel();
+ bool mustSpecifyAssignment();
/** must communicate fact */
bool mustCommunicateFact( Node n, Node exp );
private:
diff --git a/src/theory/datatypes/type_enumerator.h b/src/theory/datatypes/type_enumerator.h
index d8557fcaf..2a14d7fba 100644
--- a/src/theory/datatypes/type_enumerator.h
+++ b/src/theory/datatypes/type_enumerator.h
@@ -57,6 +57,7 @@ class DatatypesEnumerator : public TypeEnumeratorBase<DatatypesEnumerator> {
}
}
+
public:
DatatypesEnumerator(TypeNode type) throw() :
@@ -91,6 +92,25 @@ public:
newEnumerators();
}
+ DatatypesEnumerator(const DatatypesEnumerator& other) :
+ TypeEnumeratorBase<DatatypesEnumerator>(other.getType()),
+ d_datatype(other.d_datatype),
+ d_ctor(other.d_ctor),
+ d_zeroCtor(other.d_zeroCtor),
+ d_argEnumerators(NULL) {
+
+ if (other.d_argEnumerators != NULL) {
+ d_argEnumerators = new TypeEnumerator*[d_datatype[d_ctor].getNumArgs()];
+ for(size_t a = 0; a < d_datatype[d_ctor].getNumArgs(); ++a) {
+ if (other.d_argEnumerators[a] != NULL) {
+ d_argEnumerators[a] = new TypeEnumerator(*other.d_argEnumerators[a]);
+ } else {
+ d_argEnumerators[a] = NULL;
+ }
+ }
+ }
+ }
+
~DatatypesEnumerator() throw() {
deleteEnumerators();
}
diff --git a/src/theory/model.cpp b/src/theory/model.cpp
index 3880aaad9..713587be2 100644
--- a/src/theory/model.cpp
+++ b/src/theory/model.cpp
@@ -77,66 +77,72 @@ Cardinality TheoryModel::getCardinality( Type t ) const{
Node TheoryModel::getModelValue(TNode n, bool hasBoundVars) const
{
- Assert(n.getKind() != kind::FORALL && n.getKind() != kind::EXISTS);
- if(n.getKind() == kind::LAMBDA) {
- NodeManager* nm = NodeManager::currentNM();
- Node body = getModelValue(n[1], true);
- // This is a bit ugly, but cache inside simplifier can change, so can't be const
- // The ite simplifier is needed to get rid of artifacts created by Boolean terms
- body = const_cast<ITESimplifier*>(&d_iteSimp)->simpITE(body);
- body = Rewriter::rewrite(body);
- return nm->mkNode(kind::LAMBDA, n[0], body);
- }
- if(n.isConst() || (hasBoundVars && n.getKind() == kind::BOUND_VARIABLE)) {
- return n;
- }
-
- TypeNode t = n.getType();
- if (t.isFunction() || t.isPredicate()) {
- if (d_enableFuncModels) {
- std::map< Node, Node >::const_iterator it = d_uf_models.find(n);
- if (it != d_uf_models.end()) {
- // Existing function
- return it->second;
- }
- // Unknown function symbol: return LAMBDA x. c, where c is the first constant in the enumeration of the range type
- vector<TypeNode> argTypes = t.getArgTypes();
- vector<Node> args;
+ if(n.getKind() == kind::EXISTS || n.getKind() == kind::FORALL) {
+ CheckArgument(d_equalityEngine.hasTerm(n), n, "Cannot get the model value for a previously-unseen quantifier: %s", n.toString().c_str());
+ } else {
+ if(n.getKind() == kind::LAMBDA) {
NodeManager* nm = NodeManager::currentNM();
- for (unsigned i = 0; i < argTypes.size(); ++i) {
- args.push_back(nm->mkBoundVar(argTypes[i]));
- }
- Node boundVarList = nm->mkNode(kind::BOUND_VAR_LIST, args);
- TypeEnumerator te(t.getRangeType());
- return nm->mkNode(kind::LAMBDA, boundVarList, *te);
+ Node body = getModelValue(n[1], true);
+ // This is a bit ugly, but cache inside simplifier can change, so can't be const
+ // The ite simplifier is needed to get rid of artifacts created by Boolean terms
+ body = const_cast<ITESimplifier*>(&d_iteSimp)->simpITE(body);
+ body = Rewriter::rewrite(body);
+ return nm->mkNode(kind::LAMBDA, n[0], body);
}
- // TODO: if func models not enabled, throw an error?
- Unreachable();
- }
-
- if (n.getNumChildren() > 0) {
- std::vector<Node> children;
- if (n.getKind() == APPLY_UF) {
- Node op = getModelValue(n.getOperator(), hasBoundVars);
- children.push_back(op);
+ if(n.isConst() || (hasBoundVars && n.getKind() == kind::BOUND_VARIABLE)) {
+ return n;
}
- else if (n.getMetaKind() == kind::metakind::PARAMETERIZED) {
- children.push_back(n.getOperator());
+
+ TypeNode t = n.getType();
+ if (t.isFunction() || t.isPredicate()) {
+ if (d_enableFuncModels) {
+ std::map< Node, Node >::const_iterator it = d_uf_models.find(n);
+ if (it != d_uf_models.end()) {
+ // Existing function
+ return it->second;
+ }
+ // Unknown function symbol: return LAMBDA x. c, where c is the first constant in the enumeration of the range type
+ vector<TypeNode> argTypes = t.getArgTypes();
+ vector<Node> args;
+ NodeManager* nm = NodeManager::currentNM();
+ for (unsigned i = 0; i < argTypes.size(); ++i) {
+ args.push_back(nm->mkBoundVar(argTypes[i]));
+ }
+ Node boundVarList = nm->mkNode(kind::BOUND_VAR_LIST, args);
+ TypeEnumerator te(t.getRangeType());
+ return nm->mkNode(kind::LAMBDA, boundVarList, *te);
+ }
+ // TODO: if func models not enabled, throw an error?
+ Unreachable();
}
- //evaluate the children
- for (unsigned i = 0; i < n.getNumChildren(); ++i) {
- Node val = getModelValue(n[i], hasBoundVars);
- children.push_back(val);
+
+ if (n.getNumChildren() > 0) {
+ std::vector<Node> children;
+ if (n.getKind() == APPLY_UF) {
+ Node op = getModelValue(n.getOperator(), hasBoundVars);
+ children.push_back(op);
+ }
+ else if (n.getMetaKind() == kind::metakind::PARAMETERIZED) {
+ children.push_back(n.getOperator());
+ }
+ //evaluate the children
+ for (unsigned i = 0; i < n.getNumChildren(); ++i) {
+ Node val = getModelValue(n[i], hasBoundVars);
+ children.push_back(val);
+ }
+ Node val = Rewriter::rewrite(NodeManager::currentNM()->mkNode(n.getKind(), children));
+ if(val.getKind() == kind::CARDINALITY_CONSTRAINT) {
+ val = NodeManager::currentNM()->mkConst(getCardinality(val[0].getType().toType()).getFiniteCardinality() <= val[1].getConst<Rational>().getNumerator());
+ }
+ Assert(hasBoundVars || val.isConst());
+ return val;
}
- Node val = Rewriter::rewrite(NodeManager::currentNM()->mkNode(n.getKind(), children));
- Assert(hasBoundVars || val.isConst());
- return val;
- }
- if (!d_equalityEngine.hasTerm(n)) {
- // Unknown term - return first enumerated value for this type
- TypeEnumerator te(n.getType());
- return *te;
+ if (!d_equalityEngine.hasTerm(n)) {
+ // Unknown term - return first enumerated value for this type
+ TypeEnumerator te(n.getType());
+ return *te;
+ }
}
Node val = d_equalityEngine.getRepresentative(n);
Assert(d_reps.find(val) != d_reps.end());
diff --git a/src/theory/quantifiers/first_order_model.cpp b/src/theory/quantifiers/first_order_model.cpp
index 3d98674a8..8272ce168 100644
--- a/src/theory/quantifiers/first_order_model.cpp
+++ b/src/theory/quantifiers/first_order_model.cpp
@@ -42,10 +42,6 @@ void FirstOrderModel::reset(){
TheoryModel::reset();
}
-void FirstOrderModel::addTerm( Node n ){
- TheoryModel::addTerm( n );
-}
-
void FirstOrderModel::initialize( bool considerAxioms ){
//rebuild models
d_uf_model_tree.clear();
diff --git a/src/theory/quantifiers/first_order_model.h b/src/theory/quantifiers/first_order_model.h
index 3779579fd..50a941968 100644
--- a/src/theory/quantifiers/first_order_model.h
+++ b/src/theory/quantifiers/first_order_model.h
@@ -33,8 +33,6 @@ class TermDb;
class FirstOrderModel : public TheoryModel
{
private:
- //add term function
- void addTerm( Node n );
//for initialize model
void initializeModelForTerm( Node n );
/** whether an axiom is asserted */
diff --git a/src/theory/quantifiers/inst_match.cpp b/src/theory/quantifiers/inst_match.cpp
index 1a48ec161..dcd7a1b79 100644
--- a/src/theory/quantifiers/inst_match.cpp
+++ b/src/theory/quantifiers/inst_match.cpp
@@ -217,6 +217,88 @@ bool InstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, b
}
+
+/** add match m for quantifier f starting at index, take into account equalities q, return true if successful */
+void CDInstMatchTrie::addInstMatch2( QuantifiersEngine* qe, Node f, InstMatch& m, context::Context* c, int index, ImtIndexOrder* imtio ){
+ if( long(index)<long(f[0].getNumChildren()) && ( !imtio || long(index)<long(imtio->d_order.size()) ) ){
+ int i_index = imtio ? imtio->d_order[index] : index;
+ Node n = m.getValue( qe->getTermDatabase()->getInstantiationConstant( f, i_index ) );
+ std::map< Node, CDInstMatchTrie* >::iterator it = d_data.find( n );
+ if( it!=d_data.end() ){
+ it->second->addInstMatch2( qe, f, m, c, index+1, imtio );
+ }else{
+ CDInstMatchTrie* imt = new CDInstMatchTrie( c );
+ d_data[n] = imt;
+ imt->d_valid = true;
+ imt->addInstMatch2( qe, f, m, c, index+1, imtio );
+ }
+ }
+}
+
+/** exists match */
+bool CDInstMatchTrie::existsInstMatch2( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, bool modInst, int index, ImtIndexOrder* imtio ){
+ if( !d_valid ){
+ return false;
+ }else if( long(index)==long(f[0].getNumChildren()) || ( imtio && long(index)==long(imtio->d_order.size()) ) ){
+ return true;
+ }else{
+ int i_index = imtio ? imtio->d_order[index] : index;
+ Node n = m.getValue( qe->getTermDatabase()->getInstantiationConstant( f, i_index ) );
+ std::map< Node, CDInstMatchTrie* >::iterator it = d_data.find( n );
+ if( it!=d_data.end() ){
+ if( it->second->existsInstMatch2( qe, f, m, modEq, modInst, index+1, imtio ) ){
+ return true;
+ }
+ }
+ //check if m is an instance of another instantiation if modInst is true
+ if( modInst ){
+ if( !n.isNull() ){
+ Node nl;
+ it = d_data.find( nl );
+ if( it!=d_data.end() ){
+ if( it->second->existsInstMatch2( qe, f, m, modEq, modInst, index+1, imtio ) ){
+ return true;
+ }
+ }
+ }
+ }
+ if( modEq ){
+ //check modulo equality if any other instantiation match exists
+ if( !n.isNull() && qe->getEqualityQuery()->getEngine()->hasTerm( n ) ){
+ eq::EqClassIterator eqc( qe->getEqualityQuery()->getEngine()->getRepresentative( n ),
+ qe->getEqualityQuery()->getEngine() );
+ while( !eqc.isFinished() ){
+ Node en = (*eqc);
+ if( en!=n ){
+ std::map< Node, CDInstMatchTrie* >::iterator itc = d_data.find( en );
+ if( itc!=d_data.end() ){
+ if( itc->second->existsInstMatch2( qe, f, m, modEq, modInst, index+1, imtio ) ){
+ return true;
+ }
+ }
+ }
+ ++eqc;
+ }
+ }
+ }
+ return false;
+ }
+}
+
+bool CDInstMatchTrie::existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, bool modInst, ImtIndexOrder* imtio ){
+ return existsInstMatch2( qe, f, m, modEq, modInst, 0, imtio );
+}
+
+bool CDInstMatchTrie::addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, Context* c, bool modEq, bool modInst, ImtIndexOrder* imtio ){
+ if( !existsInstMatch( qe, f, m, modEq, modInst, imtio ) ){
+ addInstMatch2( qe, f, m, c, 0, imtio );
+ return true;
+ }else{
+ return false;
+ }
+}
+
+
}/* CVC4::theory::inst namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/quantifiers/inst_match.h b/src/theory/quantifiers/inst_match.h
index c8f843c90..8b2d9726b 100644
--- a/src/theory/quantifiers/inst_match.h
+++ b/src/theory/quantifiers/inst_match.h
@@ -18,6 +18,7 @@
#define __CVC4__THEORY__QUANTIFIERS__INST_MATCH_H
#include "util/hash.h"
+#include "context/cdo.h"
#include <ext/hash_set>
#include <map>
@@ -141,6 +142,42 @@ public:
bool modInst = false, ImtIndexOrder* imtio = NULL );
};/* class InstMatchTrie */
+
+/** trie for InstMatch objects */
+class CDInstMatchTrie {
+public:
+ class ImtIndexOrder {
+ public:
+ std::vector< int > d_order;
+ };/* class InstMatchTrie ImtIndexOrder */
+private:
+ /** add match m for quantifier f starting at index, take into account equalities q, return true if successful */
+ void addInstMatch2( QuantifiersEngine* qe, Node f, InstMatch& m, context::Context* c, int index, ImtIndexOrder* imtio );
+ /** exists match */
+ bool existsInstMatch2( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq, bool modInst, int index, ImtIndexOrder* imtio );
+public:
+ /** the data */
+ std::map< Node, CDInstMatchTrie* > d_data;
+ /** is valid */
+ context::CDO< bool > d_valid;
+public:
+ CDInstMatchTrie( context::Context* c ) : d_valid( c, false ){}
+ ~CDInstMatchTrie(){}
+public:
+ /** return true if m exists in this trie
+ modEq is if we check modulo equality
+ modInst is if we return true if m is an instance of a match that exists
+ */
+ bool existsInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, bool modEq = false,
+ bool modInst = false, ImtIndexOrder* imtio = NULL );
+ /** add match m for quantifier f, take into account equalities if modEq = true,
+ if imtio is non-null, this is the order to add to trie
+ return true if successful
+ */
+ bool addInstMatch( QuantifiersEngine* qe, Node f, InstMatch& m, context::Context* c, bool modEq = false,
+ bool modInst = false, ImtIndexOrder* imtio = NULL );
+};/* class CDInstMatchTrie */
+
class InstMatchTrieOrdered{
private:
InstMatchTrie::ImtIndexOrder* d_imtio;
diff --git a/src/theory/quantifiers/inst_strategy_e_matching.h b/src/theory/quantifiers/inst_strategy_e_matching.h
index ea22486a6..23f0d8a54 100755
--- a/src/theory/quantifiers/inst_strategy_e_matching.h
+++ b/src/theory/quantifiers/inst_strategy_e_matching.h
@@ -87,6 +87,9 @@ private:
/** generate triggers */
void generateTriggers( Node f );
public:
+ /** tstrt is the type of triggers to use (maximum depth, minimum depth, or all)
+ rstrt is the relevance setting for trigger (use only relevant triggers vs. use all)
+ rgfr is the frequency at which triggers are generated */
InstStrategyAutoGenTriggers( QuantifiersEngine* qe, int tstrt, int rstrt, int rgfr = -1 ) :
InstStrategy( qe ), d_tr_strategy( tstrt ), d_rlv_strategy( rstrt ), d_generate_additional( false ){
setRegenerateFrequency( rgfr );
diff --git a/src/theory/quantifiers/instantiation_engine.cpp b/src/theory/quantifiers/instantiation_engine.cpp
index 579c53665..53977ee4f 100644
--- a/src/theory/quantifiers/instantiation_engine.cpp
+++ b/src/theory/quantifiers/instantiation_engine.cpp
@@ -48,8 +48,8 @@ void InstantiationEngine::finishInit(){
}else{
d_isup = NULL;
}
- InstStrategyAutoGenTriggers* i_ag = new InstStrategyAutoGenTriggers( d_quantEngine, Trigger::TS_ALL,
- InstStrategyAutoGenTriggers::RELEVANCE_DEFAULT, 3 );
+ int rlv = options::relevantTriggers() ? InstStrategyAutoGenTriggers::RELEVANCE_DEFAULT : InstStrategyAutoGenTriggers::RELEVANCE_NONE;
+ InstStrategyAutoGenTriggers* i_ag = new InstStrategyAutoGenTriggers( d_quantEngine, Trigger::TS_ALL, rlv, 3 );
i_ag->setGenerateAdditional( true );
addInstStrategy( i_ag );
//addInstStrategy( new InstStrategyAddFailSplits( this, ie ) );
@@ -60,11 +60,10 @@ void InstantiationEngine::finishInit(){
//d_isup->setPriorityOver( i_agm );
//i_ag->setPriorityOver( i_agm );
}
- //CBQI: FIXME
//for arithmetic
- //if( options::cbqi() ){
- // addInstStrategy( new InstStrategySimplex( d_quantEngine ) );
- //}
+ if( options::cbqi() ){
+ addInstStrategy( new InstStrategySimplex( (arith::TheoryArith*)d_quantEngine->getTheoryEngine()->theoryOf( THEORY_ARITH ), d_quantEngine ) );
+ }
//for datatypes
//if( options::cbqi() ){
// addInstStrategy( new InstStrategyDatatypesValue( d_quantEngine ) );
diff --git a/src/theory/quantifiers/options b/src/theory/quantifiers/options
index 24d0c4047..bc45e6051 100644
--- a/src/theory/quantifiers/options
+++ b/src/theory/quantifiers/options
@@ -44,6 +44,9 @@ option macrosQuant --macros-quant bool :default false
# Whether to use smart triggers
option smartTriggers /--disable-smart-triggers bool :default true
disable smart triggers
+# Whether to use relevent triggers
+option relevantTriggers /--relevant-triggers bool :default true
+ prefer triggers that are more relevant based on SInE style method
# Whether to consider terms in the bodies of quantifiers for matching
option registerQuantBodyTerms --register-quant-body-terms bool :default false
diff --git a/src/theory/quantifiers/quantifiers_attributes.cpp b/src/theory/quantifiers/quantifiers_attributes.cpp
index 493a49e54..2f6dc47db 100644
--- a/src/theory/quantifiers/quantifiers_attributes.cpp
+++ b/src/theory/quantifiers/quantifiers_attributes.cpp
@@ -22,7 +22,7 @@ using namespace CVC4::context;
using namespace CVC4::theory;
using namespace CVC4::theory::quantifiers;
-void QuantifiersAttributes::setUserAttribute( std::string& attr, Node n ){
+void QuantifiersAttributes::setUserAttribute( const std::string& attr, Node n ){
if( n.getKind()==FORALL ){
if( attr=="axiom" ){
Trace("quant-attr") << "Set axiom " << n << std::endl;
diff --git a/src/theory/quantifiers/quantifiers_attributes.h b/src/theory/quantifiers/quantifiers_attributes.h
index 822d6c59f..88bac8bc9 100644
--- a/src/theory/quantifiers/quantifiers_attributes.h
+++ b/src/theory/quantifiers/quantifiers_attributes.h
@@ -40,7 +40,7 @@ struct QuantifiersAttributes
* This function will apply a custom set of attributes to all top-level universal
* quantifiers contained in n
*/
- static void setUserAttribute( std::string& attr, Node n );
+ static void setUserAttribute( const std::string& attr, Node n );
};
diff --git a/src/theory/quantifiers/theory_quantifiers.cpp b/src/theory/quantifiers/theory_quantifiers.cpp
index cfdb30f38..d1dbae90c 100644
--- a/src/theory/quantifiers/theory_quantifiers.cpp
+++ b/src/theory/quantifiers/theory_quantifiers.cpp
@@ -93,7 +93,15 @@ Node TheoryQuantifiers::getValue(TNode n) {
}
void TheoryQuantifiers::collectModelInfo( TheoryModel* m, bool fullModel ){
-
+ if( fullModel ){
+ for(assertions_iterator i = facts_begin(); i != facts_end(); ++i) {
+ if((*i).assertion.getKind() == kind::NOT) {
+ m->assertPredicate((*i).assertion[0], false);
+ } else {
+ m->assertPredicate(*i, true);
+ }
+ }
+ }
}
void TheoryQuantifiers::check(Effort e) {
@@ -192,6 +200,6 @@ bool TheoryQuantifiers::restart(){
}
}
-void TheoryQuantifiers::setUserAttribute( std::string& attr, Node n ){
+void TheoryQuantifiers::setUserAttribute( const std::string& attr, Node n ){
QuantifiersAttributes::setUserAttribute( attr, n );
}
diff --git a/src/theory/quantifiers/theory_quantifiers.h b/src/theory/quantifiers/theory_quantifiers.h
index c3987144c..b4c8966c7 100644
--- a/src/theory/quantifiers/theory_quantifiers.h
+++ b/src/theory/quantifiers/theory_quantifiers.h
@@ -70,7 +70,7 @@ public:
void shutdown() { }
std::string identify() const { return std::string("TheoryQuantifiers"); }
bool flipDecision();
- void setUserAttribute( std::string& attr, Node n );
+ void setUserAttribute( const std::string& attr, Node n );
eq::EqualityEngine* getMasterEqualityEngine() { return d_masterEqualityEngine; }
private:
void assertUniversal( Node n );
diff --git a/src/theory/quantifiers_engine.cpp b/src/theory/quantifiers_engine.cpp
index c04920ab8..08bdd496b 100644
--- a/src/theory/quantifiers_engine.cpp
+++ b/src/theory/quantifiers_engine.cpp
@@ -35,9 +35,10 @@ using namespace CVC4::context;
using namespace CVC4::theory;
using namespace CVC4::theory::inst;
-QuantifiersEngine::QuantifiersEngine(context::Context* c, TheoryEngine* te):
+QuantifiersEngine::QuantifiersEngine(context::Context* c, context::UserContext* u, TheoryEngine* te):
d_te( te ),
-d_quant_rel( false ){ //currently do not care about relevance
+d_quant_rel( false ),
+d_lemmas_produced_c(u){
d_eq_query = new EqualityQueryQuantifiersEngine( this );
d_term_db = new quantifiers::TermDb( this );
d_tr_trie = new inst::TriggerTrie;
@@ -92,6 +93,10 @@ context::Context* QuantifiersEngine::getSatContext(){
return d_te->theoryOf( THEORY_QUANTIFIERS )->getSatContext();
}
+context::Context* QuantifiersEngine::getUserContext(){
+ return d_te->theoryOf( THEORY_QUANTIFIERS )->getUserContext();
+}
+
OutputChannel& QuantifiersEngine::getOutputChannel(){
return d_te->theoryOf( THEORY_QUANTIFIERS )->getOutputChannel();
}
@@ -309,7 +314,7 @@ Node QuantifiersEngine::getInstantiation( Node f, InstMatch& m ){
bool QuantifiersEngine::existsInstantiation( Node f, InstMatch& m, bool modEq, bool modInst ){
if( d_inst_match_trie.find( f )!=d_inst_match_trie.end() ){
- if( d_inst_match_trie[f].existsInstMatch( this, f, m, modEq, modInst ) ){
+ if( d_inst_match_trie[f]->existsInstMatch( this, f, m, modEq, modInst ) ){
return true;
}
}
@@ -323,9 +328,9 @@ bool QuantifiersEngine::existsInstantiation( Node f, InstMatch& m, bool modEq, b
bool QuantifiersEngine::addLemma( Node lem ){
Debug("inst-engine-debug") << "Adding lemma : " << lem << std::endl;
lem = Rewriter::rewrite(lem);
- if( d_lemmas_produced.find( lem )==d_lemmas_produced.end() ){
+ if( d_lemmas_produced_c.find( lem )==d_lemmas_produced_c.end() ){
//d_curr_out->lemma( lem );
- d_lemmas_produced[ lem ] = true;
+ d_lemmas_produced_c[ lem ] = true;
d_lemmas_waiting.push_back( lem );
Debug("inst-engine-debug") << "Added lemma : " << lem << std::endl;
return true;
@@ -355,11 +360,21 @@ bool QuantifiersEngine::addInstantiation( Node f, InstMatch& m, bool modEq, bool
}
}
//check for duplication modulo equality
- if( !d_inst_match_trie[f].addInstMatch( this, f, m, modEq, modInst ) ){
+ inst::CDInstMatchTrie* imt;
+ std::map< Node, inst::CDInstMatchTrie* >::iterator it = d_inst_match_trie.find( f );
+ if( it!=d_inst_match_trie.end() ){
+ imt = it->second;
+ }else{
+ imt = new CDInstMatchTrie( getUserContext() );
+ d_inst_match_trie[f] = imt;
+ }
+ Trace("inst-add-debug") << "Adding into inst trie" << std::endl;
+ if( !imt->addInstMatch( this, f, m, getUserContext(), modEq, modInst ) ){
Trace("inst-add-debug") << " -> Already exists." << std::endl;
++(d_statistics.d_inst_duplicate);
return false;
}
+ Trace("inst-add-debug") << "compute terms" << std::endl;
//compute the vector of terms for the instantiation
std::vector< Node > terms;
for( size_t i=0; i<d_term_db->d_inst_constants[f].size(); i++ ){
diff --git a/src/theory/quantifiers_engine.h b/src/theory/quantifiers_engine.h
index 8169c78fb..29381a309 100644
--- a/src/theory/quantifiers_engine.h
+++ b/src/theory/quantifiers_engine.h
@@ -104,12 +104,13 @@ private:
std::vector< Node > d_quants;
/** list of all lemmas produced */
std::map< Node, bool > d_lemmas_produced;
+ BoolMap d_lemmas_produced_c;
/** lemmas waiting */
std::vector< Node > d_lemmas_waiting;
/** has added lemma this round */
bool d_hasAddedLemma;
/** list of all instantiations produced for each quantifier */
- std::map< Node, inst::InstMatchTrie > d_inst_match_trie;
+ std::map< Node, inst::CDInstMatchTrie* > d_inst_match_trie;
/** term database */
quantifiers::TermDb* d_term_db;
/** all triggers will be stored in this trie */
@@ -121,7 +122,7 @@ private:
private:
KEEP_STATISTIC(TimerStat, d_time, "theory::QuantifiersEngine::time");
public:
- QuantifiersEngine(context::Context* c, TheoryEngine* te);
+ QuantifiersEngine(context::Context* c, context::UserContext* u, TheoryEngine* te);
~QuantifiersEngine();
/** get instantiator for id */
//Instantiator* getInstantiator( theory::TheoryId id );
@@ -136,6 +137,8 @@ public:
quantifiers::ModelEngine* getModelEngine() { return d_model_engine; }
/** get default sat context for quantifiers engine */
context::Context* getSatContext();
+ /** get default sat context for quantifiers engine */
+ context::Context* getUserContext();
/** get default output channel for the quantifiers engine */
OutputChannel& getOutputChannel();
/** get default valuation for the quantifiers engine */
diff --git a/src/theory/rewriterules/theory_rewriterules.cpp b/src/theory/rewriterules/theory_rewriterules.cpp
index c6fd9611c..a82b94f73 100644
--- a/src/theory/rewriterules/theory_rewriterules.cpp
+++ b/src/theory/rewriterules/theory_rewriterules.cpp
@@ -276,7 +276,7 @@ void TheoryRewriteRules::check(Effort level) {
if(glast.inst == RULEINST_TRUE||glast.inst == RULEINST_FALSE)
continue;
// If it has a value it should already has been notified
- bool value; value = value; // avoiding the warning in non debug mode
+ bool value CVC4_UNUSED;
Assert(!getValuation().hasSatValue(g,value));
Debug("rewriterules::check") << "RewriteRules::Check Narrowing on:" << g << std::endl;
/** Can split on already rewritten instrule... but... */
diff --git a/src/theory/theory.h b/src/theory/theory.h
index f317d4b92..5b2032430 100644
--- a/src/theory/theory.h
+++ b/src/theory/theory.h
@@ -33,6 +33,7 @@
#include "options/options.h"
#include "util/statistics_registry.h"
#include "util/dump.h"
+#include "lib/ffs.h"
#include <string>
#include <iostream>
@@ -49,13 +50,13 @@ namespace theory {
class QuantifiersEngine;
class TheoryModel;
-namespace rrinst{
-class CandidateGenerator;
-}
+namespace rrinst {
+ class CandidateGenerator;
+}/* CVC4::theory::rrinst namespace */
namespace eq {
-class EqualityEngine;
-}
+ class EqualityEngine;
+}/* CVC4::theory::eq namespace */
/**
* Information about an assertion for the theories.
@@ -786,14 +787,10 @@ public:
std::hash_set<TNode, TNodeHashFunction> currentlySharedTerms() const;
};/* class Theory */
-std::ostream& operator<<(std::ostream& os, Theory::Effort level);
-
-namespace eq{
- class EqualityEngine;
-}
-
+std::ostream& operator<<(std::ostream& os, theory::Theory::Effort level);
+inline std::ostream& operator<<(std::ostream& out, const theory::Assertion& a);
-inline Assertion Theory::get() {
+inline theory::Assertion Theory::get() {
Assert( !done(), "Theory::get() called with assertion queue empty!" );
// Get the assertion
@@ -809,7 +806,9 @@ inline Assertion Theory::get() {
return fact;
}
-}/* CVC4::theory namespace */
+inline std::ostream& operator<<(std::ostream& out, const theory::Assertion& a) {
+ return out << a.assertion;
+}
inline std::ostream& operator<<(std::ostream& out,
const CVC4::theory::Theory& theory) {
@@ -830,6 +829,7 @@ inline std::ostream& operator << (std::ostream& out, theory::Theory::PPAssertSta
return out;
}
+}/* CVC4::theory namespace */
}/* CVC4 namespace */
#endif /* __CVC4__THEORY__THEORY_H */
diff --git a/src/theory/theory_engine.cpp b/src/theory/theory_engine.cpp
index c0aa58647..35ed63bed 100644
--- a/src/theory/theory_engine.cpp
+++ b/src/theory/theory_engine.cpp
@@ -127,7 +127,7 @@ TheoryEngine::TheoryEngine(context::Context* context,
}
// initialize the quantifiers engine
- d_quantEngine = new QuantifiersEngine(context, this);
+ d_quantEngine = new QuantifiersEngine(context, userContext, this);
// build model information if applicable
d_curr_model = new theory::TheoryModel(userContext, "DefaultModel", true);
@@ -740,8 +740,7 @@ theory::Theory::PPAssertStatus TheoryEngine::solve(TNode literal, SubstitutionMa
}
// Recursively traverse a term and call the theory rewriter on its sub-terms
-Node TheoryEngine::ppTheoryRewrite(TNode term)
-{
+Node TheoryEngine::ppTheoryRewrite(TNode term) {
NodeMap::iterator find = d_ppCache.find(term);
if (find != d_ppCache.end()) {
return (*find).second;
@@ -826,7 +825,8 @@ Node TheoryEngine::preprocess(TNode assertion) {
// If this is an atom, we preprocess its terms with the theory ppRewriter
if (Theory::theoryOf(current) != THEORY_BOOL) {
- d_ppCache[current] = ppTheoryRewrite(current);
+ Node ppRewritten = ppTheoryRewrite(current);
+ d_ppCache[current] = ppRewritten;
Assert(Rewriter::rewrite(d_ppCache[current]) == d_ppCache[current]);
continue;
}
@@ -1378,19 +1378,19 @@ void TheoryEngine::handleUserAttribute(const char* attr, Theory* t) {
d_attr_handle[ str ].push_back( t );
}
-void TheoryEngine::checkTheoryAssertionsWithModel()
-{
- for (TheoryId theoryId = THEORY_FIRST; theoryId < THEORY_LAST; ++theoryId) {
- Theory* theory = d_theoryTable[theoryId];
- if (theory && d_logicInfo.isTheoryEnabled(theoryId)) {
- if (theoryId == THEORY_QUANTIFIERS || theoryId == THEORY_REWRITERULES) {
- continue;
- }
- context::CDList<Assertion>::const_iterator it = theory->facts_begin(), it_end = theory->facts_end();
- for (unsigned i = 0; it != it_end; ++ it, ++i) {
- Node assertion = (*it).assertion;
- Node val = getModel()->getValue(assertion);
- Assert(val == d_true);
+void TheoryEngine::checkTheoryAssertionsWithModel() {
+ for(TheoryId theoryId = THEORY_FIRST; theoryId < THEORY_LAST; ++theoryId) {
+ if(theoryId != THEORY_REWRITERULES) {
+ Theory* theory = d_theoryTable[theoryId];
+ if(theory && d_logicInfo.isTheoryEnabled(theoryId)) {
+ for(context::CDList<Assertion>::const_iterator it = theory->facts_begin(),
+ it_end = theory->facts_end();
+ it != it_end;
+ ++it) {
+ Node assertion = (*it).assertion;
+ Node val = getModel()->getValue(assertion);
+ Assert(val == d_true);
+ }
}
}
}
diff --git a/src/util/bitvector.h b/src/util/bitvector.h
index 5df632ff4..c9661c0c7 100644
--- a/src/util/bitvector.h
+++ b/src/util/bitvector.h
@@ -190,22 +190,27 @@ public:
return d_value.isBitSet(i);
}
- BitVector unsignedDiv (const BitVector& y) const {
+ /**
+ * Total division function that returns 0 when the denominator is 0.
+ */
+ BitVector unsignedDivTotal (const BitVector& y) const {
+
CheckArgument(d_size == y.d_size, y);
- // TODO: decide whether we really want these semantics
if (y.d_value == 0) {
- return BitVector(d_size, Integer(0));
+ return BitVector(d_size, 0u);
}
CheckArgument(d_value >= 0, this);
CheckArgument(y.d_value > 0, y);
return BitVector(d_size, d_value.floorDivideQuotient(y.d_value));
}
-
- BitVector unsignedRem(const BitVector& y) const {
+
+ /**
+ * Total division function that returns 0 when the denominator is 0.
+ */
+ BitVector unsignedRemTotal(const BitVector& y) const {
CheckArgument(d_size == y.d_size, y);
- // TODO: decide whether we really want these semantics
if (y.d_value == 0) {
- return BitVector(d_size, d_value);
+ return BitVector(d_size, 0u);
}
CheckArgument(d_value >= 0, this);
CheckArgument(y.d_value > 0, y);
diff --git a/src/util/integer_cln_imp.h b/src/util/integer_cln_imp.h
index e2a8f4a62..81c0428cb 100644
--- a/src/util/integer_cln_imp.h
+++ b/src/util/integer_cln_imp.h
@@ -285,6 +285,61 @@ public:
}
/**
+ * Computes a quoitent and remainder according to Boute's Euclidean definition.
+ * euclidianDivideQuotient, euclidianDivideRemainder.
+ *
+ * Boute, Raymond T. (April 1992).
+ * The Euclidean definition of the functions div and mod.
+ * ACM Transactions on Programming Languages and Systems (TOPLAS)
+ * ACM Press. 14 (2): 127 - 144. doi:10.1145/128861.128862.
+ */
+ static void euclidianQR(Integer& q, Integer& r, const Integer& x, const Integer& y) {
+ // compute the floor and then fix the value up if needed.
+ floorQR(q,r,x,y);
+
+ if(r.strictlyNegative()){
+ // if r < 0
+ // abs(r) < abs(y)
+ // - abs(y) < r < 0, then 0 < r + abs(y) < abs(y)
+ // n = y * q + r
+ // n = y * q - abs(y) + r + abs(y)
+ if(r.sgn() >= 0){
+ // y = abs(y)
+ // n = y * q - y + r + y
+ // n = y * (q-1) + (r+y)
+ q -= 1;
+ r += y;
+ }else{
+ // y = -abs(y)
+ // n = y * q + y + r - y
+ // n = y * (q+1) + (r-y)
+ q += 1;
+ r -= y;
+ }
+ }
+ }
+
+ /**
+ * Returns the quoitent according to Boute's Euclidean definition.
+ * See the documentation for euclidianQR.
+ */
+ Integer euclidianDivideQuotient(const Integer& y) const {
+ Integer q,r;
+ euclidianQR(q,r, *this, y);
+ return q;
+ }
+
+ /**
+ * Returns the remainfing according to Boute's Euclidean definition.
+ * See the documentation for euclidianQR.
+ */
+ Integer euclidianDivideRemainder(const Integer& y) const {
+ Integer q,r;
+ euclidianQR(q,r, *this, y);
+ return r;
+ }
+
+ /**
* If y divides *this, then exactQuotient returns (this/y)
*/
Integer exactQuotient(const Integer& y) const {
@@ -381,15 +436,24 @@ public:
return cln::cl_I_to_int(sgn);
}
- bool isZero() const {
- return cln::zerop(d_value);
+
+ inline bool strictlyPositive() const {
+ return sgn() > 0;
+ }
+
+ inline bool strictlyNegative() const {
+ return sgn() < 0;
+ }
+
+ inline bool isZero() const {
+ return sgn() == 0;
}
- bool isOne() const {
+ inline bool isOne() const {
return d_value == 1;
}
- bool isNegativeOne() const {
+ inline bool isNegativeOne() const {
return d_value == -1;
}
diff --git a/src/util/integer_gmp_imp.h b/src/util/integer_gmp_imp.h
index d6882b6ac..85d49f921 100644
--- a/src/util/integer_gmp_imp.h
+++ b/src/util/integer_gmp_imp.h
@@ -199,16 +199,16 @@ public:
mpz_class res = d_value;
for (unsigned i = size; i < size + amount; ++i) {
- mpz_setbit(res.get_mpz_t(), i);
+ mpz_setbit(res.get_mpz_t(), i);
}
-
- return Integer(res);
+
+ return Integer(res);
}
-
+
uint32_t toUnsignedInt() const {
return mpz_get_ui(d_value.get_mpz_t());
}
-
+
/** See GMP Documentation. */
Integer extractBitRange(uint32_t bitCount, uint32_t low) const {
// bitCount = high-low+1
@@ -265,6 +265,61 @@ public:
}
/**
+ * Computes a quoitent and remainder according to Boute's Euclidean definition.
+ * euclidianDivideQuotient, euclidianDivideRemainder.
+ *
+ * Boute, Raymond T. (April 1992).
+ * The Euclidean definition of the functions div and mod.
+ * ACM Transactions on Programming Languages and Systems (TOPLAS)
+ * ACM Press. 14 (2): 127 - 144. doi:10.1145/128861.128862.
+ */
+ static void euclidianQR(Integer& q, Integer& r, const Integer& x, const Integer& y) {
+ // compute the floor and then fix the value up if needed.
+ floorQR(q,r,x,y);
+
+ if(r.strictlyNegative()){
+ // if r < 0
+ // abs(r) < abs(y)
+ // - abs(y) < r < 0, then 0 < r + abs(y) < abs(y)
+ // n = y * q + r
+ // n = y * q - abs(y) + r + abs(y)
+ if(r.sgn() >= 0){
+ // y = abs(y)
+ // n = y * q - y + r + y
+ // n = y * (q-1) + (r+y)
+ q -= 1;
+ r += y;
+ }else{
+ // y = -abs(y)
+ // n = y * q + y + r - y
+ // n = y * (q+1) + (r-y)
+ q += 1;
+ r -= y;
+ }
+ }
+ }
+ /**
+ * Returns the quoitent according to Boute's Euclidean definition.
+ * See the documentation for euclidianQR.
+ */
+ Integer euclidianDivideQuotient(const Integer& y) const {
+ Integer q,r;
+ euclidianQR(q,r, *this, y);
+ return q;
+ }
+
+ /**
+ * Returns the remainfing according to Boute's Euclidean definition.
+ * See the documentation for euclidianQR.
+ */
+ Integer euclidianDivideRemainder(const Integer& y) const {
+ Integer q,r;
+ euclidianQR(q,r, *this, y);
+ return r;
+ }
+
+
+ /**
* If y divides *this, then exactQuotient returns (this/y)
*/
Integer exactQuotient(const Integer& y) const {
@@ -278,7 +333,7 @@ public:
* Returns y mod 2^exp
*/
Integer modByPow2(uint32_t exp) const {
- mpz_class res;
+ mpz_class res;
mpz_fdiv_r_2exp(res.get_mpz_t(), d_value.get_mpz_t(), exp);
return Integer(res);
}
@@ -292,12 +347,20 @@ public:
return Integer(res);
}
-
+
int sgn() const {
return mpz_sgn(d_value.get_mpz_t());
}
- bool isZero() const {
+ inline bool strictlyPositive() const {
+ return sgn() > 0;
+ }
+
+ inline bool strictlyNegative() const {
+ return sgn() < 0;
+ }
+
+ inline bool isZero() const {
return sgn() == 0;
}
diff --git a/src/util/node_visitor.h b/src/util/node_visitor.h
index e444ba6e2..4c8e646bd 100644
--- a/src/util/node_visitor.h
+++ b/src/util/node_visitor.h
@@ -36,10 +36,11 @@ class NodeVisitor {
/**
* Guard against NodeVisitor<> being re-entrant.
*/
+ template <class T>
class GuardReentry {
- bool& d_guard;
+ T& d_guard;
public:
- GuardReentry(bool& guard)
+ GuardReentry(T& guard)
: d_guard(guard) {
Assert(!d_guard);
d_guard = true;
@@ -71,7 +72,7 @@ public:
*/
static typename Visitor::return_type run(Visitor& visitor, TNode node) {
- GuardReentry guard(bool(s_inRun));
+ GuardReentry<CVC4_THREADLOCAL_TYPE(bool)> guard(s_inRun);
// Notify of a start
visitor.start(node);
diff --git a/src/util/record.h b/src/util/record.h
index 2c15d30e0..27b090e1d 100644
--- a/src/util/record.h
+++ b/src/util/record.h
@@ -29,7 +29,7 @@
namespace CVC4 {
-class Record;
+class CVC4_PUBLIC Record;
// operators for record select and update
diff --git a/src/util/statistics_registry.h b/src/util/statistics_registry.h
index 3bf990dbb..af9088663 100644
--- a/src/util/statistics_registry.h
+++ b/src/util/statistics_registry.h
@@ -23,6 +23,7 @@
#include "util/statistics.h"
#include "util/exception.h"
+#include "lib/clock_gettime.h"
#include <sstream>
#include <iomanip>
@@ -612,12 +613,17 @@ public:
};/* class StatisticsRegistry */
+}/* CVC4 namespace */
+
/****************************************************************************/
/* Some utility functions for timespec */
/****************************************************************************/
+inline std::ostream& operator<<(std::ostream& os, const timespec& t);
+
/** Compute the sum of two timespecs. */
inline timespec& operator+=(timespec& a, const timespec& b) {
+ using namespace CVC4;
// assumes a.tv_nsec and b.tv_nsec are in range
const long nsec_per_sec = 1000000000L; // one thousand million
CheckArgument(a.tv_nsec >= 0 && a.tv_nsec < nsec_per_sec, a);
@@ -640,6 +646,7 @@ inline timespec& operator+=(timespec& a, const timespec& b) {
/** Compute the difference of two timespecs. */
inline timespec& operator-=(timespec& a, const timespec& b) {
+ using namespace CVC4;
// assumes a.tv_nsec and b.tv_nsec are in range
const long nsec_per_sec = 1000000000L; // one thousand million
CheckArgument(a.tv_nsec >= 0 && a.tv_nsec < nsec_per_sec, a);
@@ -716,6 +723,8 @@ inline std::ostream& operator<<(std::ostream& os, const timespec& t) {
<< std::setfill('0') << std::setw(8) << std::right << t.tv_nsec;
}
+namespace CVC4 {
+
class CodeTimer;
/**
@@ -765,7 +774,6 @@ public:
};/* class TimerStat */
-
/**
* Utility class to make it easier to call stop() at the end of a
* code block. When constructed, it starts the timer. When
@@ -788,7 +796,6 @@ public:
}
};/* class CodeTimer */
-
/**
* To use a statistic, you need to declare it, initialize it in your
* constructor, register it in your constructor, and deregister it in
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback