/*++ Copyright (c) 2019 Microsoft Corporation Module Name: sat_prob.h Abstract: PROB Local search module for clauses Author: Nikolaj Bjorner 2019-4-23 Notes: http://www.ict.griffith.edu.au/~johnt/publications/CP2006raouf.pdf --*/ #pragma once #include "util/uint_set.h" #include "util/rlimit.h" #include "sat/sat_clause.h" #include "sat/sat_types.h" namespace sat { class solver; class prob : public i_local_search { struct clause_info { unsigned m_trues = 0; // set of literals that are true unsigned m_num_trues = 0; // size of true set bool is_true() const { return m_num_trues > 0; } void add(literal lit) { ++m_num_trues; m_trues += lit.index(); } void del(literal lit) { SASSERT(m_num_trues > 0); --m_num_trues; m_trues -= lit.index(); } }; struct config { unsigned m_prob_random_init; unsigned m_restart_offset; double m_cb; double m_eps; config() { reset(); } void reset() { m_prob_random_init = 4; m_restart_offset = 1000000; m_cb = 2.85; m_eps = 0.9; } }; config m_config; reslimit m_limit; clause_allocator m_alloc; clause_vector m_clause_db; svector m_clauses; bool_vector m_values, m_best_values; unsigned m_best_min_unsat{ 0 }; vector m_use_list; unsigned_vector m_flat_use_list; unsigned_vector m_use_list_index; svector m_prob_break; svector m_probs; indexed_uint_set m_unsat; random_gen m_rand; unsigned_vector m_breaks; uint64_t m_flips{ 0 }; uint64_t m_next_restart{ 0 }; unsigned m_restart_count{ 0 }; stopwatch m_stopwatch; model m_model; class use_list { prob& p; unsigned i; public: use_list(prob& p, literal lit): p(p), i(lit.index()) {} unsigned const* begin() { return p.m_flat_use_list.data() + p.m_use_list_index[i]; } unsigned const* end() { return p.m_flat_use_list.data() + p.m_use_list_index[i+1]; } }; void flatten_use_list(); bool is_true(literal lit) const { return m_values[lit.var()] != lit.sign(); } inline clause const& get_clause(unsigned idx) const { return *m_clause_db[idx]; } inline bool is_true(unsigned idx) const { return m_clauses[idx].is_true(); } inline void inc_break(literal lit) { m_breaks[lit.var()]++; } inline void dec_break(literal lit) { m_breaks[lit.var()]--; } void flip(); bool_var pick_var(); void flip(bool_var v); void reinit_values(); void save_best_values(); void init(); void init_random_values(); void init_best_values(); void init_near_best_values(); void init_clauses(); void auto_config(); bool should_restart(); void do_restart(); void invariant(); void log(); void add(unsigned sz, literal const* c); public: ~prob() override; lbool check(unsigned sz, literal const* assumptions, parallel* p) override; void set_seed(unsigned n) override { m_rand.set_seed(n); } reslimit& rlimit() override { return m_limit; } void add(solver const& s) override; model const& get_model() const override { return m_model; } std::ostream& display(std::ostream& out) const; void updt_params(params_ref const& p) override {} unsigned num_non_binary_clauses() const override { return 0; } void collect_statistics(statistics& st) const override {} void reinit(solver& s) override { UNREACHABLE(); } }; }