mirror of
https://github.com/Z3Prover/z3
synced 2025-04-10 19:27:06 +00:00
add backtrack level to cuber interface
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
0a9946578b
commit
75b8d10f48
|
@ -529,9 +529,9 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_solver_cube(Z3_context c, Z3_solver s) {
|
||||
Z3_ast Z3_API Z3_solver_cube(Z3_context c, Z3_solver s, unsigned cutoff) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_cube(c, s);
|
||||
LOG_Z3_solver_cube(c, s, cutoff);
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
expr_ref result(m);
|
||||
unsigned timeout = to_solver(s)->m_params.get_uint("timeout", mk_c(c)->get_timeout());
|
||||
|
@ -544,7 +544,7 @@ extern "C" {
|
|||
scoped_timer timer(timeout, &eh);
|
||||
scoped_rlimit _rlimit(mk_c(c)->m().limit(), rlimit);
|
||||
try {
|
||||
result = to_solver_ref(s)->cube();
|
||||
result = to_solver_ref(s)->cube(cutoff);
|
||||
}
|
||||
catch (z3_exception & ex) {
|
||||
mk_c(c)->handle_exception(ex);
|
||||
|
|
|
@ -353,6 +353,12 @@ namespace Microsoft.Z3
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Backtrack level that can be adjusted by conquer process
|
||||
/// </summary>
|
||||
public uint BacktrackLevel { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Return a set of cubes.
|
||||
/// </summary>
|
||||
|
@ -360,10 +366,8 @@ namespace Microsoft.Z3
|
|||
{
|
||||
int rounds = 0;
|
||||
while (true) {
|
||||
BoolExpr r = (BoolExpr)Expr.Create(Context, Native.Z3_solver_cube(Context.nCtx, NativeObject));
|
||||
BoolExpr r = (BoolExpr)Expr.Create(Context, Native.Z3_solver_cube(Context.nCtx, NativeObject, BacktrackLevel));
|
||||
if (r.IsFalse) {
|
||||
if (rounds == 0)
|
||||
yield return r;
|
||||
break;
|
||||
}
|
||||
if (r.IsTrue) {
|
||||
|
@ -412,6 +416,7 @@ namespace Microsoft.Z3
|
|||
: base(ctx, obj)
|
||||
{
|
||||
Contract.Requires(ctx != null);
|
||||
this.BacktrackLevel = uint.MaxValue;
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
|
|
|
@ -6283,19 +6283,16 @@ class Solver(Z3PPObject):
|
|||
consequences = [ consequences[i] for i in range(sz) ]
|
||||
return CheckSatResult(r), consequences
|
||||
|
||||
def cube(self):
|
||||
def cube(self, level_ref):
|
||||
"""Get set of cubes"""
|
||||
rounds = 0
|
||||
while True:
|
||||
r = _to_expr_ref(Z3_solver_cube(self.ctx.ref(), self.solver), self.ctx)
|
||||
backtrack_level = level_ref.backtrack_level
|
||||
r = _to_expr_ref(Z3_solver_cube(self.ctx.ref(), self.solver, backtrack_level), self.ctx)
|
||||
if (is_false(r)):
|
||||
if (rounds == 0):
|
||||
yield r
|
||||
return
|
||||
if (is_true(r)):
|
||||
yield r
|
||||
return
|
||||
rounds += 1
|
||||
yield r
|
||||
|
||||
def proof(self):
|
||||
|
|
|
@ -6232,10 +6232,13 @@ extern "C" {
|
|||
The number of (non-constant) cubes is by default 1. For the sat solver cubing is controlled
|
||||
using parameters sat.lookahead.cube.cutoff and sat.lookahead.cube.fraction.
|
||||
|
||||
def_API('Z3_solver_cube', AST, (_in(CONTEXT), _in(SOLVER)))
|
||||
The last argument is a backtracking level. It instructs the cube process to backtrack below
|
||||
the indicated level for the next cube.
|
||||
|
||||
def_API('Z3_solver_cube', AST, (_in(CONTEXT), _in(SOLVER), _in(UINT)))
|
||||
*/
|
||||
|
||||
Z3_ast Z3_API Z3_solver_cube(Z3_context c, Z3_solver s);
|
||||
Z3_ast Z3_API Z3_solver_cube(Z3_context c, Z3_solver s, unsigned backtrack_level);
|
||||
|
||||
/**
|
||||
\brief Retrieve the model for the last #Z3_solver_check or #Z3_solver_check_assumptions
|
||||
|
|
|
@ -119,7 +119,7 @@ public:
|
|||
{NOT_IMPLEMENTED_YET();}
|
||||
virtual void assert_lemma(expr* e) { NOT_IMPLEMENTED_YET(); }
|
||||
virtual expr_ref lookahead(const expr_ref_vector &,const expr_ref_vector &) { return expr_ref(m.mk_true(), m); }
|
||||
virtual expr_ref cube() { return expr_ref(m.mk_true(), m); }
|
||||
virtual expr_ref cube(unsigned) { return expr_ref(m.mk_true(), m); }
|
||||
|
||||
|
||||
virtual void push();
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
virtual void reset();
|
||||
|
||||
virtual void set_progress_callback(progress_callback *callback) {UNREACHABLE();}
|
||||
virtual expr_ref cube() { return expr_ref(m.mk_true(), m); }
|
||||
virtual expr_ref cube(unsigned) { return expr_ref(m.mk_true(), m); }
|
||||
|
||||
virtual solver *translate(ast_manager &m, params_ref const &p);
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ namespace opt {
|
|||
virtual ast_manager& get_manager() const { return m; }
|
||||
virtual lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes);
|
||||
virtual lbool preferred_sat(expr_ref_vector const& asms, vector<expr_ref_vector>& cores);
|
||||
virtual expr_ref cube() { return expr_ref(m.mk_true(), m); }
|
||||
virtual expr_ref cube(unsigned) { return expr_ref(m.mk_true(), m); }
|
||||
void set_logic(symbol const& logic);
|
||||
|
||||
smt::theory_var add_objective(app* term);
|
||||
|
|
|
@ -349,7 +349,7 @@ namespace sat {
|
|||
}
|
||||
bool nullify = p.lit() != null_literal && value(p.lit()) == l_true;
|
||||
if (nullify) {
|
||||
IF_VERBOSE(10, display(verbose_stream() << "nullify tracking literal\n", p, true););
|
||||
IF_VERBOSE(100, display(verbose_stream() << "nullify tracking literal\n", p, true););
|
||||
SASSERT(lvl(p.lit()) == 0);
|
||||
nullify_tracking_literal(p);
|
||||
init_watch(p, true);
|
||||
|
@ -374,7 +374,7 @@ namespace sat {
|
|||
if (p.k() == 1 && p.lit() == null_literal) {
|
||||
literal_vector lits(p.literals());
|
||||
s().mk_clause(lits.size(), lits.c_ptr(), p.learned());
|
||||
IF_VERBOSE(10, display(verbose_stream() << "add clause: " << lits << "\n", p, true););
|
||||
IF_VERBOSE(100, display(verbose_stream() << "add clause: " << lits << "\n", p, true););
|
||||
remove_constraint(p, "implies clause");
|
||||
}
|
||||
else if (true_val == 0 && num_false == 0) {
|
||||
|
@ -384,14 +384,14 @@ namespace sat {
|
|||
}
|
||||
else if (true_val >= p.k()) {
|
||||
if (p.lit() != null_literal) {
|
||||
IF_VERBOSE(10, display(verbose_stream() << "assign true literal ", p, true););
|
||||
IF_VERBOSE(100, display(verbose_stream() << "assign true literal ", p, true););
|
||||
s().assign(p.lit(), justification());
|
||||
}
|
||||
remove_constraint(p, "is true");
|
||||
}
|
||||
else if (slack + true_val < p.k()) {
|
||||
if (p.lit() != null_literal) {
|
||||
IF_VERBOSE(10, display(verbose_stream() << "assign false literal ", p, true););
|
||||
IF_VERBOSE(100, display(verbose_stream() << "assign false literal ", p, true););
|
||||
s().assign(~p.lit(), justification());
|
||||
}
|
||||
else {
|
||||
|
@ -2877,7 +2877,7 @@ namespace sat {
|
|||
bool ba_solver::elim_pure(literal lit) {
|
||||
if (value(lit) == l_undef && !m_cnstr_use_list[lit.index()].empty() &&
|
||||
use_count(~lit) == 0 && get_num_unblocked_bin(~lit) == 0) {
|
||||
IF_VERBOSE(10, verbose_stream() << "pure literal: " << lit << "\n";);
|
||||
IF_VERBOSE(100, verbose_stream() << "pure literal: " << lit << "\n";);
|
||||
s().assign(lit, justification());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1964,7 +1964,7 @@ namespace sat {
|
|||
bool_var_vector vars;
|
||||
for (bool_var v : m_freevars) vars.push_back(v);
|
||||
while (true) {
|
||||
lbool result = cube(vars, lits);
|
||||
lbool result = cube(vars, lits, UINT_MAX);
|
||||
if (lits.empty() || result != l_undef) {
|
||||
return l_undef;
|
||||
}
|
||||
|
@ -1973,7 +1973,7 @@ namespace sat {
|
|||
return l_undef;
|
||||
}
|
||||
|
||||
lbool lookahead::cube(bool_var_vector const& vars, literal_vector& lits) {
|
||||
lbool lookahead::cube(bool_var_vector const& vars, literal_vector& lits, unsigned backtrack_level) {
|
||||
scoped_ext _scoped_ext(*this);
|
||||
lits.reset();
|
||||
m_select_lookahead_vars.reset();
|
||||
|
@ -2006,6 +2006,14 @@ namespace sat {
|
|||
continue;
|
||||
}
|
||||
pick_up_work:
|
||||
if (m_cube_state.m_cube.size() >= backtrack_level) {
|
||||
IF_VERBOSE(10, verbose_stream() << "(sat-cube :cube: " << m_cube_state.m_cube.size() << " :backtrack_level " << backtrack_level << ")\n";);
|
||||
while (m_cube_state.m_cube.size() >= backtrack_level) {
|
||||
set_conflict();
|
||||
backtrack(m_cube_state.m_cube, m_cube_state.m_is_decision);
|
||||
}
|
||||
backtrack_level = UINT_MAX;
|
||||
}
|
||||
depth = m_cube_state.m_cube.size();
|
||||
if ((m_config.m_cube_cutoff != 0 && depth == m_config.m_cube_cutoff) ||
|
||||
(m_config.m_cube_cutoff == 0 && m_freevars.size() < m_cube_state.m_freevars_threshold)) {
|
||||
|
|
|
@ -567,7 +567,7 @@ namespace sat {
|
|||
|
||||
lbool cube();
|
||||
|
||||
lbool cube(bool_var_vector const& vars, literal_vector& lits);
|
||||
lbool cube(bool_var_vector const& vars, literal_vector& lits, unsigned backtrack_level);
|
||||
|
||||
literal select_lookahead(literal_vector const& assumptions, bool_var_vector const& vars);
|
||||
/**
|
||||
|
|
|
@ -837,11 +837,11 @@ namespace sat {
|
|||
return lh.select_lookahead(assumptions, vars);
|
||||
}
|
||||
|
||||
lbool solver::cube(bool_var_vector const& vars, literal_vector& lits) {
|
||||
lbool solver::cube(bool_var_vector const& vars, literal_vector& lits, unsigned backtrack_level) {
|
||||
if (!m_cuber) {
|
||||
m_cuber = alloc(lookahead, *this);
|
||||
}
|
||||
lbool result = m_cuber->cube(vars, lits);
|
||||
lbool result = m_cuber->cube(vars, lits, backtrack_level);
|
||||
if (result == l_false) {
|
||||
dealloc(m_cuber);
|
||||
m_cuber = nullptr;
|
||||
|
|
|
@ -352,7 +352,7 @@ namespace sat {
|
|||
bool check_clauses(model const& m) const;
|
||||
|
||||
literal select_lookahead(literal_vector const& assumptions, bool_var_vector const& vars);
|
||||
lbool cube(bool_var_vector const& vars, literal_vector& lits);
|
||||
lbool cube(bool_var_vector const& vars, literal_vector& lits, unsigned backtrack_level);
|
||||
|
||||
protected:
|
||||
unsigned m_conflicts_since_init;
|
||||
|
|
|
@ -301,7 +301,7 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
virtual expr_ref cube() {
|
||||
virtual expr_ref cube(unsigned backtrack_level) {
|
||||
if (!m_internalized) {
|
||||
dep2asm_t dep2asm;
|
||||
m_model = 0;
|
||||
|
@ -315,7 +315,7 @@ public:
|
|||
vars.push_back(kv.m_value);
|
||||
}
|
||||
sat::literal_vector lits;
|
||||
lbool result = m_solver.cube(vars, lits);
|
||||
lbool result = m_solver.cube(vars, lits, backtrack_level);
|
||||
if (result == l_false || lits.empty()) {
|
||||
return expr_ref(m.mk_false(), m);
|
||||
}
|
||||
|
|
|
@ -226,7 +226,7 @@ namespace smt {
|
|||
return expr_ref(m.mk_true(), m);
|
||||
}
|
||||
|
||||
virtual expr_ref cube() {
|
||||
virtual expr_ref cube(unsigned) {
|
||||
ast_manager& m = get_manager();
|
||||
return expr_ref(m.mk_true(), m);
|
||||
}
|
||||
|
|
|
@ -281,8 +281,8 @@ public:
|
|||
return m_solver1->get_num_assumptions() + m_solver2->get_num_assumptions();
|
||||
}
|
||||
|
||||
virtual expr_ref cube() {
|
||||
return m_solver1->cube();
|
||||
virtual expr_ref cube(unsigned backtrack_level) {
|
||||
return m_solver1->cube(backtrack_level);
|
||||
}
|
||||
|
||||
virtual expr * get_assumption(unsigned idx) const {
|
||||
|
|
|
@ -189,7 +189,7 @@ public:
|
|||
\brief extract a lookahead candidates for branching.
|
||||
*/
|
||||
|
||||
virtual expr_ref cube() = 0;
|
||||
virtual expr_ref cube(unsigned backtrack_level) = 0;
|
||||
|
||||
/**
|
||||
\brief Display the content of this solver.
|
||||
|
|
|
@ -223,7 +223,7 @@ public:
|
|||
virtual void get_labels(svector<symbol> & r) { return m_base->get_labels(r); }
|
||||
virtual void set_progress_callback(progress_callback * callback) { m_base->set_progress_callback(callback); }
|
||||
|
||||
virtual expr_ref cube() { return expr_ref(m.mk_true(), m); }
|
||||
virtual expr_ref cube(unsigned ) { return expr_ref(m.mk_true(), m); }
|
||||
|
||||
virtual ast_manager& get_manager() const { return m_base->get_manager(); }
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
|
||||
virtual ast_manager& get_manager() const;
|
||||
|
||||
virtual expr_ref cube() {
|
||||
virtual expr_ref cube(unsigned ) {
|
||||
ast_manager& m = get_manager();
|
||||
return expr_ref(m.mk_true(), m);
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ public:
|
|||
virtual void set_reason_unknown(char const* msg) { m_solver->set_reason_unknown(msg); }
|
||||
virtual void get_labels(svector<symbol> & r) { m_solver->get_labels(r); }
|
||||
virtual ast_manager& get_manager() const { return m; }
|
||||
virtual expr_ref cube() { flush_assertions(); return m_solver->cube(); }
|
||||
virtual expr_ref cube(unsigned backtrack_level) { flush_assertions(); return m_solver->cube(backtrack_level); }
|
||||
virtual lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes) { return m_solver->find_mutexes(vars, mutexes); }
|
||||
virtual lbool get_consequences_core(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) {
|
||||
flush_assertions();
|
||||
|
|
|
@ -113,7 +113,7 @@ public:
|
|||
virtual void get_labels(svector<symbol> & r) { m_solver->get_labels(r); }
|
||||
virtual ast_manager& get_manager() const { return m; }
|
||||
virtual lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes) { return m_solver->find_mutexes(vars, mutexes); }
|
||||
virtual expr_ref cube() { return m_solver->cube(); }
|
||||
virtual expr_ref cube(unsigned backtrack_level) { return m_solver->cube(backtrack_level); }
|
||||
|
||||
virtual lbool get_consequences_core(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) {
|
||||
datatype_util dt(m);
|
||||
|
|
|
@ -414,7 +414,7 @@ private:
|
|||
cubes.reset();
|
||||
s.set_cube_params();
|
||||
while (true) {
|
||||
expr_ref c = s.get_solver().cube();
|
||||
expr_ref c = s.get_solver().cube(UINT_MAX); // TBD tune this
|
||||
VERIFY(c);
|
||||
if (m.is_false(c)) {
|
||||
break;
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
virtual void set_reason_unknown(char const* msg) { m_solver->set_reason_unknown(msg); }
|
||||
virtual void get_labels(svector<symbol> & r) { m_solver->get_labels(r); }
|
||||
virtual ast_manager& get_manager() const { return m; }
|
||||
virtual expr_ref cube() { flush_assertions(); return m_solver->cube(); }
|
||||
virtual expr_ref cube(unsigned backtrack_level) { flush_assertions(); return m_solver->cube(backtrack_level); }
|
||||
virtual lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes) { return m_solver->find_mutexes(vars, mutexes); }
|
||||
virtual lbool get_consequences_core(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) {
|
||||
flush_assertions();
|
||||
|
|
Loading…
Reference in a new issue