See {@link #getUpperAsVector()} for triple semantics. + */ + public ArithExpr[] getLowerAsVector() + { + return opt.GetLowerAsVector(handle); + } + + /** + * Retrieve the value of an objective. + **/ + public ArithExpr getValue() + { + return getLower(); + } + + /** + * Print a string representation of the handle. + **/ + @Override + public String toString() { return getValue().toString(); } } - /** + /** * Assert soft constraint * * Return an objective which associates with the group of constraints. * - **/ - + **/ public Handle AssertSoft(BoolExpr constraint, int weight, String group) { getContext().checkContextMatch(constraint); Symbol s = getContext().mkSymbol(group); return new Handle(this, Native.optimizeAssertSoft(getContext().nCtx(), getNativeObject(), constraint.getNativeObject(), Integer.toString(weight), s.getNativeObject())); } - - /** + /** * Check satisfiability of asserted constraints. * Produce a model that (when the objectives are bounded and * don't use strict inequalities) meets the objectives. **/ - public Status Check() { Z3_lbool r = Z3_lbool.fromInt(Native.optimizeCheck(getContext().nCtx(), getNativeObject())); @@ -153,7 +173,7 @@ public class Optimize extends Z3Object return Status.UNKNOWN; } } - + /** * Creates a backtracking point. **/ @@ -162,13 +182,11 @@ public class Optimize extends Z3Object Native.optimizePush(getContext().nCtx(), getNativeObject()); } - - /** + /** * Backtrack one backtracking point. * * Note that an exception is thrown if Pop is called without a corresponding Push. **/ - public void Pop() { Native.optimizePop(getContext().nCtx(), getNativeObject()); @@ -191,7 +209,7 @@ public class Optimize extends Z3Object } } - /** + /** * Declare an arithmetical maximization objective. * Return a handle to the objective. The handle is used as * to retrieve the values of objectives after calling Check. @@ -200,11 +218,11 @@ public class Optimize extends Z3Object { return new Handle(this, Native.optimizeMaximize(getContext().nCtx(), getNativeObject(), e.getNativeObject())); } - + /** * Declare an arithmetical minimization objective. * Similar to MkMaximize. - **/ + **/ public Handle MkMinimize(ArithExpr e) { return new Handle(this, Native.optimizeMinimize(getContext().nCtx(), getNativeObject(), e.getNativeObject())); @@ -212,21 +230,56 @@ public class Optimize extends Z3Object /** * Retrieve a lower bound for the objective handle. - **/ + **/ private ArithExpr GetLower(int index) { return (ArithExpr)Expr.create(getContext(), Native.optimizeGetLower(getContext().nCtx(), getNativeObject(), index)); } - - + /** * Retrieve an upper bound for the objective handle. - **/ + **/ private ArithExpr GetUpper(int index) { return (ArithExpr)Expr.create(getContext(), Native.optimizeGetUpper(getContext().nCtx(), getNativeObject(), index)); } + /** + * @return Triple representing the upper bound for the objective handle. + * + *
See {@link Handle#getUpperAsVector}. + */ + private ArithExpr[] GetUpperAsVector(int index) { + return unpackObjectiveValueVector( + Native.optimizeGetUpperAsVector( + getContext().nCtx(), getNativeObject(), index + ) + ); + } + + /** + * @return Triple representing the upper bound for the objective handle. + * + *
See {@link Handle#getLowerAsVector}.
+ */
+ private ArithExpr[] GetLowerAsVector(int index) {
+ return unpackObjectiveValueVector(
+ Native.optimizeGetLowerAsVector(
+ getContext().nCtx(), getNativeObject(), index
+ )
+ );
+ }
+
+ private ArithExpr[] unpackObjectiveValueVector(long nativeVec) {
+ ASTVector vec = new ASTVector(
+ getContext(), nativeVec
+ );
+ return new ArithExpr[] {
+ (ArithExpr) vec.get(0), (ArithExpr) vec.get(1), (ArithExpr) vec.get(2)
+ };
+
+ }
+
/**
* Return a string the describes why the last to check returned unknown
**/
@@ -235,8 +288,7 @@ public class Optimize extends Z3Object
return Native.optimizeGetReasonUnknown(getContext().nCtx(),
getNativeObject());
}
-
-
+
/**
* Print the context to a String (SMT-LIB parseable benchmark).
**/
@@ -245,7 +297,7 @@ public class Optimize extends Z3Object
{
return Native.optimizeToString(getContext().nCtx(), getNativeObject());
}
-
+
/**
* Optimize statistics.
**/
diff --git a/src/api/python/z3/z3.py b/src/api/python/z3/z3.py
index 6729d99b5..a0aba95d6 100644
--- a/src/api/python/z3/z3.py
+++ b/src/api/python/z3/z3.py
@@ -6719,12 +6719,24 @@ class OptimizeObjective:
opt = self._opt
return _to_expr_ref(Z3_optimize_get_upper(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
+ def lower_values(self):
+ opt = self._opt
+ return AstVector(Z3_optimize_get_lower_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
+
+ def upper_values(self):
+ opt = self._opt
+ return AstVector(Z3_optimize_get_upper_as_vector(opt.ctx.ref(), opt.optimize, self._value), opt.ctx)
+
def value(self):
if self._is_max:
return self.upper()
else:
return self.lower()
+ def __str__(self):
+ return "%s:%s" % (self._value, self._is_max)
+
+
class Optimize(Z3PPObject):
"""Optimize API provides methods for solving using objective functions and weighted soft constraints"""
@@ -6829,6 +6841,16 @@ class Optimize(Z3PPObject):
raise Z3Exception("Expecting objective handle returned by maximize/minimize")
return obj.upper()
+ def lower_values(self, obj):
+ if not isinstance(obj, OptimizeObjective):
+ raise Z3Exception("Expecting objective handle returned by maximize/minimize")
+ return obj.lower_values()
+
+ def upper_values(self, obj):
+ if not isinstance(obj, OptimizeObjective):
+ raise Z3Exception("Expecting objective handle returned by maximize/minimize")
+ return obj.upper_values()
+
def from_file(self, filename):
"""Parse assertions and objectives from a file"""
Z3_optimize_from_file(self.ctx.ref(), self.optimize, filename)
diff --git a/src/api/z3_optimization.h b/src/api/z3_optimization.h
index f7a9a8fe9..795b4b8fd 100644
--- a/src/api/z3_optimization.h
+++ b/src/api/z3_optimization.h
@@ -186,6 +186,33 @@ extern "C" {
*/
Z3_ast Z3_API Z3_optimize_get_upper(Z3_context c, Z3_optimize o, unsigned idx);
+
+ /**
+ \brief Retrieve lower bound value or approximation for the i'th optimization objective.
+ The returned vector is of length 3. It always contains numerals.
+ The three numerals are coefficients a, b, c and encode the result of \c Z3_optimize_get_lower
+ a * infinity + b + c * epsilon.
+
+ \param c - context
+ \param o - optimization context
+ \param idx - index of optimization objective
+
+ def_API('Z3_optimize_get_lower_as_vector', AST_VECTOR, (_in(CONTEXT), _in(OPTIMIZE), _in(UINT)))
+ */
+ Z3_ast_vector Z3_API Z3_optimize_get_lower_as_vector(Z3_context c, Z3_optimize o, unsigned idx);
+
+ /**
+ \brief Retrieve upper bound value or approximation for the i'th optimization objective.
+
+ \param c - context
+ \param o - optimization context
+ \param idx - index of optimization objective
+
+ def_API('Z3_optimize_get_upper_as_vector', AST_VECTOR, (_in(CONTEXT), _in(OPTIMIZE), _in(UINT)))
+ */
+ Z3_ast_vector Z3_API Z3_optimize_get_upper_as_vector(Z3_context c, Z3_optimize o, unsigned idx);
+
+
/**
\brief Print the current context as a string.
\param c - context.
diff --git a/src/ast/rewriter/enum2bv_rewriter.cpp b/src/ast/rewriter/enum2bv_rewriter.cpp
index cd0f54503..08e7b0f69 100644
--- a/src/ast/rewriter/enum2bv_rewriter.cpp
+++ b/src/ast/rewriter/enum2bv_rewriter.cpp
@@ -85,7 +85,7 @@ struct enum2bv_rewriter::imp {
void throw_non_fd(expr* e) {
std::stringstream strm;
- strm << "unabled nested data-type expression " << mk_pp(e, m);
+ strm << "unable to handle nested data-type expression " << mk_pp(e, m);
throw rewriter_exception(strm.str().c_str());
}
diff --git a/src/ast/seq_decl_plugin.cpp b/src/ast/seq_decl_plugin.cpp
index 597ab5e4a..5022c57a6 100644
--- a/src/ast/seq_decl_plugin.cpp
+++ b/src/ast/seq_decl_plugin.cpp
@@ -473,6 +473,7 @@ void seq_decl_plugin::init() {
sort* str2TintT[3] = { strT, strT, intT };
sort* seqAintT[2] = { seqA, intT };
sort* seq3A[3] = { seqA, seqA, seqA };
+ sort* reTintT[2] = { reT, intT };
m_sigs.resize(LAST_SEQ_OP);
// TBD: have (par ..) construct and load parameterized signature from premable.
m_sigs[OP_SEQ_UNIT] = alloc(psig, m, "seq.unit", 1, 1, &A, seqA);
@@ -516,6 +517,7 @@ void seq_decl_plugin::init() {
m_sigs[_OP_REGEXP_EMPTY] = alloc(psig, m, "re.nostr", 0, 0, 0, reT);
m_sigs[_OP_REGEXP_FULL] = alloc(psig, m, "re.allchar", 0, 0, 0, reT);
m_sigs[_OP_STRING_SUBSTR] = alloc(psig, m, "str.substr", 0, 3, strTint2T, strT);
+ m_sigs[_OP_RE_UNROLL] = alloc(psig, m, "_re.unroll", 0, 2, reTintT, strT);
}
void seq_decl_plugin::set_manager(ast_manager* m, family_id id) {
@@ -672,6 +674,9 @@ func_decl * seq_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters,
m.raise_exception("Incorrect number of arguments passed to loop. Expected 1 regular expression and two integer parameters");
}
+ case _OP_RE_UNROLL:
+ match(*m_sigs[k], arity, domain, range, rng);
+ return m.mk_func_decl(m_sigs[k]->m_name, arity, domain, rng, func_decl_info(m_family_id, k));
case OP_STRING_CONST:
if (!(num_parameters == 1 && arity == 0 && parameters[0].is_symbol())) {
diff --git a/src/ast/seq_decl_plugin.h b/src/ast/seq_decl_plugin.h
index fbbcba5de..b07e4d307 100644
--- a/src/ast/seq_decl_plugin.h
+++ b/src/ast/seq_decl_plugin.h
@@ -79,6 +79,7 @@ enum seq_op_kind {
_OP_REGEXP_EMPTY,
_OP_REGEXP_FULL,
_OP_SEQ_SKOLEM,
+ _OP_RE_UNROLL,
LAST_SEQ_OP
};
@@ -334,6 +335,7 @@ public:
MATCH_UNARY(is_opt);
bool is_loop(expr const* n, expr*& body, unsigned& lo, unsigned& hi);
bool is_loop(expr const* n, expr*& body, unsigned& lo);
+ bool is_unroll(expr const* n) const { return is_app_of(n, m_fid, _OP_RE_UNROLL); }
};
str str;
re re;
diff --git a/src/cmd_context/tactic_cmds.cpp b/src/cmd_context/tactic_cmds.cpp
index 2f7b1ea6e..2b60486f7 100644
--- a/src/cmd_context/tactic_cmds.cpp
+++ b/src/cmd_context/tactic_cmds.cpp
@@ -223,7 +223,7 @@ public:
cmd_context::scoped_watch sw(ctx);
lbool r = l_undef;
try {
- r = check_sat(t, g, md, result->labels, pr, core, reason_unknown);
+ r = check_sat(t, g, md, result->labels, pr, core, reason_unknown);
ctx.display_sat_result(r);
result->set_status(r);
if (r == l_undef) {
diff --git a/src/opt/opt_context.cpp b/src/opt/opt_context.cpp
index 56b152caa..ebe56381a 100644
--- a/src/opt/opt_context.cpp
+++ b/src/opt/opt_context.cpp
@@ -1290,6 +1290,15 @@ namespace opt {
return to_expr(get_upper_as_num(idx));
}
+ void context::to_exprs(inf_eps const& n, expr_ref_vector& es) {
+ rational inf = n.get_infinity();
+ rational r = n.get_rational();
+ rational eps = n.get_infinitesimal();
+ es.push_back(m_arith.mk_numeral(inf, inf.is_int()));
+ es.push_back(m_arith.mk_numeral(r, r.is_int()));
+ es.push_back(m_arith.mk_numeral(eps, eps.is_int()));
+ }
+
expr_ref context::to_expr(inf_eps const& n) {
rational inf = n.get_infinity();
rational r = n.get_rational();
@@ -1455,9 +1464,10 @@ namespace opt {
void context::validate_maxsat(symbol const& id) {
maxsmt& ms = *m_maxsmts.find(id);
+ TRACE("opt", tout << "Validate: " << id << "\n";);
for (unsigned i = 0; i < m_objectives.size(); ++i) {
objective const& obj = m_objectives[i];
- if (obj.m_id == id) {
+ if (obj.m_id == id && obj.m_type == O_MAXSMT) {
SASSERT(obj.m_type == O_MAXSMT);
rational value(0);
expr_ref val(m);
diff --git a/src/opt/opt_context.h b/src/opt/opt_context.h
index 461506258..f51f75830 100644
--- a/src/opt/opt_context.h
+++ b/src/opt/opt_context.h
@@ -207,6 +207,9 @@ namespace opt {
expr_ref get_lower(unsigned idx);
expr_ref get_upper(unsigned idx);
+ void get_lower(unsigned idx, expr_ref_vector& es) { to_exprs(get_lower_as_num(idx), es); }
+ void get_upper(unsigned idx, expr_ref_vector& es) { to_exprs(get_upper_as_num(idx), es); }
+
std::string to_string() const;
@@ -238,6 +241,7 @@ namespace opt {
lbool adjust_unknown(lbool r);
bool scoped_lex();
expr_ref to_expr(inf_eps const& n);
+ void to_exprs(inf_eps const& n, expr_ref_vector& es);
void reset_maxsmts();
void import_scoped_state();
diff --git a/src/smt/tactic/smt_tactic.cpp b/src/smt/tactic/smt_tactic.cpp
index bd2c72c3e..eef22fe06 100644
--- a/src/smt/tactic/smt_tactic.cpp
+++ b/src/smt/tactic/smt_tactic.cpp
@@ -25,6 +25,9 @@ Notes:
#include"filter_model_converter.h"
#include"ast_util.h"
#include"solver2tactic.h"
+#include"smt_solver.h"
+#include"solver.h"
+#include"mus.h"
typedef obj_map