satSolver.c 62.2 KB
Newer Older
Alan Mishchenko committed
1 2 3 4
/**************************************************************************************************
MiniSat -- Copyright (c) 2005, Niklas Sorensson
http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/

5
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
Alan Mishchenko committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
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>

#include "satSolver.h"
28 29 30
#include "satStore.h"

ABC_NAMESPACE_IMPL_START
31

32
#define SAT_USE_ANALYZE_FINAL
33

Alan Mishchenko committed
34 35 36 37 38 39 40
//=================================================================================================
// Debug:

//#define VERBOSEDEBUG

// For derivation output (verbosity level 2)
#define L_IND    "%-*d"
41
#define L_ind    sat_solver_dl(s)*2+2,sat_solver_dl(s)
Alan Mishchenko committed
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 69 70 71 72 73
#define L_LIT    "%sx%d"
#define L_lit(p) lit_sign(p)?"~":"", (lit_var(p))

// Just like 'assert()' but expression will be evaluated in the release version as well.
static inline void check(int expr) { assert(expr); }

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); }


//=================================================================================================
74 75 76 77 78 79 80 81 82 83 84 85 86 87
// Variable datatype + minor functions:

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

struct varinfo_t
{
    unsigned val    :  2;  // variable value 
    unsigned pol    :  1;  // last polarity
    unsigned tag    :  1;  // conflict analysis tag
    unsigned lev    : 28;  // variable level
};

88 89
static inline int     var_level     (sat_solver* s, int v)            { return s->levels[v];   }
static inline int     var_value     (sat_solver* s, int v)            { return s->assigns[v];  }
90 91
static inline int     var_polar     (sat_solver* s, int v)            { return s->polarity[v]; }

92 93
static inline void    var_set_level (sat_solver* s, int v, int lev)   { s->levels[v] = lev;    }
static inline void    var_set_value (sat_solver* s, int v, int val)   { s->assigns[v] = val;   }
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
static inline void    var_set_polar (sat_solver* s, int v, int pol)   { s->polarity[v] = pol;  }

// variable tags
static inline int     var_tag       (sat_solver* s, int v)            { return s->tags[v]; }
static inline void    var_set_tag   (sat_solver* s, int v, int tag)   { 
    assert( tag > 0 && tag < 16 );
    if ( s->tags[v] == 0 )
        veci_push( &s->tagged, v );
    s->tags[v] = tag;                           
}
static inline void    var_add_tag   (sat_solver* s, int v, int tag)   { 
    assert( tag > 0 && tag < 16 );
    if ( s->tags[v] == 0 )
        veci_push( &s->tagged, v );
    s->tags[v] |= tag;                           
}
static inline void    solver2_clear_tags(sat_solver* s, int start)    { 
    int i, * tagged = veci_begin(&s->tagged);
    for (i = start; i < veci_size(&s->tagged); i++)
        s->tags[tagged[i]] = 0;
    veci_resize(&s->tagged,start);
}

int sat_solver_get_var_value(sat_solver* s, int v)
{
    if ( var_value(s, v) == var0 )
        return l_False;
    if ( var_value(s, v) == var1 )
        return l_True;
    if ( var_value(s, v) == varX )
        return l_Undef;
    assert( 0 );
    return 0;
}
Alan Mishchenko committed
128 129 130 131

//=================================================================================================
// Simple helpers:

132 133
static inline int      sat_solver_dl(sat_solver* s)                { return veci_size(&s->trail_lim); }
static inline veci*    sat_solver_read_wlist(sat_solver* s, lit l) { return &s->wlists[l];            }
Alan Mishchenko committed
134 135 136 137 138 139 140 141 142 143 144 145 146 147

//=================================================================================================
// Variable order functions:

static inline void order_update(sat_solver* 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);

148
    while (i != 0 && s->activity[x] > s->activity[heap[parent]]){
Alan Mishchenko committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
        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_solver* s, int v) 
{
}

static inline void order_unassigned(sat_solver* 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);
Alan Mishchenko committed
169
//printf( "+%d ", v );
Alan Mishchenko committed
170 171 172
    }
}

Alan Mishchenko committed
173
static inline int  order_select(sat_solver* s, float random_var_freq) // selectvar
Alan Mishchenko committed
174
{
175 176
    int*      heap     = veci_begin(&s->order);
    int*      orderpos = s->orderpos;
Alan Mishchenko committed
177 178 179 180
    // Random decision:
    if (drand(&s->random_seed) < random_var_freq){
        int next = irand(&s->random_seed,s->size);
        assert(next >= 0 && next < s->size);
181
        if (var_value(s, next) == varX)
Alan Mishchenko committed
182 183 184 185 186 187 188 189 190 191 192 193 194
            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){
            int    i     = 0;
            int    child = 1;
            while (child < size){
195
                if (child+1 < size && s->activity[heap[child]] < s->activity[heap[child+1]])
Alan Mishchenko committed
196 197
                    child++;
                assert(child < size);
198
                if (s->activity[x] >= s->activity[heap[child]])
Alan Mishchenko committed
199 200 201 202 203 204 205 206 207
                    break;
                heap[i]           = heap[child];
                orderpos[heap[i]] = i;
                i                 = child;
                child             = 2 * child + 1;
            }
            heap[i]           = x;
            orderpos[heap[i]] = i;
        }
208
        if (var_value(s, next) == varX)
Alan Mishchenko committed
209 210 211 212 213 214 215 216
            return next;
    }
    return var_Undef;
}

//=================================================================================================
// Activity functions:

217 218 219
#ifdef USE_FLOAT_ACTIVITY

static inline void act_var_rescale(sat_solver* s)  {
Alan Mishchenko committed
220 221 222 223 224 225
    double* activity = s->activity;
    int i;
    for (i = 0; i < s->size; i++)
        activity[i] *= 1e-100;
    s->var_inc *= 1e-100;
}
226
static inline void act_clause_rescale(sat_solver* s) {
227
//    static abctime Total = 0;
228
    clause** cs = (clause**)veci_begin(&s->learnts);
229
    int i;//, clk = Abc_Clock();
230
    for (i = 0; i < veci_size(&s->learnts); i++){
231 232 233 234
        float a = clause_activity(cs[i]);
        clause_setactivity(cs[i], a * (float)1e-20);
    }
    s->cla_inc *= (float)1e-20;
Alan Mishchenko committed
235

236
    Total += Abc_Clock() - clk;
237 238
//    printf( "Rescaling...   Cla inc = %10.3f  Conf = %10d   ", s->cla_inc,  s->stats.conflicts );
//    Abc_PrintTime( 1, "Time", Total );
239
}
Alan Mishchenko committed
240
static inline void act_var_bump(sat_solver* s, int v) {
241
    s->activity[v] += s->var_inc;
Alan Mishchenko committed
242
    if (s->activity[v] > 1e100)
Alan Mishchenko committed
243 244 245 246
        act_var_rescale(s);
    if (s->orderpos[v] != -1)
        order_update(s,v);
}
247
static inline void act_var_bump_global(sat_solver* s, int v) {
248 249
    if ( !s->pGlobalVars )
        return;
250
    s->activity[v] += (s->var_inc * 3.0 * s->pGlobalVars[v]);
Alan Mishchenko committed
251
    if (s->activity[v] > 1e100)
Alan Mishchenko committed
252 253 254 255
        act_var_rescale(s);
    if (s->orderpos[v] != -1)
        order_update(s,v);
}
256
static inline void act_var_bump_factor(sat_solver* s, int v) {
257 258
    if ( !s->factors )
        return;
259
    s->activity[v] += (s->var_inc * s->factors[v]);
Alan Mishchenko committed
260 261 262 263 264
    if (s->activity[v] > 1e100)
        act_var_rescale(s);
    if (s->orderpos[v] != -1)
        order_update(s,v);
}
265 266 267 268 269 270 271
static inline void act_clause_bump(sat_solver* s, clause *c) {
    float a = clause_activity(c) + s->cla_inc;
    clause_setactivity(c,a);
    if (a > 1e20) act_clause_rescale(s);
}
static inline void act_var_decay(sat_solver* s)    { s->var_inc *= s->var_decay; }
static inline void act_clause_decay(sat_solver* s) { s->cla_inc *= s->cla_decay; }
Alan Mishchenko committed
272

273
#else
Alan Mishchenko committed
274

275 276 277 278 279 280 281 282
static inline void act_var_rescale(sat_solver* 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) );
}
283

Alan Mishchenko committed
284
static inline void act_clause_rescale(sat_solver* s) {
285 286
    static abctime Total = 0;
    abctime clk = Abc_Clock();
287 288 289 290
    unsigned* activity = (unsigned *)veci_begin(&s->act_clas);
    int i;
    for (i = 0; i < veci_size(&s->act_clas); i++)
        activity[i] >>= 14;
291 292
    s->cla_inc >>= 14;
    s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) );
293
    Total += Abc_Clock() - clk;
294 295
//    printf( "Rescaling...   Cla inc = %5d  Conf = %10d   ", s->cla_inc,  s->stats.conflicts );
//    Abc_PrintTime( 1, "Time", Total );
Alan Mishchenko committed
296
}
297

298 299 300 301 302 303 304
static inline void act_var_bump(sat_solver* 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);
}
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
static inline void act_var_bump_global(sat_solver* s, int v) {
    if ( !s->pGlobalVars )
        return;
    s->activity[v] += (int)(s->var_inc * 3 * s->pGlobalVars[v]);
    if (s->activity[v] & 0x80000000)
        act_var_rescale(s);
    if (s->orderpos[v] != -1)
        order_update(s,v);
}
static inline void act_var_bump_factor(sat_solver* s, int v) {
    if ( !s->factors )
        return;
    s->activity[v] += (int)(s->var_inc * s->factors[v]);
    if (s->activity[v] & 0x80000000)
        act_var_rescale(s);
    if (s->orderpos[v] != -1)
        order_update(s,v);
}
323

324
static inline void act_clause_bump(sat_solver* s, clause*c) {
325 326 327
    unsigned* act = (unsigned *)veci_begin(&s->act_clas) + c->lits[c->size];
    *act += s->cla_inc;
    if ( *act & 0x80000000 )
328 329
        act_clause_rescale(s);
}
330

331
static inline void act_var_decay(sat_solver* s)    { s->var_inc += (s->var_inc >>  4); }
332
static inline void act_clause_decay(sat_solver* s) { s->cla_inc += (s->cla_inc >> 10); }
333 334

#endif
Alan Mishchenko committed
335 336 337


//=================================================================================================
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
// Sorting functions (sigh):

static inline void selectionsort(void** array, int size, int(*comp)(const void *, const void *))
{
    int     i, j, best_i;
    void*   tmp;

    for (i = 0; i < size-1; i++){
        best_i = i;
        for (j = i+1; j < size; j++){
            if (comp(array[j], array[best_i]) < 0)
                best_i = j;
        }
        tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
    }
}

static void sortrnd(void** array, int size, int(*comp)(const void *, const void *), double* seed)
{
    if (size <= 15)
        selectionsort(array, size, comp);

    else{
        void*       pivot = array[irand(seed, size)];
        void*       tmp;
        int         i = -1;
        int         j = size;

        for(;;){
            do i++; while(comp(array[i], pivot)<0);
            do j--; while(comp(pivot, array[j])<0);

            if (i >= j) break;

            tmp = array[i]; array[i] = array[j]; array[j] = tmp;
        }

        sortrnd(array    , i     , comp, seed);
        sortrnd(&array[i], size-i, comp, seed);
    }
}

//=================================================================================================
Alan Mishchenko committed
381 382
// Clause functions:

383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399
static inline int sat_clause_compute_lbd( sat_solver* s, clause* c )
{
    int i, lev, minl = 0, lbd = 0;
    for (i = 0; i < (int)c->size; i++)
    {
        lev = var_level(s, lit_var(c->lits[i]));
        if ( !(minl & (1 << (lev & 31))) )
        {
            minl |= 1 << (lev & 31);
            lbd++;
//            printf( "%d ", lev );
        }
    }
//    printf( " -> %d\n", lbd );
    return lbd;
}

Alan Mishchenko committed
400 401
/* pre: size > 1 && no variable occurs twice
 */
