PageRenderTime 97ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 1ms

/precosat.cc

https://github.com/damelang/precosat
C++ | 4619 lines | 4292 code | 285 blank | 42 comment | 1877 complexity | b1229db92acdb3e22002814499f67276 MD5 | raw file
  1. /***************************************************************************
  2. Copyright (c) 2009, Armin Biere, Johannes Kepler University.
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to
  5. deal in the Software without restriction, including without limitation the
  6. rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  7. sell copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  16. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  17. IN THE SOFTWARE.
  18. ****************************************************************************/
  19. #include "precosat.hh"
  20. #include "precobnr.hh"
  21. #include <cstdio>
  22. #include <cstring>
  23. #include <cstdarg>
  24. extern "C" {
  25. #include <ctype.h>
  26. #include <sys/time.h>
  27. #include <sys/resource.h>
  28. #include <sys/unistd.h>
  29. #if !defined(__APPLE__)
  30. #include <malloc.h>
  31. #endif
  32. #include <unistd.h>
  33. };
  34. #ifndef NLOGPRECO
  35. #include <iostream>
  36. #define LOG(code) \
  37. do { std::cout << prfx << "LOG " << code << std::endl; } while (false)
  38. #else
  39. #define LOG(code) do { } while (false)
  40. #endif
  41. #if 0
  42. #include <iostream>
  43. #define COVER(code) \
  44. do { std::cout << prfx << "COVER " << __FUNCTION__ << ' ' \
  45. << __LINE__ << ' ' << code << std::endl; } while (false)
  46. #else
  47. #define COVER(code) do { } while (false)
  48. #endif
  49. //#define PRECOCHECK
  50. #ifdef PRECOCHECK
  51. #warning "PRECOCHECK enabled"
  52. #endif
  53. #ifndef NSTATSPRECO
  54. #define INC(s) do { stats.s++; } while (0)
  55. #else
  56. #define INC(s) do { } while (0)
  57. #endif
  58. namespace PrecoSat {
  59. template<class T> inline static void swap (T & a, T & b)
  60. { T tmp = a; a = b; b = tmp; }
  61. template<class T> inline static const T min (const T a, const T b)
  62. { return a < b ? a : b; }
  63. template<class T> inline static const T max (const T a, const T b)
  64. { return a > b ? a : b; }
  65. template<class T> inline static void fix (T * & p, long moved)
  66. { char * q = (char*) p; q += moved; p = (T*) q; }
  67. inline static int logsize (int size) { return (128 >> size) + 1; }
  68. static inline Val lit2val (int lit) { return (lit & 1) ? -1 : 1; }
  69. static inline Cls * lit2conflict (Cls & bins, int a, int b) {
  70. bins.lits[0] = a;
  71. bins.lits[1] = b;
  72. assert (!bins.lits[2]);
  73. return &bins;
  74. }
  75. static inline unsigned ggt (unsigned a, unsigned b)
  76. { while (b) { unsigned r = a % b; a = b, b = r; } return a; }
  77. inline static unsigned minuscap (unsigned a, unsigned b)
  78. { return (a <= b) ? 0 : (a - b); }
  79. static inline double mb (size_t bytes)
  80. { return bytes / (double) (1<<20); }
  81. static inline bool sigsubs (unsigned s, unsigned t)
  82. { return !(s&~t); }
  83. static inline unsigned listig (int lit)
  84. { return (1u << (31u & (unsigned)(lit/2))); }
  85. static inline double average (double a, double b) { return b ? a/b : 0; }
  86. static inline double percent (double a, double b) { return 100*average(a,b); }
  87. static bool parity (unsigned x)
  88. { bool res = false; while (x) res = !res, x &= x-1; return res; }
  89. }
  90. using namespace PrecoSat;
  91. inline unsigned RNG::next () {
  92. unsigned res = state;
  93. state *= 1664525u;
  94. state += 1013904223u;
  95. return res;
  96. }
  97. inline bool RNG::oneoutof (unsigned spread) {
  98. return spread ? !(next () % spread) : true;
  99. }
  100. inline size_t Cls::bytes (int n) {
  101. return sizeof (Cls) + (n - 3 + 1) * sizeof (int);
  102. }
  103. inline size_t Cls::bytes () const { return bytes (size); }
  104. inline Anchor<Cls> & Solver::anchor (Cls * c) {
  105. if (c->binary) return binary;
  106. if (!c->lnd) return original;
  107. if (c->fresh) return fresh;
  108. return learned[c->glue];
  109. }
  110. inline int Cls::minlit () const {
  111. int res = INT_MAX, other;
  112. for (const int * p = lits; (other = *p); p++)
  113. if (other < res) res = other;
  114. return res;
  115. }
  116. inline bool Cls::contains (int lit) const {
  117. if (!(sig & listig (lit))) return false;
  118. for (const int * p = lits; *p; p++)
  119. if (*p == lit) return true;
  120. return false;
  121. }
  122. inline void Solver::setsig (Cls * cls) {
  123. int except = cls->minlit (), lit;
  124. unsigned fwsig = 0, bwsig = 0;
  125. for (const int * p = cls->lits; (lit = *p); p++) {
  126. unsigned sig = listig (lit);
  127. bwsig |= sig;
  128. if (lit != except) fwsig |= sig;
  129. }
  130. cls->sig = bwsig;
  131. for (const int * p = cls->lits; (lit = *p); p++)
  132. bwsigs[lit] |= bwsig;
  133. if (fwsigs)
  134. fwsigs[except] |= fwsig;
  135. }
  136. inline unsigned Solver::litsig () {
  137. unsigned res = 0;
  138. for (int i = 0; i < lits; i++)
  139. res |= listig (lits[i]);
  140. return res;
  141. }
  142. inline bool Solver::clt (int a, int b) const {
  143. Var & u = vars[a/2], &v = vars[b/2];
  144. int l = u.dlevel, k = v.dlevel;
  145. if (l < 0) return false;
  146. if (k < 0) return true;
  147. if (l < k) return true;
  148. if (l > k) return false;
  149. Val r = vals[a], s = vals[b];
  150. if (r < s) return true;
  151. return false;
  152. }
  153. inline void Solver::connect (Cls * c) {
  154. for (int i = 0; i <= 1; i++) {
  155. int lit, * r = c->lits + i, * q = r, best = *q;
  156. for (int * p = q + 1; (lit = *p); p++)
  157. if (clt (best, lit)) q = p, best = lit;
  158. *q = *r, *r = best;
  159. }
  160. assert (c->lits[0] && c->lits[1]);
  161. Anchor<Cls> & a = anchor (c);
  162. if (!connected (a, c)) push (a, c);
  163. if (c->binary) {
  164. for (int i = 0; i <= 1; i++)
  165. occs[c->lits[i]].bins.push (mem, c->lits[!i]);
  166. } else {
  167. for (int i = 0; i <= 1; i++)
  168. occs[c->lits[i]].large.push (mem, Occ (c->lits[!i], c));
  169. }
  170. if (orgs)
  171. for (const int * p = c->lits; *p; p++)
  172. orgs[*p].push (mem, c);
  173. if (fwds) fwds[c->minlit ()].push (mem, c);
  174. setsig (c);
  175. }
  176. inline void Solver::disconnect (Cls * c) {
  177. assert (!c->locked && !c->dirty && !c->trash);
  178. int l0 = c->lits[0], l1 = c->lits[1];
  179. assert (l0 && l1);
  180. Anchor<Cls> & a = anchor (c);
  181. if (connected (a, c)) dequeue (a, c);
  182. if (c->binary) {
  183. occs[l0].bins.remove(l1);
  184. occs[l1].bins.remove(l0);
  185. } else {
  186. occs[l0].large.remove(Occ(0,c));
  187. occs[l1].large.remove(Occ(0,c));
  188. }
  189. if (fwds) fwds[c->minlit ()].remove (c);
  190. if (!orgs || c->lnd) return;
  191. for (const int * p = c->lits; *p; p++)
  192. orgs[*p].remove (c);
  193. }
  194. inline Rnk * Solver::prb (const Rnk * r) { return prbs + (r - rnks); }
  195. inline Rnk * Solver::rnk (const Var * v) { return rnks + (v - vars); }
  196. inline Var * Solver::var (const Rnk * r) { return vars + (r - rnks); }
  197. inline Val Solver::fixed (int lit) const {
  198. return vars[lit/2].dlevel ? 0 : vals[lit];
  199. }
  200. inline void Solver::collect (Cls * cls) {
  201. assert (!cls->locked && !cls->dirty && !cls->trash && !cls->gate);
  202. if (cls->binary) assert (stats.clauses.bin), stats.clauses.bin--;
  203. else if (cls->lnd) assert (stats.clauses.lnd), stats.clauses.lnd--;
  204. else assert (stats.clauses.orig), stats.clauses.orig--;
  205. if (!cls->lnd) assert (stats.clauses.irr), stats.clauses.irr--;
  206. size_t bytes = cls->bytes ();
  207. #ifdef PRECOCHECK
  208. if (!cls->lnd) {
  209. for (const int * p = cls->lits; *p; p++)
  210. check.push (mem, *p);
  211. check.push (mem, 0);
  212. }
  213. #endif
  214. #ifndef NLOGPRECO
  215. dbgprint ("LOG recycle clause ", cls);
  216. #endif
  217. mem.deallocate (cls, bytes);
  218. stats.collected += bytes;
  219. simplified = true;
  220. }
  221. void Solver::touchblkd (int lit) {
  222. assert (blkmode);
  223. int idx = lit/2, notlit = lit^1;
  224. Var * v = vars + idx;
  225. if (v->type != FREE) return;
  226. assert (!val (lit) && !repr[lit]);
  227. Rnk * r = blks + notlit;
  228. assert (orgs);
  229. int nh = -orgs[lit], oh = r->heat; r->heat = nh;
  230. if (oh == nh && schedule.block.contains (r)) return;
  231. if (oh == nh) LOG ("touchblkd " << notlit << " again " << nh);
  232. else LOG ("touchblkd " << notlit << " from " << oh << " to " << nh);
  233. if (!schedule.block.contains (r)) schedule.block.push (mem, r);
  234. else if (nh > oh) schedule.block.up (r);
  235. else if (nh < oh) schedule.block.down (r);
  236. }
  237. void Solver::touchelim (int lit) {
  238. assert (elimode);
  239. lit &= ~1;
  240. int idx = lit/2;
  241. Var * v = vars + idx;
  242. if (v->type != FREE) return;
  243. assert (!val (lit) && !repr[lit]);
  244. if (idx == elimvar) return;
  245. Rnk * r = elms + idx;
  246. assert (orgs);
  247. int pos = orgs[lit];
  248. int neg = orgs[1^lit];
  249. long long tmp = -(((long long)pos) * (long long) neg);
  250. int nh = (tmp >= INT_MIN) ? (int) tmp : INT_MIN;
  251. int oh = r->heat; r->heat = nh;
  252. if (oh == nh && schedule.elim.contains (r)) return;
  253. if (oh == nh) LOG ("touchelim " << lit << " again " << nh);
  254. else LOG ("touchelim " << lit << " from " << oh << " to " << nh);
  255. if (pos > 1 && neg > 1 && nh <= opts.elimin) {
  256. if (schedule.elim.contains (r)) {
  257. schedule.elim.remove (r);
  258. }
  259. } else if (!schedule.elim.contains (r)) schedule.elim.push (mem, r);
  260. else if (nh > oh) schedule.elim.up (r);
  261. else if (nh < oh) schedule.elim.down (r);
  262. }
  263. void Solver::touchpure (int lit) {
  264. assert (puremode);
  265. int idx = lit/2;
  266. Var * v = vars + idx;
  267. if (v->onplits) return;
  268. LOG ("touchpure " << lit);
  269. v->onplits = true;
  270. plits.push (mem, idx);
  271. }
  272. void Solver::touch (int lit) {
  273. assert (elimode + blkmode == 1);
  274. if (elimode) touchelim (lit);
  275. else touchblkd (lit);
  276. if (puremode) touchpure (lit);
  277. }
  278. void Solver::touch (Cls * c) {
  279. assert (asymode || !c->lnd);
  280. assert (elimode || blkmode);
  281. for (int * p = c->lits; *p; p++)
  282. touch (*p);
  283. }
  284. inline void Solver::recycle (Cls * c) {
  285. stats.clauses.gc++;
  286. disconnect (c);
  287. if (c->trash) trash.remove (c);
  288. if (c->gate) cleangate ();
  289. if (c->str) strnd.remove (c);
  290. if (elimode || blkmode) touch (c);
  291. collect (c);
  292. }
  293. inline void Solver::dump (Cls * c) {
  294. assert (!c->dirty);
  295. if (c->trash) return;
  296. c->trash = true;
  297. trash.push (mem, c);
  298. }
  299. inline void Solver::cleantrash () {
  300. if (!trash) return;
  301. int old = stats.clauses.orig;
  302. while (trash) {
  303. Cls * cls = trash.pop ();
  304. assert (cls->trash);
  305. cls->trash = false;
  306. recycle (cls);
  307. }
  308. shrink (old);
  309. }
  310. inline void Solver::gcls (Cls * c) {
  311. assert (!c->gate);
  312. c->gate = true;
  313. gate.push (mem, c);
  314. }
  315. inline void Solver::strcls (Cls * c) {
  316. assert (!c->str);
  317. c->str = true;
  318. strnd.push (mem, c);
  319. }
  320. inline void Solver::cleangate () {
  321. while (gate) {
  322. Cls * cls = gate.pop ();
  323. assert (cls->gate); cls->gate = false;
  324. }
  325. gatepivot = 0;
  326. gatestats = 0;
  327. gatelen = 0;
  328. }
  329. inline void Solver::recycle (int lit) {
  330. LOG ("recycle literal " << lit);
  331. assert (!level);
  332. #ifndef NDEBUG
  333. Var * v = vars + (lit/2); Vrt t = v->type;
  334. assert (t == FIXED || t == PURE || t == ZOMBIE || t == ELIM);
  335. #endif
  336. if (!orgs) return;
  337. while (int size = orgs[lit]) recycle (orgs[lit][size - 1]);
  338. orgs[lit].release (mem);
  339. occs[lit].bins.release (mem);
  340. occs[lit].large.release (mem);
  341. }
  342. Opt::Opt (const char * n, int v, int * vp, int mi, int ma) :
  343. name (n), valptr (vp), min (mi), max (ma)
  344. {
  345. assert (min <= v);
  346. assert (v <= max);
  347. *vp = v;
  348. }
  349. bool Opts::set (const char * opt, int val) {
  350. for (Opt * o = opts.begin (); o < opts.end (); o++)
  351. if (!strcmp (o->name, opt)) {
  352. if (val < o->min) return false;
  353. if (val > o->max) return false;
  354. *o->valptr = val;
  355. return true;
  356. }
  357. return false;
  358. }
  359. bool Opts::set (const char * opt, const char * val) {
  360. if (strcmp (opt, "output")) return false;
  361. output = val;
  362. return true;
  363. }
  364. void Opts::add (Mem & mem, const char * n, int v, int * vp, int mi, int ma) {
  365. opts.push (mem, Opt (n, v, vp, mi, ma));
  366. }
  367. void Opts::printoptions (FILE * file, const char * prfx) const {
  368. assert (prfx);
  369. int lenprfx = strlen (prfx);
  370. fputs (prfx, file); int pos = 0;
  371. const Opt * o = opts.begin ();
  372. while (o < opts.end ()) {
  373. char line[80];
  374. sprintf (line, " --%s=%d", o->name, *o->valptr);
  375. int len = strlen (line); assert (len < 80);
  376. if (len + pos >= 77 - lenprfx) {
  377. fprintf (file, "\n%s", prfx);
  378. pos = lenprfx;
  379. }
  380. fputs (line, file);
  381. pos += len;
  382. o++;
  383. }
  384. fputc ('\n', file);
  385. if (output)
  386. fprintf (file, "%s\n%s --output=%s\n", prfx, prfx, output);
  387. }
  388. void Solver::initbwsigs () {
  389. assert (!bwsigs);
  390. size_t bytes = 2 * size * sizeof *bwsigs;
  391. bwsigs = (unsigned*) mem.callocate (bytes);
  392. }
  393. void Solver::rszbwsigs (int newsize) {
  394. assert (bwsigs);
  395. size_t old_bytes = 2 * size * sizeof *bwsigs;
  396. size_t new_bytes = 2 * newsize * sizeof *bwsigs;
  397. bwsigs = (unsigned*) mem.recallocate (bwsigs, old_bytes, new_bytes);
  398. }
  399. void Solver::clrbwsigs () {
  400. size_t bytes = 2 * size * sizeof *bwsigs;
  401. memset (bwsigs, 0, bytes);
  402. }
  403. void Solver::delbwsigs () {
  404. size_t bytes = 2 * size * sizeof *bwsigs;
  405. mem.deallocate (bwsigs, bytes);
  406. bwsigs = 0;
  407. }
  408. void Solver::initorgs () {
  409. size_t bytes = 2 * (maxvar + 1) * sizeof *orgs;
  410. orgs = (Orgs*) mem.callocate (bytes);
  411. }
  412. void Solver::delorgs () {
  413. for (int lit = 2; lit <= 2*maxvar+1; lit++) orgs[lit].release (mem);
  414. size_t bytes = 2 * (maxvar + 1) * sizeof *orgs;
  415. mem.deallocate (orgs, bytes);
  416. orgs = 0;
  417. }
  418. void Solver::initfwds () {
  419. size_t bytes = 2 * (maxvar + 1) * sizeof *fwds;
  420. fwds = (Fwds*) mem.callocate (bytes);
  421. }
  422. void Solver::delfwds () {
  423. for (int lit = 2; lit <= 2*maxvar+1; lit++) fwds[lit].release (mem);
  424. size_t bytes = 2 * (maxvar + 1) * sizeof *fwds;
  425. mem.deallocate (fwds, bytes);
  426. fwds = 0;
  427. }
  428. void Solver::initfwsigs () {
  429. assert (!fwsigs);
  430. size_t bytes = 2 * (maxvar + 1) * sizeof *fwsigs;
  431. fwsigs = (unsigned*) mem.callocate (bytes);
  432. }
  433. void Solver::delfwsigs () {
  434. size_t bytes = 2 * (maxvar + 1) * sizeof *fwsigs;
  435. mem.deallocate (fwsigs, bytes);
  436. fwsigs = 0;
  437. }
  438. void Solver::initprfx (const char * newprfx) {
  439. prfx = (char*) mem.allocate (strlen (newprfx) + 1);
  440. strcpy (prfx, newprfx);
  441. }
  442. void Solver::delprfx () {
  443. assert (prfx);
  444. mem.deallocate (prfx, strlen (prfx) + 1);
  445. }
  446. #define OPT(n,v,mi,ma) \
  447. do { opts.add (mem, # n, v, &opts.n, mi, ma); } while (0)
  448. void Solver::initerm (void) {
  449. terminal = (out == stdout) && isatty(1);
  450. }
  451. void Solver::init (int initialmaxvar)
  452. {
  453. maxvar = initialmaxvar;
  454. size = 1;
  455. while (maxvar >= size)
  456. size *= 2;
  457. queue = 0;
  458. queue2 = 0;
  459. level = 0;
  460. conflict = 0;
  461. hinc = 128;
  462. agility = 0;
  463. typecount = 1;
  464. lastype = 0;
  465. out = stdout;
  466. initerm ();
  467. measure = true;
  468. iterating = false;
  469. elimode = false;
  470. blkmode = false;
  471. puremode = false;
  472. asymode = false;
  473. extending = false;
  474. assert (!initialized);
  475. vars = (Var*) mem.callocate (size * sizeof *vars);
  476. for (int i = 1; i <= maxvar; i++)
  477. vars[i].dlevel = -1;
  478. iirfs = 0;
  479. repr = (int*) mem.callocate (2 * size * sizeof *repr);
  480. jwhs = (int*) mem.callocate (2 * size * sizeof *jwhs);
  481. vals = (Val*) mem.callocate (2 * size * sizeof *vals);
  482. occs = (Occs*) mem.callocate (2 * size * sizeof *occs);
  483. rnks = (Rnk*) mem.allocate (size * sizeof *rnks);
  484. prbs = (Rnk*) mem.allocate (size * sizeof *prbs);
  485. elms = (Rnk*) mem.allocate (size * sizeof *elms);
  486. blks = (Rnk*) mem.allocate (2 * size * sizeof *blks);
  487. for (Rnk * p = rnks + maxvar; p > rnks; p--)
  488. p->heat = 0, p->pos = -1, schedule.decide.push (mem, p);
  489. for (Rnk * p = prbs + maxvar; p > prbs; p--) p->heat = 0, p->pos = -1;
  490. for (Rnk * p = elms + maxvar; p > elms; p--) p->heat = 0, p->pos = -1;
  491. for (Rnk * p = blks + 2*maxvar+1; p > blks+1; p--) p->heat = 0, p->pos = -1;
  492. bwsigs = 0;
  493. initbwsigs ();
  494. orgs = 0;
  495. fwds = 0;
  496. fwsigs = 0;
  497. frames.push (mem, Frame (trail));
  498. empty.lits[0] = 0;
  499. dummy.lits[2] = 0;
  500. int m = INT_MIN, M = INT_MAX;
  501. OPT (plain,0,0,1);
  502. OPT (rtc,0,0,2);
  503. OPT (quiet,0,0,1);
  504. OPT (verbose,0,0,2);
  505. OPT (print,0,0,1);
  506. OPT (check,0,0,2);
  507. OPT (order,3,1,9);
  508. OPT (simprd,20,0,M); OPT (simpinc,26,0,100); OPT (simprtc,0,0,2);
  509. OPT (merge,1,0,1);
  510. OPT (dominate,1,0,1);
  511. OPT (maxdoms,5*1000*1000,0,M);
  512. OPT (otfs,1,0,1);
  513. OPT (block,1,0,1);
  514. OPT (blockrtc,0,0,2); OPT (blockimpl,1,0,1);
  515. OPT (blockprd,10,1,M); OPT (blockint,300*1000,0,M);
  516. OPT (blockotfs,1,0,1);
  517. OPT (blockreward,100,0,10000);
  518. OPT (blockboost,3,0,100);
  519. OPT (heatinc,10,0,100);
  520. OPT (luby,1,0,1);
  521. OPT (restart,1,0,1); OPT (restartint,100,1,M);
  522. OPT (restartinner,10,0,1000); OPT (restartouter,10,0,1000);
  523. OPT (rebias,1,0,1); OPT (rebiasint,1000,1,M);
  524. OPT (probe,1,0,1);
  525. OPT (probeint,100*1000,1000,M); OPT (probeprd,10,1,M);
  526. OPT (probertc,0,0,2); OPT (probereward,2000,0,10000);
  527. OPT (probeboost,5,0,10000);
  528. OPT (decompose,1,0,1);
  529. OPT (inverse,0,0,1); OPT (inveager,0,0,1);
  530. OPT (mtfall,0,0,1); OPT (mtfrev,1,0,1);
  531. OPT (bumpuip,1,0,1);
  532. OPT (bumpsort,1,0,1); OPT (bumprev,1,0,1);
  533. OPT (bumpturbo,0,0,1); OPT (bumpbulk,0,0,1);
  534. OPT (fresh,50,0,100);
  535. OPT (glue,Cls::MAXGLUE,0,Cls::MAXGLUE);
  536. OPT (slim,1,0,1); OPT (sticky,1,0,Cls::MAXGLUE);
  537. OPT (redsub,2,0,M);
  538. OPT (minimize,4,0,4); OPT (maxdepth,1000,2,10000); OPT (strength,100,0,M);
  539. OPT (elim,1,0,1);
  540. OPT (elimgain,0,m/2,M/2);
  541. OPT (elimint,300*1000,0,M); OPT (elimprd,20,1,M);
  542. OPT (elimrtc,0,0,2);
  543. OPT (elimin,-10000,-m,M);
  544. OPT (elimclim,20,0,M);
  545. OPT (elimboost,1,0,100);
  546. OPT (elimreward,100,0,10000);
  547. OPT (elimasym,2,1,100);
  548. OPT (elimasymint,100000,100,M);
  549. OPT (elimasymreward,1000,0,M);
  550. OPT (fwmaxlen,100,0,M);OPT (bwmaxlen,1000,0,M); OPT (reslim,20,0,M);
  551. OPT (blkmaxlen,1000,0,M);
  552. OPT (subst,1,0,1); OPT (ands,1,0,1); OPT (xors,1,0,1); OPT (ites,1,0,1);
  553. OPT (minlimit,500,10,10000); OPT (maxlimit,3*1000*1000,100,M);
  554. OPT (dynred,4,-1,100000);
  555. OPT (liminitmode,1,0,1);
  556. OPT (limincmode,0,0,1);
  557. OPT (liminitconst,2000,0,1000*1000);
  558. OPT (liminitmax,20000,0,10*1000*1000);
  559. OPT (liminitpercent,10,0,1000);
  560. OPT (liminconst1,2000,0,100*1000);
  561. OPT (liminconst2,1000,0,100*1000);
  562. OPT (limincpercent,10,0,1000);
  563. OPT (enlinc,20,0,1000);
  564. OPT (shrink,2,0,2); OPT (shrinkfactor,100,1,1000);
  565. OPT (random,1,0,1); OPT (spread,2000,0,M); OPT (seed,0,0,M);
  566. OPT (skip,25,0,100);
  567. opts.set ("output", (const char*) 0);
  568. initprfx ("c ");
  569. initialized = true;
  570. }
  571. void Solver::initiirfs () {
  572. if (opts.order < 2) return;
  573. size_t bytes = size * (opts.order - 1) * sizeof *iirfs;
  574. iirfs = (int *) mem.allocate (bytes);
  575. for (Var * v = vars + 1; v <= vars + maxvar; v++)
  576. for (int i = 1; i < opts.order; i++)
  577. iirf (v, i) = -1;
  578. }
  579. void Solver::rsziirfs (int newsize) {
  580. if (opts.order < 2) return;
  581. size_t old_bytes = size * (opts.order - 1) * sizeof *iirfs;
  582. size_t new_bytes = newsize * (opts.order - 1) * sizeof *iirfs;
  583. iirfs = (int *) mem.reallocate (iirfs, old_bytes, new_bytes);
  584. }
  585. void Solver::deliirfs () {
  586. assert (iirfs);
  587. assert (opts.order >= 2);
  588. size_t bytes = size * (opts.order - 1) * sizeof *iirfs;
  589. mem.deallocate (iirfs, bytes);
  590. iirfs = 0;
  591. }
  592. void Solver::delclauses (Anchor<Cls> & anchor) {
  593. Cls * prev;
  594. for (Cls * p = anchor.head; p; p = prev) {
  595. p->bytes (); prev = p->prev; mem.deallocate (p, p->bytes ());
  596. }
  597. anchor.head = anchor.tail = 0;
  598. }
  599. void Solver::reset () {
  600. assert (initialized);
  601. initialized = false;
  602. #ifndef NDEBUG
  603. delprfx ();
  604. size_t bytes;
  605. for (int lit = 2; lit <= 2 * maxvar + 1; lit++) occs[lit].bins.release (mem);
  606. for (int lit = 2; lit <= 2 * maxvar + 1; lit++) occs[lit].large.release (mem);
  607. bytes = 2 * size * sizeof *occs; mem.deallocate (occs, bytes);
  608. bytes = 2 * size * sizeof *vals; mem.deallocate (vals, bytes);
  609. bytes = 2 * size * sizeof *repr; mem.deallocate (repr, bytes);
  610. bytes = 2 * size * sizeof *jwhs; mem.deallocate (jwhs, bytes);
  611. bytes = 2 * size * sizeof *blks; mem.deallocate (blks, bytes);
  612. bytes = size * sizeof *vars; mem.deallocate (vars, bytes);
  613. bytes = size * sizeof *prbs; mem.deallocate (prbs, bytes);
  614. bytes = size * sizeof *rnks; mem.deallocate (rnks, bytes);
  615. bytes = size * sizeof *elms; mem.deallocate (elms, bytes);
  616. delclauses (original);
  617. delclauses (binary);
  618. for (int glue = 0; glue <= opts.glue; glue++)
  619. delclauses (learned[glue]);
  620. delclauses (fresh);
  621. if (iirfs) deliirfs ();
  622. if (orgs) delorgs ();
  623. if (fwds) delfwds ();
  624. if (bwsigs) delbwsigs ();
  625. if (fwsigs) delfwsigs ();
  626. schedule.block.release (mem);
  627. schedule.elim.release (mem);
  628. schedule.decide.release (mem);
  629. schedule.probe.release (mem);
  630. opts.opts.release (mem);
  631. trail.release (mem);
  632. frames.release (mem);
  633. levels.release (mem);
  634. trash.release (mem);
  635. gate.release (mem);
  636. strnd.release (mem);
  637. saved.release (mem);
  638. elits.release (mem);
  639. plits.release (mem);
  640. #ifdef PRECOCHECK
  641. check.release (mem);
  642. #endif
  643. units.release (mem);
  644. lits.release (mem);
  645. seen.release (mem);
  646. assert (!mem);
  647. #endif
  648. }
  649. void Solver::fxopts () {
  650. assert (!opts.fixed);
  651. opts.fixed = true;
  652. initiirfs ();
  653. if (!opts.plain) return;
  654. opts.merge = 0;
  655. opts.block = 0;
  656. opts.dominate = 0;
  657. opts.rebias = 0;
  658. opts.probe = 0;
  659. opts.decompose = 0;
  660. opts.minimize = 2;
  661. opts.elim = 0;
  662. opts.random = 0;
  663. }
  664. void Solver::propts () {
  665. assert (opts.fixed);
  666. opts.printoptions (out, prfx);
  667. fflush (out);
  668. }
  669. void Solver::prstats () {
  670. double overalltime = stats.seconds ();
  671. fprintf (out, "%s%d conflicts, %d decisions, %d random\n", prfx,
  672. stats.conflicts, stats.decisions, stats.random);
  673. fprintf (out, "%s%d iterations, %d restarts, %d skipped\n", prfx,
  674. stats.iter, stats.restart.count, stats.restart.skipped);
  675. fprintf (out, "%s%d enlarged, %d shrunken, %d rescored, %d rebiased\n", prfx,
  676. stats.enlarged, stats.shrunken, stats.rescored, stats.rebias.count);
  677. fprintf (out, "%s%d simplifications, %d reductions\n", prfx,
  678. stats.simps, stats.reductions);
  679. fprintf (out, "%s\n", prfx);
  680. fprintf (out, "%svars: %d fixed, %d equiv, %d elim, %d pure, %d zombies\n",
  681. prfx,
  682. stats.vars.fixed, stats.vars.equiv,
  683. stats.vars.elim, stats.vars.pure, stats.vars.zombies);
  684. fprintf (out, "%selim: %lld resolutions, %d phases, %d rounds\n", prfx,
  685. stats.elim.resolutions, stats.elim.phases, stats.elim.rounds);
  686. fprintf (out, "%sextd: %d forced, %d assumed, %d flipped\n", prfx,
  687. stats.extend.forced, stats.extend.assumed, stats.extend.flipped);
  688. fprintf (out, "%ssbst: %.0f%% subst, "
  689. "%.1f%% nots, %.1f%% ands, %.1f%% xors, %.1f%% ites\n", prfx,
  690. percent (stats.vars.subst,stats.vars.elim),
  691. percent (stats.subst.nots.count,stats.vars.subst),
  692. percent (stats.subst.ands.count,stats.vars.subst),
  693. percent (stats.subst.xors.count,stats.vars.subst),
  694. percent (stats.subst.ites.count,stats.vars.subst));
  695. fprintf (out, "%sarty: %.2f ands %.2f xors average arity\n", prfx,
  696. average (stats.subst.ands.len, stats.subst.ands.count),
  697. average (stats.subst.xors.len, stats.subst.xors.count));
  698. fprintf (out, "%sprbe: %d probed, %d phases, %d rounds\n", prfx,
  699. stats.probe.variables, stats.probe.phases, stats.probe.rounds);
  700. fprintf (out, "%sprbe: %d failed, %d lifted, %d merged\n", prfx,
  701. stats.probe.failed, stats.probe.lifted, stats.probe.merged);
  702. fprintf (out, "%ssccs: %d non trivial, %d fixed, %d merged\n", prfx,
  703. stats.sccs.nontriv, stats.sccs.fixed, stats.sccs.merged);
  704. #ifndef NSTATSPRECO
  705. long long l1s = stats.sigs.bw.l1.srch + stats.sigs.fw.l1.srch;
  706. long long l1h = stats.sigs.bw.l1.hits + stats.sigs.fw.l1.hits;
  707. long long l2s = stats.sigs.bw.l2.srch + stats.sigs.fw.l2.srch;
  708. long long l2h = stats.sigs.bw.l2.hits + stats.sigs.fw.l2.hits;
  709. long long bws = stats.sigs.bw.l1.srch + stats.sigs.bw.l2.srch;
  710. long long bwh = stats.sigs.bw.l1.hits + stats.sigs.bw.l2.hits;
  711. long long fws = stats.sigs.fw.l1.srch + stats.sigs.fw.l2.srch;
  712. long long fwh = stats.sigs.fw.l1.hits + stats.sigs.fw.l2.hits;
  713. long long hits = bwh + fwh, srch = bws + fws;
  714. if (opts.verbose > 1) {
  715. fprintf (out, "%ssigs: %13lld srch %3.0f%% hits, %3.0f%% L1, %3.0f%% L2\n",
  716. prfx,
  717. srch, percent (hits,srch), percent (l1h,l1s), percent(l2h,l2s));
  718. fprintf (out,
  719. "%s fw: %13lld %3.0f%% %3.0f%% hits, %3.0f%% L1, %3.0f%% L2\n",
  720. prfx,
  721. fws, percent (fws,srch), percent (fwh,fws),
  722. percent (stats.sigs.fw.l1.hits, stats.sigs.fw.l1.srch),
  723. percent (stats.sigs.fw.l2.hits, stats.sigs.fw.l2.srch));
  724. fprintf (out,
  725. "%s bw: %13lld %3.0f%% %3.0f%% hits, %3.0f%% L1, %3.0f%% L2\n",
  726. prfx,
  727. bws, percent (bws,srch), percent (bwh,bws),
  728. percent (stats.sigs.bw.l1.hits, stats.sigs.bw.l1.srch),
  729. percent (stats.sigs.bw.l2.hits, stats.sigs.bw.l2.srch));
  730. } else
  731. fprintf (out,
  732. "%ssigs: %lld searched, %.0f%% hits, %.0f%% L1, %.0f%% L2\n",
  733. prfx,
  734. srch, percent (hits,srch), percent (l1h,l1s), percent(l2h,l2s));
  735. #endif
  736. long long alllits = stats.lits.added + stats.mins.deleted;
  737. fprintf (out,
  738. "%smins: %lld lrnd, %.0f%% del, %lld strng, %lld inv, %d dpth\n",
  739. prfx,
  740. stats.lits.added,
  741. percent (stats.mins.deleted, alllits),
  742. stats.mins.strong, stats.mins.inverse, stats.mins.depth);
  743. fprintf (out,
  744. "%ssubs: %d fw, %d bw, %d dynamic, %d org, %d doms, %d gc\n",
  745. prfx,
  746. stats.subs.fw, stats.subs.bw,
  747. stats.subs.dyn, stats.subs.org,
  748. stats.subs.doms, stats.subs.red);
  749. fprintf (out,
  750. "%sblkd: %lld resolutions, %d phases, %d rounds\n",
  751. prfx,
  752. stats.blkd.resolutions,
  753. stats.blkd.phases, stats.blkd.rounds);
  754. fprintf (out,
  755. "%sblkd: %d = %d implicit + %d explicit\n",
  756. prfx,
  757. stats.blkd.impl + stats.blkd.expl,
  758. stats.blkd.impl, stats.blkd.expl);
  759. assert (stats.vars.pure ==
  760. stats.pure.elim + stats.pure.blkd + stats.pure.expl);
  761. fprintf (out, "%spure: %d = %d explicit + %d elim + %d blkd\n",
  762. prfx,
  763. stats.vars.pure,
  764. stats.pure.expl, stats.pure.elim, stats.pure.blkd);
  765. assert (stats.vars.zombies ==
  766. stats.zombies.elim + stats.zombies.blkd + stats.zombies.expl);
  767. fprintf (out, "%szmbs: %d = %d explicit + %d elim + %d blkd\n",
  768. prfx,
  769. stats.vars.zombies,
  770. stats.zombies.expl, stats.zombies.elim, stats.zombies.blkd);
  771. fprintf (out,
  772. "%sstrs: %d forward, %d backward, %d dynamic, %d org, %d asym\n",
  773. prfx,
  774. stats.str.fw, stats.str.bw, stats.str.dyn,
  775. stats.str.org, stats.str.asym);
  776. fprintf (out, "%sotfs: dynamic %d = %d bin + %d trn + %d large\n",
  777. prfx,
  778. stats.otfs.dyn.bin + stats.otfs.dyn.trn + stats.otfs.dyn.large,
  779. stats.otfs.dyn.bin, stats.otfs.dyn.trn, stats.otfs.dyn.large);
  780. fprintf (out, "%sotfs: static %d = %d bin + %d trn + %d large\n",
  781. prfx,
  782. stats.otfs.stat.bin + stats.otfs.stat.trn + stats.otfs.stat.large,
  783. stats.otfs.stat.bin, stats.otfs.stat.trn, stats.otfs.stat.large);
  784. fprintf (out,
  785. "%sglue: %.2f avg, %lld slimmed = %.2f per conflict\n",
  786. prfx,
  787. average (stats.glue.sum, stats.glue.count),
  788. stats.glue.slimmed,
  789. average (stats.glue.slimmed, stats.conflicts));
  790. assert (stats.doms.count >= stats.doms.level1);
  791. assert (stats.doms.level1 >= stats.doms.probing);
  792. fprintf (out, "%sdoms: %d dominators, %d high, %d low\n", prfx,
  793. stats.doms.count,
  794. stats.doms.count - stats.doms.level1,
  795. stats.doms.level1 - stats.doms.probing);
  796. long long props = stats.props.srch + stats.props.simp;
  797. fprintf (out, "%svsts: %lld visits, %.2f per prop, %.0f%% blkd",
  798. prfx,
  799. stats.visits, average (stats.visits, props),
  800. percent (stats.blocked, stats.visits));
  801. #ifndef NSTATSPRECO
  802. fprintf (out, ", %.0f%% trn",
  803. percent (stats.ternaryvisits, stats.visits));
  804. #endif
  805. fputc ('\n', out);
  806. double othrtime = overalltime - stats.simptime - stats.srchtime;
  807. fprintf (out, "%stime: "
  808. "%.1f = "
  809. "%.1f srch (%.0f%%) + "
  810. "%.1f simp (%.0f%%) + "
  811. "%.1f othr (%.0f%%)\n",
  812. prfx,
  813. overalltime,
  814. stats.srchtime, percent (stats.srchtime, overalltime),
  815. stats.simptime, percent (stats.simptime, overalltime),
  816. othrtime, percent (othrtime, overalltime));
  817. fprintf (out, "%sprps: %lld srch props, %.2f megaprops per second\n",
  818. prfx, stats.props.srch,
  819. (stats.srchtime>0) ? stats.props.srch/1e6/stats.srchtime : 0);
  820. fprintf (out, "%sclss: %d recycled\n", prfx,
  821. stats.clauses.gc);
  822. fprintf (out, "%s\n", prfx);
  823. fprintf (out, "%s%.1f seconds, %.0f MB max, %.0f MB recycled\n", prfx,
  824. overalltime, mb (mem.getMax ()), mb (stats.collected));
  825. fflush (out);
  826. }
  827. inline void Solver::assign (int lit) {
  828. assert (!vals [lit]);
  829. vals[lit] = 1; vals[lit^1] = -1;
  830. Var & v = vars[lit/2];
  831. assert ((v.type == ELIM) == extending);
  832. if (!(v.dlevel = level)) {
  833. if (v.type == EQUIV) {
  834. assert (repr[lit]);
  835. assert (stats.vars.equiv);
  836. stats.vars.equiv--;
  837. stats.vars.fixed++;
  838. v.type = FIXED;
  839. } else {
  840. assert (!repr[lit]);
  841. if (v.type == FREE) {
  842. stats.vars.fixed++;
  843. v.type = FIXED;
  844. } else assert (v.type == ZOMBIE || v.type == PURE);
  845. }
  846. simplified = true;
  847. }
  848. if (measure) {
  849. Val val = lit2val (lit);
  850. agility -= agility/10000;
  851. if (v.phase && v.phase != val) agility += 1000;
  852. v.phase = val;
  853. }
  854. v.tlevel = trail;
  855. trail.push (mem, lit);
  856. #ifndef NLOGPRECO
  857. printf ("%sLOG assign %d at level %d <=", prfx, lit, level);
  858. if (v.binary) printf (" %d %d\n", lit, v.reason.lit);
  859. else if (v.reason.cls)
  860. printf (" %d %d %d%s\n",
  861. v.reason.cls->lits[0],
  862. v.reason.cls->lits[1],
  863. v.reason.cls->lits[2],
  864. v.reason.cls->size > 3 ? " ..." : "");
  865. else if (!level) printf (" top level\n");
  866. else printf (" decision\n");
  867. #endif
  868. }
  869. inline void Solver::assume (int lit, bool inclevel) {
  870. if (inclevel) {
  871. frames.push (mem, Frame (trail));
  872. level++;
  873. LOG ("assume new level " << level);
  874. assert (level + 1 == frames);
  875. LOG ("assuming " << lit);
  876. } else {
  877. assert (!level);
  878. LOG ("permanently assume " << lit << " on top level");
  879. }
  880. Var & v = vars[lit/2]; v.binary = false; v.reason.cls = 0;
  881. v.dominator = lit;
  882. assign (lit);
  883. }
  884. inline void Solver::imply (int lit, int reason) {
  885. assert (lit/2 != reason/2);
  886. assert (vals[reason] < 0);
  887. assert (vars[reason/2].dlevel == level);
  888. Var & v = vars[lit/2];
  889. if (level) v.binary = true, v.reason.lit = reason;
  890. else v.binary = false, v.reason.lit = 0;
  891. if (level) v.dominator = vars[reason/2].dominator;
  892. assign (lit);
  893. }
  894. inline int Solver::dominator (int lit, Cls * reason, bool & contained) {
  895. if (!opts.dominate) return 0;
  896. if (asymode) return 0;
  897. if (opts.maxdoms <= stats.doms.count) return 0;
  898. contained = false;
  899. assert (level > 0);
  900. int vdom = 0, other, oldvdom;
  901. Var * u;
  902. for (const int * p = reason->lits; vdom >= 0 && (other = *p); p++) {
  903. if (other == lit) continue;
  904. u = vars + (other/2);
  905. if (!u->dlevel) continue;
  906. if (u->dlevel < level) { vdom = -1; break; }
  907. int udom = u->dominator;
  908. assert (udom);
  909. if (vdom) {
  910. assert (vdom > 0);
  911. if (udom != vdom) vdom = -1;
  912. } else vdom = udom;
  913. }
  914. assert (vdom);
  915. if (vdom <= 0) return vdom;
  916. assert (vals[vdom] > 0);
  917. LOG (vdom << " dominates " << lit);
  918. for (const int * p = reason->lits; !contained && (other = *p); p++)
  919. contained = (other^1) == vdom;
  920. if (contained) goto DONE;
  921. oldvdom = vdom; vdom = 0;
  922. for (const int * p = reason->lits; (other = *p); p++) {
  923. if (other == lit) continue;
  924. assert (vals[other] < 0);
  925. u = vars + other/2;
  926. if (!u->dlevel) continue;
  927. assert (u->dlevel == level);
  928. assert (u->dominator == oldvdom);
  929. other ^= 1;
  930. assert (other != oldvdom);
  931. if (other == vdom) continue;
  932. if (vdom) {
  933. while (!u->mark &&
  934. (other = (assert (u->binary), 1^u->reason.lit)) != oldvdom &&
  935. other != vdom) {
  936. assert (vals[other] > 0);
  937. u = vars + other/2;
  938. assert (u->dlevel == level);
  939. assert (u->dominator == oldvdom);
  940. }
  941. while (vdom != other) {
  942. u = vars + (vdom/2);
  943. assert (u->mark);
  944. u->mark = 0;
  945. assert (u->binary);
  946. vdom = 1^u->reason.lit;
  947. }
  948. if (vdom == oldvdom) break;
  949. } else {
  950. vdom = 1^u->reason.lit;
  951. if (vdom == oldvdom) break;
  952. assert (vals[vdom] > 0);
  953. other = vdom;
  954. do {
  955. u = vars + other/2;
  956. assert (u->dlevel == level);
  957. assert (u->dominator == oldvdom);
  958. assert (!u->mark);
  959. u->mark = 1;
  960. assert (u->binary);
  961. other = 1^u->reason.lit;
  962. assert (vals[other] > 0);
  963. } while (other != oldvdom);
  964. }
  965. }
  966. other = vdom;
  967. while (other != oldvdom) {
  968. u = vars + other/2;
  969. assert (u->dlevel == level);
  970. assert (u->dominator == oldvdom);
  971. assert (u->mark);
  972. u->mark = 0;
  973. assert (u->binary);
  974. other = 1^u->reason.lit;
  975. assert (vals[other] > 0);
  976. }
  977. if (vdom == oldvdom) goto DONE;
  978. assert (vdom);
  979. LOG (vdom << " also dominates " << lit);
  980. assert (!contained);
  981. for (const int * p = reason->lits; !contained && (other = *p); p++)
  982. contained = (other^1) == vdom;
  983. DONE:
  984. stats.doms.count++;
  985. if (level == 1) stats.doms.level1++;
  986. if (!measure) { assert (level == 1); stats.doms.probing++; }
  987. if (contained) {
  988. reason->garbage = true;
  989. stats.subs.doms++;
  990. LOG ("dominator clause is subsuming");
  991. }
  992. return vdom;
  993. }
  994. inline void Solver::unit (int lit) {
  995. Var * v;
  996. Val val = vals[lit];
  997. assert (!level);
  998. if (val < 0) {
  999. LOG ("conflict after adding unit"); conflict = &empty; return;
  1000. }
  1001. if (!val) {
  1002. v = vars + (lit/2);
  1003. v->binary = false, v->reason.cls = 0;
  1004. assign (lit);
  1005. }
  1006. int other = find (lit);
  1007. if (other == lit) return;
  1008. val = vals[other];
  1009. if (val < 0) {
  1010. LOG ("conflict after adding unit"); conflict = &empty; return;
  1011. }
  1012. if (val) return;
  1013. v = vars + (other/2);
  1014. v->binary = false, v->reason.cls = 0;
  1015. assign (other);
  1016. }
  1017. inline unsigned Solver::gluelits () {
  1018. const int * eol = lits.end ();
  1019. int lit, found = 0;
  1020. unsigned res = 0;
  1021. assert (uip);
  1022. for (const int * p = lits.begin (); p < eol; p++) {
  1023. lit = *p;
  1024. assert (val (lit) < 0);
  1025. Var * v = vars + (lit/2);
  1026. int dlevel = v->dlevel;
  1027. if (dlevel == level) { assert (!found); found = lit; continue; }
  1028. assert (dlevel > 0);
  1029. Frame * f = &frames[dlevel];
  1030. if (f->contained) continue;
  1031. f->contained = true;
  1032. res++;
  1033. }
  1034. assert (found == uip);
  1035. for (const int * p = lits.begin (); p < eol; p++)
  1036. frames[vars[*p/2].dlevel].contained = false;
  1037. return res;
  1038. }
  1039. inline void Solver::slim (Cls * cls) {
  1040. if (!opts.slim) return;
  1041. if (!level) return;
  1042. assert (cls);
  1043. if (!cls->lnd) return;
  1044. assert (!cls->binary);
  1045. unsigned oldglue = cls->glue;
  1046. if (!oldglue) return;
  1047. const int * p = cls->lits;
  1048. unsigned newglue = 0;
  1049. int lit, nonfalse = 0;
  1050. while ((lit = *p++)) {
  1051. Val val = vals[lit];
  1052. if (val >= 0 && nonfalse++) { newglue = oldglue; break; }
  1053. Var * v = vars + (lit/2);
  1054. int dlevel = v->dlevel;
  1055. if (dlevel <= 0) continue;
  1056. assert (dlevel < frames);
  1057. Frame * f = &frames[dlevel];
  1058. if (f->contained) continue;
  1059. if (++newglue >= oldglue) break;
  1060. f->contained = true;
  1061. }
  1062. while (p > cls->lits) {
  1063. lit = *--p;
  1064. if (!lit) continue;
  1065. Var * v = vars + (lit/2);
  1066. int dlevel = v->dlevel;
  1067. if (dlevel <= 0) continue;
  1068. assert (dlevel < frames);
  1069. Frame * f = &frames[dlevel];
  1070. f->contained = false;
  1071. }
  1072. if (cls->glued) {
  1073. assert (oldglue >= newglue);
  1074. if (oldglue == newglue) return;
  1075. assert (newglue >= 1);
  1076. LOG ("slimmed glue from " << oldglue << " to " << newglue);
  1077. } else LOG ("new glue " << newglue);
  1078. assert (newglue <= (unsigned) opts.glue);
  1079. if (!cls->fresh) dequeue (anchor (cls), cls);
  1080. cls->glue = newglue;
  1081. if (!cls->fresh) push (anchor (cls), cls);
  1082. if (cls->glued) stats.glue.slimmed++;
  1083. stats.glue.count++;
  1084. stats.glue.sum += newglue;
  1085. cls->glued = true;
  1086. }
  1087. inline void Solver::force (int lit, Cls * reason) {
  1088. assert (reason);
  1089. assert (!reason->binary);
  1090. Val val = vals[lit];
  1091. if (val < 0) { LOG ("conflict forcing literal"); conflict = reason; }
  1092. if (val) return;
  1093. #ifndef NDEBUG
  1094. for (const int * p = reason->lits; *p; p++)
  1095. if (*p != lit) assert (vals[*p] < 0);
  1096. #endif
  1097. Var * v = vars + (lit/2);
  1098. int vdom;
  1099. bool sub;
  1100. if (!level) {
  1101. v->binary = false, v->reason.cls = 0;
  1102. } else if (!lits && (vdom = dominator (lit, reason, sub)) > 0) {
  1103. v->dominator = vdom;
  1104. assert (vals[vdom] > 0);
  1105. vdom ^= 1;
  1106. LOG ("dominating learned clause " << vdom << ' ' << lit);
  1107. assert (!lits);
  1108. lits.push (mem, vdom);
  1109. lits.push (mem, lit);
  1110. bool lnd = reason->lnd || !sub;
  1111. clause (lnd, lnd);
  1112. v->binary = true, v->reason.lit = vdom;
  1113. } else {
  1114. v->binary = false, v->reason.cls = reason;
  1115. reason->locked = true;
  1116. if (reason->lnd) stats.clauses.lckd++;
  1117. v->dominator = lit;
  1118. }
  1119. assign (lit);
  1120. }
  1121. inline void Solver::jwh (Cls * cls) {
  1122. //if (cls->lnd) return; // TODO better not ?
  1123. int * p;
  1124. for (p = cls->lits; *p; p++)
  1125. ;
  1126. int size = p - cls->lits;
  1127. int inc = logsize (size);
  1128. while (p > cls->lits) {
  1129. int l = *--p;
  1130. jwhs[l] += inc;
  1131. if (jwhs[l] < 0) die ("maximum large JWH score exceeded");
  1132. }
  1133. }
  1134. int Solver::find (int a) {
  1135. assert (2 <= a && a <= 2 * maxvar + 1);
  1136. int res, tmp;
  1137. for (res = a; (tmp = repr[res]); res = tmp)
  1138. ;
  1139. for (int fix = a; (tmp = repr[fix]) && tmp != res; fix = tmp)
  1140. repr[fix] = res, repr[fix^1] = res^1;
  1141. return res;
  1142. }
  1143. inline void Solver::merge (int l, int k, int & merged) {
  1144. int a, b;
  1145. if (!opts.merge) return;
  1146. assert (!elimode);
  1147. assert (!blkmode);
  1148. if ((a = find (l)) == (b = find (k))) return;
  1149. assert (a/2 != b/2);
  1150. #ifndef NLOGPRECO
  1151. int m = min (a, b);
  1152. LOG ("merge " << l << " and " << k << " to " << m);
  1153. if (k != m) LOG ("learned clause " << k << ' ' << (m^1));
  1154. if (k != m) LOG ("learned clause " << (k^1) << ' ' << m);
  1155. if (l != m) LOG ("learned clause " << l << ' ' << (m^1));
  1156. if (l != m) LOG ("learned clause " << (l^1) << ' ' << m);
  1157. #endif
  1158. if (a < b) repr[k] = repr[b] = a, repr[k^1] = repr[b^1] = a^1;
  1159. else repr[l] = repr[a] = b, repr[l^1] = repr[a^1] = b^1;
  1160. assert (vars[a/2].type == FREE && vars[b/2].type == FREE);
  1161. vars[max (a,b)/2].type = EQUIV;
  1162. stats.vars.merged++;
  1163. stats.vars.equiv++;
  1164. simplified = true;
  1165. merged++;
  1166. }
  1167. Cls * Solver::clause (bool lnd, unsigned glue) {
  1168. assert (asymode || !elimode || !lnd);
  1169. assert (lnd || !glue);
  1170. Cls * res = 0;
  1171. #ifndef NLOGPRECO
  1172. std::cout << prfx << "LOG " << (lnd ? "learned" : "original") << " clause";
  1173. for (const int * p = lits.begin (); p < lits.end (); p++)
  1174. std::cout << ' ' << *p;
  1175. std::cout << std::endl;
  1176. #endif
  1177. #ifndef NDEBUG
  1178. for (int i = 0; i < lits; i++)
  1179. assert (vars[lits[i]/2].type != ELIM);
  1180. #endif
  1181. if (lits == 0) {
  1182. LOG ("conflict after added empty clause");
  1183. conflict = &empty;
  1184. } else if (lits == 1) {
  1185. int lit = lits[0];
  1186. Val val;
  1187. if ((val = vals[lit]) < 0) {
  1188. LOG ("conflict after adding falsified unit clause");
  1189. conflict = &empty;
  1190. } else if (!val) unit (lit);
  1191. } else {
  1192. if (lits >= (int)Cls::MAXSZ) die ("maximal clause size exceeded");
  1193. size_t bytes = Cls::bytes (lits);
  1194. res = (Cls *) mem.callocate (bytes);
  1195. res->lnd = lnd;
  1196. if (!lnd) stats.clauses.irr++;
  1197. res->size = lits;
  1198. int * q = res->lits, * eol = lits.end ();
  1199. for (const int * p = lits.begin (); p < eol; p++)
  1200. *q++ = *p;
  1201. *q = 0;
  1202. if (lits == 2) res->binary = true, stats.clauses.bin++;
  1203. else {
  1204. res->glue = min ((unsigned)opts.glue,glue);
  1205. res->fresh = res->lnd;
  1206. if (lnd) stats.clauses.lnd++;
  1207. else stats.clauses.orig++;
  1208. }
  1209. connect (res);
  1210. }
  1211. lits.shrink ();
  1212. simplified = true;
  1213. return res;
  1214. }
  1215. inline void Solver::marklits () {
  1216. for (const int * p = lits.begin (); p < lits.end (); p++)
  1217. vars[*p/2].mark = lit2val (*p);
  1218. }
  1219. inline void Solver::unmarklits () {
  1220. for (const int * p = lits.begin (); p < lits.end (); p++)
  1221. vars[*p/2].mark = 0;
  1222. }
  1223. inline bool Solver::bwsub (unsigned sig, Cls * c) {
  1224. assert (!c->trash && !c->dirty && !c->garbage);
  1225. limit.budget.bw.sub--;
  1226. int count = lits;
  1227. if (c->size < (unsigned) count) return false;
  1228. INC (sigs.bw.l1.srch);
  1229. if (!sigsubs (sig, c->sig)) { INC (sigs.bw.l1.hits); return false; }
  1230. int lit;
  1231. for (int * p = c->lits; count && (lit = *p); p++) {
  1232. Val u = lit2val (lit), v = vars[lit/2].mark;
  1233. if (u == v) count--;
  1234. }
  1235. return !count;
  1236. }
  1237. int Solver::bwstr (unsigned sig, Cls * c) {
  1238. assert (!c->trash && !c->dirty && !c->garbage);
  1239. limit.budget.bw.str--;
  1240. int count = lits;
  1241. if (c->size < (unsigned) count) return 0;
  1242. INC (sigs.bw.l1.srch);
  1243. if (!sigsubs (sig, c->sig)) { INC (sigs.bw.l1.hits); return 0; }
  1244. int lit, res = 0;
  1245. for (int * p = c->lits; count && (lit = *p); p++) {
  1246. Val u = lit2val (lit), v = vars[lit/2].mark;
  1247. if (abs (u) != abs (v)) continue;
  1248. if (u == -v) { if (res) return 0; res = lit; }
  1249. count--;
  1250. }
  1251. assert (count >= 0);
  1252. res = count ? 0 : res;
  1253. return res;
  1254. }
  1255. void Solver::remove (int del, Cls * c) {
  1256. assert (!c->trash && !c->garbage && !c->dirty && !c->gate);
  1257. assert (c->lits[0] && c->lits[1]);
  1258. if (c->binary) {
  1259. int pos = (c->lits[1] == del);
  1260. assert (c->lits[pos] == del);
  1261. LOG ("will not remove " << del << " but will simply produce unit instead");
  1262. unit (c->lits[!pos]);
  1263. } else {
  1264. disconnect (c);
  1265. int * p = c->lits, lit;
  1266. while ((lit = *p) != del) assert (lit), p++;
  1267. while ((lit = *++p)) p[-1] = lit;
  1268. p[-1] = 0;
  1269. assert (p - c->lits >= 3);
  1270. if (p - c->lits == 3) {
  1271. if (c->lnd) {
  1272. assert (stats.clauses.lnd > 0);
  1273. stats.clauses.lnd--;
  1274. } else {
  1275. assert (stats.clauses.orig > 0);
  1276. stats.clauses.orig--;
  1277. }
  1278. c->binary = true;
  1279. stats.clauses.bin++;
  1280. }
  1281. setsig (c);
  1282. connect (c);
  1283. if (elimode || blkmode) touch (del);
  1284. simplified = true;
  1285. #ifndef NLOGPRECO
  1286. LOG ("removed " << del << " and got");
  1287. dbgprint ("LOG learned clause ", c);
  1288. #endif
  1289. }
  1290. }
  1291. void Solver::bworgs () {
  1292. if (lits <= 1) return;
  1293. limit.budget.bw.str += 2;
  1294. limit.budget.bw.sub += 4;
  1295. marklits ();
  1296. int first = 0;
  1297. int minlen = INT_MAX;
  1298. for (int i = 0; i < lits; i++) {
  1299. int other = lits[i];
  1300. int len = orgs[other];
  1301. if (len < minlen) first = other, minlen = len;
  1302. }
  1303. unsigned sig = litsig ();
  1304. assert (first);
  1305. INC (sigs.bw.l2.srch);
  1306. if (!sigsubs (sig, bwsigs[first])) INC (sigs.bw.l2.hits);
  1307. else if (orgs[first] <= opts.bwmaxlen)
  1308. for (int i = 0; limit.budget.bw.sub >= 0 && i < orgs[first]; i++) {
  1309. Cls * other = orgs[first][i];
  1310. assert (!other->locked);
  1311. if (other->trash || other->dirty || other->garbage) continue;
  1312. if (!bwsub (sig, other)) continue;
  1313. #ifndef NLOGPRECO
  1314. dbgprint ("LOG static backward subsumed clause ", other);
  1315. #endif
  1316. stats.subs.bw++;
  1317. limit.budget.bw.sub += 12;
  1318. dump (other);
  1319. }
  1320. int second = 0;
  1321. minlen = INT_MAX;
  1322. for (int i = 0; i < lits; i++) {
  1323. int other = lits[i];
  1324. if (other == first) continue;
  1325. int len = orgs[other];
  1326. if (len < minlen) second = other, minlen = len;
  1327. }
  1328. assert (second);
  1329. if (orgs[first^1] < minlen) second = (first^1);
  1330. for (int round = 0; round <= 1; round++) {
  1331. int start = round ? second : first;
  1332. INC (sigs.bw.l2.srch);
  1333. if (!sigsubs (sig, bwsigs[start])) { INC (sigs.bw.l2.hits); continue; }
  1334. Orgs & org = orgs[start];
  1335. if (org > opts.bwmaxlen) continue;
  1336. for (int i = 0; limit.budget.bw.str >= 0 && i < org; i++) {
  1337. Cls * other = org[i];
  1338. assert (!other->locked);
  1339. if (other->trash || other->dirty || other->garbage) continue;
  1340. int del = bwstr (sig, other);
  1341. if (!del) continue;
  1342. LOG ("static backward strengthened clause by removing " << del);
  1343. stats.str.bw++;
  1344. limit.budget.bw.str += 10;
  1345. remove (del, other);
  1346. assert (litsig () == sig);
  1347. }
  1348. }
  1349. unmarklits ();
  1350. }
  1351. void Solver::bwoccs (bool & lnd) {
  1352. if (lits <= 1) return;
  1353. limit.budget.bw.sub += lnd ? 30 : 10;
  1354. limit.budget.bw.str += lnd ? 20 : 8;
  1355. marklits ();
  1356. unsigned sig = litsig ();
  1357. for (int i = 0; i < lits; i++) {
  1358. int first = lits[i];
  1359. if (limit.budget.bw.sub >= 0) {
  1360. INC (sigs.bw.l2.srch);
  1361. if (!sigsubs (sig, bwsigs[first])) INC (sigs.bw.l2.hits);
  1362. else if (occs[first].large <= opts.bwmaxlen) {
  1363. for (int i = 0;
  1364. limit.budget.bw.sub >= 0 && i < occs[first].large; i++) {
  1365. Cls * other = occs[first].large[i].cls;
  1366. assert (!other->dirty && !other->trash);
  1367. if (other->garbage) continue;
  1368. if (!bwsub (sig, other)) continue;
  1369. if (!other->lnd && lnd) lnd = false;
  1370. LOG ((level ? "dynamic" : "static")
  1371. << " backward subsumed "
  1372. << (other->lnd ? "learned" : "original")
  1373. << " clause");
  1374. #ifndef NLOGPRECO
  1375. {
  1376. std::cout << prfx << "LOG subsumed clause";
  1377. for (const int * p = other->lits; *p; p++)
  1378. std::cout << ' ' << *p;
  1379. std::cout << std::endl;
  1380. }
  1381. #endif
  1382. if (level) {
  1383. stats.subs.dyn++;
  1384. if (!other->lnd) stats.subs.org++;
  1385. } else stats.subs.bw++;
  1386. limit.budget.bw.sub += 20;
  1387. if (other->locked) other->garbage = true; else recycle (other);
  1388. }
  1389. }
  1390. }
  1391. if (limit.budget.bw.str >= 0) {
  1392. INC (sigs.bw.l2.srch);
  1393. if (!sigsubs (sig, bwsigs[first])) INC (sigs.bw.l2.hits);
  1394. else if (occs[first].large <= opts.bwmaxlen) {
  1395. for (int i = 0;
  1396. limit.budget.bw.sub >= 0 && i < occs[first].large;
  1397. i++) {
  1398. Cls* other = occs[first].large[i].cls;
  1399. assert (!other->dirty && !other->trash);
  1400. if (other->locked || other->garbage) continue;
  1401. int del = bwstr (sig, other);
  1402. if (!del) continue;
  1403. LOG ((level ? "dynamic" : "static")
  1404. << " backward strengthened "
  1405. << (other->lnd ? "learned" : "original")
  1406. << " clause by removing "
  1407. << del);
  1408. #ifndef NLOGPRECO
  1409. {
  1410. std::cout << prfx << "LOG strengthened clause";
  1411. for (const int * p = other->lits; *p; p++)
  1412. std::cout << ' ' << *p;
  1413. std::cout << std::endl;
  1414. }
  1415. #endif
  1416. if (level) {
  1417. stats.str.dyn++;
  1418. if (!other->lnd) stats.str.org++;
  1419. } else stats.str.bw++;
  1420. limit.budget.bw.str += 15;
  1421. remove (del, other);
  1422. if (level) strcls (other);
  1423. }
  1424. }
  1425. }
  1426. }
  1427. unmarklits ();
  1428. }
  1429. inline bool Solver::fwsub (unsigned sig, Cls * c) {
  1430. assert (!c->trash && !c->dirty && !c->garbage);
  1431. limit.budget.fw.sub--;
  1432. INC (sigs.fw.l1.srch);
  1433. if (!sigsubs (c->sig, sig)) { INC (sigs.fw.l1.hits); return false; }
  1434. int lit;
  1435. for (const int * p = c->lits; (lit = *p); p++) {
  1436. Val u = lit2val (lit), v = vars[lit/2].mark;
  1437. if (u != v) return false;
  1438. }
  1439. return true;
  1440. }
  1441. inline int Solver::fwstr (unsigned sig, Cls * c) {
  1442. assert (!c->trash && !c->dirty && !c->garbage);
  1443. limit.budget.fw.str--;
  1444. INC (sigs.fw.l1.srch);
  1445. if (!sigsubs (c->sig, sig)) { INC (sigs.fw.l1.hits); return 0; }
  1446. int res = 0, lit;
  1447. for (const int * p = c->lits; (lit = *p); p++) {
  1448. Val u = lit2val (lit), v = vars[lit/2].mark;
  1449. if (u == v) continue;
  1450. if (u != -v) return 0;
  1451. if (res) return 0;
  1452. res = (lit^1);
  1453. }
  1454. return res;
  1455. }
  1456. bool Solver::fworgs () {
  1457. if (lits <= 1) return false;
  1458. limit.budget.fw.str += 3;
  1459. limit.budget.fw.sub += 5;
  1460. assert (fwds);
  1461. marklits ();
  1462. unsigned sig = litsig ();
  1463. bool res = false;
  1464. if (lits >= 2) {
  1465. for (int i = 0; !res && limit.budget.fw.sub >= 0 && i < lits; i++) {
  1466. int lit = lits[i];
  1467. INC (sigs.fw.l2.srch);
  1468. if (!(fwsigs[lit] & sig)) { INC (sigs.fw.l2.hits); continue; }
  1469. Fwds & f = fwds[lit];
  1470. if (f > opts.fwmaxlen) continue;
  1471. for (int j = 0; !res && limit.budget.fw.sub >= 0 && j < f; j++) {
  1472. Cls * c = f[j];
  1473. if (c->trash || c->dirty || c->garbage) continue;
  1474. res = fwsub (sig, c);
  1475. }
  1476. }
  1477. if (res) {
  1478. LOG ("new clause is subsumed");
  1479. stats.subs.fw++;
  1480. limit.budget.fw.sub += 5;
  1481. }
  1482. }
  1483. if (!res)
  1484. for (int sign = 0; sign <= 1; sign++)
  1485. for (int i = 0; limit.budget.fw.str >= 0 && i < lits; i++) {
  1486. int lit = lits[i];
  1487. INC (sigs.fw.l2.srch);
  1488. if (!(fwsigs[lit] & sig)) { INC (sigs.fw.l2.hits); continue; }
  1489. lit ^= sign;
  1490. Fwds & f = fwds[lit];
  1491. if (f > opts.fwmaxlen) continue;
  1492. int del = 0;
  1493. for (int j = 0; !del && limit.budget.fw.str >= 0 && j < f; j++) {
  1494. Cls * c = f[j];
  1495. if (c->trash || c->dirty || c->garbage) continue;
  1496. del = fwstr (sig, c);
  1497. }
  1498. if (!del) continue;
  1499. assert (sign || del/2 != lit/2);
  1500. LOG ("strengthen new clause by removing " << del);
  1501. stats.str.fw++;
  1502. limit.budget.fw.str += 8;
  1503. assert (vars[del/2].mark == lit2val (del));
  1504. vars[del/2].mark = 0;
  1505. lits.remove (del);
  1506. sig = litsig ();
  1507. i = -1;
  1508. }
  1509. unmarklits ();
  1510. return res;
  1511. }
  1512. void Solver::resize (int newmaxvar) {
  1513. assert (maxvar < size);
  1514. assert (newmaxvar > maxvar);
  1515. int newsize = size;
  1516. while (newsize <= newmaxvar)
  1517. newsize *= 2;
  1518. if (newsize > size) {
  1519. size_t o, n;
  1520. o = size * sizeof * vars;
  1521. n = newsize * sizeof * vars;
  1522. vars = (Var *) mem.recallocate (vars, o, n);
  1523. o = 2 * size * sizeof *repr;
  1524. n = 2 * newsize * sizeof *repr;
  1525. repr = (int*) mem.recallocate (repr, o, n);
  1526. o = 2 * size * sizeof *jwhs;
  1527. n = 2 * newsize * sizeof *jwhs;
  1528. jwhs = (int*) mem.recallocate (jwhs, o, n);
  1529. o = 2 * size * sizeof *vals;
  1530. n = 2 * newsize * sizeof *vals;
  1531. vals = (Val*) mem.recallocate (vals, o, n);
  1532. o = 2 * size * sizeof *occs;
  1533. n = 2 * newsize * sizeof *occs;
  1534. occs = (Occs*) mem.recallocate (occs, o, n);
  1535. ptrdiff_t diff;
  1536. char * c;
  1537. o = size * sizeof *rnks;
  1538. n = newsize * sizeof *rnks;
  1539. c = (char *) rnks;
  1540. rnks = (Rnk*) mem.reallocate (rnks, o, n);
  1541. diff = c - (char *) rnks;
  1542. schedule.decide.fix (diff);
  1543. o = size * sizeof *prbs;
  1544. n = newsize * sizeof *prbs;
  1545. c = (char *) prbs;
  1546. prbs = (Rnk*) mem.reallocate (prbs, o, n);
  1547. diff = c - (char *) prbs;
  1548. schedule.probe.fix (diff);
  1549. o = size * sizeof *elms;
  1550. n = newsize * sizeof *elms;
  1551. c = (char *) elms;
  1552. elms = (Rnk*) mem.reallocate (elms, o, n);
  1553. diff = c - (char *) elms;
  1554. schedule.elim.fix (diff);
  1555. rszbwsigs (newsize);
  1556. rsziirfs (newsize);
  1557. size = newsize;
  1558. }
  1559. assert (newmaxvar < size);
  1560. while (maxvar < newmaxvar) {
  1561. Var * v = vars + ++maxvar;
  1562. v->dlevel = -1;
  1563. for (int i = 1; i < opts.order; i++)
  1564. iirf (v, i) = -1;
  1565. Rnk * r = rnks + maxvar;
  1566. r->heat = 0, r->pos = -1, schedule.decide.push (mem, r);
  1567. Rnk * p = prbs + maxvar;
  1568. p->heat = 0, p->pos = -1;
  1569. Rnk * e = elms + maxvar;
  1570. e->heat = 0, e->pos = -1;
  1571. }
  1572. assert (maxvar < size);
  1573. }
  1574. void Solver::import () {
  1575. bool trivial = false;
  1576. int * q = lits.begin ();
  1577. const int * p, * eol = lits.end ();
  1578. for (p = lits.begin (); !trivial && p < eol; p++) {
  1579. int lit = *p, v = lit/2;
  1580. assert (1 <= v);
  1581. if (v > maxvar) resize (v);
  1582. Val tmp = vals[lit];
  1583. if (!tmp) {
  1584. int prev = vars[v].mark;
  1585. int val = lit2val (lit);
  1586. if (prev) {
  1587. if (val == prev) continue;
  1588. assert (val == -prev);
  1589. trivial = 1;
  1590. } else {
  1591. vars[v].mark = val;
  1592. *q++ = lit;
  1593. }
  1594. } else if (tmp > 0)
  1595. trivial = true;
  1596. }
  1597. while (p > lits.begin ()) vars[*--p/2].mark = 0;
  1598. if (!trivial) {
  1599. lits.shrink (q);
  1600. bool lnd = false;
  1601. bwoccs (lnd);
  1602. assert (!lnd);
  1603. clause (lnd, lnd);
  1604. }
  1605. lits.shrink ();
  1606. }
  1607. inline bool Solver::satisfied (const Cls * c) {
  1608. int lit;
  1609. for (const int * p = c->lits; (lit = *p); p++)
  1610. if (val (lit) > 0) return true;
  1611. return false;
  1612. }
  1613. inline bool Solver::satisfied (Anchor<Cls> & anchor) {
  1614. for (const Cls * p = anchor.head; p; p = p->prev)
  1615. if (!satisfied (p)) return false;
  1616. return true;
  1617. }
  1618. bool Solver::satisfied () {
  1619. if (!satisfied (binary)) return false;
  1620. if (!satisfied (original)) return false;
  1621. #ifndef NDEBUG
  1622. for (int glue = 0; glue <= opts.glue; glue++)
  1623. if (!satisfied (learned[glue])) return false;
  1624. if (!satisfied (fresh)) return false;
  1625. #endif
  1626. #ifdef PRECOCHECK
  1627. for (const int * p = check.begin (); p < check.end (); p++) {
  1628. bool found = false;
  1629. int lit;
  1630. while ((lit = *p)) {
  1631. if (val (lit) > 0) found = true;
  1632. p++;
  1633. }
  1634. if (!found) return false;
  1635. }
  1636. #endif
  1637. return true;
  1638. }
  1639. inline void Solver::prop2 (int lit) {
  1640. assert (vals[lit] < 0);
  1641. LOG ("prop2 " << lit);
  1642. const Stack<int> & os = occs[lit].bins;
  1643. const int * eos = os.end ();
  1644. for (const int * p = os.begin (); p < eos; p++) {
  1645. int other = *p;
  1646. Val val = vals[other];
  1647. if (val > 0) continue;
  1648. if (!val) { imply (other, lit); continue; }
  1649. LOG ("conflict in binary clause while propagating " << (1^lit));
  1650. conflict = lit2conflict (dummy, lit, other);
  1651. LOG ("conflicting clause " << lit << ' ' << other);
  1652. }
  1653. }
  1654. inline void Solver::propl (int lit) {
  1655. assert (vals[lit] < 0);
  1656. LOG ("propl " << lit);
  1657. Stack<Occ> & os = occs[lit].large;
  1658. Occ * a = os.begin (), * t = os.end (), * p = a, * q = a;
  1659. CONTINUE_OUTER_LOOP:
  1660. while (p < t) {
  1661. int blit = p->blit;
  1662. Cls * cls = p++->cls;
  1663. *q++ = Occ (blit, cls);
  1664. stats.visits++;
  1665. Val val = vals[blit];
  1666. if (val > 0) { stats.blocked++; continue; }
  1667. #ifndef NSTATSPRECO
  1668. if (cls->lits[2] && !*(cls->lits + 3)) INC (ternaryvisits);
  1669. #endif
  1670. int sum = cls->lits[0]^cls->lits[1];
  1671. int other = sum^lit;
  1672. val = vals[other];
  1673. q[-1].blit = other;
  1674. if (val > 0) continue;
  1675. int prev = lit, next, *l, *lits2 = cls->lits+2;
  1676. for (l = lits2; (next = *l); l++) {
  1677. *l = prev; prev = next;
  1678. if (vals[next] < 0) continue;
  1679. occs[next].large.push (mem, Occ (other, cls));
  1680. int pos = (cls->lits[1] == lit);
  1681. cls->lits[pos] = next;
  1682. q--; goto CONTINUE_OUTER_LOOP;
  1683. }
  1684. while (l > lits2) { next = *--l; *l = prev; prev = next; }
  1685. slim (cls);
  1686. if (val) {
  1687. LOG ("conflict in large clause while propagating " << (1^lit));
  1688. conflict = cls;
  1689. #ifndef NLOGPRECO
  1690. dbgprint ("LOG conflicting clause ", cls);
  1691. #endif
  1692. break;
  1693. }
  1694. force (other, cls);
  1695. long moved = ((char*)os.begin ()) - (char*)a;
  1696. if (moved) fix (p,moved), fix (q,moved), fix (t,moved), a = os.begin ();
  1697. }
  1698. while (p < t) *q++ = *p++;
  1699. os.shrink (q - a);
  1700. }
  1701. bool Solver::bcp () {
  1702. if (conflict) return false;
  1703. if (!level && units) flushunits ();
  1704. if (conflict) return false;
  1705. int lit, props = 0;
  1706. for (;;) {
  1707. if (queue2 < trail) {
  1708. props++;
  1709. lit = 1^trail[queue2++];
  1710. prop2 (lit);
  1711. if (!measure && conflict) break;
  1712. } else if (queue < trail) {
  1713. if (conflict) break;
  1714. lit = 1^trail[queue++];
  1715. propl (lit);
  1716. if (conflict) break;
  1717. } else
  1718. break;
  1719. }
  1720. if (measure) stats.props.srch += props;
  1721. else stats.props.simp += props;
  1722. return !conflict;
  1723. }
  1724. inline bool Solver::needtoflush () const {
  1725. return queue2 < trail;
  1726. }
  1727. bool Solver::flush () {
  1728. assert (!level);
  1729. int fixed = queue2;
  1730. if (!bcp ()) return false;
  1731. while (fixed < trail) {
  1732. int lit = trail[fixed++];
  1733. recycle (lit);
  1734. }
  1735. assert (!conflict);
  1736. return true;
  1737. }
  1738. inline int Solver::phase (Var * v) {
  1739. int lit = 2 * (v - vars) + 1;
  1740. if (v->phase > 0 ||
  1741. (!v->phase && (jwhs[lit^1] > jwhs[lit]))) lit ^= 1;
  1742. return lit;
  1743. }
  1744. void Solver::extend () {
  1745. report (2, 't');
  1746. extending = true;
  1747. int n = elits;
  1748. while (n > 0) {
  1749. int unblock = elits[--n];
  1750. int lit = elits[--n];
  1751. if (unblock) {
  1752. LOG ("unblocking " << lit);
  1753. Val valit = val (lit);
  1754. assert (valit);
  1755. bool forced = (valit < 0);
  1756. int other;
  1757. while ((other = elits[--n])) {
  1758. if (!forced) continue;
  1759. other = find (other);
  1760. Val v = val (other);
  1761. assert (v);
  1762. forced = (v < 0);
  1763. }
  1764. if (!forced) continue;
  1765. // TODO make this in an assertion ...
  1766. // We have 'in principle' a proof that this can not happen.
  1767. if (repr[lit]) die ("internal error extending assignment");
  1768. LOG ("assign " << (1^lit) << " at level " << level << " <= unblock");
  1769. vals[lit] = 1, vals[lit^1] = -1;
  1770. assert (trail[vars[lit/2].tlevel] == (1^lit));
  1771. trail[vars[lit/2].tlevel] = lit;
  1772. stats.extend.flipped++;
  1773. } else {
  1774. LOG ("extending " << lit);
  1775. assert (!repr [lit]);
  1776. while (elits[n-1]) {
  1777. bool forced = true;
  1778. int other;
  1779. while ((other = elits[--n])) {
  1780. if (!forced) continue;
  1781. other = find (other);
  1782. if (other == lit) continue;
  1783. if (other == (lit^1)) { forced = false; continue; }
  1784. Val v = val (other);
  1785. if (v > 0) forced = false;
  1786. }
  1787. if (!forced) continue;
  1788. Val v = val (lit);
  1789. if (v) assert (v > 0);
  1790. else { assume (lit); stats.extend.forced++; }
  1791. }
  1792. if (!val (lit)) { assume (lit^1); stats.extend.assumed++; }
  1793. n--;
  1794. }
  1795. }
  1796. #ifndef NDEBUG
  1797. for (int lit = 2; lit <= 2 * maxvar + 1; lit += 2)
  1798. assert (val (lit));
  1799. #endif
  1800. extending = false;
  1801. }
  1802. bool Solver::decide () {
  1803. Rnk * r;
  1804. for (;;) {
  1805. if (!schedule.decide) { extend (); return false; }
  1806. r = schedule.decide.max ();
  1807. int idx = r - rnks;
  1808. int lit = 2 * idx;
  1809. if (vars[idx].type == FREE && !vals[lit]) break;
  1810. (void) schedule.decide.pop ();
  1811. }
  1812. assert (r);
  1813. stats.decisions++;
  1814. stats.sumheight += level;
  1815. if (opts.random && agility <= 10 * 100000 && rng.oneoutof (opts.spread)) {
  1816. stats.random++;
  1817. unsigned n = schedule.decide; assert (n);
  1818. unsigned s = rng.next () % n, d = rng.next () % n;
  1819. while (ggt (n, d) != 1) {
  1820. d++; if (d >= n) d = 1;
  1821. }
  1822. for (;;) {
  1823. r = schedule.decide[s];
  1824. int lit = 2 * (r - rnks);
  1825. if (vars[lit/2].type == FREE && !vals[lit]) break;
  1826. s += d; if (s >= n) s -= n;
  1827. }
  1828. }
  1829. int lit = phase (var (r));
  1830. assert (!vals[lit]);
  1831. LOG ("decision " << lit);
  1832. assume (lit);
  1833. iterating = false;
  1834. return true;
  1835. }
  1836. inline bool Solver::min2 (int lit, int other, int depth) {
  1837. assert (lit != other && vals[lit] > 0);
  1838. if (vals[other] >= 0) return false;
  1839. Var * v = vars + (lit/2);
  1840. if (v->binary && v->reason.lit == other) {
  1841. Var * d = vars + (v->dominator/2);
  1842. //assert (d != v);
  1843. assert (depth);
  1844. if (d->removable) return true;
  1845. if (d->mark) return true;
  1846. }
  1847. Var * u = vars + (other/2);
  1848. assert (opts.minimize > Opts::RECUR || u->tlevel < v->tlevel);
  1849. if (u->tlevel > v->tlevel) return false;
  1850. if (u->mark) return true;
  1851. if (u->removable) return true;
  1852. if (u->poison) return false;
  1853. return minimize (u, depth);
  1854. }
  1855. inline bool Solver::minl (int lit, Cls * cls, int depth) {
  1856. assert (vals[lit] > 0);
  1857. assert (cls->locked || cls->lits[0] == lit || cls->lits[1] == lit);
  1858. Var * v = vars + (lit/2);
  1859. int other;
  1860. for (const int * p = cls->lits; (other = *p); p++) {
  1861. if (other == lit) continue;
  1862. if (vals[other] >= 0) return false;
  1863. Var * u = vars + (other/2);
  1864. assert (opts.minimize > Opts::RECUR || u->tlevel < v->tlevel);
  1865. if (u->tlevel > v->tlevel) {
  1866. if (!opts.inveager) return false;
  1867. if (u != vars + uip/2 && (u->binary || u->reason.cls))
  1868. return false;
  1869. }
  1870. if (u->mark) continue;
  1871. if (u->removable) continue;
  1872. if (u->poison) return false;
  1873. int l = u->dlevel;
  1874. if (!l) continue;
  1875. if (!frames[l].pulled) return false;
  1876. }
  1877. //int old = pulled;
  1878. for (const int * p = cls->lits; (other = *p); p++) {
  1879. if (other == lit) continue;
  1880. Var * u = vars + other/2;
  1881. if (u->mark) continue;
  1882. if (u->removable) continue;
  1883. if (u->poison) return false;
  1884. int l = u->dlevel;
  1885. if (!l) continue;
  1886. if (!minimize (u, depth)) { /*cleanpulled (old); */ return false; }
  1887. }
  1888. return true;
  1889. }
  1890. inline bool Solver::strengthen (int lit, int depth) {
  1891. assert (vals[lit] > 0);
  1892. assert (opts.minimize >= Opts::STRONG);
  1893. const Stack<int> & os2 = occs[lit].bins;
  1894. const int * eos2 = os2.end ();
  1895. for (const int * o = os2.begin (); o < eos2 && limit.strength-- >= 0; o++)
  1896. if (min2 (lit, *o, depth)) return true;
  1897. if (opts.minimize < Opts::STRONGER) return false;
  1898. const Stack<Occ> & osl = occs[lit].large;
  1899. const Occ * eosl = osl.end ();
  1900. for (const Occ * o = osl.begin (); o < eosl && limit.strength-- >= 0; o++)
  1901. if (minl (lit, o->cls, depth)) {
  1902. if (opts.mtfall && depth == 1 && o->cls->lnd)
  1903. mtf (anchor (o->cls), o->cls);
  1904. return true;
  1905. }
  1906. return false;
  1907. }
  1908. bool Solver::minimize (Var * v, int depth) {
  1909. if (!depth) limit.strength = opts.strength;
  1910. if (depth > stats.mins.depth) stats.mins.depth = depth;
  1911. assert (v->dlevel != level);
  1912. if (v->removable) return true;
  1913. if (depth && v->mark) return true;
  1914. if (v->poison) return false;
  1915. int l = v->dlevel;
  1916. if (!l) return true;
  1917. if (opts.minimize == Opts::NONE) return false;
  1918. if (depth && opts.minimize == Opts::LOCAL) return false;
  1919. if (!v->binary && !v->reason.cls) return false;
  1920. if (!frames[l].pulled) return false;
  1921. if (depth++ >= opts.maxdepth) return false;
  1922. assert (!v->onstack);
  1923. v->onstack = true;
  1924. bool res = false;
  1925. int lit = 2 * (v - vars);
  1926. Val val = vals[lit];
  1927. if (val < 0) lit ^= 1;
  1928. assert (vals[lit] > 0);
  1929. if (v->binary) res = min2 (lit, v->reason.lit, depth);
  1930. else if ((res = minl (lit, v->reason.cls, depth))) {
  1931. if (opts.mtfall && depth == 1 && v->reason.cls->lnd)
  1932. mtf (anchor (v->reason.cls), v->reason.cls);
  1933. }
  1934. if (opts.minimize >= Opts::STRONG && !res)
  1935. if ((res = strengthen (lit, depth)))
  1936. stats.mins.strong++;
  1937. v->onstack = false;
  1938. if (res) v->removable = true;
  1939. else v->poison = true;
  1940. seen.push (mem, v);
  1941. return res;
  1942. }
  1943. bool Solver::inverse (int lit) {
  1944. assert (vals[lit] > 0);
  1945. Var * v = vars + (lit/2);
  1946. if (v->dlevel != jlevel) return false;
  1947. const Stack<Occ> & osl = occs[lit].large;
  1948. const Occ * eosl = osl.end ();
  1949. bool foundlit = false, founduip = false;
  1950. for (const Occ * o = osl.begin (); o < eosl; o++) {
  1951. Cls * c = o->cls;
  1952. int other = 0;
  1953. for (const int * p = c->lits; (other = *p); p++) {
  1954. if (other == lit) { foundlit = true; continue; }
  1955. if (other == uip) { founduip = true; continue; }
  1956. if (vals[other] >= 0) break;
  1957. Var * u = vars + (other/2);
  1958. if (u->dlevel >= jlevel) break;
  1959. if (!u->mark) break;
  1960. }
  1961. if (other) continue;
  1962. assert (founduip);
  1963. assert (foundlit);
  1964. #ifndef NLOGPRECO
  1965. dbgprint ("LOG inverse arc ", c);
  1966. #endif
  1967. if (opts.mtfall && c->lnd) mtf (anchor (c), c);
  1968. return true;
  1969. }
  1970. return false;
  1971. }
  1972. void Solver::undo (int newlevel, bool save) {
  1973. LOG ("undo " << newlevel);
  1974. assert (newlevel <= level);
  1975. if (newlevel == level) return;
  1976. if (save) saved.shrink ();
  1977. int tlevel = frames[newlevel+1].tlevel;
  1978. while (tlevel < trail) {
  1979. int lit = trail.pop ();
  1980. assert (vals[lit] > 0);
  1981. vals[lit] = vals[lit^1] = 0;
  1982. LOG("unassign " << lit);
  1983. if (!repr[lit]) {
  1984. if (save) saved.push (mem, lit);
  1985. Rnk & r = rnks[lit/2];
  1986. if (!schedule.decide.contains (&r)) schedule.decide.push (mem, &r);
  1987. }
  1988. int idx = lit/2;
  1989. Var & v = vars[idx];
  1990. v.dlevel = -1;
  1991. if (v.binary) continue;
  1992. Cls * c = v.reason.cls;
  1993. if (!c) continue;
  1994. c->locked = false;
  1995. if (!c->lnd) continue;
  1996. assert (stats.clauses.lckd > 0);
  1997. stats.clauses.lckd--;
  1998. }
  1999. frames.shrink (newlevel + 1);
  2000. level = newlevel;
  2001. queue = queue2 = trail;
  2002. conflict = 0;
  2003. LOG ("backtrack new level " << newlevel);
  2004. }
  2005. inline int & Solver::iirf (Var * v, int t) {
  2006. assert (1 <= t && t < opts.order && 2 <= opts.order);
  2007. return iirfs[(opts.order - 1) * (v - vars) + (t - 1)];
  2008. }
  2009. inline void Solver::rescore () {
  2010. stats.rescored++;
  2011. hinc >>= 14;
  2012. for (Rnk * s = rnks + 1; s <= rnks + maxvar; s++) s->heat >>= 14;
  2013. schedule.decide.construct ();
  2014. }
  2015. inline void Solver::bump (Var * v, int add) {
  2016. assert (stats.conflicts > 0);
  2017. int inc = hinc;
  2018. if (opts.order >= 2) {
  2019. inc /= 2;
  2020. int w = inc, c = stats.conflicts - 1, s = 512, l = 9;
  2021. for (int i = 1; i <= opts.order - 1; i++) {
  2022. w >>= 1, l--;
  2023. for (int j = 1; j <= opts.order - 1; j++) {
  2024. int d = iirf (v, j);
  2025. if (d > c) continue;
  2026. if (d == c) inc += w, s += (1<<l);
  2027. break;
  2028. }
  2029. c--;
  2030. }
  2031. for (int i = opts.order - 1; i > 1; i--)
  2032. iirf (v, i) = iirf (v, i - 1);
  2033. iirf (v, 1) = stats.conflicts;
  2034. assert ((hinc >> (opts.order-1)) <= inc && inc <= hinc);
  2035. }
  2036. Rnk * r = rnk (v);
  2037. r->heat += inc + add;
  2038. LOG ("bump " << 2*(v - vars) << " by " << inc << " new score " << r->heat);
  2039. schedule.decide.up (r);
  2040. assert (hinc < (1<<28));
  2041. if (r->heat >= (1<<24)) {
  2042. if (opts.bumpbulk) needrescore = true;
  2043. else rescore ();
  2044. }
  2045. }
  2046. inline void Solver::pull (int lit) {
  2047. Var * v = vars + (lit/2);
  2048. assert (v->dlevel && !v->mark);
  2049. LOG ("pulling " << lit << " open " << open);
  2050. v->mark = 1;
  2051. seen.push (mem, v);
  2052. if (v->dlevel == level) open++;
  2053. else {
  2054. lits.push (mem, lit);
  2055. if (!frames[v->dlevel].pulled) {
  2056. frames[v->dlevel].pulled = true;
  2057. levels.push (mem, v->dlevel);
  2058. }
  2059. }
  2060. }
  2061. void Solver::cleanlevels () {
  2062. while (levels) {
  2063. int l = levels.pop ();
  2064. assert (frames[l].pulled);
  2065. frames[l].pulled = false;
  2066. }
  2067. }
  2068. void Solver::jump () {
  2069. jlevel = 0;
  2070. int * eolits = lits.end ();
  2071. for (const int * p = lits.begin(); p < eolits; p++) {
  2072. Var * v = vars + (*p/2);
  2073. if (v->dlevel < level && v->dlevel > jlevel)
  2074. jlevel = v->dlevel;
  2075. }
  2076. LOG ("new jump level " << jlevel);
  2077. }
  2078. void Solver::cleanseen () {
  2079. Var ** eos = seen.end ();
  2080. for (Var ** p = seen.begin(); p < eos; p++) {
  2081. Var * v = *p; v->mark = 0; v->removable = v->poison = false;
  2082. }
  2083. seen.shrink ();
  2084. }
  2085. void Solver::bump (Cls * c) {
  2086. if (c == &dummy) return;
  2087. assert (c);
  2088. if (c->garbage) return;
  2089. if (!c->lnd) return;
  2090. assert (!c->binary);
  2091. mtf (anchor (c), c);
  2092. #ifndef NLOGPRECO
  2093. int lit;
  2094. for (const int * p = c->lits; (lit = *p); p++)
  2095. if (val (lit) > 0) break;
  2096. if (lit) {
  2097. char buffer[100];
  2098. sprintf (buffer, "LOG bump %d forcing clause ", lit);
  2099. dbgprint (buffer, c);
  2100. } else dbgprint ("LOG bump conflicting clause ", c);
  2101. #endif
  2102. }
  2103. static int revcmptlevel (const void * p, const void * q) {
  2104. Var * u = *(Var**) p, * v = *(Var**) q;
  2105. return v->tlevel - u->tlevel;
  2106. }
  2107. void Solver::bump () {
  2108. assert (conflict);
  2109. Var ** start, ** end, ** bos = seen.begin (), ** eos = seen.end ();
  2110. if (opts.bumpsort) qsort (bos, seen, sizeof *bos, revcmptlevel);
  2111. #ifndef NDEBUG
  2112. for (Var ** p = bos; p < eos; p++)
  2113. if (p+1 < eos) assert (p[0]->tlevel > p[1]->tlevel);
  2114. #endif
  2115. Var * uipvar = vars + (uip/2), * except = opts.bumpuip ? 0 : uipvar;
  2116. int dir;
  2117. if (opts.mtfrev) start = bos, end = eos, dir = 1;
  2118. else start = eos-1, end = bos-1, dir = -1;
  2119. if (opts.mtfrev) bump (conflict);
  2120. for (Var ** p = start; p != end; p += dir) {
  2121. Var * v = *p;
  2122. if (v == uipvar) continue;
  2123. if (v->dlevel < level) continue;
  2124. if (v->binary) continue;
  2125. Cls * r = v->reason.cls;
  2126. if (!r) continue;
  2127. bump (r);
  2128. }
  2129. if (!opts.mtfrev) bump (conflict);
  2130. // NOTE: this case split is actually redundant since
  2131. // we use the variable index order as tie breaker anyhow.
  2132. // TODO not really true, since rescore may happen?
  2133. if (opts.bumpbulk) needrescore = false;
  2134. if (opts.bumprev) start = eos-1, end = bos-1, dir = -1;
  2135. else start = bos, end = eos, dir = 1;
  2136. int turbo = opts.bumpturbo ? eos - bos - 1 : 0;
  2137. for (Var ** p = start; p != end; p += dir) {
  2138. Var * v = *p;
  2139. if (v == except) continue;
  2140. bump (v, turbo);
  2141. if (opts.bumpturbo) turbo--;
  2142. }
  2143. if (opts.bumpbulk && needrescore) rescore ();
  2144. }
  2145. bool Solver::analyze () {
  2146. RESTART:
  2147. assert (conflict);
  2148. stats.conflicts++;
  2149. if (!level) return false;
  2150. assert (!lits); assert (!seen); assert (!levels);
  2151. int i = trail, lit;
  2152. bool unit = false;
  2153. resolved = open = 0;
  2154. Var * u = 0;
  2155. uip = 0;
  2156. do {
  2157. assert (seen >= resolved);
  2158. int otf = seen - resolved;
  2159. if (uip) {
  2160. LOG ("resolving " << uip);
  2161. resolved++;
  2162. }
  2163. if (!u || !u->binary) {
  2164. Cls * r = (u ? u->reason.cls : conflict); assert (r);
  2165. for (const int * p = r->lits; (lit = *p); p++) {
  2166. Var * v = vars + (lit/2);
  2167. if (!v->dlevel) continue;
  2168. if (!v->mark) { pull (lit); otf = INT_MAX; }
  2169. else if (v->tlevel <= i) otf--;
  2170. else otf = INT_MAX;
  2171. }
  2172. if (level > 0 && opts.otfs && otf <= 0 && r != &dummy) {
  2173. #ifndef NLOGPRECO
  2174. printf ("%sLOG on-the-fly strengthened %s clause ",
  2175. prfx, r->lnd ? "learned" : "original");
  2176. r->print ();
  2177. printf ("%sLOG on-the-fly strengthening resolvent", prfx);
  2178. for (Var ** p = seen.begin (); p < seen.end (); p++)
  2179. if ((*p)->tlevel <= i) {
  2180. int lit = 2 * (*p - vars);
  2181. int val = vals[lit];
  2182. assert (val);
  2183. if (val > 0) lit++;
  2184. printf (" %d", lit);
  2185. }
  2186. fputc ('\n', stdout);
  2187. #endif
  2188. #ifndef NDEBUG
  2189. assert (u);
  2190. if (opts.check) {
  2191. for (Var ** p = seen.begin (); p < seen.end (); p++) {
  2192. Var * v = *p;
  2193. assert (v->mark);
  2194. if (v->tlevel > i) continue;
  2195. int idx = v - vars, * q;
  2196. for (q = r->lits; *q; q++) if (*q/2 == idx) break;
  2197. assert (*q);
  2198. }
  2199. }
  2200. #endif
  2201. lit = 2 * (u - vars);
  2202. int val = vals[lit];
  2203. assert (val);
  2204. if (val < 0) lit++;
  2205. assert (r->locked);
  2206. assert (u->reason.cls == r);
  2207. u->reason.cls = 0;
  2208. r->locked = false;
  2209. if (r->lnd) {
  2210. assert (stats.clauses.lckd > 0);
  2211. stats.clauses.lckd--;
  2212. }
  2213. bump ();
  2214. if (r->garbage) r->garbage = false;
  2215. remove (lit, r);
  2216. if (r->binary) {
  2217. conflict = lit2conflict (dummy, r->lits[0], r->lits[1]);
  2218. stats.otfs.dyn.trn++;
  2219. } else {
  2220. conflict = r;
  2221. slim (r);
  2222. stats.otfs.dyn.large++;
  2223. }
  2224. cleanlevels ();
  2225. cleanseen ();
  2226. lits.shrink ();
  2227. goto RESTART;
  2228. }
  2229. } else {
  2230. assert (u && u->binary);
  2231. otf--;
  2232. lit = u->reason.lit;
  2233. Var * v = vars + (lit/2);
  2234. if (v->dlevel) {
  2235. if (v->mark) { if (v->tlevel < i) otf--; }
  2236. else { pull (lit); otf = INT_MAX; }
  2237. }
  2238. if (level > 0 && opts.otfs && otf <= 0) {
  2239. stats.otfs.dyn.bin++;
  2240. unit = true;
  2241. }
  2242. }
  2243. for (;;) {
  2244. assert (i > 0);
  2245. uip = trail[--i];
  2246. u = vars + (uip/2);
  2247. if (!u->mark) continue;
  2248. assert (u->dlevel == level);
  2249. assert (open > 0);
  2250. open--;
  2251. break;
  2252. }
  2253. } while (open);
  2254. assert (uip);
  2255. LOG ("uip " << uip);
  2256. uip ^= 1;
  2257. lits.push (mem, uip);
  2258. #ifndef NLOGPRECO
  2259. printf ("%sLOG 1st uip clause", prfx);
  2260. for (const int * p = lits.begin (); p < lits.end (); p++)
  2261. printf (" %d", *p);
  2262. fputc ('\n', stdout);
  2263. #endif
  2264. bump ();
  2265. #ifndef NDEBUG
  2266. for (Var **p = seen.begin (); p < seen.end (); p++) {
  2267. Var * v = *p; assert (v->mark && !v->removable && !v->poison);
  2268. }
  2269. #endif
  2270. int * q = lits.begin (), * eolits = lits.end ();
  2271. for (const int * p = q; p < eolits; p++) {
  2272. lit = *p; Var * v = vars + (lit/2);
  2273. assert ((v->dlevel == level) == (lit == uip));
  2274. if (v->dlevel < level && minimize (v, 0)) {
  2275. LOG ("removing 1st uip literal " << lit);
  2276. stats.mins.deleted++;
  2277. } else *q++ = lit;
  2278. }
  2279. lits.shrink (q);
  2280. jump ();
  2281. int cjlevel = 0;
  2282. eolits = lits.end ();
  2283. for (const int * p = lits.begin(); p < eolits; p++) {
  2284. lit = *p;
  2285. Var * v = vars + (lit/2);
  2286. if (v->dlevel != jlevel) continue;
  2287. LOG ("literal " << lit << " on jump level " << jlevel);
  2288. cjlevel++;
  2289. }
  2290. LOG (cjlevel <<
  2291. " variables in minimized 1st UIP clause on jump level " << jlevel);
  2292. if (opts.inverse && cjlevel == 1) {
  2293. q = lits.begin (), eolits = lits.end ();
  2294. {
  2295. int * p;
  2296. for (p = q; p < eolits; p++) {
  2297. if (inverse (1^*p)) {
  2298. stats.mins.inverse++;
  2299. stats.mins.deleted++;
  2300. LOG ("literal " << *p << " removed due to inverse arc");
  2301. assert (cjlevel > 0);
  2302. cjlevel--;
  2303. p++;
  2304. break;
  2305. } else *q++ = *p;
  2306. }
  2307. while (p < eolits)
  2308. *q++ = *p++;
  2309. if (!cjlevel) {
  2310. LOG ("inverse arc decreases jump level");
  2311. jump ();
  2312. }
  2313. }
  2314. lits.shrink (q);
  2315. }
  2316. unsigned glue = gluelits ();
  2317. cleanseen ();
  2318. cleanlevels ();
  2319. stats.lits.added += lits;
  2320. #ifndef NLOGPRECO
  2321. printf ("%sLOG minimized clause", prfx);
  2322. for (const int * p = lits.begin (); p < lits.end (); p++)
  2323. printf (" %d", *p);
  2324. fputc ('\n', stdout);
  2325. #endif
  2326. #ifndef NDEBUG
  2327. for (const int * p = lits.begin (); p < lits.end (); p++)
  2328. assert (*p == uip || vars[*p/2].dlevel < level);
  2329. if (unit) assert (!jlevel);
  2330. #endif
  2331. #ifndef NLOGPRECO
  2332. if (jlevel + 1 < level) LOG ("backjump to " << jlevel);
  2333. else LOG ("backtrack to " << jlevel);
  2334. #endif
  2335. undo (jlevel);
  2336. if (!jlevel) iterating = true;
  2337. assert (!conflict);
  2338. bool lnd = true;
  2339. bwoccs (lnd);
  2340. int strlevel = jlevel;
  2341. bool skip = false;
  2342. if (strnd) {
  2343. LOG ("analyzing " << strnd << " strengthened clauses");
  2344. for (Cls ** p = strnd.begin (); p < strnd.end (); p++) {
  2345. Cls * c = *p;
  2346. int countnonfalse = 0, maxlevel = 0;
  2347. for (int * q = c->lits; (lit = *q); q++) {
  2348. int val = vals[lit];
  2349. if (val > 0) break;
  2350. if (!val && ++countnonfalse >= 2) break;
  2351. }
  2352. if (lit || countnonfalse >= 2) continue;
  2353. for (int * q = c->lits; (lit = *q); q++) {
  2354. int tmp = vars[lit/2].dlevel;
  2355. if (tmp > maxlevel) maxlevel = tmp;
  2356. }
  2357. int newstrlevel = 0;
  2358. for (int * q = c->lits; (lit = *q); q++) {
  2359. int tmp = vars[lit/2].dlevel;
  2360. if (tmp == maxlevel) continue;
  2361. assert (tmp < maxlevel);
  2362. if (tmp > newstrlevel) newstrlevel = tmp;
  2363. }
  2364. if (newstrlevel < strlevel) strlevel = newstrlevel;
  2365. }
  2366. if (strlevel < jlevel) {
  2367. LOG ("strengthened backtrack level " << strlevel);
  2368. undo (strlevel);
  2369. }
  2370. marklits ();
  2371. unsigned sig = litsig ();
  2372. for (Cls ** p = strnd.begin (); !skip && p < strnd.end (); p++)
  2373. if (fwsub (sig, *p)) skip = true;
  2374. unmarklits ();
  2375. if (skip)
  2376. LOG ("learned clause subsumed by strengthened clause");
  2377. for (Cls ** p = strnd.begin (); p < strnd.end (); p++) {
  2378. Cls * c = *p;
  2379. int unit = 0;
  2380. for (int * q = c->lits; (lit = *q); q++) {
  2381. Val val = vals[lit];
  2382. if (val < 0) continue;
  2383. if (val > 0) break;
  2384. if (unit) break;
  2385. unit = lit;
  2386. }
  2387. if (lit) continue;
  2388. assert (unit);
  2389. assert (!c->garbage);
  2390. if (c->binary) {
  2391. int other = c->lits[0] + c->lits[1];
  2392. other -= unit;
  2393. imply (unit, other);
  2394. } else force (unit, c);
  2395. if (skip) continue;
  2396. skip = true;
  2397. LOG ("learned clause skipped because of forcing strengthened clause");
  2398. }
  2399. for (Cls ** p = strnd.begin (); p < strnd.end (); p++)
  2400. assert ((*p)->str), (*p)->str = false;
  2401. strnd.shrink ();
  2402. }
  2403. if (!skip || !lnd) {
  2404. for (Frame * f = frames.begin (); f < frames.end (); f++)
  2405. assert (!f->contained);
  2406. Cls * cls = clause (lnd, lnd ? glue : 0); //TODO: move before if?
  2407. if (!vals[uip] && strlevel == jlevel) {
  2408. if (cls) {
  2409. if (cls->binary) {
  2410. int other = cls->lits[0] + cls->lits[1];
  2411. other -= uip;
  2412. imply (uip, other);
  2413. } else {
  2414. force (uip, cls);
  2415. slim (cls);
  2416. }
  2417. }
  2418. }
  2419. if (lnd) {
  2420. while (fresh.count > limit.reduce.fresh && fresh.tail) {
  2421. Cls * f = fresh.tail;
  2422. dequeue (fresh, f);
  2423. assert (f->fresh);
  2424. assert (!f->binary);
  2425. assert (f->lnd);
  2426. f->fresh = false;
  2427. push (anchor (f), f);
  2428. }
  2429. int count = opts.dynred;
  2430. Cls * ctc;
  2431. for (int glue = opts.glue;
  2432. glue >= opts.sticky && count >= 0 && recycling ();
  2433. glue--) {
  2434. ctc = learned[glue].tail;
  2435. while (ctc && count-- >= 0 && recycling ()) {
  2436. Cls * next = ctc->next;
  2437. assert (!ctc->binary);
  2438. if (ctc != cls && !ctc->locked) recycle (ctc);
  2439. ctc = next;
  2440. }
  2441. }
  2442. }
  2443. } else lits.shrink ();
  2444. long long tmp = hinc;
  2445. tmp *= 100 + opts.heatinc; tmp /= 100;
  2446. assert (tmp <= INT_MAX);
  2447. hinc = tmp;
  2448. return true;
  2449. }
  2450. int Solver::luby (int i) {
  2451. int k;
  2452. for (k = 1; k < 32; k++)
  2453. if (i == (1 << k) - 1)
  2454. return 1 << (k-1);
  2455. for (k = 1;; k++)
  2456. if ((1 << (k-1)) <= i && i < (1 << k) - 1)
  2457. return luby (i - (1u << (k-1)) + 1);
  2458. }
  2459. inline double Stats::height () {
  2460. return decisions ? sumheight / (double) decisions : 0.0;
  2461. }
  2462. void Solver::increp () {
  2463. if ((stats.reports++ % 19)) return;
  2464. fprintf (out,
  2465. "%s .\n"
  2466. "%s ."
  2467. " clauses fixed eliminated learned agility"
  2468. "\n"
  2469. "%s ."
  2470. " seconds variables equivalent conflicts height MB"
  2471. "\n"
  2472. "%s .\n", prfx, prfx, prfx, prfx);
  2473. }
  2474. int Solver::remvars () const {
  2475. int res = maxvar;
  2476. res -= stats.vars.fixed;
  2477. res -= stats.vars.equiv;
  2478. res -= stats.vars.elim;
  2479. res -= stats.vars.pure;
  2480. res -= stats.vars.zombies;
  2481. assert (res >= 0);
  2482. return res;
  2483. }
  2484. void Solver::report (int v, char type) {
  2485. if (opts.quiet || v > opts.verbose) return;
  2486. char countch[2];
  2487. countch[0] = countch[1] = ' ';
  2488. if (terminal && type == lastype) {
  2489. typecount++;
  2490. if (type != 'e' && type != 'p' && type != 'k') {
  2491. countch[0] = '0' + (typecount % 10);
  2492. if (typecount >= 10) countch[1] = '0' + (typecount % 100)/10;
  2493. }
  2494. } else {
  2495. typecount = 1;
  2496. if (terminal && lastype) fputc ('\n', out);
  2497. increp ();
  2498. }
  2499. assert (maxvar >= stats.vars.fixed + stats.vars.equiv + stats.vars.elim);
  2500. fprintf (out, "%s%c%c%c%7.1f %7d %7d %6d %6d %6d %7d %6d %6.1f %2.0f %4.0f",
  2501. prfx,
  2502. countch[1], countch[0], type, stats.seconds (),
  2503. stats.clauses.irr,
  2504. remvars (),
  2505. stats.vars.fixed, stats.vars.equiv,
  2506. stats.vars.elim,
  2507. type=='e'?schedule.elim:
  2508. (type=='p'?schedule.probe:
  2509. (type=='k'?schedule.block:stats.conflicts)),
  2510. (type=='F'?limit.reduce.fresh:
  2511. (type=='l' || type=='+' || type == '-') ?
  2512. limit.reduce.learned : stats.clauses.lnd),
  2513. stats.height (),
  2514. agility / 100000.0,
  2515. mem / (double) (1<<20));
  2516. if (!terminal || type=='0' || type=='1' || type=='?') fputc ('\n', out);
  2517. else fputc ('\r', out);
  2518. fflush (out);
  2519. lastype = type;
  2520. }
  2521. void Solver::restart () {
  2522. int skip = agility >= opts.skip * 100000;
  2523. if (skip) stats.restart.skipped++;
  2524. else stats.restart.count++;
  2525. limit.restart.conflicts = stats.conflicts;
  2526. int delta;
  2527. if (opts.luby) delta = opts.restartint * luby (++limit.restart.lcnt);
  2528. else {
  2529. if (limit.restart.inner >= limit.restart.outer) {
  2530. limit.restart.inner = opts.restartint;
  2531. limit.restart.outer *= 100 + opts.restartouter;
  2532. limit.restart.outer /= 100;
  2533. } else {
  2534. limit.restart.inner *= 100 + opts.restartinner;
  2535. limit.restart.inner /= 100;
  2536. }
  2537. delta = limit.restart.inner;
  2538. }
  2539. limit.restart.conflicts += delta;
  2540. if (!skip) undo (0);
  2541. if (stats.restart.maxdelta < delta) {
  2542. stats.restart.maxdelta = delta;
  2543. report (1, skip ? 'N' : 'R');
  2544. } else
  2545. report (2, skip ? 'n' :'r');
  2546. }
  2547. void Solver::rebias () {
  2548. limit.rebias.conflicts = stats.conflicts;
  2549. int delta = opts.rebiasint * luby (++limit.rebias.lcnt);
  2550. limit.rebias.conflicts += delta;
  2551. if (!opts.rebias) return;
  2552. stats.rebias.count++;
  2553. for (Var * v = vars + 1; v <= vars + maxvar; v++) v->phase = 0;
  2554. jwh ();
  2555. if (stats.rebias.maxdelta >= delta) report (2, 'b');
  2556. else stats.rebias.maxdelta = delta, report (1, 'B');
  2557. }
  2558. inline int Solver::redundant (Cls * c) {
  2559. assert (!level);
  2560. assert (!c->locked);
  2561. assert (!c->garbage);
  2562. #ifndef NDEBUG
  2563. for (const int * p = c->lits; *p; p++) {
  2564. Var * v = vars + (*p/2);
  2565. assert (!v->mark);
  2566. assert (v->type != ELIM);
  2567. }
  2568. #endif
  2569. int res = 0, * p, lit;
  2570. #ifdef PRECOCHECK
  2571. bool shrink = false;
  2572. for (p = c->lits; !res && (lit = *p); p++) {
  2573. int other = find (lit);
  2574. Var * v = vars + (other/2);
  2575. assert ((v->type != ELIM));
  2576. Val val = vals[other];
  2577. if (val > 0 && !v->dlevel) res = 1;
  2578. else if (val < 0 && !v->dlevel) shrink = true;
  2579. else {
  2580. val = lit2val (other);
  2581. if (v->mark == val) { shrink = true; continue; }
  2582. else if (v->mark == -val) res = 1;
  2583. else v->mark = val;
  2584. }
  2585. }
  2586. while (p > c->lits) vars[find (*--p)/2].mark = 0;
  2587. #ifndef NDEBUG
  2588. for (p = c->lits; *p; p++) assert (!vars[find (*p)/2].mark);
  2589. #endif
  2590. if (shrink || res) {
  2591. for (p = c->lits; *p; p++) check.push (mem, *p);
  2592. check.push (mem, 0);
  2593. }
  2594. if (res) return res;
  2595. #endif
  2596. p = c->lits; int * q = p;
  2597. while (!res && (lit = *p)) {
  2598. p++;
  2599. int other = find (lit);
  2600. if (other != lit) simplified = true;
  2601. Var * v = vars + (other/2);
  2602. assert (v->type != ELIM);
  2603. Val val = vals[other];
  2604. if (val && !v->dlevel) {
  2605. if (val > 0) res = 1;
  2606. } else {
  2607. val = lit2val (other);
  2608. if (v->mark == val) continue;
  2609. if (v->mark == -val) res = 1;
  2610. else { assert (!v->mark); v->mark = val; *q++ = other; }
  2611. }
  2612. }
  2613. *q = 0;
  2614. if (!res) assert (!*q && !*p);
  2615. int newsize = q - c->lits;
  2616. if (!res &&
  2617. newsize > 1 &&
  2618. newsize <= opts.redsub &&
  2619. (!c->lnd || c->binary)) {
  2620. limit.budget.red += 10;
  2621. setsig (c);
  2622. for (p = c->lits; !res && (lit = *p) && limit.budget.red >= 0; p++) {
  2623. INC (sigs.fw.l2.srch);
  2624. if (!(fwsigs[lit] & c->sig)) { INC (sigs.fw.l2.hits); continue; }
  2625. if (fwds[lits] > opts.fwmaxlen) continue;
  2626. for (int i = 0; !res && i < fwds[lit] && limit.budget.red >= 0; i++) {
  2627. limit.budget.red--;
  2628. Cls * d = fwds[lit][i];
  2629. assert (!d->trash);
  2630. if (d->garbage) continue;
  2631. if (d->size > (unsigned) newsize) continue;
  2632. if (d->size > (unsigned) opts.redsub) continue;
  2633. if (!c->lnd && d->lnd && !d->binary) continue;
  2634. INC (sigs.fw.l1.srch);
  2635. if (!sigsubs (d->sig, c->sig)) { INC (sigs.fw.l1.hits); continue; };
  2636. int other;
  2637. for (const int * r = d->lits; (other = *r); r++) {
  2638. Val u = lit2val (other), v = vars[other/2].mark;
  2639. if (u != v) break;
  2640. }
  2641. if ((res = !other)) {
  2642. stats.subs.red++;
  2643. limit.budget.red += 20;
  2644. if (!c->lnd && d->lnd) {
  2645. assert (d->binary);
  2646. d->lnd = false;
  2647. stats.clauses.irr++;
  2648. }
  2649. }
  2650. }
  2651. }
  2652. }
  2653. while (q-- > c->lits) {
  2654. assert (vars[*q/2].mark); vars[*q/2].mark = 0;
  2655. }
  2656. if (res) return res;
  2657. if (newsize > 1 && newsize <= opts.redsub && (!c->lnd || c->binary))
  2658. fwds[c->minlit ()].push (mem, c);
  2659. res = newsize <= 1;
  2660. if (!newsize) conflict = &empty;
  2661. else if (newsize == 1) {
  2662. LOG ("learned clause " << c->lits[0]);
  2663. unit (c->lits[0]);
  2664. } else if (newsize == 2 && !c->binary && 2 < c->size) {
  2665. if (c->lnd) assert (stats.clauses.lnd), stats.clauses.lnd--;
  2666. else assert (stats.clauses.orig), stats.clauses.orig--;
  2667. stats.clauses.bin++;
  2668. c->binary = true;
  2669. push (binary, c);
  2670. res = -1;
  2671. } else assert (!res);
  2672. return res;
  2673. }
  2674. void Solver::checkvarstats () {
  2675. #ifndef NDEBUG
  2676. assert (!level);
  2677. int fixed = 0, equivalent = 0, eliminated = 0, pure = 0, zombies = 0;
  2678. for (Var * v = vars + 1; v <= vars + maxvar; v++) {
  2679. int lit = 2 * (v - vars);
  2680. if (v->type == ELIM) eliminated++;
  2681. else if (v->type == PURE) pure++;
  2682. else if (v->type == ZOMBIE) zombies++;
  2683. else if (vals[lit]) { assert (v->type == FIXED); fixed++; }
  2684. else if (repr[lit]) { assert (v->type == EQUIV); equivalent++; }
  2685. else assert (v->type == FREE);
  2686. }
  2687. assert (fixed == stats.vars.fixed);
  2688. assert (eliminated == stats.vars.elim);
  2689. assert (pure == stats.vars.pure);
  2690. assert (zombies == stats.vars.zombies);
  2691. assert (equivalent == stats.vars.equiv);
  2692. #endif
  2693. }
  2694. void Solver::decompose () {
  2695. assert (!level);
  2696. if (!opts.decompose) return;
  2697. report (2, 'd');
  2698. int n = 0;
  2699. size_t bytes = 2 * (maxvar + 1) * sizeof (SCC);
  2700. SCC * sccs = (SCC*) mem.callocate (bytes);
  2701. Stack<int> work;
  2702. saved.shrink ();
  2703. int dfsi = 0;
  2704. LOG ("starting scc decomposition");
  2705. for (int root = 2; !conflict && root <= 2*maxvar + 1; root++) {
  2706. if (sccs[root].idx) { assert (sccs[root].done); continue; }
  2707. assert (!work);
  2708. work.push (mem, root);
  2709. LOG ("new scc root " << root);
  2710. while (!conflict && work) {
  2711. int lit = work.top ();
  2712. if (sccs[lit^1].idx && !sccs[lit^1].done) {
  2713. Val val = vals[lit];
  2714. if (val < 0) {
  2715. LOG ("conflict while learning unit in scc");
  2716. conflict = &empty;
  2717. } else if (!val) {
  2718. LOG ("learned clause " << lit);
  2719. unit (lit);
  2720. stats.sccs.fixed++;
  2721. flush ();
  2722. }
  2723. }
  2724. if (conflict) break;
  2725. Stack<int> & os = occs[1^lit].bins;
  2726. unsigned i = os;
  2727. if (!sccs[lit].idx) {
  2728. assert (!sccs[lit].done);
  2729. sccs[lit].idx = sccs[lit].min = ++dfsi;
  2730. saved.push (mem, lit);
  2731. while (i) {
  2732. int other = os[--i];
  2733. if (sccs[other].idx) continue;
  2734. work.push (mem, other);
  2735. }
  2736. } else {
  2737. work.pop ();
  2738. if (!sccs[lit].done) {
  2739. while (i) {
  2740. int other = os[--i];
  2741. if (sccs[other].done) continue;
  2742. sccs[lit].min = min (sccs[lit].min, sccs[other].min);
  2743. }
  2744. SCC * scc = sccs + lit;
  2745. unsigned min = scc->min;
  2746. if (min != scc->idx) { assert (min < scc->idx); continue; }
  2747. n++; LOG ("new scc " << n);
  2748. int m = 0, prev = 0, other = 0;
  2749. while (!conflict && other != lit) {
  2750. other = saved.pop ();
  2751. sccs[other].done = true;
  2752. LOG ("literal " << other << " added to scc " << n);
  2753. if (prev) {
  2754. int a = find (prev), b = find (other);
  2755. if (a == b) continue;
  2756. if (a == (1^b)) {
  2757. LOG ("conflict while merging scc");
  2758. conflict = &empty;
  2759. } else if (val (a) || val (b)) {
  2760. assert (val (a) == val (b));
  2761. } else {
  2762. merge (prev, other, stats.sccs.merged);
  2763. m++;
  2764. }
  2765. } else prev = other;
  2766. }
  2767. if (m) stats.sccs.nontriv++;
  2768. }
  2769. }
  2770. }
  2771. }
  2772. LOG ("found " << n << " sccs");
  2773. assert (conflict || dfsi <= 2 * maxvar);
  2774. work.release (mem);
  2775. mem.deallocate (sccs, bytes);
  2776. flush ();
  2777. #ifndef NDEBUG
  2778. checkvarstats ();
  2779. #endif
  2780. report (2, 'd');
  2781. }
  2782. void Solver::disconnect () {
  2783. cleangate (), cleantrash ();
  2784. for (int lit = 2; lit <= 2*maxvar + 1; lit++)
  2785. occs[lit].bins.release (mem), occs[lit].large.release (mem);
  2786. assert (!orgs && !fwds && !fwsigs);
  2787. clrbwsigs ();
  2788. }
  2789. void Solver::connect (Anchor<Cls> & anchor, bool orgonly) {
  2790. for (Cls * p = anchor.tail; p; p = p->next) {
  2791. assert (&anchor == &this->anchor (p));
  2792. if (!orgonly || !p->lnd) connect (p);
  2793. }
  2794. }
  2795. void Solver::gc (Anchor<Cls> & anchor, const char * type) {
  2796. limit.budget.red = 10000;
  2797. Cls * p = anchor.tail;
  2798. int collected = 0;
  2799. anchor.head = anchor.tail = 0;
  2800. anchor.count = 0;
  2801. while (p) {
  2802. Cls * next = p->next;
  2803. #ifndef NDEBUG
  2804. p->next = p->prev = 0;
  2805. #endif
  2806. int red = 1;
  2807. if (!p->garbage) {
  2808. red = redundant (p);
  2809. if (red > 0) p->garbage = true;
  2810. }
  2811. if (p->garbage) { collect (p); collected++; }
  2812. else if (!red) push (anchor, p);
  2813. else assert (connected (binary, p));
  2814. p = next;
  2815. }
  2816. #ifndef NLOGPRECO
  2817. if (collected)
  2818. LOG ("collected " << collected << ' ' << type << " clauses");
  2819. #else
  2820. (void) type;
  2821. #endif
  2822. }
  2823. inline void Solver::checkclean () {
  2824. #ifndef NDEBUG
  2825. if (opts.check) {
  2826. for (int i = 0; i <= 3 + opts.glue; i++) {
  2827. Cls * p;
  2828. if (i == 0) p = original.head;
  2829. if (i == 1) p = binary.head;
  2830. if (i == 2) p = fresh.head;
  2831. if (i >= 3) p = learned[i-3].head;
  2832. while (p) {
  2833. for (int * q = p->lits; *q; q++) {
  2834. int lit = *q;
  2835. assert (!repr[lit]);
  2836. assert (!vals[lit]);
  2837. Var * v = vars + (lit/2);
  2838. assert (v->type == FREE);
  2839. }
  2840. p = p->prev;
  2841. }
  2842. }
  2843. }
  2844. #endif
  2845. }
  2846. void Solver::gc () {
  2847. #ifndef NLOGPRECO
  2848. size_t old = stats.collected;
  2849. #endif
  2850. report (2, 'g');
  2851. undo (0);
  2852. disconnect ();
  2853. initfwds ();
  2854. initfwsigs ();
  2855. gc (binary, "binary");
  2856. gc (original, "original");
  2857. gc (fresh, "fresh");
  2858. for (int glue = 0; glue <= opts.glue; glue++) {
  2859. char buffer[80];
  2860. sprintf (buffer, "learned[%u]", glue);
  2861. gc (learned[glue], buffer);
  2862. }
  2863. delfwds ();
  2864. delfwsigs ();
  2865. connect (binary);
  2866. connect (original);
  2867. for (int glue = 0; glue <= opts.glue; glue++)
  2868. connect (learned[glue]);
  2869. connect (fresh);
  2870. checkclean ();
  2871. #ifndef NLOGPRECO
  2872. size_t bytes = stats.collected - old;
  2873. LOG ("collected " << bytes << " bytes");
  2874. dbgprint ();
  2875. #endif
  2876. flush ();
  2877. stats.gcs++;
  2878. report (2, 'c');
  2879. }
  2880. inline int Solver::recyclelimit () const {
  2881. return limit.reduce.learned + stats.clauses.lckd;
  2882. }
  2883. inline bool Solver::recycling () const {
  2884. return stats.clauses.lnd >= recyclelimit ();
  2885. }
  2886. void Solver::reduce () {
  2887. assert (!conflict);
  2888. assert (trail == queue);
  2889. stats.reductions++;
  2890. Cls * f;
  2891. while ((f = fresh.tail)) {
  2892. dequeue (fresh, f);
  2893. assert (f->fresh);
  2894. assert (!f->binary);
  2895. assert (f->lnd);
  2896. f->fresh = false;
  2897. push (anchor (f), f);
  2898. }
  2899. int goal = (stats.clauses.lnd - stats.clauses.lckd)/2, count = 0;
  2900. for (int glue = opts.glue; glue >= opts.sticky && count < goal; glue--) {
  2901. Cls * next;
  2902. for (Cls * p = learned[glue].tail; p && count < goal; p = next) {
  2903. next = p->next;
  2904. if (p->locked) continue;
  2905. p->garbage = true;
  2906. count++;
  2907. }
  2908. }
  2909. gc ();
  2910. jwh ();
  2911. if (count >= goal/2) report (1, '/');
  2912. else report (1, '='), enlarge ();
  2913. }
  2914. inline void Solver::checkeliminated () {
  2915. #ifndef NDEBUG
  2916. if (opts.check) {
  2917. for (int i = 0; i <= 3 + (int)opts.glue; i++) {
  2918. Cls * p;
  2919. if (i == 0) p = original.head;
  2920. if (i == 1) p = binary.head;
  2921. if (i == 1) p = fresh.head;
  2922. if (i >= 3) p = learned[i-3].head;
  2923. while (p) {
  2924. for (int * q = p->lits; *q; q++) {
  2925. int lit = *q;
  2926. Var * v = vars + (lit/2);
  2927. assert (v->type != ELIM);
  2928. }
  2929. p = p->prev;
  2930. }
  2931. }
  2932. }
  2933. #endif
  2934. }
  2935. void Solver::probe () {
  2936. stats.sw2simp ();
  2937. assert (!conflict);
  2938. assert (queue2 == trail);
  2939. undo (0);
  2940. stats.probe.phases++;
  2941. measure = false;
  2942. for (const Rnk * r = rnks + 1; r <= rnks + maxvar; r++) {
  2943. Rnk * p = prb (r);
  2944. int lit = 2 * (r - rnks);
  2945. int old_heat = p->heat;
  2946. int new_heat = jwhs[lit] + jwhs[lit^1];
  2947. if (new_heat < 0) new_heat = INT_MAX;
  2948. p->heat = new_heat;
  2949. if (schedule.probe.contains (p)) {
  2950. if (new_heat > old_heat) schedule.probe.up (p);
  2951. else if (new_heat < old_heat) schedule.probe.down (p);
  2952. }
  2953. }
  2954. int repcounter = 111;
  2955. long long bound;
  2956. if (opts.rtc == 2 || opts.probertc == 2 ||
  2957. ((opts.rtc == 1 || opts.probertc == 1) && !stats.probe.rounds))
  2958. bound = LLONG_MAX;
  2959. else {
  2960. bound = stats.props.simp + opts.probeint;
  2961. for (int i = stats.probe.phases; i <= opts.probeboost; i++)
  2962. bound += opts.probeint;
  2963. }
  2964. int last = -1, filled = 0;
  2965. if (!schedule.probe) {
  2966. FILL:
  2967. filled++;
  2968. for (int idx = 1; idx <= maxvar; idx++) {
  2969. Var & v = vars[idx];
  2970. if (v.type != FREE && v.type != EQUIV) continue;
  2971. int lit = 2 * idx;
  2972. assert (!vals[lit]);
  2973. if (repr[lit]) continue;
  2974. #if 0
  2975. // TODO replace && by '==' for incremental scc computation
  2976. if (!occs[lit].bins == !occs[lit^1].bins) continue;
  2977. #else
  2978. if (!occs[lit].bins && !occs[lit^1].bins) continue;
  2979. #endif
  2980. Rnk * p = prbs + idx;
  2981. schedule.probe.push (mem, p);
  2982. }
  2983. }
  2984. report (2, 'p');
  2985. while (stats.props.simp < bound && !conflict) {
  2986. if (!--repcounter) {
  2987. if (terminal) report (2, 'p');
  2988. repcounter = 111;
  2989. }
  2990. assert (!level);
  2991. if (!schedule.probe) {
  2992. stats.probe.rounds++;
  2993. if (last == filled) goto FILL;
  2994. break;
  2995. }
  2996. Rnk * p = schedule.probe.pop ();
  2997. int idx = p - prbs;
  2998. Var & v = vars[idx];
  2999. if (v.type != FREE && v.type != EQUIV) continue;
  3000. int lit = 2*idx;
  3001. assert (!vals[lit]);
  3002. if (repr[lit]) continue;
  3003. assert (!level);
  3004. long long old = stats.props.simp;
  3005. LOG ("probing " << lit);
  3006. stats.probe.variables++;
  3007. assume (lit);
  3008. bool ok = bcp ();
  3009. undo (0, ok);
  3010. if (!ok) goto FAILEDLIT;
  3011. lit ^= 1;
  3012. LOG ("probing " << lit);
  3013. assume (lit);
  3014. stats.probe.variables++;
  3015. if (!bcp ()) { undo (0); goto FAILEDLIT; }
  3016. {
  3017. int * q = saved.begin (), * eos = saved.end ();
  3018. for (const int * p = q; p < eos; p++) {
  3019. int other = *p;
  3020. if (other == (lit^1)) continue;
  3021. if (vals[other] < 0) merge (lit, other^1, stats.probe.merged);
  3022. if (vals[other] <= 0) continue;
  3023. *q++ = other;
  3024. }
  3025. undo (0);
  3026. if (q == saved.begin ()) continue;
  3027. saved.shrink (q);
  3028. for (const int * p = saved.begin (); p < q; p++) {
  3029. stats.probe.lifted++;
  3030. last = filled;
  3031. int other = *p;
  3032. LOG ("lifting " << other);
  3033. LOG ("learned clause " << other);
  3034. unit (other);
  3035. }
  3036. }
  3037. goto BCPANDINCBOUND;
  3038. FAILEDLIT:
  3039. stats.probe.failed++;
  3040. last = filled;
  3041. LOG ("learned clause " << (1^lit));
  3042. unit (1^lit);
  3043. BCPANDINCBOUND:
  3044. flush ();
  3045. if (bound != LLONG_MAX)
  3046. bound += opts.probereward + (stats.props.simp - old);
  3047. }
  3048. measure = true;
  3049. limit.props.probe = opts.probeprd;
  3050. limit.props.probe *= opts.probeint;
  3051. limit.props.probe += stats.props.srch;
  3052. limit.fixed.probe = stats.vars.fixed;
  3053. checkvarstats ();
  3054. report (2, 'p');
  3055. stats.sw2srch ();
  3056. }
  3057. bool Solver::andgate (int lit) {
  3058. // TODO L2 sigs?
  3059. assert (vars[lit/2].type != ELIM);
  3060. assert (!gate && !gatestats);
  3061. if (!opts.subst) return false;
  3062. if (!opts.ands) return false;
  3063. if (!orgs[lit] || !orgs[1^lit]) return false;
  3064. Cls * b = 0;
  3065. int other, notlit = (1^lit), bound = 1000;
  3066. for (int i = 0; !b && i < orgs[lit] && bound-- >= 0; i++) {
  3067. Cls * c = orgs[lit][i];
  3068. if (!sigsubs (c->sig, bwsigs[lit^1])) continue;
  3069. assert (!gate);
  3070. gcls (c);
  3071. gatelen = 0;
  3072. bool hit = false;
  3073. for (const int * p = c->lits; (other = *p); p++) {
  3074. if (lit == other) { hit = true; continue; }
  3075. assert (!vars[other/2].mark);
  3076. vars[other/2].mark = -lit2val (other);
  3077. gatelen++;
  3078. }
  3079. assert (hit);
  3080. assert (gatelen);
  3081. int count = gatelen;
  3082. for (int j = 0; j < orgs[notlit] && bound-- >= 0; j++) {
  3083. if (orgs[notlit] - j < count) break;
  3084. Cls * d = orgs[notlit][j];
  3085. if (d->lits[2]) continue;
  3086. int pos = (d->lits[1] == notlit);
  3087. assert (d->lits[pos] == notlit);
  3088. assert (d->binary);
  3089. other = d->lits[!pos];
  3090. if (vars[other/2].mark != lit2val (other)) continue;
  3091. vars[other/2].mark = 0;
  3092. gcls (d);
  3093. if (!--count) break;
  3094. }
  3095. for (const int * p = c->lits; (other = *p); p++)
  3096. vars[other/2].mark = 0;
  3097. if (count) cleangate (); else b = c;
  3098. }
  3099. if (!b) { assert (!gate); return false; }
  3100. assert (gate == gatelen + 1);
  3101. gatestats = (gatelen >= 2) ? &stats.subst.ands : &stats.subst.nots;
  3102. gatepivot = lit;
  3103. posgate = 1;
  3104. #ifndef NLOGPRECO
  3105. printf ("%sLOG %s gate %d = ", prfx, (gatelen >= 2) ? "and" : "not", lit);
  3106. for (const int * p = b->lits; (other = *p); p++) {
  3107. if (other == lit) continue;
  3108. printf ("%d", (1^other));
  3109. if (p[1] && (p[1] != lit || p[2])) fputs (" & ", stdout);
  3110. }
  3111. fputc ('\n', stdout);
  3112. dbgprintgate ();
  3113. #endif
  3114. return true;
  3115. }
  3116. bool Solver::xorgate (int lit) {
  3117. // TODO L2 sigs
  3118. assert (vars[lit/2].type != ELIM);
  3119. assert (!gate && !gatestats);
  3120. if (!opts.subst) return false;
  3121. if (!opts.xors) return false;
  3122. if (orgs[lit] < 2 || orgs[1^lit] < 2) return false;
  3123. if (orgs[lit] > orgs[1^lit]) lit ^= 1;
  3124. Cls * b = 0;
  3125. int len = 0, other, bound = 600;
  3126. for (int i = 0; i < orgs[lit] && !b && bound-- >= 0; i++) {
  3127. Cls * c = orgs[lit][i];
  3128. const int maxlen = 20;
  3129. assert (maxlen < 31);
  3130. if (c->size > (unsigned) maxlen) continue;
  3131. if (!c->lits[2]) continue;
  3132. assert (!c->binary);
  3133. if (!sigsubs (c->sig, bwsigs[lit^1])) continue;
  3134. int * p;
  3135. for (p = c->lits; *p; p++)
  3136. ;
  3137. len = p - c->lits;
  3138. assert (len >= 3);
  3139. int required = (1 << (len-1));
  3140. for (p = c->lits; (other = *p); p++) {
  3141. if (other == lit) continue;
  3142. if (orgs[other] < required) break;
  3143. if (orgs[other^1] < required) break;
  3144. if (!sigsubs (c->sig, bwsigs[other])) break;
  3145. if (!sigsubs (c->sig, bwsigs[1^other])) break;
  3146. }
  3147. if (other) continue;
  3148. assert (!gate);
  3149. assert (0 < len && len <= maxlen);
  3150. unsigned signs;
  3151. for (signs = 0; signs < (1u<<len) && bound-- >= 0; signs++) {
  3152. if (parity (signs)) continue;
  3153. int start = 0, startlen = INT_MAX, s = 0;
  3154. for (p = c->lits; (other = *p); p++, s++) {
  3155. if ((signs & (1u<<s))) other ^= 1;
  3156. int tmp = orgs[other];
  3157. if (start && tmp >= startlen) continue;
  3158. startlen = tmp;
  3159. start = other;
  3160. }
  3161. assert (s == len && start && startlen < INT_MAX);
  3162. int j;
  3163. Cls * found = 0;
  3164. for (j = 0; !found && j < orgs[start] && bound-- >= 0; j++) {
  3165. Cls * d = orgs[start][j];
  3166. if (d->sig != c->sig) continue;
  3167. for (p = d->lits; *p; p++)
  3168. ;
  3169. if (p - d->lits != len) continue;
  3170. bool hit = false;
  3171. s = 0;
  3172. for (p = c->lits; (other = *p); p++, s++) {
  3173. if ((signs & (1u<<s))) other ^= 1;
  3174. if (other == start) { hit = true; continue; }
  3175. if (!d->contains (other)) break;
  3176. }
  3177. assert (other || hit);
  3178. if (!other) found = d;
  3179. }
  3180. assert (bound < 0 || signs || found);
  3181. if (!found) break;
  3182. assert (required);
  3183. required--;
  3184. gcls (found);
  3185. }
  3186. if (signs == (1u<<len)) { assert (!required); b = c; }
  3187. else cleangate ();
  3188. }
  3189. if (!b) { assert (!gate); return false; }
  3190. assert (len >= 3);
  3191. assert (gate == (1<<(len-1)));
  3192. gatepivot = lit;
  3193. gatestats = &stats.subst.xors;
  3194. gatelen = len - 1;
  3195. int pos = -1, neg = gate;
  3196. for (;;) {
  3197. while (pos+1 < neg && gate[pos+1]->contains (lit)) pos++;
  3198. assert (pos >= gate || gate[pos+1]->contains(1^lit));
  3199. if (pos+1 == neg) break;
  3200. while (pos < neg-1 && gate[neg-1]->contains ((1^lit))) neg--;
  3201. assert (neg < 0 || gate[neg-1]->contains(lit));
  3202. if (pos+1 == neg) break;
  3203. assert (pos < neg);
  3204. swap (gate[++pos], gate[--neg]);
  3205. }
  3206. posgate = pos + 1;
  3207. #ifndef NLOGPRECO
  3208. printf ("%sLOG %d-ary xor gate %d = ", prfx, len-1, (lit^1));
  3209. for (const int * p = b->lits; (other = *p); p++) {
  3210. if (other == lit) continue;
  3211. printf ("%d", other);
  3212. if (p[1] && (p[1] != lit || p[2])) fputs (" ^ ", stdout);
  3213. }
  3214. fputc ('\n', stdout);
  3215. dbgprintgate ();
  3216. #endif
  3217. return true;
  3218. }
  3219. Cls * Solver::find (int a, int b, int c) {
  3220. unsigned sig = listig (a) | listig (b) | listig (c);
  3221. unsigned all = bwsigs[a] & bwsigs[b] & bwsigs[c];
  3222. if (!sigsubs (sig, all)) return 0;
  3223. int start = a;
  3224. if (orgs[start] > orgs[b]) start = b;
  3225. if (orgs[start] > orgs[c]) start = c;
  3226. for (int i = 0; i < orgs[start]; i++) {
  3227. Cls * res = orgs[start][i];
  3228. if (res->sig != sig) continue;
  3229. assert (res->lits[0] && res->lits[1]);
  3230. if (!res->lits[2]) continue;
  3231. assert (!res->binary);
  3232. if (res->lits[3]) continue;
  3233. int l0 = res->lits[0], l1 = res->lits[1], l2 = res->lits[2];
  3234. if ((a == l0 && b == l1 && c == l2) ||
  3235. (a == l0 && b == l2 && c == l1) ||
  3236. (a == l1 && b == l0 && c == l2) ||
  3237. (a == l1 && b == l2 && c == l0) ||
  3238. (a == l2 && b == l0 && c == l1) ||
  3239. (a == l2 && b == l1 && c == l2)) return res;
  3240. }
  3241. return 0;
  3242. }
  3243. int Solver::itegate (int lit, int cond, int t) {
  3244. Cls * c = find (lit^1, cond, t^1);
  3245. if (!c) return 0;
  3246. int start = lit, nc = (cond^1), bound = 200;
  3247. if (orgs[nc] < orgs[start]) start = nc;
  3248. unsigned sig = listig (lit) | listig (nc);
  3249. for (int i = 0; i < orgs[start] && --bound >= 0; i++) {
  3250. Cls * d = orgs[start][i];
  3251. if (!sigsubs (sig, d->sig)) continue;
  3252. assert (d->lits[0] && d->lits[1]);
  3253. if (!d->lits[2]) continue;
  3254. assert (!d->binary);
  3255. if (d->lits[3]) continue;
  3256. int l0 = d->lits[0], l1 = d->lits[1], l2 = d->lits[2], res;
  3257. if (l0 == lit && l1 == nc) res = l2;
  3258. else if (l1 == lit && l0 == nc) res = l2;
  3259. else if (l0 == lit && l2 == nc) res = l1;
  3260. else if (l2 == lit && l0 == nc) res = l1;
  3261. else if (l1 == lit && l2 == nc) res = l0;
  3262. else if (l2 == lit && l1 == nc) res = l0;
  3263. else continue;
  3264. Cls * e = find (lit^1, nc, res^1);
  3265. if (!e) continue;
  3266. gcls (d);
  3267. gcls (c);
  3268. gcls (e);
  3269. return res;
  3270. }
  3271. return 0;
  3272. }
  3273. bool Solver::itegate (int lit) {
  3274. // TODO L2 sigs
  3275. assert (vars[lit/2].type != ELIM);
  3276. assert (!gate && !gatestats);
  3277. if (!opts.subst) return false;
  3278. if (!opts.ites) return false;
  3279. if (orgs[lit] < 2 || orgs[1^lit] < 2) return false;
  3280. if (orgs[lit] > orgs[1^lit]) lit ^= 1;
  3281. Cls * b = 0;
  3282. int cond = 0, t = 0, e = 0;
  3283. for (int i = 0; i < orgs[lit] && !b; i++) {
  3284. Cls * c = orgs[lit][i];
  3285. assert (c->lits[0] && c->lits[1]);
  3286. if (!c->lits[2]) continue;
  3287. assert (!c->binary);
  3288. if (c->lits[3]) continue;
  3289. assert (!gate);
  3290. int o0, o1, l0 = c->lits[0], l1 = c->lits[1], l2 = c->lits[2];
  3291. if (lit == l0) o0 = l1, o1 = l2;
  3292. else if (lit == l1) o0 = l0, o1 = l2;
  3293. else assert (lit == l2), o0 = l0, o1 = l1;
  3294. assert (!gate);
  3295. gcls (c);
  3296. if ((e = itegate (lit, cond = o0, t = o1)) ||
  3297. (e = itegate (lit, cond = o1, t = o0))) b = c;
  3298. else cleangate ();
  3299. }
  3300. if (!b) { assert (!gate); return false; }
  3301. assert (cond && t && e);
  3302. assert (gate == 4);
  3303. gatestats = &stats.subst.ites;
  3304. gatepivot = lit;
  3305. posgate = 2;
  3306. #ifndef NLOGPRECO
  3307. LOG ("ite gate " << lit << " = " <<
  3308. (1^cond) << " ? " << (1^t) << " : " << (1^e));
  3309. dbgprintgate ();
  3310. #endif
  3311. return true;
  3312. }
  3313. bool Solver::resolve (Cls * c, int pivot, Cls * d, bool tryonly) {
  3314. if (tryonly) resotfs = reslimhit = false;
  3315. assert (tryonly || (c->dirty && d->dirty));
  3316. assert (tryonly != (vars[pivot/2].type == ELIM));
  3317. assert (!vals[pivot] && !repr[pivot]);
  3318. if (!tryonly && gate && c->gate == d->gate) return false;
  3319. if (elimode) stats.elim.resolutions++;
  3320. else { assert (blkmode); stats.blkd.resolutions++; }
  3321. int other, notpivot = (1^pivot), clits = 0, dlits = 0;
  3322. bool found = false, res = true;
  3323. const int * p;
  3324. assert (!lits);
  3325. for (p = c->lits; (other = *p); p++) {
  3326. if (other == pivot) { found = true; continue; }
  3327. assert (other != notpivot);
  3328. assert (find (other) == other);
  3329. assert (other != notpivot);
  3330. if (other == pivot) continue;
  3331. Val v = vals [other];
  3332. if (v < 0) continue;
  3333. if (v > 0) { res = false; goto DONE; }
  3334. assert (!vars[other/2].mark);
  3335. Val u = lit2val (other);
  3336. vars[other/2].mark = u;
  3337. lits.push (mem, other);
  3338. clits++;
  3339. }
  3340. assert (found);
  3341. found = false;
  3342. for (p = d->lits; (other = *p); p++) {
  3343. if (other == notpivot) { found = true; continue; }
  3344. assert (other != pivot);
  3345. assert (find (other) == other);
  3346. assert (other != pivot);
  3347. if (other == notpivot) continue;
  3348. Val v = vals[other];
  3349. if (v < 0) continue;
  3350. if (v > 0) { res = false; goto DONE; }
  3351. dlits++;
  3352. v = vars[other/2].mark;
  3353. Val u = lit2val (other);
  3354. if (!v) {
  3355. vars[other/2].mark = u;
  3356. lits.push (mem, other);
  3357. } else if (v != u) { res = false; goto DONE; }
  3358. }
  3359. assert (found);
  3360. if (opts.otfs && tryonly) {
  3361. #ifndef NLOGPRECO
  3362. bool logresolvent = false;
  3363. #endif
  3364. if (lits == clits && (!blkmode || opts.blockotfs)) {
  3365. #ifndef NLOGPRECO
  3366. dbgprint ("LOG static on-the-fly strengthened clause ", c);
  3367. dbgprint ("LOG static on-the-fly antecedent ", d);
  3368. logresolvent = true;
  3369. #endif
  3370. if (c->gate) cleangate ();
  3371. remove (pivot, c);
  3372. resotfs = true;
  3373. if (clits == 1) stats.otfs.stat.bin++;
  3374. else if (clits == 2) stats.otfs.stat.trn++;
  3375. else stats.otfs.stat.large++;
  3376. }
  3377. if (lits == dlits && (!blkmode || opts.blockotfs)) {
  3378. #ifndef NLOGPRECO
  3379. dbgprint ("LOG static on-the-fly strengthened clause ", d);
  3380. dbgprint ("LOG static on-the-fly antecedent ", c);
  3381. logresolvent = true;
  3382. #endif
  3383. if (d->gate) cleangate ();
  3384. remove (notpivot, d);
  3385. resotfs = true;
  3386. if (dlits == 1) stats.otfs.stat.bin++;
  3387. else if (dlits == 2) stats.otfs.stat.trn++;
  3388. else stats.otfs.stat.large++;
  3389. }
  3390. #ifndef NLOGPRECO
  3391. if (logresolvent) {
  3392. printf ("%sLOG static on-the-fly subsuming resolvent", prfx);
  3393. for (p = lits.begin (); p < lits.end (); p++) printf (" %d", *p);
  3394. fputc ('\n', stdout);
  3395. }
  3396. #endif
  3397. }
  3398. DONE:
  3399. for (p = lits.begin (); p < lits.end (); p++) {
  3400. Var * u = vars + (*p/2);
  3401. assert (u->mark);
  3402. u->mark = 0;
  3403. }
  3404. if (res) {
  3405. if (!lits) {
  3406. LOG ("conflict in resolving clauses");
  3407. conflict = &empty;
  3408. res = false;
  3409. } else if (lits == 1) {
  3410. LOG ("learned clause " << lits[0]);
  3411. unit (lits[0]);
  3412. res = false;
  3413. } else if (!tryonly) {
  3414. if (!fworgs ()) {
  3415. bworgs ();
  3416. clause (false, 0);
  3417. }
  3418. } else {
  3419. if (lits > opts.reslim) reslimhit = true;
  3420. }
  3421. }
  3422. lits.shrink ();
  3423. return res;
  3424. }
  3425. inline void Solver::checkgate () {
  3426. #ifndef NDEBUG
  3427. for (int i = 0; i < posgate; i++) assert (gate[i]->contains (gatepivot));
  3428. for (int i = posgate; i < gate; i++) assert (gate[i]->contains (1^gatepivot));
  3429. for (int i = 0; i < posgate; i++)
  3430. for (int j = posgate; j < gate; j++)
  3431. assert (!resolve (gate[i], gatepivot, gate[j], true));
  3432. #endif
  3433. }
  3434. inline void Solver::block (Cls * c, int lit) {
  3435. assert (opts.block);
  3436. #ifndef NLOGPRECO
  3437. dbgprint ("LOG blocked clause ", c);
  3438. LOG ("blocked on literal " << lit);
  3439. #endif
  3440. assert (!blklit);
  3441. blklit = lit;
  3442. if (c->gate) cleangate ();
  3443. elits.push (mem, 0);
  3444. bool found = false;
  3445. int other;
  3446. for (const int * p = c->lits; (other = *p); p++) {
  3447. if (other == lit) { found = true; continue; }
  3448. elits.push (mem, other);
  3449. }
  3450. assert (found);
  3451. elits.push (mem, lit);
  3452. elits.push (mem, INT_MAX);
  3453. // NOTE: we can not simply turn binary blocked clauses
  3454. // into learned clauses, which can be removed without
  3455. // any further check in the future, because adding
  3456. // resolvents to the CNF (either through learning,
  3457. // elimination, dominator clauses etc) may unblock
  3458. // clauses. These binary clauses would need to
  3459. // be treated differently in all operations that
  3460. // remove clauses from the CNF.
  3461. recycle (c);
  3462. blklit = 0;
  3463. }
  3464. bool Solver::trelim (int idx) {
  3465. assert (!elimvar);
  3466. assert (!conflict);
  3467. assert (queue == trail);
  3468. assert (vars[idx].type == FREE);
  3469. RESTART:
  3470. int lit = 2*idx, pos = orgs[lit], neg = orgs[lit^1];
  3471. if (val (lit)) return false;
  3472. if (opts.elimgain <= 1 && (pos <= 1 || neg <= 1)) return true;
  3473. if (opts.elimgain <= 0 && pos <= 2 && neg <= 2) return true;
  3474. LOG ("trelim " << lit << " bound " << elms[idx].heat);
  3475. if (gate) LOG ("actually trelim gate for " << gatepivot);
  3476. for (int sign = 0; sign <= 1; sign++)
  3477. for (int i = 0; i < orgs[lit^sign]; i++)
  3478. if (orgs[lit^sign][i]->size > (unsigned)opts.elimclim)
  3479. return false;
  3480. int gain = pos + neg, l = opts.elimgain, found, i, j;
  3481. Cls * c, * d;
  3482. if (gate) {
  3483. assert (gatepivot/2 == lit/2);
  3484. int piv, s0, e0, s1, e1;
  3485. piv = gatepivot;
  3486. s0 = 0, e0 = posgate;
  3487. s1 = posgate, e1 = gate;
  3488. for (i = s0; !conflict && i < e0 && gain >= l; i++) {
  3489. found = 0;
  3490. c = gate[i];
  3491. for (j = 0; !conflict && gain >= l && j < orgs[piv^1]; j++) {
  3492. d = orgs[piv^1][j];
  3493. if (d->gate) continue;
  3494. if (resolve (c, piv, d, true)) gain--, found++;
  3495. if (needtoflush ()) { if (!flush ()) return false; goto RESTART; }
  3496. if (val (piv)) return false;
  3497. if (resotfs) goto RESTART;
  3498. if (reslimhit) gain = INT_MIN, found++;
  3499. }
  3500. if (opts.block && opts.blockimpl && !found) { lit = piv; goto BLKD; }
  3501. }
  3502. for (i = s1; !conflict && i < e1 && gain >= l; i++) {
  3503. found = 0;
  3504. c = gate[i];
  3505. for (j = 0; !conflict && gain >= l && j < orgs[piv]; j++) {
  3506. d = orgs[piv][j];
  3507. if (d->gate) continue;
  3508. if (resolve (d, piv, c, true)) gain--, found++;
  3509. if (needtoflush ()) { if (!flush ()) return false; goto RESTART; }
  3510. if (val (piv)) return false;
  3511. if (resotfs) goto RESTART;
  3512. if (reslimhit) gain = INT_MIN, found++;
  3513. }
  3514. if (opts.block && opts.blockimpl && !found) { lit = 1^piv; goto BLKD; }
  3515. }
  3516. } else {
  3517. for (i = 0; !conflict && gain >= l && i < orgs[lit]; i++) {
  3518. found = 0;
  3519. c = orgs[lit][i];
  3520. for (j = 0; !conflict && gain >= l && j < orgs[lit^1]; j++) {
  3521. d = orgs[lit^1][j];
  3522. if (resolve (c, lit, d, true)) gain--, found++;
  3523. if (needtoflush ()) { if (!flush ()) return false; goto RESTART; }
  3524. if (val (lit)) return false;
  3525. if (resotfs) goto RESTART;
  3526. if (reslimhit) gain = INT_MIN, found++;
  3527. }
  3528. if (opts.block && opts.blockimpl && !found) {
  3529. BLKD:
  3530. block (c, lit);
  3531. stats.blkd.impl++;
  3532. goto RESTART;
  3533. }
  3534. }
  3535. }
  3536. if (conflict) return false;
  3537. LOG ("approximated gain for " << lit << " is " << gain);
  3538. if (!val (lit) && gain < l) {
  3539. measure = false;
  3540. asymode = true;
  3541. ASYMMAGAIN:
  3542. for (int sign = 0; sign <= 1; sign++, lit^=1) {
  3543. if (orgs[lit] < 2) goto DONE;
  3544. assert (!val (lit));
  3545. if (orgs[lit] <= opts.elimasym) {
  3546. if (limit.props.asym < 0) goto DONE;
  3547. long long old = stats.props.simp;
  3548. LOG ("trying to eliminate one out of " << orgs[lit] <<
  3549. " occurences of " << lit);
  3550. for (i = orgs[lit]-1; !conflict && i >= 0; i--) {
  3551. Cls * c = orgs[lit][i];
  3552. if (c->gate) continue;
  3553. #ifndef NLOGPRECO
  3554. dbgprint ("LOG trying to eliminate literal from ", c);
  3555. #endif
  3556. assert (c->lits[1]);
  3557. assume (lit);
  3558. bool ok = bcp (), fl = true;
  3559. int other;
  3560. for (const int * p = c->lits; ok && (other = *p); p++) {
  3561. if (val (other)) continue;
  3562. assert (other != lit);
  3563. assume (other^1);
  3564. ok = bcp ();
  3565. fl = false;
  3566. }
  3567. undo (0);
  3568. if (ok) {
  3569. limit.props.asym -= stats.props.simp - old;
  3570. continue;
  3571. }
  3572. stats.str.asym++;
  3573. LOG ("asymmetric branching eliminates literal " << lit);
  3574. if (fl) assign (lit^1); else remove (lit, c);
  3575. limit.props.asym += opts.elimasymreward;
  3576. if (val (lit)) goto DONE;
  3577. if (needtoflush ()) {
  3578. if (!flush ()) goto DONE;
  3579. if (val (lit)) goto DONE;
  3580. goto ASYMMAGAIN;
  3581. }
  3582. if (orgs[lit] < 2) goto DONE;
  3583. if (orgs[lit] == 2 && orgs[lit^1] == 2) goto DONE;
  3584. }
  3585. }
  3586. }
  3587. DONE:
  3588. measure = true;
  3589. asymode = false;
  3590. if (conflict) return false;
  3591. if (vals[lit]) return false;
  3592. if (opts.elimgain <= 1 && (orgs[lit] <= 1 || orgs[1^lit] <= 1))
  3593. return true;
  3594. if (opts.elimgain <= 0 && orgs[lit] <= 2 && orgs[1^lit] <= 2)
  3595. return true;
  3596. }
  3597. return gain >= l;
  3598. }
  3599. void Solver::elim (int idx) {
  3600. assert (!elimvar);
  3601. elimvar = idx;
  3602. int lit = 2 * idx;
  3603. assert (!conflict);
  3604. assert (!units);
  3605. assert (queue == trail);
  3606. assert (vars[idx].type == FREE);
  3607. assert (!vals[lit]);
  3608. assert (!repr[lit]);
  3609. #if 0
  3610. #ifndef NLOGPRECO
  3611. dbgprint ();
  3612. #endif
  3613. #endif
  3614. LOG ("elim " << lit);
  3615. assert (!vals[lit] && !repr[lit]);
  3616. {
  3617. int slit;
  3618. Cls ** begin, ** end;
  3619. if (gate) {
  3620. slit = gatepivot;
  3621. int pos = posgate;
  3622. int neg = gate - pos;
  3623. assert (pos > 0 && neg > 0);
  3624. begin = gate.begin ();
  3625. if (pos < neg) end = begin + posgate;
  3626. else begin += posgate, end = gate.end (), slit ^= 1;
  3627. } else {
  3628. slit = lit;
  3629. int pos = orgs[lit];
  3630. int neg = orgs[lit^1];
  3631. if (!pos && !neg) zombie (vars + idx);
  3632. else if (!pos) pure (lit^1);
  3633. else if (!neg) pure (lit);
  3634. if (!pos || !neg) { elimvar = 0; return; }
  3635. if (pos < neg) begin = orgs[lit].begin (), end = orgs[lit].end ();
  3636. else begin = orgs[1^lit].begin (), end = orgs[1^lit].end (), slit ^= 1;
  3637. }
  3638. elits.push (mem, 0);
  3639. LOG ("elit 0");
  3640. for (Cls ** p = begin; p < end; p++) {
  3641. elits.push (mem, 0);
  3642. LOG ("elit 0");
  3643. Cls * c = *p;
  3644. int other;
  3645. for (int * p = c->lits; (other = *p); p++) {
  3646. if (other == (slit)) continue;
  3647. assert (other != (1^slit));
  3648. elits.push (mem, other);
  3649. LOG ("elit " << other);
  3650. }
  3651. }
  3652. elits.push (mem, slit);
  3653. LOG ("elit " << slit);
  3654. elits.push (mem, 0);
  3655. }
  3656. vars[idx].type = ELIM;
  3657. stats.vars.elim++;
  3658. for (int sign = 0; sign <= 1; sign++)
  3659. for (int i = 0; i < orgs[lit^sign]; i++) {
  3660. Cls * c = orgs[lit^sign][i];
  3661. c->dirty = true;
  3662. }
  3663. int gatecount = gate;
  3664. if (gatecount) {
  3665. LOG ("actually elim gate for " << gatepivot);
  3666. assert (gatepivot/2 == lit/2);
  3667. int piv = gatepivot;
  3668. for (int i = 0; !conflict && i < posgate; i++)
  3669. for (int j = 0; !conflict && j < orgs[piv^1]; j++)
  3670. resolve (gate[i], piv, orgs[piv^1][j], false);
  3671. for (int i = posgate; !conflict && i < gate; i++)
  3672. for (int j = 0; !conflict && j < orgs[piv]; j++)
  3673. resolve (orgs[piv][j], piv, gate[i], false);
  3674. } else {
  3675. for (int i = 0; !conflict && i < orgs[lit]; i++)
  3676. for (int j = 0; !conflict && j < orgs[lit^1]; j++)
  3677. resolve (orgs[lit][i], lit, orgs[lit^1][j], false);
  3678. }
  3679. for (int sign = 0; sign <= 1; sign++)
  3680. for (int i = 0; i < orgs[lit^sign]; i++)
  3681. orgs[lit^sign][i]->dirty = false;
  3682. assert (gate == gatecount);
  3683. cleangate (), cleantrash ();
  3684. for (int sign = 0; sign <= 1; sign++)
  3685. recycle (lit^sign);
  3686. elimvar = 0;
  3687. }
  3688. inline long long Solver::clauses () const {
  3689. return stats.clauses.orig + stats.clauses.lnd + stats.clauses.bin;
  3690. }
  3691. inline bool Solver::hasgate (int idx) {
  3692. assert (0 < idx && idx <= maxvar);
  3693. assert (!gate);
  3694. int lit = 2*idx;
  3695. if (andgate (lit)) return true;
  3696. if (andgate (1^lit)) return true;
  3697. if (xorgate (lit)) return true;
  3698. if (itegate (lit)) return true;
  3699. return false;
  3700. }
  3701. void Solver::cleans () {
  3702. assert (!level);
  3703. assert (elimode || blkmode);
  3704. assert (orgs);
  3705. for (int i = 0; i <= 3 + (int)opts.glue; i++) {
  3706. Cls * p = 0;
  3707. if (i == 0) p = binary.head;
  3708. if (i == 1) p = original.head;
  3709. if (i == 2) p = fresh.head;
  3710. if (i >= 3) p = learned[i-3].head;
  3711. while (p) {
  3712. assert (!p->locked); assert (!p->garbage);
  3713. Cls * prev = p->prev;
  3714. int other;
  3715. for (int * q = p->lits; (other = *q); q++) {
  3716. Var * v = vars + (other/2);
  3717. if (v->type == FREE) continue;
  3718. if (v->type == FIXED) continue;
  3719. break;
  3720. }
  3721. if (other) { /*assert (p->lnd);*/ p->garbage = true; }
  3722. p = prev;
  3723. }
  3724. }
  3725. }
  3726. void Solver::elim () {
  3727. if (!eliminating ()) return;
  3728. stats.elim.phases++;
  3729. elimode = true;
  3730. elimvar = 0;
  3731. checkclean ();
  3732. disconnect ();
  3733. initorgs ();
  3734. initfwds ();
  3735. initfwsigs ();
  3736. clrbwsigs ();
  3737. connect (binary, true);
  3738. connect (original, true);
  3739. if (!flush ()) return;
  3740. int repcounter = 111;
  3741. long long bound;
  3742. limit.budget.bw.sub = limit.budget.fw.sub = opts.elimint;
  3743. limit.budget.bw.str = limit.budget.fw.str = opts.elimint;
  3744. if (opts.rtc == 2 || opts.elimrtc == 2 ||
  3745. ((opts.rtc == 1 || opts.elimrtc == 1) && !stats.elim.rounds))
  3746. bound = LLONG_MAX;
  3747. else {
  3748. bound = stats.elim.resolutions + opts.elimint;
  3749. for (int i = stats.elim.phases; i <= opts.elimboost; i++)
  3750. bound += opts.elimint;
  3751. }
  3752. limit.props.asym = opts.elimasymint;
  3753. if (schedule.elim) {
  3754. for (int idx = 1; idx <= maxvar; idx++) {
  3755. int lit = 2*idx, pos = orgs[lit], neg = orgs[lit^1];
  3756. if (pos <= 2 || neg <= 2 || schedule.elim.contains (elms + idx))
  3757. touch (lit);
  3758. }
  3759. } else {
  3760. for (int idx = 1; idx <= maxvar; idx++) touch (2*idx);
  3761. }
  3762. pure ();
  3763. report (2, 'e');
  3764. while (!conflict && schedule.elim) {
  3765. Rnk * e = schedule.elim.max ();
  3766. int idx = e - elms, lit = 2*idx, pos = orgs[lit], neg = orgs[1^lit];
  3767. if (pos > 1 && neg > 1 && (pos > 2 || neg > 2))
  3768. if (stats.elim.resolutions > bound) break;
  3769. if (!--repcounter) {
  3770. if (terminal) report (2, 'e');
  3771. repcounter = 111;
  3772. }
  3773. (void) schedule.elim.pop ();
  3774. Var * v = vars + idx;
  3775. if (v->type != FREE) continue;
  3776. if (!pos && !neg) zombie (vars + idx);
  3777. else if (!pos) pure (lit^1);
  3778. else if (!neg) pure (lit);
  3779. else {
  3780. if (hasgate (idx)) assert (gatestats), checkgate ();
  3781. bool eliminate = trelim (idx);
  3782. if (needtoflush () && !flush ()) break;
  3783. if (!eliminate || vals[lit]) { cleangate (); continue; }
  3784. if (gatestats) {
  3785. gatestats->count += 1;
  3786. gatestats->len += gatelen;
  3787. stats.vars.subst++;
  3788. }
  3789. elim (idx);
  3790. if (needtoflush () && !flush ()) break;
  3791. if (bound != LLONG_MAX) bound += opts.elimreward;
  3792. }
  3793. }
  3794. report (2, 'e');
  3795. #ifndef NDEBUG
  3796. for (int idx = 1; !conflict && idx <= maxvar; idx++) {
  3797. if (vars[idx].type != FREE) continue;
  3798. if (elms[idx].pos == -1) continue;
  3799. int lit = 2*idx, pos = orgs[lit], neg = orgs[lit+1];
  3800. assert (pos >= 2);
  3801. assert (neg >= 2);
  3802. assert (pos != 2 || neg != 2);
  3803. }
  3804. #endif
  3805. if (conflict) return;
  3806. assert (!gate);
  3807. assert (!trash);
  3808. if (bound != LLONG_MAX) pure ();
  3809. cleans ();
  3810. delorgs ();
  3811. delfwds ();
  3812. delfwsigs ();
  3813. gc ();
  3814. checkeliminated ();
  3815. elimode = false;
  3816. if (!schedule.elim) {
  3817. stats.elim.rounds++;
  3818. limit.fixed.elim = remvars ();
  3819. }
  3820. limit.props.elim = opts.elimprd;
  3821. limit.props.elim *= opts.elimint;
  3822. limit.props.elim += stats.props.srch;
  3823. checkvarstats ();
  3824. }
  3825. void Solver::zombie (Var * v) {
  3826. assert (elimode || blkmode);
  3827. assert (!level);
  3828. assert (v->type == FREE);
  3829. int idx = v - vars, lit = 2*idx;
  3830. assert (!val (lit));
  3831. assert (!orgs[lit]);
  3832. assert (!orgs[lit^1]);
  3833. assert (!repr [lit]);
  3834. if (puremode) {
  3835. LOG ("explicit zombie literal " << lit);
  3836. stats.zombies.expl++;
  3837. } else if (blkmode) {
  3838. LOG ("blocking zombie literal " << lit);
  3839. stats.zombies.blkd++;
  3840. } else {
  3841. assert (elimode);
  3842. LOG ("eliminating zombie literal " << lit);
  3843. stats.zombies.elim++;
  3844. }
  3845. stats.vars.zombies++;
  3846. v->type = ZOMBIE;
  3847. assume (lit, false);
  3848. recycle (lit);
  3849. recycle (lit^1);
  3850. flush ();
  3851. assert (!conflict);
  3852. }
  3853. void Solver::pure (int lit) {
  3854. assert (elimode || blkmode);
  3855. assert (!level);
  3856. assert (!val (lit));
  3857. assert (!orgs[lit^1]);
  3858. assert (!repr [lit]);
  3859. Var * v = vars + (lit/2);
  3860. assert (v->type == FREE);
  3861. if (puremode) {
  3862. LOG ("explicit pure literal " << lit);
  3863. stats.pure.expl++;
  3864. } else if (blkmode) {
  3865. LOG ("blocking pure literal " << lit);
  3866. stats.pure.blkd++;
  3867. } else {
  3868. assert (elimode);
  3869. LOG ("eliminating pure literal " << lit);
  3870. stats.pure.elim++;
  3871. }
  3872. stats.vars.pure++;
  3873. v->type = PURE;
  3874. assume (lit, false);
  3875. flush ();
  3876. assert (!conflict);
  3877. }
  3878. void Solver::block () {
  3879. if (!blocking ()) return;
  3880. stats.blkd.phases++;
  3881. blkmode = true;
  3882. blklit = 0;
  3883. checkclean ();
  3884. disconnect ();
  3885. initorgs ();
  3886. connect (binary, true);
  3887. connect (original, true);
  3888. if (!flush ()) return;
  3889. int repcounter = 111;
  3890. long long bound;
  3891. if (opts.rtc == 2 || opts.blockrtc == 2 ||
  3892. ((opts.rtc == 1 || opts.blockrtc == 1) && !stats.blkd.rounds)) {
  3893. bound = LLONG_MAX;
  3894. } else {
  3895. bound = stats.blkd.resolutions + opts.blockint;
  3896. for (int i = stats.blkd.phases; i <= opts.blockboost; i++)
  3897. bound += opts.blockint;
  3898. }
  3899. if (schedule.block) {
  3900. for (int lit = 2; lit <= 2*maxvar+1; lit++)
  3901. if (schedule.block.contains (blks + lit)) touchblkd (lit);
  3902. } else {
  3903. for (int lit = 2; lit <= 2*maxvar+1; lit++) touchblkd (lit);
  3904. }
  3905. pure ();
  3906. report (2, 'k');
  3907. while (!conflict && schedule.block && stats.blkd.resolutions <= bound) {
  3908. Rnk * b = schedule.block.pop ();
  3909. int lit = b - blks;
  3910. if (!repcounter--) {
  3911. if (terminal) report (2, 'k');
  3912. repcounter = 111;
  3913. }
  3914. RESTART:
  3915. Var * v = vars + (lit/2);
  3916. if (v->type != FREE) continue;
  3917. int pos = orgs[lit], neg = orgs[1^lit];
  3918. if (!pos && !neg) zombie (v);
  3919. else if (!pos) pure (1^lit);
  3920. else if (!neg) pure (lit);
  3921. else if (orgs[lit] <= opts.blkmaxlen || orgs[1^lit] <= opts.blkmaxlen) {
  3922. assert (!val (lit));
  3923. if (orgs[1^lit] > opts.blkmaxlen) continue;
  3924. LOG ("tryblk " << lit);
  3925. for (int i = orgs[lit]-1; !conflict && i >= 0; i--) {
  3926. Cls * c = orgs[lit][i];
  3927. bool blocked = true;
  3928. for (int j = 0; !conflict && blocked && j < orgs[lit^1]; j++) {
  3929. blocked = !resolve (c, lit, orgs[lit^1][j], true);
  3930. if (needtoflush ()) { if (!flush ()) goto DONE; goto RESTART; }
  3931. if (blocked && resotfs) goto RESTART;
  3932. }
  3933. if (!blocked) continue;
  3934. if (conflict) break;
  3935. if (val (lit)) break;
  3936. block (c, lit);
  3937. stats.blkd.expl++;
  3938. if (bound != LLONG_MAX) bound += opts.blockreward;
  3939. }
  3940. }
  3941. }
  3942. DONE:
  3943. report (2, 'k');
  3944. if (conflict) return;
  3945. assert (schedule.block || stats.clauses.irr != 1);
  3946. if (bound != LLONG_MAX) pure ();
  3947. cleans ();
  3948. delorgs ();
  3949. gc ();
  3950. blkmode = false;
  3951. if (!schedule.block) {
  3952. stats.blkd.rounds++;
  3953. limit.fixed.block = remvars ();
  3954. }
  3955. limit.props.block = opts.blockprd;
  3956. limit.props.block *= opts.blockint;
  3957. limit.props.block += stats.props.srch;
  3958. checkvarstats ();
  3959. }
  3960. void Solver::pure () {
  3961. assert (orgs);
  3962. assert (blkmode || elimode);
  3963. assert (!puremode);
  3964. if (!flush ()) return;
  3965. puremode = true;
  3966. assert (!plits);
  3967. report (2, 'u');
  3968. for (int idx = 1; idx <= maxvar; idx++) {
  3969. Var * v = vars + idx;
  3970. assert (!v->onplits);
  3971. if (v->type != FREE) continue;
  3972. plits.push (mem, idx);
  3973. v->onplits = true;
  3974. }
  3975. while (plits) {
  3976. int idx = plits.pop (), lit = 2*idx;
  3977. Var * v = vars + idx;
  3978. assert (v->type == FREE);
  3979. assert (v->onplits);
  3980. if (!orgs[lit] && !orgs[lit^1]) zombie (v);
  3981. else if (!orgs[lit]) pure (1^lit);
  3982. else if (!orgs[1^lit]) pure (lit);
  3983. v->onplits = false;
  3984. }
  3985. puremode = false;
  3986. report (2, 'u');
  3987. }
  3988. void Solver::jwh () {
  3989. memset (jwhs, 0, 2 * (maxvar + 1) * sizeof *jwhs);
  3990. for (Cls * p = original.head; p; p = p->prev) jwh (p);
  3991. for (Cls * p = binary.head; p; p = p->prev) jwh (p);
  3992. for (Cls * p = fresh.head; p; p = p->prev) jwh (p);
  3993. for (int glue = 0; glue <= opts.glue; glue++)
  3994. for (Cls * p = learned[glue].head; p; p = p->prev) jwh (p);
  3995. }
  3996. void Solver::initfresh () {
  3997. limit.reduce.fresh = (opts.fresh * limit.reduce.learned + 99) / 100;
  3998. report (2, 'F');
  3999. }
  4000. void Solver::initreduce () {
  4001. int l;
  4002. if (opts.liminitmode) l = (opts.liminitpercent*stats.clauses.orig + 99)/100;
  4003. else l = opts.liminitconst;
  4004. if (l > opts.liminitmax) l = opts.liminitmax;
  4005. if (l > opts.maxlimit) l = opts.maxlimit;
  4006. if (l < opts.minlimit) l = opts.minlimit;
  4007. limit.enlarge.conflicts = limit.enlarge.inc = limit.enlarge.init = l;
  4008. limit.reduce.learned = limit.reduce.init = l;
  4009. initfresh ();
  4010. report (1, 'l');
  4011. }
  4012. void Solver::enlarge () {
  4013. stats.enlarged++;
  4014. if (opts.limincmode) {
  4015. limit.reduce.learned =
  4016. ((100 + opts.limincpercent) * limit.reduce.learned + 99) / 100;
  4017. limit.enlarge.inc = ((100 + opts.enlinc) * limit.enlarge.inc + 99) / 100;
  4018. limit.enlarge.conflicts = stats.conflicts + limit.enlarge.inc;
  4019. } else {
  4020. limit.enlarge.inc += opts.liminconst1;
  4021. limit.enlarge.conflicts += limit.enlarge.inc;
  4022. limit.reduce.learned += opts.liminconst2;
  4023. }
  4024. if (limit.reduce.learned > opts.maxlimit) {
  4025. limit.reduce.learned = opts.maxlimit;
  4026. limit.enlarge.conflicts = INT_MAX;
  4027. }
  4028. initfresh ();
  4029. report (1, '+');
  4030. }
  4031. void Solver::shrink (int old) {
  4032. if (!opts.shrink) return;
  4033. if (limit.reduce.learned <= opts.minlimit) return;
  4034. int now = stats.clauses.orig;
  4035. if (!now) return;
  4036. old /= 100, now /= 100;
  4037. if (old <= now) return;
  4038. assert (old);
  4039. int red = (100 * (old - now)) / old;
  4040. assert (red <= 100);
  4041. if (!red) return;
  4042. int rl = limit.reduce.learned, drl;
  4043. drl = (opts.shrink < 2) ? limit.reduce.init : rl;
  4044. drl *= (opts.shrinkfactor*red+99)/100;
  4045. rl -= drl/100;
  4046. if (rl < opts.minlimit) rl = opts.minlimit;
  4047. if (limit.reduce.learned == rl) return;
  4048. limit.reduce.learned = rl;
  4049. stats.shrunken++;
  4050. initfresh ();
  4051. report (1, '-');
  4052. }
  4053. void Solver::simplify () {
  4054. stats.sw2simp ();
  4055. int old = stats.clauses.orig, inc, rv;
  4056. undo (0);
  4057. RESTART:
  4058. simplified = false;
  4059. decompose ();
  4060. if (conflict) goto DONE;
  4061. gc ();
  4062. if (conflict) goto DONE;
  4063. block ();
  4064. if (conflict) goto DONE;
  4065. elim ();
  4066. if (conflict) goto DONE;
  4067. if (simplified &&
  4068. ((opts.rtc == 2 || opts.simprtc == 2) ||
  4069. ((opts.rtc == 1 || opts.simprtc == 1) && !stats.simps)))
  4070. goto RESTART;
  4071. jwh ();
  4072. limit.props.simp = stats.props.srch + simprd * clauses ();
  4073. limit.simp = stats.vars.fixed + stats.vars.merged;
  4074. limit.fixed.simp = stats.vars.fixed;
  4075. rv = remvars ();
  4076. inc = opts.simpinc;
  4077. if (rv) while (rv < 1000000) rv *= 10, inc /= 2;
  4078. simprd *= 100 + inc; simprd += 99; simprd /= 100;
  4079. report (1, 's');
  4080. if (!stats.simps) initreduce ();
  4081. else shrink (old);
  4082. DONE:
  4083. if (opts.print) print ();
  4084. stats.simps++;
  4085. stats.sw2srch ();
  4086. }
  4087. void Solver::flushunits () {
  4088. assert (units);
  4089. undo (0);
  4090. while (units && !conflict) unit (units.pop ());
  4091. flush ();
  4092. }
  4093. void Solver::initrestart () {
  4094. int delta;
  4095. limit.restart.conflicts = stats.conflicts;
  4096. if (opts.luby) delta = opts.restartint * luby (limit.restart.lcnt = 1);
  4097. else delta = limit.restart.inner = limit.restart.outer = opts.restartint;
  4098. limit.restart.conflicts += delta;
  4099. }
  4100. void Solver::initbias () {
  4101. jwh ();
  4102. limit.rebias.conflicts = opts.rebiasint * luby (limit.rebias.lcnt = 1);
  4103. limit.rebias.conflicts += stats.conflicts;
  4104. }
  4105. void Solver::iteration () {
  4106. assert (!level);
  4107. assert (iterating);
  4108. assert (limit.fixed.iter < trail);
  4109. stats.iter++;
  4110. initrestart ();
  4111. int old = stats.clauses.orig;
  4112. while (limit.fixed.iter < trail) {
  4113. int lit = trail[limit.fixed.iter++];
  4114. recycle (lit);
  4115. }
  4116. iterating = false;
  4117. report (2, 'i');
  4118. shrink (old);
  4119. }
  4120. inline bool Solver::reducing () const {
  4121. int learned_not_locked = stats.clauses.lnd;
  4122. learned_not_locked -= stats.clauses.lckd;
  4123. return 2 * learned_not_locked > 3 * limit.reduce.learned;
  4124. }
  4125. inline bool Solver::eliminating () const {
  4126. if (!opts.elim) return false;
  4127. if (!stats.elim.phases) return true;
  4128. if (opts.rtc == 2 || opts.simprtc == 2 ||
  4129. ((opts.rtc == 1 || opts.simprtc == 1) && !stats.simps)) return true;
  4130. if (schedule.elim) return true;
  4131. if (stats.props.srch <= limit.props.elim) return false;
  4132. return remvars () < limit.fixed.elim;
  4133. }
  4134. inline bool Solver::blocking () const {
  4135. if (!opts.block) return false;
  4136. if (!stats.elim.phases) return true;
  4137. if (opts.rtc == 2 || opts.simprtc == 2 ||
  4138. ((opts.rtc == 1 || opts.simprtc == 1) && !stats.simps)) return true;
  4139. if (schedule.block) return true;
  4140. if (stats.props.srch <= limit.props.block) return false;
  4141. return remvars () < limit.fixed.block;
  4142. }
  4143. inline bool Solver::simplifying () const {
  4144. if (!stats.simps) return true;
  4145. if (stats.props.srch < limit.props.simp) return false;
  4146. return limit.simp < stats.vars.fixed + stats.vars.merged;
  4147. }
  4148. inline bool Solver::restarting () const {
  4149. return level >= 2 && limit.restart.conflicts <= stats.conflicts;
  4150. }
  4151. inline bool Solver::rebiasing () const {
  4152. return limit.rebias.conflicts <= stats.conflicts;
  4153. }
  4154. inline bool Solver::probing () const {
  4155. if (!opts.probe) return false;
  4156. if (stats.props.srch < limit.props.probe) return false;
  4157. if (!level) return true;
  4158. if (schedule.probe) return true;
  4159. return limit.fixed.probe < stats.vars.fixed;
  4160. }
  4161. inline bool Solver::enlarging () const {
  4162. if (limit.reduce.learned >= opts.maxlimit) return false;
  4163. return stats.conflicts >= limit.enlarge.conflicts;
  4164. }
  4165. inline bool Solver::exhausted () const {
  4166. return stats.decisions >= limit.decisions;
  4167. }
  4168. int Solver::search () {
  4169. stats.entered2 = seconds ();
  4170. for (;;)
  4171. if (!bcp ()) { if (!analyze ()) return -1; }
  4172. else if (iterating) iteration ();
  4173. else if (units) flushunits ();
  4174. else if (probing ()) probe ();
  4175. else if (simplifying ()) simplify ();
  4176. else if (rebiasing ()) rebias ();
  4177. else if (restarting ()) restart ();
  4178. else if (reducing ()) reduce ();
  4179. else if (enlarging ()) enlarge ();
  4180. else if (exhausted ()) return 0;
  4181. else if (!decide ()) return 1;
  4182. stats.srchtime += seconds () - stats.entered2;
  4183. }
  4184. void Solver::initlimit (int decision_limit) {
  4185. memset (&limit, 0, sizeof limit);
  4186. limit.decisions = decision_limit;
  4187. simprd = opts.simprd;
  4188. rng.init (opts.seed);
  4189. }
  4190. void Solver::initsearch (int decision_limit) {
  4191. assert (opts.fixed);
  4192. initlimit (decision_limit);
  4193. initbias ();
  4194. initrestart ();
  4195. report (1, '*');
  4196. }
  4197. int Solver::solve (int decision_limit) {
  4198. initsearch (decision_limit);
  4199. int res = search ();
  4200. report (1, res < 0 ? '0' : (res ? '1' : '?'));
  4201. if (!stats.simps && opts.print) print ();
  4202. return res;
  4203. }
  4204. double Stats::now () {
  4205. struct rusage u;
  4206. if (getrusage (RUSAGE_SELF, &u))
  4207. return 0;
  4208. double res = u.ru_utime.tv_sec + 1e-6 * u.ru_utime.tv_usec;
  4209. res += u.ru_stime.tv_sec + 1e-6 * u.ru_stime.tv_usec;
  4210. return res;
  4211. }
  4212. double Stats::seconds () {
  4213. double t = now (), delta = t - entered;
  4214. delta = (delta < 0) ? 0 : delta;
  4215. time += delta;
  4216. entered = t;
  4217. return time;
  4218. }
  4219. void Stats::sw2srch () {
  4220. double t = seconds ();
  4221. simptime += t - entered2;
  4222. entered2 = t;
  4223. }
  4224. void Stats::sw2simp () {
  4225. double t = seconds ();
  4226. srchtime += t - entered2;
  4227. entered2 = t;
  4228. }
  4229. Stats::Stats () {
  4230. memset (this, 0, sizeof *this);
  4231. entered = now ();
  4232. }
  4233. Limit::Limit () {
  4234. memset (this, 0, sizeof *this);
  4235. budget.fw.sub = budget.bw.sub = budget.bw.str = budget.fw.str = 10000;
  4236. }
  4237. void PrecoSat::die (const char * msg, ...) {
  4238. va_list ap;
  4239. fprintf (stdout, "c\nc\nc ");
  4240. va_start (ap, msg);
  4241. vfprintf (stdout, msg, ap);
  4242. va_end (ap);
  4243. fputs ("\nc\nc\n", stdout);
  4244. fflush (stdout);
  4245. abort ();
  4246. }
  4247. void Solver::print () {
  4248. bool close_file;
  4249. FILE * file;
  4250. if (opts.output) {
  4251. file = fopen (opts.output, "w");
  4252. if (!file) die ("can not write '%s'", opts.output);
  4253. close_file = true;
  4254. } else file = stdout, close_file = false;
  4255. assert (!level);
  4256. int m, n;
  4257. if (conflict) fprintf (file, "p cnf 0 1\n0\n"), m=0, n=1;
  4258. else {
  4259. size_t bytes = 2*(maxvar+1) * sizeof (int);
  4260. int * map = (int*) mem.callocate (bytes);
  4261. m = 0;
  4262. for (int idx = 1; idx <= maxvar; idx++)
  4263. if (vars[idx].type == FREE) map[idx] = ++m;
  4264. assert (m == remvars ());
  4265. n = 0;
  4266. for (int i = 0; i <= 1; i++)
  4267. for (Cls * p = (i ? original : binary).tail; p; p = p->next)
  4268. if (!p->lnd && !satisfied (p)) n++;
  4269. fprintf (file, "p cnf %d %d\n", m, n);
  4270. fflush (file);
  4271. for (int i = 0; i <= 1; i++)
  4272. for (Cls * p = (i ? binary : original).tail; p; p = p->next) {
  4273. if (p->lnd) continue;
  4274. if (satisfied (p)) continue;
  4275. int lit;
  4276. for (int * q = p->lits; (lit = *q); q++) {
  4277. Val tmp = val (lit);
  4278. if (tmp < 0) continue;
  4279. assert (!tmp);
  4280. int ilit = map[lit/2];
  4281. if (lit&1) ilit = -ilit;
  4282. fprintf (file, "%d ", ilit);
  4283. }
  4284. fputs ("0\n", file);
  4285. }
  4286. mem.deallocate (map, bytes);
  4287. }
  4288. if (close_file) fclose (file);
  4289. report (1, 'w');
  4290. }
  4291. void Cls::print (const char * prefix) const {
  4292. fputs (prefix, stdout);
  4293. for (const int * p = lits; *p; p++) {
  4294. if (p != lits) fputc (' ', stdout);
  4295. printf ("%d", *p);
  4296. }
  4297. fputc ('\n', stdout);
  4298. }
  4299. void Solver::dbgprint (const char * type, Anchor<Cls>& anchor) {
  4300. size_t len = strlen (type) + strlen (prfx) + 80;
  4301. char * str = (char*) mem.allocate (len);
  4302. sprintf (str, "%sPRINT %s clause ", prfx, type);
  4303. for (Cls * p = anchor.tail; p; p = p->next) p->print (str);
  4304. mem.deallocate (str, len);
  4305. }
  4306. void Solver::dbgprint (const char * type, Cls * cls) {
  4307. size_t len = strlen (type) + strlen (prfx) + 1;
  4308. char * str = (char*) mem.allocate (len);
  4309. sprintf (str, "%s%s", prfx, type);
  4310. cls->print (str);
  4311. mem.deallocate (str, len);
  4312. }
  4313. void Solver::dbgprint () {
  4314. dbgprint ("binary", binary);
  4315. dbgprint ("original", original);
  4316. for (int glue = 0; glue <= opts.glue; glue++) {
  4317. char buffer[80];
  4318. sprintf (buffer, "learned[%u]", glue);
  4319. dbgprint (buffer, learned[glue]);
  4320. }
  4321. dbgprint ("fresh", fresh);
  4322. }
  4323. void Solver::dbgprintgate () {
  4324. for (Cls ** p = gate.begin(); p < gate.end (); p++) {
  4325. printf ("%sLOG gate clause", prfx);
  4326. Cls * c = *p;
  4327. for (const int * q = c->lits; *q; q++)
  4328. printf (" %d", *q);
  4329. printf ("\n");
  4330. }
  4331. }