3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-12-09 09:50:53 -08:00
commit dcdbbfb925
144 changed files with 1528 additions and 517 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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();
}

View file

@ -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

View file

@ -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();

View file

@ -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, &params, 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;
}

View file

@ -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) {

View file

@ -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

View file

@ -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)

View file

@ -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.

View file

@ -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:

View file

@ -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;

View file

@ -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) {

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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";

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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)) {

View file

@ -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);
}

View file

@ -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());

View file

@ -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>>();

View file

@ -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 {

View file

@ -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;
}

View file

@ -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);
);
}
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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
}

View file

@ -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

View file

@ -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

View file

@ -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();

View file

@ -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
}
}
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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();

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -1257,6 +1257,8 @@ namespace qe {
~qsat() override {
clear();
}
char const* name() const override { return "qsat"; }
void updt_params(params_ref const & p) override {
}

View file

@ -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";);

View file

@ -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";

View file

@ -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;

View file

@ -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:

View file

@ -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;

View file

@ -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; )

View file

@ -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);
}

View file

@ -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";);
}

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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));
}
};

View file

@ -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);

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
/**

View file

@ -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();

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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,

View file

@ -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: {

View file

@ -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();
}
}

View file

@ -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());
}

View file

@ -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);

View file

@ -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);

View file

@ -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.
*/

View file

@ -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); }

View file

@ -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) {

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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 {
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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 {}

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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 {

View file

@ -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 {

View file

@ -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);

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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