mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 20:18:18 +00:00
expose incremental cubing over API
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
e507a6ccd1
commit
a625301a41
|
@ -2735,6 +2735,7 @@ def get_header_files_for_components(component_src_dirs):
|
||||||
def mk_install_tactic_cpp(cnames, path):
|
def mk_install_tactic_cpp(cnames, path):
|
||||||
component_src_dirs = []
|
component_src_dirs = []
|
||||||
for cname in cnames:
|
for cname in cnames:
|
||||||
|
print("Component %s" % cname)
|
||||||
c = get_component(cname)
|
c = get_component(cname)
|
||||||
component_src_dirs.append(c.src_dir)
|
component_src_dirs.append(c.src_dir)
|
||||||
h_files_full_path = get_header_files_for_components(component_src_dirs)
|
h_files_full_path = get_header_files_for_components(component_src_dirs)
|
||||||
|
|
|
@ -6294,10 +6294,33 @@ class Solver(Z3PPObject):
|
||||||
candidates = _cs
|
candidates = _cs
|
||||||
return _to_expr_ref(Z3_solver_lookahead(self.ctx.ref(), self.solver, candidates), self.ctx)
|
return _to_expr_ref(Z3_solver_lookahead(self.ctx.ref(), self.solver, candidates), self.ctx)
|
||||||
|
|
||||||
|
def cube(self):
|
||||||
|
"""Get set of cubes"""
|
||||||
|
rounds = 0
|
||||||
|
while True:
|
||||||
|
r = _to_expr_ref(Z3_solver_cube(self.ctx.ref(), self.solver), 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):
|
def proof(self):
|
||||||
"""Return a proof for the last `check()`. Proof construction must be enabled."""
|
"""Return a proof for the last `check()`. Proof construction must be enabled."""
|
||||||
return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
|
return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
|
||||||
|
|
||||||
|
def from_file(self, filename):
|
||||||
|
"""Parse assertions from a file"""
|
||||||
|
self.add([f for f in parse_smt2_file(filename)])
|
||||||
|
|
||||||
|
def from_string(self, s):
|
||||||
|
"""Parse assertions from a string"""
|
||||||
|
self.add([f for f in parse_smt2_string(s)])
|
||||||
|
|
||||||
def assertions(self):
|
def assertions(self):
|
||||||
"""Return an AST vector containing all added constraints.
|
"""Return an AST vector containing all added constraints.
|
||||||
|
|
||||||
|
|
|
@ -657,7 +657,6 @@ namespace sat {
|
||||||
}
|
}
|
||||||
// case watched::EXTERNAL:
|
// case watched::EXTERNAL:
|
||||||
}
|
}
|
||||||
// std::cout << "tsum: " << tsum << "\n";
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// std::cout << "sum: " << sum << " afactor " << afactor << " sqfactor " << sqfactor << " tsum " << tsum << "\n";
|
// std::cout << "sum: " << sum << " afactor " << afactor << " sqfactor " << sqfactor << " tsum " << tsum << "\n";
|
||||||
|
@ -2221,7 +2220,7 @@ namespace sat {
|
||||||
SASSERT(dl_no_overflow(base));
|
SASSERT(dl_no_overflow(base));
|
||||||
unsigned dl_truth = base + 2 * m_lookahead.size() * (m_config.m_dl_max_iterations + 1);
|
unsigned dl_truth = base + 2 * m_lookahead.size() * (m_config.m_dl_max_iterations + 1);
|
||||||
scoped_level _sl(*this, dl_truth);
|
scoped_level _sl(*this, dl_truth);
|
||||||
IF_VERBOSE(2, verbose_stream() << "double: " << l << "\n";);
|
IF_VERBOSE(2, verbose_stream() << "double: " << l << " depth: " << m_trail_lim.size() << "\n";);
|
||||||
init_lookahead_reward();
|
init_lookahead_reward();
|
||||||
assign(l);
|
assign(l);
|
||||||
propagate();
|
propagate();
|
||||||
|
@ -2353,63 +2352,24 @@ namespace sat {
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool lookahead::cube() {
|
lbool lookahead::cube() {
|
||||||
#if 0
|
|
||||||
literal_vector lits;
|
literal_vector lits;
|
||||||
while (true) {
|
while (true) {
|
||||||
lbool result = cube(lits);
|
lbool result = cube(lits);
|
||||||
if (lits.empty() || result != l_undef) {
|
if (lits.empty() || result != l_undef) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
display_cube(std::cout, cube);
|
display_cube(std::cout, lits);
|
||||||
}
|
|
||||||
#endif
|
|
||||||
lbool result = l_false;
|
|
||||||
init_search();
|
|
||||||
m_model.reset();
|
|
||||||
scoped_level _sl(*this, c_fixed_truth);
|
|
||||||
literal_vector cube;
|
|
||||||
svector<bool> is_decision;
|
|
||||||
m_search_mode = lookahead_mode::searching;
|
|
||||||
double freevars_threshold = 0;
|
|
||||||
while (true) {
|
|
||||||
TRACE("sat", display(tout););
|
|
||||||
inc_istamp();
|
|
||||||
checkpoint();
|
|
||||||
literal l = choose();
|
|
||||||
if (inconsistent()) {
|
|
||||||
TRACE("sat", tout << "inconsistent: " << cube << "\n";);
|
|
||||||
freevars_threshold = m_freevars.size();
|
|
||||||
if (!backtrack(cube, is_decision)) return result;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (l == null_literal) {
|
|
||||||
return l_true;
|
|
||||||
}
|
|
||||||
unsigned depth = cube.size();
|
|
||||||
if ((m_config.m_cube_cutoff != 0 && depth == m_config.m_cube_cutoff) ||
|
|
||||||
(m_config.m_cube_cutoff == 0 && m_freevars.size() < freevars_threshold)) {
|
|
||||||
display_cube(std::cout, cube);
|
|
||||||
freevars_threshold *= (1.0 - pow(m_config.m_cube_fraction, depth));
|
|
||||||
result = l_undef;
|
|
||||||
set_conflict();
|
|
||||||
if (!backtrack(cube, is_decision)) return result;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
TRACE("sat", tout << "choose: " << l << " cube: " << cube << "\n";);
|
|
||||||
++m_stats.m_decisions;
|
|
||||||
push(l, c_fixed_truth);
|
|
||||||
cube.push_back(l);
|
|
||||||
is_decision.push_back(true);
|
|
||||||
SASSERT(inconsistent() || !is_unsat());
|
|
||||||
}
|
}
|
||||||
|
return l_undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool lookahead::cube(literal_vector& lits) {
|
lbool lookahead::cube(literal_vector& lits) {
|
||||||
lits.reset();
|
lits.reset();
|
||||||
bool is_first = (m_cube_state.m_lit == null_literal);
|
bool is_first = m_cube_state.m_first;
|
||||||
if (is_first) {
|
if (is_first) {
|
||||||
init_search();
|
init_search();
|
||||||
m_model.reset();
|
m_model.reset();
|
||||||
|
m_cube_state.m_first = false;
|
||||||
}
|
}
|
||||||
scoped_level _sl(*this, c_fixed_truth);
|
scoped_level _sl(*this, c_fixed_truth);
|
||||||
m_search_mode = lookahead_mode::searching;
|
m_search_mode = lookahead_mode::searching;
|
||||||
|
@ -2421,39 +2381,43 @@ namespace sat {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
TRACE("sat", display(tout););
|
TRACE("sat", display(tout););
|
||||||
inc_istamp();
|
|
||||||
checkpoint();
|
checkpoint();
|
||||||
m_cube_state.m_lit = choose();
|
inc_istamp();
|
||||||
if (inconsistent()) {
|
if (inconsistent()) {
|
||||||
TRACE("sat", tout << "inconsistent: " << cube << "\n";);
|
TRACE("sat", tout << "inconsistent: " << m_cube_state.m_cube << "\n";);
|
||||||
m_cube_state.m_freevars_threshold = m_freevars.size();
|
m_cube_state.m_freevars_threshold = m_freevars.size();
|
||||||
if (!backtrack(m_cube_state.m_cube, m_cube_state.m_is_decision)) return m_cube_state.m_result;
|
if (!backtrack(m_cube_state.m_cube, m_cube_state.m_is_decision)) return l_false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (m_cube_state.m_lit == null_literal) {
|
pick_up_work:
|
||||||
return l_true;
|
|
||||||
}
|
|
||||||
depth = m_cube_state.m_cube.size();
|
depth = m_cube_state.m_cube.size();
|
||||||
if ((m_config.m_cube_cutoff != 0 && depth == m_config.m_cube_cutoff) ||
|
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)) {
|
(m_config.m_cube_cutoff == 0 && m_freevars.size() < m_cube_state.m_freevars_threshold)) {
|
||||||
m_cube_state.m_freevars_threshold *= (1.0 - pow(m_config.m_cube_fraction, depth));
|
m_cube_state.m_freevars_threshold *= (1.0 - pow(m_config.m_cube_fraction, depth));
|
||||||
m_cube_state.m_result = l_undef;
|
|
||||||
set_conflict();
|
set_conflict();
|
||||||
if (!backtrack(m_cube_state.m_cube, m_cube_state.m_is_decision)) return m_cube_state.m_result;
|
|
||||||
lits.append(m_cube_state.m_cube);
|
lits.append(m_cube_state.m_cube);
|
||||||
|
backtrack(m_cube_state.m_cube, m_cube_state.m_is_decision);
|
||||||
return l_undef;
|
return l_undef;
|
||||||
}
|
}
|
||||||
pick_up_work:
|
literal lit = choose();
|
||||||
TRACE("sat", tout << "choose: " << m_cube_state.m_lit << " cube: " << m_cube_state.m_cube << "\n";);
|
if (inconsistent()) {
|
||||||
|
TRACE("sat", tout << "inconsistent: " << m_cube_state.m_cube << "\n";);
|
||||||
|
m_cube_state.m_freevars_threshold = m_freevars.size();
|
||||||
|
if (!backtrack(m_cube_state.m_cube, m_cube_state.m_is_decision)) return l_false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (lit == null_literal) {
|
||||||
|
return l_true;
|
||||||
|
}
|
||||||
|
TRACE("sat", tout << "choose: " << lit << " cube: " << m_cube_state.m_cube << "\n";);
|
||||||
++m_stats.m_decisions;
|
++m_stats.m_decisions;
|
||||||
push(m_cube_state.m_lit, c_fixed_truth);
|
push(lit, c_fixed_truth);
|
||||||
m_cube_state.m_cube.push_back(m_cube_state.m_lit);
|
m_cube_state.m_cube.push_back(lit);
|
||||||
m_cube_state.m_is_decision.push_back(true);
|
m_cube_state.m_is_decision.push_back(true);
|
||||||
SASSERT(inconsistent() || !is_unsat());
|
SASSERT(inconsistent() || !is_unsat());
|
||||||
}
|
}
|
||||||
lbool result = m_cube_state.m_result;
|
|
||||||
m_cube_state.reset();
|
m_cube_state.reset();
|
||||||
return result;
|
return l_undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lookahead::init_model() {
|
void lookahead::init_model() {
|
||||||
|
|
|
@ -140,17 +140,15 @@ namespace sat {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct cube_state {
|
struct cube_state {
|
||||||
|
bool m_first;
|
||||||
svector<bool> m_is_decision;
|
svector<bool> m_is_decision;
|
||||||
literal_vector m_cube;
|
literal_vector m_cube;
|
||||||
literal m_lit;
|
|
||||||
lbool m_result;
|
|
||||||
double m_freevars_threshold;
|
double m_freevars_threshold;
|
||||||
cube_state() { reset(); }
|
cube_state() { reset(); }
|
||||||
void reset() {
|
void reset() {
|
||||||
|
m_first = true;
|
||||||
m_is_decision.reset();
|
m_is_decision.reset();
|
||||||
m_cube.reset();
|
m_cube.reset();
|
||||||
m_lit = null_literal;
|
|
||||||
m_result = l_false;
|
|
||||||
m_freevars_threshold = 0;
|
m_freevars_threshold = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,7 +40,7 @@ def_module_params('sat',
|
||||||
('lookahead.cube.cutoff', UINT, 0, 'cut-off depth to create cubes. Only enabled when non-zero. Used when lookahead_cube is true.'),
|
('lookahead.cube.cutoff', UINT, 0, 'cut-off depth to create cubes. Only enabled when non-zero. Used when lookahead_cube is true.'),
|
||||||
('lookahead_search', BOOL, False, 'use lookahead solver'),
|
('lookahead_search', BOOL, False, 'use lookahead solver'),
|
||||||
('lookahead_simplify', BOOL, False, 'use lookahead solver during simplification'),
|
('lookahead_simplify', BOOL, False, 'use lookahead solver during simplification'),
|
||||||
('lookahead.reward', SYMBOL, 'heuleu', 'select lookahead heuristic: ternary, hs (Heule Schur), heuleu (Heule Unit), or unit'),
|
('lookahead.reward', SYMBOL, 'heuleu', 'select lookahead heuristic: ternary, heule_schur (Heule Schur), heuleu (Heule Unit), or unit'),
|
||||||
('dimacs.display', BOOL, False, 'display SAT instance in DIMACS format and return unknown instead of solving'),
|
('dimacs.display', BOOL, False, 'display SAT instance in DIMACS format and return unknown instead of solving'),
|
||||||
('dimacs.inprocess.display', BOOL, False, 'display SAT instance in DIMACS format if unsolved after inprocess.max inprocessing passes')))
|
('dimacs.inprocess.display', BOOL, False, 'display SAT instance in DIMACS format if unsolved after inprocess.max inprocessing passes')))
|
||||||
|
|
||||||
|
|
|
@ -345,6 +345,14 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
virtual expr_ref cube() {
|
virtual expr_ref cube() {
|
||||||
|
if (!m_internalized) {
|
||||||
|
dep2asm_t dep2asm;
|
||||||
|
m_model = 0;
|
||||||
|
lbool r = internalize_formulas();
|
||||||
|
if (r != l_true) return expr_ref(m.mk_true(), m);
|
||||||
|
m_internalized = true;
|
||||||
|
}
|
||||||
|
convert_internalized();
|
||||||
sat::literal_vector lits;
|
sat::literal_vector lits;
|
||||||
lbool result = m_solver.cube(lits);
|
lbool result = m_solver.cube(lits);
|
||||||
if (result == l_false || lits.empty()) {
|
if (result == l_false || lits.empty()) {
|
||||||
|
|
|
@ -18,4 +18,5 @@ z3_add_component(portfolio
|
||||||
ufbv_tactic
|
ufbv_tactic
|
||||||
TACTIC_HEADERS
|
TACTIC_HEADERS
|
||||||
default_tactic.h
|
default_tactic.h
|
||||||
|
fd_solver.h
|
||||||
)
|
)
|
||||||
|
|
|
@ -163,7 +163,7 @@ public:
|
||||||
virtual void get_labels(svector<symbol> & r) { m_solver->get_labels(r); }
|
virtual void get_labels(svector<symbol> & r) { m_solver->get_labels(r); }
|
||||||
virtual ast_manager& get_manager() const { return m; }
|
virtual ast_manager& get_manager() const { return m; }
|
||||||
virtual expr_ref lookahead(expr_ref_vector const& assumptions, expr_ref_vector const& candidates) { flush_assertions(); return m_solver->lookahead(assumptions, candidates); }
|
virtual expr_ref lookahead(expr_ref_vector const& assumptions, expr_ref_vector const& candidates) { flush_assertions(); return m_solver->lookahead(assumptions, candidates); }
|
||||||
virtual expr_ref cube() { return m_solver->cube(); }
|
virtual expr_ref cube() { flush_assertions(); return m_solver->cube(); }
|
||||||
virtual void get_lemmas(expr_ref_vector & lemmas) { flush_assertions(); m_solver->get_lemmas(lemmas); }
|
virtual void get_lemmas(expr_ref_vector & lemmas) { flush_assertions(); m_solver->get_lemmas(lemmas); }
|
||||||
virtual lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes) { return m_solver->find_mutexes(vars, mutexes); }
|
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) {
|
virtual lbool get_consequences_core(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) {
|
||||||
|
|
|
@ -99,7 +99,7 @@ public:
|
||||||
virtual void get_labels(svector<symbol> & r) { m_solver->get_labels(r); }
|
virtual void get_labels(svector<symbol> & r) { m_solver->get_labels(r); }
|
||||||
virtual ast_manager& get_manager() const { return m; }
|
virtual ast_manager& get_manager() const { return m; }
|
||||||
virtual expr_ref lookahead(expr_ref_vector const& assumptions, expr_ref_vector const& candidates) { flush_assertions(); return m_solver->lookahead(assumptions, candidates); }
|
virtual expr_ref lookahead(expr_ref_vector const& assumptions, expr_ref_vector const& candidates) { flush_assertions(); return m_solver->lookahead(assumptions, candidates); }
|
||||||
virtual expr_ref cube() { return m_solver->cube(); }
|
virtual expr_ref cube() { flush_assertions(); return m_solver->cube(); }
|
||||||
virtual void get_lemmas(expr_ref_vector & lemmas) { flush_assertions(); m_solver->get_lemmas(lemmas); }
|
virtual void get_lemmas(expr_ref_vector & lemmas) { flush_assertions(); m_solver->get_lemmas(lemmas); }
|
||||||
virtual lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes) { return m_solver->find_mutexes(vars, mutexes); }
|
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) {
|
virtual lbool get_consequences_core(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) {
|
||||||
|
|
Loading…
Reference in a new issue