1 /*-------------------------------------------------------------------------*/
2 /* Copyright 2010-2014 Armin Biere Johannes Kepler University Linz Austria */
3 /*-------------------------------------------------------------------------*/
7 /*-------------------------------------------------------------------------*/
18 #include <sys/resource.h>
22 /*-------------------------------------------------------------------------*/
36 /*-------------------------------------------------------------------------*/
38 #define REMOVED INT_MAX
39 #define NOTALIT ((INT_MAX >> RMSHFT))
40 #define MAXVAR ((INT_MAX >> RMSHFT) - 2)
43 #define POW2GLUE (1 << GLUESHFT)
44 #define MAXGLUE (POW2GLUE - 1)
45 #define GLUEMASK (POW2GLUE - 1)
46 #define MAXREDLIDX ((1 << (31 - GLUESHFT)) - 2)
47 #define MAXIRRLIDX ((1 << (31 - RMSHFT)) - 2)
53 #define FUNQUADS (1<<(FUNVAR - 6))
54 #define FALSECNF (1ll<<32)
58 #define EXPMIN (0x0000 ## 0000)
59 #define EXPZRO (0x1000 ## 0000)
60 #define EXPMAX (0x7fff ## ffff)
61 #define MNTBIT (0x0000 ## 0001 ## 0000 ## 0000 ## ull)
62 #define MNTMAX (0x0000 ## 0001 ## ffff ## ffff ## ull)
63 #define FLTMIN (0x0000 ## 0000 ## 0000 ## 0000 ## ll)
64 #define FLTMAX (0x7fff ## ffff ## ffff ## ffff ## ll)
66 #define LGL_SCORE_AVG 4
67 #define LGL_SCORE_EVSIDS 5
68 #define LGL_SCORE_VSIDS256 6
69 #define LGL_SCORE_FAVG 7
72 #define MAXSCOREXP (1<<30)
74 #define MAXSCOREXP (1<<9)
77 #define DEFSCOREXP 500
84 /*------------------------------------------------------------------------*/
86 /*------------------------------------------------------------------------*/
88 #define MAPLOGLEVEL(LEVEL) (LEVEL)
90 #define LOG(LEVEL,FMT,ARGS...) \
92 if (MAPLOGLEVEL(LEVEL) > lgl->opts->log.val) break; \
93 lglogstart (lgl, MAPLOGLEVEL(LEVEL), FMT, ##ARGS); \
97 #define LOGCLS(LEVEL,CLS,FMT,ARGS...) \
100 if (MAPLOGLEVEL(LEVEL) > lgl->opts->log.val) break; \
101 lglogstart (lgl, MAPLOGLEVEL(LEVEL), FMT, ##ARGS); \
102 for (P = (CLS); *P; P++) fprintf (lgl->out, " %d", *P); \
106 #define LOGMCLS(LEVEL,CLS,FMT,ARGS...) \
109 if (MAPLOGLEVEL(LEVEL) > lgl->opts->log.val) break; \
110 lglogstart (lgl, MAPLOGLEVEL(LEVEL), FMT, ##ARGS); \
111 for (P = (CLS); *P; P++) fprintf (lgl->out, " %d", lglm2i (lgl, *P)); \
115 #define LOGRESOLVENT(LEVEL,FMT,ARGS...) \
118 if (MAPLOGLEVEL(LEVEL) > lgl->opts->log.val) break; \
119 lglogstart (lgl, MAPLOGLEVEL(LEVEL), FMT, ##ARGS); \
120 for (P = lgl->resolvent.start; P < lgl->resolvent.top; P++) \
121 fprintf (lgl->out, " %d", *P); \
125 #define LOGREASON(LEVEL,LIT,REASON0,REASON1,FMT,ARGS...) \
127 int TAG, TMP, RED, G; \
128 const int * C, * P; \
129 if (MAPLOGLEVEL(LEVEL) > lgl->opts->log.val) break; \
130 lglogstart (lgl, MAPLOGLEVEL(LEVEL), FMT, ##ARGS); \
131 TMP = (REASON0 >> RMSHFT); \
132 RED = (REASON0 & REDCS); \
133 TAG = (REASON0 & MASKCS); \
134 if (TAG == DECISION) fputs (" decision", lgl->out); \
135 else if (TAG == UNITCS) fprintf (lgl->out, " unit %d", LIT); \
136 else if (TAG == BINCS) { \
138 " %s binary clause %d %d", lglred2str (RED), LIT, TMP); \
139 } else if (TAG == TRNCS) { \
140 fprintf (lgl->out, " %s ternary clause %d %d %d", \
141 lglred2str (RED), LIT, TMP, REASON1); \
143 assert (TAG == LRGCS); \
144 C = lglidx2lits (lgl, RED, REASON1); \
145 for (P = C; *P; P++) \
147 fprintf (lgl->out, " size %ld", (long)(P - C)); \
149 G = (REASON1 & GLUEMASK); \
150 fprintf (lgl->out, " glue %d redundant", G); \
151 } else fputs (" irredundant", lgl->out); \
152 fputs (" clause", lgl->out); \
153 for (P = C; *P; P++) { \
154 fprintf (lgl->out, " %d", *P); \
160 #define LOGDSCHED(LEVEL,LIT,FMT,ARGS...) \
163 if (MAPLOGLEVEL(LEVEL) > lgl->opts->log.val) break; \
164 POS = *lgldpos (lgl, LIT); \
165 lglogstart (lgl, MAPLOGLEVEL(LEVEL), "dsched[%d] = %d ", POS, LIT); \
166 printf (FMT, ##ARGS); \
167 printf (" score %s", lglscr2str (lgl, lglqvar (lgl, LIT)->score)); \
171 #define LOGESCHED(LEVEL,LIT,FMT,ARGS...) \
175 if (MAPLOGLEVEL(LEVEL) > lgl->opts->log.val) break; \
176 POS = *lglepos (lgl, LIT); \
177 EV = lglevar (lgl, LIT); \
178 lglogstart (lgl, MAPLOGLEVEL(LEVEL), "esched[%d] = %d ", POS, LIT); \
179 fprintf (lgl->out, FMT, ##ARGS); \
180 fprintf (lgl->out, " score"); \
181 fprintf (lgl->out, " occ %d %d", EV->occ[0], EV->occ[1]); \
185 #define LOGEQN(LEVEL,EQN,FMT,ARGS...) \
187 const int * P, * START; \
188 if (MAPLOGLEVEL(LEVEL) > lgl->opts->log.val) break; \
189 lglogstart (lgl, MAPLOGLEVEL(LEVEL), FMT, ##ARGS); \
190 START = lgl->gauss->xors.start + (EQN); \
191 assert (START < lgl->gauss->xors.top); \
192 for (P = START; *P > 1; P++) fprintf (lgl->out, " %d", *P); \
193 fprintf (lgl->out, " = %d", *P); \
197 /*------------------------------------------------------------------------*/
198 #else /* end of then start of else part of 'ifndef NLGLOG' */
199 /*------------------------------------------------------------------------*/
201 #define LOG(ARGS...) do { } while (0)
202 #define LOGCLS(ARGS...) do { } while (0)
203 #define LOGMCLS(ARGS...) do { } while (0)
204 #define LOGRESOLVENT(ARGS...) do { } while (0)
205 #define LOGREASON(ARGS...) do { } while (0)
206 #define LOGDSCHED(ARGS...) do { } while (0)
207 #define LOGESCHED(ARGS...) do { } while (0)
208 #define LOGEQN(ARGS...) do { } while (0)
210 /*------------------------------------------------------------------------*/
211 #endif /* end of else part of 'ifndef NLGLOG' */
212 /*------------------------------------------------------------------------*/
214 #define ABORTIF(COND,FMT,ARGS...) \
216 if (!(COND)) break; \
217 fprintf (stderr, "*** API usage error of '%s' in '%s'", \
218 __FILE__, __FUNCTION__); \
219 if (lgl && lgl->tid >= 0) fprintf (stderr, " (tid %d)", lgl->tid); \
220 fputs (": ", stderr); \
221 fprintf (stderr, FMT, ##ARGS); \
222 fputc ('\n', stderr); \
228 // Useful for using our 'sleeponabort' and other hooks 'on abort' ...
231 #define ASSERT(COND) \
235 "liblgl.a: %s:%d: %s: Lingeling Assertion `%s' failed.", \
236 __FUNCTION__, __LINE__, __FILE__, # COND); \
237 if (lgl && lgl->tid >= 0) fprintf (stderr, " (tid %d)", lgl->tid); \
238 fputc ('\n', stderr); \
244 #define ASSERT(COND) do { } while (0)
247 #define COVER(COND) \
249 if (!(COND)) break; \
251 "liblgl.a: %s:%d: %s: Coverage target `%s' reached.", \
252 __FUNCTION__, __LINE__, __FILE__, # COND); \
253 if (lgl && lgl->tid >= 0) fprintf (stderr, " (tid %d)", lgl->tid); \
254 fputc ('\n', stderr); \
256 abort (); /* TODO: why not 'lglabort' */ \
261 ABORTIF (!lgl, "uninitialized manager"); \
264 #define REQINITNOTFORKED() \
267 ABORTIF (lgl->forked, "forked manager"); \
270 #define REQUIRE(STATE) \
273 ABORTIF(!(lgl->state & (STATE)), "!(%s)", #STATE); \
276 #define TRANS(STATE) \
278 assert (lgl->state != STATE); \
279 LOG (1, "transition to state " #STATE); \
280 lgl->state = STATE; \
283 /*------------------------------------------------------------------------*/
285 #if !defined(NDEBUG) || !defined(NLGLOG)
289 /*------------------------------------------------------------------------*/
291 #define TRAPI(MSG,ARGS...) \
293 if (!lgl->apitrace) break; \
294 lgltrapi (lgl, MSG, ##ARGS); \
297 #define LGLCHKACT(ACT) \
298 do { assert (NOTALIT <= (ACT) && (ACT) < REMOVED - 1); } while (0)
300 /*------------------------------------------------------------------------*/
302 #define OPT(SHRT,LNG,VAL,MIN,MAX,DESCRP) \
304 Opt * opt = &lgl->opts->LNG; \
307 opt->dflt = opt->val = VAL; \
308 assert (MIN <= VAL); \
310 assert (VAL <= MAX); \
312 opt->descrp = DESCRP; \
313 lglgetenv (lgl, opt, #LNG); \
316 /*------------------------------------------------------------------------*/
319 do { (P) = lglnew (lgl, (N) * sizeof *(P)); } while (0)
322 do { lgldel (lgl, (P), (N) * sizeof *(P)); (P) = 0; } while (0)
325 do { (P) = lglrsz (lgl, (P), (O)*sizeof*(P), (N)*sizeof*(P)); } while (0)
328 do { memset ((P), 0, (N) * sizeof *(P)); } while (0)
331 do { memset ((P), 0, sizeof *(P)); } while (0)
334 do { memset (&(P), 0, sizeof (P)); } while (0)
336 /*------------------------------------------------------------------------*/
338 #define SWAP(TYPE,A,B) \
339 do { TYPE TMP = (A); (A) = (B); (B) = TMP; } while (0)
343 #define CMPSWAP(TYPE,CMP,P,Q) \
344 do { if (CMP (&(P), &(Q)) > 0) SWAP (TYPE, P, Q); } while(0)
346 #define QPART(TYPE,CMP,A,L,R) \
353 while (CMP (&(A)[++I], &PIVOT) < 0) \
355 while (CMP (&PIVOT, &(A)[--J]) < 0) \
356 if (J == (L)) break; \
358 SWAP (TYPE, (A)[I], (A)[J]); \
360 SWAP (TYPE, (A)[I], (A)[R]); \
363 #define QSORT(TYPE,CMP,A,N) \
365 int L = 0, R = (N) - 1, M, LL, RR, I; \
366 assert (lglmtstk (&lgl->sortstk)); \
367 if (R - L <= ISORTLIM) break; \
370 SWAP (TYPE, (A)[M], (A)[R - 1]); \
371 CMPSWAP (TYPE, CMP, (A)[L], (A)[R - 1]); \
372 CMPSWAP (TYPE, CMP, (A)[L], (A)[R]); \
373 CMPSWAP (TYPE, CMP, (A)[R - 1], (A)[R]); \
374 QPART (TYPE, CMP, (A), L + 1, R - 1); \
375 if (I - L < R - I) { LL = I + 1; RR = R; R = I - 1; } \
376 else { LL = L; RR = I - 1; L = I + 1; } \
377 if (R - L > ISORTLIM) { \
378 assert (RR - LL > ISORTLIM); \
379 lglpushstk (lgl, &lgl->sortstk, LL); \
380 lglpushstk (lgl, &lgl->sortstk, RR); \
381 } else if (RR - LL > ISORTLIM) L = LL, R = RR; \
382 else if (!lglmtstk (&lgl->sortstk)) { \
383 R = lglpopstk (&lgl->sortstk); \
384 L = lglpopstk (&lgl->sortstk); \
389 #define ISORT(TYPE,CMP,A,N) \
392 int L = 0, R = (N) - 1, I, J; \
393 for (I = R; I > L; I--) \
394 CMPSWAP (TYPE, CMP, (A)[I - 1], (A)[I]); \
395 for (I = L + 2; I <= R; I++) { \
398 while (CMP (&PIVOT, &(A)[J - 1]) < 0) { \
399 (A)[J] = (A)[J - 1]; \
407 #define CHKSORT(CMP,A,N) do { } while(0)
409 #define CHKSORT(CMP,A,N) \
412 for (I = 0; I < (N) - 1; I++) \
413 assert (CMP (&(A)[I], &(A)[I + 1]) <= 0); \
417 #define SORT(TYPE,A,N,CMP) \
421 QSORT (TYPE, CMP, AA, NN); \
422 ISORT (TYPE, CMP, AA, NN); \
423 CHKSORT (CMP, AA, NN); \
426 /*------------------------------------------------------------------------*/
428 #define LGLPOPWTK(WTK,WRAG,LIT,OTHER,RED,REMOVED) \
430 assert (!lglmtwtk (WTK)); \
432 (WRAG) = (WTK)->top->wrag; \
433 (LIT) = (WTK)->top->lit; \
434 (OTHER) = (WTK)->top->other; \
435 (RED) = (WTK)->top->red ? REDCS : 0; \
436 (REMOVED) = (WTK)->top->removed; \
439 /*------------------------------------------------------------------------*/
441 #define CLONE(FIELD,SIZE) \
443 NEW (lgl->FIELD, (SIZE)); \
444 memcpy (lgl->FIELD, orig->FIELD, (SIZE) * sizeof *(lgl->FIELD)); \
447 #define CLONESTK(NAME) \
449 size_t COUNT = orig->NAME.top - orig->NAME.start; \
450 size_t SIZE = orig->NAME.end - orig->NAME.start; \
451 size_t BYTES = SIZE * sizeof *lgl->NAME.start; \
452 NEW (lgl->NAME.start, SIZE); \
453 memcpy (lgl->NAME.start, orig->NAME.start, BYTES); \
454 lgl->NAME.top = lgl->NAME.start + COUNT; \
455 lgl->NAME.end = lgl->NAME.start + SIZE; \
458 /*------------------------------------------------------------------------*/
460 #define INCSTEPS(NAME) \
461 ((lgl->stats->steps++), (lgl->stats->NAME++))
463 #define ADDSTEPS(NAME,INC) \
464 ((lgl->stats->steps += INC), (lgl->stats->NAME += INC))
466 /*------------------------------------------------------------------------*/
468 #define LGLUPDPEN(NAME,SUCCESS) \
470 assert (!lgl->limits->NAME.del.rem); \
471 if ((SUCCESS) && lgl->limits->NAME.pen) \
472 lgl->limits->NAME.pen--; \
473 if (!(SUCCESS) && lgl->limits->NAME.pen < lgl->opts->penmax.val) \
474 lgl->limits->NAME.pen++; \
475 if ((SUCCESS) && lgl->limits->NAME.del.cur) \
476 lgl->limits->NAME.del.cur /= 2; \
477 if (!(SUCCESS) && lgl->limits->NAME.del.cur < lgl->opts->delmax.val) \
478 lgl->limits->NAME.del.cur++; \
479 lgl->limits->NAME.del.rem = lgl->limits->NAME.del.cur; \
482 /*-------------------------------------------------------------------------*/
484 #define LGLL long long
486 /*-------------------------------------------------------------------------*/
514 UNSATISFIED = (1<<7),
527 typedef enum GTag { ANDTAG, ITETAG, XORTAG } GTag;
529 /*------------------------------------------------------------------------*/
533 const char * lng, * descrp;
534 int val, min, max, dflt;
537 typedef struct Opts {
588 Opt bumpseenaftermin;
589 Opt bumpseenbeforemin;
759 Opt prbsimpleliftdepth;
879 #define FIRSTOPT(lgl) (&(lgl)->opts->beforefirst + 1)
880 #define LASTOPT(lgl) (&(lgl)->opts->afterlast - 1)
882 /*------------------------------------------------------------------------*/
885 typedef uint64_t Mnt;
888 typedef uint64_t Fun[FUNQUADS];
889 typedef signed char Val;
892 /*------------------------------------------------------------------------*/
898 /*------------------------------------------------------------------------*/
900 typedef struct Conf { int lit, rsn[2]; } Conf;
901 typedef struct Ctk { struct Ctr * start, * top, * end; } Ctk;
902 typedef struct DFOPF { int observed, pushed, flag; } DFOPF;
903 typedef struct DFPR { int discovered, finished, parent, root; } DFPR;
904 typedef struct EVar { int occ[2], pos, score; } EVar;
905 typedef struct Ftk { Flt * start, * top, * end; } Ftk;
906 typedef struct HTS { int offset, count; } HTS;
907 typedef struct ITEC { int other, other2; } ITEC;
908 typedef struct Lim { int64_t confs, decs, props; } Lim;
909 typedef struct PASL { int psm, act, size, lidx; } PASL;
910 typedef struct PSz { int pos, size; } PSz;
911 typedef struct Qnd { int prev, next; struct Qln * line; } Qnd;
912 typedef struct RNG { unsigned z, w; } RNG;
913 typedef struct Stk { int * start, * top, * end; } Stk;
914 typedef struct Tmrs { double phase[MAXPHN]; int idx[MAXPHN], nest; } Tmrs;
915 typedef struct Trv { void * state; void (*trav)(void *, int); } Trv;
916 typedef struct TVar { signed int val : 30; unsigned mark : 2; } TVar;
917 typedef struct Wtk { struct Work * start, * top, * end; } Wtk;
919 /*------------------------------------------------------------------------*/
922 signed int decision : 31;
926 typedef struct DVar { HTS hts[2]; } DVar;
928 typedef struct QVar { Scr score; int pos; } QVar;
932 unsigned lrglue:1, irr:1;
936 typedef struct ID { int level, lit, rsn[2]; } ID;
938 typedef struct Impls { ID * start, * top, * end; } Impls;
940 typedef struct AVar {
943 unsigned simp:1, wasfalse:1;
945 unsigned equiv:1, lcamark:4;
946 signed int phase:2, bias:2, fase:2;
947 unsigned inred:2, poisoned:1, assumed:2, failed:2, gate:1;
948 unsigned donotelm:1, donotblk:1, donotcgrcls:1, donotlft:1, donoternres:1;
949 unsigned donotbasicprobe:1, donotsimpleprobe:1, donotreelook:1, mega:2;
951 signed int locsval:2;
957 unsigned equiv:1,melted:1,blocking:2,eliminated:1,tmpfrozen:1,imported:1;
958 unsigned assumed:2,failed:2,internal:1,defined:1;
959 signed int val:2, oldval:2;
963 typedef struct Work {
965 signed int lit : 30, other : 30;
966 unsigned red : 1, removed : 1;
970 int discovered, finished;
971 union { int lit, sign; };
981 signed int size : 29;
984 struct { int * cls, origlhs; };
985 struct { int cond, pos, neg; };
989 /*------------------------------------------------------------------------*/
991 typedef struct Stats {
992 int64_t steps, trims;
993 int defrags, iterations, acts, reported, repcntdown, gcs, decomps;
995 struct { int64_t count, steps; struct { int max, min; } mincut; } force;
996 struct { int clauses, vars; } rescored;
998 struct {int64_t scaled, orig; } intsum;
999 struct { int count, saturating, agile, reuse; } skipped;
1000 struct { int count; int64_t sum; } kept; } restarts;
1001 struct { int count, reset, geom, gul, arith, arith2, memlim; } reduced;
1002 int64_t prgss, irrprgss, enlwchs, pshwchs, height, dense, sparse;
1003 int64_t confs, decisions, randecs, randecsflipped, flipped, fliphases;
1004 int64_t uips, decflipped;
1005 struct { struct { int cur, max; int64_t add; } clauses, lits; } irr;
1006 struct { int64_t sat, mosat, simp, deref, fixed, freeze, lkhd;
1007 int64_t melt, add, assume, cassume, failed, repr; } calls;
1008 struct { int64_t search, hits; } poison;
1009 struct { int64_t search, simp, lkhd; } props, visits, travs;
1010 struct { size_t current, max; } bytes;
1011 struct { int bin, trn, lrg; } red;
1012 struct { int cnt, simple, trn, lrg, sub; } hbr;
1013 struct { int current, sum; } fixed, equiv;
1014 struct { int count, bin, trn; int64_t steps; } trnr;
1015 struct { int count, clauses, lits, pure; int64_t res, steps; } blk;
1016 struct { int count, eq, units; int64_t esteps, csteps;
1017 struct { int all, and, xor, ite; } matched;
1018 struct { int all, and, xor, ite; } simplified;
1019 struct { int64_t all, and, xor, ite; } extracted; } cgr;
1021 struct { int count, failed, eqs; int64_t probed, steps; } simple;
1022 struct { int count, failed, lifted;
1023 int64_t probed, steps, lastate;
1024 struct { int trnr, lrg, count; } ate; } basic;
1025 struct { int count, failed, lifted; int64_t probed, steps; } treelook;
1027 struct { int count, eqs, units, impls; int64_t probed0, probed1; } lift;
1028 struct { int count, red, failed; int64_t lits, bins, steps; } trd;
1029 struct { int removed, red; } bindup;
1030 struct { int count, rounds;
1031 struct { int trds, failed, sccs; int64_t sumsccsizes; } stamp;
1032 struct { int lits, bin, trn, lrg; } failed;
1033 struct { int bin, trn, lrg, red; } tauts;
1034 struct { int bin, trn, lrg; } units;
1035 struct { int trn, lrg, red; } hbrs;
1036 struct { int trn, lrg, red; } str;
1037 int64_t steps; } unhd;
1039 int count, elmd, large, sub, str, blkd, rounds;
1040 struct { int elm, tried, failed; } small;
1041 int64_t resolutions, copies, subchks, strchks, ipos, steps; } elm;
1043 int sub2, sub3, subl, str2, str3, str3self, strl, strlself;
1044 struct { int64_t lits, clauses, occs; } tried;
1048 struct { struct { int irr, red; } dyn; } sub, str;
1049 int64_t driving, restarting; } otfs;
1050 struct { int64_t nonmin, learned; } lits;
1052 int64_t learned, glue, realglue, nonmaxglue, maxglue, scglue; }
1056 int64_t added, reduced, resolved, forcing, conflicts, saved;
1058 struct { int64_t sum; int count; } glues;
1059 struct { int count; int64_t set, pos, neg; } phase;
1060 struct { int count; struct { int confs, irr, vars; } limhit; } simp;
1061 struct { int count; int64_t steps; } luby, inout;
1062 struct { int count, gcs, units, equivs, trneqs;
1063 struct { int max; int64_t sum; } arity;
1064 struct { int64_t extr, elim; } steps;
1065 int64_t extracted; } gauss;
1066 struct { int count, eliminated, ate, abce, failed, lifted;
1067 int64_t steps, probed;
1068 struct { int64_t search, hits, cols, ins, rsz; } cache; } cce;
1069 struct { int count, failed, lifted; int64_t decisions, steps; } cliff;
1071 int count, units, expam1, resched;
1072 int64_t steps, eliminated, resolved, subsumed;
1073 struct { struct { int64_t sum, cnt; } found, used; } am1, am2; } card;
1074 struct { int64_t bin, trn, lrg; } moved;
1075 struct { int count, inc; } rephase;
1076 struct { int count; int64_t added, skipped, steps; } bca;
1077 struct { int count; int64_t added, removed; } bva;
1081 struct { int64_t actual, tried, calls; } consumed;
1084 struct { struct { int64_t orig, red; } sum; } deco;
1085 struct { int64_t min, bin, size, deco; } mincls;
1086 int64_t drupped, druplig;
1088 int64_t count, units, bin, trn, steps, elim, res;
1089 struct { int64_t bound, len, model; } limhit; } rdp;
1090 struct { int64_t count, tried, cands, sub; } subl;
1091 struct { int count; int64_t flips, mems; int min; } locs;
1092 struct { int count; } tabr;
1093 struct { int count, failed, lifted, eqs, rounds; } mega;
1096 /*------------------------------------------------------------------------*/
1098 typedef struct Times {
1099 double all, dcp, elm, trd, gc, dfg, red, blk, ana, unhd, dec, lkhd;
1100 double rsts, lft, trn, cgr, phs, srch, prep, inpr, bump, mcls, gauss;
1101 double card, cce, cliff, ctw, force, bca, rdp, locs, bkwd, bva, tabr;
1103 struct { double all, simple, basic, treelook; } prb;
1106 /*------------------------------------------------------------------------*/
1108 typedef struct Del { int cur, rem; } Del;
1110 typedef struct Limits {
1111 int flipint, lkhdpen;
1112 int64_t randec, dfg;
1115 struct { int64_t add; int start; } clauses;
1116 struct { int start; } vars;
1118 struct { int clauses, vars; } tabr;
1119 struct { int inner, outer, extra; } reduce;
1120 struct { struct { int64_t otfs, confs; } vars; } rescore;
1121 struct { int pen; Del del; int64_t esteps, csteps; } cgr;
1122 struct { int pen; Del del; int64_t steps, irrprgss; } elm, blk, cliff;
1123 struct { int pen; Del del; int64_t steps; }
1124 rdp, trd, unhd, trnr, lft, cce, card;
1125 struct { int pen; Del del; struct { int64_t extr, elim; } steps; } gauss;
1126 struct { int64_t confs; } rephase;
1127 struct { int64_t confs; int wasmaxdelta, maxdelta, luby, inout; } restart;
1128 struct { int64_t steps;
1129 struct { int pen; Del del; } simple, basic, treelook; } prb;
1130 struct { int64_t vars, confs; int pen, cinc; } simp;
1131 struct { int64_t steps, confs; } sync;
1132 struct { int64_t steps; } term;
1133 struct { int64_t fixed; } gc;
1134 struct { Del del; int64_t steps; } bca;
1135 struct { int64_t steps, time; } trep;
1136 struct { int64_t confs, inc; int vars; } locs;
1139 /*------------------------------------------------------------------------*/
1141 typedef struct Cbs {
1142 struct { int (*fun)(void*); void * state; int done; } term;
1144 struct { void (*fun)(void*,int); void * state; } produce, consumed;
1145 struct { void(*fun)(void*,int**,int**); void*state; } consume;
1148 struct { void (*fun)(void*,int*,int); void * state; } produce;
1149 struct { void(*fun)(void*,int**,int*); void*state; } consume;
1150 struct { void (*fun)(void*,int); void * state; } consumed;
1153 struct { int * (*fun)(void*); void * state; } lock;
1154 struct { void (*fun)(void*,int,int); void * state; } unlock;
1156 struct { void(*lock)(void*); void (*unlock)(void*); void*state; } msglock;
1157 double (*getime)(void);
1158 void (*onabort)(void *); void * abortstate;
1161 typedef struct Cgr {
1162 struct { int units, eq, all, and, xor, ite, org; } extracted;
1163 struct { int all, and, xor, ite, org; } simplified;
1164 struct { int all, and, xor, ite, org; } matched;
1165 Stk * goccs, units; Gat * gates; int szgates;
1168 typedef struct Cliff { Stk lift, lits; } Cliff;
1170 typedef struct BCA { Stk covered; } BCA;
1172 typedef struct Dis { struct { Stk bin, trn; } red, irr; } Dis;
1174 typedef struct Elm {
1176 int pivot, negcls, necls, neglidx, round, oldelmd;
1177 Stk lits, next, clv, csigs, sizes, occs, noccs, mark, m2i;
1180 typedef struct RDP {
1181 int * count, eliminated;
1186 typedef struct Card {
1187 Stk atmost1, atmost2, cards, elim, * occs, units, expam1;
1188 char * eliminated, * lit2used, * marked;
1189 signed char * count;
1193 typedef struct FltStr { int current; char str[MAXFLTSTR][100]; } FltStr;
1195 typedef struct SPE { signed int count : 31; unsigned mark : 1, sum; } SPE;
1197 typedef struct SPrb {
1198 Stk units, impls, eqs, counted, marked;
1202 typedef struct Gauss {
1203 Stk xors, order, * occs;
1204 signed char * eliminated;
1208 typedef struct CCE {
1209 Stk cla, extend, clauses;
1210 int * rem, bin, trn;
1213 typedef struct Tlk { Stk stk, seen; TVar * tvars; LKHD * lkhd; } Tlk;
1215 typedef struct Mem {
1217 lglalloc alloc; lglrealloc realloc; lgldealloc dealloc;
1220 typedef struct Wchs { Stk stk; int start[MAXLDFW], free; } Wchs;
1222 typedef struct Wrk {
1224 int count, head, size, posonly, fifo, * pos;
1227 /*------------------------------------------------------------------------*/
1232 int probing, flipping, notflipped, tid, tids, bias, phaseneg;
1233 int nvars, szvars, maxext, szext, maxdef, szdef, changed, mt, repcntdown;
1234 int szdrail, bnext, next, next2, flushed, level, alevel, wait;
1235 int unassigned, lrgluereasons, failed, assumed, cassumed, ncassumed;
1237 Scr scinc, scincf, maxscore;
1239 char lifting, cceing, gaussing, cliffing, bcaing, forcerephead;
1240 char cgrclosing, searching, simp, allphaseset, flushphases, occs;
1241 char unhiding, basicprobing, simpleprobing, treelooking, setuponce;
1242 char eliminating, donotsched, blocking, ternresing, lkhd, allfrozen;
1243 char blkall, blkrem, blkrtc, elmall, elmrem, elmrtc, decomposing;
1244 char frozen, dense, notfullyconnected, forcegc, allowforce;
1245 char ccertc, elmstuck, blkstuck;
1250 unsigned long long flips;
1255 // the state above this line is copied during 'clone' with 'memcpy'
1276 Stk clause, eclause, extend, irr, trail, frames;
1277 Stk dsched, eassume, assume, cassume, fassume, learned;
1283 Elm * elm; Cgr * cgr; SPrb * sprb; Tlk * tlk; Gauss * gauss;
1284 CCE * cce; Cliff * cliff; BCA * bca; Card * card; RDP * rdp;
1286 union { Stk lcaseen, sortstk, resolvent; };
1287 Stk poisoned, seen, esched, minstk;
1294 FILE * out, * apitrace;
1301 #if !defined(NLGLPICOSAT)
1302 struct { PicoSAT * solver; int res; char chk; } picosat;
1304 #if !defined(NLGLDRUPLIG)
1309 /*-------------------------------------------------------------------------*/
1311 #define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
1313 static const char lglfloorldtab[256] =
1315 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1316 -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
1317 LT(4), LT(5), LT(5), LT(6), LT(6), LT(6), LT(6),
1318 LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7)
1321 static const uint64_t lglbasevar2funtab[6] = {
1322 0xaaaaaaaaaaaaaaaaull, 0xccccccccccccccccull, 0xf0f0f0f0f0f0f0f0ull,
1323 0xff00ff00ff00ff00ull, 0xffff0000ffff0000ull, 0xffffffff00000000ull,
1326 /*-------------------------------------------------------------------------*/
1328 static int lglfloorld (int n) {
1330 if (n < (1<<8)) return lglfloorldtab[n];
1331 if (n < (1<<16)) return 8 + lglfloorldtab[n>>8];
1332 if (n < (1<<24)) return 16 + lglfloorldtab[n>>16];
1333 return 24 + lglfloorldtab[n>>24];
1336 static int lglispow2 (int n) {
1337 assert (0 <= n && n <= INT_MAX);
1338 return !(n & (n - 1));
1341 static int lglceilld (int n) {
1342 int res = lglfloorld (n);
1343 if (!lglispow2 (n)) res++;
1347 static int lglceilsqrt32 (int x) {
1348 int l = 0, m, r, mm, rr;
1352 if (x <= 0) return 0;
1353 r = 46340; rr = r*r;
1354 if (x >= rr) return r;
1357 assert (ll < x && x < rr);
1358 if (r - l == 1) return r;
1361 if (mm == x) return m;
1367 } else r = m, rr = mm;
1371 static int lglceilsqrt64 (int x) {
1372 int64_t l = 0, m, r, mm, rr;
1376 if (x <= 0) return 0;
1377 r = 3037000499ll; rr = r*r;
1378 if (x >= rr) return r;
1381 assert (ll < x && x < rr);
1382 if (r - l == 1) return r;
1385 if (mm == x) return m;
1391 } else r = m, rr = mm;
1395 static void lglchkflt (Flt a) {
1398 assert (FLTMAX >= (uint64_t) a);
1404 static Exp lglexp (Flt a) {
1405 Exp res = a >> FLTPRC;
1406 assert (0 <= res && res <= EXPMAX);
1411 static Mnt lglmnt (Flt a) {
1412 Mnt res = a & MNTMAX;
1414 assert (res <= MNTMAX);
1418 static Flt lglflt (Exp e, Mnt m) {
1420 if (!m) return FLTMIN;
1422 while (!(m & MNTBIT)) {
1424 if (e > INT_MIN) e--;
1428 while (m > MNTMAX) {
1430 if (e > INT_MIN) e++;
1434 if (e < -EXPZRO) return FLTMIN;
1435 if (e > EXPMAX - EXPZRO) return FLTMAX;
1437 assert (0 <= e && e <= EXPMAX);
1438 assert (m <= MNTMAX);
1439 assert (m & MNTBIT);
1441 res |= ((Flt)e) << FLTPRC;
1446 static Flt lglrat (unsigned n, unsigned d) {
1449 if (!n) return FLTMIN;
1450 if (!d) return FLTMAX;
1453 while (!(m & (1ull << 63))) m <<= 1, e--;
1455 return lglflt (e, m);
1460 double lglflt2dbl (Flt a) {
1461 return lglmnt (a) * pow (2.0, lglexp (a));
1466 static const char * lgll2str (LGL * lgl, Flt a) {
1467 assert (lgl->fltstr);
1468 lgl->fltstr->current++;
1469 if (lgl->fltstr->current == MAXFLTSTR) lgl->fltstr->current = 0;
1470 sprintf (lgl->fltstr->str[lgl->fltstr->current], "%lld", (LGLL) a);
1471 return lgl->fltstr->str[lgl->fltstr->current];
1475 static const char * lglflt2str (LGL * lgl, Flt a) {
1477 assert (lgl->fltstr);
1478 if (a == FLTMIN) return "0";
1479 if (a == FLTMAX) return "inf";
1484 lgl->fltstr->current++;
1485 if (lgl->fltstr->current == MAXFLTSTR) lgl->fltstr->current = 0;
1486 sprintf (lgl->fltstr->str[lgl->fltstr->current], "%.6fd%+03.0f", d, e);
1487 return lgl->fltstr->str[lgl->fltstr->current];
1490 static Flt lgladdflt (Flt a, Flt b) {
1495 if (a == FLTMAX) return FLTMAX;
1496 if (b == FLTMAX) return FLTMAX;
1497 if (a == FLTMIN) return b;
1498 if (b == FLTMIN) return a;
1501 if (e < f) g = e, e = f, f = g, o = a, a = b, b = o;
1505 return lglflt (e, m);
1508 static Flt lglmulflt (Flt a, Flt b) {
1513 if (a == FLTMAX) return FLTMAX;
1514 if (b == FLTMAX) return FLTMAX;
1515 if (a == FLTMIN) return FLTMIN;
1516 if (b == FLTMIN) return FLTMIN;
1517 ea = lglexp (a); eb = lglexp (b);
1518 if (ea > 0 && eb > 0 && (INT_MAX - ea < eb)) return FLTMAX;
1520 if (e > EXPMAX - EXPZRO - 32) return FLTMAX;
1522 ma = lglmnt (a); mb = lglmnt (b);
1525 assert (3ull << 62);
1527 return lglflt (e, m);
1531 static Flt lglshflt (Flt a, int s) {
1534 if (a == FLTMAX) return FLTMAX;
1535 if (a == FLTMIN) return FLTMIN;
1538 if (e < INT_MIN + s) return FLTMIN;
1541 return lglflt (e, m);
1545 /*------------------------------------------------------------------------*/
1548 static const char * lglscr2str (LGL * lgl, Scr scr) {
1549 if (lgl->opts->score.val == LGL_SCORE_EVSIDS ||
1550 lgl->opts->score.val == LGL_SCORE_AVG) return lglflt2str (lgl, scr);
1551 else return lgll2str (lgl, scr);
1554 static Scr lgladdscr (Scr a, Scr b) { return lgladdflt (a, b); }
1555 static Scr lglmulscr (Scr a, Scr b) { return lglmulflt (a, b); }
1557 #else /* !NDBLSCR */
1559 static const char * lgldbl2str (LGL * lgl, double d) {
1560 assert (lgl->fltstr);
1561 lgl->fltstr->current++;
1562 if (lgl->fltstr->current == MAXFLTSTR) lgl->fltstr->current = 0;
1563 sprintf (lgl->fltstr->str[lgl->fltstr->current], "%g", d);
1564 return lgl->fltstr->str[lgl->fltstr->current];
1567 static const char * lglscr2str (LGL * lgl, Scr scr) {
1568 return lgldbl2str (lgl, scr);
1571 static Scr lgladdscr (Scr a, Scr b) { return a + b; }
1572 static Scr lglmulscr (Scr a, Scr b) { return a * b; }
1575 /*------------------------------------------------------------------------*/
1577 static void lglwrn (LGL * lgl, const char * msg, ...) {
1579 fprintf (lgl->out, "*** warning in '%s': ", __FILE__);
1581 vfprintf (lgl->out, msg, ap);
1583 fputc ('\n', lgl->out);
1587 static void lgldie (LGL * lgl, const char * msg, ...) {
1589 fprintf (lgl->out, "*** internal error in '%s': ", __FILE__);
1591 vfprintf (lgl->out, msg, ap);
1593 fputc ('\n', lgl->out);
1598 static void lglabort (LGL * lgl) {
1600 if (lgl->opts && lgl->opts->sleeponabort.val) {
1602 "liblgl.a: Process %d will sleep for %d seconds "
1603 " before continuing with 'lglabort' procedure.\n",
1604 getpid (), lgl->opts->sleeponabort.val);
1605 sleep (lgl->opts->sleeponabort.val);
1607 if (lgl->cbs && lgl->cbs->onabort)
1608 lgl->cbs->onabort (lgl->cbs->abortstate);
1609 if (lgl->opts && lgl->opts->exitonabort.val) exit (1);
1613 static const char * lglprefix (LGL * lgl) {
1614 return lgl && lgl->prefix ? lgl->prefix : "c (LGL HAS NO PREFIX YET) ";
1617 static int lglmsgstart (LGL * lgl, int level) {
1619 if (lgl->opts->log.val <= 0)
1621 if (lgl->opts->verbose.val < level) return 0;
1622 if (lgl->cbs && lgl->cbs->msglock.lock)
1623 lgl->cbs->msglock.lock (lgl->cbs->msglock.state);
1624 fputs (lglprefix (lgl), lgl->out);
1625 if (lgl->tid >= 0) fprintf (lgl->out, "%d ", lgl->tid);
1629 static void lglmsgend (LGL * lgl) {
1630 fputc ('\n', lgl->out);
1632 if (lgl->cbs && lgl->cbs->msglock.unlock)
1633 lgl->cbs->msglock.unlock (lgl->cbs->msglock.state);
1636 static void lglprt (LGL * lgl, int level, const char * msg, ...) {
1639 if (lgl->opts->log.val <= 0)
1641 if (lgl->opts->verbose.val < level) return;
1642 lglmsgstart (lgl, level);
1644 vfprintf (lgl->out, msg, ap);
1650 static void lglogstart (LGL * lgl, int level, const char * msg, ...) {
1652 assert (lgl->opts->log.val >= level);
1653 if (lgl->cbs && lgl->cbs->msglock.lock)
1654 lgl->cbs->msglock.lock (lgl->cbs->msglock.state);
1655 fputs (lglprefix (lgl), lgl->out);
1656 if (lgl->tid >= 0) fprintf (lgl->out, "%d ", lgl->tid);
1657 fprintf (lgl->out, "LOG%d %d ", level, lgl->level);
1659 vfprintf (lgl->out, msg, ap);
1663 #define lglogend lglmsgend
1666 /*------------------------------------------------------------------------*/
1668 void lglsetid (LGL * lgl, int tid, int tids) {
1669 REQINITNOTFORKED ();
1670 ABORTIF (tid < 0, "negative id");
1671 ABORTIF (tid >= tids, "id exceed number of ids");
1676 /*------------------------------------------------------------------------*/
1678 static void lglinc (LGL * lgl, size_t bytes) {
1679 lgl->stats->bytes.current += bytes;
1680 if (lgl->stats->bytes.max < lgl->stats->bytes.current) {
1681 lgl->stats->bytes.max = lgl->stats->bytes.current;
1682 LOG (5, "maximum allocated %ld bytes", lgl->stats->bytes.max);
1686 static void lgldec (LGL * lgl, size_t bytes) {
1687 assert (lgl->stats->bytes.current >= bytes);
1688 lgl->stats->bytes.current -= bytes;
1691 static void * lglnew (LGL * lgl, size_t bytes) {
1693 if (!bytes) return 0;
1694 if (lgl->mem->alloc) res = lgl->mem->alloc (lgl->mem->state, bytes);
1695 else res = malloc (bytes);
1696 if (!res) lgldie (lgl, "out of memory allocating %ld bytes", bytes);
1698 LOG (5, "allocating %p with %ld bytes", res, bytes);
1699 lglinc (lgl, bytes);
1700 if (res) memset (res, 0, bytes);
1704 static void lgldel (LGL * lgl, void * ptr, size_t bytes) {
1705 if (!ptr) { assert (!bytes); return; }
1706 lgldec (lgl, bytes);
1707 LOG (5, "freeing %p with %ld bytes", ptr, bytes);
1708 if (lgl->mem->dealloc) lgl->mem->dealloc (lgl->mem->state, ptr, bytes);
1712 static void * lglrsz (LGL * lgl, void * ptr, size_t old, size_t new) {
1714 assert (!ptr == !old);
1715 if (!ptr) return lglnew (lgl, new);
1716 if (!new) { lgldel (lgl, ptr, old); return 0; }
1717 if (old == new) return ptr;
1719 if (lgl->mem->realloc)
1720 res = lgl->mem->realloc (lgl->mem->state, ptr, old, new);
1721 else res = realloc (ptr, new);
1723 lgldie (lgl, "out of memory reallocating %ld to %ld bytes", old, new);
1725 LOG (5, "reallocating %p to %p from %ld to %ld bytes", ptr, res, old, new);
1727 if (new > old) memset (res + old, 0, new - old);
1731 /*------------------------------------------------------------------------*/
1733 static char * lglstrdup (LGL * lgl, const char * str) {
1735 NEW (res, strlen (str) + 1);
1736 return strcpy (res, str);
1739 static void lgldelstr (LGL * lgl, char * str) {
1740 DEL (str, strlen (str) + 1);
1743 /*------------------------------------------------------------------------*/
1745 static void lglinitcbs (LGL * lgl) {
1746 if (!lgl->cbs) NEW (lgl->cbs, 1);
1749 void lglonabort (LGL * lgl, void * abortstate, void (*onabort)(void*)) {
1750 REQINITNOTFORKED ();
1752 lgl->cbs->abortstate = abortstate;
1753 lgl->cbs->onabort = onabort;
1756 void lglseterm (LGL * lgl, int (*fun)(void*), void * state) {
1757 REQINITNOTFORKED ();
1759 lgl->cbs->term.fun = fun;
1760 lgl->cbs->term.state = state;
1763 void lglsetproduceunit (LGL * lgl, void (*fun) (void*, int), void * state) {
1764 REQINITNOTFORKED ();
1766 lgl->cbs->units.produce.fun = fun;
1767 lgl->cbs->units.produce.state = state;
1770 void lglsetconsumeunits (LGL * lgl,
1771 void (*fun) (void*, int **, int **),
1773 REQINITNOTFORKED ();
1775 lgl->cbs->units.consume.fun = fun;
1776 lgl->cbs->units.consume.state = state;
1779 void lglsetconsumedunits (LGL * lgl,
1780 void (*fun) (void*, int), void * state) {
1781 REQINITNOTFORKED ();
1783 lgl->cbs->units.consumed.fun = fun;
1784 lgl->cbs->units.consumed.state = state;
1787 void lglsetproducecls (LGL * lgl,
1788 void (*fun) (void*, int *, int), void * state) {
1789 REQINITNOTFORKED ();
1791 lgl->cbs->cls.produce.fun = fun;
1792 lgl->cbs->cls.produce.state = state;
1795 void lglsetconsumecls (LGL * lgl,
1796 void (*fun) (void*, int **, int *),
1798 REQINITNOTFORKED ();
1800 lgl->cbs->cls.consume.fun = fun;
1801 lgl->cbs->cls.consume.state = state;
1804 void lglsetconsumedcls (LGL * lgl,
1805 void (*fun) (void*, int), void * state) {
1806 REQINITNOTFORKED ();
1808 lgl->cbs->cls.consumed.fun = fun;
1809 lgl->cbs->cls.consumed.state = state;
1812 void lglsetlockeq (LGL * lgl, int * (*fun)(void*), void * state) {
1813 REQINITNOTFORKED ();
1815 lgl->cbs->eqs.lock.fun = fun;
1816 lgl->cbs->eqs.lock.state = state;
1819 void lglsetunlockeq (LGL * lgl, void (*fun)(void*,int,int), void * state) {
1820 REQINITNOTFORKED ();
1822 lgl->cbs->eqs.unlock.fun = fun;
1823 lgl->cbs->eqs.unlock.state = state;
1826 void lglsetmsglock (LGL * lgl,
1827 void (*lock)(void*), void (*unlock)(void*),
1829 REQINITNOTFORKED ();
1831 lgl->cbs->msglock.lock = lock;
1832 lgl->cbs->msglock.unlock = unlock;
1833 lgl->cbs->msglock.state = state;
1836 void lglsetime (LGL * lgl, double (*time)(void)) {
1837 REQINITNOTFORKED ();
1839 lgl->cbs->getime = time;
1842 /*------------------------------------------------------------------------*/
1844 static int lglfullstk (Stk * s) { return s->top == s->end; }
1845 static int lglmtstk (Stk * s) { return s->top == s->start; }
1846 static size_t lglcntstk (Stk * s) { return s->top - s->start; }
1847 static size_t lglszstk (Stk * s) { return s->end - s->start; }
1849 static int lglpeek (Stk * s, int pos) {
1850 assert (0 <= pos && pos < lglszstk (s));
1851 return s->start[pos];
1854 static void lglpoke (Stk * s, int pos, int val) {
1855 assert (0 <= pos && pos <= lglszstk (s));
1856 s->start[pos] = val;
1859 static void lglenlstk (LGL * lgl, Stk * s) {
1860 size_t old_size = lglszstk (s);
1861 size_t new_size = old_size ? 2 * old_size : 1;
1862 size_t count = lglcntstk (s);
1863 RSZ (s->start, old_size, new_size);
1864 s->top = s->start + count;
1865 s->end = s->start + new_size;
1868 static void lglrelstk (LGL * lgl, Stk * s) {
1869 DEL (s->start, lglszstk (s));
1873 static void lglshrstk (LGL * lgl, Stk * s, int new_size) {
1874 size_t old_size, count = lglcntstk (s);
1875 assert (new_size >= 0);
1876 assert (count <= new_size);
1878 old_size = lglszstk (s);
1879 RSZ (s->start, old_size, new_size);
1880 s->top = s->start + count;
1881 s->end = s->start + new_size;
1882 } else lglrelstk (lgl, s);
1885 static void lglfitstk (LGL * lgl, Stk * s) {
1886 lglshrstk (lgl, s, lglcntstk (s));
1889 static void lglpushstk (LGL * lgl, Stk * s, int elem) {
1890 if (lglfullstk (s)) lglenlstk (lgl, s);
1894 static void lglrmstk (Stk * s, int elem) {
1896 for (p = s->start; p < s->top; p++)
1897 if (*p == elem) break;
1898 assert (p < s->top);
1905 static int lglpopstk (Stk * s) { assert (!lglmtstk (s)); return *--s->top; }
1907 static int lgltopstk (Stk * s) { assert (!lglmtstk (s)); return s->top[-1]; }
1909 static void lglrststk (Stk * s, int newsz) {
1910 assert (0 <= newsz && newsz <= lglcntstk (s));
1911 s->top = s->start + newsz;
1914 static void lglclnstk (Stk * s) { lglrststk (s, 0); }
1916 /*------------------------------------------------------------------------*/
1918 static void lgltrapi (LGL * lgl, const char * msg, ...) {
1920 assert (lgl->apitrace);
1922 vfprintf (lgl->apitrace, msg, ap);
1924 fputc ('\n', lgl->apitrace);
1927 static void lglopenapitrace (LGL * lgl, const char * name) {
1931 len = strlen (name);
1932 if (len >= 3 && !strcmp (name + len - 3, ".gz")) {
1935 sprintf (cmd, "gzip -c > %s", name);
1936 file = popen (cmd, "w");
1938 if (file) lgl->closeapitrace = 2;
1940 file = fopen (name, "w");
1941 if (file) lgl->closeapitrace = 1;
1943 if (file) lgl->apitrace = file;
1944 else lglwrn (lgl, "can not write API trace to '%s'", name);
1948 void lglwtrapi (LGL * lgl, FILE * apitrace) {
1950 ABORTIF (lgl->apitrace, "can only write one API trace");
1951 lgl->apitrace = apitrace;
1955 /*------------------------------------------------------------------------*/
1956 #if !defined(NLGLPICOSAT) && !defined(NDEBUG)
1958 static void lglpicosatinit (LGL * lgl) {
1959 if (lgl->picosat.solver) return;
1960 lgl->picosat.solver = picosat_init ();
1961 picosat_set_prefix (lgl->picosat.solver, "c PST ");
1962 lgl->picosat.chk = 1;
1963 picosat_add (lgl->picosat.solver, 1);
1964 picosat_add (lgl->picosat.solver, 0);
1965 LOG (1, "PicoSAT initialized");
1969 /*------------------------------------------------------------------------*/
1971 static unsigned lglrand (LGL * lgl) {
1973 lgl->rng.z = 36969 * (lgl->rng.z & 65535) + (lgl->rng.z >> 16);
1974 lgl->rng.w = 18000 * (lgl->rng.w & 65535) + (lgl->rng.w >> 16);
1975 res = (lgl->rng.z << 16) + lgl->rng.w;
1976 LOG (5, "rng %u", res);
1980 /*------------------------------------------------------------------------*/
1982 static int lglmtftk (Ftk * ftk) { return ftk->top == ftk->start; }
1984 static int lglfullftk (Ftk * ftk) { return ftk->top == ftk->end; }
1986 static int lglsizeftk (Ftk * ftk) { return ftk->end - ftk->start; }
1988 static int lglcntftk (Ftk * ftk) { return ftk->top - ftk->start; }
1990 static void lglrelftk (LGL * lgl, Ftk * ftk) {
1991 DEL (ftk->start, lglsizeftk (ftk));
1992 memset (ftk, 0, sizeof *ftk);
1995 static void lglenlftk (LGL * lgl, Ftk * ftk) {
1996 int oldsize = lglsizeftk (ftk);
1997 int newsize = oldsize ? 2*oldsize : 1;
1998 int count = lglcntftk (ftk);
1999 RSZ (ftk->start, oldsize, newsize);
2000 ftk->top = ftk->start + count;
2001 ftk->end = ftk->start + newsize;
2004 static void lglpushftk (LGL * lgl, Ftk * ftk, Flt f) {
2005 if (lglfullftk (ftk)) lglenlftk (lgl, ftk);
2009 static Flt lgltopftk (Ftk * ftk) {
2010 assert (!lglmtftk (ftk));
2011 return ftk->top[-1];
2014 static Flt lglpopftk (Ftk * ftk) {
2015 assert (!lglmtftk (ftk));
2019 /*------------------------------------------------------------------------*/
2021 static int lglfullctk (Ctk * ctk) { return ctk->top == ctk->end; }
2023 static int lglsizectk (Ctk * ctk) { return ctk->end - ctk->start; }
2025 static int lglcntctk (Ctk * ctk) { return ctk->top - ctk->start; }
2027 static void lglrelctk (LGL * lgl, Ctk * ctk) {
2028 DEL (ctk->start, lglsizectk (ctk));
2029 memset (ctk, 0, sizeof *ctk);
2032 static void lglenlctk (LGL * lgl, Ctk * ctk) {
2033 int oldsize = lglsizectk (ctk);
2034 int newsize = oldsize ? 2*oldsize : 1;
2035 int count = lglcntctk (ctk);
2036 RSZ (ctk->start, oldsize, newsize);
2037 ctk->top = ctk->start + count;
2038 ctk->end = ctk->start + newsize;
2041 static void lglpushcontrol (LGL * lgl, int decision) {
2042 Ctk * ctk = &lgl->control;
2044 if (lglfullctk (ctk)) lglenlctk (lgl, ctk);
2046 ctr->decision = decision;
2050 static void lglpopcontrol (LGL * lgl) {
2051 assert (lgl->control.top > lgl->control.start);
2055 static void lglrstcontrol (LGL * lgl, int count) {
2056 while (lglcntctk (&lgl->control) > count)
2057 lglpopcontrol (lgl);
2060 static int lglevelused (LGL * lgl, int level) {
2061 Ctk * ctk = &lgl->control;
2063 assert (0 < level && level < lglsizectk (ctk));
2064 ctr = ctk->start + level;
2068 static void lgluselevel (LGL * lgl, int level) {
2069 Ctk * ctk = &lgl->control;
2071 assert (0 < level && level < lglsizectk (ctk));
2072 ctr = ctk->start + level;
2076 static void lglunuselevel (LGL * lgl, int level) {
2077 Ctk * ctk = &lgl->control;
2080 assert (level < lglcntctk (ctk));
2082 ctr = ctk->start + level;
2087 /*------------------------------------------------------------------------*/
2089 static void lglgetenv (LGL * lgl, Opt * opt, const char * lname) {
2090 const char * q, * valstr;
2091 char uname[40], * p;
2093 assert (strlen (lname) + 3 + 1 < sizeof (uname));
2094 uname[0] = 'L'; uname[1] = 'G'; uname[2] = 'L';
2096 for (q = lname; *q; q++) {
2097 assert (p < uname + sizeof uname);
2098 *p++ = toupper (*q);
2100 assert (p < uname + sizeof uname);
2102 valstr = getenv (uname);
2103 if (!valstr) return;
2105 newval = atoi (valstr);
2106 if (newval < opt->min) newval = opt->min;
2107 if (newval > opt->max) newval = opt->max;
2108 if (newval == oldval) return;
2110 TRAPI ("option %s %d", lname, newval);
2112 if (lgl->clone) lglsetopt (lgl->clone, lname, newval);
2115 static void lglchkenv (LGL * lgl) {
2116 extern char ** environ;
2117 char * src, *eos, * dst;
2118 char ** p, * s, * d;
2120 for (p = environ; (src = *p); p++) {
2121 if (src[0] != 'L' || src[1] != 'G' || src[2] != 'L') continue;
2122 for (eos = src; *eos && *eos != '='; eos++)
2124 len = eos - (src + 3);
2127 for (s = src + 3; s < eos; s++) *d++ = tolower (*s);
2129 if (!lglhasopt (lgl, dst) && strcmp (dst, "apitrace"))
2130 lglwrn (lgl, "invalid 'LGL...' environment '%s'", src);
2135 #define SETPLAIN(NAME) \
2137 if (val) lgl->opts->NAME.val = 0; \
2138 else lgl->opts->NAME.val = lgl->opts->NAME.dflt; \
2141 #define SETDRUP SETPLAIN
2143 static void lglsetdrup (LGL * lgl, int val) {
2146 SETDRUP (decompose);
2154 lglprt (lgl, 1, "[drup] drup solving switched %s", val ? "on" : "off");
2157 #define SETDRUPLIG SETPLAIN
2159 static void lglsetdruplig (LGL * lgl, int val) {
2162 SETDRUPLIG (decompose);
2165 SETDRUPLIG (cgrclsr);
2169 SETDRUPLIG (smallve);
2171 "[druplig] druplig checking switched %s",
2172 val ? "on" : "off");
2175 static void lglsetplain (LGL * lgl, int val) {
2183 SETPLAIN (decompose);
2192 SETPLAIN (transred);
2194 lglprt (lgl, 1, "[plain] plain solving switched %s", val ? "on" : "off");
2197 #define SETWAIT(NAME) \
2199 if (val) lgl->opts->NAME.val = lgl->opts->NAME.dflt; \
2200 else lgl->opts->NAME.val = 0; \
2203 static void lglsetwait (LGL * lgl, int val) {
2206 SETWAIT (blockwait);
2208 SETWAIT (cgrclsrwait);
2209 SETWAIT (cliffwait);
2210 SETWAIT (elmblkwait);
2211 SETWAIT (gausswait);
2213 SETWAIT (smallvewait);
2214 SETWAIT (ternreswait);
2215 SETWAIT (transredwait);
2216 SETWAIT (unhidewait);
2217 lglprt (lgl, 1, "[wait] waiting %s", val ? "enabled" : "disabled");
2220 static LGL * lglnewlgl (void * mem,
2223 lgldealloc dealloc) {
2224 LGL * lgl = alloc ? alloc (mem, sizeof *lgl) : malloc (sizeof *lgl);
2225 ABORTIF (!lgl, "out of memory allocating main solver object");
2228 lgl->mem = alloc ? alloc (mem, sizeof *lgl->mem) : malloc (sizeof *lgl->mem);
2229 ABORTIF (!lgl->mem, "out of memory allocating memory manager object");
2231 lgl->mem->state = mem;
2232 lgl->mem->alloc = alloc;
2233 lgl->mem->realloc = realloc;
2234 lgl->mem->dealloc = dealloc;
2236 lgl->opts = alloc ? alloc (mem, sizeof (Opts)) : malloc (sizeof (Opts));
2237 ABORTIF (!lgl->opts, "out of memory allocating option manager object");
2240 lgl->stats = alloc ? alloc (mem, sizeof (Stats)) : malloc (sizeof (Stats));
2241 ABORTIF (!lgl->stats, "out of memory allocating statistic counters");
2242 CLRPTR (lgl->stats);
2244 lglinc (lgl, sizeof *lgl);
2245 lglinc (lgl, sizeof *lgl->mem);
2246 lglinc (lgl, sizeof *lgl->opts);
2247 lglinc (lgl, sizeof *lgl->stats);
2252 static void lglinitscores (LGL * lgl) {
2253 Scr oldscincf, oldmaxscore = lgl->maxscore;
2254 if (lgl->opts->score.val != LGL_SCORE_EVSIDS) {
2255 lgl->maxscore = (1ll << 60);
2256 if (oldmaxscore != lgl->maxscore)
2258 "[init-scores] fixed maxium score %s",
2259 lglscr2str (lgl, lgl->maxscore));
2261 oldscincf = lgl->scincf;
2263 lgl->scincf = lglrat (1000 + lgl->opts->scincinc.val, 1000);
2264 lgl->maxscore = lglflt (lgl->opts->maxscorexp.val, 1);
2266 lgl->scincf = (1000.0 + lgl->opts->scincinc.val) / 1000.0;
2267 lgl->maxscore = scalbln (1.0, lgl->opts->maxscorexp.val);
2269 if (oldscincf != lgl->scincf)
2271 "[init-scores] score increment factor %s (--scincinc=%d)",
2272 lglscr2str (lgl, lgl->scincf), lgl->opts->scincinc.val);
2274 if (oldmaxscore != lgl->maxscore)
2276 "[init-scores] maxium score limit %s (--maxscorexp=%d)",
2277 lglscr2str (lgl, lgl->maxscore), lgl->opts->maxscorexp.val);
2281 LGL * lglminit (void * mem,
2284 lgldealloc dealloc) {
2285 const int K = 1000, M = K*K, I = INT_MAX;
2286 const int MG = MAXGLUE, MG0 = MG*10;
2287 const char * apitracename;
2292 ABORTIF (!alloc+!realloc+!dealloc != 0 && !alloc+!realloc+!dealloc != 3,
2293 "inconsistent set of external memory handlers");
2295 assert (sizeof (long) == sizeof (void*));
2297 assert (REMOVED > ((MAXVAR << RMSHFT) | MASKCS | REDCS));
2298 assert (REMOVED > MAXREDLIDX);
2299 assert (REMOVED > MAXIRRLIDX);
2301 assert (MAXREDLIDX == MAXIRRLIDX);
2302 assert (GLUESHFT == RMSHFT);
2304 assert (INT_MAX > ((MAXREDLIDX << GLUESHFT) | GLUEMASK));
2305 assert (INT_MAX > ((MAXIRRLIDX << RMSHFT) | MASKCS | REDCS));
2307 assert (MAXGLUE < POW2GLUE);
2309 lgl = lglnewlgl (mem, alloc, realloc, dealloc);
2312 lglpushcontrol (lgl, 0);
2313 assert (lglcntctk (&lgl->control) == lgl->level + 1);
2316 lgl->prefix = lglstrdup (lgl, "c ");
2318 apitracename = getenv ("LGLAPITRACE");
2319 if (apitracename) lglopenapitrace (lgl, apitracename);
2321 OPT(0,abstime,0,0,1,"print absolute time when reporting");
2322 OPT(0,actavgmax,3*MG0/4,0,MG0,"glue average max limit for dyn acts");
2323 OPT(0,actdblarithlim,3,0,MG,"glue lim for dbl arith increase");
2324 OPT(0,actgeomlim,2,0,MG,"glue limit for geometric increase");
2325 OPT(0,actgsdul,7,0,MG0,"glue useless standard deviation limit");
2326 OPT(0,acts,2,0,2,"activity based reduction: 0=no,1=enable,2=dyn");
2327 OPT(0,actstdmax,3*MG0/4,0,MG0,"glue std dev max limit for dyn acts");
2328 OPT(0,actstdmin,10,0,MG0,"glue std dev min limit for dyn acts");
2329 OPT(0,actvlim,200*K,0,I,"activity based reduction variable limit");
2330 OPT(0,agile,1,0,2,"agility based restart skipping, 1=std, 2=sinus");
2331 OPT(0,agilelim,30,0,100,"agility limit for restarts");
2332 OPT(0,agilesinint,100*K,1,I,"agility limit sinus interval");
2333 OPT(0,bate,1,0,1,"basic ATE removal during probing");
2334 OPT(0,batewait,2,0,2,"wait for BCE (1) and/or BVE (2)");
2335 OPT(0,bca,1,0,2,"enable blocked clause addition (1=week,2=strong)");
2336 OPT(0,bcamaxeff,10*M,0,I,"BCA maximum number of steps");
2337 OPT(0,bcaminuse,100,0,I,"min number of literals required to be usable");
2338 OPT(0,bcawait,2,0,2,"wait for BCE (1) and/or BVE (2)");
2339 OPT(0,bva,0,0,1,"enable bounded variable addition (BVA)");
2340 OPT(0,bias,2,-1,2,"decision order initial bias (0=no,2=cw)");
2341 OPT(0,binlocsdel,10,0,1000,"delay local seach after learning binary clause");
2342 OPT(0,binsimpdel,2,0,1000,"delay simp after learning binary clause");
2343 OPT(0,bkwdscale,2,1,1000,"backward steps scaled vs elimination steps");
2344 OPT(0,blkboost,10,1,10000,"initial BCE boost");
2345 OPT(0,blkboostvlim,1000000,0,I,"init BCE boost variable limit");
2346 OPT(0,blkclslim,1*M,3,I,"max blocked clause size");
2347 OPT(0,blklarge,1,0,1,"BCE of large clauses");
2348 OPT(0,blkmaxeff,800*M,-1,I,"max effort in BCE (-1=unlimited)");
2349 OPT(0,blkmineff,50*M,0,I,"min effort in BCE");
2350 OPT(0,blkocclim1,100*K,1,I,"one-sided max occ of BCE");
2351 OPT(0,blkocclim,1*M,3,I,"max occ in BCE");
2352 OPT(0,blkocclim2,10*K,2,I,"two-sided max occ of BCE");
2353 OPT(0,blkreleff,100,0,K,"rel effort in BCE");
2354 OPT(0,blkrtc,0,0,1,"run BCE until completion");
2355 OPT(0,blksched2b2,0,0,1,"BCE schedule 2x2 first");
2356 OPT(0,blkschedmin,0,0,1,"BCE schedule based on minimum of occurrences");
2357 OPT(0,blkschedprod,0,0,1,"BCE schedule based on product too");
2358 OPT(0,blkschedpure,1,0,1,"BCE schedule pure literals first");
2359 OPT(0,blkschedsum,1,0,1,"BCE schedule based on sum of occurrences too");
2360 OPT(0,blksmall,1,0,1,"BCE of small clauses");
2361 OPT(0,blksuccesslim,10*K,0,I,"BCE success limit");
2362 OPT(0,blksuccessrat,1000,1,I,"BCE success ratio");
2363 OPT(0,block,1,0,1,"blocked clause elimination (BCE)");
2364 OPT(0,blockwait,1,0,1,"wait for BVE");
2365 OPT(0,boost,1,0,1,"enable boosting of preprocessors");
2366 OPT(0,bumpbcplits,0,0,1,"bump unseen but propagated literals");
2367 OPT(0,bumpclslits,0,0,1,"bump literals in minimized clause");
2368 OPT(0,bumpseenaftermin,0,0,1,"bump seen after minimization");
2369 OPT(0,bumpseenbeforemin,1,0,1,"bump seen before minimization");
2370 OPT(0,bumpseenlits,1,0,1,"bump seen literals");
2371 OPT(0,bumpseenminsize,3,0,I,"minimum 1st UIP clause for bumping seen");
2372 OPT(0,card,1,0,1,"cardinality constraint reasoning");
2373 OPT(0,cardcut,2,0,2,"1=gomoroy-cuts,2=strengthen");
2374 OPT(0,cardexpam1,3,2,I,"min length of exported at-most-one constraint");
2375 OPT(0,cardglue,0,-1,MAXGLUE,"use lrg red cls too (-1=irr,0=moved,...)");
2376 OPT(0,cardignused,0,0,1,"ignored already used literals in extraction");
2377 OPT(0,cardmaxeff,300*M,-1,I,"max effort for cardmineff reasoning");
2378 OPT(0,cardmaxlen,1000,0,I,"maximal length of cardinality constraints");
2379 OPT(0,cardmineff,2*M,0,I,"min effort for cardmineff reasoning");
2380 OPT(0,cardminlen,3,0,I,"minimal length of (initial) card constraints");
2381 OPT(0,cardocclim1,300,0,I,"one-sided cardinality constraints occ limit");
2382 OPT(0,cardocclim2,15,0,I,"two-sided cardinality constraints occ limit");
2383 OPT(0,cardreleff,5,0,10*K,"rel effort for cardinality reasoning");
2384 OPT(0,cardreschedint,10,1,I,"reschedule variable for card reasoning");
2385 OPT(0,carduse,2,0,3,"use clauses (1=oneside,2=bothsidetoo,3=anyside)");
2386 OPT(0,cardwait,0,0,2,"wait for BCE (1) and/or BVE (2)");
2387 OPT(0,cce2wait,1,0,I,"wait for ATE to finish before doing ABCE");
2388 OPT(0,cce,3,0,3,"covered clause elimination (1=ate,2=abce,3=acce)");
2389 OPT(0,cceboost,10,1,1000,"initial CCE boost");
2390 OPT(0,cceboostvlim,1000000,0,I,"initial CCE boost variable limit");
2391 OPT(0,cce3wait,2,0,I,"wait for ABCE to finish before doing ACCE");
2392 OPT(0,ccemaxeff,I,-1,I,"max effort in covered clause elimination");
2393 OPT(0,ccemineff,30*M,0,I,"min effort in covered clause elimination");
2394 OPT(0,cceonlyifstuck,0,0,1,"ABCE+ACCE only if elm+blk stuck");
2395 OPT(0,ccereleff,20,0,K,"rel effort in covered clause elimination");
2396 OPT(0,ccertc,0,0,1,"run CCE until completition");
2397 OPT(0,ccesuccesslim,10*K,0,I,"CCE success limit");
2398 OPT(0,ccesuccessrat,1000,1,I,"CCE success ratio");
2399 OPT(0,ccewait,2,0,2,"wait for BCE (1) and/or BVE (2)");
2400 OPT(0,cgrclsr,1,0,1,"gate extraction and congruence closure");
2401 OPT(0,cgrclsrwait,2,0,2,"wait for BCE (1) and/or BVE (2)");
2402 OPT(0,cgreleff,1,0,10*K,"rel effort in congruence closure");
2403 OPT(0,cgrextand,1,0,1,"extract and gates");
2404 OPT(0,cgrexteq,1,0,1,"extract equivalences");
2405 OPT(0,cgrextite,1,0,1,"extract ite gates");
2406 OPT(0,cgrextunits,1,0,1,"extract units");
2407 OPT(0,cgrextxor,1,0,1,"extract xor gates");
2408 OPT(0,cgrmaxeff,8*M,-1,I,"max effort in congruence closure");
2409 OPT(0,cgrmaxority,20,2,30,"maximum xor arity to be extracted");
2410 OPT(0,cgrmineff,200*K,0,I,"min effort in congruence closure");
2411 OPT(0,cintinc,20*K,10,M,"inprocessing conflict interval increment");
2412 OPT(0,cintincdiv,1,0,3,"cintinc reduce policy: 0=no,1=div1,2=div2,3=heur");
2413 OPT(0,cintmaxhard,10*M,-1,I,"hard max conflict interval limit");
2414 OPT(0,cintmaxsoft,1*M,-1,I,"soft max conflict interval limit");
2415 OPT(0,cliff,1,0,1,"cliffing");
2416 OPT(0,cliffmaxeff,100*M,-1,I,"max effort in cliffing");
2417 OPT(0,cliffmineff,10*M,0,I,"min effort in cliffing");
2418 OPT(0,cliffreleff,8,0,10*K,"rel effort in cliffing");
2419 OPT(0,cliffwait,2,0,2,"wait for BCE (1) and/or BVE (2)");
2420 OPT(0,clim,-1,-1,I,"conflict limit");
2421 OPT(0,compact,0,0,2,"compactify after 'lglsat/lglsimp' (1=UNS,2=SAT)");
2422 OPT(0,deco,1,0,2,"learn decision-only clauses too (2=all-decisions)");
2423 OPT(0,decolim,30,0,I,"decision-only clauses glue limit");
2424 OPT(0,decompose,1,0,1,"enable decompose");
2425 OPT(0,defragfree,50,10,K,"defragmentation free watches limit");
2426 OPT(0,defragint,10*M,100,I,"defragmentation pushed watches interval");
2427 OPT(0,delmax,10,0,10,"maximum delay");
2428 OPT(0,dlim,-1,-1,I,"decision limit");
2429 OPT(0,drup,0,0,1,"print DRUP proof");
2431 OPT(0,druplig,0,0,1,"check proof through Druplig internally");
2433 OPT(0,druplig,1,1,1,"check proof through Druplig internally");
2435 OPT(0,elim,1,0,1,"bounded variable eliminiation (BVE)");
2436 OPT(0,elmaxeff,800*M,-1,I,"max effort in BVE (-1=unlimited)");
2437 OPT(0,elmblk,1,0,1,"enable BCE during BVE");
2438 OPT(0,elmblkwait,1,0,1,"wait for BVE to be completed once");
2439 OPT(0,elmboost,40,1,1000,"initial elimination boost");
2440 OPT(0,elmclslim,1*M,3,I,"max antecendent size in elimination");
2441 OPT(0,elmfull,0,0,1,"no elimination limits");
2442 OPT(0,elmineff,20*M,0,I,"min effort in BVE");
2443 OPT(0,elmlitslim,200,0,I,"one side literals limit for elimination");
2444 OPT(0,elmocclim1,1000,1,I,"one-sided max occ of BVE");
2445 OPT(0,elmocclim,1*M,3,I,"max occurrences in BVE");
2446 OPT(0,elmocclim2,100,2,I,"two-sided max occ of BVE");
2447 OPT(0,elmreleff,200,0,10*K,"rel effort in BVE");
2448 OPT(0,elmroundlim,3,1,I,"variable elimination rounds limit");
2449 OPT(0,elmrtc,0,0,1,"run BVE until completion");
2450 OPT(0,elmsched2b2,0,0,1,"BVE schedule 2x2 first");
2451 OPT(0,elmschediff,0,0,1,"BVE schedule based on diff of occurrences too");
2452 OPT(0,elmschedmin,0,0,1,"BVE schedule based on minimum of occurrences");
2453 OPT(0,elmschedprod,0,0,1,"BVE schedule based on product too");
2454 OPT(0,elmschedpure,1,0,1,"BVE schedule pure literals first");
2455 OPT(0,elmschedsum,1,0,1,"BVE schedule based on sum of occurrences too");
2456 OPT(0,elmsuccesslim,1000,0,I,"BVE success limit");
2457 OPT(0,elmsuccessrat,1000,1,I,"BVE success ratio");
2458 OPT(0,exitonabort,0,0,1,"exit instead abort after internal error");
2459 OPT(0,factmax,100000,1,I,"maximum factor");
2460 OPT(0,factor,3,0,3,"{cls,occ}lim factors (0=const1,1=ld,2=lin,3=sqr)");
2461 OPT(0,flipdur,10,1,I,"flipping duration in number of conflicts");
2462 OPT(0,flipint,10,0,I,"flipping interval in number top level decision");
2463 OPT(0,flipldmod,4,0,30,"flipping phase log2 of mod");
2464 OPT(0,fliplevels,6,0,30,"flipping decision levels");
2465 OPT(0,flipping,1,0,1,"enable point flipping");
2466 OPT(0,fliptop,1,0,1,"flipping only at the top level");
2467 OPT(0,flipvlim,100*K,0,I,"no flipping beyond this number vars");
2468 OPT(0,force,0,0,I,"reorder variables with force algorithm");
2469 OPT(0,gauss,1,0,1,"enable gaussian elimination");
2470 OPT(0,gaussexptrn,1,0,1,"export trn cls from gaussian elimination");
2471 OPT(0,gaussextrall,1,0,1,"extract all xors (with duplicates)");
2472 OPT(0,gaussmaxeff,50*M,-1,I,"max effort in gaussian elimination");
2473 OPT(0,gaussmaxor,20,2,64,"maximum xor size in gaussian elimination");
2474 OPT(0,gaussmineff,2*M,0,I,"min effort in gaussian elimination");
2475 OPT(0,gaussreleff,2,0,10*K,"rel effort in gaussian elimination");
2476 OPT(0,gausswait,2,0,2,"wait for BCE (1) and/or BVE (2)");
2477 OPT(0,gluekeep,3,0,I,"keep clauses with this original glue");
2478 OPT(0,gluescale,4,1,4,"glue scaling: 1=linear,2=sqrt,3=ld,4=hybrid");
2479 OPT(0,import,1,0,1,"import external indices and map them");
2480 OPT(0,incredcint,1,1,I,"incremental reduce conflict interval");
2481 OPT(0,incredconfslim,0,0,100,"incremental reduce conflict limit");
2482 OPT(0,incsavevisits,0,0,1,"incremental start new visits counter");
2483 OPT(0,inprocessing,1,0,1,"enable inprocessing");
2484 OPT(0,irrlim,1,0,1,"use irredundant clauses as limit for simps");
2485 OPT(0,itlocsdel,100,0,100*K,"local search delay after iteration");
2486 OPT(0,itsimpdel,20,0,100*K,"simplification delay after iteration");
2487 OPT(0,jwhred,1,0,1,"compute JWH score based on redundant clauses too");
2488 OPT(0,keepmaxglue,1,0,1,"keep maximum glue clauses");
2489 OPT(0,lftmaxeff,20*M,-1,I,"max effort in lifting");
2490 OPT(0,lftmineff,500*K,0,I,"min effort in lifting");
2491 OPT(0,lftreleff,6,0,10*K,"rel effort in lifting");
2492 OPT(0,lftroundlim,5,0,I,"lifting round limit");
2493 OPT(0,lhbr,1,0,1, "enable lazy hyber binary reasoning");
2494 OPT(0,lift,1,0,1,"enable double lookahead lifting");
2495 OPT(0,liftlrg,3,0,I,"consider large clauses with this many unassigned");
2496 OPT(0,liftwait,2,0,2,"wait for BCE (1) and/or BVE (2)");
2497 OPT(0,lkhd,2,-1,3, "-1=LOCS,0=LIS,1=JWH,2=TREELOOK,3=LENSUM");
2498 OPT(0,lkhdmisifelmrtc,0,0,1,"MIS if elimination ran to completion");
2499 OPT(0,locs,0,-1,I,"use local search (-1=always otherwise how often)");
2500 OPT(0,locsclim,1*M,0,(I>>8),"clause limit for local search");
2501 OPT(0,locsboost,2,0,100,"initial local search boost");
2502 OPT(0,locscint,10*K,1,I,"conflict interval for LOCS");
2503 OPT(0,locsdec,2,0,2,"bump 1=mostflipped 2=minlits");
2504 OPT(0,locset,2,0,2,"initialize local search phases (1=prev,2=cur)");
2505 OPT(0,locsexport,1,0,1,"export phases from local search");
2506 OPT(0,locsmaxeff,100000,0,I,"max effort in local search");
2507 OPT(0,locsmineff,1000,0,I,"min effort in local search");
2508 OPT(0,locsred,0,0,4,"apply local search on redundant clauses too");
2509 OPT(0,locsreleff,5,0,100,"rel effort in local search");
2510 OPT(0,locsrtc,0,0,1,"run local search until completion");
2511 OPT(0,locsvared,100,0,1000,"max variable reduction for LOCS");
2512 OPT(0,locswait,2,0,2,"wait for BCE(1) and/or BVE(2)");
2513 OPT(0,maxglue,I,0,I,"min glue which is considered as MAXGLUE");
2514 OPT(0,maxscorexp,DEFSCOREXP,7,MAXSCOREXP,"maximum score exponent");
2515 OPT(0,mega,0,0,1,"mega probing through preprocessor look-ahead");
2516 OPT(0,megaint,4,1,I,"mega probing interval");
2517 OPT(0,megawait,2,0,2,"mega probing waiting for BCE / BVE");
2518 OPT(0,memlim,-1,-1,I,"memory limit in MB (-1=no limit)");
2519 OPT(0,minimize,2,0,2,"minimize learned clauses (1=local,2=recursive)");
2520 OPT(0,minlocalgluelim,30,0,I,"glue limit for using local minimization");
2521 OPT(0,minrecgluelim,20,0,I,"glue limit for using recursive minimization");
2522 OPT(0,mocint,1000,1,I,"multiple objectives conflict limit interval");
2523 OPT(0,move,2,0,3,"move redundant cls (1=only-binary,2=ternary,3=all)");
2524 OPT(0,otfs,1,0,1,"enable on-the-fly subsumption");
2525 OPT(0,otfsbump,0,0,2,"bump literals during OTFS (1=conflict,2=drive)");
2526 OPT(0,otfsconf,0,0,1,"count on-the-fly restart as conflict");
2527 OPT(0,penmax,4,0,16,"maximum penalty");
2528 OPT(0,phase,0,-1,1,"default phase (-1=neg,0=JeroslowWang,1=pos)");
2529 OPT(0,phaseflip,0,0,1,"flip Jeroslow Wang phase");
2530 OPT(0,phasegluebit,0,0,I,"Glue-Bit phase selection on these levels");
2531 OPT(0,phaseneginit,0,0,I,"initial zero phase conflict interval");
2532 OPT(0,plain,0,0,1,"plain mode disables all preprocessing");
2533 OPT(0,plim,-1,-1,I,"propagation limit (thousands)");
2534 OPT(0,prbasic,1,0,2,"enable basic probing procedure (1=roots-only)");
2535 OPT(0,prbasicmaxeff,100*M,-1,I,"max effort in basic probing");
2536 OPT(0,prbasicmineff,M,0,I,"min effort in basic probing");
2537 OPT(0,prbasicreleff,10,0,10*K,"rel effort in basic probing");
2538 OPT(0,prbasicroundlim,9,1,I,"basic probing round limit");
2539 OPT(0,prbasicrtc,0,0,1,"run basic probing until completion");
2540 OPT(0,prbrtc,0,0,1,"run all probing until completion");
2541 OPT(0,prbsimple,2,0,3,"simple probing (1=shallow,2=deep,3=touchall)");
2542 OPT(0,prbsimpleboost,10,1,1000,"initial simple probing boost");
2543 OPT(0,prbsimpleliftdepth,2,1,4,"simple probing lifting depth");
2544 OPT(0,prbsimplemaxeff,200*M,-1,I,"max effort in simple probing");
2545 OPT(0,prbsimplemineff,2*M,0,I,"min effort in simple probing");
2546 OPT(0,prbsimplereleff,40,0,10*K,"rel effort in simple probing");
2547 OPT(0,prbsimplertc,0,0,1,"run simple probing until completion");
2548 OPT(0,probe,1,0,1,"enable probing");
2549 OPT(0,psm,3,0,3,"use PSM metric (1=afteract,2=afterglue,3=first");
2550 OPT(0,pure,1,0,1,"enable pure literal elimination during BCE");
2551 OPT(0,randec,0,0,1,"enable random decisions");
2552 OPT(0,randecflipint,0,0,I,"random decision flip phase interval");
2553 OPT(0,randecint,1000,2,I/2,"random decision interval");
2554 OPT(0,rdp,0,0,3,"random DP (2=redbin,3=redtrn");
2555 OPT(0,rdpclslim,3,0,I,"random DP resolvent size limit");
2556 OPT(0,rdplim,100,0,200,"limit #resolvents in percent original clauses");
2557 OPT(0,rdpmaxeff,10*M,-1,I,"max effort in RDP");
2558 OPT(0,rdpmineff,10*K,0,I,"min effort in RDP");
2559 OPT(0,rdpmodelm,0,0,1,"use model elimination in RDP");
2560 OPT(0,rdpreleff,2,0,10*K,"rel effort in RDP");
2561 OPT(0,rdpwait,2,0,2,"wait for BCE (1) and/or BVE (2)");
2562 OPT(0,redfixed,0,0,1,"keep a fixed size of learned clauses");
2563 OPT(0,redinoutinc,100,1,1000,"reduce inner/outer relative increment");
2564 OPT(0,redlbound,0,0,1,"relative and absolute bounds on learned clauses");
2565 OPT(0,redlexpfac,10,0,1000,"exponential reduce limit increment factor");
2566 OPT(0,redlinc,1000,1,10*M,"reduce limit increment");
2567 OPT(0,redlinit,4*K,1,100*M,"initial reduce limit");
2568 OPT(0,redlmaxabs,1000000,10,I/2,"maximum absolute reduce limit");
2569 OPT(0,redlmaxinc,200,1,100*K,"rel max reduce limit increment");
2570 OPT(0,redlmaxrel,300,10,10000,"maximum relative reduce limit");
2571 OPT(0,redlminabs,500,10,1000000,"minimum absolute reduce limit");
2572 OPT(0,redlmininc,10,1,100*K,"rel min reduce limit increment");
2573 OPT(0,redlminrel,10,10,1000,"minimum relative reduce limit");
2574 OPT(0,redloutinc,10000,0,1000000,"outer arithmetic reduce increment");
2575 OPT(0,redoutclim,5000,0,I,"clause limit for outer reduce schedule");
2576 OPT(0,redoutvlim,1000,0,I,"variable limit for outer reduce schedule");
2577 OPT(0,reduce,2,0,4,"clause reduction (1=noouter,2=luby,3=inout,4=arith)");
2578 OPT(0,rephase,1,0,2,"enable flushing and recomputation of phases (2=full)");
2579 OPT(0,rephaseinc,10000,1,I,"rephasing increment");
2580 OPT(0,restart,2,0,3,"enable restarting (0=no,1=fixed,2=luby,3=inout)");
2581 OPT(0,restartinit,0,0,I,"initial restart interval");
2582 OPT(0,restartint,5,1,I,"restart interval");
2583 OPT(0,restartintscale,0,-1,1,"scale restart interval");
2584 OPT(0,reusetrail,1,0,1,"reuse trail");
2585 OPT(0,rmincpen,4,0,32,"logarithm of watcher removal penalty");
2586 OPT(0,rstinoutinc,110,1,1000,"restart inner/outer relative increment");
2587 OPT(0,saturating,70,0,1000,"saturating level (no restart)");
2588 OPT(0,scincinc,200,0,10*K,"score increment increment in per mille");
2589 OPT(0,score,5,0,6,"0=static,1=inc,2=vmtf,3=sum,4=avg,5=evsids,6=vsids256");
2590 OPT(0,seed,0,0,I,"random number generator seed");
2591 OPT(0,simpdelay,0,0,I,"initial simplification delay");
2592 OPT(0,simpen,0,0,24,"logarithmic initial simplification penalty");
2593 OPT(0,simpidiv,3,1,100,"simplification inter delay divisor");
2594 OPT(0,simpinterdelay,2000,0,I,"inprocessing simplification delay");
2595 OPT(0,simpiscale,100,1,10000,"relative simplification inter delay scale");
2596 OPT(0,simplify,2,0,2,"enable simplification");
2597 OPT(0,simprtc,5,1,100,"min var reduction for simplification RTC");
2598 OPT(0,simpvarchg,100,1,1000, "simp remaining vars percentage change lim");
2599 OPT(0,simpvarlim,100,0,I, "simp remaining vars min limit");
2600 OPT(0,sizemaxpen,5,0,20,"maximum logarithmic size penalty");
2601 OPT(0,sizepen,1*M,1,I,"number of clauses size penalty starting point");
2602 OPT(0,sleeponabort,0,0,I,"sleep this seconds before abort/exit");
2603 OPT(0,smallirr,90,0,100,"max percentage irr lits for BCE and VE");
2604 OPT(0,smallve,1,0,1,"enable small number variables elimination");
2605 OPT(0,smallvevars,FUNVAR,4,FUNVAR, "variables small variable elimination");
2606 OPT(0,smallvewait,0,0,1,"wait with small variable elimination");
2607 OPT(0,sortlits,0,0,1,"sort lits of cls during garbage collection");
2608 OPT(0,subl,9,0,10*K,"try to subsume this many recent learned clauses");
2609 OPT(0,synclsall,1,0,1,"always synchronize all unconsumed clauses");
2610 OPT(0,synclsglue,8,0,I,"clause synchronization glue limit");
2611 OPT(0,synclsint,100,0,1000,"clause synchronization confs interval");
2612 OPT(0,synclslen,40,0,I,"clause synchronization length limit");
2613 OPT(0,syncunint,111111,0,M,"unit synchronization steps interval");
2614 OPT(0,tabr,3,0,4,"tabula rasa (1=red,2=phases,3=cinc,4=scores");
2615 OPT(0,tabrcfactor,2,1,I,"tabula rasa clause factor");
2616 OPT(0,tabrkeep,3,1,4,"1=none,2=bin,3=bin+trn,4=bin+trn+glue0");
2617 OPT(0,tabrvfactor,4,1,I,"tabula rasa variable factor");
2618 OPT(0,termint,122222,0,M,"termination check interval");
2619 OPT(0,ternres,1,0,1,"generate ternary resolvents");
2620 OPT(0,ternresboost,5,1,100,"initial ternary reslution boost");
2621 OPT(0,ternresrtc,0,0,1,"run ternary resolvents until completion");
2622 OPT(0,ternreswait,2,0,2,"wait for BCE (1) and/or BVE (2)");
2623 OPT(0,transred,1,0,1,"enable transitive reduction");
2624 OPT(0,transredwait,2,0,2,"wait for BCE (1) and/or BVE (2)");
2625 OPT(0,trdmaxeff,2*M,-1,I,"max effort in transitive reduction");
2626 OPT(0,trdmineff,100*K,0,I,"min effort in transitive reduction");
2627 OPT(0,trdreleff,10,0,10*K,"rel effort in transitive reduction");
2628 OPT(0,treelook,1,0,2,"enable tree-based look-ahead (2=scheduleprobing)");
2629 OPT(0,treelookboost,20,1,100000,"tree-based look-head boost factor");
2630 OPT(0,treelookfull,0,0,1,"do not limit tree-based look-head");
2631 OPT(0,treelooklrg,1,0,1,"use large clauses during tree-look");
2632 OPT(0,treelookmaxeff,50*M,-1,I,"max effort in tree-look based probing");
2633 OPT(0,treelookmineff,300*K,0,I,"min effort in tree-look based probing");
2634 OPT(0,treelookreleff,1,0,10*K,"rel effort in tree-look based probing");
2635 OPT(0,treelookrtc,0,0,1,"run tree-based look-ahead until completion");
2636 OPT(0,trep,0,0,1,"enable time based interval reporting");
2637 OPT(0,trepint,55555,1,I,"interval for time based reporting");
2638 OPT(0,trnreleff,10,0,K,"rel effort in ternary resolutions");
2639 OPT(0,trnrmaxeff,200*M,-1,I,"max effort in ternary resolutions");
2640 OPT(0,trnrmineff,4*M,0,I,"min effort in ternary resolutions");
2641 OPT(0,unhdatrn,2,0,2,"unhide redundant ternary clauses (1=move,2=force)");
2642 OPT(0,unhdextstamp,1,0,1,"used extended stamping features");
2643 OPT(0,unhdhbr,0,0,1,"enable unhiding hyper binary resolution");
2644 OPT(0,unhdlnpr,3,0,I,"unhide no progress round limit");
2645 OPT(0,unhdmaxeff,20*M,-1,I,"max effort in unhiding");
2646 OPT(0,unhdmineff,100*K,0,I,"min effort in unhiding");
2647 OPT(0,unhdreleff,2,0,10*K,"rel effort in unhiding");
2648 OPT(0,unhdroundlim,20,0,100,"unhide round limit");
2649 OPT(0,unhide,1,0,1,"enable unhiding");
2650 OPT(0,unhidewait,0,0,2,"wait for BCE (1) and/or BVE (2)");
2651 OPT(0,wait,1,0,1,"enable or disable all waiting");
2652 OPT(0,waitmax,4,-1,I,"max simps to wait (-1=nomax)");
2653 OPT(0,witness,1,0,1,"print witness");
2655 OPT('c',check,0,0,3,"check level");
2656 OPT('l',log,-1,-1,5,"log level");
2657 OPT('v',verbose,0,-1,4,"verbosity level");
2659 if (lgl->opts->plain.val) lglsetplain (lgl, 1);
2660 if (lgl->opts->drup.val) lglsetdrup (lgl, 1);
2661 if (lgl->opts->druplig.val) lglsetdruplig (lgl, 1);
2662 if (!lgl->opts->wait.val) lglsetwait (lgl, 0);
2664 if (abs (lgl->opts->bias.val) <= 1) lgl->bias = lgl->opts->bias.val;
2667 NEW (lgl->times, 1);
2668 NEW (lgl->timers, 1);
2669 NEW (lgl->limits, 1);
2670 NEW (lgl->fltstr, 1);
2671 NEW (lgl->red, MAXGLUE+1);
2673 for (i = 0; i < MAXLDFW; i++) lgl->wchs->start[i] = INT_MAX;
2674 lglpushstk (lgl, &lgl->wchs->stk, INT_MAX);
2675 lglpushstk (lgl, &lgl->wchs->stk, INT_MAX);
2678 lgl->scinc = lglflt (0, 1);
2688 static void lglcopyclonenfork (LGL * dst, LGL * src) {
2689 memcpy (dst->opts, src->opts, sizeof *src->opts);
2690 dst->out = src->out;
2691 if (dst->prefix) lgldelstr (dst, dst->prefix);
2692 dst->prefix = lglstrdup (dst, src->prefix);
2695 if (src->cbs->onabort) {
2696 dst->cbs->abortstate = src->cbs->abortstate;
2697 dst->cbs->onabort = src->cbs->onabort;
2699 if (src->cbs->getime) dst->cbs->getime = src->cbs->getime;
2703 static void lglcompact (LGL *);
2705 LGL * lglmclone (LGL * orig,
2709 lgldealloc dealloc) {
2710 size_t max_bytes, current_bytes;
2714 if (!orig) return 0;
2717 lgl = lglnewlgl (mem, alloc, realloc, dealloc);
2718 memcpy (lgl, orig, ((char*)&orig->mem) - (char*) orig);
2719 max_bytes = lgl->stats->bytes.max;
2720 current_bytes = lgl->stats->bytes.current;
2721 memcpy (lgl->stats, orig->stats, sizeof *orig->stats);
2722 lgl->stats->bytes.current = current_bytes;
2723 lgl->stats->bytes.max = max_bytes;
2725 lglcopyclonenfork (lgl, orig);
2729 CLONE (timers, 1); assert (!lgl->timers->nest);
2731 CLONE (ext, orig->szext);
2732 CLONE (i2e, orig->szvars);
2733 CLONE (doms, 2*orig->szvars);
2734 CLONE (dvars, orig->szvars);
2735 CLONE (qvars, orig->szvars);
2736 CLONE (avars, orig->szvars);
2737 CLONE (vals, orig->szvars);
2738 CLONE (jwh, 2*orig->szvars);
2739 CLONE (drail, orig->szdrail);
2741 NEW (lgl->red, MAXGLUE+1);
2742 for (glue = 0; glue <= MAXGLUE; glue++) CLONESTK (red[glue]);
2745 memcpy (lgl->wchs, orig->wchs, sizeof *orig->wchs);
2746 CLONESTK (wchs->stk);
2767 for (p = (char*)&orig->elm; p < (char*)(&orig->repr+1); p++) assert (!*p);
2770 assert (lgl->stats->bytes.current == orig->stats->bytes.current);
2771 assert (lgl->stats->bytes.max <= orig->stats->bytes.max);
2772 lgl->stats->bytes.max = orig->stats->bytes.max;
2776 LGL * lglclone (LGL * lgl) {
2778 return lglmclone (lgl,
2785 void lglchkclone (LGL * lgl) {
2786 REQINITNOTFORKED ();
2789 if (!lgl->opts->druplig.val) {
2790 if (lgl->clone) lglrelease (lgl->clone);
2791 lgl->clone = lglclone (lgl);
2796 LGL * lglinit (void) { return lglminit (0, 0, 0, 0); }
2798 static int lglmaxoptnamelen (LGL * lgl) {
2801 for (o = FIRSTOPT (lgl); o <= LASTOPT (lgl); o++)
2802 if ((len = strlen (o->lng)) > res)
2807 void lglusage (LGL * lgl) {
2811 REQINITNOTFORKED ();
2812 len = lglmaxoptnamelen (lgl);
2813 sprintf (fmt, "--%%-%ds", len);
2814 for (o = FIRSTOPT (lgl); o <= LASTOPT (lgl); o++) {
2815 if (o->shrt) fprintf (lgl->out, "-%c|", o->shrt);
2816 else fprintf (lgl->out, " ");
2817 fprintf (lgl->out, fmt, o->lng);
2818 fprintf (lgl->out, " %s [%d]\n", o->descrp, o->val);
2822 static int lglignopt (const char * name) {
2823 if (!strcmp (name, "abstime")) return 1;
2824 if (!strcmp (name, "check")) return 1;
2825 if (!strcmp (name, "drup")) return 1;
2826 if (!strcmp (name, "exitonabort")) return 1;
2827 if (!strcmp (name, "log")) return 1;
2828 if (!strcmp (name, "sleeponabort")) return 1;
2829 if (!strcmp (name, "verbose")) return 1;
2830 if (!strcmp (name, "witness")) return 1;
2834 void lglopts (LGL * lgl, const char * prefix, int ignsome) {
2836 REQINITNOTFORKED ();
2837 for (o = FIRSTOPT (lgl); o <= LASTOPT (lgl); o++) {
2838 if (ignsome && lglignopt (o->lng)) continue;
2839 fprintf (lgl->out, "%s--%s=%d\n", prefix, o->lng, o->val);
2843 void lglrgopts (LGL * lgl) {
2845 REQINITNOTFORKED ();
2846 for (o = FIRSTOPT (lgl); o <= LASTOPT (lgl); o++)
2847 fprintf (lgl->out, "%s %d %d %d\n", o->lng, o->val, o->min, o->max);
2850 void lglpcs (LGL * lgl, int mixed) {
2851 int i, printi, printl;
2854 REQINITNOTFORKED ();
2855 for (o = FIRSTOPT (lgl); o <= LASTOPT (lgl); o++) {
2856 if (lglignopt (o->lng)) continue;
2857 range = o->max; range -= o->min;
2858 if (range >= 7 && mixed < 0) continue;
2859 printi = printl = 0;
2860 printf ("%s ", o->lng);
2862 printf ("{%d", o->min);
2863 for (i = o->min + 1; i <= o->max; i++) printf (",%d", i);
2865 } else if (!mixed) {
2866 printf ("[%d,%d]", o->min, o->max);
2868 printl = (o->min > 0 && range >= 100);
2869 } else if (o->dflt == o->min || o->dflt == o->max) {
2870 printf ("{%d,%d,%d,%d,%d}",
2872 (int)(o->min + (1*range + 3)/4),
2873 (int)(o->min + (2*range + 3)/4),
2874 (int)(o->min + (3*range + 3)/4),
2876 } else if (o->dflt == o->min + 1) {
2877 printf ("{%d,%d,%d,%d}",
2880 (int)(o->dflt + (o->max - (int64_t) o->dflt)/2),
2882 } else if (o->dflt + 1 == o->max) {
2883 printf ("{%d,%d,%d,%d}",
2885 (int)(o->min + (o->dflt - (int64_t) o->min)/2),
2889 assert (o->dflt - o->min >= 2);
2890 assert (o->max - o->dflt >= 2);
2891 printf ("{%d,%d,%d,%d,%d}",
2893 (int)(o->min + (o->dflt - (int64_t) o->min)/2),
2895 (int)(o->dflt + (o->max - (int64_t) o->min)/2),
2898 printf ("[%d]", o->dflt);
2899 if (printi) printf ("i");
2900 if (printl) printf ("l");
2901 printf (" # %s\n",o->descrp);
2905 int lglhasopt (LGL * lgl, const char * opt) {
2907 REQINITNOTFORKED ();
2908 for (o = FIRSTOPT (lgl); o <= LASTOPT (lgl); o++) {
2909 if (!opt[1] && o->shrt == opt[0]) return 1;
2910 if (!strcmp (o->lng, opt)) return 1;
2915 void * lglfirstopt (LGL * lgl) { return FIRSTOPT (lgl); }
2917 void * lglnextopt (LGL * lgl,
2919 const char **nameptr,
2920 int *valptr, int *minptr, int *maxptr) {
2921 Opt * opt = current, * res = opt + 1;
2922 if (res > LASTOPT (lgl)) return 0;
2923 if (nameptr) *nameptr = opt->lng;
2924 if (valptr) *valptr = opt->val;
2925 if (minptr) *minptr = opt->min;
2926 if (maxptr) *maxptr = opt->max;
2930 void lglsetopt (LGL * lgl, const char * opt, int val) {
2933 REQINITNOTFORKED ();
2934 for (o = FIRSTOPT (lgl); o <= LASTOPT (lgl); o++) {
2935 if (!opt[1] && o->shrt == opt[0]) break;
2936 if (!strcmp (o->lng, opt)) break;
2938 if (o > LASTOPT (lgl)) return;
2939 if (val < o->min) val = o->min;
2940 if (o->max < val) val = o->max;
2943 if (o == &lgl->opts->flipping && !oldval)
2944 lgl->flipping = lgl->notflipped = 0;
2945 if (o == &lgl->opts->plain) {
2946 if (val > 0 && !oldval) lglsetplain (lgl, 1);
2947 if (!val && oldval) lglsetplain (lgl, 0);
2949 if (o == &lgl->opts->drup) {
2950 if (val > 0 && !oldval) lglsetdrup (lgl, 1);
2951 if (!val && oldval) lglsetdrup (lgl, 0);
2953 if (o == &lgl->opts->druplig) {
2954 if (val > 0 && !oldval) lglsetdruplig (lgl, 1);
2955 if (!val && oldval) lglsetdruplig (lgl, 0);
2957 if (o == &lgl->opts->wait) {
2958 if (val > 0 && !oldval) lglsetwait (lgl, 1);
2959 if (!val && oldval) lglsetwait (lgl, 0);
2961 if (o == &lgl->opts->phase && val != oldval) lgl->flushphases = 1;
2962 if (lgl->state == UNUSED) TRANS (OPTSET);
2963 TRAPI ("option %s %d", opt, val);
2966 static int lglws (int ch) {
2967 return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
2970 int lglreadopts (LGL * lgl, FILE * file) {
2971 int res, ch, val, nvalbuf, noptbuf;
2972 char optbuf[40], valbuf[40];
2976 while (lglws (ch = getc (file)))
2978 if (ch == EOF) break;
2980 optbuf[noptbuf++] = ch;
2981 while ((ch = getc (file)) != EOF && !lglws (ch)) {
2982 if (noptbuf + 1 >= sizeof optbuf) { ch = EOF; break; }
2983 optbuf[noptbuf++] = ch;
2985 if (ch == EOF) break;
2986 assert (noptbuf < sizeof optbuf);
2987 optbuf[noptbuf++] = 0;
2988 assert (lglws (ch));
2989 while (lglws (ch = getc (file)))
2991 if (ch == EOF) break;
2993 valbuf[nvalbuf++] = ch;
2994 while ((ch = getc (file)) != EOF && !lglws (ch)) {
2995 if (nvalbuf + 1 >= sizeof valbuf) break;
2996 valbuf[nvalbuf++] = ch;
2998 assert (nvalbuf < sizeof valbuf);
2999 valbuf[nvalbuf++] = 0;
3001 val = atoi (valbuf);
3002 lglprt (lgl, 1, "read option --%s=%d", opt, val);
3003 lglsetopt (lgl, opt, val);
3009 void lglsetout (LGL * lgl, FILE * out) { lgl->out = out; }
3011 FILE * lglgetout (LGL * lgl) { return lgl->out; }
3013 void lglsetprefix (LGL * lgl, const char * prefix) {
3014 lgldelstr (lgl, lgl->prefix);
3015 lgl->prefix = lglstrdup (lgl, prefix);
3018 const char * lglgetprefix (LGL * lgl) { return lgl->prefix; }
3020 static Opt * lgligetopt (LGL * lgl, const char * opt) {
3022 REQINITNOTFORKED ();
3023 for (o = FIRSTOPT (lgl); o <= LASTOPT (lgl); o++) {
3024 if (!opt[1] && o->shrt == opt[0]) return o;
3025 if (!strcmp (o->lng, opt)) return o;
3030 int lglgetopt (LGL * lgl, const char * opt) {
3031 Opt * o = lgligetopt (lgl, opt);
3032 return o ? o->val : 0;
3035 int lglgetoptminmax (LGL * lgl, const char * opt,
3036 int * min_ptr, int * max_ptr) {
3037 Opt * o = lgligetopt (lgl, opt);
3039 if (min_ptr) *min_ptr = o->min;
3040 if (max_ptr) *max_ptr = o->max;
3044 /*------------------------------------------------------------------------*/
3046 static void lglrszvars (LGL * lgl, int new_size) {
3047 int old_size = lgl->szvars;
3048 assert (lgl->nvars <= new_size);
3049 RSZ (lgl->vals, old_size, new_size);
3050 RSZ (lgl->i2e, old_size, new_size);
3051 RSZ (lgl->doms, 2*old_size, 2*new_size);
3052 RSZ (lgl->dvars, old_size, new_size);
3053 RSZ (lgl->avars, old_size, new_size);
3054 RSZ (lgl->qvars, old_size, new_size);
3055 RSZ (lgl->jwh, 2*old_size, 2*new_size);
3056 lgl->szvars = new_size;
3059 static void lglenlvars (LGL * lgl) {
3060 size_t old_size, new_size;
3061 old_size = lgl->szvars;
3062 new_size = old_size ? 2 * old_size : 4;
3063 LOG (3, "enlarging internal variables from %ld to %ld", old_size, new_size);
3064 lglrszvars (lgl, new_size);
3067 static void lglredvars (LGL * lgl) {
3068 size_t old_size, new_size;
3069 old_size = lgl->szvars;
3070 new_size = lgl->nvars;
3071 if (new_size == old_size) return;
3072 LOG (3, "reducing variables from %ld to %ld", old_size, new_size);
3073 lglrszvars (lgl, new_size);
3076 static int lglmax (int a, int b) { return a > b ? a : b; }
3078 static int lglmin (int a, int b) { return a < b ? a : b; }
3080 /*------------------------------------------------------------------------*/
3082 static DVar * lgldvar (LGL * lgl, int lit) {
3083 assert (2 <= abs (lit) && abs (lit) < lgl->nvars);
3084 return lgl->dvars + abs (lit);
3087 /*------------------------------------------------------------------------*/
3089 static AVar * lglavar (LGL * lgl, int lit) {
3090 assert (2 <= abs (lit) && abs (lit) < lgl->nvars);
3091 return lgl->avars + abs (lit);
3094 static Val lglval (LGL * lgl, int lit) {
3095 int idx = abs (lit);
3097 ASSERT (2 <= idx && idx < lgl->nvars);
3098 res = lgl->vals[idx];
3099 if (lit < 0) res = -res;
3103 static int lgltrail (LGL * lgl, int lit) { return lglavar (lgl, lit)->trail; }
3105 static TD * lgltd (LGL * lgl, int lit) {
3106 int pos = lgltrail (lgl, lit);
3107 assert (0 <= pos && pos < lgl->szdrail);
3108 return lgl->drail + pos;
3111 static int lglevel (LGL * lgl, int lit) { return lgltd (lgl, lit)->level; }
3113 static int lglisfree (LGL * lgl, int lit) {
3114 return lglavar (lgl, lit)->type == FREEVAR;
3117 /*------------------------------------------------------------------------*/
3119 static QVar * lglqvar (LGL * lgl, int lit) {
3120 assert (2 <= abs (lit) && abs (lit) < lgl->nvars);
3121 return lgl->qvars + abs (lit);
3124 static int * lgldpos (LGL * lgl, int lit) {
3127 qv = lglqvar (lgl, lit);
3132 static int lglscrcmp (Scr a, Scr b) {
3133 if (a < b) return -1;
3134 if (a > b) return 1;
3138 static int lgldcmp (LGL * lgl, int l, int k) {
3139 QVar * pv = lglqvar (lgl, l);
3140 QVar * qv = lglqvar (lgl, k);
3142 if ((res = lglscrcmp (pv->score, qv->score))) return res;
3143 res = lgl->bias * (l - k);
3148 static void lglchkdsched (LGL * lgl) {
3149 int * p, parent, child, ppos, cpos, size, i, tmp;
3150 Stk * s = &lgl->dsched;
3151 size = lglcntstk (s);
3153 for (ppos = 0; ppos < size; ppos++) {
3155 tmp = *lgldpos (lgl, parent);
3156 assert (ppos == tmp);
3157 for (i = 0; i <= 1; i++) {
3158 cpos = 2*ppos + 1 + i;
3159 if (cpos >= size) continue;
3161 tmp = *lgldpos (lgl, child);
3162 assert (cpos == tmp);
3163 assert (lgldcmp (lgl, parent, child) >= 0);
3169 static void lgldup (LGL * lgl, int lit) {
3170 int child = lit, parent, cpos, ppos, * p, * cposptr, * pposptr;
3171 Stk * s = &lgl->dsched;
3173 cposptr = lgldpos (lgl, child);
3177 ppos = (cpos - 1)/2;
3179 if (lgldcmp (lgl, parent, lit) >= 0) break;
3180 pposptr = lgldpos (lgl, parent);
3181 assert (*pposptr == ppos);
3184 LOGDSCHED (5, parent, "down from %d", ppos);
3187 if (*cposptr == cpos) return;
3193 LOGDSCHED (5, lit, "up from %d", ppos);
3195 if (lgl->opts->check.val >= 2) lglchkdsched (lgl);
3199 static void lglddown (LGL * lgl, int lit) {
3200 int parent = lit, child, right, ppos, cpos;
3201 int * p, * pposptr, * cposptr, size;
3202 Stk * s = &lgl->dsched;
3203 size = lglcntstk (s);
3205 pposptr = lgldpos (lgl, parent);
3210 if (cpos >= size) break;
3212 if (cpos + 1 < size) {
3213 right = p[cpos + 1];
3214 if (lgldcmp (lgl, child, right) < 0) cpos++, child = right;
3216 if (lgldcmp (lgl, child, lit) <= 0) break;
3217 cposptr = lgldpos (lgl, child);
3218 assert (*cposptr = cpos);
3221 LOGDSCHED (5, child, "up from %d", cpos);
3224 if (*pposptr == ppos) return;
3230 LOGDSCHED (5, lit, "down from %d", cpos);
3232 if (lgl->opts->check.val >= 2) lglchkdsched (lgl);
3236 static void lgldsched (LGL * lgl, int lit) {
3237 int * p = lgldpos (lgl, lit);
3238 Stk * s = &lgl->dsched;
3241 lglpushstk (lgl, s, lit);
3243 lglddown (lgl, lit);
3244 LOGDSCHED (4, lit, "pushed");
3247 static int lgltopdsched (LGL * lgl) {
3248 assert (!lglmtstk (&lgl->dsched));
3249 return lgl->dsched.start[0];
3252 static int lglpopdsched (LGL * lgl) {
3253 Stk * s = &lgl->dsched;
3254 int res, last, cnt, * p;
3256 assert (!lglmtstk (s));
3258 LOGDSCHED (4, res, "popped");
3259 qv = lglqvar (lgl, res);
3262 last = lglpopstk (s);
3263 cnt = lglcntstk (s);
3264 if (!cnt) { assert (last == res); return res; }
3265 p = lgldpos (lgl, last);
3269 lglddown (lgl, last);
3273 static void lgldreschedule (LGL * lgl) {
3274 Stk * s = &lgl->dsched;
3275 int idx, i, pos, cnt = lglcntstk (s);
3277 LOG (1, "rescheduling %d variables", cnt);
3278 for (idx = 2; idx < lgl->nvars; idx++) lglqvar (lgl, idx)->pos = -1;
3281 for (i = 0; i < cnt; i++) {
3283 assert (s->start + pos == s->top);
3285 if (abs (idx) <= 1) continue;
3286 qv = lglqvar (lgl, idx);
3287 if (!lglisfree (lgl, idx)) { qv->pos = -1; continue; }
3288 assert (qv->pos == -1);
3289 s->start[pos] = idx;
3293 lglddown (lgl, idx);
3295 LOG (1, "new schedule with %d variables", lglcntstk (s));
3298 if (lgl->opts->check.val >= 1) lglchkdsched (lgl);
3304 static void lglrescorevars (LGL * lgl) {
3305 Scr oldscinc, oldscore, newscore, oldmaxscore = 0, newmaxscore = 0;
3309 lgl->stats->rescored.vars++;
3310 for (idx = 2; idx < lgl->nvars; idx++) {
3311 qv = lglqvar (lgl, idx);
3312 oldscore = qv->score;
3313 if (oldscore > oldmaxscore) oldmaxscore = oldscore;
3315 if (lgl->opts->score.val == LGL_SCORE_EVSIDS ||
3316 lgl->opts->score.val == LGL_SCORE_AVG)
3317 newscore = lglshflt (oldscore, lgl->opts->maxscorexp.val);
3318 else newscore = (oldscore >> 32);
3320 newscore = oldscore / lgl->maxscore;
3322 qv->score = newscore;
3323 if (qv->score > newmaxscore) newmaxscore = qv->score;
3324 LOG (3, "rescored variable %d from %s to %s",
3325 idx, lglscr2str (lgl, oldscore), lglscr2str (lgl, qv->score));
3327 lgldreschedule (lgl);
3328 newotfs = lgl->stats->otfs.driving + lgl->stats->otfs.restarting;
3329 assert (newotfs >= lgl->limits->rescore.vars.otfs);
3330 assert (lgl->stats->confs >= lgl->limits->rescore.vars.confs);
3332 "[rescored-vars-%d] after %lld conflicts and %lld OTFS",
3333 lgl->stats->rescored.vars,
3334 lgl->stats->confs - lgl->limits->rescore.vars.confs,
3335 newotfs - lgl->limits->rescore.vars.otfs);
3336 lgl->limits->rescore.vars.confs = lgl->stats->confs;
3337 lgl->limits->rescore.vars.otfs = newotfs;
3339 "[rescored-vars-%d] old maximum score %s",
3340 lgl->stats->rescored.vars, lglscr2str (lgl, oldmaxscore));
3342 "[rescored-vars-%d] new maximum score %s",
3343 lgl->stats->rescored.vars, lglscr2str (lgl, newmaxscore));
3344 if (lgl->opts->score.val == LGL_SCORE_EVSIDS) {
3345 oldscinc = lgl->scinc;
3347 lgl->scinc = lglshflt (oldscinc, lgl->opts->maxscorexp.val);
3349 lgl->scinc = oldscinc / lgl->maxscore;
3351 assert (lgl->scinc > 0);
3353 "[rescored-vars-%d] old score increment %s",
3354 lgl->stats->rescored.vars, lglscr2str (lgl, oldscinc));
3356 "[rescored-vars-%d] new score increment %s",
3357 lgl->stats->rescored.vars, lglscr2str (lgl, lgl->scinc));
3361 static void lglbumpscinc (LGL * lgl) {
3363 if (lgl->opts->score.val == LGL_SCORE_VSIDS256) {
3364 if (!(lgl->stats->confs & 255)) {
3366 for (idx = 2; idx < lgl->nvars; idx++) {
3367 QVar * qv = lglqvar (lgl, idx);
3369 if (qv->pos < 0) continue;
3370 lglddown (lgl, idx);
3373 } else if (lgl->opts->score.val == LGL_SCORE_EVSIDS) {
3374 oldscinc = lgl->scinc;
3375 lgl->scinc = lglmulscr (oldscinc, lgl->scincf);
3376 LOG (3, "bumped variable score increment from %s to %s",
3377 lglscr2str (lgl, oldscinc), lglscr2str (lgl, lgl->scinc));
3378 if (lgl->scinc < lgl->maxscore) return;
3379 LOG (2, "variable max score %s hit", lglscr2str (lgl, lgl->maxscore));
3380 lglrescorevars (lgl);
3384 /*------------------------------------------------------------------------*/
3386 static int lglnewvar (LGL * lgl) {
3391 assert (!lgl->dense);
3392 if (lgl->nvars == lgl->szvars) lglenlvars (lgl);
3393 if (lgl->nvars) res = lgl->nvars++;
3394 else res = 2, lgl->nvars = 3;
3395 assert (res < lgl->szvars);
3396 if (res > MAXVAR) lgldie (lgl, "more than %d variables", MAXVAR - 1);
3397 assert (res <= MAXVAR);
3398 assert (((res << RMSHFT) >> RMSHFT) == res);
3399 assert (((-res << RMSHFT) >> RMSHFT) == -res);
3400 LOG (3, "new internal variable %d", res);
3401 dv = lgl->dvars + res;
3403 av = lgl->avars + res;
3405 qv = lgl->qvars + res;
3408 lgldsched (lgl, res);
3410 lgl->allphaseset = 0;
3414 static int lglsgn (int lit) { return (lit < 0) ? -1 : 1; }
3416 static Ext * lglelit2ext (LGL * lgl, int elit) {
3417 int idx = abs (elit);
3418 assert (0 < idx), assert (idx <= lgl->maxext);
3419 return lgl->ext + idx;
3423 static Ext * lgldlit2ext (LGL * lgl, int dlit) {
3424 int idx = abs (dlit);
3425 assert (0 < idx), assert (idx <= lgl->maxdef);
3426 return lgl->def + idx;
3430 static int lglerepr (LGL * lgl, int elit) {
3433 assert (0 < abs (elit)), assert (abs (elit) <= lgl->maxext);
3436 ext = lglelit2ext (lgl, res);
3437 if (!ext->equiv) break;
3439 if (res < 0) next = -next;
3444 ext = lglelit2ext (lgl, tmp);
3445 if (!ext->equiv) { assert (tmp == res); break; }
3447 ext->repr = (tmp < 0) ? -res : res;
3448 if (tmp < 0) next = -next;
3454 static void lgladjext (LGL * lgl, int eidx) {
3456 assert (eidx >= lgl->szext);
3457 assert (eidx > lgl->maxext);
3458 assert (lgl->szext >= lgl->maxext);
3460 new = old ? 2*old : 2;
3461 while (eidx >= new) new *= 2;
3462 assert (eidx < new), assert (new >= lgl->szext);
3463 LOG (3, "enlarging external variables from %ld to %ld", old, new);
3464 RSZ (lgl->ext, old, new);
3469 static void lgladjdef (LGL * lgl, int didx) {
3472 assert (didx >= lgl->szdef);
3473 assert (didx > lgl->maxdef);
3474 assert (lgl->szdef > lgl->maxdef);
3476 new = old ? 2*old : 2;
3477 while (didx >= new) new *= 2;
3478 assert (didx < new), assert (new >= lgl->szdef);
3479 LOG (3, "enlarging defined variables from %ld to %ld", old, new);
3480 RSZ (lgl->def, old, new);
3485 static void lglmelter (LGL * lgl) {
3486 if (lgl->allfrozen) {
3488 "[melter] not all literals assumed to be frozen anymore");
3491 if (lgl->limits->elm.pen || lgl->limits->blk.pen || lgl->limits->cce.pen) {
3493 "[melter] reset penalties: %d elm, %d blk, %d cce",
3494 lgl->limits->elm.pen, lgl->limits->blk.pen, lgl->limits->cce.pen);
3495 lgl->limits->elm.pen = lgl->limits->blk.pen = lgl->limits->cce.pen = 0;
3497 lgl->frozen = lgl->allfrozen = 0;
3498 LOG (2, "melted solver");
3501 static int lglimportaux (LGL * lgl, int elit) {
3502 int res, repr, eidx = abs (elit);
3505 if (eidx >= lgl->szext) lgladjext (lgl, eidx);
3506 if (eidx > lgl->maxext) {
3510 repr = lglerepr (lgl, elit);
3511 ext = lglelit2ext (lgl, repr);
3512 assert (!ext->equiv);
3514 if (!ext->imported) {
3515 res = lglnewvar (lgl);
3516 assert (!ext->equiv);
3519 assert (eidx <= INT_MAX/2);
3520 lgl->i2e[res] = 2*eidx;
3521 LOG (3, "mapping external variable %d to %d", eidx, res);
3524 if (repr < 0) res = -res;
3525 LOG (2, "importing %d as %d", elit, res);
3529 static int lglimport (LGL * lgl, int elit) {
3531 if (!lgl->opts->import.val) {
3532 if (!lgl->maxext) (void) lglimportaux (lgl, 1);
3533 while (lgl->maxext < abs (elit))
3534 (void) lglimportaux (lgl, lgl->maxext + 1);
3536 return lglimportaux (lgl, elit);
3539 static Stk * lglidx2stk (LGL * lgl, int red, int lidx) {
3542 assert (red == 0 || red == REDCS);
3544 if (!red) s = &lgl->irr;
3546 glue = lidx & GLUEMASK;
3548 assert (lidx <= MAXREDLIDX);
3549 s = &lgl->red[glue];
3554 static int * lglidx2lits (LGL * lgl, int red, int lidx) {
3555 Stk * s = lglidx2stk (lgl, red, lidx);
3557 assert (red == 0 || red == REDCS);
3559 res = s->start + (red ? (lidx >> GLUESHFT) : lidx);
3561 if (red && (lidx & GLUEMASK) == MAXGLUE) assert (res < s->end);
3562 else assert (res < s->top);
3568 static const char * lglred2str (int red) {
3569 assert (!red || red == REDCS);
3570 return red ? "redundant" : "irredundant";
3574 static int lgliselim (LGL * lgl, int lit) {
3575 Tag tag = lglavar (lgl, lit)->type;
3576 return tag == ELIMVAR;
3580 static int lglisdef (LGL * lgl, int ilit) {
3581 int iidx = abs (ilit), tidx, res;
3582 assert (2 <= iidx), assert (iidx < lgl->nvars);
3583 tidx = lgl->i2e[iidx];
3589 static int lglexport (LGL * lgl, int ilit) {
3590 int iidx, tidx, eidx, def, res;
3592 assert (2 <= iidx), assert (iidx < lgl->nvars);
3593 tidx = lgl->i2e[iidx];
3598 if (def) eidx += lgl->maxext;
3600 if (ilit < 0) res = -res;
3604 static int * lglrsn (LGL * lgl, int lit) { return lgltd (lgl, lit)->rsn; }
3606 static int lglulit (int lit) { return 2*abs (lit) + (lit < 0); }
3608 static void lglsetdom (LGL * lgl, int lit, int dom) {
3609 assert (2 <= abs (lit) && abs (lit) < lgl->nvars);
3610 assert (2 <= abs (dom) && abs (dom) < lgl->nvars);
3611 ASSERT (lglval (lgl, lit) >= 0);
3612 ASSERT (lglval (lgl, dom) >= 0);
3613 lgl->doms[lglulit (lit)] = dom;
3614 LOG (3, "literal %d dominated by %d", lit, dom);
3617 static int lglgetdom (LGL * lgl, int lit) {
3619 assert (2 <= abs (lit) && abs (lit) < lgl->nvars);
3620 assert (lglval (lgl, lit) >= 0);
3621 res = lgl->doms[lglulit (lit)];
3625 static HTS * lglhts (LGL * lgl, int lit) {
3626 return lgldvar (lgl, lit)->hts + (lit < 0);
3629 static int * lglhts2wchs (LGL * lgl, HTS * hts) {
3630 int * res = lgl->wchs->stk.start + hts->offset;
3631 assert (res < lgl->wchs->stk.top);
3632 assert (res + hts->count < lgl->wchs->stk.top);
3633 assert (res + hts->count < lgl->wchs->stk.top);
3637 static void lglassign (LGL * lgl, int lit, int r0, int r1) {
3638 int * p, other, other2, * c, lidx, found;
3639 int idx, phase, glue, tag, dom, red, irr;
3640 AVar * av = lglavar (lgl, lit);
3642 LOGREASON (2, lit, r0, r1, "assign %d through", lit);
3643 av->trail = lglcntstk (&lgl->trail);
3644 if (av->trail >= lgl->szdrail) {
3645 int newszdrail = lgl->szdrail ? 2*lgl->szdrail : 1;
3646 RSZ (lgl->drail, lgl->szdrail, newszdrail);
3647 lgl->szdrail = newszdrail;
3649 td = lgltd (lgl, lit);
3651 dom = (tag == BINCS) ? lglgetdom (lgl, -(r0 >> RMSHFT)) : lit;
3652 lglsetdom (lgl, lit, dom);
3655 if (tag == BINCS || tag == TRNCS) {
3656 other = r0 >> RMSHFT;
3657 assert (lglval (lgl, other) < 0);
3660 assert (lglval (lgl, other2) < 0);
3662 } else if (tag == LRGCS) {
3665 c = lglidx2lits (lgl, red, lidx);
3667 for (p = c; (other = *p); p++)
3668 if (other == lit) found++;
3669 else assert (lglval (lgl, other) < 0);
3670 assert (found == 1);
3671 } else assert (tag == DECISION || tag == UNITCS);
3673 assert (!lglval (lgl, lit));
3674 assert (lgl->unassigned > 0);
3675 assert (!lgliselim (lgl, lit));
3678 phase = lglsgn (lit);
3679 lgl->vals[idx] = phase;
3680 if (!lgl->simp && !lgl->flipping && !lgl->phaseneg) {
3681 lgl->flips -= lgl->flips/100000ull;
3682 if (av->phase != phase) lgl->flips += 10000ull;
3686 if (phase < 0) av->wasfalse = 1; else av->wasfalse = 0;
3688 td->level = lgl->level;
3691 if (av->type == EQUIVAR) {
3692 assert (lgl->stats->equiv.current > 0);
3693 lgl->stats->equiv.current--;
3694 assert (lgl->stats->equiv.sum > 0);
3695 lgl->stats->equiv.sum--;
3697 assert (av->type == FREEVAR);
3698 av->type = FIXEDVAR;
3700 lgl->stats->fixed.sum++;
3701 lgl->stats->fixed.current++;
3702 lgl->stats->prgss++;
3703 lgl->stats->irrprgss++;
3704 td->rsn[0] = UNITCS | (lit << RMSHFT);
3706 if (lgl->cbs && lgl->cbs->units.produce.fun) {
3707 LOG (2, "trying to export internal unit %d external %d\n",
3708 lgl->tid, lit, lglexport (lgl, lit));
3709 lgl->stats->sync.units.produced++;
3710 lgl->cbs->units.produce.fun (lgl->cbs->units.produce.state,
3711 lglexport (lgl, lit));
3712 LOG (2, "exporting internal unit %d external %d\n",
3713 lgl->tid, lit, lglexport (lgl, lit));
3718 if (lgl->level == 1) {
3719 assert (tag != UNITCS);
3720 if (tag == DECISION) irr = 1;
3721 else if ((irr = !(red = (r0 & REDCS)))) {
3723 other = r0 >> RMSHFT;
3724 irr = lgltd (lgl, other)->irr;
3725 } else if (tag == TRNCS) {
3726 other = r0 >> RMSHFT;
3727 if ((irr = lgltd (lgl, other)->irr)) {
3729 irr = lgltd (lgl, other2)->irr;
3732 assert (tag == LRGCS);
3734 c = lglidx2lits (lgl, red, lidx);
3736 for (p = c; irr && (other = *p); p++)
3737 if (other == lit) found++;
3738 else irr = lgltd (lgl, other)->irr;
3739 assert (!irr || found == 1);
3746 lglpushstk (lgl, &lgl->trail, lit);
3747 if (!lgl->failed && (av->assumed & (1u << (lit > 0)))) {
3748 LOG (2, "failed assumption %d", -lit);
3753 if ((r0 & REDCS) && (r0 & MASKCS) == LRGCS) {
3754 glue = r1 & GLUEMASK;
3755 lgl->stats->lir[glue].forcing++;
3756 assert (lgl->stats->lir[glue].forcing > 0);
3757 if (lgl->level && 0 < glue && glue < MAXGLUE) {
3758 lgl->lrgluereasons++;
3759 assert (lgl->lrgluereasons > 0);
3763 if (glue == MAXGLUE)
3764 assert ((r1 >> GLUESHFT) + 4 < lglcntstk (&lgl->red[MAXGLUE]));
3769 static void lglf2rce (LGL * lgl, int lit, int other, int red) {
3770 assert (lglval (lgl, other) < 0);
3771 assert (!red || red == REDCS);
3772 assert (!lgliselim (lgl, other));
3773 lglassign (lgl, lit, ((other << RMSHFT) | BINCS | red), 0);
3776 static void lglf3rce (LGL * lgl, int lit, int other, int other2, int red) {
3777 assert (lglval (lgl, other) < 0);
3778 assert (lglval (lgl, other2) < 0);
3779 assert (!lgliselim (lgl, other));
3780 assert (!lgliselim (lgl, other2));
3781 assert (!red || red == REDCS);
3782 lglassign (lgl, lit, ((other << RMSHFT) | TRNCS | red), other2);
3785 static void lglflrce (LGL * lgl, int lit, int red, int lidx) {
3787 int * p = lglidx2lits (lgl, red, lidx), other;
3788 while ((other = *p++)) {
3789 assert (!lgliselim (lgl, other));
3790 if (other != lit) assert (lglval (lgl, other) < 0);
3792 assert (red == 0 || red == REDCS);
3794 lglassign (lgl, lit, red | LRGCS, lidx);
3797 static int lgldscheduled (LGL * lgl, int lit) {
3798 return lglqvar (lgl, lit)->pos >= 0;
3801 static void lglunassign (LGL * lgl, int lit) {
3802 int idx = abs (lit), r0, r1, tag, lidx, glue;
3804 LOG (2, "unassign %d", lit);
3805 assert (lglval (lgl, lit) > 0);
3806 assert (lgl->vals[idx] == lglsgn (lit));
3809 assert (lgl->unassigned > 0);
3810 if (!lgldscheduled (lgl, lit)) lgldsched (lgl, idx);
3811 td = lgltd (lgl, idx);
3813 if (!(r0 & REDCS)) return;
3815 if (tag != LRGCS) return;
3817 glue = r1 & GLUEMASK;
3819 assert (lgl->lrgluereasons > 0);
3820 lgl->lrgluereasons--;
3822 if (glue < MAXGLUE) return;
3823 lidx = r1 >> GLUESHFT;
3824 LOG (2, "eagerly deleting maximum glue clause at %d", lidx);
3825 lglrststk (&lgl->red[glue], lidx);
3828 static Val lglifixed (LGL * lgl, int lit) {
3830 if (!(res = lglval (lgl, lit))) return 0;
3831 if (lglevel (lgl, lit) > 0) return 0;
3835 static void lglbacktrack (LGL * lgl, int level) {
3837 assert (level >= 0);
3838 assert (lgl->level > level);
3839 LOG (2, "backtracking to level %d", level);
3840 assert (level <= lgl->level);
3841 assert (abs (lgl->failed) != 1 || lgl->failed == -1);
3843 lgl->failed != -1 &&
3844 lglevel (lgl, lgl->failed) > level) {
3845 LOG (2, "resetting failed assumption %d", lgl->failed);
3848 while (!lglmtstk (&lgl->trail)) {
3849 lit = lgltopstk (&lgl->trail);
3850 assert (abs (lit) > 1);
3851 if (lglevel (lgl, lit) <= level) break;
3852 lglunassign (lgl, lit);
3856 assert (!lgl->lrgluereasons);
3857 while (!lglmtstk (&lgl->red[MAXGLUE])) {
3858 int tmp = lglpopstk (&lgl->red[MAXGLUE]);
3859 assert (tmp >= NOTALIT);
3863 if (lgl->alevel > level) {
3865 "resetting assumption decision level to %d from %d",
3866 level, lgl->alevel);
3867 lgl->alevel = level;
3870 "resetting assumption queue level to 0 from %d",
3876 lglrstcontrol (lgl, level + 1);
3877 assert (lglcntctk (&lgl->control) == lgl->level + 1);
3879 lgl->conf.rsn[0] = lgl->conf.rsn[1] = 0;
3880 lgl->next2 = lgl->next = lglcntstk (&lgl->trail);
3881 LOG (2, "backtracked ");
3884 static int lglmarked (LGL * lgl, int lit) {
3885 int res = lglavar (lgl, lit)->mark;
3886 if (lit < 0) res = -res;
3890 static void lgldrupinc (LGL * lgl) {
3891 assert (lgl->opts->drup.val);
3892 if (lgl->stats->drupped++) return;
3893 printf ("o proof DRUP\n");
3896 static void lgldrupclsaux (LGL * lgl, const int * cls) {
3899 for (p = cls; *p; p++) printf ("%d ", lglexport (lgl, *p));
3904 static void lgldrupcls (LGL * lgl) {
3905 lgldrupclsaux (lgl, lgl->clause.start);
3908 static void lgldrupclsarg (LGL * lgl, int first, ...) {
3911 assert (lgl->opts->drup.val);
3913 printf ("%d", first ? lglexport (lgl, first) : 0);
3915 va_start (ap, first);
3917 lit = va_arg (ap, int);
3918 printf (" %d", lit ? lglexport (lgl, lit) : 0);
3927 #define PICOSAT (assert (lgl && lgl->picosat.solver), lgl->picosat.solver)
3930 static void lglpicosataddcls (LGL* lgl, const int * c){
3932 lglpicosatinit (lgl);
3933 for (p = c; *p; p++) picosat_add (PICOSAT, *p);
3934 picosat_add (PICOSAT, 0);
3938 static void lglpicosatchkclsaux (LGL * lgl, int * c) {
3941 lglpicosatinit (lgl);
3942 if (picosat_inconsistent (PICOSAT)) {
3943 LOG (3, "no need to check since PicoSAT is already inconsistent");
3946 LOGCLS (3, c, "checking consistency with PicoSAT of clause");
3947 for (p = c; *p; p++) picosat_assume (PICOSAT, -*p);
3948 (void) picosat_sat (PICOSAT, -1);
3949 assert (picosat_res (PICOSAT) == 20);
3953 static void lglpicosatchkcls (LGL * lgl) {
3954 lglpicosatchkclsaux (lgl, lgl->clause.start);
3957 static void lglpicosatchkclsarg (LGL * lgl, int first, ...) {
3962 if (!lgl->opts->check.val) return;
3963 lglpicosatinit (lgl);
3966 va_start (ap, first);
3967 lglpushstk (lgl, &stk, first);
3969 lit = va_arg (ap, int);
3971 lglpushstk (lgl, &stk, lit);
3975 lglpushstk (lgl, &stk, 0);
3976 lglpicosatchkclsaux (lgl, stk.start);
3977 lglrelstk (lgl, &stk);
3981 static void lglpicosatchkunsat (LGL * lgl) {
3984 lglpicosatinit (lgl);
3985 if (lgl->picosat.res) {
3986 LOG (1, "determined earlier that PicoSAT proved unsatisfiability");
3987 assert (lgl->picosat.res == 20);
3989 if (picosat_inconsistent (PICOSAT)) {
3990 LOG (1, "PicoSAT is already in inconsistent state");
3993 for (p = lgl->eassume.start; p < lgl->eassume.top; p++)
3994 picosat_assume (PICOSAT, lglimport (lgl, *p));
3995 res = picosat_sat (PICOSAT, -1);
3997 LOG (1, "PicoSAT proved unsatisfiability");
4002 static void lglunitnocheck (LGL * lgl, int lit) {
4003 ASSERT (!lgl->level);
4004 LOG (1, "unit %d", lit);
4005 lglassign (lgl, lit, (lit << RMSHFT) | UNITCS, 0);
4009 static int lgldruplig (LGL * lgl) {
4010 if (!lgl->opts->druplig.val) return 0;
4011 if (!lgl->druplig) lgl->druplig = druplig_init ();
4016 static void lgldrupligaddclsarg (LGL * lgl, int red, ...) {
4018 if (lgldruplig (lgl)) {
4022 int lit = va_arg (ap, int);
4024 druplig_add_literal (lgl->druplig, lglexport (lgl, lit));
4026 if (red) druplig_check_and_add_redundant_clause (lgl->druplig);
4027 else druplig_add_original_clause (lgl->druplig);
4030 (void) lgl, (void) red;
4034 static void lglunit (LGL * lgl, int lit) {
4035 if (lgl->opts->drup.val) lgldrupclsarg (lgl, lit, 0);
4037 lglpicosatchkclsarg (lgl, lit, 0);
4039 lgldrupligaddclsarg (lgl, REDCS, lglexport (lgl, lit), 0);
4040 lglunitnocheck (lgl, lit);
4043 static void lglmark (LGL * lgl, int lit) {
4044 lglavar (lgl, lit)->mark = lglsgn (lit);
4047 static void lglmarkunmarked (LGL * lgl, int lit) {
4048 AVar * av = lglavar (lgl, lit);
4050 av->mark = lglsgn (lit);
4053 static void lglunmark (LGL * lgl, int lit) { lglavar (lgl, lit)->mark = 0; }
4055 static void lglchksimpcls (LGL * lgl) {
4059 for (p = lgl->clause.start; (lit = *p); p++) {
4060 tmp = lglifixed (lgl, lit);
4062 av = lglavar (lgl, lit);
4066 while (p > lgl->clause.start)
4067 lglavar (lgl, *--p)->simp = 0;
4071 static int lglcval (LGL * lgl, int litorval) {
4073 if (litorval == 1 || litorval == -1) return litorval;
4074 return lglval (lgl, litorval);
4077 /*------------------------------------------------------------------------*/
4079 static int lglsimpcls (LGL * lgl) {
4080 int * p, * q = lgl->clause.start, lit, tmp, mark;
4081 for (p = lgl->clause.start; (lit = *p); p++) {
4082 tmp = lglcval (lgl, lit);
4083 if (tmp == 1) { LOG (4, "literal %d satisfies clauses", lit); break; }
4084 if (tmp == -1) { LOG (4, "removing false literal %d", lit); continue; }
4085 mark = lglmarked (lgl, lit);
4087 { LOG (4, "removing duplicated literal %d", lit); continue; }
4089 { LOG (4, "literals %d and %d occur both", -lit, lit); break; }
4095 lgl->clause.top = q + 1;
4097 while (q > lgl->clause.start) lglunmark (lgl, *--q);
4099 if (lit) LOG (2, "simplified clause is trivial");
4100 else LOGCLS (2, lgl->clause.start, "simplified clause");
4105 static void lglorderclsaux (LGL * lgl, int * start) {
4106 int * p, max = 0, level, lit;
4107 for (p = start; (lit = *p); p++) {
4108 if (!lglval (lgl, lit)) continue;
4109 level = lglevel (lgl, lit);
4110 if (level <= max) continue;
4117 static void lglordercls (LGL * lgl) {
4118 assert (lglcntstk (&lgl->clause) > 2);
4119 lglorderclsaux (lgl, lgl->clause.start);
4120 LOG (3, "head literal %d", lgl->clause.start[0]);
4121 lglorderclsaux (lgl, lgl->clause.start + 1);
4122 LOG (3, "tail literal %d", lgl->clause.start[1]);
4123 LOGCLS (3, lgl->clause.start, "ordered clause");
4125 /*------------------------------------------------------------------------*/
4128 static void lglfreewch (LGL * lgl, int oldoffset, int oldhcount) {
4129 int ldoldhcount = lglceilld (oldhcount);
4130 lgl->wchs->stk.start[oldoffset] = lgl->wchs->start[ldoldhcount];
4132 lgl->wchs->start[ldoldhcount] = oldoffset;
4134 assert (lgl->wchs->free > 0);
4135 LOG (5, "saving watch stack at %d of size %d on free list %d",
4136 oldoffset, oldhcount, ldoldhcount);
4139 static void lglshrinkhts (LGL * lgl, HTS * hts, int newcount) {
4140 int * p, i, oldcount = hts->count;
4141 assert (newcount <= oldcount);
4142 if (newcount == oldcount) return;
4143 p = lglhts2wchs (lgl, hts);
4144 for (i = newcount; i < oldcount; i++) p[i] = 0;
4145 hts->count = newcount;
4146 if (newcount) return;
4147 lglfreewch (lgl, hts->offset, oldcount);
4151 static long lglenlwchs (LGL * lgl, HTS * hts) {
4152 int oldhcount = hts->count, oldoffset = hts->offset, newoffset;
4153 int oldwcount, newwcount, oldwsize, newwsize, i, j;
4154 int newhcount = oldhcount ? 2*oldhcount : 1;
4155 int * oldwstart, * newwstart, * start;
4156 int ldnewhcount = lglfloorld (newhcount);
4159 newhcount = (1<<ldnewhcount);
4160 assert (newhcount > oldhcount);
4162 LOG (5, "increasing watch stack at %d from %d to %d",
4163 oldoffset, oldhcount, newhcount);
4165 assert (!oldoffset == !oldhcount);
4167 lgl->stats->enlwchs++;
4169 newoffset = lgl->wchs->start[ldnewhcount];
4170 start = lgl->wchs->stk.start;
4171 if (newoffset != INT_MAX) {
4172 lgl->wchs->start[ldnewhcount] = start[newoffset];
4173 start[newoffset] = 0;
4174 assert (lgl->wchs->free > 0);
4176 LOG (5, "reusing free watch stack at %d of size %d",
4177 newoffset, (1 << ldnewhcount));
4179 assert (lgl->wchs->stk.start[hts->offset]);
4180 assert (lgl->wchs->stk.top[-1] == INT_MAX);
4182 oldwcount = lglcntstk (&lgl->wchs->stk);
4183 newwcount = oldwcount + newhcount;
4184 oldwsize = lglszstk (&lgl->wchs->stk);
4185 newwsize = oldwsize;
4187 assert (lgl->wchs->stk.top == lgl->wchs->stk.start + oldwcount);
4188 assert (oldwcount > 0);
4190 while (newwsize < newwcount) newwsize *= 2;
4191 if (newwsize > oldwsize) {
4192 newwstart = oldwstart = lgl->wchs->stk.start;
4193 RSZ (newwstart, oldwsize, newwsize);
4194 LOG (3, "resized global watcher stack from %d to %d",
4195 oldwsize, newwsize);
4196 res = newwstart - oldwstart;
4198 LOG (3, "moved global watcher stack by %ld", res);
4199 start = lgl->wchs->stk.start = newwstart;
4201 lgl->wchs->stk.end = start + newwsize;
4203 lgl->wchs->stk.top = start + newwcount;
4204 lgl->wchs->stk.top[-1] = INT_MAX;
4205 newoffset = oldwcount - 1;
4207 "new watch stack of size %d at end of global watcher stack at %d",
4208 newhcount, newoffset);
4210 assert (start == lgl->wchs->stk.start);
4213 for (i = oldoffset; i < oldoffset + oldhcount; i++) {
4214 start[j++] = start[i];
4217 while (j < newoffset + newhcount)
4219 assert (start + j <= lgl->wchs->stk.top);
4220 hts->offset = newoffset;
4221 if (oldhcount > 0) lglfreewch (lgl, oldoffset, oldhcount);
4225 static long lglpushwch (LGL * lgl, HTS * hts, int wch) {
4227 int * wchs = lglhts2wchs (lgl, hts);
4228 assert (sizeof (res) == sizeof (void*));
4229 assert (hts->count >= 0);
4230 if (wchs[hts->count]) {
4231 res = lglenlwchs (lgl, hts);
4232 wchs = lglhts2wchs (lgl, hts);
4234 assert (!wchs[hts->count]);
4235 assert (wch != INT_MAX);
4236 wchs[hts->count++] = wch;
4237 lgl->stats->pshwchs++;
4238 assert (lgl->stats->pshwchs > 0);
4242 static long lglwchbin (LGL * lgl, int lit, int other, int red) {
4243 HTS * hts = lglhts (lgl, lit);
4244 int cs = ((other << RMSHFT) | BINCS | red);
4246 assert (red == 0 || red == REDCS);
4247 res = lglpushwch (lgl, hts, cs);
4248 LOG (3, "new %s binary watch %d blit %d", lglred2str (red), lit, other);
4252 static long lglwchtrn (LGL * lgl, int a, int b, int c, int red) {
4253 HTS * hts = lglhts (lgl, a);
4254 int cs = ((b << RMSHFT) | TRNCS | red);
4256 assert (red == 0 || red == REDCS);
4257 res = lglpushwch (lgl, hts, cs);
4258 res += lglpushwch (lgl, hts, c);
4259 LOG (3, "new %s ternary watch %d blits %d %d", lglred2str (red), a, b, c);
4263 static long lglwchlrg (LGL * lgl, int lit, int other, int red, int lidx) {
4264 HTS * hts = lglhts (lgl, lit);
4265 int blit = ((other << RMSHFT) | LRGCS | red);
4267 assert (red == 0 || red == REDCS);
4268 res += lglpushwch (lgl, hts, blit);
4269 res += lglpushwch (lgl, hts, lidx);
4272 int * p = lglidx2lits (lgl, red, lidx);
4275 "watching %d with blit %d in red[%d][%d] %d %d %d %d%s",
4276 lit, other, (lidx & GLUEMASK), (lidx >> GLUESHFT),
4277 p[0], p[1], p[2], p[3], (p[4] ? " ..." : ""));
4280 "watching %d with blit %d in irr[%d] %d %d %d %d%s",
4281 lit, other, lidx, p[0], p[1], p[2], p[3], (p[4] ? " ..." : ""));
4284 assert (sizeof (res) == sizeof (void*));
4288 /*------------------------------------------------------------------------*/
4290 static EVar * lglevar (LGL * lgl, int lit) {
4291 int idx = abs (lit);
4292 assert (1 <= idx && idx < lgl->nvars);
4293 return lgl->evars + idx;
4296 static int * lglepos (LGL * lgl, int lit) {
4299 ev = lglevar (lgl, lit);
4304 static int lglecmp (LGL * lgl, int l, int k) {
4305 return lglevar (lgl,k)->score - lglevar (lgl,l)->score;
4309 static void lglchkesched (LGL * lgl) {
4310 int * p, parent, child, ppos, cpos, size, i, tmp;
4311 Stk * s = &lgl->esched;
4312 size = lglcntstk (s);
4314 for (ppos = 0; ppos < size; ppos++) {
4316 tmp = *lglepos (lgl, parent);
4317 assert (ppos == tmp);
4318 for (i = 0; i <= 1; i++) {
4319 cpos = 2*ppos + 1 + i;
4320 if (cpos >= size) continue;
4322 tmp = *lglepos (lgl, child);
4323 assert (cpos == tmp);
4324 assert (lglecmp (lgl, parent, child) >= 0);
4330 static void lgleup (LGL * lgl, int lit) {
4331 int child = lit, parent, cpos, ppos, * p, * cposptr, * pposptr;
4332 Stk * s = &lgl->esched;
4334 cposptr = lglepos (lgl, child);
4338 ppos = (cpos - 1)/2;
4340 if (lglecmp (lgl, parent, lit) >= 0) break;
4341 pposptr = lglepos (lgl, parent);
4342 assert (*pposptr == ppos);
4345 LOGESCHED (5, parent, "down from %d", ppos);
4348 if (*cposptr == cpos) return;
4354 LOGESCHED (5, lit, "up from %d", ppos);
4356 if (lgl->opts->check.val >= 2) lglchkesched (lgl);
4360 static void lgledown (LGL * lgl, int lit) {
4361 int parent = lit, child, right, ppos, cpos;
4362 int * p, * pposptr, * cposptr, size;
4363 Stk * s = &lgl->esched;
4364 size = lglcntstk (s);
4366 pposptr = lglepos (lgl, parent);
4371 if (cpos >= size) break;
4373 if (cpos + 1 < size) {
4374 right = p[cpos + 1];
4375 if (lglecmp (lgl, child, right) < 0)
4376 cpos++, child = right;
4378 if (lglecmp (lgl, child, lit) <= 0) break;
4379 cposptr = lglepos (lgl, child);
4380 assert (*cposptr = cpos);
4383 LOGESCHED (5, child, "up from %d", cpos);
4386 if (*pposptr == ppos) return;
4392 LOGESCHED (5, lit, "down from %d", cpos);
4394 if (lgl->opts->check.val >= 2) lglchkesched (lgl);
4398 static int lglifrozen (LGL * lgl, int ilit) {
4399 int elit = lglexport (lgl, ilit);
4400 Ext * ext = lglelit2ext (lgl, elit);
4401 return ext->frozen || ext->tmpfrozen;
4404 static void lglesched (LGL * lgl, int lit) {
4408 if (lgl->cceing) return;
4409 if (lgl->cgrclosing) return;
4410 if (lglifrozen (lgl, lit)) return;
4411 if (!lglisfree (lgl, lit)) return;
4412 if (lgl->donotsched) {
4413 av = lglavar (lgl, lit);
4414 if (lgl->eliminating && av->donotelm) return;
4415 if (lgl->blocking && av->donotblk) return;
4417 p = lglepos (lgl, lit);
4419 if (*p >= 0) return;
4421 lglpushstk (lgl, s, lit);
4423 lgledown (lgl, lit);
4424 LOGESCHED (4, lit, "pushed");
4427 /*------------------------------------------------------------------------*/
4429 static unsigned lglgcd (unsigned a, unsigned b) {
4431 assert (a), assert (b);
4432 if (a < b) SWAP (unsigned, a, b);
4433 while (b) tmp = b, b = a % b, a = tmp;
4437 static uint64_t lglgcd64 (uint64_t a, uint64_t b) {
4439 assert (a), assert (b);
4440 if (a < b) SWAP (uint64_t, a, b);
4441 while (b) tmp = b, b = a % b, a = tmp;
4445 static int lglrandidxtrav (LGL * lgl, int (*fun)(LGL*,int idx)) {
4446 int idx, delta, mod, prev, first, res;
4447 first = mod = lglmax (lgl->nvars, 2);
4448 idx = lglrand (lgl) % mod;
4449 delta = lglrand (lgl) % mod;
4450 if (!delta) delta++;
4451 while (lglgcd (delta, mod) > 1)
4452 if (++delta == mod) delta = 1;
4455 "random index traversal start %d delta %d mod %d",
4458 if (idx >= 2 && !fun (lgl, idx)) res = 0;
4462 if (idx >= mod) idx -= mod;
4463 if (idx == first) break;
4464 if (first == mod) first = prev;
4470 static int lglrem (LGL * lgl) {
4471 int res = lgl->nvars;
4474 res -= lgl->stats->fixed.current + 2;
4479 static double lglpcnt (double n, double d) {
4480 if (d <= 0 || !n) return 0.0;
4481 return 100.0 * n / d;
4484 static int lglecalc (LGL * lgl, EVar * ev) {
4485 int oldscore = ev->score, o0 = ev->occ[0], o1 = ev->occ[1], newscore;
4486 if (lgl->eliminating) {
4487 if (lgl->opts->elmschedpure.val && (!o0 || !o1)) newscore = 0;
4488 else if (lgl->opts->elmsched2b2.val && o0 <= 2 && o1 <= 2) newscore = 1;
4491 if (lgl->opts->elmschedsum.val) newscore += o0 + o1;
4492 if (lgl->opts->elmschedmin.val) newscore += lglmin (o0, o1);
4493 if (lgl->opts->elmschediff.val) newscore -= o0 < o1 ? o1-o0 : o0-o1;
4494 if (lgl->opts->elmschedprod.val) {
4495 int64_t tmp = newscore, prod = o0 * (int64_t) o1;
4497 newscore = tmp <= INT_MAX ? tmp : INT_MAX;
4501 assert (lgl->blocking);
4502 if (lgl->opts->blkschedpure.val && (!o0 || !o1)) newscore = 0;
4503 else if (lgl->opts->blksched2b2.val && o0 <= 2 && o1 <= 2) newscore = 1;
4506 if (lgl->opts->blkschedsum.val) newscore += o0 + o1;
4507 if (lgl->opts->blkschedmin.val) newscore += lglmin (o0, o1);
4508 if (lgl->opts->blkschedprod.val) {
4509 int64_t tmp = newscore, prod = o0 * (int64_t) o1;
4511 newscore = tmp <= INT_MAX ? tmp : INT_MAX;
4515 ev->score = newscore;
4516 return newscore - oldscore;
4519 static int lglocc (LGL * lgl, int lit) {
4520 if (!lgl->occs) return lglhts (lgl, lit)->count;
4521 return lglevar (lgl, lit)->occ[lit < 0];
4524 static void lglincocc (LGL * lgl, int lit) {
4525 int idx, sign, change;
4527 if (!lgl->occs) return;
4528 idx = abs (lit), sign = (lit < 0);
4529 ev = lglevar (lgl, lit);
4530 assert (lglisfree (lgl, lit));
4532 assert (ev->occ[sign] > 0);
4533 change = lglecalc (lgl, ev);
4534 LOG (3, "inc occ of %d now occs[%d] = %d %d",
4535 lit, idx, ev->occ[0], ev->occ[1]);
4536 if (ev->pos < 0) lglesched (lgl, idx);
4537 else if (change > 0) lgledown (lgl, idx);
4538 else if (change < 0) lgleup (lgl, idx);
4541 static int lglisact (int act) { return NOTALIT <= act && act < REMOVED-1; }
4543 static int lglrescoreglue (LGL * lgl, int glue) {
4544 int * c, * p, oldact, newact, count = 0;;
4545 Stk * lir = lgl->red + glue;
4546 for (c = lir->start; c < lir->top; c = p + 1) {
4548 if (oldact == REMOVED) {
4549 for (p = c + 1; p < lir->top && *p == REMOVED; p++)
4551 assert (p >= lir->top || *p < NOTALIT || lglisact (*p));
4554 assert (NOTALIT <= oldact && oldact <= REMOVED - 1);
4555 newact = NOTALIT + ((oldact - NOTALIT) + 1) / 2;
4557 LOGCLS (5, c, "rescoring activity from %d to %d of clause",
4558 oldact - NOTALIT, newact - NOTALIT);
4559 for (p = c; *p; p++)
4567 static void lglrescoreclauses (LGL * lgl) {
4568 int glue, count = 0;;
4569 lgl->stats->rescored.clauses++;
4570 for (glue = 0; glue < MAXGLUE; glue++)
4571 count += lglrescoreglue (lgl, glue);
4572 lglprt (lgl, RVL, "[rescored-clauses-%d] rescored activity of %d clauses",
4573 lgl->stats->rescored.clauses, count);
4576 static void lglchkirrstats (LGL * lgl) {
4578 int idx, sign, lit, blit, tag, red, other, other2, clauses, lits;
4579 const int * p, * w, * eow, * c, * top;
4582 for (idx = 2; idx < lgl->nvars; idx++)
4583 for (sign = -1; sign <= 1; sign += 2) {
4585 hts = lglhts (lgl, lit);
4586 w = lglhts2wchs (lgl, hts);
4587 eow = w + hts->count;
4588 for (p = w; p < eow; p++) {
4590 tag = blit & MASKCS;
4591 if (tag == TRNCS || tag == LRGCS) p++;
4595 other = blit >> RMSHFT;
4596 if (abs (other) < idx) continue;
4598 } else if (tag == TRNCS) {
4599 other = blit >> RMSHFT;
4600 if (abs (other) < idx) continue;
4602 if (abs (other2) < idx) continue;
4609 for (c = lgl->irr.start; c < top; c = p + 1) {
4610 if (*(p = c) >= NOTALIT) continue;
4616 assert (clauses == lgl->stats->irr.clauses.cur);
4617 assert (lits == lgl->stats->irr.lits.cur);
4623 static void lglincirr (LGL * lgl, int size) {
4624 if (size < 2) return;
4625 lgl->stats->irr.clauses.cur++;
4626 assert (lgl->stats->irr.clauses.cur > 0);
4627 if (lgl->stats->irr.clauses.cur > lgl->stats->irr.clauses.max)
4628 lgl->stats->irr.clauses.max = lgl->stats->irr.clauses.cur;
4629 lgl->stats->irr.lits.cur += size;
4630 assert (lgl->stats->irr.lits.cur >= size);
4631 if (lgl->stats->irr.lits.cur > lgl->stats->irr.lits.max)
4632 lgl->stats->irr.lits.max = lgl->stats->irr.lits.cur;
4633 lgl->stats->irrprgss++;
4636 static void lgldecirr (LGL * lgl, int size) {
4638 assert (lgl->stats->irr.clauses.cur > 0);
4639 lgl->stats->irr.clauses.cur--;
4640 assert (lgl->stats->irr.lits.cur >= size);
4641 lgl->stats->irr.lits.cur -= size;
4642 assert (!lgl->stats->irr.clauses.cur == !lgl->stats->irr.lits.cur);
4643 lgl->stats->irrprgss++;
4646 static void lglbumplidx (LGL * lgl, int lidx) {
4647 int glue = (lidx & GLUEMASK), * c, *ap, act;
4648 Stk * lir = lgl->red + glue;
4649 if (glue >= MAXGLUE) return;
4651 c = lir->start + lidx;
4652 assert (lir->start < c && c < lir->end);
4655 if (act < REMOVED - 1) {
4661 LOGCLS (4, c, "bumped activity to %d of glue %d clause", act-NOTALIT, glue);
4662 lgl->stats->lir[glue].resolved++;
4663 assert (lgl->stats->lir[glue].resolved > 0);
4664 if (act >= REMOVED - 1) lglrescoreclauses (lgl);
4667 static void lglincjwh (LGL * lgl, int lit, Flt inc) {
4668 int ulit = lglulit (lit);
4669 Flt old = lgl->jwh[ulit];
4670 Flt new = lgladdflt (old, inc);
4671 lgl->jwh[ulit] = new;
4674 static int lglscaleglue (LGL * lgl, int origlue) {
4675 int scaledglue, redglue;
4676 assert (0 <= origlue);
4677 if (origlue <= lgl->opts->gluekeep.val) scaledglue = 0;
4678 else if (origlue >= lgl->opts->maxglue.val) scaledglue = MAXGLUE;
4680 redglue = origlue - lgl->opts->gluekeep.val;
4681 assert (redglue >= 1);
4682 switch (lgl->opts->gluescale.val) {
4684 scaledglue = lglceilsqrt32 (redglue);
4685 if (scaledglue > MAXGLUE/2)
4686 scaledglue = MAXGLUE/2 + 1 + lglceilld (scaledglue - MAXGLUE/2);
4688 case 3: scaledglue = 1 + lglceilld (redglue); break;
4689 case 2: scaledglue = lglceilsqrt32 (redglue); break;
4690 default: scaledglue = redglue; break;
4692 assert (scaledglue > 0);
4693 if (scaledglue > MAXGLUE) scaledglue = MAXGLUE;
4695 if (lgl->opts->keepmaxglue.val && scaledglue == MAXGLUE)
4696 scaledglue = MAXGLUE-1;
4697 assert (0 <= scaledglue && scaledglue <= MAXGLUE);
4701 static void lgldrupligaddcls (LGL * lgl, int red) {
4703 if (lgldruplig (lgl)) {
4706 for (p = lgl->clause.start; p < lgl->clause.top; p++)
4708 druplig_add_literal (lgl->druplig, lglexport (lgl, lit));
4709 if (red) druplig_check_and_add_redundant_clause (lgl->druplig);
4710 else druplig_add_original_clause (lgl->druplig);
4713 (void) lgl, (void) red;
4717 static int lgladdcls (LGL * lgl, int red, int origlue, int force) {
4718 int size, lit, other, other2, * p, lidx, unit, blit;
4719 int scaledglue, prevglue;
4723 lgl->stats->prgss++;
4724 if (lgl->eliminating) {
4725 size = lglcntstk (&lgl->clause);
4726 ADDSTEPS (elm.steps, size);
4728 if (!red) lgl->stats->irrprgss++;
4729 assert (!lglmtstk (&lgl->clause));
4730 assert (!lgl->clause.top[-1]);
4731 if (force) lglchksimpcls (lgl);
4732 #if !defined(NLGLPICOSAT) && !defined(NDEBUG)
4733 lglpicosataddcls (lgl, lgl->clause.start);
4735 size = lglcntstk (&lgl->clause) - 1;
4736 if (!red) lglincirr (lgl, size);
4737 else if (size == 2) lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
4738 else if (size == 3) lgl->stats->red.trn++, assert (lgl->stats->red.trn > 0);
4741 LOG (1, "found empty clause");
4745 lit = lgl->clause.start[0];
4747 assert (lglval (lgl, lit) >= 0);
4748 if (!lglval (lgl, lit)) {
4749 if (red) lglunit (lgl, lit);
4750 else lglunitnocheck (lgl, lit);
4754 inc = lglflt (-size, 1);
4755 other = lgl->clause.start[1];
4757 lglwchbin (lgl, lit, other, red);
4758 lglwchbin (lgl, other, lit, red);
4760 if (force && lglval (lgl, lit) < 0) lglf2rce (lgl, other, lit, REDCS);
4761 if (force && lglval (lgl, other) < 0) lglf2rce (lgl, lit, other, REDCS);
4762 } else if (lgl->dense) {
4764 lglincocc (lgl, lit);
4765 lglincocc (lgl, other);
4767 if (!red) lglincjwh (lgl, lit, inc), lglincjwh (lgl, other, inc);
4771 lit = lgl->clause.start[0];
4772 other = lgl->clause.start[1];
4774 other2 = lgl->clause.start[2];
4775 lglwchtrn (lgl, lit, other, other2, red);
4776 lglwchtrn (lgl, other, lit, other2, red);
4777 lglwchtrn (lgl, other2, lit, other, red);
4779 if (force && lglval (lgl, lit) < 0 && lglval (lgl, other) < 0)
4780 lglf3rce (lgl, other2, lit, other, REDCS);
4781 if (force && lglval (lgl, lit) < 0 && lglval (lgl, other2) < 0)
4782 lglf3rce (lgl, other, lit, other2, REDCS);
4783 if (force && lglval (lgl, other) < 0 && lglval (lgl, other2) < 0)
4784 lglf3rce (lgl, lit, other, other2, REDCS);
4785 } else if (lgl->dense) {
4787 lglincocc (lgl, lit);
4788 lglincocc (lgl, other);
4789 lglincocc (lgl, other2);
4791 if (!red) lglincjwh (lgl, lit, inc),
4792 lglincjwh (lgl, other, inc),
4793 lglincjwh (lgl, other2, inc);
4798 scaledglue = lglscaleglue (lgl, origlue);
4799 lgl->stats->clauses.scglue += scaledglue;
4800 if (scaledglue == MAXGLUE) lgl->stats->clauses.maxglue++;
4801 else lgl->stats->clauses.nonmaxglue++;
4802 w = lgl->red + scaledglue;
4803 lidx = lglcntstk (w) + 1;
4804 if (lidx > MAXREDLIDX) {
4805 prevglue = scaledglue;
4806 if (lidx > MAXREDLIDX) {
4807 scaledglue = prevglue;
4808 while (scaledglue + 1 < MAXGLUE && lidx > MAXREDLIDX) {
4809 w = lgl->red + ++scaledglue;
4810 lidx = lglcntstk (w) + 1;
4813 if (lidx > MAXREDLIDX) {
4814 scaledglue = prevglue;
4815 while (scaledglue > 0 && lidx > MAXREDLIDX) {
4816 w = lgl->red + --scaledglue;
4817 lidx = lglcntstk (w) + 1;
4820 if (lidx > MAXREDLIDX && scaledglue < MAXGLUE) {
4821 w = lgl->red + (scaledglue = MAXGLUE);
4822 lidx = lglcntstk (w) + 1;
4824 if (lidx > MAXREDLIDX && scaledglue == MAXGLUE) {
4825 lglbacktrack (lgl, 0);
4826 lidx = lglcntstk (w);
4829 if (lidx > MAXREDLIDX)
4830 lgldie (lgl, "number of redundant large clause literals exhausted");
4832 lglpushstk (lgl, w, NOTALIT);
4833 assert (lidx == lglcntstk (w));
4837 lgl->stats->lir[scaledglue].clauses++;
4838 assert (lgl->stats->lir[scaledglue].clauses > 0);
4839 lgl->stats->lir[scaledglue].added++;
4840 assert (lgl->stats->lir[scaledglue].added > 0);
4843 lidx = lglcntstk (w);
4845 if (lidx <= 0 && !lglmtstk (w))
4846 lgldie (lgl, "number of irredundant large clause literals exhausted");
4848 for (p = lgl->clause.start; (other2 = *p); p++)
4849 lglpushstk (lgl, w, other2), lglincjwh (lgl, other2, inc);
4850 lglpushstk (lgl, w, 0);
4853 for (p = lgl->clause.start; (other2 = *p); p++) {
4854 val = lglval (lgl, other2);
4855 assert (!force || val <= 0);
4856 if (val < 0) continue;
4857 if (unit) unit = INT_MAX;
4860 if (force && unit && unit != INT_MAX) lglflrce (lgl, unit, red, lidx);
4862 assert (red == 0 || red == REDCS);
4863 if (!red || (red && scaledglue < MAXGLUE)) {
4864 (void) lglwchlrg (lgl, lit, other, red, lidx);
4865 (void) lglwchlrg (lgl, other, lit, red, lidx);
4867 if (red && scaledglue != MAXGLUE) {
4868 lglbumplidx (lgl, lidx);
4869 lgl->stats->red.lrg++;
4871 if (!red && lgl->dense >= 2) {
4872 if (lidx > MAXIRRLIDX)
4873 lgldie (lgl, "number of irredundant large clause literals exhausted");
4874 blit = (lidx << RMSHFT) | OCCS;
4875 for (p = lgl->clause.start; (other2 = *p); p++) {
4876 lglincocc (lgl, other2);
4877 lglpushwch (lgl, lglhts (lgl, other2), blit);
4880 lglchkirrstats (lgl);
4884 static void lgliadd (LGL * lgl, int ilit) {
4887 if (lglmtstk (&lgl->clause)) LOG (4, "opening irredundant clause");
4889 assert (abs (ilit) < 2 || abs (ilit) < lgl->nvars);
4890 lglpushstk (lgl, &lgl->clause, ilit);
4892 LOG (4, "added literal %d", ilit);
4894 LOG (4, "closing irredundant clause");
4895 LOGCLS (3, lgl->clause.start, "unsimplified irredundant clause");
4896 if (!lglsimpcls (lgl)) {
4897 lgldrupligaddcls (lgl, 0);
4898 lgladdcls (lgl, 0, 0, 1);
4899 lgl->stats->irr.clauses.add++;
4900 size = lglcntstk (&lgl->clause) - 1;
4902 lgl->stats->irr.lits.add += size;
4904 lglclnstk (&lgl->clause);
4908 static void lgleunassignall (LGL * lgl) {
4910 for (eidx = 1; eidx <= lgl->maxext; eidx++)
4911 lglelit2ext (lgl, eidx)->val = 0;
4914 static void lglchkeassumeclean (LGL * lgl) {
4915 assert (lglmtstk (&lgl->eassume));
4918 for (eidx = 1; eidx <= lgl->maxext; eidx++) {
4919 Ext * ext = lglelit2ext (lgl, eidx);
4920 assert (!ext->assumed);
4921 assert (!ext->failed);
4926 static void lglchkassumeclean (LGL * lgl) {
4927 assert (!lgl->failed);
4928 assert (!lgl->assumed);
4929 assert (!lgl->cassumed);
4930 assert (!lgl->ncassumed);
4931 assert (lglmtstk (&lgl->assume));
4933 if (lgl->opts->check.val >= 1) {
4935 for (idx = 2; idx < lgl->nvars; idx++) {
4936 AVar * av = lglavar (lgl, idx);
4937 assert (!av->assumed);
4938 assert (!av->failed);
4944 static void lglreset (LGL * lgl) {
4945 int elit, ilit, erepr;
4949 if (lgl->state == RESET) return;
4950 if (lgl->state <= USED) return;
4951 assert (lgl->state & (UNKNOWN|SATISFIED|EXTENDED|UNSATISFIED|FAILED|LOOKED));
4952 if (lgl->level > 0) lglbacktrack (lgl, 0);
4953 if (!lglmtstk (&lgl->eassume)) {
4954 LOG (2, "resetting %d external assumptions", lglcntstk (&lgl->eassume));
4955 while (!lglmtstk (&lgl->eassume)) {
4956 elit = lglpopstk (&lgl->eassume);
4957 ext = lglelit2ext (lgl, elit);
4961 erepr = lglerepr (lgl, elit);
4962 if (erepr != elit) {
4963 rext = lglelit2ext (lgl, erepr);
4969 lglchkeassumeclean (lgl);
4970 if (!lglmtstk (&lgl->assume)) {
4971 LOG (2, "resetting %d internal assumptions", lglcntstk (&lgl->assume));
4972 while (!lglmtstk (&lgl->assume)) {
4973 ilit = lglpopstk (&lgl->assume);
4974 av = lglavar (lgl, ilit);
4975 bit = (1u << (ilit < 0));
4976 assert (av->assumed & bit);
4977 av->assumed &= ~bit;
4981 if (!lglmtstk (&lgl->cassume)) {
4982 assert (lgl->ncassumed);
4983 LOG (2, "resetting assumed clause of size %d", lglcntstk (&lgl->cassume));
4984 lglclnstk (&lgl->cassume);
4985 lgl->cassumed = lgl->ncassumed = 0;
4986 } else assert (!lgl->ncassumed), assert (!lgl->cassumed);
4988 LOG (2, "resetting internal failed assumption %d", lgl->failed);
4992 LOG (2, "resetting assumption queue level to 0 from %d", lgl->assumed);
4995 lglchkassumeclean (lgl);
4996 #if !defined(NDEBUG) && !defined (NLGLPICOSAT)
4997 if (lgl->picosat.res) {
4998 LOG (2, "resetting earlier PicoSAT result %d", lgl->picosat.res);
4999 lgl->picosat.res = 0;
5002 lgleunassignall (lgl);
5003 if (lgl->cbs && lgl->cbs->term.done) {
5004 LOG (2, "resetting forced termination done flag");
5005 lgl->cbs->term.done = 0;
5010 static void lgluse (LGL * lgl) {
5011 if (lgl->state >= USED) return;
5012 assert (lgl->state == UNUSED || lgl->state == OPTSET);
5016 static void lgleadd (LGL * lgl, int elit) {
5020 ilit = lglimport (lgl, elit);
5021 LOG (4, "adding external literal %d as %d", elit, ilit);
5024 LOG (4, "closing external clause");
5026 lgliadd (lgl, ilit);
5028 lglpushstk (lgl, &lgl->orig, elit);
5032 void lgladd (LGL * lgl, int elit) {
5033 int eidx = abs (elit);
5035 REQINITNOTFORKED ();
5036 TRAPI ("add %d", elit);
5037 if (0 < eidx && eidx <= lgl->maxext) {
5038 ext = lglelit2ext (lgl, elit);
5039 ABORTIF (ext->melted, "adding melted literal %d", elit);
5041 lgl->stats->calls.add++;
5042 lgleadd (lgl, elit);
5044 if (lgl->clone) lgladd (lgl->clone, elit);
5047 static void lglisetphase (LGL * lgl, int lit, int phase) {
5049 if (lit < 0) lit = -lit, phase = -phase;
5050 av = lglavar (lgl, lit);
5052 LOG (2, "setting phase of internal literal %d to %d", lit, phase);
5055 static void lglesetphase (LGL * lgl, int elit, int phase) {
5056 int ilit = lglimport (lgl, elit);
5057 if (abs (ilit) >= 2) {
5058 LOG (2, "setting phase of external literal %d to %d", elit, phase);
5059 lglisetphase (lgl, ilit, phase);
5060 } else LOG (2, "setting phase of external literal %d skipped", elit);
5063 void lglsetphase (LGL * lgl, int elit) {
5064 REQINITNOTFORKED ();
5065 TRAPI ("setphase %d", elit);
5066 ABORTIF (!elit, "invalid literal argument");
5067 if (elit < 0) lglesetphase (lgl, -elit, -1);
5068 else lglesetphase (lgl, elit, 1);
5069 if (lgl->clone) lglsetphase (lgl->clone, elit);
5072 void lglresetphase (LGL * lgl, int elit) {
5073 REQINITNOTFORKED ();
5074 TRAPI ("resetphase %d", elit);
5075 ABORTIF (!elit, "invalid literal argument");
5076 lglesetphase (lgl, elit, 0);
5077 if (lgl->clone) lglresetphase (lgl->clone, elit);
5080 static void lgleassume (LGL * lgl, int elit) {
5086 ilit = lglimport (lgl, elit);
5087 LOG (2, "assuming external literal %d", elit);
5088 bit = 1u << (elit < 0);
5089 ext = lglelit2ext (lgl, elit);
5090 if (!(ext->assumed & bit)) {
5091 ext->assumed |= bit;
5092 lglpushstk (lgl, &lgl->eassume, elit);
5094 assert (!lgl->level);
5095 if (!(val = lglcval (lgl, ilit))) {
5096 av = lglavar (lgl, ilit);
5097 bit = (1u << (ilit < 0));
5098 if (av->assumed & bit) {
5099 LOG (2, "internal literal %d already assumed", ilit);
5102 if (av->assumed & (bit^3))
5103 LOG (2, "negation %d was also already assumed", -ilit);
5104 lglpushstk (lgl, &lgl->assume, ilit);
5106 } else if (val > 0) {
5107 LOG (2, "externally assumed literal %d already fixed to true", elit);
5110 LOG (2, "externally assumed literal %d already fixed to false", elit);
5112 av = lglavar (lgl, ilit);
5113 bit = (1u << (ilit < 0));
5114 if (!(av->assumed & bit)) {
5116 lglpushstk (lgl, &lgl->assume, ilit);
5119 if (!lgl->failed) lgl->failed = ilit;
5123 static void lglecassume (LGL * lgl, int elit) {
5124 LOG (2, "adding external literal %d to assumed clause", elit);
5127 void lglassume (LGL * lgl, int elit) {
5128 int eidx = abs (elit);
5130 REQINITNOTFORKED ();
5131 TRAPI ("assume %d", elit);
5132 lgl->stats->calls.assume++;
5133 ABORTIF (!elit, "can not assume invalid literal 0");
5134 if (0 < eidx && eidx <= lgl->maxext) {
5135 ext = lglelit2ext (lgl, elit);
5136 ABORTIF (ext->melted, "assuming melted literal %d", elit);
5138 lgleassume (lgl, elit);
5141 if (lgl->clone) lglassume (lgl->clone, elit);
5144 void lglcassume (LGL * lgl, int elit) {
5145 int eidx = abs (elit);
5147 REQINITNOTFORKED ();
5148 TRAPI ("cassume %d", elit);
5149 lgl->stats->calls.cassume++;
5150 if (0 < eidx && eidx <= lgl->maxext) {
5151 ext = lglelit2ext (lgl, elit);
5152 ABORTIF (ext->melted, "assuming melted literal %d", elit);
5154 lglecassume (lgl, elit);
5156 if (lgl->clone) lglcassume (lgl->clone, elit);
5159 void lglfixate (LGL * lgl) {
5162 REQINITNOTFORKED ();
5164 if (lgl->mt) return;
5166 for (p = lgl->eassume.start; p < lgl->eassume.top; p++)
5167 lglpushstk (lgl, &eassume, *p);
5168 for (p = eassume.start; p < eassume.top; p++)
5169 lgleadd (lgl, *p), lgleadd (lgl, 0);
5170 lglrelstk (lgl, &eassume);
5172 if (lgl->clone) lglfixate (lgl->clone);
5175 static void lglbonflict (LGL * lgl, int lit, int blit) {
5176 assert (lglevel (lgl, lit) >= lglevel (lgl, blit >> RMSHFT));
5177 assert (!lgliselim (lgl, blit >> RMSHFT));
5178 assert (!lgliselim (lgl, lit));
5179 lgl->conf.lit = lit;
5180 lgl->conf.rsn[0] = blit;
5181 LOG (2, "inconsistent %s binary clause %d %d",
5182 lglred2str (blit & REDCS), lit, (blit >> RMSHFT));
5185 static void lgltonflict (LGL * lgl, int lit, int blit, int other2) {
5186 assert ((blit & MASKCS) == TRNCS);
5187 assert (lglevel (lgl, lit) >= lglevel (lgl, blit >> RMSHFT));
5188 assert (lglevel (lgl, lit) >= lglevel (lgl, other2));
5189 assert (!lgliselim (lgl, blit >> RMSHFT));
5190 assert (!lgliselim (lgl, other2));
5191 assert (!lgliselim (lgl, lit));
5192 lgl->conf.lit = lit;
5193 lgl->conf.rsn[0] = blit;
5194 lgl->conf.rsn[1] = other2;
5195 LOG (2, "inconsistent %s ternary clause %d %d %d",
5196 lglred2str (blit & REDCS), lit, (blit>>RMSHFT), other2);
5199 static void lglonflict (LGL * lgl, int check, int lit, int red, int lidx) {
5201 #if !defined (NLGLOG) || !defined (NDEBUG)
5202 int * p, * c = lglidx2lits (lgl, red, lidx);
5204 assert (red == REDCS || !red);
5208 for (p = c; *p; p++) {
5209 if(*p == lit) found++;
5210 assert (lglval (lgl, *p) <= -check);
5211 assert (lglevel (lgl, lit) >= lglevel (lgl, *p));
5212 assert (!lgliselim (lgl, lit));
5214 assert (found == 1);
5217 lgl->conf.lit = lit;
5218 lgl->conf.rsn[0] = red | LRGCS;
5219 lgl->conf.rsn[1] = lidx;
5221 if (lgl->opts->log.val >= 2) {
5222 lglogstart (lgl, 2, "inconsistent %s large clause", lglred2str (red));
5223 for (p = c ; *p; p++)
5224 fprintf (lgl->out, " %d", *p);
5229 glue = lidx & GLUEMASK;
5230 lgl->stats->lir[glue].conflicts++;
5231 assert (lgl->stats->lir[glue].conflicts > 0);
5235 static void lgldeclscnt (LGL * lgl, int size, int red, int glue) {
5236 assert (!red || red == REDCS);
5237 if (!red) lgldecirr (lgl, size);
5238 else if (size == 2) assert (lgl->stats->red.bin), lgl->stats->red.bin--;
5239 else if (size == 3) assert (lgl->stats->red.trn), lgl->stats->red.trn--;
5241 assert (lgl->stats->red.lrg > 0);
5242 lgl->stats->red.lrg--;
5243 assert (lgl->stats->lir[glue].clauses > 0);
5244 lgl->stats->lir[glue].clauses--;
5248 static void lglrminc (LGL * lgl, const int * w, const int * eow) {
5251 assert (sizeof w < 8 || eow <= w + INT_MAX);
5254 inc >>= lgl->opts->rmincpen.val;
5256 assert (lgl->blocking + lgl->eliminating + lgl->simpleprobing <= 1);
5257 if (lgl->blocking) ADDSTEPS (blk.steps, inc);
5258 else if (lgl->eliminating) ADDSTEPS (elm.steps, inc);
5259 else if (lgl->simpleprobing) ADDSTEPS (prb.simple.steps, inc);
5262 static void lglrmtwch (LGL * lgl, int lit, int other1, int other2, int red) {
5263 int * p, blit, other, blit1, blit2, * w, * eow, tag;
5265 assert (!red || red == REDCS);
5266 LOG (3, "removing %s ternary watch %d blits %d %d",
5267 lglred2str (red), lit, other1, other2);
5268 hts = lglhts (lgl, lit);
5269 assert (hts->count >= 2);
5270 p = w = lglhts2wchs (lgl, hts);
5271 eow = w + hts->count;
5272 lglrminc (lgl, w, eow);
5273 blit1 = (other1 << RMSHFT) | red | TRNCS;
5274 blit2 = (other2 << RMSHFT) | red | TRNCS;
5278 tag = blit & MASKCS;
5279 if (tag == BINCS || tag == OCCS) continue;
5281 if (tag == LRGCS) continue;
5282 assert (tag == TRNCS);
5283 if (blit == blit1 && other == other2) break;
5284 if (blit == blit2 && other == other1) break;
5286 while (p < eow) p[-2] = p[0], p++;
5287 lglshrinkhts (lgl, hts, p - w - 2);
5290 static void lglpopnunmarkstk (LGL * lgl, Stk * stk) {
5291 while (!lglmtstk (stk))
5292 lglavar (lgl, lglpopstk (stk))->mark = 0;
5295 static void lglpopnunlcamarkstk (LGL * lgl, Stk * stk) {
5296 while (!lglmtstk (stk))
5297 lglavar (lgl, lglpopstk (stk))->lcamark = 0;
5300 static int lglcamarked (LGL * lgl, int lit) {
5301 switch (lglavar (lgl, lit)->lcamark) {
5302 case 1: return (lit < 0) ? -1 : 1;
5303 case 2: return (lit < 0) ? -2 : 2;
5304 case 4: return (lit < 0) ? 1 : -1;
5305 case 8: return (lit < 0) ? 2 : -2;
5306 default: assert (!lglavar (lgl, lit)->lcamark); return 0;
5310 static void lglcamark (LGL * lgl, int lit, int mark) {
5313 assert (mark == 1 || mark == 2);
5314 av = lglavar (lgl, lit);
5315 assert (!av->lcamark);
5317 if (lit < 0) newmark <<= 2;
5318 av->lcamark = newmark;
5319 lglpushstk (lgl, &lgl->lcaseen, lit);
5320 assert (lglcamarked (lgl, lit) == mark);
5321 assert (lglcamarked (lgl, -lit) == -mark);
5324 static int lglca (LGL * lgl, int a, int b) {
5325 int blit, tag, mark, negmark, prevmark, c, res, prev, next, al, bl;
5326 const int * p, * w, * eow;
5330 if (a == b) return a;
5331 if (a == -b) return 0;
5332 al = lglevel (lgl, a);
5333 bl = lglevel (lgl, b);
5336 assert (lglval (lgl, a) > 0);
5337 assert (lglval (lgl, b) > 0);
5338 assert (lglmtstk (&lgl->lcaseen));
5339 lglcamark (lgl, a, 1);
5340 lglcamark (lgl, b, 2);
5342 while (next < lglcntstk (&lgl->lcaseen)) {
5343 c = lglpeek (&lgl->lcaseen, next++);
5344 assert (lglval (lgl, c) > 0);
5345 assert (lglevel (lgl, c) > 0);
5346 mark = lglcamarked (lgl, c);
5347 assert (mark == 1 || mark == 2);
5349 hts = lglhts (lgl, c);
5350 if (!hts->count) continue;
5351 w = lglhts2wchs (lgl, hts);
5352 eow = w + hts->count;
5353 for (p = w; p < eow; p++) {
5355 tag = blit & MASKCS;
5356 if (tag == TRNCS || tag == LRGCS) p++;
5357 if (tag != BINCS) continue;
5358 prev = -(blit >> RMSHFT);
5359 if (!lglevel (lgl, prev)) continue;
5360 if (lglval (lgl, prev) <= 0) continue;
5361 if ((prevmark = lglcamarked (lgl, prev)) < 0) continue;
5362 if (mark == prevmark) continue;
5363 if (prevmark == negmark) { res = prev; goto DONE; }
5364 lglcamark (lgl, prev, mark);
5368 lglpopnunlcamarkstk (lgl, &lgl->lcaseen);
5369 LOG (3, "least common ancestor of %d and %d is %d", a, b, res);
5373 static void lglrmlwch (LGL * lgl, int lit, int red, int lidx) {
5374 int blit, tag, * p, * q, * w, * eow, ored, olidx;
5377 p = lglidx2lits (lgl, red, lidx);
5379 LOG (3, "removing watch %d in red[%d][%d] %d %d %d %d%s",
5380 lit, (lidx & GLUEMASK), (lidx >> GLUESHFT), p[0], p[1], p[2], p[3],
5381 (p[4] ? " ..." : ""));
5383 LOG (3, "removing watch %d in irr[%d] %d %d %d %d%s",
5384 lit, lidx, p[0], p[1], p[2], p[3], (p[4] ? " ..." : ""));
5386 hts = lglhts (lgl, lit);
5387 assert (hts->count >= 2);
5388 p = w = lglhts2wchs (lgl, hts);
5389 eow = w + hts->count;
5390 lglrminc (lgl, w, eow);
5394 tag = blit & MASKCS;
5395 if (tag == BINCS) continue;
5396 if (tag == OCCS) { assert (lgl->dense); continue; }
5398 if (tag == TRNCS) continue;
5399 assert (tag == LRGCS);
5400 ored = blit & REDCS;
5401 if (ored != red) continue;
5402 if (olidx == lidx) break;
5404 assert ((p[-2] & REDCS) == red);
5405 assert (p[-1] == lidx);
5406 for (q = p; q < eow; q++)
5408 lglshrinkhts (lgl, hts, q - w - 2);
5411 static void lglpropsearch (LGL * lgl, int lit) {
5412 int * q, * eos, blit, other, other2, other3, red, prev;
5413 int tag, val, val2, lidx, * c, * l;
5420 LOG (3, "propagating %d in search", lit);
5422 assert (!lgl->simp);
5423 assert (!lgl->lkhd);
5424 assert (!lgl->probing);
5425 assert (!lgl->lifting);
5426 assert (!lgl->cliffing);
5427 assert (!lgl->dense);
5428 assert (!lgliselim (lgl, lit));
5429 assert (lglval (lgl, lit) == 1);
5431 hts = lglhts (lgl, -lit);
5432 if (!hts->offset) return;
5433 q = lglhts2wchs (lgl, hts);
5434 assert (hts->count >= 0);
5435 eos = q + hts->count;
5438 for (p = q; p < eos; p++) {
5441 tag = blit & MASKCS;
5443 assert (tag == TRNCS || tag == LRGCS);
5446 other = (blit >> RMSHFT);
5448 val = lglval (lgl, other);
5449 if (val > 0) continue;
5452 if (val < 0) { lglbonflict (lgl, -lit, blit); p++; break; }
5453 lglf2rce (lgl, other, -lit, red);
5454 } else if (tag == TRNCS) {
5457 val2 = lglval (lgl, other2);
5458 if (val2 > 0) continue;
5459 if (!val && !val2) continue;
5460 if (val < 0 && val2 < 0) {
5461 lgltonflict (lgl, -lit, blit, other2);
5465 if (!val) SWAP (int, other, other2);
5466 else assert (val < 0);
5467 lglf3rce (lgl, other2, -lit, other, red);
5469 assert (tag == LRGCS);
5473 c = lglidx2lits (lgl, red, lidx);
5475 if (other2 == -lit) other2 = c[0] = c[1], c[1] = -lit;
5476 else assert (c[1] == -lit);
5477 if (other2 != other) {
5480 val = lglval (lgl, other);
5482 q[-2] = LRGCS | (other2 << RMSHFT) | red;
5486 assert (!red || !lgliselim (lgl, other));
5489 for (l = c + 2; (other2 = *l); l++) {
5492 val2 = lglval (lgl, other2);
5493 if (val2 >= 0) break;
5494 assert (!red || !lgliselim (lgl, other));
5497 assert (val2 != INT_MAX);
5498 if (other2 && val2 >= 0) {
5500 assert (other == c[0]);
5501 delta = lglwchlrg (lgl, other2, other, red, lidx);
5502 if (delta) p += delta, q += delta, eos += delta;
5511 assert (!other2 || val2 >= 0);
5513 lglonflict (lgl, 1, -lit, red, lidx);
5518 lglflrce (lgl, other, red, lidx);
5521 while (p < eos) *q++ = *p++;
5522 lglshrinkhts (lgl, hts, hts->count - (p - q));
5523 assert (!lgl->simp);
5525 lgl->stats->visits.search += visits;
5526 lgl->stats->travs.search += travs;
5529 static int lglhbred (LGL * lgl, int subsumed, int red) {
5530 int res = subsumed ? red : REDCS;
5531 LOG (3, "hyber binary learned clause becomes %s", lglred2str (res));
5535 static void lgldecocc (LGL *, int); //TODO move scheduling ...
5537 static void lglrmlocc (LGL * lgl, int lit, int red, int lidx) {
5538 int search, blit, tag, * p, * q, * w, * eow;
5540 if (lgl->dense < 2) return;
5542 if (red) LOG (3, "removing occurrence %d in red[0][%d]", lit, lidx);
5543 else LOG (3, "removing occurrence %d in irr[%d]", lit, lidx);
5545 assert (!red || red == REDCS);
5546 hts = lglhts (lgl, lit);
5547 assert (hts->count >= 1);
5548 assert (lidx <= MAXIRRLIDX);
5549 search = (lidx << RMSHFT) | OCCS | red;
5550 assert (search >= 0);
5551 p = w = lglhts2wchs (lgl, hts);
5552 eow = w + hts->count;
5553 lglrminc (lgl, w, eow);
5557 tag = blit & MASKCS;
5558 if (tag == TRNCS || tag == LRGCS) p++;
5559 } while (blit != search);
5560 assert (p[-1] == search);
5561 for (q = p ; q < eow; q++)
5563 lglshrinkhts (lgl, hts, q - w - 1);
5566 static void lglflushremovedoccs (LGL * lgl, int lit) {
5567 HTS * hts = lglhts (lgl, lit);
5568 int * w = lglhts2wchs (lgl, hts);
5569 int * eow = w + hts->count;
5570 int blit, tag, red, lidx;
5572 lglrminc (lgl, w, eow);
5573 for (p = q = w; p < eow; p++) {
5575 tag = blit & MASKCS;
5577 if (tag == TRNCS || tag == LRGCS) p++;
5578 if (tag == BINCS) *q++ = blit;
5579 else if (tag == TRNCS) *q++ = blit, *q++ = *p;
5581 assert (tag == LRGCS || tag == OCCS);
5583 lidx = (tag == LRGCS) ? *p : (blit >> RMSHFT);
5584 c = lglidx2lits (lgl, red, lidx);
5585 if (c[0] == REMOVED) continue;
5588 if (tag == LRGCS) *q++ = *p;
5591 lglshrinkhts (lgl, hts, q - w);
5594 static void lglpropupdvisits (LGL * lgl, int visits, int64_t travs) {
5595 if (lgl->lkhd) lgl->stats->visits.lkhd += visits;
5596 else if (lgl->simp) lgl->stats->visits.simp += visits;
5597 else lgl->stats->visits.search += visits;
5599 if (lgl->lkhd) lgl->stats->travs.lkhd += travs;
5600 else if (lgl->simp) lgl->stats->travs.simp += travs;
5601 else lgl->stats->travs.search += travs;
5603 if (lgl->basicprobing) ADDSTEPS (prb.basic.steps, visits);
5604 if (lgl->simpleprobing) ADDSTEPS (prb.simple.steps, visits);
5605 if (lgl->treelooking) ADDSTEPS (prb.treelook.steps, visits);
5606 if (lgl->cceing) ADDSTEPS (cce.steps, visits);
5607 if (lgl->cliffing) ADDSTEPS (cliff.steps, visits);
5610 static void lglprop (LGL * lgl, int lit) {
5611 int * p, * q, * eos, blit, other, other2, other3, red, prev;
5612 int tag, val, val2, lidx, * c, * l, dom, hbred, subsumed;
5613 int glue, flushoccs, visits;
5617 LOG (3, "propagating %d over ternary and large clauses", lit);
5618 assert (!lgliselim (lgl, lit));
5619 assert (lglval (lgl, lit) == 1);
5620 hts = lglhts (lgl, -lit);
5621 if (!hts->offset) return;
5623 q = lglhts2wchs (lgl, hts);
5624 assert (hts->count >= 0);
5625 eos = q + hts->count;
5628 for (p = q; p < eos; p++) {
5630 tag = blit & MASKCS;
5633 assert (lgl->dense);
5639 other = (blit >> RMSHFT);
5641 val = lglval (lgl, other);
5644 if (val > 0) continue;
5645 if (red && lgliselim (lgl, other)) continue;
5647 lglbonflict (lgl, -lit, blit);
5652 lglf2rce (lgl, other, -lit, red);
5653 } else if (tag == TRNCS) {
5657 if (val > 0) continue;
5659 if (red && lgliselim (lgl, other)) continue;
5660 val2 = lglval (lgl, other2);
5661 if (val2 > 0) continue;
5662 if (!val && !val2) continue;
5663 if (red && lgliselim (lgl, other2)) continue;
5664 if (val < 0 && val2 < 0) {
5665 lgltonflict (lgl, -lit, blit, other2);
5669 if (!val) SWAP (int, other, other2); else assert (val < 0);
5672 lgl->opts->lhbr.val &&
5675 dom = lglgetdom (lgl, lit);
5676 if (lglgetdom (lgl, -other) != dom) goto NO_HBR_JUST_F3RCE;
5677 dom = lglca (lgl, lit, -other);
5678 if (!dom) goto NO_HBR_JUST_F3RCE;
5679 subsumed = (dom == lit || dom == -other);
5680 hbred = lglhbred (lgl, subsumed, red);
5681 LOG (2, "hyper binary resolved %s clause %d %d",
5682 lglred2str (hbred), -dom, other2);
5683 if (lgl->opts->drup.val) lgldrupclsarg (lgl, -dom, other2, 0);
5685 lglpicosatchkclsarg (lgl, -dom, other2, 0);
5688 LOG (2, "subsumes %s ternary clause %d %d %d",
5689 lglred2str (red), -lit, other, other2);
5690 lglrmtwch (lgl, other2, other, -lit, red);
5691 lglrmtwch (lgl, other, other2, -lit, red);
5692 lgl->stats->hbr.sub++;
5693 if (red) assert (lgl->stats->red.trn), lgl->stats->red.trn--;
5697 if (-dom == -lit) lgldecocc (lgl, other);
5698 else { assert (-dom == other); lgldecocc (lgl, -lit); }
5705 "replacing %s ternary watch %d blits %d %d with binary %d blit %d",
5706 lglred2str (red), -lit, other, other2, -dom, other2);
5708 blit = (other2 << RMSHFT) | BINCS | hbred;
5712 if (dom == -other) {
5713 LOG (3, "removing %s ternary watch %d blits %d %d",
5714 lglred2str (red), -lit, other, other2);
5718 LOG (2, "replaces %s ternary clause %d %d %d as reason for %d",
5719 lglred2str (red), -lit, other, other2, other2);
5721 assert (abs (dom) != abs (lit));
5722 assert (abs (other2) != abs (lit));
5724 delta += lglwchbin (lgl, -dom, other2, hbred);
5726 delta += lglwchbin (lgl, other2, -dom, hbred);
5727 if (delta) p += delta, q += delta, eos += delta;
5728 if (hbred) lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
5729 else lglincirr (lgl, 2);
5730 lglf2rce (lgl, other2, -dom, hbred);
5731 lgl->stats->hbr.trn++;
5732 lgl->stats->hbr.cnt++;
5733 lgl->stats->prgss++;
5736 lglf3rce (lgl, other2, -lit, other, red);
5739 assert (tag == LRGCS);
5740 if (val > 0) goto COPYL;
5742 c = lglidx2lits (lgl, red, lidx);
5744 if (other2 >= NOTALIT) {
5748 if (other2 == -lit) other2 = c[0] = c[1], c[1] = -lit;
5749 if (other2 != other) {
5752 val = lglval (lgl, other);
5755 blit |= other2 << RMSHFT;
5756 if (val > 0) goto COPYL;
5758 if (red && lgliselim (lgl, other)) goto COPYL;
5761 for (l = c + 2; (other2 = *l); l++) {
5764 val2 = lglval (lgl, other2);
5765 if (val2 >= 0) break;
5766 if (red && lgliselim (lgl, other2)) break;
5769 assert (val2 != INT_MAX);
5770 if (other2 && val2 >= 0) {
5772 assert (other == c[0]);
5773 delta = lglwchlrg (lgl, other2, other, red, lidx);
5774 if (delta) p += delta, q += delta, eos += delta;
5785 if (other2 && val2 < 0) goto COPYL;
5788 lglonflict (lgl, 1, -lit, red, lidx);
5795 lgl->opts->lhbr.val &&
5799 for (l = c; (other2 = *l); l++) {
5800 if (other2 == other) continue;
5802 if (!lglevel (lgl, other2)) continue;
5803 assert (lglval (lgl, other2) < 0);
5804 if (!dom) dom = lglgetdom (lgl, -other);
5805 if (dom != lglgetdom (lgl, -other2)) goto NO_HBR_JUST_FLRCE;
5807 LOGCLS (2, c, "dominator %d for %s clause", dom, lglred2str (red));
5809 for (l = c; (other2 = *l); l++) {
5810 if (other2 == other) continue;
5811 if (!lglevel (lgl, other2)) continue;
5812 dom = lglca (lgl, dom, -other2);
5814 if (!dom) goto NO_HBR_JUST_FLRCE;
5815 LOGCLS (2, c, "closest dominator %d", dom);
5817 for (l = c; !subsumed && (other2 = *l); l++)
5818 subsumed = (dom == -other2);
5819 assert (lit != dom || subsumed);
5820 hbred = lglhbred (lgl, subsumed, red);
5821 LOG (2, "hyper binary resolved %s clause %d %d",
5822 lglred2str (hbred), -dom, other);
5823 if (lgl->opts->drup.val) lgldrupclsarg (lgl, -dom, other, 0);
5825 lglpicosatchkclsarg (lgl, -dom, other, 0);
5828 LOGCLS (2, c, "subsumes %s large clause", lglred2str (red));
5829 lglrmlwch (lgl, other, red, lidx);
5830 lgl->stats->hbr.sub++;
5832 glue = lidx & GLUEMASK;
5833 if (glue != MAXGLUE) {
5834 assert (lgl->stats->red.lrg);
5835 lgl->stats->red.lrg--;
5836 assert (lgl->stats->lir[glue].clauses > 0);
5837 lgl->stats->lir[glue].clauses--;
5840 if (!red && lgl->dense) {
5841 for (l = c; (other2 = *l); l++) {
5842 if (other2 != -lit) lglrmlocc (lgl, other2, 0, lidx);
5843 if (other2 == -dom) continue;
5844 if (other2 == other) continue;
5845 lgldecocc (lgl, other2);
5849 if (red && glue < MAXGLUE) { LGLCHKACT (c[-1]); c[-1] = REMOVED; }
5850 for (l = c; *l; l++) *l = REMOVED;
5851 if (!red) lgldecirr (lgl, l - c);
5858 "replacing %s large watch %d with binary watch %d blit %d",
5859 lglred2str (red), -lit, -lit, -dom);
5860 blit = (other << RMSHFT) | BINCS | hbred;
5864 LOG (3, "removing %s large watch %d", lglred2str (red), -lit);
5868 "%s binary clause %d %d becomes reasons "
5869 "for %d instead of %s large clause",
5870 lglred2str (hbred), -dom, other, other, lglred2str (red));
5871 assert (hbred == REDCS);
5873 delta += lglwchbin (lgl, -dom, other, hbred);
5875 delta += lglwchbin (lgl, other, -dom, hbred);
5876 if (delta) p += delta, q += delta, eos += delta;
5877 if (hbred) lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
5878 else lglincirr (lgl, 2);
5879 lglf2rce (lgl, other, -dom, hbred);
5880 lgl->stats->hbr.lrg++;
5881 lgl->stats->hbr.cnt++;
5882 lgl->stats->prgss++;
5883 if (subsumed) continue;
5886 lglflrce (lgl, other, red, lidx);
5893 while (p < eos) *q++ = *p++;
5894 lglshrinkhts (lgl, hts, hts->count - (p - q));
5895 if (flushoccs) lglflushremovedoccs (lgl, -lit);
5896 lglpropupdvisits (lgl, visits, travs);
5899 static void lglprop2 (LGL * lgl, int lit) {
5900 int other, blit, tag, val, red, visits;
5901 const int * p, * w, * eow;
5904 LOG (3, "propagating %d over binary clauses", lit);
5905 assert (!lgliselim (lgl, lit));
5906 assert (lglval (lgl, lit) == 1);
5909 hts = lglhts (lgl, -lit);
5910 w = lglhts2wchs (lgl, hts);
5911 eow = w + hts->count;
5912 for (p = w; p < eow; p++) {
5914 tag = blit & MASKCS;
5915 if (tag == TRNCS || tag == LRGCS) p++;
5916 if (tag != BINCS) continue;
5919 other = blit >> RMSHFT;
5921 if (lgliselim (lgl, other)) { assert (red); continue; }
5922 val = lglval (lgl, other);
5923 if (val > 0) continue;
5924 if (val < 0) { lglbonflict (lgl, -lit, blit); break; }
5925 lglf2rce (lgl, other, -lit, red);
5928 lglpropupdvisits (lgl, visits, travs);
5931 static int lglbcp (LGL * lgl) {
5932 int lit, trail, count;
5934 assert (!lgl->conf.lit);
5935 assert (!lgl->notfullyconnected);
5937 while (!lgl->conf.lit) {
5938 trail = lglcntstk (&lgl->trail);
5939 if (lgl->next2 < trail) {
5940 lit = lglpeek (&lgl->trail, lgl->next2++);
5941 lglprop2 (lgl, lit);
5944 if (lgl->next >= trail) break;
5946 lit = lglpeek (&lgl->trail, lgl->next++);
5949 if (lgl->lkhd) ADDSTEPS (props.lkhd, count);
5950 else if (lgl->simp) ADDSTEPS (props.simp, count);
5951 else ADDSTEPS (props.search, count);
5952 return !lgl->conf.lit;
5955 static int lglbcpsearch (LGL * lgl) {
5957 assert (!lgl->simp);
5958 assert (!lgl->notfullyconnected);
5959 while ((!lgl->failed || !lgl->level) &&
5961 lgl->next < lglcntstk (&lgl->trail)) {
5962 lit = lglpeek (&lgl->trail, lgl->next++);
5963 lglpropsearch (lgl, lit);
5966 ADDSTEPS (props.search, count);
5967 lgl->next2 = lgl->next;
5968 if (lgl->conf.lit && lgl->failed) {
5969 LOG (2, "inconsistency overwrites failed assumption %d", lgl->failed);
5972 return !lgl->conf.lit && !lgl->failed;
5976 static void lglchkclnvar (LGL * lgl) {
5979 for (i = 2; i < lgl->nvars; i++) {
5980 av = lglavar (lgl, i);
5987 static int lglmaintainresolvent (LGL * lgl) {
5989 if (lgl->opts->check.val >= 1) return 1;
5992 if (lgl->opts->log.val >= 2) return 1;
5998 static int lgldecision (LGL * lgl, int lit) {
5999 int * rsn = lglrsn (lgl, lit);
6000 int tag = rsn[0] & MASKCS;
6001 return tag == DECISION;
6004 static int lglassumption (LGL * lgl, int lit) {
6005 return lglavar (lgl, lit)->assumed;
6008 static int lglpull (LGL * lgl, int lit) {
6009 AVar * av = lglavar (lgl, lit);
6011 level = lglevel (lgl, lit);
6012 if (!level) return 0;
6013 if (av->mark) return 0;
6015 lglpushstk (lgl, &lgl->seen, lit);
6017 if (lglmaintainresolvent (lgl)) {
6018 lglpushstk (lgl, &lgl->resolvent, lit);
6019 LOG (2, "adding %d to resolvent", lit);
6020 LOGRESOLVENT (3, "resolvent after adding %d is", lit);
6023 if (level == lgl->level) {
6024 LOG (2, "reason literal %d at same level %d", lit, lgl->level);
6027 lglpushstk (lgl, &lgl->clause, lit);
6028 LOG (2, "adding literal %d at upper level %d to 1st UIP clause",
6029 lit, lglevel (lgl, lit));
6030 if (!lglevelused (lgl, level)) {
6031 lgluselevel (lgl, level);
6032 lglpushstk (lgl, &lgl->frames, level);
6033 LOG (2, "pulled in decision level %d", level);
6040 static int lglpoison (LGL * lgl, int lit, Stk * stk, int local) {
6041 AVar * av = lglavar (lgl, lit);
6043 if (av->mark) res = 0;
6045 level = lglevel (lgl, lit);
6046 if (!level) res = 0;
6048 assert (level < lgl->level);
6049 if (lgldecision (lgl, lit)) res = 1;
6050 else if (!lglevelused (lgl, level)) res = 1;
6052 lgl->stats->poison.search++;
6054 lgl->stats->poison.hits++;
6056 } else if (local) res = 1;
6059 lglpushstk (lgl, &lgl->seen, lit);
6060 lglpushstk (lgl, stk, lit);
6066 if (res && !av->poisoned) {
6068 lglpushstk (lgl, &lgl->poisoned, lit);
6073 static int lglminclslit (LGL * lgl, int start, int local) {
6074 int lit, tag, r0, r1, other, * p, * q, *top, old;
6075 int poisoned, * rsn, found;
6077 assert (lglmarked (lgl, start));
6079 rsn = lglrsn (lgl, lit);
6081 tag = (r0 & MASKCS);
6082 if (tag == DECISION) return 0;
6083 old = lglcntstk (&lgl->seen);
6084 assert (lglmtstk (&lgl->minstk));
6087 if (tag == BINCS || tag == TRNCS) {
6088 other = r0 >> RMSHFT;
6089 if (lglpoison (lgl, other, &lgl->minstk, local)) goto FAILED;
6091 lglpoison (lgl, r1, &lgl->minstk, local)) goto FAILED;
6093 assert (tag == LRGCS);
6094 p = lglidx2lits (lgl, (r0 & REDCS), r1);
6096 while ((other = *p++)) {
6097 if (other == -lit) found++;
6098 else if (lglpoison (lgl, other, &lgl->minstk, local)) goto FAILED;
6100 assert (found == 1);
6102 if (lglmtstk (&lgl->minstk)) { lglrelstk (lgl, &lgl->minstk); return 1; }
6103 lit = lglpopstk (&lgl->minstk);
6104 assert (lglavar (lgl, lit)->mark);
6105 rsn = lglrsn (lgl, lit);
6107 tag = (r0 & MASKCS);
6110 lglclnstk (&lgl->minstk);
6112 top = lgl->seen.top = lgl->seen.start + old;
6115 av = lglavar (lgl, lit);
6118 poisoned = av->poisoned;
6119 if (poisoned) continue;
6120 rsn = lglrsn (lgl, lit);
6122 tag = (r0 & MASKCS);
6123 assert (tag != DECISION);
6125 if (tag == BINCS || tag == TRNCS) {
6126 other = r0 >> RMSHFT;
6127 bv = lglavar (lgl, other);
6128 if (bv->poisoned) poisoned = 1;
6129 else if (tag == TRNCS) {
6130 bv = lglavar (lgl, r1);
6131 if (bv->poisoned) poisoned = 1;
6134 assert (tag == LRGCS);
6135 q = lglidx2lits (lgl, (r0 & REDCS), r1);
6136 while (!poisoned && (other = *q++))
6137 poisoned = lglavar (lgl, other)->poisoned;
6139 if (!poisoned) continue;
6140 assert (!av->poisoned);
6142 lglpushstk (lgl, &lgl->poisoned, lit);
6147 double lglprocesstime (void) {
6150 if (getrusage (RUSAGE_SELF, &u)) return 0;
6151 res = u.ru_utime.tv_sec + 1e-6 * u.ru_utime.tv_usec;
6152 res += u.ru_stime.tv_sec + 1e-6 * u.ru_stime.tv_usec;
6156 static double lglgetime (LGL * lgl) {
6157 if (lgl->cbs && lgl->cbs->getime) return lgl->cbs->getime ();
6158 else return lglprocesstime ();
6161 static void lglstart (LGL * lgl, double * timestatsptr) {
6162 int nest = lgl->timers->nest;
6163 assert (timestatsptr);
6164 assert (nest < MAXPHN);
6165 assert ((double*) lgl->times <= timestatsptr);
6166 assert (timestatsptr < (double*)(sizeof *lgl->times + (char*) lgl->times));
6167 lgl->timers->idx[nest] = timestatsptr - (double*)lgl->times;
6168 lgl->timers->phase[nest] = lglgetime (lgl);
6169 lgl->timers->nest++;
6172 void lglflushtimers (LGL * lgl) {
6173 double time = lglgetime (lgl), delta, entered, * ptr;
6175 for (nest = 0; nest < lgl->timers->nest; nest++) {
6176 entered = lgl->timers->phase[nest];
6177 lgl->timers->phase[nest] = time;
6178 delta = time - entered;
6179 if (delta < 0) delta = 0;
6180 ptr = lgl->timers->idx[nest] + (double*)lgl->times;
6185 double lglsec (LGL * lgl) {
6187 lglflushtimers (lgl);
6188 return lgl->times->all;
6191 static void lglstop (LGL * lgl) {
6192 lglflushtimers (lgl);
6193 lgl->timers->nest--;
6194 assert (lgl->timers->nest >= 0);
6197 double lglmaxmb (LGL * lgl) {
6199 return (lgl->stats->bytes.max + sizeof *lgl) / (double)(1<<20);
6202 size_t lglbytes (LGL * lgl) {
6204 return lgl->stats->bytes.current;
6207 double lglmb (LGL * lgl) {
6209 return (lgl->stats->bytes.current + sizeof *lgl) / (double)(1<<20);
6212 static double lglagility (LGL * lgl) { return lgl->flips/1e7; }
6214 static double lglavg (double n, double d) {
6215 return d != 0 ? n / d : 0.0;
6218 static double lglheight (LGL * lgl) {
6219 return lglavg (lgl->stats->height, lgl->stats->decisions);
6222 static double lglglue (LGL * lgl) {
6223 return lglavg (lgl->stats->glues.sum, lgl->stats->glues.count);
6226 static void lglrephead (LGL * lgl) {
6227 if (lgl->tid > 0) return;
6228 lgl->forcerephead = 0;
6229 lgl->repcntdown = REPMOD;
6230 if (lgl->tid > 0) return;
6231 if (lgl->cbs && lgl->cbs->msglock.lock)
6232 lgl->cbs->msglock.lock (lgl->cbs->msglock.state);
6233 assert (lgl->prefix);
6234 fprintf (lgl->out, "%s\n", lgl->prefix);
6235 fprintf (lgl->out, "%s%s"
6236 " seconds irredundant redundant clauses agility "
6237 " height\n", lgl->prefix, !lgl->tid ? " " : "");
6238 fprintf (lgl->out, "%s%s"
6239 " variables clauses conflicts large ternary binary "
6240 "glue MB\n", lgl->prefix, !lgl->tid ? " " : "");
6241 fprintf (lgl->out, "%s\n", lgl->prefix);
6243 if (lgl->cbs && lgl->cbs->msglock.unlock)
6244 lgl->cbs->msglock.unlock (lgl->cbs->msglock.state);
6247 static void lglrep (LGL * lgl, int level, char type) {
6248 if (lgl->opts->verbose.val < level) return;
6249 if ((level > 0 && lgl->forcerephead) || !lgl->repcntdown--)
6252 "%c %6.1f %7d %8d %9lld %7d %6d %5d %3.0f %4.1f %5.1f %4.0f",
6254 lgl->opts->abstime.val ? lglgetime (lgl) : lglsec (lgl),
6256 lgl->stats->irr.clauses.cur,
6257 (LGLL) lgl->stats->confs,
6258 lgl->stats->red.lrg,
6259 lgl->stats->red.trn,
6260 lgl->stats->red.bin,
6265 lgl->stats->reported++;
6268 static void lglflshrep (LGL * lgl) {
6269 if (!lgl->stats->reported) return;
6270 if (lgl->stats->reported % REPMOD) lglrephead (lgl);
6271 else lglprt (lgl, 1, "");
6274 static void lglfitlir (LGL * lgl, Stk * lir) {
6275 lglfitstk (lgl, lir);
6278 static void lglchkred (LGL * lgl) {
6280 int glue, idx, sign, lit, thisum, sum, sum2, sum3;
6281 int blit, tag, red, other, other2;
6282 int * p, * c, * w, * eow;
6285 if (lgl->mt) return;
6287 for (glue = 0; glue < MAXGLUE; glue++) {
6288 lir = lgl->red + glue;
6290 for (c = lir->start; c < lir->top; c = p + 1) {
6292 if (*p >= NOTALIT) continue;
6294 assert (p - c >= 4);
6297 assert (thisum == lgl->stats->lir[glue].clauses);
6300 assert (sum == lgl->stats->red.lrg);
6302 for (idx = 2; idx < lgl->nvars; idx++)
6303 for (sign = -1; sign <= 1; sign += 2) {
6305 hts = lglhts (lgl, lit);
6306 w = lglhts2wchs (lgl, hts);
6307 eow = w + hts->count;
6308 for (p = w; p < eow; p++) {
6310 tag = blit & MASKCS;
6312 if (tag == TRNCS || tag == LRGCS) p++;
6313 if (!red || tag == LRGCS || tag == OCCS) continue;
6314 other = blit >> RMSHFT;
6315 if (abs (other) < idx) continue;
6316 if (tag == BINCS) sum2++;
6318 assert (tag == TRNCS);
6320 if (abs (other2) < idx) continue;
6325 assert (sum2 == lgl->stats->red.bin);
6326 assert (sum3 == lgl->stats->red.trn);
6330 static int lglcmppasl (LGL * lgl, PASL * a, PASL * b, int glueuseless) {
6331 int res, psmval, psmdiff, aglue, bglue, gluediff;
6332 psmdiff = a->psm - b->psm;
6333 psmval = lgl->opts->psm.val;
6334 if (psmval == 3 && psmdiff) return psmdiff;
6335 aglue = (a->lidx & GLUEMASK);
6336 bglue = (b->lidx & GLUEMASK);
6337 gluediff = aglue - bglue;
6338 if (!glueuseless && gluediff) return gluediff;
6339 if (psmval == 2 && psmdiff) return psmdiff;
6340 if ((res = (a->act - b->act))) return res;
6341 if (psmval == 1 && psmdiff) return psmdiff;
6342 if ((res = (b->size - a->size))) return res;
6343 if (glueuseless && gluediff) return gluediff;
6344 return a->lidx - b->lidx;
6347 #define LGLCMPPASL(A,B) lglcmppasl (lgl, (A), (B), glueuseless)
6349 static int lglneedacts (LGL * lgl,
6350 int * glueuselessptr,
6351 int * needmoreclausesptr) {
6352 int64_t clauses = 0, weighted = 0, tmp, avg, var = 0, std, delta;
6353 int glue, maxglue = 0;
6355 for (glue = 0; glue <= MAXGLUE; glue++) {
6356 tmp = lgl->stats->lir[glue].clauses;
6357 if (tmp) maxglue = glue;
6359 weighted += glue * tmp;
6361 avg = clauses ? (10*weighted)/clauses : 0;
6363 "[needacts-%d] existing clauses glue average %.1f",
6364 lgl->stats->reduced.count, avg/10.0);
6365 for (glue = 1; glue <= MAXGLUE; glue++) {
6366 delta = (10*glue - avg);
6367 var += delta*delta * lgl->stats->lir[glue].clauses;
6369 var = clauses ? var / clauses : 0;
6370 std = lglceilsqrt64 (var);
6372 "[needacts-%d] existing clauses glue standard deviation %.1f",
6373 lgl->stats->reduced.count, std/10.0);
6375 if (std < lgl->opts->actgsdul.val) {
6377 "[needacts-%d] glue useless since standard deviation %.1f < %.1f",
6378 lgl->stats->reduced.count, std/10.0, lgl->opts->actgsdul.val/10.0);
6379 *glueuselessptr = 1;
6382 "[needacts-%d] glue useful since standard deviation %.1f >= %.1f",
6383 lgl->stats->reduced.count, std/10.0, lgl->opts->actgsdul.val/10.0);
6384 *glueuselessptr = 0;
6387 if (maxglue <= lgl->opts->actgeomlim.val) {
6389 "[needacts-%d] really need more clauses since maxglue %d <= %d",
6390 lgl->stats->reduced.count, maxglue, lgl->opts->actgeomlim.val);
6391 *needmoreclausesptr = 2;
6392 } else if (maxglue <= lgl->opts->actdblarithlim.val) {
6394 "[needacts-%d] could use more clauses since maxglue %d <= %d",
6395 lgl->stats->reduced.count, maxglue, lgl->opts->actdblarithlim.val);
6396 *needmoreclausesptr = 1;
6399 "[needacts-%d] no need for more clauses since maxglue %d > %d",
6400 lgl->stats->reduced.count, maxglue, lgl->opts->actdblarithlim.val);
6401 *needmoreclausesptr = 0;
6404 if (lglrem (lgl) > lgl->opts->actvlim.val) {
6406 "[needacts-%d] too many variables %d > %d",
6407 lgl->stats->reduced.count, lglrem (lgl), lgl->opts->actvlim.val);
6410 if (avg > lgl->opts->actavgmax.val) {
6412 "[needacts-%d] very large average glue %.1f > %.1f",
6413 lgl->stats->reduced.count, avg/10.0, lgl->opts->actavgmax.val/10.0);
6416 if (std <= lgl->opts->actstdmin.val) {
6418 "[needacts-%d] very small standard deviation glue %.1f <= %.1f",
6419 lgl->stats->reduced.count, std/10.0, lgl->opts->actstdmin.val/10.0);
6422 if (std > lgl->opts->actstdmax.val) {
6424 "[needacts-%d] very large standard deviation glue %.1f > %.1f",
6425 lgl->stats->reduced.count, std/10.0, lgl->opts->actstdmax.val/10.0);
6430 "[needacts-%d] regular glue average and standard deviation",
6431 lgl->stats->reduced.count);
6436 static int lglagile (LGL * lgl) {
6437 switch (lgl->opts->agile.val) {
6439 return lgl->flips >= lgl->opts->agilelim.val * 10000000ull;
6441 return lgl->flips >=
6442 (50*(sin(lgl->stats->confs*M_PI/2.0/lgl->opts->agilesinint.val) + 1))
6448 static int lglsaturating (LGL * lgl) {
6449 int64_t avglue, avgheight;
6450 if (!lgl->opts->saturating.val) return 0;
6451 if (!lgl->stats->glues.count) return 0;
6452 if (!lgl->stats->decisions) return 0;
6453 avglue = lgl->stats->glues.sum;
6454 avglue *= 100 + lgl->opts->saturating.val;
6455 avglue /= lgl->stats->glues.count;
6456 avgheight = lgl->stats->height;
6458 avgheight /= lgl->stats->decisions;
6459 return avglue >= avgheight;
6462 static void lglboundredl (LGL * lgl) {
6463 int64_t minabs, minrel, maxabs, maxrel, oldlim, newlim;
6465 newlim = oldlim = lgl->limits->reduce.inner;
6466 if (!lgl->opts->redlbound.val) goto SKIP;
6469 "[bound-reduce-limit] preliminary reduce limit %d before bounding",
6472 minrel = lgl->opts->redlminrel.val;
6473 minrel *= (lgl->stats->irr.clauses.cur + 99ll)/100ll;
6474 minabs = lgl->opts->redlminabs.val;
6476 lglprt (lgl, 2, "[bound-reduce-limit] minrel = %d, minabs = %d",
6479 if (minrel < minabs) {
6480 if (minrel > lgl->limits->reduce.inner) {
6482 "[bound-reduce-limit] relative minimum reduce limit %d hit", minrel);
6486 if (minabs > lgl->limits->reduce.inner) {
6488 "[bound-reduce-limit] absolute minimum reduce limit of %d hit",
6494 maxrel = lgl->opts->redlmaxrel.val;
6495 maxrel *= (lgl->stats->irr.clauses.cur + 99ll)/100ll;
6496 maxrel += lgl->opts->redlmininc.val * (int64_t) lgl->limits->reduce.extra;
6497 maxabs = lgl->opts->redlmaxabs.val;
6500 "[bound-reduce-limit] maxrel = %d, maxabs = %d", maxrel, maxabs);
6502 if (maxrel < maxabs) {
6503 lgl->limits->reduce.extra++;
6504 if (maxrel < lgl->limits->reduce.inner) {
6506 "[bound-reduce-limit] relative maximum reduce limit %d hit", maxrel);
6510 if (maxabs < lgl->limits->reduce.inner) {
6512 "[bound-reduce-limit] absolute maximum reduce limit of %d hit",
6520 lgl->limits->reduce.inner = newlim;
6522 "[bound-reduce-limit] new reduce limit of %d after %lld conflicts",
6523 lgl->limits->reduce.inner, (LGLL) lgl->stats->confs);
6526 static int64_t lglubyrec (LGL * lgl, int i) {
6527 int64_t res = 0, s = 0;
6530 for (k = 1; !res && k < 32; s++, k++) {
6531 if (i == (1 << k) - 1)
6535 for (k = 1; !res; k++, s++)
6536 if ((1 << (k - 1)) <= i && i < (1 << k) - 1)
6537 res = lglubyrec (lgl, i - (1 << (k-1)) + 1);
6539 lgl->stats->luby.steps += s;
6545 static int64_t lgluby (LGL * lgl, int i) {
6547 lgl->stats->luby.count++;
6548 return lglubyrec (lgl, i);
6551 static int64_t lglinout (LGL * lgl, int c, int relincpcnt) {
6552 int64_t i = 1, o = 1;
6556 lgl->stats->inout.count++;
6557 lgl->stats->inout.steps += c;
6560 i = ((100 + relincpcnt)*i + 99)/100;
6561 if (i < o) continue;
6563 o = ((100 + relincpcnt)*o + 99)/100;
6570 static int lglmemout (LGL * lgl) {
6573 if (lgl->opts->memlim.val < 0) return 0;
6574 cur = lgl->stats->bytes.current;
6576 res = (cur >= lgl->opts->memlim.val);
6578 lglprt (lgl, 2, "memory limit of %d MB hit after allocating %lld MB",
6579 lgl->opts->memlim.val, (LGLL) cur);
6583 static Val lgliphase (LGL * lgl, int lit) {
6584 Val res = lglavar (lgl, lit)->phase;
6585 if (lit < 0) res = -res;
6589 static void lglreduce (LGL * lgl, int forced) {
6590 int * p, * q, * start, * c, ** maps, * sizes, * map, * eow, * rsn;
6591 int nlocked, collected, sumcollected, nunlocked, moved, act, psm;
6592 int glue, minredglue, maxredglue, target, rem, nkeep;
6593 int inc, acts, glueuseless, needmoreclauses, delta;
6594 PASL * pasls, * pasl; int npasls, szpasls;
6595 int size, idx, tag, red, i, blit;
6596 int r0, lidx, src, dst, lit;
6603 lglstart (lgl, &lgl->times->red);
6604 lgl->stats->reduced.count++;
6605 LOG (1, "starting reduction %d", lgl->stats->reduced.count);
6606 acts = lglneedacts (lgl, &glueuseless, &needmoreclauses);
6607 delta = lgl->stats->red.lrg;
6608 delta -= lgl->lrgluereasons;
6609 delta -= lgl->stats->lir[0].clauses;
6610 assert (delta >= 0);
6611 if (delta > 3*lgl->limits->reduce.inner/2)
6612 target = delta - lgl->limits->reduce.inner/2;
6613 else target = delta/2;
6615 LOG (2, "target is to collect %d clauses out of %d", target, delta);
6616 for (maxredglue = MAXGLUE-1; maxredglue >= 0; maxredglue--)
6617 if (lgl->stats->lir[maxredglue].clauses > 0) break;
6618 LOG (2, "maximum reduction glue %d", maxredglue);
6619 if (lgl->opts->acts.val < 2) acts = lgl->opts->acts.val;
6623 "[needacts-%d] using primarily activities for reduction",
6624 lgl->stats->reduced.count);
6625 szpasls = lgl->stats->red.lrg;
6629 "[needacts-%d] using primarily glues for reduction",
6630 lgl->stats->reduced.count);
6632 if (maxredglue > 0) {
6633 for (minredglue = maxredglue; minredglue > 1; minredglue--) {
6634 LOG (2, "%d candidate clauses with glue %d",
6635 lgl->stats->lir[minredglue].clauses, minredglue);
6636 if (lgl->stats->lir[minredglue].clauses >= rem) break;
6637 rem -= lgl->stats->lir[minredglue].clauses;
6639 } else minredglue = 1;
6640 szpasls = lgl->stats->lir[minredglue].clauses;
6642 LOG (2, "minum reduction glue %d with %d remaining target clauses %.0f%%",
6643 minredglue, rem, lglpcnt (rem, target));
6644 NEW (maps, maxredglue + 1);
6645 NEW (sizes, maxredglue + 1);
6646 for (glue = minredglue; glue <= maxredglue; glue++) {
6647 lir = lgl->red + glue;
6648 size = lglcntstk (lir);
6649 assert (!size || size >= 6);
6650 size = (size + 5)/6;
6652 lglfitstk (lgl, lir);
6653 NEW (maps[glue], size);
6655 for (i = 0; i < size; i++) map[i] = -2;
6658 for (i = 0; i < lglcntstk (&lgl->trail); i++) {
6659 lit = lglpeek (&lgl->trail, i);
6661 rsn = lglrsn (lgl, idx);
6666 if (tag != LRGCS) continue;
6668 glue = lidx & GLUEMASK;
6669 if (glue == MAXGLUE) continue;
6670 if (glue < minredglue) continue;
6671 if (glue > maxredglue) continue;
6674 lir = lgl->red + glue;
6675 LOGCLS (5, lir->start + lidx,
6676 "locking reason of literal %d glue %d clause",
6680 assert (lidx < sizes[glue]);
6681 assert (maps[glue][lidx] == -2);
6682 maps[glue][lidx] = -1;
6685 LOG (2, "locked %d learned clauses %.0f%%",
6686 nlocked, lglpcnt (nlocked, lgl->stats->red.lrg));
6687 NEW (pasls, szpasls);
6689 for (glue = minredglue; glue <= maxredglue; glue++) {
6690 lir = lgl->red + glue;
6692 for (c = start; c < lir->top; c = p + 1) {
6695 if (act == REMOVED) {
6696 for (p = c + 1; p < lir->top && *p == REMOVED; p++)
6701 for (p = ++c; (lit = *p); p++)
6702 if (lgliphase (lgl, lit) >= 0) psm++;
6703 assert (npasls < szpasls);
6704 pasl = pasls + npasls++;
6708 pasl->lidx = ((c - start) << GLUESHFT) | glue;
6710 if (!acts) { assert (glue == minredglue); break; }
6712 assert (npasls <= szpasls);
6716 "[reduce-%d] ignoring useless glue",
6717 lgl->stats->reduced.count);
6718 lgl->stats->reduced.gul++;
6720 SORT (PASL, pasls, npasls, LGLCMPPASL);
6721 LOG (1, "copied and sorted %d activities", npasls);
6724 for (idx = rem; idx < npasls; idx++) {
6727 glue = lidx & GLUEMASK;
6730 assert (lidx < sizes[glue]);
6731 maps[glue][lidx] = -1;
6734 DEL (pasls, szpasls);
6735 LOG (1, "explicity marked %d additional clauses to keep", nkeep);
6737 for (glue = minredglue; glue <= maxredglue; glue++) {
6738 lir = lgl->red + glue;
6743 q = start = lir->start;
6745 for (c = start; c < lir->top; c = p + 1) {
6747 if (act == REMOVED) {
6748 for (p = c; p < lir->top && *p == REMOVED; p++)
6750 assert (p >= lir->top || *p < NOTALIT || lglisact (*p));
6756 src = (c - start)/6;
6757 assert (src < size);
6758 if (map[src] == -2) {
6759 assert (collected < lgl->stats->lir[glue].clauses);
6761 LOGCLS (5, c, "collecting glue %d clause", glue);
6764 dst = q - start + 1;
6771 LOGCLS (5, c, "moving from %d to %d glue %d clause",
6772 (c - start), dst, glue);
6773 while (*p) *q++ = *p++;
6778 LOG (2, "collected %d glue %d clauses", collected, glue);
6779 sumcollected += collected;
6780 assert (sumcollected <= lgl->stats->red.lrg);
6781 assert (lgl->stats->lir[glue].clauses >= collected);
6782 lgl->stats->lir[glue].clauses -= collected;
6783 lgl->stats->lir[glue].reduced += collected;
6785 lglfitlir (lgl, lir);
6787 LOG (2, "collected altogether %d clauses", sumcollected);
6788 assert (sumcollected <= lgl->stats->red.lrg);
6789 lgl->stats->red.lrg -= sumcollected;
6791 for (idx = 2; idx < lgl->nvars; idx++) {
6792 if (!lglval (lgl, idx)) continue;
6793 rsn = lglrsn (lgl, idx);
6798 if (tag != LRGCS) continue;
6800 glue = lidx & GLUEMASK;
6801 if (glue < minredglue) continue;
6802 if (glue > maxredglue) continue;
6803 src = (lidx >> GLUESHFT);
6804 assert (src/6 < sizes[glue]);
6805 dst = maps[glue][src/6];
6808 dst |= lidx & GLUEMASK;
6812 LOG (2, "unlocked %d reasons", nunlocked);
6813 assert (nlocked == nunlocked);
6814 collected = moved = 0;
6815 for (idx = 2; idx < lgl->nvars; idx++) {
6816 dv = lgldvar (lgl, idx);
6817 for (i = 0; i <= 1; i++) {
6819 if (!hts->offset) continue;
6820 q = lglhts2wchs (lgl, hts);
6821 assert (hts->count >= 0);
6822 eow = q + hts->count;
6823 for (p = q; p < eow; p++) {
6826 tag = blit & MASKCS;
6827 if (red && tag == LRGCS) {
6829 glue = lidx & GLUEMASK;
6830 if (glue < minredglue || glue > maxredglue) {
6831 dst = lidx >> GLUESHFT;
6833 src = lidx >> GLUESHFT;
6834 assert (src/6 < sizes[glue]);
6835 dst = maps[glue][src/6];
6840 *q++ = (dst << GLUESHFT) | (lidx & GLUEMASK);
6845 assert (tag == TRNCS || tag == LRGCS);
6850 lglshrinkhts (lgl, hts, hts->count - (p - q));
6853 LOG (1, "moved %d and collected %d occurrences", moved, collected);
6854 for (glue = minredglue; glue <= maxredglue; glue++)
6855 DEL (maps[glue], sizes[glue]);
6856 DEL (sizes, maxredglue+1);
6857 DEL (maps, maxredglue+1);
6858 if (lgl->opts->redfixed.val) goto NOINC;
6859 if (lglmemout (lgl)) {
6862 "[reduce-%d] no increase of reduce limit since memory limit was hit",
6863 lgl->stats->reduced.count);
6864 lgl->stats->reduced.memlim++;
6865 } else if (!needmoreclauses) {
6866 inc = lgl->opts->redlinc.val;
6868 "[reduce-%d] arithmetic increase of reduce limit",
6869 lgl->stats->reduced.count);
6870 lgl->stats->reduced.arith++;
6871 } else if (needmoreclauses == 1) {
6872 inc = 2*lgl->opts->redlinc.val;
6874 "[reduce-%d] double-arithmetic increase of reduce limit",
6875 lgl->stats->reduced.count);
6876 lgl->stats->reduced.arith2++;
6877 lgl->stats->reduced.arith++;
6879 inc = (lgl->opts->redlexpfac.val * lgl->limits->reduce.inner + 99)/100;
6882 "[reduce-%d] geometric increase of reduce limit",
6883 lgl->stats->reduced.count);
6884 lgl->stats->reduced.geom++;
6886 LOG (1, "reduce increment %d", inc);
6887 lgl->limits->reduce.inner += inc;
6888 assert (forced || lgl->opts->reduce.val);
6889 if (lgl->opts->reduce.val > 1 &&
6890 (lglrem (lgl) < lgl->opts->redoutvlim.val ||
6891 lgl->stats->irr.clauses.cur < lgl->opts->redoutclim.val) &&
6892 lgl->limits->reduce.inner >= lgl->limits->reduce.outer) {
6894 lgl->stats->reduced.reset++;
6895 lgl->limits->reduce.inner = lgl->opts->redlinit.val;
6897 if (lgl->opts->reduce.val == 2) {
6898 outer = lgl->limits->reduce.inner;
6899 outer *= lgluby (lgl, lgl->stats->reduced.reset);
6900 } else if (lgl->opts->reduce.val == 3) {
6901 outer = lgl->limits->reduce.inner;
6902 outer *= lglinout (lgl, lgl->stats->reduced.reset,
6903 lgl->opts->redinoutinc.val);
6905 assert (lgl->opts->reduce.val == 4);
6906 outer = lgl->limits->reduce.outer + lgl->opts->redloutinc.val;
6907 if (outer < lgl->limits->reduce.inner)
6908 outer = lgl->limits->reduce.inner;
6910 if (outer > (int64_t) INT_MAX) outer = INT_MAX;
6911 lgl->limits->reduce.outer = outer;
6912 } else lglboundredl (lgl);
6914 lglrelstk (lgl, &lgl->learned);
6915 lglrep (lgl, 1, type);
6920 void lglreducecache (LGL * lgl) {
6921 REQINITNOTFORKED ();
6923 if (lgl->mt) return;
6924 lgl->limits->reduce.inner = lgl->opts->redlinit.val;
6927 lgl->limits->reduce.inner = lgl->opts->redlinit.val;
6929 lgl->limits->reduce.outer = 2*lgl->limits->reduce.inner;
6930 lglprt (lgl, 1, "[reduce-cache] new limit %d", lgl->limits->reduce.inner);
6931 if (lgl->clone) lglreducecache (lgl->clone);
6935 static void lglpicosatrestart (LGL *);
6938 static void lgliflushcache (LGL * lgl, int keep) {
6939 int idx, sign, lit, blit, tag, red, * w, * q, lidx, glue;
6940 int bin, trn, lrg, start;
6941 const int * p, * eow;
6943 assert (1 <= keep), assert (keep <= 4);
6944 if (lgl->level) lglbacktrack (lgl, 0);
6945 bin = trn = lrg = 0;
6946 for (idx = 2; idx < lgl->nvars; idx++) {
6947 for (sign = -1; sign <= 1; sign += 2) {
6949 hts = lglhts (lgl, lit);
6950 w = lglhts2wchs (lgl, hts);
6951 eow = w + hts->count;
6953 for (p = q; p < eow; p++) {
6955 tag = blit & MASKCS;
6956 if (tag == TRNCS || tag == LRGCS) p++;
6960 if (keep < 2) continue;
6961 } else if (tag == TRNCS) {
6962 if (keep < 3) continue;
6964 assert (tag == LRGCS);
6965 if (keep < 4) continue;
6967 glue = lidx & GLUEMASK;
6968 if (glue > 0) continue;
6972 if (tag == TRNCS || tag == LRGCS) *q++ = *p;
6974 lglshrinkhts (lgl, hts, q - w);
6977 if (keep < 2) bin = lgl->stats->red.bin, lgl->stats->red.bin = 0;
6978 if (keep < 3) trn = lgl->stats->red.trn, lgl->stats->red.trn = 0;
6979 start = (keep >= 4);
6980 for (glue = start; glue < MAXGLUE; glue++) {
6981 lrg += lgl->stats->lir[glue].clauses;
6982 lgl->stats->lir[glue].clauses = 0;
6984 assert (lrg <= lgl->stats->red.lrg), lgl->stats->red.lrg -= lrg;
6985 lglrelstk (lgl, &lgl->learned);
6986 for (glue = start; glue < MAXGLUE; glue++)
6987 lglrelstk (lgl, lgl->red + glue);
6989 "[flush-cache] %d binary, %d ternary, %d large",
6992 lglpicosatrestart (lgl);
6996 void lglflushcache (LGL * lgl) {
6997 REQINITNOTFORKED ();
6999 if (lgl->mt) return;
7000 lgl->limits->reduce.inner = lgl->opts->redlinit.val;
7002 lgliflushcache (lgl, 1);
7003 lgl->limits->reduce.inner = lgl->opts->redlinit.val;
7005 lgl->limits->reduce.outer = 2*lgl->limits->reduce.inner;
7006 lglprt (lgl, 1, "[flush-cache] new limit %d", lgl->limits->reduce.inner);
7007 if (lgl->clone) lglflushcache (lgl->clone);
7011 static void lglrmbwch (LGL * lgl, int lit, int other, int red) {
7012 int * p, blit, blit1, * w, * eow, tag;
7014 assert (!red || red == REDCS);
7015 LOG (3, "removing %s binary watch %d blit %d",
7016 lglred2str (red), lit, other);
7017 hts = lglhts (lgl, lit);
7018 assert (hts->count >= 1);
7019 p = w = lglhts2wchs (lgl, hts);
7020 eow = w + hts->count;
7021 lglrminc (lgl, w, eow);
7022 blit1 = (other << RMSHFT) | red | BINCS;
7026 tag = blit & MASKCS;
7027 if (tag == TRNCS || tag == LRGCS) { p++; continue; }
7028 if (tag == OCCS) { assert (lgl->dense); continue; }
7029 assert (tag == BINCS);
7030 if (blit == blit1) break;
7032 while (p < eow) p[-1] = p[0], p++;
7033 lglshrinkhts (lgl, hts, p - w - 1);
7036 static int lglpopesched (LGL * lgl) {
7037 Stk * s = &lgl->esched;
7038 int res, last, cnt, * p;
7040 assert (!lglmtstk (s));
7042 assert (!lglifrozen (lgl, res));
7043 LOGESCHED (4, res, "popped");
7044 ev = lglevar (lgl, res);
7047 last = lglpopstk (s);
7048 cnt = lglcntstk (s);
7049 if (!cnt) { assert (last == res); return res; }
7050 p = lglepos (lgl, last);
7054 lgledown (lgl, last);
7058 static void lgldecocc (LGL * lgl, int lit) {
7059 int idx, sign, change;
7061 if (!lgl->occs) return;
7062 idx = abs (lit), sign = (lit < 0);
7063 ev = lglevar (lgl, lit);
7064 assert (ev->occ[sign] > 0);
7066 if (!lglisfree (lgl, lit)) return;
7067 change = lglecalc (lgl, ev);
7068 LOG (3, "dec occ of %d now occs[%d] = %d %d",
7069 lit, idx, ev->occ[0], ev->occ[1]);
7070 if (ev->pos < 0) lglesched (lgl, idx);
7071 else if (change < 0) lgleup (lgl, idx);
7072 else if (change > 0) lgledown (lgl, idx);
7075 static void lglrmbcls (LGL * lgl, int a, int b, int red) {
7076 lglrmbwch (lgl, a, b, red);
7077 lglrmbwch (lgl, b, a, red);
7078 LOG (2, "removed %s binary clause %d %d", lglred2str (red), a, b);
7079 lgldeclscnt (lgl, 2, red, 0);
7080 if (!red && lgl->dense) lgldecocc (lgl, a), lgldecocc (lgl, b);
7083 static void lglrmtcls (LGL * lgl, int a, int b, int c, int red) {
7084 lglrmtwch (lgl, a, b, c, red);
7085 lglrmtwch (lgl, b, a, c, red);
7086 lglrmtwch (lgl, c, a, b, red);
7087 LOG (2, "removed %s ternary clause %d %d %d", lglred2str (red), a, b, c);
7088 lgldeclscnt (lgl, 3, red, 0);
7089 if (!red && lgl->dense)
7090 lgldecocc (lgl, a), lgldecocc (lgl, b), lgldecocc (lgl, c);
7093 static void lgltrimlitstk (LGL * lgl, int red, int lidx) {
7094 Stk * s = lglidx2stk (lgl, red, lidx);
7096 while (p > s->start && p[-1] == REMOVED)
7099 int64_t trimmed = s->top - p;
7101 if (red) LOG (4, "trimmed 'red[%d]' by %lld", (LGLL) trimmed);
7102 else LOG (4, "trimmed 'irr' by %lld", (LGLL) trimmed);
7104 lgl->stats->trims += trimmed;
7107 int glue = (lidx & GLUEMASK), maxlidx;
7108 assert (s == &lgl->red[glue]);
7109 maxlidx = (lglcntstk (s) << GLUESHFT) | glue;
7110 for (p = lgl->learned.start; p < lgl->learned.top; p += 3) {
7111 int olidx = *p, oglue = (olidx & GLUEMASK);
7112 if (oglue == glue && olidx >= maxlidx) *p = INT_MIN;
7118 static void lglrmlcls (LGL * lgl, int lidx, int red) {
7119 int * c, * p, glue, lit;
7120 assert (!red || red == REDCS);
7121 glue = red ? (lidx & GLUEMASK) : 0;
7122 c = lglidx2lits (lgl, red, lidx);
7123 if (!red || glue < MAXGLUE) {
7124 lglrmlwch (lgl, c[0], red, lidx);
7125 lglrmlwch (lgl, c[1], red, lidx);
7127 if (!red && lgl->dense) {
7128 for (p = c; (lit = *p); p++) {
7129 lglrmlocc (lgl, lit, red, lidx);
7130 lgldecocc (lgl, lit);
7133 if (red && glue < MAXGLUE) { LGLCHKACT (c[-1]); c[-1] = REMOVED; }
7134 for (p = c; *p; p++) *p = REMOVED;
7136 if (glue != MAXGLUE) lgldeclscnt (lgl, p - c, red, glue);
7137 lgltrimlitstk (lgl, red, lidx);
7140 static void lgldynsub (LGL * lgl, int lit, int r0, int r1) {
7143 LOGREASON (2, lit, r0, r1, "removing on-the-fly subsumed");
7145 if (red) lgl->stats->otfs.sub.dyn.red++;
7146 else lgl->stats->otfs.sub.dyn.irr++;
7147 if (tag == BINCS) lglrmbcls (lgl, lit, (r0>>RMSHFT), red);
7148 else if (tag == TRNCS) lglrmtcls (lgl, lit, (r0>>RMSHFT), r1, red);
7149 else { assert (tag == LRGCS); lglrmlcls (lgl, r1, red); }
7152 static void lglunflict (LGL * lgl, int lit) {
7153 lgl->conf.lit = lit;
7154 lgl->conf.rsn[0] = (lit << RMSHFT) | UNITCS;
7155 LOG (1, "inconsistent unary clause %d", lit);
7158 static void lgldynstr (LGL * lgl, int del, int lit, int r0, int r1) {
7159 int * p, * c, lidx, other, red, tag, glue, other2, other3, blit;
7161 LOGREASON (2, lit, r0, r1,
7162 "on-the-fly strengthening by removing %d from", del);
7164 if (red) lgl->stats->otfs.str.dyn.red++;
7165 else lgl->stats->otfs.str.dyn.irr++;
7166 lgl->stats->prgss++;
7167 if (!red) lgl->stats->irrprgss++;
7169 other = (del == lit) ? (r0 >> RMSHFT) : lit;
7170 assert (other != del);
7171 lglrmbcls (lgl, del, other, red);
7172 if (lgl->opts->drup.val) lgldrupclsarg (lgl, other, 0);
7174 lglpicosatchkclsarg (lgl, other, 0);
7176 lglunflict (lgl, other);
7180 if (lit == del) other = (r0 >> RMSHFT), other2 = r1;
7181 else if (del == r1) other = lit, other2 = (r0 >> RMSHFT);
7182 else other = lit, other2 = r1;
7183 assert (del != other && del != other2);
7184 lglrmtcls (lgl, del, other, other2, red);
7185 if (lgl->opts->drup.val) lgldrupclsarg (lgl, other, other2, 0);
7187 lglpicosatchkclsarg (lgl, other, other2, 0);
7189 if (!red) lglincirr (lgl, 2);
7190 else lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
7191 lglwchbin (lgl, other, other2, red);
7192 lglwchbin (lgl, other2, other, red);
7193 if (lglevel (lgl, other) < lglevel (lgl, other2)) SWAP (int, other, other2);
7194 blit = (other2 << RMSHFT) | BINCS | red;
7195 lglbonflict (lgl, other, blit);
7198 assert (tag == LRGCS);
7200 glue = red ? (lidx & GLUEMASK) : 0;
7201 c = lglidx2lits (lgl, red, lidx);
7202 for (p = c; *p != del; p++)
7204 if (glue < MAXGLUE) {
7205 lglrmlwch (lgl, c[0], red, lidx);
7206 lglrmlwch (lgl, c[1], red, lidx);
7208 while ((other = *++p)) p[-1] = other;
7209 p[-1] = 0, *p = REMOVED;
7210 lgltrimlitstk (lgl, red, lidx);
7211 if (!red) assert (lgl->stats->irr.lits.cur), lgl->stats->irr.lits.cur--;
7212 lglorderclsaux (lgl, c + 0);
7213 lglorderclsaux (lgl, c + 1);
7214 if (lgl->opts->drup.val) lgldrupclsaux (lgl, c);
7216 lglpicosatchkclsaux (lgl, c);
7220 assert (!c[3] && c[4] >= NOTALIT);
7221 other = c[0], other2 = c[1], other3 = c[2];
7222 if (red && glue < MAXGLUE) { LGLCHKACT (c[-1]); c[-1] = REMOVED; }
7223 c[0] = c[1] = c[2] = c[3] = REMOVED;
7224 lgltrimlitstk (lgl, red, lidx);
7225 if (lglevel (lgl, other2) < lglevel (lgl, other3))
7226 SWAP (int, other2, other3);
7227 if (lglevel (lgl, other) < lglevel (lgl, other2))
7228 SWAP (int, other, other2);
7229 lglwchtrn (lgl, other, other2, other3, red);
7230 lglwchtrn (lgl, other2, other, other3, red);
7231 lglwchtrn (lgl, other3, other, other2, red);
7233 if (glue < MAXGLUE) {
7234 assert (lgl->stats->red.lrg > 0);
7235 lgl->stats->red.lrg--;
7236 assert (lgl->stats->lir[glue].clauses > 0);
7237 lgl->stats->lir[glue].clauses--;
7239 lgl->stats->red.trn++;
7240 assert (lgl->stats->red.trn > 0);
7242 lgltonflict (lgl, other, (other2 << RMSHFT) | red | TRNCS, other3);
7244 if (glue < MAXGLUE) {
7245 LOG (3, "new head literal %d", c[0]);
7246 (void) lglwchlrg (lgl, c[0], c[1], red, lidx);
7247 LOG (3, "new tail literal %d", c[1]);
7248 (void) lglwchlrg (lgl, c[1], c[0], red, lidx);
7250 lglonflict (lgl, 0, c[0], red, lidx);
7254 static void lglclnframes (LGL * lgl) {
7255 while (!lglmtstk (&lgl->frames))
7256 lglunuselevel (lgl, lglpopstk (&lgl->frames));
7259 static void lglclnpoisoned (LGL * lgl) {
7260 while (!lglmtstk (&lgl->poisoned)) {
7261 int lit = lglpopstk (&lgl->poisoned);
7262 AVar * av = lglavar (lgl, lit);
7264 assert (av->poisoned);
7269 static void lglclnana (LGL * lgl) {
7271 if (lglmaintainresolvent (lgl)) lglclnstk (&lgl->resolvent);
7273 lglclnstk (&lgl->clause);
7274 lglpopnunmarkstk (lgl, &lgl->seen);
7278 static void lglbumplit (LGL * lgl, int lit) {
7279 int idx = abs (lit), mightneedtorescore = 0;
7280 QVar * qv = lglqvar (lgl, idx);
7281 Scr oldscore, newscore;
7282 oldscore = qv->score;
7283 switch (lgl->opts->score.val) {
7289 assert (lgl->opts->score.val == LGL_SCORE_VSIDS256);
7291 newscore = oldscore + 1;
7293 "incrementing score of variable %d from %lld to %lld",
7294 idx, (LGLL) oldscore, (LGLL) newscore);
7297 newscore = lgl->stats->confs;
7299 "setting last conflict of variable %d from %lld to %lld",
7300 idx, (LGLL) oldscore, (LGLL) newscore);
7303 newscore = oldscore + lgl->stats->confs;
7305 "changing sum of conflict counts of variable %d from %lld to %lld",
7306 idx, (LGLL) oldscore, (LGLL) newscore);
7307 mightneedtorescore = 1;
7310 assert (lgl->opts->score.val == LGL_SCORE_AVG);
7312 newscore = lglflt (0, (uint64_t) (lgl->stats->confs + 1));
7313 newscore = lgladdflt (oldscore, newscore);
7314 newscore = lglshflt (newscore, 1);
7316 newscore = (oldscore + lgl->stats->confs)/2.0;
7318 assert (newscore > oldscore);
7320 "averaging of %d from %s to %s after %lld conflicts",
7321 idx, lglscr2str (lgl, oldscore), lglscr2str (lgl, newscore),
7322 (LGLL) lgl->stats->confs);
7325 assert (lgl->opts->score.val == LGL_SCORE_EVSIDS);
7326 newscore = lgladdscr (oldscore, lgl->scinc);
7328 "bumping EVSIDS score of variable %d from %s to %s",
7329 idx, lglscr2str (lgl, oldscore), lglscr2str (lgl, newscore));
7330 assert (newscore > oldscore);
7331 mightneedtorescore = 1;
7334 qv->score = newscore;
7335 if (lgldscheduled (lgl, idx)) lgldup (lgl, idx);
7336 if (mightneedtorescore && newscore >= lgl->maxscore) lglrescorevars (lgl);
7339 static void lglbumpseenlits (LGL * lgl) {
7341 if (!lgl->opts->bumpseenlits.val) return;
7342 lglstart (lgl, &lgl->times->bump);
7343 for (p = lgl->seen.start; p < lgl->seen.top; p++) lglbumplit (lgl, *p);
7347 static void lglbumpclslits (LGL * lgl) {
7350 lglstart (lgl, &lgl->times->bump);
7351 p = lgl->clause.start;
7352 while ((lit = *p++)) lglbumplit (lgl, lit);
7356 static void lglmincls (LGL * lgl, int uip, int glue) {
7357 int origsize = lglcntstk (&lgl->clause) - 1;
7358 int * p, * q, other, minimized, local;
7359 if (!lgl->opts->minimize.val) return;
7360 if (glue > lgl->opts->minlocalgluelim.val) return;
7361 lglstart (lgl, &lgl->times->mcls);
7362 q = lgl->clause.start;
7364 local = lgl->opts->minimize.val <= 1 || glue > lgl->opts->minrecgluelim.val;
7365 assert (lglmtstk (&lgl->poisoned));
7366 for (p = q; (other = *p); p++)
7367 if (other != uip && lglminclslit (lgl, other, local)) {
7368 LOG (2, "removed %d", other);
7370 } else *q++ = other;
7372 lglclnpoisoned (lgl);
7373 assert (lgl->clause.top - q == minimized);
7374 COVER (glue + 1 >= origsize && minimized > 0); // unreachable ...
7375 LOG (2, "clause minimized by %d literals", minimized);
7376 LOGCLS (2, lgl->clause.start, "minimized clause");
7377 lgl->clause.top = q;
7381 static void lgliassume (LGL * lgl, int lit) {
7383 lglpushcontrol (lgl, lit);
7384 assert (lglcntctk (&lgl->control) == lgl->level + 1);
7385 LOG (2, "internally assuming %d", lit);
7386 lglassign (lgl, lit, DECISION, 0);
7389 static void lgldassume (LGL * lgl, int lit) {
7390 LOG (1, "next assumed decision %d external %d", lit, lglexport (lgl, lit));
7391 lgl->stats->decisions++;
7392 lgl->stats->height += lgl->level;
7393 lgliassume (lgl, lit);
7394 assert (lgldecision (lgl, lit));
7397 void lgldeco2 (LGL * lgl) {
7398 int next, level, lit, tag, r0, r1, other, count;
7399 const int * p, * rsn;
7401 assert (lgl->opts->deco.val == 2);
7402 assert (lglmtstk (&lgl->clause));
7403 for (p = lgl->seen.start; p < lgl->seen.top; p++)
7404 lglavar (lgl, *p)->mark = 0;
7406 count = lglcntstk (&lgl->seen);
7407 LOG (2, "starting only-decision clause analysis after seeing %d", count);
7408 while (next < lglcntstk (&lgl->seen)) {
7409 lit = lglpeek (&lgl->seen, next++);
7410 level = lglevel (lgl, lit);
7411 if (!level || level == lgl->level) continue;
7412 av = lglavar (lgl, lit);
7413 if (av->mark) continue;
7415 if (lgldecision (lgl, lit)) lglpushstk (lgl, &lgl->clause, lit);
7417 rsn = lglrsn (lgl, lit);
7418 r0 = rsn[0], r1 = rsn[1];
7420 if (tag == BINCS || tag == TRNCS) {
7421 other = r0 >> RMSHFT;
7422 lglpushstk (lgl, &lgl->seen, other);
7423 if (tag == TRNCS) lglpushstk (lgl, &lgl->seen, r1);
7425 assert (tag == LRGCS);
7426 p = lglidx2lits (lgl, (r0 & REDCS), r1);
7427 while ((other = *p++))
7429 lglpushstk (lgl, &lgl->seen, other);
7433 assert (next >= count);
7434 LOG (2, "saw %d more in only-decision clause analysis", next - count);
7435 while (lglcntstk (&lgl->seen) > count)
7436 lglavar (lgl, lglpopstk (&lgl->seen))->mark = 0;
7439 void lgldeco1 (LGL * lgl, int jlevel) {
7442 assert (lgl->opts->deco.val == 1);
7443 assert (lglmtstk (&lgl->clause));
7444 for (p = lgl->control.start + 1; p <= lgl->control.start + jlevel; p++) {
7445 assert (p < lgl->control.top);
7447 assert (lgldecision (lgl, lit));
7448 assert (lglevel (lgl, lit));
7449 assert (lglevel (lgl, lit) <= jlevel);
7450 lglpushstk (lgl, &lgl->clause, lit);
7454 void lgldeco (LGL * lgl, int jlevel) {
7455 assert (lgl->opts->deco.val);
7456 if (lgl->opts->deco.val == 1) lgldeco1 (lgl, jlevel);
7457 else lgldeco2 (lgl);
7462 static int lglsubl (LGL * lgl, int lidx, int size, int glue) {
7466 assert ((lidx & GLUEMASK) < MAXGLUE);
7467 c = lglidx2lits (lgl, REDCS, lidx);
7469 for (p = c; count < size && (lit = *p); p++) {
7470 if (lit == REMOVED) return 1;
7471 if (lglmarked (lgl, lit) > 0) count++;
7473 lgl->stats->subl.tried++;
7475 LOGCLS (4, c, "only %d literals shared in clause", count);
7479 "subsuming learned scaled glue %d clause",
7480 (int)(lidx & GLUEMASK));
7481 LOGCLS (2, lgl->clause.start,
7482 "subsumed by new size %d scaled glue %d clause",
7483 size, lglscaleglue (lgl, glue));
7484 lgl->stats->subl.sub++;
7485 lglrmlcls (lgl, lidx, REDCS);
7489 static int lglana (LGL * lgl) {
7490 int open, resolved, tag, lit, uip, r0, r1, other, other2, * p, * q, lidx;
7491 int size, savedsize, resolventsize, level, red, glue, realglue;
7492 int jlevel, mlevel, nmlevel, origsize, redsize;
7493 int del, cl, c0, c1, sl, s0, s1;
7500 if (lgl->mt) return 0;
7501 if (lgl->failed) return 0;
7502 if (!lgl->conf.lit) return 1;
7504 if (lgl->opts->drup.val) lgldrupclsarg (lgl, 0);
7506 lglpicosatchkclsarg (lgl, 0);
7511 if (lgl->flipping) {
7512 assert (lgl->flipping > 0);
7513 if (lgl->flipping == 1) LOG (1, "switching off phase flipping");
7516 if (lgl->phaseneg) {
7517 assert (lgl->phaseneg > 0);
7518 if (lgl->phaseneg == 1) LOG (1, "switching off initial negative phase");
7521 lglstart (lgl, &lgl->times->ana);
7522 lgl->stats->confs++;
7524 assert (lgl->conf.lit);
7525 assert (lglmtstk (&lgl->seen));
7526 assert (lglmtstk (&lgl->clause));
7527 assert (lglmtstk (&lgl->resolvent));
7529 if (lgl->opts->check.val > 0) lglchkclnvar (lgl);
7532 lit = lgl->conf.lit, r0 = lgl->conf.rsn[0], r1 = lgl->conf.rsn[1];
7533 savedsize = resolved = 0;
7534 open += lglpull (lgl, lit);
7535 LOG (2, "starting analysis with reason of literal %d", lit);
7537 LOGREASON (2, lit, r0, r1, "analyzing");
7540 if (lglmaintainresolvent (lgl)) {
7541 LOG (2, "removing %d from resolvent", -lit);
7542 lglrmstk (&lgl->resolvent, -lit);
7543 LOGRESOLVENT (3, "resolvent after removing %d is", -lit);
7547 assert (lglevel (lgl, lit) == lgl->level);
7549 if (tag == BINCS || tag == TRNCS) {
7550 other = r0 >> RMSHFT;
7551 size = lglevel (lgl, other) ? 2 : 1;
7552 if (lglpull (lgl, other)) open++;
7554 if (lglevel (lgl, r1)) size++;
7555 if (lglpull (lgl, r1)) open++;
7558 assert (tag == LRGCS);
7560 p = lglidx2lits (lgl, red, r1);
7562 while ((other = *p++)) {
7563 if (lglevel (lgl, other)) size++;
7564 if (lglpull (lgl, other)) open++;
7566 if (red) lglbumplidx (lgl, r1);
7568 LOG (3, "open %d antecendents %d learned %d resolved %d",
7569 open-1, size, lglcntstk (&lgl->clause), lglcntstk (&lgl->resolvent));
7571 resolventsize = open + lglcntstk (&lgl->clause);
7573 LOGRESOLVENT (2, "resolvent");
7574 if (lglmaintainresolvent (lgl))
7575 assert (lglcntstk (&lgl->resolvent) == resolventsize);
7577 if (lgl->opts->otfs.val &&
7579 resolventsize > 1 &&
7580 (resolventsize < size || (resolved==2 && resolventsize<savedsize))) {
7582 c0 = lgl->conf.rsn[0];
7583 c1 = lgl->conf.rsn[1];
7584 assert (resolved >= 2);
7587 else if (resolventsize >= size) del = -lit, lit = cl, r0 = c0, r1 = c1;
7588 else if (resolventsize >= savedsize) ;
7591 sl = lit, s0 = r0, s1 = r1;
7592 del = -lit, lit = cl, r0 = c0, r1 = c1;
7593 } else sl = cl, s0 = c0, s1 = c1;
7594 lgldynsub (lgl, sl, s0, s1);
7596 lgldynstr (lgl, del, lit, r0, r1);
7597 lit = lgl->conf.lit;
7598 r0 = lgl->conf.rsn[0];
7599 r1 = lgl->conf.rsn[1];
7600 assert (lglevel (lgl, lit) == lgl->level);
7602 if (tag == UNITCS) {
7603 mlevel = lglevel (lgl, lit);
7606 } else if (tag == BINCS) {
7607 jlevel = lglevel (lgl, lit);
7608 other = r0 >> RMSHFT;
7609 mlevel = lglevel (lgl, other);
7610 if (jlevel > mlevel) { nmlevel = 1; SWAP (int, mlevel, jlevel); }
7611 else if (jlevel == mlevel) nmlevel = 2;
7612 else assert (jlevel < mlevel), nmlevel = 1;
7613 } else if (tag== TRNCS) {
7614 jlevel = lglevel (lgl, lit);
7615 other = r0 >> RMSHFT;
7616 level = lglevel (lgl, other);
7618 mlevel = lglevel (lgl, other2);
7619 if (jlevel > mlevel) SWAP (int, jlevel, mlevel);
7620 if (level > mlevel) SWAP (int, level, mlevel);
7621 if (level > jlevel) SWAP (int, level, jlevel);
7622 assert (mlevel >= jlevel);
7623 assert (jlevel >= level);
7624 if (mlevel == jlevel) nmlevel = 2 + (jlevel == level);
7625 else assert (mlevel > jlevel), nmlevel = 1;
7626 assert (nmlevel == 1 + (mlevel == jlevel) + (mlevel == level));
7628 mlevel = lglevel (lgl, lit), nmlevel = 1, jlevel = 0;
7629 assert (tag == LRGCS);
7631 p = lglidx2lits (lgl, red, r1);
7632 while (jlevel < lgl->level && (other = *p++)) {
7633 if (other == lit) continue;
7634 assert (other != -lit);
7635 level = lglevel (lgl, other);
7636 if (level < mlevel) {
7637 if (level > jlevel) jlevel = level;
7640 if (level == mlevel) nmlevel++;
7642 assert (level > mlevel);
7648 if (red) lglbumplidx (lgl, r1);
7651 LOG (2, "restarting analysis after on-the-fly strengthening");
7652 lgl->stats->otfs.restarting++;
7653 if (lgl->opts->otfsbump.val >= 1)
7654 lglbumpseenlits (lgl), lglbumpscinc (lgl);
7656 if (lgl->level > mlevel) lglbacktrack (lgl, mlevel);
7657 if (lgl->opts->otfsconf.val) lgl->stats->confs++;
7660 assert (nmlevel == 1);
7661 assert (mlevel > jlevel);
7662 assert (lglevel (lgl, lit) == mlevel);
7663 LOGREASON (2, lit, r0, r1,
7664 "driving %d at level %d through strengthened", lit, jlevel);
7665 lgl->stats->otfs.driving++;
7666 lglbacktrack (lgl, jlevel);
7667 if (tag == LRGCS && (r0 & REDCS) && (r1 & GLUEMASK) == MAXGLUE) {
7668 // Note, that 'lit' is unassigned by 'backtrack' above and thus if
7669 // it's reason is at the end of the MAXGLUE stack, then the reason
7670 // becomes invalid. See the corresponding 'assert' in 'lglassign'.
7671 // Our original incorrect fix to this problem was to simply increase
7672 // the size of the stack to point after the zero sentinel, which
7673 // however produces garbage on the MAXGLUE stack and thus we only
7674 // follow this idea if the reason of 'lit' is exactly after the
7675 // current end of the MAXGLUE stack. If it starts before the end
7676 // nothing has to be done. Otherwise we have to move the reason
7677 // literals and update the reason.
7678 p = lglidx2lits (lgl, REDCS, r1);
7679 if (p > lgl->red[MAXGLUE].top) {
7681 rsn = lglrsn (lgl, lit);
7682 r1 = lglcntstk (&lgl->red[MAXGLUE]);
7686 for (q = lgl->red[MAXGLUE].top; *p; p++) {
7691 lgl->red[MAXGLUE].top = q;
7692 } else if (p == lgl->red[MAXGLUE].top) {
7693 while (*p) { assert (*p < NOTALIT); p++; }
7694 if (++p > lgl->red[MAXGLUE].top) lgl->red[MAXGLUE].top = p;
7697 lglassign (lgl, lit, r0, r1);
7698 if (lgl->opts->otfsbump.val >= 2)
7699 lglbumpseenlits (lgl), lglbumpscinc (lgl);
7704 while (!lglmarked (lgl, lit = lglpopstk (&lgl->trail))) {
7705 if (lgl->opts->bumpbcplits.val) lglbumplit (lgl, lit);
7706 lglunassign (lgl, lit);
7708 lglunassign (lgl, lit);
7709 if (!--open) { uip = -lit; break; }
7710 LOG (2, "analyzing reason of literal %d next", lit);
7711 rsn = lglrsn (lgl, lit);
7712 r0 = rsn[0], r1 = rsn[1];
7715 LOG (2, "adding UIP %d at same level %d to 1st UIP clause",
7717 lglpushstk (lgl, &lgl->clause, uip);
7718 assert (lglmarked (lgl, uip));
7720 LOGRESOLVENT (3, "final resolvent before flushing fixed literals");
7721 if (lglmaintainresolvent (lgl)) {
7722 int * q = lgl->resolvent.start;
7723 for (p = q; p < lgl->resolvent.top; p++)
7724 if (lglevel (lgl, (other = *p)))
7726 lgl->resolvent.top = q;
7727 LOGRESOLVENT (2, "final resolvent after flushing fixed literals");
7728 assert (lglcntstk (&lgl->resolvent) == lglcntstk (&lgl->clause));
7729 for (p = lgl->clause.start; p < lgl->clause.top; p++)
7730 assert (lglavar (lgl, *p)->mark > 0);
7731 for (p = lgl->resolvent.start; p < lgl->resolvent.top; p++) {
7732 av = lglavar (lgl, *p); assert (av->mark > 0); av->mark = -av->mark;
7734 for (p = lgl->clause.start; p < lgl->clause.top; p++)
7735 assert (lglavar (lgl, *p)->mark < 0);
7736 for (p = lgl->resolvent.start; p < lgl->resolvent.top; p++) {
7737 av = lglavar (lgl, *p); assert (av->mark < 0); av->mark = -av->mark;
7739 lglclnstk (&lgl->resolvent);
7742 lglpushstk (lgl, &lgl->clause, 0);
7743 LOGCLS (2, lgl->clause.start, "1st UIP clause");
7744 if (lgl->opts->drup.val) lgldrupcls (lgl);
7746 lglpicosatchkcls (lgl);
7749 mlevel = lgl->level;
7750 jlevel = glue = realglue = 0;
7751 for (p = lgl->frames.start; p < lgl->frames.top; p++) {
7753 assert (0 < level && level < lgl->level);
7754 if (level < mlevel) mlevel = level;
7755 if (level > jlevel) jlevel = level;
7756 if (level >= lgl->alevel) realglue++;
7759 assert (realglue <= glue);
7760 assert (glue == lglcntstk (&lgl->frames));
7761 LOG (2, "jump level %d", jlevel);
7762 LOG (2, "minimum level %d", mlevel);
7763 LOG (2, "glue %d covers %.0f%%", glue,
7764 (float)(jlevel ? lglpcnt (glue, (jlevel - mlevel) + 1) : 100.0));
7766 if (lglrsn (lgl, uip)[0]) lgl->stats->uips++;
7767 else if (jlevel + 1 == lgl->level) lgl->stats->decflipped++;
7769 origsize = lglcntstk (&lgl->clause) - 1;
7770 assert (glue + 1 <= origsize);
7771 if (origsize >= lgl->opts->bumpseenminsize.val &&
7772 lgl->opts->bumpseenbeforemin.val) lglbumpseenlits (lgl);
7773 lgl->stats->lits.nonmin += origsize;
7774 redsize = jlevel + 1;
7775 if (origsize == 2) {
7776 lgl->stats->mincls.bin++;
7777 LOGCLS (2, lgl->clause.start, "binary 1st UIP clause not minimized");
7778 } else if (glue + 1 == origsize) {
7779 lgl->stats->mincls.size++;
7780 LOGCLS (2, lgl->clause.start,
7781 "size %d 1st UIP clause with glue %d can not minimized",
7783 } else if (jlevel > 1 &&
7784 lgl->opts->deco.val &&
7785 redsize < 2*origsize/3 &&
7786 glue > lgl->opts->decolim.val) {
7787 assert (origsize > 2);
7788 lgl->stats->mincls.deco++;
7789 lgl->stats->deco.sum.orig += origsize;
7790 lglclnstk (&lgl->clause);
7791 lgldeco (lgl, jlevel);
7792 glue = lglcntstk (&lgl->clause);
7793 lglpushstk (lgl, &lgl->clause, uip);
7794 lgl->stats->deco.sum.red += lglcntstk (&lgl->clause);
7795 lglpushstk (lgl, &lgl->clause, 0);
7796 LOGCLS (2, lgl->clause.start,
7797 "size %d 1st UIP clause discarded for size %d decision-only clause",
7800 lgl->stats->mincls.min++;
7801 lglmincls (lgl, uip, glue);
7804 if (origsize >= lgl->opts->bumpseenminsize.val &&
7805 lgl->opts->bumpseenaftermin.val) lglbumpseenlits (lgl);
7806 if (origsize < lgl->opts->bumpseenminsize.val ||
7807 lgl->opts->bumpclslits.val) lglbumpclslits (lgl);
7810 lglbacktrack (lgl, jlevel);
7812 len = lglcntstk (&lgl->clause) - 1;
7813 lgl->stats->clauses.glue += glue;
7814 lgl->stats->clauses.realglue += realglue;
7815 lgl->stats->lits.learned += len;
7816 lgl->stats->clauses.learned++;
7817 lgl->stats->glues.count++;
7818 lgl->stats->glues.sum += glue;
7819 if (lgl->opts->drup.val) lgldrupcls (lgl);
7821 lglpicosatchkcls (lgl);
7823 lgldrupligaddcls (lgl, REDCS);
7824 lidx = lgladdcls (lgl, REDCS, realglue, 1);
7826 if (lgl->opts->subl.val) {
7827 lgl->stats->subl.count++;
7828 lglpopnunmarkstk (lgl, &lgl->seen);
7829 size = lglcntstk (&lgl->clause) - 1;
7832 p = lgl->clause.start;
7833 while ((lit = *p++)) {
7834 sig |= (1u << (lglulit (lit) & 31));
7837 q = lgl->learned.start;
7838 for (p = q; p < lgl->learned.top; p += 3) {
7839 int olidx = p[0], osize = p[1];
7840 unsigned osig = (unsigned) p[2];
7841 if (olidx < 0) continue;
7842 if (osize <= size ||
7844 !lglsubl (lgl, olidx, size, glue))
7845 *q++ = olidx, *q++ = osize, *q++ = (int) osig;
7847 lgl->learned.top = q;
7848 if (lidx && (lidx & GLUEMASK) < MAXGLUE) {
7849 lgl->stats->subl.cands++;
7850 lglpushstk (lgl, &lgl->learned, lidx);
7851 lglpushstk (lgl, &lgl->learned, size);
7852 lglpushstk (lgl, &lgl->learned, (int) sig);
7853 if (lglcntstk (&lgl->learned) / 3 > lgl->opts->subl.val) {
7854 q = lgl->learned.start;
7855 for (p = q + 3; p < lgl->learned.top; p++) *q++ = *p;
7856 lgl->learned.top = q;
7859 p = lgl->clause.start;
7860 while ((lit = *p++)) lglunmark (lgl, lit);
7865 lgl->cbs->cls.produce.fun &&
7866 glue <= lgl->opts->synclsglue.val &&
7867 lglcntstk (&lgl->clause) - 1 <= lgl->opts->synclslen.val) {
7868 assert (lglmtstk (&lgl->eclause));
7869 for (p = lgl->clause.start; *p; p++)
7870 lglpushstk (lgl, &lgl->eclause, lglexport (lgl, *p));
7871 lglpushstk (lgl, &lgl->eclause, 0);
7872 LOGCLS (SCL, lgl->eclause.start,
7873 "exporting external redundant glue %d length %d clause",
7874 glue, lglcntstk (&lgl->clause) -1);
7875 lgl->stats->sync.cls.produced++;
7876 lgl->cbs->cls.produce.fun (lgl->cbs->cls.produce.state,
7877 lgl->eclause.start, glue);
7878 lglclnstk (&lgl->eclause);
7885 cpi = lgl->stats->confs / (1 + lgl->stats->iterations);
7888 if ((delay = lgl->opts->binsimpdel.val)) {
7889 if (cpi/2 < (int64_t) delay) delay = (int) cpi/2;
7890 lgl->limits->simp.confs += delay;
7892 if ((delay = lgl->opts->binlocsdel.val)) {
7893 if (cpi/2 < (int64_t) delay) delay = (int) cpi/2;
7894 lgl->limits->locs.confs += delay;
7896 lglrep (lgl, 2, 'b');
7900 if ((delay = lgl->opts->itsimpdel.val)) {
7901 if (cpi/2 < (int64_t) delay) delay = (int) cpi/2;
7902 lgl->limits->simp.confs += delay;
7904 if ((delay = lgl->opts->itlocsdel.val)) {
7905 if (cpi/2 < (int64_t) delay) delay = (int) cpi/2;
7906 lgl->limits->locs.confs += delay;
7908 lgl->stats->iterations++;
7909 lglrep (lgl, 1, 'i');
7919 static int lglscalerestartint (LGL * lgl, int delta) {
7920 int64_t res = delta;
7921 if (lgl->opts->restartintscale.val > 0) {
7922 res *= lgl->stats->decisions + 1;
7923 res /= lgl->stats->confs + 1;
7924 } else if (lgl->opts->restartintscale.val < 0) {
7925 res *= lgl->stats->confs + 1;
7926 res /= lgl->stats->decisions + 1;
7928 if (res <= 1) res = 1;
7929 lgl->stats->restarts.intsum.orig += delta;
7930 lgl->stats->restarts.intsum.scaled += res;
7934 static void lglincrestartlfixed (LGL * lgl) {
7935 int delta = lgl->opts->restartint.val;
7936 delta = lglscalerestartint (lgl, delta);
7937 lgl->limits->restart.confs = lgl->stats->confs + delta;
7938 lglrep (lgl, 1, 'R');
7941 static void lglincrestartaux (LGL * lgl, int skip) {
7942 int delta = lgl->opts->restartint.val, count;
7943 if (lgl->opts->restart.val == 2) {
7944 count = ++lgl->limits->restart.luby;
7945 delta *= lgluby (lgl, count);
7947 assert (lgl->opts->restart.val == 3);
7948 count = ++lgl->limits->restart.inout;
7949 delta *= lglinout (lgl, count, lgl->opts->rstinoutinc.val);
7951 delta = lglscalerestartint (lgl, delta);
7952 lgl->limits->restart.confs = lgl->stats->confs + delta;
7953 if (lgl->limits->restart.wasmaxdelta)
7954 lglrep (lgl, 1 + skip, skip ? 'N' : 'R');
7955 else lglrep (lgl, 2, skip ? 'n' : 'r');
7956 if (delta > lgl->limits->restart.maxdelta) {
7957 lgl->limits->restart.wasmaxdelta = 1;
7958 lgl->limits->restart.maxdelta = delta;
7959 } else lgl->limits->restart.wasmaxdelta = 0;
7962 static void lglincrestartl (LGL * lgl, int skip) {
7963 switch (lgl->opts->restart.val) {
7964 case 1: lglincrestartlfixed (lgl); break;
7965 case 2: case 3: lglincrestartaux (lgl, skip); break;
7970 static int lglnextdecision (LGL * lgl) {
7972 if (!lgl->unassigned) return 0;
7973 lglstart (lgl, &lgl->times->dec);
7974 while (!res && !lglmtstk (&lgl->dsched)) {
7975 int next = lgltopdsched (lgl);
7976 if (!lglval (lgl, next) && lglisfree (lgl, next)) res = next;
7977 else lglpopdsched (lgl);
7979 LOG (2, "next decision would be %d", res);
7984 static int lglreusetrail (LGL * lgl) {
7985 int next = 0, res = 0, prev, level;
7987 assert (lgl->opts->reusetrail.val);
7988 if (lgl->flipping) {
7991 "[reuse-trail] no reuse after forced termination of flipping");
7994 if (!(next = lglnextdecision (lgl))) return 0;
7995 for (p = lgl->control.start + 1; p < lgl->control.top; p++) {
7997 assert (lgldecision (lgl, prev));
7998 if (!lglassumption (lgl, prev) && lgldcmp (lgl, prev, next) < 0) break;
7999 level = lglevel (lgl, prev);
8000 assert (level == p - lgl->control.start);
8001 assert (res + 1 == level);
8006 "[reuse-trail] reusing level %d from current level %d", res, lgl->level);
8008 lglprt (lgl, 2, "[reuse-trail] can not reuse any level");
8012 static void lglrestart (LGL * lgl) {
8015 assert (lgl->opts->restart.val);
8016 lglstart (lgl, &lgl->times->rsts);
8018 lgl->stats->restarts.skipped.agile++, skip = 1;
8019 else if (lglsaturating (lgl))
8020 lgl->stats->restarts.skipped.saturating++, skip = 1;
8023 lgl->stats->restarts.skipped.count++;
8024 LOG (1, "skipping restart with agility %.0f%%", lglagility (lgl));
8026 LOG (1, "restarting with agility %.0f%% not saturating",
8028 if (!lgl->opts->reusetrail.val ||
8029 lgl->opts->restart.val <= 1 ||
8030 lgl->opts->phasegluebit.val) level = 0;
8031 else level = lglreusetrail (lgl);
8032 if (level < lgl->alevel) level = lgl->alevel;
8033 else if (level > lgl->alevel) {
8034 kept = (100*level) / lgl->level;
8035 lgl->stats->restarts.kept.sum += kept;
8036 lgl->stats->restarts.kept.count++;
8038 if (level < lgl->level) {
8039 lglbacktrack (lgl, level);
8040 lgl->stats->restarts.count++;
8042 lgl->stats->restarts.skipped.count++;
8043 lgl->stats->restarts.skipped.reuse++;
8046 lglincrestartl (lgl, skip);
8050 static void lgldefrag (LGL * lgl) {
8051 int * wchs, nwchs, i, idx, bit, ldsize, size, offset, * start, * q, * end;
8052 const int * p, * eow, * w;
8054 lglstart (lgl, &lgl->times->dfg);
8055 lgl->stats->defrags++;
8056 nwchs = lglcntstk (&lgl->wchs->stk);
8058 memcpy (wchs, lgl->wchs->stk.start, nwchs * sizeof *wchs);
8059 for (i = 0; i < MAXLDFW; i++) lgl->wchs->start[i] = INT_MAX;
8060 lgl->wchs->free = 0;
8061 start = lgl->wchs->stk.start;
8062 assert (nwchs >= 1);
8063 assert (start[0] == INT_MAX);
8065 for (idx = 2; idx < lgl->nvars; idx++)
8066 for (bit = 0; bit <= 1; bit++) {
8067 hts = lgl->dvars[idx].hts + bit;
8068 if (!hts->offset) { assert (!hts->count); continue; }
8069 ldsize = lglceilld (hts->count);
8070 size = (1 << ldsize);
8071 assert (size >= hts->count);
8072 w = wchs + hts->offset;
8073 hts->offset = offset;
8074 eow = w + hts->count;
8076 for (p = w; p < eow; p++) *q++ = *p;
8078 end = start + offset;
8079 while (q < end) *q++ = 0;
8084 assert (q <= lgl->wchs->stk.top);
8085 lgl->wchs->stk.top = q;
8086 lglfitstk (lgl, &lgl->wchs->stk);
8087 lgl->limits->dfg = lgl->stats->pshwchs + lgl->opts->defragint.val;
8088 lglrep (lgl, 2, 'F');
8092 static void lgldis (LGL * lgl) {
8093 int blit, nblit, tag, red, * p, * q, * eow, * w;
8094 int idx, sign, lit, other, other2;
8098 assert (!lgl->level);
8099 CLR (bins); CLR (trns);
8100 for (idx = 2; idx < lgl->nvars; idx++)
8101 for (sign = -1; sign <= 1; sign += 2) {
8103 hts = lglhts (lgl, lit);
8104 if (!hts->offset) continue;
8105 val = lglval (lgl, lit);
8106 assert (hts->count > 0);
8107 if (val || lgliselim (lgl, lit))
8108 { lglshrinkhts (lgl, hts, 0); continue; }
8109 assert (lglisfree (lgl, lit));
8110 assert (lglmtstk (&bins));
8111 assert (lglmtstk (&trns));
8112 w = lglhts2wchs (lgl, hts);
8113 eow = w + hts->count;
8114 for (p = w; p < eow; p++) {
8116 tag = blit & MASKCS;
8118 if (tag == OCCS) continue;
8119 if (tag == TRNCS || tag == LRGCS) p++;
8120 if (tag == LRGCS) continue;
8121 other = blit >> RMSHFT;
8122 val = lglval (lgl, other);
8123 if (val > 0) continue;
8124 if (lgliselim (lgl, other)) continue;
8127 lglpushstk (lgl, &bins, blit);
8130 assert (tag == TRNCS);
8132 val2 = lglval (lgl, other2);
8133 if (val2 > 0) continue;
8134 if (lgliselim (lgl, other2)) continue;
8136 assert (val < 0 && !val2);
8137 nblit = red | (other2<<RMSHFT) | BINCS;
8138 lglpushstk (lgl, &bins, nblit);
8142 assert (!val && val2 < 0);
8143 nblit = red | (other<<RMSHFT) | BINCS;
8144 lglpushstk (lgl, &bins, nblit);
8147 assert (!val && !val2);
8148 lglpushstk (lgl, &trns, blit);
8149 lglpushstk (lgl, &trns, other2);
8152 for (p = bins.start; p != bins.top; p++) *q++ = *p;
8153 for (p = trns.start; p != trns.top; p++) *q++ = *p;
8154 lglshrinkhts (lgl, hts, q - w);
8158 lglrelstk (lgl, &bins);
8159 lglrelstk (lgl, &trns);
8160 lglrelstk (lgl, &lgl->learned);
8163 static int lglcmphase (LGL * lgl, int a, int b) {
8164 return lgliphase (lgl, b) - lgliphase (lgl, a);
8167 #define LGLCMPHASE(A,B) lglcmphase (lgl, *(A), *(B))
8169 static void lglconnaux (LGL * lgl, int glue) {
8170 int lit, satisfied, lidx, size, red, act;
8171 const int * p, * c, * start, * top;
8176 assert (glue < MAXGLUE);
8178 stk = lgl->red + glue;
8179 } else red = 0, stk = &lgl->irr;
8180 c = start = q = stk->start;
8184 if (act == REMOVED) {
8185 for (p = c + 1; p < top && *p == REMOVED; p++)
8187 assert (p >= top || *p < NOTALIT || lglisact (*p));
8191 if (lglisact (act)) *q++ = *c++; else act = -1;
8195 while (assert (p < top), (lit = *p++)) {
8196 assert (lit < NOTALIT);
8197 if (satisfied) continue;
8198 val = lglval (lgl, lit);
8199 if (lgliselim (lgl, lit)) {
8200 assert (lgl->eliminating || lgl->blocking);
8202 } else if (val > 0) satisfied = 1;
8203 else if (!val) *q++ = lit;
8205 if (satisfied || p == c + 1) {
8207 } else if (!(size = q - d)) {
8210 LOG (1, "empty clause during connection garbage collection phase");
8213 } else if (size == 1) {
8215 LOG (1, "unit during garbage collection");
8216 lglunit (lgl, d[0]);
8217 } else if (size == 2) {
8219 lglwchbin (lgl, d[0], d[1], red);
8220 lglwchbin (lgl, d[1], d[0], red);
8221 } else if (size == 3) {
8223 lglwchtrn (lgl, d[0], d[1], d[2], red);
8224 lglwchtrn (lgl, d[1], d[0], d[2], red);
8225 lglwchtrn (lgl, d[2], d[0], d[1], red);
8228 if (lgl->opts->sortlits.val) SORT (int, d, size, LGLCMPHASE);
8232 assert (lidx <= MAXREDLIDX);
8237 (void) lglwchlrg (lgl, d[0], d[1], red, lidx);
8238 (void) lglwchlrg (lgl, d[1], d[0], red, lidx);
8245 static void lglfullyconnected (LGL * lgl) {
8246 if (!lgl->notfullyconnected) return;
8247 LOG (1, "switching to fully connected mode");
8248 lgl->notfullyconnected = 0;
8251 static void lglcon (LGL * lgl) {
8253 for (glue = -1; glue < MAXGLUE; glue++) lglconnaux (lgl, glue);
8254 lglfullyconnected (lgl);
8257 static void lglcount (LGL * lgl) {
8258 int idx, sign, lit, tag, blit, red, other, other2, glue, count;
8259 const int * p, * w, * c, * eow;
8262 lgl->stats->irr.clauses.cur = 0;
8263 lgl->stats->irr.lits.cur = 0;
8264 lgl->stats->red.bin = 0;
8265 lgl->stats->red.trn = 0;
8266 lgl->stats->red.lrg = 0;
8267 for (idx = 2; idx < lgl->nvars; idx++)
8268 for (sign = -1; sign <= 1; sign += 2) {
8270 hts = lglhts (lgl, lit);
8271 if (!hts->offset) continue;
8272 w = lglhts2wchs (lgl, hts);
8273 eow = w + hts->count;
8274 for (p = w; p < eow; p++) {
8277 tag = blit & MASKCS;
8278 if (tag == LRGCS || tag == TRNCS) p++;
8279 if (tag == LRGCS) continue;
8280 assert (tag == BINCS || tag == TRNCS);
8281 other = blit >> RMSHFT;
8282 assert (abs (other) != abs (lit));
8283 if (abs (lit) >= abs (other)) continue;
8284 assert (2 == BINCS && 3 == TRNCS);
8287 assert (abs (other2) != abs (lit));
8288 assert (abs (other2) != abs (other));
8289 if (abs (lit) >= abs (other2)) continue;
8292 lgl->stats->irr.clauses.cur++;
8293 if (tag == BINCS) lgl->stats->irr.lits.cur += 2;
8294 else assert (tag == TRNCS), lgl->stats->irr.lits.cur += 3;
8295 } else if (tag == BINCS) lgl->stats->red.bin++;
8296 else assert (tag == TRNCS), lgl->stats->red.trn++;
8299 assert (lgl->stats->red.bin >= 0 && lgl->stats->red.trn >= 0);
8300 for (c = lgl->irr.start; c < lgl->irr.top; c = p + 1) {
8301 if (*(p = c) >= REMOVED) continue;
8303 lgl->stats->irr.lits.cur += p - c;
8304 lgl->stats->irr.clauses.cur++;
8306 LOG (1, "counted %d irredundant clauses with %d literals",
8307 lgl->stats->irr.clauses.cur, lgl->stats->irr.lits.cur);
8308 for (glue = 0; glue < MAXGLUE; glue++) {
8309 lir = lgl->red + glue;
8311 for (c = lir->start; c < lir->top; c++)
8314 LOG (1, "counted %d redundant clauses with glue %d", count, glue);
8315 lgl->stats->red.lrg += count;
8316 lgl->stats->lir[glue].clauses = count;
8318 assert (lgl->stats->red.lrg >= 0);
8319 if (lgl->stats->red.bin)
8320 LOG (1, "counted %d binary redundant clauses altogether",
8321 lgl->stats->red.bin);
8322 if (lgl->stats->red.trn)
8323 LOG (1, "counted %d ternary redundant clauses altogether",
8324 lgl->stats->red.trn);
8325 if (lgl->stats->red.lrg)
8326 LOG (1, "counted %d large redundant clauses altogether",
8327 lgl->stats->red.lrg);
8330 static int lglilit (int ulit) {
8333 if (ulit & 1) res = -res;
8337 static void lgljwh (LGL * lgl) {
8338 int idx, sign, lit, tag, blit, other, other2, red, size, glue;
8339 const int *p, * w, * eow, * c;
8344 CLN (lgl->jwh, 2*lgl->nvars);
8345 for (idx = 2; idx < lgl->nvars; idx++)
8346 for (sign = -1; sign <= 1; sign += 2) {
8348 val = lglval (lgl, lit);
8349 if (val > 0) continue;
8350 hts = lglhts (lgl, lit);
8351 if (!hts->offset) continue;
8352 w = lglhts2wchs (lgl, hts);
8353 eow = w + hts->count;
8354 for (p = w; p < eow; p++) {
8356 tag = blit & MASKCS;
8357 if (tag == TRNCS || tag == LRGCS) p++;
8358 if (tag == LRGCS) continue;
8360 if (!lgl->opts->jwhred.val && red) continue;
8361 other = blit >> RMSHFT;
8362 if (abs (other) < abs (lit)) continue;
8363 tmp = lglval (lgl, other);
8364 if (tmp > 0) continue;
8367 inc = lglflt (-2, 1);
8368 lglincjwh (lgl, lit, inc);
8369 lglincjwh (lgl, other, inc);
8371 assert (tag == TRNCS);
8373 if (abs (other2) < abs (lit)) continue;
8374 tmp2 = lglval (lgl, other2);
8375 if (tmp2 > 0) continue;
8376 assert ((val > 0) + (tmp > 0) + (tmp2 > 0) == 0);
8377 assert ((val < 0) + (tmp < 0) + (tmp2 < 0) <= 1);
8378 size = 3 + val + tmp + tmp2;
8379 assert (2 <= size && size <= 3);
8380 inc = lglflt (-size, 1);
8381 if (!val) lglincjwh (lgl, lit, inc);
8382 if (!tmp) lglincjwh (lgl, other, inc);
8383 if (!tmp2) lglincjwh (lgl, other2, inc);
8387 for (glue = -1; glue < MAXGLUE; glue++) {
8388 if (glue < 0) s = &lgl->irr;
8389 else if (!lgl->opts->jwhred.val) continue;
8390 else s = &lgl->red[glue];
8391 for (c = s->start; c < s->top; c = p + 1) {
8393 if (*p >= NOTALIT) continue;
8396 while ((other = *p)) {
8397 tmp = lglval (lgl, other);
8398 if (tmp > val) val = tmp;
8402 if (val > 0) continue;
8403 inc = lglflt (-size, 1);
8404 for (p = c; (other = *p); p++)
8405 if (!lglval (lgl, other))
8406 lglincjwh (lgl, other, inc);
8411 static int * lglis (LGL * lgl) {
8412 int idx, sign, lit, tag, blit, other, other2, red, * res;
8413 const int *p, * w, * eow, * c;
8417 NEW (res, 2*lgl->nvars);
8419 for (idx = 2; idx < lgl->nvars; idx++)
8420 for (sign = -1; sign <= 1; sign += 2) {
8422 val = lglval (lgl, lit);
8423 if (val > 0) continue;
8424 hts = lglhts (lgl, lit);
8425 if (!hts->offset) continue;
8426 w = lglhts2wchs (lgl, hts);
8427 eow = w + hts->count;
8428 for (p = w; p < eow; p++) {
8430 tag = blit & MASKCS;
8431 if (tag == TRNCS || tag == LRGCS) p++;
8432 if (tag == LRGCS) continue;
8435 other = blit >> RMSHFT;
8436 if (abs (other) < abs (lit)) continue;
8437 tmp = lglval (lgl, other);
8438 if (tmp > 0) continue;
8444 assert (tag == TRNCS);
8446 if (abs (other2) < abs (lit)) continue;
8447 tmp2 = lglval (lgl, other2);
8448 if (tmp2 > 0) continue;
8449 assert ((val > 0) + (tmp > 0) + (tmp2 > 0) == 0);
8450 assert ((val < 0) + (tmp < 0) + (tmp2 < 0) <= 1);
8451 if (!val) res[lit]++;
8452 if (!tmp) res[other]++;
8453 if (!tmp2) res[other2]++;
8458 for (c = s->start; c < s->top; c = p + 1) {
8460 if (*p >= NOTALIT) continue;
8462 while ((other = *p)) {
8463 tmp = lglval (lgl, other);
8464 if (tmp > val) val = tmp;
8467 if (val > 0) continue;
8468 for (p = c; (other = *p); p++)
8469 if (!lglval (lgl, other))
8475 static int lglsetjwhbias (LGL * lgl, int idx) {
8476 AVar * av = lglavar (lgl, idx);
8480 pos = lgl->jwh[lglulit (idx)];
8481 neg = lgl->jwh[lglulit (-idx)];
8482 if (av->phase) return av->phase;
8483 if (lgl->opts->phaseflip.val) SWAP (int, pos, neg);
8484 bias = (pos > neg) ? 1 : -1;
8485 if (av->bias == bias) return bias;
8487 lgl->stats->phase.set++;
8488 if (bias > 0) lgl->stats->phase.pos++; else lgl->stats->phase.neg++;
8489 LOG (1, "JW bias %d (pos %s, neg %s)",
8490 bias * idx, lglflt2str (lgl, pos), lglflt2str (lgl, neg));
8494 static void lglsetallphases (LGL * lgl) {
8496 for (idx = 2; res && idx < lgl->nvars; idx++)
8497 res = (!lglisfree (lgl, idx) || lglavar (lgl, idx)->phase);
8498 lgl->allphaseset = res;
8501 static void lglflushphasesaux (LGL * lgl, int full) {
8502 int idx, flushed = 0;
8504 for (idx = 2; idx < lgl->nvars; idx++) {
8505 if (!lglisfree (lgl, idx)) continue;
8506 av = lglavar (lgl, idx);
8507 if (!full && av->phase) continue;
8512 "[flushphases] %d phases reset%s",
8513 flushed, (full ? " fully" : ""));
8514 lgl->allphaseset = !flushed;
8515 lgl->flushphases = 0;
8518 static void lglflushphases (LGL * lgl) {
8519 int full = (lgl->opts->rephase.val >= 2);
8520 lglflushphasesaux (lgl, full);
8523 static void lglphase (LGL * lgl) {
8524 int64_t set = lgl->stats->phase.set;
8525 int64_t pos = lgl->stats->phase.pos;
8526 int64_t neg = lgl->stats->phase.neg;
8528 lglstart (lgl, &lgl->times->phs);
8529 if (lgl->flushphases) lglflushphases (lgl);
8530 if (lgl->opts->phase.val) goto DONE;
8531 lglsetallphases (lgl);
8532 if (lgl->allphaseset) goto DONE;
8533 lgl->stats->phase.count++;
8535 for (idx = 2; idx < lgl->nvars; idx++) lglsetjwhbias (lgl, idx);
8536 set = lgl->stats->phase.set - set;
8537 pos = lgl->stats->phase.pos - pos;
8538 neg = lgl->stats->phase.neg - neg;
8540 "[phase-%d] phase bias: %lld positive %.0f%%, %lld negative %.0f%%",
8541 lgl->stats->phase.count,
8542 (LGLL) pos, lglpcnt (pos, set),
8543 (LGLL) neg, lglpcnt (neg, set));
8548 static int lglrephasing (LGL * lgl) {
8549 if (!lgl->opts->rephase.val) return 0;
8550 if (lgl->stats->confs < lgl->limits->rephase.confs) return 0;
8554 static void lglrephase (LGL * lgl) {
8555 lgl->stats->rephase.count++;
8556 lgl->stats->rephase.inc *= 2;
8557 lgl->limits->rephase.confs = lgl->stats->confs + lgl->stats->rephase.inc;
8559 "[rephase-%d] after %lld conflicts (new increment %d, next %lld)",
8560 lgl->stats->rephase.count, (LGLL) lgl->stats->confs,
8561 lgl->stats->rephase.inc, (LGLL) lgl->limits->rephase.confs);
8562 lglflushphases (lgl);
8565 static void lglchkbcpclean (LGL * lgl, const char * where) {
8566 ASSERT (lgl->next2 == lgl->next && lgl->next == lglcntstk (&lgl->trail));
8567 ASSERT (!lgl->conf.lit);
8571 static void lglcutwidth (LGL * lgl) {
8572 int lidx, res, l4, r4, b4, l10, r10, b10, m, oldbias;
8573 int idx, sign, lit, blit, tag, red, other, other2;
8574 const int * p, * w, * eow, * c, * q;
8575 int * widths, max, cut, min4, min10;
8578 if (lgl->nvars <= 2) return;
8579 lgl->stats->cutwidths++;
8580 lglstart (lgl, &lgl->times->ctw);
8581 oldbias = lgl->bias;
8582 assert (abs (oldbias) <= 1);
8583 if (abs (lgl->opts->bias.val) <= 1) {
8584 lgl->bias = lgl->opts->bias.val;
8587 min4 = min10 = INT_MAX;
8588 sum = max = cut = 0;
8589 NEW (widths, lgl->nvars);
8590 l4 = 2 + (lgl->nvars - 2 + 3)/4;
8591 r4 = 2 + (3*(lgl->nvars - 2)+3)/4;
8592 assert (2 <= l4 && l4 <= r4 && r4 <= lgl->nvars);
8593 l10 = 2 + (lgl->nvars - 2 + 9)/10;
8594 r10 = 2 + (9*(lgl->nvars - 2)+9)/10;
8595 assert (2 <= l10 && l10 <= r10 && r10 <= lgl->nvars);
8597 for (idx = 2; idx < lgl->nvars; idx++) {
8598 for (sign = -1; sign <= 1; sign += 2) {
8600 hts = lglhts (lgl, lit);
8601 w = lglhts2wchs (lgl, hts);
8602 eow = w + hts->count;
8603 for (p = w; p < eow; p++) {
8606 tag = blit & MASKCS;
8607 other = abs (blit >> RMSHFT);
8610 if (other > idx) widths[other]++, cut++;
8611 } else if (tag == TRNCS) {
8612 other2 = abs (*++p);
8614 if (other > idx) widths[other]++, cut++;
8615 if (other2 > idx) widths[other2]++, cut++;
8617 assert (tag == LRGCS);
8620 c = lglidx2lits (lgl, 0, lidx);
8621 for (q = c; (other = abs (*q)); q++) {
8622 if (other == idx) continue;
8623 if (other > idx) widths[other]++, cut++;
8628 assert (0 <= cut && 0 <= widths[idx]);
8631 if (cut > max) max = cut;
8632 if (l4 <= idx && idx <= r4 && cut < min4) b4 = idx, min4 = cut;
8633 if (l10 <= idx && idx <= r10 && cut < min10) b10 = idx, min10 = cut;
8637 DEL (widths, lgl->nvars);
8638 assert (lgl->nvars > 0);
8639 avg = sum / (LGLL) lgl->nvars;
8640 assert (avg <= INT_MAX);
8643 "[cut-width] %d, max %d, min4 %d at %.0f%%, min10 %d at %.0f%%",
8645 min4, lglpcnt ((b4 - 2), lgl->nvars - 2),
8646 min10, lglpcnt ((b10 - 2), lgl->nvars - 2));
8647 m = (lgl->nvars + 2)/2;
8648 if (b4 < m && b10 < m) lgl->bias = -1;
8649 if (b4 > m && b10 > m) lgl->bias = 1;
8650 lglprt (lgl, 1, "[cut-width] cut-width based bias %d", lgl->bias);
8652 lgldreschedule (lgl);
8653 assert (abs (lgl->bias <= 1));
8654 lglprt (lgl, 1, "[decision-order] bias %d, old %d", lgl->bias, oldbias);
8658 static int lglmaplit (int * map, int lit) {
8659 return map [ abs (lit) ] * lglsgn (lit);
8662 static void lglmapstk (LGL * lgl, int * map, Stk * lits) {
8665 for (p = lits->start; p < eol; p++)
8666 *p = lglmaplit (map, *p);
8669 static void lglmapglue (LGL * lgl, int * map, Stk * lits) {
8672 for (p = lits->start; p < eol; p++)
8673 if (!lglisact (*p)) *p = lglmaplit (map, *p);
8676 static void lglmaplits (LGL * lgl, int * map) {
8678 lglmapstk (lgl, map, &lgl->irr);
8679 for (glue = 0; glue < MAXGLUE; glue++)
8680 lglmapglue (lgl, map, &lgl->red[glue]);
8683 static void lglmapvars (LGL * lgl, int * map, int nvars) {
8684 int i, oldnvars = lgl->nvars, sign, udst, idst, usrc, isrc;
8692 if (nvars > 2) assert (nvars <= oldnvars);
8695 DEL (lgl->doms, 2*lgl->szvars);
8696 NEW (lgl->doms, 2*nvars);
8699 for (i = 2; i < oldnvars; i++)
8700 if (lglisfree (lgl, i))
8701 vals[map[i]] = lgl->vals[i];
8702 DEL (lgl->vals, lgl->szvars);
8706 for (i = 2; i < oldnvars; i++)
8707 if (lglisfree (lgl, i))
8708 i2e[map[i]] = lgl->i2e[i];
8709 DEL (lgl->i2e, lgl->szvars);
8713 for (i = 2; i < oldnvars; i++)
8714 if (lglisfree (lgl, i))
8715 dvars[map[i]] = lgl->dvars[i];
8716 DEL (lgl->dvars, lgl->szvars);
8720 for (i = 2; i < oldnvars; i++)
8721 if (lglisfree (lgl, i))
8722 qvars[map[i]] = lgl->qvars[i];
8723 DEL (lgl->qvars, lgl->szvars);
8727 for (i = 2; i < oldnvars; i++)
8728 if (lglisfree (lgl, i))
8729 for (sign = -1; sign <= 1; sign += 2) {
8731 idst = sign * map[i];
8732 usrc = lglulit (isrc);
8733 udst = lglulit (idst);
8734 jwh[udst] = lgladdflt (jwh[udst], lgl->jwh[usrc]);
8736 DEL (lgl->jwh, 2*lgl->szvars);
8740 for (i = 2; i < oldnvars; i++)
8741 if (lglisfree (lgl, i))
8742 avars[map[i]] = lgl->avars[i];
8743 DEL (lgl->avars, lgl->szvars);
8744 lgl->avars = avars; // Last since 'lglisfree' depends on it !!!
8746 lgl->nvars = lgl->szvars = nvars;
8747 lgl->stats->fixed.current = 0;
8750 static void lglmaphts (LGL * lgl, int * map) {
8751 int idx, sign, lit, * w, *eow, * p, other, other2, blit, tag, red;
8752 int newblit, newother, newother2;
8754 for (idx = 2; idx < lgl->nvars; idx++)
8755 for (sign = -1; sign <= 1; sign += 2) {
8757 hts = lglhts (lgl, lit);
8758 if (!hts->count) continue;
8759 w = lglhts2wchs (lgl, hts);
8760 eow = w + hts->count;
8761 for (p = w; p < eow; p++) {
8763 tag = blit & MASKCS;
8764 assert (tag == BINCS || tag == TRNCS || tag == LRGCS);
8766 other = blit >> RMSHFT;
8767 newother = lglmaplit (map, other);
8768 newblit = (newother << RMSHFT) | tag | red;
8770 if (tag == BINCS) continue;
8772 if (tag == LRGCS) continue;
8773 assert (tag == TRNCS);
8774 newother2 = lglmaplit (map, other2);
8780 static void lglmaptrail (LGL * lgl, int * map) {
8781 int * p, * q, src, dst;
8782 for (p = lgl->trail.start; p < lgl->trail.top; p++)
8783 if (lglevel (lgl, *p) > 0) break;
8784 for (q = lgl->trail.start; p < lgl->trail.top; p++) {
8786 assert (lglevel (lgl, src) > 0);
8787 dst = lglmaplit (map, src);
8791 lgl->flushed = lgl->next2 = lgl->next = lglcntstk (&lgl->trail);
8794 static int lglptrjmp (int * repr, int max, int start) {
8796 int prev = 0, count = 0;
8798 int next, idx, res, sgn, tmp;
8804 assert (idx <= max);
8809 if (prev || next) assert (prev != next);
8811 assert (count <= max);
8815 while (tmp != res) {
8816 idx = abs (tmp), sgn = lglsgn (tmp);
8817 next = repr[idx] * sgn;
8818 repr[idx] = sgn * res;
8824 static int lglirepr (LGL * lgl, int lit) {
8826 return lglptrjmp (lgl->repr, lgl->nvars - 1, lit);
8829 static void lglmapext (LGL * lgl, int * map) {
8830 int eidx, ilit, mlit;
8832 for (eidx = 1; eidx <= lgl->maxext; eidx++) (void) lglerepr (lgl, eidx);
8833 for (eidx = 1; eidx <= lgl->maxext; eidx++) {
8834 ext = lgl->ext + eidx;
8835 if (!ext->imported) continue;
8837 LOG (3, "mapping external %d to equivalent external %d",
8842 mlit = lglmaplit (map, ilit);
8843 LOG (3, "mapping external %d to internal %d", eidx, mlit);
8848 static void lglmapdef (LGL * lgl, int * map) {
8849 int didx, mlit, recycle, recycled;
8851 if (!lgl->maxdef) return;
8853 for (didx = 1; didx <= lgl->maxdef; didx++) {
8854 ext = lgl->def + didx;
8855 assert (!ext->imported);
8856 assert (ext->defined);
8857 mlit = lglmaplit (map, ext->repr);
8858 if (ext->blocking) {
8859 LOG (3, "keeping definition %d since it was blocked", didx);
8861 } else if (ext->eliminated) {
8862 LOG (3, "keeping definition %d since it was eliminated", didx);
8864 } else if (ext->equiv) {
8865 LOG (3, "keeping definition %d since it was equivalent", didx);
8869 if (abs (mlit) == 1) {
8871 "recycling definition %d since it is mapped to constant %d",
8876 if (recycle) recycled++;
8877 LOG (3, "definition %d mapped to internal %d", didx, mlit);
8880 LOG (2, "could have recycled %d definitions", recycled);
8883 static void lglsignedmark (LGL * lgl, int lit) {
8884 AVar * av = lglavar (lgl, lit);
8885 int bit = 1 << (lit < 0);
8886 if (av->mark & bit) return;
8890 static void lglsignedunmark (LGL * lgl, int lit) {
8891 AVar * av = lglavar (lgl, lit);
8892 int bit = 1 << (lit < 0);
8893 if (!(av->mark & bit)) return;
8897 static int lglsignedmarked (LGL * lgl, int lit) {
8898 AVar * av = lglavar (lgl, lit);
8899 int bit = 1 << (lit < 0);
8900 return av->mark & bit;
8903 static void lglmapass (LGL * lgl, int * map) {
8904 int * p, * q, iass, mass, flushed;
8907 if (abs (lgl->failed) != 1) lgl->failed = lglmaplit (map, lgl->failed);
8908 for (p = q = lgl->assume.start; p < lgl->assume.top; p++) {
8910 mass = lglmaplit (map, iass);
8911 if (mass == 1) continue;
8913 if (lgl->failed != -1) {
8916 for (r = lgl->eassume.start; r < lgl->eassume.top; r++)
8917 if (lglimport (lgl, *r) == -1) break;
8918 assert (r < lgl->eassume.top);
8920 LOG (2, "enforcing a failed assumption");
8925 LOG (2, "mapping previous internal assumption %d to %d", iass, mass);
8926 av = lglavar (lgl, mass);
8927 bit = 1u << (mass < 0);
8928 if (!(av->assumed & bit)) {
8929 LOG (2, "assuming new representative %d instead of %d", mass, iass);
8934 lgl->assume.top = q;
8936 for (p = q = lgl->assume.start; p < lgl->assume.top; p++) {
8938 if (lglsignedmarked (lgl, iass)) { flushed++; continue; }
8939 lglsignedmark (lgl, iass);
8942 lgl->assume.top = q;
8943 for (p = lgl->assume.start; p < lgl->assume.top; p++) {
8945 assert (lglsignedmarked (lgl, iass));
8946 lglsignedunmark (lgl, iass);
8949 LOG (2, "flushed %d duplicated internal assumptions", flushed);
8952 #if !defined(NDEBUG) && !defined(NLGLPICOSAT)
8953 static void lglpicosataddstk (LGL * lgl, const Stk * stk) {
8956 for (p = stk->start; p < stk->top; p++) {
8958 if (lit >= NOTALIT) continue;
8959 picosat_add (PICOSAT, lit);
8963 static void lglpicosataddunits (LGL * lgl) {
8965 assert (!lgl->level);
8966 assert (lgl->picosat.solver);
8967 for (idx = 2; idx < lgl->nvars; idx++) {
8968 val = lglval (lgl, idx);
8970 picosat_add (PICOSAT, (val < 0) ? -idx : idx);
8971 picosat_add (PICOSAT, 0);
8975 static void lglpicosataddhts (LGL * lgl) {
8976 int idx, sign, lit, tag, blit, other, other2;
8977 const int * w, * p, * eow;
8979 assert (lgl->picosat.solver);
8980 for (idx = 2; idx < lgl->nvars; idx++)
8981 for (sign = -1; sign <= 1; sign += 2) {
8983 hts = lglhts (lgl, lit);
8984 if (!hts->count) continue;
8985 w = lglhts2wchs (lgl, hts);
8986 eow = w + hts->count;
8987 for (p = w; p < eow; p++) {
8989 tag = blit & MASKCS;
8991 other = blit >> RMSHFT;
8992 if (abs (other) < idx) continue;
8993 picosat_add (PICOSAT, lit);
8994 picosat_add (PICOSAT, other);
8995 picosat_add (PICOSAT, 0);
8996 } else if (tag == TRNCS) {
8997 other = blit >> RMSHFT;
8999 if (abs (other) < idx) continue;
9000 if (abs (other2) < idx) continue;
9001 picosat_add (PICOSAT, lit);
9002 picosat_add (PICOSAT, other);
9003 picosat_add (PICOSAT, other2);
9004 picosat_add (PICOSAT, 0);
9005 } else if (tag == LRGCS) p++;
9006 else assert (lgl->dense && tag == OCCS);
9012 static void lglpicosatchkall (LGL * lgl) {
9013 #if !defined(NDEBUG) && !defined(NLGLPICOSAT)
9015 lglpicosatinit (lgl);
9016 if (lgl->opts->check.val >= 2) {
9017 for (p = lgl->eassume.start; p < lgl->eassume.top; p++)
9018 picosat_assume (PICOSAT, lglimport (lgl, *p));
9019 res = picosat_sat (PICOSAT, -1);
9020 LOG (1, "PicoSAT returns %d", res);
9021 if (lgl->picosat.res) assert (res == lgl->picosat.res);
9022 lgl->picosat.res = res;
9024 if (picosat_inconsistent (PICOSAT)) {
9025 assert (!lgl->picosat.res || lgl->picosat.res == 20);
9026 lgl->picosat.res = 20;
9031 static void lglpicosatrestart (LGL * lgl) {
9032 #if !defined(NDEBUG) && !defined(NLGLPICOSAT)
9034 if (lgl->picosat.solver) {
9035 picosat_reset (lgl->picosat.solver);
9036 LOG (1, "PicoSAT reset");
9037 lgl->picosat.solver = 0;
9039 lglpicosatinit (lgl);
9040 lglpicosataddunits (lgl);
9041 if (lgl->mt) picosat_add (PICOSAT, 0);
9042 lglpicosataddhts (lgl);
9043 lglpicosataddstk (lgl, &lgl->irr);
9044 for (glue = 0; glue < MAXGLUE; glue++)
9045 lglpicosataddstk (lgl, &lgl->red[glue]);
9049 static void lglmaplkhdscore (LGL * lgl, int * map, int oldnvars) {
9050 LKHD * oldlkhdscore = lgl->tlk->lkhd, score;
9051 int idx, src, sign, dst;
9052 NEW (lgl->tlk->lkhd, 2*lgl->nvars);
9053 lgl->tlk->lkhd += lgl->nvars;
9054 for (idx = oldnvars-1; idx >= 2; idx--) {
9055 for (sign = -1; sign <= 1; sign += 2) {
9057 dst = lglmaplit (map, src);
9058 if (abs (dst) <= 1) continue;
9059 score = oldlkhdscore[src];
9060 LOG (2, "mapping look-ahead score %s of %d as score of %d",
9061 lglflt2str (lgl, score), src, dst);
9062 lgl->tlk->lkhd[dst] = score;
9065 oldlkhdscore -= oldnvars;
9066 DEL (oldlkhdscore, 2*oldnvars);
9069 static int lglmapsize (LGL * lgl) {
9071 for (idx = 2; idx < lgl->nvars; idx++)
9072 if (lglisfree (lgl, idx)) size++;
9073 LOG (1, "mapping %d remaining variables", size);
9077 static void lglmapnonequiv (LGL * lgl, int * map, int size) {
9081 map[0] = 0, map[1] = 1;
9082 for (idx = 2; idx < lgl->nvars; idx++) {
9083 if (map[idx]) continue;
9084 av = lglavar (lgl, idx);
9085 if (av->type == FREEVAR) {
9087 if (map[idx]) { assert (map[idx] < idx); continue; }
9088 LOG (3, "mapping free %d to %d", idx, count + 2);
9089 map[idx] = count + 2;
9091 } else if (av->type == EQUIVAR) {
9094 } else if (av->type == FIXEDVAR) {
9095 val = lgl->vals[idx];
9097 LOG (3, "mapping assigned %d to %d", idx, (int) val);
9100 assert (av->type == ELIMVAR);
9101 assert (!lglifrozen (lgl, idx));
9105 assert (count == size);
9108 static void lglmapequiv (LGL * lgl, int * map) {
9111 for (idx = 2; idx < lgl->nvars; idx++) {
9112 if (map[idx]) continue;
9113 av = lglavar (lgl, idx);
9114 if (av->type == ELIMVAR) continue;
9115 assert (av->type == EQUIVAR);
9118 repr = lglirepr (lgl, idx);
9119 assert (repr != idx);
9120 assert (map[abs (repr)]);
9121 dst = lglmaplit (map, repr);
9122 LOG (3, "mapping equivalent %d to %d", idx, dst);
9127 typedef struct ForceData { int pos, count; double sum; } ForceData;
9129 static void lglincfdat (ForceData * fdat, int lit, double cog) {
9130 int idx = abs (lit);
9132 fdat[idx].sum += cog;
9135 static int lglcmpfdat (ForceData * fdat, int l, int k) {
9141 if (d->sum < e->sum) return -1;
9142 if (d->sum > e->sum) return 1;
9143 if (d->pos < e->pos) return -1;
9144 if (d->pos > e->pos) return 1;
9148 static int64_t lglsteps (LGL * lgl) {
9149 int64_t res = lgl->stats->steps;
9151 // Note, this would be bulky and slow ...
9153 steps += lgl->stats->bca.steps;
9154 steps += lgl->stats->blk.steps;
9155 steps += lgl->stats->card.steps;
9156 steps += lgl->stats->cce.steps;
9157 steps += lgl->stats->cgr.csteps;
9158 steps += lgl->stats->cgr.esteps;
9159 steps += lgl->stats->cliff.steps;
9160 steps += lgl->stats->elm.copies;
9161 steps += lgl->stats->elm.resolutions;
9162 steps += lgl->stats->elm.steps;
9163 steps += lgl->stats->force.steps;
9164 steps += lgl->stats->gauss.steps.elim;
9165 steps += lgl->stats->gauss.steps.extr;
9166 steps += lgl->stats->prb.basic.steps;
9167 steps += lgl->stats->prb.simple.steps;
9168 steps += lgl->stats->prb.treelook.steps;
9169 steps += lgl->stats->props.lkhd;
9170 steps += lgl->stats->props.search;
9171 steps += lgl->stats->props.simp;
9172 steps += lgl->stats->rdp.steps;
9173 steps += lgl->stats->trd.steps;
9174 steps += lgl->stats->trnr.steps;
9175 steps += lgl->stats->unhd.steps;
9176 assert (steps == res);
9181 static void lgltrep (LGL * lgl) {
9184 if (!lgl->opts->trep.val) return;
9185 if (lgl->opts->verbose.val) return;
9186 steps = lglsteps (lgl);
9187 if (steps < lgl->limits->trep.steps) return;
9188 lgl->limits->trep.steps += lgl->opts->trepint.val;
9189 t = lgl->opts->abstime.val ? lglgetime (lgl) : lglsec (lgl);
9190 if (t < lgl->limits->trep.time) return;
9191 lglrep (lgl, 0, (lgl->simp ? 'P' : 'S'));
9192 i = lgl->limits->trep.time;
9195 else if (i == 1) i = 2;
9196 else if (i == 2) i = 5;
9197 else if (i < 10) i = 10;
9198 else if (i < 60) i += 10;
9199 else if (i < 300) i += 60;
9200 else if (i < 900) i += 300;
9201 else if (i < 7200) i += 900;
9204 lgl->limits->trep.time = i;
9207 static int lglterminate (LGL * lgl) {
9211 if (!lgl->cbs) return 0;
9212 if (!lgl->cbs->term.fun) return 0;
9213 if (lgl->cbs->term.done) return 1;
9214 steps = lglsteps (lgl);
9215 if (steps < lgl->limits->term.steps) return 0;
9216 res = lgl->cbs->term.fun (lgl->cbs->term.state);
9217 if (res) lgl->cbs->term.done = res;
9218 else lgl->limits->term.steps = steps + lgl->opts->termint.val;
9222 #define LGLCMPFDAT(A,B) (lglcmpfdat(fdat, *(A), *(B)))
9224 static void lglforce (LGL * lgl, int * map) {
9225 int idx, lit, sign, blit, tag, red, other, other2, size, C, V, o, min, max;
9226 int round = 1, first = !lgl->stats->force.count;
9227 double cog, span, oldspan, mincut;
9228 const int * p, * w, * eow, * c;
9232 if (!lgl->allowforce) return;
9233 if (!lgl->opts->force.val) return;
9234 lglstart (lgl, &lgl->times->force);
9238 lgl->stats->force.count++;
9239 NEW (fdat, lgl->nvars);
9242 for (idx = 2; idx < lgl->nvars; idx++) {
9243 if (!lglisfree (lgl, idx)) continue;
9244 fdat[idx].pos = map[idx];
9245 lglpushstk (lgl, &order, idx);
9248 if (V <= 1) goto DONE;
9251 for (idx = 2; idx < lgl->nvars; idx++)
9252 for (sign = -1; sign <= 1; sign += 2) {
9253 INCSTEPS (force.steps);
9255 hts = lglhts (lgl, lit);
9256 w = lglhts2wchs (lgl, hts);
9257 eow = w + hts->count;
9258 for (p = w; p < eow; p++) {
9260 tag = blit & MASKCS;
9261 if (tag == TRNCS || tag == LRGCS) p++;
9262 if (tag == LRGCS) continue;
9265 other = abs (blit >> RMSHFT);
9266 if (other < idx) continue;
9268 cog = fdat[idx].pos + fdat[other].pos;
9270 lglincfdat (fdat, idx, cog);
9271 lglincfdat (fdat, other, cog);
9272 o = fdat[idx].pos, min = o, max = o;
9273 o = fdat[other].pos, min = lglmin (min, o), max = lglmax (max, o);
9276 } else if (tag == TRNCS) {
9278 if (other2 < idx) continue;
9279 cog = fdat[idx].pos + fdat[other].pos + fdat[other2].pos;
9281 lglincfdat (fdat, idx, cog);
9282 lglincfdat (fdat, other, cog);
9283 lglincfdat (fdat, other2, cog);
9284 o = fdat[idx].pos, min = o, max = o;
9285 o = fdat[other].pos, min = lglmin (min, o), max = lglmax (max, o);
9286 o = fdat[other2].pos, min = lglmin (min, o), max = lglmax (max, o);
9292 for (c = lgl->irr.start; c < lgl->irr.top; c = p + 1) {
9293 if (*(p = c) >= NOTALIT) continue;
9294 INCSTEPS (force.steps);
9296 while ((idx = abs (*p))) cog += fdat[idx].pos, p++;
9299 assert (p >= c + 4);
9301 min = INT_MAX, max = INT_MIN;
9302 for (p = c; (idx = abs (*p)); p++) {
9303 o = fdat[idx].pos, min = lglmin (min, o), max = lglmax (max, o);
9304 lglincfdat (fdat, idx, cog);
9309 for (idx = 2; idx < lgl->nvars; idx++) {
9310 if (!lglisfree (lgl, idx)) continue;
9311 if (!(size = fdat[idx].count)) continue;
9312 fdat[idx].sum /= size;
9315 mincut = span / (V - 1);
9316 if (C > 0) span /= C; else span = 0;
9317 if (lgl->stats->force.count > 1) {
9318 if (lgl->stats->force.mincut.min > mincut)
9319 lgl->stats->force.mincut.min = mincut;
9320 if (lgl->stats->force.mincut.max < mincut)
9321 lgl->stats->force.mincut.max = mincut;
9322 } else lgl->stats->force.mincut.min = lgl->stats->force.mincut.max = mincut;
9324 "[force-%lld] mincut %.1f, span %.1f, %d variables, %d clauses",
9325 (LGLL) lgl->stats->force.count, mincut, span, V, C);
9326 SORT (int, order.start, lglcntstk (&order), LGLCMPFDAT);
9328 for (p = order.start; p < order.top; p++) {
9330 assert (lglisfree (lgl, idx));
9331 LOG (3, "forced mapping free %d to %d", idx, o);
9335 DEL (fdat, lgl->nvars);
9336 lglrelstk (lgl, &order);
9337 if (first && !lglterminate (lgl)) {
9338 if (round++ < lgl->opts->force.val) goto RESTART;
9339 if (round < lglceilld (lglrem (lgl))) goto RESTART;
9340 if (oldspan > span && (oldspan - span) > oldspan/100.0) goto RESTART;
9345 static void lglmap (LGL * lgl) {
9346 int size, * map, oldnvars, mapsize;
9348 lglpicosatchkall (lgl);
9350 assert (!lgl->level);
9351 lgldreschedule (lgl);
9352 size = lglmapsize (lgl);
9353 oldnvars = lgl->nvars;
9354 mapsize = lglmax (oldnvars, 2);
9356 lglmapnonequiv (lgl, map, size);
9357 lglmapequiv (lgl, map);
9358 lglforce (lgl, map);
9359 lglmaptrail (lgl, map);
9360 lglmapvars (lgl, map, size + 2);
9361 lglmaplits (lgl, map);
9362 lglmapstk (lgl, map, &lgl->dsched);
9363 if (lgl->cgrclosing) lglmapstk (lgl, map, &lgl->cgr->units);
9364 lglmapext (lgl, map);
9365 lglmapdef (lgl, map);
9366 lglmapass (lgl, map);
9367 if (lgl->treelooking && lgl->tlk && lgl->tlk->lkhd)
9368 lglmaplkhdscore (lgl, map, oldnvars);
9369 assert (lglmtstk (&lgl->clause));
9370 lglmaphts (lgl, map);
9372 if (lgl->repr) DEL (lgl->repr, oldnvars);
9373 lglpicosatrestart (lgl);
9374 lgl->unassigned = size;
9375 lgldreschedule (lgl);
9378 static int lglgcnotnecessary (LGL * lgl) {
9379 if (lgl->forcegc) return 0;
9380 if (lgl->notfullyconnected) return 0;
9381 return lgl->stats->fixed.sum <= lgl->limits->gc.fixed;
9384 static void lglcompact (LGL * lgl) {
9386 lglfitstk (lgl, &lgl->assume);
9387 lglfitstk (lgl, &lgl->clause);
9388 lglfitstk (lgl, &lgl->eclause);
9389 lglfitstk (lgl, &lgl->dsched);
9390 lglfitstk (lgl, &lgl->eassume);
9391 lglfitstk (lgl, &lgl->extend);
9392 lglfitstk (lgl, &lgl->fassume);
9393 lglfitstk (lgl, &lgl->learned);
9394 lglfitstk (lgl, &lgl->cassume);
9395 lglfitstk (lgl, &lgl->frames);
9397 lglfitstk (lgl, &lgl->orig);
9399 lglfitstk (lgl, &lgl->trail);
9401 lglfitstk (lgl, &lgl->wchs->stk);
9403 lglfitstk (lgl, &lgl->irr);
9404 for (glue = 0; glue <= MAXGLUE; glue++)
9405 lglfitlir (lgl, lgl->red + glue);
9406 lglrelstk (lgl, &lgl->lcaseen);
9407 lglrelstk (lgl, &lgl->minstk);
9408 lglrelstk (lgl, &lgl->poisoned);
9409 lglrelstk (lgl, &lgl->seen);
9410 lglrelstk (lgl, &lgl->esched);
9413 static void lglgc (LGL * lgl) {
9414 if (lgl->mt) return;
9416 if (lglgcnotnecessary (lgl)) return;
9417 lglstart (lgl, &lgl->times->gc);
9418 lglchkbcpclean (lgl, "gc");
9419 lglrep (lgl, 2, 'g');
9421 if (lgl->level > 0) lglbacktrack (lgl, 0);
9426 if (lgl->next2 == lgl->next &&
9427 lgl->next == lglcntstk (&lgl->trail)) break;
9428 if (!lglbcp (lgl)) {
9430 LOG (1, "empty clause after propagating garbage collection unit");
9440 lgl->limits->gc.fixed = lgl->stats->fixed.sum;
9443 lglrep (lgl, 2, 'c');
9447 static int lgltopgc (LGL * lgl) {
9448 if (lgl->mt) return 0;
9449 assert (!lgl->forcegc && !lgl->allowforce);
9450 lgl->forcegc = lgl->allowforce = 1;
9452 assert (lgl->forcegc && lgl->allowforce);
9453 lgl->forcegc = lgl->allowforce = 0;
9457 static int lglrandec (LGL * lgl) {
9458 unsigned size, pos, start, delta;
9460 lgl->limits->randec = lgl->stats->decisions;
9461 lgl->limits->randec += lgl->opts->randecint.val/2;
9462 lgl->limits->randec += lglrand (lgl) % lgl->opts->randecint.val;
9463 assert (lgl->nvars > 2);
9464 size = lgl->nvars - 2;
9465 if (!size) return 0;
9466 pos = start = lglrand (lgl) % size;
9468 assert (2 <= lit && lit < lgl->nvars);
9469 if (lglval (lgl, lit)) {
9470 delta = lglrand (lgl) % size;
9471 if (size == 1) return 0;
9472 if (!delta) delta++;
9473 while (lglgcd (delta, size) != 1)
9474 if (++delta == size) delta = 1;
9477 if (pos >= size) pos -= size;
9478 if (pos == start) return 0;
9480 assert (2 <= lit && lit < lgl->nvars);
9481 } while (lglval (lgl, lit));
9483 lgl->stats->randecs++;
9487 static int lgladecide (LGL * lgl) {
9489 while (lgl->assumed < lglcntstk (&lgl->assume)) {
9490 res = lglpeek (&lgl->assume, lgl->assumed);
9491 val = lglcval (lgl, res);
9492 if (val > 0) LOG (3, "assumption %d already satisfied", res);
9494 LOG (3, "new assumption queue level %d", lgl->assumed);
9496 if (!val) return res;
9501 static int lgldefphase (LGL * lgl, int idx) {
9505 av = lglavar (lgl, idx);
9507 bias = lgl->opts->phase.val;
9508 if (!bias) bias = av->bias;
9509 if (!bias) bias = lglsetjwhbias (lgl, idx);
9515 static int lgldecidephase (LGL * lgl, int lit) {
9516 int res = abs (lit), flipped, diff;
9517 AVar * av = lglavar (lgl, lit);
9518 if (av->fase) return av->fase * res;
9519 if ((diff = lgl->level - lgl->alevel) < lgl->opts->phasegluebit.val) {
9520 LOG (1, "Glue-Bit initial level counting");
9521 if (!((lgl->stats->restarts.count >> (diff & 3)) & 1)) res = -res;
9524 if (lgl->phaseneg || lgldefphase (lgl, res) <= 0) res = -res;
9525 if (!lgl->flipping &&
9527 lgl->opts->flipping.val &&
9528 lglrem (lgl) <= lgl->opts->flipvlim.val &&
9529 lgl->level >= lgl->alevel &&
9530 lgl->assumed == lglcntstk (&lgl->assume) &&
9531 (!lgl->opts->fliptop.val || lgl->level == lgl->alevel)) {
9532 if (lgl->notflipped >= lgl->limits->flipint) {
9533 LOG (1, "switching on phase flipping");
9534 lgl->stats->fliphases++;
9535 lgl->limits->flipint = lgl->opts->flipint.val;
9536 lgl->flipping = lgl->opts->flipdur.val;
9537 lgl->notflipped = 0;
9538 } else lgl->notflipped++;
9540 if (lgl->flipping) {
9541 const int fliplevels = lgl->opts->fliplevels.val;
9542 const int ldmod = lgl->opts->flipldmod.val;
9543 const int level = lgl->level - lgl->alevel;
9544 int shift = fliplevels - lglmin (level, fliplevels);
9545 int flip = !((lgl->stats->fliphases >> ldmod) & (1 << shift));
9546 if (level > fliplevels) flip = 0;
9547 assert (!lgl->phaseneg);
9548 flipped = flip ? -res : res;
9549 LOG (2, "flipping phase of %d to %d", res, flipped);
9550 lgl->stats->flipped++;
9556 static int lglhasbins (LGL * lgl, int lit) {
9557 int blit, tag, other, other2, val, val2, implied;
9558 const int * p, * w, * eos, * q;
9560 assert (!lgl->level);
9561 assert (lglisfree (lgl, lit));
9562 hts = lglhts (lgl, lit);
9563 w = lglhts2wchs (lgl, hts);
9564 eos = w + hts->count;
9565 for (p = w; p < eos; p++) {
9566 if (lgl->treelooking) INCSTEPS (prb.treelook.steps);
9568 tag = blit & MASKCS;
9570 other = blit >> RMSHFT;
9571 val = lglval (lgl, other);
9574 } else if (tag == TRNCS) {
9575 other = blit >> RMSHFT;
9577 val = lglval (lgl, other);
9578 val2 = lglval (lgl, other2);
9579 assert (val >= 0 || val2 >= 0);
9580 if (val > 0 || val2 > 0) continue;
9581 if (!val && val2 < 0) return 1;
9582 if (val < 0 && !val2) return 1;
9584 assert (tag == LRGCS);
9585 q = lglidx2lits (lgl, (blit & REDCS), *++p);
9587 while ((other = *q++)) {
9588 if (other == lit) continue;
9589 val = lglval (lgl, other);
9591 if (val < 0) continue;
9595 if (other) continue;
9596 if (implied) return 1;
9602 static int lglhasbinortrn (LGL * lgl, int lit) {
9603 int blit, tag, other, other2, val, val2, implied;
9604 const int * p, * w, * eos, * q;
9606 assert (!lgl->level);
9607 assert (lglisfree (lgl, lit));
9608 hts = lglhts (lgl, lit);
9609 w = lglhts2wchs (lgl, hts);
9610 eos = w + hts->count;
9611 for (p = w; p < eos; p++) {
9612 if (lgl->treelooking) INCSTEPS (prb.treelook.steps);
9614 tag = blit & MASKCS;
9616 other = blit >> RMSHFT;
9617 val = lglval (lgl, other);
9620 } else if (tag == TRNCS) {
9621 other = blit >> RMSHFT;
9623 val = lglval (lgl, other);
9624 val2 = lglval (lgl, other2);
9625 assert (val >= 0 || val2 >= 0);
9626 if (val <= 0 && val2 <= 0) return 1;
9628 assert (tag == LRGCS);
9629 q = lglidx2lits (lgl, (blit & REDCS), *++p);
9631 while (implied <= 2 && (other = *q++)) {
9632 if (other == lit) continue;
9633 val = lglval (lgl, other);
9635 if (!val) implied++;
9637 if (other) continue;
9638 if (implied <= 2) return 1;
9644 static int lgldecide (LGL * lgl) {
9646 lglchkbcpclean (lgl, "decide");
9647 if (!lgl->unassigned) return 0;
9648 if ((lit = lgladecide (lgl))) {
9649 LOG (2, "using assumption %d as decision", lit);
9650 lgl->alevel = lgl->level + 1;
9651 LOG (2, "new assumption decision level %d", lgl->alevel);
9653 if (lgl->opts->randec.val &&
9654 lgl->limits->randec <= lgl->stats->decisions) {
9655 lit = lglrandec (lgl);
9656 lit = lgldecidephase (lgl, lit);
9657 LOG (2, "random decision %d", lit);
9658 if (lgl->opts->randecflipint.val &&
9659 !(lgl->stats->randecs % lgl->opts->randecflipint.val)) {
9661 LOG (2, "flipped random decision %d", lit);
9662 lgl->stats->randecsflipped++;
9665 lit = lglnextdecision (lgl);
9666 lit = lgldecidephase (lgl, lit);
9669 if (lit) lgldassume (lgl, lit);
9673 static void lgldcpdis (LGL * lgl) {
9674 int idx, sign, lit, tag, blit, red, other, other2, i;
9675 const int * w, * p, * eow;
9680 for (idx = 2; idx < lgl->nvars; idx++)
9681 for (sign = -1; sign <= 1; sign += 2) {
9683 hts = lglhts (lgl, lit);
9684 if (!hts->offset) continue;
9685 assert (hts->count > 0);
9686 w = lglhts2wchs (lgl, hts);
9687 eow = w + hts->count;
9688 hts->count = hts->offset = 0;
9689 val = lglval (lgl, lit);
9690 if (val > 0) continue;
9691 for (p = w; p < eow; p++) {
9693 tag = blit & MASKCS;
9694 if (tag == TRNCS || tag == LRGCS) p++;
9695 if (tag == LRGCS) continue;
9696 other = blit >> RMSHFT;
9697 if (abs (other) < idx) continue;
9698 val = lglval (lgl, other);
9699 if (val > 0) continue;
9701 if (red && !lglisfree (lgl, other)) continue;
9703 s = red ? &lgl->dis->red.bin : &lgl->dis->irr.bin;
9705 assert (tag == TRNCS);
9707 if (abs (other2) < idx) continue;
9708 val = lglval (lgl, other2);
9709 if (val > 0) continue;
9710 if (red && !lglisfree (lgl, other2)) continue;
9711 s = red ? &lgl->dis->red.trn : &lgl->dis->irr.trn;
9712 lglpushstk (lgl, s, other2);
9714 lglpushstk (lgl, s, other);
9715 lglpushstk (lgl, s, lit);
9716 lglpushstk (lgl, s, 0);
9719 lglrststk (&lgl->wchs->stk, 2);
9720 lgl->wchs->stk.top[-1] = INT_MAX;
9721 for (i = 0; i < MAXLDFW; i++) lgl->wchs->start[i] = INT_MAX;
9722 lgl->wchs->free = 0;
9723 lglrelstk (lgl, &lgl->learned);
9726 static void lgldcpclnstk (LGL * lgl, int red, Stk * s) {
9727 int oldsz, newsz, lit, mark, satisfied, repr, act;
9728 const int * p, * c, * eos = s->top;
9729 int * start, * q, * r, * d;
9732 q = start = s->start;
9733 for (c = q; c < eos; c = p + 1) {
9735 if (act == REMOVED) {
9736 for (p = c + 1; p < eos && *p == REMOVED; p++)
9738 assert (p >= eos || *p < NOTALIT || lglisact (*p));
9742 if (lglisact (act)) *q++ = *c++; else act = -1;
9746 for (p = c; assert (p < eos), (lit = *p); p++) {
9747 assert (!lglavar (lgl, lit)->mark);
9748 repr = lglirepr (lgl, lit);
9749 assert (abs (repr) == 1 || !lglavar (lgl, lit)->mark);
9752 for (p = c; assert (p < eos), (lit = *p); p++) {
9753 assert (lit < NOTALIT);
9754 if (satisfied) continue;
9755 repr = lglirepr (lgl, lit);
9756 val = lglcval (lgl, repr);
9757 if (val > 0) { satisfied = 1; continue; }
9758 if (val < 0) continue;
9759 mark = lglmarked (lgl, repr);
9760 if (mark < 0) { satisfied = 1; continue; }
9761 if (mark > 0) continue;
9762 lglmark (lgl, repr);
9766 for (r = d; r < q; r++) lglunmark (lgl, *r);
9767 if (satisfied || !oldsz) { q = d - (act >= 0); continue; }
9770 assert (act < 0 || d[-1] == act);
9773 } else if (!newsz) {
9774 LOG (1, "found empty clause while cleaning decomposition");
9777 } else if (newsz == 1) {
9778 LOG (1, "new unit %d while cleaning decomposition", d[0]);
9779 lglunit (lgl, d[0]);
9781 } else if (newsz == 2) {
9782 t = red ? &lgl->dis->red.bin : &lgl->dis->irr.bin;
9784 lglpushstk (lgl, t, d[0]);
9785 lglpushstk (lgl, t, d[1]);
9786 lglpushstk (lgl, t, 0);
9790 assert (newsz == 3);
9791 t = red ? &lgl->dis->red.trn : &lgl->dis->irr.trn;
9793 lglpushstk (lgl, t, d[0]);
9794 lglpushstk (lgl, t, d[1]);
9795 lglpushstk (lgl, t, d[2]);
9796 lglpushstk (lgl, t, 0);
9804 static void lgldcpconnaux (LGL * lgl, int red, int glue, Stk * s) {
9805 int * start = s->start, * q, * d, lit, size, lidx, act;
9806 const int * p, * c, * eos = s->top;
9807 assert (red == 0 || red == REDCS);
9808 assert (!glue || red);
9810 for (c = q; c < eos; c = p + 1) {
9811 if (lglisact (act = *c)) *q++ = *c++; else act = -1;
9813 for (p = c; (lit = *p); p++) {
9814 assert (!lgl->repr[abs (lit)]);
9815 assert (!lgl->vals[abs (lit)]);
9821 lglwchbin (lgl, d[0], d[1], red);
9822 lglwchbin (lgl, d[1], d[0], red);
9823 } else if (size == 3) {
9825 lglwchtrn (lgl, d[0], d[1], d[2], red);
9826 lglwchtrn (lgl, d[1], d[0], d[2], red);
9827 lglwchtrn (lgl, d[2], d[0], d[1], red);
9833 assert (lidx <= MAXREDLIDX);
9838 (void) lglwchlrg (lgl, d[0], d[1], red, lidx);
9839 (void) lglwchlrg (lgl, d[1], d[0], red, lidx);
9845 static void lgldcpcon (LGL * lgl) {
9848 lgldcpconnaux (lgl, 0, 0, &lgl->dis->irr.bin);
9849 lgldcpconnaux (lgl, REDCS, 0, &lgl->dis->red.bin);
9850 lgldcpconnaux (lgl, 0, 0, &lgl->dis->irr.trn);
9851 lgldcpconnaux (lgl, REDCS, 0, &lgl->dis->red.trn);
9852 lglrelstk (lgl, &lgl->dis->irr.bin);
9853 lglrelstk (lgl, &lgl->dis->irr.trn);
9854 lglrelstk (lgl, &lgl->dis->red.bin);
9855 lglrelstk (lgl, &lgl->dis->red.trn);
9857 lgldcpconnaux (lgl, 0, 0, &lgl->irr);
9858 for (glue = 0; glue < MAXGLUE; glue++) {
9859 lir = lgl->red + glue;
9860 lgldcpconnaux (lgl, REDCS, glue, lir);
9862 lglfullyconnected (lgl);
9865 static void lgldcpcln (LGL * lgl) {
9866 int glue, old, rounds = 0;
9870 old = lgl->stats->fixed.current;
9871 lgldcpclnstk (lgl, 0, &lgl->irr);
9872 lgldcpclnstk (lgl, 0, &lgl->dis->irr.bin);
9873 lgldcpclnstk (lgl, 0, &lgl->dis->irr.trn);
9874 lgldcpclnstk (lgl, REDCS, &lgl->dis->red.bin);
9875 lgldcpclnstk (lgl, REDCS, &lgl->dis->red.trn);
9876 for (glue = 0; glue < MAXGLUE; glue++) {
9877 lir = lgl->red + glue;
9878 lgldcpclnstk (lgl, REDCS, lir);
9880 } while (old < lgl->stats->fixed.current);
9881 LOG (1, "iterated %d decomposition cleaning rounds", rounds);
9884 static void lglepush (LGL * lgl, int ilit) {
9885 int elit = ilit ? lglexport (lgl, ilit) : 0;
9886 lglpushstk (lgl, &lgl->extend, elit);
9887 LOG (4, "pushing external %d internal %d", elit, ilit);
9890 static void lglemerge (LGL * lgl, int ilit0, int ilit1) {
9891 int elit0 = lglexport (lgl, ilit0), elit1 = lglexport (lgl, ilit1);
9892 int repr0 = lglerepr (lgl, elit0), repr1 = lglerepr (lgl, elit1);
9893 Ext * ext0 = lglelit2ext (lgl, repr0);
9895 Ext * ext1 = lglelit2ext (lgl, repr1);
9898 assert (abs (repr0) != abs (repr1));
9907 LOG (2, "merging external literals %d and %d", repr0, repr1);
9908 assert (lglerepr (lgl, elit0) == repr);
9909 assert (lglerepr (lgl, elit1) == repr);
9910 assert (!(ext0->frozen || ext0->tmpfrozen) ||
9911 ext1->frozen || ext1->tmpfrozen);
9912 lglepush (lgl, -ilit0); lglepush (lgl, ilit1); lglepush (lgl, 0);
9913 lglepush (lgl, ilit0); lglepush (lgl, -ilit1); lglepush (lgl, 0);
9914 if (lgl->opts->drup.val) {
9915 lgldrupclsarg (lgl, -ilit0, ilit1, 0);
9916 lgldrupclsarg (lgl, ilit0, -ilit1, 0);
9920 static void lglimerge (LGL * lgl, int lit, int repr) {
9921 int idx = abs (lit);
9922 AVar * av = lglavar (lgl, idx);
9923 assert (!lglifrozen (lgl, lit) || lglifrozen (lgl, repr));
9924 if (lit < 0) repr = -repr;
9925 assert (av->type == FREEVAR);
9928 lgl->repr[idx] = repr;
9929 lgl->stats->prgss++;
9930 lgl->stats->irrprgss++;
9931 lgl->stats->equiv.sum++;
9932 lgl->stats->equiv.current++;
9933 assert (lgl->stats->equiv.sum > 0);
9934 assert (lgl->stats->equiv.current > 0);
9936 if (lgl->opts->drup.val) lgldrupclsarg (lgl, idx, -repr, 0);
9937 if (lgl->opts->drup.val) lgldrupclsarg (lgl, -idx, repr, 0);
9940 lglpicosatchkclsarg (lgl, idx, -repr, 0);
9941 lglpicosatchkclsarg (lgl, -idx, repr, 0);
9943 lglemerge (lgl, idx, repr);
9946 static void lglfreezer (LGL * lgl) {
9947 int frozen, melted, tmpfrozen, elit, erepr, ilit;
9950 if (lgl->frozen) return;
9951 for (elit = 1; elit <= lgl->maxext; elit++)
9952 lgl->ext[elit].tmpfrozen = 0;
9953 tmpfrozen = frozen = 0;
9954 if (!lglmtstk (&lgl->eassume)) {
9955 for (p = lgl->eassume.start; p < lgl->eassume.top; p++) {
9957 ext = lglelit2ext (lgl, eass);
9958 assert (!ext->melted);
9959 assert (!ext->eliminated);
9960 assert (!ext->blocking);
9961 if (!ext->frozen && !ext->tmpfrozen) {
9964 LOG (2, "temporarily freezing external assumption %d", eass);
9965 erepr = lglerepr (lgl, eass);
9966 rext = lglelit2ext (lgl, erepr);
9967 if (ext != rext && !rext->frozen && !rext->tmpfrozen) {
9968 assert (!rext->equiv);
9969 assert (!rext->eliminated);
9970 // assert (!rext->blocking);
9972 "temporarily freezing external assumption literal %d", erepr);
9973 rext->tmpfrozen = 1;
9979 for (elit = 1; elit <= lgl->maxext; elit++) {
9980 ext = lglelit2ext (lgl, elit);
9981 if (!ext->frozen) continue;
9983 assert (!ext->melted);
9984 assert (!ext->eliminated);
9985 assert (!ext->blocking);
9986 erepr = lglerepr (lgl, elit);
9987 rext = lglelit2ext (lgl, erepr);
9988 if (ext == rext) continue;
9989 if (rext->frozen) continue;
9990 if (rext->tmpfrozen) continue;
9991 // assert (!rext->melted);
9992 assert (!rext->equiv);
9993 assert (!rext->eliminated);
9994 // assert (!rext->blocking);
9995 LOG (2, "temporarily freezing external literal %d", erepr);
9996 rext->tmpfrozen = 1;
10000 for (elit = 1; elit <= lgl->maxext; elit++) {
10001 ext = lglelit2ext (lgl, elit);
10002 if (ext->frozen) continue;
10003 if (ext->melted) continue;
10004 if (ext->tmpfrozen) continue;
10005 if (!ext->imported) continue;
10006 LOG (2, "permanently melted external %d", elit);
10010 LOG (2, "found %d frozen external variables", frozen);
10011 LOG (2, "temporarily frozen %d external variables", tmpfrozen);
10012 LOG (2, "permanently melted %d external variables", melted);
10014 LOG (2, "frozen solver");
10015 melted = frozen = 0;
10016 for (ilit = 2; ilit < lgl->nvars; ilit++) {
10017 if (!lglisfree (lgl, ilit)) continue;
10018 if (lglifrozen (lgl, ilit)) frozen++; else melted++;
10020 lgl->allfrozen = !melted;
10021 if (lgl->allfrozen)
10022 lglprt (lgl, 1, "[freezer] all %d free variables frozen", frozen);
10025 "[freezer] frozen %d variables out of %d free variables %.0f%%",
10026 frozen, frozen + melted, lglpcnt (frozen, frozen + melted));
10029 static int lglcmprepr (LGL * lgl, int a, int b) {
10030 int f = lglifrozen (lgl, a), g = lglifrozen (lgl, b), res;
10031 if ((res = g - f)) return res;
10032 if ((res = (abs (a) - abs (b)))) return res;
10036 static int lgltarjan (LGL * lgl) {
10037 int * dfsimap, * mindfsimap, idx, oidx, sign, lit, blit, tag, other;
10038 int dfsi, mindfsi, ulit, uother, tmp, repr, res, sgn, frozen;
10039 const int * p, * w, * eow;
10040 Stk stk, component;
10043 if (!lgl->nvars) return 1;
10044 assert (lgl->frozen);
10046 NEW (dfsimap, 2*lgl->nvars);
10047 NEW (mindfsimap, 2*lgl->nvars);
10048 NEW (lgl->repr, lgl->nvars);
10049 CLR (stk); CLR (component);
10051 for (idx = 2; idx < lgl->nvars; idx++) {
10052 for (sign = -1; sign <= 1; sign += 2) {
10054 ulit = lglulit (lit);
10055 tmp = dfsimap[ulit];
10057 lglpushstk (lgl, &stk, lit);
10058 while (!lglmtstk (&stk)) {
10059 lit = lglpopstk (&stk);
10061 ulit = lglulit (lit);
10062 if (dfsimap[ulit]) continue;
10063 dfsimap[ulit] = mindfsimap[ulit] = ++dfsi;
10064 lglpushstk (lgl, &component, lit);
10066 lglpushstk (lgl, &stk, lit);
10067 lglpushstk (lgl, &stk, 0);
10068 hts = lglhts (lgl, -lit);
10069 if (!hts->offset) continue;
10070 assert (hts->count > 0);
10071 w = lglhts2wchs (lgl, hts);
10072 eow = w + hts->count;
10073 for (p = w; p < eow; p++) {
10075 tag = blit & MASKCS;
10076 if (tag != BINCS) { p++; continue; }
10077 other = blit >> RMSHFT;
10078 uother = lglulit (other);
10079 tmp = dfsimap[uother];
10081 lglpushstk (lgl, &stk, other);
10084 assert (!lglmtstk (&stk));
10085 lit = lglpopstk (&stk);
10086 ulit = lglulit (lit);
10087 mindfsi = dfsimap[ulit];
10089 hts = lglhts (lgl, -lit);
10090 w = lglhts2wchs (lgl, hts);
10091 eow = w + hts->count;
10092 for (p = w; p < eow; p++) {
10094 tag = blit & MASKCS;
10095 if (tag != BINCS) { p++; continue; }
10096 other = blit >> RMSHFT;
10097 uother = lglulit (other);
10098 tmp = mindfsimap[uother];
10099 if (tmp >= mindfsi) continue;
10102 if (mindfsi == dfsimap[ulit]) {
10104 frozen = lglifrozen (lgl, repr);
10105 for (p = component.top - 1; (other = *p) != lit; p--) {
10106 if (lglcmprepr (lgl, other, repr) < 0) repr = other;
10107 if (!frozen && lglifrozen (lgl, other)) frozen = 1;
10109 while ((other = lglpopstk (&component)) != lit) {
10110 mindfsimap[lglulit (other)] = INT_MAX;
10111 if (other == repr) continue;
10112 if (other == -repr) {
10113 if (lgl->opts->drup.val) lgldrupclsarg (lgl, repr, 0);
10114 LOG (1, "empty clause since repr[%d] = %d", repr, other);
10115 lgl->mt = 1; res = 0; goto DONE;
10117 sgn = lglsgn (other);
10118 oidx = abs (other);
10119 tmp = lgl->repr[oidx];
10120 if (tmp == sgn * repr) continue;
10121 LOG (2, "repr[%d] = %d", oidx, sgn * repr);
10123 if (lgl->opts->drup.val) lgldrupclsarg (lgl, repr, 0);
10124 LOG (1, "empty clause since repr[%d] = %d and repr[%d] = %d",
10125 oidx, tmp, oidx, sgn * repr);
10126 lgl->mt = 1; res = 0; goto DONE;
10128 av = lglavar (lgl, oidx);
10129 assert (sgn*oidx == other);
10130 if (av->type == FREEVAR) lglimerge (lgl, other, repr);
10131 else assert (av->type == FIXEDVAR);
10134 mindfsimap[lglulit (lit)] = INT_MAX;
10136 LOG (2, "equivalence class of %d is frozen", repr);
10137 assert (lglifrozen (lgl, repr));
10139 } else mindfsimap[ulit] = mindfsi;
10145 lglrelstk (lgl, &stk);
10146 lglrelstk (lgl, &component);
10147 DEL (mindfsimap, 2*lgl->nvars);
10148 DEL (dfsimap, 2*lgl->nvars);
10149 if (!res) DEL (lgl->repr, lgl->nvars);
10153 static int lglsyncunits (LGL * lgl) {
10154 int * units, * eou, * p, elit, erepr, ilit, res, count = 0;
10155 void (*produce)(void*, int);
10159 if (lgl->mt) return 0;
10160 if (!lgl->cbs) return 1;
10161 if (!lgl->cbs->units.consume.fun) return 1;
10162 assert (!lgl->simp || !lgl->level);
10163 steps = lglsteps (lgl);
10164 if (steps < lgl->limits->sync.steps) return 1;
10165 lgl->limits->sync.steps = steps + lgl->opts->syncunint.val;
10166 lgl->stats->sync.units.consumed.calls++;
10167 lgl->cbs->units.consume.fun (lgl->cbs->units.consume.state, &units, &eou);
10168 if (units == eou) return 1;
10169 lgl->stats->sync.units.consumed.tried++;
10170 produce = lgl->cbs->units.produce.fun;
10171 lgl->cbs->units.produce.fun = 0;
10172 for (p = units; !lgl->mt && p < eou; p++) {
10174 erepr = lglerepr (lgl, elit);
10175 ext = lglelit2ext (lgl, erepr);
10176 assert (!ext->equiv);
10178 if (!ilit) continue;
10179 if (erepr < 0) ilit = -ilit;
10180 if (ilit == 1) continue;
10181 if (ilit == -1) val = -1;
10183 assert (abs (ilit) > 1);
10184 val = lglval (lgl, ilit);
10185 if (val && lglevel (lgl, ilit)) val = 0;
10187 if (val == 1) continue;
10189 LOG (1, "mismatching synchronized external unit %d", elit);
10190 if (lgl->level > 0) lglbacktrack (lgl, 0);
10192 } else if (!lglisfree (lgl, ilit)) continue;
10195 if (lgl->level > 0) lglbacktrack (lgl, 0);
10196 lglunit (lgl, ilit);
10197 LOG (2, "importing internal unit %d external %d",
10198 lgl->tid, ilit, elit);
10202 lgl->cbs->units.produce.fun = produce;
10203 if (lgl->cbs->units.consumed.fun)
10204 lgl->cbs->units.consumed.fun (lgl->cbs->units.consumed.state, count);
10205 if (count) lgl->stats->sync.units.consumed.actual++;
10206 if (lgl->mt) return 0;
10207 if (count) LOG (1, "imported %d units", count);
10208 if (!count) return 1;
10209 assert (!lgl->level);
10210 res = lglbcp (lgl);
10211 if(!res && !lgl->mt) lgl->mt = 1;
10215 static int lglelitblockingoreliminated (LGL * lgl, int elit) {
10216 Ext * ext = lglelit2ext (lgl, elit);
10217 return ext->blocking || ext->eliminated;
10220 static int lglsynclsexist (LGL * lgl) {
10221 int len, lit, blit, tag, other, other2;
10222 int * s, * p, * w, * eow;
10224 len = lglcntstk (&lgl->clause);
10225 assert (!len || lgl->clause.top[-1]);
10226 if (len <= 1) return 0;
10227 s = lgl->clause.start;
10228 for (p = s + 1; p + 1 < lgl->clause.top; p++) {
10229 assert (lglmarked (lgl, *p) > 0);
10230 if (lglhts (lgl, *s)->count > lglhts (lgl, *p)->count)
10231 SWAP (int, *s, *p);
10233 hts = lglhts (lgl, (lit = *s));
10234 assert (lglmarked (lgl, lit) > 0);
10235 w = lglhts2wchs (lgl, hts);
10236 eow = w + hts->count;
10237 for (p = w; p < eow; p++) {
10239 tag = blit & MASKCS;
10240 if (tag == TRNCS || tag == LRGCS) p++;
10241 if (tag == LRGCS) continue;
10242 if (tag == BINCS) {
10243 other = blit >> RMSHFT;
10244 if (lglmarked (lgl, other) > 0) return 1;
10246 assert (tag == TRNCS);
10247 if (len <= 2) continue;
10248 other = blit >> RMSHFT;
10249 if (lglmarked (lgl, other) > 0) return 1;
10251 if (lglmarked (lgl, other2) > 0) return 1;
10257 static int lglsyncls (LGL * lgl) {
10258 int maxlevel, level, nonfalse, numtrue, res, delta, glue, consumed;
10259 int * cls, elit, erepr, tmp, ilit, len, newglue;
10262 if (lgl->mt) return 0;
10263 if (!lgl->cbs) return 1;
10264 if (!lgl->cbs->cls.consume.fun) return 1;
10265 assert (!lgl->simp);
10266 if (lgl->stats->confs < lgl->limits->sync.confs) return 1;
10267 delta = lgl->opts->synclsint.val;
10268 if (lgl->stats->sync.cls.consumed.calls) {
10269 rate = 100*lgl->stats->sync.cls.consumed.tried;
10270 rate /= lgl->stats->sync.cls.consumed.calls;
10271 LOG (SCL, "syncls tried/calls = %lld/%lld = %d%%",
10272 (LGLL) lgl->stats->sync.cls.consumed.tried,
10273 (LGLL) lgl->stats->sync.cls.consumed.calls,
10275 if (rate) delta /= rate;
10277 lgl->limits->sync.confs = lgl->stats->confs + delta;
10278 lgl->stats->sync.cls.consumed.calls++;
10281 lgl->cbs->cls.consume.fun (lgl->cbs->cls.consume.state, &cls, &glue);
10282 if (!cls) return 1;
10283 lgl->stats->sync.cls.consumed.tried++;
10284 LOGCLS (SCL, cls, "trying to import external clause");
10285 assert (lglmtstk (&lgl->clause));
10286 maxlevel = nonfalse = numtrue = 0;
10288 for (p = cls; (elit = *p); p++) {
10289 ilit = lglimport (lgl, elit);
10290 if (abs (ilit) <= 1) continue;
10291 assert (!lglmarked (lgl, ilit));
10294 for (p = cls; (elit = *p); p++) {
10295 erepr = lglerepr (lgl, elit);
10296 if (lglelitblockingoreliminated (lgl, erepr)) break;
10297 ilit = lglimport (lgl, erepr);
10299 if (ilit == 1) break;
10300 if (ilit == -1) continue;
10301 tmp = lglifixed (lgl, ilit);
10302 if (tmp > 0) break;
10303 if (tmp < 0) continue;
10304 tmp = lglmarked (lgl, ilit);
10305 if (tmp > 0) continue;
10306 if (tmp < 0) break;
10307 lglpushstk (lgl, &lgl->clause, ilit);
10308 lglmark (lgl, ilit);
10309 tmp = lglval (lgl, ilit);
10310 if (tmp > 0) numtrue++;
10311 else if (!tmp) nonfalse++;
10312 else if ((level = lglevel (lgl, ilit)) > maxlevel) maxlevel = level;
10315 if (!elit && lglsynclsexist (lgl)) elit = INT_MAX;
10316 for (p = lgl->clause.start; p < lgl->clause.top; p++)
10317 lglunmark (lgl, *p);
10318 if (elit) goto DONE;
10319 len = lglcntstk (&lgl->clause);
10320 if (!numtrue && nonfalse <= 1) {
10321 if (len <= 1 || maxlevel <= 1) level = 0;
10324 for (p = lgl->clause.start; p < lgl->clause.top; p++) {
10326 tmp = lglval (lgl, ilit);
10328 if (!tmp) continue;
10329 tmp = lglevel (lgl, ilit);
10330 if (tmp < maxlevel && tmp > level) level = tmp;
10333 if (level < lgl->level) {
10334 LOG (SCL, "importing clause requires to backtrack to level %d", level);
10335 lglbacktrack (lgl, level);
10338 lglpushstk (lgl, &lgl->clause, 0);
10341 if (len > 3 && glue <= lgl->opts->gluekeep.val)
10342 newglue = lgl->opts->gluekeep.val + 1;
10344 LOGCLS (SCL, lgl->clause.start,
10345 "successfully imported as glue %d redundant glue %d length %d clause",
10346 newglue, glue, len);
10347 lgl->stats->sync.cls.consumed.actual++;
10348 lgldrupligaddcls (lgl, REDCS);
10349 lgladdcls (lgl, REDCS, newglue, !numtrue);
10351 if (lgl->mt) res = 0;
10352 else res = lglbcpsearch (lgl);
10354 lglclnstk (&lgl->clause);
10355 if (res && lgl->opts->synclsall.val) goto RESTART;
10356 if (lgl->cbs->cls.consumed.fun)
10357 lgl->cbs->cls.consumed.fun (lgl->cbs->cls.consumed.state, consumed);
10361 static int lglprbpull (LGL * lgl, int lit, int probe) {
10363 assert (lgl->level == 1);
10364 av = lglavar (lgl, lit);
10365 if (av->mark) return 0;
10366 if (!lglevel (lgl, lit)) return 0;
10367 assert (lglevel (lgl, lit) == 1);
10369 lglpushstk (lgl, &lgl->seen, -lit);
10370 LOG (3, "pulled in literal %d during probing analysis", -lit);
10374 static int lglprbana (LGL * lgl, int probe) {
10375 int open, lit, r0, r1, tag, red, other, res, * p, * rsn;
10376 assert (lgl->level == 1);
10377 assert (lgl->conf.lit);
10378 assert (lglmtstk (&lgl->seen));
10379 lit = lgl->conf.lit;
10380 r0 = lgl->conf.rsn[0], r1 = lgl->conf.rsn[1];
10381 open = lglprbpull (lgl, lit, probe);
10382 LOG (2, "starting probing analysis with reason of literal %d", lit);
10384 assert (lglevel (lgl, lit) == 1);
10386 if (tag == BINCS || tag == TRNCS) {
10387 other = r0 >> RMSHFT;
10388 if (lglprbpull (lgl, other, probe)) open++;
10389 if (tag == TRNCS && lglprbpull (lgl, r1, probe)) open++;
10391 assert (tag == LRGCS);
10393 p = lglidx2lits (lgl, red, r1);
10394 while ((other = *p++)) open += lglprbpull (lgl, other, probe);
10396 LOG (3, "open %d antecedents in probing analysis", open-1);
10398 while (!lglmarked (lgl, lit = lglpopstk (&lgl->trail)))
10399 lglunassign (lgl, lit);
10400 lglunassign (lgl, lit);
10401 if (!--open) { res = lit; break; }
10402 LOG (2, "analyzing reason of literal %d in probing analysis next", lit);
10403 rsn = lglrsn (lgl, lit);
10404 r0 = rsn[0], r1 = rsn[1];
10408 LOG (2, "probing analysis returns the probe %d as 1st UIP", probe);
10410 LOG (2, "probing analysis returns different 1st UIP %d and not probe %d",
10412 lglpopnunmarkstk (lgl, &lgl->seen);
10416 static int lglederef (LGL * lgl, int elit) {
10420 if (abs (elit) > lgl->maxext) return -1;
10421 ext = lglelit2ext (lgl, elit);
10422 if (!(res = ext->val)) {
10423 assert (!ext->equiv);
10425 res = ilit ? lglcval (lgl, ilit) : -1;
10427 if (elit < 0) res = -res;
10431 static int lgldecomp (LGL *); // TODO move
10433 static int lglhasbin (LGL * lgl, int a, int b) {
10434 const int * w, * eow, * p;
10435 int blit, tag, other;
10437 ha = lglhts (lgl, a);
10438 hb = lglhts (lgl, b);
10439 if (hb->count < ha->count) {
10440 SWAP (int, a, b); SWAP (HTS *, ha, hb);
10442 w = lglhts2wchs (lgl, ha);
10443 eow = w + ha->count;
10444 for (p = w; p < eow; p++) {
10446 tag = blit & MASKCS;
10447 if (tag == OCCS) continue;
10448 if (tag == TRNCS || tag == LRGCS) { p++; continue; }
10449 assert (tag == BINCS);
10450 other = blit >> RMSHFT;
10451 if (other == b) return 1;
10456 static void lglwrkinit (LGL * lgl, int posonly, int fifo) {
10459 lgl->wrk->fifo = fifo;
10460 size = lgl->wrk->size = lgl->nvars;
10462 NEW (lgl->wrk->pos, size);
10463 lgl->wrk->posonly = 1;
10465 NEW (lgl->wrk->pos, 2*size);
10466 lgl->wrk->pos += size;
10467 for (lit = -size + 1; lit < -1; lit++) lgl->wrk->pos[lit] = -1;
10469 for (lit = 2; lit < size; lit++) lgl->wrk->pos[lit] = -1;
10472 static void lglwrkreset (LGL * lgl) {
10473 lglrelstk (lgl, &lgl->wrk->queue);
10474 if (lgl->wrk->posonly) DEL (lgl->wrk->pos, lgl->wrk->size);
10476 lgl->wrk->pos -= lgl->wrk->size;
10477 DEL (lgl->wrk->pos, 2*lgl->wrk->size);
10482 static void lglwrkcompact (LGL * lgl) {
10483 int i, j = 0, lit, tail = lglcntstk (&lgl->wrk->queue);
10484 for (i = lgl->wrk->head; i < tail; i++) {
10485 lit = lgl->wrk->queue.start[i];
10486 if (!lit) continue;
10487 assert (!lgl->wrk->posonly || 1 < lit);
10488 assert (1 < abs (lit) && abs (lit) < lgl->wrk->size);
10489 assert (lgl->wrk->pos[lit] == i);
10490 if (!lglisfree (lgl, lit)) {
10491 lgl->wrk->pos[lit] = -1;
10492 assert (lgl->wrk->count > 0);
10495 lgl->wrk->queue.start[j] = lit;
10496 lgl->wrk->pos[lit] = j++;
10499 lglrststk (&lgl->wrk->queue, j);
10500 lgl->wrk->head = 0;
10503 static int lglwrktouched (LGL * lgl, int lit) {
10504 if (lgl->wrk->posonly) lit = abs (lit);
10505 return lgl->wrk->pos[lit] >= 0;
10508 static int lglwrktouch (LGL * lgl, int lit) {
10510 if (!lglisfree (lgl, lit)) return 1;
10511 if (lgl->donotsched) {
10512 if (lgl->cgrclosing && lglavar (lgl, lit)->donotcgrcls) return 1;
10513 if (lgl->ternresing && lglavar (lgl, lit)->donoternres) return 1;
10514 if (lgl->simpleprobing && lglavar (lgl, lit)->donotsimpleprobe) return 1;
10516 if (lgl->wrk->posonly) lit = abs (lit);
10517 tail = lglcntstk (&lgl->wrk->queue);
10518 LOG (4, "work touch %d", lit);
10519 if ((pos = lgl->wrk->pos[lit]) >= 0) {
10520 assert (lgl->wrk->queue.start[pos] == lit);
10521 lgl->wrk->queue.start[pos] = 0;
10524 assert (lgl->wrk->count > 0);
10525 lgl->wrk->pos[lit] = tail;
10526 lglpushstk (lgl, &lgl->wrk->queue, lit);
10527 if (tail/2 > lgl->wrk->count) lglwrkcompact (lgl);
10531 static int lglwrkdeq (LGL * lgl) {
10533 while ((pos = lgl->wrk->head) < lglcntstk (&lgl->wrk->queue)) {
10535 res = lgl->wrk->queue.start[pos];
10536 if (!res) continue;
10537 lgl->wrk->queue.start[pos] = 0;
10538 assert (lgl->wrk->count > 0);
10540 assert (lgl->wrk->pos[res] == pos);
10541 lgl->wrk->pos[res] = -1;
10542 if (lglisfree (lgl, res)) return res;
10547 static int lglwrkpop (LGL * lgl) {
10549 while (lglcntstk (&lgl->wrk->queue) > lgl->wrk->head) {
10550 res = lglpopstk (&lgl->wrk->queue);
10551 if (!res) continue;
10554 int pos = lglcntstk (&lgl->wrk->queue);
10555 assert (lgl->wrk->pos[res] == pos);
10558 lgl->wrk->pos[res] = -1;
10559 if (lglisfree (lgl, res)) return res;
10564 static int lglwrknext (LGL * lgl) {
10565 return lgl->wrk->fifo ? lglwrkdeq (lgl) : lglwrkpop (lgl);
10568 static int lglrandlitrav (LGL * lgl, int (*fun)(LGL*,int lit)) {
10569 int delta, mod, prev, first, ulit, count;
10570 if (lgl->nvars < 2) return 0;
10571 first = mod = 2*lgl->nvars;
10572 ulit = lglrand (lgl) % mod;
10573 delta = lglrand (lgl) % mod;
10574 if (!delta) delta++;
10575 while (lglgcd (delta, mod) > 1)
10576 if (++delta == mod) delta = 1;
10579 "random literal traversal start %d delta %d mod %d",
10583 assert (count >= 0);
10584 if (ulit >= 4 && !fun (lgl, lglilit (ulit))) return 0;
10587 if (ulit >= mod) ulit -= mod;
10588 if (ulit == first) { assert (!count); break; }
10589 if (first == mod) first = prev;
10594 static void lglsimpleprobeinit (LGL * lgl) {
10595 int idx, rem = 0, ret = 0;
10596 for (idx = 2; idx < lgl->nvars; idx++) lgl->avars[idx].equiv = 0;
10597 for (idx = 2; idx < lgl->nvars; idx++) {
10598 if (!lglisfree (lgl, idx)) continue;
10599 if (lglavar (lgl, idx)->donotsimpleprobe) ret++; else rem++;
10603 for (idx = 2; idx < lgl->nvars; idx++) {
10604 if (!lglisfree (lgl, idx)) continue;
10605 lglavar (lgl, idx)->donotsimpleprobe = 0;
10610 lglprt (lgl, 1, "[simpleprobe-%d] all %d free variables schedulable",
10611 lgl->stats->prb.simple.count, rem);
10614 "[simpleprobe-%d] %d schedulable variables %.0f%%",
10615 lgl->stats->prb.simple.count, rem, lglpcnt (rem, lglrem (lgl)));
10616 lglwrkinit (lgl, 0, 1);
10617 assert (!lgl->donotsched), lgl->donotsched = 1;
10618 lglrandlitrav (lgl, lglwrktouch);
10619 assert (lgl->donotsched), lgl->donotsched = 0;
10620 assert (lgl->opts->prbsimple.val);
10621 lglchkirrstats (lgl);
10624 static void lglsimpleprobereset (LGL * lgl, int nvars) {
10627 lglrelstk (lgl, &lgl->sprb->units);
10628 lglrelstk (lgl, &lgl->sprb->impls);
10629 lglrelstk (lgl, &lgl->sprb->eqs);
10630 for (idx = 2; idx < lgl->nvars; idx++) lgl->avars[idx].donotsimpleprobe = 1;
10631 for (p = lgl->wrk->queue.start; p < lgl->wrk->queue.top; p++)
10632 lgl->avars[abs (*p)].donotsimpleprobe = 0;
10634 lglrelstk (lgl, &lgl->sprb->counted);
10635 lglrelstk (lgl, &lgl->sprb->marked);
10636 assert (nvars == lgl->nvars);
10637 lgl->sprb->spes -= nvars;
10638 DEL (lgl->sprb->spes, 2*nvars);
10641 static int lglflush (LGL *);
10642 static void lgldense (LGL *, int);
10643 static void lglsparse (LGL *);
10645 static int lglsimpleprobeunits (LGL * lgl) {
10650 lglchkirrstats (lgl);
10651 for (p = lgl->sprb->units.start; !lgl->mt && p < lgl->sprb->units.top; p++) {
10653 val = lglval (lgl, lit);
10654 if (val > 0) continue;
10655 lgl->stats->prb.simple.failed++;
10657 if (lgl->opts->drup.val) lgldrupclsarg (lgl, lit, 0);
10658 LOG (1, "inconsistent unit %d", lit);
10661 lglunit (lgl, lit);
10663 if (!lglflush (lgl)) {
10664 LOG (1, "propagating simple HBR unit %d results in conflict", lit);
10672 static int lglsimpleprobeimpls (LGL * lgl) {
10675 while (!lglmtstk (&lgl->sprb->impls)) {
10676 b = lglpopstk (&lgl->sprb->impls);
10677 a = lglpopstk (&lgl->sprb->impls);
10678 if (lglval (lgl, a) || lglval (lgl, b)) continue;
10679 if (lglhasbin (lgl, a, b)) continue;
10680 LOG (2, "adding previously detected hyper binary resolvent %d %d", a, b);
10681 if (lgl->opts->drup.val) lgldrupclsarg (lgl, a, b, 0);
10682 #ifndef NLGLPICOSAT
10683 lglpicosatchkclsarg (lgl, a, b, 0);
10686 lgl->stats->hbr.cnt++;
10687 lgl->stats->hbr.simple++;
10688 (void) lglwchbin (lgl, a, b, REDCS);
10689 (void) lglwchbin (lgl, b, a, REDCS);
10690 lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
10691 lglwrktouch (lgl, -a);
10692 lglwrktouch (lgl, -b);
10693 if (!lglhasbin (lgl, -a, -b)) continue;
10694 LOG (2, "found equivalent literals %d and %d", -a, b);
10695 lglpushstk (lgl, &lgl->sprb->eqs, -a);
10696 lglpushstk (lgl, &lgl->sprb->eqs, b);
10701 static int lglhasonlybin (LGL * lgl, int lit, int other) {
10702 HTS * hts = lglhts (lgl, lit);
10705 if (hts->count != 1) return 0;
10706 w = lglhts2wchs (lgl, hts);
10708 if ((blit & MASKCS) != BINCS) return 0;
10709 return (blit >> RMSHFT) == other;
10712 static int lglsimpleprobemerged (LGL * lgl, int a, int b) {
10713 return lglhasonlybin (lgl, -a, b) && lglhasonlybin (lgl, -b, a);
10716 static int lglflushclauses (LGL * lgl, int lit);
10718 static void lglsimpleprobeclscp (LGL * lgl, int nonrepr, int repr, Stk * stk) {
10719 int blit, tag, red, other, other2, lidx, count, found, start, trivial;
10720 const int * p, * w, * eow, * c, * q;
10721 HTS * hts = lglhts (lgl, nonrepr);
10722 assert (abs (repr) < abs (nonrepr));
10723 w = lglhts2wchs (lgl, hts);
10724 eow = w + hts->count;
10726 for (p = w; p < eow; p++) {
10727 INCSTEPS (prb.simple.steps);
10729 tag = blit & MASKCS;
10730 if (tag == TRNCS || tag == LRGCS) p++;
10731 if (tag == LRGCS) continue;
10732 start = lglcntstk (stk);
10734 red = blit & REDCS;
10735 lglpushstk (lgl, stk, red);
10736 lglpushstk (lgl, stk, repr);
10737 if (tag == BINCS || tag == TRNCS) {
10738 other = blit >> RMSHFT;
10739 if (other == -repr) trivial = 1;
10740 else if (other != repr) lglpushstk (lgl, stk, other);
10741 if (tag == TRNCS) {
10743 if (other2 == -repr) trivial = 1;
10744 else if (other2 != repr) lglpushstk (lgl, stk, other2);
10747 assert (tag == OCCS);
10748 lidx = blit >> RMSHFT;
10749 c = lglidx2lits (lgl, red, lidx);
10751 for (q = c; !trivial && (other = *q); q++) {
10752 if (other >= NOTALIT) trivial = 1;
10753 else if (other == nonrepr) found++;
10754 else if (other == -repr) trivial = 1;
10755 else if (other != repr) lglpushstk (lgl, stk, other);
10757 assert (trivial || found);
10759 if (trivial) lglrststk (stk, start);
10760 else lglpushstk (lgl, stk, 0), count++;
10762 LOG (2, "copied %d clauses with %d replacing %d by %d",
10763 count, nonrepr, nonrepr, repr);
10766 static int lglsimpleprobebinexists (LGL * lgl, int a, int b) {
10767 const int * p, * w, * eow;
10768 int blit, tag, red, other;
10770 hts = lglhts (lgl, a);
10771 w = lglhts2wchs (lgl, hts);
10772 eow = w + hts->count;
10773 for (p = w; p < eow; p++) {
10775 tag = blit & MASKCS;
10776 if (tag == TRNCS || tag == LRGCS) p++;
10777 if (tag != BINCS) continue;
10778 red = blit & REDCS;
10780 other = blit >> RMSHFT;
10781 if (other == b) return 1;
10786 static int lglsimpleprobetrnexists (LGL * lgl, int a, int b, int c) {
10787 int blit, tag, red, other, other2;
10788 const int * p, * w, * eow;
10790 hts = lglhts (lgl, a);
10791 w = lglhts2wchs (lgl, hts);
10792 eow = w + hts->count;
10793 for (p = w; p < eow; p++) {
10795 tag = blit & MASKCS;
10796 if (tag == TRNCS || tag == LRGCS) p++;
10797 red = blit & REDCS;
10799 other = blit >> RMSHFT;
10800 if (tag == BINCS) {
10801 if (other == b) return 1;
10802 if (other == c) return 1;
10803 } else if (tag == TRNCS) {
10805 if (other == b && other2 == c) return 1;
10806 if (other == c && other2 == b) return 1;
10812 static int lglsimpleprobelrgexists (LGL * lgl, int a) {
10813 int blit, tag, red, other, other2, lidx, res;
10814 const int * p, * w, * eow, * c, * q;
10816 for (p = lgl->clause.start; p + 1 < lgl->clause.top; p++) {
10818 assert (!lglsignedmarked (lgl, other));
10819 lglsignedmark (lgl, other);
10821 assert (lglsignedmarked (lgl, a));
10822 hts = lglhts (lgl, a);
10823 w = lglhts2wchs (lgl, hts);
10824 eow = w + hts->count;
10826 for (p = w; !res && p < eow; p++) {
10828 tag = blit & MASKCS;
10829 if (tag == TRNCS || tag == LRGCS) p++;
10830 red = blit & REDCS;
10831 if (red || tag == LRGCS) continue;
10832 other = blit >> RMSHFT;
10833 if (tag == BINCS) {
10834 res = lglsignedmarked (lgl, other);
10835 } else if (tag == TRNCS) {
10837 res = lglsignedmarked (lgl, other) && lglsignedmarked (lgl, other2);
10839 assert (tag == OCCS);
10841 c = lglidx2lits (lgl, 0, lidx);
10842 for (q = c; (other = *q); q++)
10843 if (!lglsignedmarked (lgl, other)) break;
10847 for (p = lgl->clause.start; p + 1 < lgl->clause.top; p++)
10848 lglunmark (lgl, *p);
10852 static int lglsimpleprobeclausexists (LGL * lgl) {
10853 int len = lglcntstk (&lgl->clause) - 1, a, b, c, * p, * s, res;
10855 assert (!lgl->clause.top[-1]);
10856 s = lgl->clause.start;
10857 for (p = s + 1; p + 1 < lgl->clause.top; p++)
10858 if (lglhts (lgl, *s)->count > lglhts (lgl, *p)->count)
10859 SWAP (int, *s, *p);
10860 a = lgl->clause.start[0];
10862 b = lgl->clause.start[1];
10863 res = lglsimpleprobebinexists (lgl, a, b);
10864 } else if (len == 3) {
10865 b = lgl->clause.start[1];
10866 c = lgl->clause.start[2];
10867 res = lglsimpleprobetrnexists (lgl, a, b, c);
10868 } else if (len > 3)
10869 res = lglsimpleprobelrgexists (lgl, a);
10871 if (res) LOG (2, "will not add already existing clause");
10875 static void lglsimpleprobeaddclausesonstack (LGL * lgl, Stk * stk) {
10876 int count, red, lit, size;
10877 const int * c, * p, * q;
10879 for (c = stk->start; c < stk->top; c = p + 1) {
10881 if (p[1] == REMOVED) {
10883 while (p + 1 < stk->top && p[1] == REMOVED) p++;
10886 assert (!red || red == REDCS);
10887 assert (lglmtstk (&lgl->clause));
10890 lglpushstk (lgl, &lgl->clause, lit);
10892 if (!lglsimpcls (lgl) && !lglsimpleprobeclausexists (lgl)) {
10893 if (lgl->opts->drup.val) lgldrupcls (lgl);
10894 #ifndef NLGLPICOSAT
10895 lglpicosatchkcls (lgl);
10897 q = lgl->clause.start;
10898 size = lglcntstk (&lgl->clause);
10900 assert (!q[size-1]);
10902 if (size > 2 && lgl->opts->prbsimple.val >= 3)
10903 while ((lit = *q++))
10904 lglwrktouch (lgl, lit);
10905 if (size == 2 && lgl->opts->prbsimple.val >= 2)
10906 lglwrktouch (lgl, -q[0]),
10907 lglwrktouch (lgl, -q[1]);
10908 lgldrupligaddcls (lgl, REDCS);
10909 lgladdcls (lgl, red, 0, 1);
10912 lglclnstk (&lgl->clause);
10913 if (!lglflush (lgl)) break;
10915 LOG (2, "added %d non-trivial clauses", count);
10918 static void lglsimpleprobeaddprbincls (LGL * lgl, int a, int b) {
10919 assert (lgl->probing);
10920 assert (lglmtstk (&lgl->clause));
10921 assert (abs (a) != abs (b));
10922 assert (!lglval (lgl, a));
10923 assert (!lglval (lgl, b));
10924 lglpushstk (lgl, &lgl->clause, a);
10925 lglpushstk (lgl, &lgl->clause, b);
10926 lglpushstk (lgl, &lgl->clause, 0);
10927 if (!lglsimpleprobeclausexists (lgl)) {
10928 LOG (2, "added simple probing connecting binary clause", a, b);
10929 if (lgl->opts->drup.val) lgldrupcls (lgl);
10930 #ifndef NLGLPICOSAT
10931 lglpicosatchkcls (lgl);
10933 lgldrupligaddcls (lgl, REDCS);
10934 lgladdcls (lgl, 0, 0, 1);
10936 lglclnstk (&lgl->clause);
10939 static int lglcmpilit (int * a, int * b) {
10940 int res, l = *a, k = *b;
10941 if ((res = abs (l) - abs (k))) return res;
10945 static int lglcmpcls (LGL * lgl, const int * c, const int * d) {
10946 const int * p, * q;
10947 for (p = c, q = d; *p && *q == *p; p++, q++)
10952 static int lglcmpsz (LGL * lgl, const int * start, PSz * p, PSz * q) {
10953 const int * c, * d;
10955 if ((res = p->size - q->size)) return res;
10956 c = start + p->pos, d = start + q->pos;
10957 if ((res = lglcmpcls (lgl, c, d))) return res;
10958 if ((res = c[-1] - d[-1])) return res;
10959 return p->pos - q->pos;
10962 #define LGLCMPSZ(A,B) (lglcmpsz(lgl, start, (A), (B)))
10964 static void lglrmdupclsonstack (LGL * lgl, Stk * stk, Stk * sort) {
10965 int * start, * c, * p, * d, pos, size, i;
10968 start = stk->start;
10969 for (c = start; c < stk->top; c = p + 1) {
10971 assert (c < stk->top);
10974 for (p = c; *p; p++) size++;
10975 SORT (int, c, size, lglcmpilit);
10976 lglpushstk (lgl, sort, pos);
10977 lglpushstk (lgl, sort, size);
10979 size = lglcntstk (sort)/2;
10980 if (size <= 1) return;
10981 ps = (PSz *) sort->start;
10982 SORT (PSz, ps, size, LGLCMPSZ);
10983 for (i = 1; i < size; i++) {
10984 if (ps[i-1].size != ps[i].size) continue;
10985 c = stk->start + ps[i-1].pos;
10986 d = stk->start + ps[i].pos;
10987 if (lglcmpcls (lgl, c, d)) continue;
10988 LOGCLS (4, d, "not copying duplicate %s clause", lglred2str (d[-1]));
10989 while (*d) *d++ = REMOVED;
10994 static void lglsimpleprobemerge (LGL * lgl, int repr, int nonrepr) {
10995 Val valrepr, valnonrepr;
10998 lglchkirrstats (lgl);
10999 lgl->stats->prb.simple.eqs++;
11000 assert (abs (repr) < abs (nonrepr));
11001 lglavar (lgl, nonrepr)->equiv = 1;
11002 CLR (stk); CLR (sort);
11003 lglsimpleprobeclscp (lgl, nonrepr, repr, &stk);
11004 lglsimpleprobeclscp (lgl, -nonrepr, -repr, &stk);
11005 lglflushclauses (lgl, nonrepr);
11006 lglflushclauses (lgl, -nonrepr);
11007 lglrmdupclsonstack (lgl, &stk, &sort);
11008 lglsimpleprobeaddclausesonstack (lgl, &stk);
11009 lglrelstk (lgl, &sort);
11010 lglrelstk (lgl, &stk);
11011 if (lgl->mt) return;
11012 valrepr = lglval (lgl, repr);
11013 valnonrepr = lglval (lgl, nonrepr);
11014 if (valrepr && valnonrepr == valrepr) return;
11015 if (valrepr && valrepr == -valrepr) {
11016 LOG (1, "equality between %d and %d became inconsistent", repr, nonrepr);
11020 if (valrepr && !valnonrepr) unit = valrepr < 0 ? -nonrepr : nonrepr;
11021 else if (!valrepr && valnonrepr) unit = valnonrepr < 0 ? -repr : repr;
11022 else unit = 0, assert (!valrepr), assert (!valnonrepr);
11024 LOG (1, "new unit %d from equality between %d and %d", unit, repr, nonrepr);
11025 lglunit (lgl, unit);
11026 (void) lglflush (lgl);
11027 } else lglsimpleprobeaddprbincls (lgl, repr, -nonrepr),
11028 lglsimpleprobeaddprbincls (lgl, -repr, nonrepr);
11029 lglchkirrstats (lgl);
11032 static int lglsimpleprobeqs (LGL * lgl) {
11035 while (!lgl->mt && !lglmtstk (&lgl->sprb->eqs)) {
11036 a = lglpopstk (&lgl->sprb->eqs);
11037 b = lglpopstk (&lgl->sprb->eqs);
11038 if (lglval (lgl, a)) continue;
11039 assert (!lglval (lgl, b));
11040 assert (abs (a) != abs (b));
11041 if (lglsimpleprobemerged (lgl, a, b)) continue;
11042 if (abs (b) < abs (a)) SWAP (int, a, b);
11043 lglsimpleprobemerge (lgl, a, b);
11049 static SPE * lglspe (LGL * lgl, int lit) {
11050 assert (2 <= abs (lit) && abs (lit) < lgl->nvars);
11051 return lgl->sprb->spes + lit;
11054 static void lglsimpleprobehbr (LGL * lgl, int touched, const int * c) {
11055 int blit, tag, lit, other, count, val, maxcount, rem, first, second;
11056 const int * p, * q, * w, * eow;
11060 first = second = count = sum = 0;
11061 for (p = c; (lit = *p); p++) {
11062 if (lglwrktouched (lgl, lit)) return;
11063 if ((val = lglval (lgl, lit)) > 0) return;
11064 if (val < 0) continue;
11065 if (!first) first = lit;
11066 else if (!second) second = lit;
11067 sum += (unsigned) lit;
11071 assert (first && second);
11072 if (lglhasbin (lgl, -first, -second)) {
11073 LOG (2, "found equivalent literals %d and %d", -first, second);
11074 lglpushstk (lgl, &lgl->sprb->eqs, -first);
11075 lglpushstk (lgl, &lgl->sprb->eqs, second);
11081 assert (lglmtstk (&lgl->sprb->counted));
11082 for (p = c; (lit = *p); p++) {
11083 if (INCSTEPS (prb.simple.steps) >= lgl->limits->prb.steps) goto DONE;
11084 val = lglval (lgl, lit);
11087 hts = lglhts (lgl, -lit);
11088 w = lglhts2wchs (lgl, hts);
11089 eow = w + hts->count;
11090 assert (lglmtstk (&lgl->sprb->marked));
11091 for (q = w; q < eow; q++) {
11092 if (INCSTEPS (prb.simple.steps) >= lgl->limits->prb.steps) goto DONE;
11094 tag = blit & MASKCS;
11095 if (tag == TRNCS || tag == LRGCS) q++;
11096 if (tag != BINCS) continue;
11097 other = blit >> RMSHFT;
11098 val = lglval (lgl, other);
11101 if ((spe = lglspe (lgl, other))->mark) continue;
11102 if (lglspe (lgl, -other)->mark) {
11103 LOG (2, "unit %d through very simple hyper binary resolution", -lit);
11104 lglpushstk (lgl, &lgl->sprb->units, -lit);
11107 if (!spe->count) lglpushstk (lgl, &lgl->sprb->counted, other);
11108 spe->sum += (unsigned) lit;
11111 lglpushstk (lgl, &lgl->sprb->marked, other);
11112 if (spe->count > maxcount) maxcount = spe->count;
11114 while (!lglmtstk (&lgl->sprb->marked)) {
11115 other = lglpopstk (&lgl->sprb->marked);
11116 spe = lglspe (lgl, other);
11117 assert (spe->mark);
11121 assert (maxcount + rem <= count);
11122 if (maxcount + rem + 1 < count) goto DONE;
11124 if (count <= 2) goto DONE;
11125 for (q = lgl->sprb->counted.start; q < lgl->sprb->counted.top; q++) {
11127 assert (!lglval (lgl, other));
11128 spe = lglspe (lgl, other);
11129 assert (spe->count <= count);
11130 if (spe->count == count) {
11131 LOG (2, "unit %d through simple hyper binary resolution", other);
11132 lglpushstk (lgl, &lgl->sprb->units, other);
11133 } else if (spe->count + 1 == count) {
11134 tmp = sum - spe->sum;
11136 assert (2 <= abs (lit) && abs (lit) < lgl->nvars);
11137 if (abs (lit) != abs (other) && !lglhasbin (lgl, other, lit)) {
11138 LOG (2, "simple hyper binary resolvent %d %d", other, lit);
11139 lglpushstk (lgl, &lgl->sprb->impls, other);
11140 lglpushstk (lgl, &lgl->sprb->impls, lit);
11144 for (p = c; (lit = *p); p++) {
11145 if (lglval (lgl, lit)) continue;
11146 spe = lglspe (lgl, lit);
11147 if (spe->count + 2 != count) continue;
11148 tmp = sum - spe->sum;
11149 tmp -= (unsigned) lit;
11151 assert (2 <= abs (other) && abs (other) < lgl->nvars);
11152 if (abs (lit) != abs (other) && !lglhasbin (lgl, other, lit)) {
11153 LOG (2, "self-subsuming hyper binary resolvent %d %d", other, lit);
11154 lglpushstk (lgl, &lgl->sprb->impls, other);
11155 lglpushstk (lgl, &lgl->sprb->impls, lit);
11159 while (!lglmtstk (&lgl->sprb->counted)) {
11160 lit = lglpopstk (&lgl->sprb->counted);
11161 spe = lglspe (lgl, lit);
11164 lglclnstk (&lgl->sprb->marked);
11167 static void lglpushnmarkseen (LGL * lgl, int lit) {
11168 lglpushstk (lgl, &lgl->seen, lit);
11169 lglmarkunmarked (lgl, lit);
11172 static void lglsignedmarknpushseen (LGL * lgl, int lit) {
11173 lglsignedmark (lgl, lit);
11174 lglpushstk (lgl, &lgl->seen, lit);
11177 static void lglsimpleliftmark (LGL * lgl, int root, int level) {
11178 const int * p, * w, * eow;
11179 int blit, tag, other;
11181 INCSTEPS (prb.simple.steps);
11182 assert (level > 0);
11183 assert (lglsignedmarked (lgl, -root));
11184 LOG (3, "next simple lifting marking from %d at level %d", root, level);
11185 hts = lglhts (lgl, root);
11186 w = lglhts2wchs (lgl, hts);
11187 eow = w + hts->count;
11188 for (p = w; p < eow; p++) {
11190 tag = blit & MASKCS;
11191 if (tag == TRNCS || tag == LRGCS) p++;
11192 if (tag != BINCS) continue;
11193 other = blit >> RMSHFT;
11194 if (lglsignedmarked (lgl, other)) continue;
11195 lglsignedmarknpushseen (lgl, other);
11196 LOG (4, "next simple lifting marking from %d at level %d marked %d",
11197 root, level, other);
11198 if (level > 1) lglsimpleliftmark (lgl, -other, level-1);
11202 static void lglsimpleliftcollect (LGL * lgl, int root, int start, int level) {
11203 const int * p, * w, * eow;
11204 int blit, tag, other;
11206 INCSTEPS (prb.simple.steps);
11207 assert (level > 0);
11208 LOG (3, "next simple lifting collecting from %d at level %d", start, level);
11209 hts = lglhts (lgl, start);
11210 w = lglhts2wchs (lgl, hts);
11211 eow = w + hts->count;
11212 for (p = w; p < eow; p++) {
11214 tag = blit & MASKCS;
11215 if (tag == TRNCS || tag == LRGCS) p++;
11216 if (tag != BINCS) continue;
11217 other = blit >> RMSHFT;
11218 if (other == -root) continue;
11219 if (lglsignedmarked (lgl, other)) {
11220 LOG (2, "simple lifted unit %d with root %d", other, root);
11221 lglpushstk (lgl, &lgl->sprb->units, other);
11222 } else if (other != root && lglsignedmarked (lgl, -other)) {
11223 LOG (2, "found equivalent literals %d and %d", root, other);
11224 lglpushstk (lgl, &lgl->sprb->eqs, root);
11225 lglpushstk (lgl, &lgl->sprb->eqs, other);
11227 if (level > 1) lglsimpleliftcollect (lgl, root, -other, level-1);
11231 static void lglsimplelift (LGL * lgl, int root) {
11232 int count, pos, neg;
11233 pos = lglhts (lgl, root)->count;
11234 neg = lglhts (lgl, -root)->count;
11235 if (neg < pos) root = -root;
11236 LOG (2, "next simple lifting %d", root);
11237 assert (lglmtstk (&lgl->seen));
11238 assert (!lglsignedmarked (lgl, -root));
11239 lglsignedmarknpushseen (lgl, -root);
11240 lglsimpleliftmark (lgl, root, lgl->opts->prbsimpleliftdepth.val);
11241 count = lglcntstk (&lgl->seen);
11242 LOG (3, "simple probing lifting marked %d literals for root %d",
11244 if (!count) return;
11245 lglsimpleliftcollect (lgl, root, -root, lgl->opts->prbsimpleliftdepth.val);
11248 int units = lglcntstk (&lgl->sprb->units);
11249 int eqs = lglcntstk (&lgl->sprb->eqs);
11250 assert (!(eqs & 1));
11252 LOG (3, "found %d units through simple lifting for %d", units, root);
11253 LOG (3, "found %d equivalences through simple lifting for %d", eqs, root);
11256 lglpopnunmarkstk (lgl, &lgl->seen);
11259 static void lglsimpleprobelit (LGL * lgl, int lit) {
11260 int blit, tag, other, other2, red, lidx, cls[4];
11261 const int * p, * w, * eow, * c;
11263 lgl->stats->prb.simple.probed++;
11264 assert (!lglval (lgl, lit));
11265 lglclnstk (&lgl->sprb->units);
11266 lglclnstk (&lgl->sprb->impls);
11267 if (!lglwrktouched (lgl, -lit)) lglsimplelift (lgl, lit);
11268 LOG (2, "next simple probing %d", lit);
11269 hts = lglhts (lgl, lit);
11270 if (!hts->count) return;
11271 w = lglhts2wchs (lgl, hts);
11272 eow = w + hts->count;
11273 for (p = w; p < eow; p++) {
11274 if (INCSTEPS (prb.simple.steps) >= lgl->limits->prb.steps) goto DONE;
11276 tag = blit & MASKCS;
11277 if (tag == TRNCS || tag == LRGCS) p++;
11278 if (tag == BINCS || tag == LRGCS) continue;
11279 if (tag == TRNCS) {
11280 other = blit >> RMSHFT;
11281 if (lglval (lgl, other)) continue;
11283 if (lglval (lgl, other2)) continue;
11284 cls[0] = lit, cls[1] = other, cls[2] = other2, cls[3] = 0;
11285 lglsimpleprobehbr (lgl, lit, cls);
11287 assert (tag == OCCS);
11288 red = (blit & REDCS);
11289 lidx = (blit >> RMSHFT);
11290 c = lglidx2lits (lgl, red, lidx);
11291 lglsimpleprobehbr (lgl, lit, c);
11295 assert (lglmtstk (&lgl->seen));
11296 lglpopnunmarkstk (lgl, &lgl->seen);
11299 static void lglprtsimpleproberem (LGL * lgl) {
11300 int idx, ret = 0, rem = 0;
11301 for (idx = 2; idx < lgl->nvars; idx++) {
11302 if (!lglisfree (lgl, idx)) continue;
11303 if (lglavar (lgl, idx)->donotsimpleprobe) ret++; else rem++;
11307 "[simpleprobe-%d] %d variables remain %.0f%% (%d retained)",
11308 lgl->stats->prb.simple.count, rem, lglpcnt (rem, lglrem (lgl)), ret);
11310 lglprt (lgl, 1, "[simpleprobe-%d] fully completed simple probing",
11311 lgl->stats->prb.simple.count);
11312 for (idx = 2; idx < lgl->nvars; idx++)
11313 lglavar (lgl, idx)->donotsimpleprobe = 0;
11317 static int lglszpen (LGL * lgl) {
11318 int res = lglceilld (lgl->stats->irr.clauses.cur/lgl->opts->sizepen.val);
11319 if (res < 0) res = 0;
11320 if (res > lgl->opts->sizemaxpen.val) res = lgl->opts->sizemaxpen.val;
11326 static int lglitszpen (LGL * lgl) {
11327 int res = lglceilld (lgl->stats->irr.lits.cur/lgl->opts->sizepen.val);
11328 if (res < 0) res = 0;
11329 if (res > lgl->opts->sizemaxpen.val + 2)
11330 res = lgl->opts->sizemaxpen.val + 2;
11336 static int64_t lglvisearch (LGL * lgl) {
11337 int64_t res = lgl->stats->visits.search;
11338 assert (res >= lgl->limits->inc.visits);
11339 res -= lgl->limits->inc.visits;
11343 static void lglsetprbsimplelim (LGL * lgl) {
11344 int64_t limit, irrlim;
11346 if (lgl->opts->prbsimplertc.val || lgl->opts->prbrtc.val) {
11347 lgl->limits->prb.steps = LLMAX;
11349 "[simpleprobe-%d] no limit (run to completion)",
11350 lgl->stats->prb.simple.count);
11352 limit = (lgl->opts->prbsimplereleff.val*lglvisearch (lgl))/1000;
11353 if (limit < lgl->opts->prbsimplemineff.val)
11354 limit = lgl->opts->prbsimplemineff.val;
11355 if (lgl->opts->prbsimplemaxeff.val >= 0 &&
11356 limit > lgl->opts->prbsimplemaxeff.val)
11357 limit = lgl->opts->prbsimplemaxeff.val;
11358 if (lgl->stats->prb.simple.count <= 1 &&
11359 lgl->opts->boost.val &&
11360 lgl->opts->prbsimpleboost.val > 1) {
11362 "[simpleprobe-%d] boosting simple probing limit by %d",
11363 lgl->stats->prb.simple.count, lgl->opts->prbsimpleboost.val);
11364 limit *= lgl->opts->prbsimpleboost.val;
11366 limit >>= (pen = lgl->limits->prb.simple.pen + lglszpen (lgl));
11367 irrlim = lgl->stats->irr.clauses.cur/4;
11368 irrlim >>= lgl->limits->simp.pen;
11369 if (lgl->opts->irrlim.val && limit < irrlim) {
11372 "[simpleprobe-%d] limit %lld based on %d irredundant clauses",
11373 lgl->stats->prb.simple.count,
11374 (LGLL) limit, lgl->stats->irr.clauses.cur);
11377 "[simpleprobe-%d] limit %lld penalty %d = %d + %d",
11378 lgl->stats->prb.simple.count, (LGLL) limit,
11379 pen, lgl->limits->prb.simple.pen, lglszpen (lgl));
11380 lgl->limits->prb.steps = lgl->stats->prb.simple.steps + limit;
11384 static int lgldelaying (LGL * lgl, const char * name, int * delptr) {
11385 if (!*delptr) return 0;
11388 "[%s-delayed] skipping this scheduled invocation and %d more",
11393 static int lglsimpleprobe (LGL * lgl) {
11394 int deltarem, nunits, hbrs, neqs, oldrem = lglrem (lgl);
11395 int lit, success, nvars;
11397 if (lgldelaying (lgl, "simpleprobe",
11398 &lgl->limits->prb.simple.del.rem)) return 1;
11400 lglstart (lgl, &lgl->times->prb.simple);
11401 lgl->stats->prb.simple.count++;
11403 assert (!lgl->simp && !lgl->probing && !lgl->simpleprobing);
11404 lgl->simp = lgl->probing = lgl->simpleprobing = 1;
11407 NEW (lgl->sprb, 1);
11409 if (lgl->level > 0) lglbacktrack (lgl, 0);
11411 assert (lgl->frozen);
11413 lglsimpleprobeinit (lgl);
11414 lglsetprbsimplelim (lgl);
11415 neqs = hbrs = nunits = 0;
11417 nvars = lgl->nvars;
11418 NEW (lgl->sprb->spes, 2*nvars);
11419 lgl->sprb->spes += nvars;
11421 while (!lgl->mt && (lit = lglwrknext (lgl))) {
11422 if (INCSTEPS (prb.simple.steps) >= lgl->limits->prb.steps) break;
11423 if (!lglisfree (lgl, lit)) continue;
11424 if (lglavar (lgl, lit)->equiv) continue;
11425 lglsimpleprobelit (lgl, lit);
11426 if (lgl->mt) break;
11427 lglchkirrstats (lgl);
11428 nunits += lglsimpleprobeunits (lgl);
11429 if (lgl->mt) break;
11430 hbrs += lglsimpleprobeimpls (lgl);
11431 if (lgl->mt) break;
11432 neqs += lglsimpleprobeqs (lgl);
11433 if (!lglflush (lgl)) break;
11434 if (lglterminate (lgl)) break;
11435 if (!lglsyncunits (lgl)) break;
11438 lglsimpleprobereset (lgl, nvars);
11440 if (!lgl->mt) lgldecomp (lgl);
11442 DEL (lgl->sprb, 1);
11444 deltarem = oldrem - lglrem (lgl);
11445 success = deltarem || hbrs || nunits;
11446 LGLUPDPEN (prb.simple, deltarem);
11447 lglprtsimpleproberem (lgl);
11449 lglprt (lgl, 1 + !success,
11450 "[simpleprobe-%d] removed %d variables, found %d hbrs, %d units",
11451 lgl->stats->prb.simple.count, deltarem, hbrs, nunits);
11453 assert (lgl->simp && lgl->probing && lgl->simpleprobing);
11454 lgl->simp = lgl->probing = lgl->simpleprobing = 0;
11455 lglrep (lgl, 2, 'p');
11460 static void lglmvbcls (LGL * lgl, int a, int b) {
11461 assert (abs (a) != abs (b));
11462 assert (!lglval (lgl, a));
11463 assert (!lglval (lgl, b));
11464 assert (lglmtstk (&lgl->clause));
11465 lglpushstk (lgl, &lgl->clause, a);
11466 lglpushstk (lgl, &lgl->clause, b);
11467 lglpushstk (lgl, &lgl->clause, 0);
11468 if (!lglsimpleprobeclausexists (lgl)) {
11469 LOG (2, "moving redundant binary clause %d %d", a, b);
11470 #ifndef NLGLPICOSAT
11471 lglpicosatchkcls (lgl);
11473 lgldrupligaddcls (lgl, REDCS);
11474 lgladdcls (lgl, REDCS, 0, 1);
11476 lglclnstk (&lgl->clause);
11477 lgl->stats->moved.bin++;
11480 static void lglrmvbcls (LGL * lgl, int a, int b) {
11481 lglrmbcls (lgl, a, b, 0);
11482 if (lgl->opts->move.val) lglmvbcls (lgl, a, b);
11485 static void lglmvtcls (LGL * lgl, int a, int b, int c) {
11486 assert (abs (a) != abs (b));
11487 assert (abs (a) != abs (c));
11488 assert (abs (b) != abs (c));
11489 assert (lglmtstk (&lgl->clause));
11490 lglpushstk (lgl, &lgl->clause, a);
11491 lglpushstk (lgl, &lgl->clause, b);
11492 lglpushstk (lgl, &lgl->clause, c);
11493 lglpushstk (lgl, &lgl->clause, 0);
11494 if (!lglsimpleprobeclausexists (lgl)) {
11495 LOG (2, "moving redundant ternary clause %d %d %d", a, b, c);
11496 #ifndef NLGLPICOSAT
11497 lglpicosatchkcls (lgl);
11499 lgldrupligaddcls (lgl, REDCS);
11500 lgladdcls (lgl, REDCS, 0, 1);
11502 lglclnstk (&lgl->clause);
11503 lgl->stats->moved.trn++;
11506 static void lglrmvtcls (LGL * lgl, int a, int b, int c) {
11507 assert (abs (a) != abs (b));
11508 assert (abs (a) != abs (c));
11509 assert (abs (b) != abs (c));
11510 lglrmtcls (lgl, a, b, c, 0);
11511 if (lgl->opts->move.val >= 2) lglmvtcls (lgl, a, b, c);
11514 static void lglmvlcls (LGL * lgl, int lidx) {
11515 const int * p, * c;
11517 assert (lglmtstk (&lgl->clause));
11518 c = lglidx2lits (lgl, 0, lidx);
11519 for (p = c; (other = *p); p++)
11520 lglpushstk (lgl, &lgl->clause, other);
11521 lglpushstk (lgl, &lgl->clause, 0);
11522 if (!lglsimpleprobeclausexists (lgl)) {
11523 LOGCLS (2, c, "moving redundant large clause");
11524 #ifndef NLGLPICOSAT
11525 lglpicosatchkcls (lgl);
11527 lgldrupligaddcls (lgl, REDCS);
11528 lgladdcls (lgl, REDCS, 0, 0);
11530 lglclnstk (&lgl->clause);
11531 lgl->stats->moved.lrg++;
11534 static void lglrmvlcls (LGL * lgl, int lidx) {
11535 if (lgl->opts->move.val >= 3) lglmvlcls (lgl, lidx);
11536 lglrmlcls (lgl, lidx, 0);
11539 static int lglwaiting (LGL * lgl, const char * str, int wait) {
11540 if (!wait) return 0;
11541 if (!lgl->wait) return 0;
11542 if (wait >= 2 && lgl->opts->elim.val && !lgl->elmrtc) {
11545 "[%s-waiting] on variable elimination to be completed", str);
11548 if (wait >= 1 && lgl->opts->block.val && !lgl->blkrtc) {
11551 "[%s-waiting] on blocked clause elimination to be completed", str);
11557 static void lglbasicate (LGL * lgl, int lit) {
11558 int blit, tag, red, other, other2, lidx;
11559 const int * w, * eow, * p, * c, * l;
11560 int nonfalse, numtrue, val;
11562 if (!lgl->opts->bate.val) return;
11563 if (lglwaiting (lgl, 0, lgl->opts->batewait.val)) return;
11565 hts = lglhts (lgl, -lit);
11566 w = lglhts2wchs (lgl, hts);
11567 eow = w + hts->count;
11568 for (p = w; p < eow; p++) {
11570 tag = blit & MASKCS;
11571 if (tag == TRNCS || tag == LRGCS) p++;
11572 red = blit & REDCS;
11574 if (tag == BINCS) continue;
11575 if (tag == TRNCS) {
11576 other = blit >> RMSHFT;
11578 if ((val = lglval (lgl, other)) < 0) continue;
11580 if (!lglevel (lgl, other)) continue;
11581 if (lgltd (lgl, other)->irr) numtrue++;
11584 if ((val = lglval (lgl, other2)) < 0) continue;
11586 if (!lglevel (lgl, other2)) continue;
11587 if (lgltd (lgl, other2)->irr) numtrue++;
11589 if (!numtrue) continue;
11590 LOG (2, "basic ATE ternary clause %d %d %d", -lit, other, other2);
11591 lgl->stats->prb.basic.ate.trnr++;
11592 lglrmvtcls (lgl, -lit, other, other2);
11595 assert (tag == OCCS || tag == LRGCS);
11596 if (tag == LRGCS && lgl->dense) continue;
11597 lidx = (tag == LRGCS) ? *p : (blit >> RMSHFT);
11599 c = lglidx2lits (lgl, 0, lidx);
11600 numtrue = nonfalse = 0;
11601 for (l = c; (nonfalse < 2 || !numtrue) && (other = *l); l++) {
11602 if (other == -lit) continue;
11603 assert (other != lit);
11604 if ((val = lglval (lgl, other)) >= 0) nonfalse++;
11606 if (!lglevel (lgl, other)) { numtrue = -1; break; }
11607 if (lgltd (lgl, other)->irr) numtrue++;
11610 if (numtrue > 0 && nonfalse >= 2) {
11611 LOGCLS (2, c, "basic ATE large clause");
11612 lgl->stats->prb.basic.ate.lrg++;
11613 lglrmvlcls (lgl, lidx);
11620 static void lglbasicatestats (LGL * lgl) {
11621 int n = lgl->stats->prb.basic.ate.lrg + lgl->stats->prb.basic.ate.trnr;
11622 int d = n - lgl->stats->prb.basic.lastate;
11624 if (d <= 0) return;
11625 lgl->stats->prb.basic.ate.count++;
11627 "[bate-%d] eliminated %d asymmetric tautologies during probing",
11628 lgl->stats->prb.basic.ate.count, d);
11629 lgl->stats->prb.basic.lastate = n;
11632 static void lglbasicprobelit (LGL * lgl, int root) {
11633 int old, ok, dom, lit, val;
11636 CLR (lift); CLR (saved);
11637 assert (lgl->simp);
11638 assert (lgl->probing || lgl->cceing);
11639 assert (!lgl->level);
11640 LOG (2, "next probe %d positive phase", root);
11641 assert (!lgl->level);
11642 if (lgl->treelooking) lgl->stats->prb.treelook.probed++;
11643 else if (lgl->cceing) lgl->stats->cce.probed++;
11644 else assert (lgl->basicprobing), lgl->stats->prb.basic.probed++;
11645 if (lglrand (lgl) & (1<<12)) root = -root;
11646 lgliassume (lgl, root);
11651 lglclnstk (&saved);
11652 lglbasicate (lgl, root);
11653 for (p = lgl->trail.start + old; p < lgl->trail.top; p++) {
11655 if (lit == root) continue;
11656 lglpushstk (lgl, &saved, lit);
11658 } else dom = lglprbana (lgl, root);
11659 lglbacktrack (lgl, 0);
11661 LOG (1, "failed literal %d on probing", dom, root);
11662 lglpushstk (lgl, &lift, -dom);
11665 LOG (2, "next probe %d negative phase", -root);
11666 assert (!lgl->level);
11667 if (lgl->treelooking) lgl->stats->prb.treelook.probed++;
11668 else if (lgl->cceing) lgl->stats->cce.probed++;
11669 else assert (lgl->basicprobing), lgl->stats->prb.basic.probed++;
11670 lgliassume (lgl, -root);
11673 lglbasicate (lgl, -root);
11674 for (p = saved.start; p < saved.top; p++) {
11676 val = lglval (lgl, lit);
11677 if (val <= 0) continue;
11678 if (lgl->treelooking) lgl->stats->prb.treelook.lifted++;
11679 else if (lgl->cceing) lgl->stats->cce.lifted++;
11680 else assert (lgl->basicprobing), lgl->stats->prb.basic.lifted++;
11681 lglpushstk (lgl, &lift, lit);
11682 LOG (2, "lifted %d", lit);
11684 } else dom = lglprbana (lgl, -root);
11685 lglbacktrack (lgl, 0);
11687 LOG (1, "failed literal %d on probing %d", dom, -root);
11688 lglpushstk (lgl, &lift, -dom);
11691 while (!lglmtstk (&lift)) {
11692 lit = lglpopstk (&lift);
11693 val = lglval (lgl, lit);
11694 if (val > 0) continue;
11695 if (val < 0) goto EMPTY;
11696 lglunit (lgl, lit);
11697 if (lgl->treelooking) lgl->stats->prb.treelook.failed++;
11698 else if (lgl->cceing) lgl->stats->cce.failed++;
11699 else assert (lgl->basicprobing), lgl->stats->prb.basic.failed++;
11700 if (lglbcp (lgl)) continue;
11702 LOG (1, "empty clause after propagating lifted and failed literals");
11705 lglrelstk (lgl, &lift);
11706 lglrelstk (lgl, &saved);
11709 static TVar * lgltvar (LGL * lgl, int lit) {
11710 int idx = abs (lit);
11711 assert (2 <= idx && idx < lgl->nvars);
11713 return lgl->tlk->tvars + idx;
11716 static void lglsignedtlmark (LGL * lgl, int lit) {
11717 TVar * tv = lgltvar (lgl, lit);
11718 unsigned bit = 1u << (lit < 0);
11719 if (tv->mark & bit) return;
11723 static int lglsignedtlmarked (LGL * lgl, int lit) {
11724 TVar * tv = lgltvar (lgl, lit);
11725 unsigned bit = 1u << (lit < 0);
11726 return tv->mark & bit;
11729 static void lgltlenq (LGL * lgl, int start) {
11730 int lit, blit, tag, other, oldcount, newcount, * stk;
11731 unsigned delta, i, j, mod;
11732 const int * p, * w, * eos;
11734 assert (!lglsignedtlmarked (lgl, start));
11735 lglsignedtlmark (lgl, start);
11736 lglpushstk (lgl, &lgl->tlk->stk, start);
11737 while (!lglmtstk (&lgl->tlk->stk)) {
11738 lit = lglpopstk (&lgl->tlk->stk);
11739 LOG (2, "tree-look enqueue %d%s", lit, lit == start ? " start":"");
11741 assert (!lglval (lgl, lit));
11742 assert (lglsignedtlmarked (lgl, lit));
11743 lglpushstk (lgl, &lgl->tlk->seen, lit);
11744 lglpushstk (lgl, &lgl->tlk->stk, 0);
11745 hts = lglhts (lgl, lit);
11746 w = lglhts2wchs (lgl, hts);
11747 eos = w + hts->count;
11748 oldcount = lglcntstk (&lgl->tlk->stk);
11749 for (p = w; p < eos; p++) {
11750 INCSTEPS (prb.treelook.steps);
11752 tag = blit & MASKCS;
11753 if (tag == OCCS) continue;
11754 if (tag == TRNCS || tag == LRGCS) { p++; continue; }
11755 assert (tag == BINCS);
11756 other = -(blit >> RMSHFT);
11757 if (lglval (lgl, other)) assert (lglval (lgl, other) < 0);
11758 else if (!lglsignedtlmarked (lgl, other)) {
11759 lglsignedtlmark (lgl, other);
11760 lglpushstk (lgl, &lgl->tlk->stk, other);
11763 newcount = lglcntstk (&lgl->tlk->stk);
11764 delta = newcount - oldcount;
11765 assert (delta >= 0);
11766 if ((mod = delta) <= 1) continue;
11767 stk = lgl->tlk->stk.start;
11768 for (i = 0; i < delta-1; i++, mod--) {
11770 j = i + (lglrand (lgl) % mod);
11771 assert (i <= j && j < delta);
11772 if (i == j) continue;
11773 SWAP (int, stk[i + oldcount], stk[j + oldcount]);
11775 } else lglpushstk (lgl, &lgl->tlk->seen, 0);
11779 static int lglisroot (LGL * lgl, int lit) { return !lglhasbins (lgl, lit); }
11781 static void lgltlunmarkall (LGL * lgl) {
11783 for (idx = 2; idx < lgl->nvars; idx++)
11784 lgl->tlk->tvars[idx].mark = 0;
11787 static int lgltlschedlit (LGL * lgl, int lit) {
11788 if (INCSTEPS (prb.treelook.steps) > lgl->limits->prb.steps) return 0;
11789 if (!lglisfree (lgl, lit)) return 1;
11790 if (lglsignedtlmarked (lgl, lit)) return 1;
11791 if (!lglisroot (lgl, -lit)) return 1;
11792 if (!lgl->tlk->lkhd && lglavar (lgl, lit)->donotreelook) return 1;
11793 if (lgl->opts->treelook.val >= 2) {
11794 lglbasicprobelit (lgl, -lit);
11795 if (lgl->mt) return 0;
11796 if (lglterminate (lgl)) return 0;
11797 if (!lglisfree (lgl, lit)) return 1;
11798 if (!lglisroot (lgl, -lit)) return 1;
11799 if (!lglhasbins (lgl, lit)) return 1;
11801 lgltlenq (lgl, lit);
11805 static int lgltlschedanylit (LGL * lgl, int lit) {
11806 if (INCSTEPS (prb.treelook.steps) > lgl->limits->prb.steps) return 0;
11807 if (!lglisfree (lgl, lit)) return 1;
11808 if (lglsignedtlmarked (lgl, lit)) return 1;
11809 if (!lgl->tlk->lkhd && lglavar (lgl, lit)->donotreelook) return 1;
11810 if (lgl->opts->treelook.val >= 2) {
11811 lglbasicprobelit (lgl, -lit);
11812 if (lgl->mt) return 0;
11813 if (lglterminate (lgl)) return 0;
11814 if (!lglisfree (lgl, lit)) return 1;
11816 lgltlenq (lgl, lit);
11820 static void lgltlsched (LGL * lgl) {
11821 int idx, round, count, * p;
11822 LOG (1, "scheduling tree-look literals");
11823 for (round = 0; !lgl->mt && round < 2; round++) {
11824 assert (lglmtstk (&lgl->tlk->seen));
11825 assert (lglmtstk (&lgl->tlk->stk));
11826 if (lglrandlitrav (lgl, lgltlschedlit))
11827 lglrandlitrav (lgl, lgltlschedanylit);
11828 lgltlunmarkall (lgl);
11829 lglrelstk (lgl, &lgl->tlk->stk);
11830 if (!lglmtstk (&lgl->tlk->seen)) break;
11831 for (idx = 2; idx < lgl->nvars; idx++)
11832 lglavar (lgl, idx)->donotreelook = 0;
11834 lglfitstk (lgl, &lgl->tlk->seen);
11836 for (p = lgl->tlk->seen.start; p < lgl->tlk->seen.top; p++)
11839 "[treelook-%d] scheduled %d literals %.0f%%",
11840 lgl->stats->prb.treelook.count, count, lglpcnt (count, 2*lglrem (lgl)));
11842 for (idx = 2; idx < lgl->nvars; idx++)
11843 lglavar (lgl, idx)->donotreelook = 0;
11846 static void lgltlassign (LGL * lgl, Stk * assignment, int lit) {
11848 LOG (2, "tree-look assign %d", lit);
11849 tv = lgltvar (lgl, lit);
11851 tv->val = lglsgn (lit) * (1 + lglcntstk (assignment));
11852 lglpushstk (lgl, assignment, lit);
11854 assert (lglsgn (tv->val) == lglsgn (lit));
11857 static void lgltlunassign (LGL * lgl, int lit) {
11859 LOG (2, "tree-look unassign %d", lit);
11860 tv = lgltvar (lgl, lit);
11862 assert (lglsgn (tv->val) == lglsgn (lit));
11866 static int lgltlval (LGL * lgl, int lit) {
11867 TVar * tv = lgltvar (lgl, lit);
11869 if (!tv->val) return 0;
11870 res = lglsgn (tv->val);
11871 if (lit < 0) res = -res;
11875 static void lglincreducedptr (LGL * lgl, Flt * reducedptr, int size) {
11876 Flt reduced = *reducedptr, inc = lglflt (-size, 1);
11877 reduced = lgladdflt (reduced, inc);
11878 LOG (2, "reduced score incremented to %s from %s by %s (size %d)",
11879 lglflt2str (lgl, reduced),
11880 lglflt2str (lgl, *reducedptr),
11881 lglflt2str (lgl, inc),
11883 *reducedptr = reduced;
11886 static int lgltlbcp (LGL * lgl,
11887 Stk * assignment, Flt * reducedptr, int dom) {
11888 int next = lglcntstk (assignment), next2 = next, lit, size, implied;
11889 int blit, tag, other, other2, val, lidx, red, found, trivial;
11890 int numnonfalse, numfalse, firstfalse, litval, skip;
11891 const int * p, * w, * eos, * c, * q;
11893 if (lglval (lgl, dom)) return 1;
11894 assert (!lgltlval (lgl, dom));
11895 lgltlassign (lgl, assignment, dom);
11896 lgl->stats->prb.treelook.probed++;
11897 LOG (2, "starting tree-look bcp on %d", dom);
11899 if (next2 < lglcntstk (assignment)) {
11900 assert (lgl->simp);
11901 INCSTEPS (props.simp);
11902 if (lgl->lkhd) INCSTEPS (props.lkhd);
11903 lit = lglpeek (assignment, next2++);
11904 assert (lgltlval (lgl, lit) > 0);
11905 LOG (2, "tree-look binary clause bcp on %d", lit);
11906 hts = lglhts (lgl, -lit);
11907 w = lglhts2wchs (lgl, hts);
11908 eos = w + hts->count;
11909 for (p = w; p < eos; p++) {
11910 assert (lgl->simp);
11911 lgl->stats->visits.simp++;
11912 if (lgl->lkhd) lgl->stats->visits.lkhd++;
11913 INCSTEPS (prb.treelook.steps);
11915 tag = blit & MASKCS;
11916 if (tag == OCCS) continue;
11917 if (tag == TRNCS || tag == LRGCS) { p++; continue; }
11918 assert (tag == BINCS);
11919 other = blit >> RMSHFT;
11920 val = lglval (lgl, other);
11921 if (val < 0) return 0;
11922 if (val > 0) continue;
11923 val = lgltlval (lgl, other);
11924 if (val < 0) return 0;
11925 if (reducedptr) lglincreducedptr (lgl, reducedptr, 2);
11926 if (val > 0) continue;
11927 lgltlassign (lgl, assignment, other);
11929 } else if (next < lglcntstk (assignment)) {
11930 lit = lglpeek (assignment, next++);
11931 litval = lgltlval (lgl, lit);
11932 assert (litval > 0);
11933 LOG (2, "tree-look non-binary clause bcp on %d", lit);
11934 hts = lglhts (lgl, -lit);
11935 w = lglhts2wchs (lgl, hts);
11936 eos = w + hts->count;
11937 for (p = w; p < eos; p++) {
11939 tag = blit & MASKCS;
11940 if (tag == LRGCS || tag == TRNCS) p++;
11941 if (tag == BINCS || tag == LRGCS) continue;
11942 INCSTEPS (prb.treelook.steps);
11943 assert (lglmtstk (&lgl->clause));
11944 skip = trivial = 0;
11945 if (tag == TRNCS) {
11946 other = blit >> RMSHFT;
11948 if (lglval (lgl, other) > 0 ||
11949 lglval (lgl, other2) > 0) skip = 1;
11951 if (lgltlval (lgl, other) > 0 ||
11952 lgltlval (lgl, other2) > 0) trivial = 1;
11953 lglpushstk (lgl, &lgl->clause, -lit),
11954 lglpushstk (lgl, &lgl->clause, other),
11955 lglpushstk (lgl, &lgl->clause, other2);
11958 assert (tag == OCCS);
11959 red = blit & REDCS;
11960 lidx = blit >> RMSHFT;
11961 found = trivial = 0;
11962 c = lglidx2lits (lgl, red, lidx);
11963 INCSTEPS (prb.treelook.steps);
11964 for (q = c; !skip && (other = *q); q++) {
11965 if (other >= NOTALIT) skip = 1;
11966 else if (lglval (lgl, other) > 0) skip = 1;
11968 if (other == -lit) assert (!found), found++;
11969 if (lgltlval (lgl, other) > 0) trivial = 1;
11970 lglpushstk (lgl, &lgl->clause, other);
11973 assert (skip || found);
11975 numnonfalse = numfalse = size = implied = 0;
11978 INCSTEPS (prb.treelook.steps);
11979 for (q = lgl->clause.start; q < lgl->clause.top; q++) {
11981 if (lglval (lgl, other) < 0) continue;
11983 if ((val = lgltlval (lgl, other)) < 0) {
11984 if (reducedptr && -val < litval) firstfalse = 0;
11989 if (implied == NOTALIT) continue;
11990 else if (implied) implied = NOTALIT;
11991 else implied = other;
11994 lglclnstk (&lgl->clause);
11995 if (skip) continue;
11996 if (reducedptr && firstfalse)
11997 lglincreducedptr (lgl, reducedptr, size);
11998 if (trivial) continue;
11999 if (!numnonfalse) { assert (!implied); return 0; }
12001 if (implied == NOTALIT) continue;
12002 assert (numnonfalse == 1);
12003 if (!numfalse) continue; // TODO remove?
12004 INCSTEPS (prb.treelook.steps);
12005 if (tag == TRNCS) lgl->stats->hbr.trn++; else lgl->stats->hbr.lrg++;
12006 LOG (2, "tree-look hyper binary resolvent %d %d", -dom, implied);
12007 if (lgl->opts->drup.val) lgldrupclsarg (lgl, -dom, implied, 0);
12008 #ifndef NLGLPICOSAT
12009 lglpicosatchkclsarg (lgl, -dom, implied, 0);
12011 (void) lglwchbin (lgl, -dom, implied, REDCS);
12012 (void) lglwchbin (lgl, implied, -dom, REDCS);
12013 lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
12014 lgl->stats->hbr.cnt++;
12015 lgl->stats->prgss++;
12016 lgltlassign (lgl, assignment, implied);
12017 assert (next > 0), next--; // force to redo this trn/lrg literal
12018 break; // and continue outer 'next2' prop on 'implied'
12022 if (reducedptr) assert (lgl->tlk->lkhd), lgl->tlk->lkhd[dom] = *reducedptr;
12026 static void lgltreelooklit (LGL * lgl, Stk * a, Ftk * r, int lit) {
12028 LOG (2, "treelook dequeue %d", lit);
12030 if (lgl->opts->treelook.val >= 2 &&
12032 lglisfree (lgl, lit)) lglbasicprobelit (lgl, -lit);
12034 reduced = lglmtftk (r) ? FLTMIN : lgltopftk (r);
12035 lglpushftk (lgl, r, reduced);
12037 lglpushstk (lgl, a, 0);
12038 if (lgl->mt || !lglisfree (lgl, lit)) return;
12039 if (lgltlval (lgl, -lit) > 0 ||
12040 (!lgltlval (lgl, lit) &&
12041 !lgltlbcp (lgl, a, r ? &reduced : 0, lit))) {
12043 LOG (1, "tree-look failed literal %d", lit);
12044 if (!(tmp = lglval (lgl, lit))) {
12045 lgl->stats->prb.treelook.failed++;
12046 lglunit (lgl, -lit);
12047 if (!lglbcp (lgl)) {
12048 if (!lgl->mt) lgl->mt = 1;
12049 LOG (1, "inconsistent tree-look failed literal");
12051 } else if (tmp > 0) {
12052 lgl->stats->prb.treelook.failed++;
12053 LOG (1, "tree-look failed literal literal %d inconsistent", lit);
12054 if (!lgl->mt) lgl->mt = 1;
12055 } else LOG (1, "tree-look failed literal %d already found", lit);
12058 assert (r->start < r->top);
12059 assert (r->top[-1] <= reduced);
12060 r->top[-1] = reduced;
12063 if (r) lglpopftk (r);
12064 while ((lit = lglpopstk (a)))
12065 lgltlunassign (lgl, lit);
12069 static int64_t lglsetprbtreelooklim (LGL * lgl, int * lkhdresptr) {
12070 int sizepen, lastpen, pen, boost;
12071 int64_t limit, irrlim;
12072 if (lgl->opts->treelookrtc.val || lgl->opts->prbrtc.val) {
12073 limit = lgl->limits->prb.steps = LLMAX;
12074 lglprt (lgl, 1, "[treelook-%d] no limit (run to completion)",
12075 lgl->stats->prb.treelook.count);
12076 } else if (lkhdresptr && lgl->opts->treelookfull.val) {
12077 limit = lgl->limits->prb.steps = LLMAX;
12078 lglprt (lgl, 1, "[treelook-%d] unlimited look-ahead requested",
12079 lgl->stats->prb.treelook.count);
12081 limit = (lgl->opts->treelookreleff.val*lglvisearch (lgl))/2000;
12082 if (limit < lgl->opts->treelookmineff.val)
12083 limit = lgl->opts->treelookmineff.val;
12084 if (lgl->opts->treelookmaxeff.val >= 0 &&
12085 limit > lgl->opts->treelookmaxeff.val)
12086 limit = lgl->opts->treelookmaxeff.val;
12088 sizepen = lglszpen (lgl);
12089 lastpen = lgl->tlk->lkhd ?
12090 lgl->limits->lkhdpen : lgl->limits->prb.treelook.pen;
12091 pen = sizepen + lastpen;
12093 irrlim = lgl->stats->irr.clauses.cur/4;
12094 irrlim >>= lgl->limits->simp.pen;
12095 if (lgl->opts->boost.val && lgl->tlk->lkhd)
12096 boost = lgl->opts->treelookboost.val;
12099 if (lgl->opts->irrlim.val && limit < irrlim) {
12102 "[treelook-%d] limit %lld based on %d irredundant clauses",
12103 lgl->stats->prb.treelook.count,
12104 (LGLL) limit, lgl->stats->irr.clauses.cur);
12107 "[treelook-%d] limit %lld penalty %d = %d + %d boost %d",
12108 lgl->stats->prb.treelook.count, (LGLL) limit,
12109 pen, lastpen, sizepen, boost);
12111 lglprt (lgl, 1, "[treelook-%d] limited look-ahead requested",
12112 lgl->stats->prb.treelook.count);
12113 lgl->limits->prb.steps = lgl->stats->prb.treelook.steps + limit;
12119 static void lglclntlvals (LGL * lgl) {
12121 for (idx = 2; idx < lgl->nvars; idx++) lgl->tlk->tvars[idx].val = 0;
12125 static int lglieliminated (LGL * lgl, int ilit) {
12126 return lglelit2ext (lgl, lglexport (lgl, ilit))->eliminated;
12130 static int lgliblocking (LGL * lgl, int ilit) {
12131 return lglelit2ext (lgl, lglexport (lgl, ilit))->blocking;
12134 static void lgltlsetlkhd (LGL * lgl, int * lkhdresptr, int remlits) {
12135 LKHD lkhdrescore, lkhdscore, lkhdpos, lkhdneg;
12136 Flt jwhrescore, jwhscore, jwhpos, jwhneg;
12137 int idx, lkhdres, phase, elit;
12139 assert (lkhdresptr);
12140 lkhdres = 0; lkhdrescore = FLTMIN; jwhrescore = FLTMIN;
12141 assert (!lgl->nvars || lgl->tlk->lkhd);
12143 for (idx = 2; idx < lgl->nvars; idx++) {
12144 if (!lglisfree (lgl, idx)) continue;
12145 assert (!lglieliminated (lgl, idx));
12146 if (lkhdresptr && lgliblocking (lgl, idx)) continue;
12148 lkhdpos = lgl->tlk->lkhd[idx];
12149 lkhdneg = lgl->tlk->lkhd[-idx];
12150 lkhdscore = lglmulflt (lkhdneg, lkhdpos);
12151 if (lkhdscore > FLTMIN)
12152 lkhdscore = lgladdflt (lkhdscore, lgladdflt (lkhdneg, lkhdpos));
12153 } else lkhdscore = lkhdpos = lkhdneg = FLTMIN;
12154 jwhpos = lgl->jwh[lglulit (idx)];
12155 jwhneg = lgl->jwh[lglulit (-idx)];
12156 jwhscore = lglmulflt (jwhpos, jwhneg);
12157 jwhscore = lgladdflt (jwhscore, lgladdflt (jwhpos, jwhneg));
12159 "final tree based look-ahead score [%s,%s] "
12160 "(pos [%s,%s], neg [%s,%s]) of %d",
12161 lglflt2str (lgl, lkhdscore), lglflt2str (lgl,jwhscore),
12162 lglflt2str (lgl, lkhdpos), lglflt2str (lgl,jwhpos),
12163 lglflt2str (lgl, lkhdneg), lglflt2str (lgl,jwhneg),
12166 // phase with less weighted reductions
12167 if (lkhdpos > lkhdneg) phase = -1;
12168 else if (lkhdpos < lkhdneg) phase = 1;
12169 // then with more weighted occs
12170 else if (jwhpos > jwhneg) phase = 1;
12171 else if (jwhpos < jwhneg) phase = -1;
12172 // otherwise negative phase
12176 if (lkhdscore < lkhdrescore) continue;
12177 if (lkhdscore == lkhdrescore && jwhscore <= jwhrescore) continue;
12179 lkhdrescore = lkhdscore;
12180 jwhrescore = jwhscore;
12181 lkhdres = phase * idx;
12184 elit = lglexport (lgl, lkhdres);
12185 ext = lglelit2ext (lgl, elit);
12186 assert (!ext->eliminated);
12187 assert (!ext->blocking);
12188 lglprt (lgl, 1, "[treelook-%d] best look-ahead %d score [%s,%s]",
12189 lgl->stats->prb.treelook.count, lkhdres,
12190 lglflt2str (lgl, lkhdrescore), lglflt2str (lgl, jwhrescore));
12193 LOG (2, "tree-look-ahead winner external %d not melted anymore", elit);
12196 "tree-look-ahead winner external %d was not melted anyhow", elit);
12197 } else LOG (1, "no proper best tree-look-ahead literal found");
12198 if (lkhdresptr) *lkhdresptr = lkhdres;
12201 static void lglgenericreport (LGL * lgl, const char * name, int count,
12202 int probed, int nprobes, double start) {
12204 assert (nprobes >= 0);
12205 if (!nprobes || lgl->opts->verbose.val < 2) return;
12206 if (lgl->opts->verbose.val == 2) div = 10;
12207 else if (lgl->opts->verbose.val == 3) div = 100;
12209 mod = div ? (nprobes + div - 1) / div : 1;
12211 if (probed % mod) return;
12213 "[%s-%d] probed %d/%d (%.0f%%) %.1f sec %d vars %.0f MB",
12214 name, count, probed, nprobes, lglpcnt (probed, nprobes),
12215 lglgetime (lgl) - start, lglrem (lgl), lglmb (lgl));
12218 static void lgltreelookreport (LGL * lgl,
12219 int probed, int nprobes, double start) {
12220 lglgenericreport (lgl,
12221 "treelook", lgl->stats->prb.treelook.count, probed, nprobes, start);
12224 static int lgltreelookaux (LGL * lgl, int * lkhdresptr) {
12225 int oldhbrs, oldrem, remvarsall, remvarslkhd, remlits, notfullyscheduled;
12226 int deltavars, newhbrs, success, idx, next, lit, nseen;
12227 int64_t oldsteps, steps, limit;
12234 if (lgl->mt) return 0;
12235 if (lkhdresptr) *lkhdresptr = 0;
12236 if (!lgl->nvars) return 1;
12238 lglstart (lgl, &lgl->times->prb.treelook);
12239 lgl->stats->prb.treelook.count++;
12242 NEW (lgl->tlk->tvars, lgl->nvars);
12244 assert (!lgl->simp && !lgl->probing && !lgl->treelooking);
12245 lgl->simp = lgl->probing = lgl->treelooking = 1;
12247 if (lgl->level > 0) lglbacktrack (lgl, 0);
12248 oldhbrs = lgl->stats->hbr.cnt;
12249 oldrem = lglrem (lgl);
12251 assert (!lgl->tlk->lkhd);
12253 NEW (lgl->tlk->lkhd, 2*lgl->nvars);
12254 lgl->tlk->lkhd += lgl->nvars;
12255 assert (lgl->tlk->lkhd);
12258 limit = lglsetprbtreelooklim (lgl, lkhdresptr);
12259 oldsteps = lgl->stats->prb.treelook.steps;
12263 steps = lgl->stats->prb.treelook.steps - oldsteps;
12264 lglprt (lgl, 1, "[treelook-%d] scheduling used %lld steps",
12265 lgl->stats->prb.treelook.count, (LGLL) steps);
12267 if (limit != LLMAX) {
12268 notfullyscheduled =
12269 (lgl->stats->prb.treelook.steps >= lgl->limits->prb.steps);
12270 lgl->limits->prb.steps = lgl->stats->prb.treelook.steps + limit;
12271 if (notfullyscheduled)
12272 lglprt (lgl, 1, "[treelook-%d] not fully scheduled",
12273 lgl->stats->prb.treelook.count);
12275 lglprt (lgl, 1, "[treelook-%d] scheduled completely",
12276 lgl->stats->prb.treelook.count);
12277 } else notfullyscheduled = 0;
12279 CLR (assignment); CLR (reduced);
12280 remlits = remvarsall = remvarslkhd = 0;
12282 nseen = lglcntstk (&lgl->tlk->seen);
12283 if (!lgl->mt && nseen) {
12285 (void) lglsetprbtreelooklim (lgl, lkhdresptr);
12286 oldsteps = lgl->stats->prb.treelook.steps;
12288 lgldense (lgl, lgl->opts->treelooklrg.val);
12290 start = lglgetime (lgl);
12291 lgltreelookreport (lgl, next, nseen, start);
12293 !lglterminate (lgl) &&
12294 lglsyncunits (lgl) &&
12296 lgl->stats->prb.treelook.steps < lgl->limits->prb.steps) {
12297 lit = lglpeek (&lgl->tlk->seen, next++);
12298 lgltreelooklit (lgl, &assignment, lkhdresptr ? &reduced : 0, lit);
12299 lgltreelookreport (lgl, next, nseen, start);
12301 lgltreelookreport (lgl, next, nseen, start);
12302 lglclntlvals (lgl);
12303 assert (lgl->stats->prb.treelook.steps >= oldsteps);
12304 steps = lgl->stats->prb.treelook.steps - oldsteps;
12305 lglprt (lgl, 1, "[treelook-%d] used %lld steps",
12306 lgl->stats->prb.treelook.count, (LGLL) steps);
12307 while (next < lglcntstk (&lgl->tlk->seen)) {
12308 lit = lglpeek (&lgl->tlk->seen, next++);
12309 if (!lit) continue;
12310 if (!lglisfree (lgl, lit)) continue;
12312 tv = lgltvar (lgl, lit);
12315 for (idx = 2; idx < lgl->nvars; idx++)
12316 if (lglisfree (lgl, idx)) {
12317 tv = lgltvar (lgl, idx);
12318 av = lglavar (lgl, idx);
12321 if (!av->donotreelook) remvarsall++;
12323 } else if (!av->donotreelook) av->donotreelook = 1;
12325 assert (remvarslkhd >= remvarsall);
12327 if (remvarsall || notfullyscheduled) {
12328 lglprt (lgl, 1, "[treelook-%d] %d literals remain %.0f%%%s",
12329 lgl->stats->prb.treelook.count,
12330 remlits, lglpcnt (remlits, 2*lglrem (lgl)),
12331 lkhdresptr ? " in look-ahead" : "");
12333 lglprt (lgl, 1, "[treelook-%d] %d look-ahead variables remain %.0f%%",
12334 lgl->stats->prb.treelook.count,
12335 remvarslkhd, lglpcnt (remvarslkhd, lglrem (lgl)));
12337 "[treelook-%d] %d variables remain to probed next time %.0f%%",
12338 lgl->stats->prb.treelook.count,
12339 remvarsall, lglpcnt (remvarsall, lglrem (lgl)));
12342 "[treelook-%d] fully completed tree based probing%s",
12343 lgl->stats->prb.treelook.count, lkhdresptr ? " in look-ahead" : "");
12344 for (idx = 2; idx < lgl->nvars; idx++)
12345 lglavar (lgl, idx)->donotreelook = 0;
12350 DEL (lgl->tlk->tvars, lgl->nvars);
12352 lglrelftk (lgl, &reduced);
12353 lglrelstk (lgl, &assignment);
12354 lglrelstk (lgl, &lgl->tlk->seen);
12355 if (!lgl->mt && lkhdresptr)
12356 lgltlsetlkhd (lgl, lkhdresptr, remlits || notfullyscheduled);
12357 if (lgl->tlk->lkhd) {
12358 lgl->tlk->lkhd -= lgl->nvars;
12359 DEL (lgl->tlk->lkhd, 2*lgl->nvars);
12362 newhbrs = lgl->stats->hbr.cnt - oldhbrs;
12363 if (newhbrs && !lgl->mt && !lkhdresptr) lgldecomp (lgl);
12365 assert (lgl->simp && lgl->probing && lgl->treelooking);
12366 lgl->simp = lgl->probing = lgl->treelooking = 0;
12368 deltavars = oldrem - lglrem (lgl);
12369 success = deltavars || newhbrs;
12370 if (!lkhdresptr) LGLUPDPEN (prb.treelook, deltavars);
12371 else if (remlits && lgl->limits->lkhdpen < lgl->opts->penmax.val)
12372 lgl->limits->lkhdpen++;
12373 else if (!remlits && lgl->limits->lkhdpen)
12374 lgl->limits->lkhdpen--;
12375 lglprt (lgl, 1 + !success,
12376 "[treelook-%d] removed %d variables, found %d hbrs",
12377 lgl->stats->prb.treelook.count, deltavars, newhbrs);
12378 lglrep (lgl, 2, 'p');
12380 lglbasicatestats (lgl);
12384 static int lgltreelook (LGL * lgl) {
12385 if (lgldelaying (lgl, "treelook",
12386 &lgl->limits->prb.treelook.del.rem)) return 1;
12387 return lgltreelookaux (lgl, 0);
12390 static int lgljwhlook (LGL * lgl) {
12391 Flt best, pos, neg, score;
12392 int res, idx, elit;
12397 for (idx = 2; idx < lgl->nvars; idx++) {
12398 if (!lglisfree (lgl, idx)) continue;
12399 assert (!lglieliminated (lgl, idx));
12400 if (lgliblocking (lgl, idx)) continue;
12401 pos = lgl->jwh[lglulit (idx)];
12402 neg = lgl->jwh[lglulit (-idx)];
12403 score = lglmulflt (pos, neg);
12404 score = lgladdflt (score, lgladdflt (pos, neg));
12405 if (res && score <= best) continue;
12406 LOG (1, "jwh look-ahead score %s (pos %s, neg %s) of %d",
12407 lglflt2str (lgl, score), lglflt2str (lgl, pos), lglflt2str (lgl, neg),
12409 res = (pos > neg) ? idx : -idx;
12413 elit = lglexport (lgl, res);
12414 ext = lglelit2ext (lgl, elit);
12415 lglprt (lgl, 1, "[jwhlook] best look-ahead %d score %s",
12416 res, lglflt2str (lgl, best));
12419 LOG (2, "jwh-look-ahead winner external %d not melted anymore", elit);
12421 LOG (2, "jwh-look-ahead winner external %d was not melted anyhow", elit);
12422 } else LOG (1, "no proper best jwh-look-ahead literal found");
12426 static int lglismislook (LGL * lgl, int max) {
12427 int64_t best, pos, neg, score;
12428 int res, idx, elit, * scores;
12430 scores = lglis (lgl);
12432 for (idx = 2; idx < lgl->nvars; idx++) {
12433 if (!lglisfree (lgl, idx)) continue;
12434 assert (!lglieliminated (lgl, idx));
12435 if (lgliblocking (lgl, idx)) continue;
12436 pos = scores[idx], neg = scores[-idx];
12437 score = pos * neg + pos + neg;
12438 assert (0 <= score && pos <= score && neg <= score);
12440 if (max && score <= best) continue;
12441 if (!max && score >= best) continue;
12443 LOG (1, "%s look-ahead score %lld (pos %lld, neg %lld) of %d",
12444 (max ? "LIS" : "MIS"), (LGLL) score, (LGLL) pos, (LGLL) neg, idx);
12445 res = (pos > neg) ? idx : -idx;
12448 scores -= lgl->nvars;
12449 DEL (scores, 2*lgl->nvars);
12451 elit = lglexport (lgl, res);
12452 ext = lglelit2ext (lgl, elit);
12453 assert (!ext->eliminated && !ext->blocking);
12454 lglprt (lgl, 1, "[lislook] best %s look-ahead %d score %lld",
12455 (max ? "LIS" : "MIS"), res, (LGLL) best);
12458 LOG (2, "look-ahead winner external %d not melted anymore", elit);
12460 LOG (2, "look-ahead winner external %d was not melted anyhow", elit);
12461 } else LOG (1, "no proper best %s-look-ahead literal found",
12462 (max ? "LIS" : "MIS"));
12466 static int lglislook (LGL * lgl) { return lglismislook (lgl, 1); }
12467 static int lglmislook (LGL * lgl) { return lglismislook (lgl, 0); }
12469 static int64_t lglsatmul64 (int64_t a, int64_t b) {
12470 assert (a >= 0), assert (b >= 0);
12471 return (b && (LLMAX / b < a)) ? LLMAX : a * b;
12474 static int64_t lglsatadd64 (int64_t a, int64_t b) {
12475 assert (a >= 0), assert (b >= 0);
12476 return (LLMAX - b < a) ? LLMAX : a + b;
12479 static int64_t * lglsumlenscores (LGL * lgl) {
12480 int idx, sign, lit, tag, blit, other, other2, red;
12481 const int *p, * w, * eow, * c;
12482 int64_t * res, len;
12483 Val val, tmp, tmp2;
12486 NEW (res, 2*lgl->nvars);
12488 for (idx = 2; idx < lgl->nvars; idx++)
12489 for (sign = -1; sign <= 1; sign += 2) {
12491 val = lglval (lgl, lit);
12492 if (val > 0) continue;
12493 hts = lglhts (lgl, lit);
12494 if (!hts->offset) continue;
12495 w = lglhts2wchs (lgl, hts);
12496 eow = w + hts->count;
12497 for (p = w; p < eow; p++) {
12499 tag = blit & MASKCS;
12500 if (tag == TRNCS || tag == LRGCS) p++;
12501 if (tag == LRGCS) continue;
12502 red = blit & REDCS;
12504 other = blit >> RMSHFT;
12505 if (abs (other) < abs (lit)) continue;
12506 tmp = lglval (lgl, other);
12507 if (tmp > 0) continue;
12508 if (tag == BINCS) {
12513 assert (tag == TRNCS);
12515 if (abs (other2) < abs (lit)) continue;
12516 tmp2 = lglval (lgl, other2);
12517 if (tmp2 > 0) continue;
12518 assert ((val > 0) + (tmp > 0) + (tmp2 > 0) == 0);
12519 assert ((val < 0) + (tmp < 0) + (tmp2 < 0) <= 1);
12520 len = !val + !tmp + !tmp2;
12521 if (!val) res[lit] += len;
12522 if (!tmp) res[other] += len;
12523 if (!tmp2) res[other2] += len;
12528 for (c = s->start; c < s->top; c = p + 1) {
12530 if (*p >= NOTALIT) continue;
12533 while ((other = *p)) {
12534 tmp = lglval (lgl, other);
12535 if (tmp > val) val = tmp;
12539 if (val > 0) continue;
12540 for (p = c; (other = *p); p++)
12541 if (!lglval (lgl, other))
12547 static int lglsumlenlook (LGL * lgl) {
12548 int64_t best, pos, neg, score, * scores;
12549 int res, idx, elit;
12551 scores = lglsumlenscores (lgl);
12553 for (idx = 2; idx < lgl->nvars; idx++) {
12554 if (!lglisfree (lgl, idx)) continue;
12555 assert (!lglieliminated (lgl, idx));
12556 if (lgliblocking (lgl, idx)) continue;
12557 pos = scores[idx], neg = scores[-idx];
12558 score = lglsatadd64 (lglsatmul64 (pos, neg), lglsatadd64 (pos, neg));
12559 assert (0 <= score), assert (pos <= score), assert (neg <= score);
12560 if (res && score <= best) continue;
12562 "look-ahead score %lld (pos %lld, neg %lld) of %d",
12563 (LGLL) score, (LGLL) pos, (LGLL) neg, idx);
12564 res = (pos > neg) ? idx : -idx;
12567 scores -= lgl->nvars;
12568 DEL (scores, 2*lgl->nvars);
12570 elit = lglexport (lgl, res);
12571 ext = lglelit2ext (lgl, elit);
12572 assert (!ext->eliminated && !ext->blocking);
12574 "[sumlook] best look-ahead %d score %lld",
12578 LOG (2, "look-ahead winner external %d not melted anymore", elit);
12580 LOG (2, "look-ahead winner external %d was not melted anyhow", elit);
12581 } else LOG (1, "no proper best look-ahead literal found");
12585 static int lglschedbasicprobe (LGL * lgl, Stk * probes, int round) {
12586 int idx, res, i, j, donotbasicprobes, keepscheduled;
12587 assert (lglmtstk (probes));
12588 for (idx = 2; idx < lgl->nvars; idx++) {
12589 if (!lglisfree (lgl, idx)) continue;
12590 if (lgl->opts->prbasic.val <= 1 &&
12591 (lglhasbins (lgl, idx) == lglhasbins (lgl, -idx))) continue;
12592 LOG (1, "new probe %d", idx);
12593 lglpushstk (lgl, probes, idx);
12595 res = lglcntstk (probes);
12596 donotbasicprobes = keepscheduled = 0;
12597 for (i = 0; i < res; i++) {
12598 idx = lglpeek (probes, i);
12599 if (!idx) continue;
12600 assert (lglisfree (lgl, idx));
12601 if (lglavar (lgl, idx)->donotbasicprobe) donotbasicprobes++;
12602 else keepscheduled++;
12604 if (!keepscheduled) {
12605 for (i = 0; i < res; i++) {
12606 idx = lglpeek (probes, i);
12607 if (!idx) continue;
12608 assert (lglisfree (lgl, idx));
12609 lglavar (lgl, idx)->donotbasicprobe = 0;
12612 donotbasicprobes = 0;
12614 for (i = 0; i < res; i++) {
12615 idx = lglpeek (probes, i);
12616 if (!idx) continue;
12617 assert (lglisfree (lgl, idx));
12618 if (lglavar (lgl, idx)->donotbasicprobe) donotbasicprobes++;
12619 else keepscheduled++;
12622 for (i = 0; i < res; i++) {
12623 idx = lglpeek (probes, i);
12624 if (!idx) continue;
12625 if (!lglavar (lgl, idx)->donotbasicprobe)
12626 lglpoke (probes, j++, idx);
12628 lglrststk (probes, (res = j));
12630 lglprt (lgl, 2, "[basicprobe-%d-%d] no potential probes found",
12631 lgl->stats->prb.basic.count, round);
12632 else if (!donotbasicprobes)
12633 lglprt (lgl, 2, "[basicprobe-%d-%d] scheduled all %d potential probes",
12634 lgl->stats->prb.basic.count, round, res);
12636 lglprt (lgl, 2, "[basicprobe-%d-%d] scheduled %d probes %.0f%%",
12637 lgl->stats->prb.basic.count, round,
12638 res, lglpcnt (res, lglrem (lgl)));
12642 static void lglsetprbasiclim (LGL * lgl) {
12643 int64_t limit, irrlim;
12645 if (lgl->opts->prbasicrtc.val || lgl->opts->prbrtc.val) {
12646 lgl->limits->prb.steps = LLMAX;
12647 lglprt (lgl, 1, "[basicprobe-%d] no limit (run to completion)",
12648 lgl->stats->prb.basic.count);
12650 limit = (lgl->opts->prbasicreleff.val*lglvisearch (lgl))/1000;
12651 if (limit < lgl->opts->prbasicmineff.val)
12652 limit = lgl->opts->prbasicmineff.val;
12653 if (lgl->opts->prbasicmaxeff.val >= 0 &&
12654 limit > lgl->opts->prbasicmaxeff.val)
12655 limit = lgl->opts->prbasicmaxeff.val;
12656 limit >>= (pen = lgl->limits->prb.basic.pen + lglszpen (lgl));
12657 irrlim = 2*lgl->stats->irr.clauses.cur;
12658 irrlim >>= lgl->limits->simp.pen;
12659 if (lgl->opts->irrlim.val && limit < irrlim) {
12662 "[basicprobe-%d] limit %lld based on %d irredundant clauses",
12663 lgl->stats->prb.basic.count,
12664 (LGLL) limit, lgl->stats->irr.clauses.cur);
12666 lglprt (lgl, 1, "[basicprobe-%d] limit %lld penalty %d = %d + %d",
12667 lgl->stats->prb.basic.count, (LGLL) limit,
12668 pen, lgl->limits->prb.basic.pen, lglszpen (lgl));
12669 lgl->limits->prb.steps = lgl->stats->prb.basic.steps + limit;
12673 static void lglbasicprobereport (LGL * lgl,
12674 int probed, int nprobes, double start) {
12675 lglgenericreport (lgl,
12676 "basicprobe", lgl->stats->prb.basic.count, probed, nprobes, start);
12679 static int lglbasicprobe (LGL * lgl) {
12681 int origprobed = lgl->stats->prb.basic.probed;
12683 int origfailed = lgl->stats->prb.basic.failed;
12684 int origlifted = lgl->stats->prb.basic.lifted;
12685 int orighbr = lgl->stats->hbr.cnt;
12686 int root, failed, lifted, units, first, idx;
12687 int oldrem, deltarem, deltahbr, remprobes;
12688 int nprobes, success, round, probed;
12689 int oldhbr, oldfailed, oldlifted;
12690 Stk probes, lift, saved;
12691 unsigned pos, delta;
12693 if (!lgl->nvars) return 1;
12694 if (!lgl->opts->probe.val) return 1;
12695 if (lgldelaying (lgl, "basicprobe",
12696 &lgl->limits->prb.basic.del.rem)) return 1;
12697 lglstart (lgl, &lgl->times->prb.basic);
12698 lgl->stats->prb.basic.count++;
12699 if (lgl->level > 0) lglbacktrack (lgl, 0);
12700 assert (!lgl->simp && !lgl->probing && !lgl->basicprobing);
12701 lgl->simp = lgl->probing = lgl->basicprobing = 1;
12702 CLR (lift); CLR (probes); CLR (saved);
12703 lglsetprbasiclim (lgl);
12704 oldfailed = origfailed;
12705 oldlifted = origlifted;
12706 oldhbr = lgl->stats->hbr.cnt;
12707 oldrem = lglrem (lgl);
12710 nprobes = lglschedbasicprobe (lgl, &probes, round);
12712 if (!nprobes) goto DONE;
12713 pos = lglrand (lgl) % nprobes;
12714 delta = lglrand (lgl) % nprobes;
12715 if (!delta) delta++;
12717 start = lglgetime (lgl);
12718 lglbasicprobereport (lgl, probed, nprobes, start);
12719 while (lglgcd (delta, nprobes) > 1)
12720 if (++delta == nprobes) delta = 1;
12721 LOG (1, "probing start %u delta %u mod %u", pos, delta, nprobes);
12724 if (lgl->stats->prb.basic.steps >= lgl->limits->prb.steps) break;
12725 if (lglterminate (lgl)) break;
12726 if (!lglsyncunits (lgl)) break;
12727 assert (pos < (unsigned) nprobes);
12728 root = probes.start[pos];
12729 probes.start[pos] = 0;
12730 if (!root || root == first) {
12732 "[basicprobe-%d-%d] %d sched %.0f%%, %d failed, %d lifted, %d hbrs",
12733 lgl->stats->prb.basic.count, round,
12734 nprobes, lglpcnt (nprobes, lglrem (lgl)),
12735 lgl->stats->prb.basic.failed - oldfailed,
12736 lgl->stats->prb.basic.lifted - oldlifted,
12737 lgl->stats->hbr.cnt - oldhbr);
12738 for (idx = 2; idx < lgl->nvars; idx++)
12739 lglavar (lgl, idx)->donotbasicprobe = 0;
12742 lglavar (lgl, root)->donotbasicprobe = 1;
12743 if (!first) first = root;
12745 if (pos >= nprobes) pos -= nprobes;
12746 if (!lglisfree (lgl, root)) continue;
12747 lglbasicprobereport (lgl, ++probed, nprobes, start);
12748 lglbasicprobelit (lgl, root);
12750 lglbasicprobereport (lgl, probed, nprobes, start);
12752 if (lgl->stats->prb.basic.steps >= lgl->limits->prb.steps) {
12753 while (!lglmtstk (&probes))
12754 if((idx = lglpopstk (&probes)) && lglisfree (lgl, idx)) remprobes++;
12756 "[basicprobe-%d-%d] %d probes remain %.0f%% after last round",
12757 lgl->stats->prb.basic.count, round,
12758 remprobes, lglpcnt (remprobes, lglrem (lgl)));
12759 } else if (round >= lgl->opts->prbasicroundlim.val) {
12761 "[basicprobe-%d-%d] round limit %d hit",
12762 lgl->stats->prb.basic.count, round,
12763 lgl->opts->prbasicroundlim.val);
12764 } else if (lgl->stats->prb.basic.failed > oldfailed ||
12765 lgl->stats->prb.basic.lifted > oldlifted ||
12766 lgl->stats->hbr.cnt > oldhbr) {
12767 oldfailed = lgl->stats->prb.basic.failed;
12768 oldlifted = lgl->stats->prb.basic.lifted;
12769 lglclnstk (&probes);
12770 if (oldhbr < lgl->stats->hbr.cnt && lgl->opts->decompose.val)
12771 if (!lgldecomp (lgl)) goto DONE;
12772 oldhbr = lgl->stats->hbr.cnt;
12776 assert (!remprobes);
12778 "[basicprobe-%d-%d] fully completed probing",
12779 lgl->stats->prb.basic.count, round);
12780 for (idx = 2; idx < lgl->nvars; idx++)
12781 lglavar (lgl, idx)->donotbasicprobe = 0;
12785 lglrelstk (lgl, &lift);
12786 lglrelstk (lgl, &probes);
12787 lglrelstk (lgl, &saved);
12789 assert (lgl->stats->hbr.cnt >= orighbr);
12790 assert (lglrem (lgl) <= oldrem);
12791 deltarem = oldrem - lglrem (lgl);
12792 deltahbr = lgl->stats->hbr.cnt - orighbr;
12793 success = deltarem || deltahbr;
12794 LGLUPDPEN (prb.basic, deltarem);
12795 assert (lgl->stats->prb.basic.failed >= origfailed);
12796 assert (lgl->stats->prb.basic.lifted >= origlifted);
12797 failed = lgl->stats->prb.basic.failed - origfailed;
12798 lifted = lgl->stats->prb.basic.lifted - origlifted;
12800 assert (lgl->stats->prb.basic.probed >= origprobed);
12801 probed = lgl->stats->prb.basic.probed - origprobed;
12802 LOG (1, "%ssuccessfully probed %d out of %d probes %.1f%%",
12803 success ? "" : "un", probed, nprobes, lglpcnt (probed, nprobes));
12804 LOG (1, "found %d failed %.1f%% lifted %d through probing",
12805 failed, lglpcnt (failed, probed), lifted);
12807 assert (lgl->probing && lgl->simp && lgl->basicprobing);
12808 lgl->simp = lgl->probing = lgl->basicprobing = 0;
12809 units = failed + lifted;
12810 lglprt (lgl, 1 + !units,
12811 "[basicprobe-%d-%d] %d units = %d failed (%.0f%%) + %d lifted (%.0f%%)",
12812 lgl->stats->prb.basic.count, round,
12813 units, failed, lglpcnt (failed, units), lifted, lglpcnt (lifted, units));
12814 lglprt (lgl, 1 + !success,
12815 "[basicprobe-%d-%d] removed %d variables, found %d hbrs",
12816 lgl->stats->prb.basic.count, round, deltarem, deltahbr);
12817 lglrep (lgl, 2, 'p');
12819 lglbasicatestats (lgl);
12823 static int lglsmallirr (LGL * lgl) {
12824 int maxirrlidx = lglcntstk (&lgl->irr), limit;
12825 int64_t tmp = MAXREDLIDX;
12826 tmp *= lgl->opts->smallirr.val;
12828 limit = (tmp < INT_MAX) ? tmp : INT_MAX;
12829 if (maxirrlidx >= limit) return 0;
12833 static int lglprobe (LGL * lgl) {
12834 int res = 1, mod = 0, all, small = lglsmallirr (lgl);
12835 int (*prb[3])(LGL *);
12836 lglstart (lgl, &lgl->times->prb.all);
12837 if (small && lgl->opts->prbsimple.val) prb[mod++] = lglsimpleprobe;
12838 if (small && lgl->opts->treelook.val) prb[mod++] = lgltreelook;
12839 if (lgl->opts->prbasic.val) prb[mod++] = lglbasicprobe;
12840 all = lgl->stats->prb.simple.count;
12841 all += lgl->stats->prb.basic.count;
12842 all += lgl->stats->prb.treelook.count;
12843 if (lgl->stats->simp.count == 2) {
12846 for (i = 0; res && i < mod; i++) res = prb[i] (lgl);
12847 } else res = mod ? prb[all % mod] (lgl) : 1;
12852 static void lglinitevars (LGL * lgl) {
12855 assert (lgl->occs);
12856 NEW (lgl->evars, lgl->nvars);
12857 for (idx = 2; idx < lgl->nvars; idx++) {
12858 ev = lgl->evars + idx;
12863 static void lgldense (LGL * lgl, int occstoo) {
12864 int lit, lidx, count, idx, other, other2, blit, sign, tag, red;
12865 const int * start, * top, * c, * p, * eow;
12869 LOG (1, "transition to dense mode");
12870 assert (!lgl->dense);
12871 assert (!lgl->evars);
12872 assert (lglsmallirr (lgl));
12873 assert (lglmtstk (&lgl->esched));
12874 assert (!lgl->eliminating || !lgl->elm->pivot);
12875 lgl->stats->dense++;
12877 if (lgl->occs) lglinitevars (lgl);
12878 for (idx = 2; idx < lgl->nvars; idx++)
12879 for (sign = -1; sign <= 1; sign += 2) {
12881 hts = lglhts (lgl, lit);
12882 if (!hts->count) continue;
12883 q = w = lglhts2wchs (lgl, hts);
12884 eow = w + hts->count;
12885 for (p = w; p < eow; p++) {
12887 tag = blit & MASKCS;
12888 if (tag == TRNCS || tag == LRGCS) p++;
12889 red = blit & REDCS;
12890 if (red && tag == LRGCS) continue;
12892 if (tag == LRGCS || tag == TRNCS) *q++ = *p;
12894 if (tag == BINCS || tag == TRNCS) {
12895 other = blit >> RMSHFT;
12896 if (abs (other) < idx) continue;
12897 if (tag == TRNCS) {
12899 if (abs (other2) < idx) continue;
12900 lglincocc (lgl, other2), count++;
12902 lglincocc (lgl, lit), count++;
12903 lglincocc (lgl, other), count++;
12905 assert (tag == LRGCS);
12908 lglshrinkhts (lgl, hts, q - w);
12911 LOG (1, "counted %d occurrences in small irredundant clauses", count);
12914 start = lgl->irr.start;
12915 top = lgl->irr.top;
12916 for (c = start; c < top; c = p + 1) {
12918 if (*c >= NOTALIT) continue;
12920 assert (lidx < MAXIRRLIDX);
12921 blit = (lidx << RMSHFT) | OCCS;
12922 for (; (lit = *p); p++) {
12923 hts = lglhts (lgl, lit);
12924 lglpushwch (lgl, hts, blit);
12925 lglincocc (lgl, lit), count++;
12930 LOG (1, "counted %d occurrences in large irredundant clauses", count);
12933 for (idx = 2; idx < lgl->nvars; idx++) {
12934 ev = lglevar (lgl, idx);
12935 if (ev->pos >= 0) continue;
12936 if (lglifrozen (lgl, idx)) continue;
12937 if (lgl->donotsched) {
12938 AVar * av = lglavar (lgl, idx);
12939 if (lgl->eliminating && av->donotelm) continue;
12940 if (lgl->blocking && av->donotblk) continue;
12942 assert (!ev->occ[0] && !ev->occ[1]);
12943 lglesched (lgl, idx);
12946 if (count) LOG (1, "scheduled %d zombies", count);
12948 LOG (1, "continuing in dense mode");
12949 lgl->dense = 1 + occstoo;
12950 lglfullyconnected (lgl);
12951 if (lgl->occs && lgl->opts->verbose.val >= 1) {
12955 if (lgl->eliminating) str = "elim", inst = lgl->stats->elm.count, vl = 1;
12956 else if (lgl->blocking) str = "block", inst = lgl->stats->blk.count, vl=1;
12957 else str = "dense", inst = lgl->stats->dense, vl = 2;
12958 for (idx = 2; idx < lgl->nvars; idx++)
12959 if (lglevar (lgl, idx)->pos >= 0) count++;
12961 "[%s-%d] scheduled %d variables %.0f%%",
12962 str, inst, count, lglpcnt (count, lgl->nvars-2));
12966 static void lglsparse (LGL * lgl) {
12967 int idx, sign, lit, count, blit, tag;
12968 int * w, *p, * eow, * q;
12970 assert (!lgl->notfullyconnected);
12971 assert (lgl->dense);
12972 lgl->stats->sparse++;
12974 for (idx = 2; idx < lgl->nvars; idx++)
12975 for (sign = -1; sign <= 1; sign += 2) {
12977 hts = lglhts (lgl, lit);
12978 if (!hts->count) continue;
12979 w = lglhts2wchs (lgl, hts);
12980 eow = w + hts->count;
12981 for (p = q = w; p < eow; p++) {
12983 tag = blit & MASKCS;
12984 if (tag == OCCS) { count++; continue; }
12986 if (tag == BINCS) continue;
12987 assert (tag == LRGCS || tag == TRNCS);
12988 assert (p + 1 < eow);
12991 assert (hts->count - (p - q) == q - w);
12992 lglshrinkhts (lgl, hts, q - w);
12995 DEL (lgl->evars, lgl->nvars);
12996 lglrelstk (lgl, &lgl->esched);
12998 LOG (1, "removed %d full irredundant occurrences", count);
13000 lgl->notfullyconnected = 1;
13001 LOG (1, "large clauses not fully connected yet");
13004 static int lglm2i (LGL * lgl, int mlit) {
13005 int res, midx = abs (mlit);
13007 res = lglpeek (&lgl->elm->m2i, midx);
13008 if (mlit < 0) res = -res;
13012 static int lgli2m (LGL * lgl, int ilit) {
13013 AVar * av = lglavar (lgl, ilit);
13014 int res = av->mark;
13016 res = lglcntstk (&lgl->seen) + 1;
13018 assert (2*lglcntstk (&lgl->seen) == lglcntstk (&lgl->elm->noccs) - 2);
13019 assert (2*lglcntstk (&lgl->seen) == lglcntstk (&lgl->elm->mark) - 2);
13020 assert (2*lglcntstk (&lgl->seen) == lglcntstk (&lgl->elm->occs) - 2);
13021 assert (lglcntstk (&lgl->seen) == lglcntstk (&lgl->elm->m2i) - 1);
13022 lglpushstk (lgl, &lgl->seen, abs (ilit));
13023 lglpushstk (lgl, &lgl->elm->noccs, 0);
13024 lglpushstk (lgl, &lgl->elm->noccs, 0);
13025 lglpushstk (lgl, &lgl->elm->mark, 0);
13026 lglpushstk (lgl, &lgl->elm->mark, 0);
13027 lglpushstk (lgl, &lgl->elm->occs, 0);
13028 lglpushstk (lgl, &lgl->elm->occs, 0);
13029 lglpushstk (lgl, &lgl->elm->m2i, abs (ilit));
13030 LOG (4, "mapped internal variable %d to marked variable %d",
13033 if (ilit < 0) res = -res;
13037 static unsigned lglsig (int lit) {
13038 unsigned ulit = lglulit (lit), res;
13039 assert (ulit >= 2);
13041 res = (1u << (ulit & 31));
13045 static void lgladdecl (LGL * lgl, const int * c) {
13046 int ilit, mlit, umlit, size = 0, next, prev;
13050 #if !defined (NDEBUG) || !defined (NLGLOG)
13053 LOGCLS (3, c, "copying irredundant clause");
13054 INCSTEPS (elm.copies);
13056 for (p = c; (ilit = *p); p++) {
13057 val = lglval (lgl, ilit);
13059 if (val < 0) continue;
13061 if (abs (ilit) == lgl->elm->pivot) continue;
13062 mlit = lgli2m (lgl, ilit);
13063 assert (abs (mlit) != 1);
13064 csig |= lglsig (mlit);
13066 assert (size >= 1);
13067 next = lglcntstk (&lgl->elm->lits);
13068 #if !defined (NDEBUG) || !defined (NLGLOG)
13072 for (p = c; (ilit = *p); p++) {
13073 val = lglval (lgl, ilit);
13074 if (val < 0) continue;
13075 mlit = lgli2m (lgl, ilit);
13076 lglpushstk (lgl, &lgl->elm->lits, mlit);
13077 umlit = lglulit (mlit);
13078 prev = lglpeek (&lgl->elm->occs, umlit);
13079 lglpushstk (lgl, &lgl->elm->next, prev);
13080 lglpoke (&lgl->elm->occs, umlit, next++);
13081 lglpushstk (lgl, &lgl->elm->csigs, csig);
13082 lglpushstk (lgl, &lgl->elm->sizes, size);
13083 lgl->elm->noccs.start[umlit]++;
13085 lglpushstk (lgl, &lgl->elm->lits, 0);
13086 lglpushstk (lgl, &lgl->elm->next, 0);
13087 lglpushstk (lgl, &lgl->elm->csigs, 0);
13088 lglpushstk (lgl, &lgl->elm->sizes, 0);
13090 LOGCLS (4, lgl->elm->lits.start + lidx, "copied and mapped clause");
13092 LOGMCLS (4, lgl->elm->lits.start + lidx, "copied and remapped clause");
13095 for (i = 0; c[i]; i++) {
13096 Val val = lglval (lgl, c[i]);
13098 if (val < 0) continue;
13099 assert (c[i] == lglm2i (lgl, lglpeek (&lgl->elm->lits, lidx + j++)));
13105 static int lglecls (LGL * lgl, int lit) {
13106 int blit, tag, red, other, lidx, count;
13107 const int * p, * w, * eow, * c;
13110 LOG (3, "copying irredundant clauses with %d", lit);
13112 hts = lglhts (lgl, lit);
13113 if (!hts->count) return 0;
13114 w = lglhts2wchs (lgl, hts);
13115 eow = w + hts->count;
13116 for (p = w; p < eow; p++) {
13118 tag = blit & MASKCS;
13119 if (tag == TRNCS || tag == LRGCS) p++;
13120 if (tag == LRGCS) continue;
13121 red = blit & REDCS;
13123 if (tag == BINCS || tag == TRNCS) {
13125 other = blit >> RMSHFT;
13127 if (tag == TRNCS) d[2] = *p, d[3] = 0;
13131 assert (tag == OCCS);
13132 lidx = (tag == OCCS) ? (blit >> RMSHFT) : *p;
13133 c = lglidx2lits (lgl, 0, lidx);
13135 lgladdecl (lgl, c);
13141 static void lglrstecls (LGL * lgl) {
13142 assert (lgl->elm->pivot);
13143 lglclnstk (&lgl->elm->lits);
13144 lglclnstk (&lgl->elm->next);
13145 lglclnstk (&lgl->elm->csigs);
13146 lglclnstk (&lgl->elm->sizes);
13147 lglclnstk (&lgl->elm->occs);
13148 lglclnstk (&lgl->elm->noccs);
13149 lglclnstk (&lgl->elm->mark);
13150 lglclnstk (&lgl->elm->m2i);
13151 lglpopnunmarkstk (lgl, &lgl->seen);
13152 lgl->elm->pivot = 0;
13155 static void lglrelecls (LGL * lgl) {
13156 lglrelstk (lgl, &lgl->elm->lits);
13157 lglrelstk (lgl, &lgl->elm->next);
13158 lglrelstk (lgl, &lgl->elm->csigs);
13159 lglrelstk (lgl, &lgl->elm->sizes);
13160 lglrelstk (lgl, &lgl->elm->occs);
13161 lglrelstk (lgl, &lgl->elm->noccs);
13162 lglrelstk (lgl, &lgl->elm->mark);
13163 lglrelstk (lgl, &lgl->elm->m2i);
13164 lglrelstk (lgl, &lgl->elm->clv);
13167 static void lglinitecls (LGL * lgl, int idx) {
13171 assert (!lgl->elm->pivot);
13173 assert (lglmtstk (&lgl->elm->lits));
13174 assert (lglmtstk (&lgl->elm->next));
13175 assert (lglmtstk (&lgl->elm->csigs));
13176 assert (lglmtstk (&lgl->elm->sizes));
13177 assert (lglmtstk (&lgl->elm->occs));
13178 assert (lglmtstk (&lgl->elm->noccs));
13179 assert (lglmtstk (&lgl->elm->m2i));
13180 assert (lglmtstk (&lgl->seen));
13181 lgl->elm->pivot = idx;
13182 lglpushstk (lgl, &lgl->elm->mark, 0);
13183 lglpushstk (lgl, &lgl->elm->mark, 0);
13184 lglpushstk (lgl, &lgl->elm->occs, 0);
13185 lglpushstk (lgl, &lgl->elm->occs, 0);
13186 lglpushstk (lgl, &lgl->elm->noccs, 0);
13187 lglpushstk (lgl, &lgl->elm->noccs, 0);
13188 lglpushstk (lgl, &lgl->elm->m2i, 0);
13189 (void) lgli2m (lgl, idx);
13190 lglpushstk (lgl, &lgl->elm->lits, 0);
13191 lglpushstk (lgl, &lgl->elm->next, 0);
13192 lglpushstk (lgl, &lgl->elm->csigs, 0);
13193 lglpushstk (lgl, &lgl->elm->sizes, 0);
13194 lgl->elm->necls = 0;
13198 lglecls (lgl, idx);
13199 lgl->elm->negcls = lgl->elm->necls;
13200 lgl->elm->neglidx = lglcntstk (&lgl->elm->lits);
13204 lglecls (lgl, -idx);
13205 LOG (2, "found %d variables in %d clauses with %d or %d",
13206 lglcntstk (&lgl->seen), clauses, idx, -idx);
13207 assert (lgl->elm->pivot);
13210 static void lglelrmcls (LGL * lgl, int lit, int * c, int clidx) {
13211 int lidx, i, other, ulit, * lits, * csigs, blit, tag, red, other2;
13212 int * p, * eow, * w, count;
13217 lits = lgl->elm->lits.start;
13218 csigs = lgl->elm->csigs.start;
13219 assert (lits < c && c < lgl->elm->lits.top - 1);
13221 LOGCLS (2, c, "removing clause");
13222 for (i = lidx; (other = lits[i]); i++) {
13223 assert (other < NOTALIT);
13226 ulit = lglulit (other);
13227 assert (ulit < lglcntstk (&lgl->elm->noccs));
13228 assert (lgl->elm->noccs.start[ulit] > 0);
13229 lgl->elm->noccs.start[ulit] -= 1;
13232 size = lglpeek (&lgl->elm->sizes, lidx);
13234 hts = lglhts (lgl, lit);
13235 assert (hts->count > 0 && hts->count >= clidx);
13236 w = lglhts2wchs (lgl, hts);
13237 eow = w + hts->count;
13238 blit = tag = count = 0;
13239 for (p = w; p < eow; p++) {
13241 tag = blit & MASKCS;
13242 if (tag == TRNCS || tag == LRGCS) p++;
13243 if (tag == LRGCS) continue;
13244 red = blit & REDCS;
13246 if (count == clidx) break;
13249 assert (count == clidx);
13250 assert (blit && tag);
13252 if (tag == BINCS) {
13253 assert (size >= 2);
13254 other = blit >> RMSHFT;
13255 lglrmbcls (lgl, lit, other, 0);
13256 } else if (tag == TRNCS) {
13257 other = blit >> RMSHFT;
13259 lglrmtcls (lgl, lit, other, other2, 0);
13261 assert (tag == OCCS);
13262 lidx = (tag == OCCS) ? (blit >> RMSHFT) : *p;
13265 int * q, * d = lglidx2lits (lgl, 0, lidx);
13266 for (q = d; *q; q++)
13268 assert (q - d >= size);
13271 lglrmlcls (lgl, lidx, 0);
13277 static int lglbacksub (LGL * lgl, int * c, int str) {
13278 int * start = lgl->elm->lits.start, * p, * q, marked = 0, res, * d;
13279 int lit, ulit, occ, next, osize, other, uolit, size, plit, phase, clidx;
13280 unsigned ocsig, csig = 0, masksig;
13282 const char * mode = str ? "strengthening" : "subsumption";
13284 LOGMCLS (BWL + 1, c, "backward %s check for clause", mode);
13285 LOGCLS (BWL + 1, c, "backward %s check for mapped clause", mode);
13286 phase = (c - start) >= lgl->elm->neglidx;
13287 for (p = c; (lit = *p); p++)
13288 if (abs (lit) != 1)
13289 csig |= lglsig (lit);
13291 assert (csig == lglpeek (&lgl->elm->csigs, c - start));
13292 assert (size == lglpeek (&lgl->elm->sizes, c - start));
13295 if (str) phase = !phase;
13296 lit = phase ? -1 : 1;
13297 masksig = ~(lglsig (-lit) | lglsig (lit));
13299 ulit = lglulit (lit);
13300 occ = lglpeek (&lgl->elm->noccs, ulit);
13301 if (!str && occ <= 1) return 0;
13302 if (str && !occ) return 0;
13303 for (next = lglpeek (&lgl->elm->occs, ulit);
13305 next = lglpeek (&lgl->elm->next, next)) {
13306 INCSTEPS (elm.steps);
13307 if (next == p - start) continue;
13308 if (phase != (next >= lgl->elm->neglidx)) continue;
13309 plit = lglpeek (&lgl->elm->lits, next);
13310 if (plit >= NOTALIT) continue;
13311 assert (plit == lit);
13312 osize = lglpeek (&lgl->elm->sizes, next);
13313 if (osize > size) continue;
13314 ocsig = lglpeek (&lgl->elm->csigs, next);
13317 if ((ocsig & ~csig)) continue;
13319 for (q = c; (other = *q); q++) {
13320 if (str && abs (other) == 1) other = -other;
13321 uolit = lglulit (other);
13322 assert (!lglpeek (&lgl->elm->mark, uolit));
13323 lglpoke (&lgl->elm->mark, uolit, 1);
13327 d = lgl->elm->lits.start + next;
13328 if (c <= d && d < c + size) continue;
13329 if (str) lgl->stats->elm.strchks++; else lgl->stats->elm.subchks++;
13332 LOGMCLS (BWL + 1, d, "backward %s check with clause", mode);
13334 for (q = d; res && (other = *q); q++) {
13335 uolit = lglulit (other);
13336 res = lglpeek (&lgl->elm->mark, uolit);
13338 if (!res || !str || osize < size) continue;
13340 "static double strengthened by double self-subsuming resolution");
13341 assert ((c - start) < lgl->elm->neglidx);
13342 assert ((d - start) >= lgl->elm->neglidx);
13345 q = lgl->elm->lits.start + lgl->elm->neglidx;
13348 if (other >= NOTALIT) { while (*q++) ; continue; }
13349 if (!other) clidx++;
13352 "strengthened and subsumed original irredundant clause");
13354 "strengthened and subsumed mapped irredundant clause");
13355 lglelrmcls (lgl, -lgl->elm->pivot, d, clidx);
13358 for (p = c; (lit = *p); p++) {
13359 if (str && abs (lit) == 1) lit = -lit;
13360 ulit = lglulit (lit);
13361 assert (lglpeek (&lgl->elm->mark, ulit));
13362 lglpoke (&lgl->elm->mark, ulit, 0);
13368 static void lglelmsub (LGL * lgl) {
13369 int clidx, count, subsumed, pivot, * c;
13370 count = clidx = subsumed = 0;
13371 pivot = lgl->elm->pivot;
13372 for (c = lgl->elm->lits.start + 1;
13373 c < lgl->elm->lits.top &&
13374 lgl->limits->elm.steps > lgl->stats->elm.steps;
13376 INCSTEPS (elm.steps);
13377 if (count++ == lgl->elm->negcls) clidx = 0, pivot = -pivot;
13378 if (lglbacksub (lgl, c, 0)) {
13380 lgl->stats->elm.sub++;
13381 LOGMCLS (BWL, c, "subsumed original irredundant clause");
13382 LOGCLS (3, c, "subsumed mapped irredundant clause");
13383 lglelrmcls (lgl, pivot, c, clidx);
13387 LOG (BWL + !subsumed,
13388 "subsumed %d clauses containing %d or %d",
13389 subsumed, lgl->elm->pivot, -lgl->elm->pivot);
13392 static int lglelmstr (LGL * lgl) {
13393 int clidx, count, strengthened, pivot, * c, * p, mlit, ilit, res, found;
13395 count = clidx = strengthened = 0;
13396 pivot = lgl->elm->pivot;
13398 LOG (3, "strengthening with pivot %d", pivot);
13399 for (c = lgl->elm->lits.start + 1;
13400 c < lgl->elm->lits.top &&
13401 lgl->limits->elm.steps > lgl->stats->elm.steps;
13403 INCSTEPS (elm.steps);
13404 if (count++ == lgl->elm->negcls) {
13405 clidx = 0, pivot = -pivot;
13406 LOG (3, "strengthening with pivot %d", pivot);
13408 if (*c == REMOVED) {
13409 while (*c) { assert (*c == REMOVED); c++; }
13412 if (lglbacksub (lgl, c, 1)) {
13414 lgl->stats->elm.str++;
13415 LOGMCLS (2, c, "strengthening original irredundant clause");
13416 LOGCLS (3, c, "strengthening mapped irredundant clause");
13417 assert (lglmtstk (&lgl->clause));
13420 for (p = c; (mlit = *p); p++) {
13421 ilit = lglm2i (lgl, *p);
13422 if (ilit == pivot) { found++; continue; }
13423 assert (!lglval (lgl, ilit));
13424 lglpushstk (lgl, &lgl->clause, ilit);
13428 lglpushstk (lgl, &lgl->clause, 0);
13429 LOGCLS (2, lgl->clause.start, "static strengthened irredundant clause");
13430 if (lgl->opts->drup.val) lgldrupcls (lgl);
13431 #ifndef NLGLPICOSAT
13432 lglpicosatchkcls (lgl);
13434 lglelrmcls (lgl, pivot, c, clidx);
13435 lgldrupligaddcls (lgl, REDCS);
13436 lgladdcls (lgl, 0, 0, 1);
13437 lglclnstk (&lgl->clause);
13438 if (size == 1) { res = 1; break; }
13442 LOG (2, "strengthened %d clauses containing %d or %d",
13443 strengthened, lgl->elm->pivot, -lgl->elm->pivot);
13447 static int lglflushclauses (LGL * lgl, int lit) {
13448 int blit, tag, red, other, other2, count, glue, res;
13449 const int * p, * w, * eow;
13450 int lidx, glidx, slidx;
13457 lglchkirrstats (lgl);
13458 assert (lgl->probing || lgl->lkhd || lgl->dense);
13459 hts = lglhts (lgl, lit);
13460 if (!hts->count) return 0;
13462 occs = lgl->occs ? lglocc (lgl, lit) : 0;
13465 LOG (2, "flushing clauses with literal %d", lit);
13466 w = lglhts2wchs (lgl, hts);
13467 eow = w + hts->count;
13469 for (p = w; p < eow; p++) {
13470 if (lgl->blocking) INCSTEPS (blk.steps);
13471 if (lgl->eliminating) INCSTEPS (elm.steps);
13472 if (lgl->simpleprobing) INCSTEPS (prb.simple.steps);
13474 tag = blit & MASKCS;
13475 red = blit & REDCS;
13476 other = blit >> RMSHFT;
13477 if (tag == TRNCS || tag == LRGCS) p++;
13478 if (tag == BINCS) {
13479 lglrmbwch (lgl, other, lit, red);
13480 LOG (2, "flushed %s binary clause %d %d", lglred2str (red), lit, other);
13481 lgldeclscnt (lgl, 2, red, 0);
13482 if (!red) lgldecocc (lgl, lit), lgldecocc (lgl, other), res++;
13484 } else if (tag == TRNCS) {
13486 lglrmtwch (lgl, other2, lit, other, red);
13487 lglrmtwch (lgl, other, lit, other2, red);
13488 LOG (2, "flushed %s ternary clause %d %d %d",
13489 lglred2str (red), lit, other, other2);
13490 lgldeclscnt (lgl, 3, red, 0);
13492 lgldecocc (lgl, lit);
13493 lgldecocc (lgl, other);
13494 lgldecocc (lgl, other2);
13499 assert (tag == OCCS || tag == LRGCS);
13500 if (tag == LRGCS) {
13502 s = lglidx2stk (lgl, red, lidx);
13504 glue = lidx & GLUEMASK;
13505 c = s->start + (lidx >> GLUESHFT);
13508 c = s->start + lidx;
13511 lidx = (blit >> RMSHFT);
13513 c = s->start + lidx;
13516 if (c >= s->top || (other = c[0]) >= NOTALIT) continue;
13517 LOGCLS (2, c, "flushed %s large clause", lglred2str (red));
13518 if (tag == LRGCS) {
13519 if (other == lit) other = c[1];
13520 assert (abs (other) != abs (lit));
13521 lglrmlwch (lgl, other, red, lidx);
13524 if (red) glidx <<= GLUESHFT;
13525 if (c[1] != lit) lglrmlwch (lgl, c[1], red, glidx);
13526 if (other != lit) lglrmlwch (lgl, other, red, glidx);
13532 } else lgldecocc (lgl, lit);
13533 for (q = c; (other = *q); q++) { assert (other < NOTALIT);
13535 if (other == lit) continue;
13536 if (red && glue) continue;
13538 if (red && tag == LRGCS) slidx >>= GLUESHFT;
13539 lglrmlocc (lgl, other, red, slidx);
13540 if (!red) lgldecocc (lgl, other);
13543 lgldeclscnt (lgl, q - c, red, glue);
13544 lgltrimlitstk (lgl, red, lidx);
13550 if (lgl->occs) assert (occs == res);
13552 lglshrinkhts (lgl, hts, 0);
13553 LOG (2, "flushed %d clauses with %d including %d irredundant",
13555 lglchkirrstats (lgl);
13559 static int lglflushlits (LGL * lgl, int lit) {
13560 int blit, tag, red, other, other2, size, satisfied, d[3], glue;
13561 int * p, * w, * eow, * c, * l, * k;
13562 int lidx, slidx, glidx;
13568 // Some compilers do not like local functions, thus we use macros instead.
13570 #define FIXPTRS() do { p += delta, w += delta, eow += delta; } while (0)
13573 LOG (2, "flushing literal %d from clauses", lit);
13574 assert (!lgl->level);
13575 assert (lglifixed (lgl, lit) < 0);
13576 assert (lgl->dense);
13577 lglchkirrstats (lgl);
13578 hts = lglhts (lgl, lit);
13579 w = lglhts2wchs (lgl, hts);
13580 eow = w + hts->count;
13582 for (p = w; p < eow; p++) {
13583 if (lgl->blocking) INCSTEPS (blk.steps);
13584 if (lgl->eliminating) INCSTEPS (elm.steps);
13585 if (lgl->simpleprobing) INCSTEPS (prb.simple.steps);
13588 tag = blit & MASKCS;
13589 red = blit & REDCS;
13590 if (tag == BINCS) {
13591 other = blit >> RMSHFT;
13592 assert ((red && lgliselim (lgl, other)) || lglval (lgl, other) > 0);
13593 lglrmbwch (lgl, other, lit, red);
13594 LOG (2, "flushed %s binary clause %d %d", lglred2str (red), lit, other);
13595 lgldeclscnt (lgl, 2, red, 0);
13597 if (lgl->dense) lgldecocc (lgl, lit), lgldecocc (lgl, other);
13600 } else if (tag == TRNCS) {
13601 other = blit >> RMSHFT;
13603 lglrmtwch (lgl, other2, lit, other, red);
13604 lglrmtwch (lgl, other, lit, other2, red);
13605 LOG (2, "flushed %s ternary clause %d %d %d",
13606 lglred2str (red), lit, other, other2);
13607 lgldeclscnt (lgl, 3, red, 0);
13610 lgldecocc (lgl, lit);
13611 lgldecocc (lgl, other);
13612 lgldecocc (lgl, other2);
13616 val = lglval (lgl, other);
13617 val2 = lglval (lgl, other2);
13618 if (!val && !val2) {
13620 "reducing flushed %s ternary clause %d %d %d to binary %s clause %d %d",
13622 lit, other, other2,
13625 delta = lglwchbin (lgl, other, other2, red);
13626 delta += lglwchbin (lgl, other2, other, red);
13627 if (lgl->simpleprobing && lgl->opts->prbsimple.val >= 2)
13628 lglwrktouch (lgl, -other), lglwrktouch (lgl, -other2);
13629 if (delta) FIXPTRS ();
13631 lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
13633 lglincirr (lgl, 2);
13634 if (lgl->dense) lglincocc (lgl, other), lglincocc (lgl, other2);
13638 if (!red || (!lgliselim (lgl, other) && !lgliselim (lgl, other2)))
13639 assert (val > 0 || val2 > 0);
13643 assert (tag == OCCS || tag == LRGCS);
13644 lidx = (tag == LRGCS) ? *++p : (blit >> RMSHFT);
13645 s = lglidx2stk (lgl, red, lidx);
13646 c = s->start + (red ? (lidx >> GLUESHFT) : lidx);
13647 if (c >= s->top || c[0] >= NOTALIT) continue;
13648 size = satisfied = 0;
13649 for (l = c; (other = *l); l++) {
13650 if (other == lit) continue;
13651 if ((val = lglval (lgl, other)) < 0) continue;
13652 if (val > 0) { satisfied = 1; break; }
13653 if (size < 3) d[size] = other;
13656 if (!satisfied && size == 2) {
13658 "reducing to binary %s clause %d %d flushed large %s clause",
13659 lglred2str (red), d[0], d[1], lglred2str (red));
13660 delta = lglwchbin (lgl, d[0], d[1], red);
13661 delta += lglwchbin (lgl, d[1], d[0], red);
13662 if (delta) FIXPTRS ();
13664 lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
13666 lglincirr (lgl, 2);
13667 if (lgl->dense) lglincocc (lgl, d[0]), lglincocc (lgl, d[1]);
13669 if (lgl->simpleprobing && lgl->opts->prbsimple.val >= 2)
13670 lglwrktouch (lgl, -d[0]), lglwrktouch (lgl, -d[1]);
13672 if (!satisfied && size == 3) {
13674 "reducing to ternary %s clause %d %d %d flushed large %s clause",
13675 lglred2str (red), d[0], d[1], d[2], lglred2str (red));
13676 delta = lglwchtrn (lgl, d[0], d[1], d[2], red);
13677 delta += lglwchtrn (lgl, d[1], d[0], d[2], red);
13678 delta += lglwchtrn (lgl, d[2], d[0], d[1], red);
13679 if (delta) FIXPTRS ();
13681 lgl->stats->red.trn++, assert (lgl->stats->red.trn > 0);
13683 lglincirr (lgl, 3);
13685 lglincocc (lgl, d[0]);
13686 lglincocc (lgl, d[1]);
13687 lglincocc (lgl, d[2]);
13690 if (lgl->simpleprobing && lgl->opts->prbsimple.val >= 3)
13691 lglwrktouch (lgl, d[0]),
13692 lglwrktouch (lgl, d[1]),
13693 lglwrktouch (lgl, d[2]);
13695 if (lgl->dense && !red) {
13696 for (l = c; (other = *l); l++) {
13697 if (satisfied || size <= 3 || lglval (lgl, other) < 0) {
13698 if (!red) lgldecocc (lgl, other);
13699 if (other != lit) {
13701 if (red && tag == LRGCS) slidx >>= GLUESHFT;
13702 lglrmlocc (lgl, other, red, slidx);
13708 if (red && tag == OCCS) glidx <<= GLUESHFT;
13709 if (c[0] != lit) lglrmlwch (lgl, c[0], red, glidx);
13710 if (c[1] != lit) lglrmlwch (lgl, c[1], red, glidx);
13711 if (satisfied || size <= 3) {
13712 if (red) { LGLCHKACT (c[-1]); c[-1] = REMOVED; }
13713 for (k = c; (other = *k); k++) *k = REMOVED;
13716 glue = (tag == LRGCS) ? (lidx & GLUEMASK) : 0;
13717 assert (lgl->stats->lir[glue].clauses > 0);
13718 lgl->stats->lir[glue].clauses--;
13719 assert (lgl->stats->red.lrg > 0);
13720 lgl->stats->red.lrg--;
13721 } else lgldecirr (lgl, k - c);
13723 for (l = k = c; (other = *l); l++) {
13724 if ((val = lglval (lgl, other)) < 0) continue;
13725 if (lgl->simpleprobing && lgl->opts->prbsimple.val >= 3)
13726 lglwrktouch (lgl, other);
13727 assert (abs (other) != abs (lit));
13731 assert (size == k - c);
13732 if (!red && k < l) {
13733 assert (lgl->stats->irr.lits.cur >= l - k);
13734 lgl->stats->irr.lits.cur -= l - k;
13737 while (k <= l) *k++ = REMOVED;
13738 delta = lglwchlrg (lgl, c[0], c[1], red, glidx);
13739 delta += lglwchlrg (lgl, c[1], c[0], red, glidx);
13740 if (delta) FIXPTRS ();
13742 lgltrimlitstk (lgl, red, lidx);
13745 hts = lglhts (lgl, lit);
13746 lglshrinkhts (lgl, hts, 0);
13747 LOG (2, "flushed %d occurrences of literal %d including %d irredundant",
13749 lglchkirrstats (lgl);
13756 static int lglflush (LGL * lgl) {
13758 if (lgl->mt) return 0;
13759 lglchkirrstats (lgl);
13760 assert (!lgl->level);
13761 assert (lgl->probing || lgl->lkhd || lgl->dense);
13762 if (lgl->flushed == lglcntstk (&lgl->trail)) return 1;
13763 if (!lglbcp (lgl)) { lgl->mt = 1; return 0; }
13764 if (!lglsyncunits (lgl)) { assert (lgl->mt); return 0; }
13766 while (lgl->flushed < lglcntstk (&lgl->trail)) {
13767 lit = lglpeek (&lgl->trail, lgl->flushed++);
13768 lglflushclauses (lgl, lit);
13769 lglflushlits (lgl, -lit);
13772 LOG (2, "flushed %d literals", count);
13777 static void lglblockinglit (LGL * lgl, int ilit) {
13778 int elit = lglexport (lgl, ilit), sgnbit = (1 << (elit < 0));
13779 Ext * ext = lglelit2ext (lgl, elit);
13780 assert (!ext->equiv);
13781 assert (!ext->eliminated);
13782 assert (abs (ext->repr) == abs (ilit));
13783 if (ext->blocking & sgnbit) return;
13784 ext->blocking |= sgnbit;
13785 LOG (3, "marking external %d internal %d as blocking", elit, ilit);
13786 lgl->stats->blk.lits++;
13789 static void lglelmfrelit (LGL * lgl, int mpivot,
13790 int * sop, int * eop, int * son, int * eon) {
13791 int ipivot = mpivot * lgl->elm->pivot, clidx, ilit, tmp, cover, maxcover;
13792 int * c, * d, * p, * q, lit, nontrivial, idx, sgn, clen, reslen;
13793 assert (mpivot == 1 || mpivot == -1);
13796 "blocked clause elimination and forced resolution of clauses with %d",
13799 cover = lglpeek (&lgl->elm->noccs, lglulit (-mpivot));
13800 for (c = sop; c < eop; c = p + 1) {
13801 if (lgl->eliminating) INCSTEPS (elm.steps);
13802 if (*c == REMOVED) { for (p = c + 1; *p; p++) ; continue; }
13804 for (p = c; (lit = *p); p++) {
13805 if (lit == mpivot) continue;
13806 assert (lit != -mpivot);
13807 maxcover += lglpeek (&lgl->elm->noccs, lglulit (-lit));
13809 if (maxcover < cover - 1) { clidx++; continue; }
13810 for (p = c; (lit = *p); p++) {
13811 if (lit == mpivot) continue;
13812 assert (lit != -mpivot);
13814 assert (!lglpeek (&lgl->elm->mark, idx));
13815 sgn = lglsgn (lit);
13816 lglpoke (&lgl->elm->mark, idx, sgn);
13820 for (d = son; !nontrivial && d < eon; d = q + 1) {
13821 INCSTEPS (elm.steps);
13822 if (*d == REMOVED) { for (q = d + 1; *q; q++) ; continue; }
13823 INCSTEPS (elm.resolutions);
13824 LOGMCLS (3, c, "trying forced resolution 1st antecedent");
13825 LOGMCLS (3, d, "trying forced resolution 2nd antecedent");
13828 for (q = d; (lit = *q); q++) {
13829 if (lit == -mpivot) continue;
13830 assert (lit != mpivot);
13831 idx = abs (lit), sgn = lglsgn (lit);
13832 tmp = lglpeek (&lgl->elm->mark, idx);
13833 if (tmp == -sgn) break;
13834 if (tmp != sgn) reslen++;
13838 LOG (3, "trying forced resolution ends with trivial resolvent");
13840 LOG (3, "non trivial resolvent in blocked clause elimination");
13841 nontrivial = INT_MAX;
13844 for (p = c; (lit = *p); p++) {
13845 if (lit == mpivot) continue;
13846 assert (lit != -mpivot);
13848 assert (lglpeek (&lgl->elm->mark, idx) == lglsgn (lit));
13849 lglpoke (&lgl->elm->mark, idx, 0);
13851 assert (lgl->opts->elim.val);
13853 lgl->opts->block.val &&
13854 lgl->opts->elmblk.val &&
13855 (!lgl->opts->elmblkwait.val || !lgl->opts->elim.val || lgl->elmrtc)) {
13856 assert (maxcover >= cover);
13857 lgl->stats->elm.blkd++;
13858 LOGMCLS (2, c, "blocked on %d clause", ipivot);
13859 lglepush (lgl, ipivot);
13860 for (p = c; (lit = *p); p++) {
13861 if (lit == mpivot) continue;
13862 assert (lit != -mpivot);
13863 ilit = lglm2i (lgl, lit);
13864 lglepush (lgl, ilit);
13867 lglelrmcls (lgl, ipivot, c, clidx);
13868 lglblockinglit (lgl, ipivot);
13872 if (lgl->limits->elm.steps <= lgl->stats->elm.steps) {
13873 LOG (2, "maximum number of steps in elimination exhausted");
13879 static void lglelmfre (LGL * lgl) {
13880 int * sop, * eop, * son, * eon;
13881 assert (lgl->elm->pivot);
13882 sop = lgl->elm->lits.start + 1;
13883 eop = son = lgl->elm->lits.start + lgl->elm->neglidx;
13884 eon = lgl->elm->lits.top;
13885 lglelmfrelit (lgl, 1, sop, eop, son, eon);
13886 lglelmfrelit (lgl, -1, son, eon, sop, eop);
13889 static void lgleliminated (LGL * lgl, int pivot) {
13893 assert (!lglifrozen (lgl, pivot));
13894 av = lglavar (lgl, pivot);
13895 assert (av->type == FREEVAR);
13896 av->type = ELIMVAR;
13897 lgl->stats->elm.elmd++;
13898 assert (lgl->stats->elm.elmd > 0);
13899 lglflushclauses (lgl, pivot);
13900 lglflushclauses (lgl, -pivot);
13901 LOG (2, "eliminated %d", pivot);
13902 elit = lglexport (lgl, pivot);
13903 e = lglelit2ext (lgl, elit);
13904 assert (!e->eliminated);
13905 assert (!e->equiv);
13909 static void lglepusheliminated (LGL * lgl, int idx) {
13910 const int * p, * w, * eow, * c, * l;
13911 int lit, blit, tag, red, other;
13913 lit = (lglocc (lgl, idx) < lglocc (lgl, -idx)) ? idx : -idx;
13914 LOG (3, "keeping clauses with %d for extending assignment", lit);
13915 hts = lglhts (lgl, lit);
13916 w = lglhts2wchs (lgl, hts);
13917 eow = w + hts->count;
13918 for (p = w; p < eow; p++) {
13920 tag = blit & MASKCS;
13921 if (tag == TRNCS || tag == LRGCS) p++;
13922 if (tag == LRGCS) continue;
13923 red = blit & REDCS;
13925 lglepush (lgl, lit);
13926 if (tag == BINCS || tag == TRNCS) {
13927 lglepush (lgl, blit >> RMSHFT);
13929 lglepush (lgl, *p);
13931 assert (tag == OCCS);
13932 c = lglidx2lits (lgl, 0, blit >> RMSHFT);
13933 for (l = c; (other = *l); l++)
13935 lglepush (lgl, other);
13939 lglepush (lgl, -lit);
13941 lgleliminated (lgl, idx);
13944 static int lglunhimpl (const DFPR * dfpr, int a, int b) {
13945 int u = lglulit (a), v = lglulit (b), c, d, f, g;
13946 c = dfpr[u].discovered; if (!c) return 0;
13947 d = dfpr[v].discovered; if (!d) return 0;
13948 f = dfpr[u].finished, g = dfpr[v].finished;
13949 assert (0 < c && c < f);
13950 assert (0 < d && d < g);
13951 return c < d && g < f;
13954 static int lglunhimplies2 (const DFPR * dfpr, int a, int b) {
13955 return lglunhimpl (dfpr, a, b) || lglunhimpl (dfpr, -b, -a);
13958 static int lglunhimplincl (const DFPR * dfpr, int a, int b) {
13959 int u = lglulit (a), v = lglulit (b), c, d, f, g;
13960 c = dfpr[u].discovered; if (!c) return 0;
13961 d = dfpr[v].discovered; if (!d) return 0;
13962 f = dfpr[u].finished, g = dfpr[v].finished;
13963 assert (0 < c && c < f);
13964 assert (0 < d && d < g);
13965 return c <= d && g <= f;
13968 static int lglunhimplies2incl (const DFPR * dfpr, int a, int b) {
13969 return lglunhimplincl (dfpr, a, b) || lglunhimplincl (dfpr, -b, -a);
13972 static int lglhastrn (LGL * lgl, int a, int b, int c) {
13973 int blit, tag, other, other2;
13974 const int * w, * eow, * p;
13975 HTS * ha, * hb, * hc;
13976 ha = lglhts (lgl, a);
13977 hb = lglhts (lgl, b);
13978 if (hb->count < ha->count) { SWAP (int, a, b); SWAP (HTS *, ha, hb); }
13979 hc = lglhts (lgl, c);
13980 if (hc->count < ha->count) { SWAP (int, a, c); SWAP (HTS *, ha, hc); }
13981 w = lglhts2wchs (lgl, ha);
13982 eow = w + ha->count;
13983 for (p = w; p < eow; p++) {
13985 tag = blit & MASKCS;
13986 if (tag == OCCS) continue;
13987 if (tag == BINCS) {
13988 other = blit >> RMSHFT;
13989 if (other == b || other == c) return 1;
13992 if (tag == TRNCS || tag == LRGCS) p++;
13993 if (tag == LRGCS) continue;
13994 assert (tag == TRNCS);
13995 other = blit >> RMSHFT;
13996 if (other != b && other != c) continue;
13998 if (other2 == b || other2 == c) return 1;
14000 if (hc->count < hb->count) { SWAP (int, b, c); SWAP (HTS *, hb, hc); }
14001 w = lglhts2wchs (lgl, hb);
14002 eow = w + hb->count;
14003 for (p = w; p < eow; p++) {
14005 tag = blit & MASKCS;
14006 if (tag == OCCS) continue;
14007 if (tag == TRNCS || tag == LRGCS) { p++; continue; }
14008 assert (tag == BINCS);
14009 other = blit >> RMSHFT;
14010 if (other == c) return 1;
14015 static int64_t lglfactor (LGL * lgl, int lim, int count) {
14016 int64_t factor, res;
14017 if (!count) return lim;
14018 switch (lgl->opts->factor.val) {
14019 default: factor = 1; break;
14020 case 1: factor = lglceilld (count); break;
14021 case 2: factor = count; break;
14022 case 3: factor = count*(int64_t)count; break;
14024 if (!factor) factor = 1;
14025 if (factor > lgl->opts->factmax.val) factor = lgl->opts->factmax.val;
14026 res = lim * factor;
14030 static int lglforcedve (LGL * lgl, int idx) {
14031 int pocc = lglocc (lgl, idx);
14032 int nocc = lglocc (lgl, -idx);
14033 int count = lgl->stats->elm.count;
14034 if (!pocc) return 1;
14035 if (!nocc) return 1;
14036 if (lgl->opts->elmfull.val) return 0;
14037 if (pocc >= lglfactor (lgl, lgl->opts->elmocclim1.val, count)) return -1;
14038 if (nocc >= lglfactor (lgl, lgl->opts->elmocclim1.val, count)) return -1;
14039 if (pocc < lglfactor (lgl, lgl->opts->elmocclim2.val, count)) return 0;
14040 if (nocc < lglfactor (lgl, lgl->opts->elmocclim2.val, count)) return 0;
14044 static int lgltrylargeve (LGL * lgl) {
14045 const int * c, * d, * sop, * eop, * son, * eon, * p, * q, * start, * end;
14046 int lit, idx, sgn, tmp, ip, ilit, npocc, nnocc, limit, count, i, res;
14047 int clen, dlen, reslen, maxreslen;
14048 ip = lgl->elm->pivot;
14050 if ((res = lglforcedve (lgl, ip))) return res > 0;
14051 sop = lgl->elm->lits.start + 1;
14052 eop = son = lgl->elm->lits.start + lgl->elm->neglidx;
14053 eon = lgl->elm->lits.top;
14054 npocc = lglpeek (&lgl->elm->noccs, lglulit (1));
14055 nnocc = lglpeek (&lgl->elm->noccs, lglulit (-1));
14056 limit = npocc + nnocc;
14058 for (i = 0; i <= 1; i++) {
14059 start = i ? son : sop;
14060 end = i ? eon : eop;
14061 for (c = start; c < end; c++) {
14062 INCSTEPS (elm.steps);
14063 if (*c == REMOVED) { while (*c) c++; continue; }
14064 while ((lit = *c)) {
14065 (void) lglm2i (lgl, lit);
14071 assert (count == limit);
14072 LOG (3, "trying clause distribution for %d with limit %d", ip, limit);
14074 for (c = sop; c < eop && limit >= 0; c = p + 1) {
14075 INCSTEPS (elm.steps);
14076 if (*c == REMOVED) { for (p = c + 1; *p; p++) ; continue; }
14077 assert (lglmtstk (&lgl->resolvent));
14079 for (p = c; (lit = *p); p++) {
14080 if (lit == 1) continue;
14081 assert (lit != -1);
14083 assert (!lglpeek (&lgl->elm->mark, idx));
14084 sgn = lglsgn (lit);
14085 lglpoke (&lgl->elm->mark, idx, sgn);
14086 ilit = lglm2i (lgl, lit);
14087 lglpushstk (lgl, &lgl->resolvent, ilit);
14090 for (d = son; limit >= 0 && d < eon; d = q + 1) {
14091 INCSTEPS (elm.steps);
14092 if (*d == REMOVED) { for (q = d + 1; *q; q++) ; continue; }
14093 INCSTEPS (elm.resolutions);
14094 LOGMCLS (3, c, "trying resolution 1st antecedent");
14095 LOGMCLS (3, d, "trying resolution 2nd antecedent");
14098 for (q = d; (lit = *q); q++) {
14099 if (lit == -1) continue;
14102 idx = abs (lit), sgn = lglsgn (lit);
14103 tmp = lglpeek (&lgl->elm->mark, idx);
14104 if (tmp == -sgn) break;
14105 if (tmp == sgn) continue;
14106 ilit = lglm2i (lgl, lit);
14107 lglpushstk (lgl, &lgl->resolvent, ilit);
14110 assert (reslen == lglcntstk (&lgl->resolvent));
14111 if (!lit && reslen == 1) {
14112 LOG (3, "trying resolution ends with unit clause");
14113 lit = lglpeek (&lgl->resolvent, 0);
14114 limit += lglevar (lgl, lit)->occ[lit < 0];
14117 LOG (3, "trying resolution ends with trivial resolvent");
14121 "trying resolution with non trivial resolvent remaining %d",
14123 if (reslen > maxreslen) maxreslen = reslen;
14126 lglrststk (&lgl->resolvent, clen);
14128 lglclnstk (&lgl->resolvent);
14129 for (p = c; (lit = *p); p++) {
14130 if (lit == 1) continue;
14131 assert (lit != -1);
14133 assert (lglpeek (&lgl->elm->mark, idx) == lglsgn (lit));
14134 lglpoke (&lgl->elm->mark, idx, 0);
14136 if (lgl->limits->elm.steps <= lgl->stats->elm.steps) {
14137 LOG (2, "maximum number of steps in elimination exhausted");
14141 assert (lglm2i (lgl, 1) == ip);
14143 LOG (3, "resolving away %d would increase number of clauses", ip);
14146 if (limit) LOG (2, "resolving away %d removes %d clauses", ip, limit);
14147 else LOG (2, "resolving away %d does not change number of clauses", ip);
14151 static void lgldolargeve (LGL * lgl) {
14152 const int * c, * d, * sop, * eop, * son, * eon, * p, * q, * start, * end;
14153 int lit, idx, sgn, tmp, ip, ilit, mp, npocc, nnocc;
14154 int clen, dlen, reslen;
14156 ip = lgl->elm->pivot;
14158 sop = lgl->elm->lits.start + 1;
14159 eop = son = lgl->elm->lits.start + lgl->elm->neglidx;
14160 eon = lgl->elm->lits.top;
14161 npocc = lglpeek (&lgl->elm->noccs, lglulit (1));
14162 nnocc = lglpeek (&lgl->elm->noccs, lglulit (-1));
14163 LOG (2, "(large) variable elimination of %d", lgl->elm->pivot);
14164 lglflushclauses (lgl, ip);
14165 lglflushclauses (lgl, -ip);
14166 if (npocc < nnocc) start = sop, end = eop, mp = 1;
14167 else start = son, end = eon, ip = -ip, mp = -1;
14168 LOG (3, "will save clauses with %d for extending assignment", ip);
14169 for (c = start; c < end; c = p + 1) {
14170 INCSTEPS (elm.steps);
14171 if (*c == REMOVED) { for (p = c + 1; *p; p++) ; continue; }
14172 lglepush (lgl, ip);
14173 for (p = c; (lit = *p); p++) {
14174 if (lit == mp) continue;
14175 assert (lit != -mp);
14176 ilit = lglm2i (lgl, lit);
14177 lglepush (lgl, ilit);
14181 lglepush (lgl, -ip);
14183 for (c = sop; c < eop; c = p + 1) {
14184 INCSTEPS (elm.steps);
14185 if (*c == REMOVED) { for (p = c + 1; *p; p++) ; continue; }
14186 assert (lglmtstk (&lgl->resolvent));
14188 for (p = c; (lit = *p); p++) {
14189 if (lit == 1) continue;
14190 assert (lit != -1);
14192 assert (!lglpeek (&lgl->elm->mark, idx));
14193 sgn = lglsgn (lit);
14194 lglpoke (&lgl->elm->mark, idx, sgn);
14195 ilit = lglm2i (lgl, lit);
14196 lglpushstk (lgl, &lgl->resolvent, ilit);
14199 for (d = son; d < eon; d = q + 1) {
14200 INCSTEPS (elm.steps);
14201 if (*d == REMOVED) { for (q = d + 1; *q; q++) ; continue; }
14202 INCSTEPS (elm.resolutions);
14203 assert (lglmtstk (&lgl->clause));
14206 for (q = d; (lit = *q); q++) {
14207 if (lit == -1) continue;
14210 idx = abs (lit), sgn = lglsgn (lit);
14211 tmp = lglpeek (&lgl->elm->mark, idx);
14212 if (tmp == sgn) continue;
14213 if (tmp == -sgn) break;
14214 ilit = lglm2i (lgl, lit);
14215 val = lglval (lgl, ilit);
14216 if (val < 0) continue;
14217 if (val > 0) break;
14218 lglpushstk (lgl, &lgl->clause, ilit);
14219 ilit = lglm2i (lgl, lit);
14220 lglpushstk (lgl, &lgl->resolvent, ilit);
14223 assert (reslen == lglcntstk (&lgl->resolvent));
14224 if (!lit && reslen == 1) {
14230 LOGMCLS (3, c, "resolving variable elimination 1st antecedent");
14231 LOGMCLS (3, d, "resolving variable elimination 2nd antecedent");
14232 for (p = c; (lit = *p); p++) {
14233 if (lit == 1) continue;
14234 assert (lit != -1);
14235 ilit = lglm2i (lgl, lit);
14236 val = lglval (lgl, ilit);
14237 if (val < 0) continue;
14238 if (val > 0) break;
14239 lglpushstk (lgl, &lgl->clause, ilit);
14242 lglpushstk (lgl, &lgl->clause, 0);
14243 LOGCLS (3, lgl->clause.start, "variable elimination resolvent");
14244 lgldrupligaddcls (lgl, REDCS);
14245 lgladdcls (lgl, 0, 0, 1);
14246 if (lgl->opts->drup.val) lgldrupcls (lgl);
14249 lglclnstk (&lgl->clause);
14251 lglrststk (&lgl->resolvent, clen);
14253 lglclnstk (&lgl->resolvent);
14254 for (p = c; (lit = *p); p++) {
14255 if (lit == 1) continue;
14256 assert (lit != -1);
14258 assert (lglpeek (&lgl->elm->mark, idx) == lglsgn (lit));
14259 lglpoke (&lgl->elm->mark, idx, 0);
14262 lgleliminated (lgl, lgl->elm->pivot);
14263 lgl->stats->elm.large++;
14266 static void lglelimlitaux (LGL * lgl, int idx) {
14268 if (lglelmstr (lgl)) return;
14270 if (lgltrylargeve (lgl)) lgldolargeve (lgl);
14273 static int lgls2m (LGL * lgl, int ilit) {
14274 AVar * av = lglavar (lgl, ilit);
14275 int res = av->mark;
14277 res = lglcntstk (&lgl->seen) + 1;
14278 if (res > lgl->opts->smallvevars.val + 1) return 0;
14280 assert (lglcntstk (&lgl->seen) == lglcntstk (&lgl->elm->m2i) - 1);
14281 lglpushstk (lgl, &lgl->seen, abs (ilit));
14282 lglpushstk (lgl, &lgl->elm->m2i, abs (ilit));
14283 LOG (4, "mapped internal variable %d to marked variable %d",
14286 if (ilit < 0) res = -res;
14290 static void lglvar2funaux (int v, Fun res, int negate) {
14293 assert (0 <= v && v < FUNVAR);
14295 tmp = lglbasevar2funtab[v];
14296 if (negate) tmp = ~tmp;
14297 for (i = 0; i < FUNQUADS; i++)
14300 tmp = negate ? ~0ull : 0ull;
14303 for (i = 0; i < FUNQUADS; i++) {
14305 if (++j < p) continue;
14312 static void lglvar2fun (int v, Fun res) {
14313 lglvar2funaux (v, res, 0);
14316 static void lglnegvar2fun (int v, Fun res) {
14317 lglvar2funaux (v, res, 1);
14320 static void lglfuncpy (Fun dst, const Fun src) {
14322 for (i = 0; i < FUNQUADS; i++)
14326 static void lglfalsefun (Fun res) {
14328 for (i = 0; i < FUNQUADS; i++)
14332 static void lgltruefun (Fun res) {
14334 for (i = 0; i < FUNQUADS; i++)
14338 static int lglisfalsefun (const Fun f) {
14340 for (i = 0; i < FUNQUADS; i++)
14341 if (f[i] != 0ll) return 0;
14345 static int lglistruefun (const Fun f) {
14347 for (i = 0; i < FUNQUADS; i++)
14348 if (f[i] != ~0ll) return 0;
14352 static void lglorfun (Fun a, const Fun b) {
14354 for (i = 0; i < FUNQUADS; i++)
14358 static void lglornegfun (Fun a, const Fun b) {
14360 for (i = 0; i < FUNQUADS; i++)
14364 static void lglor3fun (Fun a, const Fun b, const Fun c) {
14366 for (i = 0; i < FUNQUADS; i++)
14367 a[i] = b[i] | c[i];
14370 static void lglor3negfun (Fun a, const Fun b, const Fun c) {
14372 for (i = 0; i < FUNQUADS; i++)
14373 a[i] = b[i] | ~c[i];
14376 static void lglandornegfun (Fun a, const Fun b, const Fun c) {
14378 for (i = 0; i < FUNQUADS; i++)
14379 a[i] &= b[i] | ~c[i];
14382 static void lglandfun (Fun a, const Fun b) {
14384 for (i = 0; i < FUNQUADS; i++)
14388 static void lgland3fun (Fun a, const Fun b, const Fun c) {
14390 for (i = 0; i < FUNQUADS; i++)
14391 a[i] = b[i] & c[i];
14394 static void lgland3negfun (Fun a, const Fun b, const Fun c) {
14396 for (i = 0; i < FUNQUADS; i++)
14397 a[i] = b[i] & ~c[i];
14400 static void lglsrfun (Fun a, int shift) {
14401 uint64_t rest, tmp;
14403 assert (0 <= shift);
14410 while (j < FUNQUADS) {
14411 if (i < FUNQUADS) {
14413 rest = (b && i+1 < FUNQUADS) ? (a[i+1] << l) : 0ull;
14415 } else a[j] = 0ull;
14420 static void lglslfun (Fun a, int shift) {
14421 uint64_t rest, tmp;
14423 assert (0 <= shift);
14432 rest = (b && i > 0) ? (a[i-1] >> l) : 0ll;
14439 static void lgls2fun (int mlit, Fun res) {
14440 int midx = abs (mlit), sidx = midx - 2;
14441 assert (0 <= sidx && sidx < FUNVAR);
14442 if (mlit < 0) lglnegvar2fun (sidx, res);
14443 else lglvar2fun (sidx, res);
14446 static int lglinitsmallve (LGL * lgl, int lit, Fun res) {
14447 int blit, tag, red, other, other2, lidx, mlit;
14448 const int * p, * w, * eow, * c, * q;
14452 assert (!lglval (lgl, lit));
14453 LOG (3, "initializing small variable eliminiation for %d", lit);
14458 assert (abs (mlit) == 1);
14459 hts = lglhts (lgl, lit);
14461 if (!hts->count) goto DONE;
14462 w = lglhts2wchs (lgl, hts);
14463 eow = w + hts->count;
14464 for (p = w; p < eow; p++) {
14465 INCSTEPS (elm.steps);
14467 tag = blit & MASKCS;
14468 if (tag == TRNCS || tag == LRGCS) p++;
14469 if (tag == LRGCS) continue;
14470 red = blit & REDCS;
14473 if (tag == BINCS || tag == TRNCS) {
14474 other = blit >> RMSHFT;
14475 val = lglval (lgl, other);
14478 mlit = lgls2m (lgl, other);
14479 if (!mlit) return 0;
14480 lgls2fun (mlit, tmp);
14481 lglorfun (cls, tmp);
14483 if (tag == TRNCS) {
14485 val = lglval (lgl, other2);
14488 mlit = lgls2m (lgl, other2);
14489 if (!mlit) return 0;
14490 lgls2fun (mlit, tmp);
14491 lglorfun (cls, tmp);
14495 assert (tag == OCCS);
14496 lidx = blit >> RMSHFT;
14497 c = lglidx2lits (lgl, 0, lidx);
14498 for (q = c; (other = *q); q++) {
14499 if (other == lit) continue;
14500 assert (other != -lit);
14501 val = lglval (lgl, other);
14504 mlit = lgls2m (lgl, other);
14505 if (!mlit) return 0;
14506 lgls2fun (mlit, tmp);
14507 lglorfun (cls, tmp);
14511 assert (!lglisfalsefun (cls));
14512 assert (!lglistruefun (cls));
14513 lglandfun (res, cls);
14514 INCSTEPS (elm.copies);
14520 static void lglresetsmallve (LGL * lgl) {
14521 lglclnstk (&lgl->elm->m2i);
14522 lglclnstk (&lgl->elm->clv);
14523 lglpopnunmarkstk (lgl, &lgl->seen);
14526 static void lglsmallevalcls (unsigned cls, Fun res) {
14530 for (v = 0; v < FUNVAR; v++) {
14531 if (cls & (1 << (2*v + 1))) {
14532 lglvar2fun (v, tmp);
14533 lglornegfun (res, tmp);
14534 } else if (cls & (1 << (2*v))) {
14535 lglvar2fun (v, tmp);
14536 lglorfun (res, tmp);
14541 static Cnf lglpos2cnf (int pos) { assert (pos >=0 ); return pos; }
14542 static Cnf lglsize2cnf (int s) { assert (s >=0 ); return ((Cnf)s) << 32; }
14543 static int lglcnf2pos (Cnf cnf) { return cnf & 0xfffffll; }
14544 static int lglcnf2size (Cnf cnf) { return cnf >> 32; }
14546 static Cnf lglcnf (int pos, int size) {
14547 return lglpos2cnf (pos) | lglsize2cnf (size);
14550 static void lglsmallevalcnf (LGL * lgl, Cnf cnf, Fun res) {
14553 p = lglcnf2pos (cnf);
14554 n = lglcnf2size (cnf);
14556 for (i = 0; i < n; i++) {
14557 cls = lglpeek (&lgl->elm->clv, p + i);
14558 lglsmallevalcls (cls, tmp);
14559 lglandfun (res, tmp);
14563 static void lglnegcofactorfun (const Fun f, int v, Fun res) {
14565 lglvar2fun (v, mask);
14566 lgland3negfun (masked, f, mask);
14567 lglfuncpy (res, masked);
14568 lglslfun (masked, (1 << v));
14569 lglorfun (res, masked);
14572 static void lglposcofactorfun (const Fun f, int v, Fun res) {
14574 lglvar2fun (v, mask);
14575 lgland3fun (masked, f, mask);
14576 lglfuncpy (res, masked);
14577 lglsrfun (masked, (1 << v));
14578 lglorfun (res, masked);
14581 static int lglsmallfundeps0 (const Fun f) {
14583 for (i = 0; i < FUNQUADS; i++)
14584 if (((f[i] & 0xaaaaaaaaaaaaaaaaull)>>1) !=
14585 (f[i] & 0x5555555555555555ull)) return 1;
14589 static int lglsmallfundeps1 (const Fun f) {
14591 for (i = 0; i < FUNQUADS; i++)
14592 if (((f[i] & 0xccccccccccccccccull)>>2) !=
14593 (f[i] & 0x3333333333333333ull)) return 1;
14597 static int lglsmallfundeps2 (const Fun f) {
14599 for (i = 0; i < FUNQUADS; i++)
14600 if (((f[i] & 0xf0f0f0f0f0f0f0f0ull)>>4) !=
14601 (f[i] & 0x0f0f0f0f0f0f0f0full)) return 1;
14605 static int lglsmallfundeps3 (const Fun f) {
14607 for (i = 0; i < FUNQUADS; i++)
14608 if (((f[i] & 0xff00ff00ff00ff00ull)>>8) !=
14609 (f[i] & 0x00ff00ff00ff00ffull)) return 1;
14613 static int lglsmallfundeps4 (const Fun f) {
14615 for (i = 0; i < FUNQUADS; i++)
14616 if (((f[i] & 0xffff0000ffff0000ull)>>16) !=
14617 (f[i] & 0x0000ffff0000ffffull)) return 1;
14621 static int lglsmallfundeps5 (const Fun f) {
14623 for (i = 0; i < FUNQUADS; i++)
14624 if (((f[i] & 0xffffffff00000000ull)>>32) !=
14625 (f[i] & 0x00000000ffffffffull)) return 1;
14629 static int lglsmallfundepsgen (const Fun f, int min) {
14630 const int c = (1 << (min - 6));
14633 for (i = 0; i < FUNQUADS; i += (1 << (min - 5)))
14634 for (j = 0; j < c; j++)
14635 if (f[i + j] != f[i + c + j]) return 1;
14639 static int lglsmalltopvar (const Fun f, int min) {
14642 case 0: if (lglsmallfundeps0 (f)) return 0;
14643 case 1: if (lglsmallfundeps1 (f)) return 1;
14644 case 2: if (lglsmallfundeps2 (f)) return 2;
14645 case 3: if (lglsmallfundeps3 (f)) return 3;
14646 case 4: if (lglsmallfundeps4 (f)) return 4;
14647 case 5: if (lglsmallfundeps5 (f)) return 5;
14649 for (i = lglmax (6, min); i <= FUNVAR - 2; i++)
14650 if (lglsmallfundepsgen (f, i)) return i;
14654 static Cnf lglsmalladdlit2cnf (LGL * lgl, Cnf cnf, int lit) {
14655 int p, m, q, n, i, cls;
14657 p = lglcnf2pos (cnf);
14658 m = lglcnf2size (cnf);
14659 q = lglcntstk (&lgl->elm->clv);
14660 for (i = 0; i < m; i++) {
14661 cls = lglpeek (&lgl->elm->clv, p + i);
14662 assert (!(cls & lit));
14664 lglpushstk (lgl, &lgl->elm->clv, cls);
14666 n = lglcntstk (&lgl->elm->clv) - q;
14667 res = lglcnf (q, n);
14672 static int lglefun (const Fun a, const Fun b) {
14674 for (i = 0; i < FUNQUADS; i++)
14675 if (a[i] & ~b[i]) return 0;
14680 // The dual version of Minato's algorithm for computing an irredundant
14681 // product of sums. The original algorithm computes an irredundant sum of
14682 // products. It uses BDDs for representing boolean functions and ZDDs for
14683 // manipulating sum of product. We work with function tables stored as bit
14684 // maps and plain CNFs stored as lists of clauses instead.
14686 static Cnf lglsmallipos (LGL * lgl, const Fun U, const Fun L, int min) {
14687 Fun U0, U1, L0, L1, Unew, ftmp;
14688 Cnf c0, c1, cstar, ctmp, res;
14690 assert (lglefun (L, U));
14691 if (lglistruefun (U)) return TRUECNF;
14692 if (lglisfalsefun (L)) return FALSECNF;
14693 lgl->stats->elm.ipos++;
14694 assert (min < lglcntstk (&lgl->elm->m2i));
14695 y = lglsmalltopvar (U, min);
14696 z = lglsmalltopvar (L, min);
14697 INCSTEPS (elm.steps);
14698 x = (y < z) ? y : z;
14699 assert (x < FUNVAR);
14700 lglnegcofactorfun (U, x, U0); lglposcofactorfun (U, x, U1);
14701 lglnegcofactorfun (L, x, L0); lglposcofactorfun (L, x, L1);
14702 lglor3negfun (ftmp, U0, L1);
14703 c0 = lglsmallipos (lgl, ftmp, L0, min+1);
14704 lglor3negfun (ftmp, U1, L0);
14705 c1 = lglsmallipos (lgl, ftmp, L1, min+1);
14706 lglsmallevalcnf (lgl, c0, ftmp);
14707 lglor3negfun (Unew, U0, ftmp);
14708 lglsmallevalcnf (lgl, c1, ftmp);
14709 lglandornegfun (Unew, U1, ftmp);
14710 lglor3fun (ftmp, L0, L1);
14711 cstar = lglsmallipos (lgl, Unew, ftmp, min+1);
14712 assert (cstar != FALSECNF);
14713 ctmp = lglsmalladdlit2cnf (lgl, c1, (1 << (2*x + 1)));
14714 res = lglcnf2pos (ctmp);
14715 ctmp = lglsmalladdlit2cnf (lgl, c0, (1 << (2*x)));
14716 if (res == TRUECNF) res = lglcnf2pos (ctmp);
14717 ctmp = lglsmalladdlit2cnf (lgl, cstar, 0);
14718 if (res == TRUECNF) res = lglcnf2pos (ctmp);
14719 res |= lglsize2cnf (lglcntstk (&lgl->elm->clv) - res);
14723 static void lglsmallve (LGL * lgl, Cnf cnf) {
14724 int * soc = lgl->elm->clv.start + lglcnf2pos (cnf);
14725 int * eoc = soc + lglcnf2size (cnf);
14726 int * p, cls, v, lit, trivial;
14728 for (p = soc; !lgl->mt && p < eoc; p++) {
14730 assert (lglmtstk (&lgl->clause));
14732 for (v = 0; v < FUNVAR; v++) {
14733 if (cls & (1 << (2*v + 1))) lit = -lglm2i (lgl, v+2);
14734 else if (cls & (1 << (2*v))) lit = lglm2i (lgl, v+2);
14736 val = lglval (lgl, lit);
14737 if (val < 0) continue;
14738 if (val > 0) trivial = 1;
14739 lglpushstk (lgl, &lgl->clause, lit);
14742 INCSTEPS (elm.resolutions);
14743 lglpushstk (lgl, &lgl->clause, 0);
14744 LOGCLS (3, lgl->clause.start, "small elimination resolvent");
14745 if (lgl->opts->drup.val) lgldrupcls (lgl);
14746 #ifndef NLGLPICOSAT
14747 lglpicosatchkcls (lgl);
14749 lgladdcls (lgl, 0, 0, 1);
14751 lglclnstk (&lgl->clause);
14755 static int lglsmallisunitcls (LGL * lgl, int cls) {
14756 int fidx, fsign, flit, mlit, ilit;
14758 for (fidx = 0; fidx < FUNVAR; fidx++)
14759 for (fsign = 0; fsign <= 1; fsign++) {
14760 flit = 1<<(2*fidx + fsign);
14761 if (!(cls & flit)) continue;
14762 if (ilit) return 0;
14763 mlit = (fidx + 2) * (fsign ? -1 : 1);
14764 ilit = lglm2i (lgl, mlit);
14769 static int lglsmallcnfunits (LGL * lgl, Cnf cnf) {
14770 int p, m, i, res, cls, ilit;
14771 p = lglcnf2pos (cnf);
14772 m = lglcnf2size (cnf);
14774 for (i = 0; i < m; i++) {
14775 cls = lglpeek (&lgl->elm->clv, p + i);
14776 ilit = lglsmallisunitcls (lgl, cls);
14777 if (!ilit) continue;
14778 assert (lglval (lgl, ilit) >= 0);
14779 lglunit (lgl, ilit);
14785 static int lgltrysmallve (LGL * lgl, int idx) {
14786 int res, new, old, units;
14790 assert (lglmtstk (&lgl->elm->m2i));
14791 assert (lglmtstk (&lgl->seen));
14792 assert (lglmtstk (&lgl->elm->clv));
14793 if (!lgl->opts->smallve.val) return 0;
14794 if (lgl->opts->smallvewait.val && !lgl->elmrtc) return 0;
14795 lglpushstk (lgl, &lgl->elm->m2i, 0);
14796 lglpushstk (lgl, &lgl->elm->clv, 0);
14798 if (lglinitsmallve (lgl, idx, pos) && lglinitsmallve (lgl, -idx, neg)) {
14799 lglor3fun (fun, pos, neg);
14800 cnf = lglsmallipos (lgl, fun, fun, 0);
14801 new = lglcnf2size (cnf);
14802 units = lglsmallcnfunits (lgl, cnf);
14803 assert (units <= new);
14805 ev = lglevar (lgl, idx);
14806 old = ev->occ[0] + ev->occ[1];
14807 LOG (2, "small elimination of %d replaces "
14808 "%d old with %d new clauses and %d units",
14809 idx, old, new, units);
14810 lgl->stats->elm.small.tried++;
14812 LOG (2, "small elimination of %d removes %d clauses", idx, old - new);
14813 lglepusheliminated (lgl, idx);
14814 lglflushclauses (lgl, idx);
14815 lglflushclauses (lgl, -idx);
14816 lglsmallve (lgl, cnf);
14817 lgl->stats->elm.small.elm++;
14820 LOG (2, "small elimination of %d would add %d clauses", idx, new - old);
14821 if (units > 0) res = 1;
14822 else lgl->stats->elm.small.failed++;
14824 } else LOG (2, "too many variables for small elimination");
14825 lglresetsmallve (lgl);
14829 static int lgl2manyoccs4elm (LGL * lgl, int lit) {
14830 return lglocc (lgl, lit) >
14831 lglfactor (lgl, lgl->opts->elmocclim.val, lgl->stats->elm.count);
14834 static int lglchkoccs4elmlit (LGL * lgl, int lit) {
14835 int blit, tag, red, other, other2, lidx, size, lits, count;
14836 const int * p, * w, * eow, * c, * l;
14839 if (lgl->opts->elmfull.val) return 1;
14840 count = lgl->stats->elm.count;
14841 litslim = lglfactor (lgl, lgl->opts->elmlitslim.val, count);
14842 hts = lglhts (lgl, lit);
14843 w = lglhts2wchs (lgl, hts);
14844 eow = w + hts->count;
14846 for (p = w; p < eow; p++) {
14848 tag = blit & MASKCS;
14849 red = blit & REDCS;
14850 if (tag == TRNCS || tag == LRGCS) p++;
14851 if (red || tag == LRGCS) continue;
14852 if (tag == BINCS) {
14853 other = blit >> RMSHFT;
14854 if (lgl2manyoccs4elm (lgl, other)) return 0;
14856 } else if (tag == TRNCS) {
14857 other = blit >> RMSHFT;
14858 if (lgl2manyoccs4elm (lgl, other)) return 0;
14860 if (lgl2manyoccs4elm (lgl, other2)) return 0;
14863 assert (tag == OCCS);
14864 lidx = blit >> RMSHFT;
14865 c = lglidx2lits (lgl, 0, lidx);
14867 for (l = c; (other = *l); l++) {
14868 if (lgl2manyoccs4elm (lgl, other)) return 0;
14869 if (++size > lglfactor (lgl, lgl->opts->elmclslim.val, count))
14874 if (lits > litslim) return 0;
14879 static int lglchkoccs4elm (LGL * lgl, int idx) {
14881 if ((res = lglforcedve (lgl, idx)) > 0) return 1;
14882 if (res < 0) return 0;
14883 if (lgl2manyoccs4elm (lgl, idx)) return 0;
14884 if (lgl2manyoccs4elm (lgl, -idx)) return 0;
14885 if (!lglchkoccs4elmlit (lgl, idx)) return 0;
14886 if (!lglchkoccs4elmlit (lgl, -idx)) return 0;
14890 static void lglelimlit (LGL * lgl, int idx) {
14892 if (!lglisfree (lgl, idx)) return;
14893 if (!lglchkoccs4elm (lgl, idx)) return;
14894 LOG (2, "trying to eliminate %d", idx);
14895 if ((forced = lglforcedve (lgl, idx)) < 0) return;
14896 if (!forced && lgltrysmallve (lgl, idx)) return;
14897 lglinitecls (lgl, idx);
14898 lglelimlitaux (lgl, idx);
14899 if (lgl->elm->pivot) lglrstecls (lgl);
14902 static int lglblockcls (LGL * lgl, int lit) {
14903 int blit, tag, red, other, other2, lidx, val, count, size;
14904 const int * p, * w, * eow, * c, *l;
14905 int bc = lgl->stats->blk.count;
14907 INCSTEPS (blk.steps);
14908 hts = lglhts (lgl, lit);
14909 if (!hts->count) return 1;
14910 w = lglhts2wchs (lgl, hts);
14911 eow = w + hts->count;
14913 for (p = w; p < eow; p++) {
14915 tag = blit & MASKCS;
14916 if (tag == TRNCS || tag == LRGCS) p++;
14917 if (tag == LRGCS) continue;
14918 red = blit & REDCS;
14921 lgl->stats->blk.res++;
14922 INCSTEPS (blk.steps);
14923 if (tag == BINCS || tag == TRNCS) {
14924 other = blit >> RMSHFT;
14925 val = lglmarked (lgl, other);
14926 if (val < 0) continue;
14927 if (tag == TRNCS) {
14929 val = lglmarked (lgl, other2);
14930 if (val < 0) continue;
14933 assert (tag == OCCS);
14934 lidx = blit >> RMSHFT;
14935 c = lglidx2lits (lgl, 0, lidx);
14937 for (l = c; (other = *l); l++) {
14938 val = lglmarked (lgl, other);
14939 if (++size > lglfactor (lgl, lgl->opts->blkclslim.val, bc)) return 0;
14940 if (val < 0) break;
14942 if (other) continue;
14946 LOG (3, "resolved %d trivial resolvents on %d", count, lit);
14950 static int lglpurelit (LGL * lgl, int lit) {
14952 LOG(1, "pure literal %d", lit);
14953 lgl->stats->blk.pure++;
14954 assert (!lglocc (lgl, -lit));
14955 res = lglflushclauses (lgl, lit);
14956 lgl->stats->blk.clauses += res;
14957 if (lgl->blocking) ADDSTEPS (blk.steps, res);
14958 lglepusheliminated (lgl, lit);
14962 static int lgl2manyoccs4blk (LGL * lgl, int lit) {
14963 return lglhts (lgl, lit)->count >
14964 lglfactor (lgl, lgl->opts->blkocclim.val, lgl->stats->blk.count);
14967 static int lgldonotblocklit (LGL * lgl, int lit) {
14968 int pocc = lglocc (lgl, lit);
14969 int nocc = lglocc (lgl, -lit);
14970 int count = lgl->stats->blk.count;
14971 if (pocc >= lglfactor (lgl, lgl->opts->blkocclim1.val, count)) return 1;
14972 if (nocc >= lglfactor (lgl, lgl->opts->blkocclim1.val, count)) return 1;
14973 if (pocc < lglfactor (lgl, lgl->opts->blkocclim2.val, count)) return 0;
14974 if (nocc < lglfactor (lgl, lgl->opts->blkocclim2.val, count)) return 0;
14978 static int lglblocklit (LGL * lgl, int lit, Stk * stk) {
14979 int blit, tag, red, blocked, other, other2, lidx, count, size;
14980 int bc = lgl->stats->blk.count;
14981 int * p, * w, * eow, * c, * l;
14983 if (lglval (lgl, lit)) return 0;
14984 if (lgldonotblocklit (lgl, lit)) return 0;
14985 if (lgl2manyoccs4blk (lgl, lit)) return 0;
14986 hts = lglhts (lgl, lit);
14987 assert (!lgl->opts->pure.val || hts->count > 0);
14988 w = lglhts2wchs (lgl, hts);
14989 eow = w + hts->count;
14991 assert (lglmtstk (stk+2) && lglmtstk (stk+3) && lglmtstk (stk+4));
14992 for (p = w; p < eow; p++) {
14993 if (INCSTEPS (blk.steps) >= lgl->limits->blk.steps) break;
14994 if (lglterminate (lgl)) break;
14996 tag = blit & MASKCS;
14997 if (tag == TRNCS || tag == LRGCS) p++;
14998 if (tag == LRGCS) continue;
14999 red = blit & REDCS;
15001 assert (lglmtstk (&lgl->seen));
15003 if (tag == BINCS || tag == TRNCS) {
15004 if (!lgl->opts->blksmall.val) continue;
15005 other = blit >> RMSHFT;
15006 if (lgl2manyoccs4blk (lgl, other)) continue;
15007 lglpushnmarkseen (lgl, other);
15008 if (tag == TRNCS) {
15010 if (lgl2manyoccs4blk (lgl, other2)) goto CONTINUE;
15011 lglpushnmarkseen (lgl, other2);
15014 assert (tag == OCCS);
15015 if (!lgl->opts->blklarge.val) continue;
15016 lidx = blit >> RMSHFT;
15017 c = lglidx2lits (lgl, 0, lidx);
15019 for (l = c; (other = *l); l++) {
15020 if (other == lit) continue;
15021 if (lgl2manyoccs4blk (lgl, other)) goto CONTINUE;
15022 if (++size > lglfactor (lgl, lgl->opts->blkclslim.val, bc))
15024 lglpushnmarkseen (lgl, other);
15027 blocked = lglblockcls (lgl, -lit);
15029 lglpopnunmarkstk (lgl, &lgl->seen);
15030 if (!blocked) continue;
15031 if (tag == BINCS) {
15032 other = blit >> RMSHFT;
15033 lglpushstk (lgl, stk+2, other);
15034 } else if (tag == TRNCS) {
15035 other = blit >> RMSHFT;
15036 lglpushstk (lgl, stk+3, other);
15038 lglpushstk (lgl, stk+3, other2);
15040 assert (tag == OCCS);
15041 lidx = blit >> RMSHFT;
15042 lglpushstk (lgl, stk+4, lidx);
15045 while (!lglmtstk (stk+2)) {
15046 if (INCSTEPS (blk.steps) >= lgl->limits->blk.steps) break;
15048 other = lglpopstk (stk+2);
15049 LOG (2, "blocked binary clause %d %d on %d", lit, other, lit);
15050 lglrmbcls (lgl, lit, other, 0);
15051 lglepush (lgl, lit);
15052 lglepush (lgl, other);
15054 if (lgl->opts->move.val) lglmvbcls (lgl, lit, other);
15056 while (!lglmtstk (stk+3)) {
15057 if (INCSTEPS (blk.steps) >= lgl->limits->blk.steps) break;
15059 other2 = lglpopstk (stk+3);
15060 other = lglpopstk (stk+3);
15061 LOG (2, "blocked ternary clause %d %d %d on %d", lit, other, other2, lit);
15062 lglrmtcls (lgl, lit, other, other2, 0);
15063 lglepush (lgl, lit);
15064 lglepush (lgl, other);
15065 lglepush (lgl, other2);
15067 if (lgl->opts->move.val >= 2) lglmvtcls (lgl, lit, other, other2);
15069 while (!lglmtstk (stk+4)) {
15070 if (INCSTEPS (blk.steps) >= lgl->limits->blk.steps) break;
15071 lidx = lglpopstk (stk+4);
15073 c = lglidx2lits (lgl, 0, lidx);
15074 LOGCLS (2, c, "blocked on %d large clause", lit);
15075 lglepush (lgl, lit);
15076 for (l = c; (other = *l); l++)
15077 if (other != lit) lglepush (lgl, other);
15079 lglrmvlcls (lgl, lidx);
15081 LOG (2, "found %d blocked clauses with %d", count, lit);
15082 lgl->stats->blk.clauses += count;
15083 if (count > 0) lglblockinglit (lgl, lit);
15084 lglclnstk (stk+2), lglclnstk (stk+3), lglclnstk (stk+4);
15088 static void lglsetblklim (LGL * lgl) {
15089 int64_t limit, irrlim;
15091 if (lgl->opts->blkrtc.val) {
15092 lgl->limits->blk.steps = LLMAX;
15093 lglprt (lgl, 1, "[block-%d] no limit", lgl->stats->blk.count);
15095 limit = (lgl->opts->blkreleff.val*lglvisearch (lgl))/1000;
15096 if (limit < lgl->opts->blkmineff.val) limit = lgl->opts->blkmineff.val;
15097 if (lgl->opts->blkmaxeff.val >= 0 && limit > lgl->opts->blkmaxeff.val)
15098 limit = lgl->opts->blkmaxeff.val;
15099 if (lgl->stats->blk.count <= 1 &&
15100 lgl->opts->boost.val &&
15101 lgl->nvars < lgl->opts->blkboostvlim.val) {
15103 "[block-%d] boosting limit by %d",
15104 lgl->stats->blk.count, lgl->opts->blkboost.val);
15105 limit *= lgl->opts->blkboost.val;
15107 limit >>= (pen = lgl->limits->blk.pen + lglszpen (lgl));
15108 irrlim = lgl->stats->irr.clauses.cur/2;
15109 irrlim >>= lgl->limits->simp.pen;
15110 if (lgl->opts->irrlim.val && limit < irrlim) {
15113 "[block-%d] limit of %lld steps based on %d irredundant clauses",
15114 lgl->stats->blk.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
15117 "[block-%d] limit of %lld steps penalty %d = %d + %d",
15118 lgl->stats->blk.count, (LGLL) limit,
15119 pen, lgl->limits->blk.pen, lglszpen (lgl));
15120 lgl->limits->blk.steps = lgl->stats->blk.steps + limit;
15124 static int lgleschedrem (LGL * lgl, int this_time) {
15125 int idx, res = 0, count;
15128 for (idx = 2; idx < lgl->nvars; idx++) {
15129 if (lglifrozen (lgl, idx)) continue;
15130 if (!lglisfree (lgl, idx)) continue;
15131 av = lglavar (lgl, idx);
15132 if (lgl->eliminating && av->donotelm) continue;
15133 if (lgl->blocking && av->donotblk) continue;
15136 assert (lgl->eliminating || lgl->blocking);
15137 if (lgl->eliminating) count = lgl->stats->elm.count, str = "elim";
15138 else assert (lgl->blocking), count = lgl->stats->blk.count, str = "block";
15141 "[%s-%d] %d variables %.0f%% %s time",
15143 res, lglpcnt (res, lglrem (lgl)),
15144 this_time ? "will be scheduled this" : "remain to be tried next");
15147 "[%s-%d] no untried remaining variables left",
15149 for (idx = 2; idx < lgl->nvars; idx++) {
15150 av = lglavar (lgl, idx);
15151 if (lgl->eliminating) av->donotelm = 0;
15152 if (lgl->blocking) av->donotblk = 0;
15158 static void lglsetdonotesched (LGL * lgl, int completed) {
15162 assert (lgl->eliminating + lgl->blocking == 1);
15163 for (idx = 2; idx < lgl->nvars; idx++) {
15164 av = lglavar (lgl, idx);
15165 ev = lglevar (lgl, idx);
15166 if (lgl->eliminating) {
15167 if (completed) av->donotelm = 0;
15168 else if (ev->pos < 0) av->donotelm = 1;
15170 if (lgl->blocking) {
15171 if (completed) av->donotblk = 0;
15172 else if (ev->pos < 0) av->donotblk = 1;
15177 static int lglblkdone (LGL * lgl) {
15178 if (!lglsmallirr (lgl)) return 1;
15179 if (lglterminate (lgl)) return 1;
15180 if (lglmtstk (&lgl->esched)) return 1;
15181 if (lgl->stats->blk.steps >= lgl->limits->blk.steps) return 1;
15185 static int lglispure (LGL * lgl, int lit) {
15186 if (!lgl->opts->pure.val) return 0;
15187 if (lglifrozen (lgl, lit)) return 0;
15188 return !lglocc (lgl, -lit);
15191 static void lglblock (LGL * lgl) {
15192 int oldrem = lgl->blkrem, oldall = lgl->blkall;
15193 int oldirr = lgl->stats->irr.clauses.cur;
15194 int idx, count, all, rem, success;
15196 assert (lglsmallirr (lgl));
15197 assert (!lgl->simp);
15198 assert (!lgl->dense);
15199 assert (!lgl->eliminating);
15200 assert (!lgl->blocking);
15201 assert (!lgl->occs);
15202 lglstart (lgl, &lgl->times->blk);
15203 if (lgl->level) lglbacktrack (lgl, 0);
15204 lgl->simp = lgl->blocking = lgl->occs = 1;
15205 lgl->stats->blk.count++;
15207 assert (lgl->frozen);
15208 assert (!(oldall && !oldrem));
15209 all = !oldrem || !oldall;
15212 "[block-%d] scheduling all variables this time",
15213 lgl->stats->blk.count);
15214 else if (!lgleschedrem (lgl, 1)) all = 1, oldrem = 0;
15215 if (!all) assert (!lgl->donotsched), lgl->donotsched = 1;
15217 if (!all) assert (lgl->donotsched), lgl->donotsched = 0;
15218 lglsetblklim (lgl);
15221 while (!lglblkdone (lgl)) {
15222 idx = lglpopesched (lgl);
15223 lglavar (lgl, idx)->donotblk = 1;
15224 if (!lglisfree (lgl, idx)) continue;
15225 if (lglispure (lgl, -idx)) count += lglpurelit (lgl, -idx);
15226 else if (lglispure (lgl, idx)) count += lglpurelit (lgl, idx);
15228 if (lglocc (lgl, -idx) > lglocc (lgl, idx)) idx = -idx;
15229 count += lglblocklit (lgl, idx, blocked);
15230 count += lglblocklit (lgl, -idx, blocked);
15233 rem = lglcntstk (&lgl->esched);
15236 "[block-%d] fully completed",
15237 lgl->stats->blk.count);
15241 "[block-%d] incomplete %d not tried %.0f%%",
15242 lgl->stats->blk.count, rem, lglpcnt (rem, lgl->nvars - 2));
15244 lglsetdonotesched (lgl, !rem);
15245 lglrelstk (lgl, &lgl->esched);
15248 lglrelstk (lgl, blocked+2);
15249 lglrelstk (lgl, blocked+3);
15250 lglrelstk (lgl, blocked+4);
15251 lgl->blkrem = rem > 0;
15252 lgl->blkall = all && lgl->blkrem;
15254 "[block-%d] transition to [ all %d rem %d ] state",
15255 lgl->stats->blk.count, lgl->blkall, lgl->blkrem);
15256 assert (lgl->simp && lgl->blocking && lgl->occs);
15257 lgl->blocking = lgl->simp = lgl->occs = 0;
15258 lgl->stats->irrprgss += count;
15260 "[block-%d] eliminated %d blocked clauses",
15261 lgl->stats->blk.count, count);
15262 if (oldirr < lgl->opts->blksuccesslim.val) success = count;
15264 success = (oldirr/lgl->opts->blksuccessrat.val <= count);
15267 "[block-%d] %d < 1/%d * %d = %d considered unsuccessful",
15268 lgl->stats->blk.count, count, lgl->opts->blksuccessrat.val,
15269 oldirr, oldirr/lgl->opts->blksuccessrat.val);
15270 } else success = 0;
15271 LGLUPDPEN (blk, success);
15272 lgl->blkstuck = !rem && !count;
15275 "[block-%d] completed but nothing eliminated thus stuck",
15276 lgl->stats->blk.count);
15277 lglrep (lgl, 2, 'k');
15282 static void lglsetccelim (LGL * lgl) {
15283 int64_t limit, irrlim;
15285 if (lgl->opts->ccertc.val) {
15286 lgl->limits->cce.steps = LLMAX;
15287 lglprt (lgl, 1, "[cce-%d] no limit", lgl->stats->cce.count);
15289 limit = (lgl->opts->ccereleff.val*lglvisearch (lgl))/1000;
15290 if (limit < lgl->opts->ccemineff.val) limit = lgl->opts->ccemineff.val;
15291 if (lgl->opts->ccemaxeff.val >= 0 && limit > lgl->opts->ccemaxeff.val)
15292 limit = lgl->opts->ccemaxeff.val;
15293 if (lgl->stats->cce.count <= 1 &&
15294 lgl->opts->boost.val &&
15295 lgl->nvars < lgl->opts->cceboostvlim.val) {
15297 "[cce-%d] boosting limit by %d",
15298 lgl->stats->cce.count, lgl->opts->cceboost.val);
15299 limit *= lgl->opts->cceboost.val;
15301 limit >>= (pen = lgl->limits->cce.pen + lglszpen (lgl));
15302 irrlim = lgl->stats->irr.clauses.cur/2;
15303 irrlim >>= lgl->limits->simp.pen;
15304 if (lgl->opts->irrlim.val && limit < irrlim) {
15307 "[cce-%d] limit of %lld steps based on %d irredundant clauses",
15308 lgl->stats->cce.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
15311 "[cce-%d] limit of %lld steps penalty %d = %d + %d",
15312 lgl->stats->cce.count, (LGLL) limit,
15313 pen, lgl->limits->cce.pen, lglszpen (lgl));
15314 lgl->limits->cce.steps = lgl->stats->cce.steps + limit;
15318 #define CCELOGLEVEL 2
15320 static void lglsignedmark2 (LGL * lgl, int lit) {
15321 AVar * av = lglavar (lgl, lit);
15322 int bit = 1 << (2 + (lit < 0));
15323 if (av->mark & bit) return;
15327 static void lglsignedunmark2 (LGL * lgl, int lit) {
15328 AVar * av = lglavar (lgl, lit);
15329 int bit = 1 << (2 + (lit < 0));
15330 if (!(av->mark & bit)) return;
15334 static int lglsignedmarked2 (LGL * lgl, int lit) {
15335 AVar * av = lglavar (lgl, lit);
15336 int bit = 1 << (2 + (lit < 0));
15337 return av->mark & bit;
15340 static int lglabcecls (LGL * lgl, int lit, const int * c) {
15341 int other, found = 0;
15343 for (p = c; (other = *p); p++)
15344 if (other == -lit) found++;
15345 else if (lglsignedmarked (lgl, -other)) return 1;
15346 assert (found == 1);
15350 static int lglabce (LGL * lgl, int lit) {
15351 const int * p, * w, * eow, * c;
15352 int blit, tag, other, cls[4];
15354 assert (!lglifrozen (lgl, lit));
15355 hts = lglhts (lgl, -lit);
15356 w = lglhts2wchs (lgl, hts);
15357 eow = w + hts->count;
15358 cls[0] = -lit, cls[3] = 0;
15359 for (p = w; p < eow; p++) {
15360 if (lgl->limits->cce.steps <= INCSTEPS (cce.steps)) return 0;
15362 tag = blit & MASKCS;
15363 if (tag == TRNCS || tag == LRGCS) p++;
15364 if (blit & REDCS) continue;
15365 if (tag == LRGCS) continue;
15366 other = blit >> RMSHFT;
15368 if (tag == BINCS) cls[2] = 0, c = cls;
15369 else if (tag == TRNCS) cls[2] = *p, c = cls;
15370 else assert (tag == OCCS), c = lglidx2lits (lgl, 0, other);
15371 if (!lglabcecls (lgl, lit, c)) return 0;
15376 static int lglcceclause (LGL * lgl,
15380 int other, res, nextala, nextcla, lit, blit, tag, other2, i, j, n;
15381 const int * p, * eow, * w, * d, * q;
15382 int unit, first, old, prev;
15385 LOGCLS (CCELOGLEVEL, c, "trying CCE on clause");
15386 assert (lglmtstk (&lgl->cce->extend));
15387 assert (lglmtstk (&lgl->cce->cla));
15388 assert (lglmtstk (&lgl->seen));
15389 for (p = c; (other = *p); p++) {
15390 assert (!lglmarked (lgl, other));
15391 lglpushstk (lgl, &lgl->seen, other);
15392 lglpushstk (lgl, &lgl->cce->cla, other);
15393 lglsignedmark (lgl, other);
15395 n = lglcntstk (&lgl->seen);
15396 for (i = n-1; i > 0; i--) {
15397 j = lglrand (lgl) % (i + 1);
15398 if (j == i) continue;
15399 SWAP (int, lgl->seen.start[i], lgl->seen.start[j]);
15400 SWAP (int, lgl->cce->cla.start[i], lgl->cce->cla.start[j]);
15402 nextcla = nextala = res = 0;
15404 while (!res && nextala < lglcntstk (&lgl->seen)) {
15405 lit = lglpeek (&lgl->seen, nextala++);
15406 assert (lglsignedmarked (lgl, lit));
15407 assert (!lglsignedmarked (lgl, -lit));
15408 hts = lglhts (lgl, lit);
15409 w = lglhts2wchs (lgl, hts);
15410 eow = w + hts->count;
15411 for (p = w; !res && p < eow; p++) {
15412 if (lgl->limits->cce.steps <= INCSTEPS (cce.steps)) goto DONE;
15414 tag = blit & MASKCS;
15415 if (tag == TRNCS || tag == LRGCS) p++;
15416 if (tag == LRGCS) continue;
15417 if (blit & REDCS) continue;
15418 other = blit >> RMSHFT;
15419 if (tag == BINCS) {
15420 if (lglsignedmarked (lgl, -other)) continue;
15421 else if (lglsignedmarked (lgl, other)) {
15422 if (igntag == BINCS) {
15423 if (c[0] == lit && c[1] == other) continue;
15424 if (c[1] == lit && c[0] == other) continue;
15427 "ALA on binary clause %d %d results in ATE", lit, other);
15430 assert (!lglmarked (lgl, other));
15431 LOG (CCELOGLEVEL, "ALA %d through binary clause %d %d",
15432 -other, lit, other);
15433 lglsignedmark (lgl, -other);
15434 lglpushstk (lgl, &lgl->seen, -other);
15436 } else if (tag == TRNCS) {
15437 if (lglsignedmarked (lgl, -other)) continue;
15439 if (lglsignedmarked (lgl, -other2)) continue;
15440 if (lglsignedmarked (lgl, other)) {
15441 if (lglsignedmarked (lgl, other2)) {
15442 if (igntag == TRNCS) {
15443 if (c[0] == lit && c[1] == other && c[2] == other2) continue;
15444 if (c[0] == lit && c[2] == other && c[1] == other2) continue;
15445 if (c[1] == lit && c[0] == other && c[2] == other2) continue;
15446 if (c[1] == lit && c[2] == other && c[0] == other2) continue;
15447 if (c[2] == lit && c[0] == other && c[1] == other2) continue;
15448 if (c[2] == lit && c[1] == other && c[0] == other2) continue;
15451 "ALA on ternary clause %d %d %d results in ATE",
15452 lit, other, other2);
15455 assert (!lglmarked (lgl, other2));
15457 "ALA %d through ternary clause %d %d %d (1st case)",
15458 -other2, lit, other, other2);
15459 lglsignedmark (lgl, -other2);
15460 lglpushstk (lgl, &lgl->seen, -other2);
15462 } else if (lglsignedmarked (lgl, other2)) {
15463 assert (!lglmarked (lgl, other));
15465 "ALA %d through ternary clause %d %d %d (2nd case)",
15466 -other, lit, other, other2);
15467 lglsignedmark (lgl, -other);
15468 lglpushstk (lgl, &lgl->seen, -other);
15471 assert (tag == OCCS);
15472 d = lglidx2lits (lgl, 0, other);
15473 if (d == c) { assert (igntag == OCCS); continue; }
15475 for (q = d; (other = *q); q++) {
15476 if (other == lit) continue;
15477 if (lglsignedmarked (lgl, -other)) break;
15478 if (lglsignedmarked (lgl, other)) continue;
15482 if (other) continue;
15484 LOGCLS (CCELOGLEVEL, d, "ATE after ALA on large clause");
15487 assert (!lglmarked (lgl, unit));
15488 LOGCLS (CCELOGLEVEL, d, "ALA %d through large clause", unit);
15489 lglsignedmark (lgl, unit);
15490 lglpushstk (lgl, &lgl->seen, unit);
15495 if (res || !lgl->opts->block.val || cce < 3) goto SKIPCLA;
15496 while (!res && nextcla < lglcntstk (&lgl->cce->cla)) {
15497 lit = lglpeek (&lgl->cce->cla, nextcla++);
15498 if (lglifrozen (lgl, lit)) continue;
15499 assert (lglsignedmarked (lgl, lit));
15500 assert (!lglsignedmarked (lgl, -lit));
15501 hts = lglhts (lgl, -lit);
15502 w = lglhts2wchs (lgl, hts);
15503 eow = w + hts->count;
15504 old = lglcntstk (&lgl->cce->cla);
15506 for (p = w; p < eow; p++) {
15507 if (lgl->limits->cce.steps <= INCSTEPS (cce.steps)) goto DONE;
15509 tag = blit & MASKCS;
15510 if (tag == TRNCS || tag == LRGCS) p++;
15511 if (tag == LRGCS) continue;
15512 if (blit & REDCS) continue;
15513 other = blit >> RMSHFT;
15515 if (tag == BINCS) {
15516 if (lglsignedmarked (lgl, -other)) continue;
15517 if (!lglsignedmarked (lgl, other))
15518 lglpushstk (lgl, &lgl->cce->cla, other);
15519 } else if (tag == TRNCS) {
15520 if (lglsignedmarked (lgl, -other)) continue;
15521 if (lglsignedmarked (lgl, -*p)) continue;
15522 if (!lglsignedmarked (lgl, other))
15523 lglpushstk (lgl, &lgl->cce->cla, other);
15524 if (!lglsignedmarked (lgl, *p))
15525 lglpushstk (lgl, &lgl->cce->cla, *p);
15527 assert (tag == OCCS);
15528 d = lglidx2lits (lgl, 0, other);
15530 for (q = d; (other = *q); q++)
15531 if (other != -lit && lglsignedmarked (lgl, -other)) break;
15532 if (other) continue;
15533 for (q = d; (other = *q); q++)
15534 if (other != -lit && !lglsignedmarked (lgl, other))
15535 lglpushstk (lgl, &lgl->cce->cla, other);
15539 r = lgl->cce->cla.start + old;
15540 if (tag == BINCS) {
15541 if (lglsignedmarked (lgl, -other)) continue;
15542 for (q = r; q < lgl->cce->cla.top; q++)
15543 if (*q == other) *r++ = *q;
15544 } else if (tag == TRNCS) {
15545 if (lglsignedmarked (lgl, -other)) continue;
15546 if (lglsignedmarked (lgl, -(other2 = *p))) continue;
15547 for (q = r; q < lgl->cce->cla.top; q++)
15548 if (*q == other || *q == other2) *r++ = *q;
15550 assert (tag == OCCS);
15551 d = lglidx2lits (lgl, 0, other);
15553 for (q = d; (other = *q); q++)
15554 if (other != -lit && lglsignedmarked (lgl, -other)) break;
15555 if (other) continue;
15556 for (q = d; (other = *q); q++) {
15557 if (other == -lit) continue;
15558 assert (other != lit);
15559 assert (!lglsignedmarked2 (lgl, other));
15560 assert (!lglsignedmarked2 (lgl, -other));
15561 lglsignedmark2 (lgl, other);
15563 for (q = r; q < lgl->cce->cla.top; q++)
15564 if (lglsignedmarked2 (lgl, (other = *q)))
15566 for (q = d; (other = *q); q++) {
15567 if (other == -lit) continue;
15568 assert (other != lit);
15569 assert (lglsignedmarked2 (lgl, other));
15570 lglsignedunmark2 (lgl, other);
15573 if ((lgl->cce->cla.top = r) == lgl->cce->cla.start + old) break;
15576 if (lglcntstk (&lgl->cce->cla) > old) {
15578 lglpushstk (lgl, &lgl->cce->extend, lit);
15579 for (q = lgl->cce->cla.start; q < lgl->cce->cla.start + old; q++)
15580 if (*q != lit) lglpushstk (lgl, &lgl->cce->extend, *q);
15581 lglpushstk (lgl, &lgl->cce->extend, 0);
15583 for (q = lgl->cce->cla.start + old; !res && q < lgl->cce->cla.top; q++) {
15584 if (lglsignedmarked (lgl, -*q)) {
15585 LOG (CCELOGLEVEL, "CLA on %d results in ATE", *q);
15588 LOG (CCELOGLEVEL, "CLA %d on %d", *q, lit);
15589 lglpushstk (lgl, &lgl->seen, *q);
15590 lglsignedmark (lgl, *q);
15593 if (!res && p == eow && nextala < lglcntstk (&lgl->seen)) goto ALA;
15597 LOGCLS (CCELOGLEVEL, c, "ATE clause");
15598 lgl->stats->cce.ate++;
15599 } else if (lgl->opts->block.val && cce >= 2) {
15600 for (p = lgl->cce->cla.start; p < lgl->cce->cla.top; p++)
15601 if (!lglifrozen (lgl, (other = *p)) && (res = lglabce (lgl, other)))
15604 LOGCLS (CCELOGLEVEL, c, "ABCE on %d clause", other);
15605 lglpushstk (lgl, &lgl->cce->extend, other);
15606 for (p = lgl->cce->cla.start; p < lgl->cce->cla.top; p++)
15607 if (*p != other) lglpushstk (lgl, &lgl->cce->extend, *p);
15608 lglpushstk (lgl, &lgl->cce->extend, 0);
15609 lgl->stats->cce.abce++;
15612 if (res) lgl->stats->cce.eliminated++;
15614 lglpopnunmarkstk (lgl, &lgl->seen);
15615 lglclnstk (&lgl->cce->cla);
15616 if (res && !lglmtstk (&lgl->cce->extend)) {
15618 assert (lgl->opts->block.val);
15620 for (p = lgl->cce->extend.start; p < lgl->cce->extend.top; p++) {
15622 lglepush (lgl, lit);
15623 if (!prev) assert (!lglifrozen (lgl, lit)), lglblockinglit (lgl, lit);
15627 lglclnstk (&lgl->cce->extend);
15631 static const char * lglcce2str (int cce) {
15632 assert (0 <= cce), assert (cce <= 3);
15633 if (cce == 3) return "ACCE";
15634 else if (cce == 2) return "ABCE";
15635 else if (cce == 1) return "ATE";
15636 else return "none";
15639 static int lglccesmallclauses (LGL * lgl, int lit) {
15640 int idx = abs (lit), blit, tag, red, other, other2;
15641 HTS * hts = lglhts (lgl, lit);
15642 const int * p, * w, * eow;
15643 CCE * cce = lgl->cce;
15646 if (!lglisfree (lgl, lit)) return 1;
15647 clauses = &cce->clauses;
15648 w = lglhts2wchs (lgl, hts);
15649 eow = w + hts->count;
15650 INCSTEPS (cce.steps);
15651 for (p = w; p < eow; p++) {
15653 tag = blit & MASKCS;
15654 if (tag == OCCS) continue;
15655 if (tag == TRNCS || tag == LRGCS) p++;
15656 if (tag == LRGCS) continue;
15657 red = blit & REDCS;
15659 other = blit >> RMSHFT;
15660 if (abs (other) < idx) continue;
15661 if (!lglisfree (lgl, other)) continue;
15662 if (tag == TRNCS) {
15664 if (abs (other2) < idx) continue;
15665 if (abs (other2) < abs (other)) continue;
15666 if (!lglisfree (lgl, other2)) continue;
15667 lglpushstk (lgl, clauses, other2);
15670 assert (tag == BINCS);
15673 lglpushstk (lgl, clauses, other);
15674 lglpushstk (lgl, clauses, lit);
15675 lglpushstk (lgl, clauses, 0);
15680 static void lglccesmall (LGL * lgl, int cce) {
15681 int count, valid, invalid, tried, eliminated, elim2, elim3;
15682 int size, lit, tag;
15683 const int * p, * c;
15686 clauses = &lgl->cce->clauses;
15687 assert (!lgl->cce->clauses.start);
15688 lglrandlitrav (lgl, lglccesmallclauses);
15689 lglfitstk (lgl, &lgl->cce->clauses);
15690 count = lgl->cce->bin + lgl->cce->trn;
15692 "[cce-%d] scheduling %d clauses = %d binary + %d ternary",
15693 lgl->stats->cce.count, count, lgl->cce->bin, lgl->cce->trn);
15694 tried = eliminated = invalid = elim2 = elim3 = 0;
15695 for (c = clauses->start; c < clauses->top; c = p + 1) {
15696 if (lgl->mt) break;
15697 if (lglterminate (lgl)) break;
15698 if (lgl->limits->cce.steps <= lgl->stats->cce.steps) break;
15700 for (p = c; (lit = *p); p++)
15701 if (!lglisfree (lgl, lit))
15706 assert (2 <= size), assert (size <= 3);
15707 tag = size == 2 ? BINCS : TRNCS;
15708 if (!lglcceclause (lgl, c, tag, cce)) continue;
15711 lglrmvbcls (lgl, c[0], c[1]);
15714 assert (size == 3);
15715 lglrmvtcls (lgl, c[0], c[1], c[2]);
15720 assert (count >= tried + invalid);
15721 lglrelstk (lgl, &lgl->cce->clauses);
15724 "[cce-%d] tried to eliminate %d small clauses %.0f%%",
15725 lgl->stats->cce.count, tried, lglpcnt (tried, count));
15728 "[cce-%d] eliminated %d small clauses %.0f%%",
15729 lgl->stats->cce.count, eliminated, lglpcnt (eliminated, count));
15732 "[cce-%d] eliminated %d binary clauses %.0f%%",
15733 lgl->stats->cce.count, elim2, lglpcnt (elim2, lgl->cce->bin));
15736 "[cce-%d] eliminated %d ternary clauses %.0f%%",
15737 lgl->stats->cce.count, elim3, lglpcnt (elim3, lgl->cce->trn));
15740 static int lglcce (LGL * lgl) {
15741 int oldvars = lgl->nvars, cce, lenlim, startirr, success;
15742 int oldirr, eliminated, total, idx, round;
15743 int completedsmall, completedlarge;
15744 int64_t oldsteps, deltasteps;
15745 int elmlarge, elmsmall;
15746 lglstart (lgl, &lgl->times->cce);
15747 lgl->stats->cce.count++;
15748 lglsetccelim (lgl);
15750 if (lglprogressincelastcce (lgl)) {
15752 "[cce-%d] there was progress since last CCE so focusing on ATE first",
15753 lgl->stats->cce.count);
15754 lgl->ccertc = 0; // TODO keep this?
15757 "[cce-%d] no progress since last CCE so keeping ccertc=%s",
15758 lgl->stats->cce.count, lglcce2str (lgl->ccertc));
15763 startirr = lgl->stats->irr.clauses.cur;
15766 cce = lgl->opts->cce.val;
15767 if (cce == 3 && lgl->ccertc < 2 &&
15768 lgl->opts->cce3wait.val >= lgl->stats->cce.count) {
15770 "[cce-%d-%d] restricted to ABCE since ccertc=%s",
15771 lgl->stats->cce.count, round, lglcce2str (lgl->ccertc));
15774 if (cce == 2 && lgl->ccertc < 1 &&
15775 lgl->opts->cce2wait.val >= lgl->stats->cce.count) {
15777 "[cce-%d-%d] restricted to ATE since ccertc=%s",
15778 lgl->stats->cce.count, round, lglcce2str (lgl->ccertc));
15781 oldirr = lgl->stats->irr.clauses.cur;
15782 lglprt (lgl, 2, "[cce-%d-%d] starting round %d (%s)",
15783 lgl->stats->cce.count, round, round, lglcce2str (cce));
15784 assert (!lgl->simp && !lgl->cceing && !lgl->occs);
15785 lgl->cceing = lgl->simp = 1;
15786 if (lgl->level > 0) lglbacktrack (lgl, 0);
15788 NEW (lgl->cce->rem, oldvars);
15789 for (idx = 2; idx < oldvars; idx++) lgl->cce->rem[idx] = INT_MAX;
15791 assert (lgl->frozen);
15793 oldsteps = lgl->stats->cce.steps;
15797 !lglterminate (lgl) &&
15798 lgl->limits->cce.steps > lgl->stats->cce.steps) {
15799 int maxlen = 0, count;
15800 const int * p, * c;
15803 for (c = lgl->irr.start; c < lgl->irr.top; c = p + 1) {
15805 if (*(p = c) >= NOTALIT) continue;
15808 if (len >= lenlim) continue;
15809 if (len < maxlen) continue;
15810 if (len > maxlen) {
15811 lglclnstk (&lidcs);
15814 lidx = c - lgl->irr.start;
15815 lglpushstk (lgl, &lidcs, lidx);
15817 ADDSTEPS (cce.steps, lglcntstk (&lgl->irr)/128);
15818 count = lglcntstk (&lidcs);
15820 "[cce-%d-%d] scheduling %d clauses of length %d",
15821 lgl->stats->cce.count, round, count, maxlen);
15823 for (p = lidcs.start;
15826 !lglterminate (lgl) &&
15827 lgl->limits->cce.steps > lgl->stats->cce.steps;
15830 c = lgl->irr.start + lidx;
15831 if (*c >= NOTALIT) continue;
15832 if (!lglcceclause (lgl, c, OCCS, cce)) continue;
15833 lglrmvlcls (lgl, lidx);
15836 elmlarge += eliminated;
15837 lglrelstk (lgl, &lidcs);
15839 lglprt (lgl, 1 + !eliminated,
15840 "[cce-%d-%d] eliminated %d clauses out of %d (%.0f%%) of length %d",
15841 lgl->stats->cce.count, round,
15842 eliminated, count, lglpcnt (eliminated, count), maxlen);
15844 completedlarge = (lgl->limits->cce.steps > lgl->stats->cce.steps);
15845 if (completedlarge)
15847 "[cce-%d-%d] completed large round (%s)",
15848 lgl->stats->cce.count, round, lglcce2str (cce));
15851 "[cce-%d-%d] incomplete large round (%s)",
15852 lgl->stats->cce.count, round, lglcce2str (cce));
15853 deltasteps = lgl->stats->cce.steps - oldsteps;
15854 lglprt (lgl, 1 + !elmlarge,
15855 "[cce-%d-%d] eliminated %d large clauses in %lld steps",
15856 lgl->stats->cce.count, round, elmlarge, (LGLL) deltasteps);
15858 if (LLMAX - deltasteps > lgl->limits->cce.steps) {
15859 lgl->limits->cce.steps += deltasteps;
15861 "[cce-%d-%d] allowing another %lld steps for small clauses",
15862 lgl->stats->cce.count, round, deltasteps);
15864 lgl->limits->cce.steps = LLMAX;
15866 "[cce-%d-%d] unlimited number of steps for small clauses",
15867 lgl->stats->cce.count, round);
15869 lglccesmall (lgl, cce);
15870 elmsmall = oldirr - lgl->stats->irr.clauses.cur - elmlarge;
15871 lglprt (lgl, 1 + !elmsmall,
15872 "[cce-%d-%d] eliminated %d small clauses in %lld steps",
15873 lgl->stats->cce.count, round, elmsmall,
15874 (LGLL) lgl->stats->cce.steps - oldsteps - deltasteps);
15875 completedsmall = (lgl->limits->cce.steps > lgl->stats->cce.steps);
15876 COVER (!completedsmall && lgl->opts->ccertc.val);
15877 if (completedsmall)
15879 "[cce-%d-%d] completed small round (%s)",
15880 lgl->stats->cce.count, round, lglcce2str (cce));
15883 "[cce-%d-%d] incomplete small round (%s)",
15884 lgl->stats->cce.count, round, lglcce2str (cce));
15885 if (completedsmall && completedlarge) {
15886 if (lgl->ccertc < cce) {
15889 "[cce-%d-%d] completed small and large (%s)",
15890 lgl->stats->cce.count, round, lglcce2str (cce));
15895 lglrelstk (lgl, &lgl->cce->extend);
15896 lglrelstk (lgl, &lgl->cce->cla);
15897 DEL (lgl->cce->rem, oldvars);
15899 assert (oldirr >= lgl->stats->irr.clauses.cur);
15900 eliminated = oldirr - lgl->stats->irr.clauses.cur;
15901 total += eliminated;
15903 "[cce-%d-%d] eliminated %d covered clauses in round %d",
15904 lgl->stats->cce.count, round, eliminated, round);
15905 assert (lgl->simp && lgl->cceing);
15906 lgl->cceing = lgl->simp = 0;
15909 !lglterminate (lgl) &&
15910 lgl->limits->cce.steps > lgl->stats->cce.steps) goto RESTART;
15912 "[cce-%d] eliminated %d covered clauses in TOTAL during %d rounds",
15913 lgl->stats->cce.count, total, round);
15914 if (startirr < lgl->opts->ccesuccesslim.val) success = total;
15916 success = (startirr/lgl->opts->ccesuccessrat.val <= total);
15919 "[cce-%d] %d < 1/%d * %d = %d considered unsuccessful",
15920 lgl->stats->cce.count, total, lgl->opts->ccesuccessrat.val,
15921 startirr, startirr/lgl->opts->ccesuccessrat.val);
15922 } else success = 0;
15923 LGLUPDPEN (cce, success);
15924 lglrep (lgl, 2, 'E');
15926 lglbasicatestats (lgl);
15930 static void lglcliffclause (LGL * lgl, const int * c) {
15931 int lit, start, i, first, dom, other, * r;
15932 const int * p, * q;
15933 for (p = c; (lit = *p); p++) if (lglval (lgl, lit) > 0) return;
15934 LOGCLS (2, c, "cliffing clause");
15935 assert (lgl->cliff);
15936 assert (lglmtstk (&lgl->cliff->lift));
15937 assert (!lgl->level);
15939 start = lglcntstk (&lgl->trail);
15941 for (p = c; (lit = *p); p++) {
15942 if (lglval (lgl, lit) < 0) continue;
15943 lgl->stats->cliff.decisions++;
15944 lgliassume (lgl, lit);
15945 if (!lglbcp (lgl)) {
15946 LOG (1, "cliffing failed literal %d", lit);
15947 dom = lglprbana (lgl, lit);
15948 lglbacktrack (lgl, 0);
15949 lgl->stats->cliff.failed++;
15950 lglunit (lgl, -dom);
15951 if (!lglbcp (lgl)) {
15952 LOG (1, "empty clause after propagating %d", -dom);
15958 for (i = start; i < lglcntstk (&lgl->trail); i++) {
15959 other = lglpeek (&lgl->trail, i);
15960 lglpushstk (lgl, &lgl->cliff->lift, other);
15964 r = lgl->cliff->lift.start;
15965 for (q = r; q < lgl->cliff->lift.top; q++)
15966 if (lglval (lgl, (other = *q)) > 0)
15968 lgl->cliff->lift.top = r;
15970 lglbacktrack (lgl, 0);
15971 if (lglmtstk (&lgl->cliff->lift)) return;
15973 while (!lglmtstk (&lgl->cliff->lift)) {
15974 lit = lglpopstk (&lgl->cliff->lift);
15975 LOG (1, "cliffing lifted unit %d", lit);
15976 lgl->stats->cliff.lifted++;
15977 if (lglval (lgl, lit) > 0) continue;
15978 if (lglval (lgl, lit) < 0) {
15979 LOG (1, "inconsistent lifted unit %d", lit);
15983 lglunit (lgl, lit);
15984 if (!lglbcp (lgl)) {
15985 LOG (1, "empty clause after propagating lifted unit %d", lit);
15991 lglclnstk (&lgl->cliff->lift);
15994 static int lglcliffclauses (LGL * lgl, Stk * stk) {
15995 const int * c, * p;
15996 for (c = stk->start; c < stk->top; c = p + 1) {
15997 if (*(p = c) >= NOTALIT) continue;
15998 if (INCSTEPS (cliff.steps) >= lgl->limits->cliff.steps) return 0;
15999 if (lglterminate (lgl)) return 0;
16000 lglcliffclause (lgl, c);
16001 if (lgl->mt) return 0;
16002 for (p = c; *p; p++)
16008 static int lglclifflitrn (LGL * lgl, int lit) {
16009 const int * w, * eow, * p;
16010 int res, blit, tag, other, other2;
16012 assert (lglmtstk (&lgl->cliff->lits));
16013 if (!lglisfree (lgl, lit)) return 1;
16014 if (INCSTEPS (cliff.steps) >= lgl->limits->cliff.steps) return 0;
16015 hts = lglhts (lgl, lit);
16016 w = lglhts2wchs (lgl, hts);
16017 eow = w + hts->count;
16018 for (p = w; p < eow; p++) {
16020 tag = blit & MASKCS;
16021 if (tag == TRNCS || tag == LRGCS) p++;
16022 if (tag == BINCS) continue;
16023 if (tag == LRGCS) continue;
16024 assert (tag == TRNCS);
16025 other = blit >> RMSHFT;
16026 if (abs (other) < abs (lit)) continue;
16028 if (abs (other2) < abs (lit)) continue;
16029 lglpushstk (lgl, &lgl->cliff->lits, lit);
16030 lglpushstk (lgl, &lgl->cliff->lits, other);
16031 lglpushstk (lgl, &lgl->cliff->lits, other2);
16032 lglpushstk (lgl, &lgl->cliff->lits, 0);
16034 res = lglcliffclauses (lgl, &lgl->cliff->lits);
16035 lglclnstk (&lgl->cliff->lits);
16036 return res && !lgl->mt;
16039 static int lglcliffred (LGL * lgl) {
16041 for (glue = 0; glue < MAXGLUE; glue++)
16042 if (!lglcliffclauses (lgl, &lgl->red[glue]))
16047 static void lglsetclifflim (LGL * lgl) {
16048 int64_t limit, irrlim;
16050 limit = (lgl->opts->cliffreleff.val*lglvisearch (lgl))/1000;
16051 if (limit < lgl->opts->cliffmineff.val) limit = lgl->opts->cliffmineff.val;
16052 if (lgl->opts->cliffmaxeff.val >= 0 && limit > lgl->opts->cliffmaxeff.val)
16053 limit = lgl->opts->cliffmaxeff.val;
16054 limit >>= (pen = lgl->limits->cliff.pen + lglszpen (lgl));
16055 irrlim = 2*lgl->stats->irr.clauses.cur;
16056 irrlim >>= lgl->limits->simp.pen;
16057 if (lgl->opts->irrlim.val && limit < irrlim) {
16060 "[cliff-%d] limit of %lld steps based on %d irredundant clauses",
16061 lgl->stats->cliff.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
16063 lglprt (lgl, 1, "[cliff-%d] limit of %lld steps penalty %d = %d + %d",
16064 lgl->stats->cliff.count, (LGLL) limit,
16065 pen, lgl->limits->cliff.pen, lglszpen (lgl));
16066 lgl->limits->cliff.steps = lgl->stats->cliff.steps + limit;
16069 static int lglcliff (LGL * lgl) {
16070 int lifted, failed, oldlifted, oldfailed, success;
16071 lglstart (lgl, &lgl->times->cliff);
16072 lgl->stats->cliff.count++;
16073 assert (!lgl->simp && !lgl->cliffing);
16074 lgl->simp = lgl->cliffing = 1;
16075 assert (!lgl->cliff);
16076 NEW (lgl->cliff, 1);
16077 if (lgl->level > 0) lglbacktrack (lgl, 0);
16078 oldlifted = lgl->stats->cliff.lifted;
16079 oldfailed = lgl->stats->cliff.failed;
16080 lglsetclifflim (lgl);
16081 if (lglcliffclauses (lgl, &lgl->irr))
16082 if (lglrandlitrav (lgl, lglclifflitrn))
16083 (void) lglcliffred (lgl);
16084 lifted = lgl->stats->cliff.lifted - oldlifted;
16085 failed = lgl->stats->cliff.failed - oldfailed;
16086 lglprt (lgl, 1, "[cliff-%d] failed %d, lifted %d",
16087 lgl->stats->cliff.count, failed, lifted);
16088 assert (lgl->simp && lgl->cliffing);
16089 lgl->simp = lgl->cliffing = 0;
16090 lglrelstk (lgl, &lgl->cliff->lift);
16091 lglrelstk (lgl, &lgl->cliff->lits);
16092 DEL (lgl->cliff, 1);
16093 success = failed || lifted;
16094 LGLUPDPEN (cliff, success);
16095 lglrep (lgl, 2, 'K');
16100 static void lglsetelmlim (LGL * lgl) {
16101 int64_t limit, irrlim;
16103 if (lgl->opts->elmrtc.val) {
16104 lgl->limits->elm.steps = LLMAX;
16105 lglprt (lgl, 1, "[elim-%d] no limit", lgl->stats->elm.count);
16107 limit = (lgl->opts->elmreleff.val*lglvisearch (lgl))/1000;
16108 if (limit < lgl->opts->elmineff.val) limit = lgl->opts->elmineff.val;
16109 if (lgl->opts->elmaxeff.val >= 0 && limit > lgl->opts->elmaxeff.val)
16110 limit = lgl->opts->elmaxeff.val;
16111 if (lgl->stats->elm.count <= 1 &&
16112 lgl->opts->boost.val &&
16113 lgl->opts->elmboost.val > 1) {
16115 "[elim-%d] boosting limit by %d",
16116 lgl->stats->elm.count, lgl->opts->elmboost.val);
16117 limit *= lgl->opts->elmboost.val;
16119 limit >>= (pen = lgl->limits->elm.pen + lglszpen (lgl));
16120 irrlim = lgl->stats->irr.clauses.cur;
16121 irrlim >>= lgl->limits->simp.pen;
16122 if (lgl->opts->irrlim.val && limit < irrlim) {
16125 "[elim-%d] limit of %lld steps based on %d irredundant clauses",
16126 lgl->stats->elm.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
16129 "[elim-%d] limit of %lld steps penalty %d = %d + %d",
16130 lgl->stats->elm.count, (LGLL) limit,
16131 pen, lgl->limits->elm.pen, lglszpen (lgl));
16132 lgl->limits->elm.steps = lgl->stats->elm.steps + limit;
16136 static int lglforceschedall (LGL * lgl) {
16139 assert (lgl->eliminating);
16140 assert (lglmtstk (&lgl->esched));
16141 lgl->donotsched = 0;
16142 for (idx = 2; idx < lgl->nvars; idx++) {
16143 if (lglifrozen (lgl, idx)) continue;
16144 if (!lglisfree (lgl, idx)) continue;
16145 av = lglavar (lgl, idx);
16147 lglesched (lgl, idx);
16151 "[elim-%d-%d] fully rescheduled %d variables %.0f%%",
16152 lgl->stats->elm.count, lgl->elm->round,
16153 res, lglpcnt (res, lgl->nvars - 2));
16157 static void lgladdstrbincls (LGL * lgl, int a, int b) {
16158 assert (lglisfree (lgl, a));
16159 assert (lglisfree (lgl, b));
16160 assert (lglmtstk (&lgl->clause));
16161 lglpushstk (lgl, &lgl->clause, a);
16162 lglpushstk (lgl, &lgl->clause, b);
16163 lglpushstk (lgl, &lgl->clause, 0);
16164 LOG (BWL, "strengthened binary clause", a, b);
16165 if (lgl->opts->drup.val) lgldrupcls (lgl);
16166 #ifndef NLGLPICOSAT
16167 lglpicosatchkcls (lgl);
16169 lgldrupligaddcls (lgl, REDCS);
16170 lgladdcls (lgl, 0, 0, 1);
16171 lglclnstk (&lgl->clause);
16174 static int lglbackwardlit (LGL * lgl,
16175 const int * clause, const int * skip,
16176 int size, int minlit,
16177 int *subptr, int *strptr) {
16178 int res, blit, tag, red, other, other2, lidx, count, remove, hit;
16179 const int * p, * w, * eow, * c, * l;
16180 int marked, marked2, val;
16182 assert (!lgl->level);
16183 lgl->stats->bkwd.tried.lits++;
16184 LOGCLS (BWL, clause,
16185 "backward subsume and strengthen clauses with %d by size %d clause",
16188 hts = lglhts (lgl, minlit);
16189 w = lglhts2wchs (lgl, hts);
16190 eow = w + hts->count;
16191 for (p = w; !res && p < eow; p++) {
16193 tag = blit & MASKCS;
16194 if (tag == TRNCS || tag == LRGCS) p++;
16195 if (tag == LRGCS) continue;
16196 if (p == skip) continue;
16197 red = blit & REDCS;
16199 lgl->stats->bkwd.tried.occs++;
16200 INCSTEPS (elm.steps);
16201 if (tag == BINCS) {
16202 if (size > 2) continue;
16203 other = blit >> RMSHFT;
16204 if (!lglisfree (lgl, other)) continue;
16205 marked = lglmarked (lgl, other);
16207 if (size == 2 && !hit++) continue;
16208 LOG (BWL, "subsumed binary clause %d %d", minlit, other);
16209 assert (!(w <= skip && skip < eow) || skip < p);
16210 ADDSTEPS (elm.steps, 2);
16211 lglrmbcls (lgl, minlit, other, 0);
16212 lgl->stats->bkwd.sub2++;
16215 } else if (marked < 0) {
16217 "removing %d and thus strengthening binary clause %d %d",
16218 other, minlit, other);
16219 assert (p != skip);
16220 ADDSTEPS (elm.steps, 2);
16221 lglunit (lgl, minlit);
16222 lgl->stats->bkwd.str2++;
16226 } else if (tag == TRNCS) {
16227 if (size > 3) continue;
16228 other = blit >> RMSHFT;
16230 if (!lglisfree (lgl, other)) continue;
16231 if (!lglisfree (lgl, other2)) continue;
16232 marked = lglmarked (lgl, other);
16233 marked2 = lglmarked (lgl, other2);
16234 if ((size == 2 && (marked > 0 || marked2 > 0)) ||
16235 (size == 3 && marked > 0 && marked2 > 0)) {
16236 if (size == 3 && !hit++) continue;
16237 assert (!(w <= skip && skip < eow) || skip < p);
16239 "subsumed ternary clause %d %d %d",
16240 minlit, other, other2);
16241 ADDSTEPS (elm.steps, 3);
16242 lglrmtcls (lgl, minlit, other, other2, 0);
16243 lgl->stats->bkwd.sub3++;
16247 if (marked < 0 && marked2 > 0) {
16248 int tmp = other; other = other2; other2 = tmp;
16249 } else if (marked <= 0 || marked2 >= 0) continue;
16251 "removing %d and thus strengthening ternary clause %d %d %d",
16252 other2, minlit, other, other2);
16253 assert (lglmarked (lgl, other) > 0);
16254 assert (lglmarked (lgl, other2) < 0);
16255 lgladdstrbincls (lgl, minlit, other);
16256 lglrmtcls (lgl, minlit, other, other2, 0);
16259 "removing %d and thus strengthening ternary clause %d %d %d",
16260 other2, minlit, other, -other2);
16261 lglrmtcls (lgl, minlit, other, -other2, 0);
16262 lgl->stats->bkwd.str3self++;
16264 ADDSTEPS (elm.steps, 3);
16265 lgl->stats->bkwd.str3++;
16270 assert (tag == OCCS);
16271 lidx = blit >> RMSHFT;
16272 c = lglidx2lits (lgl, 0, lidx);
16273 if (c == skip) continue;
16274 INCSTEPS (elm.steps);
16277 for (l = c; (other = *l); l++) {
16278 val = lglval (lgl, other);
16279 if (val > 0) { remove = INT_MAX; break; }
16280 if (val < 0) continue;
16282 marked = lglmarked (lgl, other);
16283 if (!marked) continue;
16285 if (marked > 0) continue;
16286 if (remove) { remove = INT_MAX; break; }
16289 if (count > 0) continue;
16290 if (remove == INT_MAX) continue;
16292 assert (!(w <= skip && skip < eow) || skip < p);
16293 LOGCLS (BWL, c, "subsumed large clause");
16294 ADDSTEPS (elm.steps, (l - c));
16295 lglrmlcls (lgl, lidx, 0);
16296 lgl->stats->bkwd.subl++;
16299 } else if (lglsmallirr (lgl)) {
16300 LOGCLS (BWL, c, "removing %d and thus strengthening clause", remove);
16301 assert (lglmtstk (&lgl->clause));
16302 for (l = c; (other = *l); l++) {
16303 if (other == remove) continue;
16304 val = lglval (lgl, other);
16305 if (val < 0) continue;
16307 lglpushstk (lgl, &lgl->clause, other);
16309 lglpushstk (lgl, &lgl->clause, 0);
16310 LOGCLS (BWL, lgl->clause.start, "strengthened clause");
16311 if (lgl->opts->drup.val) lgldrupcls (lgl);
16312 #ifndef NLGLPICOSAT
16313 lglpicosatchkcls (lgl);
16315 ADDSTEPS (elm.steps, (l - c));
16316 lglrmlcls (lgl, lidx, 0);
16317 if (l - c == size) lgl->stats->bkwd.strlself++;
16318 lgldrupligaddcls (lgl, REDCS);
16319 lgladdcls (lgl, 0, 0, 1);
16320 lglclnstk (&lgl->clause);
16321 lgl->stats->bkwd.strl++;
16330 static int lglbackwardclause (LGL * lgl,
16331 const int * clause, const int * skip,
16332 int * subsumedptr, int * strengthenedptr) {
16333 int lit, size, minlit, minlit2, minocc, minocc2, tmpocc, res, large;
16336 lgl->stats->bkwd.tried.clauses++;
16337 INCSTEPS (elm.steps);
16338 minocc = minlit = minocc2 = minlit2 = 0;
16339 for (p = clause; (lit = *p); p++) {
16340 lglmarkunmarked (lgl, lit);
16341 tmpocc = lglocc (lgl, lit);
16342 if (!minlit || tmpocc < minocc) {
16343 minocc2 = minocc, minlit2 = minlit;
16344 minocc = tmpocc, minlit = lit;
16345 } else if (!minlit2 || tmpocc < minocc2) {
16346 minocc2 = tmpocc, minlit2 = lit;
16350 assert (size >= 2);
16351 LOG (BWL, "minimum occurrence %d of literal %d", minocc, minlit);
16352 LOG (BWL, "next minimum occurrence %d of literal %d", minocc2, minlit2);
16353 large = (lgl->irr.start <= clause && clause < lgl->irr.top);
16354 delta = large ? clause - lgl->irr.start : 0;
16355 res = lglbackwardlit (lgl, clause, skip,
16356 size, minlit, subsumedptr, strengthenedptr);
16358 res = lglbackwardlit (lgl, clause, skip,
16359 size, minlit2, subsumedptr, strengthenedptr);
16361 if (res && large) clause = lgl->irr.start + delta;
16362 for (p = clause; (lit = *p); p++)
16363 lglunmark (lgl, lit);
16367 static void lglbackward (LGL * lgl, int * u, int * t, int64_t steps) {
16368 int idx, sign, lit, blit, red, tag, other, other2, clause[4], * w;
16369 int64_t limit, delta, scaled;
16370 const int * p, * eow, * c;
16374 lglstart (lgl, &lgl->times->bkwd);
16377 if (LLMAX/lgl->opts->bkwdscale.val <= steps) scaled = LLMAX;
16378 else scaled = steps * lgl->opts->bkwdscale.val;
16379 if (lgl->limits->elm.steps - scaled <= lgl->stats->elm.steps)
16380 limit = lgl->limits->elm.steps;
16381 else limit = lgl->stats->elm.steps + scaled;
16382 delta = limit - lgl->stats->elm.steps;
16384 "[elim-%d-%d] backward subsumption/strengthening limit %lld",
16385 lgl->stats->elm.count, lgl->elm->round, delta);
16386 for (idx = 2; idx < lgl->nvars; idx++) {
16387 for (sign = -1; sign <= 1; sign += 2) {
16389 if (lgl->mt) goto DONE;
16390 if (lglterminate (lgl)) goto DONE;
16392 // TODO DID NOT WORK? REMOVE OR FIX?
16393 // if (!lglsyncunits (lgl)) goto DONE;
16395 if (!lglisfree (lgl, idx)) continue;
16396 if (INCSTEPS (elm.steps) >= limit) goto DONE;
16398 hts = lglhts (lgl, lit);
16399 w = lglhts2wchs (lgl, hts);
16400 eow = w + hts->count;
16402 for (p = w; p < eow; p++) {
16404 tag = blit & MASKCS;
16405 if (tag == TRNCS || tag == LRGCS) p++;
16406 if (tag != BINCS) continue;
16407 red = blit & REDCS;
16409 lglpushstk (lgl, &stk, blit);
16411 for (p = w; p < eow; p++) {
16413 tag = blit & MASKCS;
16414 if (tag == TRNCS || tag == LRGCS) p++;
16415 if (tag != TRNCS) continue;
16416 red = blit & REDCS;
16418 lglpushstk (lgl, &stk, blit);
16419 lglpushstk (lgl, &stk, *p);
16421 for (p = w; p < eow; p++) {
16423 tag = blit & MASKCS;
16424 if (tag == TRNCS || tag == LRGCS) p++;
16425 red = blit & REDCS;
16426 if (!red && (tag == BINCS || tag == TRNCS)) continue;
16427 lglpushstk (lgl, &stk, blit);
16428 if (tag == TRNCS || tag == LRGCS)
16429 lglpushstk (lgl, &stk, *p);
16431 assert (lglcntstk (&stk) == hts->count);
16432 memcpy (w, stk.start, lglcntstk (&stk) * sizeof *w);
16434 for (p = w; p < eow; p++) {
16436 tag = blit & MASKCS;
16437 if (tag == TRNCS || tag == LRGCS) p++;
16438 if (tag == LRGCS) continue;
16439 red = blit & REDCS;
16441 if (INCSTEPS (elm.steps) >= limit) goto DONE;
16442 if (tag == BINCS) {
16443 other = blit >> RMSHFT;
16444 if (abs (other) < idx) continue;
16445 clause[1] = other, clause[2] = 0;
16446 if (!lglbackwardclause (lgl, clause, p, u, t)) continue;
16447 } else if (tag == TRNCS) {
16448 other = blit >> RMSHFT;
16449 if (abs (other) < idx) continue;
16451 if (abs (other2) < idx) continue;
16452 clause[1] = other, clause[2] = other2, clause[3] = 0;
16453 if (!lglbackwardclause (lgl, clause, p, u, t)) continue;
16454 } else { assert (tag == OCCS); continue; }
16455 if (lglflush (lgl)) goto RESTART;
16460 for (c = lgl->irr.start; c < lgl->irr.top; c = p + 1) {
16461 if (!lglsmallirr (lgl)) goto DONE;
16462 if (INCSTEPS (elm.steps) >= limit) goto DONE;
16463 if (*(p = c) >= NOTALIT) continue;
16465 i = p - lgl->irr.start;
16466 if (lglbackwardclause (lgl, c, c, u, t)) p = lgl->irr.start + i;
16469 lglrelstk (lgl, &stk);
16473 static int lglelmdone (LGL * lgl, int * allptr) {
16474 int newelmd, eliminated, subsumed, strengthened;
16475 int64_t steps, oldsteps;
16476 if (!lglsmallirr (lgl)) return 1;
16477 if (lglterminate (lgl)) return 1;
16478 if (lgl->limits->elm.steps <= lgl->stats->elm.steps) return 1;
16479 if (!lglmtstk (&lgl->esched)) return 0;
16480 steps = ((oldsteps = lgl->stats->elm.steps) - lgl->elm->oldsteps);
16481 eliminated = (newelmd = lgl->stats->elm.elmd) - lgl->elm->oldelmd;
16482 assert (eliminated >= 0);
16483 if (eliminated <= 0) {
16485 "[elim-%d-%d] no variable eliminated in round %d in %lld steps",
16486 lgl->stats->elm.count, lgl->elm->round,
16487 lgl->elm->round, (LGLL) steps);
16491 "[elim-%d-%d] eliminated %d variables %.0f%% in round %d in %lld steps",
16492 lgl->stats->elm.count, lgl->elm->round, eliminated,
16493 lglpcnt (eliminated, lgl->nvars - 2), lgl->elm->round, (LGLL) steps);
16494 lglbackward (lgl, &subsumed, &strengthened, steps);
16495 steps = lgl->stats->elm.steps - oldsteps;
16497 "[elim-%d-%d] subsumed %d and strengthened %d clauses in %lld steps",
16498 lgl->stats->elm.count, lgl->elm->round, subsumed, strengthened,
16500 lgl->stats->elm.rounds++;
16501 lgl->elm->oldelmd = newelmd;
16502 lgl->elm->oldsteps = lgl->stats->elm.steps;
16503 if (lgl->mt) return 1;
16504 if (lgl->limits->elm.steps <= lgl->stats->elm.steps) return 1;
16505 if (lgl->elm->round >= lgl->opts->elmroundlim.val) return 1;
16506 if (!lglmtstk (&lgl->esched)) {
16508 "[elim-%d-%d] rescheduled %d variables %.0f%% by backward subsumption",
16509 lgl->stats->elm.count, lgl->elm->round,
16510 lglcntstk (&lgl->esched),
16511 lglpcnt (lglcntstk (&lgl->esched), lglrem (lgl)));
16515 if (*allptr) return 1;
16517 if (!lglforceschedall (lgl)) return 1;
16522 static int lglelim (LGL * lgl) {
16523 int res = 1, idx, elmd, oldnvars, success, all, rem;
16524 int oldrem = lgl->elmrem, oldall = lgl->elmall;
16525 assert (lgl->opts->elim.val);
16527 assert (lgl->nvars > 2);
16528 assert (!lgl->eliminating);
16529 assert (!lgl->simp);
16530 assert (!lgl->occs);
16531 lglstart (lgl, &lgl->times->elm);
16532 lgl->stats->elm.count++;
16533 lgl->eliminating = lgl->simp = lgl->occs = 1;
16535 lgl->elm->oldelmd = lgl->stats->elm.elmd;
16536 lgl->elm->round = 1;
16537 lgl->elm->oldsteps = lgl->stats->elm.steps;
16538 lgl->stats->elm.rounds++;
16539 if (lgl->level > 0) lglbacktrack (lgl, 0);
16540 oldnvars = lglrem (lgl);
16542 assert (lgl->frozen);
16543 assert (!(oldall && !oldrem));
16544 all = !oldrem || !oldall;
16547 "[elim-%d] scheduling all variables this time",
16548 lgl->stats->elm.count);
16549 else if (!lgleschedrem (lgl, 1)) all = 1, oldrem = 0;
16550 if (!all) assert (!lgl->donotsched), lgl->donotsched = 1;
16552 if (!all) assert (lgl->donotsched), lgl->donotsched = 0;
16553 lglsetelmlim (lgl);
16554 while (res && !lglelmdone (lgl, &all)) {
16555 idx = lglpopesched (lgl);
16556 lglavar (lgl, idx)->donotelm = 1;
16557 lglelimlit (lgl, idx);
16558 res = lglflush (lgl);
16559 assert (res || lgl->mt);
16561 rem = lglcntstk (&lgl->esched);
16564 "[elim-%d] fully completed in %d rounds",
16565 lgl->stats->elm.count, lgl->elm->round);
16569 "[elim-%d] incomplete %d not tried %.0f%% in round %d",
16570 lgl->stats->elm.count,
16571 rem, lglpcnt (rem, lgl->nvars - 2),
16574 lglsetdonotesched (lgl, !rem);
16575 lglrelstk (lgl, &lgl->esched);
16580 lgl->elmrem = rem > 0;
16581 lgl->elmall = all && lgl->elmrem;
16583 "[elim-%d] transition to [ all %d rem %d ] state",
16584 lgl->stats->elm.count, lgl->elmall, lgl->elmrem);
16585 elmd = oldnvars - lglrem (lgl);
16586 lgl->stats->irrprgss += elmd;
16588 "[elim-%d] eliminated %d = %.0f%% variables out of %d",
16589 lgl->stats->elm.count, elmd, lglpcnt (elmd, oldnvars), oldnvars);
16590 if (oldnvars < lgl->opts->elmsuccesslim.val) success = elmd;
16592 success = (oldnvars/lgl->opts->elmsuccessrat.val <= elmd);
16595 "[elim-%d] %d < 1/%d * %d = %d considered unsuccessful",
16596 lgl->stats->elm.count, elmd, lgl->opts->elmsuccessrat.val,
16597 oldnvars, oldnvars/lgl->opts->elmsuccessrat.val);
16598 } else success = 0;
16599 LGLUPDPEN (elm, success);
16600 lgl->elmstuck = !rem && !success;
16603 "[elim-%d] completed but nothing eliminated thus stuck",
16604 lgl->stats->elm.count);
16605 lglrep (lgl, 2, 'e');
16606 assert (lgl->eliminating && lgl->simp && lgl->occs);
16607 lgl->eliminating = lgl->simp = lgl->occs = 0;
16612 static int lglsynceqs (LGL * lgl) {
16613 int * ereprs, emax = lgl->maxext;
16614 int elit1, erepr1, elit2, erepr2;
16615 int ilit1, irepr1, ilit2, irepr2;
16616 int consumed = 0, produced = 0;
16618 assert (!lgl->level);
16619 if (!lgl->nvars) return 1;
16620 if (!lgl->cbs) return 1;
16621 if (!lgl->cbs->eqs.lock.fun) return 1;
16622 assert (lgl->repr);
16623 ereprs = lgl->cbs->eqs.lock.fun (lgl->cbs->eqs.lock.state);
16624 produced = consumed = 0;
16625 for (elit1 = 1; elit1 <= emax; elit1++) {
16626 if (lglelitblockingoreliminated (lgl, elit1)) continue;
16627 elit2 = lglptrjmp (ereprs, emax, elit1);
16628 if (elit2 == elit1) continue;
16629 if (lglelitblockingoreliminated (lgl, elit2)) continue;
16630 assert (elit2 != -elit1);
16631 erepr1 = lglerepr (lgl, elit1);
16632 if (lglelitblockingoreliminated (lgl, erepr1)) continue;
16633 erepr2 = lglerepr (lgl, elit2);
16634 if (lglelitblockingoreliminated (lgl, erepr2)) continue;
16635 if (erepr1 == erepr2) continue;
16636 if (erepr1 == -erepr2) {
16638 LOG (1, "inconsistent external equivalence %d %d", elit1, elit2);
16639 assert (!lgl->level);
16643 ilit1 = lglimport (lgl, elit1);
16644 ilit2 = lglimport (lgl, elit2);
16645 if (ilit1 == ilit2) continue;
16646 if (ilit1 == -ilit2) goto INCONSISTENT;
16647 if (abs (ilit1) <= 1) continue;
16648 if (abs (ilit2) <= 1) continue;
16649 irepr1 = lglirepr (lgl, ilit1);
16650 irepr2 = lglirepr (lgl, ilit2);
16651 if (irepr1 == irepr2) continue;
16652 if (irepr1 == -irepr2) goto INCONSISTENT;
16653 if (abs (irepr1) <= 1) continue;
16654 if (abs (irepr2) <= 1) continue;
16655 LOG (2, "importing external equivalence %d %d as internal %d %d",
16656 elit1, elit2, irepr1, irepr2);
16657 if (!lglisfree (lgl, irepr1)) continue;
16658 if (!lglisfree (lgl, irepr2)) continue;
16660 lglimerge (lgl, irepr1, irepr2);
16662 LOG (1, "consumed %d equivalences", consumed);
16663 for (elit1 = 1; elit1 <= emax; elit1++) {
16664 elit2 = lglerepr (lgl, elit1);
16665 if (elit1 == elit2) continue;
16666 assert (elit1 != -elit2);
16667 erepr1 = lglptrjmp (ereprs, emax, elit1);
16668 erepr2 = lglptrjmp (ereprs, emax, elit2);
16669 if (erepr1 == erepr2) continue;
16670 assert (erepr1 != -erepr2);
16671 LOG (2, "exporting external equivalence %d %d", erepr1, erepr2);
16673 ereprs[abs (erepr1)] = (erepr1 < 0) ? -erepr2 : erepr2;
16675 LOG (1, "produced %d equivalences", produced);
16677 if (lgl->cbs->eqs.unlock.fun)
16678 lgl->cbs->eqs.unlock.fun (lgl->cbs->eqs.unlock.state, consumed, produced);
16682 static int lgldecomp (LGL * lgl) {
16683 int res = 1, oldnvars = lgl->nvars, removed;
16684 assert (lgl->opts->decompose.val || lgl->probing || lgl->gaussing);
16685 assert (!lgl->decomposing);
16686 lglstart (lgl, &lgl->times->dcp);
16687 lgl->stats->decomps++;
16688 lgl->decomposing = 1;
16690 assert (lgl->simp > 0);
16691 if (lgl->level > 0) lglbacktrack (lgl, 0);
16694 if (!lglsyncunits (lgl)) goto DONE;
16696 if (lgl->mt) goto DONE;
16697 if (!lgltarjan (lgl)) goto DONE;
16698 if (!lglsynceqs (lgl)) goto DONE;
16705 if (lgl->mt) goto DONE;
16706 if (!lglbcp (lgl)) { if (!lgl->mt) lgl->mt = 1; goto DONE; }
16709 if (lgl->mt) goto DONE;
16710 if (!lgl->mt) { lglpicosatchkall (lgl); lglpicosatrestart (lgl); }
16713 if (lgl->repr) DEL (lgl->repr, lgl->nvars);
16714 assert (lgl->decomposing);
16715 lgl->decomposing = 0;
16716 ASSERT (lgl->simp > 0);
16718 removed = oldnvars - lgl->nvars;
16719 if (removed) lglprt (lgl, 1, "[decomp-%d] removed %d variables",
16720 lgl->stats->decomps, removed);
16721 lglrep (lgl, 2, 'd');
16726 int lglnvars (LGL * lgl) { return lglrem (lgl); }
16728 int lglnclauses (LGL * lgl) { return lgl->stats->irr.clauses.cur; }
16730 static int lglcgrepr (LGL * lgl, int lit) {
16731 return lglptrjmp (lgl->repr, lgl->nvars - 1, lit);
16734 static void lglpushgocc (LGL * lgl, int lit, int gidx) {
16737 repr = lglcgrepr (lgl, lit);
16738 if (abs (repr) == 1) repr = lit;
16740 assert (2 <= idx && idx < lgl->nvars);
16741 goccs = lgl->cgr->goccs + idx;
16742 lglpushstk (lgl, goccs, gidx);
16745 static void lglenlargegates (LGL * lgl) {
16746 int oldsize = lgl->cgr->szgates;
16747 int newsize = oldsize ? 2*oldsize : 1;
16748 RSZ (lgl->cgr->gates, oldsize, newsize);
16749 lgl->cgr->szgates = newsize;
16752 static int lglcgreprnotconst (LGL * lgl, int lit) {
16754 assert (abs (lit) != 1);
16755 res = lglcgrepr (lgl, lit);
16756 if (abs (res) == 1) res = lit;
16760 static Gat * lglnewgate (LGL * lgl, GTag tag, int lhs, int size) {
16763 assert (size >= 2);
16764 if (lgl->cgr->extracted.all >= lgl->cgr->szgates) lglenlargegates (lgl);
16765 assert (lgl->cgr->extracted.all < lgl->cgr->szgates);
16766 lgl->stats->cgr.extracted.all++;
16767 gidx = lgl->cgr->extracted.all++;
16768 res = lgl->cgr->gates + gidx;
16770 lhs = lglcgreprnotconst (lgl, lhs);
16772 lglpushgocc (lgl, lhs, gidx);
16773 lglavar (lgl, lhs)->gate = 1;
16779 static Gat * lglgidx2gat (LGL * lgl, int gidx) {
16780 assert (0 <= gidx && gidx < lgl->cgr->extracted.all);
16781 return lgl->cgr->gates + gidx;
16784 static int lglgat2idx (LGL * lgl, Gat * g) {
16785 assert (lgl->cgr->gates <= g &&
16786 g < lgl->cgr->gates + lgl->cgr->extracted.all);
16787 return g - lgl->cgr->gates;
16790 static int lglcgeq (LGL * lgl, int a, int b) {
16791 return lglcgrepr (lgl, a) == lglcgrepr (lgl, b);
16794 static int lglhasitegate (LGL * lgl, int lhs, int cond, int pos, int neg) {
16798 repr = lglcgrepr (lgl, lhs);
16799 if (abs (repr) == 1) repr = lhs;
16800 s = lgl->cgr->goccs + abs (repr);
16802 for (p = s->start; p < s->top; p++) {
16803 g = lglgidx2gat (lgl, *p);
16804 if (g->tag != ITETAG) continue;
16805 assert (g->size == 2);
16806 if (g->lhs != lhs) continue;
16807 if (!lglcgeq (lgl, g->cond, cond)) continue;
16808 if (!lglcgeq (lgl, g->pos, pos)) continue;
16809 if (!lglcgeq (lgl, g->neg, neg)) continue;
16817 static void lglnewitegate (LGL * lgl, int lhs, int cond, int pos, int neg) {
16820 lhs = lglcgreprnotconst (lgl, lhs);
16821 if (lhs < 0) lhs = -lhs, pos = -pos, neg = -neg;
16822 if ((pos < 0 && neg > 0) || (cond < 0 && lglsgn (pos) == lglsgn (neg))) {
16823 SWAP (int, pos, neg);
16826 cond = lglcgreprnotconst (lgl, cond);
16827 pos = lglcgreprnotconst (lgl, pos);
16828 neg = lglcgreprnotconst (lgl, neg);
16829 assert (abs (pos) != -abs (neg));
16830 if (lglhasitegate (lgl, lhs, cond, pos, neg)) return;
16831 g = lglnewgate (lgl, ITETAG, lhs, 2);
16832 gidx = lglgat2idx (lgl, g);
16833 g->cond = cond, g->pos = pos, g->neg = neg;
16834 lglpushgocc (lgl, cond, gidx);
16835 lglpushgocc (lgl, pos, gidx);
16836 lglpushgocc (lgl, neg, gidx);
16837 LOG (EL, "extracted ite gate %d = %d ? %d : %d", lhs, cond, pos, neg);
16838 lgl->stats->cgr.extracted.ite++;
16839 lgl->cgr->extracted.ite++;
16842 static int lglhasbingate (LGL * lgl, GTag tag, int lhs, int rhs0, int rhs1) {
16846 lhs = lglcgreprnotconst (lgl, lhs);
16847 rhs0 = lglcgreprnotconst (lgl, rhs0);
16848 rhs1 = lglcgreprnotconst (lgl, rhs1);
16849 s = lgl->cgr->goccs + abs (lhs);
16850 for (p = s->start; p < s->top; p++) {
16851 g = lglgidx2gat (lgl, *p);
16852 if (g->tag != tag) continue;
16853 if (g->size != 2) continue;
16854 if (g->lhs != lhs) continue;
16855 if (!lglcgeq (lgl, g->lits[0], rhs0)) continue;
16856 if (!lglcgeq (lgl, g->lits[1], rhs1)) continue;
16862 static int lglnewbingate (LGL * lgl, GTag tag, int lhs, int rhs0, int rhs1) {
16865 lhs = lglcgreprnotconst (lgl, lhs);
16866 rhs0 = lglcgreprnotconst (lgl, rhs0);
16867 rhs1 = lglcgreprnotconst (lgl, rhs1);
16868 if (abs (rhs0) > abs (rhs1)) SWAP (int, rhs0, rhs1);
16869 if (tag == XORTAG && lhs < 0) lhs = -lhs, rhs0 = -rhs0;
16870 if (tag == XORTAG && rhs0 < 0) rhs0 = -rhs0, rhs1 = -rhs1;
16871 if (lglhasbingate (lgl, tag, lhs, rhs0, rhs1)) return 0;
16872 g = lglnewgate (lgl, tag, lhs, 2);
16873 gidx = lglgat2idx (lgl, g);
16874 g->lits[0] = rhs0, g->lits[1] = rhs1;
16875 lglpushgocc (lgl, rhs0, gidx);
16876 lglpushgocc (lgl, rhs1, gidx);
16877 if (tag == ANDTAG) {
16878 lgl->cgr->extracted.and++;
16879 lgl->stats->cgr.extracted.and++;
16880 LOG (EL, "extracted binary and gate %d = %d & %d", lhs, -rhs0, -rhs1);
16881 } else if (tag == XORTAG) {
16882 lgl->cgr->extracted.xor++;
16883 lgl->stats->cgr.extracted.xor++;
16884 LOG (EL, "extracted binary xor gate %d = %d ^ %d", -lhs, rhs0, rhs1);
16889 static void lglnewlrgate (LGL * lgl, GTag tag, int lhs, int * cls, int size) {
16890 int gidx, other, lhsrepr;
16893 assert (size >= 3);
16894 lhsrepr = lglcgreprnotconst (lgl, lhs);
16895 g = lglnewgate (lgl, tag, lhsrepr, size);
16897 gidx = lglgat2idx (lgl, g);
16899 for (p = cls; (other = *p); p++) {
16900 if (abs (other) == lhs) continue;
16901 other = lglcgreprnotconst (lgl, other);
16902 lglpushgocc (lgl, other, gidx);
16904 if (tag == ANDTAG) lgl->cgr->extracted.and++, lgl->stats->cgr.extracted.and++;
16905 if (tag == XORTAG) lgl->cgr->extracted.xor++, lgl->stats->cgr.extracted.xor++;
16907 if (lgl->opts->log.val >= EL) {
16908 if (tag == ANDTAG) {
16910 lglogstart (lgl, EL, "extracted %d-ary and gate %d = ", size, lhsrepr);
16911 for (p = cls; (other = *p); p++) {
16912 if (abs (other) == abs (lhs)) continue;
16913 if (count++) fputs (" & ", lgl->out);
16914 fprintf (lgl->out, "%d", -lglcgrepr (lgl, other));
16917 } else if (tag == XORTAG) {
16919 lglogstart (lgl, EL, "extracted %d-ary xor gate %d = ", size, -lhs);
16920 for (p = cls; (other = *p); p++) {
16921 if (abs (other) == abs (lhs)) continue;
16922 if (count++) fputs (" ^ ", lgl->out);
16923 fprintf (lgl->out, "%d", lglcgrepr (lgl, other));
16931 static void lglcgmerge (LGL * lgl, int other, int repr) {
16932 int * p, * q, gidx;
16935 assert (lgl->cgrclosing);
16936 if (abs (other) == 1) SWAP (int, other, repr);
16937 if (repr == -1) other = -other, repr = 1;
16938 assert (lglcgrepr (lgl, other) == other);
16939 assert (abs (repr) != abs (other));
16941 assert (abs (other) >= 2);
16942 if (lgl->opts->drup.val) lgldrupclsarg (lgl, other, 0);
16943 #ifndef NLGLPICOSAT
16944 if (lgl->picosat.chk) lglpicosatchkclsarg (lgl, other, 0);
16946 if (other < 0) other = -other, repr = -repr;
16947 lgl->repr[other] = repr;
16948 lglwrktouch (lgl, other);
16950 assert (abs (repr) >= 2);
16951 assert (lglcgrepr (lgl, repr) == repr);
16952 if (lglcmprepr (lgl, other, repr) < 0) SWAP (int, repr, other);
16953 if (other < 0) other = -other, repr = -repr;
16954 lglimerge (lgl, other, repr);
16955 assert (0 < other);
16956 from = lgl->cgr->goccs + abs (other);
16957 to = lgl->cgr->goccs + abs (repr);
16959 for (p = q; p < to->top; p++) {
16960 g = lglgidx2gat (lgl, (gidx = *p));
16961 if (g->mark) continue;
16966 LOG (2, "merging %d gate occurrences of %d with %d occurrences of %d",
16967 lglcntstk (from), other, lglcntstk (to), repr);
16968 for (p = from->start; p < from->top; p++) {
16969 g = lglgidx2gat (lgl, (gidx = *p));
16970 if (g->mark) continue;
16972 lglpushstk (lgl, to, gidx);
16974 lglrelstk (lgl, from);
16975 for (p = to->start; p < to->top; p++) {
16976 g = lglgidx2gat (lgl, *p); assert (g->mark); g->mark = 0;
16978 lglwrktouch (lgl, repr);
16982 static int lglcmpocc (LGL * lgl, int a, int b) {
16983 return lglocc (lgl, a) - lglocc (lgl, b);
16986 #define LGLCMPOCC(A,B) lglcmpocc (lgl, *(A), *(B))
16988 static int lglcgextractlimhit (LGL * lgl) {
16989 return lgl->stats->cgr.esteps >= lgl->limits->cgr.esteps;
16992 static int lglincextractlimhit (LGL * lgl) {
16993 INCSTEPS (cgr.esteps);
16994 return lglcgextractlimhit (lgl);
16997 static int lglcgunit (LGL * lgl, int lit) {
16998 int next, repr, other, ok;
16999 Val val = lglval (lgl, lit);
17000 if (val > 0) return 1;
17002 LOG (1, "extracted unit already %d falsified", lit);
17007 lglunit (lgl, lit);
17008 if ((ok = lglbcp (lgl))) {
17009 while (next < lgl->next) {
17010 other = lglpeek (&lgl->trail, next++);
17011 repr = lglcgrepr (lgl, other);
17012 if (repr == 1) continue;
17013 if (repr == -1) { ok = 0; break; }
17014 assert (repr != -1);
17015 lglcgmerge (lgl, repr, 1);
17019 LOG (1, "propagation of congruence closure unit %d failed", lit);
17025 static int lglcgextractands (LGL * lgl, int lit) {
17026 int blit, tag, other, other2, lidx, size, tmp, repr;
17027 const int * p, * w, * eow, * l;
17031 if (!lgl->opts->cgrextand.val) return 1;
17032 repr = lglcgrepr (lgl, lit);
17033 if (lglval (lgl, lit)) { assert (abs (repr) == 1); return 1; }
17034 if (abs (repr) == 1) return 1;
17035 hts = lglhts (lgl, lit);
17036 w = lglhts2wchs (lgl, hts);
17037 eow = w + hts->count;
17038 for (p = w; p < eow; p++) {
17039 if (lglincextractlimhit (lgl)) return 0;
17041 tag = blit & MASKCS;
17042 if (tag == BINCS) {
17043 if (!lgl->opts->cgrexteq.val && !lgl->opts->cgrextunits.val) continue;
17044 tmp = blit >> RMSHFT;
17045 if ((val = lglval (lgl, tmp))) { assert (val > 0); continue; }
17046 repr = lglcgrepr (lgl, lit);
17047 other = lglcgrepr (lgl, -tmp);
17048 if (repr == other) continue;
17049 if (lglincextractlimhit (lgl)) return 0;
17050 if (lgl->opts->cgrextunits.val &&
17052 lglhasbin (lgl, lit, -tmp)) {
17053 LOG (EL, "extracted unit %d with %d %d and %d %d",
17054 lit, lit, tmp, lit, -tmp);
17055 lgl->cgr->extracted.units++;
17056 lgl->stats->cgr.units++;
17058 LOG (1, "extracted unit %d in conflict with previous unit %d",
17063 if (!lglcgunit (lgl, repr)) return 0;
17064 if (lglval (lgl, lit)) return 1;
17065 } else if (lgl->opts->cgrexteq.val && lglhasbin (lgl, -lit, -tmp)) {
17066 lgl->cgr->extracted.eq++;
17067 lgl->stats->cgr.eq++;
17068 LOG (EL, "extracted equivalence %d = %d with representatives %d = %d",
17069 lit, -tmp, repr, other);
17070 if (repr == -other) {
17072 LOG (1, "merging equivalence classes of opposite literals");
17076 lglcgmerge (lgl, other, repr);
17080 if (tag == TRNCS || tag == LRGCS) p++;
17081 if (tag == LRGCS) continue;
17082 if (tag == TRNCS) {
17083 other = blit >> RMSHFT;
17085 if (lglocc (lgl, other) > lglocc (lgl, other2)) SWAP (int, other, other2);
17086 if (lglincextractlimhit (lgl)) return 0;
17087 if (!lglhasbin (lgl, -lit, -other)) continue;
17088 if (lglincextractlimhit (lgl)) return 0;
17089 if (!lglhasbin (lgl, -lit, -other2)) continue;
17090 lglnewbingate (lgl, ANDTAG, lit, other, other2);
17092 assert (tag == OCCS);
17093 if (lglincextractlimhit (lgl)) return 0;
17094 assert (lglmtstk (&lgl->clause));
17095 lidx = blit >> RMSHFT;
17096 c = lglidx2lits (lgl, (blit & REDCS), lidx);
17097 for (l = c; (other = *l); l++)
17098 if (other != lit) lglpushstk (lgl, &lgl->clause, other);
17100 assert (size >= 3);
17101 SORT (int, lgl->clause.start, size, LGLCMPOCC);
17102 for (l = lgl->clause.start; l < lgl->clause.top; l++) {
17103 if (lglincextractlimhit (lgl)) { lglclnstk (&lgl->clause); return 0; }
17104 if (!lglhasbin (lgl, -lit, -*l)) break;
17106 if (l == lgl->clause.top) lglnewlrgate (lgl, ANDTAG, lit, c, size);
17107 lglclnstk (&lgl->clause);
17113 static int lglparity (LGL * lgl) {
17116 for (p = lgl->clause.start; p < lgl->clause.top; p++)
17117 if (*p < 0) res = !res;
17121 static void lglinclause (LGL * lgl, int parity) {
17123 assert (lglparity (lgl) == parity);
17125 for (p = lgl->clause.start; p < lgl->clause.top; p++)
17126 if ((*p = -*p) < 0) break;
17127 } while (lglparity (lgl) != parity);
17130 static int lglxorhascls (LGL * lgl) {
17131 int lit, res, minlit = 0, minoccs = INT_MAX, litoccs, blit, tag, lidx;
17132 const int * p, * w, * eow, * l, * c;
17134 for (p = lgl->clause.start; p < lgl->clause.top; p++) {
17136 litoccs = lglocc (lgl, lit);
17137 if (litoccs < minoccs) minlit = lit, minoccs = litoccs;
17138 lglsignedmark (lgl, lit);
17141 hts = lglhts (lgl, minlit);
17142 w = lglhts2wchs (lgl, hts);
17143 eow = w + hts->count;
17144 for (p = w; !res && p < eow; p++) {
17146 if (lglincextractlimhit (lgl)) { assert (!res); break; }
17147 tag = blit & MASKCS;
17148 if (tag == TRNCS || tag == LRGCS) p++;
17149 if (tag != OCCS) continue;
17150 lidx = blit >> RMSHFT;
17151 if (lglincextractlimhit (lgl)) { assert (!res); break; }
17152 c = lglidx2lits (lgl, (blit & REDCS), lidx);
17153 for (l = c; (lit = *l); l++) if (!lglsignedmarked (lgl, lit)) break;
17156 for (p = lgl->clause.start; p < lgl->clause.top; p++) lglunmark (lgl, *p);
17160 static int lglcgextractxors (LGL * lgl, int lit) {
17161 int blit, tag, other, other2, lidx, size, count, parity, * c;
17162 const int * p, * w, * eow, * l;
17164 if (!lgl->opts->cgrextxor.val) return 1;
17165 hts = lglhts (lgl, lit);
17166 w = lglhts2wchs (lgl, hts);
17167 eow = w + hts->count;
17168 for (p = w; p < eow; p++) {
17169 if (lglincextractlimhit (lgl)) return 0;
17171 tag = blit & MASKCS;
17172 if (tag == BINCS) continue;
17173 if (tag == TRNCS || tag == LRGCS) p++;
17174 if (tag == LRGCS) continue;
17175 if (tag == TRNCS) {
17176 if ((other = blit >> RMSHFT) < 0) continue;
17177 if ((other2 = *p) < 0) continue;
17178 INCSTEPS (cgr.esteps);
17179 if (!lglhastrn (lgl, lit, -other, -other2)) continue;
17180 INCSTEPS (cgr.esteps);
17181 if (!lglhastrn (lgl, -lit, other, -other2)) continue;
17182 INCSTEPS (cgr.esteps);
17183 if (!lglhastrn (lgl, -lit, -other, other2)) continue;
17184 lglnewbingate (lgl, XORTAG, lit, other, other2);
17186 assert (tag == OCCS);
17187 if (lglincextractlimhit (lgl)) return 0;
17188 assert (lglmtstk (&lgl->clause));
17189 lidx = blit >> RMSHFT;
17190 c = lglidx2lits (lgl, (blit & REDCS), lidx);
17191 for (l = c; (other = *l); l++) {
17192 if (other != lit && other < 0) break;
17193 lglpushstk (lgl, &lgl->clause, other);
17195 if (!other && (size = l - c - 1) <= lgl->opts->cgrmaxority.val) {
17196 assert (3 <= size && size <= 30);
17197 count = (1 << size);
17198 assert (count > 0);
17199 parity = (lit < 0);
17201 lglinclause (lgl, parity);
17202 INCSTEPS (cgr.esteps);
17203 if (!lglxorhascls (lgl)) break;
17208 lglinclause (lgl, parity);
17209 for (i = 0; i <= size; i++) assert (lgl->clause.start[i] == c[i]);
17211 lglnewlrgate (lgl, XORTAG, lit, c, size);
17214 lglclnstk (&lgl->clause);
17217 return !lglcgextractlimhit (lgl);
17220 static int lglcmpitecands (const ITEC * c, const ITEC * d) {
17221 int a = c->other, b = d->other;
17222 int res = abs (a) - abs (b);
17223 if (res) return res;
17224 if ((res = a - b)) return res;
17225 return c->other2 - d->other2;
17228 static int lglcgmergelhsrhs (LGL * lgl, int lhs, int rhs) {
17230 lhs = lglcgrepr (lgl, lhs);
17231 rhs = lglcgrepr (lgl, rhs);
17232 if (lhs == rhs) return 0;
17233 if (lhs == -rhs) conflict = 1;
17234 else if (lhs == 1) {
17235 if (rhs == -1) conflict = 1;
17236 else assert (rhs != 1), conflict = !lglcgunit (lgl, rhs);
17237 } else if (lhs == -1) {
17238 if (rhs == 1) conflict = 1;
17239 else assert (rhs != -1), conflict = !lglcgunit (lgl, -rhs);
17240 } else if (rhs == 1) conflict = !lglcgunit (lgl, lhs);
17241 else if (rhs == -1) conflict = !lglcgunit (lgl, -lhs);
17242 else lglcgmerge (lgl, lhs, rhs);
17246 static void lglcgextractitecands (LGL * lgl, int lhs, ITEC * cands, int ncands) {
17247 int cond, pos, neg;
17249 for (l = 0; l < ncands; l = r) {
17250 for (r = l + 1; r < ncands; r++)
17251 if (abs (cands[l].other) != abs (cands[r].other)) break;
17252 if (cands[l].other == cands[r-1].other) continue;
17253 assert (cands[l].other < 0);
17254 assert (cands[r-1].other > 0);
17255 assert (cands[l].other == -cands[r-1].other);
17256 for (m = l + 1; cands[m].other < 0; m++) assert (m + 1 < r);
17257 for (i = l; i + 1 < m; i++) assert (cands[i].other == cands[i+1].other);
17258 for (i = m; i + 1 < r; i++) assert (cands[i].other == cands[i+1].other);
17259 for (i = l; i < m; i++) {
17260 for (j = m; j < r; j++) {
17261 lhs = lglcgreprnotconst (lgl, lhs);
17262 INCSTEPS (cgr.esteps);
17263 cond = -cands[l].other;
17264 pos = -cands[l].other2;
17265 neg = -cands[m].other2;
17266 pos = lglcgreprnotconst (lgl, pos);
17267 neg = lglcgreprnotconst (lgl, neg);
17268 if (pos == -neg) continue; // skip XORTAGs
17270 if (lhs != pos && lglcgmergelhsrhs (lgl, lhs, pos)) return;
17271 } else lglnewitegate (lgl, lhs, cond, pos, neg);
17277 static int lglcgextractites (LGL * lgl, int lit) {
17278 int blit, tag, other, other2;
17279 ITEC * cands; int ncands;
17280 const int * p, * w, * eow;
17282 if (!lgl->opts->cgrextite.val) return 1;
17283 hts = lglhts (lgl, lit);
17284 w = lglhts2wchs (lgl, hts);
17285 eow = w + hts->count;
17286 for (p = w; p < eow; p++) {
17287 INCSTEPS (cgr.esteps);
17289 tag = blit & MASKCS;
17290 if (tag == BINCS || tag == OCCS) continue;
17292 if (tag == LRGCS) continue;
17293 assert (tag == TRNCS);
17294 other = blit >> RMSHFT;
17296 lglsignedmark (lgl, other);
17297 lglsignedmark (lgl, other2);
17299 assert (lglmtstk (&lgl->seen));
17300 for (p = w; p < eow; p++) {
17302 tag = blit & MASKCS;
17303 if (tag == BINCS || tag == OCCS) continue;
17305 if (tag == LRGCS) continue;
17306 INCSTEPS (cgr.esteps);
17307 assert (tag == TRNCS);
17308 other = blit >> RMSHFT;
17310 if (lglsignedmarked (lgl, -other)) {
17311 INCSTEPS (cgr.esteps);
17312 if (lglhastrn (lgl, -lit, other, -other2)) {
17313 lglpushstk (lgl, &lgl->seen, other);
17314 lglpushstk (lgl, &lgl->seen, other2);
17317 if (lglsignedmarked (lgl, -other2)) {
17318 INCSTEPS (cgr.esteps);
17319 if (lglhastrn (lgl, -lit, -other, other2)) {
17320 lglpushstk (lgl, &lgl->seen, other2);
17321 lglpushstk (lgl, &lgl->seen, other);
17325 for (p = w; p < eow; p++) {
17326 INCSTEPS (cgr.esteps);
17328 tag = blit & MASKCS;
17329 if (tag == BINCS || tag == OCCS) continue;
17331 if (tag == LRGCS) continue;
17332 assert (tag == TRNCS);
17333 other = blit >> RMSHFT;
17335 lglunmark (lgl, other);
17336 lglunmark (lgl, other2);
17338 if ((ncands = lglcntstk (&lgl->seen))) {
17339 cands = (ITEC *) lgl->seen.start;
17340 assert (!(ncands & 1));
17342 SORT (ITEC, cands, ncands, lglcmpitecands);
17343 lglcgextractitecands (lgl, lit, cands, ncands);
17345 lglclnstk (&lgl->seen);
17346 return !lglcgextractlimhit (lgl);
17349 static int lglcgextractidx (LGL * lgl, int idx) {
17350 if (!lglisfree (lgl, idx)) return 1;
17351 if (lglavar (lgl, idx)->donotcgrcls) return 1;
17352 if (lglcgextractlimhit (lgl)) return 0;
17353 if (lglterminate (lgl)) return 0;
17354 if (!lgl->mt && !lglcgextractands (lgl, idx)) return 0;
17355 if (!lgl->mt && !lglcgextractands (lgl, -idx)) return 0;
17356 if (!lgl->mt && !lglcgextractxors (lgl, idx)) return 0;
17357 if (!lgl->mt && !lglcgextractxors (lgl, -idx)) return 0;
17358 if (!lgl->mt && !lglcgextractites (lgl, idx)) return 0;
17359 if (!lgl->mt && !lglcgextractites (lgl, -idx)) return 0;
17363 static void lglgateextract (LGL * lgl) {
17365 LOG (EL, "starting new extraction %d", lgl->stats->cgr.count);
17366 lglrandidxtrav (lgl, lglcgextractidx);
17368 for (idx = 2; idx < lgl->nvars; idx++) count += lgl->avars[idx].gate;
17369 if (lgl->cgr->extracted.units)
17370 lglprt (lgl, 2, "[extract-%d] extracted %d units",
17371 lgl->stats->cgr.count, lgl->cgr->extracted.units);
17372 if (lgl->cgr->extracted.eq)
17373 lglprt (lgl, 2, "[extract-%d] extracted %d equivalences",
17374 lgl->stats->cgr.count, lgl->cgr->extracted.eq);
17375 if (lgl->cgr->extracted.all)
17377 "[extract-%d] extracted %d gates for %d variables %.0f%%",
17378 lgl->stats->cgr.count, lgl->cgr->extracted.all,
17379 count, lglpcnt (count, lgl->nvars));
17380 if (lgl->cgr->extracted.and)
17382 "[extract-%d] %d and gates %.0f%% of all extracted gates",
17383 lgl->stats->cgr.count,
17384 lgl->cgr->extracted.and, lglpcnt (lgl->cgr->extracted.and, lgl->cgr->extracted.all));
17385 if (lgl->cgr->extracted.xor)
17387 "[extract-%d] %d xor gates %.0f%% of all extracted gates",
17388 lgl->stats->cgr.count,
17389 lgl->cgr->extracted.xor, lglpcnt (lgl->cgr->extracted.xor, lgl->cgr->extracted.all));
17390 if (lgl->cgr->extracted.ite)
17392 "[extract-%d] %d ite gates %.0f%% of all extracted gates",
17393 lgl->stats->cgr.count,
17394 lgl->cgr->extracted.ite, lglpcnt (lgl->cgr->extracted.ite, lgl->cgr->extracted.all));
17397 static void lglprtcgrem (LGL * lgl) {
17398 int idx, ret = 0, rem = 0;
17399 for (idx = 2; idx < lgl->nvars; idx++) {
17400 if (!lglisfree (lgl, idx)) continue;
17401 if (lglavar (lgl, idx)->donotcgrcls) ret++; else rem++;
17404 lglprt (lgl, 1, "[cgrclsr-%d] %d variables remain %.0f%% (%d retained)",
17405 lgl->stats->cgr.count, rem, lglpcnt (rem, lglrem (lgl)), ret);
17407 lglprt (lgl, 1, "[cgrclsr-%d] fully completed congruence closure",
17408 lgl->stats->cgr.count);
17409 for (idx = 2; idx < lgl->nvars; idx++)
17410 lglavar (lgl, idx)->donotcgrcls = 0;
17414 static void lglcginit (LGL * lgl) {
17415 int idx, schedulable = 0, donotcgrcls = 0;
17416 for (idx = 2; idx < lgl->nvars; idx++) {
17417 if (!lglisfree (lgl, idx)) continue;
17418 if (lglavar (lgl, idx)->donotcgrcls) donotcgrcls++;
17419 else schedulable++;
17421 if (!schedulable) {
17423 for (idx = 2; idx < lgl->nvars; idx++) {
17424 if (!lglisfree (lgl, idx)) continue;
17425 lglavar (lgl, idx)->donotcgrcls = 0;
17430 lglprt (lgl, 1, "[cgrclsr-%d] all %d free variables schedulable",
17431 lgl->stats->cgr.count, schedulable);
17434 "[cgrclsr-%d] %d schedulable variables %.0f%%",
17435 lgl->stats->cgr.count, schedulable, lglpcnt (schedulable, lglrem (lgl)));
17436 lglwrkinit (lgl, 1, 1);
17437 assert (!lgl->donotsched), lgl->donotsched = 1;
17438 lglrandidxtrav (lgl, lglwrktouch);
17439 assert (lgl->donotsched), lgl->donotsched = 0;
17440 NEW (lgl->cgr->goccs, lgl->nvars);
17443 static void lglcgreset (LGL * lgl) {
17446 for (idx = 2; idx < lgl->nvars; idx++) lgl->avars[idx].donotcgrcls = 1;
17447 for (p = lgl->wrk->queue.start; p < lgl->wrk->queue.top; p++)
17448 lgl->avars[abs (*p)].donotcgrcls = 0;
17450 for (idx = 2; idx < lgl->nvars; idx++) lgl->avars[idx].gate = 0;
17451 for (idx = 2; idx < lgl->nvars; idx++) lglrelstk (lgl, lgl->cgr->goccs + idx);
17452 DEL (lgl->cgr->goccs, lgl->nvars);
17453 DEL (lgl->cgr->gates, lgl->cgr->szgates);
17454 lgl->cgr->szgates = 0;
17457 static void lglsetbinminrhs (LGL * lgl, Gat * g) {
17458 int a = lglcgrepr (lgl, g->lits[0]);
17459 int b = lglcgrepr (lgl, g->lits[1]);
17460 assert (g->size == 2);
17461 assert (g->tag != ITETAG);
17462 if (abs (a) == 1 && abs (b) == 1) g->minrhs = INT_MAX;
17463 else if (abs (a) == 1) g->minrhs = b;
17464 else if (abs (b) == 1) g->minrhs = a;
17465 else g->minrhs = (abs (a) < abs (b)) ? a : b;
17468 static void lglsetlrgminrhs (LGL * lgl, Gat * g) {
17470 assert (g->size >= 3);
17471 g->minrhs = INT_MAX;
17472 for (p = g->cls; (other = *p); p++) {
17473 if (abs (other) == abs (g->lhs)) continue;
17474 other = lglcgrepr (lgl, other);
17475 if (abs (other) == 1) continue;
17476 if (abs (g->minrhs) > abs (other)) g->minrhs = other;
17478 assert (g->minrhs);
17481 static void lglsetiteminrhs (LGL * lgl, Gat * g) {
17482 assert (g->tag == ITETAG);
17483 g->minrhs = lglcgrepr (lgl, g->cond);
17486 static void lglsetminrhs (LGL * lgl, Gat * g) {
17487 if (g->tag == ITETAG) lglsetiteminrhs (lgl, g);
17488 else if (g->size == 2) lglsetbinminrhs (lgl, g);
17489 else lglsetlrgminrhs (lgl, g);
17490 if (g->tag != ANDTAG && g->minrhs < 0) g->minrhs = -g->minrhs;
17493 static int lglcmpgoccs (LGL * lgl, int a, int b) {
17494 Gat * g = lglgidx2gat (lgl, a);
17495 Gat * h = lglgidx2gat (lgl, b);
17496 int res = (g->tag - h->tag); if (res) return res;
17497 if ((res = (g->size - h->size))) return res;
17498 if ((res = g->minrhs - h->minrhs)) return res;
17502 #define LGLCMPGOCCS(A,B) lglcmpgoccs (lgl, *(A), *(B))
17504 static int lglgoccsmatchcand (LGL * lgl, int a, int b) {
17505 Gat * g = lglgidx2gat (lgl, a);
17506 Gat * h = lglgidx2gat (lgl, b);
17507 return g->tag == h->tag && g->size == h->size && g->minrhs == h->minrhs;
17510 static int lglmatchitegate (LGL * lgl, Gat * g, Gat * h) {
17511 int gc = lglcgrepr (lgl, g->cond);
17512 int gp = lglcgrepr (lgl, g->pos);
17513 int gn = lglcgrepr (lgl, g->neg);
17514 int hc = lglcgrepr (lgl, h->cond);
17515 int hp = lglcgrepr (lgl, h->pos);
17516 int hn = lglcgrepr (lgl, h->neg);
17517 assert (g->tag == ITETAG);
17518 assert (g->size == 2);
17519 INCSTEPS (cgr.csteps);
17521 if (hc == 1 && gp == hp) return 1;
17522 if (hc == -1 && gp == hn) return 1;
17523 } else if (gc == -1) {
17524 if (hc == 1 && gn == hp) return 1;
17525 if (hc == -1 && gn == hn) return 1;
17526 } else if (gc == hc) {
17527 if (gp == hp && gn == hn) return 1;
17528 if (gp == -hp && gn == -hn) return -1;
17529 } else if (gc == -hc) {
17530 if (gp == hn && gn == hp) return 1;
17531 if (gp == -hn && gn == -hp) return -1;
17536 static int lglmatchbingate (LGL * lgl, Gat * g, Gat * h) {
17537 int g0 = lglcgrepr (lgl, g->lits[0]);
17538 int g1 = lglcgrepr (lgl, g->lits[1]);
17539 int h0 = lglcgrepr (lgl, h->lits[0]);
17540 int h1 = lglcgrepr (lgl, h->lits[1]);
17542 INCSTEPS (cgr.csteps);
17543 assert (g->size == 2);
17544 if (g->tag == XORTAG) {
17546 if (g0 < 0) sign = -sign, g0 = -g0;
17547 if (g1 < 0) sign = -sign, g1 = -g1;
17548 if (h0 < 0) sign = -sign, h0 = -h0;
17549 if (h1 < 0) sign = -sign, h1 = -h1;
17551 if (g0 == h0 && g1 == h1) return sign;
17552 if (g0 == h1 && g1 == h0) return sign;
17556 static int lglmatchlrgandaux (LGL * lgl, Gat * g, Gat * h) {
17557 int * p, other, repr, bit, res, jumped, gfalse, gtrue, htrue, hfalse;
17560 assert (g->tag == ANDTAG);
17562 gtrue = 1, gfalse = 0;
17564 for (p = g->cls; (other = *p); p++) {
17565 INCSTEPS (cgr.csteps);
17566 if (abs (other) == abs (g->origlhs)) {
17567 assert (other == g->origlhs);
17571 repr = lglcgrepr (lgl, -other);
17572 if (repr == -1) { gfalse = 1; break; }
17573 if (repr == 1) continue;
17575 if (repr != other) jumped = -1;
17576 u = lglavar (lgl, repr);
17577 bit = 1 << (repr < 0);
17578 if (u->mark & (bit^3)) gfalse = 1;
17579 if (u->mark & bit) continue;
17582 assert (other || found);
17584 htrue = 1, hfalse = 0;
17586 for (p = h->cls; res && (other = *p); p++) {
17587 if (abs (other) == abs (h->origlhs)) {
17589 assert (other == h->origlhs);
17592 repr = lglcgrepr (lgl, -other);
17593 if (repr == -1) { hfalse = 1; break; }
17594 if (repr == 1) continue;
17596 if (repr != other) jumped = -1;
17597 u = lglavar (lgl, repr);
17598 bit = 1 << (repr < 0);
17599 if (!(u->mark & bit)) res = 0;
17601 assert (!res || other || found);
17603 for (p = g->cls; (other = *p); p++) {
17604 if (abs (other) == abs (g->origlhs)) { found++; continue; }
17605 repr = lglcgrepr (lgl, other);
17606 if (abs (repr) == 1) continue;
17607 u = lglavar (lgl, repr);
17612 lglcgmergelhsrhs (lgl, g->lhs, -1);
17614 } else if (res && gtrue) {
17615 lglcgmergelhsrhs (lgl, g->lhs, 1);
17619 lglcgmergelhsrhs (lgl, h->lhs, -1);
17621 } else if (htrue) {
17622 lglcgmergelhsrhs (lgl, h->lhs, 1);
17625 return jumped * res;
17628 static int lglmatchlrgand (LGL * lgl, Gat * g, Gat * h) {
17629 int res = lglmatchlrgandaux (lgl, g, h);
17630 if (res >= 0) return res;
17631 res = lglmatchlrgandaux (lgl, h, g);
17635 static int lglmatchlrgxor (LGL * lgl, Gat * g, Gat * h) {
17636 int * p, other, repr, res, gconst, hconst, hpar, gpar, sign, found;
17638 gconst = 1, gpar = -1;
17641 for (p = g->cls; (other = *p); p++) {
17642 INCSTEPS (cgr.csteps);
17643 if (abs (other) == abs (g->origlhs)) {
17644 assert (other == g->origlhs);
17648 repr = lglcgrepr (lgl, other);
17649 if (repr < 0) sign = -sign, gpar = -gpar;
17650 if (abs (repr) == 1) continue;
17652 u = lglavar (lgl, repr);
17653 u->mark = !u->mark;
17656 hconst = 1, hpar = -1;
17658 for (p = h->cls; (other = *p); p++) {
17659 if (abs (other) == abs (h->origlhs)) {
17660 assert (other == h->origlhs);
17664 repr = lglcgrepr (lgl, other);
17665 if (abs (repr) != 1) hconst = 0;
17666 if (repr < 0) sign = -sign, hpar = -hpar;
17667 if (abs (repr) == 1) continue;
17669 u = lglavar (lgl, repr);
17670 u->mark = !u->mark;
17675 for (p = g->cls; (other = *p); p++) {
17676 if (abs (other) == abs (g->origlhs)) { found++; continue; }
17677 repr = lglcgrepr (lgl, other);
17678 if (abs (repr) == 1) continue;
17679 u = lglavar (lgl, repr);
17680 if (!u->mark) continue;
17686 for (p = h->cls; (other = *p); p++) {
17687 if (abs (other) == abs (h->origlhs)) { found++; continue; }
17688 repr = lglcgrepr (lgl, other);
17689 if (abs (repr) == 1) continue;
17690 u = lglavar (lgl, repr);
17691 if (!u->mark) continue;
17697 lglcgmergelhsrhs (lgl, g->lhs, gpar);
17701 lglcgmergelhsrhs (lgl, h->lhs, hpar);
17707 static int lglmatchgate (LGL * lgl, int fixed, Gat * g, Gat * h) {
17708 int l = lglcgrepr (lgl, g->lhs);
17709 int k = lglcgrepr (lgl, h->lhs);
17710 int repr, other, s;
17712 INCSTEPS (cgr.csteps);
17713 assert (g->tag == h->tag);
17714 assert (g->size == h->size);
17715 assert (g->minrhs == h->minrhs);
17716 assert (g->size >= 2);
17717 if (g->tag == ITETAG) { if (!(s = lglmatchitegate (lgl, g, h))) return 0; }
17718 else if (g->size == 2) { if (!(s = lglmatchbingate (lgl, g, h))) return 0; }
17719 else if (g->tag == ANDTAG) { if (!(s = lglmatchlrgand (lgl, g, h))) return 0; }
17720 else if (g->tag == XORTAG) { if (!(s = lglmatchlrgxor (lgl, g, h))) return 0; }
17722 repr = s*l, other = k;
17723 if (repr == other) return 0;
17724 lgl->stats->cgr.matched.all++;
17725 lgl->cgr->matched.all++;
17726 if (g->tag == ANDTAG) lgl->cgr->matched.and++, lgl->stats->cgr.matched.and++;
17727 if (g->tag == XORTAG) lgl->cgr->matched.xor++, lgl->stats->cgr.matched.xor++;
17728 if (g->tag == ITETAG) lgl->cgr->matched.ite++, lgl->stats->cgr.matched.ite++;
17729 if (repr == -other) {
17731 LOG (1, "gate match to same literal only differing in sign");
17735 LOG (1, "gates with lhs %d and %d match", g->lhs, h->lhs);
17736 lglcgmerge (lgl, other, repr);
17737 if (abs (fixed) == abs (other)) return 1;
17738 if (abs (fixed) == abs (repr)) return 1;
17742 static int lglcgrlimhit (LGL * lgl) {
17743 return lgl->stats->cgr.csteps >= lgl->limits->cgr.csteps;
17746 static int lglsimpbinand (LGL * lgl, Gat * g) {
17747 int lhs, a, b, res, conflict;
17748 assert (g->tag == ANDTAG && g->size == 2);
17749 lhs = lglcgrepr (lgl, g->lhs);
17750 a = lglcgrepr (lgl, -g->lits[0]);
17751 b = lglcgrepr (lgl, -g->lits[1]);
17752 conflict = res = 0;
17753 if (a == 1 && b == 1) {
17754 if (lhs == 1) return 0;
17756 LOG (2, "binary and gate with lhs %d simplified to true", g->lhs);
17757 if (lhs == -1) conflict = 1; else conflict = !lglcgunit (lgl, lhs);
17758 } else if (a == -1 || b == -1 || a == -b) {
17759 if (lhs == -1) return 0;
17761 LOG (2, "binary and gate with lhs %d simplified to false", g->lhs);
17762 if (lhs == 1) conflict = 1; else conflict = !lglcgunit (lgl, -lhs);
17764 if (b == 1) SWAP (int, a, b);
17766 if (lhs == b) return 0;
17768 LOG (2, "binary and gate with lhs %d simplifies to %d", g->lhs, b);
17769 if (lhs == -b) conflict = 1; else lglcgmerge (lgl, lhs, b);
17773 lgl->cgr->simplified.all++;
17774 lgl->stats->cgr.simplified.all++;
17775 lgl->cgr->simplified.and++;
17776 lgl->stats->cgr.simplified.and++;
17780 "simplifying binary and gate with lhs %d leads to conflict", g->lhs);
17787 static int lglsimplrgand (LGL * lgl, Gat * g) {
17788 int * p, lhs, other, repr, conflict, res, foundfalse, rhs, bit, found;
17790 assert (g->tag == ANDTAG && g->size > 2);
17791 lhs = lglcgrepr (lgl, g->lhs);
17792 rhs = foundfalse = 0;
17794 for (p = g->cls; !foundfalse && (other = *p); p++) {
17795 if (other == g->origlhs) { found++; continue; }
17796 INCSTEPS (cgr.csteps);
17797 repr = lglcgrepr (lgl, -other);
17798 if (repr == 1) continue;
17799 if (repr == -1) { foundfalse = 1; break; }
17800 if (rhs) rhs = INT_MAX; else { assert (repr); rhs = repr; }
17801 u = lglavar (lgl, repr);
17802 bit = (1 << (repr < 0));
17803 if (u->mark & bit) continue;
17804 if (u->mark & (bit^3)) { foundfalse = 1; break; }
17807 assert (foundfalse || found);
17808 for (p = g->cls; (other = *p); p++) {
17809 if (other == g->origlhs) continue;
17810 repr = lglcgrepr (lgl, other);
17811 if (abs (repr) == 1) continue;
17812 lglavar (lgl, repr)->mark = 0;
17814 conflict = res = 0;
17818 LOG (2, "gate with lhs %d simplifies to false", g->lhs);
17819 if (lhs == 1) conflict = 1; else conflict = !lglcgunit (lgl, -lhs);
17824 LOG (2, "large and gate with lhs %d simplifies to true", g->lhs);
17825 if (lhs == -1) conflict = 1; else conflict = !lglcgunit (lgl, lhs);
17827 } else if (rhs != INT_MAX) {
17830 LOG (2, "large and gate with lhs %d simplifies to %d", g->lhs, rhs);
17831 if (lhs == -rhs) conflict = 1; else lglcgmerge (lgl, lhs, rhs);
17835 lgl->cgr->simplified.all++;
17836 lgl->stats->cgr.simplified.all++;
17837 lgl->cgr->simplified.and++;
17838 lgl->stats->cgr.simplified.and++;
17842 "simplifying large and gate with lhs %d leads to conflict", g->lhs);
17849 static int lglsimpand (LGL * lgl, Gat * g) {
17850 assert (g->tag == ANDTAG);
17851 if (g->size == 2) return lglsimpbinand (lgl, g);
17852 else return lglsimplrgand (lgl, g);
17855 static int lglsimpbinxor (LGL * lgl, Gat * g) {
17856 int res, conflict, lhs, rhs, a, b;
17857 assert (g->size == 2);
17858 assert (g->tag == XORTAG);
17859 lhs = -lglcgrepr (lgl, g->lhs);
17860 a = lglcgrepr (lgl, g->lits[0]);
17861 b = lglcgrepr (lgl, g->lits[1]);
17862 rhs = conflict = res = 0;
17863 if (a == b) rhs = -1;
17864 else if (a == -b) rhs = 1;
17865 else if (a == 1) rhs = -b;
17866 else if (a == -1) rhs = b;
17867 else if (b == 1) rhs = -a;
17868 else if (b == -1) rhs = a;
17869 else if (lhs == 1) lhs = a, rhs = -b;
17870 else if (lhs == -1) lhs = a, rhs = b;
17871 if (rhs && rhs != lhs) res = 1;
17873 LOG (2, "simplified binary xor gate with lhs %d", g->lhs);
17875 assert (lhs != rhs);
17876 lgl->cgr->simplified.all++;
17877 lgl->stats->cgr.simplified.all++;
17878 lgl->cgr->simplified.xor++;
17879 lgl->stats->cgr.simplified.xor++;
17880 conflict = lglcgmergelhsrhs (lgl, lhs, rhs);
17884 "simplifying binary xor gate with lhs %d leads to conflict", g->lhs);
17891 static int lglsimplrgxor (LGL * lgl, Gat * g) {
17892 int conflict, lhs, rhs, other, repr, * p, found;
17893 assert (g->size > 2);
17894 assert (g->tag == XORTAG);
17895 lhs = -lglcgrepr (lgl, g->lhs);
17898 for (p = g->cls; (other = *p); p++) {
17899 if (other == g->origlhs) { found++; continue; }
17900 repr = lglcgrepr (lgl, other);
17901 if (repr == -1) continue;
17902 else if (repr == 1) rhs = -rhs;
17903 else if (repr == rhs) rhs = -1;
17904 else if (repr == lhs) lhs = -1;
17905 else if (repr == -lhs) lhs = 1;
17906 else if (lhs == -1) lhs = repr;
17907 else if (lhs == 1) lhs = -repr;
17908 else if (abs (rhs) != 1) return 0;
17909 else if (rhs == -1) rhs = repr;
17910 else { assert (rhs == 1); rhs = -repr; }
17913 if (lhs == rhs) return 0;
17914 LOG (2, "simplified large xor gate with lhs %d", g->lhs);
17915 assert (lhs != rhs);
17916 lgl->cgr->simplified.all++;
17917 lgl->stats->cgr.simplified.all++;
17918 lgl->cgr->simplified.xor++;
17919 lgl->stats->cgr.simplified.xor++;
17920 conflict = lglcgmergelhsrhs (lgl, lhs, rhs);
17923 "simplifying large xor gate with lhs %d leads to conflict", g->lhs);
17929 static int lglsimpxor (LGL * lgl, Gat * g) {
17930 assert (g->tag == XORTAG);
17931 if (g->size == 2) return lglsimpbinxor (lgl, g);
17932 else return lglsimplrgxor (lgl, g);
17935 static int lglsimpite (LGL * lgl, Gat * g) {
17937 int lhs = lglcgrepr (lgl, glhs);
17938 int gc = lglcgrepr (lgl, g->cond);
17939 int gp = lglcgrepr (lgl, g->pos);
17940 int gn = lglcgrepr (lgl, g->neg);
17941 int res, conflict, rhs, gate;
17942 assert (g->tag == ITETAG);
17943 assert (g->size == 2);
17944 gate = rhs = conflict = res = 0;
17945 if (gc == 1 || gp == gn) res = 1, rhs = gp;
17946 else if (gc == -1) res = 1, rhs = gn;
17947 else if (gp == 1 && gn == -1) res = 1, rhs = gc;
17948 else if (gp == -1 && gn == 1) res = 1, rhs = -gc;
17949 else if (gn == -1 || gc == gn) {
17950 // (lhs = gc ? gp : -1) => lhs = gc & gp
17951 // (lhs = gc ? gp : gc) => lhs = gc & gp
17952 // COVER ("simplified ite to 'gc & gp'");
17953 if (gp == 1) res = 1, rhs = gc;
17954 else if (gp == -1) {
17955 assert (gn != -1 && gc == gn);
17958 res = lglnewbingate (lgl, ANDTAG, glhs, -gc, -gp);
17961 } else if (gp == -1 || gc == -gp) {
17962 // (lhs = gc ? -1 : gn) => lhs = -gc & gn
17963 // (lhs = gc ? -gc : gn) => lhs = -gc & gn
17964 // COVER ("simplified ite to '-gc & gn'");
17966 if (gn == 1) res = 1, rhs = -gc;
17969 res = lglnewbingate (lgl, ANDTAG, glhs, gc, -gn);
17972 } else if (gp == 1 || gc == gp) {
17973 // (lhs = gc ? 1 : gn) => lhs = gc | gn
17974 // (lhs = gc ? gp : gn) => lhs = gc | gn
17975 // COVER ("simplified ite to 'gc | gn'");
17976 if (gn == 1) res = 1, rhs = 1;
17979 res = lglnewbingate (lgl, ANDTAG, -glhs, gc, gn);
17982 } else if (gn == 1 || gc == -gn) {
17983 // (lhs = gc ? gp : 1) => lhs = gc gp | -gc = gp | -gc
17984 // (lhs = gc ? gp : -gc) => lhs = gc gp | -gc = gp | -gc
17985 // COVER ("simplified ite to 'gp | -gc'");
17986 if (gp == 1) res = 1, rhs = 1;
17989 res = lglnewbingate (lgl, ANDTAG, -glhs, gp, -gc);
17992 } else if (gp == -gn) {
17993 // (lhs = gc ? -gn : gn) => lhs = gc&-gn | -gc&gn = gc ^ gn
17994 // COVER ("simplified ite to 'gc ^ gn'");
17995 res = lglnewbingate (lgl, XORTAG, -glhs, gc, gn);
17998 if (res && !gate && lhs == rhs) res = 0;
17999 if (res && (gate || lhs != rhs)) {
18000 LOG (2, "simplified ite gate with lhs %d", glhs);
18001 lgl->cgr->simplified.all++;
18002 lgl->stats->cgr.simplified.all++;
18003 lgl->cgr->simplified.ite++;
18004 lgl->stats->cgr.simplified.ite++;
18007 assert (lhs != rhs);
18008 if (lhs != rhs) conflict = lglcgmergelhsrhs (lgl, lhs, rhs);
18013 LOG (1, "simplifying ite gate with lhs %d leads to conflict", glhs);
18020 static int lglsimpgate (LGL * lgl, Gat * g) {
18021 if (g->tag == ANDTAG) return lglsimpand (lgl, g);
18022 else if (g->tag == ITETAG) return lglsimpite (lgl, g);
18023 else { assert (g->tag == XORTAG); return lglsimpxor (lgl, g); }
18026 static void lglcgrlit (LGL * lgl, int lit) {
18027 int * p, * q, * l, * r, round;
18032 if (lgl->mt) return;
18033 goccs = lgl->cgr->goccs + abs (lit);
18034 if (lglmtstk (goccs)) return;
18036 LOG (2, "simplifying gates with lhs %d", lit);
18037 for (l = goccs->start; !lgl->mt && l < goccs->top; l++) {
18038 INCSTEPS (cgr.csteps);
18039 if (lglcgrlimhit (lgl)) return;
18040 g = lglgidx2gat (lgl, *l);
18041 if (lglsimpgate (lgl, g)) goto RESTART;// goccs->start moves
18044 "checking congruences of %d gates with rhs %d round %d",
18045 lglcntstk (goccs), lit, round);
18046 for (p = goccs->start; p < goccs->top; p++) {
18047 INCSTEPS (cgr.csteps);
18048 if (lglcgrlimhit (lgl)) return;
18049 g = lglgidx2gat (lgl, *p);
18050 lglsetminrhs (lgl, g);
18052 SORT (int, goccs->start, lglcntstk (goccs), LGLCMPGOCCS);
18053 q = goccs->start + 1;
18054 for (p = q; p < goccs->top; p++) if (*p != q[-1]) *q++ = *p;
18056 for (l = goccs->start; !lgl->mt && l < goccs->top; l = r) {
18057 INCSTEPS (cgr.csteps);
18058 if (lglcgrlimhit (lgl)) return;
18059 for (r = l + 1; r < goccs->top && lglgoccsmatchcand (lgl, *l, *r); r++)
18061 for (p = l; !lgl->mt && p + 1 < r; p++) {
18062 g = lglgidx2gat (lgl, *p);
18063 if (abs (lglcgrepr (lgl, g->lhs)) == 1) continue;
18064 for (q = p + 1; !lgl->mt && q < r; q++) {
18065 // if (lglsimpgate (lgl, g)) goto RESTART;// goccs->start moves
18066 h = lglgidx2gat (lgl, *q);
18067 if (abs (lglcgrepr (lgl, h->lhs)) == 1) continue;
18068 if (lglsimpgate (lgl, h)) goto RESTART;// goccs->start moves
18069 if (lglmatchgate (lgl, lit, g, h)) goto RESTART;// goccs->start moves
18075 static void lglclsr (LGL * lgl) {
18078 !lglterminate (lgl) &&
18079 (lit = lglwrknext (lgl)) &&
18080 !lglcgrlimhit (lgl)) {
18081 lglcgrlit (lgl, lit);
18082 if (!lgl->mt && !lglcgrlimhit (lgl)) lglcgrlit (lgl, -lit);
18085 if (lgl->cgr->simplified.all)
18086 lglprt (lgl, 2, "[closure-%d] simplified %d gates",
18087 lgl->stats->cgr.count, lgl->cgr->simplified.all);
18088 if (lgl->cgr->simplified.and)
18089 lglprt (lgl, 2, "[closure-%d] simplified %d and gates",
18090 lgl->stats->cgr.count, lgl->cgr->simplified.and);
18091 if (lgl->cgr->simplified.xor)
18092 lglprt (lgl, 2, "[closure-%d] simplified %d xor gates",
18093 lgl->stats->cgr.count, lgl->cgr->simplified.xor);
18094 if (lgl->cgr->simplified.ite)
18095 lglprt (lgl, 2, "[closure-%d] simplified %d ite gates",
18096 lgl->stats->cgr.count, lgl->cgr->simplified.ite);
18098 if (lgl->cgr->matched.all)
18099 lglprt (lgl, 2, "[closure-%d] matched %d gates",
18100 lgl->stats->cgr.count, lgl->cgr->matched.all);
18101 if (lgl->cgr->matched.and)
18102 lglprt (lgl, 2, "[closure-%d] matched %d and gates %.0f%%",
18103 lgl->stats->cgr.count, lgl->cgr->matched.and,
18104 lglpcnt (lgl->cgr->matched.and, lgl->cgr->matched.all));
18105 if (lgl->cgr->matched.xor)
18106 lglprt (lgl, 2, "[closure-%d] matched %d xor gates %.0f%%",
18107 lgl->stats->cgr.count, lgl->cgr->matched.xor,
18108 lglpcnt (lgl->cgr->matched.xor, lgl->cgr->matched.all));
18109 if (lgl->cgr->matched.ite)
18110 lglprt (lgl, 2, "[closure-%d] matched %d ite gates %.0f%%",
18111 lgl->stats->cgr.count, lgl->cgr->matched.ite,
18112 lglpcnt (lgl->cgr->matched.ite, lgl->cgr->matched.all));
18115 static int lgladdunits (LGL * lgl) {
18116 int idx, lit, repr;
18119 assert (lglmtstk (&lgl->cgr->units));
18120 for (idx = 2; idx < lgl->nvars; idx++) {
18121 repr = lglcgrepr (lgl, idx);
18122 if (abs (repr) >= 2) continue;
18123 lit = (repr > 0) ? idx : -idx;
18124 val = lglval (lgl, lit);
18125 if (val > 0) continue;
18127 LOG (1, "inconsistent congruence closure unit %d", lit);
18131 LOG (1, "adding congruence closure unit %d", lit);
18132 lglpushstk (lgl, &lgl->cgr->units, lit);
18137 static int lglpropunits (LGL * lgl) {
18141 assert (!lgl->level);
18142 while (!lglmtstk (&lgl->cgr->units)) {
18143 lit = lglpopstk (&lgl->cgr->units);
18144 val = lglcval (lgl, lit);
18145 if (val > 0) continue;
18147 LOG (1, "inconsistent congruence closure unit %d", lit);
18150 LOG (1, "assigning congruence closure unit %d", lit);
18151 lglunitnocheck (lgl, lit);
18152 #if !defined(NLGLPICOSAT) && !defined(NDEBUG)
18154 int cls[2]; cls[0] = lit; cls[1] = 0;
18155 lglpicosataddcls (lgl, cls);
18158 if (lglbcp (lgl)) continue;
18159 LOG (1, "conflict after assigning congruence closure unit %d", lit);
18166 static void lglsetcgrclsrlim (LGL * lgl) {
18167 int64_t limit, irrlim;
18169 limit = (lgl->opts->cgreleff.val*lglvisearch (lgl))/1000;
18170 if (limit < lgl->opts->cgrmineff.val) limit = lgl->opts->cgrmineff.val;
18171 if (lgl->opts->cgrmaxeff.val >= 0 && limit > lgl->opts->cgrmaxeff.val)
18172 limit = lgl->opts->cgrmaxeff.val;
18173 limit >>= (pen = lgl->limits->cgr.pen + lglszpen (lgl));
18174 irrlim = lgl->stats->irr.clauses.cur/2;
18175 irrlim >>= lgl->limits->simp.pen;
18176 if (lgl->opts->irrlim.val && limit < irrlim) {
18179 "[cgrclsr-%d] limit %lld based on %d irredundant clauses",
18180 lgl->stats->cgr.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
18182 lglprt (lgl, 1, "[cgrclsr-%d] limit %lld penalty %d = %d + %d",
18183 lgl->stats->cgr.count, (LGLL) limit,
18184 pen, lgl->limits->cgr.pen, lglszpen (lgl));
18185 lgl->limits->cgr.esteps = lgl->stats->cgr.esteps + limit;
18186 lgl->limits->cgr.csteps = lgl->stats->cgr.csteps + 2*limit;
18189 static int lglcgrclsr (LGL * lgl) {
18190 int nvars, oldrem, removed;
18192 assert (lgl->opts->cgrclsr.val);
18193 assert (lglsmallirr (lgl));
18194 assert (!lgl->cgrclosing && !lgl->simp);
18196 lglstart (lgl, &lgl->times->cgr);
18198 oldrem = lglrem (lgl);
18200 lgl->stats->cgr.count++;
18201 lgl->cgrclosing = lgl->simp = 1;
18205 if (lgl->level > 0) lglbacktrack (lgl, 0);
18208 assert (lgl->frozen);
18211 nvars = lgl->nvars;
18212 NEW (lgl->repr, nvars);
18214 lglsetcgrclsrlim (lgl);
18217 lglgateextract (lgl);
18218 if (!lgl->mt) lglclsr (lgl);
18222 if (lgl->mt) goto DONE;
18223 if (!lgladdunits (lgl)) { assert (lgl->mt); goto DONE; }
18230 if (lgl->mt) goto DONE;
18231 if (!lglbcp (lgl)) goto DONE;
18232 if (!lglpropunits (lgl)) { assert (lgl->mt); goto DONE; }
18235 if (lgl->mt) goto DONE;
18236 if (!lgl->mt) { lglpicosatchkall (lgl); lglpicosatrestart (lgl); }
18240 lglrelstk (lgl, &lgl->cgr->units);
18241 if (lgl->repr) { assert (lgl->mt); DEL (lgl->repr, nvars); }
18242 removed = oldrem - lglrem (lgl);
18243 LGLUPDPEN (cgr, removed);
18245 assert (lgl->simp && lgl->cgrclosing);
18246 lgl->cgrclosing = lgl->simp = 0;
18248 lglprt (lgl, 1 + !removed,
18249 "[cgrclsr-%d] removed %d variables", lgl->stats->cgr.count, removed);
18250 lglrep (lgl, 2, 'C');
18255 static int lglrandomprobe (LGL * lgl, Stk * outer) {
18256 unsigned pos, delta, mod, first;
18258 mod = lglcntstk (outer);
18259 if (!mod) return 0;
18260 first = pos = lglrand (lgl) % mod;
18261 res = lglpeek (outer, pos);
18262 if (!lglval (lgl, res)) return res;
18263 if (mod == 1) return 0;
18264 delta = lglrand (lgl) % mod;
18265 if (!delta) delta++;
18266 while (lglgcd (delta, mod) != 1)
18267 if (++delta == mod) { delta = 1; break; }
18268 assert (1 <= delta && delta < mod);
18271 if (pos >= mod) pos -= mod;
18272 assert (0 <= pos && pos < mod);
18273 if (pos == first) break;
18274 res = lglpeek (outer, pos);
18275 if (!lglval (lgl, res)) return res;
18280 static int lglinnerprobe (LGL * lgl, int old, Stk * outer,
18281 Stk * tmp1, Stk * tmp2) {
18282 int i, lit, blit, tag, other, other2, red, lidx, res, val, count;
18283 const int * w, * eow, * p, * c, * q;
18285 assert (old < lglcntstk (&lgl->trail));
18286 assert (!tmp2 || lglmtstk (tmp2));
18287 for (p = tmp1->start; p < tmp1->top; p++) {
18288 assert (!lglmarked (lgl, *p));
18291 for (i = old; i < lglcntstk (&lgl->trail); i++) {
18292 lit = lglpeek (&lgl->trail, i);
18293 hts = lglhts (lgl, -lit);
18294 w = lglhts2wchs (lgl, hts);
18295 eow = w + hts->count;
18296 for (p = w; p < eow; p++) {
18298 tag = blit & MASKCS;
18299 if (tag == TRNCS || tag == LRGCS) p++;
18300 if (tag == BINCS) continue;
18301 if (tag == TRNCS) {
18302 other = blit >> RMSHFT;
18303 if (lglval (lgl, other) > 0) continue;
18305 if (lglval (lgl, other2) > 0) continue;
18306 assert (!lglval (lgl, other));
18307 assert (!lglval (lgl, other2));
18308 other = abs (other);
18309 if (!lglmarked (lgl, other)) {
18310 lglmark (lgl, other);
18311 lglpushstk (lgl, tmp1, other);
18312 LOG (4, "potential inner probe %d for %d", other, lit);
18314 other2 = abs (other2);
18315 if (!lglmarked (lgl, other2)) {
18316 lglmark (lgl, other2);
18317 lglpushstk (lgl, tmp1, other2);
18318 LOG (3, "potential inner probe %d for %d", other2, lit);
18320 } else if (tmp2 && lgl->opts->liftlrg.val) {
18321 assert (tag == LRGCS);
18323 red = blit & REDCS;
18324 c = lglidx2lits (lgl, red, lidx);
18325 count = lgl->opts->liftlrg.val;
18326 for (q = c; (other = *q) && count > 0; q++) {
18327 if (other == -lit) continue;
18328 assert (other != lit);
18329 val = lglval (lgl, other);
18330 if (val > 0) break;
18333 if (other) continue;
18334 for (q = c; (other = *q); q++) {
18335 if (other == -lit) continue;
18336 assert (other != lit);
18337 val = lglval (lgl, other);
18339 if (val < 0) continue;
18341 if (lglmarked (lgl, other)) continue;
18342 lglmark (lgl, other);
18343 lglpushstk (lgl, tmp2, other);
18344 LOG (3, "potential inner probe %d for %d", other, lit);
18349 LOG (2, "found %d inner probes", lglcntstk (tmp1));
18350 res = lglrandomprobe (lgl, tmp1);
18351 lglpopnunmarkstk (lgl, tmp1);
18352 if (!res) res = lglrandomprobe (lgl, outer);
18354 for (p = tmp2->start; p < tmp2->top; p++) lglunmark (lgl, *p);
18358 static void lglcleanrepr (LGL * lgl, Stk * represented, int * repr) {
18360 while (!lglmtstk (represented)) {
18361 idx = lglpopstk (represented);
18362 assert (2 <= idx && idx < lgl->nvars);
18363 assert (repr[idx]);
18368 static void lgladdliftbincls (LGL * lgl, int a, int b) {
18369 assert (lgl->lifting);
18370 assert (lglmtstk (&lgl->clause));
18371 lglpushstk (lgl, &lgl->clause, a);
18372 lglpushstk (lgl, &lgl->clause, b);
18373 lglpushstk (lgl, &lgl->clause, 0);
18374 LOG (2, "lifted binary clause", a, b);
18375 if (lgl->opts->drup.val) lgldrupcls (lgl);
18376 #ifndef NLGLPICOSAT
18377 lglpicosatchkcls (lgl);
18379 lgldrupligaddcls (lgl, REDCS);
18380 lgladdcls (lgl, REDCS, 0, 1);
18381 lglclnstk (&lgl->clause);
18382 lgl->stats->lift.impls++;
18385 static int64_t lglobalftlim (LGL * lgl) {
18386 int64_t limit, irrlim;
18388 limit = (lgl->opts->lftreleff.val*lglvisearch (lgl))/1000;
18389 if (limit < lgl->opts->lftmineff.val) limit = lgl->opts->lftmineff.val;
18390 if (lgl->opts->lftmaxeff.val >= 0 && limit > lgl->opts->lftmaxeff.val)
18391 limit = lgl->opts->lftmaxeff.val;
18392 limit >>= (pen = lgl->limits->lft.pen + lglszpen (lgl));
18393 irrlim = lgl->stats->irr.clauses.cur/4;
18394 irrlim >>= lgl->limits->simp.pen;
18395 if (lgl->opts->irrlim.val && limit < irrlim) {
18398 "[lift-%d] limit %lld based on %d irredundant clauses",
18399 lgl->stats->lift.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
18401 lglprt (lgl, 1, "[lift-%d] limit %lld with penalty %d = %d + %d",
18402 lgl->stats->lift.count, (LGLL) limit,
18403 pen, lgl->limits->lft.pen, lglszpen (lgl));
18407 static void lglprtlftrem (LGL * lgl) {
18408 int idx, ret = 0, rem = 0;
18409 for (idx = 2; idx < lgl->nvars; idx++) {
18410 if (!lglisfree (lgl, idx)) continue;
18411 if (lglavar (lgl, idx)->donotlft) ret++; else rem++;
18414 lglprt (lgl, 1, "[lift-%d] %d variables remain %.0f%% (%d retained)",
18415 lgl->stats->lift.count, rem, lglpcnt (rem, lglrem (lgl)), ret);
18417 lglprt (lgl, 1, "[lift-%d] fully completed lifting",
18418 lgl->stats->lift.count);
18419 for (idx = 2; idx < lgl->nvars; idx++)
18420 lglavar (lgl, idx)->donotlft = 0;
18424 static int lgliftaux (LGL * lgl) {
18425 int deltaunits, deltaimpls, origeqs, origunits, origimpls, units, impls, eqs;
18426 int lit1, lit2, repr1, repr2, orepr1, orepr2, tobeprobed, notobeprobed;
18427 int i, idx, lit, * reprs[3], first, outer, inner, round, branch;
18428 Stk probes, represented[2], saved, tmp1, tmp2;
18429 int ok, oldouter, dom, repr, other;
18430 unsigned pos, delta, mod;
18431 Val val, val1, val2;
18436 assert (lgl->simp && lgl->lifting && !lgl->level);
18437 NEW (lgl->repr, lgl->nvars);
18438 CLR (probes); CLR (saved); CLR (tmp1); CLR (tmp2);
18439 CLR (represented[0]); CLR (represented[1]);
18440 NEW (reprs[0], lgl->nvars);
18441 NEW (reprs[1], lgl->nvars);
18442 NEW (reprs[2], lgl->nvars);
18443 global = lgl->stats->visits.simp + lglobalftlim (lgl);
18444 tobeprobed = notobeprobed = 0;
18445 for (idx = 2; idx < lgl->nvars; idx++) {
18446 if (!lglisfree (lgl, idx)) continue;
18447 if (lglavar (lgl, idx)->donotlft) notobeprobed++;
18448 else if (lglhasbinortrn (lgl, idx) && lglhasbinortrn (lgl, -idx))
18452 for (idx = 2; idx < lgl->nvars; idx++) {
18453 if (!lglisfree (lgl, idx)) continue;
18454 lglavar (lgl, idx)->donotlft = 0;
18458 for (idx = 2; idx < lgl->nvars; idx++) {
18459 if (!lglisfree (lgl, idx)) continue;
18460 if (lglavar (lgl, idx)->donotlft) continue;
18461 if (!lglhasbinortrn (lgl, idx)) continue;
18462 if (!lglhasbinortrn (lgl, -idx)) continue;
18463 LOG (1, "new outer probe %d", idx);
18464 lit = (lglrand (lgl) & 1) ? idx : -idx;
18465 lglpushstk (lgl, &probes, lit);
18467 mod = lglcntstk (&probes);
18468 lglprt (lgl, 1, "[lift-%d] using %d probes %.0f%%",
18469 lgl->stats->lift.count, mod, lglpcnt (mod, (lgl->nvars - 2)));
18471 origimpls = impls = lgl->stats->lift.impls;
18472 origunits = units = lgl->stats->lift.units;
18473 origeqs = lgl->stats->lift.eqs;
18474 if (!(mod)) goto DONE;
18475 LOG (1, "found %u active outer probes out of %d variables %.1f%%",
18476 mod, lgl->nvars - 1, lglpcnt (mod, lgl->nvars-1));
18477 pos = lglrand (lgl) % mod;
18478 delta = lglrand (lgl) % mod;
18479 if (!delta) delta++;
18480 while (lglgcd (delta, mod) > 1)
18481 if (++delta == mod) delta = 1;
18482 LOG (1, "lifting start %u delta %u mod %u", pos, delta, mod);
18484 assert (lgl->simp);
18486 if (lgl->stats->visits.simp >= global) break;
18487 if (lglterminate (lgl)) break;
18488 if (!lglsyncunits (lgl)) break;
18489 assert (pos < (unsigned) mod);
18490 outer = probes.start[pos];
18491 lglavar (lgl, outer)->donotlft = 1;
18492 if (outer == first) {
18493 assert (impls <= lgl->stats->lift.impls);
18494 assert (units <= lgl->stats->lift.units);
18495 deltaimpls = lgl->stats->lift.impls - impls;
18496 deltaunits = lgl->stats->lift.units - units;
18497 lglprt (lgl, 1, "[lift-%d-%d] found %d units %d impls in round %d",
18498 lgl->stats->lift.count, round, deltaunits, deltaimpls, round);
18499 impls = lgl->stats->lift.impls;
18500 units = lgl->stats->lift.units;
18501 if (round++ >= lgl->opts->lftroundlim.val) break;
18503 if (!first) first = outer;
18505 if (pos >= mod) pos -= mod;
18506 if (lglval (lgl, outer)) continue;
18507 lgl->stats->lift.probed0++;
18508 LOG (2, "1st outer branch %d during lifting", outer);
18509 oldouter = lglcntstk (&lgl->trail);
18510 lgliassume (lgl, outer);
18513 FIRST_OUTER_BRANCH_FAILED:
18514 dom = lglprbana (lgl, outer);
18515 LOG (1, "1st outer branch failed literal %d during lifting", outer);
18516 lgl->stats->lift.units++;
18517 lglbacktrack (lgl, 0);
18518 lglunit (lgl, -dom);
18519 if (lglbcp (lgl)) continue;
18520 LOG (1, "empty clause after propagating outer probe during lifting");
18526 inner = lglinnerprobe (lgl, oldouter, &probes, &tmp1, &tmp2);
18527 assert (lglmtstk (&represented[0]));
18529 FIRST_OUTER_BRANCH_WIHOUT_INNER_PROBE:
18530 LOG (2, "no inner probe for 1st outer probe %d", outer);
18531 for (i = oldouter; i < lglcntstk (&lgl->trail); i++) {
18532 lit = lglpeek (&lgl->trail, i);
18534 assert (!reprs[0][idx]);
18535 reprs[0][idx] = lglsgn (lit);
18536 lglpushstk (lgl, &represented[0], idx);
18538 assert (lgl->level == 1);
18539 goto END_OF_FIRST_OUTER_BRANCH;
18542 oldinner = lglcntstk (&lgl->trail);
18544 LOG (2, "1st inner branch %d in outer 1st branch %d", inner, outer);
18545 lgl->stats->lift.probed1++;
18546 lgliassume (lgl, inner);
18549 LOG (1, "1st inner branch failed literal %d on 1st outer branch %d",
18551 lglbacktrack (lgl, 1);
18552 assert (lglcntstk (&lgl->trail) == oldinner);
18553 lgladdliftbincls (lgl, -inner, -outer);
18554 assert (lglcntstk (&lgl->trail) == oldinner + 1);
18556 if (ok) goto FIRST_OUTER_BRANCH_WIHOUT_INNER_PROBE;
18557 LOG (1, "conflict after propagating negation of 1st inner branch");
18558 goto FIRST_OUTER_BRANCH_FAILED;
18560 lglclnstk (&saved);
18561 for (i = oldouter; i < lglcntstk (&lgl->trail); i++)
18562 lglpushstk (lgl, &saved, lglpeek (&lgl->trail, i));
18563 LOG (3, "saved %d assignments of 1st inner branch %d in 1st outer branch",
18564 lglcntstk (&saved), inner, outer);
18565 lglbacktrack (lgl, 1);
18566 assert (lglcntstk (&lgl->trail) == oldinner);
18567 LOG (2, "2nd inner branch %d in 1st outer branch %d", -inner, outer);
18568 lgl->stats->lift.probed1++;
18569 lgliassume (lgl, -inner);
18572 LOG (2, "2nd inner branch failed literal %d on 1st outer branch %d",
18574 lglbacktrack (lgl, 1);
18575 assert (lglcntstk (&lgl->trail) == oldinner);
18576 lgladdliftbincls (lgl, inner, -outer);
18577 assert (lglcntstk (&lgl->trail) == oldinner + 1);
18579 if (ok) goto FIRST_OUTER_BRANCH_WIHOUT_INNER_PROBE;
18580 LOG (1, "conflict after propagating negation of 2nd inner branch");
18581 goto FIRST_OUTER_BRANCH_FAILED;
18583 while (!lglmtstk (&saved)) {
18584 lit = lglpopstk (&saved);
18586 val1 = lglsgn (lit);
18587 val2 = lglval (lgl, idx);
18588 if (val1 == val2) {
18589 assert (!reprs[0][idx]);
18590 reprs[0][idx] = val1;
18591 lglpushstk (lgl, &represented[0], idx);
18592 } else if (lit != inner && val1 == -val2) {
18593 assert (lit != -inner);
18594 repr = lglptrjmp (reprs[0], lgl->nvars-1, inner);
18595 other = lglptrjmp (reprs[0], lgl->nvars-1, lit);
18596 if (lglcmprepr (lgl, other, repr) < 0) SWAP (int, repr, other);
18597 if (other < 0) other = -other, repr = -repr;
18598 assert (!reprs[0][other]);
18599 reprs[0][other] = repr;
18600 lglpushstk (lgl, &represented[0], other);
18601 } else assert (lit == inner || !val2);
18603 lglbacktrack (lgl, 1);
18604 END_OF_FIRST_OUTER_BRANCH:
18605 assert (lgl->level == 1);
18608 LOG (1, "start of 1st outer branch %d equivalences:", outer);
18609 for (i = 0; i < lglcntstk (&represented[0]); i++) {
18610 other = lglpeek (&represented[0], i);
18611 repr = reprs[0][other];
18612 LOG (1, " 1st branch equivalence %d : %d = %d", i + 1, other, repr);
18614 LOG (1, "end of 1st outer branch %d equivalences.", outer);
18617 lglbacktrack (lgl, 0);
18618 assert (lglcntstk (&lgl->trail) == oldouter);
18619 lgl->stats->lift.probed0++;
18620 LOG (2, "2nd outer branch %d during lifting", -outer);
18621 lgliassume (lgl, -outer);
18624 SECOND_OUTER_BRANCH_FAILED:
18625 dom = lglprbana (lgl, -outer);
18626 LOG (1, "2nd branch outer failed literal %d during lifting", -outer);
18627 lgl->stats->lift.units++;
18628 lglbacktrack (lgl, 0);
18629 lglunit (lgl, -dom);
18630 if (lglbcp (lgl)) goto CONTINUE;
18635 assert (lglmtstk (&represented[1]));
18637 oldinner = lglcntstk (&lgl->trail);
18639 if (!inner || lglval (lgl, inner))
18640 inner = lglinnerprobe (lgl, oldouter, &probes, &tmp2, 0);
18642 SECOND_OUTER_BRANCH_WIHOUT_INNER_PROBE:
18643 LOG (2, "no inner probe for 2nd outer branch %d", -outer);
18644 for (i = oldouter; i < lglcntstk (&lgl->trail); i++) {
18645 lit = lglpeek (&lgl->trail, i);
18647 assert (!reprs[1][idx]);
18648 reprs[1][idx] = lglsgn (lit);
18649 lglpushstk (lgl, &represented[1], idx);
18651 assert (lgl->level == 1);
18652 goto END_OF_SECOND_BRANCH;
18654 LOG (2, "1st inner branch %d in outer 2nd branch %d", inner, -outer);
18655 lgl->stats->lift.probed1++;
18656 lgliassume (lgl, inner);
18659 LOG (1, "1st inner branch failed literal %d on 2nd outer branch %d",
18661 lglbacktrack (lgl, 1);
18662 assert (lglcntstk (&lgl->trail) == oldinner);
18663 lgladdliftbincls (lgl, -inner, outer);
18664 assert (lglcntstk (&lgl->trail) == oldinner + 1);
18666 if (ok) goto SECOND_OUTER_BRANCH_WIHOUT_INNER_PROBE;
18667 LOG (1, "conflict after propagating negation of 1st inner branch");
18668 goto SECOND_OUTER_BRANCH_FAILED;
18670 lglclnstk (&saved);
18671 for (i = oldouter; i < lglcntstk (&lgl->trail); i++)
18672 lglpushstk (lgl, &saved, lglpeek (&lgl->trail, i));
18674 "saved %d assignments of 1st inner branch %d in 2nd outer branch %d",
18675 lglcntstk (&saved), inner, -outer);
18676 lglbacktrack (lgl, 1);
18677 assert (lglcntstk (&lgl->trail) == oldinner);
18678 LOG (2, "2nd inner branch %d in 2nd outer branch %d", -inner, -outer);
18679 lgl->stats->lift.probed1++;
18680 lgliassume (lgl, -inner);
18683 LOG (1, "2nd inner branch failed literal %d on 2nd outer branch %d",
18685 lglbacktrack (lgl, 1);
18686 assert (lglcntstk (&lgl->trail) == oldinner);
18687 lgladdliftbincls (lgl, inner, outer);
18688 assert (lglcntstk (&lgl->trail) == oldinner + 1);
18690 if (ok) goto SECOND_OUTER_BRANCH_WIHOUT_INNER_PROBE;
18691 LOG (1, "conflict after propagating negation of 2nd inner branch");
18692 goto SECOND_OUTER_BRANCH_FAILED;
18694 while (!lglmtstk (&saved)) {
18695 lit = lglpopstk (&saved);
18697 val1 = lglsgn (lit);
18698 val2 = lglval (lgl, idx);
18699 if (val1 == val2) {
18700 assert (!reprs[1][idx]);
18701 reprs[1][idx] = val1;
18702 lglpushstk (lgl, &represented[1], idx);
18703 } else if (lit != inner && val1 == -val2) {
18704 assert (lit != -inner);
18705 repr = lglptrjmp (reprs[1], lgl->nvars-1, inner);
18706 other = lglptrjmp (reprs[1], lgl->nvars-1, lit);
18707 if (lglcmprepr (lgl, other, repr) < 0) SWAP (int, repr, other);
18708 if (other < 0) other = -other, repr = -repr;
18709 assert (!reprs[1][other]);
18710 reprs[1][other] = repr;
18711 lglpushstk (lgl, &represented[1], other);
18712 } else assert (lit == inner || !val2);
18714 lglbacktrack (lgl, 1);
18715 END_OF_SECOND_BRANCH:
18716 assert (lgl->level == 1);
18719 LOG (1, "start of 2nd outer branch %d equivalences:", -outer);
18720 for (i = 0; i < lglcntstk (&represented[1]); i++) {
18721 other = lglpeek (&represented[1], i);
18722 repr = reprs[1][other];
18723 LOG (1, " 2nd branch equivalence %d : %d = %d", i + 1, other, repr);
18725 LOG (1, "end of 2nd outer branch %d equivalences.", outer);
18728 lglbacktrack (lgl, 0);
18729 for (branch = 0; branch <= 1; branch++) {
18730 assert (lglptrjmp (reprs[!branch], lgl->nvars-1, 1) == 1);
18731 assert (lglptrjmp (reprs[!branch], lgl->nvars-1, -1) == -1);
18732 for (i = 0; i < lglcntstk (&represented[branch]); i++) {
18733 lit1 = lglpeek (&represented[branch], i);
18734 assert (2 <= lit1 && lit1 < lgl->nvars);
18735 lit2 = reprs[branch][lit1];
18737 if (abs (lit2) == 1) {
18738 val = lglval (lgl, lit1);
18739 assert (!val || val == lit2);
18741 repr1 = lglptrjmp (reprs[!branch], lgl->nvars-1, lit1);
18742 if (repr1 != lit2) continue;
18743 LOG (1, " common constant equivalence : %d = %d (branch %d)",
18744 lit1, lit2, branch);
18745 lglunit (lgl, lit2*lit1);
18746 lgl->stats->lift.units++;
18748 repr1 = lglptrjmp (reprs[2], lgl->nvars-1, lit1);
18749 repr2 = lglptrjmp (reprs[2], lgl->nvars-1, lit2);
18750 if (repr1 == repr2) continue;
18751 orepr1 = lglptrjmp (reprs[!branch], lgl->nvars-1, lit1);
18752 orepr2 = lglptrjmp (reprs[!branch], lgl->nvars-1, lit2);
18753 if (orepr1 != orepr2) continue;
18754 assert (abs (repr1) > 1 && abs (repr2) > 1);
18755 if (lglcmprepr (lgl, repr2, repr1) < 0) SWAP (int, repr1, repr2);
18756 if (repr2 < 0) repr2 = -repr2, repr1 = -repr1;
18757 LOG (2, " common equivalence candidate : %d = %d (branch %d)",
18758 repr2, repr1, branch);
18759 reprs[2][repr2] = repr1;
18763 if (!lglbcp (lgl)) lgl->mt = 1;
18765 assert (!lgl->level);
18766 lglcleanrepr (lgl, &represented[0], reprs[0]);
18767 lglcleanrepr (lgl, &represented[1], reprs[1]);
18769 if (lgl->mt) goto DONE;
18770 for (idx = 2; idx < lgl->nvars; idx++)
18771 (void) lglptrjmp (reprs[2], lgl->nvars-1, idx);
18772 for (idx = 2; idx < lgl->nvars; idx++) {
18773 repr = lglptrjmp (reprs[2], lgl->nvars-1, idx);
18774 val = lglval (lgl, idx);
18775 if (!val) continue;
18776 if (repr == -val) {
18777 LOG (1, "inconsistent assigned members of equivalence classe");
18781 if (repr < 0) repr = -repr, val = -val;
18782 if (repr == 1) { assert (val == 1); continue; }
18783 reprs[2][repr] = val;
18785 for (idx = 2; idx < lgl->nvars; idx++) {
18786 repr = lglptrjmp (reprs[2], lgl->nvars-1, idx);
18788 assert (repr != -idx);
18789 if (repr == idx) continue;
18790 if (abs (repr) == 1) continue;
18791 lgl->stats->lift.eqs++;
18792 LOG (1, " real common equivalence : %d = %d", idx, repr);
18793 lglimerge (lgl, idx, repr);
18796 assert (origimpls <= lgl->stats->lift.impls);
18797 assert (origunits <= lgl->stats->lift.units);
18798 assert (origeqs <= lgl->stats->lift.eqs);
18799 impls = lgl->stats->lift.impls - origimpls;
18800 units = lgl->stats->lift.units - origunits;
18801 eqs = lgl->stats->lift.eqs - origeqs;
18802 lglprt (lgl, 1, "[lift-%d] %d units, %d impls, %d eqs in %d rounds",
18803 lgl->stats->lift.count, units, impls, eqs, round);
18804 assert (!lgl->level);
18805 DEL (reprs[0], lgl->nvars);
18806 DEL (reprs[1], lgl->nvars);
18807 DEL (reprs[2], lgl->nvars);
18808 lglrelstk (lgl, &probes);
18809 lglrelstk (lgl, &represented[0]);
18810 lglrelstk (lgl, &represented[1]);
18811 lglrelstk (lgl, &saved);
18812 lglrelstk (lgl, &tmp1);
18813 lglrelstk (lgl, &tmp2);
18814 if (lgl->mt) DEL (lgl->repr, lgl->nvars);
18818 static int lglift (LGL * lgl) {
18819 int oldrem = lglrem (lgl), removed;
18820 assert (lgl->opts->lift.val);
18821 lglstart (lgl, &lgl->times->lft);
18822 assert (!lgl->lifting);
18824 lgl->stats->lift.count++;
18825 assert (!lgl->simp);
18827 if (lgl->level > 0) lglbacktrack (lgl, 0);
18828 if (!lglbcp (lgl)) goto DONE;
18830 if (lgl->mt) goto DONE;
18831 if (!lgliftaux (lgl)) { assert (lgl->mt); goto DONE; }
18832 if (!lglsynceqs (lgl)) { assert (lgl->mt); goto DONE; }
18839 if (lgl->mt) goto DONE;
18840 if (!lglbcp (lgl)) goto DONE;
18843 if (lgl->mt) goto DONE;
18844 if (!lgl->mt) { lglpicosatchkall (lgl); lglpicosatrestart (lgl); }
18846 removed = oldrem - lglrem (lgl);
18847 LGLUPDPEN (lft, removed);
18848 assert (lgl->lifting && lgl->simp);
18849 lgl->lifting = lgl->simp = 0;
18850 lglprtlftrem (lgl);
18851 lglprt (lgl, 1 + !removed,
18852 "[lift-%d] removed %d variables", lgl->stats->lift.count, removed);
18853 lglrep (lgl, 2, '^');
18858 static int lgldstpull (LGL * lgl, int lit) {
18860 av = lglavar (lgl, lit);
18861 assert ((lit > 0) == av->wasfalse);
18862 if (av->mark) return 0;
18863 if (!lglevel (lgl, lit)) return 0;
18865 if (lgldecision (lgl, lit)) {
18866 lglpushstk (lgl, &lgl->clause, lit);
18867 LOG (3, "added %d to learned clause", lit);
18869 lglpushstk (lgl, &lgl->seen, -lit);
18870 LOG (3, "pulled in distillation literal %d", -lit);
18875 static int lglanalit (LGL * lgl, int lit) {
18876 int r0, r1, antecedents, other, next, tag, * p, * rsn;
18878 assert (lglmtstk (&lgl->seen));
18879 assert (lglmtstk (&lgl->clause));
18881 av = lglavar (lgl, lit);
18882 rsn = lglrsn (lgl, lit);
18883 r0 = rsn[0], r1 = rsn[1];
18884 LOGREASON (2, lit, r0, r1, "starting literal analysis for %d with", lit);
18885 LOG (3, "added %d to learned clause", lit);
18886 lglpushstk (lgl, &lgl->clause, lit);
18887 assert ((lit < 0) == av->wasfalse);
18888 assert (!av->mark);
18893 if (tag == BINCS || tag == TRNCS) {
18894 other = r0 >> RMSHFT;
18895 lgldstpull (lgl, other);
18896 if (tag == TRNCS) lgldstpull (lgl, r1);
18897 } else if (tag == UNITCS) assert (!lglevel (lgl, lit));
18898 else if (tag == DECISION) assert (lglavar (lgl, lit)->assumed);
18900 assert (tag == LRGCS);
18901 for (p = lglidx2lits (lgl, (r0 & REDCS), r1); (other = *p); p++)
18902 if (other != lit) lgldstpull (lgl, *p);
18904 if (next == lglcntstk (&lgl->seen)) break;
18905 lit = lglpeek (&lgl->seen, next++);
18906 assert ((lit < 0) == lglavar (lgl, lit)->wasfalse);
18907 rsn = lglrsn (lgl, lit);
18908 r0 = rsn[0], r1 = rsn[1];
18909 LOGREASON (2, lit, r0, r1, "literal analysis of");
18912 lglpopnunmarkstk (lgl, &lgl->seen);
18913 LOG (2, "literal analysis used %d antecedents", antecedents);
18914 assert (lglcntstk (&lgl->clause) >= 1);
18915 return antecedents;
18918 static int lglfailedass (LGL * lgl) {
18919 assert (lgl->level >= lgl->alevel);
18920 return lgl->level == lgl->alevel && lgl->failed;
18923 static void lglanafailed (LGL * lgl) {
18924 int ilit, elit, erepr, failed, size;
18925 unsigned bit, rbit, ibit, count;
18929 assert (lgl->mt || lglfailedass (lgl));
18931 LOG (1, "no failed assumptions since CNF unconditionally inconsistent");
18932 } else if ((failed = lgl->failed) == -1) {
18933 assert (!lgl->level);
18935 for (p = lgl->eassume.start; !elit && p < lgl->eassume.top; p++) {
18936 erepr = lglerepr (lgl, *p);
18937 if (lglederef (lgl, erepr) < 0) elit = *p;
18940 LOG (1, "found single external failed assumption %d", elit);
18941 ext = lglelit2ext (lgl, elit);
18942 assert (!ext->failed);
18943 bit = 1u << (elit < 0);
18944 assert (ext->assumed & bit);
18945 ext->failed |= bit;
18947 assert (abs (failed) > 1);
18948 if ((av = lglavar (lgl, failed))->assumed == 3) {
18949 LOG (1, "inconsistent internal assumptions %d and %d", failed, -failed);
18950 assert (!av->failed);
18953 lglanalit (lgl, -failed);
18954 for (p = lgl->clause.start; p < lgl->clause.top; p++) {
18956 av = lglavar (lgl, ilit);
18957 bit = (1u << (ilit > 0));
18958 assert (av->assumed & bit);
18959 assert (!(av->failed & bit));
18962 size = lglcntstk (&lgl->clause);
18964 lglpushstk (lgl, &lgl->clause, 0);
18966 "[analyze-final] learned clause with size %d out of %d",
18967 size, lglcntstk (&lgl->eassume));
18968 LOGCLS (2, lgl->clause.start, "failed assumption clause");
18969 lgldrupligaddcls (lgl, REDCS);
18970 lgladdcls (lgl, REDCS, size, 0);
18971 lglpopstk (&lgl->clause);
18972 lglpopnunmarkstk (lgl, &lgl->clause);
18975 for (p = lgl->eassume.start; p < lgl->eassume.top; p++) {
18977 bit = 1u << (elit < 0);
18978 ext = lglelit2ext (lgl, elit);
18979 assert (!ext->eliminated && !ext->blocking);
18980 assert (ext->assumed & bit);
18981 if (ext->failed & bit) continue;
18985 if (erepr < 0) rbit ^= 3;
18986 if (elit < 0) erepr = -erepr;
18987 rext = lglelit2ext (lgl, erepr);
18988 assert (!rext->equiv);
18989 if (rext->failed & rbit) continue;
18992 if (ilit < 0) ilit = -ilit, ibit ^= 3;
18993 if (ilit == 1) continue;
18994 assert (ilit && ilit != -1);
18995 av = lglavar (lgl, ilit);
18996 if (!(av->failed & ibit)) continue;
18997 rext->failed |= rbit;
18999 if (rext->assumed & rbit) {
19001 "found representative external failed assumption %d",
19005 "found non representative external failed assumption %d",
19007 ext->failed |= bit;
19012 if (ilit < 0) ilit = -ilit, ibit ^= 3;
19013 if (ilit == 1) continue;
19014 assert (ilit && ilit != -1);
19015 av = lglavar (lgl, ilit);
19016 if (!(av->failed & ibit)) continue;
19017 LOG (2, "found external failed assumption %d", elit);
19018 ext->failed |= bit;
19022 LOG (1, "found %u external failed assumptions", count);
19027 static void lglternreslit (LGL * lgl, int lit) {
19028 int * pw, * peow, * nw, * neow, * p, * n;
19029 int pblit, ptag, pother, pother2, pdelta;
19030 int nblit, ntag, nother, nother2, ndelta;
19031 HTS * phts, * nhts;
19034 phts = lglhts (lgl, lit);
19035 pw = lglhts2wchs (lgl, phts);
19036 peow = pw + phts->count;
19037 nhts = lglhts (lgl, -lit);
19038 nw = lglhts2wchs (lgl, nhts);
19039 neow = nw + nhts->count;
19040 for (n = nw; n < neow; n++) {
19041 if (INCSTEPS (trnr.steps) >= lgl->limits->trnr.steps) return;
19043 ntag = nblit & MASKCS;
19044 if (ntag == BINCS || ntag == OCCS) continue;
19045 if (ntag == TRNCS) break;
19046 assert (ntag == LRGCS);
19049 if (n >= neow) return;
19051 p < peow && lgl->stats->trnr.steps < lgl->limits->trnr.steps;
19053 INCSTEPS (trnr.steps);
19055 ptag = pblit & MASKCS;
19056 if (ptag == BINCS || ptag == OCCS) continue;
19057 if (ptag == TRNCS || ptag == LRGCS) p++;
19058 if (ptag == LRGCS) continue;
19059 assert (ptag == TRNCS);
19060 pother = pblit >> RMSHFT;
19061 if (lglval (lgl, pother)) continue;
19063 if (lglval (lgl, pother2)) continue;
19065 n < neow && lgl->stats->trnr.steps < lgl->limits->trnr.steps;
19067 INCSTEPS (trnr.steps);
19069 ntag = nblit & MASKCS;
19070 if (ntag == BINCS || ntag == OCCS) continue;
19071 if (ntag == TRNCS || ntag == LRGCS) n++;
19072 if (ntag == LRGCS) continue;
19073 assert (ntag == TRNCS);
19074 nother = nblit >> RMSHFT;
19075 if (lglval (lgl, nother)) continue;
19077 if (lglval (lgl, nother2)) continue;
19078 if ((nother == pother && nother2 == pother2) ||
19079 (nother == pother2 && nother2 == pother)) {
19080 a = nother, b = nother2;
19081 if (lglhasbin (lgl, a, b)) continue;
19082 lgl->stats->trnr.bin++;
19083 LOG (2, "ternary resolvent %d %d", a, b);
19084 if (lgl->opts->drup.val) lgldrupclsarg (lgl, a, b, 0);
19085 #ifndef NLGLPICOSAT
19086 lglpicosatchkclsarg (lgl, a, b, 0);
19088 lglwchbin (lgl, a, b, REDCS);
19089 lglwchbin (lgl, b, a, REDCS);
19090 lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
19091 lglwrktouch (lgl, a);
19092 lglwrktouch (lgl, b);
19094 a = nother, b = nother2;
19095 if (nother == pother || nother2 == pother) c = pother2;
19096 else if (nother == pother2 || nother2 == pother2) c = pother;
19098 assert (a != b && b != c && a != c);
19100 if (a == -c || b == -c) continue;
19101 if (lglhastrn (lgl, a, b, c)) continue;
19102 lgl->stats->trnr.trn++;
19103 LOG (2, "ternary resolvent %d %d %d", a, b, c);
19104 if (lgl->opts->drup.val) lgldrupclsarg (lgl, a, b, c, 0);
19105 #ifndef NLGLPICOSAT
19106 lglpicosatchkclsarg (lgl, a, b, c, 0);
19108 lglwchtrn (lgl, a, b, c, REDCS);
19109 lglwchtrn (lgl, b, a, c, REDCS);
19110 lglwchtrn (lgl, c, a, b, REDCS);
19111 lgl->stats->red.trn++, assert (lgl->stats->red.trn > 0);
19112 lglwrktouch (lgl, a);
19113 lglwrktouch (lgl, b);
19114 lglwrktouch (lgl, c);
19117 phts = lglhts (lgl, lit);
19118 pw = lglhts2wchs (lgl, phts);
19119 peow = pw + phts->count;
19122 nhts = lglhts (lgl, -lit);
19123 nw = lglhts2wchs (lgl, nhts);
19124 neow = nw + nhts->count;
19130 static void lglternresidx (LGL * lgl, int idx) {
19131 lglternreslit (lgl, idx);
19132 lglternreslit (lgl, -idx);
19135 static void lglseternreslim (LGL * lgl) {
19136 int64_t limit, irrlim;
19138 if (lgl->opts->ternresrtc.val) {
19139 lgl->limits->trnr.steps = LLMAX;
19140 lglprt (lgl, 1, "[ternres-%d] no limit (run to completion)",
19141 lgl->stats->trnr.count);
19143 limit = (lgl->opts->trnreleff.val*lglvisearch (lgl))/1000;
19144 if (limit < lgl->opts->trnrmineff.val) limit = lgl->opts->trnrmineff.val;
19145 if (lgl->opts->trnrmaxeff.val >= 0 && limit > lgl->opts->trnrmaxeff.val)
19146 limit = lgl->opts->trnrmaxeff.val;
19147 if (lgl->stats->trnr.count <= 1 &&
19148 lgl->opts->boost.val &&
19149 lgl->opts->ternresboost.val > 1) {
19151 "[ternres-%d] boosting ternary resolution limit by %d",
19152 lgl->stats->trnr.count, lgl->opts->ternresboost.val);
19153 limit *= lgl->opts->ternresboost.val;
19155 limit >>= (pen = lgl->limits->trnr.pen + lglszpen (lgl));
19156 irrlim = 4*lgl->stats->irr.clauses.cur;
19157 irrlim >>= lgl->limits->simp.pen;
19158 if (lgl->opts->irrlim.val && limit < irrlim) {
19161 "[ternres-%d] limit %lld based on %d irredundant clauses",
19162 lgl->stats->trnr.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
19164 lglprt (lgl, 1, "[ternres-%d] limit %lld with penalty %d = %d + %d",
19165 lgl->stats->trnr.count, (LGLL) limit,
19166 pen, lgl->limits->trnr.pen, lglszpen (lgl));
19167 lgl->limits->trnr.steps = lgl->stats->trnr.steps + limit;
19171 static void lglprternresrem (LGL * lgl) {
19172 int idx, ret = 0, rem = 0;
19173 for (idx = 2; idx < lgl->nvars; idx++) {
19174 if (!lglisfree (lgl, idx)) continue;
19175 if (lglavar (lgl, idx)->donoternres) ret++; else rem++;
19178 lglprt (lgl, 1, "[ternres-%d] %d variables remain %.0f%% (%d retained)",
19179 lgl->stats->trnr.count, rem, lglpcnt (rem, lglrem (lgl)), ret);
19181 lglprt (lgl, 1, "[ternres-%d] fully completed ternary resolution",
19182 lgl->stats->trnr.count);
19183 for (idx = 2; idx < lgl->nvars; idx++)
19184 lglavar (lgl, idx)->donoternres = 0;
19188 static void lglternresinit (LGL * lgl) {
19189 int idx, schedulable = 0, donoternres = 0;
19190 lglwrkinit (lgl, 1, 1);
19191 for (idx = 2; idx < lgl->nvars; idx++) {
19192 if (!lglisfree (lgl, idx)) continue;
19193 if (lglavar (lgl, idx)->donoternres) donoternres++;
19194 else schedulable++;
19196 if (!schedulable) {
19198 for (idx = 2; idx < lgl->nvars; idx++) {
19199 if (!lglisfree (lgl, idx)) continue;
19200 lglavar (lgl, idx)->donoternres = 0;
19205 lglprt (lgl, 1, "[ternres-%d] all %d free variables schedulable",
19206 lgl->stats->trnr.count, schedulable);
19209 "[ternres-%d] %d schedulable variables %.0f%%",
19210 lgl->stats->trnr.count, schedulable, lglpcnt (schedulable, lgl->nvars-2));
19211 assert (!lgl->donotsched), lgl->donotsched = 1;
19212 lglrandidxtrav (lgl, lglwrktouch);
19213 assert (lgl->donotsched), lgl->donotsched = 0;
19216 static int lglternres (LGL * lgl) {
19217 int before, after, delta;
19218 int before2, after2, delta2;
19219 int before3, after3, delta3;
19221 if (lgl->nvars <= 2) return 1;
19222 lglstart (lgl, &lgl->times->trn);
19223 ASSERT (!lgl->simp && !lgl->ternresing);
19224 lgl->simp = lgl->ternresing = 1;
19225 lgl->stats->trnr.count++;
19226 if (lgl->level > 0) lglbacktrack (lgl, 0);
19227 lglseternreslim (lgl);
19229 lglternresinit (lgl);
19231 before2 = lgl->stats->trnr.bin;
19232 before3 = lgl->stats->trnr.trn;
19233 while (lgl->stats->trnr.steps < lgl->limits->trnr.steps) {
19234 if (lglterminate (lgl)) break;
19235 if (!lglsyncunits (lgl)) break;
19236 if (!(lit = lglwrknext (lgl))) {
19237 lglprt (lgl, 2, "[ternres-%d] saturated", lgl->stats->trnr.count);
19240 INCSTEPS (trnr.steps);
19242 if (!lglisfree (lgl, lit)) continue;
19243 lglavar (lgl, lit)->donoternres = 1;
19244 lglternresidx (lgl, lit);
19246 after2 = lgl->stats->trnr.bin;
19247 after3 = lgl->stats->trnr.trn;
19248 after = after2 + after3;
19249 before = before2 + before3;
19250 delta2 = after2 - before2;
19251 delta3 = after3 - before3;
19252 delta = after - before;
19253 success = before < after;
19254 lglprt (lgl, 1, "[ternres-%d] %d ternary resolvents (%d bin, %d trn)",
19255 lgl->stats->trnr.count, delta, delta2, delta3);
19256 LGLUPDPEN (trnr, success);
19257 assert (lgl->simp && lgl->ternresing);
19258 lgl->simp = lgl->ternresing = 0;
19259 lglprternresrem (lgl);
19260 lglrep (lgl, 2, 'T');
19266 static int lgltrdbin (LGL * lgl, int start, int target, int irr) {
19267 int lit, next, blit, tag, red, other, * p, * w, * eow, res, ign, val;
19269 assert (lglmtstk (&lgl->seen));
19270 assert (abs (start) < abs (target));
19271 LOG (2, "trying transitive reduction of %s binary clause %d %d",
19272 lglred2str (irr^REDCS), start, target);
19273 lgl->stats->trd.bins++;
19274 lglpushnmarkseen (lgl, -start);
19278 while (next < lglcntstk (&lgl->seen)) {
19279 lit = lglpeek (&lgl->seen, next++);
19280 INCSTEPS (trd.steps);
19281 LOG (3, "transitive reduction search step %d", lit);
19282 val = lglval (lgl, lit);
19284 hts = lglhts (lgl, -lit);
19285 if (!hts->count) continue;
19286 w = lglhts2wchs (lgl, hts);
19287 eow = w + hts->count;
19288 for (p = w; p < eow; p++) {
19290 tag = blit & MASKCS;
19291 if (tag == LRGCS || tag == TRNCS) p++;
19292 if (tag != BINCS) continue;
19293 red = blit & REDCS;
19294 if (irr && red) continue;
19295 other = blit >> RMSHFT;
19296 if (other == start) continue;
19297 if (other == target) {
19298 if (lit == -start && ign) { ign = 0; continue; }
19299 LOG (2, "transitive path closed with %s binary clause %d %d",
19300 lglred2str (red), -lit, other);
19304 val = lglmarked (lgl, other);
19305 if (val > 0) continue;
19307 assert (lgl->level == 0);
19308 lgl->stats->trd.failed++;
19309 LOG (1, "failed literal %d in transitive reduction", -start);
19310 lglunit (lgl, start);
19311 val = lglbcp (lgl);
19312 if (!val && !lgl->mt) lgl->mt = 1;
19313 assert (val || lgl->mt);
19317 lglpushnmarkseen (lgl, other);
19318 LOG (3, "transitive reduction follows %s binary clause %d %d",
19319 lglred2str (red), -lit, other);
19323 lglpopnunmarkstk (lgl, &lgl->seen);
19327 static void lgltrdlit (LGL * lgl, int start) {
19328 int target, * w, * p, * eow, blit, tag, red, val;
19330 int unassigned = lgl->unassigned;
19333 val = lglval (lgl, start);
19335 LOG (2, "transitive reduction of binary clauses with %d", start);
19336 assert (lglmtstk (&lgl->seen));
19337 hts = lglhts (lgl, start);
19338 if (!hts->count) return;
19339 lgl->stats->trd.lits++;
19340 w = lglhts2wchs (lgl, hts);
19341 eow = w + hts->count;
19343 p < eow && (lgl->stats->trd.steps < lgl->limits->trd.steps);
19346 tag = blit & MASKCS;
19347 if (tag == TRNCS || tag == LRGCS) p++;
19348 if (tag != BINCS) continue;
19349 target = blit >> RMSHFT;
19350 if (abs (start) > abs (target)) continue;
19351 red = blit & REDCS;
19352 val = lgltrdbin (lgl, start, target, red^REDCS);
19353 if (!val) continue;
19354 if (val < 0) { assert (lgl->mt || lgl->unassigned < unassigned); break; }
19355 LOG (2, "removing transitive redundant %s binary clause %d %d",
19356 lglred2str (red), start, target);
19357 lgl->stats->trd.red++;
19358 lgl->stats->prgss++;
19359 lglrmbwch (lgl, start, target, red);
19360 lglrmbwch (lgl, target, start, red);
19361 assert (!lgl->dense);
19362 if (red) assert (lgl->stats->red.bin > 0), lgl->stats->red.bin--;
19363 else lgldecirr (lgl, 2);
19368 static void lglsetrdlim (LGL * lgl) {
19369 int64_t limit, irrlim;
19371 limit = (lgl->opts->trdreleff.val*lglvisearch (lgl))/1000;
19372 if (limit < lgl->opts->trdmineff.val) limit = lgl->opts->trdmineff.val;
19373 if (lgl->opts->trdmaxeff.val >= 0 && limit > lgl->opts->trdmaxeff.val)
19374 limit = lgl->opts->trdmaxeff.val;
19375 limit >>= (pen = lgl->limits->trd.pen + lglszpen (lgl));
19376 irrlim = lgl->stats->irr.clauses.cur;
19377 irrlim >>= lgl->limits->simp.pen;
19378 if (lgl->opts->irrlim.val && limit < irrlim) {
19381 "[transred-%d] limit %lld based on %d irredundant clauses",
19382 lgl->stats->trd.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
19384 lglprt (lgl, 1, "[transred-%d] limit %lld with penalty %d = %d + %d",
19385 lgl->stats->trd.count, (LGLL) limit,
19386 pen, lgl->limits->trd.pen, lglszpen (lgl));
19387 lgl->limits->trd.steps = lgl->stats->trd.steps + limit;
19390 static int lgltrd (LGL * lgl) {
19391 unsigned pos, delta, mod, ulit, first, last;
19392 int failed = lgl->stats->trd.failed;
19393 int red = lgl->stats->trd.red;
19394 int lit, count, success;
19395 if (lgl->nvars <= 2) return 1;
19396 lgl->stats->trd.count++;
19397 lglstart (lgl, &lgl->times->trd);
19398 assert (!lgl->simp);
19400 if (lgl->level > 0) lglbacktrack (lgl, 0);
19402 mod = 2*(lgl->nvars - 2);
19404 pos = lglrand (lgl) % mod;
19405 delta = lglrand (lgl) % mod;
19406 if (!delta) delta++;
19407 while (lglgcd (delta, mod) > 1)
19408 if (++delta == mod) delta = 1;
19409 LOG (1, "transitive reduction start %u delta %u mod %u", pos, delta, mod);
19412 while (lgl->stats->trd.steps < lgl->limits->trd.steps) {
19413 if (lglterminate (lgl)) break;
19414 if (!lglsyncunits (lgl)) break;
19416 lit = lglilit (ulit);
19417 lgltrdlit (lgl, lit);
19419 assert (count <= mod);
19420 if (lgl->mt) break;
19423 if (pos >= mod) pos -= mod;
19424 if (pos == first) { assert (count == mod); break; }
19425 if (mod == 1) break;
19426 if (first == mod) first = last;
19428 failed = lgl->stats->trd.failed - failed;
19429 red = lgl->stats->trd.red - red;
19430 success = failed || red;
19431 LGLUPDPEN (trd, success);
19432 assert (lgl->simp);
19434 "[transred-%d] removed %d transitive binary clauses",
19435 lgl->stats->trd.count, red);
19436 lglprt (lgl, 1 + !failed,
19437 "[transred-%d] found %d units",
19438 lgl->stats->trd.count, failed);
19440 lglrep (lgl, 2, 't');
19445 static int lglunhdhasbins (LGL * lgl, const DFPR * dfpr,
19446 int lit, int irronly) {
19447 int blit, tag, other, val, red, ulit;
19448 const int * p, * w, * eos;
19450 assert (!lglval (lgl, lit));
19451 hts = lglhts (lgl, lit);
19452 w = lglhts2wchs (lgl, hts);
19453 eos = w + hts->count;
19454 for (p = w; p < eos; p++) {
19456 tag = blit & MASKCS;
19457 if (tag == OCCS) continue;
19458 if (tag == TRNCS || tag == LRGCS) { p++; continue; }
19459 red = blit & REDCS;
19460 if (irronly && red) continue;
19461 other = blit >> RMSHFT;
19462 val = lglval (lgl, other);
19464 if (val > 0) continue;
19465 ulit = lglulit (other);
19466 if (!dfpr[ulit].discovered) return 1;
19471 static int lglunhdisroot (LGL * lgl, int lit, DFPR * dfpr, int irronly) {
19472 int res = !lglunhdhasbins (lgl, dfpr, lit, irronly);
19473 assert (!res || !dfpr[lglulit (lit)].discovered);
19477 static int lglmtwtk (Wtk * wtk) { return wtk->top == wtk->start; }
19479 static int lglfullwtk (Wtk * wtk) { return wtk->top == wtk->end; }
19481 static int lglsizewtk (Wtk * wtk) { return wtk->end - wtk->start; }
19483 static int lglcntwtk (Wtk * wtk) { return wtk->top - wtk->start; }
19485 static void lglrelwtk (LGL * lgl, Wtk * wtk) {
19486 DEL (wtk->start, lglsizewtk (wtk));
19487 memset (wtk, 0, sizeof *wtk);
19490 static void lglenlwtk (LGL * lgl, Wtk * wtk) {
19491 int oldsize = lglsizewtk (wtk);
19492 int newsize = oldsize ? 2*oldsize : 1;
19493 int count = lglcntwtk (wtk);
19494 RSZ (wtk->start, oldsize, newsize);
19495 wtk->top = wtk->start + count;
19496 wtk->end = wtk->start + newsize;
19499 static void lglpushwtk (LGL * lgl, Wtk * wtk,
19500 Wrag wrag, int lit, int other, int red) {
19502 if (lglfullwtk (wtk)) lglenlwtk (lgl, wtk);
19505 w.red = red ? 1 : 0;
19511 static int lglstamp (LGL * lgl, int root,
19512 DFPR * dfpr, DFOPF * dfopf,
19513 Wtk * work, Stk * units, Stk * sccs, Stk * trds,
19514 int * visitedptr, int stamp, int irronly) {
19515 int uroot, lit, ulit, blit, tag, red, other, failed, uother, unotother;
19516 int observed, discovered, pos, undiscovered;
19517 unsigned start, end, mod, i, j, sccsize;
19518 const int * p, * w, * eos;
19524 if (lglval (lgl, root)) return stamp;
19525 uroot = lglulit (root);
19526 if (dfpr[uroot].discovered) return stamp;
19527 assert (!dfpr[uroot].finished);
19528 assert (lglmtwtk (work));
19529 assert (lglmtstk (units));
19530 assert (lglmtstk (sccs));
19531 assert (lglmtstk (trds));
19532 LOG (3, "stamping dfs %s %d %s",
19533 (lglunhdisroot (lgl, root, dfpr, irronly) ? "root" : "start"), root,
19534 irronly ? "only over irredundant clauses" :
19535 "also over redundant clauses");
19537 lglpushwtk (lgl, work, PREFIX, root, 0, 0);
19538 while (!lglmtwtk (work)) {
19539 INCSTEPS (unhd.steps);
19540 LGLPOPWTK (work, wrag, lit, other, red, removed);
19541 if (removed) continue;
19542 if (wrag == PREFIX) {
19543 ulit = lglulit (lit);
19544 if (dfpr[ulit].discovered) {
19545 dfopf[ulit].observed = stamp;
19546 LOG (3, "stamping %d observed %d", lit, stamp);
19549 assert (!dfpr[ulit].finished);
19550 dfpr[ulit].discovered = ++stamp;
19551 dfopf[ulit].observed = stamp;
19552 LOG (3, "stamping %d observed %d", lit, stamp);
19555 startstamp = stamp;
19556 LOG (3, "root %d with stamp %d", lit, startstamp);
19557 dfpr[ulit].root = lit;
19558 LOG (4, "stamping %d root %d", lit, lit);
19559 assert (!dfpr[ulit].parent);
19560 LOG (4, "stamping %d parent %d", lit, 0);
19562 LOG (4, "stamping %d discovered %d", lit, stamp);
19563 lglpushwtk (lgl, work, POSTFIX, lit, 0, 0);
19564 assert (dfopf[ulit].pushed < 0);
19565 dfopf[ulit].pushed = lglcntwtk (work);
19566 assert (!dfopf[ulit].flag);
19567 dfopf[ulit].flag = 1;
19568 lglpushstk (lgl, sccs, lit);
19569 hts = lglhts (lgl, -lit);
19570 w = lglhts2wchs (lgl, hts);
19571 eos = w + hts->count;
19572 for (undiscovered = 0; undiscovered <= 1 ; undiscovered++) {
19573 start = lglcntwtk (work);
19574 for (p = w; p < eos; p++) {
19576 tag = blit & MASKCS;
19577 if (tag == OCCS) continue;
19578 if (tag == TRNCS || tag == LRGCS) { p++; continue; }
19579 assert (tag == BINCS);
19580 red = blit & REDCS;
19581 if (irronly && red) continue;
19582 other = blit >> RMSHFT;
19583 if (lglval (lgl, other)) continue;
19584 uother = lglulit (other);
19585 if (undiscovered != !dfpr[uother].discovered) continue;
19586 // Kind of defensive, since 'lglrmbindup' should avoid it
19587 // and this fix may not really work anyhow since it does
19588 // not distinguish between irredundant and redundant clauses.
19589 // Thus we put a hard COVER here.
19590 COVER (lglsignedmarked (lgl, other) > 0);
19591 if (lglsignedmarked (lgl, other) > 0) {
19592 LOG (2, "stamping skips duplicated edge %d %d", lit, other);
19595 lglsignedmark (lgl, other);
19596 lglpushwtk (lgl, work, BEFORE, lit, other, red);
19598 end = lglcntwtk (work);
19599 for (r = work->start + start; r < work->top; r++)
19600 lglunmark (lgl, r->other);
19601 mod = (end - start);
19602 if (mod <= 1) continue;
19603 for (i = start; i < end - 1; i++) {
19604 assert (1 < mod && mod == (end - i));
19605 j = lglrand (lgl) % mod--;
19608 SWAP (Work, work->start[i], work->start[j]);
19611 } else if (wrag == BEFORE) { // before recursive call
19612 LOG (2, "stamping edge %d %d before recursion", lit, other);
19613 lglpushwtk (lgl, work, AFTER, lit, other, red);
19614 ulit = lglulit (lit);
19615 uother = lglulit (other);
19616 unotother = lglulit (-other);
19617 if (lgl->opts->unhdextstamp.val && (irronly || red) &&
19618 dfopf[uother].observed > dfpr[ulit].discovered) {
19619 LOG (2, "transitive edge %d %d during stamping", lit, other);
19620 lgl->stats->unhd.stamp.trds++;
19621 lgl->stats->prgss++;
19622 if (red) lgl->stats->unhd.tauts.red++;
19623 lglrmbcls (lgl, -lit, other, red);
19624 if ((pos = dfopf[unotother].pushed) >= 0) {
19625 while (pos < lglcntwtk (work)) {
19626 if (work->start[pos].lit != -other) break;
19627 if (work->start[pos].other == -lit) {
19628 LOG (3, "removing edge %d %d from DFS stack", -other, -lit);
19629 work->start[pos].removed = 1;
19635 assert (dfpr[uother].discovered); // and thus 'parent' + 'root' set
19638 observed = dfopf[unotother].observed;
19639 if (lgl->opts->unhdextstamp.val && startstamp <= observed) {
19640 LOG (1, "stamping failing edge %d %d", lit, other);
19642 dfpr[lglulit (failed)].discovered > observed;
19643 failed = dfpr[lglulit (failed)].parent)
19645 LOG (1, "stamping failed literal %d", failed);
19646 lglpushstk (lgl, units, -failed);
19647 lgl->stats->unhd.stamp.failed++;
19648 if (dfpr[unotother].discovered && !dfpr[unotother].finished) {
19649 LOG (2, "stamping skips edge %d %d after failed literal %d",
19650 lit, other, failed);
19655 if (!dfpr[uother].discovered) {
19656 dfpr[uother].parent = lit;
19657 LOG (4, "stamping %d parent %d", other, lit);
19658 dfpr[uother].root = root;
19659 LOG (4, "stamping %d root %d", other, root);
19660 lglpushwtk (lgl, work, PREFIX, other, 0, 0);
19662 } else if (wrag == AFTER) { // after recursive call
19663 LOG (2, "stamping edge %d %d after recursion", lit, other);
19664 uother = lglulit (other);
19665 ulit = lglulit (lit);
19666 if (lgl->opts->unhdextstamp.val && !dfpr[uother].finished &&
19667 dfpr[uother].discovered < dfpr[ulit].discovered) {
19668 LOG (2, "stamping back edge %d %d", lit, other);
19669 dfpr[ulit].discovered = dfpr[uother].discovered;
19670 LOG (3, "stamping %d reduced discovered to %d",
19671 lit, dfpr[ulit].discovered);
19672 if (dfopf[ulit].flag) {
19673 LOG (2, "stamping %d as being part of a non-trivial SCC", lit);
19674 dfopf[ulit].flag = 0;
19677 dfopf[uother].observed = stamp;
19678 LOG (3, "stamping %d observed %d", other, stamp);
19680 assert (wrag == POSTFIX);
19681 LOG (2, "stamping postfix %d", lit);
19682 ulit = lglulit (lit);
19683 if (dfopf[ulit].flag) {
19686 discovered = dfpr[ulit].discovered;
19688 other = lglpopstk (sccs);
19689 uother = lglulit (other);
19690 dfopf[uother].pushed = -1;
19691 dfopf[uother].flag = 0;
19692 dfpr[uother].discovered = discovered;
19693 dfpr[uother].finished = stamp;
19694 LOG (3, "stamping %d interval %d %d parent %d root %d",
19695 other, dfpr[uother].discovered, dfpr[uother].finished,
19696 dfpr[uother].parent, dfpr[uother].root);
19698 } while (other != lit);
19699 assert (lgl->opts->unhdextstamp.val || sccsize == 1);
19701 LOG (2, "stamping non trivial SCC of size %d", sccsize);
19702 lgl->stats->unhd.stamp.sumsccsizes += sccsize;
19703 lgl->stats->unhd.stamp.sccs++;
19705 } else assert (lgl->opts->unhdextstamp.val);
19708 assert (lglmtwtk (work));
19709 assert (lglmtstk (sccs));
19713 static int lglunhlca (LGL * lgl, const DFPR * dfpr, int a, int b) {
19714 const DFPR * c, * d;
19716 if (a == b) return a;
19717 u = lglulit (a), v = lglulit (b);
19718 c = dfpr + u, d = dfpr + v;
19719 if (c->discovered <= d->discovered) {
19722 assert (c->discovered > d->discovered);
19724 SWAP (const DFPR *, c, d);
19727 assert (c->discovered <= d->discovered);
19728 if (d->finished <= c->finished) break;
19734 LOG (3, "unhiding least common ancestor of %d and %d is %d", a, b, p);
19738 static int lglunhidefailed (LGL * lgl, const DFPR * dfpr) {
19739 int idx, sign, lit, unit, nfailed = 0;
19740 for (idx = 2; idx < lgl->nvars; idx++) {
19741 for (sign = -1; sign <= 1; sign += 2) {
19742 if (lglterminate (lgl)) return 0;
19743 if (!lglsyncunits (lgl)) return 0;
19744 INCSTEPS (unhd.steps);
19746 if (lglval (lgl, lit)) continue;
19747 if (!dfpr[lglulit (lit)].discovered) continue;
19748 if (lglunhimplincl (dfpr, lit, -lit)) {
19750 LOG (2, "unhiding %d implies %d", lit, -lit);
19751 } else if (lglunhimplincl (dfpr, -lit, lit)) {
19753 LOG (2, "unhiding %d implies %d", -lit, lit);
19755 LOG (1, "unhiding failed literal %d", -unit);
19756 lglunit (lgl, unit);
19757 lgl->stats->unhd.failed.lits++;
19759 if (lglbcp (lgl)) continue;
19760 LOG (1, "empty clause after propagating unhidden failed literal");
19766 LOG (1, "unhiding %d failed literals in this round", nfailed);
19770 static int lglunhroot (const DFPR * dfpr, int lit) {
19771 return dfpr[lglulit (lit)].root;
19774 static int lglunhidebintrn (LGL * lgl, const DFPR * dfpr, int irronly) {
19775 int idx, sign, lit, blit, tag, red, other, other2, unit, root, lca;
19776 int nbinred, ntrnred, nbinunits, ntrnunits, ntrnstr, ntrnhbrs;
19777 const int * p, * eow;
19782 nbinred = ntrnred = nbinunits = ntrnunits = ntrnstr = ntrnhbrs = 0;
19783 for (idx = 2; idx < lgl->nvars; idx++) {
19784 for (sign = -1; sign <= 1; sign += 2) {
19785 if (lglterminate (lgl)) return 0;
19786 if (!lglsyncunits (lgl)) return 0;
19787 INCSTEPS (unhd.steps);
19789 if (lglval (lgl, lit)) continue;
19790 ulit = lglulit (lit);
19791 if (!dfpr[ulit].discovered) continue;
19792 hts = lglhts (lgl, lit);
19793 w = lglhts2wchs (lgl, hts);
19794 eow = w + hts->count;
19796 for (p = w; p < eow; p++) {
19799 tag = blit & MASKCS;
19800 if (tag == TRNCS || tag == LRGCS) *q++ = *++p;
19801 if (tag == LRGCS) continue;
19802 red = blit & REDCS;
19803 other = blit >> RMSHFT;
19804 if (lglval (lgl, other)) continue;
19805 uother = lglulit (other);
19806 if (tag == BINCS) {
19807 if (lglunhimplies2 (dfpr, other, lit)) {
19808 LOG (2, "unhiding removal of literal %d "
19809 "with implication %d %d from binary clause %d %d",
19810 other, other, lit, lit, other);
19811 lgl->stats->unhd.units.bin++;
19815 lglunit (lgl, unit);
19817 while (p < eow) *q++ = *p++;
19818 lglshrinkhts (lgl, hts, hts->count - (p - q));
19819 if (lglbcp (lgl)) goto NEXTIDX;
19820 LOG (1, "empty clause after propagating unhidden lifted unit");
19824 } else if ((root = lglunhroot (dfpr, -lit)) &&
19825 !lglval (lgl, root) &&
19826 root == lglunhroot (dfpr, -other)) {
19827 LOG (2, "negated literals in binary clause %d %d implied by %d",
19829 lgl->stats->unhd.failed.bin++;
19830 lca = lglunhlca (lgl, dfpr, -lit, -other);
19834 } else if (!irronly && !red) continue;
19836 if (dfpr[uother].parent == -lit) continue;
19837 if (dfpr[ulit].parent == -other) continue;
19838 if (!lglunhimplies2 (dfpr, -lit, other)) continue;
19839 LOG (2, "unhiding tautological binary clause %d %d", lit, other);
19840 lgl->stats->unhd.tauts.bin++;
19841 lgl->stats->prgss++;
19842 if (red) lgl->stats->unhd.tauts.red++;
19844 lglrmbwch (lgl, other, lit, red);
19845 LOG (2, "removed %s binary clause %d %d",
19846 lglred2str (red), lit, other);
19847 lgldeclscnt (lgl, 2, red, 0);
19848 assert (!lgl->dense);
19852 assert (tag == TRNCS);
19854 if (lglval (lgl, other2)) continue;
19855 if (lglunhimplies2incl (dfpr, other, lit) &&
19856 lglunhimplies2incl (dfpr, other2, lit)) {
19858 "unhiding removal of literals %d and %d with implications "
19859 "%d %d and %d %d from ternary clause %d %d %d",
19863 lit, other, other2);
19864 lgl->stats->unhd.str.trn += 2;
19865 if (red) lgl->stats->unhd.str.red += 2;
19866 lgl->stats->unhd.units.trn++;
19870 } else if ((root = lglunhroot (dfpr, -lit)) &&
19871 !lglval (lgl, root) &&
19872 root == lglunhroot (dfpr, -other) &&
19873 root == lglunhroot (dfpr, -other2)) {
19875 "negation of literals in ternary clauses %d %d %d "
19876 "implied by %d", lit, other, other2, root);
19877 lgl->stats->unhd.failed.trn++;
19878 lca = lglunhlca (lgl, dfpr, -lit, -other);
19880 lca = lglunhlca (lgl, dfpr, lca, -other2);
19884 } else if ((red || irronly) &&
19885 (lglunhimplies2incl (dfpr, -lit, other) ||
19886 lglunhimplies2incl (dfpr, -lit, other2))) {
19888 if (!lgl->opts->unhdatrn.val) continue;
19889 if (red && lgl->opts->unhdatrn.val == 1) continue;
19891 LOG (2, "unhiding %s tautological ternary clause %d %d %d",
19892 lglred2str (red), lit, other, other2);
19893 lgl->stats->unhd.tauts.trn++;
19894 lgl->stats->prgss++;
19895 if (red) lgl->stats->unhd.tauts.red++;
19897 lglrmtwch (lgl, other, lit, other2, red);
19898 lglrmtwch (lgl, other2, lit, other, red);
19899 LOG (2, "removed %s ternary clause %d %d %d",
19900 lglred2str (red), lit, other, other2);
19901 lgldeclscnt (lgl, 3, red, 0);
19902 assert (!lgl->dense);
19903 if (!red && lgl->opts->move.val >= 2) {
19906 assert (q[-2] == blit);
19907 assert (q[-1] == other2);
19909 delta = lglwchtrn (lgl, other, lit, other2, REDCS);
19910 delta += lglwchtrn (lgl, other2, lit, other, REDCS);
19911 if (delta) w += delta, eow += delta, p += delta, q += delta;
19912 LOG (2, "moved ternary clause %d %d %d", lit, other, other2);
19913 lgl->stats->red.trn++, assert (lgl->stats->red.trn > 0);
19914 lgl->stats->moved.trn++;
19916 } else if (lglunhimplies2incl (dfpr, other2, lit)) {
19919 "unhiding removal of literal %d with implication "
19920 "%d %d from ternary clause %d %d %d",
19921 other2, other2, lit, lit, other, other2);
19922 lgl->stats->unhd.str.trn++;
19923 lgl->stats->prgss++;
19924 if (red) lgl->stats->unhd.str.red++;
19926 lglrmtwch (lgl, other, lit, other2, red);
19927 lglrmtwch (lgl, other2, lit, other, red);
19928 LOG (2, "removed %s ternary clause %d %d %d",
19929 lglred2str (red), lit, other, other2);
19930 lgldeclscnt (lgl, 3, red, 0);
19931 if (!red) lglincirr (lgl, 2);
19932 else lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
19933 delta = lglwchbin (lgl, other, lit, red);
19934 if (delta) { p += delta, q += delta, eow += delta, w += delta; }
19935 (--q)[-1] = red | BINCS | (other << RMSHFT);
19936 if (lgl->opts->drup.val) lgldrupclsarg (lgl, lit, other, 0);
19937 #ifndef NLGLPICOSAT
19938 lglpicosatchkclsarg (lgl, lit, other, 0);
19941 } else if (lglunhimplies2incl (dfpr, other, lit)) {
19942 SWAP (int, other, other2);
19944 } else if (lgl->opts->unhdhbr.val &&
19945 (root = lglunhroot (dfpr, -lit)) &&
19946 !lglval (lgl, root)) {
19947 if (root == lglunhroot (dfpr, -other2)) {
19948 lca = lglunhlca (lgl, dfpr, -lit, -other2);
19949 } else if (root == lglunhroot (dfpr, -other)) {
19950 lca = lglunhlca (lgl, dfpr, -lit, -other);
19951 SWAP (int, other, other2);
19952 } else if (lglunhimplies2incl (dfpr, root, -other2)) lca = root;
19953 else if (lglunhimplies2incl (dfpr, root, -other)) {
19955 SWAP (int, other, other2);
19958 if (abs (lca) == abs (lit)) continue;
19959 if (abs (lca) == abs (other)) continue;
19960 if (abs (lca) == abs (other2)) continue;
19961 if (lglunhimplies2incl (dfpr, lca, other)) continue;
19963 "negations of literals %d %d in ternary clause %d %d %d "
19964 "implied by %d", lit, other2, lit, other, other2, lca);
19965 lgl->stats->unhd.hbrs.trn++;
19966 if (red) lgl->stats->unhd.hbrs.red++;
19967 lgl->stats->prgss++;
19969 LOG (2, "unhidden hyper binary resolved clause %d %d",-lca,other);
19970 if (lgl->opts->drup.val) lgldrupclsarg (lgl, -lca, other, 0);
19971 #ifndef NLGLPICOSAT
19972 lglpicosatchkclsarg (lgl, -lca, other, 0);
19974 assert (lca != -lit);
19975 lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
19976 delta = lglwchbin (lgl, -lca, other, REDCS);
19977 if (delta) { p += delta, q += delta, eow += delta, w += delta; }
19978 delta = lglwchbin (lgl, other, -lca, REDCS);
19979 if (delta) { p += delta, q += delta, eow += delta, w += delta; }
19983 lglshrinkhts (lgl, hts, hts->count - (p - q));
19988 if (nbinred) LOG (2, "unhiding %d tautological binary clauses", nbinred);
19989 if (nbinunits) LOG (2, "unhiding %d units in binary clauses", nbinunits);
19990 if (ntrnred) LOG (2, "unhiding %d tautological ternary clauses", ntrnred);
19991 if (ntrnstr) LOG (2, "unhiding %d strengthened ternary clauses", ntrnstr);
19992 if (ntrnunits) LOG (2, "unhiding %d units in ternary clauses", ntrnunits);
19993 if (ntrnstr) LOG (2,
19994 "unhidden %d hyper binary resolution from ternary clauses", ntrnhbrs);
19998 static int lglcmpdfl (const DFL * a, const DFL * b) {
19999 return a->discovered - b->discovered;
20002 static int lglunhideglue (LGL * lgl, const DFPR * dfpr, int glue, int irronly) {
20003 DFL * dfl, * eodfl, * d, * e; int szdfl, posdfl, negdfl, ndfl, res;
20004 int oldsize, newsize, hastobesatisfied, satisfied, tautological;
20005 int watched, lit, ulit, val, sign, nonfalse, root, lca, unit;
20006 int ntaut = 0, nstr = 0, nunits = 0, nhbrs = 0, lidx;
20007 int * p, * q, * c, * eoc, red;
20008 int lca1, lca2, root1, root2;
20012 if (glue < 0) sprintf (type, "irredundant");
20013 else sprintf (type, "redundant glue %d", glue);
20016 assert (-1 <= glue && glue < MAXGLUE);
20021 lits = lgl->red + glue;
20025 dfl = 0; szdfl = 0;
20026 // go through all clauses of this glue and for each do:
20028 // SHRINK simplify clause according to current assignment
20029 // FAILED check if it is a hidden failed literal
20030 // HTE check if it is a hidden tautology
20031 // STRNEG remove hidden literals using complement literals
20032 // STRPOS remove hidden literals using positive literals
20033 // HBR perform unhiding hyper binary resolution
20034 // NEXT clean up, unwatch if necessary, reconnect bin/trn, bcp unit
20036 for (c = lits->start; !lgl->mt && c < lits->top; c = eoc + 1) {
20037 if (lglterminate (lgl) || !lglsyncunits (lgl)) { res = 0; break; }
20038 if ((lit = *(eoc = c)) >= NOTALIT) continue;
20039 INCSTEPS (unhd.steps);
20040 lidx = c - lits->start;
20041 if (red) { lidx <<= GLUESHFT; lidx |= glue; }
20043 while (*eoc) eoc++;
20046 unit = hastobesatisfied = satisfied = tautological = ndfl = 0;
20047 //SHRINK: check satisfied + remove false literals + count visited
20049 nonfalse = posdfl = negdfl = 0;
20050 for (p = c; p < eoc; p++) {
20052 val = lglval (lgl, lit);
20060 *q++ = lit; // watched, so have to keep it
20061 hastobesatisfied = 1; // for assertion checking only
20067 if (dfpr[lglulit (lit)].discovered) posdfl++; // count pos in BIG
20068 if (dfpr[lglulit (-lit)].discovered) negdfl++; // count neg in BIG
20071 assert (eoc - c >= 2); // we assume bcp done before
20072 ndfl = posdfl + negdfl; // number of literals in BIG
20073 if (hastobesatisfied) assert (satisfied);
20074 if (satisfied || ndfl < 2) goto NEXT;
20075 assert (nonfalse = eoc - c);
20076 assert (nonfalse >= negdfl);
20077 //FAILED: find root implying all negated literals
20078 if (nonfalse != negdfl) goto HTE; // not enough complement lits in BIG
20080 root = lglunhroot (dfpr, -*c);
20081 if (lglval (lgl, root)) goto HTE;
20082 for (p = c + 1; p < eoc && lglunhroot (dfpr, -*p) == root; p++)
20084 if (p < eoc) goto HTE; // at least two roots
20085 LOGCLS (2, c, "unhiding failed literal through large %s clause",type);
20086 LOG (2, "unhiding that all negations are implied by root %d", root);
20088 for (p = c + 1; p < eoc; p++)
20089 lca = lglunhlca (lgl, dfpr, -*p, lca);
20090 assert (!lglval (lgl, lca));
20091 LOG (2, "unhiding failed large %s clause implied by LCA %d", type, lca);
20092 lgl->stats->unhd.failed.lrg++;
20094 goto NEXT; // otherwise need to properly unwatch and restart etc.
20095 // which is too difficult to implement so leave further
20096 // simplification of this clause to next unhiding round
20098 if (glue < 0 && !irronly) goto STRNEG; // skip tautology checking if
20099 // redundant clauses used and
20100 // we work on irredundant clauses
20101 if (posdfl < 2 || negdfl < 2) goto STRNEG;
20102 if (ndfl > szdfl) { RSZ (dfl, szdfl, ndfl); szdfl = ndfl; }
20104 // copy all literals and their complements to 'dfl'
20105 for (p = c; p < eoc; p++) {
20106 for (sign = -1; sign <= 1; sign += 2) {
20108 ulit = lglulit (sign * lit);
20109 if (!dfpr[ulit].discovered) continue; // not in BIG so skip
20110 assert (ndfl < szdfl);
20111 dfl[ndfl].discovered = dfpr[ulit].discovered;
20112 dfl[ndfl].finished = dfpr[ulit].finished;
20113 dfl[ndfl].sign = sign;
20115 dfl[ndfl].lit4logging = lit;
20120 ADDSTEPS (unhd.steps, 6); // rough guess
20121 SORT (DFL, dfl, ndfl, lglcmpdfl);
20122 eodfl = dfl + ndfl;
20123 // Now check if there are two consecutive literals, the first
20124 // a complement of a literal in the clause, which implies another
20125 // literal actually occurring positive in the clause, where
20126 // 'd' ranges over complement literals
20127 // 'e' ranges over original literals
20128 for (d = dfl; d < eodfl - 1; d++)
20129 if (d->sign < 0) break; // get first negative pos
20130 while (d < eodfl - 1) {
20131 assert (d->sign < 0);
20132 for (e = d + 1; e < eodfl && e->finished < d->finished; e++) {
20133 if (e->sign < 0) continue; // get next positive pos
20134 assert (d->sign < 0 && e->sign > 0);
20135 assert (d->discovered <= e->discovered);
20136 assert (e ->finished <= d->finished);
20138 "unhiding with implication %d %d tautological %s clause",
20139 -d->lit4logging, e->lit4logging, type);
20141 lgl->stats->unhd.tauts.lrg++;
20142 if (red) lgl->stats->unhd.tauts.red++;
20143 lgl->stats->prgss++;
20147 for (d = e; d < eodfl && d->sign > 0; d++)
20151 if (negdfl < 2) goto STRPOS;
20152 if (negdfl > szdfl) { RSZ (dfl, szdfl, negdfl); szdfl = negdfl; }
20153 INCSTEPS (unhd.steps);
20155 // copy complement literals to 'dfl'
20156 for (p = c; p < eoc; p++) {
20158 ulit = lglulit (-lit); // NOTE: '-lit' not 'lit'
20159 if (!dfpr[ulit].discovered) continue;
20160 assert (ndfl < szdfl);
20161 dfl[ndfl].discovered = dfpr[ulit].discovered; // of '-lit'
20162 dfl[ndfl].finished = dfpr[ulit].finished; // of '-lit'
20163 dfl[ndfl].lit = lit; // NOTE: but 'lit' here
20166 if (ndfl < 2) goto STRPOS;
20167 ADDSTEPS (unhd.steps, 3); // rough guess
20168 SORT (DFL, dfl, ndfl, lglcmpdfl);
20169 eodfl = dfl + ndfl;
20170 for (d = dfl; d < eodfl - 1; d = e) {
20171 assert (d->discovered);
20172 for (e = d + 1; e < eodfl && d->finished >= e->finished; e++) {
20173 assert (d->discovered <= e->discovered);
20176 "unhiding removal of literal %d "
20177 "with implication %d %d from large %s clause",
20178 lit, -d->lit, -e->lit, type);
20181 lgl->stats->unhd.str.lrg++;
20182 if (red) lgl->stats->unhd.str.red++;
20183 lgl->stats->prgss++;
20184 if (!watched) continue;
20185 if (lit != c[0] && lit != c[1]) continue;
20186 lglrmlwch (lgl, c[0], red, lidx);
20187 lglrmlwch (lgl, c[1], red, lidx);
20191 assert (eoc - c >= 1 );
20193 if (watched) q += 2; // keep watched literals
20194 // if we still watch
20195 // move non BIG literals
20196 for (p = q; p < eoc; p++) {
20198 ulit = lglulit (-lit); // NOTE: '-lit' not 'lit'
20199 if (dfpr[ulit].discovered) continue;
20202 // copy from 'dfl' unremoved BIG literals back to clause
20203 for (d = dfl; d < eodfl; d++) {
20205 if (!lit) continue;
20206 if (watched && lit == c[0]) continue;
20207 if (watched && lit == c[1]) continue;
20212 if (posdfl < 2) goto HBR;
20213 if (posdfl > szdfl) { RSZ (dfl, szdfl, posdfl); szdfl = posdfl; }
20215 // copy original literals to 'dfl' but sort reverse wrt 'discovered'
20216 for (p = c; p < eoc; p++) {
20218 ulit = lglulit (lit); // NOTE: now 'lit'
20219 if (!dfpr[ulit].discovered) continue;
20220 assert (ndfl < szdfl);
20221 dfl[ndfl].discovered = -dfpr[ulit].discovered; // of 'lit'
20222 dfl[ndfl].finished = -dfpr[ulit].finished; // of 'lit'
20223 dfl[ndfl].lit = lit;
20226 if (ndfl < 2) goto NEXT;
20227 ADDSTEPS (unhd.steps, 3); // rough guess
20228 SORT (DFL, dfl, ndfl, lglcmpdfl);
20229 eodfl = dfl + ndfl;
20230 for (d = dfl; d < eodfl - 1; d = e) {
20231 assert (d->discovered);
20232 for (e = d + 1; e < eodfl && d->finished >= e->finished; e++) {
20233 assert (d->discovered <= e->discovered);
20236 "unhiding removal of literal %d "
20237 "with implication %d %d from large %s clause",
20238 lit, e->lit, d->lit, type);
20241 lgl->stats->unhd.str.lrg++;
20242 if (red) lgl->stats->unhd.str.red++;
20243 lgl->stats->prgss++;
20244 if (!watched) continue;
20245 if (lit != c[0] && lit != c[1]) continue;
20246 lglrmlwch (lgl, c[0], red, lidx);
20247 lglrmlwch (lgl, c[1], red, lidx);
20251 assert (eoc - c >= 1 );
20253 if (watched) q += 2;
20254 for (p = q; p < eoc; p++) {
20256 ulit = lglulit (lit); // NOTE: now 'lit'
20257 if (dfpr[ulit].discovered) continue;
20260 for (d = dfl; d < eodfl; d++) {
20262 if (!lit) continue;
20263 if (watched && lit == c[0]) continue;
20264 if (watched && lit == c[1]) continue;
20269 if (!lgl->opts->unhdhbr.val) goto NEXT;
20270 if (eoc - c < 3) goto NEXT;
20271 root1 = root2 = lca1 = lca2 = 0;
20272 for (p = c; (lit = *p); p++) {
20273 root = lglunhroot (dfpr, -lit);
20274 if (!root) root = -lit;
20275 if (!root1) { root1 = root; continue; }
20276 if (root1 == root) continue;
20277 if (!root2) { root2 = root; continue; }
20278 if (root2 == root) continue;
20279 if (lglunhimplies2incl (dfpr, root1, -lit)) { lca1 = root1; continue; }
20280 if (lglunhimplies2incl (dfpr, root2, -lit)) { lca2 = root2; continue; }
20281 goto NEXT; // else more than two roots ...
20284 if (!root2) goto NEXT;
20285 if (root1 == -root2) goto NEXT;
20286 if (lglunhimplies2incl (dfpr, root1, -root2)) goto NEXT;
20287 LOGCLS (2, c, "root hyper binary resolution %d %d of %s clause",
20288 -root1, -root2, type);
20289 if (!lca1 && !lca2) {
20290 for (p = c; (lit = *p); p++) {
20291 root = lglunhroot (dfpr, -lit);
20294 lca1 = lca1 ? lglunhlca (lgl, dfpr, lca1, -lit) : -lit;
20296 lca2 = lca2 ? lglunhlca (lgl, dfpr, lca2, -lit) : -lit;
20299 if (lca1) lca2 = -lit; else lca1 = -lit;
20303 if (!lca1) lca1 = root1;
20304 if (!lca2) lca2 = root2;
20306 if (lca1 == -lca2) goto NEXT;
20307 if (lglunhimplies2incl (dfpr, lca1, -lca2)) goto NEXT;
20308 LOGCLS (2, c, "lca hyper binary resolution %d %d of %s clause",
20309 -lca1, -lca2, type);
20310 lgl->stats->unhd.hbrs.lrg++;
20311 if (red) lgl->stats->unhd.hbrs.red++;
20312 if (lgl->opts->drup.val) lgldrupclsarg (lgl, -lca1, -lca2, 0);
20313 #ifndef NLGLPICOSAT
20314 lglpicosatchkclsarg (lgl, -lca1, -lca2, 0);
20316 lglwchbin (lgl, -lca1, -lca2, REDCS);
20317 lglwchbin (lgl, -lca2, -lca1, REDCS);
20318 lgl->stats->red.bin++;
20319 assert (lgl->stats->red.bin > 0);
20322 assert (satisfied || tautological || newsize >= 1);
20323 if (newsize <= 3 || satisfied || tautological) {
20324 lgldeclscnt (lgl, oldsize, red, glue);
20326 lglrmlwch (lgl, c[0], red, lidx);
20327 lglrmlwch (lgl, c[1], red, lidx);
20330 assert (lgl->stats->irr.lits.cur >= c + oldsize - eoc);
20331 lgl->stats->irr.lits.cur -= c + oldsize - eoc;
20334 for (p = c + oldsize; p > eoc; p--) *p = REMOVED;
20335 if (satisfied || tautological) {
20336 while (p >= c) *p-- = REMOVED;
20337 if (red) { LGLCHKACT (c[-1]); c[-1] = REMOVED; }
20341 if (newsize < oldsize) {
20342 if (lgl->opts->drup.val) lgldrupclsaux (lgl, c);
20343 #ifndef NLGLPICOSAT
20344 lglpicosatchkclsaux (lgl, c);
20347 if (red && newsize <= 3) { LGLCHKACT (c[-1]); c[-1] = REMOVED; }
20348 if (newsize > 3 && !watched) {
20349 (void) lglwchlrg (lgl, c[0], c[1], red, lidx);
20350 (void) lglwchlrg (lgl, c[1], c[0], red, lidx);
20351 } else if (newsize == 3) {
20352 LOGCLS (2, c, "large %s clause became ternary", type);
20353 lglwchtrn (lgl, c[0], c[1], c[2], red);
20354 lglwchtrn (lgl, c[1], c[0], c[2], red);
20355 lglwchtrn (lgl, c[2], c[0], c[1], red);
20356 if (!red) lglincirr (lgl, 3);
20357 else lgl->stats->red.trn++, assert (lgl->stats->red.trn > 0);
20358 c[0] = c[1] = c[2] = *eoc = REMOVED;
20359 } else if (newsize == 2) {
20360 LOGCLS (2, c, "large %s clause became binary", type);
20361 lglwchbin (lgl, c[0], c[1], red);
20362 lglwchbin (lgl, c[1], c[0], red);
20363 if (!red) lglincirr (lgl, 2);
20364 else lgl->stats->red.bin++, assert (lgl->stats->red.bin > 0);
20365 c[0] = c[1] = *eoc = REMOVED;
20366 } else if (newsize == 1) {
20367 LOGCLS (2, c, "large %s clause became unit", type);
20368 unit = c[0]; // even works if unit already set
20369 c[0] = *eoc = REMOVED;
20370 lgl->stats->unhd.units.lrg++;
20373 if (!unit) continue;
20374 lglunit (lgl, unit);
20375 if (lglbcp (lgl)) continue;
20378 LOG (1, "unhiding large clause produces empty clause");
20382 LOG (1, "unhiding %d units from large %s clauses", nunits, type);
20384 LOG (1, "unhiding %d large tautological %s clauses", ntaut, type);
20386 LOG (1, "unhiding removal of %d literals in %s clauses", nstr, type);
20388 LOG (1, "unhiding %d hyper binary resolutions in %s clauses", nhbrs, type);
20389 if (dfl) DEL (dfl, szdfl);
20393 static void lglfixlrgwchs (LGL * lgl) {
20394 int idx, sign, lit, blit, tag, red, lidx, fixed;
20395 const int * p, * eow, * c;
20399 for (idx = 2; idx < lgl->nvars; idx++) {
20400 for (sign = -1; sign <= 1; sign += 2) {
20402 hts = lglhts (lgl, lit);
20403 w = lglhts2wchs (lgl, hts);
20404 eow = w + hts->count;
20406 for (p = w; p < eow; p++) {
20408 tag = blit & MASKCS;
20409 if (tag == BINCS) { *q++ = blit; continue; }
20411 if (tag == TRNCS) { *q++ = blit; *q++ = lidx; continue; }
20412 assert (tag == LRGCS);
20413 red = blit & REDCS;
20414 c = lglidx2lits (lgl, red, lidx);
20415 if (*c >= NOTALIT) { fixed++; continue; }
20419 lglshrinkhts (lgl, hts, hts->count - (p - q));
20422 assert (!(fixed & 1));
20423 if (fixed) LOG (1, "fixed %d large watches", fixed);
20426 static int lglunhidelrg (LGL * lgl, const DFPR * dfpr, int irronly) {
20428 for (glue = -1; res && glue < MAXGLUE; glue++)
20429 res = lglunhideglue (lgl, dfpr, glue, irronly);
20430 lglfixlrgwchs (lgl);
20434 static int lglunhdunits (LGL * lgl) {
20435 int res = lgl->stats->unhd.units.bin;
20436 res += lgl->stats->unhd.units.trn;
20437 res += lgl->stats->unhd.units.lrg;
20441 static int lglunhdfailed (LGL * lgl) {
20442 int res = lgl->stats->unhd.stamp.failed;
20443 res += lgl->stats->unhd.failed.lits;
20444 res += lgl->stats->unhd.failed.bin;
20445 res += lgl->stats->unhd.failed.trn;
20446 res += lgl->stats->unhd.failed.lrg;
20450 static int lglunhdhbrs (LGL * lgl) {
20451 int res = lgl->stats->unhd.hbrs.trn;
20452 res += lgl->stats->unhd.hbrs.lrg;
20456 static int lglunhdtauts (LGL * lgl) {
20457 int res = lgl->stats->unhd.stamp.trds;
20458 res += lgl->stats->unhd.tauts.bin;
20459 res += lgl->stats->unhd.tauts.trn;
20460 res += lgl->stats->unhd.tauts.lrg;
20464 static int lglunhdstrd (LGL * lgl) {
20465 int res = lgl->stats->unhd.units.bin; // shared!
20466 res += lgl->stats->unhd.str.trn;
20467 res += lgl->stats->unhd.str.lrg;
20471 static void lglrmbindup (LGL * lgl) {
20472 int idx, sign, lit, blit, tag, red, other, round, redrem, irrem;
20473 int * w, * eow, * p, * q;
20475 redrem = irrem = 0;
20476 for (idx = 2; idx < lgl->nvars; idx++) {
20477 for (sign = -1; sign <= 1; sign += 2) {
20479 assert (lglmtstk (&lgl->seen));
20480 for (round = 0; round < 2; round++) {
20481 hts = lglhts (lgl, lit);
20482 w = lglhts2wchs (lgl, hts);
20483 eow = w + hts->count;
20485 for (p = w; p < eow; p++) {
20487 tag = blit & MASKCS;
20488 if (tag != BINCS) *q++ = blit;
20489 if (tag== LRGCS || tag == TRNCS) *q++ = *++p;
20490 if (tag != BINCS) continue;
20491 red = blit & REDCS;
20492 other = blit >> RMSHFT;
20493 if (lglsignedmarked (lgl, other)) {
20494 if (round && !red) goto ONLYCOPY;
20495 if (red) redrem++; else irrem++;
20496 if (abs (lit) > abs (other)) {
20498 "removing duplicated %s binary clause %d %d and 2nd watch %d",
20499 lglred2str (red), lit, other, other);
20500 lgldeclscnt (lgl, 2, red, 0);
20501 if (!red && lgl->dense)
20502 lgldecocc (lgl, lit), lgldecocc (lgl, other);
20503 lgl->stats->bindup.removed++;
20504 if (red) lgl->stats->bindup.red++;
20507 "removing 1st watch %d of duplicated %s binary clause %d %d",
20508 other, lglred2str (red), other, lit);
20510 if ((!round && !red) || (round && red))
20511 lglsignedmarknpushseen (lgl, other);
20516 lglshrinkhts (lgl, hts, hts->count - (p - q));
20518 lglpopnunmarkstk (lgl, &lgl->seen);
20521 assert (!(irrem & 1));
20522 assert (!(redrem & 1));
20525 static DFPR * lglstampall (LGL * lgl, int irronly) {
20526 int roots, searches, noimpls, unassigned, visited;
20527 unsigned pos, delta, mod, ulit, first, last, count;
20528 int root, stamp, rootsonly, lit;
20529 Stk units, sccs, trds;
20530 DFOPF * dfopf, * q;
20534 if (lgl->nvars <= 2) return 0;
20536 NEW (dfpr, 2*lgl->nvars);
20537 NEW (dfopf, 2*lgl->nvars);
20538 CLR (work); CLR (sccs); CLR (trds); CLR (units);
20539 for (q = dfopf; q < dfopf + 2*lgl->nvars; q++) q->pushed = -1;
20540 searches = roots = noimpls = unassigned = stamp = visited = 0;
20541 for (rootsonly = 1; rootsonly >= 0; rootsonly--) {
20543 first = mod = 2*(lgl->nvars - 2);
20545 pos = lglrand (lgl) % mod;
20546 delta = lglrand (lgl) % mod;
20547 if (!delta) delta++;
20548 while (lglgcd (delta, mod) > 1)
20549 if (++delta == mod) delta = 1;
20550 LOG (2, "unhiding %s round start %u delta %u mod %u",
20551 (rootsonly ? "roots-only": "non-root"), pos, delta, mod);
20553 if (lglterminate (lgl)) { searches = 0; goto DONE; }
20554 if (!lglsyncunits (lgl)) { assert (lgl->mt); goto DONE; }
20556 root = lglilit (ulit);
20557 INCSTEPS (unhd.steps);
20559 if (lglval (lgl, root)) goto CONTINUE;
20560 if (rootsonly) unassigned++;
20561 if (dfpr[lglulit (root)].discovered) goto CONTINUE;
20563 !lglunhdisroot (lgl, root, dfpr, irronly)) goto CONTINUE;
20564 if (!lglunhdhasbins (lgl, dfpr, -root, irronly)) {
20565 if (rootsonly) noimpls++; goto CONTINUE;
20567 if (rootsonly) roots++;
20569 assert (lglmtstk (&units));
20570 stamp = lglstamp (lgl, root, dfpr, dfopf,
20571 &work, &units, &sccs, &trds, &visited,
20573 while (!lglmtstk (&units)) {
20574 lit = lglpopstk (&units);
20575 val = lglval (lgl, lit);
20576 if (val > 0) continue;
20579 LOG (1, "unhidding stamp unit %d already false", lit);
20583 lglunit (lgl, lit);
20584 if (!lglbcp (lgl)) {
20586 LOG (1, "propagating unhidden stamp unit %d failed", lit);
20594 if (pos >= mod) pos -= mod;
20595 if (pos == first) { assert (count == mod); break; }
20596 if (mod == 1) break;
20597 if (first == mod) first = last;
20600 assert (searches >= roots);
20602 "[unhd-%d-%d] %d unassigned variables out of %d (%.0f%%)",
20603 lgl->stats->unhd.count, lgl->stats->unhd.rounds,
20604 lgl->unassigned, lgl->nvars - 2,
20605 lglpcnt (lgl->unassigned, lgl->nvars - 2));
20607 "[unhd-%d-%d] %d root literals out of %d (%.0f%%)",
20608 lgl->stats->unhd.count, lgl->stats->unhd.rounds,
20609 roots, unassigned, lglpcnt (roots, unassigned));
20611 "[unhd-%d-%d] %d additional non-root searches out of %d (%.0f%%)",
20612 lgl->stats->unhd.count, lgl->stats->unhd.rounds,
20613 searches - roots, unassigned,
20614 lglpcnt (searches - roots, unassigned));
20616 "[unhd-%d-%d] %d literals not in F2 out of %d (%.0f%%)",
20617 lgl->stats->unhd.count, lgl->stats->unhd.rounds,
20618 noimpls, unassigned, lglpcnt (noimpls, unassigned));
20620 "[unhd-%d-%d] %d visited literals out of %d (%.0f%%)",
20621 lgl->stats->unhd.count, lgl->stats->unhd.rounds,
20622 visited, unassigned, lglpcnt (visited, unassigned));
20624 "[unhd-%d-%d] %.2f average number visited literals per search",
20625 lgl->stats->unhd.count, lgl->stats->unhd.rounds,
20626 lglavg (visited, searches));
20628 if (!searches || lgl->mt) { DEL (dfpr, 2*lgl->nvars); dfpr = 0; }
20629 lglrelwtk (lgl, &work);
20630 lglrelstk (lgl, &units);
20631 lglrelstk (lgl, &sccs);
20632 lglrelstk (lgl, &trds);
20633 DEL (dfopf, 2*lgl->nvars);
20637 static void lglsetunhdlim (LGL * lgl) {
20638 int64_t limit, irrlim;
20640 limit = (lgl->opts->unhdreleff.val*lglvisearch (lgl))/1000;
20641 if (limit < lgl->opts->unhdmineff.val) limit = lgl->opts->unhdmineff.val;
20642 if (lgl->opts->unhdmaxeff.val >= 0 && limit > lgl->opts->unhdmaxeff.val)
20643 limit = lgl->opts->unhdmaxeff.val;
20644 limit >>= (pen = lgl->limits->unhd.pen + lglszpen (lgl));
20645 irrlim = lgl->stats->irr.clauses.cur/2;
20646 irrlim >>= lgl->limits->simp.pen;
20647 if (lgl->opts->irrlim.val && limit < irrlim) {
20650 "[unhide-%d] limit %lld based on %d irredundant clauses",
20651 lgl->stats->unhd.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
20653 lglprt (lgl, 1, "[unhide-%d] limit %lld with penalty %d = %d + %d",
20654 lgl->stats->unhd.count, (LGLL) limit,
20655 pen, lgl->limits->unhd.pen, lglszpen (lgl));
20656 lgl->limits->unhd.steps = lgl->stats->unhd.steps + limit;
20659 static int lglunhide (LGL * lgl) {
20660 int irronly, round, maxrounds, noprgssrounds, success;
20661 int oldunits, oldfailed, oldtauts, oldhbrs, oldstrd;
20662 int deltaunits, deltafailed;
20663 int64_t roundprgss = 0;
20665 assert (lgl->opts->unhide.val);
20666 if (lgl->nvars <= 2) return 1;
20667 lgl->stats->unhd.count++;
20668 assert (!lgl->unhiding);
20670 assert (!lgl->simp);
20672 lglstart (lgl, &lgl->times->unhd);
20673 irronly = !lgl->stats->red.bin || (lgl->stats->unhd.count & 1);
20674 if (lgl->level > 0) lglbacktrack (lgl, 0);
20675 maxrounds = lgl->opts->unhdroundlim.val;
20676 lglsetunhdlim (lgl);
20677 oldunits = lglunhdunits (lgl);
20678 oldfailed = lglunhdfailed (lgl);
20679 oldtauts = lglunhdtauts (lgl);
20680 oldhbrs = lglunhdhbrs (lgl);
20681 oldstrd = lglunhdstrd (lgl);
20682 noprgssrounds = round = 0;
20684 if (round >= maxrounds) break;
20686 roundprgss == lgl->stats->prgss &&
20687 noprgssrounds++ == lgl->opts->unhdlnpr.val) {
20688 LOG (1, "too many non progress unhiding rounds");
20692 roundprgss = lgl->stats->prgss;
20693 lgl->stats->unhd.rounds++;
20695 if (!lgl->nvars || lgl->mt) break;
20697 dfpr = lglstampall (lgl, irronly);
20699 if (!lglunhidefailed (lgl, dfpr)) break;
20700 if (!lglunhidebintrn (lgl, dfpr, irronly)) break;
20701 if (!lglunhidelrg (lgl, dfpr, irronly)) break;
20702 if (lgl->stats->unhd.steps >= lgl->limits->unhd.steps) break;
20703 irronly = !lgl->stats->red.bin || !irronly;
20704 DEL (dfpr, 2*lgl->nvars);
20707 if (dfpr) DEL (dfpr, 2*lgl->nvars);
20709 "[unhide-%d-%d] %d units, %d failed, %d tauts, %d hbrs, %d literals",
20710 lgl->stats->unhd.count, lgl->stats->unhd.rounds,
20711 (deltaunits = lglunhdunits (lgl) - oldunits),
20712 (deltafailed = lglunhdfailed (lgl) - oldfailed),
20713 lglunhdtauts (lgl) - oldtauts,
20714 lglunhdhbrs (lgl) - oldhbrs,
20715 lglunhdstrd (lgl) - oldstrd);
20716 success = deltaunits + deltafailed;
20717 LGLUPDPEN (unhd, success);
20718 assert (lgl->simp);
20720 assert (lgl->unhiding);
20722 lglrep (lgl, 2, 'u');
20727 static int lglpar64 (uint64_t i) {
20730 for (x = i; x; x = x & (x - 1))
20735 static uint64_t lgldec64 (uint64_t i) {
20737 for (res = i - 1; lglpar64 (res); res--)
20742 static void lglgdump (LGL * lgl) {
20744 const int * p, * start, * top;
20745 start = lgl->gauss->xors.start;
20746 top = lgl->gauss->xors.top;
20747 for (p = start; p < top; p++) {
20748 if (*p >= NOTALIT) continue;
20749 fprintf (lgl->out, "c eqn[%lld]", (LGLL)(p - start));
20750 while (*p > 1) fprintf (lgl->out, " %d", *p++);
20751 fprintf (lgl->out, " = %d\n", *p);
20756 static int lglgaussubclsaux (LGL * lgl, uint64_t signs, const int * c) {
20757 int lit, i, min, minocc, tmpocc, blit, tag, other, other2, red, lidx;
20758 const int * p, * w, * eow, * d, * q;
20760 assert (lgl->dense);
20763 INCSTEPS (gauss.steps.extr);
20764 for (p = c; (lit = *p); p++) {
20765 if (lglmarked (lgl, lit)) return 0;
20766 assert (i < 8 * sizeof signs);
20767 if (signs & (1ull << i++)) lit = -lit;
20768 lglsignedmark (lgl, lit);
20769 tmpocc = lglocc (lgl, lit) + lglhts (lgl, lit)->count;
20770 assert (tmpocc < INT_MAX);
20771 if (tmpocc >= minocc) continue;
20776 hts = lglhts (lgl, min);
20777 w = lglhts2wchs (lgl, hts);
20778 eow = w + hts->count;
20779 for (p = w; p < eow; p++) {
20780 INCSTEPS (gauss.steps.extr);
20782 tag = blit & MASKCS;
20783 if (tag == TRNCS || tag == LRGCS) p++;
20784 if (tag == LRGCS) continue;
20785 if (tag == BINCS) {
20786 other = blit >> RMSHFT;
20787 if (lglsignedmarked (lgl, other)) return 1;
20788 } else if (tag == TRNCS) {
20789 other = blit >> RMSHFT;
20790 if (!lglsignedmarked (lgl, other)) continue;
20792 if (lglsignedmarked (lgl, other2)) return 1;
20794 assert (tag == OCCS);
20795 red = blit & REDCS;
20796 lidx = blit >> RMSHFT;
20797 d = lglidx2lits (lgl, red, lidx);
20798 for (q = d; (other = *q); q++)
20799 if (!lglsignedmarked (lgl, other)) break;
20800 if (!other) return 1;
20806 static int lglgaussubcls (LGL * lgl, uint64_t signs, const int * c) {
20807 int res = lglgaussubclsaux (lgl, signs, c), lit;
20809 for (p = c; (lit = *p); p++) lglunmark (lgl, lit);
20815 static int lglgaussextractxoraux (LGL * lgl, const int * c) {
20816 int lit, val, size, maxsize, negs, start, max, *d, * q;
20817 int allxors = lgl->opts->gaussextrall.val;
20820 assert (!lgl->level);
20821 maxsize = lgl->opts->gaussmaxor.val;
20822 max = negs = size = 0;
20823 start = lglcntstk (&lgl->gauss->xors);
20824 for (p = c; (lit = *p); p++) {
20825 if ((val = lglval (lgl, lit)) > 0) return 0;
20826 if (val < 0) continue;
20828 if (!allxors && negs) return 0;
20831 if (!max || abs (max) < abs (lit)) max = lit;
20832 lglpushstk (lgl, &lgl->gauss->xors, lit);
20833 if (++size > maxsize) return 0;
20835 assert (negs == 0 || negs == 1);
20836 if (size <= 1) return 0;
20837 if (!allxors && negs && max > 0) return 0;
20838 lglpushstk (lgl, &lgl->gauss->xors, 0);
20839 d = lgl->gauss->xors.start + start;
20840 assert (size <= 8 * sizeof signs);
20841 signs = lgldec64 (1ull << size);
20843 if (!lglgaussubcls (lgl, signs, d)) break;
20844 signs = lgldec64 (signs);
20846 lgl->stats->gauss.steps.extr < lgl->limits->gauss.steps.extr);
20847 if (signs) return 0;
20848 for (q = d; (lit = *q); q++) *q = abs (lit);
20850 LOGEQN (GL, start, "extracted %d-ary XOR constraint", size);
20851 lgl->stats->gauss.arity.sum += size;
20852 if (lgl->stats->gauss.arity.max < size) lgl->stats->gauss.arity.max = size;
20853 lgl->stats->gauss.extracted++;
20857 static int lglgaussextractxor (LGL * lgl, const int * c) {
20858 int old = lglcntstk (&lgl->gauss->xors), res;
20859 if (!(res = lglgaussextractxoraux (lgl, c)))
20860 lglrststk (&lgl->gauss->xors, old);
20864 static int lglgaussextractsmallit (LGL * lgl, int lit) {
20865 int allxors = lgl->opts->gaussextrall.val;
20866 int cls[4], blit, tag, other, other2;
20867 const int * w, * eow, * p;
20869 if (lgl->stats->gauss.steps.extr >= lgl->limits->gauss.steps.extr)
20871 if (lglval (lgl, lit) > 0) return 1;
20872 hts = lglhts (lgl, lit);
20873 w = lglhts2wchs (lgl, hts);
20874 eow = w + hts->count;
20875 for (p = w; p < eow; p++) {
20877 tag = blit & MASKCS;
20878 if (tag == TRNCS || tag == LRGCS) p++;
20879 if (tag == OCCS || tag == LRGCS) continue;
20880 other = blit >> RMSHFT;
20881 if (!allxors && abs (other) < lit) continue;
20884 if (tag == TRNCS) {
20886 if (!allxors && abs (other2) < lit) continue;
20890 assert (tag == BINCS);
20893 lglgaussextractxor (lgl, cls);
20898 static int lglgaussextractsmall (LGL * lgl) {
20899 int64_t before = lgl->stats->gauss.extracted, after, delta;
20901 lglrandlitrav (lgl, lglgaussextractsmallit);
20902 after = lgl->stats->gauss.extracted;
20903 delta = after - before;
20904 res = (delta > INT_MAX) ? INT_MAX : delta;
20908 static int lglgaussextractlarge (LGL * lgl) {
20909 const int * p, * c;
20911 for (c = lgl->irr.start; c < lgl->irr.top; c = p + 1) {
20912 if (lgl->stats->gauss.steps.extr >= lgl->limits->gauss.steps.extr) break;
20913 if (*(p = c) >= NOTALIT) continue;
20914 res += lglgaussextractxor (lgl, c);
20920 static void lglgaussconeqn (LGL * lgl, int eqn) {
20921 const int * xors = lgl->gauss->xors.start;
20923 INCSTEPS (gauss.steps.elim);
20924 for (i = eqn; (var = xors[i]) > 1; i++)
20925 lglpushstk (lgl, lgl->gauss->occs + var, eqn);
20928 static void lglgaussdiseqn (LGL * lgl, int eqn) {
20929 int * xors = lgl->gauss->xors.start, i, var;
20930 for (i = eqn; (var = xors[i]) > 1; i++) {
20932 lgl->gauss->garbage++;
20933 INCSTEPS (gauss.steps.elim);
20934 lglrmstk (lgl->gauss->occs + var, eqn);
20937 lgl->gauss->garbage++;
20940 static void lglgaussconnect (LGL * lgl) {
20941 int c, i, eox = lglcntstk (&lgl->gauss->xors), connected, var, vars;
20942 const int * xors = lgl->gauss->xors.start;
20944 LOG (2, "connecting equations");
20945 assert (!lgl->gauss->occs);
20946 NEW (lgl->gauss->occs, lgl->nvars);
20947 vars = connected = 0;
20948 for (c = 0; c < eox; c = i + 1) {
20949 INCSTEPS (gauss.steps.elim);
20950 for (i = c; (var = xors[i]) > 1; i++) {
20951 occs = lgl->gauss->occs + var;
20952 if (lglmtstk (occs)) vars++;
20953 lglpushstk (lgl, lgl->gauss->occs + var, c);
20958 "[gauss-%d] connected %d occurrences of %d variables (average %.1f)",
20959 lgl->stats->gauss.count, connected, vars, lglavg (connected, vars));
20962 static int lglgaussorderidx (LGL * lgl, int var) {
20963 assert (2 <= var && var < lgl->nvars);
20964 if (!lglmtstk (lgl->gauss->occs + var))
20965 lglpushstk (lgl, &lgl->gauss->order, var);
20969 static void lglgaussorder (LGL * lgl) {
20970 lglrandidxtrav (lgl, lglgaussorderidx);
20971 NEW (lgl->gauss->eliminated, lgl->nvars);
20974 static void lglgaussdisconnect (LGL * lgl) {
20976 assert (lgl->gauss->occs);
20977 LOG (2, "disconnecting equations");
20978 for (idx = 2; idx < lgl->nvars; idx++)
20979 lglrelstk (lgl, lgl->gauss->occs + idx);
20980 DEL (lgl->gauss->occs, lgl->nvars);
20981 assert (!lgl->gauss->occs);
20984 static void lglgaussextract (LGL * lgl) {
20985 int extracted, lits;
20986 assert (lglsmallirr (lgl));
20987 if (lgl->level) lglbacktrack (lgl, 0);
20989 if (lgl->mt) return;
20991 extracted = lglgaussextractsmall (lgl);
20992 extracted += lglgaussextractlarge (lgl);
20993 lits = lglcntstk (&lgl->gauss->xors) - extracted;
20995 "[gauss-%d] extracted %d xors of average arity %.1f",
20996 lgl->stats->gauss.count, extracted, lglavg (lits, extracted));
20999 if (lgl->mt) return;
21000 lglfitstk (lgl, &lgl->gauss->xors);
21003 static int lglgaussoccs (LGL * lgl, int a) {
21004 return lglcntstk (lgl->gauss->occs + a);
21007 static int lglcmpgauss (LGL * lgl, int a, int b) {
21008 int res = lglgaussoccs (lgl, a) - lglgaussoccs (lgl, b);
21009 if (!res) res = a - b;
21013 #define LGLCMPGAUSS(A,B) lglcmpgauss (lgl, *(A), *(B))
21015 static void lglgaussort (LGL * lgl) {
21016 int max = lglcntstk (&lgl->gauss->order), rest, * start;
21017 assert (lgl->gauss->next <= max);
21018 rest = max - lgl->gauss->next;
21019 start = lgl->gauss->order.start + lgl->gauss->next;
21020 ADDSTEPS (gauss.steps.elim, rest);
21021 SORT (int, start, rest, LGLCMPGAUSS);
21023 "[gauss-%d] sorted %d remaining variables",
21024 lgl->stats->gauss.count, rest);
21027 static int lglgausspickeqn (LGL * lgl, int pivot) {
21028 int res, cand, weight, size, tmp, other, found;
21029 const int * p, * e, * q;
21031 assert (lglgaussoccs (lgl, pivot));
21033 weight = INT_MAX; size = INT_MAX;
21034 occs = lgl->gauss->occs + pivot;
21035 for (p = occs->start; p < occs->top; p++) {
21036 e = lgl->gauss->xors.start + (cand = *p);
21038 INCSTEPS (gauss.steps.elim);
21039 for (q = e; (other = *q) > 1; q++) {
21040 if (lgl->gauss->eliminated[other]) break;
21041 if (other == pivot) { assert (!found); found++; continue; }
21042 tmp += lglgaussoccs (lgl, other) - 1;
21044 if (other > 1) continue;
21046 if (res >= 0 && q - e >= size) continue;
21047 if (res >= 0 && q - e == size && tmp >= weight) continue;
21053 LOGEQN (2, res, "picking size %d weight %d equation", size, weight);
21055 LOG (2, "no uneliminated equation for pivot %d left", pivot);
21059 static void lglcpystk (LGL * lgl, Stk * dst, Stk * src) {
21061 for (p = src->start; p < src->top; p++)
21062 lglpushstk (lgl, dst, *p);
21065 static int lglgaussaddeqn (LGL * lgl, int eqn) {
21069 for (p = lgl->gauss->xors.start + eqn; (var = *p) > 1; p++) {
21070 av = lglavar (lgl, var);
21071 if (!av->mark) lglpushstk (lgl, &lgl->clause, var);
21072 av->mark = !av->mark;
21077 static void lglgaussubst (LGL * lgl, int pivot, int subst) {
21078 Stk * occs = lgl->gauss->occs + pivot;
21082 assert (lglcntstk (occs) > 1);
21083 while (lglcntstk (occs) > 1) {
21084 if (lglterminate (lgl)) return;
21085 eqn = occs->start[0];
21086 if (eqn == subst) eqn = occs->start[1];
21087 assert (lglmtstk (&lgl->clause));
21088 LOGEQN (2, subst, " 1st row (kept) ");
21089 rhs = lglgaussaddeqn (lgl, eqn);
21090 LOGEQN (2, eqn, " 2nd row (replaced) ");
21091 if (lglgaussaddeqn (lgl, subst)) rhs = !rhs;
21092 lglgaussdiseqn (lgl, eqn);
21093 q = lgl->clause.start;
21094 for (p = q; p < lgl->clause.top; p++)
21095 if (lglmarked (lgl, *p)) *q++ = *p;
21096 lgl->clause.top = q;
21097 if (!lglmtstk (&lgl->clause)) {
21098 res = lglcntstk (&lgl->gauss->xors);
21099 lglcpystk (lgl, &lgl->gauss->xors, &lgl->clause);
21100 lglpushstk (lgl, &lgl->gauss->xors, rhs);
21101 LOGEQN (2, res, " result row ");
21102 lglgaussconeqn (lgl, res);
21103 } else if (rhs == 0) {
21104 LOG (2, "trivial result row 0 = 0");
21107 LOG (1, "inconsistent result row 0 = 1 from gaussian elimination");
21110 lglpopnunmarkstk (lgl, &lgl->clause);
21114 static void lglgausschkeliminated (LGL * lgl) {
21116 int idx, eliminated, occs;
21117 if (!lgl->opts->check.val) return;
21118 for (idx = 2; idx < lgl->nvars; idx++) {
21119 eliminated = lgl->gauss->eliminated[idx];
21120 occs = lglgaussoccs (lgl, idx);
21121 if (eliminated == 1) assert (occs == 1);
21122 if (eliminated == 2) assert (occs == 0);
21127 static void lglgaussgc (LGL * lgl) {
21128 int count = lglcntstk (&lgl->gauss->xors), * q;
21130 if (lgl->gauss->garbage < count/2 + 10000) return;
21131 lgl->stats->gauss.gcs++;
21133 "[gauss-%d] collecting %d garbage out of %d",
21134 lgl->stats->gauss.count, lgl->gauss->garbage, count);
21135 lglgaussdisconnect (lgl);
21136 q = lgl->gauss->xors.start;
21137 for (p = q; p < lgl->gauss->xors.top; p++)
21138 if (*p != NOTALIT) *q++ = *p;
21139 lgl->gauss->xors.top = q;
21140 lglfitstk (lgl, &lgl->gauss->xors);
21141 lglgaussconnect (lgl);
21142 lgl->gauss->garbage = 0;
21145 static int lglgausselimvar (LGL * lgl, int pivot) {
21146 int subst, changed, occs, eliminated;
21147 LOG (2, "eliminating variable %d occurring %d times",
21148 pivot, lglgaussoccs (lgl, pivot));
21149 assert (!lgl->gauss->eliminated[pivot]);
21150 if (!(occs = lglgaussoccs (lgl, pivot))) {
21151 LOG (2, "variable %d disappeared ", pivot);
21154 } else if (occs == 1) {
21155 LOG (2, "eliminated variable %d occurrs exactly once", pivot);
21160 subst = lglgausspickeqn (lgl, pivot);
21162 lglgaussubst (lgl, pivot, subst);
21170 lgl->gauss->eliminated[pivot] = eliminated;
21171 lglgausschkeliminated (lgl);
21175 static void lglgausselim (LGL * lgl) {
21176 int pivot, changed = 1;
21177 while (!lgl->mt && lgl->gauss->next < lglcntstk (&lgl->gauss->order)) {
21178 if (lgl->stats->gauss.steps.elim >= lgl->limits->gauss.steps.elim) break;
21179 if (lglterminate (lgl)) break;
21180 if (changed) lglgaussort (lgl);
21181 pivot = lglpeek (&lgl->gauss->order, lgl->gauss->next++);
21182 changed = lglgausselimvar (lgl, pivot);
21186 static void lglgaussinit (LGL * lgl) {
21187 assert (!lgl->gauss);
21188 NEW (lgl->gauss, 1);
21191 static void lglgaussreset (LGL * lgl) {
21192 assert (lgl->gauss);
21193 if (lgl->gauss->occs) lglgaussdisconnect (lgl);
21194 if (lgl->gauss->eliminated) DEL (lgl->gauss->eliminated, lgl->nvars);
21195 lglrelstk (lgl, &lgl->gauss->xors);
21196 lglrelstk (lgl, &lgl->gauss->order);
21197 DEL (lgl->gauss, 1);
21200 static int lglgaussexp2 (LGL * lgl, int a, int b) {
21201 assert (lgl->gaussing);
21202 assert (lglmtstk (&lgl->clause));
21203 if (lglhasbin (lgl, a, b)) return 0;
21204 lglpushstk (lgl, &lgl->clause, a);
21205 lglpushstk (lgl, &lgl->clause, b);
21206 lglpushstk (lgl, &lgl->clause, 0);
21207 LOGCLS (2, lgl->clause.start, "gauss exported binary clause");
21208 assert (!lgl->opts->drup.val);
21209 #ifndef NLGLPICOSAT
21210 lglpicosatchkcls (lgl);
21212 lgladdcls (lgl, REDCS, 0, 0);
21213 lglclnstk (&lgl->clause);
21217 static int lglgaussexp3 (LGL * lgl, int a, int b, int c) {
21218 assert (lgl->gaussing);
21219 assert (lglmtstk (&lgl->clause));
21220 if (lglhastrn (lgl, a, b, c)) return 0;
21221 lglpushstk (lgl, &lgl->clause, a);
21222 lglpushstk (lgl, &lgl->clause, b);
21223 lglpushstk (lgl, &lgl->clause, c);
21224 lglpushstk (lgl, &lgl->clause, 0);
21225 LOGCLS (2, lgl->clause.start, "gauss exported ternary clause");
21226 assert (!lgl->opts->drup.val);
21227 #ifndef NLGLPICOSAT
21228 lglpicosatchkcls (lgl);
21230 lgladdcls (lgl, REDCS, 0, 0);
21231 lglclnstk (&lgl->clause);
21235 static int lglgaussexport (LGL * lgl) {
21236 int var, size, val, rhs, unit, a, b, c, exported;
21237 const int * e, * p, * q;
21238 for (e = lgl->gauss->xors.start; e < lgl->gauss->xors.top; e = p + 1) {
21239 if (*(p = e) >= NOTALIT) continue;
21240 while ((var = *p) > 1) p++;
21242 assert (lglmtstk (&lgl->clause));
21243 for (q = e; q < p; q++) {
21245 val = lglval (lgl, var);
21246 if (val < 0) continue;
21247 if (val > 0) { rhs = !rhs; continue; }
21248 lglpushstk (lgl, &lgl->clause, var);
21250 size = lglcntstk (&lgl->clause);
21251 if (!size && !rhs) continue;
21252 if (!size && rhs) {
21253 LOGEQN (1, e - lgl->gauss->xors.start,
21254 "gauss exporting inconsistent equation");
21257 a = (size > 0) ? lgl->clause.start[0] : 0;
21258 b = (size > 1) ? lgl->clause.start[1] : 0;
21259 c = (size > 2) ? lgl->clause.start[2] : 0;
21260 lglclnstk (&lgl->clause);
21263 if (!rhs) unit = -unit;
21264 LOG (1, "gauss exporting unit %d", unit);
21265 lgl->stats->gauss.units++;
21266 lglunit (lgl, unit);
21267 } else if (size == 2) {
21269 exported = lglgaussexp2 (lgl, -a, b);
21270 exported |= lglgaussexp2 (lgl, a, -b);
21272 LOG (1, "gauss exporting equivalence %d = %d", a, b);
21273 lgl->stats->gauss.equivs++;
21275 } else if (size == 3 && lgl->opts->gaussexptrn.val) {
21277 exported = lglgaussexp3 (lgl, a, b, c);
21278 exported |= lglgaussexp3 (lgl, a, -b, -c);
21279 exported |= lglgaussexp3 (lgl, -a, b, -c);
21280 exported |= lglgaussexp3 (lgl, -a, -b, c);
21282 LOG (1, "gauss exporting ternary equation %d + %d + %d = 1",
21284 lgl->stats->gauss.trneqs++;
21291 static void lglsetgausslim (LGL * lgl) {
21292 int64_t limit, irrlim;
21294 limit = (lgl->opts->gaussreleff.val*lglvisearch (lgl))/1000;
21295 if (limit < lgl->opts->gaussmineff.val) limit = lgl->opts->gaussmineff.val;
21296 if (lgl->opts->gaussmaxeff.val >= 0 && limit > lgl->opts->gaussmaxeff.val)
21297 limit = lgl->opts->gaussmaxeff.val;
21298 limit >>= (pen = lgl->limits->gauss.pen + lglszpen (lgl));
21299 irrlim = lgl->stats->irr.clauses.cur/2;
21300 irrlim >>= lgl->limits->simp.pen;
21301 if (lgl->opts->irrlim.val && limit < irrlim) {
21303 lglprt (lgl, 1, "[gauss-%d] limit %lld based on %d irredundant clauses",
21304 lgl->stats->gauss.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
21306 lglprt (lgl, 1, "[gauss-%d] limit %lld penalty %d = %d + %d",
21307 lgl->stats->gauss.count, (LGLL) limit,
21308 pen, lgl->limits->gauss.pen, lglszpen (lgl));
21309 lgl->limits->gauss.steps.extr = lgl->stats->gauss.steps.extr + limit;
21310 lgl->limits->gauss.steps.elim = lgl->stats->gauss.steps.elim + limit;
21313 static int lglgauss (LGL * lgl) {
21314 int oldunits, oldequivs, oldtrneqs;
21315 int units, equivs, trneqs;
21317 assert (lgl->opts->gauss.val);
21318 if (lgl->mt) return 0;
21319 if (lgl->nvars <= 2) return 1;
21320 lglstart (lgl, &lgl->times->gauss);
21321 assert (!lgl->simp && !lgl->gaussing);
21322 lgl->simp = lgl->gaussing = 1;
21323 lgl->stats->gauss.count++;
21324 lglsetgausslim (lgl);
21325 lglgaussinit (lgl);
21326 lglgaussextract (lgl);
21327 oldunits = lgl->stats->gauss.units;
21328 oldequivs = lgl->stats->gauss.equivs;
21329 oldtrneqs = lgl->stats->gauss.trneqs;
21330 if (!lglmtstk (&lgl->gauss->xors)) {
21331 lglgaussconnect (lgl);
21332 lglgaussorder (lgl);
21333 lglsetgausslim (lgl);
21334 lglgausselim (lgl);
21335 if (!lgl->mt && !lglterminate (lgl)) {
21336 if (lgl->opts->verbose.val >= 3) lglgdump (lgl);
21337 lglgaussdisconnect (lgl);
21338 if (!lglgaussexport (lgl) || !lglbcp (lgl)) lgl->mt = 1;
21339 else if (lgl->limits->gauss.steps.extr > lgl->stats->gauss.steps.extr &&
21340 lgl->limits->gauss.steps.elim > lgl->stats->gauss.steps.elim)
21341 lglprt (lgl, 1, "[gauss-%d] fully completed", lgl->stats->gauss.count);
21344 lglgaussreset (lgl);
21345 units = lgl->stats->gauss.units - oldunits;
21346 equivs = lgl->stats->gauss.equivs - oldequivs;
21347 trneqs = lgl->stats->gauss.trneqs - oldtrneqs;
21348 success = units || equivs;
21349 if (!lgl->mt && success && !lglterminate (lgl) && lgl->opts->decompose.val)
21351 if (trneqs) success = 1;
21353 lglprt (lgl, 1, "[gauss-%d] proved unsatisfiability",
21354 lgl->stats->gauss.count);
21357 "[gauss-%d] exported %d unary, %d binary and %d ternary equations",
21358 lgl->stats->gauss.count, units, equivs, trneqs);
21360 LGLUPDPEN (gauss, success);
21361 lglrep (lgl, 2, 'G');
21362 assert (lgl->simp && lgl->gaussing);
21363 lgl->simp = lgl->gaussing = 0;
21368 /*------------------------------------------------------------------------*/
21370 #define CARDLOGLEVEL 2
21372 static int lglcardsub (LGL * lgl, const int * lits, int bound) {
21373 int count, size, res, minlit, minocc, nocc, lit, pos, otherbound;
21374 Card * card = lgl->card;
21375 const int * p, * c, * q;
21379 for (p = lits; minocc && (lit = *p); p++) {
21380 lglmarkunmarked (lgl, lit);
21381 s = card->occs + lit;
21382 INCSTEPS (card.steps);
21383 nocc = lglcntstk (s);
21384 if (nocc > minocc) continue;
21389 if (minocc && minlit) {
21391 s = card->occs + minlit;
21392 for (p = s->start; p < s->top; p++) {
21394 c = card->cards.start + pos;
21395 INCSTEPS (card.steps);
21397 if (otherbound > bound) continue;
21399 INCSTEPS (card.steps);
21400 for (q = c + 1; *q; q++) count++;
21401 if (count < size) continue;
21403 INCSTEPS (card.steps);
21404 for (q = c + 1; (count < size) && (lit = *q); q++)
21405 if (lglmarked (lgl, lit) > 0) count++;
21406 if (count >= size) {
21407 LOGCLS (CARDLOGLEVEL, lits,
21408 "subsumed cardinality constraint %d >=", bound);
21409 LOGCLS (CARDLOGLEVEL, c + 1,
21410 "subsuming cardinality constraint %d >=", otherbound);
21415 for (p = lits; (lit = *p); p++) lglunmark (lgl, lit);
21419 static int lglcard1sub (LGL * lgl, const int * lits) {
21420 int res, minlit, minocc, nocc, lit, count, size;
21421 Card * card = lgl->card;
21422 const int * p, * c, * q;
21426 for (p = lits; minocc && (lit = *p); p++) {
21427 lglmarkunmarked (lgl, lit);
21428 s = card->occs + lit;
21429 INCSTEPS (card.steps);
21430 nocc = lglcntstk (s);
21431 if (nocc > minocc) continue;
21436 if (!minocc || !minlit) goto DONE;
21438 s = card->occs + minlit;
21440 for (p = s->start; !res && p < s->top; p++) {
21441 c = card->atmost1.start + *p;
21442 for (q = c; (lit = *q); q++)
21443 if (lglmarked (lgl, lit) && ++count >= size)
21445 if (!lit) continue;
21446 LOGCLS (CARDLOGLEVEL, lits,
21447 "subsumed at-most-one cardinality constraint 1 >=");
21448 LOGCLS (CARDLOGLEVEL, c,
21449 "subsuming at-most-one cardinality constraint 1 >=");
21453 for (p = lits; (lit = *p); p++) lglunmark (lgl, lit);
21457 static int lglcard2sub (LGL * lgl, const int * lits, int * minlitptr) {
21458 int res, minlit, minocc, nocc, lit, count, size;
21459 Card * card = lgl->card;
21460 const int * p, * c, * q;
21464 for (p = lits; minocc && (lit = *p); p++) {
21465 lglmarkunmarked (lgl, lit);
21466 s = card->occs + lit;
21467 INCSTEPS (card.steps);
21468 nocc = lglcntstk (s);
21469 if (nocc > minocc) continue;
21473 assert (!minocc || p + 1 == card->atmost2.top);
21475 if (!minocc || !minlit || *minlitptr == minlit) goto DONE;
21476 *minlitptr = minlit;
21478 s = card->occs + minlit;
21480 for (p = s->start; !res && p < s->top; p++) {
21481 c = card->atmost2.start + *p;
21482 for (q = c; (lit = *q); q++)
21483 if (lglmarked (lgl, lit) && ++count >= size)
21485 if (!lit) continue;
21486 LOGCLS (CARDLOGLEVEL, lits,
21487 "subsumed at-most-two cardinality constraint 2 >=");
21488 LOGCLS (CARDLOGLEVEL, c,
21489 "subsuming at-most-two cardinality constraint 2 >=");
21493 for (p = lits; (lit = *p); p++) lglunmark (lgl, lit);
21497 static int lgladdcard (LGL * lgl, const int * lits, int bound) {
21498 Card * card = lgl->card;
21501 #if !defined(NDEBUG) || !defined(NLGLOG)
21503 for (p = lits; *p; p++) size++;
21505 if (lglcardsub (lgl, lits, bound)) {
21506 lgl->stats->card.subsumed++;
21509 LOGCLS (CARDLOGLEVEL, lits,
21510 "new %s cardinality constraint %d >=",
21511 (bound + 1 < size ? "real" : "pseudo"), bound);
21512 assert (bound <= size);
21514 lglfactor (lgl, lgl->stats->card.count, lgl->opts->cardmaxlen.val));
21516 for (p = lits; (lit = *p); p++) assert (!card->eliminated[abs (lit)]);
21517 for (p = lits; (lit = *p); p++) assert (!card->count[abs (lit)]);
21520 start = lglcntstk (&card->cards);
21521 lglpushstk (lgl, &card->cards, bound);
21522 for (p = lits; (lit = *p); p++) {
21523 lglpushstk (lgl, &card->cards, lit);
21524 lglpushstk (lgl, card->occs + lit, start);
21526 lglpushstk (lgl, &card->cards, 0);
21530 static void lglcardfmstep (LGL * lgl, int pivot,
21531 int cardposidx, int cardnegidx) {
21532 int bn, bp, ln, lp, b, c, s, lit, idx, addcard, len, unit[2], div, elim;
21533 const int cardcut = lgl->opts->cardcut.val;
21534 const int * p, * q, * cn, * cp;
21535 int * r, divsame, cardmaxlen;
21536 Card * card = lgl->card;
21537 INCSTEPS (card.steps);
21538 lgl->stats->card.resolved++;
21539 assert (0 <= cardposidx && cardposidx < lglcntstk (&card->cards));
21540 assert (0 <= cardnegidx && cardnegidx < lglcntstk (&card->cards));
21541 cp = card->cards.start + cardposidx;
21542 cn = card->cards.start + cardnegidx;
21543 bp = *cp++; assert (bp >= 0);
21544 bn = *cn++; assert (bp >= 0);
21545 LOGCLS (CARDLOGLEVEL, cp,
21546 "first antecedent fourier-motzkin on %d cardinality constraint %d >=",
21548 LOGCLS (CARDLOGLEVEL, cn,
21549 "second antecedent fourier-motzkin on %d cardinality constraint %d >=",
21552 LOG (CARDLOGLEVEL, "starting with bound %d", b);
21553 assert (lglmtstk (&lgl->clause));
21554 for (p = cp; (lit = *p); p++) {
21556 assert (!card->count[idx]);
21557 lglpushstk (lgl, &lgl->clause, idx);
21558 card->count[idx] += lglsgn (lit);
21564 for (q = cn; (lit = *q); q++) {
21566 c = card->count[idx];
21567 assert (!c || abs (c) == 1);
21569 if (!c) lglpushstk (lgl, &lgl->clause, idx);
21570 card->count[idx] += s;
21571 if (c && c != s) elim++;
21572 if (c == s) div = 2;
21577 for (p = lgl->clause.start; divsame && p < lgl->clause.top; p++) {
21579 c = card->count[idx];
21582 divsame = (c == div);
21585 if (lgl->opts->log.val >= CARDLOGLEVEL) {
21587 lglogstart (lgl, CARDLOGLEVEL,
21588 "pseudo-boolean resolvent %d - %d >= ", b, elim);
21589 for (p = lgl->clause.start; p < lgl->clause.top; p++) {
21591 assert (1 < idx), assert (idx < lgl->nvars);
21592 c = card->count[idx];
21595 fprintf (lgl->out, " %c ", (c < 0) ? '-' : '+');
21597 fputs ("-", lgl->out);
21601 if (c != 1) fprintf (lgl->out, "%d*", c);
21602 fprintf (lgl->out, "%d", idx);
21604 if (first) fputs ("0", lgl->out);
21609 "size %d cardinalty resolvent contains %d eliminated division %d %s",
21610 lglcntstk (&lgl->clause) - elim, elim, div, divsame ? "all" : "some");
21611 r = lgl->clause.start;
21612 for (p = r; p < lgl->clause.top; p++) {
21614 c = card->count[idx];
21615 if (divsame || cardcut == 1) c /= div;
21616 else if (abs (c) != 1 && cardcut == 2 && div == 2) c = 0;
21618 lit = (c < 0) ? -idx : idx;
21621 lgl->clause.top = r;
21623 assert (div == 1 || div == 2);
21624 if ((divsame || cardcut == 1) && div == 2) b /= 2;
21625 len = lglcntstk (&lgl->clause);
21626 lglpushstk (lgl, &lgl->clause, 0);
21629 lglfactor (lgl, lgl->stats->card.count, lgl->opts->cardmaxlen.val);
21630 if (!cardcut && div > 1) {
21632 "ignoring resolved cardinality constraint which requires cut");
21634 } else if (b < 0) {
21637 LOGCLS (CARDLOGLEVEL, lgl->clause.start,
21638 "inconsistent cardinality constraint %d >=", b);
21640 } else if (b == 0) {
21642 LOGCLS (CARDLOGLEVEL, lgl->clause.start,
21643 "forcing cardinality constraint %d >=", b);
21644 for (p = lgl->clause.start; p < lgl->clause.top - 1; p++) {
21647 lgl->stats->card.units++;
21648 lglpushstk (lgl, &lgl->card->units, -lit);
21649 card->count[abs (lit)] = 0;
21652 (void) lgladdcard (lgl, unit, 0);
21654 } else if (b >= len) {
21655 LOGCLS (CARDLOGLEVEL, lgl->clause.start,
21656 "trivial resolved cardinality constraint %d >=", b);
21658 } else if (len > cardmaxlen) {
21659 LOGCLS (CARDLOGLEVEL, lgl->clause.start,
21660 "length %d exceeds limit %d of resolved cardinality constraint %d >=",
21661 len, cardmaxlen, b);
21665 LOGCLS (CARDLOGLEVEL, lgl->clause.start,
21666 "resolved cardinality constraint %d >=", b);
21668 ((ln >= 3 && lp >= 3) ||
21669 lglcntstk (&lgl->clause) >
21671 lgl->stats->card.count, lgl->opts->cardexpam1.val))) {
21672 LOGCLS (CARDLOGLEVEL, lgl->clause.start,
21673 "saving to export at-most-one constraint 1 >=");
21674 for (p = lgl->clause.start; p < lgl->clause.top; p++)
21675 lglpushstk (lgl, &lgl->card->expam1, *p);
21678 cp = card->cards.start + cardposidx + 1;
21679 cn = card->cards.start + cardnegidx + 1;
21680 for (p = cp; (lit = *p); p++) card->count[abs (lit)] = 0;
21681 for (q = cn; (lit = *q); q++) card->count[abs (lit)] = 0;
21682 if (addcard > 0) (void) lgladdcard (lgl, lgl->clause.start, b);
21683 lglclnstk (&lgl->clause);
21684 // COVER (cardcut == 2 && div == 2 && divsame);
21687 static void lglrmcardexcept (LGL * lgl, int cardidx, int except) {
21688 Card * card = lgl->card;
21690 assert (0 <= cardidx && cardidx < lglcntstk (&card->cards));
21691 c = card->cards.start + cardidx + 1;
21692 LOGCLS (CARDLOGLEVEL, c, "removing cardinality constraint %d >=", c[-1]);
21693 for (p = c; (lit = *p); p++)
21695 lglrmstk (card->occs + lit, cardidx);
21698 static int lglcardocc (LGL * lgl, int a) {
21699 return lglcntstk (lgl->card->occs + a);
21702 static int lglcmpcard (LGL * lgl, int a, int b) {
21703 int64_t s = lglcardocc (lgl, a) * (int64_t) lglcardocc (lgl, -a);
21704 int64_t t = lglcardocc (lgl, b) * (int64_t) lglcardocc (lgl, -b);
21705 if (s > t) return -1;
21706 if (s < t) return 1;
21710 #define LGLCMPCARD(A,B) lglcmpcard (lgl, *(A), *(B))
21712 static void lglcardresched (LGL * lgl) {
21713 Stk * elim = &lgl->card->elim;
21714 int count = lglcntstk (elim);
21715 ADDSTEPS (card.steps, 4*count);
21716 SORT (int, elim->start, lglcntstk (elim), LGLCMPCARD);
21717 lgl->stats->card.resched++;
21720 static void lglcardfmlit (LGL * lgl, int pivot) {
21721 Stk * poccs = lgl->card->occs + pivot, * noccs = lgl->card->occs - pivot;
21722 int pcnt = lglcntstk (poccs), ncnt = lglcntstk (noccs);
21723 int count = lgl->stats->card.count;
21724 const int * p, * q;
21725 assert (pivot > 0);
21726 assert (!lgl->card->eliminated[pivot]);
21727 if (!pcnt || !ncnt) goto DONE;
21728 if (pcnt > lglfactor (lgl, lgl->opts->cardocclim1.val, count)) goto DONE;
21729 if (ncnt > lglfactor (lgl, lgl->opts->cardocclim1.val, count)) goto DONE;
21730 if (pcnt > lglfactor (lgl, lgl->opts->cardocclim2.val, count) &&
21731 ncnt > lglfactor (lgl, lgl->opts->cardocclim2.val, count)) goto DONE;
21732 lgl->stats->card.eliminated++;
21733 lgl->card->eliminated[pivot] = 1;
21735 "fourier-motzkin pivot %d with %d positive and %d negative occurrences",
21736 pivot, pcnt, ncnt);
21737 for (p = poccs->start; !lgl->mt && p < poccs->top; p++)
21738 for (q = noccs->start; !lgl->mt && q < noccs->top; q++)
21739 lglcardfmstep (lgl, pivot, *p, *q);
21741 for (p = poccs->start; !lgl->mt && p < poccs->top; p++) {
21742 lglrmcardexcept (lgl, *p, pivot);
21743 INCSTEPS (card.steps);
21745 for (q = noccs->start; !lgl->mt && q < noccs->top; q++) {
21746 lglrmcardexcept (lgl, *q, -pivot);
21747 INCSTEPS (card.steps);
21749 lglrelstk (lgl, poccs);
21750 lglrelstk (lgl, noccs);
21751 if (!(lgl->stats->card.eliminated % lgl->opts->cardreschedint.val))
21752 lglcardresched (lgl);
21755 static void lglcardfm (LGL * lgl) {
21757 lglcardresched (lgl);
21758 elim = &lgl->card->elim;
21760 !lglmtstk (elim) &&
21761 !lglterminate (lgl) &&
21762 lgl->limits->card.steps >= INCSTEPS (card.steps))
21763 lglcardfmlit (lgl, lglpopstk (elim));
21766 static int64_t lglsetcardlim (LGL * lgl) {
21767 int64_t limit, irrlim;
21769 limit = (lgl->opts->cardreleff.val*lglvisearch (lgl))/1000;
21770 if (limit < lgl->opts->cardmineff.val) limit = lgl->opts->cardmineff.val;
21771 if (lgl->opts->cardmaxeff.val >= 0 && limit > lgl->opts->cardmaxeff.val)
21772 limit = lgl->opts->cardmaxeff.val;
21773 limit >>= (pen = lgl->limits->card.pen + lglszpen (lgl));
21774 irrlim = lgl->stats->irr.clauses.cur/4;
21775 irrlim >>= lgl->limits->simp.pen;
21776 if (lgl->opts->irrlim.val && limit < irrlim) {
21779 "[card-%d] limit %lld based on %d irredundant clauses",
21780 lgl->stats->card.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
21782 lglprt (lgl, 1, "[card-%d] limit %lld penalty %d = %d + %d",
21783 lgl->stats->card.count, (LGLL) limit,
21784 pen, lgl->limits->card.pen, lglszpen (lgl));
21785 lgl->limits->card.steps = lgl->stats->card.steps + limit;
21789 static void lglsetcardlimagain (LGL * lgl, int64_t limit) {
21791 "[card-%d] using previous limit %lld for elimination",
21792 lgl->stats->card.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
21793 lgl->limits->card.steps = lgl->stats->card.steps + limit;
21796 static int lglcard1extractlit (LGL * lgl, int lit) {
21797 const int ignused = lgl->opts->cardignused.val;
21798 int start, size, trivial, subsumed;
21799 int blit, tag, other, other2, i;
21800 const int * p, * w, * eow;
21803 if (lglterminate (lgl)) return 0;
21804 if (lgl->limits->card.steps < INCSTEPS (card.steps)) return 0;
21806 if (ignused && card->lit2used[lit]) return 1;
21807 start = lglcntstk (&card->atmost1);
21808 LOG (CARDLOGLEVEL + 1,
21809 "starting at-most-one clique[%d] for %d",
21811 lglpushstk (lgl, &card->atmost1, lit);
21812 card->marked[lit] = 1;
21813 hts = lglhts (lgl, -lit);
21814 w = lglhts2wchs (lgl, hts);
21815 eow = w + hts->count;
21816 INCSTEPS (card.steps);
21817 for (p = w; p < eow; p++) {
21819 tag = blit & MASKCS;
21820 if (tag == TRNCS || tag == LRGCS) p++;
21821 if (tag != BINCS) continue;
21822 other = -(blit >> RMSHFT);
21823 if (ignused && card->lit2used[other]) continue;
21824 for (i = start + 1; i < lglcntstk (&card->atmost1); i++) {
21825 other2 = lglpeek (&card->atmost1, i);
21826 INCSTEPS (card.steps);
21827 if (!lglhasbin (lgl, -other, -other2)) break;
21829 if (i < lglcntstk (&card->atmost1)) continue;
21830 card->marked[other] = 1;
21831 lglpushstk (lgl, &card->atmost1, other);
21832 LOG (CARDLOGLEVEL + 1,
21833 "adding %d to at-most-one clique[%d] for %d", other, start, lit);
21835 size = lglcntstk (&card->atmost1) - start;
21836 trivial = (size <= 2);
21838 lglpushstk (lgl, &card->atmost1, 0);
21839 subsumed = lglcard1sub (lgl, card->atmost1.start + start);
21840 lglpopstk (&card->atmost1);
21841 } else subsumed = 0;
21842 for (p = card->atmost1.start + start; p < card->atmost1.top; p++) {
21844 assert (card->marked[other]);
21845 card->marked[other] = 0;
21846 if (!trivial && !subsumed) card->lit2used[other] = 1;
21848 if (trivial || subsumed) {
21849 LOG (CARDLOGLEVEL + 1,
21850 "resetting at-most-one clique[%d] for %d of trivial size %d",
21852 lglrststk (&card->atmost1, start);
21855 if (lgl->opts->log.val >= CARDLOGLEVEL) {
21856 lglogstart (lgl, CARDLOGLEVEL,
21857 "non trivial size %d at-most-one constraint 1 >= ", size);
21858 for (i = start; i < start + size; i++) {
21859 if (i > start) fputs (" + ", lgl->out);
21860 fprintf (lgl->out, "%d", lglpeek (&card->atmost1, i));
21866 for (i = start; i < start + size; i++) {
21867 other = lglpeek (&card->atmost1, i);
21868 lglpushstk (lgl, &card->occs[other], start);
21871 lglpushstk (lgl, &card->atmost1, 0);
21872 lgl->stats->card.am1.found.sum += size;
21873 lgl->stats->card.am1.found.cnt++;
21878 static void lglcardreloccs (LGL * lgl) {
21879 Card * card = lgl->card;
21880 int sign, idx, lit;
21881 assert (card), assert (!lgl->nvars || card->occs);
21882 for (sign = -1; sign <= 1; sign += 2)
21883 for (idx = 2; idx < lgl->nvars; idx++) {
21885 lglrelstk (lgl, &card->occs[lit]);
21887 card->occs -= lgl->nvars;
21888 DEL (card->occs, 2*lgl->nvars);
21891 static int lglcard1extract (LGL * lgl) {
21892 struct { int cnt; int64_t sum; } before, after, delta;
21893 const int ignused = lgl->opts->cardignused.val;
21894 Card * card = lgl->card;
21896 lglpushstk (lgl, &card->atmost1, 0);
21898 NEW (card->lit2used, 2*lgl->nvars);
21899 card->lit2used += lgl->nvars;
21900 NEW (card->marked, 2*lgl->nvars);
21901 card->marked += lgl->nvars;
21903 NEW (card->occs, 2*lgl->nvars);
21904 card->occs += lgl->nvars;
21907 before.cnt = lgl->stats->card.am1.found.cnt;
21908 before.sum = lgl->stats->card.am1.found.sum;
21910 lglrandlitrav (lgl, lglcard1extractlit);
21912 after.cnt = lgl->stats->card.am1.found.cnt;
21913 after.sum = lgl->stats->card.am1.found.sum;
21914 assert (after.cnt >= before.cnt);
21915 assert (after.sum >= before.sum);
21916 delta.cnt = after.cnt - before.cnt;
21917 delta.sum = after.sum - before.sum;
21919 card->lit2used -= lgl->nvars;
21920 DEL (card->lit2used, 2*lgl->nvars);
21921 card->marked -= lgl->nvars;
21922 DEL (card->marked, 2*lgl->nvars);
21923 if (!ignused) lglcardreloccs (lgl);
21927 "[card-%d] found %d at-most-one constraints of average size %.1f",
21928 lgl->stats->card.count, delta.cnt, lglavg (delta.sum, delta.cnt));
21931 "[card-%d] no at-most-one constraint found",
21932 lgl->stats->card.count);
21937 static int lglcard2extractlit (LGL * lgl, int lit) {
21938 int blit, tag, other, other2, other3, i, j, k, res = 1;
21939 const int ignused = lgl->opts->cardignused.val;
21940 int start, size, minlit;
21941 const int * p, * w, * eow;
21945 if (lglterminate (lgl)) return 0;
21946 if (lgl->limits->card.steps < INCSTEPS (card.steps)) return 0;
21948 if (ignused && card->lit2used[lit]) return 1;
21950 start = lglcntstk (&card->atmost2);
21951 LOG (CARDLOGLEVEL + 1, "starting at-most-two clique[%d] for %d", start, lit);
21952 assert (!card->lit2count[lit]);
21953 hts = lglhts (lgl, -lit);
21954 w = lglhts2wchs (lgl, hts);
21955 eow = w + hts->count;
21956 INCSTEPS (card.steps);
21957 for (p = w; p < eow; p++) {
21959 tag = blit & MASKCS;
21960 if (tag == TRNCS || tag == LRGCS) p++;
21961 if (tag != TRNCS) continue;
21962 other = -(blit >> RMSHFT);
21964 if (card->lit2count[-other] || card->lit2count[-other2]) continue;
21965 if (!card->lit2count[lit]++) lglpushstk (lgl, &card->atmost2, lit);
21966 if (!card->lit2count[other]++) lglpushstk (lgl, &card->atmost2, other);
21967 if (!card->lit2count[other2]++) lglpushstk (lgl, &card->atmost2, other2);
21969 q = card->atmost2.start + start;
21970 for (p = q; p < card->atmost2.top; p++) {
21971 if (card->lit2count [other =*p] > 1) *q++ = other;
21972 else card->lit2count[other] = 0;
21974 card->atmost2.top = q;
21975 size = lglcntstk (&card->atmost2) - start;
21977 LOG (CARDLOGLEVEL + 1,
21978 "less than 4 literals occuring 2 times in ternary clauses with %d",
21981 while (lglcntstk (&card->atmost2) > start) {
21982 int lit = lglpopstk (&card->atmost2);
21983 assert (card->lit2count[lit] > 0);
21984 card->lit2count[lit] = 0;
21992 lglpushstk (lgl, &card->atmost2, 0);
21993 subsumed = lglcard2sub (lgl, card->atmost2.start + start, &minlit);
21994 lglpopstk (&card->atmost2);
21995 if (subsumed) goto FAILED;
21997 LOG (CARDLOGLEVEL + 1, "trying to connect %d literals", size-1);
21998 for (i = 0; i < size-2; i++) {
21999 other = -lglpeek (&card->atmost2, start + i);
22000 for (j = i+1; j < size-1; j++) {
22001 other2 = -lglpeek (&card->atmost2, start + j);
22002 for (k = j+1; k < size; k++) {
22003 if (lgl->limits->card.steps < INCSTEPS (card.steps)) {
22004 LOG (CARDLOGLEVEL + 1, "cardinality extraction step limit hit");
22008 other3 = -lglpeek (&card->atmost2, start + k);
22009 if (!lglhastrn (lgl, other, other2, other3)) {
22010 LOG (CARDLOGLEVEL + 1,
22011 "ternary clause %d %d %d missing", other, other2, other3);
22012 assert (size >= 4);
22013 if (size == 4) goto FAILED;
22015 if (k > j + 1) l = k;
22017 int occ2 = card->lit2count[-other2];
22018 int occ3 = card->lit2count[-other3];
22019 if (occ2 > occ3) l = k;
22020 else if (occ2 < occ3) l = j;
22022 occ2 = lglhts (lgl, other2)->count;
22023 occ3 = lglhts (lgl, other3)->count;
22024 if (occ2 > occ3) l = k;
22025 else if (occ2 < occ3) l = j;
22026 else l = (lglrand (lgl) & 1) ? j : k;
22029 tmp = lglpeek (&card->atmost2, start + l);
22030 assert (abs (tmp) != abs (lit));
22031 assert (card->lit2count[tmp] > 0);
22032 card->lit2count[tmp] = 0;
22033 while (l + 1 < size) {
22034 tmp = lglpeek (&card->atmost2, start + l + 1);
22035 assert (abs (tmp) != abs (lit));
22036 lglpoke (&card->atmost2, start + l++, tmp);
22038 assert (l == size - 1);
22039 card->atmost2.top--;
22041 assert (size >= 4);
22042 assert (card->atmost2.start + start + size == card->atmost2.top);
22049 if (lgl->opts->log.val >= CARDLOGLEVEL) {
22050 lglogstart (lgl, CARDLOGLEVEL,
22051 "non trivial size %d at-most-two constraint 2 >= ", size);
22052 for (i = start; i < start + size; i++) {
22053 if (i > start) fputs (" + ", lgl->out);
22054 fprintf (lgl->out, "%d", lglpeek (&card->atmost2, i));
22059 for (i = start; i < start + size; i++) {
22060 other = lglpeek (&card->atmost2, i);
22061 card->lit2count[other] = 0;
22062 card->lit2used[other] = 1;
22063 if (!ignused) lglpushstk (lgl, &card->occs[other], start);
22065 lglpushstk (lgl, &card->atmost2, 0);
22066 lgl->stats->card.am2.found.sum += size;
22067 lgl->stats->card.am2.found.cnt++;
22071 static int lglcard2extract (LGL * lgl) {
22072 struct { int cnt; int64_t sum; } before, after, delta;
22073 const int ignused = lgl->opts->cardignused.val;
22074 Card * card = lgl->card;
22076 lglpushstk (lgl, &card->atmost2, 0);
22077 NEW (card->lit2used, 2*lgl->nvars);
22078 card->lit2used += lgl->nvars;
22079 NEW (card->lit2count, 2*lgl->nvars);
22080 card->lit2count += lgl->nvars;
22082 NEW (card->occs, 2*lgl->nvars);
22083 card->occs += lgl->nvars;
22086 before.cnt = lgl->stats->card.am2.found.cnt;
22087 before.sum = lgl->stats->card.am2.found.sum;
22089 lglrandlitrav (lgl, lglcard2extractlit);
22091 after.cnt = lgl->stats->card.am2.found.cnt;
22092 after.sum = lgl->stats->card.am2.found.sum;
22093 assert (after.cnt >= before.cnt);
22094 assert (after.sum >= before.sum);
22095 delta.cnt = after.cnt - before.cnt;
22096 delta.sum = after.sum - before.sum;
22098 card->lit2used -= lgl->nvars;
22099 DEL (card->lit2used, 2*lgl->nvars);
22100 card->lit2count -= lgl->nvars;
22101 DEL (card->lit2count, 2*lgl->nvars);
22102 if (!ignused) lglcardreloccs (lgl);
22106 "[card-%d] found %d at-most-two constraints of average size %.1f",
22107 lgl->stats->card.count, delta.cnt, lglavg (delta.sum, delta.cnt));
22110 "[card-%d] no at-most-two constraint found",
22111 lgl->stats->card.count);
22116 static int lglcarduseclswithlit (LGL * lgl, int lit) {
22117 int pos = !lglmtstk (lgl->card->occs + lit);
22118 int neg = !lglmtstk (lgl->card->occs - lit);
22119 int level = lgl->opts->carduse.val;
22122 case 1: return pos && !neg;
22123 case 2: return pos;
22124 default: assert (level == 3); return pos || neg;
22128 static int lglcardelim (LGL * lgl, int count) {
22129 int blit, tag, other, other2, bound, used;
22130 int idx, sign, lit, start, len, res, glue;
22131 const int * p, * w, * eow, * c, * q;
22132 Card * card = lgl->card;
22138 NEW (card->occs, 2*lgl->nvars);
22139 NEW (card->eliminated, lgl->nvars);
22140 NEW (card->count, lgl->nvars);
22141 card->occs += lgl->nvars;
22144 lglfactor (lgl, lgl->stats->card.count, lgl->opts->cardmaxlen.val);
22145 for (start = 1; start < lglcntstk (&card->atmost1); start++) {
22146 for (len = 0; lglpeek (&card->atmost1, start + len); len++)
22148 if (len >= lgl->opts->cardminlen.val &&
22149 len <= cardmaxlen &&
22150 lgladdcard (lgl, card->atmost1.start + start, 1)) {
22151 lgl->stats->card.am1.used.sum += len;
22152 lgl->stats->card.am1.used.cnt++;
22157 for (start = 1; start < lglcntstk (&card->atmost2); start++) {
22158 for (len = 0; lglpeek (&card->atmost2, start + len); len++)
22160 if (len >= lgl->opts->cardminlen.val &&
22161 len <= cardmaxlen &&
22162 lgladdcard (lgl, card->atmost2.start + start, 2)) {
22163 lgl->stats->card.am2.used.sum += len;
22164 lgl->stats->card.am2.used.cnt++;
22171 "[card-%d] %d out of %d constraints (%.0f%%) meet size limits",
22172 lgl->stats->card.count, used, count, lglpcnt (used, count));
22175 "[card-%d] no constraint out of %d meets size limits",
22176 lgl->stats->card.count, count);
22179 for (idx = 2; idx < lgl->nvars; idx++) {
22180 if (lglmtstk (card->occs + idx) &&
22181 lglmtstk (card->occs - idx)) continue;
22182 LOG (CARDLOGLEVEL, "variable %d scheduled for elimination", idx);
22183 lglpushstk (lgl, &card->elim, idx);
22185 if (!lgl->opts->carduse.val) goto DO_NOT_USE_CLAUSES;
22186 for (idx = 2; idx < lgl->nvars; idx++) {
22187 if (lglterminate (lgl) ||
22188 lgl->limits->card.steps < INCSTEPS (card.steps)) goto SKIP;
22189 for (sign = -1; sign <= 1; sign += 2) {
22191 if (!lglcarduseclswithlit (lgl, lit)) continue;
22192 hts = lglhts (lgl, lit);
22193 w = lglhts2wchs (lgl, hts);
22194 eow = w + hts->count;
22195 for (p = w; p < eow; p++) {
22197 tag = blit & MASKCS;
22198 if (tag == TRNCS || tag == LRGCS) p++;
22199 if (tag == BINCS) {
22200 other = blit >> RMSHFT;
22201 if (abs (other) < idx) continue;
22202 clause[0] = -lit, clause[1] = -other, clause[2] = 0;
22203 (void) lgladdcard (lgl, clause, 1);
22204 } else if (tag == TRNCS) {
22205 other = blit >> RMSHFT;
22206 if (abs (other) < idx) continue;
22208 if (abs (other2) < idx) continue;
22209 clause[0] = -lit, clause[1] = -other,
22210 clause[2] = -other2, clause[3] = 0;
22211 (void) lgladdcard (lgl, clause, 2);
22212 } else assert (tag == LRGCS);
22216 for (glue = -1; glue <= lgl->opts->cardglue.val; glue++) {
22217 s = (glue < 0) ? &lgl->irr : lgl->red + glue;
22218 for (c = s->start; c < s->top; c = p + 1) {
22219 if (*(p = c) >= NOTALIT) continue;
22220 for (p = c; *p; p++)
22222 for (q = c; (lit = *q); q++)
22223 if (lglcarduseclswithlit (lgl, lit)) break;
22224 if (!lit) continue;
22226 if (len > cardmaxlen) continue;
22229 assert (lglmtstk (&lgl->clause));
22230 for (q = c; (lit = *q); q++)
22231 lglpushstk (lgl, &lgl->clause, -lit);
22232 lglpushstk (lgl, &lgl->clause, 0);
22233 (void) lgladdcard (lgl, lgl->clause.start, bound);
22234 lglclnstk (&lgl->clause);
22235 if (lglterminate (lgl) ||
22236 lgl->limits->card.steps < INCSTEPS (card.steps)) goto SKIP;
22239 DO_NOT_USE_CLAUSES:
22242 lglcardreloccs (lgl);
22243 DEL (card->count, lgl->nvars);
22244 lglrelstk (lgl, &card->cards);
22245 lglrelstk (lgl, &card->elim);
22246 DEL (card->eliminated, lgl->nvars);
22249 "[card-%d] produced empty clause",
22250 lgl->stats->card.count);
22251 else if (!lglmtstk (&card->units)) {
22253 "[card-%d] found %d units",
22254 lgl->stats->card.count, lglcntstk (&card->units));
22255 while (!lgl->mt && !lglmtstk (&card->units)) {
22256 lit = lglpopstk (&card->units);
22257 if (lglval (lgl, lit) > 0) continue;
22258 if (lglval (lgl, lit) < 0) {
22260 "[card-%d] found inconsistent unit",
22261 lgl->stats->card.count);
22264 lglunit (lgl, lit);
22265 if (!lglbcp (lgl)) {
22267 "[card-%d] inconsistent unit propagation",
22268 lgl->stats->card.count);
22275 res = lglcntstk (&card->units);
22276 lglrelstk (lgl, &card->units);
22280 "[card-%d] found %d units", lgl->stats->card.count, res);
22282 lglprt (lgl, 1, "[card-%d] no units found", lgl->stats->card.count);
22284 if (!lglmtstk (&card->expam1)) {
22285 int generated = 0, exported = 0, genused = 0;
22286 for (c = card->expam1.start; c < card->expam1.top; c = p + 1) {
22287 int a, usefull = 0;
22289 for (p = c; (a = *p); p++) if (lglval (lgl, a)) break;
22290 if (a) { while (*++p) ; continue; }
22291 for (p = c; (a = -*p); p++) {
22293 for (q = p + 1; (b = -*q); q++)
22294 if (!lglhasbin (lgl, a, b)) {
22296 "exporting at-most-one constraint binary clause %d %d",
22298 assert (lglmtstk (&lgl->clause));
22299 lglpushstk (lgl, &lgl->clause, a);
22300 lglpushstk (lgl, &lgl->clause, b);
22301 lglpushstk (lgl, &lgl->clause, 0);
22302 lgladdcls (lgl, REDCS, 0, 1);
22303 lglclnstk (&lgl->clause);
22304 lgl->stats->card.expam1++;
22307 assert (!lgl->opts->drup.val);
22308 #ifndef NLGLPICOSAT
22309 lglpicosatchkclsarg (lgl, a, b, 0);
22313 if (usefull) genused++;
22316 "[card-%d] generated %d at-most-one constraints, %d used %.0f%%",
22317 lgl->stats->card.count,
22318 generated, genused, lglpcnt (genused, generated));
22320 "[card-%d] exported %d binary clauses, %.1f per/constraint",
22321 lgl->stats->card.count, exported, lglavg (exported, genused));
22324 "[card-%d] no at-most-one constraints generated",
22325 lgl->stats->card.count);
22327 lglrelstk (lgl, &card->expam1);
22331 static int lglcard (LGL * lgl) {
22332 int success, count;
22335 lglstart (lgl, &lgl->times->card);
22336 lgl->stats->card.count++;
22337 if (lgl->level) lglbacktrack (lgl, 0);
22338 limit = lglsetcardlim (lgl);
22339 assert (!lgl->card);
22340 NEW (lgl->card, 1);
22341 count = lglcard1extract (lgl) + lglcard2extract (lgl);
22342 if (!lglterminate (lgl) && count) {
22343 lglsetcardlimagain (lgl, limit);
22344 success = lglcardelim (lgl, count);
22345 } else success = 0;
22346 lglrelstk (lgl, &lgl->card->atmost1);
22347 lglrelstk (lgl, &lgl->card->atmost2);
22348 DEL (lgl->card, 1);
22349 LGLUPDPEN (card, success);
22354 /*------------------------------------------------------------------------*/
22356 static int lglrdpclslim (LGL * lgl) {
22359 res64 = lgl->opts->rdpclslim.val + (int64_t) lgl->stats->rdp.count;
22360 res = res64 > INT_MAX ? INT_MAX : res64;
22364 static void lglrdpaddcls (LGL * lgl, const int * c) {
22365 int cidx = lglcntstk (&lgl->rdp->lits), lit;
22367 for (p = c; (lit = *p); p++)
22369 if (p - c > lglrdpclslim (lgl) + 1) return;
22370 for (p = c; (lit = *p); p++) {
22371 lgl->rdp->count[lit]++;
22372 lglpushstk (lgl, &lgl->rdp->occs[lit], cidx);
22373 lglpushstk (lgl, &lgl->rdp->lits, lit);
22375 lglpushstk (lgl, &lgl->rdp->lits, 0);
22378 static void lglrdpconbintrn (LGL * lgl) {
22379 int idx, sign, lit, blit, tag, red, other, other2, cls[4];
22380 const int * p, * w, * eow;
22382 for (sign = -1; sign <= 1; sign += 2)
22383 for (idx = 2; idx < lgl->nvars; idx++) {
22385 hts = lglhts (lgl, lit);
22386 w = lglhts2wchs (lgl, hts);
22387 eow = w + hts->count;
22388 for (p = w; p < eow; p++) {
22390 tag = blit & MASKCS;
22391 red = blit & REDCS;
22392 if (tag == TRNCS || tag == LRGCS) p++;
22393 if (tag == LRGCS) continue;
22394 if (tag == BINCS) {
22395 if (red && lgl->opts->rdp.val < 2) continue;
22396 other = blit >> RMSHFT;
22397 if (abs (other) < idx) continue;
22398 cls[0] = lit, cls[1] = other, cls[2] = 0;
22399 } else if (tag == TRNCS) {
22400 if (red && lgl->opts->rdp.val < 3) continue;
22401 other = blit >> RMSHFT;
22402 if (abs (other) < idx) continue;
22404 if (abs (other2) < idx) continue;
22405 cls[0] = lit, cls[1] = other, cls[2] = other2, cls[3] = 0;
22407 lglrdpaddcls (lgl, cls);
22412 static void lglrdpconlrg (LGL * lgl) {
22413 const int * c, * p;
22414 for (c = lgl->irr.start; c < lgl->irr.top; c = p + 1) {
22415 if (*(p = c) >= NOTALIT) continue;
22419 lglrdpaddcls (lgl, c);
22423 static void lglrdpreport (LGL * lgl) {
22424 lglgenericreport (lgl,
22425 "rdp", lgl->stats->rdp.count,
22426 lgl->rdp->eliminated, lgl->nvars, lgl->rdp->start);
22429 static void lglrdpinit (LGL * lgl) {
22431 lgl->rdp->start = lglgetime (lgl);
22432 lglrdpreport (lgl);
22433 NEW (lgl->rdp->count, 2*lgl->nvars);
22434 lgl->rdp->count += lgl->nvars;
22435 NEW (lgl->rdp->occs, 2*lgl->nvars);
22436 lgl->rdp->occs += lgl->nvars;
22437 lglrdpconbintrn (lgl);
22438 lglrdpconlrg (lgl);
22439 lglfitstk (lgl, &lgl->rdp->lits);
22442 static void lglrdpreset (LGL * lgl) {
22443 int nvars = lgl->nvars;
22445 for (p = lgl->rdp->occs - nvars; p < lgl->rdp->occs + nvars; p++)
22446 lglrelstk (lgl, p);
22447 lgl->rdp->occs -= nvars;
22448 DEL (lgl->rdp->occs, 2*nvars);
22449 lgl->rdp->count -= nvars;
22450 DEL (lgl->rdp->count, 2*nvars);
22451 lglrelstk (lgl, &lgl->rdp->lits);
22457 static void lglrdpcollect (LGL * lgl, Stk * s) {
22458 int * q = s->start;
22460 for (p = q; p < s->top; p++) {
22462 const int * c = lgl->rdp->lits.start + cidx;
22463 assert (c < lgl->rdp->lits.top);
22464 if (*c != REMOVED) *q++ = cidx;
22466 LOG (RDPL, "collected %ld references", (long)(s->top - q));
22470 static void lglrdpflush (LGL * lgl, Stk * s) {
22471 const int * p, * q;
22472 for (p = s->start; p < s->top; p++) {
22473 int cidx = *p, * c = lgl->rdp->lits.start + cidx, lit;
22474 assert (c < lgl->rdp->lits.top);
22475 INCSTEPS (rdp.steps);
22476 for (q = c; (lit = *q); q++) {
22477 assert (lgl->rdp->count[lit] > 0);
22478 lgl->rdp->count[lit]--;
22482 LOG (RDPL, "flushed %d references", lglcntstk (s));
22485 static int lglrdpresolve (LGL * lgl, int pivot, int cidx, int didx) {
22486 int res, lit, val, csize, dsize, rsize, resolventsize, conlypos, donlypos;
22487 const int * c = lgl->rdp->lits.start + cidx, * p;
22488 const int * d = lgl->rdp->lits.start + didx;
22489 const int64_t lim = lglrdpclslim (lgl);
22490 res = resolventsize = 0;
22491 assert (pivot > 0);
22492 assert (c < lgl->rdp->lits.top);
22493 assert (d < lgl->rdp->lits.top);
22494 assert (lglmtstk (&lgl->clause));
22495 INCSTEPS (rdp.steps);
22496 lgl->stats->rdp.res++;
22497 LOGCLS (RDPL+1, c, "RDP resolution 1st antecedent");
22499 for (p = c; resolventsize <= lim && (lit = *p); p++) {
22500 if (lit == pivot) continue;
22501 if (lit < 0) conlypos = 0;
22502 assert (lit != -pivot);
22503 val = lglval (lgl, lit);
22504 if (val < 0) continue;
22507 LOG (RDPL + 1, "1st antecedent statisfied");
22510 lglpushstk (lgl, &lgl->clause, lit);
22511 lglmark (lgl, lit);
22515 LOGCLS (RDPL+1, d, "RDP resolution 2nd antecedent");
22517 for (p = d; resolventsize <= lim && (lit = *p); p++) {
22518 if (-lit == pivot) continue;
22519 if (lit < 0) donlypos = 0;
22520 assert (lit != -pivot);
22521 val = lglval (lgl, lit);
22522 if (val < 0) continue;
22525 LOG (RDPL + 1, "2nd antecedent statisfied");
22528 val = lglmarked (lgl, lit);
22529 if (val > 0) continue;
22532 LOG (RDPL + 1, "skipping trivial RDP resolvent");
22535 lglpushstk (lgl, &lgl->clause, lit);
22538 if (resolventsize > lim) {
22539 LOG (RDPL+1, "RDP larger than %d literals", lim);
22540 lgl->stats->rdp.limhit.len++;
22544 if (resolventsize > 1 &&
22545 lgl->opts->rdpmodelm.val && !conlypos && !donlypos) {
22546 LOG (RDPL+1, "RDP model elimination prohibits resolution");
22547 lgl->stats->rdp.limhit.model++;
22552 rsize = lglcntstk (&lgl->clause);
22553 assert (rsize == resolventsize);
22554 lglpushstk (lgl, &lgl->clause, 0);
22555 LOGCLS (RDPL+1, lgl->clause.start, "add non-trivial RDP resolvent");
22556 lglrdpaddcls (lgl, lgl->clause.start);
22558 LOG (1, "RDP produced empty clause");
22560 } else if (rsize == 1) {
22561 lit = lglpeek (&lgl->clause, 0);
22562 val = lglval (lgl, lit);
22564 LOG (1, "RDP produced inconsistent unit %d", lit);
22567 LOG (1, "RDP produced unit %d", lit);
22568 lgl->stats->rdp.units++;
22569 lglunit (lgl, lit);
22570 if (!lglbcp (lgl)) {
22571 LOG (1, "propagating RDP units produces empty clause");
22575 } else if (rsize == 2 && (csize > 2 || dsize > 2)) {
22576 int a = lglpeek (&lgl->clause, 0);
22577 int b = lglpeek (&lgl->clause, 1);
22578 INCSTEPS (rdp.steps);
22579 if (!lglhasbin (lgl, a, b)) {
22580 LOGCLS (RDPL+1, lgl->clause.start, "exporting binary RDP resolvent");
22581 lgladdcls (lgl, REDCS, 0, 1);
22582 lgl->stats->rdp.bin++;
22583 #ifndef NLGLPICOSAT
22584 lglpicosatchkcls (lgl);
22587 } else if (rsize == 3 && (csize > 3 || dsize > 3)) {
22588 int a = lglpeek (&lgl->clause, 0);
22589 int b = lglpeek (&lgl->clause, 1);
22590 int c = lglpeek (&lgl->clause, 2);
22591 INCSTEPS (rdp.steps);
22592 if (!lglhastrn (lgl, a, b, c)) {
22593 LOGCLS (RDPL+1, lgl->clause.start, "exporting ternary RDP resolvent");
22594 lgladdcls (lgl, REDCS, 0, 1);
22595 lgl->stats->rdp.trn++;
22596 #ifndef NLGLPICOSAT
22597 lglpicosatchkcls (lgl);
22603 while (!lglmtstk (&lgl->clause)) {
22604 lit = lglpopstk (&lgl->clause);
22605 if (lit) lglunmark (lgl, lit);
22610 static int lglrdplit (LGL * lgl, int idx) {
22611 int64_t npos, nneg, k, i, j, r, p, s, l;
22612 Stk * pos = &lgl->rdp->occs[idx];
22613 Stk * neg = &lgl->rdp->occs[-idx];
22614 lgl->stats->rdp.elim += 1;
22616 "RDP pivot %d: pos %d/%d + neg %d/%d",
22618 lgl->rdp->count[idx], lglcntstk (pos),
22619 lgl->rdp->count[-idx], lglcntstk (neg));
22620 lglrdpcollect (lgl, pos), lglrdpcollect (lgl, neg);
22621 assert (lgl->rdp->count[idx] >= lglcntstk (pos));
22622 assert (lgl->rdp->count[-idx] >= lglcntstk (neg));
22623 npos = lglcntstk (pos), nneg = lglcntstk (neg);
22624 if (!npos || !nneg) goto DONE;
22625 l = ((npos + nneg) * lgl->opts->rdplim.val + 50)/100;
22628 while (!p || lglgcd64 (p, r) != 1) p++;
22630 s = k = lglrand (lgl) % r;
22632 "RDP traversal range %lld = %lld * %lld start %lld period %lld limit %lld",
22633 (LGLL) r, (LGLL) npos, (LGLL) nneg, (LGLL) s, (LGLL) p, (LGLL) l);
22635 i = k / nneg, j = k % nneg;
22636 LOG (RDPL + 1, "trying index %lld RDP pair %d %d", (LGLL) k, i, j);
22637 if (lglrdpresolve (lgl, idx, lglpeek (pos, i), lglpeek (neg, j))) l--;
22638 k += p; if (k >= r) k -= r;
22639 assert (0 <= k && k < r);
22640 if (l < 0) lgl->stats->rdp.limhit.bound++;
22641 } while (!lgl->mt && l >= 0 && s != k);
22643 lglrdpflush (lgl, pos), lglrdpflush (lgl, neg);
22644 lglrelstk (lgl, pos), lglrelstk (lgl, neg);
22645 lgl->rdp->eliminated++;
22646 lglrdpreport (lgl);
22647 return !lgl->mt && lgl->stats->rdp.steps < lgl->limits->rdp.steps;
22650 static void lglsetrdplim (LGL * lgl) {
22651 int64_t limit, irrlim;
22653 limit = (lgl->opts->rdpreleff.val*lglvisearch (lgl))/1000;
22654 if (limit < lgl->opts->rdpmineff.val) limit = lgl->opts->rdpmineff.val;
22655 if (lgl->opts->rdpmaxeff.val >= 0 && limit > lgl->opts->rdpmaxeff.val)
22656 limit = lgl->opts->rdpmaxeff.val;
22657 limit >>= (pen = lgl->limits->rdp.pen + lglszpen (lgl));
22658 irrlim = 3*lgl->stats->irr.clauses.cur;
22659 irrlim >>= lgl->limits->simp.pen;
22660 if (lgl->opts->irrlim.val && limit < irrlim) {
22663 "[rdp-%d] limit %lld based on %d irredundant clauses",
22664 lgl->stats->rdp.count, (LGLL) limit, lgl->stats->irr.clauses.cur);
22666 lglprt (lgl, 1, "[rdp-%d] limit %lld with penalty %d = %d + %d",
22667 lgl->stats->rdp.count, (LGLL) limit,
22668 pen, lgl->limits->rdp.pen, lglszpen (lgl));
22669 lgl->limits->rdp.steps = lgl->stats->rdp.steps + limit;
22672 static int lglrdp (LGL * lgl) {
22673 int oldunits, newunits, deltaunits, success;
22674 int oldtrn, newtrn, deltatrn;
22675 int oldbin, newbin, deltabin;
22676 if (lgl->nvars <= 2) return 1;
22677 if (lgl->mt) return 0;
22678 lglstart (lgl, &lgl->times->rdp);
22679 lgl->stats->rdp.count++;
22680 if (lgl->level) lglbacktrack (lgl, 0);
22681 assert (!lgl->simp);
22683 lglsetrdplim (lgl);
22684 oldunits = lgl->stats->rdp.units;
22685 oldbin = lgl->stats->rdp.bin;
22686 oldtrn = lgl->stats->rdp.trn;
22688 lglrandidxtrav (lgl, lglrdplit);
22689 lglrdpreport (lgl);
22691 newunits = lgl->stats->rdp.units; deltaunits = (newunits - oldunits);
22692 newbin = lgl->stats->rdp.bin; deltabin = (newbin - oldbin);
22693 newtrn = lgl->stats->rdp.trn; deltatrn = (newtrn - oldtrn);
22695 "[rdp-%d] found %d units, %d binary and %d ternary clauses",
22696 lgl->stats->rdp.count, deltaunits, deltabin, deltatrn);
22697 success = deltaunits + deltabin + deltatrn;
22698 LGLUPDPEN (rdp, success);
22699 assert (lgl->simp);
22705 /*------------------------------------------------------------------------*/
22707 static int lglbcaoccmin (LGL * lgl, int lit) {
22708 int * p, * w, * eow;
22709 int res, blit, red, tag;
22711 hts = lglhts (lgl, lit);
22712 w = lglhts2wchs (lgl, hts);
22713 eow = w + hts->count;
22715 for (p = w; res <= 3 && p < eow; p++) {
22717 tag = blit & MASKCS;
22718 red = blit & REDCS;
22719 if (tag == TRNCS || tag == LRGCS) p++;
22720 if (tag == LRGCS) continue;
22726 static int lglbcaskiplit (LGL * lgl, int lit) {
22728 if (lgl->opts->bca.val >= 2) return 0;
22729 pocc = lglbcaoccmin (lgl, lit);
22730 if (pocc <= 1) return 1;
22731 nocc = lglbcaoccmin (lgl, -lit);
22732 if (nocc <= 1) return 1;
22733 return pocc == 2 && nocc == 2;
22736 static void lglbcalitaux (LGL * lgl, int lit) {
22737 int first, blit, tag, red, lidx, other, tmp, found, other2, found2, * r;
22738 const int * w, * p, * eow, * c, * q;
22739 Stk * covered = &lgl->bca->covered;
22742 assert (lglisfree (lgl, lit));
22743 assert (lgl->opts->bca.val);
22744 assert (!(lglavar (lgl, lit)->inred & (1 << (lit < 0))));
22745 hts = lglhts (lgl, lit);
22746 if (!hts->count) return;
22747 if (lglbcaskiplit (lgl, lit)) { lgl->stats->bca.skipped++; return; }
22748 assert (lglmtstk (covered));
22750 w = lglhts2wchs (lgl, hts);
22751 eow = w + hts->count;
22752 for (round = 0; round < 2; round++) {
22753 for (p = w; (first || !lglmtstk (covered)) && p < eow; p++) {
22755 tag = blit & MASKCS;
22756 red = blit & REDCS;
22757 if (tag == TRNCS || tag == LRGCS) p++;
22758 assert (!red || tag != LRGCS);
22759 if (tag == LRGCS) continue;
22760 if (round != (tag == OCCS)) continue;
22761 INCSTEPS (bca.steps);
22762 if (tag == BINCS) {
22764 other = blit >> RMSHFT;
22765 if (lglval (lgl, other) > 0) continue;
22766 assert (!lglval (lgl, other));
22768 while (!lglmtstk (covered))
22769 if (other == lglpopstk (covered)) found = 1;
22770 if (found) lglpushstk (lgl, covered, other);
22771 } else if (tag == TRNCS) {
22773 other = blit >> RMSHFT;
22774 if (lglval (lgl, other) > 0) continue;
22776 if (lglval (lgl, other2) > 0) continue;
22777 found = found2 = first;
22778 while (!lglmtstk (covered))
22779 if (other == (tmp = lglpopstk (covered))) found = 1;
22780 else if (tmp == other2) found2 = 1;
22781 if (found && !lglval (lgl, other)) lglpushstk (lgl, covered, other);
22782 if (found2 && !lglval (lgl, other2)) lglpushstk (lgl, covered, other2);
22786 assert (tag == OCCS);
22787 lidx = blit >> RMSHFT;
22788 c = lglidx2lits (lgl, red, lidx);
22789 INCSTEPS (bca.steps);
22790 for (q = c; (other = *q); q++)
22791 if (other != lit && lglval (lgl, other) > 0) break;
22792 if (other) continue;
22794 for (q = c; (other = *q); q++)
22795 if (other != lit && !lglval (lgl, other))
22796 lglpushstk (lgl, covered, other);
22798 for (q = covered->start; q < covered->top; q++)
22799 assert (!lglsignedmarked (lgl, *q)), lglsignedmark (lgl, *q);
22800 for (q = c; (other = *q); q++)
22801 if (other != lit && lglsignedmarked (lgl, other))
22802 assert (!lglval (lgl, other)), lglsignedunmark (lgl, other);
22803 r = covered->start;
22804 for (q = r; q < covered->top; q++)
22805 if (lglsignedmarked (lgl, (other = *q)))
22806 lglsignedunmark (lgl, other);
22816 static int lglbcalit (LGL * lgl, int lit) {
22820 if (lgl->limits->bca.steps < lgl->stats->bca.steps) return 0;
22821 if (lglterminate (lgl)) return 0;
22822 if (lglifrozen (lgl, lit)) return 1;
22823 if (!lglisfree (lgl, lit)) return 1;
22824 av = lglavar (lgl, lit);
22825 bit = (1 << (lit < 0));
22826 if (av->inred & bit) return 1;
22827 lglbcalitaux (lgl, lit);
22828 while (!lglmtstk (&lgl->bca->covered)) {
22829 INCSTEPS (bca.steps);
22830 other = lglpopstk (&lgl->bca->covered);
22831 if (lglhasbin (lgl, -lit, -other)) continue;
22832 LOG (2, "adding binary blocked clause %d %d", -lit, -other);
22833 assert (lglmtstk (&lgl->clause));
22834 lglpushstk (lgl, &lgl->clause, -lit);
22835 lglpushstk (lgl, &lgl->clause, -other);
22836 lglpushstk (lgl, &lgl->clause, 0);
22837 lgladdcls (lgl, REDCS, 0, 1);
22838 lglclnstk (&lgl->clause);
22839 lgl->stats->bca.added++;
22844 static void lglupdbcadel (LGL * lgl, int success) {
22845 if (success && lgl->limits->bca.del.cur)
22846 lgl->limits->bca.del.cur /= 2;
22847 if (!success && lgl->limits->bca.del.cur < lgl->opts->delmax.val)
22848 lgl->limits->bca.del.cur++;
22849 lgl->limits->bca.del.rem = lgl->limits->bca.del.cur;
22852 static void lglbca (LGL * lgl) {
22853 int oldadded = lgl->stats->bca.added, added;
22854 int idx, glue, other, inred, usable;
22855 const int * c, * p;
22860 lglstart (lgl, &lgl->times->bca);
22864 lgl->stats->bca.count++;
22865 oldsteps = lgl->stats->bca.steps;
22866 lgl->limits->bca.steps = oldsteps + lgl->opts->bcamaxeff.val;
22867 lglprt (lgl, 1, "[bca-%d] limit of %d steps",
22868 lgl->stats->bca.count, lgl->opts->bcamaxeff.val);
22870 assert (!lgl->bcaing);
22873 if (lgl->level > 0) lglbacktrack (lgl, 0);
22875 assert (lgl->frozen);
22877 for (idx = 2; idx < lgl->nvars; idx++) lglavar (lgl, idx)->inred = 0;
22879 for (glue = 0; glue <= MAXGLUE; glue++) {
22880 Stk * s = lgl->red + glue;
22881 for (c = s->start; c < s->top; c = p + 1) {
22883 if (*p >= NOTALIT) continue;
22884 INCSTEPS (bca.steps);
22885 while ((other = *p)) {
22887 bit = (1 << (other < 0));
22888 av = lglavar (lgl, other);
22889 if (av->inred & bit) continue;
22896 "[bca-%d] %d out of %d literals in large redundant clauses %.0f%%",
22897 lgl->stats->bca.count,
22898 inred, 2*(lgl->nvars-1), lglpcnt (inred, 2*(lgl->nvars-1)));
22901 for (idx = 2; idx < lgl->nvars; idx++) {
22902 if (lglifrozen (lgl, idx)) continue;
22903 if (!lglisfree (lgl, idx)) continue;
22904 av = lglavar (lgl, idx);
22905 for (bit = 1; bit <= 2; bit++) if (!(av->inred & bit)) usable++;
22908 "[bca-%d] %d out of %d literals actually usable %.0f%%",
22909 lgl->stats->bca.count,
22910 usable, 2*(lgl->nvars-1), lglpcnt (usable, 2*(lgl->nvars-1)));
22912 if (usable < lgl->opts->bcaminuse.val) {
22913 lglprt (lgl, 1, "[bca-%d] not enough literals usable",
22914 lgl->stats->bca.count);
22919 lglrandlitrav (lgl, lglbcalit);
22924 added = lgl->stats->bca.added - oldadded;
22925 lglprt (lgl, 1, "[bca-%d] added %d blocked clauses in %lld steps",
22926 lgl->stats->bca.count, added,
22927 (LGLL) lgl->stats->bca.steps - oldsteps);
22928 assert (lgl->bcaing);
22930 lglupdbcadel (lgl, added);
22931 lglrelstk (lgl, &lgl->bca->covered);
22936 /*------------------------------------------------------------------------*/
22940 static int lglbvamult (LGL * lgl, int mult) {
22941 int other, blit, tag, red, res = 0;
22942 const int * p, * w, * eow;
22944 hts = lglhts (lgl, mult);
22945 w = lglhts2wchs (lgl, hts);
22946 eow = w + hts->count;
22947 for (p = w; p < eow; p++) {
22949 tag = blit & MASKCS;
22950 if (tag == TRNCS || tag == LRGCS) p++;
22951 if (tag != BINCS) continue;
22952 red = blit & REDCS;
22954 other = blit >> RMSHFT;
22955 if (lglsignedmarked (lgl, other)) res++;
22960 static void lglbvadef (LGL * lgl, int lit, int mult, Stk * factors) {
22964 static void lglbvalit (LGL * lgl, int lit, Stk * factors) {
22965 int other, blit, tag, red, count, mult, factor;
22966 const int * p, * w, * eow;
22968 if (!lglisfree (lgl, lit)) return;
22969 hts = lglhts (lgl, lit);
22970 if (hts->count < 3) return;
22971 LOG (BVAL, "trying to do BVA for literal %d", lit);
22972 lglclnstk (factors);
22973 w = lglhts2wchs (lgl, hts);
22974 eow = w + hts->count;
22975 for (p = w; p < eow; p++) {
22977 tag = blit & MASKCS;
22978 if (tag == TRNCS || tag == LRGCS) p++;
22979 if (tag != BINCS) continue;
22980 red = blit & REDCS;
22982 other = blit >> RMSHFT;
22983 if (!lglisfree (lgl, other)) continue;
22984 if (lglsignedmarked (lgl, other)) continue;
22985 lglsignedmark (lgl, other);
22986 lglpushstk (lgl, factors, other);
22988 count = lglcntstk (factors);
22989 LOG (BVAL, "found %d candidates to do BVA for literal %d", count, lit);
22990 while (lglcntstk (factors) >= 3) {
22991 factor = lgltopstk (factors);
22992 LOG (BVAL, "trying factor %d for candidate BVA literal %d", factor, lit);
22993 hts = lglhts (lgl, factor);
22994 w = lglhts2wchs (lgl, hts);
22995 eow = w + hts->count;
22996 for (p = w; p < eow; p++) {
22998 tag = blit & MASKCS;
22999 if (tag == TRNCS || tag == LRGCS) p++;
23000 if (tag != BINCS) continue;
23001 red = blit & REDCS;
23003 mult = blit >> RMSHFT;
23004 if (mult == lit) continue;
23005 if (!lglisfree (lgl, mult)) continue;
23006 if ((count = lglbvamult (lgl, mult)) < 3) continue;
23007 count = lglbvamult (lgl, mult);
23009 "multiplier %d with %d common factors for BVA literal %d",
23011 if (count < 3) continue;
23012 lglbvadef (lgl, lit, mult, factors);
23015 (void) lglpopstk (factors);
23016 lglsignedunmark (lgl, factor);
23019 while (!lglmtstk (factors)) {
23020 other = lglpopstk (factors);
23021 assert (lglsignedmarked (lgl, other));
23022 lglsignedunmark (lgl, other);
23026 static int lglcmpbvacands (int * binoccs, int a, int b) {
23027 return binoccs[a] - binoccs[b];
23030 #define LGLCMPBVACANDS(A,B) lglcmpbvacands (binoccs, *(A), *(B))
23032 static void lglbva (LGL * lgl) {
23033 int * binoccs, nvars, idx, sgn, lit, blit, red, tag, other, count;
23034 int oldirr, removed, added;
23035 const int * p, * w, * eow;
23036 Stk cands, factors;
23038 nvars = lgl->nvars;
23039 if (nvars <= 2) return;
23040 lglstart (lgl, &lgl->times->bva);
23041 lgl->stats->bva.count++;
23042 oldirr = lgl->stats->irr.clauses.cur;
23044 "[bva-%d] starting with %d variables and %d clauses",
23045 lgl->stats->bva.count, nvars - 2, oldirr);
23046 if (lgl->level > 0) lglbacktrack (lgl, 0);
23047 NEW (binoccs, 2*nvars);
23050 for (idx = 2; idx < nvars; idx++) {
23051 if (!lglisfree (lgl, idx)) continue;
23052 for (sgn = -1; sgn <= 1; sgn += 2) {
23054 hts = lglhts (lgl, lit);
23055 if (hts->count < 3) continue;
23057 w = lglhts2wchs (lgl, hts);
23058 eow = w + hts->count;
23059 for (p = w; p < eow; p++) {
23061 tag = blit & MASKCS;
23062 if (tag == TRNCS || tag == LRGCS) p++;
23063 if (tag != BINCS) continue;
23064 red = blit & REDCS;
23066 other = blit >> RMSHFT;
23067 if (!lglisfree (lgl, other)) continue;
23070 if (count < 3) continue;
23071 binoccs[lit] = count;
23072 lglpushstk (lgl, &cands, lit);
23075 if (lglmtstk (&cands)) {
23077 "[bva-%d] no candidates with at least three binary occurrences",
23078 lgl->stats->bva.count);
23082 "[bva-%d] %d candidates with at least three binary occurrences",
23083 lgl->stats->bva.count, lglcntstk (&cands));
23084 SORT (int, cands.start, lglcntstk (&cands), LGLCMPBVACANDS);
23086 while (!lglmtstk (&cands)) {
23087 lit = lglpopstk (&cands);
23088 lglbvalit (lgl, lit, &factors);
23090 lglrelstk (lgl, &factors);
23093 DEL (binoccs, 2*nvars);
23094 lglrelstk (lgl, &cands);
23095 added = lgl->nvars - nvars;
23096 assert (added >= 0);
23097 removed = oldirr - lgl->stats->irr.clauses.cur;
23098 assert (removed >= 0);
23099 lgl->stats->bva.added += added;
23100 lgl->stats->bva.removed += removed;
23102 "[bva-%d] removed %d clauses and added %d variables",
23103 lgl->stats->bva.count, removed, added);
23107 /*------------------------------------------------------------------------*/
23109 static int lgltreducing (LGL * lgl) {
23110 if (lgldelaying (lgl, "transred", &lgl->limits->trd.del.rem)) return 0;
23111 if (lglwaiting (lgl, "transred", lgl->opts->transredwait.val)) return 0;
23112 return lgl->opts->transred.val;
23115 static int lglunhiding (LGL * lgl) {
23116 if (lgldelaying (lgl, "unhide", &lgl->limits->unhd.del.rem)) return 0;
23117 if (lglwaiting (lgl, "unhide", lgl->opts->unhidewait.val)) return 0;
23118 return lgl->opts->unhide.val;
23121 static int lgldecomposing (LGL * lgl) { return lgl->opts->decompose.val; }
23123 static int lglcgrclosing (LGL * lgl) {
23124 if (lgldelaying (lgl, "cgrclsr", &lgl->limits->cgr.del.rem)) return 0;
23125 if (lglwaiting (lgl, "cgrclsr", lgl->opts->cgrclsrwait.val)) return 0;
23126 return lgl->opts->cgrclsr.val && lglsmallirr (lgl);
23129 static int lglifting (LGL * lgl) {
23130 if (lgldelaying (lgl, "lift", &lgl->limits->lft.del.rem)) return 0;
23131 if (lglwaiting (lgl, "lift", lgl->opts->liftwait.val)) return 0;
23132 return lgl->opts->lift.val;
23135 static int lglblocking (LGL * lgl) {
23136 if (!lgl->opts->block.val) return 0;
23137 if (lgl->allfrozen) return 0;
23138 if (lgldelaying (lgl, "block", &lgl->limits->blk.del.rem)) return 0;
23139 if (lgl->opts->blockwait.val && lgl->wait &&
23140 (!lgl->opts->elim.val || !lgl->elmrtc)) {
23142 "[block-waiting] for bounded variable elimination to be completed");
23145 if (!lglsmallirr (lgl)) return 0;
23146 if (lgl->nvars <= 2) return 0;
23147 if (lgl->mt) return 0;
23148 if (lgl->blkrem) return 1;
23149 return lgl->stats->irrprgss > lgl->limits->blk.irrprgss;
23152 static int lgleliminating (LGL * lgl) {
23153 if (!lgl->opts->elim.val) return 0;
23154 if (lgl->allfrozen) return 0;
23155 if (lgldelaying (lgl, "elim", &lgl->limits->elm.del.rem)) return 0;
23156 if (!lglsmallirr (lgl)) return 0;
23157 if (lgl->nvars <= 2) return 0;
23158 if (lgl->mt) return 0;
23159 if (lgl->elmrem) return 1;
23160 return lgl->stats->irrprgss > lgl->limits->elm.irrprgss;
23163 static int lglrdping (LGL * lgl) {
23164 if (lgldelaying (lgl, "rdp", &lgl->limits->rdp.del.rem)) return 0;
23165 if (lglwaiting (lgl, "rdp", lgl->opts->rdpwait.val)) return 0;
23166 return lgl->opts->rdp.val;
23169 static int lglbcaing (LGL * lgl) {
23170 if (!lgl->opts->bca.val) return 0;
23171 if (lgl->allfrozen) return 0;
23172 if (lgldelaying (lgl, "bca", &lgl->limits->bca.del.rem)) return 0;
23173 if (lglwaiting (lgl, "bca", lgl->opts->bcawait.val)) return 0;
23174 if (!lglsmallirr (lgl)) return 0;
23178 static int lglbvaing (LGL * lgl) {
23179 if (!lgl->opts->bva.val) return 0;
23183 static int lglreducing (LGL * lgl) {
23185 if (!lgl->opts->reduce.val) return 0;
23186 reducable = lgl->stats->red.lrg;
23187 assert (reducable >= lgl->lrgluereasons);
23188 reducable -= lgl->lrgluereasons;
23189 assert (reducable >= lgl->stats->lir[0].clauses);
23190 reducable -= lgl->stats->lir[0].clauses;
23191 return reducable >= lgl->limits->reduce.inner;
23194 static int lgldefragmenting (LGL * lgl) {
23196 if (lgl->stats->pshwchs < lgl->limits->dfg) return 0;
23197 if (!lgl->nvars) return 0;
23198 relfree = (100 * lgl->wchs->free + 99) / lgl->nvars;
23199 return relfree >= lgl->opts->defragfree.val;
23202 static int lglrestarting (LGL * lgl) {
23204 if (!lgl->opts->restart.val) return 0;
23205 if (!lgl->level) return 0;
23206 if ((assumptions = lglcntstk (&lgl->assume))) {
23207 if (lgl->assumed < assumptions) return 0;
23208 assert (lgl->alevel <= lgl->level);
23209 if (lgl->alevel == lgl->level) return 0;
23211 return lgl->stats->confs >= lgl->limits->restart.confs;
23214 static int lglternresolving (LGL * lgl) {
23215 if (lgldelaying (lgl, "ternres", &lgl->limits->trnr.del.rem)) return 0;
23216 if (lglwaiting (lgl, "ternres", lgl->opts->ternreswait.val)) return 0;
23217 return lgl->opts->ternres.val;
23220 static int lglgaussing (LGL * lgl) {
23221 if (lgldelaying (lgl, "gauss", &lgl->limits->gauss.del.rem)) return 0;
23222 if (lglwaiting (lgl, "gauss", lgl->opts->gausswait.val)) return 0;
23223 if (!lglsmallirr (lgl)) return 0;
23224 return lgl->opts->gauss.val;
23227 static int lglcliffing (LGL * lgl) {
23228 if (lgldelaying (lgl, "cliff", &lgl->limits->cliff.del.rem)) return 0;
23229 if (lglwaiting (lgl, "cliff", lgl->opts->cliffwait.val)) return 0;
23230 return lgl->opts->cliff.val;
23233 static int lglprobing (LGL * lgl) {
23234 if (!lgl->opts->probe.val) return 0;
23235 if (lgl->opts->prbasic.val) return 1;
23236 if (!lglsmallirr (lgl)) return 0;
23237 if (lgl->opts->prbsimple.val) return 1;
23238 if (lgl->opts->treelook.val) return 1;
23242 static int lglcarding (LGL * lgl) {
23243 if (!lgl->opts->card.val) return 0;
23244 if (lgldelaying (lgl, "card", &lgl->limits->card.del.rem)) return 0;
23245 if (lglwaiting (lgl, "card", lgl->opts->cardwait.val)) return 0;
23249 static int lglcceing (LGL * lgl) {
23250 if (!lgl->opts->cce.val) return 0;
23251 if (lgl->allfrozen) return 0;
23252 if (lgldelaying (lgl, "cce", &lgl->limits->cce.del.rem)) return 0;
23253 if (lglwaiting (lgl, "cce", lgl->opts->ccewait.val)) return 0;
23254 if (!lglsmallirr (lgl)) return 0;
23255 if (lgl->opts->cceonlyifstuck.val &&
23256 ((lgl->opts->elim.val && !lgl->elmstuck) ||
23257 (lgl->opts->block.val && !lgl->blkstuck))) {
23259 "[cce-%d] skipping since elmstuck=%d blkstuck=%d",
23260 lgl->stats->cce.count, lgl->elmstuck, lgl->blkstuck);
23266 /*------------------------------------------------------------------------*/
23268 static void lglupdlocslim (LGL * lgl, int updconflimtoo) {
23269 int rem = lglrem (lgl), varslimit, vardelta;
23270 vardelta = (rem * lgl->opts->locsvared.val + 999)/1000;
23271 if (vardelta > rem) vardelta = rem;
23272 varslimit = rem - vardelta;
23273 lgl->limits->locs.vars = varslimit;
23274 lglprt (lgl, 1 + !lgl->opts->locs.val,
23275 "[locs-lim] next local search variable limit %d = %d - %d",
23276 varslimit, rem, vardelta);
23277 if (!updconflimtoo) return;
23278 lgl->limits->locs.inc += lgl->opts->locscint.val;
23279 assert (lgl->limits->locs.confs <= LLMAX - lgl->limits->locs.inc);
23280 lgl->limits->locs.confs = lgl->stats->confs + lgl->limits->locs.inc;
23281 lglprt (lgl, 1 + !lgl->opts->locs.val,
23282 "[locs-lim] next local search conflict limit increased by %d to %lld",
23283 lgl->limits->locs.inc, lgl->limits->locs.confs);
23286 static int lglocsing (LGL * lgl) {
23289 if (!lgl->opts->locs.val) return 0;
23290 if (lgl->limits->locs.confs > lgl->stats->confs) return 0;
23291 if (lgl->stats->irr.clauses.cur > lgl->opts->locsclim.val) {
23292 lglprt (lgl, 2, "[locs] skipped due to too many clauses");
23295 rem = lglrem (lgl);
23296 if (rem < lgl->limits->locs.vars) {
23298 "[locs-limit] local search skipped (remaining %d < limit %d)",
23299 rem, lgl->limits->locs.vars);
23300 lglupdlocslim (lgl, 1);
23303 if (lglwaiting (lgl, "locs", lgl->opts->locswait.val)) return 0;
23304 if (lgl->opts->locs.val < 0) return 1;
23305 return (lgl->stats->locs.count < lgl->opts->locs.val);
23314 static void lglocscopy (LGL * lgl, Yals * yals) {
23315 int idx, sign, lit, blit, tag, red, other, other2;
23316 int count, redcount, units, tmp;
23317 const int * p, * w, * eow, * c;
23320 assert (!lgl->level);
23321 if (!lgl->mt && !lglbcp (lgl)) lgl->mt = 1;
23322 if (!lgl->mt) lglgc (lgl);
23323 if (lgl->mt) return;
23324 count = redcount = units = 0;
23325 for (idx = 2; idx < lgl->nvars; idx++)
23326 for (sign = -1; sign <= 1; sign += 2) {
23328 assert (!lglval (lgl, lit));
23329 hts = lglhts (lgl, lit);
23330 w = lglhts2wchs (lgl, hts);
23331 eow = w + hts->count;
23332 for (p = w; p < eow; p++) {
23334 tag = blit & MASKCS;
23335 red = blit & REDCS;
23336 if (tag == TRNCS || tag == LRGCS) p++;
23337 if (red && tag == BINCS && lgl->opts->locsred.val < 2) continue;
23338 if (red && tag == TRNCS && lgl->opts->locsred.val < 3) continue;
23339 if (tag != BINCS && tag != TRNCS) continue;
23340 other = blit >> RMSHFT;
23341 if (abs (other) < idx) continue;
23342 assert (!lglval (lgl, other));
23343 if (tag == TRNCS) {
23345 if (abs (other2) < idx) continue;
23346 assert (!lglval (lgl, other2));
23348 yals_add (yals, lit);
23349 yals_add (yals, other);
23350 if (other2) yals_add (yals, other2);
23351 yals_add (yals, 0);
23352 if (red) redcount++;
23356 for (idx = 2; idx < lgl->nvars; idx++) {
23357 tmp = lglifixed (lgl, idx);
23358 if (!tmp) continue;
23359 lit = (tmp < 0) ? -idx : idx;
23360 yals_add (yals, lit);
23361 yals_add (yals, 0);
23364 for (red = -1; red < MAXGLUE; red++) {
23365 s = red < 0 ? &lgl->irr : lgl->red + red;
23366 if (red >= 0 && lgl->opts->locsred.val < 4) break;
23367 for (c = s->start; c < s->top; c = p + 1) {
23369 if (*p >= NOTALIT) continue;
23370 while ((other = *p)) {
23371 assert (!lglval (lgl, other));
23372 yals_add (yals, other);
23375 yals_add (yals, 0);
23376 if (red >= 0) redcount++;
23382 "[locs-%d] copied %d irredundant clauses",
23383 lgl->stats->locs.count, count - redcount);
23386 "[locs-%d] copied %d redundant clauses",
23387 lgl->stats->locs.count, redcount);
23390 "[locs-%d] copied %d units",
23391 lgl->stats->locs.count, units);
23393 for (count = 0; count < lglcntstk (&lgl->assume); count++) {
23394 lit = lglpeek (&lgl->assume, count);
23395 if (abs (lit) <= 0) continue;
23396 yals_add (yals, lit);
23397 yals_add (yals, 0);
23401 "[locs-%d] copied %d assumptions as %d unit clauses",
23402 lgl->stats->locs.count, count, count);
23405 "[locs-%d] no assumptions copied",
23406 lgl->stats->locs.count);
23409 static int64_t lglsetlocslim (LGL * lgl) {
23412 if (lgl->opts->locsrtc.val) {
23415 "[locs-%d] no limit (run to completion)",
23416 lgl->stats->locs.count);
23418 limit = (lgl->opts->locsreleff.val*lglvisearch (lgl))/100;
23419 if (limit < lgl->opts->locsmineff.val)
23420 limit = lgl->opts->locsmineff.val;
23421 if (lgl->opts->locsmaxeff.val >= 0 &&
23422 limit > lgl->opts->locsmaxeff.val)
23423 limit = lgl->opts->locsmaxeff.val;
23424 if (lgl->stats->locs.count <= 1 &&
23425 lgl->opts->boost.val &&
23426 lgl->opts->locsboost.val > 1) {
23427 boost = lgl->opts->locsboost.val;
23429 "[locs-%d] intially boosting limit by factor of %d",
23430 lgl->stats->locs.count, boost);
23433 pen = lglitszpen (lgl);
23436 "[locs-%d] limit %lld literal penalty %d",
23437 lgl->stats->locs.count, (LGLL) limit, pen);
23444 static int lglocsaux (LGL * lgl, int hitlim) {
23447 int res, min, pos, neg, idx, lit, old_val, len;
23448 const int set = lgl->opts->locset.val;
23449 int save = lgl->opts->locsexport.val;
23450 unsigned long long seed;
23456 lglstart (lgl, &lgl->times->locs);
23457 if (lgl->level) lglbacktrack (lgl, 0);
23458 if (!lgl->stats->locs.count++) {
23459 const char * yals_version ();
23462 lgl->stats->locs.count, yals_version ());
23464 yals = yals_new_with_mem_mgr ( lgl,
23465 (YalsMalloc) lglnew, (YalsRealloc) lglrsz, (YalsFree) lgldel);
23466 yals_setout (yals, lgl->out);
23467 len = strlen (lgl->prefix) + 80;
23470 sprintf (prefix, "%s%d [locs-%d] ",
23471 lgl->prefix, lgl->tid, lgl->stats->locs.count);
23473 sprintf (prefix, "%s[locs-%d] ", lgl->prefix, lgl->stats->locs.count);
23474 yals_setprefix (yals, prefix);
23476 old_val = yals_getopt (yals, "verbose");
23477 if (old_val < lgl->opts->verbose.val)
23478 yals_setopt (yals, "verbose", lgl->opts->verbose.val);
23479 seed = lglrand (lgl);
23480 if (lgl->tid >= 0) seed *= lgl->tid + 1;
23481 seed += 1237 * (unsigned) lgl->stats->locs.count;
23482 yals_srand (yals, seed);
23483 if (hitlim > 0) yals_setopt (yals, "hitlim", hitlim);
23484 lglocscopy (lgl, yals);
23485 if (lgl->mt) { res = 20; goto DONE; }
23486 limit = lglsetlocslim (lgl);
23488 for (idx = 2; idx < lgl->nvars; idx++) {
23489 av = lglavar (lgl, idx);
23490 if (set == 2 && av->phase > 0) lit = idx;
23491 else if (set == 2 && av->phase < 0) lit = -idx;
23492 else if (set == 1 && av->locsval > 0) lit = idx;
23493 else if (set == 1 && av->locsval < 0) lit = -idx;
23496 if (lit < 0) neg++; else pos++;
23497 yals_setphase (yals, lit);
23500 "[locs-%d] importing %d positive %.0f%% and %d negative %.0f%% phases",
23501 lgl->stats->locs.count,
23502 pos, lglpcnt (pos, pos + neg),
23503 neg, lglpcnt (neg, pos + neg));
23504 if (limit < LLMAX/1000) limit *= 1000; else limit = LLMAX;
23505 yals_setmemslimit (yals, limit);
23506 if (lgl->cbs && lgl->cbs->term.fun)
23507 yals_seterm (yals, lgl->cbs->term.fun, lgl->cbs->term.state);
23508 if (lgl->cbs && lgl->cbs->getime)
23509 yals_setime (yals, lgl->cbs->getime);
23510 if (lgl->cbs && lgl->cbs->msglock.lock)
23511 yals_setmsglock (yals,
23512 lgl->cbs->msglock.lock,
23513 lgl->cbs->msglock.unlock,
23514 lgl->cbs->msglock.state);
23515 res = yals_sat (yals);
23516 min = yals_minimum (yals);
23518 "[locs-%d] local search returns %d with minimum %d",
23519 lgl->stats->locs.count, res, min);
23520 if (min < lgl->stats->locs.min) lgl->stats->locs.min = min;
23521 lgl->stats->locs.flips += yals_flips (yals);
23522 lgl->stats->locs.mems += yals_mems (yals);
23523 if (res == 10) save = 1;
23525 for (idx = 2; idx < lgl->nvars; idx++) {
23526 val = yals_deref (yals, idx);
23527 assert (abs (val) == 1);
23528 av = lglavar (lgl, idx);
23529 if (val < 0) neg++, av->locsval = -1;
23530 else if (val > 0) pos++, av->locsval = 1;
23531 if (save) av->phase = val;
23534 "[locs-%d] %s %d positive %.0f%% and %d negative %.0f%% phases",
23535 lgl->stats->locs.count,
23536 save ? "exported" : "found",
23537 pos, lglpcnt (pos, pos + neg),
23538 neg, lglpcnt (neg, pos + neg));
23539 if (lgl->opts->locsdec.val == 1) {
23540 lkhd = yals_lkhd (yals);
23541 if (abs (lkhd) == 1) lkhd = 0;
23542 if (lkhd && lglisfree (lgl, lkhd)) {
23544 "[locs-%d] using local search look ahead %d",
23545 lgl->stats->locs.count, lkhd);
23546 lglbumplit (lgl, lkhd);
23548 } else if (lgl->opts->locsdec.val == 2) {
23549 const int * p = yals_minlits (yals);
23551 while ((lit = *p++))
23552 if (abs (lit) > 1 && lglisfree (lgl, lit))
23553 lglbumplit (lgl, lit), count++;
23555 "[locs-%d] bumped all %d variables in unsatisfied clauses",
23556 lgl->stats->locs.count, count);
23559 if (lgl->opts->verbose.val >= 1) yals_stats (yals);
23566 static void lglocs (LGL * lgl) {
23567 (void) lglocsaux (lgl, 0);
23568 lglupdlocslim (lgl, 1);
23571 static int lglocslook (LGL * lgl) {
23572 int res = lglocsaux (lgl, 100000), elit;
23575 elit = lglexport (lgl, res);
23576 ext = lglelit2ext (lgl, elit);
23577 if (!ext->eliminated && !ext->blocking) {
23578 lglprt (lgl, 1, "[locslook] best local search look-ahead %d", res);
23581 LOG (2, "look-ahead winner external %d not melted anymore", elit);
23583 LOG (2, "look-ahead winner external %d was not melted anyhow", elit);
23585 lglprt (lgl, 1, "[locslook] no valid local search look-ahead");
23586 lglprt (lgl, 1, "[locslook] falling back to JWH");
23587 res = lgljwhlook (lgl);
23589 } else LOG (1, "no proper local search look-ahead literal found");
23594 /*------------------------------------------------------------------------*/
23597 static void lglanaconnected (LGL * lgl) {
23598 if (!lglsmallirr (lgl)) return;
23599 if (lgl->level) lglbacktrack (lgl, 0);
23605 static void lglanabiconnected (LGL * lgl) {
23606 if (!lglsmallirr (lgl)) return;
23607 if (lgl->level) lglbacktrack (lgl, 0);
23614 /*------------------------------------------------------------------------*/
23616 static int lglforklit (int ilit) {
23617 int idx = abs (ilit), res;
23620 if (ilit < 0) res = -res;
23624 static int lglmegaing (LGL * lgl) {
23625 if (!lgl->opts->mega.val) return 0;
23626 if (lgl->nvars <= 2) return 0;
23627 if (!lglmtstk (&lgl->eassume)) return 0;
23628 if (lglwaiting (lgl, "mega", lgl->opts->megawait.val)) return 0;
23629 if (lgl->stats->simp.count % lgl->opts->megaint.val) return 0;
23633 static int lglmega (LGL * lgl) {
23634 int remain, idx, start, lit, len, res, nlits, * vals, lifted, eqs;
23639 assert (lgl->opts->mega.val);
23640 assert (lgl->nvars > 2);
23641 assert (lglmtstk (&lgl->eassume));
23642 lglstart (lgl, &lgl->times->mega);
23643 lgl->stats->mega.count++;
23644 assert (!lgl->simp), assert (!lgl->probing);
23645 lgl->simp = lgl->probing = 1;
23646 if (lgl->level > 0) lglbacktrack (lgl, 0);
23648 nlits = 2*(lgl->nvars - 2);
23649 for (idx = 2; idx < lgl->nvars; idx++) {
23650 if (!lglisfree (lgl, idx)) continue;
23651 av = lglavar (lgl, idx);
23652 if (!(av->mega & 1)) remain++;
23653 if (!(av->mega & 2)) remain++;
23657 "[mega-%d] found %d remaining literals %.0f%% to try in round %d",
23658 lgl->stats->mega.count,
23659 remain, lglpcnt (remain, nlits), lgl->stats->mega.rounds);
23661 lgl->stats->mega.rounds++;
23663 for (idx = 2; idx < lgl->nvars; idx++) {
23664 if (!lglisfree (lgl, idx)) continue;
23665 av = lglavar (lgl, idx);
23670 "[mega-%d] scheduled %d literals %.0f%% to try in new round %d",
23671 lgl->stats->mega.count,
23672 remain, lglpcnt (remain, nlits), lgl->stats->mega.rounds);
23674 if (!remain) goto DONE;
23675 mod = lgl->nvars - 2;
23676 idx = lglrand (lgl) % mod;
23679 assert (2 <= idx), assert (idx < lgl->nvars);
23682 int posbins, negbins;
23683 av = lglavar (lgl, idx);
23684 if (av->mega == 3) goto CONTINUE;
23685 posbins = lglhasbins (lgl, idx);
23686 negbins = lglhasbins (lgl, -idx);
23687 if (posbins && negbins) goto CONTINUE;
23688 if (av->mega == 1) {
23689 if (negbins) goto CONTINUE;
23692 if (av->mega == 2) {
23693 if (posbins) goto CONTINUE;
23696 assert (!av->mega);
23697 if (posbins) { lit = -idx; break; }
23698 if (negbins) { lit = idx; break; }
23699 lit = (lglrand (lgl) & 1) ? -idx : idx;
23702 if (++idx == lgl->nvars) idx = 2;
23703 if (idx == start) {
23705 "[mega-%d] no roots in binary implication graph found",
23706 lgl->stats->mega.count);
23711 forked = lglfork (lgl);
23712 lglsetopt (forked, "verbose",
23713 lglmax (lgl->opts->verbose.val - 1, 0));
23714 lglsetopt (forked, "bca", 0);
23715 lglsetopt (forked, "boost", 0);
23716 lglsetopt (forked, "mega", 0);
23717 lglsetopt (forked, "trep", 0);
23718 lglsetopt (forked, "wait", 0);
23719 len = strlen (lgl->prefix) + 40;
23721 sprintf (prefix, "%s:mega_%d_0: ", lgl->prefix, lgl->stats->mega.count);
23722 lglsetprefix (forked, prefix);
23724 lgladd (forked, lglforklit (lit)); lgladd (forked, 0);
23725 res = lglsimp (forked, 1);
23727 lgl->stats->mega.failed++;
23729 "[mega-%d] found failed literal in first branch",
23730 lgl->stats->mega.count);
23731 lglunit (lgl, -lit);
23732 if (!lglbcp (lgl)) { lgl->mt = 1; }
23735 "[mega-%d] first branch not failing",
23736 lgl->stats->mega.count);
23738 NEW (vals, lgl->nvars);
23739 for (idx = 2; idx < lgl->nvars; idx++) {
23740 int val = lglfixed (forked, lglforklit (idx));
23741 if (!val) continue;
23743 av = lglavar (lgl, idx);
23744 if (val > 0) av->mega |= 1;
23745 if (val < 0) av->mega |= 2;
23747 lglrelease (forked);
23749 forked = lglfork (lgl);
23750 lglsetopt (forked, "verbose",
23751 lglmax (lgl->opts->verbose.val - 1, 0));
23752 lglsetopt (forked, "bca", 0);
23753 lglsetopt (forked, "boost", 0);
23754 lglsetopt (forked, "mega", 0);
23755 lglsetopt (forked, "trep", 0);
23756 lglsetopt (forked, "wait", 0);
23757 len = strlen (lgl->prefix) + 40;
23759 sprintf (prefix, "%s:mega-%d-1: ", lgl->prefix, lgl->stats->mega.count);
23760 lglsetprefix (forked, prefix);
23762 lgladd (forked, lglforklit (-lit)); lgladd (forked, 0);
23763 res = lglsimp (forked, 1);
23765 lgl->stats->mega.failed++;
23767 "[mega-%d] found failed literal in second branch",
23768 lgl->stats->mega.count);
23769 lglunit (lgl, lit);
23770 if (!lglbcp (lgl)) { lgl->mt = 1; }
23773 for (idx = 2; idx < lgl->nvars; idx++) {
23774 int val = lglfixed (forked, lglforklit (idx));
23775 if (!val) continue;
23776 if (abs (idx) == abs (lit)) continue;
23777 if (vals[idx] == val) {
23778 lglunit (lgl, (val < 0) ? -idx : idx);
23779 lgl->stats->mega.lifted++;
23781 } else if (vals[idx] == -val) {
23784 lgl->stats->mega.eqs++;
23786 lgladd (lgl, lit), lgladd (lgl, idx); lgladd (lgl, 0);
23787 lgladd (lgl, -lit), lgladd (lgl, -idx); lgladd (lgl, 0);
23789 lgladd (lgl, -lit), lgladd (lgl, idx); lgladd (lgl, 0);
23790 lgladd (lgl, -lit), lgladd (lgl, -idx); lgladd (lgl, 0);
23795 if (lifted || eqs) {
23797 "[mega-%d] lifted %d literals and found %d equivalences",
23798 lgl->stats->mega.count, lifted, eqs);
23799 if (!lglbcp (lgl)) { lgl->mt = 1; }
23802 "[mega-%d] unsuccesfull",
23803 lgl->stats->mega.count);
23805 DEL (vals, lgl->nvars);
23807 lglrelease (forked);
23810 assert (lgl->simp), assert (lgl->probing);
23811 lgl->simp = lgl->probing = 0;
23816 /*------------------------------------------------------------------------*/
23818 static int lglisimp (LGL * lgl) {
23819 if (!lgl->opts->simplify.val) return 1;
23821 if (lglternresolving (lgl) && !lglternres (lgl)) return 0;
23822 if (lglterminate (lgl)) return 1;
23825 if (lglcarding (lgl) && !lglcard (lgl)) return 0;
23826 if (lglterminate (lgl)) return 1;
23829 if (lglgaussing (lgl) && !lglgauss (lgl)) return 0;
23830 if (lglterminate (lgl)) return 1;
23833 if (lgldecomposing (lgl) && !lgldecomp (lgl)) return 0;
23834 if (lglterminate (lgl)) return 1;
23837 if (lglprobing (lgl) && !lglprobe (lgl)) return 0;
23838 if (lglterminate (lgl)) return 1;
23841 if (lglcgrclosing (lgl) && !lglcgrclsr (lgl)) return 0;
23842 if (lglterminate (lgl)) return 1;
23845 if (lglifting (lgl) && !lglift (lgl)) return 0;
23846 if (lglterminate (lgl)) return 1;
23849 if (lglcliffing (lgl) && !lglcliff (lgl)) return 0;
23850 if (lglterminate (lgl)) return 1;
23853 if (lglunhiding (lgl) && !lglunhide (lgl)) return 0;
23854 if (lglterminate (lgl)) return 1;
23857 if (lgltreducing (lgl) && !lgltrd (lgl)) return 0;
23858 if (lglterminate (lgl)) return 1;
23861 if (lglblocking (lgl)) lglblock (lgl);
23862 if (lglterminate (lgl)) return 1;
23865 if (lglcceing (lgl) && !lglcce (lgl)) return 0;
23866 if (lglterminate (lgl)) return 1;
23869 if (lgleliminating (lgl) && !lglelim (lgl)) return 0;
23870 if (lglterminate (lgl)) return 1;
23873 if (lglrdping (lgl) && !lglrdp (lgl)) return 0;
23874 if (lglterminate (lgl)) return 1;
23877 if (!lgltopgc (lgl)) return 0;
23878 if (lglterminate (lgl)) return 1;
23881 if (lglmegaing (lgl) && !lglmega (lgl)) return 0;
23882 if (lglterminate (lgl)) return 1;
23885 if (lglbcaing (lgl)) lglbca (lgl);
23886 if (lglterminate (lgl)) return 1;
23889 if (lglbvaing (lgl)) lglbva (lgl);
23890 if (lglterminate (lgl)) return 1;
23893 if (lglrephasing (lgl)) lglrephase (lgl);
23894 if (!lgl->allphaseset) lglphase (lgl);
23895 if (lglterminate (lgl)) return 1;
23901 lglanaconnected (lgl);
23902 lglanabiconnected (lgl);
23908 static int lgltabring (LGL * lgl) {
23910 if (!lgl->opts->tabr.val) return 0;
23912 rem = lglrem (lgl);
23913 if (rem < lgl->limits->tabr.vars) {
23914 lgl->stats->tabr.count++, res = 1;
23916 "[tabula-rasa-%d] number variables %d drops below limit %d",
23917 lgl->stats->tabr.count, rem, lgl->limits->tabr.vars);
23919 irr = lgl->stats->irr.clauses.cur;
23920 if (irr < lgl->limits->tabr.clauses) {
23921 if (!res) lgl->stats->tabr.count++, res = 1;
23923 "[tabula-rasa-%d] number clauses %d drops below limit %d",
23924 lgl->stats->tabr.count, irr, lgl->limits->tabr.clauses);
23929 static void lglupdtabr (LGL * lgl) {
23930 lgl->limits->tabr.vars =
23931 lglrem (lgl) / lgl->opts->tabrvfactor.val;
23932 lgl->limits->tabr.clauses =
23933 lgl->stats->irr.clauses.cur / lgl->opts->tabrcfactor.val;
23935 "[tabula-rasa-%d] new variable limit %d and clause limit %d",
23936 lgl->stats->tabr.count,
23937 lgl->limits->tabr.vars, lgl->limits->tabr.clauses);
23940 static void lglincsetupreduce (LGL * lgl) {
23941 lgl->limits->reduce.inner = lgl->opts->redlinit.val;
23942 lglboundredl (lgl);
23943 lgl->limits->reduce.outer = 2*lgl->limits->reduce.inner;
23946 static void lgltabrflushred (LGL * lgl) {
23947 assert (lgl->opts->tabr.val >= 1);
23948 lgliflushcache (lgl, lgl->opts->tabrkeep.val);
23949 lglincsetupreduce (lgl);
23952 static void lgltabrflushphases (LGL * lgl) {
23953 if (lgl->opts->tabr.val < 2) return;
23954 lglflushphasesaux (lgl, 1);
23956 lgl->limits->rephase.confs = lgl->stats->rephase.inc = 10000;
23959 static void lgltabrflushscores (LGL * lgl) {
23962 if (lgl->opts->tabr.val < 4) return;
23963 lglrelstk (lgl, &lgl->dsched);
23965 for (idx = 2; idx < lgl->nvars; idx++) {
23966 qv = lgl->qvars + idx;
23969 lgldsched (lgl, idx);
23973 static void lgltabrsetup (LGL * lgl) {
23975 if (lgl->opts->tabr.val < 3) return;
23976 if (lgl->limits->simp.cinc != lgl->opts->cintinc.val) {
23977 lgl->limits->simp.cinc = lgl->opts->cintinc.val;
23979 "[tabula-rasa-%d] new conflict interval %d",
23980 lgl->stats->tabr.count, lgl->limits->simp.cinc);
23983 "[tabula-rasa-%d] conflict interval %d does not change",
23984 lgl->stats->tabr.count, lgl->limits->simp.cinc);
23985 newlimit = lgl->stats->confs + lgl->limits->simp.cinc;
23986 if (newlimit < lgl->limits->simp.confs) {
23987 lgl->limits->simp.confs = newlimit;
23989 "[tabula-rasa-%d] new conflict limit %d",
23990 lgl->stats->tabr.count, newlimit);
23993 "[tabula-rasa-%d] conflict limit %d does not change",
23994 lgl->stats->tabr.count, lgl->limits->simp.cinc);
23997 static void lgltabularasa (LGL * lgl) {
23998 lglstart (lgl, &lgl->times->tabr);
23999 if (lgl->level > 0) lglbacktrack (lgl, 0);
24000 lgltabrflushred (lgl);
24001 lgltabrflushphases (lgl);
24002 lgltabrflushscores (lgl);
24003 lgltabrsetup (lgl);
24008 static void lglregularly (LGL * lgl) {
24009 if (lglreducing (lgl)) lglreduce (lgl, 0);
24010 if (lgltabring (lgl)) lgltabularasa (lgl);
24011 if (lgldefragmenting (lgl)) lgldefrag (lgl);
24014 static void lglupdsimpcinc (LGL * lgl, int red, int success) {
24015 const char * type = "no";
24016 int inc = 0, div = 1, res;
24020 switch (lgl->opts->cintincdiv.val) {
24022 if (red >= 50) div = 4;
24023 else if (red >= 20) div = 3;
24024 else if (red >= 10) div = 2;
24026 case 2: div = red/2 + 1; break;
24027 case 1: div = red/1 + 1; break;
24030 assert (!lgl->opts->cintincdiv.val);
24034 inc = lgl->opts->cintinc.val;
24035 if (lgl->opts->simplify.val == 1) {
24036 type = "arithmetic";
24037 } else if (lgl->opts->simplify.val == 2) {
24038 if (inc < lgl->limits->simp.cinc) inc = lgl->limits->simp.cinc;
24039 type = "geometric";
24043 if (lgl->limits->simp.cinc - res <= INT_MAX)
24044 lgl->limits->simp.cinc += res;
24046 "[simplification-%d] new lgl->limits->simp.cinc %d",
24047 lgl->stats->simp.count, lgl->limits->simp.cinc);
24050 "[simplification-%d] %s conflict interval increment %d = %d / %d",
24051 lgl->stats->simp.count, type, res, inc, div);
24054 "[simplification-%d] full %s conflict interval increment %d",
24055 lgl->stats->simp.count, type, res);
24058 lgl->opts->cintmaxsoft.val >= 0 &&
24059 lgl->limits->simp.cinc >= lgl->opts->cintmaxsoft.val) {
24060 lgl->limits->simp.cinc = lgl->opts->cintmaxsoft.val;
24062 "[simplification-%d] "
24063 "conflict interval soft limit %d reached",
24064 lgl->stats->simp.count, lgl->limits->simp.cinc);
24065 } else if (lgl->opts->cintmaxhard.val >= 0 &&
24066 lgl->limits->simp.cinc >= lgl->opts->cintmaxhard.val) {
24067 lgl->limits->simp.cinc = lgl->opts->cintmaxhard.val;
24069 "[simplification-%d] "
24070 "conflict interval hard limit %d reached",
24071 lgl->stats->simp.count, lgl->limits->simp.cinc);
24075 static void lglupdsimpint (LGL * lgl, int oldrem, int oldirr, int forced) {
24076 int remvar, remirr, pcntred, simpcinc;
24077 int64_t pcntremvar64, pcntremirr64;
24078 int pcntremvar, pcntremirr;
24080 remvar = oldrem - lglrem (lgl);
24081 if (remvar < 0) remvar = 0;
24082 pcntremvar64 = (remvar > 0) ? ((1000ll*remvar)/oldrem + 5)/10 : 0ll;
24083 assert (pcntremvar64 <= 100);
24084 pcntremvar = pcntremvar64;
24086 "[simplification-%d] removed %d variables %.1f%% "
24087 "(%d remain %0.f%%)",
24088 lgl->stats->simp.count, remvar, lglpcnt (remvar, oldrem),
24089 lglrem (lgl), lglpcnt (lglrem (lgl), lgl->limits->inc.vars.start));
24091 remirr = oldirr - lgl->stats->irr.clauses.cur;
24092 if (remirr < 0) remirr = 0;
24093 pcntremirr64 = (remirr > 0) ? ((1000ll*remirr)/oldirr + 5)/10 : 0ll;
24094 assert (pcntremirr64 <= 100);
24095 pcntremirr = pcntremirr64;
24097 "[simplification-%d] removed %d irredundant clauses %.1f%% "
24098 "(%d remain %.0f%%)",
24099 lgl->stats->simp.count, remirr, lglpcnt (remirr, oldirr),
24100 lgl->stats->irr.clauses.cur,
24101 lglpcnt (lgl->stats->irr.clauses.cur, lgl->limits->inc.clauses.start));
24103 pcntred = lglmax (pcntremvar, pcntremirr);
24105 "[simplification-%d] maximum reduction of %d%% = max (%d%%, %d%%)",
24106 lgl->stats->simp.count, pcntred, pcntremvar, pcntremirr);
24111 "[simplification-%d] forced so keeping old conflict interval %d",
24112 lgl->stats->simp.count, lgl->limits->simp.cinc);
24113 } else if (lgl->stats->confs < lgl->limits->simp.confs &&
24114 (simpcinc = lgl->limits->simp.cinc)) {
24116 "[simplification-%d] keeping old conflict interval %d "
24117 "(non-conflict triggered simplification)",
24118 lgl->stats->simp.count, lgl->limits->simp.cinc);
24119 } else if (remvar > 0 && pcntred >= lgl->opts->simprtc.val) {
24120 int64_t scaledcinc;
24123 "[simplification-%d] large reduction %d%% >= %d%% limit",
24124 lgl->stats->simp.count, pcntred, lgl->opts->simprtc.val);
24125 factor = lgl->opts->simpidiv.val - lgl->stats->simp.count;
24126 if (factor <= 0) factor = 1;
24127 simpcinc = lgl->opts->simpinterdelay.val / factor;
24128 scaledcinc = lgl->stats->confs/lgl->opts->simpiscale.val;
24129 if (scaledcinc > lgl->limits->simp.cinc)
24130 scaledcinc = lgl->limits->simp.cinc;
24131 if (scaledcinc < simpcinc) {
24133 "[simplification-%d] new conflict interval %d = %d/%d",
24134 lgl->stats->simp.count,
24135 simpcinc, lgl->opts->simpinterdelay.val, factor);
24137 assert (scaledcinc <= INT_MAX);
24138 simpcinc = (int) scaledcinc;
24140 "[simplification-%d] new conflict interval %d = min (%lld/%d, %d)",
24141 lgl->stats->simp.count,
24142 simpcinc, (LGLL) lgl->stats->confs, lgl->opts->simpiscale.val,
24143 lgl->limits->simp.cinc);
24146 lglupdsimpcinc (lgl, pcntred, remvar || remirr);
24147 simpcinc = lgl->limits->simp.cinc;
24148 lglprt (lgl, 1, "[simplification-%d] new conflict interval %d",
24149 lgl->stats->simp.count, simpcinc);
24154 "[simplification-%d] conflict limit remains at %lld",
24155 lgl->stats->simp.count, (LGLL) lgl->limits->simp.confs);
24157 int penalty, pensimpcinc;
24158 if (lgl->stats->irr.clauses.cur < 1000000) penalty = 1;
24159 else if (lgl->stats->irr.clauses.cur < 10000000) penalty = 2;
24161 if (INT_MAX/penalty < simpcinc) pensimpcinc = INT_MAX;
24162 else pensimpcinc = penalty * simpcinc;
24164 "[simplification-%d] penalized conflict interval %d = %d * %d",
24165 lgl->stats->simp.count, pensimpcinc, penalty, simpcinc);
24166 assert (pensimpcinc >= 0);
24167 lgl->limits->simp.confs = lgl->stats->confs + pensimpcinc;
24168 assert (lgl->limits->simp.confs >= 0);
24170 "[simplification-%d] new conflict limit %lld",
24171 lgl->stats->simp.count, (LGLL) lgl->limits->simp.confs);
24174 if (lgl->limits->simp.pen > 0) {
24175 lgl->limits->simp.pen--;
24177 "[simplification-%d] simplification penalty reduced to %d",
24178 lgl->stats->simp.count, lgl->limits->simp.pen);
24181 lgl->limits->simp.vars = lglrem (lgl);
24182 lgl->forcerephead = 1;
24183 if (lgl->wait > 0) lgl->wait--;
24186 static int lglpreprocessing (LGL * lgl, int forced) {
24187 int res, oldrem, oldirr;
24188 if (lgl->mt) return 0;
24189 assert (!lgl->searching);
24190 lgl->stats->simp.count++;
24191 oldrem = lglrem (lgl);
24192 oldirr = lgl->stats->irr.clauses.cur;
24193 res = lglisimp (lgl);
24194 lglupdsimpint (lgl, oldrem, oldirr, forced);
24195 assert (res == !lgl->mt);
24199 static int lglsimplimhit (LGL * lgl) {
24201 int a, r, res = 0;;
24202 if (!lgl->opts->inprocessing.val && lgl->stats->simp.count) return 0;
24203 if (lgl->stats->confs >= lgl->limits->simp.confs) {
24204 lglprt (lgl, 1, "");
24206 "[simplification-%d] limit of %lld conflicts hit after %lld conflicts",
24207 lgl->stats->simp.count + 1,
24208 (LGLL) lgl->limits->simp.confs, (LGLL) lgl->stats->confs);
24209 lgl->stats->simp.limhit.confs++;
24213 (o = lgl->limits->simp.vars) &&
24214 (n = lglrem (lgl)) >= lgl->opts->simpvarlim.val) {
24218 if (r <= INT_MIN || r > INT_MAX) a = INT_MAX;
24219 else if (r < 0) a = -r;
24221 if (a >= lgl->opts->simpvarchg.val) {
24222 lglprt (lgl, 1, "");
24224 "[simplification-%d] limit hit: "
24225 "remaining variables changed from %lld to %lld by %d%%",
24226 lgl->stats->simp.count + 1, (LGLL) o, (LGLL) n, r);
24227 lgl->stats->simp.limhit.vars++;
24232 if (lgl->limits->simp.pen)
24234 "[simplification-%d] with simplification penalty of %d",
24235 lgl->stats->simp.count + 1, lgl->limits->simp.pen);
24238 "[simplification-%d] no simplification penalty",
24239 lgl->stats->simp.count + 1);
24244 static int lglinprocessing (LGL * lgl) {
24245 int res, oldrem, oldirr;
24246 assert (lgl->searching);
24247 if (!lglsimplimhit (lgl)) return !lgl->mt;
24248 lgl->stats->simp.count++;
24249 lglstart (lgl, &lgl->times->inpr);
24250 oldrem = lglrem (lgl);
24251 oldirr = lgl->stats->irr.clauses.cur;
24252 res = lglisimp (lgl);
24253 lglupdsimpint (lgl, oldrem, oldirr, 0);
24255 assert (res == !lgl->mt);
24259 static int lglbcptop (LGL * lgl) {
24261 if (lglbcp (lgl)) res = 1;
24268 if (lgl->conf.lit) {
24269 LOG (1, "top level propagation produces inconsistency");
24270 if (!lgl->mt) lgl->mt = 1;
24271 } else assert (lgl->failed);
24277 static int lglimhit (LGL * lgl, Lim * lim) {
24278 if (!lim) return 0;
24279 if (lim->decs >= 0 && lgl->stats->decisions >= lim->decs) {
24280 lglprt (lgl, 1, "[limits] decision limit %lld hit at %lld decisions",
24281 (LGLL) lim->decs, (LGLL) lgl->stats->decisions);
24284 if (lim->confs >= 0 && lgl->stats->confs >= lim->confs) {
24285 lglprt (lgl, 1, "[limits] conflict limit %lld hit at %lld conflicts",
24286 (LGLL) lim->confs, (LGLL) lgl->stats->confs);
24289 if (lim->props >= 0 && lgl->stats->props.search >= lim->props) {
24291 "[limits] propagation limit %lld hit at %lld propagations",
24292 (LGLL) lim->props, (LGLL) lgl->stats->props.search);
24298 static int lgloop (LGL * lgl, Lim * lim) {
24299 unsigned confs = 0;
24301 if (lglbcpsearch (lgl) && lglinprocessing (lgl)) {
24302 if (lglterminate (lgl)) return 0;
24303 if (!lglsyncunits (lgl)) return 20;
24304 if (!lglsyncls (lgl)) continue;
24305 if (lglfailedass (lgl)) return 20;
24306 lglregularly (lgl);
24307 if (lglimhit (lgl, lim)) return 0;
24308 if (lglocsing (lgl)) lglocs (lgl);
24309 if (lglrestarting (lgl)) { lglrestart (lgl); continue; }
24310 if (!lgldecide (lgl)) return 10;
24311 } else if (!lglana (lgl)) return 20;
24312 else if (!(++confs & 15) && lglterminate (lgl)) return 0;
24316 static int lglsearch (LGL * lgl, Lim * lim) {
24318 assert (!lgl->searching);
24319 lgl->searching = 1;
24320 lglstart (lgl, &lgl->times->srch);
24321 res = lgloop (lgl, lim);
24322 assert (lgl->searching);
24323 lgl->searching = 0;
24328 static int lgltopsimp (LGL * lgl, int forcesimp) {
24329 assert (lgl->state == READY);
24330 if (lgl->mt) return 20;
24331 if (lglfailedass (lgl)) return 20;
24332 if (!lglbcptop (lgl)) return 20;
24333 if (lgl->mt || lglfailedass (lgl)) return 20;
24334 if (lglterminate (lgl)) return 0;
24335 if ((forcesimp || lglsimplimhit (lgl)) &&
24336 !lglpreprocessing (lgl, forcesimp)) return 20;
24337 if (lglfailedass (lgl)) return 20;
24338 if (!lgl->stats->cutwidths) lglcutwidth (lgl);
24339 lglrep (lgl, 2, 's');
24343 static int lglsolve (LGL * lgl, Lim * lim, int forcesimp) {
24345 lgl->limits->simp.pen = lgl->opts->simpen.val;
24346 lglstart (lgl, &lgl->times->prep);
24347 res = lgltopsimp (lgl, forcesimp);
24349 if (res) { assert (res == 20); return res; }
24350 return lglsearch (lgl, lim);
24353 static void lglincsetup (LGL * lgl) {
24355 if (lgl->opts->incsavevisits.val)
24356 lgl->limits->inc.visits = lgl->stats->visits.search;
24358 assert (lgl->limits->inc.clauses.add <= lgl->stats->irr.clauses.add);
24359 if (lgl->limits->inc.clauses.add < lgl->stats->irr.clauses.add) {
24360 lgl->limits->inc.clauses.add = lgl->stats->irr.clauses.add;
24361 lgl->elmrtc = lgl->blkrtc = lgl->ccertc = 0;
24362 lgl->elmstuck = lgl->blkstuck = 0;
24363 lgl->wait = lgl->opts->waitmax.val;
24366 lgl->limits->inc.clauses.start = lgl->stats->irr.clauses.cur;
24367 lgl->limits->inc.vars.start = lglrem (lgl);
24369 lgl->limits->tabr.clauses = lgl->limits->inc.clauses.start;
24370 lgl->limits->tabr.vars = lgl->limits->inc.vars.start;
24371 lgl->limits->tabr.vars /= lgl->opts->tabrvfactor.val;
24372 lgl->limits->tabr.clauses /= lgl->opts->tabrcfactor.val;
24374 lglincsetupreduce (lgl);
24376 lgl->limits->flipint = lgl->opts->flipint.val;
24378 lgl->stats->locs.min = INT_MAX;
24379 lglupdlocslim (lgl, 0);
24381 lgl->limits->rephase.confs = lgl->stats->rephase.inc = 10000;
24383 CLR (lgl->limits->restart);
24384 lgl->limits->restart.confs =
24385 lgl->stats->confs + lgl->opts->restartinit.val;
24387 lgl->limits->simp.pen = 0;
24388 if (lgl->opts->incredcint.val > 1) {
24389 lgl->limits->simp.cinc /= lgl->opts->incredcint.val;
24391 "[incremental-setup] conflict interval increment reduced to %d",
24392 lgl->limits->simp.cinc);
24394 if (lgl->opts->incredconfslim.val) {
24395 lgl->limits->simp.confs =
24396 ((100-lgl->opts->incredconfslim.val)*lgl->limits->simp.confs)/100;
24398 "[incremental-setup] conflict limit reduced to %lld",
24399 (LGLL) lgl->limits->simp.confs);
24402 CLR (lgl->limits->cgr.del);
24404 CLR (lgl->limits->elm.del);
24405 CLR (lgl->limits->blk.del);
24406 CLR (lgl->limits->cliff.del);
24408 CLR (lgl->limits->rdp.del);
24409 CLR (lgl->limits->trd.del);
24410 CLR (lgl->limits->unhd.del);
24411 CLR (lgl->limits->trnr.del);
24412 CLR (lgl->limits->lft.del);
24413 CLR (lgl->limits->cce.del);
24414 CLR (lgl->limits->card.del);
24416 CLR (lgl->limits->gauss.del);
24418 CLR (lgl->limits->prb.simple.del);
24419 CLR (lgl->limits->prb.basic.del);
24420 CLR (lgl->limits->prb.treelook.del);
24422 CLR (lgl->limits->bca.del);
24425 static void lglsetup (LGL * lgl) {
24426 if (lgl->setuponce) goto DONE;
24427 lgl->limits->dfg = lgl->stats->pshwchs + lgl->opts->defragint.val;
24429 lgl->limits->blk.irrprgss = -1;
24430 lgl->limits->elm.irrprgss = -1;
24431 lgl->limits->term.steps = -1;
24433 lgl->phaseneg = lgl->opts->phaseneginit.val;
24435 lgl->rng.w = (unsigned) lgl->opts->seed.val;
24436 lgl->rng.z = ~lgl->rng.w;
24441 lgl->rng.w *= 2019164533u, lgl->rng.z *= 1000632769u;
24443 assert (!lgl->stats->decisions);
24444 lgl->limits->randec += lgl->opts->randecint.val/2;
24445 lgl->limits->randec += lglrand (lgl) % lgl->opts->randecint.val;
24447 lgl->limits->simp.vars = lglrem (lgl);
24449 lgl->setuponce = 1;
24452 lglinitscores (lgl);
24457 static void lglinitsolve (LGL * lgl) {
24458 if (lgl->state != READY) lglsetup (lgl);
24460 lglfitstk (lgl, &lgl->irr);
24462 lglfitstk (lgl, &lgl->orig);
24464 lglrep (lgl, 1, '*');
24467 #ifndef NLGLPICOSAT
24468 static void lglpicosatchksol (LGL * lgl) {
24470 int idx, lit, res, * p;
24472 if (lgl->picosat.res) assert (lgl->picosat.res == 10);
24473 lglpicosatinit (lgl);
24474 assert (!picosat_inconsistent (PICOSAT));
24475 for (idx = 2; idx < lgl->nvars; idx++) {
24476 val = lglval (lgl, idx);
24478 lit = lglsgn (val) * idx;
24479 picosat_assume (PICOSAT, lit);
24481 for (p = lgl->eassume.start; p < lgl->eassume.top; p++)
24482 picosat_assume (PICOSAT, lglimport (lgl, *p));
24483 res = picosat_sat (PICOSAT, -1);
24484 assert (res == 10);
24485 LOG (1, "PicoSAT checked solution");
24490 static void lgleassign (LGL * lgl, int lit) {
24492 ext = lglelit2ext (lgl, lit);
24493 LOG (3, "external assign %d ", lit);
24494 ext->val = lglsgn (lit);
24497 static void lglcomputechanged (LGL * lgl) {
24501 for (eidx = 1; eidx <= lgl->maxext; eidx++) {
24502 ext = lglelit2ext (lgl, eidx);
24503 if (ext->oldval && ext->oldval != ext->val) lgl->changed++;
24504 ext->oldval = ext->val;
24506 LOG (1, "changed %d assignments in extension", lgl->changed);
24509 static void lglextend (LGL * lgl) {
24510 int * p, lit, eidx, ilit, next, satisfied, val, * start, erepr, equiv;
24511 Ext * ext, * extrepr;
24512 assert (lgl->state & SATISFIED);
24513 assert (!(lgl->state & EXTENDED));
24514 lgleunassignall (lgl);
24515 for (equiv = 0; equiv <= 1; equiv++) {
24517 LOG (1, "initializing assignment of non-representative externals");
24519 LOG (1, "initializing assignment of external representatives");
24520 for (eidx = 1; eidx <= lgl->maxext; eidx++) {
24521 ext = lglelit2ext (lgl, eidx);
24522 if (!ext->imported) continue;
24523 if (equiv != ext->equiv) continue;
24524 assert (!ext->val);
24526 erepr = lglerepr (lgl, eidx);
24527 LOG (3, "initializing external %d assignment from external representative %d",
24529 assert (erepr != eidx);
24530 extrepr = lglelit2ext (lgl, erepr);
24531 if (!(val = extrepr->val)) {
24532 ilit = extrepr->repr;
24534 LOG (3, "using external %d to internal %d mapping",
24535 abs (erepr), ilit);
24536 val = lglcval (lgl, ilit);
24538 LOG (3, "external %d without internal representative", abs (erepr));
24540 if (erepr < 0) val = -val;
24542 if ((ilit = ext->repr)) {
24543 LOG (3, "using external %d to internal %d mapping", eidx, ilit);
24544 val = lglcval (lgl, ilit);
24546 LOG (3, "external %d without internal representative", eidx);
24549 lit = (val > 0) ? eidx : -eidx;
24550 lgleassign (lgl, lit);
24553 start = lgl->extend.start;
24554 p = lgl->extend.top;
24555 if (p == start) goto SKIP;
24556 assert (p > start);
24559 while (p > start) {
24561 if (lgl->opts->log.val >= 4) {
24563 for (q = p; q[-1]; q--)
24565 LOGCLS (4, q, "next sigma clause to consider");
24572 if (p == start) next = 0; else next = *--p;
24573 if (!lit || satisfied) continue;
24574 val = lglederef (lgl, lit);
24575 assert (!next || val);
24577 LOG (4, "sigma clause satisfied by %d", lit);
24582 if (satisfied) continue;
24583 lgleassign (lgl, lit);
24586 lglcomputechanged (lgl);
24590 void lglsetphases (LGL * lgl) {
24592 REQINITNOTFORKED ();
24593 TRAPI ("setphases");
24594 REQUIRE (SATISFIED | EXTENDED);
24595 if (!(lgl->state & EXTENDED)) lglextend (lgl);
24596 for (elit = 1; elit <= lgl->maxext; elit++) {
24597 phase = lglederef (lgl, elit);
24598 assert (abs (phase) <= 1);
24599 lglesetphase (lgl, elit, phase);
24601 if (lgl->clone) lglsetphases (lgl->clone);
24605 #include <signal.h>
24606 #include <unistd.h>
24607 static void lglchksol (LGL * lgl) {
24608 int * p, * c, * eoo = lgl->orig.top, lit, satisfied, sign, idx;
24611 assert (lglmtstk (&lgl->orig) || !eoo[-1]);
24612 assert (lgl->state == EXTENDED);
24613 for (c = lgl->orig.start; c < eoo; c = p + 1) {
24615 for (p = c; (lit = *p); p++)
24616 if (!satisfied && lglederef (lgl, lit) > 0)
24618 if (satisfied) continue;
24620 lglmsgstart (lgl, 0);
24621 fprintf (lgl->out, "unsatisfied original external clause");
24622 for (p = c; (lit = *p); p++) fprintf (lgl->out, " %d", lit);
24624 assert (satisfied);
24626 abort (); // NOTE: not 'lglabort' on purpose !!
24628 for (idx = 1; idx <= lgl->maxext; idx++) {
24629 ext = lglelit2ext (lgl, idx);
24630 if (!ext->assumed) continue;
24631 for (sign = -1; sign <= 1; sign += 2) {
24633 bit = 1u << (lit < 0);
24634 if (!(ext->assumed & bit)) continue;
24635 if (lglederef (lgl, lit) > 0) continue;
24636 lglprt (lgl, 0, "unsatisfied assumption %d", lit);
24637 assert (lglederef (lgl, lit) > 0);
24639 abort (); // DITO: not 'lglabort' on purpose !!
24645 static void lglclass (LGL * lgl, LGL * from) {
24646 Ext * extfrom, * extlgl;
24648 REQINITNOTFORKED ();
24649 ABORTIF (lgl->mt, "can not clone assignment into inconsistent manager");
24650 ABORTIF (!from, "uninitialized 'from' solver");
24651 ABORTIF (!(from->state & (SATISFIED | EXTENDED)),
24652 "require 'from' state to be (SATISFIED | EXTENDED)");
24653 ABORTIF (from->maxext != lgl->maxext,
24654 "can not clone assignments for different sets of variables");
24655 if (!(from->state & EXTENDED)) lglextend (from);
24657 lgleunassignall (lgl);
24658 cloned = lgl->changed = 0;
24659 for (eidx = 1; eidx <= lgl->maxext; eidx++) {
24660 extlgl = lglelit2ext (lgl, eidx);
24661 if (!extlgl->imported) continue;
24662 extfrom = lglelit2ext (from, eidx);
24663 ABORTIF (!extfrom->imported,
24664 "can not clone assignment of literal imported only by 'to'");
24665 assert (extfrom->val == 1 || extfrom->val == -1);
24666 lgleassign (lgl, extfrom->val*eidx);
24669 lglcomputechanged (lgl);
24670 lglprt (lgl, 1, "[class] cloned %d assignments (%d changed)",
24671 cloned, lgl->changed);
24676 #ifndef NLGLPICOSAT
24677 lglpicosatchksol (lgl);
24681 static void lglnegass (LGL * lgl) {
24684 REQINITNOTFORKED ();
24686 if (lgl->mt) return;
24688 for (p = lgl->eassume.start; p < lgl->eassume.top; p++)
24689 lglpushstk (lgl, &eassume, *p);
24690 for (p = eassume.start; p < eassume.top; p++)
24691 lgleadd (lgl, -*p);
24693 assert (lglmtstk (&lgl->eassume));
24694 for (p = eassume.start; p < eassume.top; p++)
24695 lglassume (lgl, *p);
24696 lglrelstk (lgl, &eassume);
24698 if (lgl->clone) lglnegass (lgl->clone);
24701 static int lglcompactify (LGL * lgl, int res) {
24702 if (!lgl->opts->compact.val) return 0;
24703 if (!res) return 1;
24704 if (res == 20) return 1;
24705 assert (res == 10);
24706 return lgl->opts->compact.val >= 2;
24709 static int lglisat (LGL * lgl, Lim * lim, int simpits) {
24710 int res, count, reported = lgl->stats->reported;
24712 lglinitsolve (lgl);
24713 res = lglsolve (lgl, lim, 0);
24714 for (count = 0; !res && count < simpits; count++) {
24716 "[simplification-%d] next forced simplification iteration %d",
24717 lgl->stats->simp.count + 1, count + 1);
24718 res = lglsolve (lgl, lim, 1);
24720 if (lglcompactify (lgl, res)) lglcompact (lgl);
24723 lglrep (lgl, 1, '?');
24727 lglrep (lgl, 1, '1');
24730 TRANS (UNSATISFIED);
24731 if (!lgl->level && !lgl->mt) assert (lgl->failed);
24732 lglrep (lgl, 1, '0');
24734 if (reported != lgl->stats->reported) lglflshrep (lgl);
24735 if (res == 10) lglextend (lgl);
24737 if (res == 10) lglchksol (lgl);
24739 #ifndef NLGLPICOSAT
24740 if (res == 10) lglpicosatchksol (lgl);
24741 if (res == 20) lglpicosatchkunsat (lgl);
24746 int lglunclone (LGL * lgl, LGL * from) {
24748 REQINITNOTFORKED ();
24749 if (lgl->mt) return 20;
24750 ABORTIF (!from, "uninitialized 'from' solver");
24751 if (from->mt || (from->state & UNSATISFIED)) {
24752 lglprt (lgl, 1, "[unclone] unsatisfied state");
24754 res = lglisat (lgl, 0, 0);
24755 } else if (from->state & (SATISFIED | EXTENDED)) {
24756 lglprt (lgl, 1, "[unclone] satisfied state");
24757 lglclass (lgl, from);
24760 lglprt (lgl, 1, "[unclone] unknown state");
24768 #define CHKCLONESTATS(STATS) \
24770 assert (clone->stats->STATS == orig->stats->STATS); \
24773 static void lglchkclonesamestats (LGL * orig) {
24775 LGL * clone = orig->clone;
24777 assert (clone->state == orig->state);
24778 CHKCLONESTATS (confs);
24779 CHKCLONESTATS (decisions);
24780 CHKCLONESTATS (bytes.current);
24781 CHKCLONESTATS (bytes.max);
24782 CHKCLONESTATS (props.search);
24783 CHKCLONESTATS (props.simp);
24784 CHKCLONESTATS (props.lkhd);
24785 CHKCLONESTATS (visits.search);
24786 CHKCLONESTATS (visits.simp);
24787 CHKCLONESTATS (visits.lkhd);
24791 #define CHKCLONE() \
24793 if (!lgl->clone) break; \
24794 lglchkclonesamestats (lgl); \
24797 #define CHKCLONENORES(FUN) \
24799 if (!lgl->clone) break; \
24800 FUN (lgl->clone); \
24804 #define CHKCLONERES(FUN,RES) \
24807 if (!lgl->clone) break; \
24808 CLONERES = FUN (lgl->clone); \
24809 ABORTIF (CLONERES != (RES), \
24810 "%s (lgl->clone) = %d differs from %s (lgl) = %d", \
24811 __FUNCTION__, CLONERES, __FUNCTION__, (RES)); \
24815 #define RETURN(FUN,RES) \
24817 TRAPI ("return %d", (RES)); \
24818 CHKCLONERES (FUN, (RES)); \
24821 #define CHKCLONEARGRES(FUN,ARG,RES) \
24824 if (!lgl->clone) break; \
24825 CLONERES = FUN (lgl->clone, (ARG)); \
24826 ABORTIF (CLONERES != (RES), \
24827 "%s (lgl->clone, %d) = %d differs from %s (lgl, %d) = %d", \
24828 __FUNCTION__, (ARG), CLONERES, __FUNCTION__, (ARG), (RES)); \
24832 #define RETURNARG(FUN,ARG,RES) \
24834 TRAPI ("return %d", (RES)); \
24835 CHKCLONEARGRES (FUN, (ARG), (RES)); \
24838 static void lglsetlim (LGL * lgl, Lim * lim) {
24839 int64_t clim, dlim, plim, confs, decs, props, delay, delayed;
24840 if ((dlim = lgl->opts->dlim.val) < 0) {
24842 lglprt (lgl, 1, "[limits] no decision limit");
24844 decs = lgl->stats->decisions;
24845 lim->decs = (decs >= LLMAX - dlim) ? LLMAX : decs + dlim;
24846 lglprt (lgl, 1, "[limits] decision limit %lld after %lld decisions",
24847 (LGLL) lim->decs, (LGLL) decs);
24849 if ((clim = lgl->opts->clim.val) < 0) {
24851 lglprt (lgl, 1, "[limits] no conflict limit");
24853 confs = lgl->stats->confs;
24854 lim->confs = (confs >= LLMAX - clim) ? LLMAX : confs + clim;
24855 lglprt (lgl, 1, "[limits] conflict limit %lld after %lld conflicts",
24856 (LGLL) lim->confs, (LGLL) confs);
24858 if ((plim = lgl->opts->plim.val) < 0) {
24860 lglprt (lgl, 1, "[limits] no propagation limit");
24863 props = lgl->stats->props.search;
24864 lim->props = (props >= LLMAX - plim) ? LLMAX : props + plim;
24866 "[limits] propagation limit %lld after %lld propagations",
24867 (LGLL) lim->props, (LGLL) props);
24869 if ((delay = lgl->opts->simpdelay.val) > 0) {
24870 delayed = lgl->stats->confs + delay;
24871 if (delayed > lgl->limits->simp.confs) {
24872 lgl->limits->simp.confs = delayed;
24874 "[limits] simplification delayed by %lld to %lld conflicts",
24875 (LGLL) delay, (LGLL) lgl->limits->simp.confs);
24876 } else lglprt (lgl, 1,
24877 "[limits] simplification conflict limit already exceeds delay");
24878 } else lglprt (lgl, 1,
24879 "[limits] simplification not delayed since 'simpdelay' zero");
24882 int lglsat (LGL * lgl) {
24885 REQINITNOTFORKED ();
24887 lglstart (lgl, &lgl->times->all);
24888 lgl->stats->calls.sat++;
24889 ABORTIF (!lglmtstk (&lgl->clause), "clause terminating zero missing");
24891 lglsetlim (lgl, &lim);
24892 res = lglisat (lgl, &lim, 0);
24894 RETURN (lglsat, res);
24898 int lglmosat (LGL * lgl, void * state, lglnotify f, int * targets) {
24899 int cint, clim, target, ntargets, rtargets, next, round, done;
24900 signed char * reported, * r;
24901 int64_t confs, totalclim;
24906 REQINITNOTFORKED ();
24907 ABORTIF (!lglmtstk (&lgl->clause), "clause terminating zero missing");
24910 lglstart (lgl, &lgl->times->all);
24911 lgl->stats->calls.mosat++;
24914 for (p = targets; *p; p++) ntargets++;
24915 NEW (reported, ntargets);
24916 rtargets = ntargets;
24918 cint = lgl->opts->mocint.val;
24919 totalclim = (lgl->opts->clim.val < 0) ?
24920 LLMAX : lgl->stats->confs + lgl->opts->clim.val;
24925 "[mosat-%lld] given %d targets",
24926 (LGLL) lgl->stats->calls.mosat, ntargets);
24930 for (p = targets, r = reported; !done && (target = *p); p++, r++) {
24932 val = lglfixed (lgl, target);
24934 if (lgl->state == SATISFIED && lglval (lgl, target) > 0) val = 1;
24937 if (!val) continue;
24938 LOG (1, "notify %d %d", target, val);
24939 done = !f (state, target, val);
24940 assert (rtargets > 0), rtargets--;
24946 "[mosat-%lld-%d] %d targets remain out of %d (%.0f%%)",
24947 (LGLL) lgl->stats->calls.mosat, round, rtargets, ntargets,
24948 lglpcnt (rtargets, ntargets));
24950 if (!rtargets) break;
24951 if (lgl->stats->confs > totalclim) break;
24954 assert (next < ntargets);
24955 if (!lglfixed (lgl, (target = targets[next]))) break;
24956 if (++next == ntargets) next = 0;
24959 LOG (1, "focusing on target %d", target);
24960 lglassume (lgl, target);
24962 confs = lgl->stats->confs;
24963 clim = lglmin (cint, lgl->opts->clim.val);
24964 lim.confs = (confs >= LLMAX - clim) ? LLMAX : confs + clim;
24966 lglprt (lgl, 1, "[limits] conflict limit %lld after %lld conflicts",
24967 (LGLL) lim.confs, (LGLL) confs);
24969 (void) lglisat (lgl, &lim, 0);
24970 cint += lgl->opts->mocint.val;
24973 DEL (reported, ntargets);
24976 "[mosat-%lld] solved %d targets out of %d, %d remain",
24977 (LGLL) lgl->stats->calls.mosat,
24978 ntargets - rtargets, ntargets, rtargets);
24985 int lglookahead (LGL * lgl) {
24987 REQINITNOTFORKED ();
24989 ABORTIF (!lglmtstk (&lgl->eassume), "imcompatible with 'lglassume'");
24990 ABORTIF (!lglmtstk (&lgl->clause), "clause terminating zero missing");
24991 lglstart (lgl, &lgl->times->all);
24992 lglstart (lgl, &lgl->times->lkhd);
24993 lgl->stats->calls.lkhd++;
24995 assert (!lgl->lkhd);
24998 if (lgl->level) lglbacktrack (lgl, 0);
24999 if (!lgl->mt && lglbcp (lgl)) {
25001 if (lgl->opts->lkhdmisifelmrtc.val &&
25002 lgl->opts->elim.val && lgl->elmrtc)
25003 ilit = lglmislook (lgl);
25004 else if (lgl->opts->lkhd.val == 2 && !lglsmallirr (lgl))
25005 ilit = lgljwhlook (lgl);
25006 else switch (lgl->opts->lkhd.val) {
25007 case -1: ilit = lglocslook (lgl); break;
25008 case 0: ilit = lglislook (lgl); break;
25009 case 1: ilit = lgljwhlook (lgl); break;
25011 if (!lgltreelookaux (lgl, &ilit)) assert (lgl->mt);
25015 assert (lgl->opts->lkhd.val == 3);
25016 ilit = lglsumlenlook (lgl);
25019 res = (!lgl->mt && ilit) ? lglexport (lgl, ilit) : 0;
25020 assert (!res || !lglelit2ext (lgl, res)->melted);
25021 } else lgl->mt = 1, res = 0;
25022 assert (lgl->lkhd);
25027 RETURN (lglookahead, res);
25031 int lglchanged (LGL * lgl) {
25033 REQINITNOTFORKED ();
25035 REQUIRE (EXTENDED);
25036 res = lgl->changed;
25037 RETURN (lglchanged, res);
25041 int lglsimp (LGL * lgl, int iterations) {
25044 REQINITNOTFORKED ();
25045 TRAPI ("simp %d", iterations);
25046 ABORTIF (iterations < 0, "negative number of simplification iterations");
25047 ABORTIF (!lglmtstk (&lgl->clause), "clause terminating zero missing");
25048 lglstart (lgl, &lgl->times->all);
25049 lgl->stats->calls.simp++;
25052 lim.decs = lgl->stats->decisions;
25053 res = lglisat (lgl, &lim, iterations);
25054 assert (!lgl->level);
25056 RETURNARG (lglsimp, iterations, res);
25060 int lglmaxvar (LGL * lgl) {
25062 REQINITNOTFORKED ();
25065 RETURN (lglmaxvar, res);
25069 int lglincvar (LGL *lgl) {
25071 REQINITNOTFORKED ();
25073 res = lgl->maxext + 1;
25074 (void) lglimport (lgl, res);
25075 RETURN (lglincvar, res);
25079 int lglderef (LGL * lgl, int elit) {
25082 TRAPI ("deref %d", elit);
25083 lgl->stats->calls.deref++;
25084 ABORTIF (!elit, "can not deref zero literal");
25085 REQUIRE (SATISFIED | EXTENDED);
25086 if (!(lgl->state & EXTENDED)) lglextend (lgl);
25087 res = lglederef (lgl, elit);
25088 RETURNARG (lglderef, elit, res);
25092 int lglfailed (LGL * lgl, int elit) {
25096 REQINITNOTFORKED ();
25097 TRAPI ("failed %d", elit);
25098 lgl->stats->calls.failed++;
25099 ABORTIF (!elit, "can not check zero failed literal");
25100 REQUIRE (UNSATISFIED | FAILED);
25101 ABORTIF (abs (elit) > lgl->maxext,
25102 "can not check unimported failed literal");
25103 ext = lglelit2ext (lgl, elit);
25104 bit = 1u << (elit < 0);
25105 ABORTIF (!(ext->assumed & bit),
25106 "can not check unassumed failed literal");
25107 if (!(lgl->state & FAILED)) {
25108 lglstart (lgl, &lgl->times->all);
25109 lglanafailed (lgl);
25112 res = (ext->failed & bit) != 0;
25113 RETURNARG (lglfailed, elit, res);
25117 int lglinconsistent (LGL * lgl) {
25119 TRAPI ("inconsistent");
25120 res = (lgl->mt != 0);
25121 RETURN (lglinconsistent, res);
25125 static int lglefixed (LGL * lgl, int elit) {
25128 if (abs (elit) > lgl->maxext) return 0;
25129 ilit = lglimport (lgl, elit);
25130 if (!ilit) res = 0;
25131 else if (abs (ilit) == 1) res = ilit;
25132 else res = lglifixed (lgl , ilit);
25136 int lglfixed (LGL * lgl, int elit) {
25138 REQINITNOTFORKED ();
25139 TRAPI ("fixed %d", elit);
25140 lgl->stats->calls.fixed++;
25141 ABORTIF (!elit, "can not deref zero literal");
25142 res = lglefixed (lgl, elit);
25143 RETURNARG (lglfixed, elit, res);
25147 int lglrepr (LGL * lgl, int elit) {
25148 int res, eidx = abs (elit);
25149 REQINITNOTFORKED ();
25150 TRAPI ("repr %d", elit);
25151 lgl->stats->calls.repr++;
25152 if (eidx > lgl->maxext) res = elit;
25154 res = lglerepr (lgl, elit);
25155 if (abs (res) <= 1) res = elit;
25157 RETURNARG (lglrepr, elit, res);
25161 void lglfreeze (LGL * lgl, int elit) {
25163 REQINITNOTFORKED ();
25164 TRAPI ("freeze %d", elit);
25165 lgl->stats->calls.freeze++;
25166 ABORTIF (!elit, "can not freeze zero literal");
25167 REQUIRE (UNUSED|OPTSET|USED|RESET|SATISFIED|UNSATISFIED|FAILED|LOOKED|
25169 LOG (2, "freezing external literal %d", elit);
25170 (void) lglimport (lgl, elit);
25171 ext = lglelit2ext (lgl, elit);
25172 ABORTIF (ext->melted, "freezing melted literal %d", elit);
25173 assert (!ext->blocking && !ext->eliminated);
25174 ABORTIF (ext->frozen == INT_MAX, "literal %d frozen too often", elit);
25176 if (!ext->frozen) {
25177 lgl->stats->irrprgss++;
25180 if (lgl->clone) lglfreeze (lgl->clone, elit);
25183 int lglfrozen (LGL * lgl, int elit) {
25186 REQINITNOTFORKED ();
25187 TRAPI ("frozen %d", elit);
25188 ABORTIF (!elit, "can not check zero literal for being frozen");
25189 if (abs (elit) > lgl->maxext) res = INT_MAX;
25190 else if (!(ext = lglelit2ext (lgl, elit))->imported) res = INT_MAX;
25191 else res = ext->frozen;
25192 RETURNARG (lglfrozen, elit, res);
25196 int lglusable (LGL * lgl, int elit) {
25199 REQINITNOTFORKED ();
25200 TRAPI ("usable %d", elit);
25201 ABORTIF (!elit, "can not check zero literal for being usable");
25202 if (abs (elit) > lgl->maxext) res = 1;
25203 else if (!(ext = lglelit2ext (lgl, elit))->imported) res = 1;
25204 else res = !ext->melted;
25205 RETURNARG (lglusable, elit, res);
25209 static int lglereusable (LGL * lgl, int elit) {
25212 if (abs (elit) > lgl->maxext) res = 1;
25213 else if (!(ext = lglelit2ext (lgl, elit))->imported) res = 1;
25214 else if (ext->blocking) res = 0;
25215 else if (ext->eliminated) res = 0;
25216 else if (ext->equiv) res = 0;
25217 else if (abs (ext->repr) == 1) res = 0;
25222 int lglreusable (LGL * lgl, int elit) {
25224 REQINITNOTFORKED ();
25225 TRAPI ("reusable %d", elit);
25226 ABORTIF (!elit, "can not check zero literal for being reusable");
25227 res = lglereusable (lgl, elit);
25228 RETURNARG (lglreusable, elit, res);
25232 void lglreuse (LGL * lgl, int elit) {
25234 REQINITNOTFORKED ();
25235 TRAPI ("reuse %d", elit);
25236 ABORTIF (!elit, "can not reuse zero literal");
25237 ABORTIF (!lglereusable (lgl, elit), "can not reuse non-reusable literal");
25238 if (abs (elit) <= lgl->maxext) {
25239 ext = lglelit2ext (lgl, elit);
25240 if (ext->imported) {
25241 assert (!ext->blocking);
25242 assert (!ext->eliminated);
25245 "forced permanently melted external %d to be reused",
25252 if (lgl->clone) lglreuse (lgl->clone, elit);
25255 void lglmeltall (LGL * lgl) {
25258 REQINITNOTFORKED ();
25261 for (idx = 1; idx <= lgl->maxext; idx++) {
25262 ext = lglelit2ext (lgl, idx);
25264 if (!ext->frozen) continue;
25265 lgl->stats->irrprgss++;
25269 lglprt (lgl, 1, "[meltall] melted %d frozen literals", melted);
25271 if (lgl->clone) lglmeltall (lgl->clone);
25274 void lglmelt (LGL * lgl, int elit) {
25276 REQINITNOTFORKED ();
25277 TRAPI ("melt %d", elit);
25278 lgl->stats->calls.melt++;
25279 ABORTIF (!elit, "can not melt zero literal");
25280 REQUIRE (UNUSED|OPTSET|USED|RESET|
25281 SATISFIED|UNSATISFIED|FAILED|UNKNOWN|LOOKED|
25283 LOG (2, "melting external literal %d", elit);
25284 (void) lglimport (lgl, elit);
25285 ext = lglelit2ext (lgl, elit);
25286 ABORTIF (!ext->frozen, "can not melt fully unfrozen literal %d", elit);
25287 assert (!ext->blocking && !ext->eliminated);
25289 lglmelter (lgl); // TODO guard by !ext->frozen?
25290 if (lgl->clone) lglmelt (lgl->clone, elit);
25293 void lglreconstk (LGL * lgl, int ** startptr, int ** toptr) {
25294 REQINITNOTFORKED ();
25295 TRAPI ("reconstk");
25296 lglfitstk (lgl, &lgl->extend); // 'lglcompact' -> 'lglclone'!!
25297 if (startptr) *startptr = lgl->extend.start;
25298 if (toptr) *toptr = lgl->extend.top;
25299 if (lgl->clone) lglreconstk (lgl->clone, 0, 0);
25302 static void lglprstart (LGL * lgl) {
25303 assert (lgl->prefix);
25304 fputs (lgl->prefix, lgl->out);
25305 if (lgl->tid >= 0) fprintf (lgl->out, "%d ", lgl->tid);
25308 static void lglprs (LGL * lgl, const char * fmt, ...) {
25311 va_start (ap, fmt);
25312 vfprintf (lgl->out, fmt, ap);
25314 fputc ('\n', lgl->out);
25317 static void lglprsline (LGL * lgl) {
25319 fputc ('\n', lgl->out);
25322 static double lglsqr (double a) { return a*a; }
25324 static void lglgluestats (LGL * lgl) {
25325 int64_t added, reduced, forcing, resolved, conflicts;
25326 int64_t wadded, wreduced, wforcing, wresolved, wconflicts;
25327 int64_t avgadded, avgreduced, avgforcing, avgresolved, avgconflicts;
25328 double madded, mreduced, mforcing, mresolved, mconflicts;
25329 double vadded, vreduced, vforcing, vresolved, vconflicts;
25330 double sadded, sreduced, sforcing, sresolved, sconflicts;
25331 Stats * s = lgl->stats;
25334 "scaledglue%7s %3s %9s %3s %9s %3s %9s %3s %9s",
25335 "added","", "reduced","", "forcing","", "resolved","", "conflicts");
25336 added = reduced = forcing = resolved = conflicts = 0;
25337 wadded = wreduced = wforcing = wresolved = wconflicts = 0;
25338 for (glue = 0; glue <= MAXGLUE; glue++) {
25339 added += s->lir[glue].added;
25340 reduced += s->lir[glue].reduced;
25341 forcing += s->lir[glue].forcing;
25342 resolved += s->lir[glue].resolved;
25343 conflicts += s->lir[glue].conflicts;
25344 wadded += glue*s->lir[glue].added;
25345 wreduced += glue*s->lir[glue].reduced;
25346 wforcing += glue*s->lir[glue].forcing;
25347 wresolved += glue*s->lir[glue].resolved;
25348 wconflicts += glue*s->lir[glue].conflicts;
25350 avgadded = added ? (((10*wadded)/added+5)/10) : 0;
25351 avgreduced = reduced ? (((10*wreduced)/reduced+5)/10) : 0;
25352 avgforcing = forcing ? (((10*wforcing)/forcing+5)/10) : 0;
25353 avgresolved = resolved ? (((10*wresolved)/resolved+5)/10) : 0;
25354 avgconflicts = conflicts ? (((10*wconflicts)/conflicts+5)/10) : 0;
25357 "all %9lld %3.0f %9lld %3.0f %9lld %3.0f %9lld %3.0f %9lld %3.0f",
25358 (LGLL) added, 100.0,
25359 (LGLL) reduced, 100.0,
25360 (LGLL) forcing, 100.0,
25361 (LGLL) resolved, 100.0,
25362 (LGLL) conflicts, 100.0);
25364 for (glue = 0; glue <= MAXGLUE; glue++) {
25366 "%2d %9lld %3.0f%c%9lld %3.0f%c%9lld %3.0f%c%9lld %3.0f%c%9lld %3.0f%c",
25368 (LGLL) s->lir[glue].added,
25369 lglpcnt (s->lir[glue].added, added),
25370 (glue == avgadded) ? '<' : ' ',
25371 (LGLL) s->lir[glue].reduced,
25372 lglpcnt (s->lir[glue].reduced, reduced),
25373 (glue == avgreduced) ? '<' : ' ',
25374 (LGLL) s->lir[glue].forcing,
25375 lglpcnt (s->lir[glue].forcing, forcing),
25376 (glue == avgforcing) ? '<' : ' ',
25377 (LGLL) s->lir[glue].resolved,
25378 lglpcnt (s->lir[glue].resolved, resolved),
25379 (glue == avgresolved) ? '<' : ' ',
25380 (LGLL) s->lir[glue].conflicts,
25381 lglpcnt (s->lir[glue].conflicts, conflicts),
25382 (glue == avgconflicts) ? '<' : ' ');
25386 madded = lglavg (wadded, added),
25387 mreduced = lglavg (wreduced, reduced),
25388 mforcing = lglavg (wforcing, forcing),
25389 mresolved = lglavg (wresolved, resolved),
25390 mconflicts = lglavg (wconflicts, conflicts);
25393 "avg %14.1f%14.1f%14.1f%14.1f%14.1f",
25394 madded, mreduced, mforcing, mresolved, mconflicts);
25396 vadded = vreduced = vforcing = vresolved = vconflicts = 0;
25397 for (glue = 0; glue <= MAXGLUE; glue++) {
25398 vadded += s->lir[glue].added * lglsqr (glue - madded);
25399 vreduced += s->lir[glue].reduced * lglsqr (glue - mreduced);
25400 vforcing += s->lir[glue].forcing * lglsqr (glue - mforcing);
25401 vresolved += s->lir[glue].resolved * lglsqr (glue - mresolved);
25402 vconflicts += s->lir[glue].conflicts * lglsqr (glue - mconflicts);
25404 sadded = sqrt (lglavg (vadded, added));
25405 sreduced = sqrt (lglavg (vreduced, reduced));
25406 sforcing = sqrt (lglavg (vforcing, forcing));
25407 sresolved = sqrt (lglavg (vresolved, resolved));
25408 sconflicts = sqrt (lglavg (vconflicts, conflicts));
25411 "std %14.1f%14.1f%14.1f%14.1f%14.1f",
25412 sadded, sreduced, sforcing, sresolved, sconflicts);
25415 typedef struct TN { double t; const char * n; } TN;
25417 static int lglcmptn (const TN * a, const TN * b) {
25418 if (a->t > b->t) return -1;
25419 if (a->t < b->t) return 1;
25420 return strcmp (a->n, b->n);
25423 #define INSTN(NAME,FIELD) \
25425 TN * tn = tns + ntns++; \
25426 assert (ntns <= sztns); \
25427 tn->t = ts->FIELD; \
25431 static void lglprofsort (LGL * lgl) {
25432 Times * ts = lgl->times;
25433 const int sztns = 31;
25437 INSTN (analysis, ana);
25438 INSTN (backward, bkwd);
25440 INSTN (block, blk);
25441 INSTN (bump, bump);
25443 INSTN (card, card);
25445 INSTN (cgrclsr, cgr);
25446 INSTN (cliff, cliff);
25447 INSTN (cutwidth, ctw);
25448 INSTN (decide, dec);
25449 INSTN (decomp, dcp);
25450 INSTN (defrag, dfg );
25452 INSTN (force, force);
25453 INSTN (gauss, gauss);
25456 INSTN (locs, locs);
25457 INSTN (mega, mega);
25458 INSTN (mincls, mcls);
25459 INSTN (phase, phs);
25460 INSTN (probe, prb.all);
25462 INSTN (reduce, red );
25463 INSTN (restart, rsts);
25464 INSTN (tabularasa, tabr);
25465 INSTN (ternres, trn);
25466 INSTN (transred, trd);
25467 INSTN (unhide, unhd);
25469 assert (ntns == sztns);
25471 // Force insertion sort to avoid implicit memory allocation!
25472 // Otherwise an already existing memory corruption will trigger
25473 // another signal and thus might result in non-termination.
25475 ISORT (TN, lglcmptn, tns, ntns);
25477 for (i = 0; i < ntns; i++)
25478 lglprs (lgl, "%8.3f %3.0f%% %s",
25479 tns[i].t, lglpcnt (tns[i].t, ts->all), tns[i].n);
25482 static void lglprof (LGL * lgl) {
25483 Times * ts = lgl->times;
25484 double t = ts->all, simp, search;
25486 assert (lgl->opts->verbose.val >= 0);
25487 simp = ts->prep + ts->inpr;
25488 if (!lgl->opts->verbose.val) goto SHORT;
25492 lglprs (lgl, "----------------------------------");
25493 lglprs (lgl, "%8.3f %3.0f%% probe simple %3.0f%%",
25495 lglpcnt (ts->prb.simple, t),
25496 lglpcnt (ts->prb.simple, ts->prb.all));
25497 lglprs (lgl, "%8.3f %3.0f%% probe basic %3.0f%%",
25499 lglpcnt (ts->prb.basic, t),
25500 lglpcnt (ts->prb.basic, ts->prb.all));
25501 lglprs (lgl, "%8.3f %3.0f%% probe tree-look %3.0f%%",
25503 lglpcnt (ts->prb.treelook, t),
25504 lglpcnt (ts->prb.treelook, ts->prb.all));
25505 lglprs (lgl, "==================================");
25506 lglprs (lgl, "%8.3f %3.0f%% preprocessing %3.0f%%",
25508 lglpcnt (ts->prep, t),
25509 lglpcnt (ts->prep, simp));
25510 lglprs (lgl, "%8.3f %3.0f%% inprocessing %3.0f%%",
25512 lglpcnt (ts->inpr, t),
25513 lglpcnt (ts->inpr, simp));
25514 lglprs (lgl, "==================================");
25516 lglprs (lgl, "%8.3f %3.0f%% simplifying", simp, lglpcnt (simp, t));
25517 if (lgl->stats->calls.lkhd)
25518 lglprs (lgl, "%8.3f %3.0f%% lookahead", ts->lkhd, lglpcnt (ts->lkhd, t));
25519 search = ts->srch - ts->inpr;
25520 lglprs (lgl, "%8.3f %3.0f%% search", search, lglpcnt (search, t));
25521 lglprs (lgl, "==================================");
25522 lglprs (lgl, "%8.3f %3.0f%% all", t, 100.0);
25525 void lglstats (LGL * lgl) {
25526 long long visits, travs, min, p, steps;
25527 int remaining, removed, sum;
25530 REQINITNOTFORKED ();
25531 if (lgl->opts->verbose.val < 0) return;
25533 t = lgl->times->all;
25534 p = s->props.search + s->props.simp + s->props.lkhd;
25535 if (!lgl->opts->verbose.val) goto SHORT;
25536 sum = s->prb.basic.ate.trnr + s->prb.basic.ate.lrg;
25538 "bate: %d basic ate = %d trn %.0f%% + %d lrg %.0f%% in %d updates",
25539 sum, s->prb.basic.ate.trnr, lglpcnt (s->prb.basic.ate.trnr, sum),
25540 s->prb.basic.ate.lrg, lglpcnt (s->prb.basic.ate.lrg, sum),
25541 s->prb.basic.ate.count);
25544 "bcas: %d count, %lld added (%lld skipped), %lld steps",
25545 s->bca.count, (LGLL) s->bca.added, s->bca.skipped, (LGLL) s->bca.steps);
25548 "bkwd: tried %lld clauses, %lld lits, %.2f lits/clause",
25549 (LGLL) s->bkwd.tried.clauses, (LGLL) s->bkwd.tried.lits,
25550 lglavg (s->bkwd.tried.lits, s->bkwd.tried.clauses));
25552 "bkwd: checked %lld occs, %.2f occs/clause, %.2f occs/lit",
25553 (LGLL) s->bkwd.tried.occs,
25554 lglavg (s->bkwd.tried.occs, s->bkwd.tried.clauses),
25555 lglavg (s->bkwd.tried.occs, s->bkwd.tried.lits));
25557 "bkwd: subsumed %d binary, %d ternary, %d large",
25558 s->bkwd.sub2, s->bkwd.sub3, s->bkwd.subl);
25560 "bkwd: strengthened %d binary, "
25561 "%d ternary (%.0f%% self), %d large (%.0f%% self)",
25563 s->bkwd.str3, lglpcnt (s->bkwd.str3self, s->bkwd.str3),
25564 s->bkwd.strl, lglpcnt (s->bkwd.strlself, s->bkwd.strl));
25567 "blkd: %d bces, %d removed, %lld resolutions, %lld steps",
25568 s->blk.count, s->blk.clauses, (LGLL) s->blk.res, (LGLL) s->blk.steps);
25570 "blkd: %d blocking literals %.0f%%, %d pure",
25571 s->blk.lits, lglpcnt (s->blk.lits, 2*lgl->maxext), s->blk.pure);
25574 "bvas: %d bvas, %d added, %d removed",
25575 s->bva.count, s->bva.added, s->bva.removed);
25578 "card: %d count, %d units, %d am1, %lld steps",
25579 s->card.count, s->card.units, s->card.expam1, (LGLL) s->card.steps);
25581 "card: %d rescheduled, %lld eliminated, %lld resolved, %lld subsumed",
25582 s->card.resched, (LGLL) s->card.eliminated,
25583 (LGLL) s->card.resolved, (LGLL) s->card.subsumed);
25585 "card: %d at-most-one constraints found, average size %.2f",
25586 s->card.am1.found.cnt,
25587 lglavg (s->card.am1.found.sum, s->card.am1.found.cnt));
25589 "card: %d at-most-one constraints used %.0f%%, average size %.2f",
25590 s->card.am1.used.cnt,
25591 lglpcnt (s->card.am1.used.cnt, s->card.am1.found.cnt),
25592 lglavg (s->card.am1.used.sum, s->card.am1.used.cnt));
25594 "card: %d at-most-two constraints found, average size %.2f",
25595 s->card.am2.found.cnt,
25596 lglavg (s->card.am2.found.sum, s->card.am2.found.cnt));
25598 "card: %d at-most-two constraints used %.0f%%, average size %.2f",
25599 s->card.am2.used.cnt,
25600 lglpcnt (s->card.am2.used.cnt, s->card.am2.found.cnt),
25601 lglavg (s->card.am2.used.sum, s->card.am2.used.cnt));
25604 "cces: %d cces, %d eliminated, %d ate %.0f%%, %d abce %.0f%%",
25605 s->cce.count, s->cce.eliminated,
25606 s->cce.ate, lglpcnt (s->cce.ate, s->cce.eliminated),
25607 s->cce.abce, lglpcnt (s->cce.abce, s->cce.eliminated));
25609 "cces: %lld probed, %d lifted, %d failed",
25610 (LGLL) s->cce.probed, s->cce.lifted, s->cce.failed);
25612 "cces: %lld cached, %lld rsz, %lld cols %.0f%%, "
25613 "%lld srch, %lld hits %.0f%%",
25614 (LGLL) s->cce.cache.ins,
25615 (LGLL) s->cce.cache.rsz,
25616 (LGLL) s->cce.cache.cols,
25617 lglpcnt (s->cce.cache.cols, s->cce.cache.ins),
25618 (LGLL) s->cce.cache.search,
25619 (LGLL) s->cce.cache.hits,
25620 lglpcnt (s->cce.cache.hits, s->cce.cache.search));
25623 "cgrs: %d count, %lld esteps, %lld csteps",
25624 s->cgr.count, (LGLL) s->cgr.esteps, (LGLL) s->cgr.csteps);
25626 "cgrs: %d eqs, %d units", s->cgr.eq, s->cgr.units);
25628 "cgrs: %d matched (%d ands %.0f%%, %d xors %.0f%%, %d ites %.0f%%)",
25629 s->cgr.matched.all,
25630 s->cgr.matched.and, lglpcnt (s->cgr.matched.and, s->cgr.matched.all),
25631 s->cgr.matched.xor, lglpcnt (s->cgr.matched.xor, s->cgr.matched.all),
25632 s->cgr.matched.ite, lglpcnt (s->cgr.matched.ite, s->cgr.matched.all));
25634 "cgrs: %d simplified (%d ands %.0f%%, %d xors %.0f%%, %d ites %.0f%%)",
25635 s->cgr.simplified.all,
25636 s->cgr.simplified.and,
25637 lglpcnt (s->cgr.simplified.and, s->cgr.simplified.all),
25638 s->cgr.simplified.xor,
25639 lglpcnt (s->cgr.simplified.xor, s->cgr.simplified.all),
25640 s->cgr.simplified.ite,
25641 lglpcnt (s->cgr.simplified.ite, s->cgr.simplified.all));
25643 "cgrs: %lld extracted "
25644 "(%lld ands %.0f%%, %lld xors %.0f%%, %lld ites %.0f%%)",
25645 (LGLL)s->cgr.extracted.all,
25646 (LGLL)s->cgr.extracted.and,
25647 lglpcnt (s->cgr.extracted.and, s->cgr.extracted.all),
25648 (LGLL)s->cgr.extracted.xor,
25649 lglpcnt (s->cgr.extracted.xor, s->cgr.extracted.all),
25650 (LGLL)s->cgr.extracted.ite,
25651 lglpcnt (s->cgr.extracted.ite, s->cgr.extracted.all));
25654 "clff: %d cliffs, %d lifted, %d failed",
25655 s->cliff.count, s->cliff.lifted, s->cliff.failed);
25657 "clff: %lld decisions, %lld steps",
25658 (LGLL) s->cliff.decisions, (LGLL) s->cliff.steps);
25661 "clls: %lld sat, %lld simp, %lld freeze, %lld melt",
25662 (LGLL) s->calls.sat, (LGLL) s->calls.simp,
25663 (LGLL) s->calls.freeze, (LGLL) s->calls.melt);
25665 "clls: %lld add, %lld assume, %lld deref, %lld failed",
25666 (LGLL) s->calls.add, (LGLL) s->calls.assume,
25667 (LGLL) s->calls.deref, (LGLL) s->calls.failed);
25669 "clls: %lld lkhd, %lld cassume, %lld mosat",
25670 (LGLL) s->calls.lkhd, (LGLL) s->calls.cassume, (LGLL) s->calls.mosat);
25673 "coll: %d gcs, %d rescored clauses, %d rescored vars",
25674 s->gcs, s->rescored.clauses, s->rescored.vars);
25677 "dcps: %d decompositions, %d equivalent %.0f%%",
25678 s->decomps, s->equiv.sum, lglpcnt (s->equiv.sum, lgl->maxext));
25681 "deco: %lld decision-only clauses %.0f%%, %.0f%% reduction",
25682 s->mincls.deco, lglpcnt (s->mincls.deco, s->clauses.learned),
25683 lglpcnt (s->deco.sum.orig - s->deco.sum.red, s->deco.sum.orig));
25686 "decs: %lld decision, %lld random %.3f%%, %lld flipped %.3f%%",
25687 (LGLL) s->decisions,
25688 (LGLL) s->randecs, lglpcnt (s->randecs, s->decisions),
25689 (LGLL) s->randecsflipped, lglpcnt (s->randecsflipped, s->randecs));
25691 "decs: %lld flipped %.3f%% (in %lld phases)",
25692 (LGLL) s->flipped, lglpcnt (s->flipped, s->decisions),
25693 (LGLL) s->fliphases);
25696 "elms: %d elims, %d eliminated %.0f%%",
25697 s->elm.count, s->elm.elmd, lglpcnt (s->elm.elmd, lgl->maxext));
25699 "elms: %d rounds, %.1f rounds/bve",
25700 s->elm.rounds, lglavg (s->elm.rounds, s->elm.count));
25702 "elms: %d small %.0f%%, %d large %.0f%%",
25703 s->elm.small.elm, lglpcnt (s->elm.small.elm, s->elm.elmd),
25704 s->elm.large, lglpcnt (s->elm.large, s->elm.elmd));
25706 "elms: %d tried small, %d succeeded %.0f%%, %d failed %.0f%%",
25707 s->elm.small.tried, s->elm.small.tried - s->elm.small.failed,
25708 lglpcnt (s->elm.small.tried - s->elm.small.failed, s->elm.small.tried),
25709 s->elm.small.failed,
25710 lglpcnt (s->elm.small.failed, s->elm.small.tried));
25712 "elms: %d subsumed, %d strengthened, %d blocked",
25713 s->elm.sub, s->elm.str, s->elm.blkd);
25715 "elms: %lld copies, %lld resolutions, %lld ipos",
25716 (LGLL) s->elm.copies, (LGLL) s->elm.resolutions, (LGLL) s->elm.ipos);
25718 "elms: %lld subchks, %lld strchks",
25719 (LGLL) s->elm.subchks, (LGLL) s->elm.strchks);
25722 "frcs: %lld computed, %d - %d average min-cut range",
25723 (LGLL) s->force.count, s->force.mincut.min, s->force.mincut.max);
25726 "gaus: %lld extractions, %lld extracted, %.1f size, %d max",
25727 s->gauss.count, s->gauss.extracted,
25728 lglavg (s->gauss.arity.sum, s->gauss.extracted), s->gauss.arity.max);
25730 "gaus: exported %d units, %d binary and %d ternary equations",
25731 s->gauss.units, s->gauss.equivs, s->gauss.trneqs);
25732 steps = s->gauss.steps.extr + s->gauss.steps.extr;
25734 "gaus: %d gc, %lld steps, %lld extr %.0f%%, %lld elim %.0f%%",
25735 s->gauss.gcs, (LGLL) steps,
25736 s->gauss.steps.extr, lglpcnt (s->gauss.steps.extr, steps),
25737 s->gauss.steps.elim, lglpcnt (s->gauss.steps.elim, steps));
25740 "glue: %.1f orig avg, %.1f real avg, %.1f scaled avg",
25741 lglavg (s->clauses.glue, s->clauses.learned),
25742 lglavg (s->clauses.realglue, s->clauses.learned),
25743 lglavg (s->clauses.scglue, s->clauses.learned));
25745 "glue: %lld maxscaledglue=%d (%.0f%%)",
25746 (LGLL) s->clauses.maxglue, MAXGLUE,
25747 lglpcnt (s->clauses.maxglue, s->clauses.learned));
25750 "hbrs: %d = %d simple + %d trn %.0f%% + %d lrg %.0f%%, %d sub %.0f%%",
25752 s->hbr.simple, lglpcnt (s->hbr.simple, s->hbr.cnt),
25753 s->hbr.trn, lglpcnt (s->hbr.trn, s->hbr.cnt),
25754 s->hbr.lrg, lglpcnt (s->hbr.lrg, s->hbr.cnt),
25755 s->hbr.sub, lglpcnt (s->hbr.sub, s->hbr.cnt));
25758 "hght: %.0f average, %.2f height/glue",
25759 lglheight (lgl), lglavg (lglheight (lgl), lglglue (lgl)));
25762 "ints: %lld luby (%lld steps), %lld inout (%lld steps)",
25763 (LGLL) s->luby.count, (LGLL) s->luby.steps,
25764 (LGLL) s->inout.count, (LGLL) s->inout.steps);
25766 sum = s->lift.probed0 + s->lift.probed1;
25768 "lift: %d phases, %d probed (%lld level1 %.0f%%, %lld level2 %.0f%%)",
25769 s->lift.count, sum,
25770 (LGLL) s->lift.probed0, lglpcnt (s->lift.probed0, sum),
25771 (LGLL) s->lift.probed1, lglpcnt (s->lift.probed1, sum));
25773 "lift: %d units, %d equivalences, %d implications",
25774 s->lift.units, s->lift.eqs, s->lift.impls);
25777 "locs: %d count, %lld flips, %lld mems, %d minimun",
25778 s->locs.count, (LGLL) s->locs.flips, (LGLL) s->locs.mems, s->locs.min);
25781 "lrnd: %lld clauses, %.1f length",
25782 (LGLL) s->clauses.learned,
25783 lglavg (s->lits.learned, s->clauses.learned));
25785 "lrnd: %lld uips %.0f%%, %lld flips %.0f%%",
25786 (LGLL) s->uips, lglpcnt (s->uips, s->clauses.learned),
25787 (LGLL) s->decflipped, lglpcnt (s->decflipped, s->clauses.learned));
25790 "mega: %d count, %d failed, %d rounds",
25791 s->mega.count, s->mega.failed, s->mega.rounds);
25793 assert (s->lits.nonmin >= s->lits.learned);
25794 min = s->lits.nonmin - s->lits.learned;
25795 sum = s->moved.bin + s->moved.trn + s->moved.lrg;
25797 "mins: %lld learned lits, %.0f%% minimized",
25798 (LGLL) s->lits.learned, lglpcnt (min, s->lits.nonmin));
25800 sum = s->mincls.min + s->mincls.bin + s->mincls.size + s->mincls.deco;
25802 "mins: %lld mins %.0f%%, %lld bin %.0f%%, "
25803 "%lld size %.0f%%, %lld deco %.0f%%",
25804 (LGLL) s->mincls.min, lglpcnt (s->mincls.min, sum),
25805 (LGLL) s->mincls.bin, lglpcnt (s->mincls.bin, sum),
25806 (LGLL) s->mincls.size, lglpcnt (s->mincls.size, sum),
25807 (LGLL) s->mincls.deco, lglpcnt (s->mincls.deco, sum));
25810 "move: moved %lld, %lld bin %.0f%%, %lld trn %.0f%%, %lld lrg %.0f%%",
25812 (LGLL) s->moved.bin, lglpcnt (s->moved.bin, sum),
25813 (LGLL) s->moved.trn, lglpcnt (s->moved.trn, sum),
25814 (LGLL) s->moved.lrg, lglpcnt (s->moved.lrg, sum));
25816 sum = s->otfs.str.dyn.red + s->otfs.str.dyn.irr;
25818 "otfs: str %d dyn (%d red, %d irr) %lld drv %.0f%%, %lld rst %.0f%%",
25820 s->otfs.str.dyn.red, s->otfs.str.dyn.irr,
25821 (LGLL) s->otfs.driving, lglpcnt (s->otfs.driving, sum),
25822 (LGLL) s->otfs.restarting, lglpcnt (s->otfs.restarting, sum));
25824 "otfs: sub %d dyn (%d red, %d irr)",
25825 s->otfs.sub.dyn.red + s->otfs.sub.dyn.irr,
25826 s->otfs.sub.dyn.red, s->otfs.sub.dyn.irr);
25829 "phas: %lld computed, %lld set, %lld pos (%.0f%%), %lld neg (%.0f%%)",
25830 (LGLL) s->phase.count, (LGLL) s->phase.set,
25831 (LGLL) s->phase.pos, lglpcnt (s->phase.pos, s->phase.set),
25832 (LGLL) s->phase.neg, lglpcnt (s->phase.neg, s->phase.set));
25835 "prbs: %d basic, %lld probed, %d failed, %d lifted",
25836 s->prb.basic.count, (LGLL) s->prb.basic.probed,
25837 s->prb.basic.failed, s->prb.basic.lifted);
25839 "prbs: %d simple, %lld probed, %d failed, %d eqs",
25840 s->prb.simple.count, (LGLL) s->prb.simple.probed,
25841 s->prb.simple.failed, s->prb.simple.eqs);
25843 "prbs: %d treelook, %lld probed, %d failed, %d lifted",
25844 s->prb.treelook.count, (LGLL) s->prb.treelook.probed,
25845 s->prb.treelook.failed, s->prb.treelook.lifted);
25848 "prps: %lld props, %.0f props/dec",
25849 (LGLL) p, lglavg (s->props.search, s->decisions));
25851 "prps: %.0f%% srch, %.0f%% simp, %.0f%% lkhd",
25852 lglpcnt (s->props.search, p), lglpcnt (s->props.simp, p),
25853 lglpcnt (s->props.lkhd, p));
25856 "psns: %lld searches, %lld hits, %.0f%% hit rate",
25857 (LGLL) s->poison.search, (LGLL) s->poison.hits,
25858 lglpcnt (s->poison.hits, s->poison.search));
25861 "rdps: %d count, %d units, %d bin, %d trn, %lld steps",
25862 s->rdp.count, s->rdp.units, s->rdp.bin, s->rdp.trn, (LGLL) s->rdp.steps);
25864 "rdps: %lld partial eliminations, %lld bounded %.0f%%",
25865 (LGLL) s->rdp.elim, (LGLL) s->rdp.limhit.bound,
25866 lglpcnt (s->rdp.limhit.bound, s->rdp.elim));
25868 "rdps: %lld resolutions, %lld size %.0f%%, %lld model %.0f%%",
25870 (LGLL) s->rdp.limhit.len, lglpcnt (s->rdp.limhit.len, s->rdp.res),
25871 (LGLL) s->rdp.limhit.model, lglpcnt (s->rdp.limhit.model, s->rdp.res));
25874 "reds: %d count, %d reset, %d acts %.0f%%",
25875 s->reduced.count, s->reduced.reset,
25876 s->acts, lglpcnt (s->acts, s->reduced.count));
25878 "reds: %d geom %.0f%%, %d glue useless %.0f%%",
25879 s->reduced.geom, lglpcnt (s->reduced.geom, s->reduced.count),
25880 s->reduced.gul, lglpcnt (s->reduced.gul, s->reduced.count));
25882 "reds: %d memlim %.0f%%, %d arith %.0f%%, %d double %.0f%%",
25883 s->reduced.memlim, lglpcnt (s->reduced.memlim, s->reduced.count),
25884 s->reduced.arith, lglpcnt (s->reduced.arith, s->reduced.count),
25885 s->reduced.arith2, lglpcnt (s->reduced.arith2, s->reduced.arith));
25888 "rmbd: %d removed, %d red %.0f%%",
25889 s->bindup.removed, s->bindup.red,
25890 lglpcnt (s->bindup.red, s->bindup.removed));
25893 "rphs: %d recomputed phases",
25896 sum = s->restarts.count + s->restarts.skipped.count;
25898 "rsts: %d restarts %.0f%%, %d skipped %.0f%%",
25899 s->restarts.count, lglpcnt (s->restarts.count, sum),
25900 s->restarts.skipped.count, lglpcnt (s->restarts.skipped.count, sum));
25902 "rsts: %d saturating %.0f%%, %d agile %.0f%%, %d reuse %.0f%%",
25903 s->restarts.skipped.saturating,
25904 lglpcnt (s->restarts.skipped.saturating, s->restarts.skipped.count),
25905 s->restarts.skipped.agile,
25906 lglpcnt (s->restarts.skipped.agile, s->restarts.skipped.count),
25907 s->restarts.skipped.reuse,
25908 lglpcnt (s->restarts.skipped.reuse, s->restarts.skipped.count));
25910 "rsts: %.1f avg interval, %.1f scaled, %.1f factor",
25911 lglavg (s->restarts.intsum.orig, s->restarts.count),
25912 lglavg (s->restarts.intsum.scaled, s->restarts.count),
25913 lglavg (s->restarts.intsum.orig, s->restarts.intsum.scaled));
25915 "rsts: %d kept %.1f%% average %.1f%%",
25916 s->restarts.kept.count,
25917 lglpcnt (s->restarts.kept.count, s->restarts.count),
25918 lglavg (s->restarts.kept.sum, s->restarts.kept.count));
25921 "simp: %d count (%d confs %0.f%%, %d irr %.0f%%, %d vars %.0f%%)",
25923 s->simp.limhit.confs, lglpcnt (s->simp.limhit.confs, s->simp.count),
25924 s->simp.limhit.irr, lglpcnt (s->simp.limhit.irr, s->simp.count),
25925 s->simp.limhit.vars, lglpcnt (s->simp.limhit.vars, s->simp.count));
25928 "subl: %lld count (%lld tried %.1f), %lld sub out of %lld (%.1f%%)",
25929 s->subl.count, s->subl.tried, lglavg (s->subl.tried, s->subl.count),
25930 s->subl.sub, s->subl.cands, lglpcnt (s->subl.sub, s->subl.cands));
25933 "sync: %lld produced units, %lld successful consumptions %.0f%%",
25934 s->sync.units.produced, s->sync.units.consumed.actual,
25935 lglpcnt (s->sync.units.consumed.actual, s->sync.units.produced));
25937 "sync: %lld consume units calls, %lld tried %.0f%%, %lld success %.0f%%",
25938 s->sync.units.consumed.calls,
25939 s->sync.units.consumed.tried,
25940 lglpcnt (s->sync.units.consumed.tried, s->sync.units.consumed.calls),
25941 s->sync.units.consumed.actual,
25942 lglpcnt (s->sync.units.consumed.actual, s->sync.units.consumed.calls));
25944 "sync: %lld produced clauses, %lld successful consumptions %.0f%%",
25945 s->sync.cls.produced, s->sync.cls.consumed.actual,
25946 lglpcnt (s->sync.cls.consumed.actual, s->sync.cls.produced));
25948 "sync: %lld consume clause calls, %lld tried %.0f%%, %lld success %.0f%%",
25949 s->sync.cls.consumed.calls,
25950 s->sync.cls.consumed.tried,
25951 lglpcnt (s->sync.cls.consumed.tried, s->sync.cls.consumed.calls),
25952 s->sync.cls.consumed.actual,
25953 lglpcnt (s->sync.cls.consumed.actual, s->sync.cls.consumed.calls));
25955 lglprs (lgl, "tabr: %d count", s->tabr.count);
25958 "tops: %d fixed %.0f%%, %d its, %.2f confs/it",
25959 s->fixed.sum, lglpcnt (s->fixed.sum, lgl->maxext),
25960 s->iterations, lglavg (s->confs, s->iterations));
25962 travs = s->travs.search + s->visits.simp + s->visits.lkhd;
25964 "trvs: %lld traversals, %.0f%% srch, %.0f%% simp, %.0f%% lkhd",
25965 (LGLL) travs, lglpcnt (s->travs.search, travs),
25966 lglpcnt (s->travs.simp, travs), lglpcnt (s->travs.lkhd, travs));
25968 "trvs: %.1f search traversals per propagation, %.1f per conflict",
25969 lglavg (s->travs.search, s->props.search),
25970 lglavg (s->travs.search, s->confs));
25972 "trvs: %.1f search traversals per search visit",
25973 lglavg (s->travs.search, s->visits.search));
25976 "trds: %d transitive reductions, %d removed, %d failed",
25977 s->trd.count, s->trd.red, s->trd.failed);
25979 "trds: %lld nodes, %lld edges, %lld steps",
25980 (LGLL) s->trd.lits, (LGLL) s->trd.bins, (LGLL) s->trd.steps);
25982 lglprs (lgl, "trim: %lld words, %.1f MB",
25983 (LGLL) s->trims, (s->trims * sizeof (int)) / (double)(1<<20));
25986 "trnr: %d count, %d bin, %d trn, %lld steps",
25987 s->trnr.count, s->trnr.bin, s->trnr.trn, (LGLL) s->trnr.steps);
25990 "unhd: %d count, %d rounds, %lld steps",
25991 s->unhd.count, s->unhd.rounds, (LGLL) s->unhd.steps);
25993 "unhd: %d non-trivial sccs of average size %.1f",
25994 s->unhd.stamp.sccs,
25995 lglavg (s->unhd.stamp.sumsccsizes, s->unhd.stamp.sccs));
25996 sum = lglunhdunits (lgl);
25998 "unhd: %d units, %d bin, %d trn, %d lrg",
25999 sum, s->unhd.units.bin, s->unhd.units.trn, s->unhd.units.lrg);
26000 sum = lglunhdfailed (lgl);
26002 "unhd: %d failed, %d stamp, %d lits, %d bin, %d trn, %d lrg",
26003 sum, s->unhd.stamp.failed, s->unhd.failed.lits,
26004 s->unhd.failed.bin, s->unhd.failed.trn, s->unhd.units.lrg);
26005 sum = lglunhdtauts (lgl);
26007 "unhd: %d tauts, %d bin %.0f%%, %d trn %.0f%%, %d lrg %.0f%%",
26009 s->unhd.tauts.bin, lglpcnt (s->unhd.tauts.bin, sum),
26010 s->unhd.tauts.trn, lglpcnt (s->unhd.tauts.trn, sum),
26011 s->unhd.tauts.lrg, lglpcnt (s->unhd.tauts.lrg, sum));
26013 "unhd: %d tauts, %d stamp %.0f%%, %d red %.0f%%",
26015 s->unhd.stamp.trds, lglpcnt (s->unhd.stamp.trds, sum),
26016 s->unhd.tauts.red, lglpcnt (s->unhd.tauts.red, sum));
26017 sum = lglunhdhbrs (lgl);
26019 "unhd: %d hbrs, %d trn %.0f%%, %d lrg %.0f%%, %d red %.0f%%",
26021 s->unhd.hbrs.trn, lglpcnt (s->unhd.hbrs.trn, sum),
26022 s->unhd.hbrs.lrg, lglpcnt (s->unhd.hbrs.lrg, sum),
26023 s->unhd.hbrs.red, lglpcnt (s->unhd.hbrs.red, sum));
26024 sum = lglunhdstrd (lgl);
26026 "unhd: %d str, %d bin %.0f%%, %d trn %.0f%%, %d lrg %.0f%%, %d red %.0f%%",
26028 s->unhd.units.bin, lglpcnt (s->unhd.units.bin, sum),
26029 s->unhd.str.trn, lglpcnt (s->unhd.str.trn, sum),
26030 s->unhd.str.lrg, lglpcnt (s->unhd.str.lrg, sum),
26031 s->unhd.str.red, lglpcnt (s->unhd.str.red, sum));
26033 removed = s->fixed.sum + s->elm.elmd + s->equiv.sum;
26034 remaining = lgl->maxext - removed;
26035 assert (remaining >= 0);
26037 "vars: %d remaining %.0f%% and %d removed %.0f%% out of %d",
26038 remaining, lglpcnt (remaining, lgl->maxext),
26039 removed, lglpcnt (removed, lgl->maxext), lgl->maxext);
26041 "vars: %d fixed %.0f%%, %d eliminated %.0f%%, %d equivalent %.0f%%",
26042 s->fixed.sum, lglpcnt (s->fixed.sum, lgl->maxext),
26043 s->elm.elmd, lglpcnt (s->elm.elmd, lgl->maxext),
26044 s->equiv.sum, lglpcnt (s->equiv.sum, lgl->maxext));
26046 visits = s->visits.search + s->visits.simp + s->visits.lkhd;
26048 "vsts: %lld visits, %.0f%% srch, %.0f%% simp, %.0f%% lkhd",
26049 (LGLL) visits, lglpcnt (s->visits.search, visits),
26050 lglpcnt (s->visits.simp, visits), lglpcnt (s->visits.lkhd, visits));
26052 "vsts: %.1f search visits per propagation, %.1f per conflict",
26053 lglavg (s->visits.search, s->props.search),
26054 lglavg (s->visits.search, s->confs));
26057 "wchs: %lld pushed, %lld enlarged, %d defrags",
26058 (LGLL) s->pshwchs, (LGLL) s->enlwchs, s->defrags);
26061 lglgluestats (lgl);
26067 "%lld decisions, %.1f decisions/sec",
26068 (LGLL) s->decisions, lglavg (s->decisions, t));
26070 "%lld conflicts, %.1f conflicts/sec",
26071 (LGLL) s->confs, lglavg (s->confs, t));
26073 "%lld propagations, %.1f megaprops/sec",
26074 (LGLL) p, lglavg (p/1e6, t));
26075 lglprs (lgl, "%.1f seconds, %.1f MB", t, lglmaxmb (lgl));
26079 int64_t lglgetprops (LGL * lgl) {
26080 REQINITNOTFORKED ();
26081 return lgl->stats->props.search + lgl->stats->props.simp;
26084 int64_t lglgetconfs (LGL * lgl) {
26085 REQINITNOTFORKED ();
26086 return lgl->stats->confs;
26089 int64_t lglgetdecs (LGL * lgl) {
26090 REQINITNOTFORKED ();
26091 return lgl->stats->decisions;
26094 void lglsizes (LGL * lgl) {
26095 lglprt (lgl, 0, "sizeof (int) == %ld", (long) sizeof (int));
26096 lglprt (lgl, 0, "sizeof (unsigned) == %ld", (long) sizeof (unsigned));
26097 lglprt (lgl, 0, "sizeof (void*) == %ld", (long) sizeof (void*));
26098 lglprt (lgl, 0, "sizeof (Stk) == %ld", (long) sizeof (Stk));
26099 lglprt (lgl, 0, "sizeof (Fun) == %ld", (long) sizeof (Fun));
26100 lglprt (lgl, 0, "sizeof (AVar) == %ld", (long) sizeof (AVar));
26101 lglprt (lgl, 0, "sizeof (DVar) == %ld", (long) sizeof (DVar));
26102 lglprt (lgl, 0, "sizeof (EVar) == %ld", (long) sizeof (EVar));
26103 lglprt (lgl, 0, "sizeof (Gat) == %ld", (long) sizeof (Gat));
26104 lglprt (lgl, 0, "sizeof (Stats.lir) == %ld", (long) sizeof ((Stats*)0)->lir);
26105 lglprt (lgl, 0, "sizeof (Stats) == %ld", (long) sizeof (Stats));
26106 lglprt (lgl, 0, "sizeof (LGL) == %ld", (long) sizeof (LGL));
26107 lglprt (lgl, 0, "MAXVAR == %ld", (long) MAXVAR);
26108 lglprt (lgl, 0, "MAXREDLIDX == %ld", (long) MAXREDLIDX);
26109 lglprt (lgl, 0, "MAXIRRLIDX == %ld", (long) MAXIRRLIDX);
26112 #define LGLRELSTK(MGR,STKPTR) \
26114 assert (lglmtstk (STKPTR)); \
26115 lglrelstk ((MGR), (STKPTR)); \
26118 void lglrelease (LGL * lgl) {
26119 lgldealloc dealloc;
26123 if (lgl->clone) lglrelease (lgl->clone), lgl->clone = 0;
26126 #ifndef NLGLDRUPLIG
26127 if (lgl->druplig) druplig_reset (lgl->druplig), lgl->druplig = 0;
26130 // Heap state starts here:
26132 DEL (lgl->avars, lgl->szvars);
26133 DEL (lgl->doms, 2*lgl->szvars);
26134 DEL (lgl->drail, lgl->szdrail);
26135 DEL (lgl->dvars, lgl->szvars);
26136 DEL (lgl->ext, lgl->szext);
26137 DEL (lgl->i2e, lgl->szvars);
26138 DEL (lgl->jwh, 2*lgl->szvars);
26139 DEL (lgl->qvars, lgl->szvars);
26140 DEL (lgl->vals, lgl->szvars);
26142 lglrelctk (lgl, &lgl->control);
26144 lglrelstk (lgl, &lgl->assume);
26145 lglrelstk (lgl, &lgl->cassume);
26146 lglrelstk (lgl, &lgl->clause);
26147 lglrelstk (lgl, &lgl->dsched);
26148 lglrelstk (lgl, &lgl->eassume);
26149 lglrelstk (lgl, &lgl->eclause);
26150 lglrelstk (lgl, &lgl->extend);
26151 lglrelstk (lgl, &lgl->fassume);
26152 lglrelstk (lgl, &lgl->learned);
26153 lglrelstk (lgl, &lgl->frames);
26154 lglrelstk (lgl, &lgl->trail);
26155 lglrelstk (lgl, &lgl->wchs->stk);
26158 lglrelstk (lgl, &lgl->orig);
26161 lglrelstk (lgl, &lgl->irr);
26162 for (i = 0; i <= MAXGLUE; i++) lglrelstk (lgl, &lgl->red[i]);
26164 // The following heap allocated memory has no state:
26166 LGLRELSTK (lgl, &lgl->lcaseen);
26167 LGLRELSTK (lgl, &lgl->minstk);
26168 LGLRELSTK (lgl, &lgl->poisoned);
26169 LGLRELSTK (lgl, &lgl->seen);
26171 DEL (lgl->limits, 1);
26172 DEL (lgl->times, 1);
26173 DEL (lgl->timers, 1);
26174 DEL (lgl->red, MAXGLUE+1);
26175 DEL (lgl->wchs, 1);
26177 if (lgl->fltstr) DEL (lgl->fltstr, 1);
26178 if (lgl->cbs) DEL (lgl->cbs, 1); // next to last
26179 lgldelstr (lgl, lgl->prefix); // last
26181 // adjust upfront the mem counters ...
26183 lgldec (lgl, sizeof *lgl->stats);
26184 lgldec (lgl, sizeof *lgl->opts);
26185 lgldec (lgl, sizeof *lgl->mem);
26186 lgldec (lgl, sizeof *lgl);
26188 assert (getenv ("LGLEAK") || !lgl->stats->bytes.current);
26190 if (lgl->closeapitrace == 1) fclose (lgl->apitrace);
26191 if (lgl->closeapitrace == 2) pclose (lgl->apitrace);
26194 #ifndef NLGLPICOSAT
26195 if (lgl->picosat.solver) {
26196 if (lgl->opts->verbose.val > 0 && lgl->opts->check.val > 0)
26197 picosat_stats (PICOSAT);
26198 picosat_reset (PICOSAT);
26199 lgl->picosat.solver = 0;
26204 if ((dealloc = lgl->mem->dealloc)) {
26205 void * memstate = lgl->mem->state;
26206 if (lgl->stats) dealloc (memstate, lgl->stats, sizeof *lgl->stats);
26207 if (lgl->times) dealloc (memstate, lgl->times, sizeof *lgl->times);
26208 if (lgl->opts) dealloc (memstate, lgl->opts, sizeof *lgl->opts);
26210 dealloc (memstate, lgl->mem, sizeof *lgl->mem);
26211 dealloc (memstate, lgl, sizeof *lgl);
26221 void lglutrav (LGL * lgl, void * state, void (*trav)(void *, int)) {
26223 REQINITNOTFORKED ();
26224 if (!lgl->mt && !lglbcp (lgl)) lgl->mt = 1;
26225 if (!lgl->mt) lglgc (lgl);
26226 if (lgl->mt) return;
26227 if (lgl->level > 0) lglbacktrack (lgl, 0);
26228 for (elit = 1; elit <= lgl->maxext; elit++) {
26229 if (!(val = lglefixed (lgl, elit))) continue;
26230 trav (state, (val < 0) ? -elit : elit);
26234 void lgletrav (LGL * lgl, void * state, void (*trav)(void *, int, int)) {
26236 REQINITNOTFORKED ();
26237 if (!lgl->mt && !lglbcp (lgl)) lgl->mt = 1;
26238 if (!lgl->mt) lglgc (lgl);
26239 if (lgl->mt) return;
26240 if (lgl->level > 0) lglbacktrack (lgl, 0);
26241 for (elit = 1; elit <= lgl->maxext; elit++) {
26242 if (lglefixed (lgl, elit)) continue;
26243 erepr = lglerepr (lgl, elit);
26244 if (erepr == elit) continue;
26245 trav (state, elit, erepr);
26249 static void lglictrav (LGL * lgl, int internal,
26250 void * state, void (*trav)(void *, int)) {
26251 int idx, sign, lit, blit, tag, red, other, other2;
26252 const int * p, * w, * eow, * c;
26254 REQINITNOTFORKED ();
26255 if (lgl->level > 0) lglbacktrack (lgl, 0);
26256 if (!lgl->mt && !lglbcp (lgl)) lgl->mt = 1;
26257 if (!lgl->mt) lglgc (lgl);
26258 if (lgl->mt) { trav (state, 0); return; }
26259 for (idx = 2; idx < lgl->nvars; idx++)
26260 for (sign = -1; sign <= 1; sign += 2) {
26262 assert (!lglval (lgl, lit));
26263 hts = lglhts (lgl, lit);
26264 w = lglhts2wchs (lgl, hts);
26265 eow = w + hts->count;
26266 for (p = w; p < eow; p++) {
26268 tag = blit & MASKCS;
26269 red = blit & REDCS;
26270 if (tag == TRNCS || tag == LRGCS) p++;
26272 if (tag != BINCS && tag != TRNCS) continue;
26273 other = blit >> RMSHFT;
26274 if (abs (other) < idx) continue;
26275 assert (!lglval (lgl, other));
26276 if (tag == TRNCS) {
26278 if (abs (other2) < idx) continue;
26279 assert (!lglval (lgl, other2));
26281 trav (state, internal ? lit : lglexport (lgl, lit));
26282 trav (state, internal ? other : lglexport (lgl, other));
26283 if (other2) trav (state, internal ? other2 : lglexport (lgl, other2));
26287 for (c = lgl->irr.start; c < lgl->irr.top; c = p + 1) {
26289 if (*p >= NOTALIT) continue;
26290 while ((other = *p)) {
26291 assert (!lglval (lgl, other));
26292 trav (state, internal ? other : lglexport (lgl, other));
26299 void lglctrav (LGL * lgl, void * state, void (*trav)(void *, int)) {
26300 lglictrav (lgl, 0, state, trav);
26303 static void lgltravcounter (void * voidptr, int lit) {
26304 int * cntptr = voidptr;
26305 if (!lit) *cntptr += 1;
26308 static void lgltravprinter (void * voidptr, int lit) {
26309 FILE * out = voidptr;
26310 if (lit) fprintf (out, "%d ", lit);
26311 else fprintf (out, "0\n");
26314 void lglprint (LGL * lgl, FILE * file) {
26316 lglctrav (lgl, &count, lgltravcounter);
26317 fprintf (file, "p cnf %d %d\n", lglmaxvar (lgl), count);
26318 lglctrav (lgl, file, lgltravprinter);
26321 void lglprintall (LGL * lgl, FILE * file) {
26323 lgltravall (lgl, &count, lgltravcounter);
26324 fprintf (file, "p cnf %d %d\n", lglmaxvar (lgl), count);
26325 lgltravall (lgl, file, lgltravprinter);
26328 void lglrtrav (LGL * lgl, void * state, void (*trav)(void *, int, int)) {
26329 int idx, sign, lit, blit, tag, red, other, other2, glue;
26330 const int * p, * c, * w, * eow;
26333 REQINITNOTFORKED ();
26334 if (lgl->mt) return;
26336 if (lgl->level > 0) lglbacktrack (lgl, 0);
26337 for (idx = 2; idx < lgl->nvars; idx++) {
26338 if (lglval (lgl, idx)) continue;
26339 for (sign = -1; sign <= 1; sign += 2) {
26341 hts = lglhts (lgl, lit);
26342 w = lglhts2wchs (lgl, hts);
26343 eow = w + hts->count;
26344 for (p = w; p < eow; p++) {
26346 tag = blit & MASKCS;
26347 red = blit & REDCS;
26348 if (tag == TRNCS || tag == LRGCS) p++;
26349 if (!red) continue;
26350 if (tag != BINCS && tag != TRNCS) continue;
26351 other = blit >> RMSHFT;
26352 if (abs (other) < idx) continue;
26353 assert (!lglval (lgl, other));
26354 if (tag == TRNCS) {
26356 if (abs (other2) < idx) continue;
26357 assert (!lglval (lgl, other2));
26359 trav (state, lglexport (lgl, lit), 0);
26360 trav (state, lglexport (lgl, other), 0);
26361 if (other2) trav (state, lglexport (lgl, other2), 0);
26362 trav (state, 0, 0);
26366 for (glue = 0; glue < MAXGLUE; glue++) {
26367 lir = lgl->red + glue;
26368 for (c = lir->start; c < lir->top; c = p + 1) {
26370 if (*p >= NOTALIT) continue;
26371 while ((other = *p)) {
26372 assert (!lglval (lgl, other));
26373 trav (state, lglexport (lgl, other), 0);
26376 trav (state, 0, 0);
26381 static void lgltravallu (void * voidptr, int unit) {
26382 Trv * state = voidptr;
26383 state->trav (state->state, unit);
26384 state->trav (state->state, 0);
26387 static void lgltravalle (void * voidptr, int lit, int repr) {
26388 Trv * state = voidptr;
26389 state->trav (state->state, -lit);
26390 state->trav (state->state, repr);
26391 state->trav (state->state, 0);
26392 state->trav (state->state, lit);
26393 state->trav (state->state, -repr);
26394 state->trav (state->state, 0);
26397 void lgltravall (LGL * lgl, void * state, void (*trav)(void *, int)) {
26399 travstate.state = state;
26400 travstate.trav = trav;
26401 lglutrav (lgl, &travstate, lgltravallu);
26402 lgletrav (lgl, &travstate, lgltravalle);
26403 lglctrav (lgl, state, trav);
26408 void lgldump (LGL * lgl) {
26409 int idx, sign, lit, blit, tag, red, other, other2, glue;
26410 const int * p, * w, * eow, * c, * top;
26413 for (idx = 2; idx < lgl->nvars; idx++)
26414 for (sign = -1; sign <= 1; sign += 2) {
26416 hts = lglhts (lgl, lit);
26417 w = lglhts2wchs (lgl, hts);
26418 eow = w + hts->count;
26419 for (p = w; p < eow; p++) {
26421 tag = blit & MASKCS;
26422 red = blit & REDCS;
26423 if (tag == TRNCS || tag == LRGCS) p++;
26424 if (tag == BINCS) {
26425 other = blit >> RMSHFT;
26426 if (abs (other) < idx) continue;
26428 } else if (tag == TRNCS) {
26429 other = blit >> RMSHFT;
26430 if (abs (other) < idx) continue;
26432 if (abs (other2) < idx) continue;
26434 fprintf (lgl->out, "%s %d %d", red ? "red" : "irr", lit, other);
26435 if (tag == TRNCS) fprintf (lgl->out, " %d", other2);
26436 fprintf (lgl->out, "\n");
26439 top = lgl->irr.top;
26440 for (c = lgl->irr.start; c < top; c = p + 1) {
26442 if (*p >= NOTALIT) continue;
26443 fprintf (lgl->out, "irr");
26444 while (*p) fprintf (lgl->out, " %d", *p++);
26445 fprintf (lgl->out, "\n");
26447 for (glue = 0; glue < MAXGLUE; glue++) {
26448 lir = lgl->red + glue;
26450 for (c = lir->start; c < top; c = p + 1) {
26452 if (*p >= NOTALIT) continue;
26453 fprintf (lgl->out, "glue%d", glue);
26454 while (*p) fprintf (lgl->out, " %d", *p++);
26455 fprintf (lgl->out, "\n");
26462 static void lglforkadd (void * ptr, int lit) {
26463 lgladd (ptr, lit ? lglforklit (lit) : 0);
26466 LGL * lglfork (LGL * parent) {
26469 LGL * lgl = parent;
26471 ABORTIF (!lglmtstk (&parent->eassume), "can not fork under assumptions");
26472 ABORTIF (parent->forked == INT_MAX, "parent forked too often");
26474 if (parent->level > 0) lglbacktrack (parent, 0);
26475 (void) lglbcp (parent);
26477 child = lglminit (parent->mem->state,
26478 parent->mem->alloc,
26479 parent->mem->realloc,
26480 parent->mem->dealloc);
26481 child->parent = parent;
26482 memcpy (child->opts, parent->opts, sizeof *parent->opts);
26483 lglcopyclonenfork (child, parent);
26484 lglictrav (parent, 1, child, lglforkadd);
26485 assert (parent->stats->irr.clauses.cur == child->stats->irr.clauses.cur);
26487 assert (parent->forked > 0);
26488 lglprt (parent, 1, "forked-%d", parent->forked);
26492 static void lglflass (LGL * lgl, LGL * from) {
26493 int idx, copied = 0;
26494 assert (!lgl->level), assert (!lgl->mt);
26495 assert ((from->state & (SATISFIED | EXTENDED)));
26496 if (lgl->nvars) assert (lgl->nvars == from->maxext + 2);
26497 else assert (!from->maxext);
26499 for (idx = 2; idx < lgl->nvars; idx++) {
26500 int val = lglderef (from, idx-1);
26501 int lit = val < 0 ? -idx : idx;
26502 lgldassume (lgl, lit);
26505 lglprt (lgl, 1, "[flass] copied %d internal assignments", copied);
26511 #ifndef NLGLPICOSAT
26512 lglpicosatchksol (lgl);
26516 int lgljoin (LGL * parent, LGL * child) {
26519 LGL * lgl = parent;
26520 ABORTIF (!parent, "uninitialized parent manager");
26521 ABORTIF (!child, "uninitialized child manager");
26522 ABORTIF (!parent->forked, "parent manager not forked");
26523 ABORTIF (!child->parent, "child manager has not parent");
26524 ABORTIF (child->parent != parent, "child manager has different parent");
26525 ABORTIF (!lglmtstk (&child->eassume),
26526 "child manager with assumptions not supported yet");
26528 if (child->mt || (child->state & UNSATISFIED)) {
26530 LGL * lgl = parent;
26532 assert (child->mt); // no assumptions yet ...
26533 lglprt (parent, 1, "[join] unsatisfied state");
26535 LOG (1, "joining empty clause");
26537 } else LOG (1, "no need to join empty clause since parent has one");
26539 } else if (child->state & (SATISFIED | EXTENDED)) {
26540 lglprt (parent, 1, "[join] satisfied state");
26541 lglflass (parent, child);
26544 lglprt (parent, 1, "[join] unknown state");
26547 LGL * lgl = parent;