402
int sat_solver_clause_new(sat_solver* s, lit* begin, lit* end, int learnt)
Alan Mishchenko committed
403
{
404
    int fUseBinaryClauses = 1;
Alan Mishchenko committed
405 406
    int size;
    clause* c;
407
    int h;
Alan Mishchenko committed
408 409 410 411

    assert(end - begin > 1);
    assert(learnt >= 0 && learnt < 2);
    size           = end - begin;
412 413

    // do not allocate memory for the two-literal problem clause
414
    if ( fUseBinaryClauses && size == 2 && !learnt )
415
    {
416 417
        veci_push(sat_solver_read_wlist(s,lit_neg(begin[0])),(clause_from_lit(begin[1])));
        veci_push(sat_solver_read_wlist(s,lit_neg(begin[1])),(clause_from_lit(begin[0])));
418 419
        s->stats.clauses++;
        s->stats.clauses_literals += size;
420
        return 0;
421 422
    }

423
    // create new clause
424
//    h = Vec_SetAppend( &s->Mem, NULL, size + learnt + 1 + 1 ) << 1;
425
    h = Sat_MemAppend( &s->Mem, begin, size, learnt, 0 );
426 427 428
    assert( !(h & 1) );
    if ( s->hLearnts == -1 && learnt )
        s->hLearnts = h;
Alan Mishchenko committed
429
    if (learnt)
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
    {
        c = clause_read( s, h );
        c->lbd = sat_clause_compute_lbd( s, c );
        assert( clause_id(c) == veci_size(&s->act_clas) );
//        veci_push(&s->learned, h);
//        act_clause_bump(s,clause_read(s, h));
        veci_push(&s->act_clas, (1<<10));
        s->stats.learnts++;
        s->stats.learnts_literals += size;
    }
    else
    {
        s->stats.clauses++;
        s->stats.clauses_literals += size;
    }
Alan Mishchenko committed
445 446 447 448 449 450 451 452 453

    assert(begin[0] >= 0);
    assert(begin[0] < s->size*2);
    assert(begin[1] >= 0);
    assert(begin[1] < s->size*2);

    assert(lit_neg(begin[0]) < s->size*2);
    assert(lit_neg(begin[1]) < s->size*2);

454 455 456 457
    //veci_push(sat_solver_read_wlist(s,lit_neg(begin[0])),c);
    //veci_push(sat_solver_read_wlist(s,lit_neg(begin[1])),c);
    veci_push(sat_solver_read_wlist(s,lit_neg(begin[0])),(size > 2 ? h : clause_from_lit(begin[1])));
    veci_push(sat_solver_read_wlist(s,lit_neg(begin[1])),(size > 2 ? h : clause_from_lit(begin[0])));
Alan Mishchenko committed
458

459
    return h;
Alan Mishchenko committed
460 461 462 463 464 465
}


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

466
static inline int sat_solver_enqueue(sat_solver* s, lit l, int from)
Alan Mishchenko committed
467
{
468
    int v  = lit_var(l);
469 470 471 472 473 474
    if ( s->pFreqs[v] == 0 )
//    {
        s->pFreqs[v] = 1;
//        s->nVarUsed++;
//    }

Alan Mishchenko committed
475 476 477
#ifdef VERBOSEDEBUG
    printf(L_IND"enqueue("L_LIT")\n", L_ind, L_lit(l));
#endif
478 479 480
    if (var_value(s, v) != varX)
        return var_value(s, v) == lit_sign(l);
    else{
481
/*
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
        if ( s->pCnfFunc )
        {
            if ( lit_sign(l) )
            {
                if ( (s->loads[v] & 1) == 0 )
                {
                    s->loads[v] ^= 1;
                    s->pCnfFunc( s->pCnfMan, l );
                }
            }
            else
            {
                if ( (s->loads[v] & 2) == 0 )
                {
                    s->loads[v] ^= 2;
                    s->pCnfFunc( s->pCnfMan, l );
                }
            }
        }
501
*/
Alan Mishchenko committed
502 503 504 505
        // New fact -- store it.
#ifdef VERBOSEDEBUG
        printf(L_IND"bind("L_LIT")\n", L_ind, L_lit(l));
#endif
506 507 508
        var_set_value(s, v, lit_sign(l));
        var_set_level(s, v, sat_solver_dl(s));
        s->reasons[v] = from;
Alan Mishchenko committed
509 510 511 512 513 514 515
        s->trail[s->qtail++] = l;
        order_assigned(s, v);
        return true;
    }
}


516
static inline int sat_solver_assume(sat_solver* s, lit l){
Alan Mishchenko committed
517
    assert(s->qtail == s->qhead);
518
    assert(var_value(s, lit_var(l)) == varX);
Alan Mishchenko committed
519
#ifdef VERBOSEDEBUG
520 521
    printf(L_IND"assume("L_LIT")  ", L_ind, L_lit(l));
    printf( "act = %.20f\n", s->activity[lit_var(l)] );
Alan Mishchenko committed
522 523
#endif
    veci_push(&s->trail_lim,s->qtail);
524
    return sat_solver_enqueue(s,l,0);
Alan Mishchenko committed
525 526 527
}


