satSolver2.c 60.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/**************************************************************************************************
MiniSat -- Copyright (c) 2005, Niklas Sorensson
http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/

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.
**************************************************************************************************/
// Modified to compile with MS Visual Studio 6.0 by Alan Mishchenko

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <math.h>
26
 
27 28 29 30
#include "satSolver2.h"

ABC_NAMESPACE_IMPL_START

31
#define SAT_USE_ANALYZE_FINAL
32
#define SAT_USE_PROOF_LOGGING
33 34 35 36 37 38 39 40

//=================================================================================================
// Debug:

//#define VERBOSEDEBUG

// For derivation output (verbosity level 2)
#define L_IND    "%-*d"
41
#define L_ind    solver2_dlevel(s)*2+2,solver2_dlevel(s)
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
#define L_LIT    "%sx%d"
#define L_lit(p) lit_sign(p)?"~":"", (lit_var(p))
static void printlits(lit* begin, lit* end)
{
    int i;
    for (i = 0; i < end - begin; i++)
        printf(L_LIT" ",L_lit(begin[i]));
}

//=================================================================================================
// Random numbers:


// Returns a random float 0 <= x < 1. Seed must never be 0.
static inline double drand(double* seed) {
    int q;
    *seed *= 1389796;
    q = (int)(*seed / 2147483647);
    *seed -= (double)q * 2147483647;
    return *seed / 2147483647; }


// Returns a random integer 0 <= x < size. Seed must never be 0.
static inline int irand(double* seed, int size) {
    return (int)(drand(seed) * size); }

//=================================================================================================
69 70 71 72 73 74
// Variable datatype + minor functions:

static const int var0  = 1;
static const int var1  = 0;
static const int varX  = 3;

75
struct varinfo2_t
76
{
77
//    unsigned val    :  2;  // variable value 
78
    unsigned pol    :  1;  // last polarity
79
    unsigned partA  :  1;  // partA variable
80
    unsigned tag    :  4;  // conflict analysis tags
81
//    unsigned lev    : 24;  // variable level
82 83
};

84 85
int    var_is_partA (sat_solver2* s, int v)              { return s->vi[v].partA;  }
void   var_set_partA(sat_solver2* s, int v, int partA)   { s->vi[v].partA = partA; }
86

87 88 89 90
//static inline int     var_level     (sat_solver2* s, int v)            { return s->vi[v].lev; }
static inline int     var_level     (sat_solver2* s, int v)            { return s->levels[v];  }
//static inline int     var_value     (sat_solver2* s, int v)            { return s->vi[v].val; }
static inline int     var_value     (sat_solver2* s, int v)            { return s->assigns[v]; }
91
static inline int     var_polar     (sat_solver2* s, int v)            { return s->vi[v].pol; }
92

93 94 95 96
//static inline void    var_set_level (sat_solver2* s, int v, int lev)   { s->vi[v].lev = lev;  }
static inline void    var_set_level (sat_solver2* s, int v, int lev)   { s->levels[v] = lev;  }
//static inline void    var_set_value (sat_solver2* s, int v, int val)   { s->vi[v].val = val;  }
static inline void    var_set_value (sat_solver2* s, int v, int val)   { s->assigns[v] = val; }
97
static inline void    var_set_polar (sat_solver2* s, int v, int pol)   { s->vi[v].pol = pol;  }
98 99

// variable tags
100
static inline int     var_tag       (sat_solver2* s, int v)            { return s->vi[v].tag; }
101
static inline void    var_set_tag   (sat_solver2* s, int v, int tag)   { 
102
    assert( tag > 0 && tag < 16 );
103 104 105 106 107
    if ( s->vi[v].tag == 0 )
        veci_push( &s->tagged, v );
    s->vi[v].tag = tag;                           
}
static inline void    var_add_tag   (sat_solver2* s, int v, int tag)   { 
108
    assert( tag > 0 && tag < 16 );
109 110 111 112 113 114 115 116 117 118
    if ( s->vi[v].tag == 0 )
        veci_push( &s->tagged, v );
    s->vi[v].tag |= tag;                           
}
static inline void    solver2_clear_tags(sat_solver2* s, int start)    { 
    int i, * tagged = veci_begin(&s->tagged);
    for (i = start; i < veci_size(&s->tagged); i++)
        s->vi[tagged[i]].tag = 0;
    veci_resize(&s->tagged,start);
}
119

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
// level marks
static inline int     var_lev_mark (sat_solver2* s, int v)             { 
    return (veci_begin(&s->trail_lim)[var_level(s,v)] & 0x80000000) > 0;   
}
static inline void    var_lev_set_mark (sat_solver2* s, int v)         { 
    int level = var_level(s,v);
    assert( level < veci_size(&s->trail_lim) );
    veci_begin(&s->trail_lim)[level] |= 0x80000000;
    veci_push(&s->mark_levels, level);
}
static inline void    solver2_clear_marks(sat_solver2* s)              { 
    int i, * mark_levels = veci_begin(&s->mark_levels);
    for (i = 0; i < veci_size(&s->mark_levels); i++)
        veci_begin(&s->trail_lim)[mark_levels[i]] &= 0x7FFFFFFF;
    veci_resize(&s->mark_levels,0);
}

137
//=================================================================================================
138 139
// Clause datatype + minor functions:

140 141 142
static inline satset* clause_read   (sat_solver2* s, cla h)      { return (h & 1) ? satset_read(&s->learnts, h>>1)  : satset_read(&s->clauses, h>>1);          }
static inline cla     clause_handle (sat_solver2* s, satset* c)  { return c->learnt ? (satset_handle(&s->learnts, c)<<1)|1: satset_handle(&s->clauses, c)<<1;  }
static inline int     clause_check  (sat_solver2* s, satset* c)  { return c->learnt ? satset_check(&s->learnts, c)  : satset_check(&s->clauses, c);            }
143
static inline int     clause_proofid(sat_solver2* s, satset* c, int partA)  { return c->learnt ? (veci_begin(&s->claProofs)[c->Id]<<2) | (partA<<1) : (satset_handle(&s->clauses, c)<<2) | (partA<<1) | 1; }
144 145
static inline int     clause_is_used(sat_solver2* s, cla h)      { return (h & 1) ? (h >> 1) < s->hLearntPivot : (h >> 1) < s->hClausePivot;                   }

146 147 148 149
//static inline int     var_reason    (sat_solver2* s, int v)      { return (s->reasons[v]&1) ? 0 : s->reasons[v] >> 1;                   } 
//static inline int     lit_reason    (sat_solver2* s, int l)      { return (s->reasons[lit_var(l)&1]) ? 0 : s->reasons[lit_var(l)] >> 1; } 
//static inline satset* var_unit_clause(sat_solver2* s, int v)           { return (s->reasons[v]&1) ? clause_read(s, s->reasons[v] >> 1) : NULL;  } 
//static inline void    var_set_unit_clause(sat_solver2* s, int v, cla i){ assert(i && !s->reasons[v]); s->reasons[v] = (i << 1) | 1;             } 
150 151
static inline int     var_reason    (sat_solver2* s, int v)            { return s->reasons[v];           } 
static inline int     lit_reason    (sat_solver2* s, int l)            { return s->reasons[lit_var(l)];  } 
152 153
static inline satset* var_unit_clause(sat_solver2* s, int v)           { return clause_read(s, s->units[v]);                                          } 
static inline void    var_set_unit_clause(sat_solver2* s, int v, cla i){ assert(v >= 0 && v < s->size && !s->units[v]); s->units[v] = i; s->nUnits++; } 
154 155

// these two only work after creating a clause before the solver is called
156 157 158
int    clause_is_partA (sat_solver2* s, int h)                   { return clause_read(s, h)->partA;         }  
void   clause_set_partA(sat_solver2* s, int h, int partA)        { clause_read(s, h)->partA = partA;        }
int    clause_id(sat_solver2* s, int h)                          { return clause_read(s, h)->Id;            }
159

160 161 162 163 164
//=================================================================================================
// Simple helpers:

static inline int     solver2_dlevel(sat_solver2* s)       { return veci_size(&s->trail_lim); }
static inline veci*   solver2_wlist(sat_solver2* s, lit l) { return &s->wlists[l];            }
165 166

//=================================================================================================
167 168 169 170 171 172
// Proof logging:

static inline void proof_chain_start( sat_solver2* s, satset* c )
{
    if ( s->fProofLogging )
    {
173 174 175 176
        s->iStartChain = veci_size(&s->proofs);
        veci_push(&s->proofs, 0);
        veci_push(&s->proofs, 0);
        veci_push(&s->proofs, clause_proofid(s, c, 0) );
177 178 179
    }
}

180
static inline void proof_chain_resolve( sat_solver2* s, satset* cls, int Var )
181
{
182
    if ( s->fProofLogging )
183
    {
184
        satset* c = cls ? cls : var_unit_clause( s, Var );
185
        veci_push(&s->proofs, clause_proofid(s, c, var_is_partA(s,Var)) );
186
//        printf( "%d %d  ", clause_proofid(s, c), Var );
187 188 189
    }
}

