164 lines
7.6 KiB
C++
164 lines
7.6 KiB
C++
/**************************************************************************************************
|
|
MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all copies or
|
|
substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
|
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
**************************************************************************************************/
|
|
|
|
#ifndef Solver_h
|
|
#define Solver_h
|
|
|
|
#include "SolverTypes.h"
|
|
#include "Constraints.h"
|
|
#include "Queue.h"
|
|
#include "VarOrder.h"
|
|
|
|
|
|
//=================================================================================================
|
|
// Solver -- the main class:
|
|
|
|
|
|
struct SolverStats {
|
|
int64 starts, decisions, propagations, inspects, conflicts;
|
|
int64 clauses, clauses_literals, learnts, learnts_literals;
|
|
SolverStats(void) : starts(0), decisions(0), propagations(0), inspects(0), conflicts(0)
|
|
, clauses(0), clauses_literals(0), learnts(0), learnts_literals(0) { }
|
|
};
|
|
|
|
|
|
struct SearchParams {
|
|
double var_decay, clause_decay, random_var_freq; // (reasonable values are: 0.95, 0.999, 0.02)
|
|
SearchParams(double v = 1, double c = 1, double r = 0) : var_decay(v), clause_decay(c), random_var_freq(r) { }
|
|
};
|
|
|
|
|
|
class Solver {
|
|
protected:
|
|
bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!
|
|
vec<Constr*> constrs; // List of problem constraints.
|
|
vec<Clause*> learnts; // List of learnt clauses.
|
|
double cla_inc; // Amount to bump next clause with.
|
|
double cla_decay; // INVERSE decay factor for clause activity: stores 1/decay.
|
|
|
|
vec<double> activity; // A heuristic measurement of the activity of a variable.
|
|
double var_inc; // Amount to bump next variable with.
|
|
double var_decay; // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order.
|
|
VarOrder order; // Keeps track of the decision variable order.
|
|
|
|
vec<vec<Constr*> > watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
|
|
vec<vec<Constr*> > undos; // 'undos[var]' is a list of constraints that will be called when 'var' becomes unbound.
|
|
Queue<Lit> propQ; // Propagation queue.
|
|
|
|
vec<char> assigns; // The current assignments (lbool:s stored as char:s).
|
|
vec<Lit> trail; // List of assignments made.
|
|
vec<int> trail_lim; // Separator indices for different decision levels in 'trail'.
|
|
vec<Constr*> reason; // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none.
|
|
vec<int> level; // 'level[var]' is the decision level at which assignment was made.
|
|
int root_level; // Level of first proper decision.
|
|
int last_simplify; // Number of top-level assignments at last 'simplifyDB()'.
|
|
|
|
// Temporaries (to reduce allocation overhead):
|
|
//
|
|
vec<char> analyze_seen;
|
|
|
|
// Main internal methods:
|
|
//
|
|
bool assume (Lit p);
|
|
void undoOne (void);
|
|
void cancel (void);
|
|
void cancelUntil (int level);
|
|
void record (const vec<Lit>& clause);
|
|
|
|
void analyze (Constr* confl, vec<Lit>& out_learnt, int& out_btlevel); // (bt = backtrack)
|
|
bool enqueue (Lit fact, Constr* from = NULL);
|
|
Constr* propagate (void);
|
|
void reduceDB (void);
|
|
Lit pickBranchLit(const SearchParams& params);
|
|
lbool search (int nof_conflicts, int nof_learnts, const SearchParams& params);
|
|
double progressEstimate(void);
|
|
|
|
// Activity:
|
|
//
|
|
void varBumpActivity(Lit p) {
|
|
if (var_decay < 0) return; // (negative decay means static variable order -- don't bump)
|
|
if ( (activity[var(p)] += var_inc) > 1e100 ) varRescaleActivity();
|
|
order.update(var(p)); }
|
|
void varDecayActivity(void) { if (var_decay >= 0) var_inc *= var_decay; }
|
|
void varRescaleActivity(void);
|
|
|
|
void claBumpActivity(Clause* c) { if ( (c->activity() += cla_inc) > 1e20 ) claRescaleActivity(); }
|
|
void claDecayActivity(void) { cla_inc *= cla_decay; }
|
|
void claRescaleActivity(void);
|
|
|
|
int decisionLevel(void) { return trail_lim.size(); }
|
|
|
|
public:
|
|
Solver(void) : ok (true)
|
|
, cla_inc (1)
|
|
, cla_decay (1)
|
|
, var_inc (1)
|
|
, var_decay (1)
|
|
, order (assigns, activity)
|
|
, last_simplify (-1)
|
|
, progress_estimate(0)
|
|
, verbosity(0)
|
|
{ }
|
|
~Solver(void) {
|
|
for (int i = 0; i < learnts.size(); i++) learnts[i]->remove(*this, true);
|
|
for (int i = 0; i < constrs.size(); i++) constrs[i]->remove(*this, true); }
|
|
|
|
// Helpers: (semi-internal)
|
|
//
|
|
lbool value(Var x) { return toLbool(assigns[x]); }
|
|
lbool value(Lit p) { return sign(p) ? ~toLbool(assigns[var(p)]) : toLbool(assigns[var(p)]); }
|
|
|
|
int nAssigns(void) { return trail.size(); }
|
|
int nConstrs(void) { return constrs.size(); }
|
|
int nLearnts(void) { return learnts.size(); }
|
|
|
|
// Statistics: (read-only member variable)
|
|
//
|
|
SolverStats stats;
|
|
|
|
// Problem specification:
|
|
//
|
|
Var newVar (void);
|
|
int nVars (void) { return assigns.size(); }
|
|
void addUnit(Lit p) { if (ok) enqueue(p); }
|
|
|
|
// -- constraints:
|
|
friend class Clause;
|
|
friend class AtMost;
|
|
friend bool Clause_new(Solver& S, const vec<Lit>& ps, bool learnt, Clause*& out_clause);
|
|
friend bool AtMost_new(Solver& S, const vec<Lit>& ps, int max , AtMost*& out_constr);
|
|
|
|
void addClause(const vec<Lit>& ps) { if (ok){ Clause* c; ok = Clause_new(*this, ps, false, c); if (c != NULL) constrs.push(c); } }
|
|
void addAtMost(const vec<Lit>& ps, int n) { if (ok){ AtMost* c; ok = AtMost_new(*this, ps, n , c); if (c != NULL) constrs.push(c); } }
|
|
|
|
// Solving:
|
|
//
|
|
bool okay(void) { return ok; }
|
|
void simplifyDB(void);
|
|
bool solve(const vec<Lit>& assumps);
|
|
bool solve(void) { vec<Lit> tmp; return solve(tmp); }
|
|
|
|
double progress_estimate; // Set by 'search()'.
|
|
vec<lbool> model; // If problem is solved, this vector contains the model (if any).
|
|
int verbosity; // Verbosity level. 0=silent, 1=some progress report, 2=everything
|
|
};
|
|
|
|
|
|
//=================================================================================================
|
|
#endif
|