All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thorsten Berger <thorsten.berger@rub.de>
To: linux-kbuild@vger.kernel.org
Cc: deltaone@debian.org, phayax@gmail.com,
	Eugene Groshev <eugene.groshev@gmail.com>,
	Sarah Nadi <nadi@ualberta.ca>, Mel Gorman <mgorman@suse.de>,
	"Luis R. Rodriguez" <mcgrof@suse.com>
Subject: [RFC v3 02/12] Add picosat.c (1/3)
Date: Fri, 22 Oct 2021 15:36:37 +0200	[thread overview]
Message-ID: <bfd8f79f-62dd-3899-621a-dfe17af70cc0@rub.de> (raw)
In-Reply-To: <7706ed5e-4771-770a-5cf2-d3c8346fa1dc@rub.de>

Subject: [RFC v3 02/12] Add picosat.c (1/3)

PicoSAT is the SAT solver used in this project. picosat.c is the actual
SAT solver. Since the file is too big for a single patch, it needs to be
split up. This patch contains the first part of the file.

---
 scripts/kconfig/picosat.c | 3000 +++++++++++++++++++++++++++++++++++++
 1 file changed, 3000 insertions(+)
 create mode 100644 scripts/kconfig/picosat.c

diff --git a/scripts/kconfig/picosat.c b/scripts/kconfig/picosat.c
new file mode 100644
index 000000000000..653bf0f0b99f
--- /dev/null
+++ b/scripts/kconfig/picosat.c
@@ -0,0 +1,3000 @@
+/****************************************************************************
+Copyright (c) 2006 - 2015, Armin Biere, Johannes Kepler University.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+****************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+#include "picosat.h"
+
+/* By default code for 'all different constraints' is disabled, since 'NADC'
+ * is defined.
+ */
+#define NADC
+
+/* By default we enable failed literals, since 'NFL' is undefined.
+ *
+#define NFL
+ */
+
+/* By default we 'detach satisfied (large) clauses', e.g. NDSC undefined.
+ *
+#define NDSC
+ */
+
+/* Do not use luby restart schedule instead of inner/outer.
+ *
+#define NLUBY
+ */
+
+/* Enabling this define, will use gnuplot to visualize how the scores evolve.
+ *
+#define VISCORES
+ */
+#ifdef VISCORES
+// #define WRITEGIF        /* ... to generate a video */
+#endif
+
+#ifdef VISCORES
+#ifndef WRITEGIF
+#include <unistd.h>        /* for 'usleep' */
+#endif
+#endif
+
+#ifdef RCODE
+#include <R.h>
+#endif
+
+#define MINRESTART    100    /* minimum restart interval */
+#define MAXRESTART    1000000 /* maximum restart interval */
+#define RDECIDE        1000    /* interval of random decisions */
+#define FRESTART    110    /* restart increase factor in percent */
+#define FREDUCE        110    /* reduce increase factor in percent  */
+#define FREDADJ        121    /* reduce increase adjustment factor */
+#define MAXCILS        10    /* maximal number of unrecycled internals */
+#define FFLIPPED    10000    /* flipped reduce factor */
+#define FFLIPPEDPREC    10000000/* flipped reduce factor precision */
+#define INTERRUPTLIM    1024    /* check interrupt after that many decisions */
+
+#ifndef TRACE
+#define NO_BINARY_CLAUSES    /* store binary clauses more compactly */
+#endif
+
+/* For debugging purposes you may want to define 'LOGGING', which actually
+ * can be enforced by using './configure.sh --log'.
+ */
+#ifdef LOGGING
+#define LOG(code) do { code; } while (0)
+#else
+#define LOG(code) do { } while (0)
+#endif
+#define NOLOG(code) do { } while (0)        /* log exception */
+#define ONLYLOG(code) do { code; } while (0)    /* force logging */
+
+#define FALSE ((Val)-1)
+#define UNDEF ((Val)0)
+#define TRUE ((Val)1)
+
+#define COMPACT_TRACECHECK_TRACE_FMT 0
+#define EXTENDED_TRACECHECK_TRACE_FMT 1
+#define RUP_TRACE_FMT 2
+
+#define NEWN(p,n) do { (p) = new (ps, sizeof (*(p)) * (n)); } while (0)
+#define CLRN(p,n) do { memset ((p), 0, sizeof (*(p)) * (n)); } while (0)
+#define CLR(p) CLRN(p,1)
+#define DELETEN(p,n) \
+  do { delete (ps, p, sizeof (*(p)) * (n)); (p) = 0; } while (0)
+
+#define RESIZEN(p,old_num,new_num) \
+  do { \
+    size_t old_size = sizeof (*(p)) * (old_num); \
+    size_t new_size = sizeof (*(p)) * (new_num); \
+    (p) = resize (ps, (p), old_size, new_size) ; \
+  } while (0)
+
+#define ENLARGE(start,head,end) \
+  do { \
+    unsigned old_num = (ptrdiff_t)((end) - (start)); \
+    size_t new_num = old_num ? (2 * old_num) : 1; \
+    unsigned count = (head) - (start); \
+    assert ((start) <= (end)); \
+    RESIZEN((start),old_num,new_num); \
+    (head) = (start) + count; \
+    (end) = (start) + new_num; \
+  } while (0)
+
+#define NOTLIT(l) (ps->lits + (1 ^ ((l) - ps->lits)))
+
+#define LIT2IDX(l) ((ptrdiff_t)((l) - ps->lits) / 2)
+#define LIT2IMPLS(l) (ps->impls + (ptrdiff_t)((l) - ps->lits))
+#define LIT2INT(l) ((int)(LIT2SGN(l) * LIT2IDX(l)))
+#define LIT2SGN(l) (((ptrdiff_t)((l) - ps->lits) & 1) ? -1 : 1)
+#define LIT2VAR(l) (ps->vars + LIT2IDX(l))
+#define LIT2HTPS(l) (ps->htps + (ptrdiff_t)((l) - ps->lits))
+#define LIT2JWH(l) (ps->jwh + ((l) - ps->lits))
+
+#ifndef NDSC
+#define LIT2DHTPS(l) (ps->dhtps + (ptrdiff_t)((l) - ps->lits))
+#endif
+
+#ifdef NO_BINARY_CLAUSES
+typedef uintptr_t Wrd;
+#define ISLITREASON(C) (1&(Wrd)C)
+#define LIT2REASON(L) \
+  (assert (L->val==TRUE), ((Cls*)(1 + (2*(L - ps->lits)))))
+#define REASON2LIT(C) ((Lit*)(ps->lits + ((Wrd)C)/2))
+#endif
+
+#define ENDOFCLS(c) ((void*)((Lit**)(c)->lits + (c)->size))
+
+#define SOC ((ps->oclauses == ps->ohead) ? ps->lclauses : ps->oclauses)
+#define EOC (ps->lhead)
+#define NXC(p) (((p) + 1 == ps->ohead) ? ps->lclauses : (p) + 1)
+
+#define OIDX2IDX(idx) (2 * ((idx) + 1))
+#define LIDX2IDX(idx) (2 * (idx) + 1)
+
+#define ISLIDX(idx) ((idx)&1)
+
+#define IDX2OIDX(idx) (assert(!ISLIDX(idx)), (idx)/2 - 1)
+#define IDX2LIDX(idx) (assert(ISLIDX(idx)), (idx)/2)
+
+#define EXPORTIDX(idx) \
+  ((ISLIDX(idx) ? (IDX2LIDX (idx) + (ps->ohead - ps->oclauses)) : IDX2OIDX(idx)) + 1)
+
+#define IDX2CLS(i) \
+  (assert(i), (ISLIDX(i) ? ps->lclauses : ps->oclauses)[(i)/2 - !ISLIDX(i)])
+
+#define IDX2ZHN(i) (assert(i), (ISLIDX(i) ? ps->zhains[(i)/2] : 0))
+
+#define CLS2TRD(c) (((Trd*)(c)) - 1)
+#define CLS2IDX(c) ((((Trd*)(c)) - 1)->idx)
+
+#define CLS2ACT(c) \
+  ((Act*)((assert((c)->learned)),assert((c)->size>2),ENDOFCLS(c)))
+
+#define VAR2LIT(v) (ps->lits + 2 * ((v) - ps->vars))
+#define VAR2RNK(v) (ps->rnks + ((v) - ps->vars))
+
+#define RNK2LIT(r) (ps->lits + 2 * ((r) - ps->rnks))
+#define RNK2VAR(r) (ps->vars + ((r) - ps->rnks))
+
+#define BLK_FILL_BYTES 8
+#define SIZE_OF_BLK (sizeof (Blk) - BLK_FILL_BYTES)
+
+#define PTR2BLK(void_ptr) \
+  ((void_ptr) ? (Blk*)(((char*)(void_ptr)) - SIZE_OF_BLK) : 0)
+
+#define AVERAGE(a,b) ((b) ? (((double)a) / (double)(b)) : 0.0)
+#define PERCENT(a,b) (100.0 * AVERAGE(a,b))
+
+#ifndef RCODE
+#define ABORT(msg) \
+  do { \
+    fputs ("*** picosat: " msg "\n", stderr); \
+    abort (); \
+  } while (0)
+#else
+#define ABORT(msg) \
+  do { \
+    Rf_error (msg); \
+  } while (0)
+#endif
+
+#define ABORTIF(cond,msg) \
+  do { \
+    if (!(cond)) break; \
+    ABORT (msg); \
+  } while (0)
+
+#define ZEROFLT        (0x00000000u)
+#define EPSFLT        (0x00000001u)
+#define INFFLT        (0xffffffffu)
+
+#define FLTCARRY    (1u << 25)
+#define FLTMSB        (1u << 24)
+#define FLTMAXMANTISSA    (FLTMSB - 1)
+
+#define FLTMANTISSA(d)    ((d) & FLTMAXMANTISSA)
+#define FLTEXPONENT(d)    ((int)((d) >> 24) - 128)
+
+#define FLTMINEXPONENT    (-128)
+#define FLTMAXEXPONENT    (127)
+
+#define CMPSWAPFLT(a,b) \
+  do { \
+    Flt tmp; \
+    if (((a) < (b))) \
+      { \
+    tmp = (a); \
+    (a) = (b); \
+    (b) = tmp; \
+      } \
+  } while (0)
+
+#define UNPACKFLT(u,m,e) \
+  do { \
+    (m) = FLTMANTISSA(u); \
+    (e) = FLTEXPONENT(u); \
+    (m) |= FLTMSB; \
+  } while (0)
+
+#define INSERTION_SORT_LIMIT 10
+
+#define SORTING_SWAP(T,p,q) \
+do { \
+  T tmp = *(q); \
+  *(q) = *(p); \
+  *(p) = tmp; \
+} while (0)
+
+#define SORTING_CMP_SWAP(T,cmp,p,q) \
+do { \
+  if ((cmp) (ps, *(p), *(q)) > 0) \
+    SORTING_SWAP (T, p, q); \
+} while(0)
+
+#define QUICKSORT_PARTITION(T,cmp,a,l,r) \
+do { \
+  T pivot; \
+  int j; \
+  i = (l) - 1;             /* result in 'i' */ \
+  j = (r); \
+  pivot = (a)[j]; \
+  for (;;) \
+    { \
+      while ((cmp) (ps, (a)[++i], pivot) < 0) \
+    ; \
+      while ((cmp) (ps, pivot, (a)[--j]) < 0) \
+        if (j == (l)) \
+      break; \
+      if (i >= j) \
+    break; \
+      SORTING_SWAP (T, (a) + i, (a) + j); \
+    } \
+  SORTING_SWAP (T, (a) + i, (a) + (r)); \
+} while(0)
+
+#define QUICKSORT(T,cmp,a,n) \
+do { \
+  int l = 0, r = (n) - 1, m, ll, rr, i; \
+  assert (ps->ihead == ps->indices); \
+  if (r - l <= INSERTION_SORT_LIMIT) \
+    break; \
+  for (;;) \
+    { \
+      m = (l + r) / 2; \
+      SORTING_SWAP (T, (a) + m, (a) + r - 1); \
+      SORTING_CMP_SWAP (T, cmp, (a) + l, (a) + r - 1); \
+      SORTING_CMP_SWAP (T, cmp, (a) + l, (a) + r); \
+      SORTING_CMP_SWAP (T, cmp, (a) + r - 1, (a) + r); \
+      QUICKSORT_PARTITION (T, cmp, (a), l + 1, r - 1); \
+      if (i - l < r - i) \
+    { \
+      ll = i + 1; \
+      rr = r; \
+      r = i - 1; \
+    } \
+      else \
+    { \
+      ll = l; \
+      rr = i - 1; \
+      l = i + 1; \
+    } \
+      if (r - l > INSERTION_SORT_LIMIT) \
+    { \
+      assert (rr - ll > INSERTION_SORT_LIMIT); \
+      if (ps->ihead == ps->eoi) \
+        ENLARGE (ps->indices, ps->ihead, ps->eoi); \
+      *ps->ihead++ = ll; \
+      if (ps->ihead == ps->eoi) \
+        ENLARGE (ps->indices, ps->ihead, ps->eoi); \
+      *ps->ihead++ = rr; \
+    } \
+      else if (rr - ll > INSERTION_SORT_LIMIT) \
+        { \
+      l = ll; \
+      r = rr; \
+    } \
+      else if (ps->ihead > ps->indices) \
+    { \
+      r = *--ps->ihead; \
+      l = *--ps->ihead; \
+    } \
+      else \
+    break; \
+    } \
+} while (0)
+
+#define INSERTION_SORT(T,cmp,a,n) \
+do { \
+  T pivot; \
+  int l = 0, r = (n) - 1, i, j; \
+  for (i = r; i > l; i--) \
+    SORTING_CMP_SWAP (T, cmp, (a) + i - 1, (a) + i); \
+  for (i = l + 2; i <= r; i++)  \
+    { \
+      j = i; \
+      pivot = (a)[i]; \
+      while ((cmp) (ps, pivot, (a)[j - 1]) < 0) \
+        { \
+      (a)[j] = (a)[j - 1]; \
+      j--; \
+    } \
+      (a)[j] = pivot; \
+    } \
+} while (0)
+
+#ifdef NDEBUG
+#define CHECK_SORTED(cmp,a,n) do { } while(0)
+#else
+#define CHECK_SORTED(cmp,a,n) \
+do { \
+  int i; \
+  for (i = 0; i < (n) - 1; i++) \
+    assert ((cmp) (ps, (a)[i], (a)[i + 1]) <= 0); \
+} while(0)
+#endif
+
+#define SORT(T,cmp,a,n) \
+do { \
+  T * aa = (a); \
+  int nn = (n); \
+  QUICKSORT (T, cmp, aa, nn); \
+  INSERTION_SORT (T, cmp, aa, nn); \
+  assert (ps->ihead == ps->indices); \
+  CHECK_SORTED (cmp, aa, nn); \
+} while (0)
+
+#define WRDSZ (sizeof (long) * 8)
+
+#ifdef RCODE
+#define fprintf(...) do { } while (0)
+#define vfprintf(...) do { } while (0)
+#define fputs(...) do { } while (0)
+#define fputc(...) do { } while (0)
+#endif
+
+typedef unsigned Flt;        /* 32 bit deterministic soft float */
+typedef Flt Act;        /* clause and variable activity */
+typedef struct Blk Blk;        /* allocated memory block */
+typedef struct Cls Cls;        /* clause */
+typedef struct Lit Lit;        /* literal */
+typedef struct Rnk Rnk;        /* variable to score mapping */
+typedef signed char Val;    /* TRUE, UNDEF, FALSE */
+typedef struct Var Var;        /* variable */
+#ifdef TRACE
+typedef struct Trd Trd;        /* trace data for clauses */
+typedef struct Zhn Zhn;        /* compressed chain (=zain) data */
+typedef unsigned char Znt;    /* compressed antecedent data */
+#endif
+
+#ifdef NO_BINARY_CLAUSES
+typedef struct Ltk Ltk;
+
+struct Ltk
+{
+  Lit ** start;
+  unsigned count : WRDSZ == 32 ? 27 : 32;
+  unsigned ldsize : WRDSZ == 32 ? 5 : 32;
+};
+#endif
+
+struct Lit
+{
+  Val val;
+};
+
+struct Var
+{
+  unsigned mark        : 1;    /*bit 1*/
+  unsigned resolved    : 1;    /*bit 2*/
+  unsigned phase    : 1;    /*bit 3*/
+  unsigned assigned    : 1;    /*bit 4*/
+  unsigned used        : 1;    /*bit 5*/
+  unsigned failed    : 1;    /*bit 6*/
+  unsigned internal    : 1;    /*bit 7*/
+  unsigned usedefphase  : 1;    /*bit 8*/
+  unsigned defphase     : 1;    /*bit 9*/
+  unsigned msspos       : 1;    /*bit 10*/
+  unsigned mssneg       : 1;    /*bit 11*/
+  unsigned humuspos     : 1;    /*bit 12*/
+  unsigned humusneg     : 1;    /*bit 13*/
+  unsigned partial      : 1;    /*bit 14*/
+#ifdef TRACE
+  unsigned core        : 1;    /*bit 15*/
+#endif
+  unsigned level;
+  Cls *reason;
+#ifndef NADC
+  Lit ** inado;
+  Lit ** ado;
+  Lit *** adotabpos;
+#endif
+};
+
+struct Rnk
+{
+  Act score;
+  unsigned pos : 30;            /* 0 iff not on heap */
+  unsigned moreimportant : 1;
+  unsigned lessimportant : 1;
+};
+
+struct Cls
+{
+  unsigned size;
+
+  unsigned collect:1;    /* bit 1 */
+  unsigned learned:1;    /* bit 2 */
+  unsigned locked:1;    /* bit 3 */
+  unsigned used:1;    /* bit 4 */
+#ifndef NDEBUG
+  unsigned connected:1;    /* bit 5 */
+#endif
+#ifdef TRACE
+  unsigned collected:1;    /* bit 6 */
+  unsigned core:1;    /* bit 7 */
+#endif
+
+#define LDMAXGLUE 25    /* 32 - 7 */
+#define MAXGLUE     ((1<<LDMAXGLUE)-1)
+
+  unsigned glue:LDMAXGLUE;
+
+  Cls *next[2];
+  Lit *lits[2];
+};
+
+#ifdef TRACE
+struct Zhn
+{
+  unsigned ref:31;
+  unsigned core:1;
+  Znt * liz;
+  Znt znt[0];
+};
+
+struct Trd
+{
+  unsigned idx;
+  Cls cls[0];
+};
+#endif
+
+struct Blk
+{
+#ifndef NDEBUG
+  union
+  {
+    size_t size;        /* this is what we really use */
+    void *as_two_ptrs[2];    /* 2 * sizeof (void*) alignment of data */
+  }
+  header;
+#endif
+  char data[BLK_FILL_BYTES];
+};
+
+enum State
+{
+  RESET = 0,
+  READY = 1,
+  SAT = 2,
+  UNSAT = 3,
+  UNKNOWN = 4,
+};
+
+enum Phase
+{
+  POSPHASE,
+  NEGPHASE,
+  JWLPHASE,
+  RNDPHASE,
+};
+
+struct PicoSAT
+{
+  enum State state;
+  enum Phase defaultphase;
+  int last_sat_call_result;
+
+  FILE *out;
+  char * prefix;
+  int verbosity;
+  int plain;
+  unsigned LEVEL;
+  unsigned max_var;
+  unsigned size_vars;
+
+  Lit *lits;
+  Var *vars;
+  Rnk *rnks;
+  Flt *jwh;
+  Cls **htps;
+#ifndef NDSC
+  Cls **dhtps;
+#endif
+#ifdef NO_BINARY_CLAUSES
+  Ltk *impls;
+  Cls impl, cimpl;
+  int implvalid, cimplvalid;
+#else
+  Cls **impls;
+#endif
+  Lit **trail, **thead, **eot, **ttail, ** ttail2;
+#ifndef NADC
+  Lit **ttailado;
+#endif
+  unsigned adecidelevel;
+  Lit **als, **alshead, **alstail, **eoals;
+  Lit **CLS, **clshead, **eocls;
+  int *rils, *rilshead, *eorils;
+  int *cils, *cilshead, *eocils;
+  int *fals, *falshead, *eofals;
+  int *mass, szmass;
+  int *mssass, szmssass;
+  int *mcsass, nmcsass, szmcsass;
+  int *humus, szhumus;
+  Lit *failed_assumption;
+  int extracted_all_failed_assumptions;
+  Rnk **heap, **hhead, **eoh;
+  Cls **oclauses, **ohead, **eoo;    /* original clauses */
+  Cls **lclauses, **lhead, ** EOL;    /* learned clauses */
+  int * soclauses, * sohead, * eoso; /* saved original clauses */
+  int saveorig;
+  int partial;
+#ifdef TRACE
+  int trace;
+  Zhn **zhains, **zhead, **eoz;
+  int ocore;
+#endif
+  FILE * rup;
+  int rupstarted;
+  int rupvariables;
+  int rupclauses;
+  Cls *mtcls;
+  Cls *conflict;
+  Lit **added, **ahead, **eoa;
+  Var **marked, **mhead, **eom;
+  Var **dfs, **dhead, **eod;
+  Cls **resolved, **rhead, **eor;
+  unsigned char *levels, *levelshead, *eolevels;
+  unsigned *dused, *dusedhead, *eodused;
+  unsigned char *buffer, *bhead, *eob;
+  Act vinc, lscore, ilvinc, ifvinc;
+#ifdef VISCORES
+  Act fvinc, nvinc;
+#endif
+  Act cinc, lcinc, ilcinc, fcinc;
+  unsigned srng;
+  size_t current_bytes;
+  size_t max_bytes;
+  size_t recycled;
+  double seconds, flseconds;
+  double entered;
+  unsigned nentered;
+  int measurealltimeinlib;
+  char *rline[2];
+  int szrline, RCOUNT;
+  double levelsum;
+  unsigned iterations;
+  int reports;
+  int lastrheader;
+  unsigned calls;
+  unsigned decisions;
+  unsigned restarts;
+  unsigned simps;
+  unsigned fsimplify;
+  unsigned isimplify;
+  unsigned reductions;
+  unsigned lreduce;
+  unsigned lreduceadjustcnt;
+  unsigned lreduceadjustinc;
+  unsigned lastreduceconflicts;
+  unsigned llocked;    /* locked large learned clauses */
+  unsigned lrestart;
+#ifdef NLUBY
+  unsigned drestart;
+  unsigned ddrestart;
+#else
+  unsigned lubycnt;
+  unsigned lubymaxdelta;
+  int waslubymaxdelta;
+#endif
+  unsigned long long lsimplify;
+  unsigned long long propagations;
+  unsigned long long lpropagations;
+  unsigned fixed;        /* top level assignments */
+#ifndef NFL
+  unsigned failedlits;
+  unsigned ifailedlits;
+  unsigned efailedlits;
+  unsigned flcalls;
+#ifdef STATS
+  unsigned flrounds;
+  unsigned long long flprops;
+  unsigned long long floopsed, fltried, flskipped;
+#endif
+  unsigned long long fllimit;
+  int simplifying;
+  Lit ** saved;
+  unsigned saved_size;
+#endif
+  unsigned conflicts;
+  unsigned contexts;
+  unsigned internals;
+  unsigned noclauses;    /* current number large original clauses */
+  unsigned nlclauses;    /* current number large learned clauses */
+  unsigned olits;        /* current literals in large original clauses */
+  unsigned llits;        /* current literals in large learned clauses */
+  unsigned oadded;        /* added original clauses */
+  unsigned ladded;        /* added learned clauses */
+  unsigned loadded;    /* added original large clauses */
+  unsigned lladded;    /* added learned large clauses */
+  unsigned addedclauses;    /* oadded + ladded */
+  unsigned vused;        /* used variables */
+  unsigned llitsadded;    /* added learned literals */
+  unsigned long long visits;
+#ifdef STATS
+  unsigned loused;        /* used large original clauses */
+  unsigned llused;        /* used large learned clauses */
+  unsigned long long bvisits;
+  unsigned long long tvisits;
+  unsigned long long lvisits;
+  unsigned long long othertrue;
+  unsigned long long othertrue2;
+  unsigned long long othertruel;
+  unsigned long long othertrue2u;
+  unsigned long long othertruelu;
+  unsigned long long ltraversals;
+  unsigned long long traversals;
+#ifdef TRACE
+  unsigned long long antecedents;
+#endif
+  unsigned uips;
+  unsigned znts;
+  unsigned assumptions;
+  unsigned rdecisions;
+  unsigned sdecisions;
+  size_t srecycled;
+  size_t rrecycled;
+  unsigned long long derefs;
+#endif
+  unsigned minimizedllits;
+  unsigned nonminimizedllits;
+#ifndef NADC
+  Lit *** ados, *** hados, *** eados;
+  Lit *** adotab;
+  unsigned nadotab;
+  unsigned szadotab;
+  Cls * adoconflict;
+  unsigned adoconflicts;
+  unsigned adoconflictlimit;
+  int addingtoado;
+  int adodisabled;
+#endif
+  unsigned long long flips;
+#ifdef STATS
+  unsigned long long FORCED;
+  unsigned long long assignments;
+  unsigned inclreduces;
+  unsigned staticphasedecisions;
+  unsigned skippedrestarts;
+#endif
+  int * indices, * ihead, *eoi;
+  unsigned sdflips;
+
+  unsigned long long saved_flips;
+  unsigned saved_max_var;
+  unsigned min_flipped;
+
+  void * emgr;
+  picosat_malloc enew;
+  picosat_realloc eresize;
+  picosat_free edelete;
+
+  struct {
+    void * state;
+    int (*function) (void *);
+  } interrupt;
+
+#ifdef VISCORES
+  FILE * fviscores;
+#endif
+};
+
+typedef PicoSAT PS;
+
+static Flt
+packflt (unsigned m, int e)
+{
+  Flt res;
+  assert (m < FLTMSB);
+  assert (FLTMINEXPONENT <= e);
+  assert (e <= FLTMAXEXPONENT);
+  res = m | ((unsigned)(e + 128) << 24);
+  return res;
+}
+
+static Flt
+base2flt (unsigned m, int e)
+{
+  if (!m)
+    return ZEROFLT;
+
+  if (m < FLTMSB)
+    {
+      do
+    {
+      if (e <= FLTMINEXPONENT)
+        return EPSFLT;
+
+      e--;
+      m <<= 1;
+
+    }
+      while (m < FLTMSB);
+    }
+  else
+    {
+      while (m >= FLTCARRY)
+    {
+      if (e >= FLTMAXEXPONENT)
+        return INFFLT;
+
+      e++;
+      m >>= 1;
+    }
+    }
+
+  m &= ~FLTMSB;
+  return packflt (m, e);
+}
+
+static Flt
+addflt (Flt a, Flt b)
+{
+  unsigned ma, mb, delta;
+  int ea, eb;
+
+  CMPSWAPFLT (a, b);
+  if (!b)
+    return a;
+
+  UNPACKFLT (a, ma, ea);
+  UNPACKFLT (b, mb, eb);
+
+  assert (ea >= eb);
+  delta = ea - eb;
+  if (delta < 32) mb >>= delta; else mb = 0;
+  if (!mb)
+    return a;
+
+  ma += mb;
+  if (ma & FLTCARRY)
+    {
+      if (ea == FLTMAXEXPONENT)
+    return INFFLT;
+
+      ea++;
+      ma >>= 1;
+    }
+
+  assert (ma < FLTCARRY);
+  ma &= FLTMAXMANTISSA;
+
+  return packflt (ma, ea);
+}
+
+static Flt
+mulflt (Flt a, Flt b)
+{
+  unsigned ma, mb;
+  unsigned long long accu;
+  int ea, eb;
+
+  CMPSWAPFLT (a, b);
+  if (!b)
+    return ZEROFLT;
+
+  UNPACKFLT (a, ma, ea);
+  UNPACKFLT (b, mb, eb);
+
+  ea += eb;
+  ea += 24;
+  if (ea > FLTMAXEXPONENT)
+    return INFFLT;
+
+  if (ea < FLTMINEXPONENT)
+    return EPSFLT;
+
+  accu = ma;
+  accu *= mb;
+  accu >>= 24;
+
+  if (accu >= FLTCARRY)
+    {
+      if (ea == FLTMAXEXPONENT)
+    return INFFLT;
+
+      ea++;
+      accu >>= 1;
+
+      if (accu >= FLTCARRY)
+    return INFFLT;
+    }
+
+  assert (accu < FLTCARRY);
+  assert (accu & FLTMSB);
+
+  ma = accu;
+  ma &= ~FLTMSB;
+
+  return packflt (ma, ea);
+}
+
+static Flt
+ascii2flt (const char *str)
+{
+  Flt ten = base2flt (10, 0);
+  Flt onetenth = base2flt (26843546, -28);
+  Flt res = ZEROFLT, tmp, base;
+  const char *p = str;
+  int ch;
+
+  ch = *p++;
+
+  if (ch != '.')
+    {
+      if (!isdigit (ch))
+    return INFFLT;    /* better abort ? */
+
+      res = base2flt (ch - '0', 0);
+
+      while ((ch = *p++))
+    {
+      if (ch == '.')
+        break;
+
+      if (!isdigit (ch))
+        return INFFLT;    /* better abort? */
+
+      res = mulflt (res, ten);
+      tmp = base2flt (ch - '0', 0);
+      res = addflt (res, tmp);
+    }
+    }
+
+  if (ch == '.')
+    {
+      ch = *p++;
+      if (!isdigit (ch))
+    return INFFLT;    /* better abort ? */
+
+      base = onetenth;
+      tmp = mulflt (base2flt (ch - '0', 0), base);
+      res = addflt (res, tmp);
+
+      while ((ch = *p++))
+    {
+      if (!isdigit (ch))
+        return INFFLT;    /* better abort? */
+
+      base = mulflt (base, onetenth);
+      tmp = mulflt (base2flt (ch - '0', 0), base);
+      res = addflt (res, tmp);
+    }
+    }
+
+  return res;
+}
+
+#if defined(VISCORES)
+
+static double
+flt2double (Flt f)
+{
+  double res;
+  unsigned m;
+  int e, i;
+
+  UNPACKFLT (f, m, e);
+  res = m;
+
+  if (e < 0)
+    {
+      for (i = e; i < 0; i++)
+    res *= 0.5;
+    }
+  else
+    {
+      for (i = 0; i < e; i++)
+    res *= 2.0;
+    }
+
+  return res;
+}
+
+#endif
+
+static int
+log2flt (Flt a)
+{
+  return FLTEXPONENT (a) + 24;
+}
+
+static int
+cmpflt (Flt a, Flt b)
+{
+  if (a < b)
+    return -1;
+
+  if (a > b)
+    return 1;
+
+  return 0;
+}
+
+static void *
+new (PS * ps, size_t size)
+{
+  size_t bytes;
+  Blk *b;
+  
+  if (!size)
+    return 0;
+
+  bytes = size + SIZE_OF_BLK;
+
+  if (ps->enew)
+    b = ps->enew (ps->emgr, bytes);
+  else
+    b = malloc (bytes);
+
+  ABORTIF (!b, "out of memory in 'new'");
+#ifndef NDEBUG
+  b->header.size = size;
+#endif
+  ps->current_bytes += size;
+  if (ps->current_bytes > ps->max_bytes)
+    ps->max_bytes = ps->current_bytes;
+  return b->data;
+}
+
+static void
+delete (PS * ps, void *void_ptr, size_t size)
+{
+  size_t bytes;
+  Blk *b;
+
+  if (!void_ptr)
+    {
+      assert (!size);
+      return;
+    }
+
+  assert (size);
+  b = PTR2BLK (void_ptr);
+
+  assert (size <= ps->current_bytes);
+  ps->current_bytes -= size;
+
+  assert (b->header.size == size);
+
+  bytes = size + SIZE_OF_BLK;
+  if (ps->edelete)
+    ps->edelete (ps->emgr, b, bytes);
+  else
+    free (b);
+}
+
+static void *
+resize (PS * ps, void *void_ptr, size_t old_size, size_t new_size)
+{
+  size_t old_bytes, new_bytes;
+  Blk *b;
+
+  b = PTR2BLK (void_ptr);
+
+  assert (old_size <= ps->current_bytes);
+  ps->current_bytes -= old_size;
+
+  if ((old_bytes = old_size))
+    {
+      assert (old_size && b && b->header.size == old_size);
+      old_bytes += SIZE_OF_BLK;
+    }
+  else
+    assert (!b);
+
+  if ((new_bytes = new_size))
+    new_bytes += SIZE_OF_BLK;
+
+  if (ps->eresize)
+    b = ps->eresize (ps->emgr, b, old_bytes, new_bytes);
+  else
+    b = realloc (b, new_bytes);
+
+  if (!new_size)
+    {
+      assert (!b);
+      return 0;
+    }
+
+  ABORTIF (!b, "out of memory in 'resize'");
+#ifndef NDEBUG
+  b->header.size = new_size;
+#endif
+
+  ps->current_bytes += new_size;
+  if (ps->current_bytes > ps->max_bytes)
+    ps->max_bytes = ps->current_bytes;
+
+  return b->data;
+}
+
+static unsigned
+int2unsigned (int l)
+{
+  return (l < 0) ? 1 + 2 * -l : 2 * l;
+}
+
+static Lit *
+int2lit (PS * ps, int l)
+{
+  return ps->lits + int2unsigned (l);
+}
+
+static Lit **
+end_of_lits (Cls * c)
+{
+  return (Lit**)c->lits + c->size;
+}
+
+#if !defined(NDEBUG) || defined(LOGGING)
+
+static void
+dumplits (PS * ps, Lit ** l, Lit ** end)
+{
+  int first;
+  Lit ** p;
+
+  if (l == end)
+    {
+      /* empty clause */
+    }
+  else if (l + 1 == end)
+    {
+      fprintf (ps->out, "%d ", LIT2INT (l[0]));
+    }
+  else
+    {
+      assert (l + 2 <= end);
+      first = (abs (LIT2INT (l[0])) > abs (LIT2INT (l[1])));
+      fprintf (ps->out, "%d ", LIT2INT (l[first]));
+      fprintf (ps->out, "%d ", LIT2INT (l[!first]));
+      for (p = l + 2; p < end; p++)
+     fprintf (ps->out, "%d ", LIT2INT (*p));
+    }
+
+  fputc ('0', ps->out);
+}
+
+static void
+dumpcls (PS * ps, Cls * c)
+{
+  Lit **end;
+
+  if (c)
+    {
+      end = end_of_lits (c);
+      dumplits (ps, c->lits, end);
+#ifdef TRACE
+      if (ps->trace)
+     fprintf (ps->out, " clause(%u)", CLS2IDX (c));
+#endif
+    }
+  else
+    fputs ("DECISION", ps->out);
+}
+
+static void
+dumpclsnl (PS * ps, Cls * c)
+{
+  dumpcls (ps, c);
+  fputc ('\n', ps->out);
+}
+
+void
+dumpcnf (PS * ps)
+{
+  Cls **p, *c;
+
+  for (p = SOC; p != EOC; p = NXC (p))
+    {
+      c = *p;
+
+      if (!c)
+    continue;
+
+#ifdef TRACE
+      if (c->collected)
+    continue;
+#endif
+
+      dumpclsnl (ps, *p);
+    }
+}
+
+#endif
+
+static void
+delete_prefix (PS * ps)
+{
+  if (!ps->prefix)
+    return;
+    
+  delete (ps, ps->prefix, strlen (ps->prefix) + 1);
+  ps->prefix = 0;
+}
+
+static void
+new_prefix (PS * ps, const char * str)
+{
+  delete_prefix (ps);
+  assert (str);
+  ps->prefix = new (ps, strlen (str) + 1);
+  strcpy (ps->prefix, str);
+}
+
+static PS *
+init (void * pmgr,
+      picosat_malloc pnew, picosat_realloc presize, picosat_free pdelete)
+{
+  PS * ps;
+
+#if 0
+  int count = 3 - !pnew - !presize - !pdelete;
+
+  ABORTIF (count && !pnew, "API usage: missing 'picosat_set_new'");
+  ABORTIF (count && !presize, "API usage: missing 'picosat_set_resize'");
+  ABORTIF (count && !pdelete, "API usage: missing 'picosat_set_delete'");
+#endif
+
+  ps = pnew ? pnew (pmgr, sizeof *ps) : malloc (sizeof *ps);
+  ABORTIF (!ps, "failed to allocate memory for PicoSAT manager");
+  memset (ps, 0, sizeof *ps);
+
+  ps->emgr = pmgr;
+  ps->enew = pnew;
+  ps->eresize = presize;
+  ps->edelete = pdelete;
+
+  ps->size_vars = 1;
+  ps->state = RESET;
+  ps->defaultphase = JWLPHASE;
+#ifdef TRACE
+  ps->ocore = -1;
+#endif
+  ps->lastrheader = -2;
+#ifndef NADC
+  ps->adoconflictlimit = UINT_MAX;
+#endif
+  ps->min_flipped = UINT_MAX;
+
+  NEWN (ps->lits, 2 * ps->size_vars);
+  NEWN (ps->jwh, 2 * ps->size_vars);
+  NEWN (ps->htps, 2 * ps->size_vars);
+#ifndef NDSC
+  NEWN (ps->dhtps, 2 * ps->size_vars);
+#endif
+  NEWN (ps->impls, 2 * ps->size_vars);
+  NEWN (ps->vars, ps->size_vars);
+  NEWN (ps->rnks, ps->size_vars);
+
+  /* because '0' pos denotes not on heap
+   */
+  ENLARGE (ps->heap, ps->hhead, ps->eoh);
+  ps->hhead = ps->heap + 1;
+
+  ps->vinc = base2flt (1, 0);        /* initial var activity */
+  ps->ifvinc = ascii2flt ("1.05");    /* var score rescore factor */
+#ifdef VISCORES
+  ps->fvinc = ascii2flt ("0.9523809");    /*     1/f =     1/1.05 */
+  ps->nvinc = ascii2flt ("0.0476191");    /* 1 - 1/f = 1 - 1/1.05 */
+#endif
+  ps->lscore = base2flt (1, 90);    /* var activity rescore limit */
+  ps->ilvinc = base2flt (1, -90);    /* inverse of 'lscore' */
+
+  ps->cinc = base2flt (1, 0);        /* initial clause activity */
+  ps->fcinc = ascii2flt ("1.001");    /* cls activity rescore factor */
+  ps->lcinc = base2flt (1, 90);        /* cls activity rescore limit */
+  ps->ilcinc = base2flt (1, -90);    /* inverse of 'ilcinc' */
+
+  ps->lreduceadjustcnt = ps->lreduceadjustinc = 100;
+  ps->lpropagations = ~0ull;
+
+#ifndef RCODE
+  ps->out = stdout;
+#else
+  ps->out = 0;
+#endif
+  new_prefix (ps, "c ");
+  ps->verbosity = 0;
+  ps->plain = 0;
+
+#ifdef NO_BINARY_CLAUSES
+  memset (&ps->impl, 0, sizeof (ps->impl));
+  ps->impl.size = 2;
+
+  memset (&ps->cimpl, 0, sizeof (ps->impl));
+  ps->cimpl.size = 2;
+#endif
+
+#ifdef VISCORES
+  ps->fviscores = popen (
+    "/usr/bin/gnuplot -background black"
+    " -xrm 'gnuplot*textColor:white'"
+    " -xrm 'gnuplot*borderColor:white'"
+    " -xrm 'gnuplot*axisColor:white'"
+    , "w");
+  fprintf (ps->fviscores, "unset key\n");
+  // fprintf (ps->fviscores, "set log y\n");
+  fflush (ps->fviscores);
+  system ("rm -rf /tmp/picosat-viscores");
+  system ("mkdir /tmp/picosat-viscores");
+  system ("mkdir /tmp/picosat-viscores/data");
+#ifdef WRITEGIF
+  system ("mkdir /tmp/picosat-viscores/gif");
+  fprintf (ps->fviscores,
+           "set terminal gif giant animate opt size 1024,768 x000000 xffffff"
+       "\n");
+
+  fprintf (ps->fviscores,
+           "set output \"/tmp/picosat-viscores/gif/animated.gif\"\n");
+#endif
+#endif
+  ps->defaultphase = JWLPHASE;
+  ps->state = READY;
+  ps->last_sat_call_result = 0;
+
+  return ps;
+}
+
+static size_t
+bytes_clause (PS * ps, unsigned size, unsigned learned)
+{
+  size_t res;
+
+  res = sizeof (Cls);
+  res += size * sizeof (Lit *);
+  res -= 2 * sizeof (Lit *);
+
+  if (learned && size > 2)
+    res += sizeof (Act);    /* add activity */
+
+#ifdef TRACE
+  if (ps->trace)
+    res += sizeof (Trd);    /* add trace data */
+#else
+  (void) ps;
+#endif
+
+  return res;
+}
+
+static Cls *
+new_clause (PS * ps, unsigned size, unsigned learned)
+{
+  size_t bytes;
+  void * tmp;
+#ifdef TRACE
+  Trd *trd;
+#endif
+  Cls *res;
+
+  bytes = bytes_clause (ps, size, learned);
+  tmp = new (ps, bytes);
+
+#ifdef TRACE
+  if (ps->trace)
+    {
+      trd = tmp;
+
+      if (learned)
+    trd->idx = LIDX2IDX (ps->lhead - ps->lclauses);
+      else
+    trd->idx = OIDX2IDX (ps->ohead - ps->oclauses);
+
+      res = trd->cls;
+    }
+  else
+#endif
+    res = tmp;
+
+  res->size = size;
+  res->learned = learned;
+
+  res->collect = 0;
+#ifndef NDEBUG
+  res->connected = 0;
+#endif
+  res->locked = 0;
+  res->used = 0;
+#ifdef TRACE
+  res->core = 0;
+  res->collected = 0;
+#endif
+
+  if (learned && size > 2)
+    {
+      Act * p = CLS2ACT (res);
+      *p = ps->cinc;
+    }
+
+  return res;
+}
+
+static void
+delete_clause (PS * ps, Cls * c)
+{
+  size_t bytes;
+#ifdef TRACE
+  Trd *trd;
+#endif
+
+  bytes = bytes_clause (ps, c->size, c->learned);
+
+#ifdef TRACE
+  if (ps->trace)
+    {
+      trd = CLS2TRD (c);
+      delete (ps, trd, bytes);
+    }
+  else
+#endif
+    delete (ps, c, bytes);
+}
+
+static void
+delete_clauses (PS * ps)
+{
+  Cls **p;
+  for (p = SOC; p != EOC; p = NXC (p))
+    if (*p)
+      delete_clause (ps, *p);
+
+  DELETEN (ps->oclauses, ps->eoo - ps->oclauses);
+  DELETEN (ps->lclauses, ps->EOL - ps->lclauses);
+
+  ps->ohead = ps->eoo = ps->lhead = ps->EOL = 0;
+}
+
+#ifdef TRACE
+
+static void
+delete_zhain (PS * ps, Zhn * zhain)
+{
+  const Znt *p, *znt;
+
+  assert (zhain);
+
+  znt = zhain->znt;
+  for (p = znt; *p; p++)
+    ;
+
+  delete (ps, zhain, sizeof (Zhn) + (p - znt) + 1);
+}
+
+static void
+delete_zhains (PS * ps)
+{
+  Zhn **p, *z;
+  for (p = ps->zhains; p < ps->zhead; p++)
+    if ((z = *p))
+      delete_zhain (ps, z);
+
+  DELETEN (ps->zhains, ps->eoz - ps->zhains);
+  ps->eoz = ps->zhead = 0;
+}
+
+#endif
+
+#ifdef NO_BINARY_CLAUSES
+static void
+lrelease (PS * ps, Ltk * stk)
+{
+  if (stk->start)
+    DELETEN (stk->start, (1 << (stk->ldsize)));
+  memset (stk, 0, sizeof (*stk));
+}
+#endif
+
+#ifndef NADC
+
+static unsigned
+llength (Lit ** a)
+{
+  Lit ** p;
+  for (p = a; *p; p++)
+    ;
+  return p - a;
+}
+
+static void
+resetadoconflict (PS * ps)
+{
+  assert (ps->adoconflict);
+  delete_clause (ps, ps->adoconflict);
+  ps->adoconflict = 0;
+}
+
+static void
+reset_ados (PS * ps)
+{
+  Lit *** p;
+
+  for (p = ps->ados; p < ps->hados; p++)
+    DELETEN (*p, llength (*p) + 1);
+
+  DELETEN (ps->ados, ps->eados - ps->ados);
+  ps->hados = ps->eados = 0;
+
+  DELETEN (ps->adotab, ps->szadotab);
+  ps->szadotab = ps->nadotab = 0;
+
+  if (ps->adoconflict)
+    resetadoconflict (ps);
+
+  ps->adoconflicts = 0;
+  ps->adoconflictlimit = UINT_MAX;
+  ps->adodisabled = 0;
+}
+
+#endif
+
+static void
+reset (PS * ps)
+{
+  ABORTIF (!ps ||
+           ps->state == RESET, "API usage: reset without initialization");
+
+  delete_clauses (ps);
+#ifdef TRACE
+  delete_zhains (ps);
+#endif
+#ifdef NO_BINARY_CLAUSES
+  {
+    unsigned i;
+    for (i = 2; i <= 2 * ps->max_var + 1; i++)
+      lrelease (ps, ps->impls + i);
+  }
+#endif
+#ifndef NADC
+  reset_ados (ps);
+#endif
+#ifndef NFL
+  DELETEN (ps->saved, ps->saved_size);
+#endif
+  DELETEN (ps->htps, 2 * ps->size_vars);
+#ifndef NDSC
+  DELETEN (ps->dhtps, 2 * ps->size_vars);
+#endif
+  DELETEN (ps->impls, 2 * ps->size_vars);
+  DELETEN (ps->lits, 2 * ps->size_vars);
+  DELETEN (ps->jwh, 2 * ps->size_vars);
+  DELETEN (ps->vars, ps->size_vars);
+  DELETEN (ps->rnks, ps->size_vars);
+  DELETEN (ps->trail, ps->eot - ps->trail);
+  DELETEN (ps->heap, ps->eoh - ps->heap);
+  DELETEN (ps->als, ps->eoals - ps->als);
+  DELETEN (ps->CLS, ps->eocls - ps->CLS);
+  DELETEN (ps->rils, ps->eorils - ps->rils);
+  DELETEN (ps->cils, ps->eocils - ps->cils);
+  DELETEN (ps->fals, ps->eofals - ps->fals);
+  DELETEN (ps->mass, ps->szmass);
+  DELETEN (ps->mssass, ps->szmssass);
+  DELETEN (ps->mcsass, ps->szmcsass);
+  DELETEN (ps->humus, ps->szhumus);
+  DELETEN (ps->added, ps->eoa - ps->added);
+  DELETEN (ps->marked, ps->eom - ps->marked);
+  DELETEN (ps->dfs, ps->eod - ps->dfs);
+  DELETEN (ps->resolved, ps->eor - ps->resolved);
+  DELETEN (ps->levels, ps->eolevels - ps->levels);
+  DELETEN (ps->dused, ps->eodused - ps->dused);
+  DELETEN (ps->buffer, ps->eob - ps->buffer);
+  DELETEN (ps->indices, ps->eoi - ps->indices);
+  DELETEN (ps->soclauses, ps->eoso - ps->soclauses);
+  delete_prefix (ps);
+  delete (ps, ps->rline[0], ps->szrline);
+  delete (ps, ps->rline[1], ps->szrline);
+  assert (getenv ("LEAK") || !ps->current_bytes);    /* found leak if failing */
+#ifdef VISCORES
+  pclose (ps->fviscores);
+#endif
+  if (ps->edelete)
+    ps->edelete (ps->emgr, ps, sizeof *ps);
+  else
+    free (ps);
+}
+
+inline static void
+tpush (PS * ps, Lit * lit)
+{
+  assert (ps->lits < lit && lit <= ps->lits + 2* ps->max_var + 1);
+  if (ps->thead == ps->eot)
+    {
+      unsigned ttail2count = ps->ttail2 - ps->trail;
+      unsigned ttailcount = ps->ttail - ps->trail;
+#ifndef NADC
+      unsigned ttailadocount = ps->ttailado - ps->trail;
+#endif
+      ENLARGE (ps->trail, ps->thead, ps->eot);
+      ps->ttail = ps->trail + ttailcount;
+      ps->ttail2 = ps->trail + ttail2count;
+#ifndef NADC
+      ps->ttailado = ps->trail + ttailadocount;
+#endif
+    }
+
+  *ps->thead++ = lit;
+}
+
+static void
+assign_reason (PS * ps, Var * v, Cls * reason)
+{
+#if defined(NO_BINARY_CLAUSES) && !defined(NDEBUG)
+  assert (reason != &ps->impl);
+#else
+  (void) ps;
+#endif
+  v->reason = reason;
+}
+
+static void
+assign_phase (PS * ps, Lit * lit)
+{
+  unsigned new_phase, idx;
+  Var * v = LIT2VAR (lit);
+
+#ifndef NFL
+  /* In 'simplifying' mode we only need to keep 'min_flipped' up to date if
+   * we force assignments on the top level.   The other assignments will be
+   * undone and thus we can keep the old saved value of the phase.
+   */
+  if (!ps->LEVEL || !ps->simplifying)
+#endif
+    {
+      new_phase = (LIT2SGN (lit) > 0);
+
+      if (v->assigned)
+    {
+      ps->sdflips -= ps->sdflips/FFLIPPED;
+
+      if (new_phase != v->phase)
+        {
+          assert (FFLIPPEDPREC >= FFLIPPED);
+          ps->sdflips += FFLIPPEDPREC / FFLIPPED;
+          ps->flips++;
+
+          idx = LIT2IDX (lit);
+          if (idx < ps->min_flipped)
+        ps->min_flipped = idx;
+
+              NOLOG (fprintf (ps->out,
+                          "%sflipped %d\n",
+                   ps->prefix, LIT2INT (lit)));
+        }
+    }
+
+      v->phase = new_phase;
+      v->assigned = 1;
+    }
+
+  lit->val = TRUE;
+  NOTLIT (lit)->val = FALSE;
+}
+
+inline static void
+assign (PS * ps, Lit * lit, Cls * reason)
+{
+  Var * v = LIT2VAR (lit);
+  assert (lit->val == UNDEF);
+#ifdef STATS
+  ps->assignments++;
+#endif
+  v->level = ps->LEVEL;
+  assign_phase (ps, lit);
+  assign_reason (ps, v, reason);
+  tpush (ps, lit);
+}
+
+inline static int
+cmp_added (PS * ps, Lit * k, Lit * l)
+{
+  Val a = k->val, b = l->val;
+  Var *u, *v;
+  int res;
+
+  if (a == UNDEF && b != UNDEF)
+    return -1;
+
+  if (a != UNDEF && b == UNDEF)
+    return 1;
+
+  u = LIT2VAR (k);
+  v = LIT2VAR (l);
+
+  if (a != UNDEF)
+    {
+      assert (b != UNDEF);
+      res = v->level - u->level;
+      if (res)
+    return res;        /* larger level first */
+    }
+
+  res = cmpflt (VAR2RNK (u)->score, VAR2RNK (v)->score);
+  if (res)
+    return res;            /* smaller activity first */
+
+  return u - v;            /* smaller index first */
+}
+
+static void
+sorttwolits (Lit ** v)
+{
+  Lit * a = v[0], * b = v[1];
+
+  assert (a != b);
+
+  if (a < b)
+    return;
+
+  v[0] = b;
+  v[1] = a;
+}
+
+inline static void
+sortlits (PS * ps, Lit ** v, unsigned size)
+{
+  if (size == 2)
+    sorttwolits (v);    /* same order with and with out 'NO_BINARY_CLAUSES' */
+  else
+    SORT (Lit *, cmp_added, v, size);
+}
+
+#ifdef NO_BINARY_CLAUSES
+static Cls *
+setimpl (PS * ps, Lit * a, Lit * b)
+{
+  assert (!ps->implvalid);
+  assert (ps->impl.size == 2);
+
+  ps->impl.lits[0] = a;
+  ps->impl.lits[1] = b;
+
+  sorttwolits (ps->impl.lits);
+  ps->implvalid = 1;
+
+  return &ps->impl;
+}
+
+static void
+resetimpl (PS * ps)
+{
+  ps->implvalid = 0;
+}
+
+static Cls *
+setcimpl (PS * ps, Lit * a, Lit * b)
+{
+  assert (!ps->cimplvalid);
+  assert (ps->cimpl.size == 2);
+
+  ps->cimpl.lits[0] = a;
+  ps->cimpl.lits[1] = b;
+
+  sorttwolits (ps->cimpl.lits);
+  ps->cimplvalid = 1;
+
+  return &ps->cimpl;
+}
+
+static void
+resetcimpl (PS * ps)
+{
+  assert (ps->cimplvalid);
+  ps->cimplvalid = 0;
+}
+
+#endif
+
+static int
+cmp_ptr (PS * ps, void *l, void *k)
+{
+  (void) ps;
+  return ((char*)l) - (char*)k;        /* arbitrarily already reverse */
+}
+
+static int
+cmp_rnk (Rnk * r, Rnk * s)
+{
+  if (!r->moreimportant && s->moreimportant)
+    return -1;
+
+  if (r->moreimportant && !s->moreimportant)
+    return 1;
+
+  if (!r->lessimportant && s->lessimportant)
+    return 1;
+
+  if (r->lessimportant && !s->lessimportant)
+    return -1;
+
+  if (r->score < s->score)
+    return -1;
+
+  if (r->score > s->score)
+    return 1;
+
+  return -cmp_ptr (0, r, s);
+}
+
+static void
+hup (PS * ps, Rnk * v)
+{
+  int upos, vpos;
+  Rnk *u;
+
+#ifndef NFL
+  assert (!ps->simplifying);
+#endif
+
+  vpos = v->pos;
+
+  assert (0 < vpos);
+  assert (vpos < ps->hhead - ps->heap);
+  assert (ps->heap[vpos] == v);
+
+  while (vpos > 1)
+    {
+      upos = vpos / 2;
+
+      u = ps->heap[upos];
+
+      if (cmp_rnk (u, v) > 0)
+    break;
+
+      ps->heap[vpos] = u;
+      u->pos = vpos;
+
+      vpos = upos;
+    }
+
+  ps->heap[vpos] = v;
+  v->pos = vpos;
+}
+
+static Cls *add_simplified_clause (PS *, int);
+
+inline static void
+add_antecedent (PS * ps, Cls * c)
+{
+  assert (c);
+
+#ifdef NO_BINARY_CLAUSES
+  if (ISLITREASON (c))
+    return;
+
+  if (c == &ps->impl)
+    return;
+#elif defined(STATS) && defined(TRACE)
+  ps->antecedents++;
+#endif
+  if (ps->rhead == ps->eor)
+    ENLARGE (ps->resolved, ps->rhead, ps->eor);
+
+  assert (ps->rhead < ps->eor);
+  *ps->rhead++ = c;
+}
+
+#ifdef TRACE
+
+#ifdef NO_BINARY_CLAUSES
+#error "can not combine TRACE and NO_BINARY_CLAUSES"
+#endif
+
+#endif /* TRACE */
+
+static void
+add_lit (PS * ps, Lit * lit)
+{
+  assert (lit);
+
+  if (ps->ahead == ps->eoa)
+    ENLARGE (ps->added, ps->ahead, ps->eoa);
+
+  *ps->ahead++ = lit;
+}
+
+static void
+push_var_as_marked (PS * ps, Var * v)
+{
+  if (ps->mhead == ps->eom)
+    ENLARGE (ps->marked, ps->mhead, ps->eom);
+
+  *ps->mhead++ = v;
+}
+
+static void
+mark_var (PS * ps, Var * v)
+{
+  assert (!v->mark);
+  v->mark = 1;
+  push_var_as_marked (ps, v);
+}
+
+#ifdef NO_BINARY_CLAUSES
+
+static Cls *
+impl2reason (PS * ps, Lit * lit)
+{
+  Lit * other;
+  Cls * res;
+  other = ps->impl.lits[0];
+  if (lit == other)
+    other = ps->impl.lits[1];
+  assert (other->val == FALSE);
+  res = LIT2REASON (NOTLIT (other));
+  resetimpl (ps);
+  return res;
+}
+
+#endif
+
+/* Whenever we have a top level derived unit we really should derive a unit
+ * clause otherwise the resolutions in 'add_simplified_clause' become
+ * incorrect.
+ */
+static Cls *
+resolve_top_level_unit (PS * ps, Lit * lit, Cls * reason)
+{
+  unsigned count_resolved;
+  Lit **p, **eol, *other;
+  Var *u, *v;
+
+  assert (ps->rhead == ps->resolved);
+  assert (ps->ahead == ps->added);
+
+  add_lit (ps, lit);
+  add_antecedent (ps, reason);
+  count_resolved = 1;
+  v = LIT2VAR (lit);
+
+  eol = end_of_lits (reason);
+  for (p = reason->lits; p < eol; p++)
+    {
+      other = *p;
+      u = LIT2VAR (other);
+      if (u == v)
+    continue;
+
+      add_antecedent (ps, u->reason);
+      count_resolved++;
+    }
+
+  /* Some of the literals could be assumptions.  If at least one
+   * variable is not an assumption, we should resolve.
+   */
+  if (count_resolved >= 2)
+    {
+#ifdef NO_BINARY_CLAUSES
+      if (reason == &ps->impl)
+    resetimpl (ps);
+#endif
+      reason = add_simplified_clause (ps, 1);
+#ifdef NO_BINARY_CLAUSES
+      if (reason->size == 2)
+    {
+      assert (reason == &ps->impl);
+      reason = impl2reason (ps, lit);
+    }
+#endif
+      assign_reason (ps, v, reason);
+    }
+  else
+    {
+      ps->ahead = ps->added;
+      ps->rhead = ps->resolved;
+    }
+
+  return reason;
+}
+
+static void
+fixvar (PS * ps, Var * v)
+{
+  Rnk * r;
+
+  assert (VAR2LIT (v) != UNDEF);
+  assert (!v->level);
+
+  ps->fixed++;
+
+  r = VAR2RNK (v);
+  r->score = INFFLT;
+
+#ifndef NFL
+  if (ps->simplifying)
+    return;
+#endif
+
+  if (!r->pos)
+    return;
+
+  hup (ps, r);
+}
+
+static void
+use_var (PS * ps, Var * v)
+{
+  if (v->used)
+    return;
+
+  v->used = 1;
+  ps->vused++;
+}
+
+static void
+assign_forced (PS * ps, Lit * lit, Cls * reason)
+{
+  Var *v;
+
+  assert (reason);
+  assert (lit->val == UNDEF);
+
+#ifdef STATS
+  ps->FORCED++;
+#endif
+  assign (ps, lit, reason);
+
+#ifdef NO_BINARY_CLAUSES
+  assert (reason != &ps->impl);
+  if (ISLITREASON (reason))
+    {
+      reason = setimpl (ps, lit, NOTLIT (REASON2LIT (reason)));
+      assert (reason);
+    }
+#endif
+  LOG ( fprintf (ps->out,
+                "%sassign %d at level %d by ",
+                ps->prefix, LIT2INT (lit), ps->LEVEL);
+       dumpclsnl (ps, reason));
+
+  v = LIT2VAR (lit);
+  if (!ps->LEVEL)
+    use_var (ps, v);
+
+  if (!ps->LEVEL && reason->size > 1)
+    {
+      reason = resolve_top_level_unit (ps, lit, reason);
+      assert (reason);
+    }
+
+#ifdef NO_BINARY_CLAUSES
+  if (ISLITREASON (reason) || reason == &ps->impl)
+    {
+      /* DO NOTHING */
+    }
+  else
+#endif
+    {
+      assert (!reason->locked);
+      reason->locked = 1;
+      if (reason->learned && reason->size > 2)
+    ps->llocked++;
+    }
+
+#ifdef NO_BINARY_CLAUSES
+  if (reason == &ps->impl)
+    resetimpl (ps);
+#endif
+
+  if (!ps->LEVEL)
+    fixvar (ps, v);
+}
+
+#ifdef NO_BINARY_CLAUSES
+
+static void
+lpush (PS * ps, Lit * lit, Cls * c)
+{
+  int pos = (c->lits[0] == lit);
+  Ltk * s = LIT2IMPLS (lit);
+  unsigned oldsize, newsize;
+
+  assert (c->size == 2);
+
+  if (!s->start)
+    {
+      assert (!s->count);
+      assert (!s->ldsize);
+      NEWN (s->start, 1);
+    }
+  else
+    {
+      oldsize = (1 << (s->ldsize));
+      assert (s->count <= oldsize);
+      if (s->count == oldsize)
+    {
+      newsize = 2 * oldsize;
+      RESIZEN (s->start, oldsize, newsize);
+      s->ldsize++;
+    }
+    }
+
+  s->start[s->count++] = c->lits[pos];
+}
+
+#endif
+
+static void
+connect_head_tail (PS * ps, Lit * lit, Cls * c)
+{
+  Cls ** s;
+  assert (c->size >= 1);
+  if (c->size == 2)
+    {
+#ifdef NO_BINARY_CLAUSES
+      lpush (ps, lit, c);
+      return;
+#else
+      s = LIT2IMPLS (lit);
+#endif
+    }
+  else
+    s = LIT2HTPS (lit);
+
+  if (c->lits[0] != lit)
+    {
+      assert (c->size >= 2);
+      assert (c->lits[1] == lit);
+      c->next[1] = *s;
+    }
+  else
+    c->next[0] = *s;
+
+  *s = c;
+}
+
+#ifdef TRACE
+static void
+zpush (PS * ps, Zhn * zhain)
+{
+  assert (ps->trace);
+
+  if (ps->zhead == ps->eoz)
+    ENLARGE (ps->zhains, ps->zhead, ps->eoz);
+
+  *ps->zhead++ = zhain;
+}
+
+static int
+cmp_resolved (PS * ps, Cls * c, Cls * d)
+{
+#ifndef NDEBUG
+  assert (ps->trace);
+#else
+  (void) ps;
+#endif
+  return CLS2IDX (c) - CLS2IDX (d);
+}
+
+static void
+bpushc (PS * ps, unsigned char ch)
+{
+  if (ps->bhead == ps->eob)
+    ENLARGE (ps->buffer, ps->bhead, ps->eob);
+
+  *ps->bhead++ = ch;
+}
+
+static void
+bpushu (PS * ps, unsigned u)
+{
+  while (u & ~0x7f)
+    {
+      bpushc (ps, u | 0x80);
+      u >>= 7;
+    }
+
+  bpushc (ps, u);
+}
+
+static void
+bpushd (PS * ps, unsigned prev, unsigned this)
+{
+  unsigned delta;
+  assert (prev < this);
+  delta = this - prev;
+  bpushu (ps, delta);
+}
+
+static void
+add_zhain (PS * ps)
+{
+  unsigned prev, this, count, rcount;
+  Cls **p, *c;
+  Zhn *res;
+
+  assert (ps->trace);
+  assert (ps->bhead == ps->buffer);
+  assert (ps->rhead > ps->resolved);
+
+  rcount = ps->rhead - ps->resolved;
+  SORT (Cls *, cmp_resolved, ps->resolved, rcount);
+
+  prev = 0;
+  for (p = ps->resolved; p < ps->rhead; p++)
+    {
+      c = *p;
+      this = CLS2TRD (c)->idx;
+      bpushd (ps, prev, this);
+      prev = this;
+    }
+  bpushc (ps, 0);
+
+  count = ps->bhead - ps->buffer;
+
+  res = new (ps, sizeof (Zhn) + count);
+  res->core = 0;
+  res->ref = 0;
+  memcpy (res->znt, ps->buffer, count);
+
+  ps->bhead = ps->buffer;
+#ifdef STATS
+  ps->znts += count - 1;
+#endif
+  zpush (ps, res);
+}
+
+#endif
+
+static void
+add_resolved (PS * ps, int learned)
+{
+#if defined(STATS) || defined(TRACE)
+  Cls **p, *c;
+
+  for (p = ps->resolved; p < ps->rhead; p++)
+    {
+      c = *p;
+      if (c->used)
+    continue;
+
+      c->used = 1;
+
+      if (c->size <= 2)
+    continue;
+
+#ifdef STATS
+      if (c->learned)
+    ps->llused++;
+      else
+    ps->loused++;
+#endif
+    }
+#endif
+
+#ifdef TRACE
+  if (learned && ps->trace)
+    add_zhain (ps);
+#else
+  (void) learned;
+#endif
+  ps->rhead = ps->resolved;
+}
+
+static void
+incjwh (PS * ps, Cls * c)
+{
+  Lit **p, *lit, ** eol;
+  Flt * f, inc, sum;
+  unsigned size = 0;
+  Var * v;
+  Val val;
+
+  eol = end_of_lits (c);
+
+  for (p = c->lits; p < eol; p++)
+    {
+      lit = *p;
+      val = lit->val;
+
+      if (val && ps->LEVEL > 0)
+    {
+      v = LIT2VAR (lit);
+      if (v->level > 0)
+        val = UNDEF;
+    }
+
+      if (val == TRUE)
+    return;
+
+      if (val != FALSE)
+    size++;
+    }
+
+  inc = base2flt (1, -size);
+
+  for (p = c->lits; p < eol; p++)
+    {
+      lit = *p;
+      f = LIT2JWH (lit);
+      sum = addflt (*f, inc);
+      *f = sum;
+    }
+}
+
+static void
+write_rup_header (PS * ps, FILE * file)
+{
+  char line[80];
+  int i;
+
+  sprintf (line, "%%RUPD32 %u %u", ps->rupvariables, ps->rupclauses);
+
+  fputs (line, file);
+  for (i = 255 - strlen (line); i >= 0; i--)
+    fputc (' ', file);
+
+  fputc ('\n', file);
+  fflush (file);
+}
+
+static Cls *
+add_simplified_clause (PS * ps, int learned)
+{
+  unsigned num_true, num_undef, num_false, size, count_resolved;
+  Lit **p, **q, *lit, ** end;
+  unsigned litlevel, glue;
+  Cls *res, * reason;
+  int reentered;
+  Val val;
+  Var *v;
+#if !defined(NDEBUG) && defined(TRACE)
+  unsigned idx;
+#endif
+
+  reentered = 0;
+
+REENTER:
+
+  size = ps->ahead - ps->added;
+
+  add_resolved (ps, learned);
+
+  if (learned)
+    {
+      ps->ladded++;
+      ps->llitsadded += size;
+      if (size > 2)
+    {
+      ps->lladded++;
+      ps->nlclauses++;
+      ps->llits += size;
+    }
+    }
+  else
+    {
+      ps->oadded++;
+      if (size > 2)
+    {
+      ps->loadded++;
+      ps->noclauses++;
+      ps->olits += size;
+    }
+    }
+
+  ps->addedclauses++;
+  assert (ps->addedclauses == ps->ladded + ps->oadded);
+
+#ifdef NO_BINARY_CLAUSES
+  if (size == 2)
+    res = setimpl (ps, ps->added[0], ps->added[1]);
+  else
+#endif
+    {
+      sortlits (ps, ps->added, size);
+
+      if (learned)
+    {
+      if (ps->lhead == ps->EOL)
+        {
+          ENLARGE (ps->lclauses, ps->lhead, ps->EOL);
+
+          /* A very difficult to find bug, which only occurs if the
+           * learned clauses stack is immediately allocated before the
+           * original clauses stack without padding.  In this case, we
+           * have 'SOC == EOC', which terminates all loops using the
+           * idiom 'for (p = SOC; p != EOC; p = NXC(p))' immediately.
+           * Unfortunately this occurred in 'fix_clause_lits' after
+           * using a recent version of the memory allocator of 'Google'
+           * perftools in the context of one large benchmark for
+           * our SMT solver 'Boolector'.
+           */
+          if (ps->EOL == ps->oclauses)
+        ENLARGE (ps->lclauses, ps->lhead, ps->EOL);
+        }
+
+#if !defined(NDEBUG) && defined(TRACE)
+      idx = LIDX2IDX (ps->lhead - ps->lclauses);
+#endif
+    }
+      else
+    {
+      if (ps->ohead == ps->eoo)
+        {
+          ENLARGE (ps->oclauses, ps->ohead, ps->eoo);
+          if (ps->EOL == ps->oclauses)
+        ENLARGE (ps->oclauses, ps->ohead, ps->eoo);    /* ditto */
+        }
+
+#if !defined(NDEBUG) && defined(TRACE)
+      idx = OIDX2IDX (ps->ohead - ps->oclauses);
+#endif
+    }
+
+      assert (ps->EOL != ps->oclauses);            /* ditto */
+
+      res = new_clause (ps, size, learned);
+
+      glue = 0;
+
+      if (learned)
+    {
+      assert (ps->dusedhead == ps->dused);
+
+      for (p = ps->added; p < ps->ahead; p++)
+        {
+          lit = *p;
+          if (lit->val)
+        {
+          litlevel = LIT2VAR (lit)->level;
+          assert (litlevel <= ps->LEVEL);
+          while (ps->levels + litlevel >= ps->levelshead)
+            {
+              if (ps->levelshead >= ps->eolevels)
+            ENLARGE (ps->levels, ps->levelshead, ps->eolevels);
+              assert (ps->levelshead < ps->eolevels);
+              *ps->levelshead++ = 0;
+            }
+          if (!ps->levels[litlevel])
+            {
+              if (ps->dusedhead >= ps->eodused)
+            ENLARGE (ps->dused, ps->dusedhead, ps->eodused);
+              assert (ps->dusedhead < ps->eodused);
+              *ps->dusedhead++ = litlevel;
+              ps->levels[litlevel] = 1;
+              glue++;
+            }
+        }
+          else
+        glue++;
+        }
+
+      while (ps->dusedhead > ps->dused)
+        {
+          litlevel = *--ps->dusedhead;
+          assert (ps->levels + litlevel < ps->levelshead);
+          assert (ps->levels[litlevel]);
+          ps->levels[litlevel] = 0;
+        }
+    }
+
+      assert (glue <= MAXGLUE);
+      res->glue = glue;
+
+#if !defined(NDEBUG) && defined(TRACE)
+      if (ps->trace)
+    assert (CLS2IDX (res) == idx);
+#endif
+      if (learned)
+    *ps->lhead++ = res;
+      else
+    *ps->ohead++ = res;
+
+#if !defined(NDEBUG) && defined(TRACE)
+      if (ps->trace && learned)
+    assert (ps->zhead - ps->zhains == ps->lhead - ps->lclauses);
+#endif
+      assert (ps->lhead != ps->oclauses);        /* ditto */
+    }
+
+  if (learned && ps->rup)
+    {
+      if (!ps->rupstarted)
+    {
+      write_rup_header (ps, ps->rup);
+      ps->rupstarted = 1;
+    }
+    }
+
+  num_true = num_undef = num_false = 0;
+
+  q = res->lits;
+  for (p = ps->added; p < ps->ahead; p++)
+    {
+      lit = *p;
+      *q++ = lit;
+
+      if (learned && ps->rup)
+    fprintf (ps->rup, "%d ", LIT2INT (lit));
+
+      val = lit->val;
+
+      num_true += (val == TRUE);
+      num_undef += (val == UNDEF);
+      num_false += (val == FALSE);
+    }
+  assert (num_false + num_true + num_undef == size);
+
+  if (learned && ps->rup)
+    fputs ("0\n", ps->rup);
+
+  ps->ahead = ps->added;        /* reset */
+
+  if (!reentered)                // TODO merge
+  if (size > 0)
+    {
+      assert (size <= 2 || !reentered);        // TODO remove
+      connect_head_tail (ps, res->lits[0], res);
+      if (size > 1)
+    connect_head_tail (ps, res->lits[1], res);
+    }
+
+  if (size == 0)
+    {
+      if (!ps->mtcls)
+    ps->mtcls = res;
+    }
+
+#ifdef NO_BINARY_CLAUSES
+  if (size != 2)
+#endif
+#ifndef NDEBUG
+    res->connected = 1;
+#endif
+
+  LOG ( fprintf (ps->out, "%s%s ", ps->prefix, learned ? "learned" : "original");
+        dumpclsnl (ps, res));
+
+  /* Shrink clause by resolving it against top level assignments.
+   */
+  if (!ps->LEVEL && num_false > 0)
+    {
+      assert (ps->ahead == ps->added);
+      assert (ps->rhead == ps->resolved);
+
+      count_resolved = 1;
+      add_antecedent (ps, res);
+
+      end = end_of_lits (res);
+      for (p = res->lits; p < end; p++)
+    {
+      lit = *p;
+      v = LIT2VAR (lit);
+      use_var (ps, v);
+
+      if (lit->val == FALSE)
+        {
+          add_antecedent (ps, v->reason);
+          count_resolved++;
+        }
+      else
+        add_lit (ps, lit);
+    }
+
+      assert (count_resolved >= 2);
+
+      learned = 1;
+#ifdef NO_BINARY_CLAUSES
+      if (res == &ps->impl)
+    resetimpl (ps);
+#endif
+      reentered = 1;
+      goto REENTER;        /* and return simplified clause */
+    }
+
+  if (!num_true && num_undef == 1)    /* unit clause */
+    {
+      lit = 0;
+      for (p = res->lits; p < res->lits + size; p++)
+    {
+      if ((*p)->val == UNDEF)
+        lit = *p;
+
+      v = LIT2VAR (*p);
+      use_var (ps, v);
+    }
+      assert (lit);
+
+      reason = res;
+#ifdef NO_BINARY_CLAUSES
+      if (size == 2)
+        {
+      Lit * other = res->lits[0];
+      if (other == lit)
+        other = res->lits[1];
+
+      assert (other->val == FALSE);
+      reason = LIT2REASON (NOTLIT (other));
+    }
+#endif
+      assign_forced (ps, lit, reason);
+      num_true++;
+    }
+
+  if (num_false == size && !ps->conflict)
+    {
+#ifdef NO_BINARY_CLAUSES
+      if (res == &ps->impl)
+    ps->conflict = setcimpl (ps, res->lits[0], res->lits[1]);
+      else
+#endif
+      ps->conflict = res;
+    }
+
+  if (!learned && !num_true && num_undef)
+    incjwh (ps, res);
+
+#ifdef NO_BINARY_CLAUSES
+  if (res == &ps->impl)
+    resetimpl (ps);
+#endif
+  return res;
+}
+
+static int
+trivial_clause (PS * ps)
+{
+  Lit **p, **q, *prev;
+  Var *v;
+
+  SORT (Lit *, cmp_ptr, ps->added,  ps->ahead - ps->added);
+
+  prev = 0;
+  q = ps->added;
+  for (p = q; p < ps->ahead; p++)
+    {
+      Lit *this = *p;
+
+      v = LIT2VAR (this);
+
+      if (prev == this)        /* skip repeated literals */
+    continue;
+
+      /* Top level satisfied ?
+       */
+      if (this->val == TRUE && !v->level)
+     return 1;
+
+      if (prev == NOTLIT (this))/* found pair of dual literals */
+    return 1;
+
+      *q++ = prev = this;
+    }
+
+  ps->ahead = q;            /* shrink */
+
+  return 0;
+}
+
+static void
+simplify_and_add_original_clause (PS * ps)
+{
+#ifdef NO_BINARY_CLAUSES
+  Cls * c;
+#endif
+  if (trivial_clause (ps))
+    {
+      ps->ahead = ps->added;
+
+      if (ps->ohead == ps->eoo)
+    ENLARGE (ps->oclauses, ps->ohead, ps->eoo);
+
+      *ps->ohead++ = 0;
+
+      ps->addedclauses++;
+      ps->oadded++;
+    }
+  else
+    {
+      if (ps->CLS != ps->clshead)
+    add_lit (ps, NOTLIT (ps->clshead[-1]));
+
+#ifdef NO_BINARY_CLAUSES
+      c =
+#endif
+      add_simplified_clause (ps, 0);
+#ifdef NO_BINARY_CLAUSES
+      if (c == &ps->impl) assert (!ps->implvalid);
+#endif
+    }
+}
+
+#ifndef NADC
+
+static void
+add_ado (PS * ps)
+{
+  unsigned len = ps->ahead - ps->added;
+  Lit ** ado, ** p, ** q, *lit;
+  Var * v, * u;
+
+#ifdef TRACE
+  assert (!ps->trace);
+#endif
+
+  ABORTIF (ps->ados < ps->hados && llength (ps->ados[0]) != len,
+           "internal: non matching all different constraint object lengths");
+
+  if (ps->hados == ps->eados)
+    ENLARGE (ps->ados, ps->hados, ps->eados);
+
+  NEWN (ado, len + 1);
+  *ps->hados++ = ado;
+
+  p = ps->added;
+  q = ado;
+  u = 0;
+  while (p < ps->ahead)
+    {
+      lit = *p++;
+      v = LIT2VAR (lit);
+      ABORTIF (v->inado,
+               "internal: variable in multiple all different objects");
+      v->inado = ado;
+      if (!u && !lit->val)
+    u = v;
+      *q++ = lit;
+    }
+
+  assert (q == ado + len);
+  *q++ = 0;
+
+  /* TODO simply do a conflict test as in propado */
+
+  ABORTIF (!u,
+    "internal: "
+    "adding fully instantiated all different object not implemented yet");
+
+  assert (u);
+  assert (u->inado == ado);
+  assert (!u->ado);
+  u->ado = ado;
+
+  ps->ahead = ps->added;
+}
+
+#endif
+
+static void
+hdown (PS * ps, Rnk * r)
+{
+  unsigned end, rpos, cpos, opos;
+  Rnk *child, *other;
+
+  assert (r->pos > 0);
+  assert (ps->heap[r->pos] == r);
+
+  end = ps->hhead - ps->heap;
+  rpos = r->pos;
+
+  for (;;)
+    {
+      cpos = 2 * rpos;
+      if (cpos >= end)
+    break;
+
+      opos = cpos + 1;
+      child = ps->heap[cpos];
+
+      if (cmp_rnk (r, child) < 0)
+    {
+      if (opos < end)
+        {
+          other = ps->heap[opos];
+
+          if (cmp_rnk (child, other) < 0)
+        {
+          child = other;
+          cpos = opos;
+        }
+        }
+    }
+      else if (opos < end)
+    {
+      child = ps->heap[opos];
+
+      if (cmp_rnk (r, child) >= 0)
+        break;
+
+      cpos = opos;
+    }
+      else
+    break;
+
+      ps->heap[rpos] = child;
+      child->pos = rpos;
+      rpos = cpos;
+    }
+
+  r->pos = rpos;
+  ps->heap[rpos] = r;
+}
+
+static Rnk *
+htop (PS * ps)
+{
+  assert (ps->hhead > ps->heap + 1);
+  return ps->heap[1];
+}
+
+static Rnk *
+hpop (PS * ps)
+{
+  Rnk *res, *last;
+  unsigned end;
+
+  assert (ps->hhead > ps->heap + 1);
+
+  res = ps->heap[1];
+  res->pos = 0;
+
+  end = --ps->hhead - ps->heap;
+  if (end == 1)
+    return res;
+
+  last = ps->heap[end];
+
+  ps->heap[last->pos = 1] = last;
+  hdown (ps, last);
+
+  return res;
+}
+
+inline static void
+hpush (PS * ps, Rnk * r)
+{
+  assert (!r->pos);
+
+  if (ps->hhead == ps->eoh)
+    ENLARGE (ps->heap, ps->hhead, ps->eoh);
+
+  r->pos = ps->hhead++ - ps->heap;
+  ps->heap[r->pos] = r;
+  hup (ps, r);
+}
+
+static void
+fix_trail_lits (PS * ps, long delta)
+{
+  Lit **p;
+  for (p = ps->trail; p < ps->thead; p++)
+    *p += delta;
+}
+
+#ifdef NO_BINARY_CLAUSES
+static void
+fix_impl_lits (PS * ps, long delta)
+{
+  Ltk * s;
+  Lit ** p;
+
+  for (s = ps->impls + 2; s <= ps->impls + 2 * ps->max_var + 1; s++)
+    for (p = s->start; p < s->start + s->count; p++)
+      *p += delta;
+}
+#endif
+
+static void
+fix_clause_lits (PS * ps, long delta)
+{
+  Cls **p, *clause;
+  Lit **q, *lit, **eol;
+
+  for (p = SOC; p != EOC; p = NXC (p))
+    {
+      clause = *p;
+      if (!clause)
+    continue;
+
+      q = clause->lits;
+      eol = end_of_lits (clause);
+      while (q < eol)
+    {
+      assert (q - clause->lits <= (int) clause->size);
+      lit = *q;
+      lit += delta;
+      *q++ = lit;
+    }
+    }
+}
+
+static void
+fix_added_lits (PS * ps, long delta)
+{
+  Lit **p;
+  for (p = ps->added; p < ps->ahead; p++)
+    *p += delta;
+}
+
+static void
+fix_assumed_lits (PS * ps, long delta)
+{
+  Lit **p;
+  for (p = ps->als; p < ps->alshead; p++)
+    *p += delta;
+}
+
+static void
+fix_cls_lits (PS * ps, long delta)
+{
+  Lit **p;
+  for (p = ps->CLS; p < ps->clshead; p++)
+    *p += delta;
+}
+
+static void
+fix_heap_rnks (PS * ps, long delta)
+{
+  Rnk **p;
+
+  for (p = ps->heap + 1; p < ps->hhead; p++)
+    *p += delta;
+}
+
+#ifndef NADC
+
+static void
+fix_ado (long delta, Lit ** ado)
+{
+  Lit ** p;
+  for (p = ado; *p; p++)
+    *p += delta;
+}
+
+static void
+fix_ados (PS * ps, long delta)
+{
+  Lit *** p;
+
+  for (p = ps->ados; p < ps->hados; p++)
+    fix_ado (delta, *p);
+}
+
+#endif
+
+static void
+enlarge (PS * ps, unsigned new_size_vars)
+{
+  long rnks_delta, lits_delta;
+  Lit *old_lits = ps->lits;
+  Rnk *old_rnks = ps->rnks;
+
+  RESIZEN (ps->lits, 2 * ps->size_vars, 2 * new_size_vars);
+  RESIZEN (ps->jwh, 2 * ps->size_vars, 2 * new_size_vars);
+  RESIZEN (ps->htps, 2 * ps->size_vars, 2 * new_size_vars);
+#ifndef NDSC
+  RESIZEN (ps->dhtps, 2 * ps->size_vars, 2 * new_size_vars);
+#endif
+  RESIZEN (ps->impls, 2 * ps->size_vars, 2 * new_size_vars);
+  RESIZEN (ps->vars, ps->size_vars, new_size_vars);
+  RESIZEN (ps->rnks, ps->size_vars, new_size_vars);
+
+  if ((lits_delta = ps->lits - old_lits))
+    {
+      fix_trail_lits (ps, lits_delta);
+      fix_clause_lits (ps, lits_delta);
+      fix_added_lits (ps, lits_delta);
+      fix_assumed_lits (ps, lits_delta);
+      fix_cls_lits (ps, lits_delta);
+#ifdef NO_BINARY_CLAUSES
+      fix_impl_lits (ps, lits_delta);
+#endif
+#ifndef NADC
+      fix_ados (ps, lits_delta);
+#endif
+    }
+
+  if ((rnks_delta = ps->rnks - old_rnks))
+    {
+      fix_heap_rnks (ps, rnks_delta);
+    }
+
+  assert (ps->mhead == ps->marked);
+
+  ps->size_vars = new_size_vars;
+}
+
+static void
+unassign (PS * ps, Lit * lit)
+{
+  Cls *reason;
+  Var *v;
+  Rnk *r;
+
+  assert (lit->val == TRUE);
+
+  LOG ( fprintf (ps->out, "%sunassign %d\n", ps->prefix, LIT2INT (lit)));
+
+  v = LIT2VAR (lit);
+  reason = v->reason;
+
+#ifdef NO_BINARY_CLAUSES
+  assert (reason != &ps->impl);
+  if (ISLITREASON (reason))
+    {
+      /* DO NOTHING */
+    }
+  else
+#endif
+  if (reason)
+    {
+      assert (reason->locked);
+      reason->locked = 0;
+      if (reason->learned && reason->size > 2)
+    {
+      assert (ps->llocked > 0);
+      ps->llocked--;
+    }
+    }
+
+  lit->val = UNDEF;
+  NOTLIT (lit)->val = UNDEF;
+
+  r = VAR2RNK (v);
+  if (!r->pos)
+    hpush (ps, r);
+
+#ifndef NDSC
+  {
+    Cls * p, * next, ** q;
+
+    q = LIT2DHTPS (lit);
+    p = *q;
+    *q = 0;
+
+    while (p)
+      {
+    Lit * other = p->lits[0];
+
+    if (other == lit)
+      {
+        other = p->lits[1];
+        q = p->next + 1;
-- 
2.33.0



  parent reply	other threads:[~2021-10-22 13:36 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-22 13:34 [RFC v3 00/12] kconfig: add support for conflict resolution Thorsten Berger
2021-10-22 13:35 ` [RFC v3 01/12] Add picosat.h Thorsten Berger
2021-10-22 16:57   ` Luis Chamberlain
2021-10-22 13:36 ` Thorsten Berger [this message]
2021-10-22 16:58   ` [RFC v3 02/12] Add picosat.c (1/3) Luis Chamberlain
2021-10-22 13:38 ` [RFC v3 03/12] Add picosat.c (2/3) Thorsten Berger
2021-10-22 16:59   ` Luis Chamberlain
2021-10-24  9:05   ` Masahiro Yamada
2021-10-24 23:52     ` Thorsten Berger
2021-10-22 13:39 ` [RFC v3 04/12] Add picosat.c (3/3) Thorsten Berger
2021-10-22 13:40 ` [RFC v3 05/12] Add definitions Thorsten Berger
2021-10-22 16:56   ` Luis Chamberlain
2021-10-22 13:41 ` [RFC v3 06/12] Add files for building constraints Thorsten Berger
2021-10-22 16:56   ` Luis Chamberlain
2021-10-22 13:43 ` [RFC v3 07/12] Add files for handling expressions Thorsten Berger
2021-10-22 13:44 ` [RFC v3 08/12] Add files for RangeFix Thorsten Berger
2021-10-22 13:45 ` [RFC v3 09/12] Add files with utility functions Thorsten Berger
2021-10-22 13:46 ` [RFC v3 10/12] Add tools Thorsten Berger
2021-10-22 13:47 ` [RFC v3 11/12] Add xconfig-modifications Thorsten Berger
2021-11-04  9:30   ` Masahiro Yamada
2021-10-22 13:48 ` [RFC v3 12/12] Simplify dependencies for MODULE_SIG_KEY_TYPE_RSA & MODULE_SIG_KEY_TYPE_ECDSA Thorsten Berger
2021-10-22 17:03   ` Luis Chamberlain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bfd8f79f-62dd-3899-621a-dfe17af70cc0@rub.de \
    --to=thorsten.berger@rub.de \
    --cc=deltaone@debian.org \
    --cc=eugene.groshev@gmail.com \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=mcgrof@suse.com \
    --cc=mgorman@suse.de \
    --cc=nadi@ualberta.ca \
    --cc=phayax@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.