190
static inline int proof_chain_stop( sat_solver2* s )
191 192 193
{
    if ( s->fProofLogging )
    {
194
        int RetValue = s->iStartChain;
195 196 197
        satset* c = (satset*)(veci_begin(&s->proofs) + s->iStartChain);
        assert( s->iStartChain > 0 && s->iStartChain < veci_size(&s->proofs) );
        c->nEnts = veci_size(&s->proofs) - s->iStartChain - 2;
198
        s->iStartChain = 0;
199
        return RetValue;
200
    }
201
    return 0;
202 203 204
}

//=================================================================================================
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
// Variable order functions:

static inline void order_update(sat_solver2* s, int v) // updateorder
{
    int*      orderpos = s->orderpos;
    int*      heap     = veci_begin(&s->order);
    int       i        = orderpos[v];
    int       x        = heap[i];
    int       parent   = (i - 1) / 2;
    assert(s->orderpos[v] != -1);
    while (i != 0 && s->activity[x] > s->activity[heap[parent]]){
        heap[i]           = heap[parent];
        orderpos[heap[i]] = i;
        i                 = parent;
        parent            = (i - 1) / 2;
    }
    heap[i]     = x;
    orderpos[x] = i;
}
static inline void order_assigned(sat_solver2* s, int v) 
{
}
static inline void order_unassigned(sat_solver2* s, int v) // undoorder
{
    int* orderpos = s->orderpos;
    if (orderpos[v] == -1){
        orderpos[v] = veci_size(&s->order);
        veci_push(&s->order,v);
        order_update(s,v);
    }
}
static inline int  order_select(sat_solver2* s, float random_var_freq) // selectvar
{
    int*      heap     = veci_begin(&s->order);
    int*      orderpos = s->orderpos;
    // Random decision:
    if (drand(&s->random_seed) < random_var_freq){
        int next = irand(&s->random_seed,s->size);
        assert(next >= 0 && next < s->size);
244
        if (var_value(s, next) == varX)
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
            return next;
    }
    // Activity based decision:
    while (veci_size(&s->order) > 0){
        int    next  = heap[0];
        int    size  = veci_size(&s->order)-1;
        int    x     = heap[size];
        veci_resize(&s->order,size);
        orderpos[next] = -1;
        if (size > 0){
            unsigned act   = s->activity[x];
            int      i     = 0;
            int      child = 1;
            while (child < size){
                if (child+1 < size && s->activity[heap[child]] < s->activity[heap[child+1]])
                    child++;
                assert(child < size);
                if (act >= s->activity[heap[child]])
                    break;
                heap[i]           = heap[child];
                orderpos[heap[i]] = i;
                i                 = child;
                child             = 2 * child + 1;
            }
            heap[i]           = x;
            orderpos[heap[i]] = i;
        }
272
        if (var_value(s, next) == varX)
273 274 275 276 277
            return next;
    }
    return var_Undef;
}

278

279 280 281
//=================================================================================================
// Activity functions:

282
#ifdef USE_FLOAT_ACTIVITY2
283 284 285 286

static inline void act_var_rescale(sat_solver2* s)  {
    double* activity = s->activity;
    int i;
287
    for (i = 0; i < s->size; i++)
288 289
        activity[i] *= 1e-100;
    s->var_inc *= 1e-100;
290
}
291 292 293 294 295 296 297
static inline void act_clause_rescale(sat_solver2* s) {
    static int Total = 0;
    float * claActs = (float *)veci_begin(&s->claActs);
    int i, clk = clock();
    for (i = 0; i < veci_size(&s->claActs); i++)
        claActs[i] *= (float)1e-20;
    s->cla_inc *= (float)1e-20;
298

299
    Total += clock() - clk;
300 301
    printf( "Rescaling...   Cla inc = %10.3f  Conf = %10d   ", s->cla_inc,  s->stats.conflicts );
    Abc_PrintTime( 1, "Time", Total );
302
}
303 304
static inline void act_var_bump(sat_solver2* s, int v) {
    s->activity[v] += s->var_inc;
305
    if (s->activity[v] > 1e100)
306 307 308 309
        act_var_rescale(s);
    if (s->orderpos[v] != -1)
        order_update(s,v);
}
310 311 312 313 314 315 316 317 318
static inline void act_clause_bump(sat_solver2* s, satset*c) {
    float * claActs = (float *)veci_begin(&s->claActs);
    assert( c->Id < veci_size(&s->claActs) );
    claActs[c->Id] += s->cla_inc;
    if (claActs[c->Id] > (float)1e20) 
        act_clause_rescale(s);
}
static inline void act_var_decay(sat_solver2* s)    { s->var_inc *= s->var_decay; }
static inline void act_clause_decay(sat_solver2* s) { s->cla_inc *= s->cla_decay; }
319

320
#else
321

322 323 324 325 326 327 328 329
static inline void act_var_rescale(sat_solver2* s) {
    unsigned* activity = s->activity;
    int i;
    for (i = 0; i < s->size; i++)
        activity[i] >>= 19;
    s->var_inc >>= 19;
    s->var_inc = Abc_MaxInt( s->var_inc, (1<<4) );
}
330 331
static inline void act_clause_rescale(sat_solver2* s) {
    static int Total = 0;
332
    int i, clk = clock();
333
    unsigned * claActs = (unsigned *)veci_begin(&s->claActs);
334
    for (i = 1; i < veci_size(&s->claActs); i++)
335
        claActs[i] >>= 14;
336 337
    s->cla_inc >>= 14;
    s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) );
338

339
//    Total += clock() - clk;
340 341
//    printf( "Rescaling...   Cla inc = %5d  Conf = %10d   ", s->cla_inc,  s->stats.conflicts );
//    Abc_PrintTime( 1, "Time", Total );
342
}
343 344 345 346 347 348 349 350 351
static inline void act_var_bump(sat_solver2* s, int v) {
    s->activity[v] += s->var_inc;
    if (s->activity[v] & 0x80000000)
        act_var_rescale(s);
    if (s->orderpos[v] != -1)
        order_update(s,v);
}
static inline void act_clause_bump(sat_solver2* s, satset*c) {
    unsigned * claActs = (unsigned *)veci_begin(&s->claActs);
352
    assert( c->Id > 0 && c->Id < veci_size(&s->claActs) );
353 354
    claActs[c->Id] += s->cla_inc;
    if (claActs[c->Id] & 0x80000000) 
355 356
        act_clause_rescale(s);
}
357
static inline void act_var_decay(sat_solver2* s)    { s->var_inc += (s->var_inc >>  4); }
358 359
static inline void act_clause_decay(sat_solver2* s) { s->cla_inc += (s->cla_inc >> 10); }

360
#endif
361 362

//=================================================================================================
363 364
// Clause functions:

365
static int clause_create_new(sat_solver2* s, lit* begin, lit* end, int learnt, int proof_id)
366 367 368 369 370 371 372 373
{
    satset* c;
    int i, Cid, nLits = end - begin;
    assert(nLits < 1 || begin[0] >= 0);
    assert(nLits < 2 || begin[1] >= 0);
    assert(nLits < 1 || lit_var(begin[0]) < s->size);
    assert(nLits < 2 || lit_var(begin[1]) < s->size);
    // add memory if needed
374

375 376 377
    // assign clause ID
    if ( learnt )
    {
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
        if ( veci_size(&s->learnts) + satset_size(nLits) > s->learnts.cap )
        {
            int nMemAlloc = s->learnts.cap ? 2 * s->learnts.cap : (1 << 20);
            s->learnts.ptr = ABC_REALLOC( int, veci_begin(&s->learnts), nMemAlloc );
    //        printf( "Reallocing from %d to %d...\n", s->learnts.cap, nMemAlloc );
            s->learnts.cap = nMemAlloc;
            if ( veci_size(&s->learnts) == 0 )
                veci_push( &s->learnts, -1 );
        }
        // create clause
        c = (satset*)(veci_begin(&s->learnts) + veci_size(&s->learnts));
        ((int*)c)[0] = 0;
        c->learnt = learnt;
        c->nEnts  = nLits;
        for (i = 0; i < nLits; i++)
            c->pEnts[i] = begin[i];
        // count the clause
395 396 397
        s->stats.learnts++;
        s->stats.learnts_literals += nLits;
        c->Id = s->stats.learnts;
398 399 400 401 402 403
        assert( c->Id == veci_size(&s->claActs) );
        veci_push(&s->claActs, 0);
        if ( proof_id )
            veci_push(&s->claProofs, proof_id);
        if ( nLits > 2 )
            act_clause_bump( s,c );
404 405 406 407 408
        // extend storage
        Cid = (veci_size(&s->learnts) << 1) | 1;
        s->learnts.size += satset_size(nLits);
        assert( veci_size(&s->learnts) <= s->learnts.cap );
        assert(((ABC_PTRUINT_T)c & 3) == 0);
409 410
//        printf( "Clause for proof %d: ", proof_id );
//        satset_print( c );
411 412
        // remember the last one
        s->hLearntLast = Cid;
413 414 415
    }
    else
    {
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
        if ( veci_size(&s->clauses) + satset_size(nLits) > s->clauses.cap )
        {
            int nMemAlloc = s->clauses.cap ? 2 * s->clauses.cap : (1 << 20);
            s->clauses.ptr = ABC_REALLOC( int, veci_begin(&s->clauses), nMemAlloc );
    //        printf( "Reallocing from %d to %d...\n", s->clauses.cap, nMemAlloc );
            s->clauses.cap = nMemAlloc;
            if ( veci_size(&s->clauses) == 0 )
                veci_push( &s->clauses, -1 );
        }
        // create clause
        c = (satset*)(veci_begin(&s->clauses) + veci_size(&s->clauses));
        ((int*)c)[0] = 0;
        c->learnt = learnt;
        c->nEnts  = nLits;
        for (i = 0; i < nLits; i++)
            c->pEnts[i] = begin[i];
        // count the clause
433 434
        s->stats.clauses++;
        s->stats.clauses_literals += nLits;
435
        c->Id = s->stats.clauses;
436 437 438 439 440
        // extend storage
        Cid = (veci_size(&s->clauses) << 1);
        s->clauses.size += satset_size(nLits);
        assert( veci_size(&s->clauses) <= s->clauses.cap );
        assert(((ABC_PTRUINT_T)c & 3) == 0);
441
    }
442 443 444 445 446
    // watch the clause
    if ( nLits > 1 ){
        veci_push(solver2_wlist(s,lit_neg(begin[0])),Cid);
        veci_push(solver2_wlist(s,lit_neg(begin[1])),Cid);
    }
447 448 449 450
    return Cid;
}

//=================================================================================================
451 452
// Minor (solver) functions:

453
static inline int solver2_enqueue(sat_solver2* s, lit l, cla from)
454
{
455
    int v = lit_var(l);
456
#ifdef VERBOSEDEBUG
457
    printf(L_IND"enqueue("L_LIT")\n", L_ind, L_lit(l));
458
#endif
459 460 461 462
    if (var_value(s, v) != varX)
        return var_value(s, v) == lit_sign(l);
    else
    {  // New fact -- store it.
463 464 465
#ifdef VERBOSEDEBUG
        printf(L_IND"bind("L_LIT")\n", L_ind, L_lit(l));
#endif
466
        var_set_value( s, v, lit_sign(l) );
467
        var_set_level( s, v, solver2_dlevel(s) );
468
        s->reasons[v] = from;  //  = from << 1;
469 470 471 472 473 474
        s->trail[s->qtail++] = l;
        order_assigned(s, v);
        return true;
    }
}

475
static inline int solver2_assume(sat_solver2* s, lit l)
476
{
477
    assert(s->qtail == s->qhead);
478
    assert(var_value(s, lit_var(l)) == varX);
479
#ifdef VERBOSEDEBUG
480 481
    printf(L_IND"assume("L_LIT")  ", L_ind, L_lit(l));
    printf( "act = %.20f\n", s->activity[lit_var(l)] );
482 483
#endif
    veci_push(&s->trail_lim,s->qtail);
484
    return solver2_enqueue(s,l,0);
485 486
}

487
static void solver2_canceluntil(sat_solver2* s, int level) {
488 489 490
    lit*     trail;   
    int      bound;
    int      lastLev;
491 492
    int      c, x;
   
493
    if (solver2_dlevel(s) <= level)
494 495 496 497 498 499
        return;

    trail   = s->trail;
    bound   = (veci_begin(&s->trail_lim))[level];
    lastLev = (veci_begin(&s->trail_lim))[veci_size(&s->trail_lim)-1];

500 501 502 503 504
    for (c = s->qtail-1; c >= bound; c--) 
    {
        x = lit_var(trail[c]);
        var_set_value(s, x, varX);
        s->reasons[x] = 0;
505
        if ( c < lastLev )
506
            var_set_polar(s, x, !lit_sign(trail[c]));
507 508 509 510 511 512 513 514 515
    }

    for (c = s->qhead-1; c >= bound; c--)
        order_unassigned(s,lit_var(trail[c]));

    s->qhead = s->qtail = bound;
    veci_resize(&s->trail_lim,level);
}

516 517

static void solver2_record(sat_solver2* s, veci* cls, int proof_id)
518
{
519 520
    lit* begin = veci_begin(cls);
    lit* end   = begin + veci_size(cls);
521
    cla  Cid   = clause_create_new(s,begin,end,1, proof_id);
522
    assert(veci_size(cls) > 0);
523 524
    if ( veci_size(cls) == 1 )
    {
525 526
        if ( s->fProofLogging )
            var_set_unit_clause(s, lit_var(begin[0]), Cid);
527
        Cid = 0;
528
    }
529
    solver2_enqueue(s, begin[0], Cid);
530 531 532
}


533
static double solver2_progress(sat_solver2* s)
534
{
535 536
    int i;
    double progress = 0.0, F = 1.0 / s->size;
537
    for (i = 0; i < s->size; i++)
538 539
        if (var_value(s, i) != varX)
            progress += pow(F, var_level(s, i));
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
    return progress / s->size;
}

//=================================================================================================
// Major methods:

/*_________________________________________________________________________________________________
|
|  analyzeFinal : (p : Lit)  ->  [void]
|  
|  Description:
|    Specialized analysis procedure to express the final conflict in terms of assumptions.
|    Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and
|    stores the result in 'out_conflict'.
|________________________________________________________________________________________________@*/
/*
556
void Solver::analyzeFinal(satset* confl, bool skip_first)
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
{
    // -- NOTE! This code is relatively untested. Please report bugs!
    conflict.clear();
    if (root_level == 0) return;

    vec<char>& seen  = analyze_seen;
    for (int i = skip_first ? 1 : 0; i < confl->size(); i++){
        Var x = var((*confl)[i]);
        if (level[x] > 0)
            seen[x] = 1;
    }

    int start = (root_level >= trail_lim.size()) ? trail.size()-1 : trail_lim[root_level];
    for (int i = start; i >= trail_lim[0]; i--){
        Var     x = var(trail[i]);
        if (seen[x]){
            GClause r = reason[x];
            if (r == GClause_NULL){
                assert(level[x] > 0);
                conflict.push(~trail[i]);
            }else{
                if (r.isLit()){
                    Lit p = r.lit();
                    if (level[var(p)] > 0)
                        seen[var(p)] = 1;
                }else{
                    Clause& c = *r.clause();
                    for (int j = 1; j < c.size(); j++)
                        if (level[var(c[j])] > 0)
                            seen[var(c[j])] = 1;
                }
            }
            seen[x] = 0;
        }
    }
}
*/

#ifdef SAT_USE_ANALYZE_FINAL

597
static int solver2_analyze_final(sat_solver2* s, satset* conf, int skip_first)
598
{
599
    int i, j, x;//, start;
600 601
    veci_resize(&s->conf_final,0);
    if ( s->root_level == 0 )
602 603
        return -1;
    proof_chain_start( s, conf );
604
    assert( veci_size(&s->tagged) == 0 );
605
    satset_foreach_var( conf, x, i, skip_first ){
606 607
        if ( var_level(s,x) )
            var_set_tag(s, x, 1);
608 609
        else
            proof_chain_resolve( s, NULL, x );
610
    }
611 612 613
    assert( s->root_level >= veci_size(&s->trail_lim) );
//    start = (s->root_level >= veci_size(&s->trail_lim))? s->qtail-1 : (veci_begin(&s->trail_lim))[s->root_level];
    for (i = s->qtail-1; i >= (veci_begin(&s->trail_lim))[0]; i--){
614 615
        x = lit_var(s->trail[i]);
        if (var_tag(s,x)){
616
            satset* c = clause_read(s, var_reason(s,x));
617
            if (c){
618
                proof_chain_resolve( s, c, x );
619
                satset_foreach_var( c, x, j, 1 ){
620 621 622 623
                    if ( var_level(s,x) )
                        var_set_tag(s, x, 1);
                    else
                        proof_chain_resolve( s, NULL, x );
624
                } 
625 626 627
            }else {
                assert( var_level(s,x) );
                veci_push(&s->conf_final,lit_neg(s->trail[i]));
628 629 630
            }
        }
    }
631
    solver2_clear_tags(s,0);
632
    return proof_chain_stop( s );
633 634 635 636 637
}

#endif


638
static int solver2_lit_removable_rec(sat_solver2* s, int v)
639
{
640 641 642 643 644 645 646 647 648 649 650 651
    // tag[0]: True if original conflict clause literal.
    // tag[1]: Processed by this procedure
    // tag[2]: 0=non-removable, 1=removable

    satset* c;
    int i, x;

    // skip visited
    if (var_tag(s,v) & 2)
        return (var_tag(s,v) & 4) > 0;

    // skip decisions on a wrong level
652
    c = clause_read(s, var_reason(s,v));
653 654 655 656 657
    if ( c == NULL ){
        var_add_tag(s,v,2);
        return 0;
    }

658
    satset_foreach_var( c, x, i, 1 ){
659
        if (var_tag(s,x) & 1)
660
            solver2_lit_removable_rec(s, x);
661 662
        else{
            if (var_level(s,x) == 0 || var_tag(s,x) == 6) continue;     // -- 'x' checked before, found to be removable (or belongs to the toplevel)
663
            if (var_tag(s,x) == 2 || !var_lev_mark(s,x) || !solver2_lit_removable_rec(s, x))
664 665 666 667 668 669
            {  // -- 'x' checked before, found NOT to be removable, or it belongs to a wrong level, or cannot be removed
                var_add_tag(s,v,2); 
                return 0; 
            }
        }
    }
670 671
    if ( s->fProofLogging && (var_tag(s,v) & 1) )
        veci_push(&s->min_lit_order, v );
672 673 674 675
    var_add_tag(s,v,6);
    return 1;
}

