mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 17:45:32 +00:00
move to self-contained trail instructions
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
2eadcd586a
commit
549b984c88
7 changed files with 87 additions and 46 deletions
|
@ -8,6 +8,7 @@ Module Name:
|
|||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2021-03-19
|
||||
Jakob Rath 2021-04-6
|
||||
|
||||
--*/
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ Module Name:
|
|||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2021-03-19
|
||||
Jakob Rath 2021-04-6
|
||||
|
||||
--*/
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ Module Name:
|
|||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2021-03-19
|
||||
Jakob Rath 2021-04-6
|
||||
|
||||
--*/
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ Module Name:
|
|||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2021-03-19
|
||||
Jakob Rath 2021-04-6
|
||||
|
||||
--*/
|
||||
#pragma once
|
||||
|
|
|
@ -12,6 +12,7 @@ Abstract:
|
|||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2021-03-19
|
||||
Jakob Rath 2021-04-6
|
||||
|
||||
--*/
|
||||
|
||||
|
@ -42,6 +43,7 @@ namespace polysat {
|
|||
for (unsigned k = size(v); k-- > 0; )
|
||||
value &= val.get_bit(k) ? m_bdd.mk_var(k) : m_bdd.mk_nvar(k);
|
||||
SASSERT((value && !m_viable[v]).is_false());
|
||||
push_viable(v);
|
||||
m_viable[v] &= !value;
|
||||
}
|
||||
|
||||
|
@ -68,14 +70,8 @@ namespace polysat {
|
|||
return is_unique ? l_true : l_undef;
|
||||
}
|
||||
|
||||
struct solver::t_del_var : public trail {
|
||||
solver& s;
|
||||
t_del_var(solver& s): s(s) {}
|
||||
void undo() override { s.del_var(); }
|
||||
};
|
||||
|
||||
solver::solver(trail_stack& s, reslimit& lim):
|
||||
m_trail(s),
|
||||
solver::solver(reslimit& lim):
|
||||
m_lim(lim),
|
||||
m_bdd(1000),
|
||||
m_dm(m_value_manager, m_alloc),
|
||||
|
@ -132,7 +128,7 @@ namespace polysat {
|
|||
m_activity.push_back(0);
|
||||
m_vars.push_back(sz2pdd(sz).mk_var(v));
|
||||
m_size.push_back(sz);
|
||||
m_trail.push(t_del_var(*this));
|
||||
m_trail.push_back(trail_instr_t::add_var_i);
|
||||
m_free_vars.mk_var_eh(v);
|
||||
return v;
|
||||
}
|
||||
|
@ -192,7 +188,7 @@ namespace polysat {
|
|||
}
|
||||
|
||||
void solver::propagate() {
|
||||
m_trail.push(value_trail(m_qhead));
|
||||
push_qhead();
|
||||
while (can_propagate())
|
||||
propagate(m_search[m_qhead++].first);
|
||||
}
|
||||
|
@ -220,15 +216,51 @@ namespace polysat {
|
|||
|
||||
void solver::push_level() {
|
||||
++m_level;
|
||||
m_trail.push_scope();
|
||||
m_trail.push_back(trail_instr_t::inc_level_i);
|
||||
}
|
||||
|
||||
void solver::pop_levels(unsigned num_levels) {
|
||||
m_trail.pop_scope(num_levels);
|
||||
m_level -= num_levels;
|
||||
while (num_levels > 0) {
|
||||
switch (m_trail.back()) {
|
||||
case trail_instr_t::qhead_i: {
|
||||
pop_qhead();
|
||||
break;
|
||||
}
|
||||
case trail_instr_t::add_var_i: {
|
||||
del_var();
|
||||
break;
|
||||
}
|
||||
case trail_instr_t::inc_level_i: {
|
||||
--m_level;
|
||||
--num_levels;
|
||||
break;
|
||||
}
|
||||
case trail_instr_t::viable_i: {
|
||||
auto p = m_viable_trail.back();
|
||||
m_viable[p.first] = p.second;
|
||||
m_viable_trail.pop_back();
|
||||
break;
|
||||
}
|
||||
case trail_instr_t::assign_i: {
|
||||
auto v = m_search.back().first;
|
||||
m_free_vars.unassign_var_eh(v);
|
||||
m_justification[v] = justification::unassigned();
|
||||
m_search.pop_back();
|
||||
break;
|
||||
}
|
||||
case trail_instr_t::just_i: {
|
||||
auto v = m_cjust_trail.back();
|
||||
m_cjust[v].pop_back();
|
||||
m_cjust_trail.pop_back();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
m_trail.pop_back();
|
||||
}
|
||||
pop_constraints(m_constraints);
|
||||
pop_constraints(m_redundant);
|
||||
pop_assignment();
|
||||
}
|
||||
|
||||
void solver::pop_constraints(scoped_ptr_vector<constraint>& cs) {
|
||||
|
@ -239,28 +271,6 @@ namespace polysat {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TBD: rewrite for proper backtracking where variable levels don't follow scope level.
|
||||
* use a marker into m_search for level as in SAT solver.
|
||||
*/
|
||||
void solver::pop_assignment() {
|
||||
while (!m_search.empty() && m_justification[m_search.back().first].level() > m_level) {
|
||||
undo_var(m_search.back().first);
|
||||
m_search.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
// Base approach just clears all assignments.
|
||||
// TBD approach allows constraints to constrain bits of v. They are
|
||||
// added to cjust and affect viable outside of search.
|
||||
void solver::undo_var(pvar v) {
|
||||
m_justification[v] = justification::unassigned();
|
||||
m_free_vars.unassign_var_eh(v);
|
||||
m_cjust[v].reset();
|
||||
m_viable[v] = m_bdd.mk_true();
|
||||
}
|
||||
|
||||
|
||||
void solver::add_watch(constraint& c) {
|
||||
auto const& vars = c.vars();
|
||||
if (vars.size() > 0)
|
||||
|
@ -327,6 +337,7 @@ namespace polysat {
|
|||
SASSERT(is_viable(v, val));
|
||||
m_value[v] = val;
|
||||
m_search.push_back(std::make_pair(v, val));
|
||||
m_trail.push_back(trail_instr_t::assign_i);
|
||||
m_justification[v] = j;
|
||||
}
|
||||
|
||||
|
@ -473,7 +484,7 @@ namespace polysat {
|
|||
if (!c)
|
||||
return;
|
||||
SASSERT(m_conflict_level <= m_justification[v].level());
|
||||
m_cjust[v].push_back(c);
|
||||
push_cjust(v, c);
|
||||
add_lemma(c);
|
||||
}
|
||||
|
||||
|
@ -490,11 +501,14 @@ namespace polysat {
|
|||
rational val = m_value[v];
|
||||
SASSERT(m_justification[v].is_decision());
|
||||
bdd viable = m_viable[v];
|
||||
m_conflict.append(m_cjust[v]);
|
||||
constraints just(m_cjust[v]);
|
||||
backjump(m_justification[v].level()-1);
|
||||
SASSERT(m_cjust[v].empty());
|
||||
m_cjust[v].append(m_conflict);
|
||||
for (unsigned i = m_cjust[v].size(); i < just.size(); ++i)
|
||||
push_cjust(v, just[i]);
|
||||
for (constraint* c : m_conflict)
|
||||
push_cjust(v, c);
|
||||
m_conflict.reset();
|
||||
push_viable(v);
|
||||
m_viable[v] = viable;
|
||||
add_non_viable(v, val);
|
||||
m_free_vars.del_var_eh(v);
|
||||
|
|
|
@ -12,6 +12,7 @@ Abstract:
|
|||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2021-03-19
|
||||
Jakob Rath 2021-04-6
|
||||
|
||||
--*/
|
||||
#pragma once
|
||||
|
@ -19,6 +20,7 @@ Author:
|
|||
#include "util/statistics.h"
|
||||
#include "math/polysat/constraint.h"
|
||||
#include "math/polysat/justification.h"
|
||||
#include "math/polysat/trail.h"
|
||||
|
||||
namespace polysat {
|
||||
|
||||
|
@ -36,7 +38,6 @@ namespace polysat {
|
|||
|
||||
typedef ptr_vector<constraint> constraints;
|
||||
|
||||
trail_stack& m_trail;
|
||||
reslimit& m_lim;
|
||||
scoped_ptr_vector<dd::pdd_manager> m_pdd;
|
||||
dd::bdd_manager m_bdd;
|
||||
|
@ -68,9 +69,35 @@ namespace polysat {
|
|||
unsigned m_qhead { 0 };
|
||||
unsigned m_level { 0 };
|
||||
|
||||
svector<trail_instr_t> m_trail;
|
||||
unsigned_vector m_qhead_trail;
|
||||
vector<std::pair<pvar, bdd>> m_viable_trail;
|
||||
unsigned_vector m_cjust_trail;
|
||||
|
||||
|
||||
unsigned_vector m_base_levels; // External clients can push/pop scope.
|
||||
|
||||
|
||||
void push_viable(pvar v) {
|
||||
m_viable_trail.push_back(std::make_pair(v, m_viable[v]));
|
||||
}
|
||||
|
||||
void push_qhead() {
|
||||
m_trail.push_back(trail_instr_t::qhead_i);
|
||||
m_qhead_trail.push_back(m_qhead);
|
||||
}
|
||||
|
||||
void pop_qhead() {
|
||||
m_qhead = m_qhead_trail.back();
|
||||
m_qhead_trail.pop_back();
|
||||
}
|
||||
|
||||
void push_cjust(pvar v, constraint* c) {
|
||||
m_cjust[v].push_back(c);
|
||||
m_trail.push_back(trail_instr_t::just_i);
|
||||
m_cjust_trail.push_back(v);
|
||||
}
|
||||
|
||||
unsigned size(pvar v) const { return m_size[v]; }
|
||||
/**
|
||||
* check if value is viable according to m_viable.
|
||||
|
@ -105,7 +132,6 @@ namespace polysat {
|
|||
* undo trail operations for backtracking.
|
||||
* Each struct is a subclass of trail and implements undo().
|
||||
*/
|
||||
struct t_del_var;
|
||||
|
||||
void del_var();
|
||||
|
||||
|
@ -113,7 +139,6 @@ namespace polysat {
|
|||
|
||||
void push_level();
|
||||
void pop_levels(unsigned num_levels);
|
||||
void pop_assignment();
|
||||
void pop_constraints(scoped_ptr_vector<constraint>& cs);
|
||||
|
||||
void assign_core(pvar v, rational const& val, justification const& j);
|
||||
|
@ -157,7 +182,6 @@ namespace polysat {
|
|||
void revert_decision(pvar v);
|
||||
void learn_lemma(pvar v, constraint* c);
|
||||
void backjump(unsigned new_level);
|
||||
void undo_var(pvar v);
|
||||
void add_lemma(constraint* c);
|
||||
|
||||
bool invariant();
|
||||
|
@ -170,7 +194,7 @@ namespace polysat {
|
|||
* every update to the solver is going to be retractable
|
||||
* by pushing an undo action on the trail stack.
|
||||
*/
|
||||
solver(trail_stack& s, reslimit& lim);
|
||||
solver(reslimit& lim);
|
||||
|
||||
~solver();
|
||||
|
||||
|
|
|
@ -7,11 +7,10 @@ namespace polysat {
|
|||
|
||||
struct solver_scope {
|
||||
reslimit lim;
|
||||
trail_stack stack;
|
||||
};
|
||||
|
||||
struct scoped_solver : public solver_scope, public solver {
|
||||
scoped_solver(): solver(stack, lim) {}
|
||||
scoped_solver(): solver(lim) {}
|
||||
|
||||
void check() {
|
||||
std::cout << check_sat() << "\n";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue