ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
satSolver.c
Go to the documentation of this file.
1/**************************************************************************************************
2MiniSat -- Copyright (c) 2005, Niklas Sorensson
3http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/
4
5Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6associated documentation files (the "Software"), to deal in the Software without restriction,
7including without limitation the rights to use, copy, modify, merge, publish, distribute,
8sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all copies or
12substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19**************************************************************************************************/
20// Modified to compile with MS Visual Studio 6.0 by Alan Mishchenko
21
22#include <stdio.h>
23#include <assert.h>
24#include <string.h>
25#include <math.h>
26
27#include "satSolver.h"
28#include "satStore.h"
29
31
32#define SAT_USE_ANALYZE_FINAL
33
34//=================================================================================================
35// Debug:
36
37//#define VERBOSEDEBUG
38
39// For derivation output (verbosity level 2)
40#define L_IND "%-*d"
41#define L_ind sat_solver_dl(s)*2+2,sat_solver_dl(s)
42#define L_LIT "%sx%d"
43#define L_lit(p) lit_sign(p)?"~":"", (lit_var(p))
44
45// Just like 'assert()' but expression will be evaluated in the release version as well.
46static inline void check(int expr) { assert(expr); }
47
48static void printlits(lit* begin, lit* end)
49{
50 int i;
51 for (i = 0; i < end - begin; i++)
52 printf(L_LIT" ",L_lit(begin[i]));
53}
54
55//=================================================================================================
56// Random numbers:
57
58
59// Returns a random float 0 <= x < 1. Seed must never be 0.
60static inline double drand(double* seed) {
61 int q;
62 *seed *= 1389796;
63 q = (int)(*seed * 4.6566128752457969e-10); // 1.0/2147483647.0;
64 *seed -= (double)q * 2147483647;
65 return *seed * 4.6566128752457969e-10; // 1.0/2147483647.0
66}
67
68
69// Returns a random integer 0 <= x < size. Seed must never be 0.
70static inline int irand(double* seed, int size) {
71 return (int)(drand(seed) * size); }
72
73
74//=================================================================================================
75// Variable datatype + minor functions:
76
77static const int var0 = 1;
78static const int var1 = 0;
79static const int varX = 3;
80
82{
83 unsigned val : 2; // variable value
84 unsigned pol : 1; // last polarity
85 unsigned tag : 1; // conflict analysis tag
86 unsigned lev : 28; // variable level
87};
88
89static inline int var_level (sat_solver* s, int v) { return s->levels[v]; }
90static inline int var_value (sat_solver* s, int v) { return s->assigns[v]; }
91static inline int var_polar (sat_solver* s, int v) { return s->polarity[v]; }
92
93static inline void var_set_level (sat_solver* s, int v, int lev) { s->levels[v] = lev; }
94static inline void var_set_value (sat_solver* s, int v, int val) { s->assigns[v] = val; }
95static inline void var_set_polar (sat_solver* s, int v, int pol) { s->polarity[v] = pol; }
96
97// variable tags
98static inline int var_tag (sat_solver* s, int v) { return s->tags[v]; }
99static inline void var_set_tag (sat_solver* s, int v, int tag) {
100 assert( tag > 0 && tag < 16 );
101 if ( s->tags[v] == 0 )
102 veci_push( &s->tagged, v );
103 s->tags[v] = tag;
104}
105static inline void var_add_tag (sat_solver* s, int v, int tag) {
106 assert( tag > 0 && tag < 16 );
107 if ( s->tags[v] == 0 )
108 veci_push( &s->tagged, v );
109 s->tags[v] |= tag;
110}
111static inline void solver2_clear_tags(sat_solver* s, int start) {
112 int i, * tagged = veci_begin(&s->tagged);
113 for (i = start; i < veci_size(&s->tagged); i++)
114 s->tags[tagged[i]] = 0;
115 veci_resize(&s->tagged,start);
116}
117
119{
120 if ( var_value(s, v) == var0 )
121 return l_False;
122 if ( var_value(s, v) == var1 )
123 return l_True;
124 if ( var_value(s, v) == varX )
125 return l_Undef;
126 assert( 0 );
127 return 0;
128}
129
130//=================================================================================================
131// Simple helpers:
132
133static inline int sat_solver_dl(sat_solver* s) { return veci_size(&s->trail_lim); }
134static inline veci* sat_solver_read_wlist(sat_solver* s, lit l) { return &s->wlists[l]; }
135
136//=================================================================================================
137// Variable order functions:
138
139static inline void order_update(sat_solver* s, int v) // updateorder
140{
141 int* orderpos = s->orderpos;
142 int* heap = veci_begin(&s->order);
143 int i = orderpos[v];
144 int x = heap[i];
145 int parent = (i - 1) / 2;
146
147 assert(s->orderpos[v] != -1);
148
149 while (i != 0 && s->activity[x] > s->activity[heap[parent]]){
150 heap[i] = heap[parent];
151 orderpos[heap[i]] = i;
152 i = parent;
153 parent = (i - 1) / 2;
154 }
155
156 heap[i] = x;
157 orderpos[x] = i;
158}
159
160static inline void order_assigned(sat_solver* s, int v)
161{
162}
163
164static inline void order_unassigned(sat_solver* s, int v) // undoorder
165{
166 int* orderpos = s->orderpos;
167 if (orderpos[v] == -1){
168 orderpos[v] = veci_size(&s->order);
169 veci_push(&s->order,v);
170 order_update(s,v);
171//printf( "+%d ", v );
172 }
173}
174
175static inline int order_select(sat_solver* s, float random_var_freq) // selectvar
176{
177 int* heap = veci_begin(&s->order);
178 int* orderpos = s->orderpos;
179 // Random decision:
180 if (drand(&s->random_seed) < random_var_freq){
181 int next = irand(&s->random_seed,s->size);
182 assert(next >= 0 && next < s->size);
183 if (var_value(s, next) == varX)
184 return next;
185 }
186 // Activity based decision:
187 while (veci_size(&s->order) > 0){
188 int next = heap[0];
189 int size = veci_size(&s->order)-1;
190 int x = heap[size];
191 veci_resize(&s->order,size);
192 orderpos[next] = -1;
193 if (size > 0){
194 int i = 0;
195 int child = 1;
196 while (child < size){
197
198 if (child+1 < size && s->activity[heap[child]] < s->activity[heap[child+1]])
199 child++;
200 assert(child < size);
201 if (s->activity[x] >= s->activity[heap[child]])
202 break;
203
204 heap[i] = heap[child];
205 orderpos[heap[i]] = i;
206 i = child;
207 child = 2 * child + 1;
208 }
209 heap[i] = x;
210 orderpos[heap[i]] = i;
211 }
212 if (var_value(s, next) == varX)
213 return next;
214 }
215 return var_Undef;
216}
217
218void sat_solver_set_var_activity(sat_solver* s, int * pVars, int nVars)
219{
220 int i;
221 for (i = 0; i < s->size; i++)
222 s->activity[i] = 0;
223 if ( s->VarActType == 0 )
224 {
225 s->var_inc = (1 << 5);
226 s->var_decay = -1;
227 for ( i = 0; i < nVars; i++ )
228 {
229 int iVar = pVars ? pVars[i] : i;
230 s->activity[iVar] = s->var_inc*(nVars-i);
231 if (s->orderpos[iVar] != -1)
232 order_update( s, iVar );
233 }
234 }
235 else if ( s->VarActType == 1 )
236 {
237 s->var_inc = Abc_Dbl2Word(1);
238 for ( i = 0; i < nVars; i++ )
239 {
240 int iVar = pVars ? pVars[i] : i;
241 s->activity[iVar] = Abc_Dbl2Word(nVars-i);
242 if (s->orderpos[iVar] != -1)
243 order_update( s, iVar );
244 }
245 }
246 else assert( 0 );
247}
248
249//=================================================================================================
250// variable activities
251
252static inline void solver_init_activities(sat_solver* s)
253{
254 // variable activities
255 s->VarActType = 0;
256 if ( s->VarActType == 0 )
257 {
258 s->var_inc = (1 << 5);
259 s->var_decay = -1;
260 }
261 else if ( s->VarActType == 1 )
262 {
263 s->var_inc = Abc_Dbl2Word(1.0);
264 s->var_decay = Abc_Dbl2Word(1.0 / 0.95);
265 }
266 else if ( s->VarActType == 2 )
267 {
268 s->var_inc = Xdbl_FromDouble(1.0);
269 s->var_decay = Xdbl_FromDouble(1.0 / 0.950);
270 }
271 else assert(0);
272
273 // clause activities
274 s->ClaActType = 0;
275 if ( s->ClaActType == 0 )
276 {
277 s->cla_inc = (1 << 11);
278 s->cla_decay = -1;
279 }
280 else
281 {
282 s->cla_inc = 1;
283 s->cla_decay = (float)(1 / 0.999);
284 }
285}
286
287static inline void act_var_rescale(sat_solver* s)
288{
289 if ( s->VarActType == 0 )
290 {
291 word* activity = s->activity;
292 int i;
293 for (i = 0; i < s->size; i++)
294 activity[i] >>= 19;
295 s->var_inc >>= 19;
296 s->var_inc = Abc_MaxInt( (unsigned)s->var_inc, (1<<4) );
297 }
298 else if ( s->VarActType == 1 )
299 {
300 double* activity = (double*)s->activity;
301 int i;
302 for (i = 0; i < s->size; i++)
303 activity[i] *= 1e-100;
304 s->var_inc = Abc_Dbl2Word( Abc_Word2Dbl(s->var_inc) * 1e-100 );
305 //printf( "Rescaling var activity...\n" );
306 }
307 else if ( s->VarActType == 2 )
308 {
309 xdbl * activity = s->activity;
310 int i;
311 for (i = 0; i < s->size; i++)
312 activity[i] = Xdbl_Div( activity[i], 200 ); // activity[i] / 2^200
313 s->var_inc = Xdbl_Div( s->var_inc, 200 );
314 }
315 else assert(0);
316}
317static inline void act_var_bump(sat_solver* s, int v)
318{
319 if ( s->VarActType == 0 )
320 {
321 s->activity[v] += s->var_inc;
322 if ((unsigned)s->activity[v] & 0x80000000)
323 act_var_rescale(s);
324 if (s->orderpos[v] != -1)
325 order_update(s,v);
326 }
327 else if ( s->VarActType == 1 )
328 {
329 double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc);
330 s->activity[v] = Abc_Dbl2Word(act);
331 if (act > 1e100)
332 act_var_rescale(s);
333 if (s->orderpos[v] != -1)
334 order_update(s,v);
335 }
336 else if ( s->VarActType == 2 )
337 {
338 s->activity[v] = Xdbl_Add( s->activity[v], s->var_inc );
339 if (s->activity[v] > ABC_CONST(0x014c924d692ca61b))
340 act_var_rescale(s);
341 if (s->orderpos[v] != -1)
342 order_update(s,v);
343 }
344 else assert(0);
345}
346static inline void act_var_bump_global(sat_solver* s, int v)
347{
348 if ( !s->pGlobalVars || !s->pGlobalVars[v] )
349 return;
350 if ( s->VarActType == 0 )
351 {
352 s->activity[v] += (int)((unsigned)s->var_inc * 3);
353 if (s->activity[v] & 0x80000000)
354 act_var_rescale(s);
355 if (s->orderpos[v] != -1)
356 order_update(s,v);
357 }
358 else if ( s->VarActType == 1 )
359 {
360 double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc) * 3.0;
361 s->activity[v] = Abc_Dbl2Word(act);
362 if ( act > 1e100)
363 act_var_rescale(s);
364 if (s->orderpos[v] != -1)
365 order_update(s,v);
366 }
367 else if ( s->VarActType == 2 )
368 {
369 s->activity[v] = Xdbl_Add( s->activity[v], Xdbl_Mul(s->var_inc, Xdbl_FromDouble(3.0)) );
370 if (s->activity[v] > ABC_CONST(0x014c924d692ca61b))
371 act_var_rescale(s);
372 if (s->orderpos[v] != -1)
373 order_update(s,v);
374 }
375 else assert( 0 );
376}
377static inline void act_var_bump_factor(sat_solver* s, int v)
378{
379 if ( !s->factors )
380 return;
381 if ( s->VarActType == 0 )
382 {
383 s->activity[v] += (int)((unsigned)s->var_inc * (float)s->factors[v]);
384 if (s->activity[v] & 0x80000000)
385 act_var_rescale(s);
386 if (s->orderpos[v] != -1)
387 order_update(s,v);
388 }
389 else if ( s->VarActType == 1 )
390 {
391 double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc) * s->factors[v];
392 s->activity[v] = Abc_Dbl2Word(act);
393 if ( act > 1e100)
394 act_var_rescale(s);
395 if (s->orderpos[v] != -1)
396 order_update(s,v);
397 }
398 else if ( s->VarActType == 2 )
399 {
400 s->activity[v] = Xdbl_Add( s->activity[v], Xdbl_Mul(s->var_inc, Xdbl_FromDouble(s->factors[v])) );
401 if (s->activity[v] > ABC_CONST(0x014c924d692ca61b))
402 act_var_rescale(s);
403 if (s->orderpos[v] != -1)
404 order_update(s,v);
405 }
406 else assert( 0 );
407}
408
409static inline void act_var_decay(sat_solver* s)
410{
411 if ( s->VarActType == 0 )
412 s->var_inc += (s->var_inc >> 4);
413 else if ( s->VarActType == 1 )
414 s->var_inc = Abc_Dbl2Word( Abc_Word2Dbl(s->var_inc) * Abc_Word2Dbl(s->var_decay) );
415 else if ( s->VarActType == 2 )
416 s->var_inc = Xdbl_Mul(s->var_inc, s->var_decay);
417 else assert(0);
418}
419
420// clause activities
421static inline void act_clause_rescale(sat_solver* s)
422{
423 if ( s->ClaActType == 0 )
424 {
425 unsigned* activity = (unsigned *)veci_begin(&s->act_clas);
426 int i;
427 for (i = 0; i < veci_size(&s->act_clas); i++)
428 activity[i] >>= 14;
429 s->cla_inc >>= 14;
430 s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) );
431 }
432 else
433 {
434 float* activity = (float *)veci_begin(&s->act_clas);
435 int i;
436 for (i = 0; i < veci_size(&s->act_clas); i++)
437 activity[i] *= (float)1e-20;
438 s->cla_inc *= (float)1e-20;
439 }
440}
441static inline void act_clause_bump(sat_solver* s, clause *c)
442{
443 if ( s->ClaActType == 0 )
444 {
445 unsigned* act = (unsigned *)veci_begin(&s->act_clas) + c->lits[c->size];
446 *act += s->cla_inc;
447 if ( *act & 0x80000000 )
448 act_clause_rescale(s);
449 }
450 else
451 {
452 float* act = (float *)veci_begin(&s->act_clas) + c->lits[c->size];
453 *act += s->cla_inc;
454 if (*act > 1e20)
455 act_clause_rescale(s);
456 }
457}
458static inline void act_clause_decay(sat_solver* s)
459{
460 if ( s->ClaActType == 0 )
461 s->cla_inc += (s->cla_inc >> 10);
462 else
463 s->cla_inc *= s->cla_decay;
464}
465
466
467//=================================================================================================
468// Sorting functions (sigh):
469
470static inline void selectionsort(void** array, int size, int(*comp)(const void *, const void *))
471{
472 int i, j, best_i;
473 void* tmp;
474
475 for (i = 0; i < size-1; i++){
476 best_i = i;
477 for (j = i+1; j < size; j++){
478 if (comp(array[j], array[best_i]) < 0)
479 best_i = j;
480 }
481 tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
482 }
483}
484
485static void sortrnd(void** array, int size, int(*comp)(const void *, const void *), double* seed)
486{
487 if (size <= 15)
488 selectionsort(array, size, comp);
489
490 else{
491 void* pivot = array[irand(seed, size)];
492 void* tmp;
493 int i = -1;
494 int j = size;
495
496 for(;;){
497 do i++; while(comp(array[i], pivot)<0);
498 do j--; while(comp(pivot, array[j])<0);
499
500 if (i >= j) break;
501
502 tmp = array[i]; array[i] = array[j]; array[j] = tmp;
503 }
504
505 sortrnd(array , i , comp, seed);
506 sortrnd(&array[i], size-i, comp, seed);
507 }
508}
509
510//=================================================================================================
511// Clause functions:
512
513static inline int sat_clause_compute_lbd( sat_solver* s, clause* c )
514{
515 unsigned int i, lev, minl = 0;
516 int lbd = 0;
517 for (i = 0; i < c->size; i++)
518 {
519 lev = var_level(s, lit_var(c->lits[i]));
520 if ( !(minl & (1U << (lev & 31))) )
521 {
522 minl |= 1U << (lev & 31);
523 lbd++;
524// printf( "%d ", lev );
525 }
526 }
527// printf( " -> %d\n", lbd );
528 return lbd;
529}
530
531/* pre: size > 1 && no variable occurs twice
532 */
533int sat_solver_clause_new(sat_solver* s, lit* begin, lit* end, int learnt)
534{
535 int fUseBinaryClauses = 1;
536 int size;
537 clause* c;
538 int h;
539
540 assert(end - begin > 1);
541 assert(learnt >= 0 && learnt < 2);
542 size = end - begin;
543
544 // do not allocate memory for the two-literal problem clause
545 if ( fUseBinaryClauses && size == 2 && !learnt )
546 {
547 veci_push(sat_solver_read_wlist(s,lit_neg(begin[0])),(clause_from_lit(begin[1])));
548 veci_push(sat_solver_read_wlist(s,lit_neg(begin[1])),(clause_from_lit(begin[0])));
549 s->stats.clauses++;
550 s->stats.clauses_literals += size;
551 return 0;
552 }
553
554 // create new clause
555// h = Vec_SetAppend( &s->Mem, NULL, size + learnt + 1 + 1 ) << 1;
556 h = Sat_MemAppend( &s->Mem, begin, size, learnt, 0 );
557 assert( !(h & 1) );
558 if ( s->hLearnts == -1 && learnt )
559 s->hLearnts = h;
560 if (learnt)
561 {
562 c = clause_read( s, h );
563 c->lbd = sat_clause_compute_lbd( s, c );
564 assert( clause_id(c) == veci_size(&s->act_clas) );
565// veci_push(&s->learned, h);
566// act_clause_bump(s,clause_read(s, h));
567 if ( s->ClaActType == 0 )
568 veci_push(&s->act_clas, (1<<10));
569 else
570 veci_push(&s->act_clas, s->cla_inc);
571 s->stats.learnts++;
572 s->stats.learnts_literals += size;
573 }
574 else
575 {
576 s->stats.clauses++;
577 s->stats.clauses_literals += size;
578 }
579
580 assert(begin[0] >= 0);
581 assert(begin[0] < s->size*2);
582 assert(begin[1] >= 0);
583 assert(begin[1] < s->size*2);
584
585 assert(lit_neg(begin[0]) < s->size*2);
586 assert(lit_neg(begin[1]) < s->size*2);
587
588 //veci_push(sat_solver_read_wlist(s,lit_neg(begin[0])),c);
589 //veci_push(sat_solver_read_wlist(s,lit_neg(begin[1])),c);
590 veci_push(sat_solver_read_wlist(s,lit_neg(begin[0])),(size > 2 ? h : clause_from_lit(begin[1])));
591 veci_push(sat_solver_read_wlist(s,lit_neg(begin[1])),(size > 2 ? h : clause_from_lit(begin[0])));
592
593 return h;
594}
595
596
597//=================================================================================================
598// Minor (solver) functions:
599
600static inline int sat_solver_enqueue(sat_solver* s, lit l, int from)
601{
602 int v = lit_var(l);
603 if ( s->pFreqs[v] == 0 )
604// {
605 s->pFreqs[v] = 1;
606// s->nVarUsed++;
607// }
608
609#ifdef VERBOSEDEBUG
610 printf(L_IND"enqueue("L_LIT")\n", L_ind, L_lit(l));
611#endif
612 if (var_value(s, v) != varX)
613 return var_value(s, v) == lit_sign(l);
614 else{
615/*
616 if ( s->pCnfFunc )
617 {
618 if ( lit_sign(l) )
619 {
620 if ( (s->loads[v] & 1) == 0 )
621 {
622 s->loads[v] ^= 1;
623 s->pCnfFunc( s->pCnfMan, l );
624 }
625 }
626 else
627 {
628 if ( (s->loads[v] & 2) == 0 )
629 {
630 s->loads[v] ^= 2;
631 s->pCnfFunc( s->pCnfMan, l );
632 }
633 }
634 }
635*/
636 // New fact -- store it.
637#ifdef VERBOSEDEBUG
638 printf(L_IND"bind("L_LIT")\n", L_ind, L_lit(l));
639#endif
640 var_set_value(s, v, lit_sign(l));
641 var_set_level(s, v, sat_solver_dl(s));
642 s->reasons[v] = from;
643 s->trail[s->qtail++] = l;
644 order_assigned(s, v);
645 return true;
646 }
647}
648
649
650static inline int sat_solver_decision(sat_solver* s, lit l){
651 assert(s->qtail == s->qhead);
652 assert(var_value(s, lit_var(l)) == varX);
653#ifdef VERBOSEDEBUG
654 printf(L_IND"assume("L_LIT") ", L_ind, L_lit(l));
655 printf( "act = %.20f\n", s->activity[lit_var(l)] );
656#endif
657 veci_push(&s->trail_lim,s->qtail);
658 return sat_solver_enqueue(s,l,0);
659}
660
661
662static void sat_solver_canceluntil(sat_solver* s, int level) {
663 int bound;
664 int lastLev;
665 int c;
666
667 if (sat_solver_dl(s) <= level)
668 return;
669
670 assert( veci_size(&s->trail_lim) > 0 );
671 bound = (veci_begin(&s->trail_lim))[level];
672 lastLev = (veci_begin(&s->trail_lim))[veci_size(&s->trail_lim)-1];
673
675 // added to cancel all assignments
676// if ( level == -1 )
677// bound = 0;
679
680 for (c = s->qtail-1; c >= bound; c--) {
681 int x = lit_var(s->trail[c]);
682 var_set_value(s, x, varX);
683 s->reasons[x] = 0;
684 if ( c < lastLev )
685 var_set_polar( s, x, !lit_sign(s->trail[c]) );
686 }
687 //printf( "\n" );
688
689 for (c = s->qhead-1; c >= bound; c--)
690 order_unassigned(s,lit_var(s->trail[c]));
691
692 s->qhead = s->qtail = bound;
693 veci_resize(&s->trail_lim,level);
694}
695
696static void sat_solver_canceluntil_rollback(sat_solver* s, int NewBound) {
697 int c, x;
698
699 assert( sat_solver_dl(s) == 0 );
700 assert( s->qtail == s->qhead );
701 assert( s->qtail >= NewBound );
702
703 for (c = s->qtail-1; c >= NewBound; c--)
704 {
705 x = lit_var(s->trail[c]);
706 var_set_value(s, x, varX);
707 s->reasons[x] = 0;
708 }
709
710 for (c = s->qhead-1; c >= NewBound; c--)
711 order_unassigned(s,lit_var(s->trail[c]));
712
713 s->qhead = s->qtail = NewBound;
714}
715
716static void sat_solver_record(sat_solver* s, veci* cls)
717{
718 lit* begin = veci_begin(cls);
719 lit* end = begin + veci_size(cls);
720 int h = (veci_size(cls) > 1) ? sat_solver_clause_new(s,begin,end,1) : 0;
721 sat_solver_enqueue(s,*begin,h);
722 assert(veci_size(cls) > 0);
723 if ( h == 0 )
724 veci_push( &s->unit_lits, *begin );
725
727 // add clause to internal storage
728 if ( s->pStore )
729 {
730 int RetValue = Sto_ManAddClause( (Sto_Man_t *)s->pStore, begin, end );
731 assert( RetValue );
732 (void) RetValue;
733 }
735/*
736 if (h != 0) {
737 act_clause_bump(s,clause_read(s, h));
738 s->stats.learnts++;
739 s->stats.learnts_literals += veci_size(cls);
740 }
741*/
742}
743
745{
746 // count top-level assignments
747 int i, Count = 0;
748 assert(sat_solver_dl(s) == 0);
749 for ( i = 0; i < s->size; i++ )
750 if (var_value(s, i) != varX)
751 Count++;
752 return Count;
753}
754
755static double sat_solver_progress(sat_solver* s)
756{
757 int i;
758 double progress = 0;
759 double F = 1.0 / s->size;
760 for (i = 0; i < s->size; i++)
761 if (var_value(s, i) != varX)
762 progress += pow(F, var_level(s, i));
763 return progress / s->size;
764}
765
766//=================================================================================================
767// Major methods:
768
769static int sat_solver_lit_removable(sat_solver* s, int x, int minl)
770{
771 int top = veci_size(&s->tagged);
772
773 assert(s->reasons[x] != 0);
774 veci_resize(&s->stack,0);
775 veci_push(&s->stack,x);
776
777 while (veci_size(&s->stack)){
778 int v = veci_pop(&s->stack);
779 assert(s->reasons[v] != 0);
780 if (clause_is_lit(s->reasons[v])){
781 v = lit_var(clause_read_lit(s->reasons[v]));
782 if (!var_tag(s,v) && var_level(s, v)){
783 if (s->reasons[v] != 0 && ((1 << (var_level(s, v) & 31)) & minl)){
784 veci_push(&s->stack,v);
785 var_set_tag(s, v, 1);
786 }else{
787 solver2_clear_tags(s, top);
788 return 0;
789 }
790 }
791 }else{
792 clause* c = clause_read(s, s->reasons[v]);
793 lit* lits = clause_begin(c);
794 int i;
795 for (i = 1; i < clause_size(c); i++){
796 int v = lit_var(lits[i]);
797 if (!var_tag(s,v) && var_level(s, v)){
798 if (s->reasons[v] != 0 && ((1 << (var_level(s, v) & 31)) & minl)){
799 veci_push(&s->stack,lit_var(lits[i]));
800 var_set_tag(s, v, 1);
801 }else{
802 solver2_clear_tags(s, top);
803 return 0;
804 }
805 }
806 }
807 }
808 }
809 return 1;
810}
811
812
813/*_________________________________________________________________________________________________
814|
815| analyzeFinal : (p : Lit) -> [void]
816|
817| Description:
818| Specialized analysis procedure to express the final conflict in terms of assumptions.
819| Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and
820| stores the result in 'out_conflict'.
821|________________________________________________________________________________________________@*/
822/*
823void Solver::analyzeFinal(Clause* confl, bool skip_first)
824{
825 // -- NOTE! This code is relatively untested. Please report bugs!
826 conflict.clear();
827 if (root_level == 0) return;
828
829 vec<char>& seen = analyze_seen;
830 for (int i = skip_first ? 1 : 0; i < confl->size(); i++){
831 Var x = var((*confl)[i]);
832 if (level[x] > 0)
833 seen[x] = 1;
834 }
835
836 int start = (root_level >= trail_lim.size()) ? trail.size()-1 : trail_lim[root_level];
837 for (int i = start; i >= trail_lim[0]; i--){
838 Var x = var(trail[i]);
839 if (seen[x]){
840 GClause r = reason[x];
841 if (r == GClause_NULL){
842 assert(level[x] > 0);
843 conflict.push(~trail[i]);
844 }else{
845 if (r.isLit()){
846 Lit p = r.lit();
847 if (level[var(p)] > 0)
848 seen[var(p)] = 1;
849 }else{
850 Clause& c = *r.clause();
851 for (int j = 1; j < c.size(); j++)
852 if (level[var(c[j])] > 0)
853 seen[var(c[j])] = 1;
854 }
855 }
856 seen[x] = 0;
857 }
858 }
859}
860*/
861
862#ifdef SAT_USE_ANALYZE_FINAL
863
864static void sat_solver_analyze_final(sat_solver* s, int hConf, int skip_first)
865{
866 clause* conf = clause_read(s, hConf);
867 int i, j, start;
868 veci_resize(&s->conf_final,0);
869 if ( s->root_level == 0 )
870 return;
871 assert( veci_size(&s->tagged) == 0 );
872// assert( s->tags[lit_var(p)] == l_Undef );
873// s->tags[lit_var(p)] = l_True;
874 for (i = skip_first ? 1 : 0; i < clause_size(conf); i++)
875 {
876 int x = lit_var(clause_begin(conf)[i]);
877 if (var_level(s, x) > 0)
878 var_set_tag(s, x, 1);
879 }
880
881 start = (s->root_level >= veci_size(&s->trail_lim))? s->qtail-1 : (veci_begin(&s->trail_lim))[s->root_level];
882 for (i = start; i >= (veci_begin(&s->trail_lim))[0]; i--){
883 int x = lit_var(s->trail[i]);
884 if (var_tag(s,x)){
885 if (s->reasons[x] == 0){
886 assert(var_level(s, x) > 0);
887 veci_push(&s->conf_final,lit_neg(s->trail[i]));
888 }else{
889 if (clause_is_lit(s->reasons[x])){
890 lit q = clause_read_lit(s->reasons[x]);
891 assert(lit_var(q) >= 0 && lit_var(q) < s->size);
892 if (var_level(s, lit_var(q)) > 0)
893 var_set_tag(s, lit_var(q), 1);
894 }
895 else{
896 clause* c = clause_read(s, s->reasons[x]);
897 int* lits = clause_begin(c);
898 for (j = 1; j < clause_size(c); j++)
899 if (var_level(s, lit_var(lits[j])) > 0)
900 var_set_tag(s, lit_var(lits[j]), 1);
901 }
902 }
903 }
904 }
905 solver2_clear_tags(s,0);
906}
907
908#endif
909
910static void sat_solver_analyze(sat_solver* s, int h, veci* learnt)
911{
912 lit* trail = s->trail;
913 int cnt = 0;
914 lit p = lit_Undef;
915 int ind = s->qtail-1;
916 lit* lits;
917 int i, j, minl;
918 veci_push(learnt,lit_Undef);
919 do{
920 assert(h != 0);
921 if (clause_is_lit(h)){
922 int x = lit_var(clause_read_lit(h));
923 if (var_tag(s, x) == 0 && var_level(s, x) > 0){
924 var_set_tag(s, x, 1);
925 act_var_bump(s,x);
926 if (var_level(s, x) == sat_solver_dl(s))
927 cnt++;
928 else
929 veci_push(learnt,clause_read_lit(h));
930 }
931 }else{
932 clause* c = clause_read(s, h);
933
934 if (clause_learnt(c))
935 act_clause_bump(s,c);
936 lits = clause_begin(c);
937 //printlits(lits,lits+clause_size(c)); printf("\n");
938 for (j = (p == lit_Undef ? 0 : 1); j < clause_size(c); j++){
939 int x = lit_var(lits[j]);
940 if (var_tag(s, x) == 0 && var_level(s, x) > 0){
941 var_set_tag(s, x, 1);
942 act_var_bump(s,x);
943 // bump variables propaged by the LBD=2 clause
944// if ( s->reasons[x] && clause_read(s, s->reasons[x])->lbd <= 2 )
945// act_var_bump(s,x);
946 if (var_level(s,x) == sat_solver_dl(s))
947 cnt++;
948 else
949 veci_push(learnt,lits[j]);
950 }
951 }
952 }
953
954 while ( !var_tag(s, lit_var(trail[ind--])) );
955
956 p = trail[ind+1];
957 h = s->reasons[lit_var(p)];
958 cnt--;
959
960 }while (cnt > 0);
961
962 *veci_begin(learnt) = lit_neg(p);
963
964 lits = veci_begin(learnt);
965 minl = 0;
966 for (i = 1; i < veci_size(learnt); i++){
967 int lev = var_level(s, lit_var(lits[i]));
968 minl |= 1 << (lev & 31);
969 }
970
971 // simplify (full)
972 for (i = j = 1; i < veci_size(learnt); i++){
973 if (s->reasons[lit_var(lits[i])] == 0 || !sat_solver_lit_removable(s,lit_var(lits[i]),minl))
974 lits[j++] = lits[i];
975 }
976
977 // update size of learnt + statistics
978 veci_resize(learnt,j);
979 s->stats.tot_literals += j;
980
981
982 // clear tags
983 solver2_clear_tags(s,0);
984
985#ifdef DEBUG
986 for (i = 0; i < s->size; i++)
987 assert(!var_tag(s, i));
988#endif
989
990#ifdef VERBOSEDEBUG
991 printf(L_IND"Learnt {", L_ind);
992 for (i = 0; i < veci_size(learnt); i++) printf(" "L_LIT, L_lit(lits[i]));
993#endif
994 if (veci_size(learnt) > 1){
995 int max_i = 1;
996 int max = var_level(s, lit_var(lits[1]));
997 lit tmp;
998
999 for (i = 2; i < veci_size(learnt); i++)
1000 if (var_level(s, lit_var(lits[i])) > max){
1001 max = var_level(s, lit_var(lits[i]));
1002 max_i = i;
1003 }
1004
1005 tmp = lits[1];
1006 lits[1] = lits[max_i];
1007 lits[max_i] = tmp;
1008 }
1009#ifdef VERBOSEDEBUG
1010 {
1011 int lev = veci_size(learnt) > 1 ? var_level(s, lit_var(lits[1])) : 0;
1012 printf(" } at level %d\n", lev);
1013 }
1014#endif
1015}
1016
1017//#define TEST_CNF_LOAD
1018
1020{
1021 int hConfl = 0;
1022 lit* lits;
1023 lit false_lit;
1024
1025 //printf("sat_solver_propagate\n");
1026 while (hConfl == 0 && s->qtail - s->qhead > 0){
1027 lit p = s->trail[s->qhead++];
1028
1029#ifdef TEST_CNF_LOAD
1030 int v = lit_var(p);
1031 if ( s->pCnfFunc )
1032 {
1033 if ( lit_sign(p) )
1034 {
1035 if ( (s->loads[v] & 1) == 0 )
1036 {
1037 s->loads[v] ^= 1;
1038 s->pCnfFunc( s->pCnfMan, p );
1039 }
1040 }
1041 else
1042 {
1043 if ( (s->loads[v] & 2) == 0 )
1044 {
1045 s->loads[v] ^= 2;
1046 s->pCnfFunc( s->pCnfMan, p );
1047 }
1048 }
1049 }
1050 {
1051#endif
1052
1053 veci* ws = sat_solver_read_wlist(s,p);
1054 int* begin = veci_begin(ws);
1055 int* end = begin + veci_size(ws);
1056 int*i, *j;
1057
1058 s->stats.propagations++;
1059// s->simpdb_props--;
1060
1061 //printf("checking lit %d: "L_LIT"\n", veci_size(ws), L_lit(p));
1062 for (i = j = begin; i < end; ){
1063 if (clause_is_lit(*i)){
1064
1065 int Lit = clause_read_lit(*i);
1066 if (var_value(s, lit_var(Lit)) == lit_sign(Lit)){
1067 *j++ = *i++;
1068 continue;
1069 }
1070
1071 *j++ = *i;
1072 if (!sat_solver_enqueue(s,clause_read_lit(*i),clause_from_lit(p))){
1073 hConfl = s->hBinary;
1074 (clause_begin(s->binary))[1] = lit_neg(p);
1075 (clause_begin(s->binary))[0] = clause_read_lit(*i++);
1076 // Copy the remaining watches:
1077 while (i < end)
1078 *j++ = *i++;
1079 }
1080 }else{
1081
1082 clause* c = clause_read(s,*i);
1083 lits = clause_begin(c);
1084
1085 // Make sure the false literal is data[1]:
1086 false_lit = lit_neg(p);
1087 if (lits[0] == false_lit){
1088 lits[0] = lits[1];
1089 lits[1] = false_lit;
1090 }
1091 assert(lits[1] == false_lit);
1092
1093 // If 0th watch is true, then clause is already satisfied.
1094 if (var_value(s, lit_var(lits[0])) == lit_sign(lits[0]))
1095 *j++ = *i;
1096 else{
1097 // Look for new watch:
1098 lit* stop = lits + clause_size(c);
1099 lit* k;
1100 for (k = lits + 2; k < stop; k++){
1101 if (var_value(s, lit_var(*k)) != !lit_sign(*k)){
1102 lits[1] = *k;
1103 *k = false_lit;
1104 veci_push(sat_solver_read_wlist(s,lit_neg(lits[1])),*i);
1105 goto next; }
1106 }
1107
1108 *j++ = *i;
1109 // Clause is unit under assignment:
1110 if ( c->lrn )
1111 c->lbd = sat_clause_compute_lbd(s, c);
1112 if (!sat_solver_enqueue(s,lits[0], *i)){
1113 hConfl = *i++;
1114 // Copy the remaining watches:
1115 while (i < end)
1116 *j++ = *i++;
1117 }
1118 }
1119 }
1120 next:
1121 i++;
1122 }
1123
1124 s->stats.inspects += j - veci_begin(ws);
1125 veci_resize(ws,j - veci_begin(ws));
1126#ifdef TEST_CNF_LOAD
1127 }
1128#endif
1129 }
1130
1131 return hConfl;
1132}
1133
1134//=================================================================================================
1135// External solver functions:
1136
1138{
1139 sat_solver* s = (sat_solver*)ABC_CALLOC( char, sizeof(sat_solver));
1140
1141// Vec_SetAlloc_(&s->Mem, 15);
1142 Sat_MemAlloc_(&s->Mem, 17);
1143 s->hLearnts = -1;
1144 s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
1145 s->binary = clause_read( s, s->hBinary );
1146
1147 s->nLearntStart = LEARNT_MAX_START_DEFAULT; // starting learned clause limit
1148 s->nLearntDelta = LEARNT_MAX_INCRE_DEFAULT; // delta of learned clause limit
1149 s->nLearntRatio = LEARNT_MAX_RATIO_DEFAULT; // ratio of learned clause limit
1150 s->nLearntMax = s->nLearntStart;
1151
1152 // initialize vectors
1153 veci_new(&s->order);
1154 veci_new(&s->trail_lim);
1155 veci_new(&s->tagged);
1156// veci_new(&s->learned);
1157 veci_new(&s->act_clas);
1158 veci_new(&s->stack);
1159// veci_new(&s->model);
1160 veci_new(&s->unit_lits);
1161 veci_new(&s->temp_clause);
1162 veci_new(&s->conf_final);
1163
1164 // initialize arrays
1165 s->wlists = 0;
1166 s->activity = 0;
1167 s->orderpos = 0;
1168 s->reasons = 0;
1169 s->trail = 0;
1170
1171 // initialize other vars
1172 s->size = 0;
1173 s->cap = 0;
1174 s->qhead = 0;
1175 s->qtail = 0;
1176
1177 solver_init_activities(s);
1178 veci_new(&s->act_vars);
1179
1180 s->root_level = 0;
1181// s->simpdb_assigns = 0;
1182// s->simpdb_props = 0;
1183 s->random_seed = 91648253;
1184 s->progress_estimate = 0;
1185// s->binary = (clause*)ABC_ALLOC( char, sizeof(clause) + sizeof(lit)*2);
1186// s->binary->size_learnt = (2 << 1);
1187 s->verbosity = 0;
1188
1189 s->stats.starts = 0;
1190 s->stats.decisions = 0;
1191 s->stats.propagations = 0;
1192 s->stats.inspects = 0;
1193 s->stats.conflicts = 0;
1194 s->stats.clauses = 0;
1195 s->stats.clauses_literals = 0;
1196 s->stats.learnts = 0;
1197 s->stats.learnts_literals = 0;
1198 s->stats.tot_literals = 0;
1199 return s;
1200}
1201
1203{
1204 sat_solver* s = (sat_solver*)ABC_CALLOC( char, sizeof(sat_solver));
1205
1206// Vec_SetAlloc_(&s->Mem, 15);
1207 Sat_MemAlloc_(&s->Mem, 15);
1208 s->hLearnts = -1;
1209 s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
1210 s->binary = clause_read( s, s->hBinary );
1211
1212 s->nLearntStart = LEARNT_MAX_START_DEFAULT; // starting learned clause limit
1213 s->nLearntDelta = LEARNT_MAX_INCRE_DEFAULT; // delta of learned clause limit
1214 s->nLearntRatio = LEARNT_MAX_RATIO_DEFAULT; // ratio of learned clause limit
1215 s->nLearntMax = s->nLearntStart;
1216
1217 // initialize vectors
1218 veci_new(&s->order);
1219 veci_new(&s->trail_lim);
1220 veci_new(&s->tagged);
1221// veci_new(&s->learned);
1222 veci_new(&s->act_clas);
1223 veci_new(&s->stack);
1224// veci_new(&s->model);
1225 veci_new(&s->unit_lits);
1226 veci_new(&s->temp_clause);
1227 veci_new(&s->conf_final);
1228
1229 // initialize arrays
1230 s->wlists = 0;
1231 s->activity = 0;
1232 s->orderpos = 0;
1233 s->reasons = 0;
1234 s->trail = 0;
1235
1236 // initialize other vars
1237 s->size = 0;
1238 s->cap = 0;
1239 s->qhead = 0;
1240 s->qtail = 0;
1241
1242 solver_init_activities(s);
1243 veci_new(&s->act_vars);
1244
1245 s->root_level = 0;
1246// s->simpdb_assigns = 0;
1247// s->simpdb_props = 0;
1248 s->random_seed = seed;
1249 s->progress_estimate = 0;
1250// s->binary = (clause*)ABC_ALLOC( char, sizeof(clause) + sizeof(lit)*2);
1251// s->binary->size_learnt = (2 << 1);
1252 s->verbosity = 0;
1253
1254 s->stats.starts = 0;
1255 s->stats.decisions = 0;
1256 s->stats.propagations = 0;
1257 s->stats.inspects = 0;
1258 s->stats.conflicts = 0;
1259 s->stats.clauses = 0;
1260 s->stats.clauses_literals = 0;
1261 s->stats.learnts = 0;
1262 s->stats.learnts_literals = 0;
1263 s->stats.tot_literals = 0;
1264 return s;
1265}
1266
1268{
1269 sat_solver_setnvars(s, s->size+1);
1270 return s->size-1;
1271}
1273{
1274 int var;
1275
1276 if (s->cap < n){
1277 int old_cap = s->cap;
1278 while (s->cap < n) s->cap = s->cap*2+1;
1279 if ( s->cap < 50000 )
1280 s->cap = 50000;
1281
1282 s->wlists = ABC_REALLOC(veci, s->wlists, s->cap*2);
1283// s->vi = ABC_REALLOC(varinfo,s->vi, s->cap);
1284 s->levels = ABC_REALLOC(int, s->levels, s->cap);
1285 s->assigns = ABC_REALLOC(char, s->assigns, s->cap);
1286 s->polarity = ABC_REALLOC(char, s->polarity, s->cap);
1287 s->tags = ABC_REALLOC(char, s->tags, s->cap);
1288 s->loads = ABC_REALLOC(char, s->loads, s->cap);
1289 s->activity = ABC_REALLOC(word, s->activity, s->cap);
1290 s->activity2 = ABC_REALLOC(word, s->activity2,s->cap);
1291 s->pFreqs = ABC_REALLOC(char, s->pFreqs, s->cap);
1292
1293 if ( s->factors )
1294 s->factors = ABC_REALLOC(double, s->factors, s->cap);
1295 s->orderpos = ABC_REALLOC(int, s->orderpos, s->cap);
1296 s->reasons = ABC_REALLOC(int, s->reasons, s->cap);
1297 s->trail = ABC_REALLOC(lit, s->trail, s->cap);
1298 s->model = ABC_REALLOC(int, s->model, s->cap);
1299 memset( s->wlists + 2*old_cap, 0, 2*(s->cap-old_cap)*sizeof(veci) );
1300 }
1301
1302 for (var = s->size; var < n; var++){
1303 assert(!s->wlists[2*var].size);
1304 assert(!s->wlists[2*var+1].size);
1305 if ( s->wlists[2*var].ptr == NULL )
1306 veci_new(&s->wlists[2*var]);
1307 if ( s->wlists[2*var+1].ptr == NULL )
1308 veci_new(&s->wlists[2*var+1]);
1309
1310 if ( s->VarActType == 0 )
1311 s->activity[var] = (1<<10);
1312 else if ( s->VarActType == 1 )
1313 s->activity[var] = 0;
1314 else if ( s->VarActType == 2 )
1315 s->activity[var] = 0;
1316 else assert(0);
1317
1318 s->pFreqs[var] = 0;
1319 if ( s->factors )
1320 s->factors [var] = 0;
1321// *((int*)s->vi + var) = 0; s->vi[var].val = varX;
1322 s->levels [var] = 0;
1323 s->assigns [var] = varX;
1324 s->polarity[var] = 0;
1325 s->tags [var] = 0;
1326 s->loads [var] = 0;
1327 s->orderpos[var] = veci_size(&s->order);
1328 s->reasons [var] = 0;
1329 s->model [var] = 0;
1330
1331 /* does not hold because variables enqueued at top level will not be reinserted in the heap
1332 assert(veci_size(&s->order) == var);
1333 */
1334 veci_push(&s->order,var);
1335 order_update(s, var);
1336 }
1337
1338 s->size = n > s->size ? n : s->size;
1339}
1340
1342{
1343// Vec_SetFree_( &s->Mem );
1344 Sat_MemFree_( &s->Mem );
1345
1346 // delete vectors
1347 veci_delete(&s->order);
1348 veci_delete(&s->trail_lim);
1349 veci_delete(&s->tagged);
1350// veci_delete(&s->learned);
1351 veci_delete(&s->act_clas);
1352 veci_delete(&s->stack);
1353// veci_delete(&s->model);
1354 veci_delete(&s->act_vars);
1355 veci_delete(&s->unit_lits);
1356 veci_delete(&s->pivot_vars);
1357 veci_delete(&s->temp_clause);
1358 veci_delete(&s->conf_final);
1359
1360 veci_delete(&s->user_vars);
1361 veci_delete(&s->user_values);
1362
1363 // delete arrays
1364 if (s->reasons != 0){
1365 int i;
1366 for (i = 0; i < s->cap*2; i++)
1367 veci_delete(&s->wlists[i]);
1368 ABC_FREE(s->wlists );
1369// ABC_FREE(s->vi );
1370 ABC_FREE(s->levels );
1371 ABC_FREE(s->assigns );
1372 ABC_FREE(s->polarity );
1373 ABC_FREE(s->tags );
1374 ABC_FREE(s->loads );
1375 ABC_FREE(s->activity );
1376 ABC_FREE(s->activity2);
1377 ABC_FREE(s->pFreqs );
1378 ABC_FREE(s->factors );
1379 ABC_FREE(s->orderpos );
1380 ABC_FREE(s->reasons );
1381 ABC_FREE(s->trail );
1382 ABC_FREE(s->model );
1383 }
1384
1386 ABC_FREE(s);
1387}
1388
1390{
1391 int i;
1392 Sat_MemRestart( &s->Mem );
1393 s->hLearnts = -1;
1394 s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
1395 s->binary = clause_read( s, s->hBinary );
1396
1397 veci_resize(&s->trail_lim, 0);
1398 veci_resize(&s->order, 0);
1399 for ( i = 0; i < s->size*2; i++ )
1400 s->wlists[i].size = 0;
1401
1402 s->nDBreduces = 0;
1403
1404 // initialize other vars
1405 s->size = 0;
1406// s->cap = 0;
1407 s->qhead = 0;
1408 s->qtail = 0;
1409
1410
1411 // variable activities
1412 solver_init_activities(s);
1413 veci_resize(&s->act_clas, 0);
1414
1415
1416 s->root_level = 0;
1417// s->simpdb_assigns = 0;
1418// s->simpdb_props = 0;
1419 s->random_seed = 91648253;
1420 s->progress_estimate = 0;
1421 s->verbosity = 0;
1422
1423 s->stats.starts = 0;
1424 s->stats.decisions = 0;
1425 s->stats.propagations = 0;
1426 s->stats.inspects = 0;
1427 s->stats.conflicts = 0;
1428 s->stats.clauses = 0;
1429 s->stats.clauses_literals = 0;
1430 s->stats.learnts = 0;
1431 s->stats.learnts_literals = 0;
1432 s->stats.tot_literals = 0;
1433}
1434
1436{
1437 int i;
1438 Sat_MemRestart( &s->Mem );
1439 s->hLearnts = -1;
1440 s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
1441 s->binary = clause_read( s, s->hBinary );
1442
1443 veci_resize(&s->trail_lim, 0);
1444 veci_resize(&s->order, 0);
1445 for ( i = 0; i < s->size*2; i++ )
1446 s->wlists[i].size = 0;
1447
1448 s->nDBreduces = 0;
1449
1450 // initialize other vars
1451 s->size = 0;
1452// s->cap = 0;
1453 s->qhead = 0;
1454 s->qtail = 0;
1455
1456 solver_init_activities(s);
1457 veci_resize(&s->act_clas, 0);
1458
1459 s->root_level = 0;
1460// s->simpdb_assigns = 0;
1461// s->simpdb_props = 0;
1462 s->random_seed = seed;
1463 s->progress_estimate = 0;
1464 s->verbosity = 0;
1465
1466 s->stats.starts = 0;
1467 s->stats.decisions = 0;
1468 s->stats.propagations = 0;
1469 s->stats.inspects = 0;
1470 s->stats.conflicts = 0;
1471 s->stats.clauses = 0;
1472 s->stats.clauses_literals = 0;
1473 s->stats.learnts = 0;
1474 s->stats.learnts_literals = 0;
1475 s->stats.tot_literals = 0;
1476}
1477
1478// returns memory in bytes used by the SAT solver
1480{
1481 int i;
1482 double Mem = sizeof(sat_solver);
1483 for (i = 0; i < s->cap*2; i++)
1484 Mem += s->wlists[i].cap * sizeof(int);
1485 Mem += s->cap * sizeof(veci); // ABC_FREE(s->wlists );
1486 Mem += s->cap * sizeof(int); // ABC_FREE(s->levels );
1487 Mem += s->cap * sizeof(char); // ABC_FREE(s->assigns );
1488 Mem += s->cap * sizeof(char); // ABC_FREE(s->polarity );
1489 Mem += s->cap * sizeof(char); // ABC_FREE(s->tags );
1490 Mem += s->cap * sizeof(char); // ABC_FREE(s->loads );
1491 Mem += s->cap * sizeof(word); // ABC_FREE(s->activity );
1492 if ( s->activity2 )
1493 Mem += s->cap * sizeof(word); // ABC_FREE(s->activity );
1494 if ( s->factors )
1495 Mem += s->cap * sizeof(double); // ABC_FREE(s->factors );
1496 Mem += s->cap * sizeof(int); // ABC_FREE(s->orderpos );
1497 Mem += s->cap * sizeof(int); // ABC_FREE(s->reasons );
1498 Mem += s->cap * sizeof(lit); // ABC_FREE(s->trail );
1499 Mem += s->cap * sizeof(int); // ABC_FREE(s->model );
1500
1501 Mem += s->order.cap * sizeof(int);
1502 Mem += s->trail_lim.cap * sizeof(int);
1503 Mem += s->tagged.cap * sizeof(int);
1504// Mem += s->learned.cap * sizeof(int);
1505 Mem += s->stack.cap * sizeof(int);
1506 Mem += s->act_vars.cap * sizeof(int);
1507 Mem += s->unit_lits.cap * sizeof(int);
1508 Mem += s->act_clas.cap * sizeof(int);
1509 Mem += s->temp_clause.cap * sizeof(int);
1510 Mem += s->conf_final.cap * sizeof(int);
1511 Mem += Sat_MemMemoryAll( &s->Mem );
1512 return Mem;
1513}
1514
1516{
1517 assert(sat_solver_dl(s) == 0);
1518 if (sat_solver_propagate(s) != 0)
1519 return false;
1520 return true;
1521}
1522
1524{
1525 static abctime TimeTotal = 0;
1526 abctime clk = Abc_Clock();
1527 Sat_Mem_t * pMem = &s->Mem;
1528 int nLearnedOld = veci_size(&s->act_clas);
1529 int * act_clas = veci_begin(&s->act_clas);
1530 int * pPerm, * pArray, * pSortValues, nCutoffValue;
1531 int i, k, j, Id, Counter, CounterStart, nSelected;
1532 clause * c;
1533
1534 assert( s->nLearntMax > 0 );
1535 assert( nLearnedOld == Sat_MemEntryNum(pMem, 1) );
1536 assert( nLearnedOld == (int)s->stats.learnts );
1537
1538 s->nDBreduces++;
1539
1540 //printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax );
1542// return;
1543
1544 // create sorting values
1545 pSortValues = ABC_ALLOC( int, nLearnedOld );
1546 Sat_MemForEachLearned( pMem, c, i, k )
1547 {
1548 Id = clause_id(c);
1549// pSortValues[Id] = act[Id];
1550 if ( s->ClaActType == 0 )
1551 pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4);
1552 else
1553 pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28);// | (act_clas[Id] >> 4);
1554 assert( pSortValues[Id] >= 0 );
1555 }
1556
1557 // preserve 1/20 of last clauses
1558 CounterStart = nLearnedOld - (s->nLearntMax / 20);
1559
1560 // preserve 3/4 of most active clauses
1561 nSelected = nLearnedOld*s->nLearntRatio/100;
1562
1563 // find non-decreasing permutation
1564 pPerm = Abc_MergeSortCost( pSortValues, nLearnedOld );
1565 assert( pSortValues[pPerm[0]] <= pSortValues[pPerm[nLearnedOld-1]] );
1566 nCutoffValue = pSortValues[pPerm[nLearnedOld-nSelected]];
1567 ABC_FREE( pPerm );
1568// ActCutOff = ABC_INFINITY;
1569
1570 // mark learned clauses to remove
1571 Counter = j = 0;
1572 Sat_MemForEachLearned( pMem, c, i, k )
1573 {
1574 assert( c->mark == 0 );
1575 if ( Counter++ > CounterStart || clause_size(c) < 3 || pSortValues[clause_id(c)] > nCutoffValue || s->reasons[lit_var(c->lits[0])] == Sat_MemHand(pMem, i, k) )
1576 act_clas[j++] = act_clas[clause_id(c)];
1577 else // delete
1578 {
1579 c->mark = 1;
1580 s->stats.learnts_literals -= clause_size(c);
1581 s->stats.learnts--;
1582 }
1583 }
1584 assert( s->stats.learnts == (unsigned)j );
1585 assert( Counter == nLearnedOld );
1586 veci_resize(&s->act_clas,j);
1587 ABC_FREE( pSortValues );
1588
1589 // update ID of each clause to be its new handle
1590 Counter = Sat_MemCompactLearned( pMem, 0 );
1591 assert( Counter == (int)s->stats.learnts );
1592
1593 // update reasons
1594 for ( i = 0; i < s->size; i++ )
1595 {
1596 if ( !s->reasons[i] ) // no reason
1597 continue;
1598 if ( clause_is_lit(s->reasons[i]) ) // 2-lit clause
1599 continue;
1600 if ( !clause_learnt_h(pMem, s->reasons[i]) ) // problem clause
1601 continue;
1602 c = clause_read( s, s->reasons[i] );
1603 assert( c->mark == 0 );
1604 s->reasons[i] = clause_id(c); // updating handle here!!!
1605 }
1606
1607 // update watches
1608 for ( i = 0; i < s->size*2; i++ )
1609 {
1610 pArray = veci_begin(&s->wlists[i]);
1611 for ( j = k = 0; k < veci_size(&s->wlists[i]); k++ )
1612 {
1613 if ( clause_is_lit(pArray[k]) ) // 2-lit clause
1614 pArray[j++] = pArray[k];
1615 else if ( !clause_learnt_h(pMem, pArray[k]) ) // problem clause
1616 pArray[j++] = pArray[k];
1617 else
1618 {
1619 c = clause_read(s, pArray[k]);
1620 if ( !c->mark ) // useful learned clause
1621 pArray[j++] = clause_id(c); // updating handle here!!!
1622 }
1623 }
1624 veci_resize(&s->wlists[i],j);
1625 }
1626
1627 // perform final move of the clauses
1628 Counter = Sat_MemCompactLearned( pMem, 1 );
1629 assert( Counter == (int)s->stats.learnts );
1630
1631 // report the results
1632 TimeTotal += Abc_Clock() - clk;
1633 if ( s->fVerbose )
1634 {
1635 Abc_Print(1, "reduceDB: Keeping %7d out of %7d clauses (%5.2f %%) ",
1636 s->stats.learnts, nLearnedOld, 100.0 * s->stats.learnts / nLearnedOld );
1637 Abc_PrintTime( 1, "Time", TimeTotal );
1638 }
1639}
1640
1641
1642// reverses to the previously bookmarked point
1644{
1645 Sat_Mem_t * pMem = &s->Mem;
1646 int i, k, j;
1647 static int Count = 0;
1648 Count++;
1649 assert( s->iVarPivot >= 0 && s->iVarPivot <= s->size );
1650 assert( s->iTrailPivot >= 0 && s->iTrailPivot <= s->qtail );
1651 // reset implication queue
1652 sat_solver_canceluntil_rollback( s, s->iTrailPivot );
1653 // update order
1654 if ( s->iVarPivot < s->size )
1655 {
1656 if ( s->activity2 )
1657 {
1658 s->var_inc = s->var_inc2;
1659 memcpy( s->activity, s->activity2, sizeof(word) * s->iVarPivot );
1660 }
1661 veci_resize(&s->order, 0);
1662 for ( i = 0; i < s->iVarPivot; i++ )
1663 {
1664 if ( var_value(s, i) != varX )
1665 continue;
1666 s->orderpos[i] = veci_size(&s->order);
1667 veci_push(&s->order,i);
1668 order_update(s, i);
1669 }
1670 }
1671 // compact watches
1672 for ( i = 0; i < s->iVarPivot*2; i++ )
1673 {
1674 cla* pArray = veci_begin(&s->wlists[i]);
1675 for ( j = k = 0; k < veci_size(&s->wlists[i]); k++ )
1676 {
1677 if ( clause_is_lit(pArray[k]) )
1678 {
1679 if ( clause_read_lit(pArray[k]) < s->iVarPivot*2 )
1680 pArray[j++] = pArray[k];
1681 }
1682 else if ( Sat_MemClauseUsed(pMem, pArray[k]) )
1683 pArray[j++] = pArray[k];
1684 }
1685 veci_resize(&s->wlists[i],j);
1686 }
1687 // reset watcher lists
1688 for ( i = 2*s->iVarPivot; i < 2*s->size; i++ )
1689 s->wlists[i].size = 0;
1690
1691 // reset clause counts
1692 s->stats.clauses = pMem->BookMarkE[0];
1693 s->stats.learnts = pMem->BookMarkE[1];
1694 // rollback clauses
1695 Sat_MemRollBack( pMem );
1696
1697 // resize learned arrays
1698 veci_resize(&s->act_clas, s->stats.learnts);
1699
1700 // initialize other vars
1701 s->size = s->iVarPivot;
1702 if ( s->size == 0 )
1703 {
1704 // s->size = 0;
1705 // s->cap = 0;
1706 s->qhead = 0;
1707 s->qtail = 0;
1708
1709 solver_init_activities(s);
1710
1711 s->root_level = 0;
1712 s->random_seed = 91648253;
1713 s->progress_estimate = 0;
1714 s->verbosity = 0;
1715
1716 s->stats.starts = 0;
1717 s->stats.decisions = 0;
1718 s->stats.propagations = 0;
1719 s->stats.inspects = 0;
1720 s->stats.conflicts = 0;
1721 s->stats.clauses = 0;
1722 s->stats.clauses_literals = 0;
1723 s->stats.learnts = 0;
1724 s->stats.learnts_literals = 0;
1725 s->stats.tot_literals = 0;
1726
1727 // initialize rollback
1728 s->iVarPivot = 0; // the pivot for variables
1729 s->iTrailPivot = 0; // the pivot for trail
1730 s->hProofPivot = 1; // the pivot for proof records
1731 }
1732}
1733
1734
1736{
1737 lit *i,*j;
1738 int maxvar;
1739 lit last;
1740 assert( begin < end );
1741 if ( s->fPrintClause )
1742 {
1743 for ( i = begin; i < end; i++ )
1744 printf( "%s%d ", (*i)&1 ? "!":"", (*i)>>1 );
1745 printf( "\n" );
1746 }
1747
1748 veci_resize( &s->temp_clause, 0 );
1749 for ( i = begin; i < end; i++ )
1750 veci_push( &s->temp_clause, *i );
1751 begin = veci_begin( &s->temp_clause );
1752 end = begin + veci_size( &s->temp_clause );
1753
1754 // insertion sort
1755 maxvar = lit_var(*begin);
1756 for (i = begin + 1; i < end; i++){
1757 lit l = *i;
1758 maxvar = lit_var(l) > maxvar ? lit_var(l) : maxvar;
1759 for (j = i; j > begin && *(j-1) > l; j--)
1760 *j = *(j-1);
1761 *j = l;
1762 }
1763 sat_solver_setnvars(s,maxvar+1);
1764
1766 // add clause to internal storage
1767 if ( s->pStore )
1768 {
1769 int RetValue = Sto_ManAddClause( (Sto_Man_t *)s->pStore, begin, end );
1770 assert( RetValue );
1771 (void) RetValue;
1772 }
1774
1775 // delete duplicates
1776 last = lit_Undef;
1777 for (i = j = begin; i < end; i++){
1778 //printf("lit: "L_LIT", value = %d\n", L_lit(*i), (lit_sign(*i) ? -s->assignss[lit_var(*i)] : s->assignss[lit_var(*i)]));
1779 if (*i == lit_neg(last) || var_value(s, lit_var(*i)) == lit_sign(*i))
1780 return true; // tautology
1781 else if (*i != last && var_value(s, lit_var(*i)) == varX)
1782 last = *j++ = *i;
1783 }
1784// j = i;
1785
1786 if (j == begin) // empty clause
1787 return false;
1788
1789 if (j - begin == 1) // unit clause
1790 return sat_solver_enqueue(s,*begin,0);
1791
1792 // create new clause
1793 sat_solver_clause_new(s,begin,j,0);
1794 return true;
1795}
1796
1797double luby(double y, int x)
1798{
1799 int size, seq;
1800 for (size = 1, seq = 0; size < x+1; seq++, size = 2*size + 1);
1801 while (size-1 != x){
1802 size = (size-1) >> 1;
1803 seq--;
1804 x = x % size;
1805 }
1806 return pow(y, (double)seq);
1807}
1808
1810{
1811 int i;
1812 for ( i = 0; i < 20; i++ )
1813 printf( "%d ", (int)luby(2,i) );
1814 printf( "\n" );
1815}
1816
1817static lbool sat_solver_search(sat_solver* s, ABC_INT64_T nof_conflicts)
1818{
1819// double var_decay = 0.95;
1820// double clause_decay = 0.999;
1821 double random_var_freq = s->fNotUseRandom ? 0.0 : 0.02;
1822 ABC_INT64_T conflictC = 0;
1823 veci learnt_clause;
1824 int i;
1825
1826 assert(s->root_level == sat_solver_dl(s));
1827
1828 s->nRestarts++;
1829 s->stats.starts++;
1830// s->var_decay = (float)(1 / var_decay ); // move this to sat_solver_new()
1831// s->cla_decay = (float)(1 / clause_decay); // move this to sat_solver_new()
1832// veci_resize(&s->model,0);
1833 veci_new(&learnt_clause);
1834
1835 // use activity factors in every even restart
1836 if ( (s->nRestarts & 1) && veci_size(&s->act_vars) > 0 )
1837// if ( veci_size(&s->act_vars) > 0 )
1838 for ( i = 0; i < s->act_vars.size; i++ )
1839 act_var_bump_factor(s, s->act_vars.ptr[i]);
1840
1841 // use activity factors in every restart
1842 if ( s->pGlobalVars && veci_size(&s->act_vars) > 0 )
1843 for ( i = 0; i < s->act_vars.size; i++ )
1844 act_var_bump_global(s, s->act_vars.ptr[i]);
1845
1846 for (;;){
1847 int hConfl = sat_solver_propagate(s);
1848 if (hConfl != 0){
1849 // CONFLICT
1850 int blevel;
1851
1852#ifdef VERBOSEDEBUG
1853 printf(L_IND"**CONFLICT**\n", L_ind);
1854#endif
1855 s->stats.conflicts++; conflictC++;
1856 if (sat_solver_dl(s) == s->root_level){
1857#ifdef SAT_USE_ANALYZE_FINAL
1858 sat_solver_analyze_final(s, hConfl, 0);
1859#endif
1860 veci_delete(&learnt_clause);
1861 return l_False;
1862 }
1863
1864 veci_resize(&learnt_clause,0);
1865 sat_solver_analyze(s, hConfl, &learnt_clause);
1866 blevel = veci_size(&learnt_clause) > 1 ? var_level(s, lit_var(veci_begin(&learnt_clause)[1])) : s->root_level;
1867 blevel = s->root_level > blevel ? s->root_level : blevel;
1868 sat_solver_canceluntil(s,blevel);
1869 sat_solver_record(s,&learnt_clause);
1870#ifdef SAT_USE_ANALYZE_FINAL
1871// if (learnt_clause.size() == 1) level[var(learnt_clause[0])] = 0; // (this is ugly (but needed for 'analyzeFinal()') -- in future versions, we will backtrack past the 'root_level' and redo the assumptions)
1872 if ( learnt_clause.size == 1 )
1873 var_set_level(s, lit_var(learnt_clause.ptr[0]), 0);
1874#endif
1875 act_var_decay(s);
1876 act_clause_decay(s);
1877
1878 }else{
1879 // NO CONFLICT
1880 int next;
1881
1882 // Reached bound on number of conflicts:
1883 if ( (!s->fNoRestarts && nof_conflicts >= 0 && conflictC >= nof_conflicts) || (s->nRuntimeLimit && (s->stats.conflicts & 63) == 0 && Abc_Clock() > s->nRuntimeLimit)){
1884 s->progress_estimate = sat_solver_progress(s);
1885 sat_solver_canceluntil(s,s->root_level);
1886 veci_delete(&learnt_clause);
1887 return l_Undef; }
1888
1889 // Reached bound on number of conflicts:
1890 if ( (s->nConfLimit && s->stats.conflicts > s->nConfLimit) ||
1891 (s->nInsLimit && s->stats.propagations > s->nInsLimit) )
1892 {
1893 s->progress_estimate = sat_solver_progress(s);
1894 sat_solver_canceluntil(s,s->root_level);
1895 veci_delete(&learnt_clause);
1896 return l_Undef;
1897 }
1898
1899 // Simplify the set of problem clauses:
1900 if (sat_solver_dl(s) == 0 && !s->fSkipSimplify)
1902
1903 // Reduce the set of learnt clauses:
1904// if (s->nLearntMax && veci_size(&s->learned) - s->qtail >= s->nLearntMax)
1905 if (s->nLearntMax && veci_size(&s->act_clas) >= s->nLearntMax)
1907
1908 // New variable decision:
1909 s->stats.decisions++;
1910 next = order_select(s,(float)random_var_freq);
1911
1912 if (next == var_Undef){
1913 // Model found:
1914 int i;
1915 for (i = 0; i < s->size; i++)
1916 s->model[i] = (var_value(s,i)==var1 ? l_True : l_False);
1917 sat_solver_canceluntil(s,s->root_level);
1918 veci_delete(&learnt_clause);
1919
1920 /*
1921 veci apa; veci_new(&apa);
1922 for (i = 0; i < s->size; i++)
1923 veci_push(&apa,(int)(s->model.ptr[i] == l_True ? toLit(i) : lit_neg(toLit(i))));
1924 printf("model: "); printlits((lit*)apa.ptr, (lit*)apa.ptr + veci_size(&apa)); printf("\n");
1925 veci_delete(&apa);
1926 */
1927
1928 return l_True;
1929 }
1930
1931 if ( var_polar(s, next) ) // positive polarity
1932 sat_solver_decision(s,toLit(next));
1933 else
1934 sat_solver_decision(s,lit_neg(toLit(next)));
1935 }
1936 }
1937
1938 return l_Undef; // cannot happen
1939}
1940
1941// internal call to the SAT solver
1943{
1944 lbool status = l_Undef;
1945 int restart_iter = 0;
1946 veci_resize(&s->unit_lits, 0);
1947 s->nCalls++;
1948
1949 if (s->verbosity >= 1){
1950 printf("==================================[MINISAT]===================================\n");
1951 printf("| Conflicts | ORIGINAL | LEARNT | Progress |\n");
1952 printf("| | Clauses Literals | Limit Clauses Literals Lit/Cl | |\n");
1953 printf("==============================================================================\n");
1954 }
1955
1956 while (status == l_Undef){
1957 ABC_INT64_T nof_conflicts;
1958 if ( s->nRuntimeLimit && Abc_Clock() > s->nRuntimeLimit )
1959 break;
1960 if (s->verbosity >= 1)
1961 {
1962 double Ratio = (s->stats.learnts == 0)? 0.0 :
1963 s->stats.learnts_literals / (double)s->stats.learnts;
1964 printf("| %9.0f | %7.0f %8.0f | %7.0f %7.0f %8.0f %7.1f | %6.3f %% |\n",
1965 (double)s->stats.conflicts,
1966 (double)s->stats.clauses,
1967 (double)s->stats.clauses_literals,
1968 (double)0,
1969 (double)s->stats.learnts,
1970 (double)s->stats.learnts_literals,
1971 Ratio,
1972 s->progress_estimate*100);
1973 fflush(stdout);
1974 }
1975 nof_conflicts = (ABC_INT64_T)( 100 * luby(2, restart_iter++) );
1976 status = sat_solver_search(s, nof_conflicts);
1977 // quit the loop if reached an external limit
1978 if ( s->nConfLimit && s->stats.conflicts > s->nConfLimit )
1979 break;
1980 if ( s->nInsLimit && s->stats.propagations > s->nInsLimit )
1981 break;
1982 if ( s->nRuntimeLimit && Abc_Clock() > s->nRuntimeLimit )
1983 break;
1984 if ( s->pFuncStop && s->pFuncStop(s->RunId) )
1985 break;
1986 }
1987 if (s->verbosity >= 1)
1988 printf("==============================================================================\n");
1989
1990 sat_solver_canceluntil(s,s->root_level);
1991 // save variable values
1992 if ( status == l_True && s->user_vars.size )
1993 {
1994 int v;
1995 for ( v = 0; v < s->user_vars.size; v++ )
1996 veci_push(&s->user_values, sat_solver_var_value(s, s->user_vars.ptr[v]));
1997 }
1998 return status;
1999}
2000
2001// pushing one assumption to the stack of assumptions
2003{
2004 assert(lit_var(p) < s->size);
2005 veci_push(&s->trail_lim,s->qtail);
2006 s->root_level++;
2007 if (!sat_solver_enqueue(s,p,0))
2008 {
2009 int h = s->reasons[lit_var(p)];
2010 if (h)
2011 {
2012 if (clause_is_lit(h))
2013 {
2014 (clause_begin(s->binary))[1] = lit_neg(p);
2015 (clause_begin(s->binary))[0] = clause_read_lit(h);
2016 h = s->hBinary;
2017 }
2018 sat_solver_analyze_final(s, h, 1);
2019 veci_push(&s->conf_final, lit_neg(p));
2020 }
2021 else
2022 {
2023 veci_resize(&s->conf_final,0);
2024 veci_push(&s->conf_final, lit_neg(p));
2025 // the two lines below are a bug fix by Siert Wieringa
2026 if (var_level(s, lit_var(p)) > 0)
2027 veci_push(&s->conf_final, p);
2028 }
2029 //sat_solver_canceluntil(s, 0);
2030 return false;
2031 }
2032 else
2033 {
2034 int fConfl = sat_solver_propagate(s);
2035 if (fConfl){
2036 sat_solver_analyze_final(s, fConfl, 0);
2037 //assert(s->conf_final.size > 0);
2038 //sat_solver_canceluntil(s, 0);
2039 return false; }
2040 }
2041 return true;
2042}
2043
2044// removing one assumption from the stack of assumptions
2046{
2047 assert( sat_solver_dl(s) > 0 );
2048 sat_solver_canceluntil(s, --s->root_level);
2049}
2050
2051void sat_solver_set_resource_limits(sat_solver* s, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal)
2052{
2053 // set the external limits
2054 s->nRestarts = 0;
2055 s->nConfLimit = 0;
2056 s->nInsLimit = 0;
2057 if ( nConfLimit )
2058 s->nConfLimit = s->stats.conflicts + nConfLimit;
2059 if ( nInsLimit )
2060// s->nInsLimit = s->stats.inspects + nInsLimit;
2061 s->nInsLimit = s->stats.propagations + nInsLimit;
2062 if ( nConfLimitGlobal && (s->nConfLimit == 0 || s->nConfLimit > nConfLimitGlobal) )
2063 s->nConfLimit = nConfLimitGlobal;
2064 if ( nInsLimitGlobal && (s->nInsLimit == 0 || s->nInsLimit > nInsLimitGlobal) )
2065 s->nInsLimit = nInsLimitGlobal;
2066}
2067
2068int sat_solver_solve(sat_solver* s, lit* begin, lit* end, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal)
2069{
2070 lbool status;
2071 lit * i;
2073 if ( s->fSolved )
2074 {
2075 if ( s->pStore )
2076 {
2077 int RetValue = Sto_ManAddClause( (Sto_Man_t *)s->pStore, NULL, NULL );
2078 assert( RetValue );
2079 (void) RetValue;
2080 }
2081 return l_False;
2082 }
2084
2085 if ( s->fVerbose )
2086 printf( "Running SAT solver with parameters %d and %d and %d.\n", s->nLearntStart, s->nLearntDelta, s->nLearntRatio );
2087
2088 sat_solver_set_resource_limits( s, nConfLimit, nInsLimit, nConfLimitGlobal, nInsLimitGlobal );
2089
2090#ifdef SAT_USE_ANALYZE_FINAL
2091 // Perform assumptions:
2092 s->root_level = 0;
2093 for ( i = begin; i < end; i++ )
2094 if ( !sat_solver_push(s, *i) )
2095 {
2096 sat_solver_canceluntil(s,0);
2097 s->root_level = 0;
2098 return l_False;
2099 }
2100 assert(s->root_level == sat_solver_dl(s));
2101#else
2102 //printf("solve: "); printlits(begin, end); printf("\n");
2103 for (i = begin; i < end; i++){
2104// switch (lit_sign(*i) ? -s->assignss[lit_var(*i)] : s->assignss[lit_var(*i)]){
2105 switch (var_value(s, *i)) {
2106 case var1: // l_True:
2107 break;
2108 case varX: // l_Undef
2109 sat_solver_decision(s, *i);
2110 if (sat_solver_propagate(s) == 0)
2111 break;
2112 // fallthrough
2113 case var0: // l_False
2114 sat_solver_canceluntil(s, 0);
2115 return l_False;
2116 }
2117 }
2118 s->root_level = sat_solver_dl(s);
2119#endif
2120
2121 status = sat_solver_solve_internal(s);
2122
2123 sat_solver_canceluntil(s,0);
2124 s->root_level = 0;
2125
2127 if ( status == l_False && s->pStore )
2128 {
2129 int RetValue = Sto_ManAddClause( (Sto_Man_t *)s->pStore, NULL, NULL );
2130 assert( RetValue );
2131 (void) RetValue;
2132 }
2134 return status;
2135}
2136
2137// This LEXSAT procedure should be called with a set of literals (pLits, nLits),
2138// which defines both (1) variable order, and (2) assignment to begin search from.
2139// It retuns the LEXSAT assigment that is the same or larger than the given one.
2140// (It assumes that there is no smaller assignment than the one given!)
2141// The resulting assignment is returned in the same set of literals (pLits, nLits).
2142// It pushes/pops assumptions internally and will undo them before terminating.
2143int sat_solver_solve_lexsat( sat_solver* s, int * pLits, int nLits )
2144{
2145 int i, iLitFail = -1;
2146 lbool status;
2147 assert( nLits > 0 );
2148 // help the SAT solver by setting desirable polarity
2149 sat_solver_set_literal_polarity( s, pLits, nLits );
2150 // check if there exists a satisfying assignment
2151 status = sat_solver_solve_internal( s );
2152 if ( status != l_True ) // no assignment
2153 return status;
2154 // there is at least one satisfying assignment
2155 assert( status == l_True );
2156 // find the first mismatching literal
2157 for ( i = 0; i < nLits; i++ )
2158 if ( pLits[i] != sat_solver_var_literal(s, Abc_Lit2Var(pLits[i])) )
2159 break;
2160 if ( i == nLits ) // no mismatch - the current assignment is the minimum one!
2161 return l_True;
2162 // mismatch happens in literal i
2163 iLitFail = i;
2164 // create assumptions up to this literal (as in pLits) - including this literal!
2165 for ( i = 0; i <= iLitFail; i++ )
2166 if ( !sat_solver_push(s, pLits[i]) ) // can become UNSAT while adding the last assumption
2167 break;
2168 if ( i < iLitFail + 1 ) // the solver became UNSAT while adding assumptions
2169 status = l_False;
2170 else // solve under the assumptions
2171 status = sat_solver_solve_internal( s );
2172 if ( status == l_True )
2173 {
2174 // we proved that there is a sat assignment with literal (iLitFail) having polarity as in pLits
2175 // continue solving recursively
2176 if ( iLitFail + 1 < nLits )
2177 status = sat_solver_solve_lexsat( s, pLits + iLitFail + 1, nLits - iLitFail - 1 );
2178 }
2179 else if ( status == l_False )
2180 {
2181 // we proved that there is no assignment with iLitFail having polarity as in pLits
2182 assert( Abc_LitIsCompl(pLits[iLitFail]) ); // literal is 0
2183 // (this assert may fail only if there is a sat assignment smaller than one originally given in pLits)
2184 // now we flip this literal (make it 1), change the last assumption
2185 // and contiue looking for the 000...0-assignment of other literals
2186 sat_solver_pop( s );
2187 pLits[iLitFail] = Abc_LitNot(pLits[iLitFail]);
2188 if ( !sat_solver_push(s, pLits[iLitFail]) )
2189 printf( "sat_solver_solve_lexsat(): A satisfying assignment should exist.\n" ); // because we know that the problem is satisfiable
2190 // update other literals to be 000...0
2191 for ( i = iLitFail + 1; i < nLits; i++ )
2192 pLits[i] = Abc_LitNot( Abc_LitRegular(pLits[i]) );
2193 // continue solving recursively
2194 if ( iLitFail + 1 < nLits )
2195 status = sat_solver_solve_lexsat( s, pLits + iLitFail + 1, nLits - iLitFail - 1 );
2196 else
2197 status = l_True;
2198 }
2199 // undo the assumptions
2200 for ( i = iLitFail; i >= 0; i-- )
2201 sat_solver_pop( s );
2202 return status;
2203}
2204
2205// This procedure is called on a set of assumptions to minimize their number.
2206// The procedure relies on the fact that the current set of assumptions is UNSAT.
2207// It receives and returns SAT solver without assumptions. It returns the number
2208// of assumptions after minimization. The set of assumptions is returned in pLits.
2209int sat_solver_minimize_assumptions( sat_solver* s, int * pLits, int nLits, int nConfLimit )
2210{
2211 int i, k, nLitsL, nLitsR, nResL, nResR, status;
2212 if ( nLits == 1 )
2213 {
2214 // since the problem is UNSAT, we will try to solve it without assuming the last literal
2215 // if the result is UNSAT, the last literal can be dropped; otherwise, it is needed
2216 if ( nConfLimit ) s->nConfLimit = s->stats.conflicts + nConfLimit;
2217 status = sat_solver_solve_internal( s );
2218 //printf( "%c", status == l_False ? 'u' : 's' );
2219 return (int)(status != l_False); // return 1 if the problem is not UNSAT
2220 }
2221 assert( nLits >= 2 );
2222 nLitsL = nLits / 2;
2223 nLitsR = nLits - nLitsL;
2224 // assume the left lits
2225 for ( i = 0; i < nLitsL; i++ )
2226 if ( !sat_solver_push(s, pLits[i]) )
2227 {
2228 for ( k = i; k >= 0; k-- )
2229 sat_solver_pop(s);
2230 return sat_solver_minimize_assumptions( s, pLits, i+1, nConfLimit );
2231 }
2232 // solve with these assumptions
2233 if ( nConfLimit ) s->nConfLimit = s->stats.conflicts + nConfLimit;
2234 status = sat_solver_solve_internal( s );
2235 if ( status == l_False ) // these are enough
2236 {
2237 for ( i = 0; i < nLitsL; i++ )
2238 sat_solver_pop(s);
2239 return sat_solver_minimize_assumptions( s, pLits, nLitsL, nConfLimit );
2240 }
2241 // solve for the right lits
2242 nResL = nLitsR == 1 ? 1 : sat_solver_minimize_assumptions( s, pLits + nLitsL, nLitsR, nConfLimit );
2243 for ( i = 0; i < nLitsL; i++ )
2244 sat_solver_pop(s);
2245 // swap literals
2246// assert( nResL <= nLitsL );
2247// for ( i = 0; i < nResL; i++ )
2248// ABC_SWAP( int, pLits[i], pLits[nLitsL+i] );
2249 veci_resize( &s->temp_clause, 0 );
2250 for ( i = 0; i < nLitsL; i++ )
2251 veci_push( &s->temp_clause, pLits[i] );
2252 for ( i = 0; i < nResL; i++ )
2253 pLits[i] = pLits[nLitsL+i];
2254 for ( i = 0; i < nLitsL; i++ )
2255 pLits[nResL+i] = veci_begin(&s->temp_clause)[i];
2256 // assume the right lits
2257 for ( i = 0; i < nResL; i++ )
2258 if ( !sat_solver_push(s, pLits[i]) )
2259 {
2260 for ( k = i; k >= 0; k-- )
2261 sat_solver_pop(s);
2262 return sat_solver_minimize_assumptions( s, pLits, i+1, nConfLimit );
2263 }
2264 // solve with these assumptions
2265 if ( nConfLimit ) s->nConfLimit = s->stats.conflicts + nConfLimit;
2266 status = sat_solver_solve_internal( s );
2267 if ( status == l_False ) // these are enough
2268 {
2269 for ( i = 0; i < nResL; i++ )
2270 sat_solver_pop(s);
2271 return nResL;
2272 }
2273 // solve for the left lits
2274 nResR = nLitsL == 1 ? 1 : sat_solver_minimize_assumptions( s, pLits + nResL, nLitsL, nConfLimit );
2275 for ( i = 0; i < nResL; i++ )
2276 sat_solver_pop(s);
2277 return nResL + nResR;
2278}
2279
2280// This is a specialized version of the above procedure with several custom changes:
2281// - makes sure that at least one of the marked literals is preserved in the clause
2282// - sets literals to zero when they do not have to be used
2283// - sets literals to zero for disproved variables
2284int sat_solver_minimize_assumptions2( sat_solver* s, int * pLits, int nLits, int nConfLimit )
2285{
2286 int i, k, nLitsL, nLitsR, nResL, nResR;
2287 if ( nLits == 1 )
2288 {
2289 // since the problem is UNSAT, we will try to solve it without assuming the last literal
2290 // if the result is UNSAT, the last literal can be dropped; otherwise, it is needed
2291 int RetValue = 1, LitNot = Abc_LitNot(pLits[0]);
2292 int status = l_False;
2293 int Temp = s->nConfLimit;
2294 s->nConfLimit = nConfLimit;
2295
2296 RetValue = sat_solver_push( s, LitNot ); assert( RetValue );
2297 status = sat_solver_solve_internal( s );
2298 sat_solver_pop( s );
2299
2300 // if the problem is UNSAT, add clause
2301 if ( status == l_False )
2302 {
2303 RetValue = sat_solver_addclause( s, &LitNot, &LitNot+1 );
2304 assert( RetValue );
2305 }
2306
2307 s->nConfLimit = Temp;
2308 return (int)(status != l_False); // return 1 if the problem is not UNSAT
2309 }
2310 assert( nLits >= 2 );
2311 nLitsL = nLits / 2;
2312 nLitsR = nLits - nLitsL;
2313 // assume the left lits
2314 for ( i = 0; i < nLitsL; i++ )
2315 if ( !sat_solver_push(s, pLits[i]) )
2316 {
2317 for ( k = i; k >= 0; k-- )
2318 sat_solver_pop(s);
2319
2320 // add clauses for these literal
2321 for ( k = i+1; k > nLitsL; k++ )
2322 {
2323 int LitNot = Abc_LitNot(pLits[i]);
2324 int RetValue = sat_solver_addclause( s, &LitNot, &LitNot+1 );
2325 assert( RetValue );
2326 }
2327
2328 return sat_solver_minimize_assumptions2( s, pLits, i+1, nConfLimit );
2329 }
2330 // solve for the right lits
2331 nResL = sat_solver_minimize_assumptions2( s, pLits + nLitsL, nLitsR, nConfLimit );
2332 for ( i = 0; i < nLitsL; i++ )
2333 sat_solver_pop(s);
2334 // swap literals
2335// assert( nResL <= nLitsL );
2336 veci_resize( &s->temp_clause, 0 );
2337 for ( i = 0; i < nLitsL; i++ )
2338 veci_push( &s->temp_clause, pLits[i] );
2339 for ( i = 0; i < nResL; i++ )
2340 pLits[i] = pLits[nLitsL+i];
2341 for ( i = 0; i < nLitsL; i++ )
2342 pLits[nResL+i] = veci_begin(&s->temp_clause)[i];
2343 // assume the right lits
2344 for ( i = 0; i < nResL; i++ )
2345 if ( !sat_solver_push(s, pLits[i]) )
2346 {
2347 for ( k = i; k >= 0; k-- )
2348 sat_solver_pop(s);
2349
2350 // add clauses for these literal
2351 for ( k = i+1; k > nResL; k++ )
2352 {
2353 int LitNot = Abc_LitNot(pLits[i]);
2354 int RetValue = sat_solver_addclause( s, &LitNot, &LitNot+1 );
2355 assert( RetValue );
2356 }
2357
2358 return sat_solver_minimize_assumptions2( s, pLits, i+1, nConfLimit );
2359 }
2360 // solve for the left lits
2361 nResR = sat_solver_minimize_assumptions2( s, pLits + nResL, nLitsL, nConfLimit );
2362 for ( i = 0; i < nResL; i++ )
2363 sat_solver_pop(s);
2364 return nResL + nResR;
2365}
2366
2367
2368
2370{
2371 return s->size;
2372}
2373
2374
2376{
2377 return s->stats.clauses;
2378}
2379
2380
2382{
2383 return (int)s->stats.conflicts;
2384}
2385
2386//=================================================================================================
2387// Clause storage functions:
2388
2390{
2391 assert( s->pStore == NULL );
2392 s->pStore = Sto_ManAlloc();
2393}
2394
2395void sat_solver_store_write( sat_solver * s, char * pFileName )
2396{
2397 if ( s->pStore ) Sto_ManDumpClauses( (Sto_Man_t *)s->pStore, pFileName );
2398}
2399
2401{
2402 if ( s->pStore ) Sto_ManFree( (Sto_Man_t *)s->pStore );
2403 s->pStore = NULL;
2404}
2405
2407{
2408 if ( s->pStore ) return Sto_ManChangeLastClause( (Sto_Man_t *)s->pStore );
2409 return -1;
2410}
2411
2413{
2414 if ( s->pStore ) Sto_ManMarkRoots( (Sto_Man_t *)s->pStore );
2415}
2416
2421
2423{
2424 void * pTemp;
2425 if ( s->pStore == NULL )
2426 return NULL;
2427 pTemp = s->pStore;
2428 s->pStore = NULL;
2429 return pTemp;
2430}
2431
2432
2434
ABC_INT64_T abctime
Definition abc_global.h:332
int * Abc_MergeSortCost(int *pCosts, int nSize)
Definition utilSort.c:442
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_REALLOC(type, obj, num)
Definition abc_global.h:268
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_CONST(number)
PARAMETERS ///.
Definition abc_global.h:240
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define l_True
Definition bmcBmcS.c:35
#define l_Undef
Definition bmcBmcS.c:34
#define l_False
Definition bmcBmcS.c:36
#define var_Undef
Definition SolverTypes.h:45
#define sat_solver_addclause
Definition cecSatG2.c:37
#define sat_solver_addvar
Definition cecSatG2.c:40
#define sat_solver
Definition cecSatG2.c:34
#define sat_solver_solve
Definition cecSatG2.c:45
Cube * p
Definition exorList.c:222
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
unsigned long long size
Definition giaNewBdd.h:39
#define Sat_MemForEachLearned(p, c, i, k)
Definition satClause.h:127
#define LEARNT_MAX_RATIO_DEFAULT
Definition satClause.h:39
#define LEARNT_MAX_START_DEFAULT
INCLUDES ///.
Definition satClause.h:37
#define LEARNT_MAX_INCRE_DEFAULT
Definition satClause.h:38
struct Sat_Mem_t_ Sat_Mem_t
Definition satClause.h:70
#define L_ind
Definition satSolver.c:41
void luby_test()
Definition satSolver.c:1809
sat_solver * sat_solver_new(void)
Definition satSolver.c:1137
int sat_solver_get_var_value(sat_solver *s, int v)
Definition satSolver.c:118
int sat_solver_store_change_last(sat_solver *s)
Definition satSolver.c:2406
int sat_solver_solve_internal(sat_solver *s)
Definition satSolver.c:1942
void sat_solver_store_mark_clauses_a(sat_solver *s)
Definition satSolver.c:2417
int sat_solver_simplify(sat_solver *s)
Definition satSolver.c:1515
void sat_solver_restart(sat_solver *s)
Definition satSolver.c:1389
int sat_solver_nconflicts(sat_solver *s)
Definition satSolver.c:2381
void sat_solver_store_free(sat_solver *s)
Definition satSolver.c:2400
int sat_solver_nclauses(sat_solver *s)
Definition satSolver.c:2375
void zsat_solver_restart_seed(sat_solver *s, double seed)
Definition satSolver.c:1435
void sat_solver_store_write(sat_solver *s, char *pFileName)
Definition satSolver.c:2395
void sat_solver_set_var_activity(sat_solver *s, int *pVars, int nVars)
Definition satSolver.c:218
void sat_solver_setnvars(sat_solver *s, int n)
Definition satSolver.c:1272
#define L_IND
Definition satSolver.c:40
void sat_solver_store_alloc(sat_solver *s)
Definition satSolver.c:2389
int sat_solver_nvars(sat_solver *s)
Definition satSolver.c:2369
void sat_solver_rollback(sat_solver *s)
Definition satSolver.c:1643
sat_solver * zsat_solver_new_seed(double seed)
Definition satSolver.c:1202
#define L_lit(p)
Definition satSolver.c:43
int sat_solver_push(sat_solver *s, int p)
Definition satSolver.c:2002
int sat_solver_clause_new(sat_solver *s, lit *begin, lit *end, int learnt)
Definition satSolver.c:533
int sat_solver_propagate(sat_solver *s)
Definition satSolver.c:1019
void sat_solver_store_mark_roots(sat_solver *s)
Definition satSolver.c:2412
int sat_solver_count_assigned(sat_solver *s)
Definition satSolver.c:744
void sat_solver_pop(sat_solver *s)
Definition satSolver.c:2045
double luby(double y, int x)
Definition satSolver.c:1797
void * sat_solver_store_release(sat_solver *s)
Definition satSolver.c:2422
int sat_solver_minimize_assumptions2(sat_solver *s, int *pLits, int nLits, int nConfLimit)
Definition satSolver.c:2284
void sat_solver_set_resource_limits(sat_solver *s, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal)
Definition satSolver.c:2051
void sat_solver_reducedb(sat_solver *s)
Definition satSolver.c:1523
void sat_solver_delete(sat_solver *s)
Definition satSolver.c:1341
int sat_solver_solve_lexsat(sat_solver *s, int *pLits, int nLits)
Definition satSolver.c:2143
#define L_LIT
Definition satSolver.c:42
int sat_solver_minimize_assumptions(sat_solver *s, int *pLits, int nLits, int nConfLimit)
Definition satSolver.c:2209
double sat_solver_memory(sat_solver *s)
Definition satSolver.c:1479
void Sto_ManMarkClausesA(Sto_Man_t *p)
Definition satStore.c:257
Sto_Man_t * Sto_ManAlloc()
MACRO DEFINITIONS ///.
Definition satStore.c:121
void Sto_ManDumpClauses(Sto_Man_t *p, char *pFileName)
Definition satStore.c:305
int Sto_ManAddClause(Sto_Man_t *p, lit *pBeg, lit *pEnd)
Definition satStore.c:160
int Sto_ManChangeLastClause(Sto_Man_t *p)
Definition satStore.c:279
void Sto_ManFree(Sto_Man_t *p)
Definition satStore.c:143
void Sto_ManMarkRoots(Sto_Man_t *p)
Definition satStore.c:235
struct Sto_Man_t_ Sto_Man_t
Definition satStore.h:81
int lit
Definition satVec.h:130
int cla
Definition satVec.h:131
struct veci_t veci
Definition satVec.h:36
signed char lbool
Definition satVec.h:135
int BookMarkE[2]
Definition satClause.h:75
unsigned lbd
Definition clause.h:22
unsigned lits[3]
Definition clause.h:39
unsigned size
Definition clause.h:37
Definition heap.h:19
char * tags
Definition satSolver.h:138
ABC_INT64_T nInsLimit
Definition satSolver.h:171
double * factors
Definition satSolver.h:175
int * pGlobalVars
Definition satSolver.h:186
int(* pCnfFunc)(void *p, int)
Definition satSolver.h:204
void * pCnfMan
Definition satSolver.h:203
int * orderpos
Definition satSolver.h:141
double random_seed
Definition satSolver.h:157
unsigned cla_inc
Definition satSolver.h:127
word * activity
Definition satSolver.h:125
veci conf_final
Definition satSolver.h:151
Sat_Mem_t Mem
Definition satSolver.h:108
ABC_INT64_T nConfLimit
Definition satSolver.h:170
unsigned cla_decay
Definition satSolver.h:128
int fNotUseRandom
Definition satSolver.h:183
int(* pFuncStop)(int)
Definition satSolver.h:208
char * assigns
Definition satSolver.h:136
char * polarity
Definition satSolver.h:137
void * pStore
Definition satSolver.h:188
int fSkipSimplify
Definition satSolver.h:182
abctime nRuntimeLimit
Definition satSolver.h:172
clause * binary
Definition satSolver.h:111
veci * wlists
Definition satSolver.h:112
veci temp_clause
Definition satSolver.h:196
double progress_estimate
Definition satSolver.h:158
stats_t stats
Definition satSolver.h:163
word * activity2
Definition satSolver.h:126
veci user_values
Definition satSolver.h:200
int * reasons
Definition satSolver.h:142
char * pFreqs
Definition satSolver.h:131
char * loads
Definition satSolver.h:139
veci pivot_vars
Definition satSolver.h:180
ABC_INT64_T decisions
Definition satVec.h:156
ABC_INT64_T learnts_literals
Definition satVec.h:157
ABC_INT64_T conflicts
Definition satVec.h:156
ABC_INT64_T tot_literals
Definition satVec.h:157
unsigned clauses
Definition satVec.h:155
unsigned starts
Definition satVec.h:155
ABC_INT64_T inspects
Definition satVec.h:156
ABC_INT64_T clauses_literals
Definition satVec.h:157
unsigned learnts
Definition satVec.h:155
ABC_INT64_T propagations
Definition satVec.h:156
Definition walk.c:24
unsigned pol
Definition satSolver.c:84
unsigned tag
Definition satSolver.c:85
unsigned val
Definition satSolver.c:83
unsigned lev
Definition satSolver.c:86
int size
Definition satVec.h:33
int * ptr
Definition satVec.h:34
int cap
Definition satVec.h:32
ABC_NAMESPACE_HEADER_START typedef word xdbl
STRUCTURE DEFINITIONS ///.
Definition utilDouble.h:49
#define assert(ex)
Definition util_old.h:213
char * memcpy()
char * memset()