Alan Mishchenko committed
528
static void sat_solver_canceluntil(sat_solver* s, int level) {
Alan Mishchenko committed
529
    int      bound;
530
    int      lastLev;
Alan Mishchenko committed
531 532
    int      c;
    
533
    if (sat_solver_dl(s) <= level)
Alan Mishchenko committed
534 535
        return;

536
    assert( veci_size(&s->trail_lim) > 0 );
Alan Mishchenko committed
537
    bound   = (veci_begin(&s->trail_lim))[level];
538
    lastLev = (veci_begin(&s->trail_lim))[veci_size(&s->trail_lim)-1];
Alan Mishchenko committed
539

Alan Mishchenko committed
540 541 542 543 544 545
    ////////////////////////////////////////
    // added to cancel all assignments
//    if ( level == -1 )
//        bound = 0;
    ////////////////////////////////////////

Alan Mishchenko committed
546
    for (c = s->qtail-1; c >= bound; c--) {
547 548 549
        int     x  = lit_var(s->trail[c]);
        var_set_value(s, x, varX);
        s->reasons[x] = 0;
550
        if ( c < lastLev )
551
            var_set_polar( s, x, !lit_sign(s->trail[c]) );
Alan Mishchenko committed
552 553 554
    }

    for (c = s->qhead-1; c >= bound; c--)
555
        order_unassigned(s,lit_var(s->trail[c]));
Alan Mishchenko committed
556 557 558

    s->qhead = s->qtail = bound;
    veci_resize(&s->trail_lim,level);
559 560
    // update decision level
    s->iDeciVar = level;
Alan Mishchenko committed
561 562
}

563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
static void sat_solver_canceluntil_rollback(sat_solver* s, int NewBound) {
    int      c, x;
   
    assert( sat_solver_dl(s) == 0 );
    assert( s->qtail == s->qhead );
    assert( s->qtail >= NewBound );

    for (c = s->qtail-1; c >= NewBound; c--) 
    {
        x = lit_var(s->trail[c]);
        var_set_value(s, x, varX);
        s->reasons[x] = 0;
    }

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

    s->qhead = s->qtail = NewBound;
}

Alan Mishchenko committed
583 584 585 586
static void sat_solver_record(sat_solver* s, veci* cls)
{
    lit*    begin = veci_begin(cls);
    lit*    end   = begin + veci_size(cls);
587
    int     h     = (veci_size(cls) > 1) ? sat_solver_clause_new(s,begin,end,1) : 0;
588
    sat_solver_enqueue(s,*begin,h);
589
    assert(veci_size(cls) > 0);
590 591
    if ( h == 0 )
        veci_push( &s->unit_lits, *begin );
Alan Mishchenko committed
592

Alan Mishchenko committed
593 594 595 596
    ///////////////////////////////////
    // add clause to internal storage
    if ( s->pStore )
    {
597
        int RetValue = Sto_ManAddClause( (Sto_Man_t *)s->pStore, begin, end );
Alan Mishchenko committed
598
        assert( RetValue );
Alan Mishchenko committed
599
        (void) RetValue;
Alan Mishchenko committed
600 601
    }
    ///////////////////////////////////
602
/*
603
    if (h != 0) {
604
        act_clause_bump(s,clause_read(s, h));
Alan Mishchenko committed
605 606 607
        s->stats.learnts++;
        s->stats.learnts_literals += veci_size(cls);
    }
608
*/
Alan Mishchenko committed
609 610
}

611 612 613 614 615 616 617 618 619 620
int sat_solver_count_assigned(sat_solver* s)
{
    // count top-level assignments
    int i, Count = 0;
    assert(sat_solver_dl(s) == 0);
    for ( i = 0; i < s->size; i++ )
        if (var_value(s, i) != varX)
            Count++;
    return Count;
}
Alan Mishchenko committed
621 622 623 624 625 626 627

static double sat_solver_progress(sat_solver* s)
{
    int     i;
    double  progress = 0;
    double  F        = 1.0 / s->size;
    for (i = 0; i < s->size; i++)
628 629
        if (var_value(s, i) != varX)
            progress += pow(F, var_level(s, i));
Alan Mishchenko committed
630 631 632 633 634 635
    return progress / s->size;
}

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

636
static int sat_solver_lit_removable(sat_solver* s, int x, int minl)
Alan Mishchenko committed
637 638 639
{
    int      top     = veci_size(&s->tagged);

640
    assert(s->reasons[x] != 0);
Alan Mishchenko committed
641
    veci_resize(&s->stack,0);
642 643 644 645 646 647 648 649 650
    veci_push(&s->stack,x);

    while (veci_size(&s->stack)){
        int v = veci_pop(&s->stack);
        assert(s->reasons[v] != 0);
        if (clause_is_lit(s->reasons[v])){
            v = lit_var(clause_read_lit(s->reasons[v]));
            if (!var_tag(s,v) && var_level(s, v)){
                if (s->reasons[v] != 0 && ((1 << (var_level(s, v) & 31)) & minl)){
Alan Mishchenko committed
651
                    veci_push(&s->stack,v);
652
                    var_set_tag(s, v, 1);
Alan Mishchenko committed
653
                }else{
654 655
                    solver2_clear_tags(s, top);
                    return 0;
Alan Mishchenko committed
656 657 658
                }
            }
        }else{
659 660 661
            clause* c = clause_read(s, s->reasons[v]);
            lit* lits = clause_begin(c);
            int  i;
662
            for (i = 1; i < clause_size(c); i++){
Alan Mishchenko committed
663
                int v = lit_var(lits[i]);
664 665
                if (!var_tag(s,v) && var_level(s, v)){
                    if (s->reasons[v] != 0 && ((1 << (var_level(s, v) & 31)) & minl)){
Alan Mishchenko committed
666
                        veci_push(&s->stack,lit_var(lits[i]));
667
                        var_set_tag(s, v, 1);
Alan Mishchenko committed
668
                    }else{
669 670
                        solver2_clear_tags(s, top);
                        return 0;
Alan Mishchenko committed
671 672 673 674 675
                    }
                }
            }
        }
    }
676
    return 1;
Alan Mishchenko committed
677 678
}

679 680 681 682 683 684 685 686 687 688 689

/*_________________________________________________________________________________________________
|
|  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'.
|________________________________________________________________________________________________@*/
/*
690
void Solver::analyzeFinal(Clause* confl, bool skip_first)
691
{
692 693 694 695 696 697 698 699 700 701
    // -- 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;
    }
702

703 704 705
    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]);
706
        if (seen[x]){
707 708 709 710
            GClause r = reason[x];
            if (r == GClause_NULL){
                assert(level[x] > 0);
                conflict.push(~trail[i]);
711
            }else{
712 713 714 715 716 717 718 719 720 721
                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;
                }
722 723 724 725 726 727 728
            }
            seen[x] = 0;
        }
    }
}
*/

729 730
#ifdef SAT_USE_ANALYZE_FINAL

731
static void sat_solver_analyze_final(sat_solver* s, int hConf, int skip_first)
732
{
733
    clause* conf = clause_read(s, hConf);
734 735 736
    int i, j, start;
    veci_resize(&s->conf_final,0);
    if ( s->root_level == 0 )
737 738
        return;
    assert( veci_size(&s->tagged) == 0 );
739 740
//    assert( s->tags[lit_var(p)] == l_Undef );
//    s->tags[lit_var(p)] = l_True;
741
    for (i = skip_first ? 1 : 0; i < clause_size(conf); i++)
742 743
    {
        int x = lit_var(clause_begin(conf)[i]);
744 745
        if (var_level(s, x) > 0)
            var_set_tag(s, x, 1);
746 747 748 749
    }

    start = (s->root_level >= veci_size(&s->trail_lim))? s->qtail-1 : (veci_begin(&s->trail_lim))[s->root_level];
    for (i = start; i >= (veci_begin(&s->trail_lim))[0]; i--){
750
        int x = lit_var(s->trail[i]);
751 752 753
        if (var_tag(s,x)){
            if (s->reasons[x] == 0){
                assert(var_level(s, x) > 0);
754
                veci_push(&s->conf_final,lit_neg(s->trail[i]));
755
            }else{
756 757
                if (clause_is_lit(s->reasons[x])){
                    lit q = clause_read_lit(s->reasons[x]);
758
                    assert(lit_var(q) >= 0 && lit_var(q) < s->size);
759 760
                    if (var_level(s, lit_var(q)) > 0)
                        var_set_tag(s, lit_var(q), 1);
761 762
                }
                else{
763
                    clause* c = clause_read(s, s->reasons[x]);
764
                    int* lits = clause_begin(c);
765
                    for (j = 1; j < clause_size(c); j++)
766 767
                        if (var_level(s, lit_var(lits[j])) > 0)
                            var_set_tag(s, lit_var(lits[j]), 1);
768 769 770 771
                }
            }
        }
    }
772
    solver2_clear_tags(s,0);
773 774
}

775 776
#endif

777
static void sat_solver_analyze(sat_solver* s, int h, veci* learnt)
Alan Mishchenko committed
778 779 780 781 782 783 784 785 786
{
    lit*     trail   = s->trail;
    int      cnt     = 0;
    lit      p       = lit_Undef;
    int      ind     = s->qtail-1;
    lit*     lits;
    int      i, j, minl;
    veci_push(learnt,lit_Undef);
    do{
787 788 789 790 791 792 793
        assert(h != 0);
        if (clause_is_lit(h)){
            int x = lit_var(clause_read_lit(h));
            if (var_tag(s, x) == 0 && var_level(s, x) > 0){
                var_set_tag(s, x, 1);
                act_var_bump(s,x);
                if (var_level(s, x) == sat_solver_dl(s))
Alan Mishchenko committed
794 795
                    cnt++;
                else
796
                    veci_push(learnt,clause_read_lit(h));
Alan Mishchenko committed
797 798
            }
        }else{
799
            clause* c = clause_read(s, h);
800 801
            if (clause_learnt(c))
                act_clause_bump(s,c);
Alan Mishchenko committed
802
            lits = clause_begin(c);
803 804
            //printlits(lits,lits+clause_size(c)); printf("\n");
            for (j = (p == lit_Undef ? 0 : 1); j < clause_size(c); j++){
805 806 807 808
                int x = lit_var(lits[j]);
                if (var_tag(s, x) == 0 && var_level(s, x) > 0){
                    var_set_tag(s, x, 1);
                    act_var_bump(s,x);
809 810 811
                    // bump variables propaged by the LBD=2 clause
//                    if ( s->reasons[x] && clause_read(s, s->reasons[x])->lbd <= 2 )
//                        act_var_bump(s,x);
812
                    if (var_level(s,x) == sat_solver_dl(s))
Alan Mishchenko committed
813 814
                        cnt++;
                    else
815
                        veci_push(learnt,lits[j]);
Alan Mishchenko committed
816 817 818 819
                }
            }
        }

820
        while ( !var_tag(s, lit_var(trail[ind--])) );
Alan Mishchenko committed
821 822

        p = trail[ind+1];
823
        h = s->reasons[lit_var(p)];
Alan Mishchenko committed
824 825 826 827 828 829 830 831 832
        cnt--;

    }while (cnt > 0);

    *veci_begin(learnt) = lit_neg(p);

    lits = veci_begin(learnt);
    minl = 0;
    for (i = 1; i < veci_size(learnt); i++){
833
        int lev = var_level(s, lit_var(lits[i]));
Alan Mishchenko committed
834 835 836 837 838
        minl    |= 1 << (lev & 31);
    }

    // simplify (full)
    for (i = j = 1; i < veci_size(learnt); i++){
839
        if (s->reasons[lit_var(lits[i])] == 0 || !sat_solver_lit_removable(s,lit_var(lits[i]),minl))
Alan Mishchenko committed
840 841 842 843 844 845 846
            lits[j++] = lits[i];
    }

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

847

Alan Mishchenko committed
848
    // clear tags
849
    solver2_clear_tags(s,0);
Alan Mishchenko committed
850 851 852

#ifdef DEBUG
    for (i = 0; i < s->size; i++)
853
        assert(!var_tag(s, i));
Alan Mishchenko committed
854 855 856 857 858 859 860 861
#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){
        int max_i = 1;
862
        int max   = var_level(s, lit_var(lits[1]));
Alan Mishchenko committed
863 864 865
        lit tmp;

        for (i = 2; i < veci_size(learnt); i++)
866 867
            if (var_level(s, lit_var(lits[i])) > max){
                max   = var_level(s, lit_var(lits[i]));
Alan Mishchenko committed
868 869 870 871 872 873 874 875 876
                max_i = i;
            }

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

883
//#define TEST_CNF_LOAD
Alan Mishchenko committed
884

885
int sat_solver_propagate(sat_solver* s)
Alan Mishchenko committed
886
{
887
    int     hConfl = 0;
Alan Mishchenko committed
888
    lit*    lits;
889
    lit false_lit;
Alan Mishchenko committed
890 891

    //printf("sat_solver_propagate\n");
892
    while (hConfl == 0 && s->qtail - s->qhead > 0){
893
        lit p = s->trail[s->qhead++];
894 895

#ifdef TEST_CNF_LOAD
896
        int v = lit_var(p);
897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
        if ( s->pCnfFunc )
        {
            if ( lit_sign(p) )
            {
                if ( (s->loads[v] & 1) == 0 )
                {
                    s->loads[v] ^= 1;
                    s->pCnfFunc( s->pCnfMan, p );
                }
            }
            else
            {
                if ( (s->loads[v] & 2) == 0 )
                {
                    s->loads[v] ^= 2;
                    s->pCnfFunc( s->pCnfMan, p );
                }
            }
        }
        {
#endif

919 920 921 922
        veci* ws    = sat_solver_read_wlist(s,p);
        int*  begin = veci_begin(ws);
        int*  end   = begin + veci_size(ws);
        int*i, *j;
Alan Mishchenko committed
923 924

        s->stats.propagations++;
925
//        s->simpdb_props--;
Alan Mishchenko committed
926

Alan Mishchenko committed
927
        //printf("checking lit %d: "L_LIT"\n", veci_size(ws), L_lit(p));
Alan Mishchenko committed
928 929
        for (i = j = begin; i < end; ){
            if (clause_is_lit(*i)){
930 931

                int Lit = clause_read_lit(*i);
932
                if (var_value(s, lit_var(Lit)) == lit_sign(Lit)){
933 934 935 936
                    *j++ = *i++;
                    continue;
                }

Alan Mishchenko committed
937
                *j++ = *i;
938
                if (!sat_solver_enqueue(s,clause_read_lit(*i),clause_from_lit(p))){
939 940 941
                    hConfl = s->hBinary;
                    (clause_begin(s->binary))[1] = lit_neg(p);
                    (clause_begin(s->binary))[0] = clause_read_lit(*i++);
Alan Mishchenko committed
942 943 944 945
                    // Copy the remaining watches:
                    while (i < end)
                        *j++ = *i++;
                }
Alan Mishchenko committed
946
            }else{
Alan Mishchenko committed
947

948 949
                clause* c = clause_read(s,*i);
                lits = clause_begin(c);
Alan Mishchenko committed
950

Alan Mishchenko committed
951
                // Make sure the false literal is data[1]:
Alan Mishchenko committed
952 953 954 955 956 957 958
                false_lit = lit_neg(p);
                if (lits[0] == false_lit){
                    lits[0] = lits[1];
                    lits[1] = false_lit;
                }
                assert(lits[1] == false_lit);

Alan Mishchenko committed
959
                // If 0th watch is true, then clause is already satisfied.
960
                if (var_value(s, lit_var(lits[0])) == lit_sign(lits[0]))
Alan Mishchenko committed
961
                    *j++ = *i;
962
                else{
Alan Mishchenko committed
963
                    // Look for new watch:
964
                    lit* stop = lits + clause_size(c);
Alan Mishchenko committed
965
                    lit* k;
Alan Mishchenko committed
966
                    for (k = lits + 2; k < stop; k++){
967
                        if (var_value(s, lit_var(*k)) != !lit_sign(*k)){
Alan Mishchenko committed
968 969
                            lits[1] = *k;
                            *k = false_lit;
970
                            veci_push(sat_solver_read_wlist(s,lit_neg(lits[1])),*i);
Alan Mishchenko committed
971
                            goto next; }
Alan Mishchenko committed
972 973 974 975
                    }

                    *j++ = *i;
                    // Clause is unit under assignment:
976 977
                    if ( c->lrn )
                        c->lbd = sat_clause_compute_lbd(s, c);
978
                    if (!sat_solver_enqueue(s,lits[0], *i)){
979
                        hConfl = *i++;
Alan Mishchenko committed
980 981 982 983 984 985
                        // Copy the remaining watches:
                        while (i < end)
                            *j++ = *i++;
                    }
                }
            }
Alan Mishchenko committed
986 987
        next:
            i++;
Alan Mishchenko committed
988 989
        }

990 991
        s->stats.inspects += j - veci_begin(ws);
        veci_resize(ws,j - veci_begin(ws));
992 993 994
#ifdef TEST_CNF_LOAD
        }
#endif
Alan Mishchenko committed
995 996
    }

997
    return hConfl;
Alan Mishchenko committed
998 999 1000 1001 1002 1003 1004
}

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

sat_solver* sat_solver_new(void)
{
1005 1006
    sat_solver* s = (sat_solver*)ABC_CALLOC( char, sizeof(sat_solver));

1007
//    Vec_SetAlloc_(&s->Mem, 15);
1008
    Sat_MemAlloc_(&s->Mem, 15);
1009
    s->hLearnts = -1;
1010
    s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
1011
    s->binary = clause_read( s, s->hBinary );
1012

1013 1014 1015 1016
    s->nLearntStart = LEARNT_MAX_START_DEFAULT;  // starting learned clause limit
    s->nLearntDelta = LEARNT_MAX_INCRE_DEFAULT;  // delta of learned clause limit
    s->nLearntRatio = LEARNT_MAX_RATIO_DEFAULT;  // ratio of learned clause limit
    s->nLearntMax   = s->nLearntStart;
Alan Mishchenko committed
1017 1018 1019 1020 1021

    // initialize vectors
    veci_new(&s->order);
    veci_new(&s->trail_lim);
    veci_new(&s->tagged);
1022 1023
//    veci_new(&s->learned);
    veci_new(&s->act_clas);
Alan Mishchenko committed
1024
    veci_new(&s->stack);
1025
//    veci_new(&s->model);
Alan Mishchenko committed
1026
    veci_new(&s->act_vars);
1027
    veci_new(&s->unit_lits);
Alan Mishchenko committed
1028
    veci_new(&s->temp_clause);
1029
    veci_new(&s->conf_final);
Alan Mishchenko committed
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042

    // initialize arrays
    s->wlists    = 0;
    s->activity  = 0;
    s->orderpos  = 0;
    s->reasons   = 0;
    s->trail     = 0;

    // initialize other vars
    s->size                   = 0;
    s->cap                    = 0;
    s->qhead                  = 0;
    s->qtail                  = 0;
1043
#ifdef USE_FLOAT_ACTIVITY
Alan Mishchenko committed
1044
    s->var_inc                = 1;
1045
    s->cla_inc                = 1;
1046 1047
    s->var_decay              = (float)(1 / 0.95 );
    s->cla_decay              = (float)(1 / 0.999);
1048 1049 1050 1051
#else
    s->var_inc                = (1 <<  5);
    s->cla_inc                = (1 << 11);
#endif
Alan Mishchenko committed
1052
    s->root_level             = 0;
1053 1054
//    s->simpdb_assigns         = 0;
//    s->simpdb_props           = 0;
Alan Mishchenko committed
1055 1056
    s->random_seed            = 91648253;
    s->progress_estimate      = 0;
1057 1058
//    s->binary                 = (clause*)ABC_ALLOC( char, sizeof(clause) + sizeof(lit)*2);
//    s->binary->size_learnt    = (2 << 1);
Alan Mishchenko committed
1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
    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;
    return s;
}

1074 1075 1076 1077 1078
void sat_solver_setnvars(sat_solver* s,int n)
{
    int var;

    if (s->cap < n){
1079
        int old_cap = s->cap;
1080
        while (s->cap < n) s->cap = s->cap*2+1;
1081 1082
        if ( s->cap < 50000 )
            s->cap = 50000;
1083

1084 1085 1086 1087 1088 1089
        s->wlists    = ABC_REALLOC(veci,   s->wlists,   s->cap*2);
//        s->vi        = ABC_REALLOC(varinfo,s->vi,       s->cap);
        s->levels    = ABC_REALLOC(int,    s->levels,   s->cap);
        s->assigns   = ABC_REALLOC(char,   s->assigns,  s->cap);
        s->polarity  = ABC_REALLOC(char,   s->polarity, s->cap);
        s->tags      = ABC_REALLOC(char,   s->tags,     s->cap);
1090
        s->loads     = ABC_REALLOC(char,   s->loads,    s->cap);
1091 1092 1093 1094
#ifdef USE_FLOAT_ACTIVITY
        s->activity  = ABC_REALLOC(double,   s->activity, s->cap);
#else
        s->activity  = ABC_REALLOC(unsigned, s->activity, s->cap);
1095
        s->activity2 = ABC_REALLOC(unsigned, s->activity2,s->cap);
1096
#endif
1097
        s->pFreqs    = ABC_REALLOC(char,   s->pFreqs,   s->cap);
1098

1099
        if ( s->factors )
1100 1101
        s->factors   = ABC_REALLOC(double, s->factors,  s->cap);
        s->orderpos  = ABC_REALLOC(int,    s->orderpos, s->cap);
1102
        s->reasons   = ABC_REALLOC(int,    s->reasons,  s->cap);
1103
        s->trail     = ABC_REALLOC(lit,    s->trail,    s->cap);
1104
        s->model     = ABC_REALLOC(int,    s->model,    s->cap);
1105 1106
        memset( s->wlists + 2*old_cap, 0, 2*(s->cap-old_cap)*sizeof(veci) );
    } 
1107 1108

    for (var = s->size; var < n; var++){
1109 1110 1111
        assert(!s->wlists[2*var].size);
        assert(!s->wlists[2*var+1].size);
        if ( s->wlists[2*var].ptr == NULL )
1112
            veci_new(&s->wlists[2*var]);
1113
        if ( s->wlists[2*var+1].ptr == NULL )
1114
            veci_new(&s->wlists[2*var+1]);
1115 1116 1117 1118 1119
#ifdef USE_FLOAT_ACTIVITY
        s->activity[var] = 0;
#else
        s->activity[var] = (1<<10);
#endif
1120
        s->pFreqs[var]   = 0;
1121 1122 1123 1124 1125 1126 1127
        if ( s->factors )
        s->factors [var] = 0;
//        *((int*)s->vi + var) = 0; s->vi[var].val = varX;
        s->levels  [var] = 0;
        s->assigns [var] = varX;
        s->polarity[var] = 0;
        s->tags    [var] = 0;
1128
        s->loads   [var] = 0;
1129 1130
        s->orderpos[var] = veci_size(&s->order);
        s->reasons [var] = 0;
1131
        s->model   [var] = 0; 
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141
        
        /* 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;
}
Alan Mishchenko committed
1142 1143 1144

void sat_solver_delete(sat_solver* s)
{
1145 1146
//    Vec_SetFree_( &s->Mem );
    Sat_MemFree_( &s->Mem );
Alan Mishchenko committed
1147 1148 1149 1150 1151

    // delete vectors
    veci_delete(&s->order);
    veci_delete(&s->trail_lim);
    veci_delete(&s->tagged);
1152 1153
//    veci_delete(&s->learned);
    veci_delete(&s->act_clas);
Alan Mishchenko committed
1154
    veci_delete(&s->stack);
1155
//    veci_delete(&s->model);
Alan Mishchenko committed
1156
    veci_delete(&s->act_vars);
1157
    veci_delete(&s->unit_lits);
1158
    veci_delete(&s->pivot_vars);
Alan Mishchenko committed
1159
    veci_delete(&s->temp_clause);
1160
    veci_delete(&s->conf_final);
1161
    veci_delete(&s->vDeciVars);    
Alan Mishchenko committed
1162 1163

    // delete arrays
1164
    if (s->reasons != 0){
Alan Mishchenko committed
1165
        int i;
1166
        for (i = 0; i < s->cap*2; i++)
1167
            veci_delete(&s->wlists[i]);
Alan Mishchenko committed
1168
        ABC_FREE(s->wlists   );
1169 1170 1171 1172 1173
//        ABC_FREE(s->vi       );
        ABC_FREE(s->levels   );
        ABC_FREE(s->assigns  );
        ABC_FREE(s->polarity );
        ABC_FREE(s->tags     );
1174
        ABC_FREE(s->loads    );
Alan Mishchenko committed
1175
        ABC_FREE(s->activity );
1176
        ABC_FREE(s->activity2);
1177
        ABC_FREE(s->pFreqs   );
Alan Mishchenko committed
1178 1179 1180 1181
        ABC_FREE(s->factors  );
        ABC_FREE(s->orderpos );
        ABC_FREE(s->reasons  );
        ABC_FREE(s->trail    );
1182
        ABC_FREE(s->model    );
Alan Mishchenko committed
1183 1184
    }

Alan Mishchenko committed
1185
    sat_solver_store_free(s);
Alan Mishchenko committed
1186
    ABC_FREE(s);
Alan Mishchenko committed
1187 1188
}

1189
void sat_solver_restart( sat_solver* s )
1190 1191
{
    int i;
1192
    Sat_MemRestart( &s->Mem );
1193
    s->hLearnts = -1;
1194
    s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
1195 1196
    s->binary = clause_read( s, s->hBinary );

1197
    veci_resize(&s->act_clas, 0);
1198 1199 1200 1201 1202
    veci_resize(&s->trail_lim, 0);
    veci_resize(&s->order, 0);
    for ( i = 0; i < s->size*2; i++ )
        s->wlists[i].size = 0;

1203
    s->nDBreduces = 0;
1204

1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219
    // initialize other vars
    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;
1220 1221
//    s->simpdb_assigns         = 0;
//    s->simpdb_props           = 0;
1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237
    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;
}

1238
// returns memory in bytes used by the SAT solver
1239
double sat_solver_memory( sat_solver* s )
1240
{
1241 1242
    int i;
    double Mem = sizeof(sat_solver);
1243 1244 1245 1246 1247 1248 1249
    for (i = 0; i < s->cap*2; i++)
        Mem += s->wlists[i].cap * sizeof(int);
    Mem += s->cap * sizeof(veci);     // ABC_FREE(s->wlists   );
    Mem += s->cap * sizeof(int);      // ABC_FREE(s->levels   );
    Mem += s->cap * sizeof(char);     // ABC_FREE(s->assigns  );
    Mem += s->cap * sizeof(char);     // ABC_FREE(s->polarity );
    Mem += s->cap * sizeof(char);     // ABC_FREE(s->tags     );
1250
    Mem += s->cap * sizeof(char);     // ABC_FREE(s->loads    );
1251 1252 1253 1254
#ifdef USE_FLOAT_ACTIVITY
    Mem += s->cap * sizeof(double);   // ABC_FREE(s->activity );
#else
    Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity );
1255 1256
    if ( s->activity2 )
    Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity2);
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
#endif
    if ( s->factors )
    Mem += s->cap * sizeof(double);   // ABC_FREE(s->factors  );
    Mem += s->cap * sizeof(int);      // ABC_FREE(s->orderpos );
    Mem += s->cap * sizeof(int);      // ABC_FREE(s->reasons  );
    Mem += s->cap * sizeof(lit);      // ABC_FREE(s->trail    );
    Mem += s->cap * sizeof(int);      // ABC_FREE(s->model    );

    Mem += s->order.cap * sizeof(int);
    Mem += s->trail_lim.cap * sizeof(int);
    Mem += s->tagged.cap * sizeof(int);
1268
//    Mem += s->learned.cap * sizeof(int);
1269 1270
    Mem += s->stack.cap * sizeof(int);
    Mem += s->act_vars.cap * sizeof(int);
1271
    Mem += s->unit_lits.cap * sizeof(int);
1272
    Mem += s->act_clas.cap * sizeof(int);
1273 1274
    Mem += s->temp_clause.cap * sizeof(int);
    Mem += s->conf_final.cap * sizeof(int);
1275
    Mem += Sat_MemMemoryAll( &s->Mem );
1276 1277 1278
    return Mem;
}

1279
int sat_solver_simplify(sat_solver* s)
1280
{
1281 1282 1283 1284
    assert(sat_solver_dl(s) == 0);
    if (sat_solver_propagate(s) != 0)
        return false;
    return true;
1285 1286
}

1287
void sat_solver_reducedb(sat_solver* s)
1288
{
1289 1290
    static abctime TimeTotal = 0;
    abctime clk = Abc_Clock();
1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304
    Sat_Mem_t * pMem = &s->Mem;
    int nLearnedOld = veci_size(&s->act_clas);
    int * act_clas = veci_begin(&s->act_clas);
    int * pPerm, * pArray, * pSortValues, nCutoffValue;
    int i, k, j, Id, Counter, CounterStart, nSelected;
    clause * c;

    assert( s->nLearntMax > 0 );
    assert( nLearnedOld == Sat_MemEntryNum(pMem, 1) );
    assert( nLearnedOld == (int)s->stats.learnts );

    s->nDBreduces++;

//    printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax );
1305
    s->nLearntMax = s->nLearntStart + s->nLearntDelta * s->nDBreduces;
1306 1307 1308 1309 1310 1311 1312 1313 1314 1315
//    return;

    // create sorting values
    pSortValues = ABC_ALLOC( int, nLearnedOld );
    Sat_MemForEachLearned( pMem, c, i, k )
    {
        Id = clause_id(c);
        pSortValues[Id] = (((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4));
//        pSortValues[Id] = act[Id];
        assert( pSortValues[Id] >= 0 );
1316 1317
    }

1318 1319
    // preserve 1/20 of last clauses
    CounterStart  = nLearnedOld - (s->nLearntMax / 20);
1320

1321
    // preserve 3/4 of most active clauses
1322
    nSelected = nLearnedOld*s->nLearntRatio/100;
1323

1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342
    // find non-decreasing permutation
    pPerm = Abc_MergeSortCost( pSortValues, nLearnedOld );
    assert( pSortValues[pPerm[0]] <= pSortValues[pPerm[nLearnedOld-1]] );
    nCutoffValue = pSortValues[pPerm[nLearnedOld-nSelected]];
    ABC_FREE( pPerm );
//    ActCutOff = ABC_INFINITY;

    // mark learned clauses to remove
    Counter = j = 0;
    Sat_MemForEachLearned( pMem, c, i, k )
    {
        assert( c->mark == 0 );
        if ( Counter++ > CounterStart || clause_size(c) < 3 || pSortValues[clause_id(c)] > nCutoffValue || s->reasons[lit_var(c->lits[0])] == Sat_MemHand(pMem, i, k) )
            act_clas[j++] = act_clas[clause_id(c)];
        else // delete
        {
            c->mark = 1;
            s->stats.learnts_literals -= clause_size(c);
            s->stats.learnts--;
1343 1344
        }
    }
1345 1346 1347 1348
    assert( s->stats.learnts == (unsigned)j );
    assert( Counter == nLearnedOld );
    veci_resize(&s->act_clas,j);
    ABC_FREE( pSortValues );
1349

1350 1351 1352
    // update ID of each clause to be its new handle
    Counter = Sat_MemCompactLearned( pMem, 0 );
    assert( Counter == (int)s->stats.learnts );
1353

1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366
    // update reasons
    for ( i = 0; i < s->size; i++ )
    {
        if ( !s->reasons[i] ) // no reason
            continue;
        if ( clause_is_lit(s->reasons[i]) ) // 2-lit clause
            continue;
        if ( !clause_learnt_h(pMem, s->reasons[i]) ) // problem clause
            continue;
        c = clause_read( s, s->reasons[i] );
        assert( c->mark == 0 );
        s->reasons[i] = clause_id(c); // updating handle here!!!
    }
1367

1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385
    // update 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++ )
        {
            if ( clause_is_lit(pArray[k]) ) // 2-lit clause
                pArray[j++] = pArray[k];
            else if ( !clause_learnt_h(pMem, pArray[k]) ) // problem clause
                pArray[j++] = pArray[k];
            else 
            {
                c = clause_read(s, pArray[k]);
                if ( !c->mark ) // useful learned clause
                   pArray[j++] = clause_id(c); // updating handle here!!!
            }
        }
        veci_resize(&s->wlists[i],j);
1386
    }
1387 1388 1389 1390 1391 1392

    // perform final move of the clauses
    Counter = Sat_MemCompactLearned( pMem, 1 );
    assert( Counter == (int)s->stats.learnts );

    // report the results
1393
    TimeTotal += Abc_Clock() - clk;
1394
    if ( s->fVerbose )
1395 1396 1397 1398
    {
    Abc_Print(1, "reduceDB: Keeping %7d out of %7d clauses (%5.2f %%)  ",
        s->stats.learnts, nLearnedOld, 100.0 * s->stats.learnts / nLearnedOld );
    Abc_PrintTime( 1, "Time", TimeTotal );
1399 1400 1401
    }
}

1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 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 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494

// reverses to the previously bookmarked point
void sat_solver_rollback( sat_solver* s )
{
    Sat_Mem_t * pMem = &s->Mem;
    int i, k, j;
    static int Count = 0;
    Count++;
    assert( s->iVarPivot >= 0 && s->iVarPivot <= s->size );
    assert( s->iTrailPivot >= 0 && s->iTrailPivot <= s->qtail );
    // reset implication queue
    sat_solver_canceluntil_rollback( s, s->iTrailPivot );
    // update order 
    if ( s->iVarPivot < s->size )
    { 
        if ( s->activity2 )
        {
            s->var_inc = s->var_inc2;
            memcpy( s->activity, s->activity2, sizeof(unsigned) * s->iVarPivot );
        }
        veci_resize(&s->order, 0);
        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->iVarPivot*2; i++ )
    {
        cla* pArray = veci_begin(&s->wlists[i]);
        for ( j = k = 0; k < veci_size(&s->wlists[i]); k++ )
            if ( Sat_MemClauseUsed(pMem, pArray[k]) )
                pArray[j++] = pArray[k];
        veci_resize(&s->wlists[i],j);
    }
    // reset watcher lists
    for ( i = 2*s->iVarPivot; i < 2*s->size; i++ )
        s->wlists[i].size = 0;

    // reset clause counts
    s->stats.clauses = pMem->BookMarkE[0];
    s->stats.learnts = pMem->BookMarkE[1];
    // rollback clauses
    Sat_MemRollBack( pMem );

    // resize learned arrays
    veci_resize(&s->act_clas,  s->stats.learnts);

    // initialize other vars
    s->size = s->iVarPivot;
    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->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;

        // initialize rollback
        s->iVarPivot              =  0; // the pivot for variables
        s->iTrailPivot            =  0; // the pivot for trail
        s->hProofPivot            =  1; // the pivot for proof records
    }
}


1495
int sat_solver_addclause(sat_solver* s, lit* begin, lit* end)
Alan Mishchenko committed
1496
{
1497
    int fVerbose = 0;
Alan Mishchenko committed
1498 1499 1500
    lit *i,*j;
    int maxvar;
    lit last;
1501
    assert( begin < end );
1502 1503 1504 1505 1506 1507
    if ( fVerbose )
    {
        for ( i = begin; i < end; i++ )
            printf( "%s%d ", (*i)&1 ? "!":"", (*i)>>1 );
        printf( "\n" );
    }
Alan Mishchenko committed
1508

Alan Mishchenko committed
1509 1510 1511 1512 1513 1514
    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 );

Alan Mishchenko committed
1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525
    // 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_solver_setnvars(s,maxvar+1);

Alan Mishchenko committed
1526 1527 1528 1529
    ///////////////////////////////////
    // add clause to internal storage
    if ( s->pStore )
    {
1530
        int RetValue = Sto_ManAddClause( (Sto_Man_t *)s->pStore, begin, end );
Alan Mishchenko committed
1531
        assert( RetValue );
Alan Mishchenko committed
1532
        (void) RetValue;
Alan Mishchenko committed
1533 1534 1535
    }
    ///////////////////////////////////

Alan Mishchenko committed
1536 1537 1538
    // delete duplicates
    last = lit_Undef;
    for (i = j = begin; i < end; i++){
1539 1540
        //printf("lit: "L_LIT", value = %d\n", L_lit(*i), (lit_sign(*i) ? -s->assignss[lit_var(*i)] : s->assignss[lit_var(*i)]));
        if (*i == lit_neg(last) || var_value(s, lit_var(*i)) == lit_sign(*i))
Alan Mishchenko committed
1541
            return true;   // tautology
1542
        else if (*i != last && var_value(s, lit_var(*i)) == varX)
Alan Mishchenko committed
1543 1544
            last = *j++ = *i;
    }
1545
//    j = i;
Alan Mishchenko committed
1546 1547 1548

    if (j == begin)          // empty clause
        return false;
Alan Mishchenko committed
1549 1550

    if (j - begin == 1) // unit clause
1551
        return sat_solver_enqueue(s,*begin,0);
Alan Mishchenko committed
1552 1553

    // create new clause
1554
    sat_solver_clause_new(s,begin,j,0);
Alan Mishchenko committed
1555 1556 1557
    return true;
}

1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576
double luby(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 luby_test()
{
    int i;
    for ( i = 0; i < 20; i++ )
        printf( "%d ", (int)luby(2,i) );
    printf( "\n" );
}
Alan Mishchenko committed
1577

1578
static lbool sat_solver_search(sat_solver* s, ABC_INT64_T nof_conflicts)
1579
{
1580 1581
//    double  var_decay       = 0.95;
//    double  clause_decay    = 0.999;
1582
    double  random_var_freq = s->fNotUseRandom ? 0.0 : 0.02;
1583 1584
    int fGuided = (veci_size(&s->vDeciVars) > 0);
    ABC_INT64_T  conflictC  = 0;
1585 1586 1587
    veci    learnt_clause;
    int     i;

1588
    assert(s->root_level == sat_solver_dl(s));
1589 1590 1591 1592 1593

    s->nRestarts++;
    s->stats.starts++;
//    s->var_decay = (float)(1 / var_decay   );  // move this to sat_solver_new()
//    s->cla_decay = (float)(1 / clause_decay);  // move this to sat_solver_new()
1594
//    veci_resize(&s->model,0);
1595 1596
    veci_new(&learnt_clause);

1597 1598 1599 1600 1601 1602 1603 1604 1605
    // update variable polarity
    if ( fGuided )
    {
        int * pVars = veci_begin(&s->vDeciVars);
        for ( i = 0; i < veci_size(&s->vDeciVars); i++ )
            var_set_polar( s, pVars[i], 0 );
        s->iDeciVar = 0;
    }

1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617
    // use activity factors in every even restart
    if ( (s->nRestarts & 1) && veci_size(&s->act_vars) > 0 )
//    if ( veci_size(&s->act_vars) > 0 )
        for ( i = 0; i < s->act_vars.size; i++ )
            act_var_bump_factor(s, s->act_vars.ptr[i]);

    // use activity factors in every restart
    if ( s->pGlobalVars && veci_size(&s->act_vars) > 0 )
        for ( i = 0; i < s->act_vars.size; i++ )
            act_var_bump_global(s, s->act_vars.ptr[i]);

    for (;;){
1618 1619
        int hConfl = sat_solver_propagate(s);
        if (hConfl != 0){
1620 1621 1622 1623 1624 1625 1626
            // CONFLICT
            int blevel;

#ifdef VERBOSEDEBUG
            printf(L_IND"**CONFLICT**\n", L_ind);
#endif
            s->stats.conflicts++; conflictC++;
1627
            if (sat_solver_dl(s) == s->root_level){
1628
#ifdef SAT_USE_ANALYZE_FINAL
1629
                sat_solver_analyze_final(s, hConfl, 0);
1630 1631 1632 1633 1634 1635
#endif
                veci_delete(&learnt_clause);
                return l_False;
            }

            veci_resize(&learnt_clause,0);
1636 1637
            sat_solver_analyze(s, hConfl, &learnt_clause);
            blevel = veci_size(&learnt_clause) > 1 ? var_level(s, lit_var(veci_begin(&learnt_clause)[1])) : s->root_level;
1638 1639 1640 1641 1642
            blevel = s->root_level > blevel ? s->root_level : blevel;
            sat_solver_canceluntil(s,blevel);
            sat_solver_record(s,&learnt_clause);
#ifdef SAT_USE_ANALYZE_FINAL
//            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)
1643 1644
            if ( learnt_clause.size == 1 ) 
                var_set_level(s, lit_var(learnt_clause.ptr[0]), 0);
1645 1646
#endif
            act_var_decay(s);
1647
            act_clause_decay(s);
1648 1649 1650 1651

        }else{
            // NO CONFLICT
            int next;
1652
 
1653
            // Reached bound on number of conflicts:
1654 1655 1656 1657 1658 1659 1660 1661
            if ( !fGuided )
            {
                if ((nof_conflicts >= 0 && conflictC >= nof_conflicts) || (s->nRuntimeLimit && (s->stats.conflicts & 63) == 0 && Abc_Clock() > s->nRuntimeLimit)){
                    s->progress_estimate = sat_solver_progress(s);
                    sat_solver_canceluntil(s,s->root_level);
                    veci_delete(&learnt_clause);
                    return l_Undef; }
            }
1662

1663
            // Reached bound on number of conflicts:
1664 1665 1666 1667 1668 1669 1670 1671 1672
            if ( (s->nConfLimit && s->stats.conflicts > s->nConfLimit) ||
                 (s->nInsLimit  && s->stats.propagations > s->nInsLimit) )
            {
                s->progress_estimate = sat_solver_progress(s);
                sat_solver_canceluntil(s,s->root_level);
                veci_delete(&learnt_clause);
                return l_Undef; 
            }

1673
            // Simplify the set of problem clauses:
1674
            if (sat_solver_dl(s) == 0 && !s->fSkipSimplify)
1675 1676
                sat_solver_simplify(s);

1677 1678 1679 1680
            // Reduce the set of learnt clauses:
//            if (s->nLearntMax && veci_size(&s->learned) - s->qtail >= s->nLearntMax)
            if (s->nLearntMax && veci_size(&s->act_clas) >= s->nLearntMax)
                sat_solver_reducedb(s);
1681 1682 1683

            // New variable decision:
            s->stats.decisions++;
1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701
            if ( fGuided )
            {
                int nVars = veci_size(&s->vDeciVars);
                int * pVars = veci_begin(&s->vDeciVars);
                next = var_Undef;
                assert( s->iDeciVar <= nVars );
                while ( s->iDeciVar < nVars )
                {
                    int iVar = pVars[s->iDeciVar++];
                    if ( var_value(s, iVar) == varX )
                    {
                        next = iVar;
                        break;
                    }
                }
            }
            else
                next = order_select(s,(float)random_var_freq);
1702 1703 1704 1705

            if (next == var_Undef){
                // Model found:
                int i;
1706 1707
                for (i = 0; i < s->size; i++)
                    s->model[i] = (var_value(s,i)==var1 ? l_True : l_False);
1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721
                sat_solver_canceluntil(s,s->root_level);
                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;
            }

1722
            if ( var_polar(s, next) ) // positive polarity
1723
                sat_solver_assume(s,toLit(next));
1724
            else
1725
                sat_solver_assume(s,lit_neg(toLit(next)));
1726 1727 1728 1729 1730 1731
        }
    }

    return l_Undef; // cannot happen
}

Alan Mishchenko committed
1732
int sat_solver_solve(sat_solver* s, lit* begin, lit* end, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal)
Alan Mishchenko committed
1733
{
1734 1735
    int restart_iter = 0;
    ABC_INT64_T  nof_conflicts;
1736
//    ABC_INT64_T  nof_learnts   = sat_solver_nclauses(s) / 3;
Alan Mishchenko committed
1737 1738
    lbool   status        = l_Undef;
    lit*    i;
Alan Mishchenko committed
1739

1740 1741 1742
    if ( s->fVerbose )
        printf( "Running SAT solver with parameters %d and %d and %d.\n", s->nLearntStart, s->nLearntDelta, s->nLearntRatio );

Alan Mishchenko committed
1743 1744 1745 1746 1747
    ////////////////////////////////////////////////
    if ( s->fSolved )
    {
        if ( s->pStore )
        {
1748
            int RetValue = Sto_ManAddClause( (Sto_Man_t *)s->pStore, NULL, NULL );
Alan Mishchenko committed
1749
            assert( RetValue );
Alan Mishchenko committed
1750
            (void) RetValue;
Alan Mishchenko committed
1751 1752 1753 1754
        }
        return l_False;
    }
    ////////////////////////////////////////////////
1755
    veci_resize(&s->unit_lits, 0);
Alan Mishchenko committed
1756

Alan Mishchenko committed
1757
    // set the external limits
Alan Mishchenko committed
1758
    s->nCalls++;
Alan Mishchenko committed
1759
    s->nRestarts  = 0;
Alan Mishchenko committed
1760 1761 1762 1763 1764
    s->nConfLimit = 0;
    s->nInsLimit  = 0;
    if ( nConfLimit )
        s->nConfLimit = s->stats.conflicts + nConfLimit;
    if ( nInsLimit )
1765 1766
//        s->nInsLimit = s->stats.inspects + nInsLimit;
        s->nInsLimit = s->stats.propagations + nInsLimit;
Alan Mishchenko committed
1767
    if ( nConfLimitGlobal && (s->nConfLimit == 0 || s->nConfLimit > nConfLimitGlobal) )
Alan Mishchenko committed
1768
        s->nConfLimit = nConfLimitGlobal;
Alan Mishchenko committed
1769
    if ( nInsLimitGlobal && (s->nInsLimit == 0 || s->nInsLimit > nInsLimitGlobal) )
Alan Mishchenko committed
1770 1771
        s->nInsLimit = nInsLimitGlobal;

1772 1773
#ifndef SAT_USE_ANALYZE_FINAL

Alan Mishchenko committed
1774 1775
    //printf("solve: "); printlits(begin, end); printf("\n");
    for (i = begin; i < end; i++){
1776 1777 1778
//        switch (lit_sign(*i) ? -s->assignss[lit_var(*i)] : s->assignss[lit_var(*i)]){
        switch (var_value(s, *i)) {
        case var1: // l_True: 
Alan Mishchenko committed
1779
            break;
1780
        case varX: // l_Undef
1781
            sat_solver_assume(s, *i);
1782
            if (sat_solver_propagate(s) == 0)
Alan Mishchenko committed
1783
                break;
Alan Mishchenko committed
1784
            // fallthrough
1785
        case var0: // l_False 
Alan Mishchenko committed
1786 1787 1788 1789
            sat_solver_canceluntil(s, 0);
            return l_False;
        }
    }
1790
    s->root_level = sat_solver_dl(s);
Alan Mishchenko committed
1791

1792 1793 1794 1795 1796 1797 1798 1799
#endif

/*
    // Perform assumptions:
    root_level = assumps.size();
    for (int i = 0; i < assumps.size(); i++){
        Lit p = assumps[i];
        assert(var(p) < nVars());
1800
        if (!sat_solver_assume(p)){
1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833
            GClause r = reason[var(p)];
            if (r != GClause_NULL){
                Clause* confl;
                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; }
        Clause* confl = propagate();
        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);
1834
        if (!sat_solver_enqueue(s,p,0))
1835
        {
1836 1837
            int h = s->reasons[lit_var(p)];
            if (h)
1838
            {
1839
                if (clause_is_lit(h))
1840
                {
1841 1842 1843
                    (clause_begin(s->binary))[1] = lit_neg(p);
                    (clause_begin(s->binary))[0] = clause_read_lit(h);
                    h = s->hBinary;
1844
                }
1845
                sat_solver_analyze_final(s, h, 1);
1846 1847 1848 1849 1850 1851
                veci_push(&s->conf_final, lit_neg(p));
            }
            else
            {
                veci_resize(&s->conf_final,0);
                veci_push(&s->conf_final, lit_neg(p));
1852
                // the two lines below are a bug fix by Siert Wieringa 
1853
                if (var_level(s, lit_var(p)) > 0)
1854
                    veci_push(&s->conf_final, p);
1855 1856 1857 1858 1859 1860
            }
            sat_solver_canceluntil(s, 0);
            return l_False; 
        }
        else
        {
1861 1862 1863
            int fConfl = sat_solver_propagate(s);
            if (fConfl){
                sat_solver_analyze_final(s, fConfl, 0);
1864
                //assert(s->conf_final.size > 0);
1865 1866 1867 1868
                sat_solver_canceluntil(s, 0);
                return l_False; }
        }
    }
1869
    assert(s->root_level == sat_solver_dl(s));
1870 1871 1872 1873
#endif

    s->nCalls2++;

Alan Mishchenko committed
1874 1875 1876 1877 1878 1879 1880 1881 1882 1883
    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){
        double Ratio = (s->stats.learnts == 0)? 0.0 :
            s->stats.learnts_literals / (double)s->stats.learnts;
1884
        if ( s->nRuntimeLimit && Abc_Clock() > s->nRuntimeLimit )
Alan Mishchenko committed
1885
            break;
Alan Mishchenko committed
1886 1887
        if (s->verbosity >= 1)
        {
Alan Mishchenko committed
1888 1889 1890 1891
            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,
1892 1893
//                (double)nof_learnts, 
                (double)0, 
Alan Mishchenko committed
1894 1895 1896 1897 1898 1899
                (double)s->stats.learnts, 
                (double)s->stats.learnts_literals,
                Ratio,
                s->progress_estimate*100);
            fflush(stdout);
        }
1900
        nof_conflicts = (ABC_INT64_T)( 100 * luby(2, restart_iter++) );
1901 1902
        status = sat_solver_search(s, nof_conflicts);
//        nof_learnts    = nof_learnts * 11 / 10; //*= 1.1;
Alan Mishchenko committed
1903 1904 1905
        // quit the loop if reached an external limit
        if ( s->nConfLimit && s->stats.conflicts > s->nConfLimit )
            break;
1906
        if ( s->nInsLimit  && s->stats.propagations > s->nInsLimit )
Alan Mishchenko committed
1907
            break;
1908
        if ( s->nRuntimeLimit && Abc_Clock() > s->nRuntimeLimit )
1909
            break;
Alan Mishchenko committed
1910 1911 1912 1913 1914
    }
    if (s->verbosity >= 1)
        printf("==============================================================================\n");

    sat_solver_canceluntil(s,0);
Alan Mishchenko committed
1915 1916

    ////////////////////////////////////////////////
Alan Mishchenko committed
1917
    if ( status == l_False && s->pStore )
Alan Mishchenko committed
1918
    {
1919
        int RetValue = Sto_ManAddClause( (Sto_Man_t *)s->pStore, NULL, NULL );
Alan Mishchenko committed
1920
        assert( RetValue );
Alan Mishchenko committed
1921
        (void) RetValue;
Alan Mishchenko committed
1922 1923
    }
    ////////////////////////////////////////////////
Alan Mishchenko committed
1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935
    return status;
}


int sat_solver_nvars(sat_solver* s)
{
    return s->size;
}


int sat_solver_nclauses(sat_solver* s)
{
1936
    return s->stats.clauses;
Alan Mishchenko committed
1937 1938 1939 1940 1941 1942 1943 1944 1945
}


int sat_solver_nconflicts(sat_solver* s)
{
    return (int)s->stats.conflicts;
}

//=================================================================================================
Alan Mishchenko committed
1946 1947 1948 1949 1950 1951 1952 1953 1954 1955
// Clause storage functions:

void sat_solver_store_alloc( sat_solver * s )
{
    assert( s->pStore == NULL );
    s->pStore = Sto_ManAlloc();
}

void sat_solver_store_write( sat_solver * s, char * pFileName )
{
1956
    if ( s->pStore ) Sto_ManDumpClauses( (Sto_Man_t *)s->pStore, pFileName );
Alan Mishchenko committed
1957 1958 1959 1960
}

void sat_solver_store_free( sat_solver * s )
{
1961
    if ( s->pStore ) Sto_ManFree( (Sto_Man_t *)s->pStore );
Alan Mishchenko committed
1962 1963
    s->pStore = NULL;
}
Alan Mishchenko committed
1964 1965 1966

int sat_solver_store_change_last( sat_solver * s )
{
1967
    if ( s->pStore ) return Sto_ManChangeLastClause( (Sto_Man_t *)s->pStore );
Alan Mishchenko committed
1968 1969
    return -1;
}
Alan Mishchenko committed
1970
 
Alan Mishchenko committed
1971 1972
void sat_solver_store_mark_roots( sat_solver * s )
{
1973
    if ( s->pStore ) Sto_ManMarkRoots( (Sto_Man_t *)s->pStore );
Alan Mishchenko committed
1974 1975 1976 1977
}

void sat_solver_store_mark_clauses_a( sat_solver * s )
{
1978
    if ( s->pStore ) Sto_ManMarkClausesA( (Sto_Man_t *)s->pStore );
Alan Mishchenko committed
1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990
}

void * sat_solver_store_release( sat_solver * s )
{
    void * pTemp;
    if ( s->pStore == NULL )
        return NULL;
    pTemp = s->pStore;
    s->pStore = NULL;
    return pTemp;
}

Alan Mishchenko committed
1991

1992 1993
ABC_NAMESPACE_IMPL_END