2018-03-17 19:26:26 +00:00
|
|
|
|
#pragma lib "libsat.a"
|
|
|
|
|
|
|
|
|
|
typedef struct SATParam SATParam;
|
|
|
|
|
typedef struct SATClause SATClause;
|
|
|
|
|
typedef struct SATSolve SATSolve;
|
|
|
|
|
typedef struct SATBlock SATBlock;
|
|
|
|
|
typedef struct SATVar SATVar;
|
|
|
|
|
typedef struct SATLit SATLit;
|
|
|
|
|
typedef struct SATConflict SATConflict;
|
2018-03-18 01:15:07 +00:00
|
|
|
|
#pragma incomplete SATClause
|
|
|
|
|
#pragma incomplete SATVar
|
|
|
|
|
#pragma incomplete SATLit
|
|
|
|
|
#pragma incomplete SATConflict
|
2018-03-17 19:26:26 +00:00
|
|
|
|
|
|
|
|
|
/* user adjustable parameters */
|
|
|
|
|
struct SATParam {
|
|
|
|
|
void (*errfun)(char *, void *);
|
|
|
|
|
void *erraux;
|
|
|
|
|
long (*randfn)(void *);
|
|
|
|
|
void *randaux;
|
|
|
|
|
|
|
|
|
|
uint goofprob; /* probability of making a random decision, times 2**31 */
|
|
|
|
|
double varρ; /* Δactivity is multiplied by this after a conflict */
|
|
|
|
|
double clauseρ; /* Δclactivity is multiplied by this after a conflict */
|
|
|
|
|
int trivlim; /* number of extra literals we're willing to tolerate before substituting the trivial clause */
|
|
|
|
|
int purgeΔ; /* initial purge interval (number of conflicts before a purge) */
|
|
|
|
|
int purgeδ; /* increase in purge interval at purge */
|
|
|
|
|
double purgeα; /* α weight factor for purge heuristic */
|
|
|
|
|
u32int flushψ; /* agility threshold for restarts */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* each block contains multiple SATClauses consecutively in its data region. each clause is 8 byte aligned and the total size is SATBLOCKSZ (64K) */
|
|
|
|
|
struct SATBlock {
|
|
|
|
|
SATBlock *next, *prev;
|
|
|
|
|
SATClause *last; /* last clause, ==nil for empty blocks */
|
|
|
|
|
void *end; /* first byte past the last clause */
|
|
|
|
|
uchar data[1];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct SATSolve {
|
|
|
|
|
SATParam;
|
|
|
|
|
|
|
|
|
|
uchar unsat; /* ==1 if unsatisfiable. don't even try to solve. */
|
|
|
|
|
uchar scratched; /* <0 if error happened, state undefined */
|
|
|
|
|
|
|
|
|
|
SATBlock bl[2]; /* two doubly linked list heads: list bl[0] contains user clauses, list bl[1] contains learned clauses */
|
|
|
|
|
SATBlock *lastbl; /* the last block we added a learned clause to */
|
|
|
|
|
SATClause *cl; /* all clauses are linked together; this is the first user clause */
|
|
|
|
|
SATClause *learncl; /* first learned clause */
|
|
|
|
|
SATClause **lastp[2]; /* this points towards the last link in each linked list */
|
|
|
|
|
int ncl; /* total number of clauses */
|
|
|
|
|
int ncl0; /* number of user clauses */
|
|
|
|
|
SATVar *var; /* all variables (array with nvar elements) */
|
|
|
|
|
SATLit *lit; /* all literals (array with 2*nvar elements) */
|
|
|
|
|
int nvar;
|
|
|
|
|
int nvaralloc; /* space allocated for variables */
|
|
|
|
|
int *trail; /* the trail contains all literals currently assumed true */
|
|
|
|
|
int ntrail;
|
|
|
|
|
int *decbd; /* decision boundaries. trail[decbd[i]] has the first literal of level i */
|
|
|
|
|
int lvl; /* current decision level */
|
|
|
|
|
SATVar **heap; /* binary heap with free variables, sorted by activity (nonfree variables are removed lazily and so may also be in it) */
|
|
|
|
|
int nheap;
|
|
|
|
|
|
|
|
|
|
uint *lvlstamp; /* used to "stamp" levels during conflict resolution and purging */
|
|
|
|
|
uint stamp; /* current "stamp" counter */
|
|
|
|
|
|
|
|
|
|
int forptr; /* trail[forptr] is the first literal we haven't explored the implications of yet */
|
|
|
|
|
int binptr; /* ditto for binary implications */
|
|
|
|
|
|
|
|
|
|
int *cflcl; /* during conflict resolution we build the learned clause in here */
|
|
|
|
|
int ncflcl;
|
|
|
|
|
int cflclalloc; /* space allocated for cflcl */
|
|
|
|
|
int cfllvl; /* the maximum level of the literals in cflcl, cflcl[0] excluded */
|
|
|
|
|
int cflctr; /* number of unresolved literals during conflict resolution */
|
|
|
|
|
|
|
|
|
|
double Δactivity; /* activity increment for variables */
|
|
|
|
|
double Δclactivity; /* activity increment for clauses */
|
|
|
|
|
|
|
|
|
|
uvlong conflicts; /* total number of conflicts so far */
|
|
|
|
|
|
|
|
|
|
uvlong nextpurge; /* purge happens when conflicts >= nextpurge */
|
|
|
|
|
uint purgeival; /* increment for nextpurge */
|
|
|
|
|
/* during a purge we do a "full run", assigning all variables and recording conflicts rather than resolving them */
|
|
|
|
|
SATConflict *fullrcfl; /* conflicts found thus */
|
|
|
|
|
int nfullrcfl;
|
|
|
|
|
int fullrlvl; /* minimum cfllvl for conflicts found during purging */
|
|
|
|
|
int *fullrlits; /* literals implied by conflicts at level fullrlvl */
|
|
|
|
|
int nfullrlits;
|
|
|
|
|
int rangecnt[256]; /* number of clauses with certain range values */
|
|
|
|
|
|
|
|
|
|
u64int nextflush; /* flush happens when conflicts >= nextflush */
|
|
|
|
|
u32int flushu, flushv, flushθ; /* variables for flush scheduling algorithm */
|
|
|
|
|
u32int agility; /* agility is a measure how quickly variables are being flipped. high agility inhibits flushes */
|
|
|
|
|
|
|
|
|
|
void *scrap; /* auxiliary memory that may need to be freed after a fatal error */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
SATSolve *satnew(void);
|
|
|
|
|
SATSolve *satadd1(SATSolve *, int *, int);
|
|
|
|
|
SATSolve *sataddv(SATSolve *, ...);
|
|
|
|
|
SATSolve *satrange1(SATSolve *, int *, int, int, int);
|
|
|
|
|
SATSolve *satrangev(SATSolve *, int, int, ...);
|
|
|
|
|
int satsolve(SATSolve *);
|
|
|
|
|
int satmore(SATSolve *);
|
|
|
|
|
int satval(SATSolve *, int);
|
|
|
|
|
void satfree(SATSolve *);
|
|
|
|
|
void satreset(SATSolve *);
|
2018-03-28 20:36:04 +00:00
|
|
|
|
int satget(SATSolve *, int, int *, int);
|
2018-04-24 11:20:07 +00:00
|
|
|
|
void satvafix(va_list);
|