Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/external/picosat/picosat.c
2065 views
1
/****************************************************************************
2
Copyright (c) 2006 - 2015, Armin Biere, Johannes Kepler University.
3
4
Permission is hereby granted, free of charge, to any person obtaining a copy
5
of this software and associated documentation files (the "Software"), to
6
deal in the Software without restriction, including without limitation the
7
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
sell copies of the Software, and to permit persons to whom the Software is
9
furnished to do so, subject to the following conditions:
10
11
The above copyright notice and this permission notice shall be included in
12
all copies or substantial portions of the Software.
13
14
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
IN THE SOFTWARE.
21
****************************************************************************/
22
23
#include <stdlib.h>
24
#include <stdio.h>
25
#include <string.h>
26
#include <assert.h>
27
#include <limits.h>
28
#include <ctype.h>
29
#include <stdarg.h>
30
#include <stdint.h>
31
32
#include "picosat.h"
33
34
/* By default code for 'all different constraints' is disabled, since 'NADC'
35
* is defined.
36
*/
37
#define NADC
38
39
/* By default we enable failed literals, since 'NFL' is undefined.
40
*
41
#define NFL
42
*/
43
44
/* By default we 'detach satisfied (large) clauses', e.g. NDSC undefined.
45
*
46
#define NDSC
47
*/
48
49
/* Do not use luby restart schedule instead of inner/outer.
50
*
51
#define NLUBY
52
*/
53
54
/* Enabling this define, will use gnuplot to visualize how the scores evolve.
55
*
56
#define VISCORES
57
*/
58
#ifdef VISCORES
59
// #define WRITEGIF /* ... to generate a video */
60
#endif
61
62
#ifdef VISCORES
63
#ifndef WRITEGIF
64
#include <unistd.h> /* for 'usleep' */
65
#endif
66
#endif
67
68
#ifdef RCODE
69
#include <R.h>
70
#endif
71
72
#define MINRESTART 100 /* minimum restart interval */
73
#define MAXRESTART 1000000 /* maximum restart interval */
74
#define RDECIDE 1000 /* interval of random decisions */
75
#define FRESTART 110 /* restart increase factor in percent */
76
#define FREDUCE 110 /* reduce increase factor in percent */
77
#define FREDADJ 121 /* reduce increase adjustment factor */
78
#define MAXCILS 10 /* maximal number of unrecycled internals */
79
#define FFLIPPED 10000 /* flipped reduce factor */
80
#define FFLIPPEDPREC 10000000/* flipped reduce factor precision */
81
#define INTERRUPTLIM 1024 /* check interrupt after that many decisions */
82
83
#ifndef TRACE
84
#define NO_BINARY_CLAUSES /* store binary clauses more compactly */
85
#endif
86
87
/* For debugging purposes you may want to define 'LOGGING', which actually
88
* can be enforced by using './configure.sh --log'.
89
*/
90
#ifdef LOGGING
91
#define LOG(code) do { code; } while (0)
92
#else
93
#define LOG(code) do { } while (0)
94
#endif
95
#define NOLOG(code) do { } while (0) /* log exception */
96
#define ONLYLOG(code) do { code; } while (0) /* force logging */
97
98
#define FALSE ((Val)-1)
99
#define UNDEF ((Val)0)
100
#define TRUE ((Val)1)
101
102
#define COMPACT_TRACECHECK_TRACE_FMT 0
103
#define EXTENDED_TRACECHECK_TRACE_FMT 1
104
#define RUP_TRACE_FMT 2
105
106
#define NEWN(p,n) do { (p) = new (ps, sizeof (*(p)) * (n)); } while (0)
107
#define CLRN(p,n) do { memset ((p), 0, sizeof (*(p)) * (n)); } while (0)
108
#define CLR(p) CLRN(p,1)
109
#define DELETEN(p,n) \
110
do { delete (ps, p, sizeof (*(p)) * (n)); (p) = 0; } while (0)
111
112
#define RESIZEN(p,old_num,new_num) \
113
do { \
114
size_t old_size = sizeof (*(p)) * (old_num); \
115
size_t new_size = sizeof (*(p)) * (new_num); \
116
(p) = resize (ps, (p), old_size, new_size) ; \
117
} while (0)
118
119
#define ENLARGE(start,head,end) \
120
do { \
121
unsigned old_num = (ptrdiff_t)((end) - (start)); \
122
size_t new_num = old_num ? (2 * old_num) : 1; \
123
unsigned count = (head) - (start); \
124
assert ((start) <= (end)); \
125
RESIZEN((start),old_num,new_num); \
126
(head) = (start) + count; \
127
(end) = (start) + new_num; \
128
} while (0)
129
130
#define NOTLIT(l) (ps->lits + (1 ^ ((l) - ps->lits)))
131
132
#define LIT2IDX(l) ((ptrdiff_t)((l) - ps->lits) / 2)
133
#define LIT2IMPLS(l) (ps->impls + (ptrdiff_t)((l) - ps->lits))
134
#define LIT2INT(l) ((int)(LIT2SGN(l) * LIT2IDX(l)))
135
#define LIT2SGN(l) (((ptrdiff_t)((l) - ps->lits) & 1) ? -1 : 1)
136
#define LIT2VAR(l) (ps->vars + LIT2IDX(l))
137
#define LIT2HTPS(l) (ps->htps + (ptrdiff_t)((l) - ps->lits))
138
#define LIT2JWH(l) (ps->jwh + ((l) - ps->lits))
139
140
#ifndef NDSC
141
#define LIT2DHTPS(l) (ps->dhtps + (ptrdiff_t)((l) - ps->lits))
142
#endif
143
144
#ifdef NO_BINARY_CLAUSES
145
typedef uintptr_t Wrd;
146
#define ISLITREASON(C) (1&(Wrd)C)
147
#define LIT2REASON(L) \
148
(assert (L->val==TRUE), ((Cls*)(1 + (2*(L - ps->lits)))))
149
#define REASON2LIT(C) ((Lit*)(ps->lits + ((Wrd)C)/2))
150
#endif
151
152
#define ENDOFCLS(c) ((void*)((Lit**)(c)->lits + (c)->size))
153
154
#define SOC ((ps->oclauses == ps->ohead) ? ps->lclauses : ps->oclauses)
155
#define EOC (ps->lhead)
156
#define NXC(p) (((p) + 1 == ps->ohead) ? ps->lclauses : (p) + 1)
157
158
#define OIDX2IDX(idx) (2 * ((idx) + 1))
159
#define LIDX2IDX(idx) (2 * (idx) + 1)
160
161
#define ISLIDX(idx) ((idx)&1)
162
163
#define IDX2OIDX(idx) (assert(!ISLIDX(idx)), (idx)/2 - 1)
164
#define IDX2LIDX(idx) (assert(ISLIDX(idx)), (idx)/2)
165
166
#define EXPORTIDX(idx) \
167
((ISLIDX(idx) ? (IDX2LIDX (idx) + (ps->ohead - ps->oclauses)) : IDX2OIDX(idx)) + 1)
168
169
#define IDX2CLS(i) \
170
(assert(i), (ISLIDX(i) ? ps->lclauses : ps->oclauses)[(i)/2 - !ISLIDX(i)])
171
172
#define IDX2ZHN(i) (assert(i), (ISLIDX(i) ? ps->zhains[(i)/2] : 0))
173
174
#define CLS2TRD(c) (((Trd*)(c)) - 1)
175
#define CLS2IDX(c) ((((Trd*)(c)) - 1)->idx)
176
177
#define CLS2ACT(c) \
178
((Act*)((assert((c)->learned)),assert((c)->size>2),ENDOFCLS(c)))
179
180
#define VAR2LIT(v) (ps->lits + 2 * ((v) - ps->vars))
181
#define VAR2RNK(v) (ps->rnks + ((v) - ps->vars))
182
183
#define RNK2LIT(r) (ps->lits + 2 * ((r) - ps->rnks))
184
#define RNK2VAR(r) (ps->vars + ((r) - ps->rnks))
185
186
#define BLK_FILL_BYTES 8
187
#define SIZE_OF_BLK (sizeof (Blk) - BLK_FILL_BYTES)
188
189
#define PTR2BLK(void_ptr) \
190
((void_ptr) ? (Blk*)(((char*)(void_ptr)) - SIZE_OF_BLK) : 0)
191
192
#define AVERAGE(a,b) ((b) ? (((double)a) / (double)(b)) : 0.0)
193
#define PERCENT(a,b) (100.0 * AVERAGE(a,b))
194
195
#ifndef RCODE
196
#define ABORT(msg) \
197
do { \
198
fputs ("*** picosat: " msg "\n", stderr); \
199
abort (); \
200
} while (0)
201
#else
202
#define ABORT(msg) \
203
do { \
204
Rf_error (msg); \
205
} while (0)
206
#endif
207
208
#define ABORTIF(cond,msg) \
209
do { \
210
if (!(cond)) break; \
211
ABORT (msg); \
212
} while (0)
213
214
#define ZEROFLT (0x00000000u)
215
#define EPSFLT (0x00000001u)
216
#define INFFLT (0xffffffffu)
217
218
#define FLTCARRY (1u << 25)
219
#define FLTMSB (1u << 24)
220
#define FLTMAXMANTISSA (FLTMSB - 1)
221
222
#define FLTMANTISSA(d) ((d) & FLTMAXMANTISSA)
223
#define FLTEXPONENT(d) ((int)((d) >> 24) - 128)
224
225
#define FLTMINEXPONENT (-128)
226
#define FLTMAXEXPONENT (127)
227
228
#define CMPSWAPFLT(a,b) \
229
do { \
230
Flt tmp; \
231
if (((a) < (b))) \
232
{ \
233
tmp = (a); \
234
(a) = (b); \
235
(b) = tmp; \
236
} \
237
} while (0)
238
239
#define UNPACKFLT(u,m,e) \
240
do { \
241
(m) = FLTMANTISSA(u); \
242
(e) = FLTEXPONENT(u); \
243
(m) |= FLTMSB; \
244
} while (0)
245
246
#define INSERTION_SORT_LIMIT 10
247
248
#define SORTING_SWAP(T,p,q) \
249
do { \
250
T tmp = *(q); \
251
*(q) = *(p); \
252
*(p) = tmp; \
253
} while (0)
254
255
#define SORTING_CMP_SWAP(T,cmp,p,q) \
256
do { \
257
if ((cmp) (ps, *(p), *(q)) > 0) \
258
SORTING_SWAP (T, p, q); \
259
} while(0)
260
261
#define QUICKSORT_PARTITION(T,cmp,a,l,r) \
262
do { \
263
T pivot; \
264
int j; \
265
i = (l) - 1; /* result in 'i' */ \
266
j = (r); \
267
pivot = (a)[j]; \
268
for (;;) \
269
{ \
270
while ((cmp) (ps, (a)[++i], pivot) < 0) \
271
; \
272
while ((cmp) (ps, pivot, (a)[--j]) < 0) \
273
if (j == (l)) \
274
break; \
275
if (i >= j) \
276
break; \
277
SORTING_SWAP (T, (a) + i, (a) + j); \
278
} \
279
SORTING_SWAP (T, (a) + i, (a) + (r)); \
280
} while(0)
281
282
#define QUICKSORT(T,cmp,a,n) \
283
do { \
284
int l = 0, r = (n) - 1, m, ll, rr, i; \
285
assert (ps->ihead == ps->indices); \
286
if (r - l <= INSERTION_SORT_LIMIT) \
287
break; \
288
for (;;) \
289
{ \
290
m = (l + r) / 2; \
291
SORTING_SWAP (T, (a) + m, (a) + r - 1); \
292
SORTING_CMP_SWAP (T, cmp, (a) + l, (a) + r - 1); \
293
SORTING_CMP_SWAP (T, cmp, (a) + l, (a) + r); \
294
SORTING_CMP_SWAP (T, cmp, (a) + r - 1, (a) + r); \
295
QUICKSORT_PARTITION (T, cmp, (a), l + 1, r - 1); \
296
if (i - l < r - i) \
297
{ \
298
ll = i + 1; \
299
rr = r; \
300
r = i - 1; \
301
} \
302
else \
303
{ \
304
ll = l; \
305
rr = i - 1; \
306
l = i + 1; \
307
} \
308
if (r - l > INSERTION_SORT_LIMIT) \
309
{ \
310
assert (rr - ll > INSERTION_SORT_LIMIT); \
311
if (ps->ihead == ps->eoi) \
312
ENLARGE (ps->indices, ps->ihead, ps->eoi); \
313
*ps->ihead++ = ll; \
314
if (ps->ihead == ps->eoi) \
315
ENLARGE (ps->indices, ps->ihead, ps->eoi); \
316
*ps->ihead++ = rr; \
317
} \
318
else if (rr - ll > INSERTION_SORT_LIMIT) \
319
{ \
320
l = ll; \
321
r = rr; \
322
} \
323
else if (ps->ihead > ps->indices) \
324
{ \
325
r = *--ps->ihead; \
326
l = *--ps->ihead; \
327
} \
328
else \
329
break; \
330
} \
331
} while (0)
332
333
#define INSERTION_SORT(T,cmp,a,n) \
334
do { \
335
T pivot; \
336
int l = 0, r = (n) - 1, i, j; \
337
for (i = r; i > l; i--) \
338
SORTING_CMP_SWAP (T, cmp, (a) + i - 1, (a) + i); \
339
for (i = l + 2; i <= r; i++) \
340
{ \
341
j = i; \
342
pivot = (a)[i]; \
343
while ((cmp) (ps, pivot, (a)[j - 1]) < 0) \
344
{ \
345
(a)[j] = (a)[j - 1]; \
346
j--; \
347
} \
348
(a)[j] = pivot; \
349
} \
350
} while (0)
351
352
#ifdef NDEBUG
353
#define CHECK_SORTED(cmp,a,n) do { } while(0)
354
#else
355
#define CHECK_SORTED(cmp,a,n) \
356
do { \
357
int i; \
358
for (i = 0; i < (n) - 1; i++) \
359
assert ((cmp) (ps, (a)[i], (a)[i + 1]) <= 0); \
360
} while(0)
361
#endif
362
363
#define SORT(T,cmp,a,n) \
364
do { \
365
T * aa = (a); \
366
int nn = (n); \
367
QUICKSORT (T, cmp, aa, nn); \
368
INSERTION_SORT (T, cmp, aa, nn); \
369
assert (ps->ihead == ps->indices); \
370
CHECK_SORTED (cmp, aa, nn); \
371
} while (0)
372
373
#define WRDSZ (sizeof (long) * 8)
374
375
#ifdef RCODE
376
#define fprintf(...) do { } while (0)
377
#define vfprintf(...) do { } while (0)
378
#define fputs(...) do { } while (0)
379
#define fputc(...) do { } while (0)
380
#endif
381
382
typedef unsigned Flt; /* 32 bit deterministic soft float */
383
typedef Flt Act; /* clause and variable activity */
384
typedef struct Blk Blk; /* allocated memory block */
385
typedef struct Cls Cls; /* clause */
386
typedef struct Lit Lit; /* literal */
387
typedef struct Rnk Rnk; /* variable to score mapping */
388
typedef signed char Val; /* TRUE, UNDEF, FALSE */
389
typedef struct Var Var; /* variable */
390
#ifdef TRACE
391
typedef struct Trd Trd; /* trace data for clauses */
392
typedef struct Zhn Zhn; /* compressed chain (=zain) data */
393
typedef unsigned char Znt; /* compressed antecedent data */
394
#endif
395
396
#ifdef NO_BINARY_CLAUSES
397
typedef struct Ltk Ltk;
398
399
struct Ltk
400
{
401
Lit ** start;
402
unsigned count : WRDSZ == 32 ? 27 : 32;
403
unsigned ldsize : WRDSZ == 32 ? 5 : 32;
404
};
405
#endif
406
407
struct Lit
408
{
409
Val val;
410
};
411
412
struct Var
413
{
414
unsigned mark : 1; /*bit 1*/
415
unsigned resolved : 1; /*bit 2*/
416
unsigned phase : 1; /*bit 3*/
417
unsigned assigned : 1; /*bit 4*/
418
unsigned used : 1; /*bit 5*/
419
unsigned failed : 1; /*bit 6*/
420
unsigned internal : 1; /*bit 7*/
421
unsigned usedefphase : 1; /*bit 8*/
422
unsigned defphase : 1; /*bit 9*/
423
unsigned msspos : 1; /*bit 10*/
424
unsigned mssneg : 1; /*bit 11*/
425
unsigned humuspos : 1; /*bit 12*/
426
unsigned humusneg : 1; /*bit 13*/
427
unsigned partial : 1; /*bit 14*/
428
#ifdef TRACE
429
unsigned core : 1; /*bit 15*/
430
#endif
431
unsigned level;
432
Cls *reason;
433
#ifndef NADC
434
Lit ** inado;
435
Lit ** ado;
436
Lit *** adotabpos;
437
#endif
438
};
439
440
struct Rnk
441
{
442
Act score;
443
unsigned pos : 30; /* 0 iff not on heap */
444
unsigned moreimportant : 1;
445
unsigned lessimportant : 1;
446
};
447
448
struct Cls
449
{
450
unsigned size;
451
452
unsigned collect:1; /* bit 1 */
453
unsigned learned:1; /* bit 2 */
454
unsigned locked:1; /* bit 3 */
455
unsigned used:1; /* bit 4 */
456
#ifndef NDEBUG
457
unsigned connected:1; /* bit 5 */
458
#endif
459
#ifdef TRACE
460
unsigned collected:1; /* bit 6 */
461
unsigned core:1; /* bit 7 */
462
#endif
463
464
#define LDMAXGLUE 25 /* 32 - 7 */
465
#define MAXGLUE ((1<<LDMAXGLUE)-1)
466
467
unsigned glue:LDMAXGLUE;
468
469
Cls *next[2];
470
Lit *lits[2];
471
};
472
473
#ifdef TRACE
474
struct Zhn
475
{
476
unsigned ref:31;
477
unsigned core:1;
478
Znt * liz;
479
Znt znt[0];
480
};
481
482
struct Trd
483
{
484
unsigned idx;
485
Cls cls[0];
486
};
487
#endif
488
489
struct Blk
490
{
491
#ifndef NDEBUG
492
union
493
{
494
size_t size; /* this is what we really use */
495
void *as_two_ptrs[2]; /* 2 * sizeof (void*) alignment of data */
496
}
497
header;
498
#endif
499
char data[BLK_FILL_BYTES];
500
};
501
502
enum State
503
{
504
RESET = 0,
505
READY = 1,
506
SAT = 2,
507
UNSAT = 3,
508
UNKNOWN = 4,
509
};
510
511
enum Phase
512
{
513
POSPHASE,
514
NEGPHASE,
515
JWLPHASE,
516
RNDPHASE,
517
};
518
519
struct PicoSAT
520
{
521
enum State state;
522
enum Phase defaultphase;
523
int last_sat_call_result;
524
525
FILE *out;
526
char * prefix;
527
int verbosity;
528
int plain;
529
unsigned LEVEL;
530
unsigned max_var;
531
unsigned size_vars;
532
533
Lit *lits;
534
Var *vars;
535
Rnk *rnks;
536
Flt *jwh;
537
Cls **htps;
538
#ifndef NDSC
539
Cls **dhtps;
540
#endif
541
#ifdef NO_BINARY_CLAUSES
542
Ltk *impls;
543
Cls impl, cimpl;
544
int implvalid, cimplvalid;
545
#else
546
Cls **impls;
547
#endif
548
Lit **trail, **thead, **eot, **ttail, ** ttail2;
549
#ifndef NADC
550
Lit **ttailado;
551
#endif
552
unsigned adecidelevel;
553
Lit **als, **alshead, **alstail, **eoals;
554
Lit **CLS, **clshead, **eocls;
555
int *rils, *rilshead, *eorils;
556
int *cils, *cilshead, *eocils;
557
int *fals, *falshead, *eofals;
558
int *mass, szmass;
559
int *mssass, szmssass;
560
int *mcsass, nmcsass, szmcsass;
561
int *humus, szhumus;
562
Lit *failed_assumption;
563
int extracted_all_failed_assumptions;
564
Rnk **heap, **hhead, **eoh;
565
Cls **oclauses, **ohead, **eoo; /* original clauses */
566
Cls **lclauses, **lhead, ** EOL; /* learned clauses */
567
int * soclauses, * sohead, * eoso; /* saved original clauses */
568
int saveorig;
569
int partial;
570
#ifdef TRACE
571
int trace;
572
Zhn **zhains, **zhead, **eoz;
573
int ocore;
574
#endif
575
FILE * rup;
576
int rupstarted;
577
int rupvariables;
578
int rupclauses;
579
Cls *mtcls;
580
Cls *conflict;
581
Lit **added, **ahead, **eoa;
582
Var **marked, **mhead, **eom;
583
Var **dfs, **dhead, **eod;
584
Cls **resolved, **rhead, **eor;
585
unsigned char *levels, *levelshead, *eolevels;
586
unsigned *dused, *dusedhead, *eodused;
587
unsigned char *buffer, *bhead, *eob;
588
Act vinc, lscore, ilvinc, ifvinc;
589
#ifdef VISCORES
590
Act fvinc, nvinc;
591
#endif
592
Act cinc, lcinc, ilcinc, fcinc;
593
unsigned srng;
594
size_t current_bytes;
595
size_t max_bytes;
596
size_t recycled;
597
double seconds, flseconds;
598
double entered;
599
unsigned nentered;
600
int measurealltimeinlib;
601
char *rline[2];
602
int szrline, RCOUNT;
603
double levelsum;
604
unsigned iterations;
605
int reports;
606
int lastrheader;
607
unsigned calls;
608
unsigned decisions;
609
unsigned restarts;
610
unsigned simps;
611
unsigned fsimplify;
612
unsigned isimplify;
613
unsigned reductions;
614
unsigned lreduce;
615
unsigned lreduceadjustcnt;
616
unsigned lreduceadjustinc;
617
unsigned lastreduceconflicts;
618
unsigned llocked; /* locked large learned clauses */
619
unsigned lrestart;
620
#ifdef NLUBY
621
unsigned drestart;
622
unsigned ddrestart;
623
#else
624
unsigned lubycnt;
625
unsigned lubymaxdelta;
626
int waslubymaxdelta;
627
#endif
628
unsigned long long lsimplify;
629
unsigned long long propagations;
630
unsigned long long lpropagations;
631
unsigned fixed; /* top level assignments */
632
#ifndef NFL
633
unsigned failedlits;
634
unsigned ifailedlits;
635
unsigned efailedlits;
636
unsigned flcalls;
637
#ifdef STATS
638
unsigned flrounds;
639
unsigned long long flprops;
640
unsigned long long floopsed, fltried, flskipped;
641
#endif
642
unsigned long long fllimit;
643
int simplifying;
644
Lit ** saved;
645
unsigned saved_size;
646
#endif
647
unsigned conflicts;
648
unsigned contexts;
649
unsigned internals;
650
unsigned noclauses; /* current number large original clauses */
651
unsigned nlclauses; /* current number large learned clauses */
652
unsigned olits; /* current literals in large original clauses */
653
unsigned llits; /* current literals in large learned clauses */
654
unsigned oadded; /* added original clauses */
655
unsigned ladded; /* added learned clauses */
656
unsigned loadded; /* added original large clauses */
657
unsigned lladded; /* added learned large clauses */
658
unsigned addedclauses; /* oadded + ladded */
659
unsigned vused; /* used variables */
660
unsigned llitsadded; /* added learned literals */
661
unsigned long long visits;
662
#ifdef STATS
663
unsigned loused; /* used large original clauses */
664
unsigned llused; /* used large learned clauses */
665
unsigned long long bvisits;
666
unsigned long long tvisits;
667
unsigned long long lvisits;
668
unsigned long long othertrue;
669
unsigned long long othertrue2;
670
unsigned long long othertruel;
671
unsigned long long othertrue2u;
672
unsigned long long othertruelu;
673
unsigned long long ltraversals;
674
unsigned long long traversals;
675
#ifdef TRACE
676
unsigned long long antecedents;
677
#endif
678
unsigned uips;
679
unsigned znts;
680
unsigned assumptions;
681
unsigned rdecisions;
682
unsigned sdecisions;
683
size_t srecycled;
684
size_t rrecycled;
685
unsigned long long derefs;
686
#endif
687
unsigned minimizedllits;
688
unsigned nonminimizedllits;
689
#ifndef NADC
690
Lit *** ados, *** hados, *** eados;
691
Lit *** adotab;
692
unsigned nadotab;
693
unsigned szadotab;
694
Cls * adoconflict;
695
unsigned adoconflicts;
696
unsigned adoconflictlimit;
697
int addingtoado;
698
int adodisabled;
699
#endif
700
unsigned long long flips;
701
#ifdef STATS
702
unsigned long long FORCED;
703
unsigned long long assignments;
704
unsigned inclreduces;
705
unsigned staticphasedecisions;
706
unsigned skippedrestarts;
707
#endif
708
int * indices, * ihead, *eoi;
709
unsigned sdflips;
710
711
unsigned long long saved_flips;
712
unsigned saved_max_var;
713
unsigned min_flipped;
714
715
void * emgr;
716
picosat_malloc enew;
717
picosat_realloc eresize;
718
picosat_free edelete;
719
720
struct {
721
void * state;
722
int (*function) (void *);
723
} interrupt;
724
725
#ifdef VISCORES
726
FILE * fviscores;
727
#endif
728
};
729
730
typedef PicoSAT PS;
731
732
static Flt
733
packflt (unsigned m, int e)
734
{
735
Flt res;
736
assert (m < FLTMSB);
737
assert (FLTMINEXPONENT <= e);
738
assert (e <= FLTMAXEXPONENT);
739
res = m | ((unsigned)(e + 128) << 24);
740
return res;
741
}
742
743
static Flt
744
base2flt (unsigned m, int e)
745
{
746
if (!m)
747
return ZEROFLT;
748
749
if (m < FLTMSB)
750
{
751
do
752
{
753
if (e <= FLTMINEXPONENT)
754
return EPSFLT;
755
756
e--;
757
m <<= 1;
758
759
}
760
while (m < FLTMSB);
761
}
762
else
763
{
764
while (m >= FLTCARRY)
765
{
766
if (e >= FLTMAXEXPONENT)
767
return INFFLT;
768
769
e++;
770
m >>= 1;
771
}
772
}
773
774
m &= ~FLTMSB;
775
return packflt (m, e);
776
}
777
778
static Flt
779
addflt (Flt a, Flt b)
780
{
781
unsigned ma, mb, delta;
782
int ea, eb;
783
784
CMPSWAPFLT (a, b);
785
if (!b)
786
return a;
787
788
UNPACKFLT (a, ma, ea);
789
UNPACKFLT (b, mb, eb);
790
791
assert (ea >= eb);
792
delta = ea - eb;
793
if (delta < 32) mb >>= delta; else mb = 0;
794
if (!mb)
795
return a;
796
797
ma += mb;
798
if (ma & FLTCARRY)
799
{
800
if (ea == FLTMAXEXPONENT)
801
return INFFLT;
802
803
ea++;
804
ma >>= 1;
805
}
806
807
assert (ma < FLTCARRY);
808
ma &= FLTMAXMANTISSA;
809
810
return packflt (ma, ea);
811
}
812
813
static Flt
814
mulflt (Flt a, Flt b)
815
{
816
unsigned ma, mb;
817
unsigned long long accu;
818
int ea, eb;
819
820
CMPSWAPFLT (a, b);
821
if (!b)
822
return ZEROFLT;
823
824
UNPACKFLT (a, ma, ea);
825
UNPACKFLT (b, mb, eb);
826
827
ea += eb;
828
ea += 24;
829
if (ea > FLTMAXEXPONENT)
830
return INFFLT;
831
832
if (ea < FLTMINEXPONENT)
833
return EPSFLT;
834
835
accu = ma;
836
accu *= mb;
837
accu >>= 24;
838
839
if (accu >= FLTCARRY)
840
{
841
if (ea == FLTMAXEXPONENT)
842
return INFFLT;
843
844
ea++;
845
accu >>= 1;
846
847
if (accu >= FLTCARRY)
848
return INFFLT;
849
}
850
851
assert (accu < FLTCARRY);
852
assert (accu & FLTMSB);
853
854
ma = accu;
855
ma &= ~FLTMSB;
856
857
return packflt (ma, ea);
858
}
859
860
static Flt
861
ascii2flt (const char *str)
862
{
863
Flt ten = base2flt (10, 0);
864
Flt onetenth = base2flt (26843546, -28);
865
Flt res = ZEROFLT, tmp, base;
866
const char *p = str;
867
int ch;
868
869
ch = *p++;
870
871
if (ch != '.')
872
{
873
if (!isdigit (ch))
874
return INFFLT; /* better abort ? */
875
876
res = base2flt (ch - '0', 0);
877
878
while ((ch = *p++))
879
{
880
if (ch == '.')
881
break;
882
883
if (!isdigit (ch))
884
return INFFLT; /* better abort? */
885
886
res = mulflt (res, ten);
887
tmp = base2flt (ch - '0', 0);
888
res = addflt (res, tmp);
889
}
890
}
891
892
if (ch == '.')
893
{
894
ch = *p++;
895
if (!isdigit (ch))
896
return INFFLT; /* better abort ? */
897
898
base = onetenth;
899
tmp = mulflt (base2flt (ch - '0', 0), base);
900
res = addflt (res, tmp);
901
902
while ((ch = *p++))
903
{
904
if (!isdigit (ch))
905
return INFFLT; /* better abort? */
906
907
base = mulflt (base, onetenth);
908
tmp = mulflt (base2flt (ch - '0', 0), base);
909
res = addflt (res, tmp);
910
}
911
}
912
913
return res;
914
}
915
916
#if defined(VISCORES)
917
918
static double
919
flt2double (Flt f)
920
{
921
double res;
922
unsigned m;
923
int e, i;
924
925
UNPACKFLT (f, m, e);
926
res = m;
927
928
if (e < 0)
929
{
930
for (i = e; i < 0; i++)
931
res *= 0.5;
932
}
933
else
934
{
935
for (i = 0; i < e; i++)
936
res *= 2.0;
937
}
938
939
return res;
940
}
941
942
#endif
943
944
static int
945
log2flt (Flt a)
946
{
947
return FLTEXPONENT (a) + 24;
948
}
949
950
static int
951
cmpflt (Flt a, Flt b)
952
{
953
if (a < b)
954
return -1;
955
956
if (a > b)
957
return 1;
958
959
return 0;
960
}
961
962
static void *
963
new (PS * ps, size_t size)
964
{
965
size_t bytes;
966
Blk *b;
967
968
if (!size)
969
return 0;
970
971
bytes = size + SIZE_OF_BLK;
972
973
if (ps->enew)
974
b = ps->enew (ps->emgr, bytes);
975
else
976
b = malloc (bytes);
977
978
ABORTIF (!b, "out of memory in 'new'");
979
#ifndef NDEBUG
980
b->header.size = size;
981
#endif
982
ps->current_bytes += size;
983
if (ps->current_bytes > ps->max_bytes)
984
ps->max_bytes = ps->current_bytes;
985
return b->data;
986
}
987
988
static void
989
delete (PS * ps, void *void_ptr, size_t size)
990
{
991
size_t bytes;
992
Blk *b;
993
994
if (!void_ptr)
995
{
996
assert (!size);
997
return;
998
}
999
1000
assert (size);
1001
b = PTR2BLK (void_ptr);
1002
1003
assert (size <= ps->current_bytes);
1004
ps->current_bytes -= size;
1005
1006
assert (b->header.size == size);
1007
1008
bytes = size + SIZE_OF_BLK;
1009
if (ps->edelete)
1010
ps->edelete (ps->emgr, b, bytes);
1011
else
1012
free (b);
1013
}
1014
1015
static void *
1016
resize (PS * ps, void *void_ptr, size_t old_size, size_t new_size)
1017
{
1018
size_t old_bytes, new_bytes;
1019
Blk *b;
1020
1021
b = PTR2BLK (void_ptr);
1022
1023
assert (old_size <= ps->current_bytes);
1024
ps->current_bytes -= old_size;
1025
1026
if ((old_bytes = old_size))
1027
{
1028
assert (old_size && b && b->header.size == old_size);
1029
old_bytes += SIZE_OF_BLK;
1030
}
1031
else
1032
assert (!b);
1033
1034
if ((new_bytes = new_size))
1035
new_bytes += SIZE_OF_BLK;
1036
1037
if (ps->eresize)
1038
b = ps->eresize (ps->emgr, b, old_bytes, new_bytes);
1039
else
1040
b = realloc (b, new_bytes);
1041
1042
if (!new_size)
1043
{
1044
assert (!b);
1045
return 0;
1046
}
1047
1048
ABORTIF (!b, "out of memory in 'resize'");
1049
#ifndef NDEBUG
1050
b->header.size = new_size;
1051
#endif
1052
1053
ps->current_bytes += new_size;
1054
if (ps->current_bytes > ps->max_bytes)
1055
ps->max_bytes = ps->current_bytes;
1056
1057
return b->data;
1058
}
1059
1060
static unsigned
1061
int2unsigned (int l)
1062
{
1063
return (l < 0) ? 1 + 2 * -l : 2 * l;
1064
}
1065
1066
static Lit *
1067
int2lit (PS * ps, int l)
1068
{
1069
return ps->lits + int2unsigned (l);
1070
}
1071
1072
static Lit **
1073
end_of_lits (Cls * c)
1074
{
1075
return (Lit**)c->lits + c->size;
1076
}
1077
1078
#if !defined(NDEBUG) || defined(LOGGING)
1079
1080
static void
1081
dumplits (PS * ps, Lit ** l, Lit ** end)
1082
{
1083
int first;
1084
Lit ** p;
1085
1086
if (l == end)
1087
{
1088
/* empty clause */
1089
}
1090
else if (l + 1 == end)
1091
{
1092
fprintf (ps->out, "%d ", LIT2INT (l[0]));
1093
}
1094
else
1095
{
1096
assert (l + 2 <= end);
1097
first = (abs (LIT2INT (l[0])) > abs (LIT2INT (l[1])));
1098
fprintf (ps->out, "%d ", LIT2INT (l[first]));
1099
fprintf (ps->out, "%d ", LIT2INT (l[!first]));
1100
for (p = l + 2; p < end; p++)
1101
fprintf (ps->out, "%d ", LIT2INT (*p));
1102
}
1103
1104
fputc ('0', ps->out);
1105
}
1106
1107
static void
1108
dumpcls (PS * ps, Cls * c)
1109
{
1110
Lit **end;
1111
1112
if (c)
1113
{
1114
end = end_of_lits (c);
1115
dumplits (ps, c->lits, end);
1116
#ifdef TRACE
1117
if (ps->trace)
1118
fprintf (ps->out, " clause(%u)", CLS2IDX (c));
1119
#endif
1120
}
1121
else
1122
fputs ("DECISION", ps->out);
1123
}
1124
1125
static void
1126
dumpclsnl (PS * ps, Cls * c)
1127
{
1128
dumpcls (ps, c);
1129
fputc ('\n', ps->out);
1130
}
1131
1132
void
1133
dumpcnf (PS * ps)
1134
{
1135
Cls **p, *c;
1136
1137
for (p = SOC; p != EOC; p = NXC (p))
1138
{
1139
c = *p;
1140
1141
if (!c)
1142
continue;
1143
1144
#ifdef TRACE
1145
if (c->collected)
1146
continue;
1147
#endif
1148
1149
dumpclsnl (ps, *p);
1150
}
1151
}
1152
1153
#endif
1154
1155
static void
1156
delete_prefix (PS * ps)
1157
{
1158
if (!ps->prefix)
1159
return;
1160
1161
delete (ps, ps->prefix, strlen (ps->prefix) + 1);
1162
ps->prefix = 0;
1163
}
1164
1165
static void
1166
new_prefix (PS * ps, const char * str)
1167
{
1168
delete_prefix (ps);
1169
assert (str);
1170
ps->prefix = new (ps, strlen (str) + 1);
1171
strcpy (ps->prefix, str);
1172
}
1173
1174
static PS *
1175
init (void * pmgr,
1176
picosat_malloc pnew, picosat_realloc presize, picosat_free pdelete)
1177
{
1178
PS * ps;
1179
1180
#if 0
1181
int count = 3 - !pnew - !presize - !pdelete;
1182
1183
ABORTIF (count && !pnew, "API usage: missing 'picosat_set_new'");
1184
ABORTIF (count && !presize, "API usage: missing 'picosat_set_resize'");
1185
ABORTIF (count && !pdelete, "API usage: missing 'picosat_set_delete'");
1186
#endif
1187
1188
ps = pnew ? pnew (pmgr, sizeof *ps) : malloc (sizeof *ps);
1189
ABORTIF (!ps, "failed to allocate memory for PicoSAT manager");
1190
memset (ps, 0, sizeof *ps);
1191
1192
ps->emgr = pmgr;
1193
ps->enew = pnew;
1194
ps->eresize = presize;
1195
ps->edelete = pdelete;
1196
1197
ps->size_vars = 1;
1198
ps->state = RESET;
1199
ps->defaultphase = JWLPHASE;
1200
#ifdef TRACE
1201
ps->ocore = -1;
1202
#endif
1203
ps->lastrheader = -2;
1204
#ifndef NADC
1205
ps->adoconflictlimit = UINT_MAX;
1206
#endif
1207
ps->min_flipped = UINT_MAX;
1208
1209
NEWN (ps->lits, 2 * ps->size_vars);
1210
NEWN (ps->jwh, 2 * ps->size_vars);
1211
NEWN (ps->htps, 2 * ps->size_vars);
1212
#ifndef NDSC
1213
NEWN (ps->dhtps, 2 * ps->size_vars);
1214
#endif
1215
NEWN (ps->impls, 2 * ps->size_vars);
1216
NEWN (ps->vars, ps->size_vars);
1217
NEWN (ps->rnks, ps->size_vars);
1218
1219
/* because '0' pos denotes not on heap
1220
*/
1221
ENLARGE (ps->heap, ps->hhead, ps->eoh);
1222
ps->hhead = ps->heap + 1;
1223
1224
ps->vinc = base2flt (1, 0); /* initial var activity */
1225
ps->ifvinc = ascii2flt ("1.05"); /* var score rescore factor */
1226
#ifdef VISCORES
1227
ps->fvinc = ascii2flt ("0.9523809"); /* 1/f = 1/1.05 */
1228
ps->nvinc = ascii2flt ("0.0476191"); /* 1 - 1/f = 1 - 1/1.05 */
1229
#endif
1230
ps->lscore = base2flt (1, 90); /* var activity rescore limit */
1231
ps->ilvinc = base2flt (1, -90); /* inverse of 'lscore' */
1232
1233
ps->cinc = base2flt (1, 0); /* initial clause activity */
1234
ps->fcinc = ascii2flt ("1.001"); /* cls activity rescore factor */
1235
ps->lcinc = base2flt (1, 90); /* cls activity rescore limit */
1236
ps->ilcinc = base2flt (1, -90); /* inverse of 'ilcinc' */
1237
1238
ps->lreduceadjustcnt = ps->lreduceadjustinc = 100;
1239
ps->lpropagations = ~0ull;
1240
1241
#ifndef RCODE
1242
ps->out = stdout;
1243
#else
1244
ps->out = 0;
1245
#endif
1246
new_prefix (ps, "c ");
1247
ps->verbosity = 0;
1248
ps->plain = 0;
1249
1250
#ifdef NO_BINARY_CLAUSES
1251
memset (&ps->impl, 0, sizeof (ps->impl));
1252
ps->impl.size = 2;
1253
1254
memset (&ps->cimpl, 0, sizeof (ps->impl));
1255
ps->cimpl.size = 2;
1256
#endif
1257
1258
#ifdef VISCORES
1259
ps->fviscores = popen (
1260
"/usr/bin/gnuplot -background black"
1261
" -xrm 'gnuplot*textColor:white'"
1262
" -xrm 'gnuplot*borderColor:white'"
1263
" -xrm 'gnuplot*axisColor:white'"
1264
, "w");
1265
fprintf (ps->fviscores, "unset key\n");
1266
// fprintf (ps->fviscores, "set log y\n");
1267
fflush (ps->fviscores);
1268
system ("rm -rf /tmp/picosat-viscores");
1269
system ("mkdir /tmp/picosat-viscores");
1270
system ("mkdir /tmp/picosat-viscores/data");
1271
#ifdef WRITEGIF
1272
system ("mkdir /tmp/picosat-viscores/gif");
1273
fprintf (ps->fviscores,
1274
"set terminal gif giant animate opt size 1024,768 x000000 xffffff"
1275
"\n");
1276
1277
fprintf (ps->fviscores,
1278
"set output \"/tmp/picosat-viscores/gif/animated.gif\"\n");
1279
#endif
1280
#endif
1281
ps->defaultphase = JWLPHASE;
1282
ps->state = READY;
1283
ps->last_sat_call_result = 0;
1284
1285
return ps;
1286
}
1287
1288
static size_t
1289
bytes_clause (PS * ps, unsigned size, unsigned learned)
1290
{
1291
size_t res;
1292
1293
res = sizeof (Cls);
1294
res += size * sizeof (Lit *);
1295
res -= 2 * sizeof (Lit *);
1296
1297
if (learned && size > 2)
1298
res += sizeof (Act); /* add activity */
1299
1300
#ifdef TRACE
1301
if (ps->trace)
1302
res += sizeof (Trd); /* add trace data */
1303
#else
1304
(void) ps;
1305
#endif
1306
1307
return res;
1308
}
1309
1310
static Cls *
1311
new_clause (PS * ps, unsigned size, unsigned learned)
1312
{
1313
size_t bytes;
1314
void * tmp;
1315
#ifdef TRACE
1316
Trd *trd;
1317
#endif
1318
Cls *res;
1319
1320
bytes = bytes_clause (ps, size, learned);
1321
tmp = new (ps, bytes);
1322
1323
#ifdef TRACE
1324
if (ps->trace)
1325
{
1326
trd = tmp;
1327
1328
if (learned)
1329
trd->idx = LIDX2IDX (ps->lhead - ps->lclauses);
1330
else
1331
trd->idx = OIDX2IDX (ps->ohead - ps->oclauses);
1332
1333
res = trd->cls;
1334
}
1335
else
1336
#endif
1337
res = tmp;
1338
1339
res->size = size;
1340
res->learned = learned;
1341
1342
res->collect = 0;
1343
#ifndef NDEBUG
1344
res->connected = 0;
1345
#endif
1346
res->locked = 0;
1347
res->used = 0;
1348
#ifdef TRACE
1349
res->core = 0;
1350
res->collected = 0;
1351
#endif
1352
1353
if (learned && size > 2)
1354
{
1355
Act * p = CLS2ACT (res);
1356
*p = ps->cinc;
1357
}
1358
1359
return res;
1360
}
1361
1362
static void
1363
delete_clause (PS * ps, Cls * c)
1364
{
1365
size_t bytes;
1366
#ifdef TRACE
1367
Trd *trd;
1368
#endif
1369
1370
bytes = bytes_clause (ps, c->size, c->learned);
1371
1372
#ifdef TRACE
1373
if (ps->trace)
1374
{
1375
trd = CLS2TRD (c);
1376
delete (ps, trd, bytes);
1377
}
1378
else
1379
#endif
1380
delete (ps, c, bytes);
1381
}
1382
1383
static void
1384
delete_clauses (PS * ps)
1385
{
1386
Cls **p;
1387
for (p = SOC; p != EOC; p = NXC (p))
1388
if (*p)
1389
delete_clause (ps, *p);
1390
1391
DELETEN (ps->oclauses, ps->eoo - ps->oclauses);
1392
DELETEN (ps->lclauses, ps->EOL - ps->lclauses);
1393
1394
ps->ohead = ps->eoo = ps->lhead = ps->EOL = 0;
1395
}
1396
1397
#ifdef TRACE
1398
1399
static void
1400
delete_zhain (PS * ps, Zhn * zhain)
1401
{
1402
const Znt *p, *znt;
1403
1404
assert (zhain);
1405
1406
znt = zhain->znt;
1407
for (p = znt; *p; p++)
1408
;
1409
1410
delete (ps, zhain, sizeof (Zhn) + (p - znt) + 1);
1411
}
1412
1413
static void
1414
delete_zhains (PS * ps)
1415
{
1416
Zhn **p, *z;
1417
for (p = ps->zhains; p < ps->zhead; p++)
1418
if ((z = *p))
1419
delete_zhain (ps, z);
1420
1421
DELETEN (ps->zhains, ps->eoz - ps->zhains);
1422
ps->eoz = ps->zhead = 0;
1423
}
1424
1425
#endif
1426
1427
#ifdef NO_BINARY_CLAUSES
1428
static void
1429
lrelease (PS * ps, Ltk * stk)
1430
{
1431
if (stk->start)
1432
DELETEN (stk->start, (1 << (stk->ldsize)));
1433
memset (stk, 0, sizeof (*stk));
1434
}
1435
#endif
1436
1437
#ifndef NADC
1438
1439
static unsigned
1440
llength (Lit ** a)
1441
{
1442
Lit ** p;
1443
for (p = a; *p; p++)
1444
;
1445
return p - a;
1446
}
1447
1448
static void
1449
resetadoconflict (PS * ps)
1450
{
1451
assert (ps->adoconflict);
1452
delete_clause (ps, ps->adoconflict);
1453
ps->adoconflict = 0;
1454
}
1455
1456
static void
1457
reset_ados (PS * ps)
1458
{
1459
Lit *** p;
1460
1461
for (p = ps->ados; p < ps->hados; p++)
1462
DELETEN (*p, llength (*p) + 1);
1463
1464
DELETEN (ps->ados, ps->eados - ps->ados);
1465
ps->hados = ps->eados = 0;
1466
1467
DELETEN (ps->adotab, ps->szadotab);
1468
ps->szadotab = ps->nadotab = 0;
1469
1470
if (ps->adoconflict)
1471
resetadoconflict (ps);
1472
1473
ps->adoconflicts = 0;
1474
ps->adoconflictlimit = UINT_MAX;
1475
ps->adodisabled = 0;
1476
}
1477
1478
#endif
1479
1480
static void
1481
reset (PS * ps)
1482
{
1483
ABORTIF (!ps ||
1484
ps->state == RESET, "API usage: reset without initialization");
1485
1486
delete_clauses (ps);
1487
#ifdef TRACE
1488
delete_zhains (ps);
1489
#endif
1490
#ifdef NO_BINARY_CLAUSES
1491
{
1492
unsigned i;
1493
for (i = 2; i <= 2 * ps->max_var + 1; i++)
1494
lrelease (ps, ps->impls + i);
1495
}
1496
#endif
1497
#ifndef NADC
1498
reset_ados (ps);
1499
#endif
1500
#ifndef NFL
1501
DELETEN (ps->saved, ps->saved_size);
1502
#endif
1503
DELETEN (ps->htps, 2 * ps->size_vars);
1504
#ifndef NDSC
1505
DELETEN (ps->dhtps, 2 * ps->size_vars);
1506
#endif
1507
DELETEN (ps->impls, 2 * ps->size_vars);
1508
DELETEN (ps->lits, 2 * ps->size_vars);
1509
DELETEN (ps->jwh, 2 * ps->size_vars);
1510
DELETEN (ps->vars, ps->size_vars);
1511
DELETEN (ps->rnks, ps->size_vars);
1512
DELETEN (ps->trail, ps->eot - ps->trail);
1513
DELETEN (ps->heap, ps->eoh - ps->heap);
1514
DELETEN (ps->als, ps->eoals - ps->als);
1515
DELETEN (ps->CLS, ps->eocls - ps->CLS);
1516
DELETEN (ps->rils, ps->eorils - ps->rils);
1517
DELETEN (ps->cils, ps->eocils - ps->cils);
1518
DELETEN (ps->fals, ps->eofals - ps->fals);
1519
DELETEN (ps->mass, ps->szmass);
1520
DELETEN (ps->mssass, ps->szmssass);
1521
DELETEN (ps->mcsass, ps->szmcsass);
1522
DELETEN (ps->humus, ps->szhumus);
1523
DELETEN (ps->added, ps->eoa - ps->added);
1524
DELETEN (ps->marked, ps->eom - ps->marked);
1525
DELETEN (ps->dfs, ps->eod - ps->dfs);
1526
DELETEN (ps->resolved, ps->eor - ps->resolved);
1527
DELETEN (ps->levels, ps->eolevels - ps->levels);
1528
DELETEN (ps->dused, ps->eodused - ps->dused);
1529
DELETEN (ps->buffer, ps->eob - ps->buffer);
1530
DELETEN (ps->indices, ps->eoi - ps->indices);
1531
DELETEN (ps->soclauses, ps->eoso - ps->soclauses);
1532
delete_prefix (ps);
1533
delete (ps, ps->rline[0], ps->szrline);
1534
delete (ps, ps->rline[1], ps->szrline);
1535
assert (getenv ("LEAK") || !ps->current_bytes); /* found leak if failing */
1536
#ifdef VISCORES
1537
pclose (ps->fviscores);
1538
#endif
1539
if (ps->edelete)
1540
ps->edelete (ps->emgr, ps, sizeof *ps);
1541
else
1542
free (ps);
1543
}
1544
1545
inline static void
1546
tpush (PS * ps, Lit * lit)
1547
{
1548
assert (ps->lits < lit && lit <= ps->lits + 2* ps->max_var + 1);
1549
if (ps->thead == ps->eot)
1550
{
1551
unsigned ttail2count = ps->ttail2 - ps->trail;
1552
unsigned ttailcount = ps->ttail - ps->trail;
1553
#ifndef NADC
1554
unsigned ttailadocount = ps->ttailado - ps->trail;
1555
#endif
1556
ENLARGE (ps->trail, ps->thead, ps->eot);
1557
ps->ttail = ps->trail + ttailcount;
1558
ps->ttail2 = ps->trail + ttail2count;
1559
#ifndef NADC
1560
ps->ttailado = ps->trail + ttailadocount;
1561
#endif
1562
}
1563
1564
*ps->thead++ = lit;
1565
}
1566
1567
static void
1568
assign_reason (PS * ps, Var * v, Cls * reason)
1569
{
1570
#if defined(NO_BINARY_CLAUSES) && !defined(NDEBUG)
1571
assert (reason != &ps->impl);
1572
#else
1573
(void) ps;
1574
#endif
1575
v->reason = reason;
1576
}
1577
1578
static void
1579
assign_phase (PS * ps, Lit * lit)
1580
{
1581
unsigned new_phase, idx;
1582
Var * v = LIT2VAR (lit);
1583
1584
#ifndef NFL
1585
/* In 'simplifying' mode we only need to keep 'min_flipped' up to date if
1586
* we force assignments on the top level. The other assignments will be
1587
* undone and thus we can keep the old saved value of the phase.
1588
*/
1589
if (!ps->LEVEL || !ps->simplifying)
1590
#endif
1591
{
1592
new_phase = (LIT2SGN (lit) > 0);
1593
1594
if (v->assigned)
1595
{
1596
ps->sdflips -= ps->sdflips/FFLIPPED;
1597
1598
if (new_phase != v->phase)
1599
{
1600
assert (FFLIPPEDPREC >= FFLIPPED);
1601
ps->sdflips += FFLIPPEDPREC / FFLIPPED;
1602
ps->flips++;
1603
1604
idx = LIT2IDX (lit);
1605
if (idx < ps->min_flipped)
1606
ps->min_flipped = idx;
1607
1608
NOLOG (fprintf (ps->out,
1609
"%sflipped %d\n",
1610
ps->prefix, LIT2INT (lit)));
1611
}
1612
}
1613
1614
v->phase = new_phase;
1615
v->assigned = 1;
1616
}
1617
1618
lit->val = TRUE;
1619
NOTLIT (lit)->val = FALSE;
1620
}
1621
1622
inline static void
1623
assign (PS * ps, Lit * lit, Cls * reason)
1624
{
1625
Var * v = LIT2VAR (lit);
1626
assert (lit->val == UNDEF);
1627
#ifdef STATS
1628
ps->assignments++;
1629
#endif
1630
v->level = ps->LEVEL;
1631
assign_phase (ps, lit);
1632
assign_reason (ps, v, reason);
1633
tpush (ps, lit);
1634
}
1635
1636
inline static int
1637
cmp_added (PS * ps, Lit * k, Lit * l)
1638
{
1639
Val a = k->val, b = l->val;
1640
Var *u, *v;
1641
int res;
1642
1643
if (a == UNDEF && b != UNDEF)
1644
return -1;
1645
1646
if (a != UNDEF && b == UNDEF)
1647
return 1;
1648
1649
u = LIT2VAR (k);
1650
v = LIT2VAR (l);
1651
1652
if (a != UNDEF)
1653
{
1654
assert (b != UNDEF);
1655
res = v->level - u->level;
1656
if (res)
1657
return res; /* larger level first */
1658
}
1659
1660
res = cmpflt (VAR2RNK (u)->score, VAR2RNK (v)->score);
1661
if (res)
1662
return res; /* smaller activity first */
1663
1664
return u - v; /* smaller index first */
1665
}
1666
1667
static void
1668
sorttwolits (Lit ** v)
1669
{
1670
Lit * a = v[0], * b = v[1];
1671
1672
assert (a != b);
1673
1674
if (a < b)
1675
return;
1676
1677
v[0] = b;
1678
v[1] = a;
1679
}
1680
1681
inline static void
1682
sortlits (PS * ps, Lit ** v, unsigned size)
1683
{
1684
if (size == 2)
1685
sorttwolits (v); /* same order with and with out 'NO_BINARY_CLAUSES' */
1686
else
1687
SORT (Lit *, cmp_added, v, size);
1688
}
1689
1690
#ifdef NO_BINARY_CLAUSES
1691
static Cls *
1692
setimpl (PS * ps, Lit * a, Lit * b)
1693
{
1694
assert (!ps->implvalid);
1695
assert (ps->impl.size == 2);
1696
1697
ps->impl.lits[0] = a;
1698
ps->impl.lits[1] = b;
1699
1700
sorttwolits (ps->impl.lits);
1701
ps->implvalid = 1;
1702
1703
return &ps->impl;
1704
}
1705
1706
static void
1707
resetimpl (PS * ps)
1708
{
1709
ps->implvalid = 0;
1710
}
1711
1712
static Cls *
1713
setcimpl (PS * ps, Lit * a, Lit * b)
1714
{
1715
assert (!ps->cimplvalid);
1716
assert (ps->cimpl.size == 2);
1717
1718
ps->cimpl.lits[0] = a;
1719
ps->cimpl.lits[1] = b;
1720
1721
sorttwolits (ps->cimpl.lits);
1722
ps->cimplvalid = 1;
1723
1724
return &ps->cimpl;
1725
}
1726
1727
static void
1728
resetcimpl (PS * ps)
1729
{
1730
assert (ps->cimplvalid);
1731
ps->cimplvalid = 0;
1732
}
1733
1734
#endif
1735
1736
static int
1737
cmp_ptr (PS * ps, void *l, void *k)
1738
{
1739
(void) ps;
1740
return ((char*)l) - (char*)k; /* arbitrarily already reverse */
1741
}
1742
1743
static int
1744
cmp_rnk (Rnk * r, Rnk * s)
1745
{
1746
if (!r->moreimportant && s->moreimportant)
1747
return -1;
1748
1749
if (r->moreimportant && !s->moreimportant)
1750
return 1;
1751
1752
if (!r->lessimportant && s->lessimportant)
1753
return 1;
1754
1755
if (r->lessimportant && !s->lessimportant)
1756
return -1;
1757
1758
if (r->score < s->score)
1759
return -1;
1760
1761
if (r->score > s->score)
1762
return 1;
1763
1764
return -cmp_ptr (0, r, s);
1765
}
1766
1767
static void
1768
hup (PS * ps, Rnk * v)
1769
{
1770
int upos, vpos;
1771
Rnk *u;
1772
1773
#ifndef NFL
1774
assert (!ps->simplifying);
1775
#endif
1776
1777
vpos = v->pos;
1778
1779
assert (0 < vpos);
1780
assert (vpos < ps->hhead - ps->heap);
1781
assert (ps->heap[vpos] == v);
1782
1783
while (vpos > 1)
1784
{
1785
upos = vpos / 2;
1786
1787
u = ps->heap[upos];
1788
1789
if (cmp_rnk (u, v) > 0)
1790
break;
1791
1792
ps->heap[vpos] = u;
1793
u->pos = vpos;
1794
1795
vpos = upos;
1796
}
1797
1798
ps->heap[vpos] = v;
1799
v->pos = vpos;
1800
}
1801
1802
static Cls *add_simplified_clause (PS *, int);
1803
1804
inline static void
1805
add_antecedent (PS * ps, Cls * c)
1806
{
1807
assert (c);
1808
1809
#ifdef NO_BINARY_CLAUSES
1810
if (ISLITREASON (c))
1811
return;
1812
1813
if (c == &ps->impl)
1814
return;
1815
#elif defined(STATS) && defined(TRACE)
1816
ps->antecedents++;
1817
#endif
1818
if (ps->rhead == ps->eor)
1819
ENLARGE (ps->resolved, ps->rhead, ps->eor);
1820
1821
assert (ps->rhead < ps->eor);
1822
*ps->rhead++ = c;
1823
}
1824
1825
#ifdef TRACE
1826
1827
#ifdef NO_BINARY_CLAUSES
1828
#error "can not combine TRACE and NO_BINARY_CLAUSES"
1829
#endif
1830
1831
#endif /* TRACE */
1832
1833
static void
1834
add_lit (PS * ps, Lit * lit)
1835
{
1836
assert (lit);
1837
1838
if (ps->ahead == ps->eoa)
1839
ENLARGE (ps->added, ps->ahead, ps->eoa);
1840
1841
*ps->ahead++ = lit;
1842
}
1843
1844
static void
1845
push_var_as_marked (PS * ps, Var * v)
1846
{
1847
if (ps->mhead == ps->eom)
1848
ENLARGE (ps->marked, ps->mhead, ps->eom);
1849
1850
*ps->mhead++ = v;
1851
}
1852
1853
static void
1854
mark_var (PS * ps, Var * v)
1855
{
1856
assert (!v->mark);
1857
v->mark = 1;
1858
push_var_as_marked (ps, v);
1859
}
1860
1861
#ifdef NO_BINARY_CLAUSES
1862
1863
static Cls *
1864
impl2reason (PS * ps, Lit * lit)
1865
{
1866
Lit * other;
1867
Cls * res;
1868
other = ps->impl.lits[0];
1869
if (lit == other)
1870
other = ps->impl.lits[1];
1871
assert (other->val == FALSE);
1872
res = LIT2REASON (NOTLIT (other));
1873
resetimpl (ps);
1874
return res;
1875
}
1876
1877
#endif
1878
1879
/* Whenever we have a top level derived unit we really should derive a unit
1880
* clause otherwise the resolutions in 'add_simplified_clause' become
1881
* incorrect.
1882
*/
1883
static Cls *
1884
resolve_top_level_unit (PS * ps, Lit * lit, Cls * reason)
1885
{
1886
unsigned count_resolved;
1887
Lit **p, **eol, *other;
1888
Var *u, *v;
1889
1890
assert (ps->rhead == ps->resolved);
1891
assert (ps->ahead == ps->added);
1892
1893
add_lit (ps, lit);
1894
add_antecedent (ps, reason);
1895
count_resolved = 1;
1896
v = LIT2VAR (lit);
1897
1898
eol = end_of_lits (reason);
1899
for (p = reason->lits; p < eol; p++)
1900
{
1901
other = *p;
1902
u = LIT2VAR (other);
1903
if (u == v)
1904
continue;
1905
1906
add_antecedent (ps, u->reason);
1907
count_resolved++;
1908
}
1909
1910
/* Some of the literals could be assumptions. If at least one
1911
* variable is not an assumption, we should resolve.
1912
*/
1913
if (count_resolved >= 2)
1914
{
1915
#ifdef NO_BINARY_CLAUSES
1916
if (reason == &ps->impl)
1917
resetimpl (ps);
1918
#endif
1919
reason = add_simplified_clause (ps, 1);
1920
#ifdef NO_BINARY_CLAUSES
1921
if (reason->size == 2)
1922
{
1923
assert (reason == &ps->impl);
1924
reason = impl2reason (ps, lit);
1925
}
1926
#endif
1927
assign_reason (ps, v, reason);
1928
}
1929
else
1930
{
1931
ps->ahead = ps->added;
1932
ps->rhead = ps->resolved;
1933
}
1934
1935
return reason;
1936
}
1937
1938
static void
1939
fixvar (PS * ps, Var * v)
1940
{
1941
Rnk * r;
1942
1943
assert (VAR2LIT (v)->val != UNDEF);
1944
assert (!v->level);
1945
1946
ps->fixed++;
1947
1948
r = VAR2RNK (v);
1949
r->score = INFFLT;
1950
1951
#ifndef NFL
1952
if (ps->simplifying)
1953
return;
1954
#endif
1955
1956
if (!r->pos)
1957
return;
1958
1959
hup (ps, r);
1960
}
1961
1962
static void
1963
use_var (PS * ps, Var * v)
1964
{
1965
if (v->used)
1966
return;
1967
1968
v->used = 1;
1969
ps->vused++;
1970
}
1971
1972
static void
1973
assign_forced (PS * ps, Lit * lit, Cls * reason)
1974
{
1975
Var *v;
1976
1977
assert (reason);
1978
assert (lit->val == UNDEF);
1979
1980
#ifdef STATS
1981
ps->FORCED++;
1982
#endif
1983
assign (ps, lit, reason);
1984
1985
#ifdef NO_BINARY_CLAUSES
1986
assert (reason != &ps->impl);
1987
if (ISLITREASON (reason))
1988
{
1989
reason = setimpl (ps, lit, NOTLIT (REASON2LIT (reason)));
1990
assert (reason);
1991
}
1992
#endif
1993
LOG ( fprintf (ps->out,
1994
"%sassign %d at level %d by ",
1995
ps->prefix, LIT2INT (lit), ps->LEVEL);
1996
dumpclsnl (ps, reason));
1997
1998
v = LIT2VAR (lit);
1999
if (!ps->LEVEL)
2000
use_var (ps, v);
2001
2002
if (!ps->LEVEL && reason->size > 1)
2003
{
2004
reason = resolve_top_level_unit (ps, lit, reason);
2005
assert (reason);
2006
}
2007
2008
#ifdef NO_BINARY_CLAUSES
2009
if (ISLITREASON (reason) || reason == &ps->impl)
2010
{
2011
/* DO NOTHING */
2012
}
2013
else
2014
#endif
2015
{
2016
assert (!reason->locked);
2017
reason->locked = 1;
2018
if (reason->learned && reason->size > 2)
2019
ps->llocked++;
2020
}
2021
2022
#ifdef NO_BINARY_CLAUSES
2023
if (reason == &ps->impl)
2024
resetimpl (ps);
2025
#endif
2026
2027
if (!ps->LEVEL)
2028
fixvar (ps, v);
2029
}
2030
2031
#ifdef NO_BINARY_CLAUSES
2032
2033
static void
2034
lpush (PS * ps, Lit * lit, Cls * c)
2035
{
2036
int pos = (c->lits[0] == lit);
2037
Ltk * s = LIT2IMPLS (lit);
2038
unsigned oldsize, newsize;
2039
2040
assert (c->size == 2);
2041
2042
if (!s->start)
2043
{
2044
assert (!s->count);
2045
assert (!s->ldsize);
2046
NEWN (s->start, 1);
2047
}
2048
else
2049
{
2050
oldsize = (1 << (s->ldsize));
2051
assert (s->count <= oldsize);
2052
if (s->count == oldsize)
2053
{
2054
newsize = 2 * oldsize;
2055
RESIZEN (s->start, oldsize, newsize);
2056
s->ldsize++;
2057
}
2058
}
2059
2060
s->start[s->count++] = c->lits[pos];
2061
}
2062
2063
#endif
2064
2065
static void
2066
connect_head_tail (PS * ps, Lit * lit, Cls * c)
2067
{
2068
Cls ** s;
2069
assert (c->size >= 1);
2070
if (c->size == 2)
2071
{
2072
#ifdef NO_BINARY_CLAUSES
2073
lpush (ps, lit, c);
2074
return;
2075
#else
2076
s = LIT2IMPLS (lit);
2077
#endif
2078
}
2079
else
2080
s = LIT2HTPS (lit);
2081
2082
if (c->lits[0] != lit)
2083
{
2084
assert (c->size >= 2);
2085
assert (c->lits[1] == lit);
2086
c->next[1] = *s;
2087
}
2088
else
2089
c->next[0] = *s;
2090
2091
*s = c;
2092
}
2093
2094
#ifdef TRACE
2095
static void
2096
zpush (PS * ps, Zhn * zhain)
2097
{
2098
assert (ps->trace);
2099
2100
if (ps->zhead == ps->eoz)
2101
ENLARGE (ps->zhains, ps->zhead, ps->eoz);
2102
2103
*ps->zhead++ = zhain;
2104
}
2105
2106
static int
2107
cmp_resolved (PS * ps, Cls * c, Cls * d)
2108
{
2109
#ifndef NDEBUG
2110
assert (ps->trace);
2111
#else
2112
(void) ps;
2113
#endif
2114
return CLS2IDX (c) - CLS2IDX (d);
2115
}
2116
2117
static void
2118
bpushc (PS * ps, unsigned char ch)
2119
{
2120
if (ps->bhead == ps->eob)
2121
ENLARGE (ps->buffer, ps->bhead, ps->eob);
2122
2123
*ps->bhead++ = ch;
2124
}
2125
2126
static void
2127
bpushu (PS * ps, unsigned u)
2128
{
2129
while (u & ~0x7f)
2130
{
2131
bpushc (ps, u | 0x80);
2132
u >>= 7;
2133
}
2134
2135
bpushc (ps, u);
2136
}
2137
2138
static void
2139
bpushd (PS * ps, unsigned prev, unsigned this)
2140
{
2141
unsigned delta;
2142
assert (prev < this);
2143
delta = this - prev;
2144
bpushu (ps, delta);
2145
}
2146
2147
static void
2148
add_zhain (PS * ps)
2149
{
2150
unsigned prev, this, count, rcount;
2151
Cls **p, *c;
2152
Zhn *res;
2153
2154
assert (ps->trace);
2155
assert (ps->bhead == ps->buffer);
2156
assert (ps->rhead > ps->resolved);
2157
2158
rcount = ps->rhead - ps->resolved;
2159
SORT (Cls *, cmp_resolved, ps->resolved, rcount);
2160
2161
prev = 0;
2162
for (p = ps->resolved; p < ps->rhead; p++)
2163
{
2164
c = *p;
2165
this = CLS2TRD (c)->idx;
2166
bpushd (ps, prev, this);
2167
prev = this;
2168
}
2169
bpushc (ps, 0);
2170
2171
count = ps->bhead - ps->buffer;
2172
2173
res = new (ps, sizeof (Zhn) + count);
2174
res->core = 0;
2175
res->ref = 0;
2176
memcpy (res->znt, ps->buffer, count);
2177
2178
ps->bhead = ps->buffer;
2179
#ifdef STATS
2180
ps->znts += count - 1;
2181
#endif
2182
zpush (ps, res);
2183
}
2184
2185
#endif
2186
2187
static void
2188
add_resolved (PS * ps, int learned)
2189
{
2190
#if defined(STATS) || defined(TRACE)
2191
Cls **p, *c;
2192
2193
for (p = ps->resolved; p < ps->rhead; p++)
2194
{
2195
c = *p;
2196
if (c->used)
2197
continue;
2198
2199
c->used = 1;
2200
2201
if (c->size <= 2)
2202
continue;
2203
2204
#ifdef STATS
2205
if (c->learned)
2206
ps->llused++;
2207
else
2208
ps->loused++;
2209
#endif
2210
}
2211
#endif
2212
2213
#ifdef TRACE
2214
if (learned && ps->trace)
2215
add_zhain (ps);
2216
#else
2217
(void) learned;
2218
#endif
2219
ps->rhead = ps->resolved;
2220
}
2221
2222
static void
2223
incjwh (PS * ps, Cls * c)
2224
{
2225
Lit **p, *lit, ** eol;
2226
Flt * f, inc, sum;
2227
unsigned size = 0;
2228
Var * v;
2229
Val val;
2230
2231
eol = end_of_lits (c);
2232
2233
for (p = c->lits; p < eol; p++)
2234
{
2235
lit = *p;
2236
val = lit->val;
2237
2238
if (val && ps->LEVEL > 0)
2239
{
2240
v = LIT2VAR (lit);
2241
if (v->level > 0)
2242
val = UNDEF;
2243
}
2244
2245
if (val == TRUE)
2246
return;
2247
2248
if (val != FALSE)
2249
size++;
2250
}
2251
2252
inc = base2flt (1, -size);
2253
2254
for (p = c->lits; p < eol; p++)
2255
{
2256
lit = *p;
2257
f = LIT2JWH (lit);
2258
sum = addflt (*f, inc);
2259
*f = sum;
2260
}
2261
}
2262
2263
static void
2264
write_rup_header (PS * ps, FILE * file)
2265
{
2266
char line[80];
2267
int i;
2268
2269
sprintf (line, "%%RUPD32 %u %u", ps->rupvariables, ps->rupclauses);
2270
2271
fputs (line, file);
2272
for (i = 255 - strlen (line); i >= 0; i--)
2273
fputc (' ', file);
2274
2275
fputc ('\n', file);
2276
fflush (file);
2277
}
2278
2279
static Cls *
2280
add_simplified_clause (PS * ps, int learned)
2281
{
2282
unsigned num_true, num_undef, num_false, size, count_resolved;
2283
Lit **p, **q, *lit, ** end;
2284
unsigned litlevel, glue;
2285
Cls *res, * reason;
2286
int reentered;
2287
Val val;
2288
Var *v;
2289
#if !defined(NDEBUG) && defined(TRACE)
2290
unsigned idx;
2291
#endif
2292
2293
reentered = 0;
2294
2295
REENTER:
2296
2297
size = ps->ahead - ps->added;
2298
2299
add_resolved (ps, learned);
2300
2301
if (learned)
2302
{
2303
ps->ladded++;
2304
ps->llitsadded += size;
2305
if (size > 2)
2306
{
2307
ps->lladded++;
2308
ps->nlclauses++;
2309
ps->llits += size;
2310
}
2311
}
2312
else
2313
{
2314
ps->oadded++;
2315
if (size > 2)
2316
{
2317
ps->loadded++;
2318
ps->noclauses++;
2319
ps->olits += size;
2320
}
2321
}
2322
2323
ps->addedclauses++;
2324
assert (ps->addedclauses == ps->ladded + ps->oadded);
2325
2326
#ifdef NO_BINARY_CLAUSES
2327
if (size == 2)
2328
res = setimpl (ps, ps->added[0], ps->added[1]);
2329
else
2330
#endif
2331
{
2332
sortlits (ps, ps->added, size);
2333
2334
if (learned)
2335
{
2336
if (ps->lhead == ps->EOL)
2337
{
2338
ENLARGE (ps->lclauses, ps->lhead, ps->EOL);
2339
2340
/* A very difficult to find bug, which only occurs if the
2341
* learned clauses stack is immediately allocated before the
2342
* original clauses stack without padding. In this case, we
2343
* have 'SOC == EOC', which terminates all loops using the
2344
* idiom 'for (p = SOC; p != EOC; p = NXC(p))' immediately.
2345
* Unfortunately this occurred in 'fix_clause_lits' after
2346
* using a recent version of the memory allocator of 'Google'
2347
* perftools in the context of one large benchmark for
2348
* our SMT solver 'Boolector'.
2349
*/
2350
if (ps->EOL == ps->oclauses)
2351
ENLARGE (ps->lclauses, ps->lhead, ps->EOL);
2352
}
2353
2354
#if !defined(NDEBUG) && defined(TRACE)
2355
idx = LIDX2IDX (ps->lhead - ps->lclauses);
2356
#endif
2357
}
2358
else
2359
{
2360
if (ps->ohead == ps->eoo)
2361
{
2362
ENLARGE (ps->oclauses, ps->ohead, ps->eoo);
2363
if (ps->EOL == ps->oclauses)
2364
ENLARGE (ps->oclauses, ps->ohead, ps->eoo); /* ditto */
2365
}
2366
2367
#if !defined(NDEBUG) && defined(TRACE)
2368
idx = OIDX2IDX (ps->ohead - ps->oclauses);
2369
#endif
2370
}
2371
2372
assert (ps->EOL != ps->oclauses); /* ditto */
2373
2374
res = new_clause (ps, size, learned);
2375
2376
glue = 0;
2377
2378
if (learned)
2379
{
2380
assert (ps->dusedhead == ps->dused);
2381
2382
for (p = ps->added; p < ps->ahead; p++)
2383
{
2384
lit = *p;
2385
if (lit->val)
2386
{
2387
litlevel = LIT2VAR (lit)->level;
2388
assert (litlevel <= ps->LEVEL);
2389
while (ps->levels + litlevel >= ps->levelshead)
2390
{
2391
if (ps->levelshead >= ps->eolevels)
2392
ENLARGE (ps->levels, ps->levelshead, ps->eolevels);
2393
assert (ps->levelshead < ps->eolevels);
2394
*ps->levelshead++ = 0;
2395
}
2396
if (!ps->levels[litlevel])
2397
{
2398
if (ps->dusedhead >= ps->eodused)
2399
ENLARGE (ps->dused, ps->dusedhead, ps->eodused);
2400
assert (ps->dusedhead < ps->eodused);
2401
*ps->dusedhead++ = litlevel;
2402
ps->levels[litlevel] = 1;
2403
glue++;
2404
}
2405
}
2406
else
2407
glue++;
2408
}
2409
2410
while (ps->dusedhead > ps->dused)
2411
{
2412
litlevel = *--ps->dusedhead;
2413
assert (ps->levels + litlevel < ps->levelshead);
2414
assert (ps->levels[litlevel]);
2415
ps->levels[litlevel] = 0;
2416
}
2417
}
2418
2419
assert (glue <= MAXGLUE);
2420
res->glue = glue;
2421
2422
#if !defined(NDEBUG) && defined(TRACE)
2423
if (ps->trace)
2424
assert (CLS2IDX (res) == idx);
2425
#endif
2426
if (learned)
2427
*ps->lhead++ = res;
2428
else
2429
*ps->ohead++ = res;
2430
2431
#if !defined(NDEBUG) && defined(TRACE)
2432
if (ps->trace && learned)
2433
assert (ps->zhead - ps->zhains == ps->lhead - ps->lclauses);
2434
#endif
2435
assert (ps->lhead != ps->oclauses); /* ditto */
2436
}
2437
2438
if (learned && ps->rup)
2439
{
2440
if (!ps->rupstarted)
2441
{
2442
write_rup_header (ps, ps->rup);
2443
ps->rupstarted = 1;
2444
}
2445
}
2446
2447
num_true = num_undef = num_false = 0;
2448
2449
q = res->lits;
2450
for (p = ps->added; p < ps->ahead; p++)
2451
{
2452
lit = *p;
2453
*q++ = lit;
2454
2455
if (learned && ps->rup)
2456
fprintf (ps->rup, "%d ", LIT2INT (lit));
2457
2458
val = lit->val;
2459
2460
num_true += (val == TRUE);
2461
num_undef += (val == UNDEF);
2462
num_false += (val == FALSE);
2463
}
2464
assert (num_false + num_true + num_undef == size);
2465
2466
if (learned && ps->rup)
2467
fputs ("0\n", ps->rup);
2468
2469
ps->ahead = ps->added; /* reset */
2470
2471
if (!reentered) // TODO merge
2472
if (size > 0)
2473
{
2474
assert (size <= 2 || !reentered); // TODO remove
2475
connect_head_tail (ps, res->lits[0], res);
2476
if (size > 1)
2477
connect_head_tail (ps, res->lits[1], res);
2478
}
2479
2480
if (size == 0)
2481
{
2482
if (!ps->mtcls)
2483
ps->mtcls = res;
2484
}
2485
2486
#ifdef NO_BINARY_CLAUSES
2487
if (size != 2)
2488
#endif
2489
#ifndef NDEBUG
2490
res->connected = 1;
2491
#endif
2492
2493
LOG ( fprintf (ps->out, "%s%s ", ps->prefix, learned ? "learned" : "original");
2494
dumpclsnl (ps, res));
2495
2496
/* Shrink clause by resolving it against top level assignments.
2497
*/
2498
if (!ps->LEVEL && num_false > 0)
2499
{
2500
assert (ps->ahead == ps->added);
2501
assert (ps->rhead == ps->resolved);
2502
2503
count_resolved = 1;
2504
add_antecedent (ps, res);
2505
2506
end = end_of_lits (res);
2507
for (p = res->lits; p < end; p++)
2508
{
2509
lit = *p;
2510
v = LIT2VAR (lit);
2511
use_var (ps, v);
2512
2513
if (lit->val == FALSE)
2514
{
2515
add_antecedent (ps, v->reason);
2516
count_resolved++;
2517
}
2518
else
2519
add_lit (ps, lit);
2520
}
2521
2522
assert (count_resolved >= 2);
2523
2524
learned = 1;
2525
#ifdef NO_BINARY_CLAUSES
2526
if (res == &ps->impl)
2527
resetimpl (ps);
2528
#endif
2529
reentered = 1;
2530
goto REENTER; /* and return simplified clause */
2531
}
2532
2533
if (!num_true && num_undef == 1) /* unit clause */
2534
{
2535
lit = 0;
2536
for (p = res->lits; p < res->lits + size; p++)
2537
{
2538
if ((*p)->val == UNDEF)
2539
lit = *p;
2540
2541
v = LIT2VAR (*p);
2542
use_var (ps, v);
2543
}
2544
assert (lit);
2545
2546
reason = res;
2547
#ifdef NO_BINARY_CLAUSES
2548
if (size == 2)
2549
{
2550
Lit * other = res->lits[0];
2551
if (other == lit)
2552
other = res->lits[1];
2553
2554
assert (other->val == FALSE);
2555
reason = LIT2REASON (NOTLIT (other));
2556
}
2557
#endif
2558
assign_forced (ps, lit, reason);
2559
num_true++;
2560
}
2561
2562
if (num_false == size && !ps->conflict)
2563
{
2564
#ifdef NO_BINARY_CLAUSES
2565
if (res == &ps->impl)
2566
ps->conflict = setcimpl (ps, res->lits[0], res->lits[1]);
2567
else
2568
#endif
2569
ps->conflict = res;
2570
}
2571
2572
if (!learned && !num_true && num_undef)
2573
incjwh (ps, res);
2574
2575
#ifdef NO_BINARY_CLAUSES
2576
if (res == &ps->impl)
2577
resetimpl (ps);
2578
#endif
2579
return res;
2580
}
2581
2582
static int
2583
trivial_clause (PS * ps)
2584
{
2585
Lit **p, **q, *prev;
2586
Var *v;
2587
2588
SORT (Lit *, cmp_ptr, ps->added, ps->ahead - ps->added);
2589
2590
prev = 0;
2591
q = ps->added;
2592
for (p = q; p < ps->ahead; p++)
2593
{
2594
Lit *this = *p;
2595
2596
v = LIT2VAR (this);
2597
2598
if (prev == this) /* skip repeated literals */
2599
continue;
2600
2601
/* Top level satisfied ?
2602
*/
2603
if (this->val == TRUE && !v->level)
2604
return 1;
2605
2606
if (prev == NOTLIT (this))/* found pair of dual literals */
2607
return 1;
2608
2609
*q++ = prev = this;
2610
}
2611
2612
ps->ahead = q; /* shrink */
2613
2614
return 0;
2615
}
2616
2617
static void
2618
simplify_and_add_original_clause (PS * ps)
2619
{
2620
#ifdef NO_BINARY_CLAUSES
2621
Cls * c;
2622
#endif
2623
if (trivial_clause (ps))
2624
{
2625
ps->ahead = ps->added;
2626
2627
if (ps->ohead == ps->eoo)
2628
ENLARGE (ps->oclauses, ps->ohead, ps->eoo);
2629
2630
*ps->ohead++ = 0;
2631
2632
ps->addedclauses++;
2633
ps->oadded++;
2634
}
2635
else
2636
{
2637
if (ps->CLS != ps->clshead)
2638
add_lit (ps, NOTLIT (ps->clshead[-1]));
2639
2640
#ifdef NO_BINARY_CLAUSES
2641
c =
2642
#endif
2643
add_simplified_clause (ps, 0);
2644
#ifdef NO_BINARY_CLAUSES
2645
if (c == &ps->impl) assert (!ps->implvalid);
2646
#endif
2647
}
2648
}
2649
2650
#ifndef NADC
2651
2652
static void
2653
add_ado (PS * ps)
2654
{
2655
unsigned len = ps->ahead - ps->added;
2656
Lit ** ado, ** p, ** q, *lit;
2657
Var * v, * u;
2658
2659
#ifdef TRACE
2660
assert (!ps->trace);
2661
#endif
2662
2663
ABORTIF (ps->ados < ps->hados && llength (ps->ados[0]) != len,
2664
"internal: non matching all different constraint object lengths");
2665
2666
if (ps->hados == ps->eados)
2667
ENLARGE (ps->ados, ps->hados, ps->eados);
2668
2669
NEWN (ado, len + 1);
2670
*ps->hados++ = ado;
2671
2672
p = ps->added;
2673
q = ado;
2674
u = 0;
2675
while (p < ps->ahead)
2676
{
2677
lit = *p++;
2678
v = LIT2VAR (lit);
2679
ABORTIF (v->inado,
2680
"internal: variable in multiple all different objects");
2681
v->inado = ado;
2682
if (!u && !lit->val)
2683
u = v;
2684
*q++ = lit;
2685
}
2686
2687
assert (q == ado + len);
2688
*q++ = 0;
2689
2690
/* TODO simply do a conflict test as in propado */
2691
2692
ABORTIF (!u,
2693
"internal: "
2694
"adding fully instantiated all different object not implemented yet");
2695
2696
assert (u);
2697
assert (u->inado == ado);
2698
assert (!u->ado);
2699
u->ado = ado;
2700
2701
ps->ahead = ps->added;
2702
}
2703
2704
#endif
2705
2706
static void
2707
hdown (PS * ps, Rnk * r)
2708
{
2709
unsigned end, rpos, cpos, opos;
2710
Rnk *child, *other;
2711
2712
assert (r->pos > 0);
2713
assert (ps->heap[r->pos] == r);
2714
2715
end = ps->hhead - ps->heap;
2716
rpos = r->pos;
2717
2718
for (;;)
2719
{
2720
cpos = 2 * rpos;
2721
if (cpos >= end)
2722
break;
2723
2724
opos = cpos + 1;
2725
child = ps->heap[cpos];
2726
2727
if (cmp_rnk (r, child) < 0)
2728
{
2729
if (opos < end)
2730
{
2731
other = ps->heap[opos];
2732
2733
if (cmp_rnk (child, other) < 0)
2734
{
2735
child = other;
2736
cpos = opos;
2737
}
2738
}
2739
}
2740
else if (opos < end)
2741
{
2742
child = ps->heap[opos];
2743
2744
if (cmp_rnk (r, child) >= 0)
2745
break;
2746
2747
cpos = opos;
2748
}
2749
else
2750
break;
2751
2752
ps->heap[rpos] = child;
2753
child->pos = rpos;
2754
rpos = cpos;
2755
}
2756
2757
r->pos = rpos;
2758
ps->heap[rpos] = r;
2759
}
2760
2761
static Rnk *
2762
htop (PS * ps)
2763
{
2764
assert (ps->hhead > ps->heap + 1);
2765
return ps->heap[1];
2766
}
2767
2768
static Rnk *
2769
hpop (PS * ps)
2770
{
2771
Rnk *res, *last;
2772
unsigned end;
2773
2774
assert (ps->hhead > ps->heap + 1);
2775
2776
res = ps->heap[1];
2777
res->pos = 0;
2778
2779
end = --ps->hhead - ps->heap;
2780
if (end == 1)
2781
return res;
2782
2783
last = ps->heap[end];
2784
2785
ps->heap[last->pos = 1] = last;
2786
hdown (ps, last);
2787
2788
return res;
2789
}
2790
2791
inline static void
2792
hpush (PS * ps, Rnk * r)
2793
{
2794
assert (!r->pos);
2795
2796
if (ps->hhead == ps->eoh)
2797
ENLARGE (ps->heap, ps->hhead, ps->eoh);
2798
2799
r->pos = ps->hhead++ - ps->heap;
2800
ps->heap[r->pos] = r;
2801
hup (ps, r);
2802
}
2803
2804
static void
2805
fix_trail_lits (PS * ps, long delta)
2806
{
2807
Lit **p;
2808
for (p = ps->trail; p < ps->thead; p++)
2809
*p += delta;
2810
}
2811
2812
#ifdef NO_BINARY_CLAUSES
2813
static void
2814
fix_impl_lits (PS * ps, long delta)
2815
{
2816
Ltk * s;
2817
Lit ** p;
2818
2819
for (s = ps->impls + 2; s <= ps->impls + 2 * ps->max_var + 1; s++)
2820
for (p = s->start; p < s->start + s->count; p++)
2821
*p += delta;
2822
}
2823
#endif
2824
2825
static void
2826
fix_clause_lits (PS * ps, long delta)
2827
{
2828
Cls **p, *clause;
2829
Lit **q, *lit, **eol;
2830
2831
for (p = SOC; p != EOC; p = NXC (p))
2832
{
2833
clause = *p;
2834
if (!clause)
2835
continue;
2836
2837
q = clause->lits;
2838
eol = end_of_lits (clause);
2839
while (q < eol)
2840
{
2841
assert (q - clause->lits <= (int) clause->size);
2842
lit = *q;
2843
lit += delta;
2844
*q++ = lit;
2845
}
2846
}
2847
}
2848
2849
static void
2850
fix_added_lits (PS * ps, long delta)
2851
{
2852
Lit **p;
2853
for (p = ps->added; p < ps->ahead; p++)
2854
*p += delta;
2855
}
2856
2857
static void
2858
fix_assumed_lits (PS * ps, long delta)
2859
{
2860
Lit **p;
2861
for (p = ps->als; p < ps->alshead; p++)
2862
*p += delta;
2863
}
2864
2865
static void
2866
fix_cls_lits (PS * ps, long delta)
2867
{
2868
Lit **p;
2869
for (p = ps->CLS; p < ps->clshead; p++)
2870
*p += delta;
2871
}
2872
2873
static void
2874
fix_heap_rnks (PS * ps, long delta)
2875
{
2876
Rnk **p;
2877
2878
for (p = ps->heap + 1; p < ps->hhead; p++)
2879
*p += delta;
2880
}
2881
2882
#ifndef NADC
2883
2884
static void
2885
fix_ado (long delta, Lit ** ado)
2886
{
2887
Lit ** p;
2888
for (p = ado; *p; p++)
2889
*p += delta;
2890
}
2891
2892
static void
2893
fix_ados (PS * ps, long delta)
2894
{
2895
Lit *** p;
2896
2897
for (p = ps->ados; p < ps->hados; p++)
2898
fix_ado (delta, *p);
2899
}
2900
2901
#endif
2902
2903
static void
2904
enlarge (PS * ps, unsigned new_size_vars)
2905
{
2906
long rnks_delta, lits_delta;
2907
Lit *old_lits = ps->lits;
2908
Rnk *old_rnks = ps->rnks;
2909
2910
RESIZEN (ps->lits, 2 * ps->size_vars, 2 * new_size_vars);
2911
RESIZEN (ps->jwh, 2 * ps->size_vars, 2 * new_size_vars);
2912
RESIZEN (ps->htps, 2 * ps->size_vars, 2 * new_size_vars);
2913
#ifndef NDSC
2914
RESIZEN (ps->dhtps, 2 * ps->size_vars, 2 * new_size_vars);
2915
#endif
2916
RESIZEN (ps->impls, 2 * ps->size_vars, 2 * new_size_vars);
2917
RESIZEN (ps->vars, ps->size_vars, new_size_vars);
2918
RESIZEN (ps->rnks, ps->size_vars, new_size_vars);
2919
2920
if ((lits_delta = ps->lits - old_lits))
2921
{
2922
fix_trail_lits (ps, lits_delta);
2923
fix_clause_lits (ps, lits_delta);
2924
fix_added_lits (ps, lits_delta);
2925
fix_assumed_lits (ps, lits_delta);
2926
fix_cls_lits (ps, lits_delta);
2927
#ifdef NO_BINARY_CLAUSES
2928
fix_impl_lits (ps, lits_delta);
2929
#endif
2930
#ifndef NADC
2931
fix_ados (ps, lits_delta);
2932
#endif
2933
}
2934
2935
if ((rnks_delta = ps->rnks - old_rnks))
2936
{
2937
fix_heap_rnks (ps, rnks_delta);
2938
}
2939
2940
assert (ps->mhead == ps->marked);
2941
2942
ps->size_vars = new_size_vars;
2943
}
2944
2945
static void
2946
unassign (PS * ps, Lit * lit)
2947
{
2948
Cls *reason;
2949
Var *v;
2950
Rnk *r;
2951
2952
assert (lit->val == TRUE);
2953
2954
LOG ( fprintf (ps->out, "%sunassign %d\n", ps->prefix, LIT2INT (lit)));
2955
2956
v = LIT2VAR (lit);
2957
reason = v->reason;
2958
2959
#ifdef NO_BINARY_CLAUSES
2960
assert (reason != &ps->impl);
2961
if (ISLITREASON (reason))
2962
{
2963
/* DO NOTHING */
2964
}
2965
else
2966
#endif
2967
if (reason)
2968
{
2969
assert (reason->locked);
2970
reason->locked = 0;
2971
if (reason->learned && reason->size > 2)
2972
{
2973
assert (ps->llocked > 0);
2974
ps->llocked--;
2975
}
2976
}
2977
2978
lit->val = UNDEF;
2979
NOTLIT (lit)->val = UNDEF;
2980
2981
r = VAR2RNK (v);
2982
if (!r->pos)
2983
hpush (ps, r);
2984
2985
#ifndef NDSC
2986
{
2987
Cls * p, * next, ** q;
2988
2989
q = LIT2DHTPS (lit);
2990
p = *q;
2991
*q = 0;
2992
2993
while (p)
2994
{
2995
Lit * other = p->lits[0];
2996
2997
if (other == lit)
2998
{
2999
other = p->lits[1];
3000
q = p->next + 1;
3001
}
3002
else
3003
{
3004
assert (p->lits[1] == lit);
3005
q = p->next;
3006
}
3007
3008
next = *q;
3009
*q = *LIT2HTPS (other);
3010
*LIT2HTPS (other) = p;
3011
p = next;
3012
}
3013
}
3014
#endif
3015
3016
#ifndef NADC
3017
if (v->adotabpos)
3018
{
3019
assert (ps->nadotab);
3020
assert (*v->adotabpos == v->ado);
3021
3022
*v->adotabpos = 0;
3023
v->adotabpos = 0;
3024
3025
ps->nadotab--;
3026
}
3027
#endif
3028
}
3029
3030
static Cls *
3031
var2reason (PS * ps, Var * var)
3032
{
3033
Cls * res = var->reason;
3034
#ifdef NO_BINARY_CLAUSES
3035
Lit * this, * other;
3036
if (ISLITREASON (res))
3037
{
3038
this = VAR2LIT (var);
3039
if (this->val == FALSE)
3040
this = NOTLIT (this);
3041
3042
other = REASON2LIT (res);
3043
assert (other->val == TRUE);
3044
assert (this->val == TRUE);
3045
res = setimpl (ps, NOTLIT (other), this);
3046
}
3047
#else
3048
(void) ps;
3049
#endif
3050
return res;
3051
}
3052
3053
static void
3054
mark_clause_to_be_collected (Cls * c)
3055
{
3056
assert (!c->collect);
3057
c->collect = 1;
3058
}
3059
3060
static void
3061
undo (PS * ps, unsigned new_level)
3062
{
3063
Lit *lit;
3064
Var *v;
3065
3066
while (ps->thead > ps->trail)
3067
{
3068
lit = *--ps->thead;
3069
v = LIT2VAR (lit);
3070
if (v->level == new_level)
3071
{
3072
ps->thead++; /* fix pre decrement */
3073
break;
3074
}
3075
3076
unassign (ps, lit);
3077
}
3078
3079
ps->LEVEL = new_level;
3080
ps->ttail = ps->thead;
3081
ps->ttail2 = ps->thead;
3082
#ifndef NADC
3083
ps->ttailado = ps->thead;
3084
#endif
3085
3086
#ifdef NO_BINARY_CLAUSES
3087
if (ps->conflict == &ps->cimpl)
3088
resetcimpl (ps);
3089
#endif
3090
#ifndef NADC
3091
if (ps->conflict && ps->conflict == ps->adoconflict)
3092
resetadoconflict (ps);
3093
#endif
3094
ps->conflict = ps->mtcls;
3095
if (ps->LEVEL < ps->adecidelevel)
3096
{
3097
assert (ps->als < ps->alshead);
3098
ps->adecidelevel = 0;
3099
ps->alstail = ps->als;
3100
}
3101
LOG ( fprintf (ps->out, "%sback to level %u\n", ps->prefix, ps->LEVEL));
3102
}
3103
3104
#ifndef NDEBUG
3105
3106
static int
3107
clause_satisfied (Cls * c)
3108
{
3109
Lit **p, **eol, *lit;
3110
3111
eol = end_of_lits (c);
3112
for (p = c->lits; p < eol; p++)
3113
{
3114
lit = *p;
3115
if (lit->val == TRUE)
3116
return 1;
3117
}
3118
3119
return 0;
3120
}
3121
3122
static void
3123
original_clauses_satisfied (PS * ps)
3124
{
3125
Cls **p, *c;
3126
3127
for (p = ps->oclauses; p < ps->ohead; p++)
3128
{
3129
c = *p;
3130
3131
if (!c)
3132
continue;
3133
3134
if (c->learned)
3135
continue;
3136
3137
assert (clause_satisfied (c));
3138
}
3139
}
3140
3141
static void
3142
assumptions_satisfied (PS * ps)
3143
{
3144
Lit *lit, ** p;
3145
3146
for (p = ps->als; p < ps->alshead; p++)
3147
{
3148
lit = *p;
3149
assert (lit->val == TRUE);
3150
}
3151
}
3152
3153
#endif
3154
3155
static void
3156
sflush (PS * ps)
3157
{
3158
double now = picosat_time_stamp ();
3159
double delta = now - ps->entered;
3160
delta = (delta < 0) ? 0 : delta;
3161
ps->seconds += delta;
3162
ps->entered = now;
3163
}
3164
3165
static double
3166
mb (PS * ps)
3167
{
3168
return ps->current_bytes / (double) (1 << 20);
3169
}
3170
3171
static double
3172
avglevel (PS * ps)
3173
{
3174
return ps->decisions ? ps->levelsum / ps->decisions : 0.0;
3175
}
3176
3177
static void
3178
rheader (PS * ps)
3179
{
3180
assert (ps->lastrheader <= ps->reports);
3181
3182
if (ps->lastrheader == ps->reports)
3183
return;
3184
3185
ps->lastrheader = ps->reports;
3186
3187
fprintf (ps->out, "%s\n", ps->prefix);
3188
fprintf (ps->out, "%s %s\n", ps->prefix, ps->rline[0]);
3189
fprintf (ps->out, "%s %s\n", ps->prefix, ps->rline[1]);
3190
fprintf (ps->out, "%s\n", ps->prefix);
3191
}
3192
3193
static unsigned
3194
dynamic_flips_per_assignment_per_mille (PS * ps)
3195
{
3196
assert (FFLIPPEDPREC >= 1000);
3197
return ps->sdflips / (FFLIPPEDPREC / 1000);
3198
}
3199
3200
#ifdef NLUBY
3201
3202
static int
3203
high_agility (PS * ps)
3204
{
3205
return dynamic_flips_per_assignment_per_mille (ps) >= 200;
3206
}
3207
3208
static int
3209
very_high_agility (PS * ps)
3210
{
3211
return dynamic_flips_per_assignment_per_mille (ps) >= 250;
3212
}
3213
3214
#else
3215
3216
static int
3217
medium_agility (PS * ps)
3218
{
3219
return dynamic_flips_per_assignment_per_mille (ps) >= 230;
3220
}
3221
3222
#endif
3223
3224
static void
3225
relemdata (PS * ps)
3226
{
3227
char *p;
3228
int x;
3229
3230
if (ps->reports < 0)
3231
{
3232
/* strip trailing white space
3233
*/
3234
for (x = 0; x <= 1; x++)
3235
{
3236
p = ps->rline[x] + strlen (ps->rline[x]);
3237
while (p-- > ps->rline[x])
3238
{
3239
if (*p != ' ')
3240
break;
3241
3242
*p = 0;
3243
}
3244
}
3245
3246
rheader (ps);
3247
}
3248
else
3249
fputc ('\n', ps->out);
3250
3251
ps->RCOUNT = 0;
3252
}
3253
3254
static void
3255
relemhead (PS * ps, const char * name, int fp, double val)
3256
{
3257
int x, y, len, size;
3258
const char *fmt;
3259
unsigned tmp, e;
3260
3261
if (ps->reports < 0)
3262
{
3263
x = ps->RCOUNT & 1;
3264
y = (ps->RCOUNT / 2) * 12 + x * 6;
3265
3266
if (ps->RCOUNT == 1)
3267
sprintf (ps->rline[1], "%6s", "");
3268
3269
len = strlen (name);
3270
while (ps->szrline <= len + y + 1)
3271
{
3272
size = ps->szrline ? 2 * ps->szrline : 128;
3273
ps->rline[0] = resize (ps, ps->rline[0], ps->szrline, size);
3274
ps->rline[1] = resize (ps, ps->rline[1], ps->szrline, size);
3275
ps->szrline = size;
3276
}
3277
3278
fmt = (len <= 6) ? "%6s%10s" : "%-10s%4s";
3279
sprintf (ps->rline[x] + y, fmt, name, "");
3280
}
3281
else if (val < 0)
3282
{
3283
assert (fp);
3284
3285
if (val > -100 && (tmp = val * 10.0 - 0.5) > -1000.0)
3286
{
3287
fprintf (ps->out, "-%4.1f ", -tmp / 10.0);
3288
}
3289
else
3290
{
3291
tmp = -val / 10.0 + 0.5;
3292
e = 1;
3293
while (tmp >= 100)
3294
{
3295
tmp /= 10;
3296
e++;
3297
}
3298
3299
fprintf (ps->out, "-%2ue%u ", tmp, e);
3300
}
3301
}
3302
else
3303
{
3304
if (fp && val < 1000 && (tmp = val * 10.0 + 0.5) < 10000)
3305
{
3306
fprintf (ps->out, "%5.1f ", tmp / 10.0);
3307
}
3308
else if (!fp && (tmp = val) < 100000)
3309
{
3310
fprintf (ps->out, "%5u ", tmp);
3311
}
3312
else
3313
{
3314
tmp = val / 10.0 + 0.5;
3315
e = 1;
3316
3317
while (tmp >= 1000)
3318
{
3319
tmp /= 10;
3320
e++;
3321
}
3322
3323
fprintf (ps->out, "%3ue%u ", tmp, e);
3324
}
3325
}
3326
3327
ps->RCOUNT++;
3328
}
3329
3330
inline static void
3331
relem (PS * ps, const char *name, int fp, double val)
3332
{
3333
if (name)
3334
relemhead (ps, name, fp, val);
3335
else
3336
relemdata (ps);
3337
}
3338
3339
static unsigned
3340
reduce_limit_on_lclauses (PS * ps)
3341
{
3342
unsigned res = ps->lreduce;
3343
res += ps->llocked;
3344
return res;
3345
}
3346
3347
static void
3348
report (PS * ps, int replevel, char type)
3349
{
3350
int rounds;
3351
3352
#ifdef RCODE
3353
(void) type;
3354
#endif
3355
3356
if (ps->verbosity < replevel)
3357
return;
3358
3359
sflush (ps);
3360
3361
if (!ps->reports)
3362
ps->reports = -1;
3363
3364
for (rounds = (ps->reports < 0) ? 2 : 1; rounds; rounds--)
3365
{
3366
if (ps->reports >= 0)
3367
fprintf (ps->out, "%s%c ", ps->prefix, type);
3368
3369
relem (ps, "seconds", 1, ps->seconds);
3370
relem (ps, "level", 1, avglevel (ps));
3371
assert (ps->fixed <= ps->max_var);
3372
relem (ps, "variables", 0, ps->max_var - ps->fixed);
3373
relem (ps, "used", 1, PERCENT (ps->vused, ps->max_var));
3374
relem (ps, "original", 0, ps->noclauses);
3375
relem (ps, "conflicts", 0, ps->conflicts);
3376
// relem (ps, "decisions", 0, ps->decisions);
3377
// relem (ps, "conf/dec", 1, PERCENT(ps->conflicts,ps->decisions));
3378
// relem (ps, "limit", 0, reduce_limit_on_lclauses (ps));
3379
relem (ps, "learned", 0, ps->nlclauses);
3380
// relem (ps, "limit", 1, PERCENT (ps->nlclauses, reduce_limit_on_lclauses (ps)));
3381
relem (ps, "limit", 0, ps->lreduce);
3382
#ifdef STATS
3383
relem (ps, "learning", 1, PERCENT (ps->llused, ps->lladded));
3384
#endif
3385
relem (ps, "agility", 1, dynamic_flips_per_assignment_per_mille (ps) / 10.0);
3386
// relem (ps, "original", 0, ps->noclauses);
3387
relem (ps, "MB", 1, mb (ps));
3388
// relem (ps, "lladded", 0, ps->lladded);
3389
// relem (ps, "llused", 0, ps->llused);
3390
3391
relem (ps, 0, 0, 0);
3392
3393
ps->reports++;
3394
}
3395
3396
/* Adapt this to the number of rows in your terminal.
3397
*/
3398
#define ROWS 25
3399
3400
if (ps->reports % (ROWS - 3) == (ROWS - 4))
3401
rheader (ps);
3402
3403
fflush (ps->out);
3404
}
3405
3406
static int
3407
bcp_queue_is_empty (PS * ps)
3408
{
3409
if (ps->ttail != ps->thead)
3410
return 0;
3411
3412
if (ps->ttail2 != ps->thead)
3413
return 0;
3414
3415
#ifndef NADC
3416
if (ps->ttailado != ps->thead)
3417
return 0;
3418
#endif
3419
3420
return 1;
3421
}
3422
3423
static int
3424
satisfied (PS * ps)
3425
{
3426
assert (!ps->mtcls);
3427
assert (!ps->failed_assumption);
3428
if (ps->alstail < ps->alshead)
3429
return 0;
3430
assert (!ps->conflict);
3431
assert (bcp_queue_is_empty (ps));
3432
return (ps->thead == ps->trail && 0 == ps->max_var)
3433
|| (ps->trail && ps->thead == ps->trail + ps->max_var); /* all assigned */
3434
}
3435
3436
static void
3437
vrescore (PS * ps)
3438
{
3439
Rnk *p, *eor = ps->rnks + ps->max_var;
3440
for (p = ps->rnks + 1; p <= eor; p++)
3441
if (p->score != INFFLT)
3442
p->score = mulflt (p->score, ps->ilvinc);
3443
ps->vinc = mulflt (ps->vinc, ps->ilvinc);;
3444
#ifdef VISCORES
3445
ps->nvinc = mulflt (ps->nvinc, ps->lscore);;
3446
#endif
3447
}
3448
3449
static void
3450
inc_score (PS * ps, Var * v)
3451
{
3452
Flt score;
3453
Rnk *r;
3454
3455
#ifndef NFL
3456
if (ps->simplifying)
3457
return;
3458
#endif
3459
3460
if (!v->level)
3461
return;
3462
3463
if (v->internal)
3464
return;
3465
3466
r = VAR2RNK (v);
3467
score = r->score;
3468
3469
assert (score != INFFLT);
3470
3471
score = addflt (score, ps->vinc);
3472
assert (score < INFFLT);
3473
r->score = score;
3474
if (r->pos > 0)
3475
hup (ps, r);
3476
3477
if (score > ps->lscore)
3478
vrescore (ps);
3479
}
3480
3481
static void
3482
inc_activity (PS * ps, Cls * c)
3483
{
3484
Act *p;
3485
3486
if (!c->learned)
3487
return;
3488
3489
if (c->size <= 2)
3490
return;
3491
3492
p = CLS2ACT (c);
3493
*p = addflt (*p, ps->cinc);
3494
}
3495
3496
static unsigned
3497
hashlevel (unsigned l)
3498
{
3499
return 1u << (l & 31);
3500
}
3501
3502
static void
3503
push (PS * ps, Var * v)
3504
{
3505
if (ps->dhead == ps->eod)
3506
ENLARGE (ps->dfs, ps->dhead, ps->eod);
3507
3508
*ps->dhead++ = v;
3509
}
3510
3511
static Var *
3512
pop (PS * ps)
3513
{
3514
assert (ps->dfs < ps->dhead);
3515
return *--ps->dhead;
3516
}
3517
3518
static void
3519
analyze (PS * ps)
3520
{
3521
unsigned open, minlevel, siglevels, l, old, i, orig;
3522
Lit *this, *other, **p, **q, **eol;
3523
Var *v, *u, **m, *start, *uip;
3524
Cls *c;
3525
3526
assert (ps->conflict);
3527
3528
assert (ps->ahead == ps->added);
3529
assert (ps->mhead == ps->marked);
3530
assert (ps->rhead == ps->resolved);
3531
3532
/* First, search for First UIP variable and mark all resolved variables.
3533
* At the same time determine the minimum decision level involved.
3534
* Increase activities of resolved variables.
3535
*/
3536
q = ps->thead;
3537
open = 0;
3538
minlevel = ps->LEVEL;
3539
siglevels = 0;
3540
uip = 0;
3541
3542
c = ps->conflict;
3543
3544
for (;;)
3545
{
3546
add_antecedent (ps, c);
3547
inc_activity (ps, c);
3548
eol = end_of_lits (c);
3549
for (p = c->lits; p < eol; p++)
3550
{
3551
other = *p;
3552
3553
if (other->val == TRUE)
3554
continue;
3555
3556
assert (other->val == FALSE);
3557
3558
u = LIT2VAR (other);
3559
if (u->mark)
3560
continue;
3561
3562
u->mark = 1;
3563
inc_score (ps, u);
3564
use_var (ps, u);
3565
3566
if (u->level == ps->LEVEL)
3567
{
3568
open++;
3569
}
3570
else
3571
{
3572
push_var_as_marked (ps, u);
3573
3574
if (u->level)
3575
{
3576
/* The statistics counter 'nonminimizedllits' sums up the
3577
* number of literals that would be added if only the
3578
* 'first UIP' scheme for learned clauses would be used
3579
* and no clause minimization.
3580
*/
3581
ps->nonminimizedllits++;
3582
3583
if (u->level < minlevel)
3584
minlevel = u->level;
3585
3586
siglevels |= hashlevel (u->level);
3587
}
3588
else
3589
{
3590
assert (!u->level);
3591
assert (u->reason);
3592
}
3593
}
3594
}
3595
3596
do
3597
{
3598
if (q == ps->trail)
3599
{
3600
uip = 0;
3601
goto DONE_FIRST_UIP;
3602
}
3603
3604
this = *--q;
3605
uip = LIT2VAR (this);
3606
}
3607
while (!uip->mark);
3608
3609
uip->mark = 0;
3610
3611
c = var2reason (ps, uip);
3612
#ifdef NO_BINARY_CLAUSES
3613
if (c == &ps->impl)
3614
resetimpl (ps);
3615
#endif
3616
open--;
3617
if ((!open && ps->LEVEL) || !c)
3618
break;
3619
3620
assert (c);
3621
}
3622
3623
DONE_FIRST_UIP:
3624
3625
if (uip)
3626
{
3627
assert (ps->LEVEL);
3628
this = VAR2LIT (uip);
3629
this += (this->val == TRUE);
3630
ps->nonminimizedllits++;
3631
ps->minimizedllits++;
3632
add_lit (ps, this);
3633
#ifdef STATS
3634
if (uip->reason)
3635
ps->uips++;
3636
#endif
3637
}
3638
else
3639
assert (!ps->LEVEL);
3640
3641
/* Second, try to mark more intermediate variables, with the goal to
3642
* minimize the conflict clause. This is a DFS from already marked
3643
* variables backward through the implication graph. It tries to reach
3644
* other marked variables. If the search reaches an unmarked decision
3645
* variable or a variable assigned below the minimum level of variables in
3646
* the first uip learned clause or a level on which no variable has been
3647
* marked, then the variable from which the DFS is started is not
3648
* redundant. Otherwise the start variable is redundant and will
3649
* eventually be removed from the learned clause in step 4. We initially
3650
* implemented BFS, but then profiling revelead that this step is a bottle
3651
* neck for certain incremental applications. After switching to DFS this
3652
* hot spot went away.
3653
*/
3654
orig = ps->mhead - ps->marked;
3655
for (i = 0; i < orig; i++)
3656
{
3657
start = ps->marked[i];
3658
3659
assert (start->mark);
3660
assert (start != uip);
3661
assert (start->level < ps->LEVEL);
3662
3663
if (!start->reason)
3664
continue;
3665
3666
old = ps->mhead - ps->marked;
3667
assert (ps->dhead == ps->dfs);
3668
push (ps, start);
3669
3670
while (ps->dhead > ps->dfs)
3671
{
3672
u = pop (ps);
3673
assert (u->mark);
3674
3675
c = var2reason (ps, u);
3676
#ifdef NO_BINARY_CLAUSES
3677
if (c == &ps->impl)
3678
resetimpl (ps);
3679
#endif
3680
if (!c ||
3681
((l = u->level) &&
3682
(l < minlevel || ((hashlevel (l) & ~siglevels)))))
3683
{
3684
while (ps->mhead > ps->marked + old) /* reset all marked */
3685
(*--ps->mhead)->mark = 0;
3686
3687
ps->dhead = ps->dfs; /* and DFS stack */
3688
break;
3689
}
3690
3691
eol = end_of_lits (c);
3692
for (p = c->lits; p < eol; p++)
3693
{
3694
v = LIT2VAR (*p);
3695
if (v->mark)
3696
continue;
3697
3698
mark_var (ps, v);
3699
push (ps, v);
3700
}
3701
}
3702
}
3703
3704
for (m = ps->marked; m < ps->mhead; m++)
3705
{
3706
v = *m;
3707
3708
assert (v->mark);
3709
assert (!v->resolved);
3710
3711
use_var (ps, v);
3712
3713
c = var2reason (ps, v);
3714
if (!c)
3715
continue;
3716
3717
#ifdef NO_BINARY_CLAUSES
3718
if (c == &ps->impl)
3719
resetimpl (ps);
3720
#endif
3721
eol = end_of_lits (c);
3722
for (p = c->lits; p < eol; p++)
3723
{
3724
other = *p;
3725
3726
u = LIT2VAR (other);
3727
if (!u->level)
3728
continue;
3729
3730
if (!u->mark) /* 'MARKTEST' */
3731
break;
3732
}
3733
3734
if (p != eol)
3735
continue;
3736
3737
add_antecedent (ps, c);
3738
v->resolved = 1;
3739
}
3740
3741
for (m = ps->marked; m < ps->mhead; m++)
3742
{
3743
v = *m;
3744
3745
assert (v->mark);
3746
v->mark = 0;
3747
3748
if (v->resolved)
3749
{
3750
v->resolved = 0;
3751
continue;
3752
}
3753
3754
this = VAR2LIT (v);
3755
if (this->val == TRUE)
3756
this++; /* actually NOTLIT */
3757
3758
add_lit (ps, this);
3759
ps->minimizedllits++;
3760
}
3761
3762
assert (ps->ahead <= ps->eoa);
3763
assert (ps->rhead <= ps->eor);
3764
3765
ps->mhead = ps->marked;
3766
}
3767
3768
static void
3769
fanalyze (PS * ps)
3770
{
3771
Lit ** eol, ** p, * lit;
3772
Cls * c, * reason;
3773
Var * v, * u;
3774
int next;
3775
3776
#ifndef RCODE
3777
double start = picosat_time_stamp ();
3778
#endif
3779
3780
assert (ps->failed_assumption);
3781
assert (ps->failed_assumption->val == FALSE);
3782
3783
v = LIT2VAR (ps->failed_assumption);
3784
reason = var2reason (ps, v);
3785
if (!reason) return;
3786
#ifdef NO_BINARY_CLAUSES
3787
if (reason == &ps->impl)
3788
resetimpl (ps);
3789
#endif
3790
3791
eol = end_of_lits (reason);
3792
for (p = reason->lits; p != eol; p++)
3793
{
3794
lit = *p;
3795
u = LIT2VAR (lit);
3796
if (u == v) continue;
3797
if (u->reason) break;
3798
}
3799
if (p == eol) return;
3800
3801
assert (ps->ahead == ps->added);
3802
assert (ps->mhead == ps->marked);
3803
assert (ps->rhead == ps->resolved);
3804
3805
next = 0;
3806
mark_var (ps, v);
3807
add_lit (ps, NOTLIT (ps->failed_assumption));
3808
3809
do
3810
{
3811
v = ps->marked[next++];
3812
use_var (ps, v);
3813
if (v->reason)
3814
{
3815
reason = var2reason (ps, v);
3816
#ifdef NO_BINARY_CLAUSES
3817
if (reason == &ps->impl)
3818
resetimpl (ps);
3819
#endif
3820
add_antecedent (ps, reason);
3821
eol = end_of_lits (reason);
3822
for (p = reason->lits; p != eol; p++)
3823
{
3824
lit = *p;
3825
u = LIT2VAR (lit);
3826
if (u == v) continue;
3827
if (u->mark) continue;
3828
mark_var (ps, u);
3829
}
3830
}
3831
else
3832
{
3833
lit = VAR2LIT (v);
3834
if (lit->val == TRUE) lit = NOTLIT (lit);
3835
add_lit (ps, lit);
3836
}
3837
}
3838
while (ps->marked + next < ps->mhead);
3839
3840
c = add_simplified_clause (ps, 1);
3841
v = LIT2VAR (ps->failed_assumption);
3842
reason = v->reason;
3843
#ifdef NO_BINARY_CLAUSES
3844
if (!ISLITREASON (reason))
3845
#endif
3846
{
3847
assert (reason->locked);
3848
reason->locked = 0;
3849
if (reason->learned && reason->size > 2)
3850
{
3851
assert (ps->llocked > 0);
3852
ps->llocked--;
3853
}
3854
}
3855
3856
#ifdef NO_BINARY_CLAUSES
3857
if (c == &ps->impl)
3858
{
3859
c = impl2reason (ps, NOTLIT (ps->failed_assumption));
3860
}
3861
else
3862
#endif
3863
{
3864
assert (c->learned);
3865
assert (!c->locked);
3866
c->locked = 1;
3867
if (c->size > 2)
3868
{
3869
ps->llocked++;
3870
assert (ps->llocked > 0);
3871
}
3872
}
3873
3874
v->reason = c;
3875
3876
while (ps->mhead > ps->marked)
3877
(*--ps->mhead)->mark = 0;
3878
3879
if (ps->verbosity)
3880
fprintf (ps->out, "%sfanalyze took %.1f seconds\n",
3881
ps->prefix, picosat_time_stamp () - start);
3882
}
3883
3884
/* Propagate assignment of 'this' to 'FALSE' by visiting all binary clauses in
3885
* which 'this' occurs.
3886
*/
3887
inline static void
3888
prop2 (PS * ps, Lit * this)
3889
{
3890
#ifdef NO_BINARY_CLAUSES
3891
Lit ** l, ** start;
3892
Ltk * lstk;
3893
#else
3894
Cls * c, ** p;
3895
Cls * next;
3896
#endif
3897
Lit * other;
3898
Val tmp;
3899
3900
assert (this->val == FALSE);
3901
3902
#ifdef NO_BINARY_CLAUSES
3903
lstk = LIT2IMPLS (this);
3904
start = lstk->start;
3905
l = start ? start + lstk->count : NULL;
3906
while (l != start)
3907
{
3908
/* The counter 'visits' is the number of clauses that are
3909
* visited during propagations of assignments.
3910
*/
3911
ps->visits++;
3912
#ifdef STATS
3913
ps->bvisits++;
3914
#endif
3915
other = *--l;
3916
tmp = other->val;
3917
3918
if (tmp == TRUE)
3919
{
3920
#ifdef STATS
3921
ps->othertrue++;
3922
ps->othertrue2++;
3923
if (LIT2VAR (other)->level < ps->LEVEL)
3924
ps->othertrue2u++;
3925
#endif
3926
continue;
3927
}
3928
3929
if (tmp != FALSE)
3930
{
3931
assign_forced (ps, other, LIT2REASON (NOTLIT(this)));
3932
continue;
3933
}
3934
3935
if (ps->conflict == &ps->cimpl)
3936
resetcimpl (ps);
3937
ps->conflict = setcimpl (ps, this, other);
3938
}
3939
#else
3940
/* Traverse all binary clauses with 'this'. Head/Tail pointers for binary
3941
* clauses do not have to be modified here.
3942
*/
3943
p = LIT2IMPLS (this);
3944
for (c = *p; c; c = next)
3945
{
3946
ps->visits++;
3947
#ifdef STATS
3948
ps->bvisits++;
3949
#endif
3950
assert (!c->collect);
3951
#ifdef TRACE
3952
assert (!c->collected);
3953
#endif
3954
assert (c->size == 2);
3955
3956
other = c->lits[0];
3957
if (other == this)
3958
{
3959
next = c->next[0];
3960
other = c->lits[1];
3961
}
3962
else
3963
next = c->next[1];
3964
3965
tmp = other->val;
3966
3967
if (tmp == TRUE)
3968
{
3969
#ifdef STATS
3970
ps->othertrue++;
3971
ps->othertrue2++;
3972
if (LIT2VAR (other)->level < ps->LEVEL)
3973
ps->othertrue2u++;
3974
#endif
3975
continue;
3976
}
3977
3978
if (tmp == FALSE)
3979
ps->conflict = c;
3980
else
3981
assign_forced (ps, other, c); /* unit clause */
3982
}
3983
#endif /* !defined(NO_BINARY_CLAUSES) */
3984
}
3985
3986
#ifndef NDSC
3987
static int
3988
should_disconnect_head_tail (PS * ps, Lit * lit)
3989
{
3990
unsigned litlevel;
3991
Var * v;
3992
3993
assert (lit->val == TRUE);
3994
3995
v = LIT2VAR (lit);
3996
litlevel = v->level;
3997
3998
if (!litlevel)
3999
return 1;
4000
4001
#ifndef NFL
4002
if (ps->simplifying)
4003
return 0;
4004
#endif
4005
4006
return litlevel < ps->LEVEL;
4007
}
4008
#endif
4009
4010
inline static void
4011
propl (PS * ps, Lit * this)
4012
{
4013
Lit **l, *other, *prev, *new_lit, **eol;
4014
Cls *next, **htp_ptr, **new_htp_ptr;
4015
Cls *c;
4016
#ifdef STATS
4017
unsigned size;
4018
#endif
4019
4020
htp_ptr = LIT2HTPS (this);
4021
assert (this->val == FALSE);
4022
4023
/* Traverse all non binary clauses with 'this'. Head/Tail pointers are
4024
* updated as well.
4025
*/
4026
for (c = *htp_ptr; c; c = next)
4027
{
4028
ps->visits++;
4029
#ifdef STATS
4030
size = c->size;
4031
assert (size >= 3);
4032
ps->traversals++; /* other is dereferenced at least */
4033
4034
if (size == 3)
4035
ps->tvisits++;
4036
else if (size >= 4)
4037
{
4038
ps->lvisits++;
4039
ps->ltraversals++;
4040
}
4041
#endif
4042
#ifdef TRACE
4043
assert (!c->collected);
4044
#endif
4045
assert (c->size > 0);
4046
4047
other = c->lits[0];
4048
if (other != this)
4049
{
4050
assert (c->size != 1);
4051
c->lits[0] = this;
4052
c->lits[1] = other;
4053
next = c->next[1];
4054
c->next[1] = c->next[0];
4055
c->next[0] = next;
4056
}
4057
else if (c->size == 1) /* With assumptions we need to
4058
* traverse unit clauses as well.
4059
*/
4060
{
4061
assert (!ps->conflict);
4062
ps->conflict = c;
4063
break;
4064
}
4065
else
4066
{
4067
assert (other == this && c->size > 1);
4068
other = c->lits[1];
4069
next = c->next[0];
4070
}
4071
assert (other == c->lits[1]);
4072
assert (this == c->lits[0]);
4073
assert (next == c->next[0]);
4074
assert (!c->collect);
4075
4076
if (other->val == TRUE)
4077
{
4078
#ifdef STATS
4079
ps->othertrue++;
4080
ps->othertruel++;
4081
#endif
4082
#ifndef NDSC
4083
if (should_disconnect_head_tail (ps, other))
4084
{
4085
new_htp_ptr = LIT2DHTPS (other);
4086
c->next[0] = *new_htp_ptr;
4087
*new_htp_ptr = c;
4088
#ifdef STATS
4089
ps->othertruelu++;
4090
#endif
4091
*htp_ptr = next;
4092
continue;
4093
}
4094
#endif
4095
htp_ptr = c->next;
4096
continue;
4097
}
4098
4099
l = c->lits + 1;
4100
eol = (Lit**) c->lits + c->size;
4101
prev = this;
4102
4103
while (++l != eol)
4104
{
4105
#ifdef STATS
4106
if (size >= 3)
4107
{
4108
ps->traversals++;
4109
if (size > 3)
4110
ps->ltraversals++;
4111
}
4112
#endif
4113
new_lit = *l;
4114
*l = prev;
4115
prev = new_lit;
4116
if (new_lit->val != FALSE) break;
4117
}
4118
4119
if (l == eol)
4120
{
4121
while (l > c->lits + 2)
4122
{
4123
new_lit = *--l;
4124
*l = prev;
4125
prev = new_lit;
4126
}
4127
assert (c->lits[0] == this);
4128
4129
assert (other == c->lits[1]);
4130
if (other->val == FALSE) /* found conflict */
4131
{
4132
assert (!ps->conflict);
4133
ps->conflict = c;
4134
return;
4135
}
4136
4137
assign_forced (ps, other, c); /* unit clause */
4138
htp_ptr = c->next;
4139
}
4140
else
4141
{
4142
assert (new_lit->val == TRUE || new_lit->val == UNDEF);
4143
c->lits[0] = new_lit;
4144
// *l = this;
4145
new_htp_ptr = LIT2HTPS (new_lit);
4146
c->next[0] = *new_htp_ptr;
4147
*new_htp_ptr = c;
4148
*htp_ptr = next;
4149
}
4150
}
4151
}
4152
4153
#ifndef NADC
4154
4155
static unsigned primes[] = { 996293, 330643, 753947, 500873 };
4156
4157
#define PRIMES ((sizeof primes)/sizeof *primes)
4158
4159
static unsigned
4160
hash_ado (PS * ps, Lit ** ado, unsigned salt)
4161
{
4162
unsigned i, res, tmp;
4163
Lit ** p, * lit;
4164
4165
assert (salt < PRIMES);
4166
4167
i = salt;
4168
res = 0;
4169
4170
for (p = ado; (lit = *p); p++)
4171
{
4172
assert (lit->val);
4173
4174
tmp = res >> 31;
4175
res <<= 1;
4176
4177
if (lit->val > 0)
4178
res |= 1;
4179
4180
assert (i < PRIMES);
4181
res *= primes[i++];
4182
if (i == PRIMES)
4183
i = 0;
4184
4185
res += tmp;
4186
}
4187
4188
return res & (ps->szadotab - 1);
4189
}
4190
4191
static unsigned
4192
cmp_ado (Lit ** a, Lit ** b)
4193
{
4194
Lit ** p, ** q, * l, * k;
4195
int res;
4196
4197
for (p = a, q = b; (l = *p); p++, q++)
4198
{
4199
k = *q;
4200
assert (k);
4201
if ((res = (l->val - k->val)))
4202
return res;
4203
}
4204
4205
assert (!*q);
4206
4207
return 0;
4208
}
4209
4210
static Lit ***
4211
find_ado (PS * ps, Lit ** ado)
4212
{
4213
Lit *** res, ** other;
4214
unsigned pos, delta;
4215
4216
pos = hash_ado (ps, ado, 0);
4217
assert (pos < ps->szadotab);
4218
res = ps->adotab + pos;
4219
4220
other = *res;
4221
if (!other || !cmp_ado (other, ado))
4222
return res;
4223
4224
delta = hash_ado (ps, ado, 1);
4225
if (!(delta & 1))
4226
delta++;
4227
4228
assert (delta & 1);
4229
assert (delta < ps->szadotab);
4230
4231
for (;;)
4232
{
4233
pos += delta;
4234
if (pos >= ps->szadotab)
4235
pos -= ps->szadotab;
4236
4237
assert (pos < ps->szadotab);
4238
res = ps->adotab + pos;
4239
other = *res;
4240
if (!other || !cmp_ado (other, ado))
4241
return res;
4242
}
4243
}
4244
4245
static void
4246
enlarge_adotab (PS * ps)
4247
{
4248
/* TODO make this generic */
4249
4250
ABORTIF (ps->szadotab,
4251
"internal: all different objects table needs larger initial size");
4252
assert (!ps->nadotab);
4253
ps->szadotab = 10000;
4254
NEWN (ps->adotab, ps->szadotab);
4255
CLRN (ps->adotab, ps->szadotab);
4256
}
4257
4258
static int
4259
propado (PS * ps, Var * v)
4260
{
4261
Lit ** p, ** q, *** adotabpos, **ado, * lit;
4262
Var * u;
4263
4264
if (ps->LEVEL && ps->adodisabled)
4265
return 1;
4266
4267
assert (!ps->conflict);
4268
assert (!ps->adoconflict);
4269
assert (VAR2LIT (v)->val != UNDEF);
4270
assert (!v->adotabpos);
4271
4272
if (!v->ado)
4273
return 1;
4274
4275
assert (v->inado);
4276
4277
for (p = v->ado; (lit = *p); p++)
4278
if (lit->val == UNDEF)
4279
{
4280
u = LIT2VAR (lit);
4281
assert (!u->ado);
4282
u->ado = v->ado;
4283
v->ado = 0;
4284
4285
return 1;
4286
}
4287
4288
if (4 * ps->nadotab >= 3 * ps->szadotab) /* at least 75% filled */
4289
enlarge_adotab (ps);
4290
4291
adotabpos = find_ado (ps, v->ado);
4292
ado = *adotabpos;
4293
4294
if (!ado)
4295
{
4296
ps->nadotab++;
4297
v->adotabpos = adotabpos;
4298
*adotabpos = v->ado;
4299
return 1;
4300
}
4301
4302
assert (ado != v->ado);
4303
4304
ps->adoconflict = new_clause (ps, 2 * llength (ado), 1);
4305
q = ps->adoconflict->lits;
4306
4307
for (p = ado; (lit = *p); p++)
4308
*q++ = lit->val == FALSE ? lit : NOTLIT (lit);
4309
4310
for (p = v->ado; (lit = *p); p++)
4311
*q++ = lit->val == FALSE ? lit : NOTLIT (lit);
4312
4313
assert (q == ENDOFCLS (ps->adoconflict));
4314
ps->conflict = ps->adoconflict;
4315
ps->adoconflicts++;
4316
return 0;
4317
}
4318
4319
#endif
4320
4321
static void
4322
bcp (PS * ps)
4323
{
4324
int props = 0;
4325
assert (!ps->conflict);
4326
4327
if (ps->mtcls)
4328
return;
4329
4330
for (;;)
4331
{
4332
if (ps->ttail2 < ps->thead) /* prioritize implications */
4333
{
4334
props++;
4335
prop2 (ps, NOTLIT (*ps->ttail2++));
4336
}
4337
else if (ps->ttail < ps->thead) /* unit clauses or clauses with length > 2 */
4338
{
4339
if (ps->conflict) break;
4340
propl (ps, NOTLIT (*ps->ttail++));
4341
if (ps->conflict) break;
4342
}
4343
#ifndef NADC
4344
else if (ps->ttailado < ps->thead)
4345
{
4346
if (ps->conflict) break;
4347
propado (ps, LIT2VAR (*ps->ttailado++));
4348
if (ps->conflict) break;
4349
}
4350
#endif
4351
else
4352
break; /* all assignments propagated, so break */
4353
}
4354
4355
ps->propagations += props;
4356
}
4357
4358
static unsigned
4359
drive (PS * ps)
4360
{
4361
unsigned res, vlevel;
4362
Lit **p;
4363
Var *v;
4364
4365
res = 0;
4366
for (p = ps->added; p < ps->ahead; p++)
4367
{
4368
v = LIT2VAR (*p);
4369
vlevel = v->level;
4370
assert (vlevel <= ps->LEVEL);
4371
if (vlevel < ps->LEVEL && vlevel > res)
4372
res = vlevel;
4373
}
4374
4375
return res;
4376
}
4377
4378
#ifdef VISCORES
4379
4380
static void
4381
viscores (PS * ps)
4382
{
4383
Rnk *p, *eor = ps->rnks + ps->max_var;
4384
char name[100], cmd[200];
4385
FILE * data;
4386
Flt s;
4387
int i;
4388
4389
for (p = ps->rnks + 1; p <= ps->eor; p++)
4390
{
4391
s = p->score;
4392
if (s == INFFLT)
4393
continue;
4394
s = mulflt (s, ps->nvinc);
4395
assert (flt2double (s) <= 1.0);
4396
}
4397
4398
sprintf (name, "/tmp/picosat-viscores/data/%08u", ps->conflicts);
4399
sprintf (cmd, "sort -n|nl>%s", name);
4400
4401
data = popen (cmd, "w");
4402
for (p = ps->rnks + 1; p <= ps->eor; p++)
4403
{
4404
s = p->score;
4405
if (s == INFFLT)
4406
continue;
4407
s = mulflt (s, ps->nvinc);
4408
fprintf (data, "%lf %d\n", 100.0 * flt2double (s), (int)(p - ps->rnks));
4409
}
4410
fflush (data);
4411
pclose (data);
4412
4413
for (i = 0; i < 8; i++)
4414
{
4415
sprintf (cmd, "awk '$3%%8==%d' %s>%s.%d", i, name, name, i);
4416
system (cmd);
4417
}
4418
4419
fprintf (ps->fviscores, "set title \"%u\"\n", ps->conflicts);
4420
fprintf (ps->fviscores, "plot [0:%u] 0, 100 * (1 - 1/1.1), 100", ps->max_var);
4421
4422
for (i = 0; i < 8; i++)
4423
fprintf (ps->fviscores,
4424
", \"%s.%d\" using 1:2:3 with labels tc lt %d",
4425
name, i, i + 1);
4426
4427
fputc ('\n', ps->fviscores);
4428
fflush (ps->fviscores);
4429
#ifndef WRITEGIF
4430
usleep (50000); /* refresh rate of 20 Hz */
4431
#endif
4432
}
4433
4434
#endif
4435
4436
static void
4437
crescore (PS * ps)
4438
{
4439
Cls **p, *c;
4440
Act *a;
4441
Flt factor;
4442
int l = log2flt (ps->cinc);
4443
assert (l > 0);
4444
factor = base2flt (1, -l);
4445
4446
for (p = ps->lclauses; p != ps->lhead; p++)
4447
{
4448
c = *p;
4449
4450
if (!c)
4451
continue;
4452
4453
#ifdef TRACE
4454
if (c->collected)
4455
continue;
4456
#endif
4457
assert (c->learned);
4458
4459
if (c->size <= 2)
4460
continue;
4461
4462
a = CLS2ACT (c);
4463
*a = mulflt (*a, factor);
4464
}
4465
4466
ps->cinc = mulflt (ps->cinc, factor);
4467
}
4468
4469
static void
4470
inc_vinc (PS * ps)
4471
{
4472
#ifdef VISCORES
4473
ps->nvinc = mulflt (ps->nvinc, ps->fvinc);
4474
#endif
4475
ps->vinc = mulflt (ps->vinc, ps->ifvinc);
4476
}
4477
4478
inline static void
4479
inc_max_var (PS * ps)
4480
{
4481
Lit *lit;
4482
Rnk *r;
4483
Var *v;
4484
4485
assert (ps->max_var < ps->size_vars);
4486
4487
if (ps->max_var + 1 == ps->size_vars)
4488
enlarge (ps, ps->size_vars + 2*(ps->size_vars + 3) / 4); /* +25% */
4489
4490
ps->max_var++; /* new index of variable */
4491
assert (ps->max_var); /* no unsigned overflow */
4492
4493
assert (ps->max_var < ps->size_vars);
4494
4495
lit = ps->lits + 2 * ps->max_var;
4496
lit[0].val = lit[1].val = UNDEF;
4497
4498
memset (ps->htps + 2 * ps->max_var, 0, 2 * sizeof *ps->htps);
4499
#ifndef NDSC
4500
memset (ps->dhtps + 2 * ps->max_var, 0, 2 * sizeof *ps->dhtps);
4501
#endif
4502
memset (ps->impls + 2 * ps->max_var, 0, 2 * sizeof *ps->impls);
4503
memset (ps->jwh + 2 * ps->max_var, 0, 2 * sizeof *ps->jwh);
4504
4505
v = ps->vars + ps->max_var; /* initialize variable components */
4506
CLR (v);
4507
4508
r = ps->rnks + ps->max_var; /* initialize rank */
4509
CLR (r);
4510
4511
hpush (ps, r);
4512
}
4513
4514
static void
4515
force (PS * ps, Cls * c)
4516
{
4517
Lit ** p, ** eol, * lit, * forced;
4518
Cls * reason;
4519
4520
forced = 0;
4521
reason = c;
4522
4523
eol = end_of_lits (c);
4524
for (p = c->lits; p < eol; p++)
4525
{
4526
lit = *p;
4527
if (lit->val == UNDEF)
4528
{
4529
assert (!forced);
4530
forced = lit;
4531
#ifdef NO_BINARY_CLAUSES
4532
if (c == &ps->impl)
4533
reason = LIT2REASON (NOTLIT (p[p == c->lits ? 1 : -1]));
4534
#endif
4535
}
4536
else
4537
assert (lit->val == FALSE);
4538
}
4539
4540
#ifdef NO_BINARY_CLAUSES
4541
if (c == &ps->impl)
4542
resetimpl (ps);
4543
#endif
4544
if (!forced)
4545
return;
4546
4547
assign_forced (ps, forced, reason);
4548
}
4549
4550
static void
4551
inc_lreduce (PS * ps)
4552
{
4553
#ifdef STATS
4554
ps->inclreduces++;
4555
#endif
4556
ps->lreduce *= FREDUCE;
4557
ps->lreduce /= 100;
4558
report (ps, 1, '+');
4559
}
4560
4561
static void
4562
backtrack (PS * ps)
4563
{
4564
unsigned new_level;
4565
Cls * c;
4566
4567
ps->conflicts++;
4568
LOG ( fprintf (ps->out, "%sconflict ", ps->prefix); dumpclsnl (ps, ps->conflict));
4569
4570
analyze (ps);
4571
new_level = drive (ps);
4572
// TODO: why not? assert (new_level != 1 || (ps->ahead - ps->added) == 2);
4573
c = add_simplified_clause (ps, 1);
4574
undo (ps, new_level);
4575
force (ps, c);
4576
4577
if (
4578
#ifndef NFL
4579
!ps->simplifying &&
4580
#endif
4581
!--ps->lreduceadjustcnt)
4582
{
4583
/* With FREDUCE==110 and FREDADJ=121 we stir 'lreduce' to be
4584
* proportional to 'sqrt(conflicts)'. In earlier version we actually
4585
* used 'FREDADJ=150', which results in 'lreduce' to approximate
4586
* 'conflicts^(log(1.1)/log(1.5))' which is close to the fourth root
4587
* of 'conflicts', since log(1.1)/log(1.5)=0.235 (as observed by
4588
* Donald Knuth). The square root is the same we get by a Glucose
4589
* style increase, which simply adds a constant at every reduction.
4590
* This would be way simpler to implement but for now we keep the more
4591
* complicated code using the adjust increments and counters.
4592
*/
4593
ps->lreduceadjustinc *= FREDADJ; ps->lreduceadjustinc /= 100; ps->lreduceadjustcnt
4594
= ps->lreduceadjustinc;
4595
inc_lreduce (ps);
4596
}
4597
4598
if (ps->verbosity >= 4 && !(ps->conflicts % 1000))
4599
report (ps, 4, 'C');
4600
}
4601
4602
static void
4603
inc_cinc (PS * ps)
4604
{
4605
ps->cinc = mulflt (ps->cinc, ps->fcinc);
4606
if (ps->lcinc < ps->cinc)
4607
crescore (ps);
4608
}
4609
4610
static void
4611
incincs (PS * ps)
4612
{
4613
inc_vinc (ps);
4614
inc_cinc (ps);
4615
#ifdef VISCORES
4616
viscores (ps);
4617
#endif
4618
}
4619
4620
static void
4621
disconnect_clause (PS * ps, Cls * c)
4622
{
4623
assert (c->connected);
4624
4625
if (c->size > 2)
4626
{
4627
if (c->learned)
4628
{
4629
assert (ps->nlclauses > 0);
4630
ps->nlclauses--;
4631
4632
assert (ps->llits >= c->size);
4633
ps->llits -= c->size;
4634
}
4635
else
4636
{
4637
assert (ps->noclauses > 0);
4638
ps->noclauses--;
4639
4640
assert (ps->olits >= c->size);
4641
ps->olits -= c->size;
4642
}
4643
}
4644
4645
#ifndef NDEBUG
4646
c->connected = 0;
4647
#endif
4648
}
4649
4650
static int
4651
clause_is_toplevel_satisfied (PS * ps, Cls * c)
4652
{
4653
Lit *lit, **p, **eol = end_of_lits (c);
4654
Var *v;
4655
4656
for (p = c->lits; p < eol; p++)
4657
{
4658
lit = *p;
4659
if (lit->val == TRUE)
4660
{
4661
v = LIT2VAR (lit);
4662
if (!v->level)
4663
return 1;
4664
}
4665
}
4666
4667
return 0;
4668
}
4669
4670
static int
4671
collect_clause (PS * ps, Cls * c)
4672
{
4673
assert (c->collect);
4674
c->collect = 0;
4675
4676
#ifdef TRACE
4677
assert (!c->collected);
4678
c->collected = 1;
4679
#endif
4680
disconnect_clause (ps, c);
4681
4682
#ifdef TRACE
4683
if (ps->trace && (!c->learned || c->used))
4684
return 0;
4685
#endif
4686
delete_clause (ps, c);
4687
4688
return 1;
4689
}
4690
4691
static size_t
4692
collect_clauses (PS * ps)
4693
{
4694
Cls *c, **p, **q, * next;
4695
Lit * lit, * eol;
4696
size_t res;
4697
int i;
4698
4699
res = ps->current_bytes;
4700
4701
eol = ps->lits + 2 * ps->max_var + 1;
4702
for (lit = ps->lits + 2; lit <= eol; lit++)
4703
{
4704
for (i = 0; i <= 1; i++)
4705
{
4706
if (i)
4707
{
4708
#ifdef NO_BINARY_CLAUSES
4709
Ltk * lstk = LIT2IMPLS (lit);
4710
Lit ** r, ** s;
4711
r = lstk->start;
4712
if (lit->val != TRUE || LIT2VAR (lit)->level)
4713
for (s = r; lstk->start && s < lstk->start + lstk->count; s++)
4714
{
4715
Lit * other = *s;
4716
Var *v = LIT2VAR (other);
4717
if (v->level ||
4718
other->val != TRUE)
4719
*r++ = other;
4720
}
4721
lstk->count = r - lstk->start;
4722
continue;
4723
#else
4724
p = LIT2IMPLS (lit);
4725
#endif
4726
}
4727
else
4728
p = LIT2HTPS (lit);
4729
4730
for (c = *p; c; c = next)
4731
{
4732
q = c->next;
4733
if (c->lits[0] != lit)
4734
q++;
4735
4736
next = *q;
4737
if (c->collect)
4738
*p = next;
4739
else
4740
p = q;
4741
}
4742
}
4743
}
4744
4745
#ifndef NDSC
4746
for (lit = ps->lits + 2; lit <= eol; lit++)
4747
{
4748
p = LIT2DHTPS (lit);
4749
while ((c = *p))
4750
{
4751
Lit * other = c->lits[0];
4752
if (other == lit)
4753
{
4754
q = c->next + 1;
4755
}
4756
else
4757
{
4758
assert (c->lits[1] == lit);
4759
q = c->next;
4760
}
4761
4762
if (c->collect)
4763
*p = *q;
4764
else
4765
p = q;
4766
}
4767
}
4768
#endif
4769
4770
for (p = SOC; p != EOC; p = NXC (p))
4771
{
4772
c = *p;
4773
4774
if (!c)
4775
continue;
4776
4777
if (!c->collect)
4778
continue;
4779
4780
if (collect_clause (ps, c))
4781
*p = 0;
4782
}
4783
4784
#ifdef TRACE
4785
if (!ps->trace)
4786
#endif
4787
{
4788
q = ps->oclauses;
4789
for (p = q; p < ps->ohead; p++)
4790
if ((c = *p))
4791
*q++ = c;
4792
ps->ohead = q;
4793
4794
q = ps->lclauses;
4795
for (p = q; p < ps->lhead; p++)
4796
if ((c = *p))
4797
*q++ = c;
4798
ps->lhead = q;
4799
}
4800
4801
assert (ps->current_bytes <= res);
4802
res -= ps->current_bytes;
4803
ps->recycled += res;
4804
4805
LOG ( fprintf (ps->out, "%scollected %ld bytes\n", ps->prefix, (long)res));
4806
4807
return res;
4808
}
4809
4810
static int
4811
need_to_reduce (PS * ps)
4812
{
4813
return ps->nlclauses >= reduce_limit_on_lclauses (ps);
4814
}
4815
4816
#ifdef NLUBY
4817
4818
static void
4819
inc_drestart (PS * ps)
4820
{
4821
ps->drestart *= FRESTART;
4822
ps->drestart /= 100;
4823
4824
if (ps->drestart >= MAXRESTART)
4825
ps->drestart = MAXRESTART;
4826
}
4827
4828
static void
4829
inc_ddrestart (PS * ps)
4830
{
4831
ps->ddrestart *= FRESTART;
4832
ps->ddrestart /= 100;
4833
4834
if (ps->ddrestart >= MAXRESTART)
4835
ps->ddrestart = MAXRESTART;
4836
}
4837
4838
#else
4839
4840
static unsigned
4841
luby (unsigned i)
4842
{
4843
unsigned k;
4844
for (k = 1; k < 32; k++)
4845
if (i == (1u << k) - 1)
4846
return 1u << (k - 1);
4847
4848
for (k = 1;; k++)
4849
if ((1u << (k - 1)) <= i && i < (1u << k) - 1)
4850
return luby (i - (1u << (k-1)) + 1);
4851
}
4852
4853
#endif
4854
4855
#ifndef NLUBY
4856
static void
4857
inc_lrestart (PS * ps, int skip)
4858
{
4859
unsigned delta;
4860
4861
delta = 100 * luby (++ps->lubycnt);
4862
ps->lrestart = ps->conflicts + delta;
4863
4864
if (ps->waslubymaxdelta)
4865
report (ps, 1, skip ? 'N' : 'R');
4866
else
4867
report (ps, 2, skip ? 'n' : 'r');
4868
4869
if (delta > ps->lubymaxdelta)
4870
{
4871
ps->lubymaxdelta = delta;
4872
ps->waslubymaxdelta = 1;
4873
}
4874
else
4875
ps->waslubymaxdelta = 0;
4876
}
4877
#endif
4878
4879
static void
4880
init_restart (PS * ps)
4881
{
4882
#ifdef NLUBY
4883
/* TODO: why is it better in incremental usage to have smaller initial
4884
* outer restart interval?
4885
*/
4886
ps->ddrestart = ps->calls > 1 ? MINRESTART : 1000;
4887
ps->drestart = MINRESTART;
4888
ps->lrestart = ps->conflicts + ps->drestart;
4889
#else
4890
ps->lubycnt = 0;
4891
ps->lubymaxdelta = 0;
4892
ps->waslubymaxdelta = 0;
4893
inc_lrestart (ps, 0);
4894
#endif
4895
}
4896
4897
static void
4898
restart (PS * ps)
4899
{
4900
int skip;
4901
#ifdef NLUBY
4902
char kind;
4903
int outer;
4904
4905
inc_drestart (ps);
4906
outer = (ps->drestart >= ps->ddrestart);
4907
4908
if (outer)
4909
skip = very_high_agility (ps);
4910
else
4911
skip = high_agility (ps);
4912
#else
4913
skip = medium_agility (ps);
4914
#endif
4915
4916
#ifdef STATS
4917
if (skip)
4918
ps->skippedrestarts++;
4919
#endif
4920
4921
assert (ps->conflicts >= ps->lrestart);
4922
4923
if (!skip)
4924
{
4925
ps->restarts++;
4926
assert (ps->LEVEL > 1);
4927
LOG ( fprintf (ps->out, "%srestart %u\n", ps->prefix, ps->restarts));
4928
undo (ps, 0);
4929
}
4930
4931
#ifdef NLUBY
4932
if (outer)
4933
{
4934
kind = skip ? 'N' : 'R';
4935
inc_ddrestart (ps);
4936
ps->drestart = MINRESTART;
4937
}
4938
else if (skip)
4939
{
4940
kind = 'n';
4941
}
4942
else
4943
{
4944
kind = 'r';
4945
}
4946
4947
assert (ps->drestart <= MAXRESTART);
4948
ps->lrestart = ps->conflicts + ps->drestart;
4949
assert (ps->lrestart > ps->conflicts);
4950
4951
report (outer ? 1 : 2, kind);
4952
#else
4953
inc_lrestart (ps, skip);
4954
#endif
4955
}
4956
4957
inline static void
4958
assign_decision (PS * ps, Lit * lit)
4959
{
4960
assert (!ps->conflict);
4961
4962
ps->LEVEL++;
4963
4964
LOG ( fprintf (ps->out, "%snew level %u\n", ps->prefix, ps->LEVEL));
4965
LOG ( fprintf (ps->out,
4966
"%sassign %d at level %d <= DECISION\n",
4967
ps->prefix, LIT2INT (lit), ps->LEVEL));
4968
4969
assign (ps, lit, 0);
4970
}
4971
4972
#ifndef NFL
4973
4974
static int
4975
lit_has_binary_clauses (PS * ps, Lit * lit)
4976
{
4977
#ifdef NO_BINARY_CLAUSES
4978
Ltk* lstk = LIT2IMPLS (lit);
4979
return lstk->count != 0;
4980
#else
4981
return *LIT2IMPLS (lit) != 0;
4982
#endif
4983
}
4984
4985
static void
4986
flbcp (PS * ps)
4987
{
4988
#ifdef STATS
4989
unsigned long long propagaions_before_bcp = ps->propagations;
4990
#endif
4991
bcp (ps);
4992
#ifdef STATS
4993
ps->flprops += ps->propagations - propagaions_before_bcp;
4994
#endif
4995
}
4996
4997
inline static int
4998
cmp_inverse_rnk (PS * ps, Rnk * a, Rnk * b)
4999
{
5000
(void) ps;
5001
return -cmp_rnk (a, b);
5002
}
5003
5004
inline static Flt
5005
rnk2jwh (PS * ps, Rnk * r)
5006
{
5007
Flt res, sum, pjwh, njwh;
5008
Lit * plit, * nlit;
5009
5010
plit = RNK2LIT (r);
5011
nlit = plit + 1;
5012
5013
pjwh = *LIT2JWH (plit);
5014
njwh = *LIT2JWH (nlit);
5015
5016
res = mulflt (pjwh, njwh);
5017
5018
sum = addflt (pjwh, njwh);
5019
sum = mulflt (sum, base2flt (1, -10));
5020
res = addflt (res, sum);
5021
5022
return res;
5023
}
5024
5025
static int
5026
cmp_inverse_jwh_rnk (PS * ps, Rnk * r, Rnk * s)
5027
{
5028
Flt a = rnk2jwh (ps, r);
5029
Flt b = rnk2jwh (ps, s);
5030
int res = cmpflt (a, b);
5031
5032
if (res)
5033
return -res;
5034
5035
return cmp_inverse_rnk (ps, r, s);
5036
}
5037
5038
static void
5039
faillits (PS * ps)
5040
{
5041
unsigned i, j, old_trail_count, common, saved_count;
5042
unsigned new_saved_size, oldladded = ps->ladded;
5043
unsigned long long limit, delta;
5044
Lit * lit, * other, * pivot;
5045
Rnk * r, ** p, ** q;
5046
int new_trail_count;
5047
double started;
5048
5049
if (ps->plain)
5050
return;
5051
5052
if (ps->heap + 1 >= ps->hhead)
5053
return;
5054
5055
if (ps->propagations < ps->fllimit)
5056
return;
5057
5058
sflush (ps);
5059
started = ps->seconds;
5060
5061
ps->flcalls++;
5062
#ifdef STATSA
5063
ps->flrounds++;
5064
#endif
5065
delta = ps->propagations/10;
5066
if (delta >= 100*1000*1000) delta = 100*1000*1000;
5067
else if (delta <= 100*1000) delta = 100*1000;
5068
5069
limit = ps->propagations + delta;
5070
ps->fllimit = ps->propagations;
5071
5072
assert (!ps->LEVEL);
5073
assert (ps->simplifying);
5074
5075
if (ps->flcalls <= 1)
5076
SORT (Rnk *, cmp_inverse_jwh_rnk, ps->heap + 1, ps->hhead - (ps->heap + 1));
5077
else
5078
SORT (Rnk *, cmp_inverse_rnk, ps->heap + 1, ps->hhead - (ps->heap + 1));
5079
5080
i = 1; /* NOTE: heap starts at position '1' */
5081
5082
while (ps->propagations < limit)
5083
{
5084
if (ps->heap + i == ps->hhead)
5085
{
5086
if (ps->ladded == oldladded)
5087
break;
5088
5089
i = 1;
5090
#ifdef STATS
5091
ps->flrounds++;
5092
#endif
5093
oldladded = ps->ladded;
5094
}
5095
5096
assert (ps->heap + i < ps->hhead);
5097
5098
r = ps->heap[i++];
5099
lit = RNK2LIT (r);
5100
5101
if (lit->val)
5102
continue;
5103
5104
if (!lit_has_binary_clauses (ps, NOTLIT (lit)))
5105
{
5106
#ifdef STATS
5107
ps->flskipped++;
5108
#endif
5109
continue;
5110
}
5111
5112
#ifdef STATS
5113
ps->fltried++;
5114
#endif
5115
LOG ( fprintf (ps->out, "%strying %d as failed literal\n",
5116
ps->prefix, LIT2INT (lit)));
5117
5118
assign_decision (ps, lit);
5119
old_trail_count = ps->thead - ps->trail;
5120
flbcp (ps);
5121
5122
if (ps->conflict)
5123
{
5124
EXPLICITLY_FAILED_LITERAL:
5125
LOG ( fprintf (ps->out, "%sfound explicitly failed literal %d\n",
5126
ps->prefix, LIT2INT (lit)));
5127
5128
ps->failedlits++;
5129
ps->efailedlits++;
5130
5131
backtrack (ps);
5132
flbcp (ps);
5133
5134
if (!ps->conflict)
5135
continue;
5136
5137
CONTRADICTION:
5138
assert (!ps->LEVEL);
5139
backtrack (ps);
5140
assert (ps->mtcls);
5141
5142
goto RETURN;
5143
}
5144
5145
if (ps->propagations >= limit)
5146
{
5147
undo (ps, 0);
5148
break;
5149
}
5150
5151
lit = NOTLIT (lit);
5152
5153
if (!lit_has_binary_clauses (ps, NOTLIT (lit)))
5154
{
5155
#ifdef STATS
5156
ps->flskipped++;
5157
#endif
5158
undo (ps, 0);
5159
continue;
5160
}
5161
5162
#ifdef STATS
5163
ps->fltried++;
5164
#endif
5165
LOG ( fprintf (ps->out, "%strying %d as failed literals\n",
5166
ps->prefix, LIT2INT (lit)));
5167
5168
new_trail_count = ps->thead - ps->trail;
5169
saved_count = new_trail_count - old_trail_count;
5170
5171
if (saved_count > ps->saved_size)
5172
{
5173
new_saved_size = ps->saved_size ? 2 * ps->saved_size : 1;
5174
while (saved_count > new_saved_size)
5175
new_saved_size *= 2;
5176
5177
RESIZEN (ps->saved, ps->saved_size, new_saved_size);
5178
ps->saved_size = new_saved_size;
5179
}
5180
5181
for (j = 0; j < saved_count; j++)
5182
ps->saved[j] = ps->trail[old_trail_count + j];
5183
5184
undo (ps, 0);
5185
5186
assign_decision (ps, lit);
5187
flbcp (ps);
5188
5189
if (ps->conflict)
5190
goto EXPLICITLY_FAILED_LITERAL;
5191
5192
pivot = (ps->thead - ps->trail <= new_trail_count) ? lit : NOTLIT (lit);
5193
5194
common = 0;
5195
for (j = 0; j < saved_count; j++)
5196
if ((other = ps->saved[j])->val == TRUE)
5197
ps->saved[common++] = other;
5198
5199
undo (ps, 0);
5200
5201
LOG (if (common)
5202
fprintf (ps->out,
5203
"%sfound %d literals implied by %d and %d\n",
5204
ps->prefix, common,
5205
LIT2INT (NOTLIT (lit)), LIT2INT (lit)));
5206
5207
#if 1 // set to zero to disable 'lifting'
5208
for (j = 0;
5209
j < common
5210
/* TODO: For some Velev benchmarks, extracting the common implicit
5211
* failed literals took quite some time. This needs to be fixed by
5212
* a dedicated analyzer. Up to then we bound the number of
5213
* propagations in this loop as well.
5214
*/
5215
&& ps->propagations < limit + delta
5216
; j++)
5217
{
5218
other = ps->saved[j];
5219
5220
if (other->val == TRUE)
5221
continue;
5222
5223
assert (!other->val);
5224
5225
LOG ( fprintf (ps->out,
5226
"%sforcing %d as forced implicitly failed literal\n",
5227
ps->prefix, LIT2INT (other)));
5228
5229
assert (pivot != NOTLIT (other));
5230
assert (pivot != other);
5231
5232
assign_decision (ps, NOTLIT (other));
5233
flbcp (ps);
5234
5235
assert (ps->LEVEL == 1);
5236
5237
if (ps->conflict)
5238
{
5239
backtrack (ps);
5240
assert (!ps->LEVEL);
5241
}
5242
else
5243
{
5244
assign_decision (ps, pivot);
5245
flbcp (ps);
5246
5247
backtrack (ps);
5248
5249
if (ps->LEVEL)
5250
{
5251
assert (ps->LEVEL == 1);
5252
5253
flbcp (ps);
5254
5255
if (ps->conflict)
5256
{
5257
backtrack (ps);
5258
assert (!ps->LEVEL);
5259
}
5260
else
5261
{
5262
assign_decision (ps, NOTLIT (pivot));
5263
flbcp (ps);
5264
backtrack (ps);
5265
5266
if (ps->LEVEL)
5267
{
5268
assert (ps->LEVEL == 1);
5269
flbcp (ps);
5270
5271
if (!ps->conflict)
5272
{
5273
#ifdef STATS
5274
ps->floopsed++;
5275
#endif
5276
undo (ps, 0);
5277
continue;
5278
}
5279
5280
backtrack (ps);
5281
}
5282
5283
assert (!ps->LEVEL);
5284
}
5285
5286
assert (!ps->LEVEL);
5287
}
5288
}
5289
assert (!ps->LEVEL);
5290
flbcp (ps);
5291
5292
ps->failedlits++;
5293
ps->ifailedlits++;
5294
5295
if (ps->conflict)
5296
goto CONTRADICTION;
5297
}
5298
#endif
5299
}
5300
5301
ps->fllimit += 9 * (ps->propagations - ps->fllimit); /* 10% for failed literals */
5302
5303
RETURN:
5304
5305
/* First flush top level assigned literals. Those are prohibited from
5306
* being pushed up the heap during 'faillits' since 'simplifying' is set.
5307
*/
5308
assert (ps->heap < ps->hhead);
5309
for (p = q = ps->heap + 1; p < ps->hhead; p++)
5310
{
5311
r = *p;
5312
lit = RNK2LIT (r);
5313
if (lit->val)
5314
r->pos = 0;
5315
else
5316
*q++ = r;
5317
}
5318
5319
/* Then resort with respect to EVSIDS score and fix positions.
5320
*/
5321
SORT (Rnk *, cmp_inverse_rnk, ps->heap + 1, ps->hhead - (ps->heap + 1));
5322
for (p = ps->heap + 1; p < ps->hhead; p++)
5323
(*p)->pos = p - ps->heap;
5324
5325
sflush (ps);
5326
ps->flseconds += ps->seconds - started;
5327
}
5328
5329
#endif
5330
5331
static void
5332
simplify (PS * ps, int forced)
5333
{
5334
Lit * lit, * notlit, ** t;
5335
unsigned collect, delta;
5336
#ifdef STATS
5337
size_t bytes_collected;
5338
#endif
5339
int * q, ilit;
5340
Cls **p, *c;
5341
Var * v;
5342
5343
#ifndef NDEDBUG
5344
(void) forced;
5345
#endif
5346
5347
assert (!ps->mtcls);
5348
assert (!satisfied (ps));
5349
assert (forced || ps->lsimplify <= ps->propagations);
5350
assert (forced || ps->fsimplify <= ps->fixed);
5351
5352
if (ps->LEVEL)
5353
undo (ps, 0);
5354
#ifndef NFL
5355
ps->simplifying = 1;
5356
faillits (ps);
5357
ps->simplifying = 0;
5358
5359
if (ps->mtcls)
5360
return;
5361
#endif
5362
5363
if (ps->cils != ps->cilshead)
5364
{
5365
assert (ps->ttail == ps->thead);
5366
assert (ps->ttail2 == ps->thead);
5367
ps->ttail = ps->trail;
5368
for (t = ps->trail; t < ps->thead; t++)
5369
{
5370
lit = *t;
5371
v = LIT2VAR (lit);
5372
if (v->internal)
5373
{
5374
assert (LIT2INT (lit) < 0);
5375
assert (lit->val == TRUE);
5376
unassign (ps, lit);
5377
}
5378
else
5379
*ps->ttail++ = lit;
5380
}
5381
ps->ttail2 = ps->thead = ps->ttail;
5382
5383
for (q = ps->cils; q != ps->cilshead; q++)
5384
{
5385
ilit = *q;
5386
assert (0 < ilit && ilit <= (int) ps->max_var);
5387
v = ps->vars + ilit;
5388
assert (v->internal);
5389
v->level = 0;
5390
v->reason = 0;
5391
lit = int2lit (ps, -ilit);
5392
assert (lit->val == UNDEF);
5393
lit->val = TRUE;
5394
notlit = NOTLIT (lit);
5395
assert (notlit->val == UNDEF);
5396
notlit->val = FALSE;
5397
}
5398
}
5399
5400
collect = 0;
5401
for (p = SOC; p != EOC; p = NXC (p))
5402
{
5403
c = *p;
5404
if (!c)
5405
continue;
5406
5407
#ifdef TRACE
5408
if (c->collected)
5409
continue;
5410
#endif
5411
5412
if (c->locked)
5413
continue;
5414
5415
assert (!c->collect);
5416
if (clause_is_toplevel_satisfied (ps, c))
5417
{
5418
mark_clause_to_be_collected (c);
5419
collect++;
5420
}
5421
}
5422
5423
LOG ( fprintf (ps->out, "%scollecting %d clauses\n", ps->prefix, collect));
5424
#ifdef STATS
5425
bytes_collected =
5426
#endif
5427
collect_clauses (ps);
5428
#ifdef STATS
5429
ps->srecycled += bytes_collected;
5430
#endif
5431
5432
if (ps->cils != ps->cilshead)
5433
{
5434
for (q = ps->cils; q != ps->cilshead; q++)
5435
{
5436
ilit = *q;
5437
assert (0 < ilit && ilit <= (int) ps->max_var);
5438
assert (ps->vars[ilit].internal);
5439
if (ps->rilshead == ps->eorils)
5440
ENLARGE (ps->rils, ps->rilshead, ps->eorils);
5441
*ps->rilshead++ = ilit;
5442
lit = int2lit (ps, -ilit);
5443
assert (lit->val == TRUE);
5444
lit->val = UNDEF;
5445
notlit = NOTLIT (lit);
5446
assert (notlit->val == FALSE);
5447
notlit->val = UNDEF;
5448
}
5449
ps->cilshead = ps->cils;
5450
}
5451
5452
delta = 10 * (ps->olits + ps->llits) + 100000;
5453
if (delta > 2000000)
5454
delta = 2000000;
5455
ps->lsimplify = ps->propagations + delta;
5456
ps->fsimplify = ps->fixed;
5457
ps->simps++;
5458
5459
report (ps, 1, 's');
5460
}
5461
5462
static void
5463
iteration (PS * ps)
5464
{
5465
assert (!ps->LEVEL);
5466
assert (bcp_queue_is_empty (ps));
5467
assert (ps->isimplify < ps->fixed);
5468
5469
ps->iterations++;
5470
report (ps, 2, 'i');
5471
#ifdef NLUBY
5472
ps->drestart = MINRESTART;
5473
ps->lrestart = ps->conflicts + ps->drestart;
5474
#else
5475
init_restart (ps);
5476
#endif
5477
ps->isimplify = ps->fixed;
5478
}
5479
5480
static int
5481
cmp_glue_activity_size (PS * ps, Cls * c, Cls * d)
5482
{
5483
Act a, b, * p, * q;
5484
5485
(void) ps;
5486
5487
assert (c->learned);
5488
assert (d->learned);
5489
5490
if (c->glue < d->glue) // smaller glue preferred
5491
return 1;
5492
5493
if (c->glue > d->glue)
5494
return -1;
5495
5496
p = CLS2ACT (c);
5497
q = CLS2ACT (d);
5498
a = *p;
5499
b = *q;
5500
5501
if (a < b) // then higher activity
5502
return -1;
5503
5504
if (b < a)
5505
return 1;
5506
5507
if (c->size < d->size) // then smaller size
5508
return 1;
5509
5510
if (c->size > d->size)
5511
return -1;
5512
5513
return 0;
5514
}
5515
5516
static void
5517
reduce (PS * ps, unsigned percentage)
5518
{
5519
unsigned redcount, lcollect, collect, target;
5520
#ifdef STATS
5521
size_t bytes_collected;
5522
#endif
5523
Cls **p, *c;
5524
5525
assert (ps->rhead == ps->resolved);
5526
5527
ps->lastreduceconflicts = ps->conflicts;
5528
5529
assert (percentage <= 100);
5530
LOG ( fprintf (ps->out,
5531
"%sreducing %u%% learned clauses\n",
5532
ps->prefix, percentage));
5533
5534
while (ps->nlclauses - ps->llocked > (unsigned)(ps->eor - ps->resolved))
5535
ENLARGE (ps->resolved, ps->rhead, ps->eor);
5536
5537
collect = 0;
5538
lcollect = 0;
5539
5540
for (p = ((ps->fsimplify < ps->fixed) ? SOC : ps->lclauses); p != EOC; p = NXC (p))
5541
{
5542
c = *p;
5543
if (!c)
5544
continue;
5545
5546
#ifdef TRACE
5547
if (c->collected)
5548
continue;
5549
#endif
5550
5551
if (c->locked)
5552
continue;
5553
5554
assert (!c->collect);
5555
if (ps->fsimplify < ps->fixed && clause_is_toplevel_satisfied (ps, c))
5556
{
5557
mark_clause_to_be_collected (c);
5558
collect++;
5559
5560
if (c->learned && c->size > 2)
5561
lcollect++;
5562
5563
continue;
5564
}
5565
5566
if (!c->learned)
5567
continue;
5568
5569
if (c->size <= 2)
5570
continue;
5571
5572
assert (ps->rhead < ps->eor);
5573
*ps->rhead++ = c;
5574
}
5575
assert (ps->rhead <= ps->eor);
5576
5577
ps->fsimplify = ps->fixed;
5578
5579
redcount = ps->rhead - ps->resolved;
5580
SORT (Cls *, cmp_glue_activity_size, ps->resolved, redcount);
5581
5582
assert (ps->nlclauses >= lcollect);
5583
target = ps->nlclauses - lcollect + 1;
5584
5585
target = (percentage * target + 99) / 100;
5586
5587
if (target >= redcount)
5588
target = redcount;
5589
5590
ps->rhead = ps->resolved + target;
5591
while (ps->rhead > ps->resolved)
5592
{
5593
c = *--ps->rhead;
5594
mark_clause_to_be_collected (c);
5595
5596
collect++;
5597
if (c->learned && c->size > 2) /* just for consistency */
5598
lcollect++;
5599
}
5600
5601
if (collect)
5602
{
5603
ps->reductions++;
5604
#ifdef STATS
5605
bytes_collected =
5606
#endif
5607
collect_clauses (ps);
5608
#ifdef STATS
5609
ps->rrecycled += bytes_collected;
5610
#endif
5611
report (ps, 2, '-');
5612
}
5613
5614
if (!lcollect)
5615
inc_lreduce (ps); /* avoid dead lock */
5616
5617
assert (ps->rhead == ps->resolved);
5618
}
5619
5620
static void
5621
init_reduce (PS * ps)
5622
{
5623
// lreduce = loadded / 2;
5624
ps->lreduce = 1000;
5625
5626
if (ps->lreduce < 100)
5627
ps->lreduce = 100;
5628
5629
if (ps->verbosity)
5630
fprintf (ps->out,
5631
"%s\n%sinitial reduction limit %u clauses\n%s\n",
5632
ps->prefix, ps->prefix, ps->lreduce, ps->prefix);
5633
}
5634
5635
static unsigned
5636
rng (PS * ps)
5637
{
5638
unsigned res = ps->srng;
5639
ps->srng *= 1664525u;
5640
ps->srng += 1013904223u;
5641
NOLOG ( fprintf (ps->out, "%srng () = %u\n", ps->prefix, res));
5642
return res;
5643
}
5644
5645
static unsigned
5646
rrng (PS * ps, unsigned low, unsigned high)
5647
{
5648
unsigned long long tmp;
5649
unsigned res, elements;
5650
assert (low <= high);
5651
elements = high - low + 1;
5652
tmp = rng (ps);
5653
tmp *= elements;
5654
tmp >>= 32;
5655
tmp += low;
5656
res = tmp;
5657
NOLOG ( fprintf (ps->out, "%srrng (ps, %u, %u) = %u\n", ps->prefix, low, high, res));
5658
assert (low <= res);
5659
assert (res <= high);
5660
return res;
5661
}
5662
5663
static Lit *
5664
decide_phase (PS * ps, Lit * lit)
5665
{
5666
Lit * not_lit = NOTLIT (lit);
5667
Var *v = LIT2VAR (lit);
5668
5669
assert (LIT2SGN (lit) > 0);
5670
if (v->usedefphase)
5671
{
5672
if (v->defphase)
5673
{
5674
/* assign to TRUE */
5675
}
5676
else
5677
{
5678
/* assign to FALSE */
5679
lit = not_lit;
5680
}
5681
}
5682
else if (!v->assigned)
5683
{
5684
#ifdef STATS
5685
ps->staticphasedecisions++;
5686
#endif
5687
if (ps->defaultphase == POSPHASE)
5688
{
5689
/* assign to TRUE */
5690
}
5691
else if (ps->defaultphase == NEGPHASE)
5692
{
5693
/* assign to FALSE */
5694
lit = not_lit;
5695
}
5696
else if (ps->defaultphase == RNDPHASE)
5697
{
5698
/* randomly assign default phase */
5699
if (rrng (ps, 1, 2) != 2)
5700
lit = not_lit;
5701
}
5702
else if (*LIT2JWH(lit) <= *LIT2JWH (not_lit))
5703
{
5704
/* assign to FALSE (Jeroslow-Wang says there are more short
5705
* clauses with negative occurence of this variable, so satisfy
5706
* those, to minimize BCP)
5707
*/
5708
lit = not_lit;
5709
}
5710
else
5711
{
5712
/* assign to TRUE (... but strictly more positive occurrences) */
5713
}
5714
}
5715
else
5716
{
5717
/* repeat last phase: phase saving heuristic */
5718
5719
if (v->phase)
5720
{
5721
/* assign to TRUE (last phase was TRUE as well) */
5722
}
5723
else
5724
{
5725
/* assign to FALSE (last phase was FALSE as well) */
5726
lit = not_lit;
5727
}
5728
}
5729
5730
return lit;
5731
}
5732
5733
static unsigned
5734
gcd (unsigned a, unsigned b)
5735
{
5736
unsigned tmp;
5737
5738
assert (a);
5739
assert (b);
5740
5741
if (a < b)
5742
{
5743
tmp = a;
5744
a = b;
5745
b = tmp;
5746
}
5747
5748
while (b)
5749
{
5750
assert (a >= b);
5751
tmp = b;
5752
b = a % b;
5753
a = tmp;
5754
}
5755
5756
return a;
5757
}
5758
5759
static Lit *
5760
rdecide (PS * ps)
5761
{
5762
unsigned idx, delta, spread;
5763
Lit * res;
5764
5765
spread = RDECIDE;
5766
if (rrng (ps, 1, spread) != 2)
5767
return 0;
5768
5769
assert (1 <= ps->max_var);
5770
idx = rrng (ps, 1, ps->max_var);
5771
res = int2lit (ps, idx);
5772
5773
if (res->val != UNDEF)
5774
{
5775
delta = rrng (ps, 1, ps->max_var);
5776
while (gcd (delta, ps->max_var) != 1)
5777
delta--;
5778
5779
assert (1 <= delta);
5780
assert (delta <= ps->max_var);
5781
5782
do {
5783
idx += delta;
5784
if (idx > ps->max_var)
5785
idx -= ps->max_var;
5786
res = int2lit (ps, idx);
5787
} while (res->val != UNDEF);
5788
}
5789
5790
#ifdef STATS
5791
ps->rdecisions++;
5792
#endif
5793
res = decide_phase (ps, res);
5794
LOG ( fprintf (ps->out, "%srdecide %d\n", ps->prefix, LIT2INT (res)));
5795
5796
return res;
5797
}
5798
5799
static Lit *
5800
sdecide (PS * ps)
5801
{
5802
Lit *res;
5803
Rnk *r;
5804
5805
for (;;)
5806
{
5807
r = htop (ps);
5808
res = RNK2LIT (r);
5809
if (res->val == UNDEF) break;
5810
(void) hpop (ps);
5811
NOLOG ( fprintf (ps->out,
5812
"%shpop %u %u %u\n",
5813
ps->prefix, r - ps->rnks,
5814
FLTMANTISSA(r->score),
5815
FLTEXPONENT(r->score)));
5816
}
5817
5818
#ifdef STATS
5819
ps->sdecisions++;
5820
#endif
5821
res = decide_phase (ps, res);
5822
5823
LOG ( fprintf (ps->out, "%ssdecide %d\n", ps->prefix, LIT2INT (res)));
5824
5825
return res;
5826
}
5827
5828
static Lit *
5829
adecide (PS * ps)
5830
{
5831
Lit *lit;
5832
Var * v;
5833
5834
assert (ps->als < ps->alshead);
5835
assert (!ps->failed_assumption);
5836
5837
while (ps->alstail < ps->alshead)
5838
{
5839
lit = *ps->alstail++;
5840
5841
if (lit->val == FALSE)
5842
{
5843
ps->failed_assumption = lit;
5844
v = LIT2VAR (lit);
5845
5846
use_var (ps, v);
5847
5848
LOG ( fprintf (ps->out, "%sfirst failed assumption %d\n",
5849
ps->prefix, LIT2INT (ps->failed_assumption)));
5850
fanalyze (ps);
5851
return 0;
5852
}
5853
5854
if (lit->val == TRUE)
5855
{
5856
v = LIT2VAR (lit);
5857
if (v->level > ps->adecidelevel)
5858
ps->adecidelevel = v->level;
5859
continue;
5860
}
5861
5862
#ifdef STATS
5863
ps->assumptions++;
5864
#endif
5865
LOG ( fprintf (ps->out, "%sadecide %d\n", ps->prefix, LIT2INT (lit)));
5866
ps->adecidelevel = ps->LEVEL + 1;
5867
5868
return lit;
5869
}
5870
5871
return 0;
5872
}
5873
5874
static void
5875
decide (PS * ps)
5876
{
5877
Lit * lit;
5878
5879
assert (!satisfied (ps));
5880
assert (!ps->conflict);
5881
5882
if (ps->alstail < ps->alshead && (lit = adecide (ps)))
5883
;
5884
else if (ps->failed_assumption)
5885
return;
5886
else if (satisfied (ps))
5887
return;
5888
else if (!(lit = rdecide (ps)))
5889
lit = sdecide (ps);
5890
5891
assert (lit);
5892
assign_decision (ps, lit);
5893
5894
ps->levelsum += ps->LEVEL;
5895
ps->decisions++;
5896
}
5897
5898
static int
5899
sat (PS * ps, int l)
5900
{
5901
int count = 0, backtracked;
5902
5903
if (!ps->conflict)
5904
bcp (ps);
5905
5906
if (ps->conflict)
5907
backtrack (ps);
5908
5909
if (ps->mtcls)
5910
return PICOSAT_UNSATISFIABLE;
5911
5912
if (satisfied (ps))
5913
goto SATISFIED;
5914
5915
if (ps->lsimplify <= ps->propagations)
5916
simplify (ps, 0);
5917
5918
if (ps->mtcls)
5919
return PICOSAT_UNSATISFIABLE;
5920
5921
if (satisfied (ps))
5922
goto SATISFIED;
5923
5924
init_restart (ps);
5925
5926
if (!ps->lreduce)
5927
init_reduce (ps);
5928
5929
ps->isimplify = ps->fixed;
5930
backtracked = 0;
5931
5932
for (;;)
5933
{
5934
if (!ps->conflict)
5935
bcp (ps);
5936
5937
if (ps->conflict)
5938
{
5939
incincs (ps);
5940
backtrack (ps);
5941
5942
if (ps->mtcls)
5943
return PICOSAT_UNSATISFIABLE;
5944
backtracked = 1;
5945
continue;
5946
}
5947
5948
if (satisfied (ps))
5949
{
5950
SATISFIED:
5951
#ifndef NDEBUG
5952
original_clauses_satisfied (ps);
5953
assumptions_satisfied (ps);
5954
#endif
5955
return PICOSAT_SATISFIABLE;
5956
}
5957
5958
if (backtracked)
5959
{
5960
backtracked = 0;
5961
if (!ps->LEVEL && ps->isimplify < ps->fixed)
5962
iteration (ps);
5963
}
5964
5965
if (l >= 0 && count >= l) /* decision limit reached ? */
5966
return PICOSAT_UNKNOWN;
5967
5968
if (ps->interrupt.function && /* external interrupt */
5969
count > 0 && !(count % INTERRUPTLIM) &&
5970
ps->interrupt.function (ps->interrupt.state))
5971
return PICOSAT_UNKNOWN;
5972
5973
if (ps->propagations >= ps->lpropagations)/* propagation limit reached ? */
5974
return PICOSAT_UNKNOWN;
5975
5976
#ifndef NADC
5977
if (!ps->adodisabled && ps->adoconflicts >= ps->adoconflictlimit)
5978
{
5979
assert (bcp_queue_is_empty (ps));
5980
return PICOSAT_UNKNOWN;
5981
}
5982
#endif
5983
5984
if (ps->fsimplify < ps->fixed && ps->lsimplify <= ps->propagations)
5985
{
5986
simplify (ps, 0);
5987
if (!bcp_queue_is_empty (ps))
5988
continue;
5989
#ifndef NFL
5990
if (ps->mtcls)
5991
return PICOSAT_UNSATISFIABLE;
5992
5993
if (satisfied (ps))
5994
return PICOSAT_SATISFIABLE;
5995
5996
assert (!ps->LEVEL);
5997
#endif
5998
}
5999
6000
if (need_to_reduce (ps))
6001
reduce (ps, 50);
6002
6003
if (ps->conflicts >= ps->lrestart && ps->LEVEL > 2)
6004
restart (ps);
6005
6006
decide (ps);
6007
if (ps->failed_assumption)
6008
return PICOSAT_UNSATISFIABLE;
6009
count++;
6010
}
6011
}
6012
6013
static void
6014
rebias (PS * ps)
6015
{
6016
Cls ** p, * c;
6017
Var * v;
6018
6019
for (v = ps->vars + 1; v <= ps->vars + ps->max_var; v++)
6020
v->assigned = 0;
6021
6022
memset (ps->jwh, 0, 2 * (ps->max_var + 1) * sizeof *ps->jwh);
6023
6024
for (p = ps->oclauses; p < ps->ohead; p++)
6025
{
6026
c = *p;
6027
6028
if (!c)
6029
continue;
6030
6031
if (c->learned)
6032
continue;
6033
6034
incjwh (ps, c);
6035
}
6036
}
6037
6038
#ifdef TRACE
6039
6040
static unsigned
6041
core (PS * ps)
6042
{
6043
unsigned idx, prev, this, delta, i, lcore, vcore;
6044
unsigned *stack, *shead, *eos;
6045
Lit **q, **eol, *lit;
6046
Cls *c, *reason;
6047
Znt *p, byte;
6048
Zhn *zhain;
6049
Var *v;
6050
6051
assert (ps->trace);
6052
6053
assert (ps->mtcls || ps->failed_assumption);
6054
if (ps->ocore >= 0)
6055
return ps->ocore;
6056
6057
lcore = ps->ocore = vcore = 0;
6058
6059
stack = shead = eos = 0;
6060
ENLARGE (stack, shead, eos);
6061
6062
if (ps->mtcls)
6063
{
6064
idx = CLS2IDX (ps->mtcls);
6065
*shead++ = idx;
6066
}
6067
else
6068
{
6069
assert (ps->failed_assumption);
6070
v = LIT2VAR (ps->failed_assumption);
6071
reason = v->reason;
6072
assert (reason);
6073
idx = CLS2IDX (reason);
6074
*shead++ = idx;
6075
}
6076
6077
while (shead > stack)
6078
{
6079
idx = *--shead;
6080
zhain = IDX2ZHN (idx);
6081
6082
if (zhain)
6083
{
6084
if (zhain->core)
6085
continue;
6086
6087
zhain->core = 1;
6088
lcore++;
6089
6090
c = IDX2CLS (idx);
6091
if (c)
6092
{
6093
assert (!c->core);
6094
c->core = 1;
6095
}
6096
6097
i = 0;
6098
delta = 0;
6099
prev = 0;
6100
for (p = zhain->znt; (byte = *p); p++, i += 7)
6101
{
6102
delta |= (byte & 0x7f) << i;
6103
if (byte & 0x80)
6104
continue;
6105
6106
this = prev + delta;
6107
assert (prev < this); /* no overflow */
6108
6109
if (shead == eos)
6110
ENLARGE (stack, shead, eos);
6111
*shead++ = this;
6112
6113
prev = this;
6114
delta = 0;
6115
i = -7;
6116
}
6117
}
6118
else
6119
{
6120
c = IDX2CLS (idx);
6121
6122
assert (c);
6123
assert (!c->learned);
6124
6125
if (c->core)
6126
continue;
6127
6128
c->core = 1;
6129
ps->ocore++;
6130
6131
eol = end_of_lits (c);
6132
for (q = c->lits; q < eol; q++)
6133
{
6134
lit = *q;
6135
v = LIT2VAR (lit);
6136
if (v->core)
6137
continue;
6138
6139
v->core = 1;
6140
vcore++;
6141
6142
if (!ps->failed_assumption) continue;
6143
if (lit != ps->failed_assumption) continue;
6144
6145
reason = v->reason;
6146
if (!reason) continue;
6147
if (reason->core) continue;
6148
6149
idx = CLS2IDX (reason);
6150
if (shead == eos)
6151
ENLARGE (stack, shead, eos);
6152
*shead++ = idx;
6153
}
6154
}
6155
}
6156
6157
DELETEN (stack, eos - stack);
6158
6159
if (ps->verbosity)
6160
fprintf (ps->out,
6161
"%s%u core variables out of %u (%.1f%%)\n"
6162
"%s%u core original clauses out of %u (%.1f%%)\n"
6163
"%s%u core learned clauses out of %u (%.1f%%)\n",
6164
ps->prefix, vcore, ps->max_var, PERCENT (vcore, ps->max_var),
6165
ps->prefix, ps->ocore, ps->oadded, PERCENT (ps->ocore, ps->oadded),
6166
ps->prefix, lcore, ps->ladded, PERCENT (lcore, ps->ladded));
6167
6168
return ps->ocore;
6169
}
6170
6171
static void
6172
trace_lits (PS * ps, Cls * c, FILE * file)
6173
{
6174
Lit **p, **eol = end_of_lits (c);
6175
6176
assert (c);
6177
assert (c->core);
6178
6179
for (p = c->lits; p < eol; p++)
6180
fprintf (file, "%d ", LIT2INT (*p));
6181
6182
fputc ('0', file);
6183
}
6184
6185
static void
6186
write_idx (PS * ps, unsigned idx, FILE * file)
6187
{
6188
fprintf (file, "%ld", EXPORTIDX (idx));
6189
}
6190
6191
static void
6192
trace_clause (PS * ps, unsigned idx, Cls * c, FILE * file, int fmt)
6193
{
6194
assert (c);
6195
assert (c->core);
6196
assert (fmt == RUP_TRACE_FMT || !c->learned);
6197
assert (CLS2IDX (c) == idx);
6198
6199
if (fmt != RUP_TRACE_FMT)
6200
{
6201
write_idx (ps, idx, file);
6202
fputc (' ', file);
6203
}
6204
6205
trace_lits (ps, c, file);
6206
6207
if (fmt != RUP_TRACE_FMT)
6208
fputs (" 0", file);
6209
6210
fputc ('\n', file);
6211
}
6212
6213
static void
6214
trace_zhain (PS * ps, unsigned idx, Zhn * zhain, FILE * file, int fmt)
6215
{
6216
unsigned prev, this, delta, i;
6217
Znt *p, byte;
6218
Cls * c;
6219
6220
assert (zhain);
6221
assert (zhain->core);
6222
6223
write_idx (ps, idx, file);
6224
fputc (' ', file);
6225
6226
if (fmt == EXTENDED_TRACECHECK_TRACE_FMT)
6227
{
6228
c = IDX2CLS (idx);
6229
assert (c);
6230
trace_lits (ps, c, file);
6231
}
6232
else
6233
{
6234
assert (fmt == COMPACT_TRACECHECK_TRACE_FMT);
6235
putc ('*', file);
6236
}
6237
6238
i = 0;
6239
delta = 0;
6240
prev = 0;
6241
6242
for (p = zhain->znt; (byte = *p); p++, i += 7)
6243
{
6244
delta |= (byte & 0x7f) << i;
6245
if (byte & 0x80)
6246
continue;
6247
6248
this = prev + delta;
6249
6250
putc (' ', file);
6251
write_idx (ps, this, file);
6252
6253
prev = this;
6254
delta = 0;
6255
i = -7;
6256
}
6257
6258
fputs (" 0\n", file);
6259
}
6260
6261
static void
6262
write_core (PS * ps, FILE * file)
6263
{
6264
Lit **q, **eol;
6265
Cls **p, *c;
6266
6267
fprintf (file, "p cnf %u %u\n", ps->max_var, core (ps));
6268
6269
for (p = SOC; p != EOC; p = NXC (p))
6270
{
6271
c = *p;
6272
6273
if (!c || c->learned || !c->core)
6274
continue;
6275
6276
eol = end_of_lits (c);
6277
for (q = c->lits; q < eol; q++)
6278
fprintf (file, "%d ", LIT2INT (*q));
6279
6280
fputs ("0\n", file);
6281
}
6282
}
6283
6284
#endif
6285
6286
static void
6287
write_trace (PS * ps, FILE * file, int fmt)
6288
{
6289
#ifdef TRACE
6290
Cls *c, ** p;
6291
Zhn *zhain;
6292
unsigned i;
6293
6294
core (ps);
6295
6296
if (fmt == RUP_TRACE_FMT)
6297
{
6298
ps->rupvariables = picosat_variables (ps),
6299
ps->rupclauses = picosat_added_original_clauses (ps);
6300
write_rup_header (ps, file);
6301
}
6302
6303
for (p = SOC; p != EOC; p = NXC (p))
6304
{
6305
c = *p;
6306
6307
if (ps->oclauses <= p && p < ps->eoo)
6308
{
6309
i = OIDX2IDX (p - ps->oclauses);
6310
assert (!c || CLS2IDX (c) == i);
6311
}
6312
else
6313
{
6314
assert (ps->lclauses <= p && p < ps->EOL);
6315
i = LIDX2IDX (p - ps->lclauses);
6316
}
6317
6318
zhain = IDX2ZHN (i);
6319
6320
if (zhain)
6321
{
6322
if (zhain->core)
6323
{
6324
if (fmt == RUP_TRACE_FMT)
6325
trace_clause (ps,i, c, file, fmt);
6326
else
6327
trace_zhain (ps, i, zhain, file, fmt);
6328
}
6329
}
6330
else if (c)
6331
{
6332
if (fmt != RUP_TRACE_FMT && c)
6333
{
6334
if (c->core)
6335
trace_clause (ps, i, c, file, fmt);
6336
}
6337
}
6338
}
6339
#else
6340
(void) file;
6341
(void) fmt;
6342
(void) ps;
6343
#endif
6344
}
6345
6346
static void
6347
write_core_wrapper (PS * ps, FILE * file, int fmt)
6348
{
6349
(void) fmt;
6350
#ifdef TRACE
6351
write_core (ps, file);
6352
#else
6353
(void) ps;
6354
(void) file;
6355
#endif
6356
}
6357
6358
static Lit *
6359
import_lit (PS * ps, int lit, int nointernal)
6360
{
6361
Lit * res;
6362
Var * v;
6363
6364
ABORTIF (lit == INT_MIN, "API usage: INT_MIN literal");
6365
ABORTIF (abs (lit) > (int) ps->max_var && ps->CLS != ps->clshead,
6366
"API usage: new variable index after 'picosat_push'");
6367
6368
if (abs (lit) <= (int) ps->max_var)
6369
{
6370
res = int2lit (ps, lit);
6371
v = LIT2VAR (res);
6372
if (nointernal && v->internal)
6373
ABORT ("API usage: trying to import invalid literal");
6374
else if (!nointernal && !v->internal)
6375
ABORT ("API usage: trying to import invalid context");
6376
}
6377
else
6378
{
6379
while (abs (lit) > (int) ps->max_var)
6380
inc_max_var (ps);
6381
res = int2lit (ps, lit);
6382
}
6383
6384
return res;
6385
}
6386
6387
#ifdef TRACE
6388
static void
6389
reset_core (PS * ps)
6390
{
6391
Cls ** p, * c;
6392
Zhn ** q, * z;
6393
unsigned i;
6394
6395
for (i = 1; i <= ps->max_var; i++)
6396
ps->vars[i].core = 0;
6397
6398
for (p = SOC; p != EOC; p = NXC (p))
6399
if ((c = *p))
6400
c->core = 0;
6401
6402
for (q = ps->zhains; q != ps->zhead; q++)
6403
if ((z = *q))
6404
z->core = 0;
6405
6406
ps->ocore = -1;
6407
}
6408
#endif
6409
6410
static void
6411
reset_assumptions (PS * ps)
6412
{
6413
Lit ** p;
6414
6415
ps->failed_assumption = 0;
6416
6417
if (ps->extracted_all_failed_assumptions)
6418
{
6419
for (p = ps->als; p < ps->alshead; p++)
6420
LIT2VAR (*p)->failed = 0;
6421
6422
ps->extracted_all_failed_assumptions = 0;
6423
}
6424
6425
ps->alstail = ps->alshead = ps->als;
6426
ps->adecidelevel = 0;
6427
}
6428
6429
static void
6430
check_ready (PS * ps)
6431
{
6432
ABORTIF (!ps || ps->state == RESET, "API usage: uninitialized");
6433
}
6434
6435
static void
6436
check_sat_state (PS * ps)
6437
{
6438
ABORTIF (ps->state != SAT, "API usage: expected to be in SAT state");
6439
}
6440
6441
static void
6442
check_unsat_state (PS * ps)
6443
{
6444
ABORTIF (ps->state != UNSAT, "API usage: expected to be in UNSAT state");
6445
}
6446
6447
static void
6448
check_sat_or_unsat_or_unknown_state (PS * ps)
6449
{
6450
ABORTIF (ps->state != SAT && ps->state != UNSAT && ps->state != UNKNOWN,
6451
"API usage: expected to be in SAT, UNSAT, or UNKNOWN state");
6452
}
6453
6454
static void
6455
reset_partial (PS * ps)
6456
{
6457
unsigned idx;
6458
if (!ps->partial)
6459
return;
6460
for (idx = 1; idx <= ps->max_var; idx++)
6461
ps->vars[idx].partial = 0;
6462
ps->partial = 0;
6463
}
6464
6465
static void
6466
reset_incremental_usage (PS * ps)
6467
{
6468
unsigned num_non_false;
6469
Lit * lit, ** q;
6470
6471
check_sat_or_unsat_or_unknown_state (ps);
6472
6473
LOG ( fprintf (ps->out, "%sRESET incremental usage\n", ps->prefix));
6474
6475
if (ps->LEVEL)
6476
undo (ps, 0);
6477
6478
reset_assumptions (ps);
6479
6480
if (ps->conflict)
6481
{
6482
num_non_false = 0;
6483
for (q = ps->conflict->lits; q < end_of_lits (ps->conflict); q++)
6484
{
6485
lit = *q;
6486
if (lit->val != FALSE)
6487
num_non_false++;
6488
}
6489
6490
// assert (num_non_false >= 2); // TODO: why this assertion?
6491
#ifdef NO_BINARY_CLAUSES
6492
if (ps->conflict == &ps->cimpl)
6493
resetcimpl (ps);
6494
#endif
6495
#ifndef NADC
6496
if (ps->conflict == ps->adoconflict)
6497
resetadoconflict (ps);
6498
#endif
6499
ps->conflict = 0;
6500
}
6501
6502
#ifdef TRACE
6503
reset_core (ps);
6504
#endif
6505
6506
reset_partial (ps);
6507
6508
ps->saved_flips = ps->flips;
6509
ps->min_flipped = UINT_MAX;
6510
ps->saved_max_var = ps->max_var;
6511
6512
ps->state = READY;
6513
}
6514
6515
static void
6516
enter (PS * ps)
6517
{
6518
if (ps->nentered++)
6519
return;
6520
6521
check_ready (ps);
6522
ps->entered = picosat_time_stamp ();
6523
}
6524
6525
static void
6526
leave (PS * ps)
6527
{
6528
assert (ps->nentered);
6529
if (--ps->nentered)
6530
return;
6531
6532
sflush (ps);
6533
}
6534
6535
static void
6536
check_trace_support_and_execute (PS * ps,
6537
FILE * file,
6538
void (*f)(PS*,FILE*,int), int fmt)
6539
{
6540
check_ready (ps);
6541
check_unsat_state (ps);
6542
#ifdef TRACE
6543
ABORTIF (!ps->trace, "API usage: tracing disabled");
6544
enter (ps);
6545
f (ps, file, fmt);
6546
leave (ps);
6547
#else
6548
(void) file;
6549
(void) fmt;
6550
(void) f;
6551
ABORT ("compiled without trace support");
6552
#endif
6553
}
6554
6555
static void
6556
extract_all_failed_assumptions (PS * ps)
6557
{
6558
Lit ** p, ** eol;
6559
Var * v, * u;
6560
int pos;
6561
Cls * c;
6562
6563
assert (!ps->extracted_all_failed_assumptions);
6564
6565
assert (ps->failed_assumption);
6566
assert (ps->mhead == ps->marked);
6567
6568
if (ps->marked == ps->eom)
6569
ENLARGE (ps->marked, ps->mhead, ps->eom);
6570
6571
v = LIT2VAR (ps->failed_assumption);
6572
mark_var (ps, v);
6573
pos = 0;
6574
6575
while (pos < ps->mhead - ps->marked)
6576
{
6577
v = ps->marked[pos++];
6578
assert (v->mark);
6579
c = var2reason (ps, v);
6580
if (!c)
6581
continue;
6582
eol = end_of_lits (c);
6583
for (p = c->lits; p < eol; p++)
6584
{
6585
u = LIT2VAR (*p);
6586
if (!u->mark)
6587
mark_var (ps, u);
6588
}
6589
#ifdef NO_BINARY_CLAUSES
6590
if (c == &ps->impl)
6591
resetimpl (ps);
6592
#endif
6593
}
6594
6595
for (p = ps->als; p < ps->alshead; p++)
6596
{
6597
u = LIT2VAR (*p);
6598
if (!u->mark) continue;
6599
u->failed = 1;
6600
LOG ( fprintf (ps->out,
6601
"%sfailed assumption %d\n",
6602
ps->prefix, LIT2INT (*p)));
6603
}
6604
6605
while (ps->mhead > ps->marked)
6606
(*--ps->mhead)->mark = 0;
6607
6608
ps->extracted_all_failed_assumptions = 1;
6609
}
6610
6611
const char *
6612
picosat_copyright (void)
6613
{
6614
return "Copyright (c) 2006 - 2014 Armin Biere JKU Linz";
6615
}
6616
6617
PicoSAT *
6618
picosat_init (void)
6619
{
6620
return init (0, 0, 0, 0);
6621
}
6622
6623
PicoSAT *
6624
picosat_minit (void * pmgr,
6625
picosat_malloc pnew,
6626
picosat_realloc presize,
6627
picosat_free pfree)
6628
{
6629
ABORTIF (!pnew, "API usage: zero 'picosat_malloc' argument");
6630
ABORTIF (!presize, "API usage: zero 'picosat_realloc' argument");
6631
ABORTIF (!pfree, "API usage: zero 'picosat_free' argument");
6632
return init (pmgr, pnew, presize, pfree);
6633
}
6634
6635
6636
void
6637
picosat_adjust (PS * ps, int new_max_var)
6638
{
6639
unsigned new_size_vars;
6640
6641
ABORTIF (abs (new_max_var) > (int) ps->max_var && ps->CLS != ps->clshead,
6642
"API usage: adjusting variable index after 'picosat_push'");
6643
enter (ps);
6644
6645
new_max_var = abs (new_max_var);
6646
new_size_vars = new_max_var + 1;
6647
6648
if (ps->size_vars < new_size_vars)
6649
enlarge (ps, new_size_vars);
6650
6651
while (ps->max_var < (unsigned) new_max_var)
6652
inc_max_var (ps);
6653
6654
leave (ps);
6655
}
6656
6657
int
6658
picosat_inc_max_var (PS * ps)
6659
{
6660
if (ps->measurealltimeinlib)
6661
enter (ps);
6662
else
6663
check_ready (ps);
6664
6665
inc_max_var (ps);
6666
6667
if (ps->measurealltimeinlib)
6668
leave (ps);
6669
6670
return ps->max_var;
6671
}
6672
6673
int
6674
picosat_context (PS * ps)
6675
{
6676
return ps->clshead == ps->CLS ? 0 : LIT2INT (ps->clshead[-1]);
6677
}
6678
6679
int
6680
picosat_push (PS * ps)
6681
{
6682
int res;
6683
Lit *lit;
6684
Var * v;
6685
6686
if (ps->measurealltimeinlib)
6687
enter (ps);
6688
else
6689
check_ready (ps);
6690
6691
if (ps->state != READY)
6692
reset_incremental_usage (ps);
6693
6694
if (ps->rils != ps->rilshead)
6695
{
6696
res = *--ps->rilshead;
6697
assert (ps->vars[res].internal);
6698
}
6699
else
6700
{
6701
inc_max_var (ps);
6702
res = ps->max_var;
6703
v = ps->vars + res;
6704
assert (!v->internal);
6705
v->internal = 1;
6706
ps->internals++;
6707
LOG ( fprintf (ps->out, "%snew internal variable index %d\n", ps->prefix, res));
6708
}
6709
6710
lit = int2lit (ps, res);
6711
6712
if (ps->clshead == ps->eocls)
6713
ENLARGE (ps->CLS, ps->clshead, ps->eocls);
6714
*ps->clshead++ = lit;
6715
6716
ps->contexts++;
6717
6718
LOG ( fprintf (ps->out, "%snew context %d at depth %ld after push\n",
6719
ps->prefix, res, (long)(ps->clshead - ps->CLS)));
6720
6721
if (ps->measurealltimeinlib)
6722
leave (ps);
6723
6724
return res;
6725
}
6726
6727
int
6728
picosat_pop (PS * ps)
6729
{
6730
Lit * lit;
6731
int res;
6732
ABORTIF (ps->CLS == ps->clshead, "API usage: too many 'picosat_pop'");
6733
ABORTIF (ps->added != ps->ahead, "API usage: incomplete clause");
6734
6735
if (ps->measurealltimeinlib)
6736
enter (ps);
6737
else
6738
check_ready (ps);
6739
6740
if (ps->state != READY)
6741
reset_incremental_usage (ps);
6742
6743
assert (ps->CLS < ps->clshead);
6744
lit = *--ps->clshead;
6745
LOG ( fprintf (ps->out, "%sclosing context %d at depth %ld after pop\n",
6746
ps->prefix, LIT2INT (lit), (long)(ps->clshead - ps->CLS) + 1));
6747
6748
if (ps->cilshead == ps->eocils)
6749
ENLARGE (ps->cils, ps->cilshead, ps->eocils);
6750
*ps->cilshead++ = LIT2INT (lit);
6751
6752
if (ps->cilshead - ps->cils > MAXCILS) {
6753
LOG ( fprintf (ps->out,
6754
"%srecycling %ld interals with forced simplification\n",
6755
ps->prefix, (long)(ps->cilshead - ps->cils)));
6756
simplify (ps, 1);
6757
}
6758
6759
res = picosat_context (ps);
6760
if (res)
6761
LOG ( fprintf (ps->out, "%snew context %d at depth %ld after pop\n",
6762
ps->prefix, res, (long)(ps->clshead - ps->CLS)));
6763
else
6764
LOG ( fprintf (ps->out, "%souter most context reached after pop\n", ps->prefix));
6765
6766
if (ps->measurealltimeinlib)
6767
leave (ps);
6768
6769
return res;
6770
}
6771
6772
void
6773
picosat_set_verbosity (PS * ps, int new_verbosity_level)
6774
{
6775
check_ready (ps);
6776
ps->verbosity = new_verbosity_level;
6777
}
6778
6779
void
6780
picosat_set_plain (PS * ps, int new_plain_value)
6781
{
6782
check_ready (ps);
6783
ps->plain = new_plain_value;
6784
}
6785
6786
int
6787
picosat_enable_trace_generation (PS * ps)
6788
{
6789
int res = 0;
6790
check_ready (ps);
6791
#ifdef TRACE
6792
ABORTIF (ps->addedclauses,
6793
"API usage: trace generation enabled after adding clauses");
6794
res = ps->trace = 1;
6795
#endif
6796
return res;
6797
}
6798
6799
void
6800
picosat_set_incremental_rup_file (PS * ps, FILE * rup_file, int m, int n)
6801
{
6802
check_ready (ps);
6803
assert (!ps->rupstarted);
6804
ps->rup = rup_file;
6805
ps->rupvariables = m;
6806
ps->rupclauses = n;
6807
}
6808
6809
void
6810
picosat_set_output (PS * ps, FILE * output_file)
6811
{
6812
check_ready (ps);
6813
ps->out = output_file;
6814
}
6815
6816
void
6817
picosat_measure_all_calls (PS * ps)
6818
{
6819
check_ready (ps);
6820
ps->measurealltimeinlib = 1;
6821
}
6822
6823
void
6824
picosat_set_prefix (PS * ps, const char * str)
6825
{
6826
check_ready (ps);
6827
new_prefix (ps, str);
6828
}
6829
6830
void
6831
picosat_set_seed (PS * ps, unsigned s)
6832
{
6833
check_ready (ps);
6834
ps->srng = s;
6835
}
6836
6837
void
6838
picosat_reset (PS * ps)
6839
{
6840
check_ready (ps);
6841
reset (ps);
6842
}
6843
6844
int
6845
picosat_add (PS * ps, int int_lit)
6846
{
6847
int res = ps->oadded;
6848
Lit *lit;
6849
6850
if (ps->measurealltimeinlib)
6851
enter (ps);
6852
else
6853
check_ready (ps);
6854
6855
ABORTIF (ps->rup && ps->rupstarted && ps->oadded >= (unsigned)ps->rupclauses,
6856
"API usage: adding too many clauses after RUP header written");
6857
#ifndef NADC
6858
ABORTIF (ps->addingtoado,
6859
"API usage: 'picosat_add' and 'picosat_add_ado_lit' mixed");
6860
#endif
6861
if (ps->state != READY)
6862
reset_incremental_usage (ps);
6863
6864
if (ps->saveorig)
6865
{
6866
if (ps->sohead == ps->eoso)
6867
ENLARGE (ps->soclauses, ps->sohead, ps->eoso);
6868
6869
*ps->sohead++ = int_lit;
6870
}
6871
6872
if (int_lit)
6873
{
6874
lit = import_lit (ps, int_lit, 1);
6875
add_lit (ps, lit);
6876
}
6877
else
6878
simplify_and_add_original_clause (ps);
6879
6880
if (ps->measurealltimeinlib)
6881
leave (ps);
6882
6883
return res;
6884
}
6885
6886
int
6887
picosat_add_arg (PS * ps, ...)
6888
{
6889
int lit;
6890
va_list ap;
6891
va_start (ap, ps);
6892
while ((lit = va_arg (ap, int)))
6893
(void) picosat_add (ps, lit);
6894
va_end (ap);
6895
return picosat_add (ps, 0);
6896
}
6897
6898
int
6899
picosat_add_lits (PS * ps, int * lits)
6900
{
6901
const int * p;
6902
int lit;
6903
for (p = lits; (lit = *p); p++)
6904
(void) picosat_add (ps, lit);
6905
return picosat_add (ps, 0);
6906
}
6907
6908
void
6909
picosat_add_ado_lit (PS * ps, int external_lit)
6910
{
6911
#ifndef NADC
6912
Lit * internal_lit;
6913
6914
if (ps->measurealltimeinlib)
6915
enter (ps);
6916
else
6917
check_ready (ps);
6918
6919
if (ps->state != READY)
6920
reset_incremental_usage (ps);
6921
6922
ABORTIF (!ps->addingtoado && ps->ahead > ps->added,
6923
"API usage: 'picosat_add' and 'picosat_add_ado_lit' mixed");
6924
6925
if (external_lit)
6926
{
6927
ps->addingtoado = 1;
6928
internal_lit = import_lit (ps, external_lit, 1);
6929
add_lit (ps, internal_lit);
6930
}
6931
else
6932
{
6933
ps->addingtoado = 0;
6934
add_ado (ps);
6935
}
6936
if (ps->measurealltimeinlib)
6937
leave (ps);
6938
#else
6939
(void) ps;
6940
(void) external_lit;
6941
ABORT ("compiled without all different constraint support");
6942
#endif
6943
}
6944
6945
static void
6946
assume (PS * ps, Lit * lit)
6947
{
6948
if (ps->alshead == ps->eoals)
6949
{
6950
assert (ps->alstail == ps->als);
6951
ENLARGE (ps->als, ps->alshead, ps->eoals);
6952
ps->alstail = ps->als;
6953
}
6954
6955
*ps->alshead++ = lit;
6956
LOG ( fprintf (ps->out, "%sassumption %d\n", ps->prefix, LIT2INT (lit)));
6957
}
6958
6959
static void
6960
assume_contexts (PS * ps)
6961
{
6962
Lit ** p;
6963
if (ps->als != ps->alshead)
6964
return;
6965
for (p = ps->CLS; p != ps->clshead; p++)
6966
assume (ps, *p);
6967
}
6968
6969
#ifndef RCODE
6970
static const char * enumstr (int i) {
6971
int last = i % 10;
6972
if (last == 1) return "st";
6973
if (last == 2) return "nd";
6974
if (last == 3) return "rd";
6975
return "th";
6976
}
6977
#endif
6978
6979
static int
6980
tderef (PS * ps, int int_lit)
6981
{
6982
Lit * lit;
6983
Var * v;
6984
6985
assert (abs (int_lit) <= (int) ps->max_var);
6986
6987
lit = int2lit (ps, int_lit);
6988
6989
v = LIT2VAR (lit);
6990
if (v->level > 0)
6991
return 0;
6992
6993
if (lit->val == TRUE)
6994
return 1;
6995
6996
if (lit->val == FALSE)
6997
return -1;
6998
6999
return 0;
7000
}
7001
7002
static int
7003
pderef (PS * ps, int int_lit)
7004
{
7005
Lit * lit;
7006
Var * v;
7007
7008
assert (abs (int_lit) <= (int) ps->max_var);
7009
7010
v = ps->vars + abs (int_lit);
7011
if (!v->partial)
7012
return 0;
7013
7014
lit = int2lit (ps, int_lit);
7015
7016
if (lit->val == TRUE)
7017
return 1;
7018
7019
if (lit->val == FALSE)
7020
return -1;
7021
7022
return 0;
7023
}
7024
7025
static void
7026
minautarky (PS * ps)
7027
{
7028
unsigned * occs, maxoccs, tmpoccs, npartial;
7029
int * p, * c, lit, best, val;
7030
#ifdef LOGGING
7031
int tl;
7032
#endif
7033
7034
assert (!ps->partial);
7035
7036
npartial = 0;
7037
7038
NEWN (occs, 2*ps->max_var + 1);
7039
CLRN (occs, 2*ps->max_var + 1);
7040
occs += ps->max_var;
7041
for (p = ps->soclauses; p < ps->sohead; p++)
7042
occs[*p]++;
7043
assert (occs[0] == ps->oadded);
7044
7045
for (c = ps->soclauses; c < ps->sohead; c = p + 1)
7046
{
7047
#ifdef LOGGING
7048
tl = 0;
7049
#endif
7050
best = 0;
7051
maxoccs = 0;
7052
for (p = c; (lit = *p); p++)
7053
{
7054
val = tderef (ps, lit);
7055
if (val < 0)
7056
continue;
7057
if (val > 0)
7058
{
7059
#ifdef LOGGING
7060
tl = 1;
7061
#endif
7062
best = lit;
7063
maxoccs = occs[lit];
7064
}
7065
7066
val = pderef (ps, lit);
7067
if (val > 0)
7068
break;
7069
if (val < 0)
7070
continue;
7071
val = int2lit (ps, lit)->val;
7072
assert (val);
7073
if (val < 0)
7074
continue;
7075
tmpoccs = occs[lit];
7076
if (best && tmpoccs <= maxoccs)
7077
continue;
7078
best = lit;
7079
maxoccs = tmpoccs;
7080
}
7081
if (!lit)
7082
{
7083
assert (best);
7084
LOG ( fprintf (ps->out, "%sautark %d with %d occs%s\n",
7085
ps->prefix, best, maxoccs, tl ? " (top)" : ""));
7086
ps->vars[abs (best)].partial = 1;
7087
npartial++;
7088
}
7089
for (p = c; (lit = *p); p++)
7090
{
7091
assert (occs[lit] > 0);
7092
occs[lit]--;
7093
}
7094
}
7095
occs -= ps->max_var;
7096
DELETEN (occs, 2*ps->max_var + 1);
7097
ps->partial = 1;
7098
7099
if (ps->verbosity)
7100
fprintf (ps->out,
7101
"%sautarky of size %u out of %u satisfying all clauses (%.1f%%)\n",
7102
ps->prefix, npartial, ps->max_var, PERCENT (npartial, ps->max_var));
7103
}
7104
7105
void
7106
picosat_assume (PS * ps, int int_lit)
7107
{
7108
Lit *lit;
7109
7110
if (ps->measurealltimeinlib)
7111
enter (ps);
7112
else
7113
check_ready (ps);
7114
7115
if (ps->state != READY)
7116
reset_incremental_usage (ps);
7117
7118
assume_contexts (ps);
7119
lit = import_lit (ps, int_lit, 1);
7120
assume (ps, lit);
7121
7122
if (ps->measurealltimeinlib)
7123
leave (ps);
7124
}
7125
7126
int
7127
picosat_sat (PS * ps, int l)
7128
{
7129
int res;
7130
char ch;
7131
7132
enter (ps);
7133
7134
ps->calls++;
7135
LOG ( fprintf (ps->out, "%sSTART call %u\n", ps->prefix, ps->calls));
7136
7137
if (ps->added < ps->ahead)
7138
{
7139
#ifndef NADC
7140
if (ps->addingtoado)
7141
ABORT ("API usage: incomplete all different constraint");
7142
else
7143
#endif
7144
ABORT ("API usage: incomplete clause");
7145
}
7146
7147
if (ps->state != READY)
7148
reset_incremental_usage (ps);
7149
7150
assume_contexts (ps);
7151
7152
res = sat (ps, l);
7153
7154
assert (ps->state == READY);
7155
7156
switch (res)
7157
{
7158
case PICOSAT_UNSATISFIABLE:
7159
ch = '0';
7160
ps->state = UNSAT;
7161
break;
7162
case PICOSAT_SATISFIABLE:
7163
ch = '1';
7164
ps->state = SAT;
7165
break;
7166
default:
7167
ch = '?';
7168
ps->state = UNKNOWN;
7169
break;
7170
}
7171
7172
if (ps->verbosity)
7173
{
7174
report (ps, 1, ch);
7175
rheader (ps);
7176
}
7177
7178
leave (ps);
7179
LOG ( fprintf (ps->out, "%sEND call %u result %d\n", ps->prefix, ps->calls, res));
7180
7181
ps->last_sat_call_result = res;
7182
7183
return res;
7184
}
7185
7186
int
7187
picosat_res (PS * ps)
7188
{
7189
return ps->last_sat_call_result;
7190
}
7191
7192
int
7193
picosat_deref (PS * ps, int int_lit)
7194
{
7195
Lit *lit;
7196
7197
check_ready (ps);
7198
check_sat_state (ps);
7199
ABORTIF (!int_lit, "API usage: can not deref zero literal");
7200
ABORTIF (ps->mtcls, "API usage: deref after empty clause generated");
7201
7202
#ifdef STATS
7203
ps->derefs++;
7204
#endif
7205
7206
if (abs (int_lit) > (int) ps->max_var)
7207
return 0;
7208
7209
lit = int2lit (ps, int_lit);
7210
7211
if (lit->val == TRUE)
7212
return 1;
7213
7214
if (lit->val == FALSE)
7215
return -1;
7216
7217
return 0;
7218
}
7219
7220
int
7221
picosat_deref_toplevel (PS * ps, int int_lit)
7222
{
7223
check_ready (ps);
7224
ABORTIF (!int_lit, "API usage: can not deref zero literal");
7225
7226
#ifdef STATS
7227
ps->derefs++;
7228
#endif
7229
if (abs (int_lit) > (int) ps->max_var)
7230
return 0;
7231
7232
return tderef (ps, int_lit);
7233
}
7234
7235
int
7236
picosat_inconsistent (PS * ps)
7237
{
7238
check_ready (ps);
7239
return ps->mtcls != 0;
7240
}
7241
7242
int
7243
picosat_corelit (PS * ps, int int_lit)
7244
{
7245
check_ready (ps);
7246
check_unsat_state (ps);
7247
ABORTIF (!int_lit, "API usage: zero literal can not be in core");
7248
7249
assert (ps->mtcls || ps->failed_assumption);
7250
7251
#ifdef TRACE
7252
{
7253
int res = 0;
7254
ABORTIF (!ps->trace, "tracing disabled");
7255
if (ps->measurealltimeinlib)
7256
enter (ps);
7257
core (ps);
7258
if (abs (int_lit) <= (int) ps->max_var)
7259
res = ps->vars[abs (int_lit)].core;
7260
assert (!res || ps->failed_assumption || ps->vars[abs (int_lit)].used);
7261
if (ps->measurealltimeinlib)
7262
leave (ps);
7263
return res;
7264
}
7265
#else
7266
ABORT ("compiled without trace support");
7267
return 0;
7268
#endif
7269
}
7270
7271
int
7272
picosat_coreclause (PS * ps, int ocls)
7273
{
7274
check_ready (ps);
7275
check_unsat_state (ps);
7276
7277
ABORTIF (ocls < 0, "API usage: negative original clause index");
7278
ABORTIF (ocls >= (int)ps->oadded, "API usage: original clause index exceeded");
7279
7280
assert (ps->mtcls || ps->failed_assumption);
7281
7282
#ifdef TRACE
7283
{
7284
Cls ** clsptr, * c;
7285
int res = 0;
7286
7287
ABORTIF (!ps->trace, "tracing disabled");
7288
if (ps->measurealltimeinlib)
7289
enter (ps);
7290
core (ps);
7291
clsptr = ps->oclauses + ocls;
7292
assert (clsptr < ps->ohead);
7293
c = *clsptr;
7294
if (c)
7295
res = c->core;
7296
if (ps->measurealltimeinlib)
7297
leave (ps);
7298
7299
return res;
7300
}
7301
#else
7302
ABORT ("compiled without trace support");
7303
return 0;
7304
#endif
7305
}
7306
7307
int
7308
picosat_failed_assumption (PS * ps, int int_lit)
7309
{
7310
Lit * lit;
7311
Var * v;
7312
ABORTIF (!int_lit, "API usage: zero literal as assumption");
7313
check_ready (ps);
7314
check_unsat_state (ps);
7315
if (ps->mtcls)
7316
return 0;
7317
assert (ps->failed_assumption);
7318
if (abs (int_lit) > (int) ps->max_var)
7319
return 0;
7320
if (!ps->extracted_all_failed_assumptions)
7321
extract_all_failed_assumptions (ps);
7322
lit = import_lit (ps, int_lit, 1);
7323
v = LIT2VAR (lit);
7324
return v->failed;
7325
}
7326
7327
int
7328
picosat_failed_context (PS * ps, int int_lit)
7329
{
7330
Lit * lit;
7331
Var * v;
7332
ABORTIF (!int_lit, "API usage: zero literal as context");
7333
ABORTIF (abs (int_lit) > (int) ps->max_var, "API usage: invalid context");
7334
check_ready (ps);
7335
check_unsat_state (ps);
7336
assert (ps->failed_assumption);
7337
if (!ps->extracted_all_failed_assumptions)
7338
extract_all_failed_assumptions (ps);
7339
lit = import_lit (ps, int_lit, 0);
7340
v = LIT2VAR (lit);
7341
return v->failed;
7342
}
7343
7344
const int *
7345
picosat_failed_assumptions (PS * ps)
7346
{
7347
Lit ** p, * lit;
7348
Var * v;
7349
int ilit;
7350
7351
ps->falshead = ps->fals;
7352
check_ready (ps);
7353
check_unsat_state (ps);
7354
if (!ps->mtcls)
7355
{
7356
assert (ps->failed_assumption);
7357
if (!ps->extracted_all_failed_assumptions)
7358
extract_all_failed_assumptions (ps);
7359
7360
for (p = ps->als; p < ps->alshead; p++)
7361
{
7362
lit = *p;
7363
v = LIT2VAR (*p);
7364
if (!v->failed)
7365
continue;
7366
ilit = LIT2INT (lit);
7367
if (ps->falshead == ps->eofals)
7368
ENLARGE (ps->fals, ps->falshead, ps->eofals);
7369
*ps->falshead++ = ilit;
7370
}
7371
}
7372
if (ps->falshead == ps->eofals)
7373
ENLARGE (ps->fals, ps->falshead, ps->eofals);
7374
*ps->falshead++ = 0;
7375
return ps->fals;
7376
}
7377
7378
const int *
7379
picosat_mus_assumptions (PS * ps, void * s, void (*cb)(void*,const int*), int fix)
7380
{
7381
int i, j, ilit, len, nwork, * work, res;
7382
signed char * redundant;
7383
Lit ** p, * lit;
7384
int failed;
7385
Var * v;
7386
#ifndef NDEBUG
7387
int oldlen;
7388
#endif
7389
#ifndef RCODE
7390
int norig = ps->alshead - ps->als;
7391
#endif
7392
7393
check_ready (ps);
7394
check_unsat_state (ps);
7395
len = 0;
7396
if (!ps->mtcls)
7397
{
7398
assert (ps->failed_assumption);
7399
if (!ps->extracted_all_failed_assumptions)
7400
extract_all_failed_assumptions (ps);
7401
7402
for (p = ps->als; p < ps->alshead; p++)
7403
if (LIT2VAR (*p)->failed)
7404
len++;
7405
}
7406
7407
if (ps->mass)
7408
DELETEN (ps->mass, ps->szmass);
7409
ps->szmass = len + 1;
7410
NEWN (ps->mass, ps->szmass);
7411
7412
i = 0;
7413
for (p = ps->als; p < ps->alshead; p++)
7414
{
7415
lit = *p;
7416
v = LIT2VAR (lit);
7417
if (!v->failed)
7418
continue;
7419
ilit = LIT2INT (lit);
7420
assert (i < len);
7421
ps->mass[i++] = ilit;
7422
}
7423
assert (i == len);
7424
ps->mass[i] = 0;
7425
if (ps->verbosity)
7426
fprintf (ps->out,
7427
"%sinitial set of failed assumptions of size %d out of %d (%.0f%%)\n",
7428
ps->prefix, len, norig, PERCENT (len, norig));
7429
if (cb)
7430
cb (s, ps->mass);
7431
7432
nwork = len;
7433
NEWN (work, nwork);
7434
for (i = 0; i < len; i++)
7435
work[i] = ps->mass[i];
7436
7437
NEWN (redundant, nwork);
7438
CLRN (redundant, nwork);
7439
7440
for (i = 0; i < nwork; i++)
7441
{
7442
if (redundant[i])
7443
continue;
7444
7445
if (ps->verbosity > 1)
7446
fprintf (ps->out,
7447
"%strying to drop %d%s assumption %d\n",
7448
ps->prefix, i, enumstr (i), work[i]);
7449
for (j = 0; j < nwork; j++)
7450
{
7451
if (i == j) continue;
7452
if (j < i && fix) continue;
7453
if (redundant[j]) continue;
7454
picosat_assume (ps, work[j]);
7455
}
7456
7457
res = picosat_sat (ps, -1);
7458
if (res == 10)
7459
{
7460
if (ps->verbosity > 1)
7461
fprintf (ps->out,
7462
"%sfailed to drop %d%s assumption %d\n",
7463
ps->prefix, i, enumstr (i), work[i]);
7464
7465
if (fix)
7466
{
7467
picosat_add (ps, work[i]);
7468
picosat_add (ps, 0);
7469
}
7470
}
7471
else
7472
{
7473
assert (res == 20);
7474
if (ps->verbosity > 1)
7475
fprintf (ps->out,
7476
"%ssuceeded to drop %d%s assumption %d\n",
7477
ps->prefix, i, enumstr (i), work[i]);
7478
redundant[i] = 1;
7479
for (j = 0; j < nwork; j++)
7480
{
7481
failed = picosat_failed_assumption (ps, work[j]);
7482
if (j <= i)
7483
{
7484
assert ((j < i && fix) || redundant[j] == !failed);
7485
continue;
7486
}
7487
7488
if (!failed)
7489
{
7490
redundant[j] = -1;
7491
if (ps->verbosity > 1)
7492
fprintf (ps->out,
7493
"%salso suceeded to drop %d%s assumption %d\n",
7494
ps->prefix, j, enumstr (j), work[j]);
7495
}
7496
}
7497
7498
#ifndef NDEBUG
7499
oldlen = len;
7500
#endif
7501
len = 0;
7502
for (j = 0; j < nwork; j++)
7503
if (!redundant[j])
7504
ps->mass[len++] = work[j];
7505
ps->mass[len] = 0;
7506
assert (len < oldlen);
7507
7508
if (fix)
7509
{
7510
picosat_add (ps, -work[i]);
7511
picosat_add (ps, 0);
7512
}
7513
7514
#ifndef NDEBUG
7515
for (j = 0; j <= i; j++)
7516
assert (redundant[j] >= 0);
7517
#endif
7518
for (j = i + 1; j < nwork; j++)
7519
{
7520
if (redundant[j] >= 0)
7521
continue;
7522
7523
if (fix)
7524
{
7525
picosat_add (ps, -work[j]);
7526
picosat_add (ps, 0);
7527
}
7528
7529
redundant[j] = 1;
7530
}
7531
7532
if (ps->verbosity)
7533
fprintf (ps->out,
7534
"%sreduced set of failed assumptions of size %d out of %d (%.0f%%)\n",
7535
ps->prefix, len, norig, PERCENT (len, norig));
7536
if (cb)
7537
cb (s, ps->mass);
7538
}
7539
}
7540
7541
DELETEN (work, nwork);
7542
DELETEN (redundant, nwork);
7543
7544
if (ps->verbosity)
7545
{
7546
fprintf (ps->out, "%sreinitializing unsat state\n", ps->prefix);
7547
fflush (ps->out);
7548
}
7549
7550
for (i = 0; i < len; i++)
7551
picosat_assume (ps, ps->mass[i]);
7552
7553
#ifndef NDEBUG
7554
res =
7555
#endif
7556
picosat_sat (ps, -1);
7557
assert (res == 20);
7558
7559
if (!ps->mtcls)
7560
{
7561
assert (!ps->extracted_all_failed_assumptions);
7562
extract_all_failed_assumptions (ps);
7563
}
7564
7565
return ps->mass;
7566
}
7567
7568
static const int *
7569
mss (PS * ps, int * a, int size)
7570
{
7571
int i, j, k, res;
7572
7573
assert (!ps->mtcls);
7574
7575
if (ps->szmssass)
7576
DELETEN (ps->mssass, ps->szmssass);
7577
7578
ps->szmssass = 0;
7579
ps->mssass = 0;
7580
7581
ps->szmssass = size + 1;
7582
NEWN (ps->mssass, ps->szmssass);
7583
7584
LOG ( fprintf (ps->out, "%ssearch MSS over %d assumptions\n", ps->prefix, size));
7585
7586
k = 0;
7587
for (i = k; i < size; i++)
7588
{
7589
for (j = 0; j < k; j++)
7590
picosat_assume (ps, ps->mssass[j]);
7591
7592
LOG ( fprintf (ps->out,
7593
"%strying to add assumption %d to MSS : %d\n",
7594
ps->prefix, i, a[i]));
7595
7596
picosat_assume (ps, a[i]);
7597
7598
res = picosat_sat (ps, -1);
7599
if (res == 10)
7600
{
7601
LOG ( fprintf (ps->out,
7602
"%sadding assumption %d to MSS : %d\n", ps->prefix, i, a[i]));
7603
7604
ps->mssass[k++] = a[i];
7605
7606
for (j = i + 1; j < size; j++)
7607
{
7608
if (picosat_deref (ps, a[j]) <= 0)
7609
continue;
7610
7611
LOG ( fprintf (ps->out,
7612
"%salso adding assumption %d to MSS : %d\n",
7613
ps->prefix, j, a[j]));
7614
7615
ps->mssass[k++] = a[j];
7616
7617
if (++i != j)
7618
{
7619
int tmp = a[i];
7620
a[i] = a[j];
7621
a[j] = tmp;
7622
}
7623
}
7624
}
7625
else
7626
{
7627
assert (res == 20);
7628
7629
LOG ( fprintf (ps->out,
7630
"%signoring assumption %d in MSS : %d\n", ps->prefix, i, a[i]));
7631
}
7632
}
7633
ps->mssass[k] = 0;
7634
LOG ( fprintf (ps->out, "%sfound MSS of size %d\n", ps->prefix, k));
7635
7636
return ps->mssass;
7637
}
7638
7639
static void
7640
reassume (PS * ps, const int * a, int size)
7641
{
7642
int i;
7643
LOG ( fprintf (ps->out, "%sreassuming all assumptions\n", ps->prefix));
7644
for (i = 0; i < size; i++)
7645
picosat_assume (ps, a[i]);
7646
}
7647
7648
const int *
7649
picosat_maximal_satisfiable_subset_of_assumptions (PS * ps)
7650
{
7651
const int * res;
7652
int i, *a, size;
7653
7654
ABORTIF (ps->mtcls,
7655
"API usage: CNF inconsistent (use 'picosat_inconsistent')");
7656
7657
enter (ps);
7658
7659
size = ps->alshead - ps->als;
7660
NEWN (a, size);
7661
7662
for (i = 0; i < size; i++)
7663
a[i] = LIT2INT (ps->als[i]);
7664
7665
res = mss (ps, a, size);
7666
reassume (ps, a, size);
7667
7668
DELETEN (a, size);
7669
7670
leave (ps);
7671
7672
return res;
7673
}
7674
7675
static void
7676
check_mss_flags_clean (PS * ps)
7677
{
7678
#ifndef NDEBUG
7679
unsigned i;
7680
for (i = 1; i <= ps->max_var; i++)
7681
{
7682
assert (!ps->vars[i].msspos);
7683
assert (!ps->vars[i].mssneg);
7684
}
7685
#else
7686
(void) ps;
7687
#endif
7688
}
7689
7690
static void
7691
push_mcsass (PS * ps, int lit)
7692
{
7693
if (ps->nmcsass == ps->szmcsass)
7694
{
7695
ps->szmcsass = ps->szmcsass ? 2*ps->szmcsass : 1;
7696
RESIZEN (ps->mcsass, ps->nmcsass, ps->szmcsass);
7697
}
7698
7699
ps->mcsass[ps->nmcsass++] = lit;
7700
}
7701
7702
static const int *
7703
next_mss (PS * ps, int mcs)
7704
{
7705
int i, *a, size, mssize, mcsize, lit, inmss;
7706
const int * res, * p;
7707
Var * v;
7708
7709
if (ps->mtcls) return 0;
7710
7711
check_mss_flags_clean (ps);
7712
7713
if (mcs && ps->mcsass)
7714
{
7715
DELETEN (ps->mcsass, ps->szmcsass);
7716
ps->nmcsass = ps->szmcsass = 0;
7717
ps->mcsass = 0;
7718
}
7719
7720
size = ps->alshead - ps->als;
7721
NEWN (a, size);
7722
7723
for (i = 0; i < size; i++)
7724
a[i] = LIT2INT (ps->als[i]);
7725
7726
(void) picosat_sat (ps, -1);
7727
7728
//TODO short cut for 'picosat_res () == 10'?
7729
7730
if (ps->mtcls)
7731
{
7732
assert (picosat_res (ps) == 20);
7733
res = 0;
7734
goto DONE;
7735
}
7736
7737
res = mss (ps, a, size);
7738
7739
if (ps->mtcls)
7740
{
7741
res = 0;
7742
goto DONE;
7743
}
7744
7745
for (p = res; (lit = *p); p++)
7746
{
7747
v = ps->vars + abs (lit);
7748
if (lit < 0)
7749
{
7750
assert (!v->msspos);
7751
v->mssneg = 1;
7752
}
7753
else
7754
{
7755
assert (!v->mssneg);
7756
v->msspos = 1;
7757
}
7758
}
7759
7760
mssize = p - res;
7761
mcsize = INT_MIN;
7762
7763
for (i = 0; i < size; i++)
7764
{
7765
lit = a[i];
7766
v = ps->vars + abs (lit);
7767
if (lit > 0 && v->msspos)
7768
inmss = 1;
7769
else if (lit < 0 && v->mssneg)
7770
inmss = 1;
7771
else
7772
inmss = 0;
7773
7774
if (mssize < mcsize)
7775
{
7776
if (inmss)
7777
picosat_add (ps, -lit);
7778
}
7779
else
7780
{
7781
if (!inmss)
7782
picosat_add (ps, lit);
7783
}
7784
7785
if (!inmss && mcs)
7786
push_mcsass (ps, lit);
7787
}
7788
picosat_add (ps, 0);
7789
if (mcs)
7790
push_mcsass (ps, 0);
7791
7792
for (i = 0; i < size; i++)
7793
{
7794
lit = a[i];
7795
v = ps->vars + abs (lit);
7796
v->msspos = 0;
7797
v->mssneg = 0;
7798
}
7799
7800
DONE:
7801
7802
reassume (ps, a, size);
7803
DELETEN (a, size);
7804
7805
return res;
7806
}
7807
7808
const int *
7809
picosat_next_maximal_satisfiable_subset_of_assumptions (PS * ps)
7810
{
7811
const int * res;
7812
enter (ps);
7813
res = next_mss (ps, 0);
7814
leave (ps);
7815
return res;
7816
}
7817
7818
const int *
7819
picosat_next_minimal_correcting_subset_of_assumptions (PS * ps)
7820
{
7821
const int * res, * tmp;
7822
enter (ps);
7823
tmp = next_mss (ps, 1);
7824
res = tmp ? ps->mcsass : 0;
7825
leave (ps);
7826
return res;
7827
}
7828
7829
const int *
7830
picosat_humus (PS * ps,
7831
void (*callback)(void*state,int nmcs,int nhumus),
7832
void * state)
7833
{
7834
int lit, nmcs, j, nhumus;
7835
const int * mcs, * p;
7836
unsigned i;
7837
Var * v;
7838
enter (ps);
7839
#ifndef NDEBUG
7840
for (i = 1; i <= ps->max_var; i++)
7841
{
7842
v = ps->vars + i;
7843
assert (!v->humuspos);
7844
assert (!v->humusneg);
7845
}
7846
#endif
7847
nhumus = nmcs = 0;
7848
while ((mcs = picosat_next_minimal_correcting_subset_of_assumptions (ps)))
7849
{
7850
for (p = mcs; (lit = *p); p++)
7851
{
7852
v = ps->vars + abs (lit);
7853
if (lit < 0)
7854
{
7855
if (!v->humusneg)
7856
{
7857
v->humusneg = 1;
7858
nhumus++;
7859
}
7860
}
7861
else
7862
{
7863
if (!v->humuspos)
7864
{
7865
v->humuspos = 1;
7866
nhumus++;
7867
}
7868
}
7869
}
7870
nmcs++;
7871
LOG ( fprintf (ps->out,
7872
"%smcs %d of size %d humus %d\n",
7873
ps->prefix, nmcs, (int)(p - mcs), nhumus));
7874
if (callback)
7875
callback (state, nmcs, nhumus);
7876
}
7877
assert (!ps->szhumus);
7878
ps->szhumus = 1;
7879
for (i = 1; i <= ps->max_var; i++)
7880
{
7881
v = ps->vars + i;
7882
if (v->humuspos)
7883
ps->szhumus++;
7884
if (v->humusneg)
7885
ps->szhumus++;
7886
}
7887
assert (nhumus + 1 == ps->szhumus);
7888
NEWN (ps->humus, ps->szhumus);
7889
j = 0;
7890
for (i = 1; i <= ps->max_var; i++)
7891
{
7892
v = ps->vars + i;
7893
if (v->humuspos)
7894
{
7895
assert (j < nhumus);
7896
ps->humus[j++] = (int) i;
7897
}
7898
if (v->humusneg)
7899
{
7900
assert (j < nhumus);
7901
assert (i < INT_MAX);
7902
ps->humus[j++] = - (int) i;
7903
}
7904
}
7905
assert (j == nhumus);
7906
assert (j < ps->szhumus);
7907
ps->humus[j] = 0;
7908
leave (ps);
7909
return ps->humus;
7910
}
7911
7912
int
7913
picosat_usedlit (PS * ps, int int_lit)
7914
{
7915
int res;
7916
check_ready (ps);
7917
check_sat_or_unsat_or_unknown_state (ps);
7918
ABORTIF (!int_lit, "API usage: zero literal can not be used");
7919
int_lit = abs (int_lit);
7920
res = (int_lit <= (int) ps->max_var) ? ps->vars[int_lit].used : 0;
7921
return res;
7922
}
7923
7924
void
7925
picosat_write_clausal_core (PS * ps, FILE * file)
7926
{
7927
check_trace_support_and_execute (ps, file, write_core_wrapper, 0);
7928
}
7929
7930
void
7931
picosat_write_compact_trace (PS * ps, FILE * file)
7932
{
7933
check_trace_support_and_execute (ps, file, write_trace,
7934
COMPACT_TRACECHECK_TRACE_FMT);
7935
}
7936
7937
void
7938
picosat_write_extended_trace (PS * ps, FILE * file)
7939
{
7940
check_trace_support_and_execute (ps, file, write_trace,
7941
EXTENDED_TRACECHECK_TRACE_FMT);
7942
}
7943
7944
void
7945
picosat_write_rup_trace (PS * ps, FILE * file)
7946
{
7947
check_trace_support_and_execute (ps, file, write_trace, RUP_TRACE_FMT);
7948
}
7949
7950
size_t
7951
picosat_max_bytes_allocated (PS * ps)
7952
{
7953
check_ready (ps);
7954
return ps->max_bytes;
7955
}
7956
7957
void
7958
picosat_set_propagation_limit (PS * ps, unsigned long long l)
7959
{
7960
ps->lpropagations = l;
7961
}
7962
7963
unsigned long long
7964
picosat_propagations (PS * ps)
7965
{
7966
return ps->propagations;
7967
}
7968
7969
unsigned long long
7970
picosat_visits (PS * ps)
7971
{
7972
return ps->visits;
7973
}
7974
7975
unsigned long long
7976
picosat_decisions (PS * ps)
7977
{
7978
return ps->decisions;
7979
}
7980
7981
int
7982
picosat_variables (PS * ps)
7983
{
7984
check_ready (ps);
7985
return (int) ps->max_var;
7986
}
7987
7988
int
7989
picosat_added_original_clauses (PS * ps)
7990
{
7991
check_ready (ps);
7992
return (int) ps->oadded;
7993
}
7994
7995
void
7996
picosat_stats (PS * ps)
7997
{
7998
#ifndef RCODE
7999
unsigned redlits;
8000
#endif
8001
#ifdef STATS
8002
check_ready (ps);
8003
assert (ps->sdecisions + ps->rdecisions + ps->assumptions == ps->decisions);
8004
#endif
8005
if (ps->calls > 1)
8006
fprintf (ps->out, "%s%u calls\n", ps->prefix, ps->calls);
8007
if (ps->contexts)
8008
{
8009
fprintf (ps->out, "%s%u contexts", ps->prefix, ps->contexts);
8010
#ifdef STATS
8011
fprintf (ps->out, " %u internal variables", ps->internals);
8012
#endif
8013
fprintf (ps->out, "\n");
8014
}
8015
fprintf (ps->out, "%s%u iterations\n", ps->prefix, ps->iterations);
8016
fprintf (ps->out, "%s%u restarts", ps->prefix, ps->restarts);
8017
#ifdef STATS
8018
fprintf (ps->out, " (%u skipped)", ps->skippedrestarts);
8019
#endif
8020
fputc ('\n', ps->out);
8021
#ifndef NFL
8022
fprintf (ps->out, "%s%u failed literals", ps->prefix, ps->failedlits);
8023
#ifdef STATS
8024
fprintf (ps->out,
8025
", %u calls, %u rounds, %llu propagations",
8026
ps->flcalls, ps->flrounds, ps->flprops);
8027
#endif
8028
fputc ('\n', ps->out);
8029
#ifdef STATS
8030
fprintf (ps->out,
8031
"%sfl: %u = %.1f%% implicit, %llu oopsed, %llu tried, %llu skipped\n",
8032
ps->prefix,
8033
ps->ifailedlits, PERCENT (ps->ifailedlits, ps->failedlits),
8034
ps->floopsed, ps->fltried, ps->flskipped);
8035
#endif
8036
#endif
8037
fprintf (ps->out, "%s%u conflicts", ps->prefix, ps->conflicts);
8038
#ifdef STATS
8039
fprintf (ps->out, " (%u uips = %.1f%%)\n", ps->uips, PERCENT(ps->uips,ps->conflicts));
8040
#else
8041
fputc ('\n', ps->out);
8042
#endif
8043
#ifndef NADC
8044
fprintf (ps->out, "%s%u adc conflicts\n", ps->prefix, ps->adoconflicts);
8045
#endif
8046
#ifdef STATS
8047
fprintf (ps->out, "%s%llu dereferenced literals\n", ps->prefix, ps->derefs);
8048
#endif
8049
fprintf (ps->out, "%s%u decisions", ps->prefix, ps->decisions);
8050
#ifdef STATS
8051
fprintf (ps->out, " (%u random = %.2f%%",
8052
ps->rdecisions, PERCENT (ps->rdecisions, ps->decisions));
8053
fprintf (ps->out, ", %u assumptions", ps->assumptions);
8054
fputc (')', ps->out);
8055
#endif
8056
fputc ('\n', ps->out);
8057
#ifdef STATS
8058
fprintf (ps->out,
8059
"%s%u static phase decisions (%.1f%% of all variables)\n",
8060
ps->prefix,
8061
ps->staticphasedecisions, PERCENT (ps->staticphasedecisions, ps->max_var));
8062
#endif
8063
fprintf (ps->out, "%s%u fixed variables\n", ps->prefix, ps->fixed);
8064
assert (ps->nonminimizedllits >= ps->minimizedllits);
8065
#ifndef RCODE
8066
redlits = ps->nonminimizedllits - ps->minimizedllits;
8067
#endif
8068
fprintf (ps->out, "%s%u learned literals\n", ps->prefix, ps->llitsadded);
8069
fprintf (ps->out, "%s%.1f%% deleted literals\n",
8070
ps->prefix, PERCENT (redlits, ps->nonminimizedllits));
8071
8072
#ifdef STATS
8073
#ifdef TRACE
8074
fprintf (ps->out,
8075
"%s%llu antecedents (%.1f antecedents per clause",
8076
ps->prefix, ps->antecedents, AVERAGE (ps->antecedents, ps->conflicts));
8077
if (ps->trace)
8078
fprintf (ps->out, ", %.1f bytes/antecedent)", AVERAGE (ps->znts, ps->antecedents));
8079
fputs (")\n", ps->out);
8080
#endif
8081
8082
fprintf (ps->out, "%s%llu propagations (%.1f propagations per decision)\n",
8083
ps->prefix, ps->propagations, AVERAGE (ps->propagations, ps->decisions));
8084
fprintf (ps->out, "%s%llu visits (%.1f per propagation)\n",
8085
ps->prefix, ps->visits, AVERAGE (ps->visits, ps->propagations));
8086
fprintf (ps->out,
8087
"%s%llu binary clauses visited (%.1f%% %.1f per propagation)\n",
8088
ps->prefix, ps->bvisits,
8089
PERCENT (ps->bvisits, ps->visits),
8090
AVERAGE (ps->bvisits, ps->propagations));
8091
fprintf (ps->out,
8092
"%s%llu ternary clauses visited (%.1f%% %.1f per propagation)\n",
8093
ps->prefix, ps->tvisits,
8094
PERCENT (ps->tvisits, ps->visits),
8095
AVERAGE (ps->tvisits, ps->propagations));
8096
fprintf (ps->out,
8097
"%s%llu large clauses visited (%.1f%% %.1f per propagation)\n",
8098
ps->prefix, ps->lvisits,
8099
PERCENT (ps->lvisits, ps->visits),
8100
AVERAGE (ps->lvisits, ps->propagations));
8101
fprintf (ps->out, "%s%llu other true (%.1f%% of visited clauses)\n",
8102
ps->prefix, ps->othertrue, PERCENT (ps->othertrue, ps->visits));
8103
fprintf (ps->out,
8104
"%s%llu other true in binary clauses (%.1f%%)"
8105
", %llu upper (%.1f%%)\n",
8106
ps->prefix, ps->othertrue2, PERCENT (ps->othertrue2, ps->othertrue),
8107
ps->othertrue2u, PERCENT (ps->othertrue2u, ps->othertrue2));
8108
fprintf (ps->out,
8109
"%s%llu other true in large clauses (%.1f%%)"
8110
", %llu upper (%.1f%%)\n",
8111
ps->prefix, ps->othertruel, PERCENT (ps->othertruel, ps->othertrue),
8112
ps->othertruelu, PERCENT (ps->othertruelu, ps->othertruel));
8113
fprintf (ps->out, "%s%llu ternary and large traversals (%.1f per visit)\n",
8114
ps->prefix, ps->traversals, AVERAGE (ps->traversals, ps->visits));
8115
fprintf (ps->out, "%s%llu large traversals (%.1f per large visit)\n",
8116
ps->prefix, ps->ltraversals, AVERAGE (ps->ltraversals, ps->lvisits));
8117
fprintf (ps->out, "%s%llu assignments\n", ps->prefix, ps->assignments);
8118
#else
8119
fprintf (ps->out, "%s%llu propagations\n", ps->prefix, picosat_propagations (ps));
8120
fprintf (ps->out, "%s%llu visits\n", ps->prefix, picosat_visits (ps));
8121
#endif
8122
fprintf (ps->out, "%s%.1f%% variables used\n", ps->prefix, PERCENT (ps->vused, ps->max_var));
8123
8124
sflush (ps);
8125
fprintf (ps->out, "%s%.1f seconds in library\n", ps->prefix, ps->seconds);
8126
fprintf (ps->out, "%s%.1f megaprops/second\n",
8127
ps->prefix, AVERAGE (ps->propagations / 1e6f, ps->seconds));
8128
fprintf (ps->out, "%s%.1f megavisits/second\n",
8129
ps->prefix, AVERAGE (ps->visits / 1e6f, ps->seconds));
8130
fprintf (ps->out, "%sprobing %.1f seconds %.0f%%\n",
8131
ps->prefix, ps->flseconds, PERCENT (ps->flseconds, ps->seconds));
8132
#ifdef STATS
8133
fprintf (ps->out,
8134
"%srecycled %.1f MB in %u reductions\n",
8135
ps->prefix, ps->rrecycled / (double) (1 << 20), ps->reductions);
8136
fprintf (ps->out,
8137
"%srecycled %.1f MB in %u simplifications\n",
8138
ps->prefix, ps->srecycled / (double) (1 << 20), ps->simps);
8139
#else
8140
fprintf (ps->out, "%s%u simplifications\n", ps->prefix, ps->simps);
8141
fprintf (ps->out, "%s%u reductions\n", ps->prefix, ps->reductions);
8142
fprintf (ps->out, "%s%.1f MB recycled\n", ps->prefix, ps->recycled / (double) (1 << 20));
8143
#endif
8144
fprintf (ps->out, "%s%.1f MB maximally allocated\n",
8145
ps->prefix, picosat_max_bytes_allocated (ps) / (double) (1 << 20));
8146
}
8147
8148
#ifndef NGETRUSAGE
8149
#include <sys/time.h>
8150
#include <sys/resource.h>
8151
#include <sys/unistd.h>
8152
#endif
8153
8154
double
8155
picosat_time_stamp (void)
8156
{
8157
double res = -1;
8158
#ifndef NGETRUSAGE
8159
struct rusage u;
8160
res = 0;
8161
if (!getrusage (RUSAGE_SELF, &u))
8162
{
8163
res += u.ru_utime.tv_sec + 1e-6 * u.ru_utime.tv_usec;
8164
res += u.ru_stime.tv_sec + 1e-6 * u.ru_stime.tv_usec;
8165
}
8166
#endif
8167
return res;
8168
}
8169
8170
double
8171
picosat_seconds (PS * ps)
8172
{
8173
check_ready (ps);
8174
return ps->seconds;
8175
}
8176
8177
void
8178
picosat_print (PS * ps, FILE * file)
8179
{
8180
#ifdef NO_BINARY_CLAUSES
8181
Lit * lit, *other, * last;
8182
Ltk * stack;
8183
#endif
8184
Lit **q, **eol;
8185
Cls **p, *c;
8186
unsigned n;
8187
8188
if (ps->measurealltimeinlib)
8189
enter (ps);
8190
else
8191
check_ready (ps);
8192
8193
n = 0;
8194
n += ps->alshead - ps->als;
8195
8196
for (p = SOC; p != EOC; p = NXC (p))
8197
{
8198
c = *p;
8199
8200
if (!c)
8201
continue;
8202
8203
#ifdef TRACE
8204
if (c->collected)
8205
continue;
8206
#endif
8207
n++;
8208
}
8209
8210
#ifdef NO_BINARY_CLAUSES
8211
last = int2lit (ps, -ps->max_var);
8212
for (lit = int2lit (ps, 1); lit <= last; lit++)
8213
{
8214
stack = LIT2IMPLS (lit);
8215
eol = stack->start + stack->count;
8216
for (q = stack->start; q < eol; q++)
8217
if (*q >= lit)
8218
n++;
8219
}
8220
#endif
8221
8222
fprintf (file, "p cnf %d %u\n", ps->max_var, n);
8223
8224
for (p = SOC; p != EOC; p = NXC (p))
8225
{
8226
c = *p;
8227
if (!c)
8228
continue;
8229
8230
#ifdef TRACE
8231
if (c->collected)
8232
continue;
8233
#endif
8234
8235
eol = end_of_lits (c);
8236
for (q = c->lits; q < eol; q++)
8237
fprintf (file, "%d ", LIT2INT (*q));
8238
8239
fputs ("0\n", file);
8240
}
8241
8242
#ifdef NO_BINARY_CLAUSES
8243
last = int2lit (ps, -ps->max_var);
8244
for (lit = int2lit (ps, 1); lit <= last; lit++)
8245
{
8246
stack = LIT2IMPLS (lit);
8247
eol = stack->start + stack->count;
8248
for (q = stack->start; q < eol; q++)
8249
if ((other = *q) >= lit)
8250
fprintf (file, "%d %d 0\n", LIT2INT (lit), LIT2INT (other));
8251
}
8252
#endif
8253
8254
{
8255
Lit **r;
8256
for (r = ps->als; r < ps->alshead; r++)
8257
fprintf (file, "%d 0\n", LIT2INT (*r));
8258
}
8259
8260
fflush (file);
8261
8262
if (ps->measurealltimeinlib)
8263
leave (ps);
8264
}
8265
8266
void
8267
picosat_enter (PS * ps)
8268
{
8269
enter (ps);
8270
}
8271
8272
void
8273
picosat_leave (PS * ps)
8274
{
8275
leave (ps);
8276
}
8277
8278
void
8279
picosat_message (PS * ps, int vlevel, const char * fmt, ...)
8280
{
8281
va_list ap;
8282
8283
if (vlevel > ps->verbosity)
8284
return;
8285
8286
fputs (ps->prefix, ps->out);
8287
va_start (ap, fmt);
8288
vfprintf (ps->out, fmt, ap);
8289
va_end (ap);
8290
fputc ('\n', ps->out);
8291
}
8292
8293
int
8294
picosat_changed (PS * ps)
8295
{
8296
int res;
8297
8298
check_ready (ps);
8299
check_sat_state (ps);
8300
8301
res = (ps->min_flipped <= ps->saved_max_var);
8302
assert (!res || ps->saved_flips != ps->flips);
8303
8304
return res;
8305
}
8306
8307
void
8308
picosat_reset_phases (PS * ps)
8309
{
8310
rebias (ps);
8311
}
8312
8313
void
8314
picosat_reset_scores (PS * ps)
8315
{
8316
Rnk * r;
8317
ps->hhead = ps->heap + 1;
8318
for (r = ps->rnks + 1; r <= ps->rnks + ps->max_var; r++)
8319
{
8320
CLR (r);
8321
hpush (ps, r);
8322
}
8323
}
8324
8325
void
8326
picosat_remove_learned (PS * ps, unsigned percentage)
8327
{
8328
enter (ps);
8329
reset_incremental_usage (ps);
8330
reduce (ps, percentage);
8331
leave (ps);
8332
}
8333
8334
void
8335
picosat_set_global_default_phase (PS * ps, int phase)
8336
{
8337
check_ready (ps);
8338
ABORTIF (phase < 0, "API usage: 'picosat_set_global_default_phase' "
8339
"with negative argument");
8340
ABORTIF (phase > 3, "API usage: 'picosat_set_global_default_phase' "
8341
"with argument > 3");
8342
ps->defaultphase = phase;
8343
}
8344
8345
void
8346
picosat_set_default_phase_lit (PS * ps, int int_lit, int phase)
8347
{
8348
unsigned newphase;
8349
Lit * lit;
8350
Var * v;
8351
8352
check_ready (ps);
8353
8354
lit = import_lit (ps, int_lit, 1);
8355
v = LIT2VAR (lit);
8356
8357
if (phase)
8358
{
8359
newphase = (int_lit < 0) == (phase < 0);
8360
v->defphase = v->phase = newphase;
8361
v->usedefphase = v->assigned = 1;
8362
}
8363
else
8364
{
8365
v->usedefphase = v->assigned = 0;
8366
}
8367
}
8368
8369
void
8370
picosat_set_more_important_lit (PS * ps, int int_lit)
8371
{
8372
Lit * lit;
8373
Var * v;
8374
Rnk * r;
8375
8376
check_ready (ps);
8377
8378
lit = import_lit (ps, int_lit, 1);
8379
v = LIT2VAR (lit);
8380
r = VAR2RNK (v);
8381
8382
ABORTIF (r->lessimportant, "can not mark variable more and less important");
8383
8384
if (r->moreimportant)
8385
return;
8386
8387
r->moreimportant = 1;
8388
8389
if (r->pos)
8390
hup (ps, r);
8391
}
8392
8393
void
8394
picosat_set_less_important_lit (PS * ps, int int_lit)
8395
{
8396
Lit * lit;
8397
Var * v;
8398
Rnk * r;
8399
8400
check_ready (ps);
8401
8402
lit = import_lit (ps, int_lit, 1);
8403
v = LIT2VAR (lit);
8404
r = VAR2RNK (v);
8405
8406
ABORTIF (r->moreimportant, "can not mark variable more and less important");
8407
8408
if (r->lessimportant)
8409
return;
8410
8411
r->lessimportant = 1;
8412
8413
if (r->pos)
8414
hdown (ps, r);
8415
}
8416
8417
#ifndef NADC
8418
8419
unsigned
8420
picosat_ado_conflicts (PS * ps)
8421
{
8422
check_ready (ps);
8423
return ps->adoconflicts;
8424
}
8425
8426
void
8427
picosat_disable_ado (PS * ps)
8428
{
8429
check_ready (ps);
8430
assert (!ps->adodisabled);
8431
ps->adodisabled = 1;
8432
}
8433
8434
void
8435
picosat_enable_ado (PS * ps)
8436
{
8437
check_ready (ps);
8438
assert (ps->adodisabled);
8439
ps->adodisabled = 0;
8440
}
8441
8442
void
8443
picosat_set_ado_conflict_limit (PS * ps, unsigned newadoconflictlimit)
8444
{
8445
check_ready (ps);
8446
ps->adoconflictlimit = newadoconflictlimit;
8447
}
8448
8449
#endif
8450
8451
void
8452
picosat_simplify (PS * ps)
8453
{
8454
enter (ps);
8455
reset_incremental_usage (ps);
8456
simplify (ps, 1);
8457
leave (ps);
8458
}
8459
8460
int
8461
picosat_haveados (void)
8462
{
8463
#ifndef NADC
8464
return 1;
8465
#else
8466
return 0;
8467
#endif
8468
}
8469
8470
void
8471
picosat_save_original_clauses (PS * ps)
8472
{
8473
if (ps->saveorig) return;
8474
ABORTIF (ps->oadded, "API usage: 'picosat_save_original_clauses' too late");
8475
ps->saveorig = 1;
8476
}
8477
8478
void picosat_set_interrupt (PicoSAT * ps,
8479
void * external_state,
8480
int (*interrupted)(void * external_state))
8481
{
8482
ps->interrupt.state = external_state;
8483
ps->interrupt.function = interrupted;
8484
}
8485
8486
int
8487
picosat_deref_partial (PS * ps, int int_lit)
8488
{
8489
check_ready (ps);
8490
check_sat_state (ps);
8491
ABORTIF (!int_lit, "API usage: can not partial deref zero literal");
8492
ABORTIF (ps->mtcls, "API usage: deref partial after empty clause generated");
8493
ABORTIF (!ps->saveorig, "API usage: 'picosat_save_original_clauses' missing");
8494
8495
#ifdef STATS
8496
ps->derefs++;
8497
#endif
8498
8499
if (!ps->partial)
8500
minautarky (ps);
8501
8502
return pderef (ps, int_lit);
8503
}
8504
8505