676
static int solver2_lit_removable(sat_solver2* s, int x)
677 678 679 680 681 682 683 684 685 686 687
{
    satset* c;
    int i, top;
    if ( !var_reason(s,x) )
        return 0;
    if ( var_tag(s,x) & 2 )
    {
        assert( var_tag(s,x) & 1 );
        return 1;
    }
    top = veci_size(&s->tagged);
688
    veci_resize(&s->stack,0);
689 690
    veci_push(&s->stack, x << 1);
    while (veci_size(&s->stack))
691
    {
692 693 694 695 696 697
        x = veci_pop(&s->stack);
        if ( s->fProofLogging ){
            if ( x & 1 ){
                if ( var_tag(s,x >> 1) & 1 )
                    veci_push(&s->min_lit_order, x >> 1 );
                continue;
698
            }
699 700 701
            veci_push(&s->stack, x ^ 1 );
        }
        x >>= 1;
702
        c = clause_read(s, var_reason(s,x));
703
        satset_foreach_var( c, x, i, 1 ){
704 705 706 707 708 709 710 711
            if (var_tag(s,x) || !var_level(s,x))
                continue;
            if (!var_reason(s,x) || !var_lev_mark(s,x)){
                solver2_clear_tags(s, top);
                return 0;
            }
            veci_push(&s->stack, x << 1);
            var_set_tag(s, x, 2);
712 713
        }
    }
714
    return 1;
715 716
}

717
static void solver2_logging_order(sat_solver2* s, int x)
718
{
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
    satset* c;
    int i;
    if ( (var_tag(s,x) & 4) )
        return;
    var_add_tag(s, x, 4);
    veci_resize(&s->stack,0);
    veci_push(&s->stack,x << 1);
    while (veci_size(&s->stack))
    {
        x = veci_pop(&s->stack);
        if ( x & 1 ){
            veci_push(&s->min_step_order, x >> 1 );
            continue;
        }
        veci_push(&s->stack, x ^ 1 );
        x >>= 1;
735
        c = clause_read(s, var_reason(s,x));
736
//        if ( !c )
737
//            printf( "solver2_logging_order(): Error in conflict analysis!!!\n" );
738
        satset_foreach_var( c, x, i, 1 ){
739 740 741 742 743 744 745
            if ( !var_level(s,x) || (var_tag(s,x) & 1) )
                continue;
            veci_push(&s->stack, x << 1);
            var_add_tag(s, x, 4);
        }
    }
}
746

747 748 749 750 751 752 753
static void solver2_logging_order_rec(sat_solver2* s, int x)
{
    satset* c;
    int i, y;
    if ( (var_tag(s,x) & 8) )
        return;
    c = clause_read(s, var_reason(s,x));
754
    satset_foreach_var( c, y, i, 1 )
755 756 757 758 759 760
        if ( var_level(s,y) && (var_tag(s,y) & 1) == 0 )
            solver2_logging_order_rec(s, y);
    var_add_tag(s, x, 8);
    veci_push(&s->min_step_order, x);
}

761
static int solver2_analyze(sat_solver2* s, satset* c, veci* learnt)
762
{
763
    int cnt      = 0;
764
    lit p        = 0;
765 766
    int x, ind   = s->qtail-1;
    int proof_id = 0;
767 768 769
    lit* lits,* vars, i, j, k;
    assert( veci_size(&s->tagged) == 0 );
    // tag[0] - visited by conflict analysis (afterwards: literals of the learned clause)
770 771
    // tag[1] - visited by solver2_lit_removable() with success
    // tag[2] - visited by solver2_logging_order()
772

773 774 775 776
    proof_chain_start( s, c );
    veci_push(learnt,lit_Undef);
    while ( 1 ){
        assert(c != 0);
777
        if (c->learnt)
778
            act_clause_bump(s,c);
779
        satset_foreach_var( c, x, j, (int)(p > 0) ){
780 781 782 783 784
            assert(x >= 0 && x < s->size);
            if ( var_tag(s, x) )
                continue;
            if ( var_level(s,x) == 0 )
            {
785
                proof_chain_resolve( s, NULL, x );
786 787 788 789 790 791 792
                continue;
            }
            var_set_tag(s, x, 1);
            act_var_bump(s,x);
            if (var_level(s,x) == solver2_dlevel(s))
                cnt++;
            else
793
                veci_push(learnt,c->pEnts[j]);
794 795 796 797 798
        }

        while (!var_tag(s, lit_var(s->trail[ind--])));

        p = s->trail[ind+1];
799
        c = clause_read(s, lit_reason(s,p));
800 801 802 803 804
        cnt--;
        if ( cnt == 0 )
            break;
        proof_chain_resolve( s, c, lit_var(p) );
    }
805 806
    *veci_begin(learnt) = lit_neg(p);

807 808
    // mark levels
    assert( veci_size(&s->mark_levels) == 0 );
809
    lits = veci_begin(learnt);
810
    for (i = 1; i < veci_size(learnt); i++)
811
        var_lev_set_mark(s, lit_var(lits[i]));
812 813

    // simplify (full)
814
    veci_resize(&s->min_lit_order, 0);
815
    for (i = j = 1; i < veci_size(learnt); i++){
816
//        if (!solver2_lit_removable( s,lit_var(lits[i])))
817
        if (!solver2_lit_removable_rec(s,lit_var(lits[i]))) // changed to vars!!!
818
            lits[j++] = lits[i];
819 820 821 822 823 824 825 826 827
    } 

    // record the proof
    if ( s->fProofLogging )
    {
        // collect additional clauses to resolve
        veci_resize(&s->min_step_order, 0);
        vars = veci_begin(&s->min_lit_order);
        for (i = 0; i < veci_size(&s->min_lit_order); i++)
828 829
//            solver2_logging_order(s, vars[i]);
            solver2_logging_order_rec(s, vars[i]);
830 831 832 833

        // add them in the reverse order
        vars = veci_begin(&s->min_step_order);
        for (i = veci_size(&s->min_step_order); i > 0; ) { i--;
834
            c = clause_read(s, var_reason(s,vars[i]));
835
            proof_chain_resolve( s, c, vars[i] );
836
            satset_foreach_var(c, x, k, 1)
837
                if ( var_level(s,x) == 0 )
838
                    proof_chain_resolve( s, NULL, x );
839
        }
840
        proof_id = proof_chain_stop( s );
841 842
    }

843 844 845
    // unmark levels
    solver2_clear_marks( s );

846 847 848 849 850
    // update size of learnt + statistics
    veci_resize(learnt,j);
    s->stats.tot_literals += j;

    // clear tags
851
    solver2_clear_tags(s,0);
852 853 854

#ifdef DEBUG
    for (i = 0; i < s->size; i++)
855
        assert(!var_tag(s, i));
856 857 858 859 860 861 862 863
#endif

#ifdef VERBOSEDEBUG
    printf(L_IND"Learnt {", L_ind);
    for (i = 0; i < veci_size(learnt); i++) printf(" "L_LIT, L_lit(lits[i]));
#endif
    if (veci_size(learnt) > 1){
        lit tmp;
864 865
        int max_i = 1;
        int max   = var_level(s, lit_var(lits[1]));
866
        for (i = 2; i < veci_size(learnt); i++)
867 868
            if (max < var_level(s, lit_var(lits[i]))) {
                max = var_level(s, lit_var(lits[i]));
869 870 871 872 873 874 875 876 877
                max_i = i;
            }

        tmp         = lits[1];
        lits[1]     = lits[max_i];
        lits[max_i] = tmp;
    }
#ifdef VERBOSEDEBUG
    {
878
        int lev = veci_size(learnt) > 1 ? var_level(s, lit_var(lits[1])) : 0;
879 880 881
        printf(" } at level %d\n", lev);
    }
#endif
882
    return proof_id;
883 884
}

885
satset* solver2_propagate(sat_solver2* s)
886
{
887
    satset* c, * confl  = NULL;
888 889 890
    veci* ws;
    lit* lits, false_lit, p, * stop, * k;
    cla* begin,* end, *i, *j;
891
    int Lit;
892

893
    while (confl == 0 && s->qtail - s->qhead > 0){
894

895
        p  = s->trail[s->qhead++];
896
        ws = solver2_wlist(s,p);
897 898
        begin = (cla*)veci_begin(ws);
        end   = begin + veci_size(ws);
899 900 901 902 903

        s->stats.propagations++;
        s->simpdb_props--;

        for (i = j = begin; i < end; ){
904 905
            c = clause_read(s,*i);
            lits = c->pEnts;
906 907 908 909 910 911 912 913 914 915 916 917 918 919

            // Make sure the false literal is data[1]:
            false_lit = lit_neg(p);
            if (lits[0] == false_lit){
                lits[0] = lits[1];
                lits[1] = false_lit;
            }
            assert(lits[1] == false_lit);

            // If 0th watch is true, then clause is already satisfied.
            if (var_value(s, lit_var(lits[0])) == lit_sign(lits[0]))
                *j++ = *i;
            else{
                // Look for new watch:
920
                stop = lits + c->nEnts;
921 922 923 924 925 926
                for (k = lits + 2; k < stop; k++){
                    if (var_value(s, lit_var(*k)) != !lit_sign(*k)){
                        lits[1] = *k;
                        *k = false_lit;
                        veci_push(solver2_wlist(s,lit_neg(lits[1])),*i);
                        goto WatchFound; }
927
                }
928

929
                // Did not find watch -- clause is unit under assignment:
930
                Lit = lits[0];
931
                if (s->fProofLogging && solver2_dlevel(s) == 0){
932 933
                    int k, x, proof_id, Cid, Var = lit_var(Lit);
                    int fLitIsFalse = (var_value(s, Var) == !lit_sign(Lit)); 
934 935
                    // Log production of top-level unit clause:
                    proof_chain_start( s, c );
936
                    satset_foreach_var( c, x, k, 1 ){
937 938 939 940 941
                        assert( var_level(s, x) == 0 );
                        proof_chain_resolve( s, NULL, x );
                    }
                    proof_id = proof_chain_stop( s );
                    // get a new clause
942
                    Cid = clause_create_new( s, &Lit, &Lit + 1, 1, proof_id );
943 944 945 946 947 948 949
                    assert( (var_unit_clause(s, Var) == NULL) != fLitIsFalse ); 
                    // if variable already has unit clause, it must be with the other polarity 
                    // in this case, we should derive the empty clause here
                    if ( var_unit_clause(s, Var) == NULL )
                        var_set_unit_clause(s, Var, Cid);
                    else{
                        // Empty clause derived:
950
                        proof_chain_start( s, clause_read(s,Cid) );
951 952
                        proof_chain_resolve( s, NULL, Var );
                        proof_id = proof_chain_stop( s );
953
                        clause_create_new( s, &Lit, &Lit, 1, proof_id );
954
                    }
955
                }
956 957 958

                *j++ = *i;
                // Clause is unit under assignment:
959
                if (!solver2_enqueue(s,Lit, *i)){
960
                    confl = clause_read(s,*i++);
961 962 963 964
                    // Copy the remaining watches:
                    while (i < end)
                        *j++ = *i++;
                }
965
            }
966
WatchFound: i++;
967
        }
968 969
        s->stats.inspects += j - (int*)veci_begin(ws);
        veci_resize(ws,j - (int*)veci_begin(ws));
970 971 972 973 974
    }

    return confl;
}

975

976
/*
977
static void clause_remove(sat_solver2* s, satset* c)
978
{
979 980
    assert(lit_neg(c->pEnts[0]) < s->size*2);
    assert(lit_neg(c->pEnts[1]) < s->size*2);
981

982 983
    veci_remove(solver2_wlist(s,lit_neg(c->pEnts[0])),clause_handle(s,c));
    veci_remove(solver2_wlist(s,lit_neg(c->pEnts[1])),clause_handle(s,c));
984

985
    if (c->learnt){
986
        s->stats.learnts--;
987
        s->stats.learnts_literals -= c->nEnts;
988 989
    }else{
        s->stats.clauses--;
990
        s->stats.clauses_literals -= c->nEnts;
991 992
    }
}
993
*/
994

995
static lbool clause_simplify(sat_solver2* s, satset* c)
996
{
997
    int i, x;
998
    assert(solver2_dlevel(s) == 0);
999 1000
    satset_foreach_var( c, x, i, 0 )
        if (var_value(s, x) == lit_sign(c->pEnts[i]))
1001 1002 1003 1004 1005 1006 1007 1008
            return l_True;
    return l_False;
}

int sat_solver2_simplify(sat_solver2* s)
{
//    int type;
    int Counter = 0;
1009
    assert(solver2_dlevel(s) == 0);
1010
    if (solver2_propagate(s) != 0)
1011 1012 1013 1014 1015 1016 1017 1018 1019
        return false;
    if (s->qhead == s->simpdb_assigns || s->simpdb_props > 0)
        return true;
/*
    for (type = 0; type < 2; type++){
        veci* cs  = type ? &s->learnts : &s->clauses;
        int*  cls = (int*)veci_begin(cs);
        int i, j;
        for (j = i = 0; i < veci_size(cs); i++){
1020 1021
            satset* c = clause_read(s,cls[i]);
            if (lit_reason(s,c->pEnts[0]) != cls[i] &&
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
                clause_simplify(s,c) == l_True)
                clause_remove(s,c), Counter++;
            else
                cls[j++] = cls[i];
        }
        veci_resize(cs,j);
    }
*/
//printf( "Simplification removed %d clauses (out of %d)...\n", Counter, s->stats.clauses );
    s->simpdb_assigns = s->qhead;
    // (shouldn't depend on 'stats' really, but it will do for now)
    s->simpdb_props   = (int)(s->stats.clauses_literals + s->stats.learnts_literals);
    return true;
}
1036 1037

/*
1038
 
1039
void solver2_reducedb(sat_solver2* s)
1040
{
1041
    satset* c;
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
    cla Cid;
    int clk = clock();

    // sort the clauses by activity
    int nLearnts = veci_size(&s->claActs) - 1;
    extern int * Abc_SortCost( int * pCosts, int nSize );
    int * pPerm, * pCosts = veci_begin(&s->claActs);
    pPerm = Abc_SortCost( pCosts, veci_size(&s->claActs) );
    assert( pCosts[pPerm[1]] <= pCosts[pPerm[veci_size(&s->claActs)-1]] );

    // mark clauses to be removed
1053
    {
1054 1055 1056 1057 1058 1059 1060
        double   extra_limD = (double)s->cla_inc / nLearnts; // Remove any clause below this activity
        unsigned extra_lim  = (extra_limD < 1.0) ? 1 : (int)extra_limD;
        unsigned * pActs = (unsigned *)veci_begin(&s->claActs);
        int k = 1, Counter = 0;
        sat_solver_foreach_learnt( s, c, Cid )
        {
            assert( c->Id == k );
1061
            c->mark = 0;
1062
            if ( c->nEnts > 2 && lit_reason(s,c->pEnts[0]) != Cid && (k < nLearnts/2 || pActs[k] < extra_lim) )
1063
            {
1064
                c->mark = 1;
1065 1066 1067 1068 1069 1070
                Counter++;
            }
            k++;
        }
printf( "ReduceDB removed %10d clauses (out of %10d)... Cutoff = %8d  ", Counter, nLearnts, extra_lim );
Abc_PrintTime( 1, "Time", clock() - clk );
1071
    }
1072
    ABC_FREE( pPerm );
1073
}
1074
*/
1075

1076

1077
static lbool solver2_search(sat_solver2* s, ABC_INT64_T nof_conflicts)
1078 1079 1080 1081 1082
{
    double  random_var_freq = s->fNotUseRandom ? 0.0 : 0.02;

    ABC_INT64_T  conflictC       = 0;
    veci    learnt_clause;
1083
    int     proof_id;
1084

1085
    assert(s->root_level == solver2_dlevel(s));
1086 1087

    s->stats.starts++;
1088 1089
//    s->var_decay = (float)(1 / 0.95   );
//    s->cla_decay = (float)(1 / 0.999);
1090 1091 1092
    veci_new(&learnt_clause);

    for (;;){
1093
        satset* confl = solver2_propagate(s);
1094 1095 1096 1097 1098 1099 1100 1101
        if (confl != 0){
            // CONFLICT
            int blevel;

#ifdef VERBOSEDEBUG
            printf(L_IND"**CONFLICT**\n", L_ind);
#endif
            s->stats.conflicts++; conflictC++;
1102
            if (solver2_dlevel(s) <= s->root_level){
1103
#ifdef SAT_USE_ANALYZE_FINAL
1104 1105 1106
                proof_id = solver2_analyze_final(s, confl, 0);
                if ( proof_id > 0 )
                    solver2_record(s,&s->conf_final, proof_id);
1107 1108 1109 1110 1111 1112
#endif
                veci_delete(&learnt_clause);
                return l_False;
            }

            veci_resize(&learnt_clause,0);
1113
            proof_id = solver2_analyze(s, confl, &learnt_clause);
1114
            blevel = veci_size(&learnt_clause) > 1 ? var_level(s, lit_var(veci_begin(&learnt_clause)[1])) : s->root_level;
1115
            blevel = s->root_level > blevel ? s->root_level : blevel;
1116 1117
            solver2_canceluntil(s,blevel);
            solver2_record(s,&learnt_clause, proof_id);
1118
#ifdef SAT_USE_ANALYZE_FINAL
1119 1120 1121 1122
            // if (learnt_clause.size() == 1) level[var(learnt_clause[0])] = 0;    
            // (this is ugly (but needed for 'analyzeFinal()') -- in future versions, we will backtrack past the 'root_level' and redo the assumptions)
            if ( learnt_clause.size == 1 ) 
                var_set_level( s, lit_var(learnt_clause.ptr[0]), 0 );
1123 1124 1125 1126 1127 1128 1129 1130 1131 1132
#endif
            act_var_decay(s);
            act_clause_decay(s);

        }else{
            // NO CONFLICT
            int next;

            if (nof_conflicts >= 0 && conflictC >= nof_conflicts){
                // Reached bound on number of conflicts:
1133 1134
                s->progress_estimate = solver2_progress(s);
                solver2_canceluntil(s,s->root_level);
1135 1136 1137 1138 1139 1140 1141 1142
                veci_delete(&learnt_clause);
                return l_Undef; }

            if ( (s->nConfLimit && s->stats.conflicts > s->nConfLimit) ||
//                 (s->nInsLimit  && s->stats.inspects  > s->nInsLimit) )
                 (s->nInsLimit  && s->stats.propagations > s->nInsLimit) )
            {
                // Reached bound on number of conflicts:
1143 1144
                s->progress_estimate = solver2_progress(s);
                solver2_canceluntil(s,s->root_level);
1145 1146 1147 1148
                veci_delete(&learnt_clause);
                return l_Undef; 
            }

1149
            if (solver2_dlevel(s) == 0 && !s->fSkipSimplify)
1150
                // Simplify the set of problem clauses:
1151
                sat_solver2_simplify(s);
1152 1153 1154 1155 1156 1157 1158 1159 1160

            // New variable decision:
            s->stats.decisions++;
            next = order_select(s,(float)random_var_freq);

            if (next == var_Undef){
                // Model found:
                int i;
                for (i = 0; i < s->size; i++) 
1161
                    s->model[i] = (var_value(s,i)==var1 ? l_True : l_False);
1162
                solver2_canceluntil(s,s->root_level);
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175
                veci_delete(&learnt_clause);

                /*
                veci apa; veci_new(&apa);
                for (i = 0; i < s->size; i++) 
                    veci_push(&apa,(int)(s->model.ptr[i] == l_True ? toLit(i) : lit_neg(toLit(i))));
                printf("model: "); printlits((lit*)apa.ptr, (lit*)apa.ptr + veci_size(&apa)); printf("\n");
                veci_delete(&apa);
                */

                return l_True;
            }

1176
            if ( var_polar(s, next) ) // positive polarity
1177
                solver2_assume(s,toLit(next));
1178
            else
1179
                solver2_assume(s,lit_neg(toLit(next)));
1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190
        }
    }

    return l_Undef; // cannot happen
}

//=================================================================================================
// External solver functions:

sat_solver2* sat_solver2_new(void)
{
1191
    sat_solver2* s = (sat_solver2 *)ABC_CALLOC( char, sizeof(sat_solver2) );
1192 1193 1194 1195 1196 1197 1198 1199

    // initialize vectors
    veci_new(&s->order);
    veci_new(&s->trail_lim);
    veci_new(&s->tagged);
    veci_new(&s->stack);
    veci_new(&s->temp_clause);
    veci_new(&s->conf_final);
1200 1201 1202
    veci_new(&s->mark_levels);
    veci_new(&s->min_lit_order); 
    veci_new(&s->min_step_order);
1203
    veci_new(&s->learnt_live);
1204 1205
    veci_new(&s->claActs);    veci_push(&s->claActs,   -1);
    veci_new(&s->claProofs);  veci_push(&s->claProofs, -1);
1206

1207
#ifdef USE_FLOAT_ACTIVITY2
1208 1209 1210 1211 1212 1213
    s->var_inc        = 1;
    s->cla_inc        = 1;
    s->var_decay      = (float)(1 / 0.95  );
    s->cla_decay      = (float)(1 / 0.999 );
//    s->cla_decay      = 1;
//    s->var_decay      = 1;
1214
#else
1215 1216
    s->var_inc        = (1 <<  5);
    s->cla_inc        = (1 << 11);
1217
#endif
1218
    s->random_seed    = 91648253;
1219 1220

#ifdef SAT_USE_PROOF_LOGGING
1221
    s->fProofLogging  =  1;
1222
#else
1223
    s->fProofLogging  =  0;
1224
#endif
1225 1226
    s->fSkipSimplify  =  1;
    s->fNotUseRandom  =  0;
1227

1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238
    // prealloc clause
    assert( !s->clauses.ptr );
    s->clauses.cap = (1 << 20);
    s->clauses.ptr = ABC_ALLOC( int, s->clauses.cap );
    veci_push(&s->clauses, -1);
    // prealloc learnt
    assert( !s->learnts.ptr );
    s->learnts.cap = (1 << 20);
    s->learnts.ptr = ABC_ALLOC( int, s->learnts.cap );
    veci_push(&s->learnts, -1);
    // prealloc proofs
1239 1240
    if ( s->fProofLogging )
    {
1241
        assert( !s->proofs.ptr );
1242
        s->proofs.cap = (1 << 20);
1243 1244
        s->proofs.ptr = ABC_ALLOC( int, s->proofs.cap );
        veci_push(&s->proofs, -1);
1245
    }
1246 1247 1248 1249
    // initialize clause pointers
    s->hClausePivot   =  1;
    s->hLearntPivot   =  1;
    s->hLearntLast    = -1; // the last learnt clause 
1250 1251 1252
    return s;
}

1253

1254 1255 1256 1257 1258
void sat_solver2_setnvars(sat_solver2* s,int n)
{
    int var;

    if (s->cap < n){
1259
        int old_cap = s->cap;
1260 1261 1262
        while (s->cap < n) s->cap = s->cap*2+1;

        s->wlists    = ABC_REALLOC(veci,     s->wlists,   s->cap*2);
1263
        s->vi        = ABC_REALLOC(varinfo2, s->vi,       s->cap);
1264 1265
        s->levels    = ABC_REALLOC(int,      s->levels,   s->cap);
        s->assigns   = ABC_REALLOC(char,     s->assigns,  s->cap);
1266
        s->trail     = ABC_REALLOC(lit,      s->trail,    s->cap);
1267 1268
        s->orderpos  = ABC_REALLOC(int,      s->orderpos, s->cap);
        s->reasons   = ABC_REALLOC(cla,      s->reasons,  s->cap);
1269 1270
        if ( s->fProofLogging )
        s->units     = ABC_REALLOC(cla,      s->units,    s->cap);
1271
#ifdef USE_FLOAT_ACTIVITY2
1272 1273 1274 1275
        s->activity  = ABC_REALLOC(double,   s->activity, s->cap);
#else
        s->activity  = ABC_REALLOC(unsigned, s->activity, s->cap);
#endif
1276
        s->model     = ABC_REALLOC(int,      s->model,    s->cap);
1277
        memset( s->wlists + 2*old_cap, 0, 2*(s->cap-old_cap)*sizeof(vecp) );
1278 1279 1280
    }

    for (var = s->size; var < n; var++){
1281 1282 1283 1284 1285 1286
        assert(!s->wlists[2*var].size);
        assert(!s->wlists[2*var+1].size);
        if ( s->wlists[2*var].ptr == NULL )
            veci_new(&s->wlists[2*var]);
        if ( s->wlists[2*var+1].ptr == NULL )
            veci_new(&s->wlists[2*var+1]);
1287 1288 1289
        *((int*)s->vi + var) = 0; //s->vi[var].val = varX;
        s->levels  [var] = 0;
        s->assigns [var] = varX;
1290 1291
        s->orderpos[var] = veci_size(&s->order);
        s->reasons [var] = 0;        
1292
        if ( s->fProofLogging )
1293
        s->units   [var] = 0;        
1294 1295 1296
#ifdef USE_FLOAT_ACTIVITY2
        s->activity[var] = 0;
#else
1297
        s->activity[var] = (1<<10);
1298
#endif
1299
        s->model   [var] = 0; 
1300 1301 1302 1303 1304 1305 1306
        // does not hold because variables enqueued at top level will not be reinserted in the heap
        // assert(veci_size(&s->order) == var); 
        veci_push(&s->order,var);
        order_update(s, var);
    }
    s->size = n > s->size ? n : s->size;
}
1307 1308 1309

void sat_solver2_delete(sat_solver2* s)
{
1310 1311
    veci * pCore;

1312
    // report statistics
1313
    printf( "Used %6.2f Mb for proof-logging.   Unit clauses = %d.\n", 2.0 * veci_size(&s->proofs) / (1<<20), s->nUnits );
1314

1315 1316 1317
    pCore = Sat_ProofCore( s );
    printf( "UNSAT core contains %d clauses (%6.2f %%).\n", veci_size(pCore), 100.0*veci_size(pCore)/veci_size(&s->clauses) );
    veci_delete( pCore );
1318
    ABC_FREE( pCore ); 
1319

1320 1321
    if ( s->fProofLogging )
        Sat_ProofCheck( s );
1322

1323 1324 1325 1326 1327 1328 1329
    // delete vectors
    veci_delete(&s->order);
    veci_delete(&s->trail_lim);
    veci_delete(&s->tagged);
    veci_delete(&s->stack);
    veci_delete(&s->temp_clause);
    veci_delete(&s->conf_final);
1330 1331 1332
    veci_delete(&s->mark_levels);
    veci_delete(&s->min_lit_order);
    veci_delete(&s->min_step_order);
1333 1334
    veci_delete(&s->learnt_live);
    veci_delete(&s->proofs);
1335 1336
    veci_delete(&s->claActs);
    veci_delete(&s->claProofs);
1337
    veci_delete(&s->clauses);
1338
    veci_delete(&s->learnts);
1339 1340

    // delete arrays
1341
    if (s->vi != 0){
1342
        int i;
1343
        if ( s->wlists )
1344
            for (i = 0; i < s->cap*2; i++)
1345
                veci_delete(&s->wlists[i]);
1346
        ABC_FREE(s->wlists   );
1347
        ABC_FREE(s->vi       );
1348 1349
        ABC_FREE(s->levels   );
        ABC_FREE(s->assigns  );
1350
        ABC_FREE(s->trail    );
1351 1352
        ABC_FREE(s->orderpos );
        ABC_FREE(s->reasons  );
1353
        ABC_FREE(s->units    );
1354
        ABC_FREE(s->activity );
1355
        ABC_FREE(s->model    );
1356 1357 1358 1359 1360
    }
    ABC_FREE(s);
}


1361
int sat_solver2_addclause__(sat_solver2* s, lit* begin, lit* end)
1362 1363 1364 1365 1366
{
    lit *i,*j;
    int maxvar;
    lit last;

1367 1368 1369 1370 1371 1372 1373
    if (begin == end) 
    {
        assert( 0 );
        return false;
    }

    // copy clause into storage
1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395
    veci_resize( &s->temp_clause, 0 );
    for ( i = begin; i < end; i++ )
        veci_push( &s->temp_clause, *i );
    begin = veci_begin( &s->temp_clause );
    end = begin + veci_size( &s->temp_clause );

    //printlits(begin,end); printf("\n");
    // insertion sort
    maxvar = lit_var(*begin);
    for (i = begin + 1; i < end; i++){
        lit l = *i;
        maxvar = lit_var(l) > maxvar ? lit_var(l) : maxvar;
        for (j = i; j > begin && *(j-1) > l; j--)
            *j = *(j-1);
        *j = l;
    }
    sat_solver2_setnvars(s,maxvar+1);

    // delete duplicates
    last = lit_Undef;
    for (i = j = begin; i < end; i++){
        //printf("lit: "L_LIT", value = %d\n", L_lit(*i), (lit_sign(*i) ? -values[lit_var(*i)] : values[lit_var(*i)]));
1396
        if (*i == lit_neg(last) || var_value(s, lit_var(*i)) == lit_sign(*i))
1397
            return true;   // tautology
1398
        else if (*i != last && var_value(s, lit_var(*i)) == varX)
1399 1400 1401 1402
            last = *j++ = *i;
    }
    //printf("final: "); printlits(begin,j); printf("\n");
    if (j == begin)          // empty clause
1403 1404
    {
        assert( 0 );
1405
        return false;
1406
    }
1407 1408

    if (j - begin == 1) // unit clause
1409
        return solver2_enqueue(s,*begin,0);
1410 1411

    // create new clause
1412
    return clause_create_new(s,begin,j,0,0);
1413
}
1414

1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440
int sat_solver2_addclause(sat_solver2* s, lit* begin, lit* end)
{
    cla Cid;
    lit *i,*j;
    int maxvar;
    assert( begin < end );

    // copy clause into storage
    veci_resize( &s->temp_clause, 0 );
    for ( i = begin; i < end; i++ )
        veci_push( &s->temp_clause, *i );
    begin = veci_begin( &s->temp_clause );
    end = begin + veci_size( &s->temp_clause );

    // insertion sort
    maxvar = lit_var(*begin);
    for (i = begin + 1; i < end; i++){
        lit l = *i;
        maxvar = lit_var(l) > maxvar ? lit_var(l) : maxvar;
        for (j = i; j > begin && *(j-1) > l; j--)
            *j = *(j-1);
        *j = l;
    }
    sat_solver2_setnvars(s,maxvar+1);

    // create a new clause
1441
    Cid = clause_create_new( s, begin, end, 0, 0 );
1442 1443 1444
    // handle unit clause
    if ( begin + 1 == end )
    {
1445
//        printf( "Adding unit clause %d\n", begin[0] );
1446 1447 1448 1449 1450 1451
//        solver2_canceluntil(s, 0);
        if ( s->fProofLogging )
            var_set_unit_clause( s, lit_var(begin[0]), Cid );
        if ( !solver2_enqueue(s,begin[0],0) )
            assert( 0 );
    }
1452
//satset_print( clause_read(s, Cid) );
1453
    return Cid;
1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476
}


double luby2(double y, int x)
{
    int size, seq;
    for (size = 1, seq = 0; size < x+1; seq++, size = 2*size + 1);
    while (size-1 != x){
        size = (size-1) >> 1;
        seq--;
        x = x % size;
    }
    return pow(y, (double)seq);
} 

void luby2_test()
{
    int i;
    for ( i = 0; i < 20; i++ )
        printf( "%d ", (int)luby2(2,i) );
    printf( "\n" );
}

1477 1478 1479 1480 1481 1482

// updates clauses, watches, units, and proof
void solver2_reducedb(sat_solver2* s)
{
    satset * c;
    cla h,* pArray,* pArray2;
1483
    int Counter = 0, CounterStart = s->stats.learnts * 3 / 4; // 2/3;
1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498
    int i, j, k, hTemp, hHandle, clk = clock();
    static int TimeTotal = 0;

    // remove 2/3 of learned clauses while skipping small clauses
    veci_resize( &s->learnt_live, 0 );
    sat_solver_foreach_learnt( s, c, h )
        if ( Counter++ > CounterStart || c->nEnts < 3 )
            veci_push( &s->learnt_live, h );
        else
            c->mark = 1;
    // report the results
    printf( "reduceDB: Keeping %7d out of %7d clauses (%5.2f %%)  ", 
        veci_size(&s->learnt_live), s->stats.learnts, 100.0 * veci_size(&s->learnt_live) / s->stats.learnts );

    // remap clause proofs and clauses
1499 1500
    hHandle = 1;
    pArray  = s->fProofLogging ? veci_begin(&s->claProofs) : NULL;
1501
    pArray2 = veci_begin(&s->claActs);
1502
    satset_foreach_entry_vec( &s->learnt_live, &s->learnts, c, i )
1503
    {
1504
        if ( pArray )
1505 1506 1507 1508
        pArray[i+1]  = pArray[c->Id];
        pArray2[i+1] = pArray2[c->Id];
        c->Id = hHandle; hHandle += satset_size(c->nEnts);
    }
1509
    if ( s->fProofLogging )
1510 1511 1512 1513 1514 1515 1516 1517
    veci_resize(&s->claProofs,veci_size(&s->learnt_live)+1);
    veci_resize(&s->claActs,veci_size(&s->learnt_live)+1);

    // compact watches 
    for ( i = 0; i < s->size*2; i++ )
    {
        pArray = veci_begin(&s->wlists[i]);
        for ( j = k = 0; k < veci_size(&s->wlists[i]); k++ )
1518
            if ( !(pArray[k] & 1) ) // problem clause
1519
                pArray[j++] = pArray[k];
1520 1521
            else if ( !(c = clause_read(s, pArray[k]))->mark ) // useful learned clause
                pArray[j++] = (c->Id << 1) | 1;
1522 1523 1524
        veci_resize(&s->wlists[i],j);
    }
    // compact units
1525
    if ( s->fProofLogging )
1526
    for ( i = 0; i < s->size; i++ )
1527
        if ( s->units[i] && (s->units[i] & 1) )
1528
            s->units[i] = (clause_read(s, s->units[i])->Id << 1) | 1;
1529
    // compact clauses
1530
    satset_foreach_entry_vec( &s->learnt_live, &s->learnts, c, i )
1531 1532
    {
        hTemp = c->Id; c->Id = i + 1;
1533
        memmove( veci_begin(&s->learnts) + hTemp, c, sizeof(int)*satset_size(c->nEnts) );
1534 1535
    }
    assert( hHandle == hTemp + satset_size(c->nEnts) );
1536
    veci_resize(&s->learnts,hHandle);
1537 1538 1539
    s->stats.learnts = veci_size(&s->learnt_live);

    // compact proof (compacts 'proofs' and update 'claProofs')
1540
    if ( s->fProofLogging )
1541
    Sat_ProofReduce( s );
1542 1543 1544 1545 1546

    TimeTotal += clock() - clk;
    Abc_PrintTime( 1, "Time", TimeTotal );
}

1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631
// reverses to the previously bookmarked point
void sat_solver2_rollback( sat_solver2* s )
{
    int i, k, j;
    assert( s->hClausePivot >= 1 && s->hClausePivot <= veci_size(&s->clauses) );
    assert( s->hLearntPivot >= 1 && s->hLearntPivot <= veci_size(&s->clauses) );
    assert( s->iVarPivot >= 0 && s->iVarPivot <= s->size );
    veci_resize(&s->order, 0);
    if ( s->hClausePivot > 1 || s->hLearntPivot > 1 )
    {
        // update order
        for ( i = 0; i < s->iVarPivot; i++ )
        {
            if ( var_value(s, i) != varX )
                continue;
            s->orderpos[i] = veci_size(&s->order);
            veci_push(&s->order,i);
            order_update(s, i);
        }
        // compact watches
        for ( i = 0; i < s->size*2; i++ )
        {
            cla* pArray = veci_begin(&s->wlists[i]);
            for ( j = k = 0; k < veci_size(&s->wlists[i]); k++ )
                if ( clause_is_used(s, pArray[k]) )
                    pArray[j++] = pArray[k];
            veci_resize(&s->wlists[i],j);
        }
        // compact units
        if ( s->fProofLogging )
        for ( i = 0; i < s->size; i++ )
            if ( s->units[i] && !clause_is_used(s, s->units[i]) )
                s->units[i] = 0;
    }
    // reset
    if ( s->hLearntPivot < veci_size(&s->learnts) )
    {
        satset* first = satset_read(&s->learnts, s->hLearntPivot);
        veci_resize(&s->claActs,   first->Id);
        if ( s->fProofLogging ) {
            veci_resize(&s->claProofs, first->Id);
            Sat_ProofReduce( s );
        }
    }
    veci_resize(&s->clauses, s->hClausePivot);
    veci_resize(&s->learnts, s->hLearntPivot);
    for ( i = s->iVarPivot; i < s->size*2; i++ )
        s->wlists[i].size = 0;
    s->size = s->iVarPivot;
    // initialize other vars
    if ( s->size == 0 )
    {
    //    s->size                   = 0;
    //    s->cap                    = 0;
        s->qhead                  = 0;
        s->qtail                  = 0;
#ifdef USE_FLOAT_ACTIVITY
        s->var_inc                = 1;
        s->cla_inc                = 1;
        s->var_decay              = (float)(1 / 0.95  );
        s->cla_decay              = (float)(1 / 0.999 );
#else
        s->var_inc                = (1 <<  5);
        s->cla_inc                = (1 << 11);
#endif
        s->root_level             = 0;
        s->simpdb_assigns         = 0;
        s->simpdb_props           = 0;
        s->random_seed            = 91648253;
        s->progress_estimate      = 0;
        s->verbosity              = 0;

        s->stats.starts           = 0;
        s->stats.decisions        = 0;
        s->stats.propagations     = 0;
        s->stats.inspects         = 0;
        s->stats.conflicts        = 0;
        s->stats.clauses          = 0;
        s->stats.clauses_literals = 0;
        s->stats.learnts          = 0;
        s->stats.learnts_literals = 0;
        s->stats.tot_literals     = 0;
    }
}

1632 1633 1634 1635 1636 1637
int sat_solver2_solve(sat_solver2* s, lit* begin, lit* end, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal)
{
    int restart_iter = 0;
    ABC_INT64_T  nof_conflicts;
    ABC_INT64_T  nof_learnts   = sat_solver2_nclauses(s) / 3;
    lbool   status        = l_Undef;
1638
//    lbool*  values        = s->assigns;
1639 1640
    lit*    i;

1641
    s->hLearntLast = -1;
1642

1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661
    // set the external limits
//    s->nCalls++;
//    s->nRestarts  = 0;
    s->nConfLimit = 0;
    s->nInsLimit  = 0;
    if ( nConfLimit )
        s->nConfLimit = s->stats.conflicts + nConfLimit;
    if ( nInsLimit )
//        s->nInsLimit = s->stats.inspects + nInsLimit;
        s->nInsLimit = s->stats.propagations + nInsLimit;
    if ( nConfLimitGlobal && (s->nConfLimit == 0 || s->nConfLimit > nConfLimitGlobal) )
        s->nConfLimit = nConfLimitGlobal;
    if ( nInsLimitGlobal && (s->nInsLimit == 0 || s->nInsLimit > nInsLimitGlobal) )
        s->nInsLimit = nInsLimitGlobal;

#ifndef SAT_USE_ANALYZE_FINAL

    //printf("solve: "); printlits(begin, end); printf("\n");
    for (i = begin; i < end; i++){
1662 1663 1664
//        switch (lit_sign(*i) ? -values[lit_var(*i)] : values[lit_var(*i)]){
        switch (var_value(s, *i)) {
        case var1: // l_True: 
1665
            break;
1666
        case varX: // l_Undef
1667 1668
            solver2_assume(s, *i);
            if (solver2_propagate(s) == NULL)
1669 1670
                break;
            // fallthrough
1671
        case var0: // l_False 
1672
            solver2_canceluntil(s, 0);
1673 1674 1675
            return l_False;
        }
    }
1676
    s->root_level = solver2_dlevel(s);
1677 1678 1679 1680 1681 1682 1683 1684 1685

#endif

/*
    // Perform assumptions:
    root_level = assumps.size();
    for (int i = 0; i < assumps.size(); i++){
        Lit p = assumps[i];
        assert(var(p) < nVars());
1686
        if (!solver2_assume(p)){
1687 1688
            GClause r = reason[var(p)];
            if (r != GClause_NULL){
1689
                satset* confl;
1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702
                if (r.isLit()){
                    confl = propagate_tmpbin;
                    (*confl)[1] = ~p;
                    (*confl)[0] = r.lit();
                }else
                    confl = r.clause();
                analyzeFinal(confl, true);
                conflict.push(~p);
            }else
                conflict.clear(),
                conflict.push(~p);
            cancelUntil(0);
            return false; }
1703
        satset* confl = propagate();
1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719
        if (confl != NULL){
            analyzeFinal(confl), assert(conflict.size() > 0);
            cancelUntil(0);
            return false; }
    }
    assert(root_level == decisionLevel());
*/

#ifdef SAT_USE_ANALYZE_FINAL
    // Perform assumptions:
    s->root_level = end - begin;
    for ( i = begin; i < end; i++ )
    {
        lit p = *i;
        assert(lit_var(p) < s->size);
        veci_push(&s->trail_lim,s->qtail);
1720
        if (!solver2_enqueue(s,p,0))
1721
        {
1722
            satset* r = clause_read(s, lit_reason(s,p));
1723 1724
            if (r != NULL)
            {
1725
                satset* confl = r;
1726
                solver2_analyze_final(s, confl, 1);
1727 1728 1729 1730 1731 1732
                veci_push(&s->conf_final, lit_neg(p));
            }
            else
            {
                veci_resize(&s->conf_final,0);
                veci_push(&s->conf_final, lit_neg(p));
1733 1734 1735
                // the two lines below are a bug fix by Siert Wieringa 
                if (var_level(s, lit_var(p)) > 0) 
                    veci_push(&s->conf_final, p);
1736
            }
1737
            solver2_canceluntil(s, 0);
1738 1739 1740 1741
            return l_False; 
        }
        else
        {
1742
            satset* confl = solver2_propagate(s);
1743
            if (confl != NULL){
1744
                solver2_analyze_final(s, confl, 0);
1745
                assert(s->conf_final.size > 0);
1746 1747 1748
                solver2_canceluntil(s, 0);
                return l_False; 
            }
1749 1750
        }
    }
1751
    assert(s->root_level == solver2_dlevel(s));
1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767
#endif

    if (s->verbosity >= 1){
        printf("==================================[MINISAT]===================================\n");
        printf("| Conflicts |     ORIGINAL     |              LEARNT              | Progress |\n");
        printf("|           | Clauses Literals |   Limit Clauses Literals  Lit/Cl |          |\n");
        printf("==============================================================================\n");
    }

    while (status == l_Undef){
        if (s->verbosity >= 1)
        {
            printf("| %9.0f | %7.0f %8.0f | %7.0f %7.0f %8.0f %7.1f | %6.3f %% |\n", 
                (double)s->stats.conflicts,
                (double)s->stats.clauses, 
                (double)s->stats.clauses_literals,
1768 1769
//                (double)nof_learnts, 
                (double)0, 
1770 1771
                (double)s->stats.learnts, 
                (double)s->stats.learnts_literals,
1772
                (s->stats.learnts == 0)? 0.0 : (double)s->stats.learnts_literals / s->stats.learnts,
1773 1774 1775
                s->progress_estimate*100);
            fflush(stdout);
        }
1776 1777 1778 1779 1780
        if ( s->nRuntimeLimit && time(NULL) > s->nRuntimeLimit )
            break;
         // reduce the set of learnt clauses:
        if (nof_learnts > 0 && s->stats.learnts > nof_learnts)
        {
1781
//            solver2_reducedb(s);
1782 1783 1784
            nof_learnts = nof_learnts * 11 / 10;
        }
        // perform next run
1785
        nof_conflicts = (ABC_INT64_T)( 100 * luby2(2, restart_iter++) );
1786
        status = solver2_search(s, nof_conflicts);
1787 1788 1789 1790 1791 1792 1793 1794 1795
        // quit the loop if reached an external limit
        if ( s->nConfLimit && s->stats.conflicts > s->nConfLimit )
            break;
        if ( s->nInsLimit  && s->stats.propagations > s->nInsLimit )
            break;
    }
    if (s->verbosity >= 1)
        printf("==============================================================================\n");

1796
    solver2_canceluntil(s,0);
1797 1798 1799 1800 1801 1802
    return status;
}


ABC_NAMESPACE_IMPL_END