mirror of
https://github.com/Z3Prover/z3
synced 2025-04-22 16:45:31 +00:00
na
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
dcdbbfb925
144 changed files with 1528 additions and 517 deletions
|
@ -31,6 +31,8 @@ public:
|
|||
|
||||
~ackermannize_bv_tactic() override { }
|
||||
|
||||
char const* name() const override { return "ackermannize_bv"; }
|
||||
|
||||
void operator()(goal_ref const & g, goal_ref_buffer & result) override {
|
||||
tactic_report report("ackermannize_bv", *g);
|
||||
fail_if_unsat_core_generation("ackermannize", g);
|
||||
|
|
|
@ -1232,6 +1232,7 @@ extern "C" {
|
|||
|
||||
if (mk_c(c)->get_char_fid() == _d->get_family_id()) {
|
||||
switch (_d->get_decl_kind()) {
|
||||
case OP_CHAR_CONST: return Z3_OP_CHAR_CONST;
|
||||
case OP_CHAR_LE: return Z3_OP_CHAR_LE;
|
||||
case OP_CHAR_TO_INT: return Z3_OP_CHAR_TO_INT;
|
||||
case OP_CHAR_TO_BV: return Z3_OP_CHAR_TO_BV;
|
||||
|
|
|
@ -87,8 +87,6 @@ namespace api {
|
|||
m_error_code = Z3_OK;
|
||||
m_print_mode = Z3_PRINT_SMTLIB_FULL;
|
||||
|
||||
|
||||
m_interruptable = nullptr;
|
||||
m_error_handler = &default_error_handler;
|
||||
|
||||
m_bv_fid = m().mk_family_id("bv");
|
||||
|
@ -98,7 +96,7 @@ namespace api {
|
|||
m_datalog_fid = m().mk_family_id("datalog_relation");
|
||||
m_fpa_fid = m().mk_family_id("fpa");
|
||||
m_seq_fid = m().mk_family_id("seq");
|
||||
m_char_fid = m().mk_family_id("char");
|
||||
m_char_fid = m().mk_family_id("char");
|
||||
m_special_relations_fid = m().mk_family_id("specrels");
|
||||
m_dt_plugin = static_cast<datatype_decl_plugin*>(m().get_plugin(m_dt_fid));
|
||||
|
||||
|
@ -120,19 +118,18 @@ namespace api {
|
|||
context::set_interruptable::set_interruptable(context & ctx, event_handler & i):
|
||||
m_ctx(ctx) {
|
||||
lock_guard lock(ctx.m_mux);
|
||||
SASSERT(m_ctx.m_interruptable == 0);
|
||||
m_ctx.m_interruptable = &i;
|
||||
m_ctx.m_interruptable.push_back(& i);
|
||||
}
|
||||
|
||||
context::set_interruptable::~set_interruptable() {
|
||||
lock_guard lock(m_ctx.m_mux);
|
||||
m_ctx.m_interruptable = nullptr;
|
||||
m_ctx.m_interruptable.pop_back();
|
||||
}
|
||||
|
||||
void context::interrupt() {
|
||||
lock_guard lock(m_mux);
|
||||
if (m_interruptable)
|
||||
(*m_interruptable)(API_INTERRUPT_EH_CALLER);
|
||||
for (auto * eh : m_interruptable)
|
||||
(*eh)(API_INTERRUPT_EH_CALLER);
|
||||
m_limit.cancel();
|
||||
m().limit().cancel();
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ namespace api {
|
|||
std::string m_exception_msg; // catch the message associated with a Z3 exception
|
||||
Z3_ast_print_mode m_print_mode;
|
||||
|
||||
event_handler * m_interruptable; // Reference to an object that can be interrupted by Z3_interrupt
|
||||
ptr_vector<event_handler> m_interruptable; // Reference to an object that can be interrupted by Z3_interrupt
|
||||
|
||||
public:
|
||||
// Scoped obj for setting m_interruptable
|
||||
|
|
|
@ -157,6 +157,9 @@ extern "C" {
|
|||
LOG_Z3_eval_smtlib2_string(c, str);
|
||||
if (!mk_c(c)->cmd()) {
|
||||
mk_c(c)->cmd() = alloc(cmd_context, false, &(mk_c(c)->m()));
|
||||
install_dl_cmds(*mk_c(c)->cmd());
|
||||
install_opt_cmds(*mk_c(c)->cmd());
|
||||
install_smt2_extra_cmds(*mk_c(c)->cmd());
|
||||
mk_c(c)->cmd()->set_solver_factory(mk_smt_strategic_solver_factory());
|
||||
}
|
||||
scoped_ptr<cmd_context>& ctx = mk_c(c)->cmd();
|
||||
|
|
|
@ -17,6 +17,7 @@ Revision History:
|
|||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include<thread>
|
||||
#include "util/scoped_ctrl_c.h"
|
||||
#include "util/cancel_eh.h"
|
||||
#include "util/file_path.h"
|
||||
|
@ -158,10 +159,19 @@ extern "C" {
|
|||
init_solver_core(c, s);
|
||||
}
|
||||
|
||||
|
||||
static void init_solver_log(Z3_context c, Z3_solver s) {
|
||||
static std::thread::id g_thread_id = std::this_thread::get_id();
|
||||
static bool g_is_threaded = false;
|
||||
solver_params sp(to_solver(s)->m_params);
|
||||
symbol smt2log = sp.smtlib2_log();
|
||||
if (smt2log.is_non_empty_string() && !to_solver(s)->m_pp) {
|
||||
if (g_is_threaded || g_thread_id != std::this_thread::get_id()) {
|
||||
g_is_threaded = true;
|
||||
std::ostringstream strm;
|
||||
strm << smt2log << "-" << std::this_thread::get_id();
|
||||
smt2log = symbol(strm.str());
|
||||
}
|
||||
to_solver(s)->m_pp = alloc(solver2smt2_pp, mk_c(c)->m(), smt2log.str());
|
||||
}
|
||||
}
|
||||
|
@ -856,7 +866,7 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
class api_context_obj : public solver::context_obj {
|
||||
class api_context_obj : public user_propagator::context_obj {
|
||||
api::context* c;
|
||||
public:
|
||||
api_context_obj(api::context* c):c(c) {}
|
||||
|
@ -873,9 +883,9 @@ extern "C" {
|
|||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
init_solver(c, s);
|
||||
solver::push_eh_t _push = push_eh;
|
||||
solver::pop_eh_t _pop = pop_eh;
|
||||
solver::fresh_eh_t _fresh = [=](void * user_ctx, ast_manager& m, solver::context_obj*& _ctx) {
|
||||
user_propagator::push_eh_t _push = push_eh;
|
||||
user_propagator::pop_eh_t _pop = pop_eh;
|
||||
user_propagator::fresh_eh_t _fresh = [=](void * user_ctx, ast_manager& m, user_propagator::context_obj*& _ctx) {
|
||||
ast_context_params params;
|
||||
params.set_foreign_manager(&m);
|
||||
auto* ctx = alloc(api::context, ¶ms, false);
|
||||
|
@ -892,7 +902,7 @@ extern "C" {
|
|||
Z3_fixed_eh fixed_eh) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
solver::fixed_eh_t _fixed = (void(*)(void*,solver::propagate_callback*,unsigned,expr*))fixed_eh;
|
||||
user_propagator::fixed_eh_t _fixed = (void(*)(void*,user_propagator::callback*,unsigned,expr*))fixed_eh;
|
||||
to_solver_ref(s)->user_propagate_register_fixed(_fixed);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
@ -903,7 +913,7 @@ extern "C" {
|
|||
Z3_final_eh final_eh) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
solver::final_eh_t _final = (bool(*)(void*,solver::propagate_callback*))final_eh;
|
||||
user_propagator::final_eh_t _final = (bool(*)(void*,user_propagator::callback*))final_eh;
|
||||
to_solver_ref(s)->user_propagate_register_final(_final);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
@ -914,7 +924,7 @@ extern "C" {
|
|||
Z3_eq_eh eq_eh) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
solver::eq_eh_t _eq = (void(*)(void*,solver::propagate_callback*,unsigned,unsigned))eq_eh;
|
||||
user_propagator::eq_eh_t _eq = (void(*)(void*,user_propagator::callback*,unsigned,unsigned))eq_eh;
|
||||
to_solver_ref(s)->user_propagate_register_eq(_eq);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
@ -925,7 +935,7 @@ extern "C" {
|
|||
Z3_eq_eh diseq_eh) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
solver::eq_eh_t _diseq = (void(*)(void*,solver::propagate_callback*,unsigned,unsigned))diseq_eh;
|
||||
user_propagator::eq_eh_t _diseq = (void(*)(void*,user_propagator::callback*,unsigned,unsigned))diseq_eh;
|
||||
to_solver_ref(s)->user_propagate_register_diseq(_diseq);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
@ -938,11 +948,19 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_solver_propagate_register_cb(Z3_context c, Z3_solver_callback s, Z3_ast e) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_propagate_register_cb(c, s, e);
|
||||
RESET_ERROR_CODE();
|
||||
return reinterpret_cast<user_propagator::callback*>(s)->register_cb(to_expr(e));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_solver_propagate_consequence(Z3_context c, Z3_solver_callback s, unsigned num_fixed, unsigned const* fixed_ids, unsigned num_eqs, unsigned const* eq_lhs, unsigned const* eq_rhs, Z3_ast conseq) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_propagate_consequence(c, s, num_fixed, fixed_ids, num_eqs, eq_lhs, eq_rhs, conseq);
|
||||
RESET_ERROR_CODE();
|
||||
reinterpret_cast<solver::propagate_callback*>(s)->propagate_cb(num_fixed, fixed_ids, num_eqs, eq_lhs, eq_rhs, to_expr(conseq));
|
||||
reinterpret_cast<user_propagator::callback*>(s)->propagate_cb(num_fixed, fixed_ids, num_eqs, eq_lhs, eq_rhs, to_expr(conseq));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
|
|
|
@ -1911,7 +1911,7 @@ namespace z3 {
|
|||
}
|
||||
inline expr bvredand(expr const & a) {
|
||||
assert(a.is_bv());
|
||||
Z3_ast r = Z3_mk_bvredor(a.ctx(), a);
|
||||
Z3_ast r = Z3_mk_bvredand(a.ctx(), a);
|
||||
a.check_error();
|
||||
return expr(a.ctx(), r);
|
||||
}
|
||||
|
@ -4030,8 +4030,12 @@ namespace z3 {
|
|||
*/
|
||||
|
||||
unsigned add(expr const& e) {
|
||||
assert(s);
|
||||
return Z3_solver_propagate_register(ctx(), *s, e);
|
||||
if (cb)
|
||||
return Z3_solver_propagate_register_cb(ctx(), cb, e);
|
||||
if (s)
|
||||
return Z3_solver_propagate_register(ctx(), *s, e);
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void conflict(unsigned num_fixed, unsigned const* fixed) {
|
||||
|
|
|
@ -1717,9 +1717,8 @@ public class Context implements AutoCloseable {
|
|||
* {@code [domain -> range]}, and {@code i} must have the sort
|
||||
* {@code domain}. The sort of the result is {@code range}.
|
||||
*
|
||||
* @see #mkArraySort
|
||||
* @see #mkArraySort(Sort[], Sort)
|
||||
* @see #mkStore
|
||||
|
||||
**/
|
||||
public <D extends Sort, R extends Sort> Expr<R> mkSelect(Expr<ArraySort<D, R>> a, Expr<D> i)
|
||||
{
|
||||
|
@ -1740,7 +1739,7 @@ public class Context implements AutoCloseable {
|
|||
* {@code [domains -> range]}, and {@code args} must have the sorts
|
||||
* {@code domains}. The sort of the result is {@code range}.
|
||||
*
|
||||
* @see #mkArraySort
|
||||
* @see #mkArraySort(Sort[], Sort)
|
||||
* @see #mkStore
|
||||
**/
|
||||
public <R extends Sort> Expr<R> mkSelect(Expr<ArraySort<Sort, R>> a, Expr<?>[] args)
|
||||
|
@ -1764,7 +1763,7 @@ public class Context implements AutoCloseable {
|
|||
* {@code select}) on all indices except for {@code i}, where it
|
||||
* maps to {@code v} (and the {@code select} of {@code a}
|
||||
* with respect to {@code i} may be a different value).
|
||||
* @see #mkArraySort
|
||||
* @see #mkArraySort(Sort[], Sort)
|
||||
* @see #mkSelect
|
||||
|
||||
**/
|
||||
|
@ -1789,7 +1788,7 @@ public class Context implements AutoCloseable {
|
|||
* {@code select}) on all indices except for {@code args}, where it
|
||||
* maps to {@code v} (and the {@code select} of {@code a}
|
||||
* with respect to {@code args} may be a different value).
|
||||
* @see #mkArraySort
|
||||
* @see #mkArraySort(Sort[], Sort)
|
||||
* @see #mkSelect
|
||||
|
||||
**/
|
||||
|
@ -1807,7 +1806,7 @@ public class Context implements AutoCloseable {
|
|||
* Remarks: The resulting term is an array, such
|
||||
* that a {@code select} on an arbitrary index produces the value
|
||||
* {@code v}.
|
||||
* @see #mkArraySort
|
||||
* @see #mkArraySort(Sort[], Sort)
|
||||
* @see #mkSelect
|
||||
*
|
||||
**/
|
||||
|
@ -1827,7 +1826,7 @@ public class Context implements AutoCloseable {
|
|||
* {@code f} must have type {@code range_1 .. range_n -> range}.
|
||||
* {@code v} must have sort range. The sort of the result is
|
||||
* {@code [domain_i -> range]}.
|
||||
* @see #mkArraySort
|
||||
* @see #mkArraySort(Sort[], Sort)
|
||||
* @see #mkSelect
|
||||
* @see #mkStore
|
||||
|
||||
|
|
|
@ -770,6 +770,8 @@ class Formatter:
|
|||
return self.pp_set("Empty", a)
|
||||
elif k == Z3_OP_RE_FULL_SET:
|
||||
return self.pp_set("Full", a)
|
||||
elif k == Z3_OP_CHAR_CONST:
|
||||
return self.pp_char(a)
|
||||
return self.pp_name(a)
|
||||
|
||||
def pp_int(self, a):
|
||||
|
@ -1060,6 +1062,10 @@ class Formatter:
|
|||
def pp_set(self, id, a):
|
||||
return seq1(id, [self.pp_sort(a.sort())])
|
||||
|
||||
def pp_char(self, a):
|
||||
n = a.params()[0]
|
||||
return to_format(str(n))
|
||||
|
||||
def pp_pattern(self, a, d, xs):
|
||||
if a.num_args() == 1:
|
||||
return self.pp_expr(a.arg(0), d, xs)
|
||||
|
|
|
@ -1222,6 +1222,7 @@ typedef enum {
|
|||
Z3_OP_RE_COMPLEMENT,
|
||||
|
||||
// char
|
||||
Z3_OP_CHAR_CONST,
|
||||
Z3_OP_CHAR_LE,
|
||||
Z3_OP_CHAR_TO_INT,
|
||||
Z3_OP_CHAR_TO_BV,
|
||||
|
@ -3450,6 +3451,10 @@ extern "C" {
|
|||
/**
|
||||
\brief Create a sort for unicode strings.
|
||||
|
||||
The sort for characters can be changed to ASCII by setting
|
||||
the global parameter \c encoding to \c ascii, or alternative
|
||||
to 16 bit characters by setting \c encoding to \c bmp.
|
||||
|
||||
def_API('Z3_mk_string_sort', SORT, (_in(CONTEXT), ))
|
||||
*/
|
||||
Z3_sort Z3_API Z3_mk_string_sort(Z3_context c);
|
||||
|
@ -3458,7 +3463,8 @@ extern "C" {
|
|||
\brief Create a sort for unicode characters.
|
||||
|
||||
The sort for characters can be changed to ASCII by setting
|
||||
the global parameter \c unicode to \c false.
|
||||
the global parameter \c encoding to \c ascii, or alternative
|
||||
to 16 bit characters by setting \c encoding to \c bmp.
|
||||
|
||||
def_API('Z3_mk_char_sort', SORT, (_in(CONTEXT), ))
|
||||
*/
|
||||
|
@ -3482,8 +3488,8 @@ extern "C" {
|
|||
\brief Create a string constant out of the string that is passed in
|
||||
The string may contain escape encoding for non-printable characters
|
||||
or characters outside of the basic printable ASCII range. For example,
|
||||
the escape encoding \u{0} represents the character 0 and the encoding
|
||||
\u{100} represents the character 256.
|
||||
the escape encoding \\u{0} represents the character 0 and the encoding
|
||||
\\u{100} represents the character 256.
|
||||
|
||||
def_API('Z3_mk_string', AST, (_in(CONTEXT), _in(STRING)))
|
||||
*/
|
||||
|
@ -3493,7 +3499,7 @@ extern "C" {
|
|||
\brief Create a string constant out of the string that is passed in
|
||||
It takes the length of the string as well to take into account
|
||||
0 characters. The string is treated as if it is unescaped so a sequence
|
||||
of characters \u{0} is treated as 5 characters and not the character 0.
|
||||
of characters \\u{0} is treated as 5 characters and not the character 0.
|
||||
|
||||
def_API('Z3_mk_lstring', AST, (_in(CONTEXT), _in(UINT), _in(STRING)))
|
||||
*/
|
||||
|
@ -6679,6 +6685,16 @@ extern "C" {
|
|||
|
||||
unsigned Z3_API Z3_solver_propagate_register(Z3_context c, Z3_solver s, Z3_ast e);
|
||||
|
||||
/**
|
||||
\brief register an expression to propagate on with the solver.
|
||||
Only expressions of type Bool and type Bit-Vector can be registered for propagation.
|
||||
Unlike \ref Z3_solver_propagate_register, this function takes a solver callback context
|
||||
as argument. It can be invoked during a callback to register new expressions.
|
||||
|
||||
def_API('Z3_solver_propagate_register_cb', UINT, (_in(CONTEXT), _in(SOLVER_CALLBACK), _in(AST)))
|
||||
*/
|
||||
unsigned Z3_API Z3_solver_propagate_register_cb(Z3_context c, Z3_solver_callback cb, Z3_ast e);
|
||||
|
||||
/**
|
||||
\brief propagate a consequence based on fixed values.
|
||||
This is a callback a client may invoke during the fixed_eh callback.
|
||||
|
|
|
@ -1050,6 +1050,12 @@ public:
|
|||
*/
|
||||
virtual bool is_value(app * a) const { return false; }
|
||||
|
||||
|
||||
/**
|
||||
\brief return true if the expression can be used as a model value.
|
||||
*/
|
||||
virtual bool is_model_value(app* a) const { return is_value(a); }
|
||||
|
||||
/**
|
||||
\brief Return true if \c a is a unique plugin value.
|
||||
The following property should hold for unique theory values:
|
||||
|
|
|
@ -717,6 +717,8 @@ namespace datatype {
|
|||
todo.pop_back();
|
||||
continue;
|
||||
}
|
||||
if (!is_declared(s))
|
||||
return true;
|
||||
already_found.insert(datatype_name(s), GRAY);
|
||||
def const& d = get_def(s);
|
||||
bool can_process = true;
|
||||
|
|
|
@ -65,7 +65,7 @@ bool has_skolem_functions(expr * n) {
|
|||
}
|
||||
|
||||
subterms::subterms(expr_ref_vector const& es, bool include_bound): m_include_bound(include_bound), m_es(es) {}
|
||||
subterms::subterms(expr_ref const& e, bool include_bound) : m_include_bound(include_bound), m_es(e.m()) { m_es.push_back(e); }
|
||||
subterms::subterms(expr_ref const& e, bool include_bound) : m_include_bound(include_bound), m_es(e.m()) {if (e) m_es.push_back(e); }
|
||||
subterms::iterator subterms::begin() { return iterator(*this, true); }
|
||||
subterms::iterator subterms::end() { return iterator(*this, false); }
|
||||
subterms::iterator::iterator(subterms& f, bool start): m_include_bound(f.m_include_bound), m_es(f.m_es) {
|
||||
|
@ -112,7 +112,7 @@ bool subterms::iterator::operator!=(iterator const& other) const {
|
|||
|
||||
|
||||
subterms_postorder::subterms_postorder(expr_ref_vector const& es): m_es(es) {}
|
||||
subterms_postorder::subterms_postorder(expr_ref const& e) : m_es(e.m()) { m_es.push_back(e); }
|
||||
subterms_postorder::subterms_postorder(expr_ref const& e) : m_es(e.m()) { if (e) m_es.push_back(e); }
|
||||
subterms_postorder::iterator subterms_postorder::begin() { return iterator(*this, true); }
|
||||
subterms_postorder::iterator subterms_postorder::end() { return iterator(*this, false); }
|
||||
subterms_postorder::iterator::iterator(subterms_postorder& f, bool start): m_es(f.m_es) {
|
||||
|
|
|
@ -855,6 +855,16 @@ br_status bv_rewriter::mk_bv_shl(expr * arg1, expr * arg2, expr_ref & result) {
|
|||
return BR_REWRITE2;
|
||||
}
|
||||
|
||||
expr* x = nullptr, *y = nullptr;
|
||||
if (m_util.is_bv_shl(arg1, x, y)) {
|
||||
expr_ref sum(m_util.mk_bv_add(y, arg2), m());
|
||||
expr_ref cond(m_util.mk_ule(y, sum), m());
|
||||
result = m().mk_ite(cond,
|
||||
m_util.mk_bv_shl(x, sum),
|
||||
mk_numeral(0, bv_size));
|
||||
return BR_REWRITE3;
|
||||
}
|
||||
|
||||
return BR_FAILED;
|
||||
}
|
||||
|
||||
|
@ -1436,18 +1446,34 @@ br_status bv_rewriter::mk_bv2int(expr * arg, expr_ref & result) {
|
|||
|
||||
|
||||
bool bv_rewriter::is_mul_no_overflow(expr* e) {
|
||||
if (!m_util.is_bv_mul(e)) return false;
|
||||
if (!m_util.is_bv_mul(e))
|
||||
return false;
|
||||
unsigned sz = get_bv_size(e);
|
||||
unsigned sum = 0;
|
||||
for (expr* x : *to_app(e)) sum += sz-num_leading_zero_bits(x);
|
||||
return sum < sz;
|
||||
for (expr* x : *to_app(e))
|
||||
sum += sz - num_leading_zero_bits(x);
|
||||
if (sum > sz + 1)
|
||||
return false;
|
||||
if (sum <= sz)
|
||||
return true;
|
||||
rational v;
|
||||
unsigned shift;
|
||||
for (expr* x : *to_app(e))
|
||||
if (m_util.is_numeral(x, v) && v.is_power_of_two(shift))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bv_rewriter::is_add_no_overflow(expr* e) {
|
||||
if (!is_add(e)) return false;
|
||||
for (expr* x : *to_app(e)) {
|
||||
if (0 == num_leading_zero_bits(x)) return false;
|
||||
}
|
||||
if (!is_add(e))
|
||||
return false;
|
||||
unsigned num_args = to_app(e)->get_num_args();
|
||||
if (num_args <= 1)
|
||||
return true;
|
||||
num_args -= 2;
|
||||
for (expr* x : *to_app(e))
|
||||
if (num_args >= num_leading_zero_bits(x))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -205,10 +205,12 @@ namespace seq {
|
|||
drop_last_axiom(e, s);
|
||||
return;
|
||||
}
|
||||
#if 1
|
||||
if (is_extract_prefix(s, _i, _l)) {
|
||||
extract_prefix_axiom(e, s, l);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (is_extract_suffix(s, _i, _l)) {
|
||||
extract_suffix_axiom(e, s, i);
|
||||
return;
|
||||
|
@ -325,8 +327,7 @@ namespace seq {
|
|||
0 <= l <= len(s) => len(e) = l
|
||||
len(s) < l => e = s
|
||||
*/
|
||||
void axioms::extract_prefix_axiom(expr* e, expr* s, expr* l) {
|
||||
|
||||
void axioms::extract_prefix_axiom(expr* e, expr* s, expr* l) {
|
||||
TRACE("seq", tout << "prefix " << mk_bounded_pp(e, m, 2) << " " << mk_bounded_pp(s, m, 2) << " " << mk_bounded_pp(l, m, 2) << "\n";);
|
||||
expr_ref le = mk_len(e);
|
||||
expr_ref ls = mk_len(s);
|
||||
|
@ -1029,6 +1030,29 @@ namespace seq {
|
|||
add_clause(le, emp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assume that r has the property that if r accepts string p
|
||||
* then r does *not* accept any suffix of p. It is conceptually easy to
|
||||
* convert a deterministic automaton for a regex to a suffix blocking acceptor
|
||||
* by removing outgoing edges from accepting states and redirecting them
|
||||
* to a sink. Alternative, introduce a different string membership predicate that is
|
||||
* prefix sensitive.
|
||||
*
|
||||
* Let e = replace_re(s, r, t)
|
||||
* Then a claim is that the following axioms suffice to encode str.replace_re
|
||||
*
|
||||
* s = "" => e = t
|
||||
* r = "" => e = s + t
|
||||
* s not in .*r.* => e = t
|
||||
* s = x + y + [z] + u & y + [z] in r & x + y not in .*r.* => e = x + t + u
|
||||
*/
|
||||
void axioms::replace_re_axiom(expr* e) {
|
||||
expr* s = nullptr, *r = nullptr, *t = nullptr;
|
||||
VERIFY(seq.str.is_replace_re(e, s, r, t));
|
||||
NOT_IMPLEMENTED_YET();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Unit is injective:
|
||||
|
@ -1170,4 +1194,5 @@ namespace seq {
|
|||
return bound_tracker;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ namespace seq {
|
|||
void unit_axiom(expr* n);
|
||||
void length_axiom(expr* n);
|
||||
void unroll_not_contains(expr* e);
|
||||
void replace_re_axiom(expr* e);
|
||||
|
||||
expr_ref length_limit(expr* s, unsigned k);
|
||||
expr_ref is_digit(expr* ch);
|
||||
|
|
|
@ -33,6 +33,7 @@ skolem::skolem(ast_manager& m, th_rewriter& rw):
|
|||
m_aut_step = "aut.step";
|
||||
m_pre = "seq.pre"; // (seq.pre s l): prefix of string s of length l
|
||||
m_post = "seq.post"; // (seq.post s l): suffix of string s of length k, based on extract starting at index i of length l
|
||||
m_postp = "seq.postp";
|
||||
m_eq = "seq.eq";
|
||||
m_max_unfolding = "seq.max_unfolding";
|
||||
m_length_limit = "seq.length_limit";
|
||||
|
|
|
@ -37,7 +37,8 @@ namespace seq {
|
|||
symbol m_aut_step; // regex unfolding state
|
||||
symbol m_accept; // regex
|
||||
symbol m_is_empty, m_is_non_empty; // regex emptiness check
|
||||
symbol m_pre, m_post; // inverse of at: (pre s i) + (at s i) + (post s i) = s if 0 <= i < (len s)
|
||||
symbol m_pre, m_post; // inverse of at: (pre s i) + (at s i) + (post s i) = s if 0 <= i < (len s)
|
||||
symbol m_postp;
|
||||
symbol m_eq; // equality atom
|
||||
symbol m_max_unfolding, m_length_limit;
|
||||
|
||||
|
@ -84,6 +85,7 @@ namespace seq {
|
|||
|
||||
expr_ref mk_tail(expr* s, expr* i) { return mk(m_tail, s, i); }
|
||||
expr_ref mk_post(expr* s, expr* i) { return mk(m_post, s, i); }
|
||||
expr_ref mk_postp(expr* s, expr* i) { return mk(m_postp, s, i); }
|
||||
expr_ref mk_ite(expr* c, expr* t, expr* e) { return mk(symbol("seq.if"), c, t, e, nullptr, t->get_sort()); }
|
||||
expr_ref mk_last(expr* s);
|
||||
expr_ref mk_first(expr* s);
|
||||
|
|
|
@ -705,6 +705,17 @@ bool seq_decl_plugin::is_value(app* e) const {
|
|||
}
|
||||
}
|
||||
|
||||
bool seq_decl_plugin::is_model_value(app* e) const {
|
||||
if (is_app_of(e, m_family_id, OP_SEQ_EMPTY))
|
||||
return true;
|
||||
if (is_app_of(e, m_family_id, OP_STRING_CONST))
|
||||
return true;
|
||||
if (is_app_of(e, m_family_id, OP_SEQ_UNIT) &&
|
||||
m_manager->is_value(e->get_arg(0)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool seq_decl_plugin::are_equal(app* a, app* b) const {
|
||||
if (a == b) return true;
|
||||
// handle concatenations
|
||||
|
|
|
@ -179,6 +179,8 @@ public:
|
|||
|
||||
bool is_value(app * e) const override;
|
||||
|
||||
bool is_model_value(app* e) const override;
|
||||
|
||||
bool is_unique_value(app * e) const override;
|
||||
|
||||
bool are_equal(app* a, app* b) const override;
|
||||
|
|
|
@ -406,12 +406,25 @@ void static_features::process(expr * e, bool form_ctx, bool or_and_ctx, bool ite
|
|||
}
|
||||
|
||||
if (stack_depth > m_max_stack_depth) {
|
||||
for (expr* arg : subterms::ground(expr_ref(e, m)))
|
||||
if (get_depth(arg) <= 3 || is_quantifier(arg))
|
||||
process(arg, form_ctx, or_and_ctx, ite_ctx, stack_depth - 10);
|
||||
ptr_vector<expr> todo;
|
||||
todo.push_back(e);
|
||||
for (unsigned i = 0; i < todo.size(); ++i) {
|
||||
e = todo[i];
|
||||
if (is_marked(e))
|
||||
continue;
|
||||
if (is_basic_expr(e)) {
|
||||
mark(e);
|
||||
todo.append(to_app(e)->get_num_args(), to_app(e)->get_args());
|
||||
}
|
||||
else {
|
||||
process(e, form_ctx, or_and_ctx, ite_ctx, stack_depth - 10);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mark(e);
|
||||
|
||||
update_core(e);
|
||||
|
||||
if (is_quantifier(e)) {
|
||||
|
|
|
@ -324,6 +324,7 @@ static void set_upper(impq & u, bool & inf_u, impq const & v) {
|
|||
}
|
||||
}
|
||||
|
||||
// this function assumes that all basic columns dependend on j are feasible
|
||||
bool int_solver::get_freedom_interval_for_column(unsigned j, bool & inf_l, impq & l, bool & inf_u, impq & u, mpq & m) {
|
||||
if (lrac.m_r_heading[j] >= 0) // the basic var
|
||||
return false;
|
||||
|
@ -336,62 +337,52 @@ bool int_solver::get_freedom_interval_for_column(unsigned j, bool & inf_l, impq
|
|||
l = u = zero_of_type<impq>();
|
||||
m = mpq(1);
|
||||
|
||||
if (has_lower(j)) {
|
||||
if (has_lower(j))
|
||||
set_lower(l, inf_l, lower_bound(j) - xj);
|
||||
}
|
||||
if (has_upper(j)) {
|
||||
|
||||
if (has_upper(j))
|
||||
set_upper(u, inf_u, upper_bound(j) - xj);
|
||||
}
|
||||
|
||||
|
||||
unsigned row_index;
|
||||
lp_assert(settings().use_tableau());
|
||||
const auto & A = lra.A_r();
|
||||
unsigned rounds = 0;
|
||||
for (auto c : A.column(j)) {
|
||||
row_index = c.var();
|
||||
const mpq & a = c.coeff();
|
||||
unsigned i = lrac.m_r_basis[row_index];
|
||||
TRACE("random_update", tout << "i = " << i << ", a = " << a << "\n";);
|
||||
if (column_is_int(i) && !a.is_int())
|
||||
m = lcm(m, denominator(a));
|
||||
}
|
||||
TRACE("random_update", tout << "m = " << m << "\n";);
|
||||
|
||||
auto delta = [](mpq const& x, impq const& y, impq const& z) {
|
||||
if (x.is_one())
|
||||
return y - z;
|
||||
if (x.is_minus_one())
|
||||
return z - y;
|
||||
return (y - z) / x;
|
||||
};
|
||||
|
||||
for (auto c : A.column(j)) {
|
||||
if (!inf_l && !inf_u && l >= u) break;
|
||||
row_index = c.var();
|
||||
unsigned row_index = c.var();
|
||||
const mpq & a = c.coeff();
|
||||
unsigned i = lrac.m_r_basis[row_index];
|
||||
impq const & xi = get_value(i);
|
||||
lp_assert(lrac.m_r_solver.column_is_feasible(i));
|
||||
if (column_is_int(i) && !a.is_int())
|
||||
m = lcm(m, denominator(a));
|
||||
|
||||
#define SET_BOUND(_fn_, a, b, x, y, z) \
|
||||
if (x.is_one()) \
|
||||
_fn_(a, b, y - z); \
|
||||
else if (x.is_minus_one()) \
|
||||
_fn_(a, b, z - y); \
|
||||
else if (z == y) \
|
||||
_fn_(a, b, zero_of_type<impq>()); \
|
||||
else \
|
||||
{ _fn_(a, b, (y - z)/x); } \
|
||||
|
||||
if (!inf_l && !inf_u) {
|
||||
if (l == u)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (a.is_neg()) {
|
||||
if (has_lower(i)) {
|
||||
SET_BOUND(set_lower, l, inf_l, a, xi, lrac.m_r_lower_bounds()[i]);
|
||||
}
|
||||
if (has_upper(i)) {
|
||||
SET_BOUND(set_upper, u, inf_u, a, xi, lrac.m_r_upper_bounds()[i]);
|
||||
}
|
||||
if (has_lower(i))
|
||||
set_lower(l, inf_l, delta(a, xi, lrac.m_r_lower_bounds()[i]));
|
||||
if (has_upper(i))
|
||||
set_upper(u, inf_u, delta(a, xi, lrac.m_r_upper_bounds()[i]));
|
||||
}
|
||||
else {
|
||||
if (has_upper(i)) {
|
||||
SET_BOUND(set_lower, l, inf_l, a, xi, lrac.m_r_upper_bounds()[i]);
|
||||
}
|
||||
if (has_lower(i)) {
|
||||
SET_BOUND(set_upper, u, inf_u, a, xi, lrac.m_r_lower_bounds()[i]);
|
||||
}
|
||||
if (has_upper(i))
|
||||
set_lower(l, inf_l, delta(a, xi, lrac.m_r_upper_bounds()[i]));
|
||||
if (has_lower(i))
|
||||
set_upper(u, inf_u, delta(a, xi, lrac.m_r_lower_bounds()[i]));
|
||||
}
|
||||
++rounds;
|
||||
}
|
||||
|
||||
l += xj;
|
||||
|
@ -545,7 +536,7 @@ for (const auto &c : row)
|
|||
}
|
||||
std::ostream& int_solver::display_row_info(std::ostream & out, unsigned row_index) const {
|
||||
auto & rslv = lrac.m_r_solver;
|
||||
auto row = rslv.m_A.m_rows[row_index];
|
||||
auto const& row = rslv.m_A.m_rows[row_index];
|
||||
return display_row(out, row);
|
||||
}
|
||||
|
||||
|
|
|
@ -179,11 +179,17 @@ void lar_core_solver::solve() {
|
|||
}
|
||||
lp_assert(!settings().use_tableau() || r_basis_is_OK());
|
||||
}
|
||||
if (m_r_solver.get_status() == lp_status::INFEASIBLE) {
|
||||
switch (m_r_solver.get_status())
|
||||
{
|
||||
case lp_status::INFEASIBLE:
|
||||
fill_not_improvable_zero_sum();
|
||||
}
|
||||
else if (m_r_solver.get_status() != lp_status::UNBOUNDED) {
|
||||
break;
|
||||
case lp_status::CANCELLED:
|
||||
case lp_status::UNBOUNDED: // do nothing in these cases
|
||||
break;
|
||||
default: // adjust the status to optimal
|
||||
m_r_solver.set_status(lp_status::OPTIMAL);
|
||||
break;
|
||||
}
|
||||
lp_assert(r_basis_is_OK());
|
||||
lp_assert(m_r_solver.non_basic_columns_are_set_correctly());
|
||||
|
|
|
@ -798,6 +798,18 @@ namespace lp {
|
|||
}
|
||||
|
||||
|
||||
// this function just looks at the status
|
||||
bool lar_solver::is_feasible() const {
|
||||
switch (this->get_status()) {
|
||||
case lp_status::OPTIMAL:
|
||||
case lp_status::FEASIBLE:
|
||||
case lp_status::UNBOUNDED:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
numeric_pair<mpq> lar_solver::get_basic_var_value_from_row(unsigned i) {
|
||||
numeric_pair<mpq> r = zero_of_type<numeric_pair<mpq>>();
|
||||
|
||||
|
|
|
@ -296,6 +296,8 @@ class lar_solver : public column_namer {
|
|||
mutable mpq m_delta;
|
||||
|
||||
public:
|
||||
// this function just looks at the status
|
||||
bool is_feasible() const;
|
||||
const map<mpq, unsigned, obj_hash<mpq>, default_eq<mpq>>& fixed_var_table_int() const {
|
||||
return m_fixed_var_table_int;
|
||||
}
|
||||
|
@ -555,6 +557,10 @@ public:
|
|||
return m_mpq_lar_core_solver.column_is_bounded(j);
|
||||
}
|
||||
|
||||
bool check_feasible() const {
|
||||
return m_mpq_lar_core_solver.m_r_solver.calc_current_x_is_feasible_include_non_basis();
|
||||
}
|
||||
|
||||
std::pair<constraint_index, constraint_index> add_equality(lpvar j, lpvar k);
|
||||
|
||||
inline void get_bound_constraint_witnesses_for_column(unsigned j, constraint_index & lc, constraint_index & uc) const {
|
||||
|
|
|
@ -116,28 +116,42 @@ class lp_bound_propagator {
|
|||
|
||||
|
||||
map<mpq, unsigned, obj_hash<mpq>, default_eq<mpq>> m_val2fixed_row;
|
||||
|
||||
bool is_fixed_row(unsigned r, unsigned & x) {
|
||||
x = UINT_MAX;
|
||||
const auto & row = lp().get_row(r);
|
||||
for (unsigned k = 0; k < row.size(); k++) {
|
||||
const auto& c = row[k];
|
||||
if (column_is_fixed(c.var()))
|
||||
continue;
|
||||
if (x != UINT_MAX)
|
||||
return false;
|
||||
x = c.var();
|
||||
}
|
||||
return x != UINT_MAX;
|
||||
}
|
||||
|
||||
void try_add_equation_with_internal_fixed_tables(unsigned r1, vertex const* v) {
|
||||
void try_add_equation_with_internal_fixed_tables(unsigned r1) {
|
||||
SASSERT(m_fixed_vertex);
|
||||
if (v != m_root)
|
||||
unsigned v1, v2;
|
||||
if (!is_fixed_row(r1, v1))
|
||||
return;
|
||||
unsigned v1 = v->column();
|
||||
unsigned r2 = UINT_MAX;
|
||||
if (!m_val2fixed_row.find(val(v1), r2) || r2 >= lp().row_count()) {
|
||||
m_val2fixed_row.insert(val(v1), r1);
|
||||
return;
|
||||
}
|
||||
unsigned v2, v3;
|
||||
int polarity;
|
||||
if (!is_tree_offset_row(r2, v2, v3, polarity) || !not_set(v3) ||
|
||||
is_int(v1) != is_int(v2) || val(v1) != val(v2)) {
|
||||
if (!is_fixed_row(r2, v2) || val(v1) != val(v2) || is_int(v1) != is_int(v2)) {
|
||||
m_val2fixed_row.insert(val(v1), r1);
|
||||
return;
|
||||
}
|
||||
if (v1 == v2)
|
||||
return;
|
||||
|
||||
explanation ex;
|
||||
explain_fixed_in_row(r1, ex);
|
||||
explain_fixed_in_row(r2, ex);
|
||||
TRACE("eq", print_row(tout, r1); print_row(tout, r2); tout << v1 << " == " << v2 << " = " << val(v1) << "\n");
|
||||
add_eq_on_columns(ex, v1, v2, true);
|
||||
}
|
||||
|
||||
|
@ -146,7 +160,7 @@ class lp_bound_propagator {
|
|||
unsigned v_j = v->column();
|
||||
unsigned j = null_lpvar;
|
||||
if (!lp().find_in_fixed_tables(val(v_j), is_int(v_j), j)) {
|
||||
// try_add_equation_with_internal_fixed_tables(row_index, v);
|
||||
try_add_equation_with_internal_fixed_tables(row_index);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -100,10 +100,7 @@ template <typename T, typename X> bool lp_dual_core_solver<T, X>::done() {
|
|||
if (this->get_status() == lp_status::OPTIMAL) {
|
||||
return true;
|
||||
}
|
||||
if (this->total_iterations() > this->m_settings.max_total_number_of_iterations) { // debug !!!!
|
||||
this->set_status(lp_status::ITERATIONS_EXHAUSTED);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // todo, need to be more cases
|
||||
}
|
||||
|
||||
|
@ -747,6 +744,6 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::solve() { // s
|
|||
one_iteration();
|
||||
} while (this->get_status() != lp_status::FLOATING_POINT_ERROR && this->get_status() != lp_status::DUAL_UNBOUNDED && this->get_status() != lp_status::OPTIMAL &&
|
||||
this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements
|
||||
&& this->total_iterations() <= this->m_settings.max_total_number_of_iterations);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,9 +31,6 @@ template <typename T, typename X> void lp_dual_simplex<T, X>::decide_on_status_a
|
|||
break;
|
||||
case lp_status::DUAL_UNBOUNDED:
|
||||
lp_unreachable();
|
||||
case lp_status::ITERATIONS_EXHAUSTED:
|
||||
this->m_status = lp_status::ITERATIONS_EXHAUSTED;
|
||||
break;
|
||||
case lp_status::TIME_EXHAUSTED:
|
||||
this->m_status = lp_status::TIME_EXHAUSTED;
|
||||
break;
|
||||
|
|
|
@ -956,8 +956,6 @@ template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::solve()
|
|||
&&
|
||||
this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements
|
||||
&&
|
||||
this->total_iterations() <= this->m_settings.max_total_number_of_iterations
|
||||
&&
|
||||
!(this->current_x_is_feasible() && this->m_look_for_feasible_solution_only));
|
||||
|
||||
lp_assert(this->get_status() == lp_status::FLOATING_POINT_ERROR
|
||||
|
@ -1097,10 +1095,8 @@ template <typename T, typename X> bool lp_primal_core_solver<T, X>::done() {
|
|||
return true;
|
||||
}
|
||||
if (this->m_iters_with_no_cost_growing >= this->m_settings.max_number_of_iterations_with_no_improvements) {
|
||||
this->get_status() = lp_status::ITERATIONS_EXHAUSTED; return true;
|
||||
}
|
||||
if (this->total_iterations() >= this->m_settings.max_total_number_of_iterations) {
|
||||
this->get_status() = lp_status::ITERATIONS_EXHAUSTED; return true;
|
||||
this->set_status(lp_status::CANCELLED);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -182,9 +182,7 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
|
|||
if (this->m_settings.get_cancel_flag()
|
||||
||
|
||||
this->iters_with_no_cost_growing() > this->m_settings.max_number_of_iterations_with_no_improvements
|
||||
||
|
||||
this->total_iterations() > this->m_settings.max_total_number_of_iterations
|
||||
) {
|
||||
) {
|
||||
this->set_status(lp_status::CANCELLED);
|
||||
break; // from the loop
|
||||
}
|
||||
|
|
|
@ -71,7 +71,6 @@ enum class lp_status {
|
|||
FEASIBLE,
|
||||
FLOATING_POINT_ERROR,
|
||||
TIME_EXHAUSTED,
|
||||
ITERATIONS_EXHAUSTED,
|
||||
EMPTY,
|
||||
UNSTABLE,
|
||||
CANCELLED
|
||||
|
@ -210,7 +209,6 @@ public:
|
|||
double harris_feasibility_tolerance { 1e-7 }; // page 179 of Istvan Maros
|
||||
double ignore_epsilon_of_harris { 10e-5 };
|
||||
unsigned max_number_of_iterations_with_no_improvements { 2000000 };
|
||||
unsigned max_total_number_of_iterations { 20000000 };
|
||||
double time_limit; // the maximum time limit of the total run time in seconds
|
||||
// dual section
|
||||
double dual_feasibility_tolerance { 1e-7 }; // page 71 of the PhD thesis of Achim Koberstein
|
||||
|
|
|
@ -45,7 +45,6 @@ const char* lp_status_to_string(lp_status status) {
|
|||
case lp_status::FEASIBLE: return "FEASIBLE";
|
||||
case lp_status::FLOATING_POINT_ERROR: return "FLOATING_POINT_ERROR";
|
||||
case lp_status::TIME_EXHAUSTED: return "TIME_EXHAUSTED";
|
||||
case lp_status::ITERATIONS_EXHAUSTED: return "ITERATIONS_EXHAUSTED";
|
||||
case lp_status::EMPTY: return "EMPTY";
|
||||
case lp_status::UNSTABLE: return "UNSTABLE";
|
||||
default:
|
||||
|
@ -62,7 +61,6 @@ lp_status lp_status_from_string(std::string status) {
|
|||
if (status == "FEASIBLE") return lp_status::FEASIBLE;
|
||||
if (status == "FLOATING_POINT_ERROR") return lp_status::FLOATING_POINT_ERROR;
|
||||
if (status == "TIME_EXHAUSTED") return lp_status::TIME_EXHAUSTED;
|
||||
if (status == "ITERATIONS_EXHAUSTED") return lp_status::ITERATIONS_EXHAUSTED;
|
||||
if (status == "EMPTY") return lp_status::EMPTY;
|
||||
lp_unreachable();
|
||||
return lp_status::UNKNOWN; // it is unreachable
|
||||
|
|
|
@ -158,13 +158,7 @@ public:
|
|||
m_settings.time_limit = time_limit_in_seconds;
|
||||
}
|
||||
|
||||
void set_max_iterations_per_stage(unsigned max_iterations) {
|
||||
m_settings.max_total_number_of_iterations = max_iterations;
|
||||
}
|
||||
|
||||
unsigned get_max_iterations_per_stage() const {
|
||||
return m_settings.max_total_number_of_iterations;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool problem_is_empty();
|
||||
|
||||
|
|
|
@ -51,25 +51,23 @@ bool random_updater::shift_var(unsigned j) {
|
|||
|
||||
|
||||
void random_updater::update() {
|
||||
// VERIFY(m_lar_solver.check_feasible());
|
||||
auto columns = m_var_set.index(); // m_var_set is going to change during the loop
|
||||
for (auto j : columns) {
|
||||
if (!m_var_set.contains(j)) {
|
||||
TRACE("lar_solver_rand", tout << "skipped " << j << "\n";);
|
||||
continue;
|
||||
}
|
||||
if (!m_lar_solver.is_base(j)) {
|
||||
if (!m_lar_solver.is_base(j))
|
||||
shift_var(j);
|
||||
} else {
|
||||
else {
|
||||
unsigned row_index = m_lar_solver.r_heading()[j];
|
||||
for (auto & row_c : m_lar_solver.get_row(row_index)) {
|
||||
unsigned cj = row_c.var();
|
||||
if (!m_lar_solver.is_base(cj) &&
|
||||
!m_lar_solver.column_is_fixed(cj)
|
||||
&&
|
||||
shift_var(cj)
|
||||
) {
|
||||
break; // done with the basic var j
|
||||
}
|
||||
!m_lar_solver.column_is_fixed(cj) &&
|
||||
shift_var(cj))
|
||||
break; // done with the basic var j
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -220,6 +220,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "subpaving"; }
|
||||
|
||||
tactic * translate(ast_manager & m) override {
|
||||
return alloc(subpaving_tactic, m, m_params);
|
||||
}
|
||||
|
|
|
@ -392,6 +392,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "horn"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
|
|
|
@ -223,6 +223,8 @@ public:
|
|||
SASSERT(m_imp == 0);
|
||||
}
|
||||
|
||||
char const* name() const override { return "nlsat"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
}
|
||||
|
|
|
@ -305,11 +305,9 @@ namespace opt {
|
|||
expr_ref fml(m), bound(m.mk_true(), m), tmp(m);
|
||||
expr* vars[1];
|
||||
{
|
||||
for (unsigned i = 0; i < m_upper.size(); ++i) {
|
||||
for (unsigned i = 0; i < m_upper.size(); ++i)
|
||||
ors.push_back(m_s->mk_ge(i, m_upper[i]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
fml = mk_or(ors);
|
||||
tmp = m.mk_fresh_const("b", m.mk_bool_sort());
|
||||
fml = m.mk_implies(tmp, fml);
|
||||
|
@ -328,8 +326,7 @@ namespace opt {
|
|||
m_s->get_model(m_model);
|
||||
m_s->get_labels(m_labels);
|
||||
for (unsigned i = 0; i < ors.size(); ++i) {
|
||||
expr_ref tmp(m);
|
||||
if (m_model->is_true(ors[i].get())) {
|
||||
if (m_model->is_true(ors.get(i))) {
|
||||
m_lower[i] = m_upper[i];
|
||||
ors[i] = m.mk_false();
|
||||
disj[i] = m.mk_false();
|
||||
|
|
|
@ -839,6 +839,8 @@ namespace qe {
|
|||
~nlqsat() override {
|
||||
}
|
||||
|
||||
char const* name() const override { return "nlqsat"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
params_ref p2(p);
|
||||
p2.set_bool("factor", false);
|
||||
|
|
|
@ -2459,6 +2459,8 @@ public:
|
|||
m_params(p),
|
||||
m_qe(m, p, true) {}
|
||||
|
||||
char const* name() const override { return "qe_lite"; }
|
||||
|
||||
tactic * translate(ast_manager & m) override {
|
||||
return alloc(qe_lite_tactic, m, m_params);
|
||||
}
|
||||
|
|
|
@ -100,6 +100,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "qe"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
|
|
|
@ -1257,6 +1257,8 @@ namespace qe {
|
|||
~qsat() override {
|
||||
clear();
|
||||
}
|
||||
|
||||
char const* name() const override { return "qsat"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
}
|
||||
|
|
|
@ -342,9 +342,7 @@ namespace sat {
|
|||
clause* solver::mk_clause(unsigned num_lits, literal * lits, sat::status st) {
|
||||
m_model_is_current = false;
|
||||
|
||||
for (unsigned i = 0; i < num_lits; i++)
|
||||
VERIFY(!was_eliminated(lits[i]));
|
||||
|
||||
|
||||
DEBUG_CODE({
|
||||
for (unsigned i = 0; i < num_lits; i++) {
|
||||
CTRACE("sat", was_eliminated(lits[i]), tout << lits[i] << " was eliminated\n";);
|
||||
|
|
|
@ -661,25 +661,25 @@ public:
|
|||
|
||||
void user_propagate_init(
|
||||
void* ctx,
|
||||
solver::push_eh_t& push_eh,
|
||||
solver::pop_eh_t& pop_eh,
|
||||
solver::fresh_eh_t& fresh_eh) override {
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh) override {
|
||||
ensure_euf()->user_propagate_init(ctx, push_eh, pop_eh, fresh_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_fixed(solver::fixed_eh_t& fixed_eh) override {
|
||||
void user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh) override {
|
||||
ensure_euf()->user_propagate_register_fixed(fixed_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_final(solver::final_eh_t& final_eh) override {
|
||||
void user_propagate_register_final(user_propagator::final_eh_t& final_eh) override {
|
||||
ensure_euf()->user_propagate_register_final(final_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_eq(solver::eq_eh_t& eq_eh) override {
|
||||
void user_propagate_register_eq(user_propagator::eq_eh_t& eq_eh) override {
|
||||
ensure_euf()->user_propagate_register_eq(eq_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_diseq(solver::eq_eh_t& diseq_eh) override {
|
||||
void user_propagate_register_diseq(user_propagator::eq_eh_t& diseq_eh) override {
|
||||
ensure_euf()->user_propagate_register_diseq(diseq_eh);
|
||||
}
|
||||
|
||||
|
@ -959,11 +959,11 @@ private:
|
|||
extract_asm2dep(asm2dep);
|
||||
sat::literal_vector const& core = m_solver.get_core();
|
||||
TRACE("sat",
|
||||
for (auto kv : m_dep2asm) {
|
||||
for (auto const& kv : m_dep2asm) {
|
||||
tout << mk_pp(kv.m_key, m) << " |-> " << sat::literal(kv.m_value) << "\n";
|
||||
}
|
||||
tout << "asm2fml: ";
|
||||
for (auto kv : asm2fml) {
|
||||
for (auto const& kv : asm2fml) {
|
||||
tout << mk_pp(kv.m_key, m) << " |-> " << mk_pp(kv.m_value, m) << "\n";
|
||||
}
|
||||
tout << "core: "; for (auto c : core) tout << c << " "; tout << "\n";
|
||||
|
|
|
@ -308,7 +308,6 @@ namespace arith {
|
|||
|
||||
bool solver::internalize_atom(expr* atom) {
|
||||
TRACE("arith", tout << mk_pp(atom, m) << "\n";);
|
||||
SASSERT(!ctx.get_enode(atom));
|
||||
expr* n1, *n2;
|
||||
rational r;
|
||||
lp_api::bound_kind k;
|
||||
|
|
|
@ -627,8 +627,9 @@ namespace arith {
|
|||
else if (use_nra_model() && lp().external_to_local(v) != lp::null_lpvar) {
|
||||
anum const& an = nl_value(v, *m_a1);
|
||||
if (a.is_int(o) && !m_nla->am().is_int(an))
|
||||
value = a.mk_numeral(rational::zero(), a.is_int(o));
|
||||
//value = a.mk_numeral(m_nla->am(), nl_value(v, *m_a1), a.is_int(o));
|
||||
value = a.mk_numeral(rational::zero(), a.is_int(o));
|
||||
else
|
||||
value = a.mk_numeral(m_nla->am(), nl_value(v, *m_a1), a.is_int(o));
|
||||
}
|
||||
else if (v != euf::null_theory_var) {
|
||||
rational r = get_value(v);
|
||||
|
@ -985,7 +986,7 @@ namespace arith {
|
|||
IF_VERBOSE(12, verbose_stream() << "final-check " << lp().get_status() << "\n");
|
||||
SASSERT(lp().ax_is_correct());
|
||||
|
||||
if (lp().get_status() != lp::lp_status::OPTIMAL || lp().has_changed_columns()) {
|
||||
if (!lp().is_feasible() || lp().has_changed_columns()) {
|
||||
switch (make_feasible()) {
|
||||
case l_false:
|
||||
get_infeasibility_explanation_and_set_conflict();
|
||||
|
@ -1096,6 +1097,8 @@ namespace arith {
|
|||
return l_false;
|
||||
case lp::lp_status::FEASIBLE:
|
||||
case lp::lp_status::OPTIMAL:
|
||||
case lp::lp_status::UNBOUNDED:
|
||||
SASSERT(!lp().has_changed_columns());
|
||||
return l_true;
|
||||
case lp::lp_status::TIME_EXHAUSTED:
|
||||
default:
|
||||
|
|
|
@ -131,6 +131,7 @@ namespace euf {
|
|||
|
||||
void solver::dependencies2values(user_sort& us, deps_t& deps, model_ref& mdl) {
|
||||
for (enode* n : deps.top_sorted()) {
|
||||
TRACE("model", tout << bpp(n->get_root()) << "\n");
|
||||
unsigned id = n->get_root_id();
|
||||
if (m_values.get(id, nullptr))
|
||||
continue;
|
||||
|
|
|
@ -295,7 +295,7 @@ namespace euf {
|
|||
return;
|
||||
bool sign = l.sign();
|
||||
m_egraph.set_value(n, sign ? l_false : l_true);
|
||||
for (auto th : enode_th_vars(n))
|
||||
for (auto const& th : enode_th_vars(n))
|
||||
m_id2solver[th.get_id()]->asserted(l);
|
||||
|
||||
size_t* c = to_ptr(l);
|
||||
|
@ -519,8 +519,7 @@ namespace euf {
|
|||
|
||||
void solver::push() {
|
||||
si.push();
|
||||
scope s;
|
||||
s.m_var_lim = m_var_trail.size();
|
||||
scope s(m_var_trail.size());
|
||||
m_scopes.push_back(s);
|
||||
m_trail.push_scope();
|
||||
for (auto* e : m_solvers)
|
||||
|
@ -994,9 +993,9 @@ namespace euf {
|
|||
|
||||
void solver::user_propagate_init(
|
||||
void* ctx,
|
||||
::solver::push_eh_t& push_eh,
|
||||
::solver::pop_eh_t& pop_eh,
|
||||
::solver::fresh_eh_t& fresh_eh) {
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh) {
|
||||
m_user_propagator = alloc(user_solver::solver, *this);
|
||||
m_user_propagator->add(ctx, push_eh, pop_eh, fresh_eh);
|
||||
for (unsigned i = m_scopes.size(); i-- > 0; )
|
||||
|
|
|
@ -72,6 +72,7 @@ namespace euf {
|
|||
};
|
||||
struct scope {
|
||||
unsigned m_var_lim;
|
||||
scope(unsigned l) : m_var_lim(l) {}
|
||||
};
|
||||
|
||||
|
||||
|
@ -400,27 +401,27 @@ namespace euf {
|
|||
// user propagator
|
||||
void user_propagate_init(
|
||||
void* ctx,
|
||||
::solver::push_eh_t& push_eh,
|
||||
::solver::pop_eh_t& pop_eh,
|
||||
::solver::fresh_eh_t& fresh_eh);
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh);
|
||||
bool watches_fixed(enode* n) const;
|
||||
void assign_fixed(enode* n, expr* val, unsigned sz, literal const* explain);
|
||||
void assign_fixed(enode* n, expr* val, literal_vector const& explain) { assign_fixed(n, val, explain.size(), explain.data()); }
|
||||
void assign_fixed(enode* n, expr* val, literal explain) { assign_fixed(n, val, 1, &explain); }
|
||||
|
||||
void user_propagate_register_final(::solver::final_eh_t& final_eh) {
|
||||
void user_propagate_register_final(user_propagator::final_eh_t& final_eh) {
|
||||
check_for_user_propagator();
|
||||
m_user_propagator->register_final(final_eh);
|
||||
}
|
||||
void user_propagate_register_fixed(::solver::fixed_eh_t& fixed_eh) {
|
||||
void user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh) {
|
||||
check_for_user_propagator();
|
||||
m_user_propagator->register_fixed(fixed_eh);
|
||||
}
|
||||
void user_propagate_register_eq(::solver::eq_eh_t& eq_eh) {
|
||||
void user_propagate_register_eq(user_propagator::eq_eh_t& eq_eh) {
|
||||
check_for_user_propagator();
|
||||
m_user_propagator->register_eq(eq_eh);
|
||||
}
|
||||
void user_propagate_register_diseq(::solver::eq_eh_t& diseq_eh) {
|
||||
void user_propagate_register_diseq(user_propagator::eq_eh_t& diseq_eh) {
|
||||
check_for_user_propagator();
|
||||
m_user_propagator->register_diseq(diseq_eh);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace sat {
|
|||
m_solver(m_params, l)
|
||||
{
|
||||
SASSERT(!m_solver.get_config().m_drat);
|
||||
m_solver.set_incremental(true);
|
||||
}
|
||||
|
||||
void dual_solver::flush() {
|
||||
|
@ -104,10 +105,10 @@ namespace sat {
|
|||
root = ext2lit(clause[0]);
|
||||
else {
|
||||
root = literal(m_solver.mk_var(), false);
|
||||
m_solver.set_external(root.var());
|
||||
for (unsigned i = 0; i < sz; ++i)
|
||||
m_solver.mk_clause(root, ~ext2lit(clause[i]), status::input());
|
||||
}
|
||||
}
|
||||
m_solver.set_external(root.var());
|
||||
m_roots.push_back(~root);
|
||||
TRACE("dual", tout << "root: " << ~root << " => " << literal_vector(sz, clause) << "\n";);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,13 @@ Author:
|
|||
namespace sat {
|
||||
|
||||
class dual_solver {
|
||||
no_drat_params m_params;
|
||||
class dual_params : public no_drat_params {
|
||||
public:
|
||||
dual_params() {
|
||||
set_bool("core.minimize", false);
|
||||
}
|
||||
};
|
||||
dual_params m_params;
|
||||
solver m_solver;
|
||||
lim_svector<literal> m_units, m_roots;
|
||||
lim_svector<bool_var> m_tracked_vars;
|
||||
|
|
|
@ -47,6 +47,10 @@ namespace user_solver {
|
|||
DEBUG_CODE(validate_propagation(););
|
||||
}
|
||||
|
||||
unsigned solver::register_cb(expr* e) {
|
||||
return add_expr(e);
|
||||
}
|
||||
|
||||
sat::check_result solver::check() {
|
||||
if (!(bool)m_final_eh)
|
||||
return sat::check_result::CR_DONE;
|
||||
|
|
|
@ -21,11 +21,12 @@ Author:
|
|||
|
||||
#include "sat/smt/sat_th.h"
|
||||
#include "solver/solver.h"
|
||||
#include "tactic/user_propagator_base.h"
|
||||
|
||||
|
||||
namespace user_solver {
|
||||
|
||||
class solver : public euf::th_euf_solver, public ::solver::propagate_callback {
|
||||
class solver : public euf::th_euf_solver, public user_propagator::callback {
|
||||
|
||||
struct prop_info {
|
||||
unsigned_vector m_ids;
|
||||
|
@ -47,15 +48,15 @@ namespace user_solver {
|
|||
};
|
||||
|
||||
void* m_user_context;
|
||||
::solver::push_eh_t m_push_eh;
|
||||
::solver::pop_eh_t m_pop_eh;
|
||||
::solver::fresh_eh_t m_fresh_eh;
|
||||
::solver::final_eh_t m_final_eh;
|
||||
::solver::fixed_eh_t m_fixed_eh;
|
||||
::solver::eq_eh_t m_eq_eh;
|
||||
::solver::eq_eh_t m_diseq_eh;
|
||||
::solver::context_obj* m_api_context { nullptr };
|
||||
unsigned m_qhead { 0 };
|
||||
user_propagator::push_eh_t m_push_eh;
|
||||
user_propagator::pop_eh_t m_pop_eh;
|
||||
user_propagator::fresh_eh_t m_fresh_eh;
|
||||
user_propagator::final_eh_t m_final_eh;
|
||||
user_propagator::fixed_eh_t m_fixed_eh;
|
||||
user_propagator::eq_eh_t m_eq_eh;
|
||||
user_propagator::eq_eh_t m_diseq_eh;
|
||||
user_propagator::context_obj* m_api_context = nullptr;
|
||||
unsigned m_qhead = 0;
|
||||
vector<prop_info> m_prop;
|
||||
unsigned_vector m_prop_lim;
|
||||
vector<sat::literal_vector> m_id2justification;
|
||||
|
@ -91,9 +92,9 @@ namespace user_solver {
|
|||
*/
|
||||
void add(
|
||||
void* ctx,
|
||||
::solver::push_eh_t& push_eh,
|
||||
::solver::pop_eh_t& pop_eh,
|
||||
::solver::fresh_eh_t& fresh_eh) {
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh) {
|
||||
m_user_context = ctx;
|
||||
m_push_eh = push_eh;
|
||||
m_pop_eh = pop_eh;
|
||||
|
@ -102,14 +103,15 @@ namespace user_solver {
|
|||
|
||||
unsigned add_expr(expr* e);
|
||||
|
||||
void register_final(::solver::final_eh_t& final_eh) { m_final_eh = final_eh; }
|
||||
void register_fixed(::solver::fixed_eh_t& fixed_eh) { m_fixed_eh = fixed_eh; }
|
||||
void register_eq(::solver::eq_eh_t& eq_eh) { m_eq_eh = eq_eh; }
|
||||
void register_diseq(::solver::eq_eh_t& diseq_eh) { m_diseq_eh = diseq_eh; }
|
||||
void register_final(user_propagator::final_eh_t& final_eh) { m_final_eh = final_eh; }
|
||||
void register_fixed(user_propagator::fixed_eh_t& fixed_eh) { m_fixed_eh = fixed_eh; }
|
||||
void register_eq(user_propagator::eq_eh_t& eq_eh) { m_eq_eh = eq_eh; }
|
||||
void register_diseq(user_propagator::eq_eh_t& diseq_eh) { m_diseq_eh = diseq_eh; }
|
||||
|
||||
bool has_fixed() const { return (bool)m_fixed_eh; }
|
||||
|
||||
void propagate_cb(unsigned num_fixed, unsigned const* fixed_ids, unsigned num_eqs, unsigned const* lhs, unsigned const* rhs, expr* conseq) override;
|
||||
unsigned register_cb(expr* e) override;
|
||||
|
||||
void new_fixed_eh(euf::theory_var v, expr* value, unsigned num_lits, sat::literal const* jlits);
|
||||
|
||||
|
|
|
@ -198,6 +198,8 @@ public:
|
|||
SASSERT(m_imp == 0);
|
||||
}
|
||||
|
||||
char const* name() const override { return "sat"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
if (m_imp) m_imp->updt_params(p);
|
||||
|
|
|
@ -70,9 +70,9 @@ z3_add_component(smt
|
|||
theory_str.cpp
|
||||
theory_str_mc.cpp
|
||||
theory_str_regex.cpp
|
||||
theory_user_propagator.cpp
|
||||
theory_utvpi.cpp
|
||||
theory_wmaxsat.cpp
|
||||
user_propagator.cpp
|
||||
uses_theory.cpp
|
||||
watch_list.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
|
|
|
@ -1120,9 +1120,9 @@ struct remove_obj_pair_map : public trail {
|
|||
remove_obj_pair_map(ast_manager& m, obj_pair_hashtable<expr, expr> & map, expr* a, expr* b):
|
||||
m(m), m_map(map), a(a), b(b) {}
|
||||
void undo() override {
|
||||
m_map.erase(std::make_pair(a, b));
|
||||
m.dec_ref(a);
|
||||
m.dec_ref(b);
|
||||
m_map.erase(std::make_pair(a, b));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ namespace smt {
|
|||
return;
|
||||
ast_translation tr(src_ctx.m, m, false);
|
||||
auto* p = get_theory(m.mk_family_id("user_propagator"));
|
||||
m_user_propagator = reinterpret_cast<user_propagator*>(p);
|
||||
m_user_propagator = reinterpret_cast<theory_user_propagator*>(p);
|
||||
SASSERT(m_user_propagator);
|
||||
for (unsigned i = 0; i < src_ctx.m_user_propagator->get_num_vars(); ++i) {
|
||||
app* e = src_ctx.m_user_propagator->get_expr(i);
|
||||
|
@ -2886,11 +2886,11 @@ namespace smt {
|
|||
|
||||
void context::user_propagate_init(
|
||||
void* ctx,
|
||||
solver::push_eh_t& push_eh,
|
||||
solver::pop_eh_t& pop_eh,
|
||||
solver::fresh_eh_t& fresh_eh) {
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh) {
|
||||
setup_context(false);
|
||||
m_user_propagator = alloc(user_propagator, *this);
|
||||
m_user_propagator = alloc(theory_user_propagator, *this);
|
||||
m_user_propagator->add(ctx, push_eh, pop_eh, fresh_eh);
|
||||
for (unsigned i = m_scopes.size(); i-- > 0; )
|
||||
m_user_propagator->push_scope_eh();
|
||||
|
@ -3552,7 +3552,7 @@ namespace smt {
|
|||
parallel p(*this);
|
||||
return p(asms);
|
||||
}
|
||||
lbool r;
|
||||
lbool r = l_undef;
|
||||
do {
|
||||
pop_to_base_lvl();
|
||||
expr_ref_vector asms(m, num_assumptions, assumptions);
|
||||
|
@ -3573,7 +3573,7 @@ namespace smt {
|
|||
if (!check_preamble(true)) return l_undef;
|
||||
TRACE("before_search", display(tout););
|
||||
setup_context(false);
|
||||
lbool r;
|
||||
lbool r = l_undef;
|
||||
do {
|
||||
pop_to_base_lvl();
|
||||
expr_ref_vector asms(cube);
|
||||
|
|
|
@ -46,7 +46,7 @@ Revision History:
|
|||
#include "util/statistics.h"
|
||||
#include "smt/fingerprints.h"
|
||||
#include "smt/proto_model/proto_model.h"
|
||||
#include "smt/user_propagator.h"
|
||||
#include "smt/theory_user_propagator.h"
|
||||
#include "model/model.h"
|
||||
#include "solver/progress_callback.h"
|
||||
#include "solver/assertions/asserted_formulas.h"
|
||||
|
@ -88,7 +88,7 @@ namespace smt {
|
|||
scoped_ptr<quantifier_manager> m_qmanager;
|
||||
scoped_ptr<model_generator> m_model_generator;
|
||||
scoped_ptr<relevancy_propagator> m_relevancy_propagator;
|
||||
user_propagator* m_user_propagator;
|
||||
theory_user_propagator* m_user_propagator;
|
||||
random_gen m_random;
|
||||
bool m_flushing; // (debug support) true when flushing
|
||||
mutable unsigned m_lemma_id;
|
||||
|
@ -1695,29 +1695,29 @@ namespace smt {
|
|||
*/
|
||||
void user_propagate_init(
|
||||
void* ctx,
|
||||
solver::push_eh_t& push_eh,
|
||||
solver::pop_eh_t& pop_eh,
|
||||
solver::fresh_eh_t& fresh_eh);
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh);
|
||||
|
||||
void user_propagate_register_final(solver::final_eh_t& final_eh) {
|
||||
void user_propagate_register_final(user_propagator::final_eh_t& final_eh) {
|
||||
if (!m_user_propagator)
|
||||
throw default_exception("user propagator must be initialized");
|
||||
m_user_propagator->register_final(final_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_fixed(solver::fixed_eh_t& fixed_eh) {
|
||||
void user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh) {
|
||||
if (!m_user_propagator)
|
||||
throw default_exception("user propagator must be initialized");
|
||||
m_user_propagator->register_fixed(fixed_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_eq(solver::eq_eh_t& eq_eh) {
|
||||
void user_propagate_register_eq(user_propagator::eq_eh_t& eq_eh) {
|
||||
if (!m_user_propagator)
|
||||
throw default_exception("user propagator must be initialized");
|
||||
m_user_propagator->register_eq(eq_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_diseq(solver::eq_eh_t& diseq_eh) {
|
||||
void user_propagate_register_diseq(user_propagator::eq_eh_t& diseq_eh) {
|
||||
if (!m_user_propagator)
|
||||
throw default_exception("user propagator must be initialized");
|
||||
m_user_propagator->register_diseq(diseq_eh);
|
||||
|
|
|
@ -223,25 +223,25 @@ namespace smt {
|
|||
|
||||
void user_propagate_init(
|
||||
void* ctx,
|
||||
solver::push_eh_t& push_eh,
|
||||
solver::pop_eh_t& pop_eh,
|
||||
solver::fresh_eh_t& fresh_eh) {
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh) {
|
||||
m_kernel.user_propagate_init(ctx, push_eh, pop_eh, fresh_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_final(solver::final_eh_t& final_eh) {
|
||||
void user_propagate_register_final(user_propagator::final_eh_t& final_eh) {
|
||||
m_kernel.user_propagate_register_final(final_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_fixed(solver::fixed_eh_t& fixed_eh) {
|
||||
void user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh) {
|
||||
m_kernel.user_propagate_register_fixed(fixed_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_eq(solver::eq_eh_t& eq_eh) {
|
||||
void user_propagate_register_eq(user_propagator::eq_eh_t& eq_eh) {
|
||||
m_kernel.user_propagate_register_eq(eq_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_diseq(solver::eq_eh_t& diseq_eh) {
|
||||
void user_propagate_register_diseq(user_propagator::eq_eh_t& diseq_eh) {
|
||||
m_kernel.user_propagate_register_diseq(diseq_eh);
|
||||
}
|
||||
|
||||
|
@ -451,25 +451,25 @@ namespace smt {
|
|||
|
||||
void kernel::user_propagate_init(
|
||||
void* ctx,
|
||||
solver::push_eh_t& push_eh,
|
||||
solver::pop_eh_t& pop_eh,
|
||||
solver::fresh_eh_t& fresh_eh) {
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh) {
|
||||
m_imp->user_propagate_init(ctx, push_eh, pop_eh, fresh_eh);
|
||||
}
|
||||
|
||||
void kernel::user_propagate_register_fixed(solver::fixed_eh_t& fixed_eh) {
|
||||
void kernel::user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh) {
|
||||
m_imp->user_propagate_register_fixed(fixed_eh);
|
||||
}
|
||||
|
||||
void kernel::user_propagate_register_final(solver::final_eh_t& final_eh) {
|
||||
void kernel::user_propagate_register_final(user_propagator::final_eh_t& final_eh) {
|
||||
m_imp->user_propagate_register_final(final_eh);
|
||||
}
|
||||
|
||||
void kernel::user_propagate_register_eq(solver::eq_eh_t& eq_eh) {
|
||||
void kernel::user_propagate_register_eq(user_propagator::eq_eh_t& eq_eh) {
|
||||
m_imp->user_propagate_register_eq(eq_eh);
|
||||
}
|
||||
|
||||
void kernel::user_propagate_register_diseq(solver::eq_eh_t& diseq_eh) {
|
||||
void kernel::user_propagate_register_diseq(user_propagator::eq_eh_t& diseq_eh) {
|
||||
m_imp->user_propagate_register_diseq(diseq_eh);
|
||||
}
|
||||
|
||||
|
|
|
@ -289,17 +289,17 @@ namespace smt {
|
|||
*/
|
||||
void user_propagate_init(
|
||||
void* ctx,
|
||||
solver::push_eh_t& push_eh,
|
||||
solver::pop_eh_t& pop_eh,
|
||||
solver::fresh_eh_t& fresh_eh);
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh);
|
||||
|
||||
void user_propagate_register_fixed(solver::fixed_eh_t& fixed_eh);
|
||||
void user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh);
|
||||
|
||||
void user_propagate_register_final(solver::final_eh_t& final_eh);
|
||||
void user_propagate_register_final(user_propagator::final_eh_t& final_eh);
|
||||
|
||||
void user_propagate_register_eq(solver::eq_eh_t& eq_eh);
|
||||
void user_propagate_register_eq(user_propagator::eq_eh_t& eq_eh);
|
||||
|
||||
void user_propagate_register_diseq(solver::eq_eh_t& diseq_eh);
|
||||
void user_propagate_register_diseq(user_propagator::eq_eh_t& diseq_eh);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -105,7 +105,7 @@ namespace smt {
|
|||
else
|
||||
proc = alloc(expr_wrapper_proc, m.mk_false());
|
||||
}
|
||||
else if (m.is_value(r->get_expr()))
|
||||
else if (m.is_model_value(r->get_expr()))
|
||||
proc = alloc(expr_wrapper_proc, r->get_expr());
|
||||
else {
|
||||
family_id fid = s->get_family_id();
|
||||
|
|
|
@ -215,25 +215,25 @@ namespace {
|
|||
|
||||
void user_propagate_init(
|
||||
void* ctx,
|
||||
solver::push_eh_t& push_eh,
|
||||
solver::pop_eh_t& pop_eh,
|
||||
solver::fresh_eh_t& fresh_eh) override {
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh) override {
|
||||
m_context.user_propagate_init(ctx, push_eh, pop_eh, fresh_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_fixed(solver::fixed_eh_t& fixed_eh) override {
|
||||
void user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh) override {
|
||||
m_context.user_propagate_register_fixed(fixed_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_final(solver::final_eh_t& final_eh) override {
|
||||
void user_propagate_register_final(user_propagator::final_eh_t& final_eh) override {
|
||||
m_context.user_propagate_register_final(final_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_eq(solver::eq_eh_t& eq_eh) override {
|
||||
void user_propagate_register_eq(user_propagator::eq_eh_t& eq_eh) override {
|
||||
m_context.user_propagate_register_eq(eq_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_diseq(solver::eq_eh_t& diseq_eh) override {
|
||||
void user_propagate_register_diseq(user_propagator::eq_eh_t& diseq_eh) override {
|
||||
m_context.user_propagate_register_diseq(diseq_eh);
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ public:
|
|||
m_fns.reset();
|
||||
}
|
||||
|
||||
char const* name() const override { return "ctx_solver_simplify"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_solver.updt_params(p);
|
||||
}
|
||||
|
|
|
@ -37,32 +37,35 @@ typedef obj_map<expr, expr *> expr2expr_map;
|
|||
|
||||
|
||||
class smt_tactic : public tactic {
|
||||
ast_manager& m;
|
||||
smt_params m_params;
|
||||
params_ref m_params_ref;
|
||||
statistics m_stats;
|
||||
smt::kernel * m_ctx;
|
||||
smt::kernel* m_ctx = nullptr;
|
||||
symbol m_logic;
|
||||
progress_callback * m_callback;
|
||||
bool m_candidate_models;
|
||||
bool m_fail_if_inconclusive;
|
||||
progress_callback* m_callback = nullptr;
|
||||
bool m_candidate_models = false;
|
||||
bool m_fail_if_inconclusive = false;
|
||||
|
||||
public:
|
||||
smt_tactic(params_ref const & p):
|
||||
smt_tactic(ast_manager& m, params_ref const & p):
|
||||
m(m),
|
||||
m_params_ref(p),
|
||||
m_ctx(nullptr),
|
||||
m_callback(nullptr) {
|
||||
m_vars(m) {
|
||||
updt_params_core(p);
|
||||
TRACE("smt_tactic", tout << "p: " << p << "\n";);
|
||||
}
|
||||
|
||||
tactic * translate(ast_manager & m) override {
|
||||
return alloc(smt_tactic, m_params_ref);
|
||||
return alloc(smt_tactic, m, m_params_ref);
|
||||
}
|
||||
|
||||
~smt_tactic() override {
|
||||
SASSERT(m_ctx == nullptr);
|
||||
}
|
||||
|
||||
char const* name() const override { return "smt"; }
|
||||
|
||||
smt_params & fparams() {
|
||||
return m_params;
|
||||
}
|
||||
|
@ -137,6 +140,7 @@ public:
|
|||
~scoped_init_ctx() {
|
||||
smt::kernel * d = m_owner.m_ctx;
|
||||
m_owner.m_ctx = nullptr;
|
||||
m_owner.m_user_ctx = nullptr;
|
||||
|
||||
if (d)
|
||||
dealloc(d);
|
||||
|
@ -151,7 +155,6 @@ public:
|
|||
goal_ref_buffer & result) override {
|
||||
try {
|
||||
IF_VERBOSE(10, verbose_stream() << "(smt.tactic start)\n";);
|
||||
ast_manager & m = in->m();
|
||||
tactic_report report("smt", *in);
|
||||
TRACE("smt_tactic", tout << this << "\nAUTO_CONFIG: " << fparams().m_auto_config << " HIDIV0: " << fparams().m_hi_div0 << " "
|
||||
<< " PREPROCESS: " << fparams().m_preprocess << "\n";
|
||||
|
@ -163,7 +166,7 @@ public:
|
|||
TRACE("smt_tactic_detail", in->display(tout););
|
||||
TRACE("smt_tactic_memory", tout << "wasted_size: " << m.get_allocator().get_wasted_size() << "\n";);
|
||||
scoped_init_ctx init(*this, m);
|
||||
SASSERT(m_ctx != 0);
|
||||
SASSERT(m_ctx);
|
||||
|
||||
expr_ref_vector clauses(m);
|
||||
expr2expr_map bool2dep;
|
||||
|
@ -194,10 +197,11 @@ public:
|
|||
if (m_ctx->canceled()) {
|
||||
throw tactic_exception(Z3_CANCELED_MSG);
|
||||
}
|
||||
user_propagate_delay_init();
|
||||
|
||||
lbool r;
|
||||
try {
|
||||
if (assumptions.empty())
|
||||
if (assumptions.empty() && !m_user_ctx)
|
||||
r = m_ctx->setup_and_check();
|
||||
else
|
||||
r = m_ctx->check(assumptions.size(), assumptions.data());
|
||||
|
@ -306,10 +310,163 @@ public:
|
|||
throw tactic_exception(ex.msg());
|
||||
}
|
||||
}
|
||||
|
||||
void* m_user_ctx = nullptr;
|
||||
user_propagator::push_eh_t m_push_eh;
|
||||
user_propagator::pop_eh_t m_pop_eh;
|
||||
user_propagator::fresh_eh_t m_fresh_eh;
|
||||
user_propagator::fixed_eh_t m_fixed_eh;
|
||||
user_propagator::final_eh_t m_final_eh;
|
||||
user_propagator::eq_eh_t m_eq_eh;
|
||||
user_propagator::eq_eh_t m_diseq_eh;
|
||||
expr_ref_vector m_vars;
|
||||
unsigned_vector m_var2internal;
|
||||
unsigned_vector m_internal2var;
|
||||
|
||||
user_propagator::fixed_eh_t i_fixed_eh;
|
||||
user_propagator::final_eh_t i_final_eh;
|
||||
user_propagator::eq_eh_t i_eq_eh;
|
||||
user_propagator::eq_eh_t i_diseq_eh;
|
||||
|
||||
|
||||
|
||||
struct callback : public user_propagator::callback {
|
||||
smt_tactic* t = nullptr;
|
||||
user_propagator::callback* cb = nullptr;
|
||||
unsigned_vector fixed, lhs, rhs;
|
||||
void propagate_cb(unsigned num_fixed, unsigned const* fixed_ids, unsigned num_eqs, unsigned const* eq_lhs, unsigned const* eq_rhs, expr* conseq) override {
|
||||
fixed.reset();
|
||||
lhs.reset();
|
||||
rhs.reset();
|
||||
for (unsigned i = 0; i < num_fixed; ++i)
|
||||
fixed.push_back(t->m_var2internal[fixed_ids[i]]);
|
||||
for (unsigned i = 0; i < num_eqs; ++i) {
|
||||
lhs.push_back(t->m_var2internal[eq_lhs[i]]);
|
||||
rhs.push_back(t->m_var2internal[eq_rhs[i]]);
|
||||
}
|
||||
cb->propagate_cb(num_fixed, fixed.data(), num_eqs, lhs.data(), rhs.data(), conseq);
|
||||
}
|
||||
|
||||
unsigned register_cb(expr* e) override {
|
||||
unsigned j = t->m_vars.size();
|
||||
t->m_vars.push_back(e);
|
||||
unsigned i = cb->register_cb(e);
|
||||
t->m_var2internal.setx(j, i, 0);
|
||||
t->m_internal2var.setx(i, j, 0);
|
||||
return j;
|
||||
}
|
||||
};
|
||||
|
||||
callback i_cb;
|
||||
|
||||
void init_i_fixed_eh() {
|
||||
if (!m_fixed_eh)
|
||||
return;
|
||||
i_fixed_eh = [this](void* ctx, user_propagator::callback* cb, unsigned id, expr* value) {
|
||||
i_cb.t = this;
|
||||
i_cb.cb = cb;
|
||||
m_fixed_eh(ctx, &i_cb, m_internal2var[id], value);
|
||||
};
|
||||
m_ctx->user_propagate_register_fixed(i_fixed_eh);
|
||||
}
|
||||
|
||||
void init_i_final_eh() {
|
||||
if (!m_final_eh)
|
||||
return;
|
||||
i_final_eh = [this](void* ctx, user_propagator::callback* cb) {
|
||||
i_cb.t = this;
|
||||
i_cb.cb = cb;
|
||||
m_final_eh(ctx, &i_cb);
|
||||
};
|
||||
m_ctx->user_propagate_register_final(i_final_eh);
|
||||
}
|
||||
|
||||
void init_i_eq_eh() {
|
||||
if (!m_eq_eh)
|
||||
return;
|
||||
i_eq_eh = [this](void* ctx, user_propagator::callback* cb, unsigned u, unsigned v) {
|
||||
i_cb.t = this;
|
||||
i_cb.cb = cb;
|
||||
m_eq_eh(ctx, &i_cb, m_internal2var[u], m_internal2var[v]);
|
||||
};
|
||||
m_ctx->user_propagate_register_eq(i_eq_eh);
|
||||
}
|
||||
|
||||
void init_i_diseq_eh() {
|
||||
if (!m_diseq_eh)
|
||||
return;
|
||||
i_diseq_eh = [this](void* ctx, user_propagator::callback* cb, unsigned u, unsigned v) {
|
||||
i_cb.t = this;
|
||||
i_cb.cb = cb;
|
||||
m_diseq_eh(ctx, &i_cb, m_internal2var[u], m_internal2var[v]);
|
||||
};
|
||||
m_ctx->user_propagate_register_diseq(i_diseq_eh);
|
||||
}
|
||||
|
||||
|
||||
void user_propagate_delay_init() {
|
||||
if (!m_user_ctx)
|
||||
return;
|
||||
m_ctx->user_propagate_init(m_user_ctx, m_push_eh, m_pop_eh, m_fresh_eh);
|
||||
init_i_fixed_eh();
|
||||
init_i_final_eh();
|
||||
init_i_eq_eh();
|
||||
init_i_diseq_eh();
|
||||
|
||||
unsigned i = 0;
|
||||
for (expr* v : m_vars) {
|
||||
unsigned j = m_ctx->user_propagate_register(v);
|
||||
m_var2internal.setx(i, j, 0);
|
||||
m_internal2var.setx(j, i, 0);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void user_propagate_clear() override {
|
||||
m_user_ctx = nullptr;
|
||||
m_vars.reset();
|
||||
m_fixed_eh = nullptr;
|
||||
m_final_eh = nullptr;
|
||||
m_eq_eh = nullptr;
|
||||
m_diseq_eh = nullptr;
|
||||
}
|
||||
|
||||
void user_propagate_init(
|
||||
void* ctx,
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh) override {
|
||||
user_propagate_clear();
|
||||
m_user_ctx = ctx;
|
||||
m_push_eh = push_eh;
|
||||
m_pop_eh = pop_eh;
|
||||
m_fresh_eh = fresh_eh;
|
||||
}
|
||||
|
||||
void user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh) override {
|
||||
m_fixed_eh = fixed_eh;
|
||||
}
|
||||
|
||||
void user_propagate_register_final(user_propagator::final_eh_t& final_eh) override {
|
||||
m_final_eh = final_eh;
|
||||
}
|
||||
|
||||
void user_propagate_register_eq(user_propagator::eq_eh_t& eq_eh) override {
|
||||
m_eq_eh = eq_eh;
|
||||
}
|
||||
|
||||
void user_propagate_register_diseq(user_propagator::eq_eh_t& diseq_eh) override {
|
||||
m_diseq_eh = diseq_eh;
|
||||
}
|
||||
|
||||
unsigned user_propagate_register(expr* e) override {
|
||||
m_vars.push_back(e);
|
||||
return m_vars.size() - 1;
|
||||
}
|
||||
};
|
||||
|
||||
static tactic * mk_seq_smt_tactic(params_ref const & p) {
|
||||
return alloc(smt_tactic, p);
|
||||
static tactic * mk_seq_smt_tactic(ast_manager& m, params_ref const & p) {
|
||||
return alloc(smt_tactic, m, p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -319,13 +476,13 @@ tactic * mk_parallel_smt_tactic(ast_manager& m, params_ref const& p) {
|
|||
|
||||
tactic * mk_smt_tactic_core(ast_manager& m, params_ref const& p, symbol const& logic) {
|
||||
parallel_params pp(p);
|
||||
return pp.enable() ? mk_parallel_tactic(mk_smt_solver(m, p, logic), p) : mk_seq_smt_tactic(p);
|
||||
return pp.enable() ? mk_parallel_tactic(mk_smt_solver(m, p, logic), p) : mk_seq_smt_tactic(m, p);
|
||||
}
|
||||
|
||||
tactic * mk_smt_tactic_core_using(ast_manager& m, bool auto_config, params_ref const& _p) {
|
||||
parallel_params pp(_p);
|
||||
params_ref p = _p;
|
||||
p.set_bool("auto_config", auto_config);
|
||||
return using_params(pp.enable() ? mk_parallel_smt_tactic(m, p) : mk_seq_smt_tactic(p), p);
|
||||
return using_params(pp.enable() ? mk_parallel_smt_tactic(m, p) : mk_seq_smt_tactic(m, p), p);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ struct unit_subsumption_tactic : public tactic {
|
|||
m_clauses(m) {
|
||||
}
|
||||
|
||||
char const* name() const override { return "unit_subsumption"; }
|
||||
|
||||
void cleanup() override {}
|
||||
|
||||
void operator()(/* in */ goal_ref const & in,
|
||||
|
|
|
@ -1529,7 +1529,7 @@ public:
|
|||
IF_VERBOSE(12, verbose_stream() << "final-check " << lp().get_status() << "\n");
|
||||
lbool is_sat = l_true;
|
||||
SASSERT(lp().ax_is_correct());
|
||||
if (lp().get_status() != lp::lp_status::OPTIMAL || lp().has_changed_columns()) {
|
||||
if (!lp().is_feasible() || lp().has_changed_columns()) {
|
||||
is_sat = make_feasible();
|
||||
}
|
||||
final_check_status st = FC_DONE;
|
||||
|
@ -2084,7 +2084,7 @@ public:
|
|||
while (m_asserted_qhead < m_asserted_atoms.size() && !ctx().inconsistent() && m.inc()) {
|
||||
auto [bv, is_true] = m_asserted_atoms[m_asserted_qhead];
|
||||
|
||||
m_bv_to_propagate.push_back(bv);
|
||||
// m_bv_to_propagate.push_back(bv);
|
||||
|
||||
api_bound* b = nullptr;
|
||||
TRACE("arith", tout << "propagate: " << literal(bv, !is_true) << "\n";
|
||||
|
@ -3083,21 +3083,14 @@ public:
|
|||
TRACE("pcs", tout << lp().constraints(););
|
||||
auto status = lp().find_feasible_solution();
|
||||
TRACE("arith_verbose", display(tout););
|
||||
switch (status) {
|
||||
case lp::lp_status::INFEASIBLE:
|
||||
return l_false;
|
||||
case lp::lp_status::FEASIBLE:
|
||||
case lp::lp_status::OPTIMAL:
|
||||
// SASSERT(lp().all_constraints_hold());
|
||||
if (lp().is_feasible())
|
||||
return l_true;
|
||||
case lp::lp_status::TIME_EXHAUSTED:
|
||||
|
||||
default:
|
||||
TRACE("arith", tout << "status treated as inconclusive: " << status << "\n";);
|
||||
if (status == lp::lp_status::INFEASIBLE)
|
||||
return l_false;
|
||||
TRACE("arith", tout << "status treated as inconclusive: " << status << "\n";);
|
||||
// TENTATIVE_UNBOUNDED, UNBOUNDED, TENTATIVE_DUAL_UNBOUNDED, DUAL_UNBOUNDED,
|
||||
// FLOATING_POINT_ERROR, TIME_EXAUSTED, ITERATIONS_EXHAUSTED, EMPTY, UNSTABLE
|
||||
return l_undef;
|
||||
}
|
||||
// FLOATING_POINT_ERROR, TIME_EXAUSTED, EMPTY, UNSTABLE
|
||||
return l_undef;
|
||||
}
|
||||
|
||||
lp::explanation m_explanation;
|
||||
|
@ -3467,7 +3460,7 @@ public:
|
|||
st = lp::lp_status::UNBOUNDED;
|
||||
}
|
||||
else {
|
||||
if (lp().get_status() != lp::lp_status::OPTIMAL || lp().has_changed_columns())
|
||||
if (!lp().is_feasible() || lp().has_changed_columns())
|
||||
make_feasible();
|
||||
|
||||
vi = get_lpvar(v);
|
||||
|
@ -3477,7 +3470,10 @@ public:
|
|||
st = lp::lp_status::FEASIBLE;
|
||||
lp().restore_x();
|
||||
}
|
||||
|
||||
if (m_nla && (st == lp::lp_status::OPTIMAL || st == lp::lp_status::UNBOUNDED)) {
|
||||
st = lp::lp_status::FEASIBLE;
|
||||
lp().restore_x();
|
||||
}
|
||||
}
|
||||
switch (st) {
|
||||
case lp::lp_status::OPTIMAL: {
|
||||
|
|
|
@ -2206,8 +2206,9 @@ expr_ref theory_seq::elim_skolem(expr* e) {
|
|||
if (m_sk.is_post(a, x, y) && cache.contains(x) && cache.contains(y)) {
|
||||
x = cache[x];
|
||||
y = cache[y];
|
||||
auto mk_max = [&](expr* x, expr* y) { return m.mk_ite(m_autil.mk_ge(x, y), x, y); };
|
||||
result = m_util.str.mk_length(x);
|
||||
result = m_util.str.mk_substr(x, y, m_autil.mk_sub(result, y));
|
||||
result = m_util.str.mk_substr(x, mk_max(y,m_autil.mk_int(0)), m_autil.mk_sub(result, y));
|
||||
trail.push_back(result);
|
||||
cache.insert(a, result);
|
||||
todo.pop_back();
|
||||
|
@ -2277,16 +2278,14 @@ expr_ref theory_seq::elim_skolem(expr* e) {
|
|||
|
||||
args.reset();
|
||||
for (expr* arg : *to_app(a)) {
|
||||
if (cache.find(arg, b)) {
|
||||
if (cache.find(arg, b))
|
||||
args.push_back(b);
|
||||
}
|
||||
else {
|
||||
else
|
||||
todo.push_back(arg);
|
||||
}
|
||||
}
|
||||
if (args.size() < to_app(a)->get_num_args()) {
|
||||
|
||||
if (args.size() < to_app(a)->get_num_args())
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_util.is_skolem(a)) {
|
||||
IF_VERBOSE(0, verbose_stream() << "unhandled skolem " << mk_pp(a, m) << "\n");
|
||||
|
@ -2367,11 +2366,12 @@ void theory_seq::validate_fmls(enode_pair_vector const& eqs, literal_vector cons
|
|||
if (r == l_true) {
|
||||
model_ref mdl;
|
||||
k.get_model(mdl);
|
||||
TRACE("seq", tout << "failed to validate\n" << *mdl << "\n");
|
||||
IF_VERBOSE(0,
|
||||
verbose_stream() << r << "\n" << fmls << "\n";
|
||||
verbose_stream() << *mdl.get() << "\n";
|
||||
k.display(verbose_stream()));
|
||||
UNREACHABLE();
|
||||
k.display(verbose_stream()) << "\n");
|
||||
//UNREACHABLE();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ Copyright (c) 2020 Microsoft Corporation
|
|||
|
||||
Module Name:
|
||||
|
||||
user_propagator.cpp
|
||||
theory_user_propagator.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
|
@ -17,20 +17,20 @@ Author:
|
|||
|
||||
|
||||
#include "ast/ast_pp.h"
|
||||
#include "smt/user_propagator.h"
|
||||
#include "smt/theory_user_propagator.h"
|
||||
#include "smt/smt_context.h"
|
||||
|
||||
using namespace smt;
|
||||
|
||||
user_propagator::user_propagator(context& ctx):
|
||||
theory_user_propagator::theory_user_propagator(context& ctx):
|
||||
theory(ctx, ctx.get_manager().mk_family_id("user_propagator"))
|
||||
{}
|
||||
|
||||
user_propagator::~user_propagator() {
|
||||
theory_user_propagator::~theory_user_propagator() {
|
||||
dealloc(m_api_context);
|
||||
}
|
||||
|
||||
void user_propagator::force_push() {
|
||||
void theory_user_propagator::force_push() {
|
||||
for (; m_num_scopes > 0; --m_num_scopes) {
|
||||
theory::push_scope_eh();
|
||||
m_push_eh(m_user_context);
|
||||
|
@ -38,7 +38,7 @@ void user_propagator::force_push() {
|
|||
}
|
||||
}
|
||||
|
||||
unsigned user_propagator::add_expr(expr* e) {
|
||||
unsigned theory_user_propagator::add_expr(expr* e) {
|
||||
force_push();
|
||||
enode* n = ensure_enode(e);
|
||||
if (is_attached_to_var(n))
|
||||
|
@ -48,17 +48,23 @@ unsigned user_propagator::add_expr(expr* e) {
|
|||
return v;
|
||||
}
|
||||
|
||||
void user_propagator::propagate_cb(
|
||||
void theory_user_propagator::propagate_cb(
|
||||
unsigned num_fixed, unsigned const* fixed_ids,
|
||||
unsigned num_eqs, unsigned const* eq_lhs, unsigned const* eq_rhs,
|
||||
expr* conseq) {
|
||||
if (ctx.lit_internalized(conseq) && ctx.get_assignment(ctx.get_literal(conseq)) == l_true)
|
||||
CTRACE("user_propagate", ctx.lit_internalized(conseq) && ctx.get_assignment(ctx.get_literal(conseq)) == l_true,
|
||||
ctx.display(tout << "redundant consequence: " << mk_pp(conseq, m) << "\n"));
|
||||
if (ctx.lit_internalized(conseq) && ctx.get_assignment(ctx.get_literal(conseq)) == l_true)
|
||||
return;
|
||||
m_prop.push_back(prop_info(num_fixed, fixed_ids, num_eqs, eq_lhs, eq_rhs, expr_ref(conseq, m)));
|
||||
}
|
||||
|
||||
theory * user_propagator::mk_fresh(context * new_ctx) {
|
||||
auto* th = alloc(user_propagator, *new_ctx);
|
||||
unsigned theory_user_propagator::register_cb(expr* e) {
|
||||
return add_expr(e);
|
||||
}
|
||||
|
||||
theory * theory_user_propagator::mk_fresh(context * new_ctx) {
|
||||
auto* th = alloc(theory_user_propagator, *new_ctx);
|
||||
void* ctx = m_fresh_eh(m_user_context, new_ctx->get_manager(), th->m_api_context);
|
||||
th->add(ctx, m_push_eh, m_pop_eh, m_fresh_eh);
|
||||
if ((bool)m_fixed_eh) th->register_fixed(m_fixed_eh);
|
||||
|
@ -68,7 +74,7 @@ theory * user_propagator::mk_fresh(context * new_ctx) {
|
|||
return th;
|
||||
}
|
||||
|
||||
final_check_status user_propagator::final_check_eh() {
|
||||
final_check_status theory_user_propagator::final_check_eh() {
|
||||
if (!(bool)m_final_eh)
|
||||
return FC_DONE;
|
||||
force_push();
|
||||
|
@ -79,7 +85,7 @@ final_check_status user_propagator::final_check_eh() {
|
|||
return done ? FC_DONE : FC_CONTINUE;
|
||||
}
|
||||
|
||||
void user_propagator::new_fixed_eh(theory_var v, expr* value, unsigned num_lits, literal const* jlits) {
|
||||
void theory_user_propagator::new_fixed_eh(theory_var v, expr* value, unsigned num_lits, literal const* jlits) {
|
||||
if (!m_fixed_eh)
|
||||
return;
|
||||
force_push();
|
||||
|
@ -91,11 +97,11 @@ void user_propagator::new_fixed_eh(theory_var v, expr* value, unsigned num_lits,
|
|||
m_fixed_eh(m_user_context, this, v, value);
|
||||
}
|
||||
|
||||
void user_propagator::push_scope_eh() {
|
||||
void theory_user_propagator::push_scope_eh() {
|
||||
++m_num_scopes;
|
||||
}
|
||||
|
||||
void user_propagator::pop_scope_eh(unsigned num_scopes) {
|
||||
void theory_user_propagator::pop_scope_eh(unsigned num_scopes) {
|
||||
unsigned n = std::min(num_scopes, m_num_scopes);
|
||||
m_num_scopes -= n;
|
||||
num_scopes -= n;
|
||||
|
@ -108,11 +114,12 @@ void user_propagator::pop_scope_eh(unsigned num_scopes) {
|
|||
m_prop_lim.shrink(old_sz);
|
||||
}
|
||||
|
||||
bool user_propagator::can_propagate() {
|
||||
bool theory_user_propagator::can_propagate() {
|
||||
return m_qhead < m_prop.size();
|
||||
}
|
||||
|
||||
void user_propagator::propagate() {
|
||||
void theory_user_propagator::propagate() {
|
||||
TRACE("user_propagate", tout << "propagating queue head: " << m_qhead << " prop queue: " << m_prop.size() << "\n");
|
||||
if (m_qhead == m_prop.size())
|
||||
return;
|
||||
force_push();
|
||||
|
@ -127,9 +134,10 @@ void user_propagator::propagate() {
|
|||
for (auto const& p : prop.m_eqs)
|
||||
m_eqs.push_back(enode_pair(get_enode(p.first), get_enode(p.second)));
|
||||
DEBUG_CODE(for (auto const& p : m_eqs) VERIFY(p.first->get_root() == p.second->get_root()););
|
||||
DEBUG_CODE(for (unsigned id : prop.m_ids) VERIFY(m_fixed.contains(id)););
|
||||
DEBUG_CODE(for (literal lit : m_lits) VERIFY(ctx.get_assignment(lit) == l_true););
|
||||
DEBUG_CODE(for (unsigned id : prop.m_ids) VERIFY(m_fixed.contains(id)););
|
||||
DEBUG_CODE(for (literal lit : m_lits) VERIFY(ctx.get_assignment(lit) == l_true););
|
||||
|
||||
TRACE("user_propagate", tout << "propagating #" << prop.m_conseq->get_id() << ": " << prop.m_conseq << "\n");
|
||||
|
||||
if (m.is_false(prop.m_conseq)) {
|
||||
js = ctx.mk_justification(
|
||||
|
@ -138,11 +146,25 @@ void user_propagator::propagate() {
|
|||
ctx.set_conflict(js);
|
||||
}
|
||||
else {
|
||||
literal lit = mk_literal(prop.m_conseq);
|
||||
js = ctx.mk_justification(
|
||||
ext_theory_propagation_justification(
|
||||
get_id(), ctx.get_region(), m_lits.size(), m_lits.data(), m_eqs.size(), m_eqs.data(), lit));
|
||||
ctx.assign(lit, js);
|
||||
for (auto& lit : m_lits)
|
||||
lit.neg();
|
||||
for (auto const& [a,b] : m_eqs)
|
||||
m_lits.push_back(~mk_eq(a->get_expr(), b->get_expr(), false));
|
||||
|
||||
literal lit;
|
||||
if (has_quantifiers(prop.m_conseq)) {
|
||||
expr_ref fn(m.mk_fresh_const("aux-literal", m.mk_bool_sort()), m);
|
||||
expr_ref eq(m.mk_eq(fn, prop.m_conseq), m);
|
||||
ctx.assert_expr(eq);
|
||||
ctx.internalize_assertions();
|
||||
lit = mk_literal(fn);
|
||||
}
|
||||
else
|
||||
lit = mk_literal(prop.m_conseq);
|
||||
ctx.mark_as_relevant(lit);
|
||||
m_lits.push_back(lit);
|
||||
ctx.mk_th_lemma(get_id(), m_lits);
|
||||
TRACE("user_propagate", ctx.display(tout););
|
||||
}
|
||||
++m_stats.m_num_propagations;
|
||||
++qhead;
|
||||
|
@ -151,7 +173,7 @@ void user_propagator::propagate() {
|
|||
m_qhead = qhead;
|
||||
}
|
||||
|
||||
void user_propagator::collect_statistics(::statistics & st) const {
|
||||
void theory_user_propagator::collect_statistics(::statistics & st) const {
|
||||
st.update("user-propagations", m_stats.m_num_propagations);
|
||||
st.update("user-watched", get_num_vars());
|
||||
}
|
|
@ -27,7 +27,7 @@ Notes:
|
|||
#include "solver/solver.h"
|
||||
|
||||
namespace smt {
|
||||
class user_propagator : public theory, public solver::propagate_callback {
|
||||
class theory_user_propagator : public theory, public user_propagator::callback {
|
||||
|
||||
struct prop_info {
|
||||
unsigned_vector m_ids;
|
||||
|
@ -49,14 +49,14 @@ namespace smt {
|
|||
};
|
||||
|
||||
void* m_user_context = nullptr;
|
||||
solver::push_eh_t m_push_eh;
|
||||
solver::pop_eh_t m_pop_eh;
|
||||
solver::fresh_eh_t m_fresh_eh;
|
||||
solver::final_eh_t m_final_eh;
|
||||
solver::fixed_eh_t m_fixed_eh;
|
||||
solver::eq_eh_t m_eq_eh;
|
||||
solver::eq_eh_t m_diseq_eh;
|
||||
solver::context_obj* m_api_context = nullptr;
|
||||
user_propagator::push_eh_t m_push_eh;
|
||||
user_propagator::pop_eh_t m_pop_eh;
|
||||
user_propagator::fresh_eh_t m_fresh_eh;
|
||||
user_propagator::final_eh_t m_final_eh;
|
||||
user_propagator::fixed_eh_t m_fixed_eh;
|
||||
user_propagator::eq_eh_t m_eq_eh;
|
||||
user_propagator::eq_eh_t m_diseq_eh;
|
||||
user_propagator::context_obj* m_api_context = nullptr;
|
||||
unsigned m_qhead = 0;
|
||||
uint_set m_fixed;
|
||||
vector<prop_info> m_prop;
|
||||
|
@ -70,18 +70,18 @@ namespace smt {
|
|||
void force_push();
|
||||
|
||||
public:
|
||||
user_propagator(context& ctx);
|
||||
theory_user_propagator(context& ctx);
|
||||
|
||||
~user_propagator() override;
|
||||
~theory_user_propagator() override;
|
||||
|
||||
/*
|
||||
* \brief initial setup for user propagator.
|
||||
*/
|
||||
void add(
|
||||
void* ctx,
|
||||
solver::push_eh_t& push_eh,
|
||||
solver::pop_eh_t& pop_eh,
|
||||
solver::fresh_eh_t& fresh_eh) {
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh) {
|
||||
m_user_context = ctx;
|
||||
m_push_eh = push_eh;
|
||||
m_pop_eh = pop_eh;
|
||||
|
@ -90,14 +90,15 @@ namespace smt {
|
|||
|
||||
unsigned add_expr(expr* e);
|
||||
|
||||
void register_final(solver::final_eh_t& final_eh) { m_final_eh = final_eh; }
|
||||
void register_fixed(solver::fixed_eh_t& fixed_eh) { m_fixed_eh = fixed_eh; }
|
||||
void register_eq(solver::eq_eh_t& eq_eh) { m_eq_eh = eq_eh; }
|
||||
void register_diseq(solver::eq_eh_t& diseq_eh) { m_diseq_eh = diseq_eh; }
|
||||
void register_final(user_propagator::final_eh_t& final_eh) { m_final_eh = final_eh; }
|
||||
void register_fixed(user_propagator::fixed_eh_t& fixed_eh) { m_fixed_eh = fixed_eh; }
|
||||
void register_eq(user_propagator::eq_eh_t& eq_eh) { m_eq_eh = eq_eh; }
|
||||
void register_diseq(user_propagator::eq_eh_t& diseq_eh) { m_diseq_eh = diseq_eh; }
|
||||
|
||||
bool has_fixed() const { return (bool)m_fixed_eh; }
|
||||
|
||||
void propagate_cb(unsigned num_fixed, unsigned const* fixed_ids, unsigned num_eqs, unsigned const* lhs, unsigned const* rhs, expr* conseq) override;
|
||||
unsigned register_cb(expr* e) override;
|
||||
|
||||
void new_fixed_eh(theory_var v, expr* value, unsigned num_lits, literal const* jlits);
|
||||
|
|
@ -757,6 +757,8 @@ public:
|
|||
init();
|
||||
}
|
||||
|
||||
char const* name() const override { return "parallel_tactic"; }
|
||||
|
||||
void operator()(const goal_ref & g,goal_ref_buffer & result) override {
|
||||
cleanup();
|
||||
fail_if_proof_generation("parallel-tactic", g);
|
||||
|
|
|
@ -18,6 +18,7 @@ Notes:
|
|||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "tactic/user_propagator_base.h"
|
||||
#include "solver/check_sat_result.h"
|
||||
#include "solver/progress_callback.h"
|
||||
#include "util/params.h"
|
||||
|
@ -47,7 +48,7 @@ solver* mk_smt2_solver(ast_manager& m, params_ref const& p);
|
|||
- statistics
|
||||
- results based on check_sat_result API
|
||||
*/
|
||||
class solver : public check_sat_result {
|
||||
class solver : public check_sat_result, public user_propagator::core {
|
||||
params_ref m_params;
|
||||
symbol m_cancel_backup_file;
|
||||
public:
|
||||
|
@ -239,52 +240,6 @@ public:
|
|||
virtual expr_ref_vector cube(expr_ref_vector& vars, unsigned backtrack_level) = 0;
|
||||
|
||||
|
||||
class propagate_callback {
|
||||
public:
|
||||
virtual ~propagate_callback() = default;
|
||||
virtual void propagate_cb(unsigned num_fixed, unsigned const* fixed_ids, unsigned num_eqs, unsigned const* eq_lhs, unsigned const* eq_rhs, expr* conseq) = 0;
|
||||
};
|
||||
class context_obj {
|
||||
public:
|
||||
virtual ~context_obj() {}
|
||||
};
|
||||
typedef std::function<void(void*, solver::propagate_callback*)> final_eh_t;
|
||||
typedef std::function<void(void*, solver::propagate_callback*, unsigned, expr*)> fixed_eh_t;
|
||||
typedef std::function<void(void*, solver::propagate_callback*, unsigned, unsigned)> eq_eh_t;
|
||||
typedef std::function<void*(void*, ast_manager&, solver::context_obj*&)> fresh_eh_t;
|
||||
typedef std::function<void(void*)> push_eh_t;
|
||||
typedef std::function<void(void*,unsigned)> pop_eh_t;
|
||||
|
||||
virtual void user_propagate_init(
|
||||
void* ctx,
|
||||
push_eh_t& push_eh,
|
||||
pop_eh_t& pop_eh,
|
||||
fresh_eh_t& fresh_eh) {
|
||||
throw default_exception("user-propagators are only supported on the SMT solver");
|
||||
}
|
||||
|
||||
|
||||
virtual void user_propagate_register_fixed(fixed_eh_t& fixed_eh) {
|
||||
throw default_exception("user-propagators are only supported on the SMT solver");
|
||||
}
|
||||
|
||||
virtual void user_propagate_register_final(final_eh_t& final_eh) {
|
||||
throw default_exception("user-propagators are only supported on the SMT solver");
|
||||
}
|
||||
|
||||
virtual void user_propagate_register_eq(eq_eh_t& eq_eh) {
|
||||
throw default_exception("user-propagators are only supported on the SMT solver");
|
||||
}
|
||||
|
||||
virtual void user_propagate_register_diseq(eq_eh_t& diseq_eh) {
|
||||
throw default_exception("user-propagators are only supported on the SMT solver");
|
||||
}
|
||||
|
||||
virtual unsigned user_propagate_register(expr* e) {
|
||||
throw default_exception("user-propagators are only supported on the SMT solver");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Display the content of this solver.
|
||||
*/
|
||||
|
|
|
@ -186,6 +186,8 @@ public:
|
|||
tactic * translate(ast_manager & m) override {
|
||||
return alloc(solver2tactic, m_solver->translate(m, m_params));
|
||||
}
|
||||
|
||||
char const* name() const override { return "solver2tactic"; }
|
||||
};
|
||||
|
||||
tactic* mk_solver2tactic(solver* s) { return alloc(solver2tactic, s); }
|
||||
|
|
|
@ -84,6 +84,39 @@ public:
|
|||
void set_phase(phase* p) override { }
|
||||
void move_to_front(expr* e) override { }
|
||||
|
||||
void user_propagate_init(
|
||||
void* ctx,
|
||||
user_propagator::push_eh_t& push_eh,
|
||||
user_propagator::pop_eh_t& pop_eh,
|
||||
user_propagator::fresh_eh_t& fresh_eh) override {
|
||||
m_tactic->user_propagate_init(ctx, push_eh, pop_eh, fresh_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_fixed(user_propagator::fixed_eh_t& fixed_eh) override {
|
||||
m_tactic->user_propagate_register_fixed(fixed_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_final(user_propagator::final_eh_t& final_eh) override {
|
||||
m_tactic->user_propagate_register_final(final_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_eq(user_propagator::eq_eh_t& eq_eh) override {
|
||||
m_tactic->user_propagate_register_eq(eq_eh);
|
||||
}
|
||||
|
||||
void user_propagate_register_diseq(user_propagator::eq_eh_t& diseq_eh) override {
|
||||
m_tactic->user_propagate_register_diseq(diseq_eh);
|
||||
}
|
||||
|
||||
unsigned user_propagate_register(expr* e) override {
|
||||
return m_tactic->user_propagate_register(e);
|
||||
}
|
||||
|
||||
void user_propagate_clear() override {
|
||||
if (m_tactic)
|
||||
m_tactic->user_propagate_clear();
|
||||
}
|
||||
|
||||
|
||||
expr_ref_vector cube(expr_ref_vector& vars, unsigned ) override {
|
||||
set_reason_unknown("cubing is not supported on tactics");
|
||||
|
@ -120,6 +153,7 @@ tactic2solver::tactic2solver(ast_manager & m, tactic * t, params_ref const & p,
|
|||
}
|
||||
|
||||
tactic2solver::~tactic2solver() {
|
||||
user_propagate_clear();
|
||||
}
|
||||
|
||||
void tactic2solver::updt_params(params_ref const & p) {
|
||||
|
|
|
@ -45,6 +45,8 @@ public:
|
|||
aig_tactic(params_ref const & p = params_ref()):m_aig_manager(nullptr) {
|
||||
updt_params(p);
|
||||
}
|
||||
|
||||
char const* name() const override { return "aig"; }
|
||||
|
||||
tactic * translate(ast_manager & m) override {
|
||||
aig_tactic * t = alloc(aig_tactic);
|
||||
|
|
|
@ -145,6 +145,8 @@ public:
|
|||
~add_bounds_tactic() override {
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "add_bounds"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
|
|
|
@ -27,6 +27,8 @@ struct arith_bounds_tactic : public tactic {
|
|||
/* out */ goal_ref_buffer & result) override {
|
||||
bounds_arith_subsumption(in, result);
|
||||
}
|
||||
|
||||
char const* name() const override { return "arith_bounds"; }
|
||||
|
||||
tactic* translate(ast_manager & mgr) override {
|
||||
return alloc(arith_bounds_tactic, mgr);
|
||||
|
|
|
@ -42,6 +42,8 @@ public:
|
|||
~card2bv_tactic() override {
|
||||
}
|
||||
|
||||
char const* name() const override { return "card2bv"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
}
|
||||
|
|
|
@ -284,6 +284,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "degree_shift"; }
|
||||
|
||||
void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result) override {
|
||||
(*m_imp)(in, result);
|
||||
|
|
|
@ -357,6 +357,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "diff_neq"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
|
|
|
@ -268,6 +268,8 @@ public:
|
|||
tactic * translate(ast_manager & m) override {
|
||||
return alloc(eq2bv_tactic, m);
|
||||
}
|
||||
|
||||
char const* name() const override { return "eq2bv"; }
|
||||
|
||||
void collect_param_descrs(param_descrs & r) override {
|
||||
}
|
||||
|
|
|
@ -294,6 +294,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "factor"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->m_rw.cfg().updt_params(p);
|
||||
|
|
|
@ -300,6 +300,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "fix_dl_var"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
|
|
|
@ -1642,6 +1642,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "fm"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
|
|
|
@ -132,6 +132,8 @@ public:
|
|||
dealloc(m_todo);
|
||||
}
|
||||
|
||||
char const* name() const override { return "lia2card"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_compile_equality = p.get_bool("compile_equality", true);
|
||||
|
|
|
@ -305,6 +305,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "lia2pb"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
|
|
|
@ -438,6 +438,8 @@ public:
|
|||
~nla2bv_tactic() override {
|
||||
}
|
||||
|
||||
char const* name() const override { return "nla2bv"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params.append(p);
|
||||
}
|
||||
|
|
|
@ -153,6 +153,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "normalize_bounds"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_imp->updt_params(p);
|
||||
}
|
||||
|
|
|
@ -1007,6 +1007,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "pb2bv"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
|
|
|
@ -49,6 +49,8 @@ public:
|
|||
|
||||
~propagate_ineqs_tactic() override;
|
||||
|
||||
char const* name() const override { return "propagate_ineqs"; }
|
||||
|
||||
void updt_params(params_ref const & p) override;
|
||||
void collect_param_descrs(param_descrs & r) override {}
|
||||
|
||||
|
|
|
@ -903,6 +903,8 @@ public:
|
|||
~purify_arith_tactic() override {
|
||||
}
|
||||
|
||||
char const* name() const override { return "purify_arith"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
}
|
||||
|
|
|
@ -398,6 +398,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "recover_01"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
|
|
|
@ -119,6 +119,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "bit_blaster"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
|
|
|
@ -431,6 +431,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "bv1_blaster"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->m_rw.cfg().updt_params(p);
|
||||
|
|
|
@ -140,6 +140,7 @@ public:
|
|||
void cleanup() override;
|
||||
void collect_statistics(statistics & st) const override;
|
||||
void reset_statistics() override;
|
||||
char const* name() const override { return "bv_bound_chk"; }
|
||||
};
|
||||
|
||||
class bv_bound_chk_tactic::imp {
|
||||
|
|
|
@ -54,6 +54,8 @@ public:
|
|||
return alloc(bv_size_reduction_tactic, m);
|
||||
}
|
||||
|
||||
char const* name() const override { return "bv_size"; }
|
||||
|
||||
void operator()(goal_ref const & g, goal_ref_buffer & result) override;
|
||||
|
||||
void cleanup() override {
|
||||
|
|
|
@ -113,6 +113,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "bvarray2uf"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
|
|
|
@ -104,6 +104,8 @@ public:
|
|||
|
||||
dt2bv_tactic(ast_manager& m, params_ref const& p):
|
||||
m(m), m_params(p), m_dt(m), m_bv(m), m_is_fd(*this) {}
|
||||
|
||||
char const* name() const override { return "dt2bv"; }
|
||||
|
||||
tactic * translate(ast_manager & m) override {
|
||||
return alloc(dt2bv_tactic, m, m_params);
|
||||
|
|
|
@ -234,6 +234,8 @@ public:
|
|||
m_params(p) {
|
||||
}
|
||||
|
||||
char const* name() const override { return "elim_small_bv"; }
|
||||
|
||||
tactic * translate(ast_manager & m) override {
|
||||
return alloc(elim_small_bv_tactic, m, m_params);
|
||||
}
|
||||
|
|
|
@ -277,6 +277,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "max_bv_sharing"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->m_rw.cfg().updt_params(p);
|
||||
|
|
|
@ -171,6 +171,8 @@ public:
|
|||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
char const* name() const override { return "blast_term_ite"; }
|
||||
|
||||
void updt_params(params_ref const & p) override {
|
||||
m_params = p;
|
||||
m_imp->m_rw.m_cfg.updt_params(p);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue