mirror of
https://github.com/Z3Prover/z3
synced 2025-08-25 04:26:00 +00:00
include chronological backtracking, two-phase sat, xor inprocessing, probsat, ddfw
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
46d23ea8d7
commit
d17248821a
32 changed files with 3246 additions and 654 deletions
|
@ -19,7 +19,7 @@ Revision History:
|
|||
#ifndef SAT_SOLVER_H_
|
||||
#define SAT_SOLVER_H_
|
||||
|
||||
|
||||
#include <cmath>
|
||||
#include "sat/sat_types.h"
|
||||
#include "sat/sat_clause.h"
|
||||
#include "sat/sat_watched.h"
|
||||
|
@ -71,6 +71,8 @@ namespace sat {
|
|||
unsigned m_elim_var_res;
|
||||
unsigned m_elim_var_bdd;
|
||||
unsigned m_units;
|
||||
unsigned m_backtracks;
|
||||
unsigned m_backjumps;
|
||||
stats() { reset(); }
|
||||
void reset();
|
||||
void collect_statistics(statistics & st) const;
|
||||
|
@ -80,6 +82,8 @@ namespace sat {
|
|||
public:
|
||||
struct abort_solver {};
|
||||
protected:
|
||||
enum search_state { s_sat, s_unsat };
|
||||
|
||||
bool m_checkpoint_enabled;
|
||||
config m_config;
|
||||
stats m_stats;
|
||||
|
@ -116,7 +120,9 @@ namespace sat {
|
|||
svector<char> m_lit_mark;
|
||||
svector<char> m_eliminated;
|
||||
svector<char> m_external;
|
||||
svector<unsigned> m_level;
|
||||
unsigned_vector m_touched;
|
||||
unsigned m_touch_index;
|
||||
literal_vector m_replay_assign;
|
||||
// branch variable selection:
|
||||
svector<unsigned> m_activity;
|
||||
unsigned m_activity_inc;
|
||||
|
@ -128,17 +134,27 @@ namespace sat {
|
|||
int m_action;
|
||||
double m_step_size;
|
||||
// phase
|
||||
svector<char> m_phase;
|
||||
svector<char> m_prev_phase;
|
||||
svector<bool> m_phase;
|
||||
svector<bool> m_best_phase;
|
||||
svector<bool> m_prev_phase;
|
||||
svector<char> m_assigned_since_gc;
|
||||
bool m_phase_cache_on;
|
||||
search_state m_search_state;
|
||||
unsigned m_search_unsat_conflicts;
|
||||
unsigned m_search_sat_conflicts;
|
||||
unsigned m_search_next_toggle;
|
||||
unsigned m_phase_counter;
|
||||
unsigned m_best_phase_size;
|
||||
unsigned m_rephase_lim;
|
||||
unsigned m_rephase_inc;
|
||||
var_queue m_case_split_queue;
|
||||
unsigned m_qhead;
|
||||
unsigned m_scope_lvl;
|
||||
unsigned m_search_lvl;
|
||||
ema m_fast_glue_avg;
|
||||
ema m_slow_glue_avg;
|
||||
ema m_fast_glue_backup;
|
||||
ema m_slow_glue_backup;
|
||||
ema m_trail_avg;
|
||||
literal_vector m_trail;
|
||||
clause_wrapper_vector m_clauses_to_reinit;
|
||||
std::string m_reason_unknown;
|
||||
|
@ -163,7 +179,7 @@ namespace sat {
|
|||
bool m_par_syncing_clauses;
|
||||
|
||||
class lookahead* m_cuber;
|
||||
class local_search* m_local_search;
|
||||
class i_local_search* m_local_search;
|
||||
|
||||
statistics m_aux_stats;
|
||||
|
||||
|
@ -174,6 +190,7 @@ namespace sat {
|
|||
friend class simplifier;
|
||||
friend class scc;
|
||||
friend class big;
|
||||
friend class binspr;
|
||||
friend class elim_eqs;
|
||||
friend class asymm_branch;
|
||||
friend class probing;
|
||||
|
@ -184,6 +201,8 @@ namespace sat {
|
|||
friend class parallel;
|
||||
friend class lookahead;
|
||||
friend class local_search;
|
||||
friend class ddfw;
|
||||
friend class prob;
|
||||
friend class unit_walk;
|
||||
friend struct mk_stat;
|
||||
friend class elim_vars;
|
||||
|
@ -251,6 +270,7 @@ namespace sat {
|
|||
void attach_clause(clause & c, bool & reinit);
|
||||
void attach_clause(clause & c) { bool reinit; attach_clause(c, reinit); }
|
||||
void set_learned(clause& c, bool learned);
|
||||
void shrink(clause& c, unsigned old_sz, unsigned new_sz);
|
||||
void set_learned(literal l1, literal l2, bool learned);
|
||||
void set_learned1(literal l1, literal l2, bool learned);
|
||||
void add_ate(clause& c) { m_mc.add_ate(c); }
|
||||
|
@ -285,7 +305,7 @@ namespace sat {
|
|||
// -----------------------
|
||||
public:
|
||||
bool inconsistent() const override { return m_inconsistent; }
|
||||
unsigned num_vars() const override { return m_level.size(); }
|
||||
unsigned num_vars() const override { return m_justification.size(); }
|
||||
unsigned num_clauses() const override;
|
||||
void num_binary(unsigned& given, unsigned& learned) const;
|
||||
unsigned num_restarts() const { return m_restarts; }
|
||||
|
@ -293,7 +313,7 @@ namespace sat {
|
|||
void set_external(bool_var v) override;
|
||||
void set_non_external(bool_var v) override;
|
||||
bool was_eliminated(bool_var v) const { return m_eliminated[v] != 0; }
|
||||
void set_eliminated(bool_var v, bool f) override { m_eliminated[v] = f; }
|
||||
void set_eliminated(bool_var v, bool f) override;
|
||||
bool was_eliminated(literal l) const { return was_eliminated(l.var()); }
|
||||
unsigned scope_lvl() const { return m_scope_lvl; }
|
||||
unsigned search_lvl() const { return m_search_lvl; }
|
||||
|
@ -301,40 +321,55 @@ namespace sat {
|
|||
bool at_base_lvl() const override { return m_scope_lvl == 0; }
|
||||
lbool value(literal l) const { return static_cast<lbool>(m_assignment[l.index()]); }
|
||||
lbool value(bool_var v) const { return static_cast<lbool>(m_assignment[literal(v, false).index()]); }
|
||||
unsigned lvl(bool_var v) const { return m_level[v]; }
|
||||
unsigned lvl(literal l) const { return m_level[l.var()]; }
|
||||
unsigned lvl(bool_var v) const { return m_justification[v].level(); }
|
||||
unsigned lvl(literal l) const { return m_justification[l.var()].level(); }
|
||||
unsigned init_trail_size() const override { return at_base_lvl() ? m_trail.size() : m_scopes[0].m_trail_lim; }
|
||||
unsigned trail_size() const { return m_trail.size(); }
|
||||
literal trail_literal(unsigned i) const override { return m_trail[i]; }
|
||||
literal scope_literal(unsigned n) const { return m_trail[m_scopes[n].m_trail_lim]; }
|
||||
void assign(literal l, justification j) {
|
||||
TRACE("sat_assign", tout << l << " previous value: " << value(l) << "\n";);
|
||||
TRACE("sat_assign", tout << l << " previous value: " << value(l) << " j: " << j << "\n";);
|
||||
switch (value(l)) {
|
||||
case l_false: set_conflict(j, ~l); break;
|
||||
case l_undef: assign_core(l, scope_lvl(), j); break;
|
||||
case l_undef: assign_core(l, j); break;
|
||||
case l_true: return;
|
||||
}
|
||||
}
|
||||
void assign_core(literal l, unsigned lvl, justification jst);
|
||||
void assign_unit(literal l) { assign(l, justification()); }
|
||||
void assign_scoped(literal l) { assign(l, justification()); }
|
||||
void assign_unit(literal l) { assign(l, justification(0)); }
|
||||
void assign_scoped(literal l) { assign(l, justification(scope_lvl())); }
|
||||
void assign_core(literal l, justification jst);
|
||||
void set_conflict(justification c, literal not_l);
|
||||
void set_conflict(justification c) { set_conflict(c, null_literal); }
|
||||
void set_conflict() { set_conflict(justification()); }
|
||||
void set_conflict() { set_conflict(justification(0)); }
|
||||
lbool status(clause const & c) const;
|
||||
clause_offset get_offset(clause const & c) const { return cls_allocator().get_offset(&c); }
|
||||
void checkpoint() {
|
||||
if (!m_checkpoint_enabled) return;
|
||||
|
||||
bool limit_reached() {
|
||||
if (!m_rlimit.inc()) {
|
||||
m_mc.reset();
|
||||
m_model_is_current = false;
|
||||
TRACE("sat", tout << "canceled\n";);
|
||||
m_reason_unknown = "sat.canceled";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool memory_exceeded() {
|
||||
++m_num_checkpoints;
|
||||
if (m_num_checkpoints < 10) return false;
|
||||
m_num_checkpoints = 0;
|
||||
return memory::get_allocation_size() > m_config.m_max_memory;
|
||||
}
|
||||
|
||||
void checkpoint() {
|
||||
if (!m_checkpoint_enabled) return;
|
||||
if (limit_reached()) {
|
||||
throw solver_exception(Z3_CANCELED_MSG);
|
||||
}
|
||||
++m_num_checkpoints;
|
||||
if (m_num_checkpoints < 10) return;
|
||||
m_num_checkpoints = 0;
|
||||
if (memory::get_allocation_size() > m_config.m_max_memory) throw solver_exception(Z3_MAX_MEMORY_MSG);
|
||||
if (memory_exceeded()) {
|
||||
throw solver_exception(Z3_MAX_MEMORY_MSG);
|
||||
}
|
||||
}
|
||||
void set_par(parallel* p, unsigned id);
|
||||
bool canceled() { return !m_rlimit.inc(); }
|
||||
|
@ -358,7 +393,6 @@ namespace sat {
|
|||
void unmark_lit(literal l) { SASSERT(is_marked_lit(l)); m_lit_mark[l.index()] = false; }
|
||||
bool check_inconsistent();
|
||||
|
||||
|
||||
// -----------------------
|
||||
//
|
||||
// Propagation
|
||||
|
@ -369,6 +403,7 @@ namespace sat {
|
|||
bool propagate(bool update);
|
||||
|
||||
protected:
|
||||
bool should_propagate() const;
|
||||
bool propagate_core(bool update);
|
||||
|
||||
// -----------------------
|
||||
|
@ -391,6 +426,8 @@ namespace sat {
|
|||
void set_activity(bool_var v, unsigned act);
|
||||
|
||||
lbool cube(bool_var_vector& vars, literal_vector& lits, unsigned backtrack_level);
|
||||
|
||||
void display_lookahead_scores(std::ostream& out);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -398,6 +435,7 @@ namespace sat {
|
|||
unsigned m_restarts;
|
||||
unsigned m_restart_next_out;
|
||||
unsigned m_conflicts_since_restart;
|
||||
bool m_force_conflict_analysis;
|
||||
unsigned m_simplifications;
|
||||
unsigned m_restart_threshold;
|
||||
unsigned m_luby_idx;
|
||||
|
@ -427,22 +465,28 @@ namespace sat {
|
|||
void reinit_assumptions();
|
||||
bool tracking_assumptions() const;
|
||||
bool is_assumption(literal l) const;
|
||||
void simplify_problem();
|
||||
bool should_simplify() const;
|
||||
void do_simplify();
|
||||
void mk_model();
|
||||
bool check_model(model const & m) const;
|
||||
void restart(bool to_base);
|
||||
void do_restart(bool to_base);
|
||||
svector<size_t> m_last_positions;
|
||||
unsigned m_last_position_log;
|
||||
unsigned m_restart_logs;
|
||||
unsigned restart_level(bool to_base);
|
||||
void log_stats();
|
||||
bool should_cancel();
|
||||
bool should_restart() const;
|
||||
void set_next_restart();
|
||||
void update_activity(bool_var v, double p);
|
||||
bool reached_max_conflicts();
|
||||
void sort_watch_lits();
|
||||
void exchange_par();
|
||||
lbool check_par(unsigned num_lits, literal const* lits);
|
||||
lbool do_local_search(unsigned num_lits, literal const* lits);
|
||||
lbool do_ddfw_search(unsigned num_lits, literal const* lits);
|
||||
lbool do_prob_search(unsigned num_lits, literal const* lits);
|
||||
lbool invoke_local_search(unsigned num_lits, literal const* lits);
|
||||
lbool do_unit_walk();
|
||||
|
||||
// -----------------------
|
||||
|
@ -451,7 +495,8 @@ namespace sat {
|
|||
//
|
||||
// -----------------------
|
||||
protected:
|
||||
void gc();
|
||||
bool should_gc() const;
|
||||
void do_gc();
|
||||
void gc_glue();
|
||||
void gc_psm();
|
||||
void gc_glue_psm();
|
||||
|
@ -492,18 +537,31 @@ namespace sat {
|
|||
unsigned m_conflict_lvl;
|
||||
literal_vector m_lemma;
|
||||
literal_vector m_ext_antecedents;
|
||||
bool use_backjumping(unsigned num_scopes);
|
||||
bool resolve_conflict();
|
||||
bool resolve_conflict_core();
|
||||
lbool resolve_conflict_core();
|
||||
void learn_lemma_and_backjump();
|
||||
unsigned get_max_lvl(literal consequent, justification js);
|
||||
inline unsigned update_max_level(literal lit, unsigned lvl2, bool& unique_max) {
|
||||
unsigned lvl1 = lvl(lit);
|
||||
if (lvl1 < lvl2) return lvl2;
|
||||
unique_max = lvl1 > lvl2;
|
||||
return lvl1;
|
||||
}
|
||||
unsigned get_max_lvl(literal consequent, justification js, bool& unique_max);
|
||||
void process_antecedent(literal antecedent, unsigned & num_marks);
|
||||
void resolve_conflict_for_unsat_core();
|
||||
void process_antecedent_for_unsat_core(literal antecedent);
|
||||
void process_consequent_for_unsat_core(literal consequent, justification const& js);
|
||||
void fill_ext_antecedents(literal consequent, justification js);
|
||||
unsigned skip_literals_above_conflict_level();
|
||||
void forget_phase_of_vars(unsigned from_lvl);
|
||||
void updt_phase_of_vars();
|
||||
void updt_phase_counters();
|
||||
void do_toggle_search_state();
|
||||
bool should_toggle_search_state();
|
||||
bool is_sat_phase() const;
|
||||
bool is_two_phase() const;
|
||||
bool should_rephase();
|
||||
void do_rephase();
|
||||
svector<char> m_diff_levels;
|
||||
unsigned num_diff_levels(unsigned num, literal const * lits);
|
||||
bool num_diff_levels_below(unsigned num, literal const* lits, unsigned max_glue, unsigned& glue);
|
||||
|
@ -518,8 +576,9 @@ namespace sat {
|
|||
bool implied_by_marked(literal lit);
|
||||
void reset_unmark(unsigned old_size);
|
||||
void updt_lemma_lvl_set();
|
||||
void reset_lemma_var_marks();
|
||||
bool minimize_lemma();
|
||||
bool minimize_lemma_binres();
|
||||
void reset_lemma_var_marks();
|
||||
bool dyn_sub_res();
|
||||
|
||||
// -----------------------
|
||||
|
@ -531,7 +590,7 @@ namespace sat {
|
|||
void pop(unsigned num_scopes);
|
||||
void pop_reinit(unsigned num_scopes);
|
||||
|
||||
void unassign_vars(unsigned old_sz);
|
||||
void unassign_vars(unsigned old_sz, unsigned new_lvl);
|
||||
void reinit_clauses(unsigned old_sz);
|
||||
|
||||
literal_vector m_user_scope_literals;
|
||||
|
@ -556,7 +615,7 @@ namespace sat {
|
|||
//
|
||||
// -----------------------
|
||||
public:
|
||||
void cleanup(bool force);
|
||||
bool do_cleanup(bool force);
|
||||
void simplify(bool learned = true);
|
||||
void asymmetric_branching();
|
||||
unsigned scc_bin();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue