smallsat的开发团队主要成员是东华大学的陈老师:
Jingchao Chen
School of Informatics, Donghua University
2999 North Renmin Road, Songjiang District, Shanghai 201620, P. R. China
chen-jc@dhu.edu.cn
相同开发人员开发的smallsat和abcdsat,在2018年及以前取得了不错的成绩。自2018年后在2019年没有出现abcdsat,2019年出现了MapleLCMdistCBTcoreFirst。
MapleLCMdistCBTcoreFirst在2019年表现优异(第三名),其中除了针对核心学习优先传播这一主要策略之外,还采用了许多新的技术。这些独到技术环节也在smallsat中有体现。由于smallsat相较于minisat改动不大,比较容易入门,所以在此先做一些分析。
首先Solver.h头文件中类成员增加:
--------------------------------------------------------------------------------------------------------------------------------
//穿插在前部的数据成员、成员函数
// Mode of operation:
double alpha, beta;
double alpha_dec;
double min_alpha;
// Statistics: (read-only member variable)
vec<uint32_t> decisionTime, varBumpCnt, canceled;
// Solver state:
vec<CRef> clauses; // List of problem clauses.
vec<CRef> learnts; // List of learnt clauses.
int learnt_small;
int small_lbd_lim;
uint64_t sumLBD;
MyQueue<int> lbdQueue; // For computing moving averages of recent LBD values.
uint64_t next_LONG_reduce;
vec<uint32_t> permDiff; // for LBD computation. 'permDiff indicate if decision level has been seen.
uint32_t MYFLAG; // Simple MYFLAG for marking purpose with 'permDiff'.
// Resource contraints:
int64_t conflict_budget; // -1 means no budget.
int64_t propagation_budget; // -1 means no budget.
bool asynch_interrupt;
// Maintaining Variable/Clause activity:
void varDecayActivity (); // Decay all variables with the specified factor. Implemented by increasing the 'bump' value instead.
void varBumpVSIDSactivity (Var v, double delta); // Increase a variable with the current 'bump' value.
void varActivityRescale (Var v);
template<class V> int computeLBD(const V & c) {
int lbd = 0;
MYFLAG++;
for (int i = 0; i < c.size(); i++) {
int l = level(var(c[i]));
if (l != 0 && permDiff[l] != MYFLAG) {
permDiff[l] = MYFLAG;
lbd++;
}
}
return lbd;
}
bool simplifysmallclause();
void simplifyLearnt(Clause & c);
int fixedUnits;
void cancelUntil_fixedunits();
void UncheckEnqueueNoLevel(Lit p, CRef from = CRef_Undef);
CRef simplePropagate();
vec<Lit> new_learntcls;
void simpleAnalyze(CRef confl, vec<Lit> & out_learnt);
uint64_t next_simplify_small;
//最后明确给出的增加部分
//sub_solve
lbool simp_solve();
lbool solve2_();
lbool subsolve(); //调用关系 solve_ ---> simp_solve() ---> solve2_ --->subsolve
lbool runSubsolver(Solver* & newsolver, Lit plit);
void ClearClause(vec<CRef>& cs, int deleteflag);
void ClearUnit();
lbool dumpClause(vec<CRef>& cs,Solver* fromSolver,Solver* toSolver,int sizelimit);
void copyAssign(Solver* fromSolver);
int subformuleClause;
int recursiveDepth;
int needExtVar;
int init_trailsize;
//probe
lbool hbr_probe();
lbool probeaux();
lbool simpleprobehbr (Clause & c);
CRef unitPropagation(Lit p);
CRef trypropagate(Lit p){ newDecisionLevel();
UncheckEnqueueNoLevel(p); return simplePropagate();
}
bool hasBin(Lit p, Lit q);
void setmark(vec<int> & liftlit);
void clearmark(vec<int> & liftlit);
lbool addequ(Lit p, Lit q);
lbool add_equ_link(int pul, int qul);
bool addbinclause(Lit p, Lit q);
bool is_conflict(vec<Lit> & lits);
bool out_binclause(Lit p, Lit q);
lbool replaceEqVar();
char * dummyVar;
void buildEquClause();
void simpAddClause(const vec<Lit> & lits);
lbool removeEqVar(vec<CRef>& cls, bool learntflag);
void cancelUntil0(int nlevel);
void solveEqu(int *equRepr, int vnum, vec<lbool> & Amodel);
int * count, *litsum;
int *equhead;
int *equlink;
char * mark, *touchMark;
int hbrsum, equsum,unitsum,probeSum;
vec<int> touchVar;
unsigned int next_probe;
//
lbool re_learn();
void swapEqTofront(Lit * lits, int sz, int eqVal);
int moveEqTofront(vec <Lit> & preLit,vec <Lit> & curLit,vec <Lit> & nxtLit);
void simpAnalyze(CRef confl, vec<Lit> & out_learnt, Lit p);
int bitVecNo;
bool uncheck_bump;
--------------------------------------------------------------------------------------------------------------------------------
组合活跃度计算
r v =(C v + S v + P v) / T
where C v , S v and P v is the number of conflict clauses, seen
clauses and reason clauses variable v participated in since v is
picked or assigned.
T = conflictCounter − pickedTime[v]
when LBD < 22, T = conflictCounter − assigedTime[v]
otherwise, where pickedTime[v] and assigedTime[v] are
the number of conflicts since v is picked and assigned,respectively.
--------------------------------------------------------------------------------------------------------------------------------
变元初始极性和活跃度——基于原始子句文字的统计
Like the solver inIDGlucose [10], the initial phase
of a decision variable in this solver is based on a weighted
literal occurrence count on the original CNF.
//--------------------------------------------------
//init activity and phase
vec<double> occs;
occs.growTo(2*nVars(),0.0);
for(int i=0; i<nClauses(); ++i){
const Clause &c = ca[clauses[i]];
double increment = 1/(double)(c.size()*c.size());
for(int j=0; j<c.size(); ++j){
occs[toInt(c[j])]=occs[toInt(c[j])]+increment;
}
}
for(int i=0; i<nVars(); ++i){
polarity[i]=occs[2*i]<=occs[2*i+1]; // initial polarity is false if the positive lit occurs more than the negative in the theory.
activity[i]=occs[2*i]*occs[2*i+1];
}
rebuildOrderHeap();
//
//--------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------
the tree-based branching solving strategy of smallsat
--------------------------------------------------------------------------------------------------------------------------------