source: vis_dev/cusp-1.1/src/sat/varelim.c@ 49

Last change on this file since 49 was 12, checked in by cecile, 15 years ago

cusp added

File size: 84.8 KB
Line 
1/**CFile***********************************************************************
2
3 FileName [ varelim.c ]
4
5 PackageName [ sat ]
6
7 Synopsis [ Routines for variable elimination ]
8
9 Author [ Hyojung Han ]
10
11 Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
12
13 All rights reserved.
14
15 Redistribution and use in source and binary forms, with or without
16 modification, are permitted provided that the following conditions
17 are met:
18
19 Redistributions of source code must retain the above copyright
20 notice, this list of conditions and the following disclaimer.
21
22 Redistributions in binary form must reproduce the above copyright
23 notice, this list of conditions and the following disclaimer in the
24 documentation and/or other materials provided with the distribution.
25
26 Neither the name of the University of Colorado nor the names of its
27 contributors may be used to endorse or promote products derived from
28 this software without specific prior written permission.
29
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 POSSIBILITY OF SUCH DAMAGE.]
42
43******************************************************************************/
44#include <setjmp.h>
45#include <signal.h>
46#include <string.h>
47#include <stdlib.h>
48#include "sat.h"
49#include "util.h"
50
51#define VERIFY_ON
52
53/* #define __DEBUG */
54/* #define DEBUG */
55#define CLENGTH_LIMIT 5
56
57/** Duplicated from util.c **/
58#define heap_left(i) ((i<<1)+1)
59#define heap_right(i) ((i+1)<<1)
60#define heap_parent(i) ((i-1)>>1)
61
62/******************************************************************************
63 * FUNCTION DECLARATIONS
64 ******************************************************************************/
65#ifndef CUR_DATE
66#define CUR_DATE "<compile date not supplied>"
67#endif
68
69#ifndef CUR_VER
70#define CUR_VER "U of Colorado/Boulder, CirCUs Release 2.0"
71#endif
72
73static int vel_compare_scores(satManager_t *m, long x, long y);
74
75/******************************************************************************
76 * FUNCTION DESCRIPTIONS
77 ******************************************************************************/
78
79/**Function********************************************************************
80
81 Synopsis [ Initialize options for preprocessing ]
82
83 Description [ Initialize options for preprocessing ]
84
85 SideEffects [ This function allows external application to initialize
86 the options to use variable elimination. ]
87
88 SeeAlso [ sat_init_options_for_distill ]
89
90******************************************************************************/
91void
92sat_init_options_for_varelim(satManager_t *m)
93{
94
95 if (m == 0)
96 fprintf(stderr, "ERROR : SAT manager is not initialized!\n");
97
98 m->simplify = 1;
99 m->grow = 0;
100 m->nIteratePreprocess = 3;
101}
102
103/**Function********************************************************************
104
105 Synopsis [ Main function of variable elimination ]
106
107 Description [ Main function of variable elimination ]
108
109 SideEffects [ Set m->marks[v] = 1 for a variable v eliminated.
110 Reset m->marks[v] for all variables v before exiting function.
111 ]
112
113 SeeAlso [ ]
114
115******************************************************************************/
116int
117sat_eliminate_var_main(satManager_t *m)
118{
119long i, v;
120int verbosity, simplified, eliminable;
121int iterations, progress, progress_n;
122long cnt, nCandidates;
123double btime, etime;
124satHeap_t *h;
125satQueue_t *subsumption_queue;
126
127 iterations = m->nIteratePreprocess;
128 btime = (double)util_cpu_time();
129
130 verbosity = m->verbosity;
131 subsumption_queue = m->satQueue;
132
133 m->nInputVars = m->nVars;
134 m->nInputClauses = m->clauses->size + m->learned->size;
135 m->nInputLiterals = m->nCurClauseLits;
136
137#ifdef DEBUG
138 fprintf(stdout, "CHECK : all clauses sorted before VARELIM Unit \n");
139 sat_check_all_clauses_sorted(m);
140#endif
141
142 /** Initialize varElimHeap of the number
143 * of unassigned variables, and insert
144 * the variables into the varElimHeap.
145 **/
146 h = m->varElimHeap;
147 simplified = 1;
148 if (sat_implication_on_all_watched_literals(m) != 0) {
149 simplified = 0;
150 goto endVarElim;
151 }
152
153 if (sat_check_clauses_high_density(m) == 1) {
154 if (!sat_backward_subsumption_check(m))
155 simplified = 0;
156 else {
157 sat_init_clauses_statistics(m);
158 sat_reset_all_watched_lists(m);
159 sat_recover_clauses_DB(m);
160 sat_remove_marked_clauses(m, m->clauses);
161 sat_remove_marked_clauses(m, m->learned);
162 }
163 goto endVarElim;
164 }
165
166 if (verbosity >= 2 ) {
167 fprintf(stdout, "Variable Elimiation Procedure\n");
168
169 fprintf(stdout, "===============================[ VarElim Statistics ]=============================\n");
170 fprintf(stdout, " TRIAL | ORIGINAL | RESOLVENT | REJECT |\n");
171 fprintf(stdout, " | Vars Clauses Literals | Clauses Literals Lit/Cl | Bnd Self |\n");
172 fprintf(stdout, "==================================================================================\n");
173 fprintf(stdout, "| %4ld | %7ld %8ld %8.f | %10ld %9ld %7s | %5ld %5ld |\n",
174 m->nVarElimTry, h->size, m->clauses->size, m->nCurClauseLits,
175 m->nResolvents, m->nResolventLits, "N/A", m->nVarElimReject, m->nSelfsubsume);
176 fflush(stdout);
177 }
178
179 progress = 0;
180 nCandidates = h->size;
181
182beginVarElim:;
183
184 if (!sat_backward_subsumption_check(m)) {
185 simplified = 0;
186 goto endVarElim;
187 }
188 m->nSubsumeTry++;
189
190 v = 0;
191 for (cnt = 0; h->size > 0; cnt++) {
192 if (m->nResolventLits > 0 && verbosity >= 2 && cnt%100 == 0) {
193 fprintf(stdout, "| %4ld | %7ld %8ld %8.f | %10ld %9ld %7.2f | %5ld %5ld |\n",
194 m->nVarElimTry, nCandidates - m->nEliminatedVars, m->clauses->size - m->nEliminatedCls,
195 (m->nCurClauseLits + m->nResolventLits) - m->nEliminatedLits,
196 m->nResolvents, m->nResolventLits, (double)m->nResolventLits/(double)m->nResolvents,
197 m->nVarElimReject, m->nSelfsubsume);
198 fflush(stdout);
199 }
200
201 v = vel_heap_remove_min(m);
202 if (m->values[v] != 2) continue;
203
204 m->nVarElimTry++;
205 eliminable = sat_eliminate_var(m, v);
206 if (eliminable == 1) {
207 /* add the resolvents generated */
208 m->values[v] = 3;
209 sat_mark_clauses_of_var_deleted(m, v);
210 sat_add_resolvents_from_lit_pool(m, m->redundant);
211
212 /* store eliminated variable to find its value
213 * if problem is satisfiable
214 */
215 m->elimtable = sat_array_insert(m->elimtable, v);
216 m->nEliminatedVars++;
217 }
218 else if (eliminable == 0)
219 m->nVarElimReject++;
220 else sat_implication_on_all_watched_literals(m);
221
222 if (!sat_backward_subsumption_check(m) || m->clauses->size == 0 || m->status < 2) {
223 fprintf(stdout, "Solved in preprocessing level!\n");
224 simplified = 0;
225 if (m->clauses->size == 0)
226 m->status = 1;
227
228 goto endVarElim;
229 }
230 }
231
232 if (!m->eliminateVar) {
233 sat_gather_touched_clauses(m);
234 if (subsumption_queue->size > 0 || h->size > 0) {
235 if (sat_implication_on_all_watched_literals(m) != 0) {
236 simplified = 0;
237 goto endVarElim;
238 }
239 goto beginVarElim;
240 }
241
242 progress_n = sat_elimination_progress(m);
243 if (iterations > 0 && (progress_n - progress) > 10) {
244 progress = progress_n;
245 sat_insert_clauses_into_subsumption_check_queue(m, m->clauses);
246 if (sat_implication_on_all_watched_literals(m) != 0) {
247 simplified = 0;
248 goto endVarElim;
249 }
250 if (subsumption_queue->size > 0) {
251 iterations--;
252 goto beginVarElim;
253 }
254 }
255 }
256
257 if (verbosity >= 2) {
258 fprintf(stdout, "| %4ld | %7ld %8ld %8.f | %10ld %9ld %7.2f | %5ld %5ld |\n",
259 m->nVarElimTry, nCandidates - m->nEliminatedVars, m->clauses->size - m->nEliminatedCls,
260 (m->nCurClauseLits + m->nResolventLits)-m->nEliminatedLits, m->nResolvents, m->nResolventLits,
261 (double)m->nResolventLits/(double)m->nResolvents, m->nVarElimReject,
262 m->nSelfsubsume);
263 fflush(stdout);
264 fprintf(stdout, "==================================================================================\n");
265 }
266
267 sat_init_clauses_statistics(m);
268 sat_reset_all_watched_lists(m);
269 sat_recover_clauses_DB(m);
270 sat_remove_marked_clauses(m, m->clauses);
271 sat_remove_marked_clauses(m, m->learned);
272
273 if (verbosity >= 2)
274 sat_print_clauses_histogram(m);
275
276 /* remove pure literals */
277 if (!m->allSat) {
278 for(i=1; i<=m->nVars; i++) {
279 if (m->values[i] == 2) {
280 if(m->pure[i] == 1) {
281 sat_enqueue_check(m, i<<1, 0);
282 }
283 else if(m->pure[i] == 2) {
284 sat_enqueue_check(m, (i<<1)+1, 0);
285 }
286 }
287 }
288 }
289
290endVarElim:;
291 etime = (double)util_cpu_time();
292 m->elimTime = (etime - btime) / 1000.0;
293 sat_report_result_for_var_elim(m);
294 fflush(stdout);
295
296 return simplified;
297}
298
299/**Function********************************************************************
300
301 Synopsis [ Calculate progress in elimination ]
302
303 Description [ Calculate progress in elimination ]
304
305 SideEffects [ retrun 0 if progress is negligible, otherwise return progress ]
306
307 SeeAlso [ ]
308
309******************************************************************************/
310int
311sat_elimination_progress(satManager_t *m)
312{
313double progress;
314
315 progress = 0;
316 progress = 100 * (double)m->nEliminatedLits / (double)m->nLits;
317
318 return (int)progress;
319}
320
321/**Function********************************************************************
322
323 Synopsis [ Write eliminated data base into a file]
324
325 Description [ Write eliminated data base into a file.
326 Note that it doesn't write them in DIMACS. ]
327
328 SideEffects [ ]
329
330 SeeAlso [ ]
331
332******************************************************************************/
333void
334sat_write_eliminated_DB(satManager_t *m, int turnOffClauses)
335{
336long i, j, size, csize;
337long v, lit;
338char filename[1024];
339FILE *fp;
340satArray_t *arr;
341satClause_t *c;
342
343 sprintf(filename, "cnf.elim");
344 fp = fopen(filename, "w");
345 fprintf(fp, "===========\n");
346 fprintf(fp, " variables \n");
347 fprintf(fp, "===========\n");
348
349 arr = m->elimtable;
350 size = arr->size;
351 for (i = 0; i < size; i++) {
352 v = arr->space[i];
353 fprintf(fp, "%ld ", v);
354
355 if ((i % 15) == 1)
356 fprintf(fp, "\n");
357 }
358 fprintf(fp, "\n");
359
360 if (!turnOffClauses) {
361 fprintf(fp, "===========\n");
362 fprintf(fp, " clauses \n");
363 fprintf(fp, "===========\n");
364
365 arr = m->deleted;
366 for (i = 0; i < arr->size; i++) {
367 c = (satClause_t*)arr->space[i];
368 csize = SATSizeClause(c);
369 fprintf(fp, "%d %f (", (int) c->size & SATCTypeMask, c->info.activity);
370 for (j = 0; j < csize; j++) {
371 lit = c->lits[j];
372 v = lit >> 1;
373 fprintf(fp, "%c%ld ", lit & 1 ? '-' : ' ', v);
374 }
375 fprintf(fp, ")\n");
376 }
377 }
378
379 fclose(fp);
380}
381
382/**Function********************************************************************
383
384 Synopsis [ Apply variable elimination ]
385
386 Description [ Apply variable elimination ]
387
388 SideEffects [ ]
389
390 SeeAlso [ ]
391
392******************************************************************************/
393int
394sat_eliminate_var(satManager_t *m, long v)
395{
396int eliminable, first;
397long lit;
398long cnt, i, j, cntLits;
399satClause_t *posc, *negc;
400satArray_t *pos, *neg;
401
402 m->temp->size = 0;
403 cntLits = 0;
404 first = 0;
405
406 /** Get the positive and
407 * negative occurrence list
408 **/
409 lit = v << 1;
410 pos = m->wls[lit^1];
411 neg = m->wls[lit];
412
413 if (!pos || pos->size == 0)
414 return 1;
415
416 else if (!neg || neg->size == 0)
417 return 1;
418
419 /** Apply resolution operation for each pair
420 * of postive and negative occurrence clauses
421 **/
422 cnt = 0;
423 for (i = 0; i < pos->size; i++) {
424 posc = (satClause_t*)pos->space[i];
425 if (SATClauseVisited(posc)) {
426 pos->space[i] = pos->space[--pos->size];
427 i--;
428 continue;
429 }
430 first++;
431
432 /** continue only if the clauses of both
433 * sign currently exist
434 **/
435 cntLits += posc->size;
436
437 for (j = 0; j < neg->size; j++) {
438 negc = (satClause_t*)neg->space[j];
439 if (SATClauseVisited(negc)) {
440 neg->space[j] = neg->space[--neg->size];
441 j--;
442 continue;
443 }
444 if (first == 1)
445 cntLits += negc->size;
446
447 eliminable = sat_merge_sort_literals(m, posc, negc, i, j, v);
448
449 if (eliminable == 1) {
450
451 /** Two criterions to limit the size of database :
452 * 1. the number of clauses to be added
453 * 2. the average number of literals to be added
454 **/
455 if ((++cnt > ((m->scores[lit] + m->scores[lit|1]) + m->grow)) ||
456#ifdef VERIFY_ON
457 (((double)(m->redundant->size - (cnt<<1)) /cnt) > (CLENGTH_LIMIT * 2*((double)m->nCurClauseLits/m->nClauses)))) {
458#else
459 (m->redundant->size - cnt) /cnt > (CLENGTH_LIMIT *(m->nCurClauseLits/m->nClauses))) {
460#endif
461 m->redundant->size = 0;
462 return 0;
463 }
464 }
465 else if (eliminable == 2) {
466 /* Skip to next i due to posc selfsubsubsumed */
467 m->nSelfsubsume++;
468 i--;
469 break;
470 }
471 else if (eliminable == 3) {
472 /* Break j loop due to negc selfsubsumed */
473 m->nSelfsubsume++;
474 j--;
475 }
476 else if (eliminable == 4) {
477 i--;
478 break;
479 }
480 else if (eliminable == 5) {
481 j--;
482 }
483 else
484 continue;
485 }
486 }
487
488 return 1;
489}
490
491/**Function********************************************************************
492
493 Synopsis [ Build occurency lists with watched lists ]
494
495 Description [ Build occurency lists with watched lists ]
496
497 SideEffects [ ]
498
499 SeeAlso [ ]
500
501******************************************************************************/
502void
503sat_build_occurrence_list(satManager_t *m)
504{
505long i, size;
506satClause_t *c;
507satArray_t *cls;
508
509 cls = m->clauses;
510 size = cls->size;
511 for (i=0; i<size; i++) {
512 c = (satClause_t*)cls->space[i];
513 if (SATClauseVisited(c)) {
514 c->size -= SATCVisited;
515 }
516 else if (SATSizeClause(c) > 1) {
517 sat_add_all_watched_literal(m, c);
518 sat_queue_insert(m->satQueue, (long)c);
519 }
520 }
521
522 cls = m->learned;
523 size = cls->size;
524 for (i=0; i<size; i++) {
525 c = (satClause_t*)cls->space[i];
526 if (SATClauseVisited(c)) {
527 c->size -= SATCVisited;
528 }
529 else if (SATSizeClause(c) > 1) {
530 sat_add_all_watched_literal(m, c);
531 sat_queue_insert(m->satQueue, (long)c);
532 }
533 }
534}
535
536/**Function********************************************************************
537
538 Synopsis [ Insert clauses into subsumption check queue ]
539
540 Description [ Insert clauses into subsumption check queue ]
541
542 SideEffects [ ]
543
544 SeeAlso [ ]
545
546******************************************************************************/
547void
548sat_insert_clauses_into_subsumption_check_queue(satManager_t *m, satArray_t *clauses)
549{
550long i, j, size, csize;
551long v, lit;
552satClause_t *c;
553
554 size = clauses->size;
555 for (i = 0; i < size; i++) {
556 c = (satClause_t*)clauses->space[i];
557 if (SATClauseVisited(c)) continue;
558
559 csize = SATSizeClause(c);
560 if (csize == 1) {
561 sat_enqueue_check(m, c->lits[0], c);
562 }
563 else {
564 if (!sat_squeeze_clause(m, c) ||
565 ((double)SATSizeClause(c)) > CLENGTH_LIMIT * ((double)m->nCurClauseLits/(double)m->nClauses))
566 continue;
567
568 for(j = 0; j < csize; j++) {
569 lit = c->lits[j];
570 v = lit >> 1;
571 if ((m->scores[lit] > 10 && m->scores[lit|1] > 10) || (m->scores[lit] + m->scores[lit|1] > 40))
572 continue;
573
574 if (m->values[v] == 2) {
575 if(m->varElimHeap->indices[v] >= 0)
576 vel_heap_down(m, m->varElimHeap->indices[v]);
577 else
578 vel_heap_insert(m, v);
579 }
580 }
581 sat_queue_insert(m->satQueue, (long)c);
582 }
583 }
584}
585
586/**Function********************************************************************
587
588 Synopsis [ Merge and sort literals ]
589
590 Description [ Merge and sort literals
591
592 Encoding eliminable :
593 0 -> tautology
594 1 -> eliminable and addable the resolvent
595 2 -> eliminable and selfsubsuming p
596 3 -> eliminable and selfsubsuming q
597 4 -> eliminable and selfsubsumming both P & q
598 ]
599
600 SideEffects [ Precondition : each set of literals of a cluase is
601 suppose to be sorted when it is instantiated. ]
602
603 SeeAlso [ ]
604
605******************************************************************************/
606int
607sat_merge_sort_literals(
608 satManager_t *m,
609 satClause_t *cp,
610 satClause_t *cq,
611 long cpindex,
612 long cqindex,
613 long v)
614{
615int eliminable, beginLit;
616long i, j, nCommon;
617long cpsize, cqsize, crsize;
618long wlpindex, wlqindex, vpindex, vqindex;
619long vp, vq, litp, litq, value;
620satArray_t *rcarray;
621
622 rcarray = m->redundant;
623 /* Use the first literal position
624 * as a flag for deletion
625 */
626 beginLit = rcarray->size;
627 rcarray = sat_array_insert(rcarray, 0);
628 eliminable = 1;
629
630#ifdef __DEBUG
631 fprintf(stdout, " ----------------------------------------------\n");
632 fprintf(stdout, " * Resolve on VAR %d\n", v);
633 fprintf(stdout, " (");
634 sat_print_clause_simple(m, cp);
635 fprintf(stdout, ") \n (");
636 sat_print_clause_simple(m, cq);
637 fprintf(stdout, ") \n");
638 fprintf(stdout, " ----------------------------------------------\n");
639#endif
640
641 vp = vq = litp = litq = 0;
642 vpindex = vqindex = 0;
643 i = j = 0;
644 crsize = 0;
645 cpsize = SATSizeClause(cp);
646 cqsize = SATSizeClause(cq);
647 nCommon = 0;
648 wlpindex = (v<<1)^1;
649 wlqindex = (v<<1);
650 while (i<cpsize || j<cqsize) {
651 if (i < cpsize) {
652 litp = cp->lits[i];
653 vp = SATVar(litp);
654 value = m->values[vp];
655
656 /* skip the false literals of p */
657 if (value < 2) {
658 if (value^(litp&1)) {
659 cp->size |= SATCVisited;
660 sat_delete_clause_from_watched_list(m, cp, wlpindex, cpindex);
661 rcarray->size = beginLit;
662 m->redundant = rcarray;
663#ifdef __DEBUG
664 fprintf(stdout, "Satisfied clause on positive literal %ld = %d\n", vp, (int)value);
665#endif
666 return 4;
667 }
668 else {
669 i++;
670 continue;
671 }
672 }
673
674 /* skip the pivot variable and
675 * storing its wl index in p
676 */
677 if (vp == v) {
678 vpindex = i++;
679 continue;
680 }
681 }
682
683 if (j < cqsize) {
684 litq = cq->lits[j];
685 vq = SATVar(litq);
686 value = m->values[vq];
687 /* skip the false literals of q */
688 if (value < 2) {
689 if (value^(litq&1)) {
690 cq->size |= SATCVisited;
691 sat_delete_clause_from_watched_list(m, cq, wlqindex, cqindex);
692 rcarray->size = beginLit;
693 m->redundant = rcarray;
694#ifdef __DEBUG
695 fprintf(stdout, "Satisfied clause on negative literal %ld = %d\n", vq, (int)value);
696#endif
697 return 5;
698 }
699 else {
700 j++;
701 continue;
702 }
703 }
704 /* skip the pivot variable and
705 * store its wl index in q
706 */
707 if (vq == v) {
708 vqindex = j++;
709 continue;
710 }
711 }
712
713 /* check common literals
714 */
715 if (vp == vq) {
716 /* return "eliminable"
717 * for tautology case
718 */
719 if (litp == (litq^1)) {
720 /* remove the current resolvent */
721 rcarray->size = beginLit;
722 m->redundant = rcarray;
723 return 0;
724 }
725
726
727 nCommon++;
728 rcarray = sat_array_insert(rcarray, litp);
729 j++;
730 i++;
731 }
732 /* insert q's literal because of no p's literal left */
733 else if (i >= cpsize) {
734 rcarray = sat_array_insert(rcarray, litq);
735 j++;
736 }
737 /* insert p's literal because of no q's literal left */
738 else if (j >= cqsize) {
739 rcarray = sat_array_insert(rcarray, litp);
740 i++;
741 }
742 /* insert the literal with smaller index */
743 else if (vp < vq) {
744 rcarray = sat_array_insert(rcarray, litp);
745 i++;
746 }
747 else {
748 rcarray = sat_array_insert(rcarray, litq);
749 j++;
750 }
751
752 crsize++;
753 }
754
755 if (m->coreGeneration) {
756 rcarray = sat_array_insert(rcarray, (long)cp);
757 rcarray = sat_array_insert(rcarray, (long)cq);
758 }
759 rcarray->space[beginLit] = -crsize;
760 m->redundant = rcarray;
761
762#ifdef __DEBUG
763 sat_check_clause_after_merge_sort(m, rcarray, beginLit);
764#endif
765
766#if 1 /* to enable self-subsumption check */
767
768 /** part for checking selfsubsumption **/
769
770 /* p is subsumed by the resolvent */
771 if (nCommon == cqsize-1) {
772 if (!sat_strengthen_clause(m, cp, vpindex))
773 m->nNewUnitLits++;
774
775#ifdef __DEBUG
776 fprintf(stdout, " [ Strengthened ] (");
777 sat_print_clause_simple(m, cp);
778 fprintf(stdout, ")\n");
779#endif
780
781 /* discard the current resolvent */
782 rcarray->size = beginLit;
783
784 /** TODO : Disable the following function to speed up **/
785 sat_delete_redundant_resolvents(m, cp);
786 sat_delete_clause_from_watched_list(m, cp, wlpindex, cpindex);
787 eliminable = 2;
788 }
789
790 /* q is subsumed by the resolvent */
791 if (nCommon == cpsize-1) {
792 /* avoid clause duplication in strengthening */
793 if (eliminable < 2) {
794 eliminable = 3;
795 if (!sat_strengthen_clause(m, cq, vqindex))
796 m->nNewUnitLits++;
797
798#ifdef __DEBUG
799 fprintf(stdout, " [ Strengthened ] (");
800 sat_print_clause_simple(m, cq);
801 fprintf(stdout, ")\n");
802#endif
803
804 }
805 /* discard the current resolvent */
806 rcarray->size = beginLit;
807 sat_delete_redundant_resolvents(m, cq);
808 sat_delete_clause_from_watched_list(m, cq, wlqindex, cqindex);
809 }
810
811#endif /* #if 0 to disable self-subsumption check */
812
813#ifdef __DEBUG
814 if (rcarray->size) {
815 fprintf(stdout, " [ Resolvent ] ");
816 sat_print_clause_array_part(m, rcarray, beginLit+1, rcarray->size);
817 fprintf(stdout, "\n");
818 }
819#endif
820 return eliminable;
821}
822
823/**Function********************************************************************
824
825 Synopsis [ Merge the literals of two clauses ]
826
827 Description [ Merge the literals of two clauses ]
828
829 SideEffects [ cp and cq must be compared by the
830 size when this function is called.
831 Thus _cq is always smaller one.]
832
833 SeeAlso [ ]
834
835******************************************************************************/
836int
837sat_merge_literals(
838 satManager_t *m,
839 satClause_t *cp,
840 satClause_t *cq,
841 satArray_t *rcarray,
842 long cpindex,
843 long cqindex,
844 long v)
845{
846int cp_smaller;
847long i, j, index, common, flag;
848long cpsize, cqsize;
849long _cpindex, wlpindex;
850long vp, vq, litp, litq;
851satClause_t *_cp, *_cq;
852
853 rcarray->size = 0;
854
855 cpsize = SATSizeClause(cp);
856 cqsize = SATSizeClause(cq);
857
858#ifdef __DEBUG
859 fprintf(stdout, " * Resolve ");
860 sat_print_clause_simple(m, cp);
861 fprintf(stdout, " (x) ");
862 sat_print_clause_simple(m, cq);
863 fprintf(stdout, "\n");
864#endif
865
866 cp_smaller = cpsize < cqsize;
867 _cp = cp_smaller ? cq : cp;
868 _cq = cp_smaller ? cp : cq;
869 _cpindex = cp_smaller ? cqindex : cpindex;
870 wlpindex = v<<1;
871 index = 0;
872 common = 0;
873 flag = 0;
874 cpsize = SATSizeClause(_cp);
875 cqsize = SATSizeClause(_cq);
876 for (i=0; i<cqsize; i++) {
877 litq = _cq->lits[i];
878 vq = SATVar(litq);
879 if (m->values[vq] != 2) continue;
880
881 if (SATVar(litq) != v) {
882 for (j = 0; j < cpsize; j++) {
883 litp = _cp->lits[j];
884 vp = SATVar(litp);
885 if (m->values[vp] != 2) continue;
886 flag = 0;
887
888 if (vp == vq) {
889 /** 1. Check tautology :
890 * Value 0 is returned.
891 * Out clause then can not be used.
892 **/
893 if (litp == (litq^1))
894 return 0;
895 else {
896 /** count the number of common literals
897 * */
898 common++;
899 flag = 1;
900 }
901 }
902 }
903 if (flag == 0)
904 rcarray = sat_array_insert(rcarray, litq);
905 }
906 }
907
908 for (i=0; i<cpsize; i++) {
909 litp = _cp->lits[i];
910 vp = SATVar(litp);
911 /** 2. Remember the position of the variable v
912 * to be eliminated. Doing so is a hand in
913 * strengthening clause for selfsubsumed case.
914 **/
915 if (vp == v) {
916 index = i;
917 }
918 else
919 rcarray = sat_array_insert(rcarray, litp);
920 }
921
922 /** 3. Check selfsubsumption :
923 * The case when all the literals of
924 * _cq but the literal v also occur
925 * in cp. Then value 1 is returned.
926 * Out clause must be cp strengthed.
927 **/
928 if (common == cqsize - 1) {
929 /* don't remove this clause strengthened */
930 m->nSelfsubsume++;
931
932 /** TODO: Copy the clause before strengthening
933 * for satisfying ussignment proof of elimination.
934 **/
935
936 if (!sat_strengthen_clause(m, _cp, index)) {
937 m->nNewUnitLits++;
938 }
939
940 /** Keep recording the clause _cp strengthened
941 * as a dependent of _cq. This information may be
942 * used to delete _cq when yet it is not deleted
943 * by eliminating a variable, while it is also
944 * subsumed by the _cq strengthened, and irredundant.
945 **/
946
947#ifdef __DEBUG
948 fprintf(stdout, " *Strengthened to ");
949 sat_print_clause_simple(m, _cp);
950 fprintf(stdout, "\n");
951#endif
952
953 /** Remove all resolvents depend on
954 * either the clauses _cp or _cq.
955 * Checking the resolvents associated
956 * with _cq(shorter) is optional as commented
957 * above, because not all of them are subsumed
958 * by the strengthened clause, while the all
959 * of resolvents for _cp(longer, strengthened)
960 * is apparently redundant.
961 **/
962 /*sat_remove_dependent_resolvents(m, _cp);*/
963 sat_delete_clause_from_watched_list(m, _cp, wlpindex, _cpindex);
964
965 if (common == rcarray->size) {
966
967#ifdef __DEBUG
968 fprintf(stdout, " * Remove the redundancy : ");
969 sat_print_clause_simple(m, _cq);
970 fprintf(stdout, "\n");
971#endif
972
973 _cq->size |= SATCVisited; /* set the clause to be deleted */
974 return 4;
975 }
976 return (3 - cp_smaller);
977 }
978
979 m->clearned = rcarray;
980 return 1;
981}
982
983/**Function********************************************************************
984
985 Synopsis [ Check backward subsumption and selfsubsumption ]
986
987 Description [ Check backward subsumption and selfsubsumption
988 by resolution on CNF clauses ].
989
990 SideEffects [ ]
991
992 SeeAlso [ ]
993
994******************************************************************************/
995int
996sat_backward_subsumption_check(satManager_t *m)
997{
998int verbosity;
999int cnt, subsumed, deleted_literals;
1000long i, j, csize, index;
1001long lit, v, best, bestLit, bestSize;
1002satQueue_t *subsumption_queue;
1003satClause_t *c, *ct;
1004/*satClause_t *cprime;*/
1005satArray_t *occur;
1006//#define DEBUG
1007
1008int test;
1009
1010 verbosity = m->verbosity;
1011
1012 //m->clearned->size = 0;
1013
1014 cnt = subsumed = deleted_literals = 0;
1015 subsumption_queue = m->satQueue;
1016 while (subsumption_queue->size > 0) {
1017 test = 0;
1018 /*if (m->status == 0) {
1019 fprintf(stdout, "conflict during bsubsumption check for CL(");
1020 sat_print_clause(m, c);
1021 fprintf(stdout, ") strengthened from CL");
1022 sat_print_array_as_clause(m, m->clearned);
1023 }
1024 m->clearned->size = 0; */
1025
1026 c = (satClause_t*)sat_queue_pop(subsumption_queue);
1027
1028 /*for (i = 0; i <SATSizeClause(c); i++) {
1029 m->clearned = sat_array_insert(m->clearned, c->lits[i]);
1030 }
1031 if (c->lits[0] == ((61935<<1)|1) && c->lits[1] == (75503<<1) &&
1032 c->lits[2] == (75505<<1))
1033 test = 1;
1034 */
1035
1036 if (SATClauseVisited(c)) continue;
1037
1038 if (verbosity >= 3 && cnt++ % 1000 == 0)
1039 fprintf(stdout, "subsumption left: %10d (%10d subsumed, %10d deleted literals)\r", (int)subsumption_queue->size, subsumed, deleted_literals);
1040
1041 /** Find the best variable to scan **/
1042 csize = SATSizeClause(c);
1043 if (csize == 1)
1044 continue;
1045
1046 bestLit = c->lits[0];
1047 best = SATVar(bestLit);
1048 for (i=1; i<csize; i++) {
1049 lit = c->lits[i];
1050 v = SATVar(lit);
1051 bestSize = m->scores[bestLit^1] + m->scores[bestLit];
1052 if ((m->scores[lit^1] + m->scores[lit]) < bestSize) {
1053 bestLit = lit;
1054 best = v;
1055 }
1056 }
1057
1058 /** Search all the candidates on the same sign **/
1059 occur = m->wls[bestLit^1];
1060 if (occur == 0) continue;
1061
1062 for (j = 0; j < occur->size; j++) {
1063 ct = (satClause_t*)occur->space[j];
1064
1065 /*if (test) {
1066 fprintf(stdout, "CT(");
1067 sat_print_clause(m, ct);
1068 fprintf(stdout, ") %s%s\n", SATClauseVisited(ct)?
1069 "visited":"", ct == c? " duplicate":" ");
1070 }*/
1071
1072 /*if (SATClauseVisited(c))
1073 break;
1074 else*/ if (!SATClauseVisited(ct) && ct != c) {
1075 lit = sat_subsume_on_sorted_clauses(m, c, ct);
1076
1077 /*if (test && lit > 0) {
1078 fprintf(stdout, "subsumed with lit = %d => C(", (int)lit);
1079 sat_print_clause_simple(m, c);
1080 fprintf(stdout, ") X CT(");
1081 sat_print_clause_simple(m, ct);
1082 fprintf(stdout, ")\n");
1083 }*/
1084
1085#if 0
1086 int check_subsume = (int)sat_subsume_on_clauses(m, c, ct);
1087 if (check_subsume == 0 && lit != -1) {
1088 fprintf(stdout, "ERROR : backwardsumption check failed!\n");
1089 fprintf(stdout, "(");
1090 sat_print_clause_simple(m, c);
1091 fprintf(stdout, ") & (");
1092 sat_print_clause_simple(m, ct);
1093 fprintf(stdout, ")\n");
1094 fprintf(stdout, "%d but subsumption checked %d\n", check_subsume, (int)lit);
1095 /*exit(0);*/
1096 }
1097#endif
1098
1099 if (lit == 0) {
1100 /** if redudnat clause is original and subsuming
1101 * clause is conflict clause, the conflict clause
1102 * must not blong to conflict clauses.
1103 * Note that the conflict must be handled when
1104 * the CNF data is simplified and recovered after
1105 * backward subsumption check.
1106 **/
1107 if (SATClauseLearned(c) && !SATClauseLearned(ct))
1108 c->size -= SATCLearned;
1109
1110 sat_set_clause_deleted(m, ct);
1111 subsumed++;
1112 }
1113 else if (lit > 0) {
1114 /** HHJ : storing clauses deledted by selfsubsumption
1115 * is unsure now. Proof of unsatisfiability
1116 * without such cleauses are still valid.
1117 **/
1118 /* if (m->coreGeneration) {
1119 m->deleted = sat_array_insert(m->deleted, (long)c);
1120 cprime = sat_copy_clause(m, c);
1121 sat_make_resolution_graph(c, cprime);
1122 c->size |= SATCVisited;
1123 c = cprime;
1124 }
1125 */
1126 m->nBackwardSelfsubsume++;
1127 /** strengthen clause with lit **/
1128 if (SATSizeClause(c) == SATSizeClause(ct)) {
1129 if (SATClauseLearned(c) && !SATClauseLearned(ct))
1130 c->size -= SATCLearned;
1131
1132 sat_set_clause_deleted(m, ct);
1133 subsumed++;
1134 index = sat_get_literal_index_of_clause(m, c, lit^1);
1135 if (!sat_strengthen_clause(m, c, index)) {
1136 if (sat_implication_on_all_watched_literals(m) != 0)
1137 return 0;
1138 }
1139 else {
1140 /* instead of sat_clean_all_watched_list_of_literal(m, lit^1);
1141 */
1142 sat_delete_clause_from_watched_list(m, c, lit, -1);
1143 }
1144 }
1145 else {
1146 index = sat_get_literal_index_of_clause(m, ct, lit);
1147 if (!sat_strengthen_clause(m, ct, index)) {
1148 if (sat_implication_on_all_watched_literals(m) != 0)
1149 return 0;
1150 }
1151 else {
1152 /* instead of sat_clean_all_watched_list_of_literal(m, lit);
1153 */
1154 sat_delete_clause_from_watched_list(m, ct, lit^1, -1);
1155 j--;
1156 continue;
1157 }
1158 }
1159 occur = m->wls[bestLit^1];
1160 }
1161 else if (lit == -2) {
1162 sat_set_clause_deleted(m, c);
1163 subsumed++;
1164 break;
1165 }
1166 }
1167 }
1168
1169 if (SATClauseVisited(c))
1170 continue;
1171 /** Search all the candidates on the opposite sign **/
1172 occur = m->wls[bestLit];
1173 if (occur == 0) continue;
1174
1175 for (j = 0; j < occur->size; j++) {
1176 ct = (satClause_t*)occur->space[j];
1177
1178 /*if (test) {
1179 fprintf(stdout, "CT(");
1180 sat_print_clause(m, ct);
1181 fprintf(stdout, ") %s\n", SATClauseVisited(ct)?
1182 "visited":"", ct == c? " duplicate":" ");
1183 }*/
1184
1185 /*if (SATClauseVisited(c))
1186 break;
1187 else*/ if (!SATClauseVisited(ct) && ct != c) {
1188 lit = sat_subsume_on_sorted_clauses(m, c, ct);
1189 /*if (test) fprintf(stdout, "lit = %d\n", lit);*/
1190
1191#if 0
1192 int check_subsume = (int)sat_subsume_on_clauses(m, c, ct);
1193 if (check_subsume == 0 && lit != -1) {
1194 fprintf(stdout, "ERROR : backwardsumption check failed on opposite, %ld!\n", lit);
1195 fprintf(stdout, "(");
1196 sat_print_clause_simple(m, c);
1197 fprintf(stdout, ") & (");
1198 sat_print_clause_simple(m, ct);
1199 fprintf(stdout, ")\n");
1200 fprintf(stdout, "%d but subsumption checked %d\n", check_subsume, (int)lit);
1201 exit(0);
1202 }
1203#endif
1204
1205 if (lit == 0) {
1206 if (SATClauseLearned(c) && !SATClauseLearned(ct))
1207 c->size -= SATCLearned;
1208
1209 sat_set_clause_deleted(m, ct);
1210 subsumed++;
1211 }
1212 else if (lit > 0) {
1213 /** HHJ : storing clauses deledted by selfsubsumption
1214 * is unsure now. Proof of unsatisfiability
1215 * without such cleauses are still valid.
1216 **/
1217 /*if (m->coreGeneration) {
1218 m->deleted = sat_array_insert(m->deleted, (long)c);
1219 cprime = sat_copy_clause(m, c);
1220 sat_make_resolution_graph(c, cprime);
1221 c->size |= SATCVisited;
1222 c = cprime;
1223 }*/
1224
1225 m->nBackwardSelfsubsume++;
1226 /** strengthen clause with lit **/
1227 if (SATSizeClause(c) == SATSizeClause(ct)) {
1228 if (SATClauseLearned(c) && !SATClauseLearned(ct))
1229 c->size -= SATCLearned;
1230
1231 subsumed++;
1232 sat_set_clause_deleted(m, ct);
1233 index = sat_get_literal_index_of_clause(m, c, lit^1);
1234 if (!sat_strengthen_clause(m, c, index)) {
1235 if (sat_implication_on_all_watched_literals(m) != 0)
1236 return 0;
1237 }
1238 else {
1239 /* instead of sat_clean_all_watched_list_of_literal(m, lit);
1240 * using following
1241 */
1242 sat_delete_clause_from_watched_list(m, c, lit, -1);
1243
1244 }
1245 }
1246 else {
1247 index = sat_get_literal_index_of_clause(m, ct, lit);
1248 if (!sat_strengthen_clause(m, ct, index)) {
1249 if (sat_implication_on_all_watched_literals(m) != 0)
1250 return 0;
1251 }
1252 else {
1253 /* instead of sat_clean_all_watched_list_of_literal(m, lit);
1254 * using following
1255 */
1256 sat_delete_clause_from_watched_list(m, ct, lit^1, -1);
1257 j--;
1258 continue;
1259 }
1260 }
1261 occur = m->wls[bestLit];
1262 }
1263 else if (lit == -2) {
1264 sat_set_clause_deleted(m, c);
1265 subsumed++;
1266 break;
1267 }
1268 }
1269 }
1270 }
1271 /*m->clearned->size = 0;*/
1272
1273 return 1;
1274}
1275
1276
1277
1278/**Function********************************************************************
1279
1280 Synopsis [ Get literal index of clause ]
1281
1282 Description [ Get literal index of clause ]
1283
1284 SideEffects [ ]
1285
1286 SeeAlso [ ]
1287
1288******************************************************************************/
1289long
1290sat_get_literal_index_of_clause(satManager_t *m, satClause_t *c, long lit)
1291{
1292long i, csize;
1293
1294 csize = SATSizeClause(c);
1295 for (i=0; i<csize; i++) {
1296 if (c->lits[i] == lit)
1297 return i;
1298 }
1299
1300 fprintf(stdout, "ERROR : literal %s%ld does not exist in CL(", lit&1 ? "-":"", lit>>1);
1301 sat_print_clause_simple(m, c);
1302 fprintf(stdout, ")\n");
1303 return -1;
1304}
1305
1306/**Function********************************************************************
1307
1308 Synopsis [ Set clause to be deleted ]
1309
1310 Description [ Set clause to be deleted with updating some of sturctures :
1311
1312 m->scores : variable scores
1313 m->varElimHeap : variable elimination heap
1314
1315 SideEffects [ Preconditions : All the literals of a clause are sorted. ]
1316
1317 SeeAlso [ sat_subsume_on_clauses]
1318
1319******************************************************************************/
1320void
1321sat_set_clause_deleted(satManager_t *m, satClause_t *c)
1322{
1323long i, csize;
1324long lit;
1325satHeap_t *h;
1326
1327 h = m->varElimHeap;
1328
1329 csize = SATSizeClause(c);
1330 for (i=0; i<csize; i++) {
1331 lit = c->lits[i];
1332
1333 if (h->indices[lit>>1] >= 0) {
1334 m->nEliminatedLits++;
1335 m->scores[lit]--;
1336 vel_heap_up(m, h->indices[lit>>1]);
1337 }
1338 }
1339 c->size |= SATCVisited;
1340 m->nEliminatedCls++;
1341}
1342
1343/**Function********************************************************************
1344
1345 Synopsis [ Check if a clause selfsubsumes/subsumes the other clause ]
1346
1347 Description [ Check if a clause selfsubsumes/subsumes the other clause.
1348 Invariants:
1349 cp subsumes cq -> sorted(cp) and sorted (cq) and
1350 forall i, lit[i] \in cp \and lit[i] \in cq
1351
1352 Result:
1353 -2 - cp is subsumed by level zero unit clauses
1354 -1 - No subsumption or simplification
1355 0 - Clause cp subsumes Clause cq
1356 p - The literal p can be deleted from cq ]
1357
1358 SideEffects [ Preconditions : the literals of a clause are sorted on
1359 the function call. ]
1360
1361 SeeAlso [ sat_subsume_on_clauses]
1362
1363******************************************************************************/
1364DD_INLINE long
1365sat_subsume_on_sorted_clauses(
1366 satManager_t *m,
1367 satClause_t *cp,
1368 satClause_t *cq)
1369{
1370char value;
1371int ret;
1372long i, j;
1373long cpsize, cqsize;
1374long litp, litq, vp, vq;
1375
1376 cpsize = SATSizeClause(cp);
1377 cqsize = SATSizeClause(cq);
1378
1379 /** check preliminary condition **/
1380 if (cqsize < cpsize || (cp->info.abstract & ~(cq->info.abstract)) != 0)
1381 return -1;
1382
1383 ret = 0;
1384 i = j = 0;
1385 while (i < cpsize) {
1386 /** No subsumption found **/
1387 if (j >= cqsize)
1388 return -1;
1389
1390 /** skip satisfied clause or false literals **/
1391 litp = cp->lits[i];
1392 vp = SATVar(litp);
1393 value = m->values[vp];
1394 if (value < 2) {
1395 if ((value^(litp&1)) == 1) {
1396 return -2;
1397 }
1398 else {
1399 i++;
1400 goto ok;
1401 }
1402 }
1403
1404 litq = cq->lits[j];
1405 vq = SATVar(litq);
1406 value = m->values[vq];
1407 if (value < 2) {
1408 if ((value^(litq&1)) == 1) {
1409 cq->size |= SATCVisited;
1410 return -1;
1411 }
1412 else {
1413 j++;
1414 goto ok;
1415 }
1416 }
1417
1418 /** check common literals **/
1419 if (litp == litq) {
1420 i++;
1421 j++;
1422 }
1423 /** check for selfsubsumption **/
1424 else if (ret == 0 && litp == (litq^1)) {
1425 ret = litq;
1426 i++;
1427 j++;
1428 }
1429 else if ((ret > 0 && vp == vq) || vp < vq)
1430 return -1;
1431 else
1432 j++;
1433
1434 ok:;
1435 }
1436
1437 return ret;
1438}
1439
1440/**Function********************************************************************
1441
1442 Synopsis [ Check if a clause selfsubsumes/subsumes the other clause ]
1443
1444 Description [ Check if a clause selfsubsumes/subsumes the other clause.
1445 This function does check subsumption relation of the two clauses
1446 with a conventional quadratic operation. In addition, one can
1447 use this function to verify the function sat_subsume_on_sorted
1448 _clauses.
1449
1450 SideEffects [ ]
1451
1452 SeeAlso [ sat_subsume_on_sorted_clauses ]
1453
1454******************************************************************************/
1455DD_INLINE long
1456sat_subsume_on_clauses(
1457 satManager_t *m,
1458 satClause_t *cp,
1459 satClause_t *cq)
1460{
1461long i, j, cpsize, cqsize;
1462long ret;
1463
1464 cpsize = SATSizeClause(cp);
1465 cqsize = SATSizeClause(cq);
1466
1467 /** check preliminary condition **/
1468 if (cqsize < cpsize || (cp->info.abstract & ~(cq->info.abstract)) != 0)
1469 return -1;
1470
1471 ret = 0;
1472 i = j = 0;
1473
1474 for (i=0; i<cpsize; i++) {
1475 if ((m->values[SATVar(cp->lits[i])]^(cp->lits[i]&1)) == 1)
1476 return -2;
1477
1478 if ((m->values[SATVar(cp->lits[i])]^(cp->lits[i]&1)) == 0)
1479 continue;
1480
1481 for (j=0; j<cqsize; j++) {
1482
1483 if ((m->values[SATVar(cq->lits[j])]^(cq->lits[j]&1)) == 1)
1484 return -1;
1485
1486 if ((m->values[SATVar(cq->lits[j])]^(cq->lits[j]&1)) == 0)
1487 continue;
1488
1489
1490 if (cp->lits[i] == cq->lits[j])
1491 goto ok;
1492 else if (ret == 0 && cp->lits[i] == (cq->lits[j] ^ 1)) {
1493 ret = cq->lits[j];
1494 goto ok;
1495 }
1496 }
1497 return -1;
1498
1499 ok:;
1500 }
1501
1502 return ret;
1503}
1504
1505/**Function********************************************************************
1506
1507 Synopsis [ Strengthen clause ]
1508
1509 Description [ Strengthen clause ]
1510
1511 SideEffects [ 1. Copy the clause into the deleted clause list
1512 before strenthening.
1513 2. Return 0 if it is pure, or return 1 otherwise.
1514 3. Do not insert the strengthen result into
1515 the list of resolvents.
1516 ]
1517
1518 SeeAlso [ ]
1519
1520******************************************************************************/
1521int
1522sat_strengthen_clause(
1523 satManager_t *m,
1524 satClause_t *c,
1525 long index)
1526{
1527long i, csize, flags, lit, assigns;
1528satClause_t *ante;
1529satHeap_t *h;
1530
1531 m->nEliminatedLits++;
1532
1533 /** Move the deleted clause to backup space, after
1534 * duplicating it, and the deleted clause is stored
1535 * as dependent clause to make resolution graph.
1536 **/
1537 ante = 0;
1538 lit = c->lits[index];
1539
1540 /** Maintain the order of the literals out of the
1541 * pivot variable, and recalculating the abstraction
1542 * of clause.
1543 **/
1544 csize = SATSizeClause(c) - 1;
1545 for (i=index; i<csize; i++) {
1546 c->lits[i] = c->lits[i+1];
1547 }
1548
1549 /** Recompute clause size and flags **/
1550 flags = c->size & SATCMask;
1551 c->size = (csize << SATCsizeShift) | flags;
1552
1553 h = m->varElimHeap;
1554 if (h->indices[lit>>1] >= 0) {
1555 m->scores[lit]--;
1556 vel_heap_up(m, h->indices[lit>>1]);
1557 }
1558
1559 /** Once the clause becomes unit
1560 * propagate at level zero.
1561 **/
1562 if (csize == 1) {
1563 c->size |= SATCVisited;
1564 assigns = m->stackPos;
1565 sat_enqueue_check(m, c->lits[0], ante);
1566 return (m->stackPos - assigns ? 0 : 1);
1567 }
1568
1569 if (!m->eliminateVar) {
1570 sat_queue_insert(m->satQueue, (long)c);
1571 }
1572 /** correct abstract value changed by
1573 * a literal removed
1574 **/
1575 sat_calculate_clause_abs(c);
1576
1577 return 1;
1578}
1579
1580/**Function********************************************************************
1581
1582 Synopsis [ Gather touched clauses for backward subsumption ]
1583
1584 Description [ Gather touched clauses for backward subsumption ]
1585
1586 SideEffects [ ]
1587
1588 SeeAlso [ ]
1589
1590******************************************************************************/
1591void sat_gather_touched_clauses(satManager_t *m)
1592{
1593long i, j, nVars, lit;
1594satClause_t *c;
1595satQueue_t *queue;
1596satArray_t *pos, *neg;
1597
1598 queue = m->satQueue;
1599 nVars = m->nVars;
1600 for (i=1; i<=nVars; i++) {
1601 if (m->marks[i] == 1) {
1602 lit = i << 1;
1603 /** get positive and
1604 * negative occurrences **/
1605 pos = m->wls[lit|1];
1606 neg = m->wls[lit];
1607
1608 if (pos) {
1609 for (j=0; j<pos->size; j++) {
1610 c = (satClause_t*)pos->space[j];
1611 if (!SATClauseIrredundant(c) && !SATClauseVisited(c)) {
1612 sat_queue_insert(m->satQueue, (long)c);
1613 c->size |= SATCIrredundant;
1614 }
1615 }
1616 }
1617 if (neg) {
1618 for (j=0; j<neg->size; j++) {
1619 c = (satClause_t*)neg->space[j];
1620 if (!SATClauseIrredundant(c) && !SATClauseVisited(c)) {
1621 sat_queue_insert(queue, (long)c);
1622 c->size |= SATCIrredundant;
1623 }
1624 }
1625 }
1626 m->marks[i] = 0;
1627 }
1628 }
1629
1630 for (i=queue->first; i != queue->last; ) {
1631 c = (satClause_t*)queue->elems[i++];
1632 i = i%(queue->max);
1633 c->size -= SATCIrredundant;
1634 }
1635}
1636
1637
1638/**Function********************************************************************
1639
1640 Synopsis [ Check implications with all enqueued literals. ]
1641
1642 Description [ Check implications with all enqueued literals on ALL-watched
1643 literal clauses.
1644 ]
1645
1646 SideEffects [ Preconditions : All clauses are sorted.
1647 Postconditions: All clauses are sorted. And no satisfied clause
1648 is left. ]
1649
1650 SeeAlso [ ]
1651
1652******************************************************************************/
1653satClause_t *
1654sat_implication_on_all_watched_literals(satManager_t *m)
1655{
1656#ifdef DEBUG
1657long unit;
1658#endif
1659
1660int nProps, nonUnit;
1661long i, index, lit;
1662satClause_t *conflicting, *c;
1663satArray_t *wl;
1664
1665 nProps = 0;
1666 conflicting = 0;
1667
1668 while (m->curPos < m->stackPos) {
1669 lit = m->decisionStack[m->curPos++];
1670
1671 /** Set the satisfied occurrencies to be removed **/
1672 wl = m->wls[lit^1];
1673 if (wl == 0) continue;
1674
1675 for (i = 0; i < wl->size; i++) {
1676 c = (satClause_t*)wl->space[i];
1677 sat_set_clause_deleted(m, c);
1678 }
1679 /** Propage the assignment over the other occurrences **/
1680 wl = m->wls[lit];
1681 if (wl == 0) continue;
1682
1683 for (i = 0; i < wl->size; i++) {
1684 nonUnit = 1;
1685
1686 c = (satClause_t*)wl->space[i];
1687 if (c && SATClauseVisited(c)) continue;
1688
1689#ifdef DEBUG
1690 unit = sat_check_unit_clause(m, c);
1691#endif
1692
1693 /** strengthen clause with lit **/
1694 index = sat_get_literal_index_of_clause(m, c, lit^1);
1695 if (index < 0)
1696 fprintf(stderr, "ERROR : cannot find strenthened literal \n");
1697 nonUnit = sat_strengthen_clause(m, c, index);
1698
1699#ifdef DEBUG
1700 if (nonUnit == 0 && (unit != m->decisionStack[m->stackPos-1]))
1701 fprintf(stdout, "ERROR : check all-watched implication (lit %ld -- %ld)\n", unit, m->decisionStack[m->stackPos-1]);
1702#endif
1703
1704 if (!nonUnit && m->status == 2)
1705 nProps++;
1706 if (!nonUnit && m->status == 0) {
1707 conflicting = c;
1708 goto foundConflict;
1709 }
1710 }
1711 }
1712foundConflict:;
1713 m->nImplications += nProps;
1714 return (conflicting);
1715}
1716
1717/**Function********************************************************************
1718
1719 Synopsis [ Clean the all-watched lists of clause ]
1720
1721 Description [ Clean the all-watched lists of clause ]
1722
1723 SideEffects [ ]
1724
1725 SeeAlso [ ]
1726
1727******************************************************************************/
1728void
1729sat_clean_all_watched_lists_of_clause(
1730 satManager_t *m,
1731 satClause_t *c)
1732{
1733long i, csize, lit;
1734
1735 csize = SATSizeClause(c);
1736 for (i=0; i<csize; i++) {
1737 lit = c->lits[i];
1738 sat_clean_all_watched_list_of_literal(m, lit);
1739 }
1740}
1741
1742/**Function********************************************************************
1743
1744 Synopsis [ Clean the all-watched list of literal ]
1745
1746 Description [ Clean the all-watched list of literal ]
1747
1748 SideEffects [ ]
1749
1750 SeeAlso [ ]
1751
1752******************************************************************************/
1753void
1754sat_clean_all_watched_list_of_literal(
1755 satManager_t *m,
1756 long lit)
1757{
1758long i;
1759satArray_t *arr;
1760satClause_t *c;
1761
1762 arr = m->wls[lit^1];
1763 if (arr)
1764 for(i=0; i<arr->size; i++) {
1765 c = (satClause_t*)arr->space[i];
1766 if (SATClauseVisited(c)) {
1767 arr->size--;
1768 arr->space[i--] = arr->space[arr->size];
1769 }
1770 }
1771}
1772
1773
1774/**Function********************************************************************
1775
1776 Synopsis [ Clean the all-watched list of variable ]
1777
1778 Description [ Clean the all-watched list of variable ]
1779
1780 SideEffects [ ]
1781
1782 SeeAlso [ ]
1783
1784******************************************************************************/
1785void
1786sat_clean_all_watched_list_of_variable(
1787 satManager_t *m,
1788 long v)
1789{
1790
1791 sat_clean_all_watched_list_of_literal(m, v<<1);
1792 sat_clean_all_watched_list_of_literal(m, (v<<1)|1);
1793}
1794
1795/**Function********************************************************************
1796
1797 Synopsis [ Delete the clause in the watched list ]
1798
1799 Description [ Delete the clause in the watched list ]
1800
1801 SideEffects [ ]
1802
1803 SeeAlso [ ]
1804
1805******************************************************************************/
1806int
1807sat_delete_clause_from_watched_list(
1808 satManager_t *m,
1809 satClause_t *c,
1810 long wlindex,
1811 long cindex)
1812{
1813long i;
1814satClause_t *ct;
1815satArray_t *arr;
1816
1817 arr = m->wls[wlindex];
1818
1819 if (arr->size == 0) return 0;
1820
1821 /** If index of the clause in watched list
1822 * is not valid, manually find it.
1823 **/
1824 i = 0;
1825 while (cindex < 0) {
1826 if (i && i >= arr->size) {
1827 fprintf(stdout, "ERROR : Cannot find clause in watched list!\n");
1828 fprintf(stdout, "(");
1829 sat_print_clause_simple(m, c);
1830 fprintf(stdout, ") : watched list of %c%ld\n", wlindex & 1 ? ' ':'-', wlindex>>1);
1831 return 0;
1832 }
1833
1834 ct = (satClause_t*)arr->space[i++];
1835 if (ct == c)
1836 cindex = i-1;
1837 }
1838
1839 arr->space[cindex] = arr->space[--arr->size];
1840 return 1;
1841}
1842
1843/**Function********************************************************************
1844
1845 Synopsis [ Delete the redundant clause out of resolvent literal pool ]
1846
1847 Description [ Delete the redundant clause out of resolvent literal pool ]
1848
1849 SideEffects [ ]
1850
1851 SeeAlso [ ]
1852
1853******************************************************************************/
1854long
1855sat_delete_redundant_resolvents(satManager_t *m, satClause_t *cp)
1856{
1857char *marks;
1858long i, j, size, cpsize, cqsize;
1859long lit, lit1, lit2, count, redundant;
1860satArray_t *resolvents;
1861
1862 /* mark the literals of
1863 * the cluase subsuming
1864 */
1865 marks = m->litMarks;
1866 cpsize = SATSizeClause(cp);
1867 for (i=0; i<cpsize; i++) {
1868 lit = cp->lits[i];
1869 marks[lit] = 1;
1870 }
1871
1872 redundant = 0;
1873 resolvents = m->redundant;
1874 size = resolvents->size;
1875 for (i=0; i<size; ) {
1876 lit1 = resolvents->space[i];
1877 cqsize = -lit1;
1878 if (cqsize > cpsize) {
1879 lit2 = resolvents->space[i+1];
1880
1881 /* resolvent is not valid if lit2 is 0. */
1882 if (lit2 != 0) {
1883 count = 0;
1884 j = i + 1;
1885 do {
1886 lit2 = resolvents->space[j++];
1887 if (marks[lit2]) count++;
1888 } while (j <= i+cqsize);
1889
1890 /* set redundant clause as invalid */
1891 if (count == cpsize) {
1892 resolvents->space[i+1] = 0;
1893 redundant++;
1894 }
1895 }
1896 }
1897 i += (m->coreGeneration ? (cqsize+3) : (cqsize + 1));
1898 }
1899
1900 /* unmark the literals of
1901 * the cluase subsuming
1902 */
1903 for (i=0; i<cpsize; i++) {
1904 lit = cp->lits[i];
1905 marks[lit] = 0;
1906 }
1907
1908 return redundant;
1909}
1910
1911/**Function********************************************************************
1912
1913 Synopsis [ Remove the resolvents created depending on the clause given ]
1914
1915 Description [ Remove the resolvents created depending on the clause given ]
1916
1917 SideEffects [ ]
1918
1919 SeeAlso [ ]
1920
1921******************************************************************************/
1922void
1923sat_remove_dependent_resolvents(satManager_t *m, satClause_t *c)
1924{
1925long i, size;
1926satArray_t *dependents;
1927satClause_t *dpc;
1928
1929 dependents = c->dependent;
1930 if (!dependents) return;
1931
1932 size = dependents->size;
1933 for (i=0; i<size; i++) {
1934 dpc= (satClause_t*)(dependents->space[i]);
1935
1936 if (dpc) {
1937 if (!SATClauseVisited(dpc)) {
1938 m->nResolvents--;
1939 m->nResolventLits -= SATSizeClause(dpc);
1940 dpc->size |= SATCVisited;
1941 }
1942 }
1943 }
1944 dependents->size = 0;
1945}
1946
1947/**Function********************************************************************
1948
1949 Synopsis [ Add resolvent clause ]
1950
1951 Description [ Add resolvent clause ]
1952
1953 SideEffects [ Adding watched literals is put off after the end of
1954 variable elimination. ]
1955
1956 SeeAlso [ ]
1957
1958******************************************************************************/
1959satClause_t *
1960sat_add_resolvent_clause(satManager_t *m, satArray_t *resolvent, long learned)
1961{
1962satClause_t *c;
1963
1964 c = sat_new_clause(resolvent, learned); /* original clause */
1965 m->resolvents = sat_array_insert(m->resolvents, (long)c);
1966 m->nResolventLits += SATSizeClause(c);
1967 m->nResolvents++;
1968 return(c);
1969}
1970
1971/**Function********************************************************************
1972
1973 Synopsis [ Add the resolvents from the literal pool ]
1974
1975 Description [ Add the resolvents from the literal pool
1976
1977 Precondition : All the literals of each resolvent are sorted. ]
1978
1979 SideEffects [ ]
1980
1981 SeeAlso [ ]
1982
1983******************************************************************************/
1984void
1985sat_add_resolvents_from_lit_pool(satManager_t *m, satArray_t *pool)
1986{
1987long i, j, k, size, csize;
1988long lit1, lit2, index;
1989long abstract;
1990satArray_t *arr;
1991satClause_t *c;
1992satHeap_t *h;
1993
1994 h = m->varElimHeap;
1995 size = pool->size;
1996 for (i=0; i+1<size; ) {
1997 lit1 = pool->space[i];
1998 lit2 = pool->space[i+1];
1999 csize = -lit1;
2000
2001 if (lit2 > 0) {
2002 /* create a new clause from the pool */
2003 c = (satClause_t *)malloc(sizeof(satClause_t) + (sizeof(long)*csize));
2004 c->size = csize << SATCsizeShift;
2005
2006 /* add the literals into the new clause */
2007 j = i + 1;
2008 k = 0;
2009 c->info.activity = 0;
2010 abstract = 0;
2011 while (k < csize) {
2012 lit2 = pool->space[j++];
2013 assert(lit2 != 0);
2014 c->lits[k++] = lit2;
2015
2016 index = lit2^1;
2017 arr = m->wls[index];
2018 m->wls[index] = sat_array_alloc_insert(arr, (long)c);
2019 abstract |= 1 << (SATVar(lit2) & 31);
2020
2021 /* update variable scores and then heap down the variable */
2022 if (h->indices[lit2>>1] >= 0) {
2023 if (!m->eliminateVar)
2024 m->marks[lit2>>1] = 1;
2025 m->scores[lit2]++;
2026 vel_heap_down(m, h->indices[lit2>>1]);
2027 }
2028 }
2029 c->info.abstract = abstract;
2030 c->dependent = 0;
2031 if (m->coreGeneration) {
2032 sat_make_resolution_graph((satClause_t*)pool->space[j++], c);
2033 sat_make_resolution_graph((satClause_t*)pool->space[j], c);
2034#ifdef DEBUG
2035 sat_check_resolvent_dependencies(m, (satClause_t*)pool->space[j-1], (satClause_t*)pool->space[j], c);
2036#endif
2037 }
2038 m->clauses = sat_array_insert(m->clauses, (long)c);
2039 if (!m->eliminateVar) {
2040 sat_queue_insert(m->satQueue, (long)c);
2041 }
2042 m->nResolventLits += csize;
2043 m->nResolvents++;
2044 }
2045 i += (m->coreGeneration ? (csize + 3) : (csize + 1));
2046 }
2047 pool->size = 0;
2048}
2049
2050/**Function********************************************************************
2051
2052 Synopsis [ Add all literals as watched ]
2053
2054 Description [ Add all literals as watched ]
2055
2056 SideEffects [ The array of indices of upper part for all variables: m->up.
2057 Watched lists must be reconstructed for two watched literal
2058 schemed being used in SAT solver. ]
2059
2060 SeeAlso [ ]
2061
2062******************************************************************************/
2063void
2064sat_add_all_watched_literal(satManager_t *m, satClause_t *c)
2065{
2066long index, i, csize;
2067satArray_t *arr;
2068
2069 csize = SATSizeClause(c);
2070 m->scores[c->lits[0]]++;
2071 if (csize > 1)
2072 m->scores[c->lits[1]]++;
2073
2074 for (i=2; i<csize; i++) {
2075 /** This list is used as occur list.
2076 * Don't use as two watched literal list.
2077 **/
2078 m->scores[c->lits[i]]++;
2079 index = (c->lits[i])^1;
2080 arr = m->wls[index];
2081 m->wls[index] = sat_array_alloc_insert(arr, (long)c);
2082 }
2083}
2084
2085/**Function********************************************************************
2086
2087 Synopsis [ Add all literals as watched with no scoring ]
2088
2089 Description [ Add all literals as watched with no scoring ]
2090
2091 SideEffects [ Only watched literals are updated ]
2092
2093 SeeAlso [ sat_add_all_watched_literal ]
2094
2095******************************************************************************/
2096void
2097sat_add_all_watched_literal_without_scoring(satManager_t *m, satClause_t *c)
2098{
2099long index, i, csize;
2100satArray_t *arr;
2101
2102 csize = SATSizeClause(c);
2103 for (i=2; i<csize; i++) {
2104 /** This list is used as occur list.
2105 * Don't use as two watched literal list.
2106 **/
2107 index = (c->lits[i])^1;
2108 arr = m->wls[index];
2109 m->wls[index] = sat_array_alloc_insert(arr, (long)c);
2110 }
2111}
2112
2113/**Function********************************************************************
2114
2115 Synopsis [ Extend model with respect to the eliminated variables ]
2116
2117 Description [ Extend model with respect to the eliminated variables ]
2118
2119 SideEffects [ Precondition :
2120
2121 1. All the survided variable are assigned.
2122 2. All watched lists of eliminated variables must point
2123 to the list of their clauses deleted by variable
2124 elimination procedure.
2125 ]
2126
2127 SeeAlso [ ]
2128
2129******************************************************************************/
2130void
2131sat_extend_model(satManager_t *m)
2132{
2133long i, index;
2134long v, lit;
2135int dontCares;
2136satArray_t *elimVars, *deleted;
2137
2138 /** Get eliminated variables **/
2139 elimVars = m->elimtable;
2140
2141 /** Find values of eliminated variables
2142 * in the reverse order of elimination
2143 **/
2144 dontCares = 0;
2145 for (i = elimVars->size - 1; i >= 0; i--) {
2146 v = elimVars->space[i];
2147 lit = v << 1;
2148
2149 /** 1. Scan posivive occurrence clauses **/
2150 index = lit | 1;
2151 deleted = m->wls[index];
2152 if (deleted)
2153 sat_find_value_of_eliminated_var_on_clauses(m, deleted, v);
2154
2155 /** 2. Scan negative occurrence clauses **/
2156 index = lit;
2157 deleted = m->wls[index];
2158 if (deleted)
2159 sat_find_value_of_eliminated_var_on_clauses(m, deleted, v);
2160
2161 if (m->values[v] >= 2) {
2162 /* don't care variable is found */
2163 m->values[v] = 1;
2164 dontCares++;
2165 }
2166 }
2167}
2168
2169/**Function********************************************************************
2170
2171 Synopsis [ Find a value of an eliminated variable ]
2172
2173 Description [ Find a value of an eliminated variable ]
2174
2175 SideEffects [ ]
2176
2177 SeeAlso [ ]
2178
2179******************************************************************************/
2180void
2181sat_find_value_of_eliminated_var_on_clauses(satManager_t *m, satArray_t *clauses, long v)
2182{
2183long i, j, csize;
2184long otherV, otherLit;
2185int sign;
2186satClause_t *c;
2187#ifdef DEBUG
2188int error = 1;
2189#endif
2190
2191 sign = 0;
2192 for (i = 0; i < clauses->size; i++) {
2193 c = (satClause_t*)clauses->space[i];
2194 csize = SATSizeClause(c);
2195 for (j = 0; j < csize; j++) {
2196 otherLit = c->lits[j];
2197 otherV = SATVar(otherLit);
2198 if (otherV == v) {
2199 sign = otherLit & 1;
2200
2201#ifdef DEBUG
2202 error = 0;
2203#endif
2204 }
2205 else if ((m->values[otherV]^(otherLit&1)) != 0) {
2206 /* skip clause satisfied by other literal */
2207 goto nextClause;
2208 }
2209 }
2210#ifdef DEBUG
2211 if (error) {
2212 fprintf(stdout, "ERROR : Invalid extension of eliminated Var %ld!\n", v);
2213 fprintf(stdout, "Check CL (");
2214 sat_print_clause_simple(m, c);
2215 fprintf(stdout, ") wrt %ld \n", v);
2216 break;
2217 }
2218#endif
2219 if (sign == 1) m->values[v] = 0;
2220 else m->values[v] = 1;
2221 /* m->values[v] = (sign==1 ? 0 : 1); HK*/
2222 break;
2223
2224nextClause:;
2225 }
2226}
2227
2228/**Function********************************************************************
2229
2230 Synopsis [ Check duplicates in clauses array ]
2231
2232 Description [ Check duplicates in clauses array ]
2233
2234 SideEffects [ ]
2235
2236 SeeAlso [ ]
2237
2238******************************************************************************/
2239void
2240sat_check_duplications_in_clauses(satArray_t *clauses)
2241{
2242long i, j, nDuplicates;
2243satClause_t *cp, *cq;
2244
2245 nDuplicates = 0;
2246
2247 for (i = 0; i < clauses->size; i++) {
2248 cp = (satClause_t*)clauses->space[i];
2249 cp->info.activity = 0;
2250 }
2251
2252 for (i = 0; i < clauses->size; i++) {
2253 cp = (satClause_t*)clauses->space[i];
2254 for (j = i+1; j < clauses->size; j++) {
2255 cq = (satClause_t*)clauses->space[j];
2256 if (sat_check_clauses_duplicate(cp, cq)) {
2257 cp->info.activity++;
2258 cq->info.activity++;
2259 nDuplicates++;
2260 }
2261 }
2262 }
2263 fprintf(stdout, "******************************************\n");
2264 fprintf(stdout, " %ld Duplicates out of %ld clauses \n", nDuplicates, clauses->size);
2265 fprintf(stdout, "******************************************\n");
2266
2267 for (i = 0; i < clauses->size; i++) {
2268 cp = (satClause_t*)clauses->space[i];
2269 fprintf(stdout, "Clause %ld : %ld duplicates\n", i, (long)cp->info.activity);
2270 }
2271}
2272
2273/**Function********************************************************************
2274
2275 Synopsis [ Check duplicate clauses ]
2276
2277 Description [ Check duplicate clauses ]
2278
2279 SideEffects [ ]
2280
2281 SeeAlso [ ]
2282
2283******************************************************************************/
2284int
2285sat_check_clauses_duplicate(satClause_t *cp, satClause_t *cq)
2286{
2287long i, j, cpsize, cqsize;
2288long lit;
2289int duplicate;
2290
2291 cpsize = SATSizeClause(cp);
2292 cqsize = SATSizeClause(cq);
2293
2294 if (cpsize != cqsize) return 0;
2295
2296 for (i = 0; i < cpsize; i++) {
2297 lit = cp->lits[i];
2298 duplicate = 0;
2299 for (j = 0; j < cqsize; j++) {
2300 if (cq->lits[j] == lit) {
2301 duplicate = 1;
2302 break;
2303 }
2304 }
2305 if (duplicate == 0)
2306 return 0;
2307 }
2308 return 1;
2309}
2310
2311
2312/******************************************************************************
2313 *
2314 * Utilities
2315 *
2316*******************************************************************************/
2317void
2318sat_report_result_for_var_elim(satManager_t *m)
2319{
2320 if (m== 0) return;
2321
2322 fprintf(stdout, "============[ Varelim Statistics ]============\n");
2323 fprintf(stdout, "Eliminated variables : %ld out of %ld\n", m->nEliminatedVars, m->nVars);
2324 fprintf(stdout, "Eliminated clauses : %ld out of %ld\n", m->nEliminatedCls, m->nClauses);
2325 fprintf(stdout, "Eliminated literals : %ld out of %ld\n", m->nEliminatedLits, m->nLits);
2326 fprintf(stdout, "Resolvent clauses : %ld\n", m->nResolvents);
2327 fprintf(stdout, "Resolvent literals : %ld\n", m->nResolventLits);
2328 fprintf(stdout, "Selfsubsumption : backward(%ld), resolution(%ld)\n", m->nBackwardSelfsubsume, m->nSelfsubsume);
2329 fprintf(stdout, "Elimination checks : %ld with %ld iterations\n", m->nVarElimTry, m->nSubsumeTry-1);
2330 if(m->status == 0) fprintf(stdout, "UNSATISFIABLE at level 0\n");
2331 else if (m->status == 1) fprintf(stdout, "SATISFIABLE at level 0\n");
2332
2333 fprintf(stdout, "Eliminate time : %10g \n", m->elimTime);
2334 fprintf(stdout, "\n");
2335}
2336
2337/**Function********************************************************************
2338
2339 Synopsis [ Heap ]
2340
2341 Description [ Heap ]
2342
2343 SideEffects [ ]
2344
2345 SeeAlso [ ]
2346
2347******************************************************************************/
2348static int
2349vel_compare_scores(satManager_t *m, long x, long y)
2350{
2351long xindex, yindex;
2352long xscore, yscore;
2353
2354 xindex = x << 1;
2355 xscore = m->scores[xindex] * (m->scores[xindex|1]);
2356 xscore -= (m->scores[xindex] + m->scores[xindex|1]);
2357
2358 yindex = y << 1;
2359 yscore = m->scores[yindex] * (m->scores[yindex|1]);
2360 yscore -= (m->scores[yindex] + m->scores[yindex|1]);
2361
2362 return(xscore < yscore);
2363}
2364
2365void
2366vel_heap_remove_var_eliminated(satManager_t *m)
2367{
2368long i, j;
2369satHeap_t *h;
2370
2371 h = m->varElimHeap;
2372 for(i=j=0; i<h->size; i++) {
2373 if(m->levels[h->heap[i]]) {
2374 h->heap[j] = h->heap[i];
2375 h->indices[h->heap[i]] = j++;
2376 }
2377 else {
2378 h->indices[h->heap[i]] = -1;
2379 }
2380 }
2381 h->size -= (i-j);
2382
2383 for(i=h->size/2-1; i>=0; i--)
2384 vel_heap_down(m, i);
2385}
2386
2387void
2388vel_heap_up(satManager_t *m, long i)
2389{
2390satHeap_t *h;
2391long *heap;
2392long x;
2393
2394 h = m->varElimHeap;
2395 heap = h->heap;
2396 x = heap[i];
2397 while(i!=0 && vel_compare_scores(m, x, heap[heap_parent(i)])) {
2398 heap[i] = heap[heap_parent(i)];
2399 h->indices[heap[i]] = i;
2400 i = heap_parent(i);
2401 }
2402 h->heap[i] = x;
2403 h->indices[x] = i;
2404}
2405
2406void
2407vel_heap_down(satManager_t *m, long i)
2408{
2409satHeap_t *h;
2410long *heap;
2411long x, c;
2412
2413 h = m->varElimHeap;
2414 heap = h->heap;
2415 x = heap[i];
2416 while(heap_left(i) < h->size) {
2417 c = (heap_right(i) < h->size &&
2418 vel_compare_scores(m, heap[heap_right(i)], heap[heap_left(i)])) ?
2419 heap_right(i) : heap_left(i);
2420 if(!vel_compare_scores(m, heap[c], x)) break;
2421 heap[i] = heap[c];
2422 h->indices[heap[i]] = i;
2423 i = c;
2424 }
2425 heap[i] = x;
2426 h->indices[x] = i;
2427}
2428
2429long
2430vel_heap_remove_min(satManager_t *m)
2431{
2432long x;
2433satHeap_t *h;
2434
2435 h = m->varElimHeap;
2436 x = h->heap[0];
2437 h->heap[0] = h->heap[h->size-1];
2438 h->indices[h->heap[0]] = 0;
2439 h->indices[x] = -1;
2440 h->size--;
2441 if(h->size > 1)
2442 vel_heap_down(m, 0);
2443
2444 return(x);
2445}
2446
2447void
2448vel_heap_clear(satManager_t *m)
2449{
2450satHeap_t *h;
2451long i;
2452
2453 h = m->varElimHeap;
2454 for(i=0; i<h->size; i++)
2455 h->indices[h->heap[i]] = -1;
2456 h->size = 0;
2457}
2458
2459void
2460vel_heap_update(satManager_t *m, long n)
2461{
2462satHeap_t *h;
2463
2464 h = m->varElimHeap;
2465 if(h->indices[n] < 0)
2466 vel_heap_insert(m, n);
2467 else {
2468 vel_heap_up(m, h->indices[n]);
2469 vel_heap_down(m, h->indices[n]);
2470 }
2471}
2472
2473void
2474vel_heap_init(satManager_t *m, long size)
2475{
2476satHeap_t *h;
2477long i;
2478
2479
2480 h = (satHeap_t *)malloc(sizeof(satHeap_t));
2481 h->size = 0;
2482
2483 size++;
2484 h->heap = (long *)malloc(sizeof(long)*size);
2485 h->indices = (long *)malloc(sizeof(long)*size);
2486 for(i=0; i<size; i++) h->indices[i] = -1;
2487
2488 m->varElimHeap = h;
2489}
2490
2491void
2492vel_heap_print(satManager_t *m)
2493{
2494satHeap_t *h;
2495int i;
2496
2497 h = m->varElimHeap;
2498 for(i=0; i<=h->size; i++) {
2499 fprintf(stdout, "%d ", i);
2500 fprintf(stdout, "%ld ", h->heap[i]);
2501 fprintf(stdout, "\n");
2502 }
2503}
2504
2505void
2506vel_heap_free(satManager_t *m)
2507{
2508satHeap_t *h;
2509
2510 h = m->varElimHeap;
2511 if(h) {
2512 free(h->heap);
2513 free(h->indices);
2514 free(h);
2515 m->varElimHeap = 0;
2516 }
2517}
2518
2519int
2520vel_heap_check(satManager_t *m, long i)
2521{
2522satHeap_t *h;
2523
2524 h = m->varElimHeap;
2525 if(i >= h->size) return(1);
2526
2527 if(i==0 || !vel_compare_scores(m, h->heap[i], h->heap[heap_parent(i)])) {
2528 return(vel_heap_check(m, heap_left(i)) && vel_heap_check(m, heap_right(i)));
2529 }
2530 return(0);
2531
2532}
2533
2534int
2535vel_heap_inHeap(satManager_t *m, long n)
2536{
2537satHeap_t *h;
2538
2539 h = m->varElimHeap;
2540 return (h->indices[n] >= 0);
2541}
2542
2543void
2544vel_heap_insert(satManager_t *m, long n)
2545{
2546satHeap_t *h;
2547
2548 h = m->varElimHeap;
2549 h->indices[n] = h->size;
2550 h->heap[h->size++] = n;
2551 vel_heap_up(m, h->indices[n]);
2552}
2553
2554long
2555sat_get_num_assignments_of_a_level(satManager_t *m, long level)
2556{
2557satArray_t *seperator;
2558long bi, ei;
2559
2560 seperator = m->decisionStackSeperator;
2561 if (seperator->size < level) {
2562 fprintf(stdout, "ERROR : level %d has been assigned\n", (int)level);
2563 return (-1);
2564 }
2565
2566 if (level == 0) bi = 0;
2567 else bi = seperator->space[level-1];
2568 ei = (seperator->size == level) ? m->stackPos : seperator->space[level];
2569
2570 return (ei - bi);
2571}
2572
2573void
2574sat_clean_resolvents_DB(satManager_t *m, long v, long begin)
2575{
2576long i, j, size, index;
2577satClause_t *c, *oc;
2578satArray_t *resolvents, *occurr;
2579
2580 /** Remove associated dependent list **/
2581 index = v << 1;
2582 occurr = m->wls[index];
2583 if (occurr)
2584 for (i=0; i<occurr->size; i++) {
2585 oc = (satClause_t*)occurr->space[i];
2586 if (oc->dependent)
2587 oc->dependent->size = 0;
2588 }
2589
2590 index += 1;
2591 occurr = m->wls[index];
2592 if (occurr)
2593 for (i=0; i<occurr->size; i++) {
2594 oc = (satClause_t*)occurr->space[i];
2595 if (oc->dependent)
2596 oc->dependent->size = 0;
2597 }
2598
2599 resolvents = m->resolvents;
2600 for (i=j=begin; i<resolvents->size; i++) {
2601 c = (satClause_t*)resolvents->space[i];
2602 if (SATClauseVisited(c)) {
2603 if (c->dependent)
2604 free(c->dependent);
2605 free(c);
2606 m->nResolventLits -= SATSizeClause(c);
2607 }
2608 else {
2609 fprintf(stdout, "clause : address %p \n", c);
2610 m->wls[c->lits[0]^1] = sat_array_alloc_insert(m->wls[c->lits[0]^1], (long)c);
2611 m->wls[c->lits[1]^1] = sat_array_alloc_insert(m->wls[c->lits[1]^1], (long)c);
2612
2613 sat_add_all_watched_literal(m,c);
2614
2615 resolvents->space[j++] = resolvents->space[i++];
2616 size = SATSizeClause(c);
2617 m->nCurClauseLits -= size;
2618 m->nTotalClauseLits -= size;
2619 }
2620 }
2621 resolvents->size -= (i-j);
2622 m->nResolvents = resolvents->size;
2623}
2624
2625void
2626sat_delete_current_resolvents_DB(satManager_t *m, long v, long begin)
2627{
2628long i, j;
2629long *space, index;
2630satClause_t *c, *oc;
2631satArray_t *resolvents, *occurr;
2632
2633 /** Remove associated dependent list **/
2634 index = v << 1;
2635 occurr = m->wls[index];
2636 for (i=0; i<occurr->size; i++) {
2637 oc = (satClause_t*)occurr->space[i];
2638 if (oc->dependent) {
2639 oc->dependent->size = 0;
2640 }
2641 }
2642 index ^= 1;
2643 occurr = m->wls[index];
2644 for (i=0; i<occurr->size; i++) {
2645 oc = (satClause_t*)occurr->space[i];
2646 if (oc->dependent) {
2647 oc->dependent->size = 0;
2648 }
2649 }
2650
2651 resolvents = m->resolvents;
2652 space = resolvents->space;
2653 for (i=begin, j=resolvents->size; i<j; i++) {
2654 c = (satClause_t*)space[i];
2655 if (c) {
2656 if (c->dependent)
2657 free(c->dependent);
2658 m->nResolventLits -= SATSizeClause(c);
2659 free(c);
2660 space[i--] = space[--j];
2661 }
2662 }
2663 resolvents->size = j;
2664 m->nResolvents = j;
2665}
2666
2667
2668/**Function********************************************************************
2669
2670 Synopsis [ Remove marked clauses in preprocessing ]
2671
2672 Description [ Remove marked clauses in preprocessing
2673
2674 Precondition : no literal in CNF DB is watched. All the watched
2675 literals will be added after this procedure. ]
2676
2677 SideEffects [ No clause is freed, but the clauses are moved to a backup
2678 data base out of the original cnf clauses. ]
2679
2680 SeeAlso [ ]
2681
2682******************************************************************************/
2683void
2684sat_remove_marked_clauses(satManager_t *m, satArray_t *arr)
2685{
2686int learned;
2687long i, j, csize;
2688satClause_t *c;
2689
2690 learned = (arr == m->learned) ? 1 : 0;
2691
2692 for (i=j=0 ; i< arr->size; i++) {
2693 c = (satClause_t*)arr->space[i];
2694 csize = SATSizeClause(c);
2695 if (csize == 1) {
2696 arr->space[j++] = arr->space[i];
2697 continue;
2698 }
2699
2700 if (SATClauseVisited(c)) {
2701#ifdef VERIFY_ON
2702 m->deleted = sat_array_insert(m->deleted, (long)c);
2703#else
2704 if (c->dependent)
2705 free(c->dependent);
2706 free(c);
2707#endif
2708 }
2709 else {
2710 if (learned && !SATClauseLearned(c))
2711 m->clauses = sat_array_insert(m->clauses, (long)c);
2712 else
2713 arr->space[j++] = arr->space[i];
2714 }
2715 }
2716 arr->size -= (i-j);
2717}
2718
2719void
2720sat_mark_clauses_of_var_deleted(satManager_t *m, long v)
2721{
2722long lit;
2723
2724 lit = v << 1;
2725 sat_mark_occur_list_to_be_deleted(m, lit);
2726 lit |= 1;
2727 sat_mark_occur_list_to_be_deleted(m, lit);
2728}
2729
2730void
2731sat_mark_occur_list_to_be_deleted(satManager_t *m, long index)
2732{
2733long i, j, csize, lit, nCls, nLits;
2734satArray_t *occur;
2735satClause_t *c;
2736satHeap_t *h;
2737
2738 h = m->varElimHeap;
2739
2740 nCls = nLits = 0;
2741 /* take the occur list */
2742 occur = m->wls[index];
2743 if (occur) {
2744 for (i=0; i<occur->size; i++) {
2745 c = (satClause_t*) occur->space[i];
2746 if (c && !(SATClauseVisited(c))) {
2747 c->size |= SATCVisited;
2748 csize = SATSizeClause(c);
2749 /* update variable heap */
2750 for (j=0; j<csize; j++) {
2751 lit = c->lits[j];
2752 if (index != lit && h->indices[lit>>1] >= 0) {
2753 m->scores[lit]--;
2754 vel_heap_update(m, lit>>1);
2755 }
2756 }
2757 nLits += csize;
2758 nCls++;
2759 }
2760 }
2761 }
2762 m->nEliminatedLits += nLits;
2763 m->nEliminatedCls += nCls;
2764}
2765
2766void sat_reset_all_watched_lists(satManager_t *m)
2767{
2768long i, index, lit;
2769satArray_t *pwl, *nwl;
2770
2771 for (i=1; i<=m->nVars; i++) {
2772 lit = i << 1;
2773 index = lit;
2774 pwl = m->wls[index|1];
2775 nwl = m->wls[index];
2776
2777 if (m->values[i] <= 2) {
2778 m->scores[index] = 0;
2779 if (pwl) pwl->size = 0;
2780
2781 m->scores[index|1] = 0;
2782 if (nwl) nwl->size = 0;
2783
2784 if (m->values[i] == 2)
2785 m->pure[i] = 0;
2786 }
2787 }
2788 m->nCurClauseLits = 0;
2789 m->nTotalClauseLits = 0;
2790 m->nCurLearnedLits = 0;
2791 m->nCurLearnedClauses = 0;
2792}
2793
2794int
2795sat_squeeze_clause(satManager_t *m, satClause_t *c)
2796{
2797long i, j, size;
2798long v, lit, flags;
2799
2800 size = SATSizeClause(c);
2801 for (i=j=0; i<size; i++) {
2802 lit = c->lits[i];
2803 v = SATVar(lit);
2804 if (m->values[v] == 2)
2805 c->lits[j++] = c->lits[i];
2806 else if ((m->values[v] ^ (lit&1)) == 1 ) {
2807 c->size |= SATCVisited;
2808 return 0;
2809 }
2810 }
2811 flags = c->size & SATCMask;
2812 size -= (i-j);
2813 c->size = (size << SATCsizeShift) | flags;
2814
2815 return 1;
2816}
2817
2818void sat_recover_clauses_DB(satManager_t *m)
2819{
2820long i, lit, *space;
2821satArray_t *clauses;
2822satClause_t *c;
2823
2824 clauses = m->clauses;
2825 space = clauses->space;
2826 for (i=0; i<clauses->size; i++) {
2827 c = (satClause_t*)space[i];
2828
2829 if (SATClauseVisited(c))
2830 continue;
2831
2832 if(SATSizeClause(c) == 1) {
2833 lit = c->lits[0];
2834 sat_enqueue_check(m, lit, c);
2835 }
2836 else {
2837 if (c) {
2838 if (sat_squeeze_clause(m, c)) {
2839 sat_mark_for_pure_lits(m, c);
2840 sat_add_watched_literal(m, c);
2841 }
2842 }
2843 }
2844 }
2845
2846 clauses = m->learned;
2847 space = clauses->space;
2848 if (m->periodicDistill)
2849 m->n2LitClauses = 0;
2850
2851 for (i=0; i<clauses->size; i++) {
2852 c = (satClause_t*)space[i];
2853
2854 if (SATClauseVisited(c))
2855 continue;
2856
2857 if(SATSizeClause(c) == 1) {
2858 lit = c->lits[0];
2859 sat_enqueue_check(m, lit, c);
2860 }
2861 else {
2862 if (c) {
2863 if (sat_squeeze_clause(m, c))
2864 sat_add_watched_literal(m, c);
2865 if (m->periodicDistill && SATSizeClause(c) == 2)
2866 m->n2LitClauses++;
2867 }
2868 }
2869 }
2870}
2871
2872void
2873sat_init_clauses_statistics(satManager_t *m)
2874{
2875int i;
2876
2877 for (i = 0; i < 13; i++) {
2878 m->clausesHistogram[i] = 0;
2879 }
2880 m->majorityClauseLength = 0;
2881}
2882
2883void
2884sat_update_clauses_statistics(satManager_t *m, satClause_t *c)
2885{
2886int index;
2887long csize;
2888
2889 csize = SATSizeClause(c);
2890 index = (csize >= 12) ? 12 : csize;
2891 m->clausesHistogram[index]++;
2892
2893 if (m->clausesHistogram[index] > m->clausesHistogram[m->majorityClauseLength]) {
2894 m->minorityClauseLength = m->majorityClauseLength;
2895 m->majorityClauseLength = index;
2896 }
2897}
2898
2899long
2900sat_check_clauses_high_density(satManager_t *m)
2901{
2902long index1, index2;
2903satArray_t *clauses;
2904
2905 clauses = m->clauses;
2906
2907 index1 = m->majorityClauseLength;
2908 index2 = m->minorityClauseLength;
2909 if ((double)m->clausesHistogram[index1]/clauses->size >= 0.95)
2910 return (1);
2911
2912 if ((double)m->clausesHistogram[index2]/clauses->size >= 0.95)
2913 return (1);
2914
2915 return 0;
2916}
2917
2918void
2919sat_print_clauses_histogram(satManager_t *m)
2920{
2921int i;
2922
2923 fprintf(stdout, "**********************************\n");
2924 fprintf(stdout, "* Histogram of clause lengths *\n");
2925 fprintf(stdout, "**********************************\n");
2926 for (i = 0; i < 11; i++) {
2927 fprintf(stdout, " Num of claues [%d] : %ld\n", i, m->clausesHistogram[i]);
2928 }
2929 fprintf(stdout, " Num of claues [ >=%d ] : %ld\n", i, m->clausesHistogram[i]);
2930 fprintf(stdout, " Length %d is majority clause length.\n", (int)m->majorityClauseLength);
2931 fprintf(stdout, "**********************************\n");
2932}
2933
2934/******************************************************************************
2935 *
2936 * Functions for Debugging
2937 *
2938 ******************************************************************************/
2939
2940/**Function********************************************************************
2941
2942 Synopsis [ Check the clause after merging and sorting ]
2943
2944 Description [ Check the clause after merging and sorting
2945
2946 Invariant : for all literal lit_i in the clause, lit_i <= lit_j,
2947 where j > i.
2948
2949 Return 1 if no error found.
2950 Return 0 Otherwise.
2951 ]
2952
2953 SideEffects [ ]
2954
2955 SeeAlso [ ]
2956
2957******************************************************************************/
2958int
2959sat_check_clause_after_merge_sort(satManager_t *m, satArray_t *arr, long begin)
2960{
2961long i, j, lit;
2962
2963 for (i=begin+1; i<arr->size; i++) {
2964 lit = arr->space[i];
2965 for (j=i+1; j<arr->size; j++) {
2966 if (lit > arr->space[j]) {
2967 fprintf(stdout, "ERROR in checking the clause after merging and sorting!\n");
2968 fprintf(stdout, "Caused in ");
2969 sat_print_array_as_clause(m, arr);
2970 return 0;
2971 }
2972 }
2973 }
2974 return 1;
2975}
2976
2977/**Function********************************************************************
2978
2979 Synopsis [ Print a part of clause array ]
2980
2981 Description [ Print a part of clause array ]
2982
2983 SideEffects [ ]
2984
2985 SeeAlso [ ]
2986
2987******************************************************************************/
2988void
2989sat_print_clause_array_part(satManager_t *m, satArray_t *arr, long begin, long end)
2990{
2991long i, lit, v;
2992
2993 fprintf(stdout, "(");
2994 for(i=begin; i<end; i++) {
2995 lit = arr->space[i];
2996 v = lit>>1;
2997 fprintf(stdout, "%c%d:%c",
2998 lit&1 ? '-' : ' ',
2999 (int)v,
3000 m->values[v]==1 ? '1' : (m->values[v]==0 ? '0' : 'x'));
3001 fprintf(stdout, " ");
3002 }
3003 fprintf(stdout, ")");
3004 fflush(stdout);
3005}
3006
3007/**Function********************************************************************
3008
3009 Synopsis [ Print current database into CNF file ]
3010
3011 Description [ Print current database into CNF file ]
3012
3013 SideEffects [ ]
3014
3015 SeeAlso [ ]
3016
3017******************************************************************************/
3018void
3019sat_print_current_DB_to_cnf(satManager_t *m, char *cnfFilename)
3020{
3021FILE *fp;
3022long i, j, lit, v;
3023long csize;
3024satClause_t *c;
3025satArray_t *clauses;
3026
3027 if (!(fp = fopen(cnfFilename, "w"))) {
3028 fprintf(stderr, "ERROR : Can't open CNF file %s\n", cnfFilename);
3029 return;
3030 }
3031
3032 clauses = m->clauses;
3033 fprintf(fp, "p cnf %d %d\n", (int)m->nVars, (int)clauses->size);
3034 for (i = 0; i < clauses->size; i++) {
3035 c = (satClause_t*)clauses->space[i];
3036 csize = SATSizeClause(c);
3037 for (j = 0; j< csize; j++) {
3038 lit = c->lits[j];
3039 v = SATVar(lit);
3040 if ((m->values[v]^(lit&1)) == 1) continue;
3041 }
3042
3043 for (j = 0; j < csize; j++) {
3044 lit = c->lits[j];
3045 v = SATVar(lit);
3046 fprintf(fp, "%d ", lit&1 ? (int) -v : (int) v);
3047 }
3048 fprintf(fp, "0\n");
3049 }
3050
3051 fclose(fp);
3052}
3053
3054/**Function********************************************************************
3055
3056 Synopsis [ Check clauses are sorted ]
3057
3058 Description [ Check clauses are sorted ]
3059
3060 SideEffects [ ]
3061
3062 SeeAlso [ ]
3063
3064******************************************************************************/
3065int
3066sat_check_all_clauses_sorted(satManager_t *m)
3067{
3068long i, j, csize, passed;
3069satClause_t *c;
3070satArray_t *clauses;
3071
3072 passed = 1;
3073 clauses = m->clauses;
3074 for (i = 0; i < clauses->size; i++) {
3075 c = (satClause_t*)clauses->space[i];
3076 csize = SATSizeClause(c);
3077 if (csize == 1) continue;
3078
3079 for (j = 0; j < csize - 1; j++) {
3080 if (SATClauseIrredundant(c))
3081 fprintf(stdout, "ERROR : Clause marked\n");
3082 if ((c->lits[j] >>1) > (c->lits[j+1] >>1)) {
3083 fprintf(stdout, "ERROR : found unsorted clause (");
3084 sat_print_clause_simple(m, c);
3085 fprintf(stdout, ") on %dth of %dth original clause of size %d\n", (int)j, (int)i, (int)csize);
3086 passed = 0;
3087 break;
3088 }
3089 }
3090 }
3091
3092 clauses = m->learned;
3093 for (i = 0; i < clauses->size; i++) {
3094 c = (satClause_t*)clauses->space[i];
3095 csize = SATSizeClause(c);
3096 if (csize == 1) continue;
3097
3098 for (j = 0; j < csize - 1; j++) {
3099 if (SATClauseIrredundant(c))
3100 fprintf(stdout, "ERROR : Clause marked\n");
3101 if ((c->lits[j] >>1) > (c->lits[j+1] >>1)) {
3102 fprintf(stdout, "ERROR : found unsorted clause (");
3103 sat_print_clause_simple(m, c);
3104 fprintf(stdout, ") on %dth of %dth conflict clause of size %d\n", (int)j, (int)i, (int)csize);
3105 sat_sort_clause_literal(c);
3106 passed = 0;
3107 }
3108 }
3109 }
3110
3111 return passed;
3112}
3113
3114/**Function********************************************************************
3115
3116 Synopsis [ Check resolvent dependencies ]
3117
3118 Description [ Check resolvent dependencies ]
3119
3120 SideEffects [ ]
3121
3122 SeeAlso [ ]
3123
3124******************************************************************************/
3125void
3126sat_check_resolvent_dependencies(satManager_t *m, satClause_t *cp, satClause_t *cq, satClause_t *c)
3127{
3128long i, j, cpsize, cqsize, csize;
3129int error;
3130char *marks;
3131
3132 error = 0;
3133 marks = m->litMarks;
3134 cpsize = SATSizeClause(cp);
3135 csize = SATSizeClause(c);
3136 for (i = 0; i < cpsize; i++)
3137 for (j = 0; j < csize; j++)
3138 if (cp->lits[i] == c->lits[j])
3139 marks[c->lits[j]] = 1;
3140
3141 cqsize = SATSizeClause(cq);
3142 for (i = 0; i < cqsize; i++)
3143 for (j = 0; j < csize; j++)
3144 if (cq->lits[i] == c->lits[j])
3145 if (marks[c->lits[j]] == 0)
3146 marks[c->lits[j]] = 1;
3147
3148 for (j = 0; j < csize; j++)
3149 if (marks[c->lits[j]] == 0)
3150 error = 1;
3151
3152 if (error) {
3153 fprintf(stdout, "ERROR : Wrong in resolution! \n");
3154 fprintf(stdout, "Resolvent (");
3155 sat_print_clause_simple(m, c);
3156 fprintf(stdout, " ) <= (");
3157 sat_print_clause_simple(m, cp);
3158 fprintf(stdout, ") (x) (");
3159 sat_print_clause_simple(m, cq);
3160 fprintf(stdout, ")\n");
3161
3162 }
3163}
3164
3165/**Function********************************************************************
3166
3167 Synopsis [ Check unit of a clause ]
3168
3169 Description [ Check unit of a clause ]
3170
3171 SideEffects [ ]
3172
3173 SeeAlso [ ]
3174
3175******************************************************************************/
3176long
3177sat_check_unit_clause(satManager_t *m, satClause_t *c)
3178{
3179long i, csize, lit, unit;
3180
3181 unit = 0;
3182 csize = SATSizeClause(c);
3183 for (i = 0; i < csize; i++) {
3184 lit = c->lits[i];
3185 if (m->values[lit>>1] == 2)
3186 if (unit == 0) unit = lit;
3187 else return 0;
3188 else if ((m->values[lit>>1]^(lit&1) ) == 1)
3189 return 0;
3190 }
3191 return unit;
3192}
3193
3194/**Function********************************************************************
3195
3196 Synopsis [ Calculate the abstract score of the clause ]
3197
3198 Description [ Calculate the abstract score of the clause ]
3199
3200 SideEffects [ ]
3201
3202 SeeAlso [ ]
3203
3204******************************************************************************/
3205void
3206sat_calculate_clause_abs(satClause_t *c)
3207{
3208long i, size, abstract;
3209
3210 abstract = 0;
3211 size = SATSizeClause(c);
3212 for (i=0; i<size; i++)
3213 abstract |= 1 << (SATVar(c->lits[i]) & 31);
3214 c->info.abstract = abstract;
3215}
3216
3217/**Function********************************************************************
3218
3219 Synopsis [ Copy a clause to another ]
3220
3221 Description [ Copy a clause to another ]
3222
3223 SideEffects [ ]
3224
3225 SeeAlso [ ]
3226
3227******************************************************************************/
3228satClause_t *
3229sat_copy_clause(satManager_t *m, satClause_t *c)
3230{
3231int learned;
3232long i, size;
3233satArray_t *arr;
3234satClause_t *ct;
3235
3236 arr = m->clearned;
3237 arr->size = 0;
3238
3239 /** Create a duplicate clause **/
3240 size = SATSizeClause(c);
3241 for (i = 0; i < size; i++) {
3242 arr = sat_array_insert(arr, c->lits[i]);
3243 }
3244 learned = SATClauseLearned(c);
3245 ct = sat_add_clause(m, arr, learned);
3246
3247 if (m->simplify)
3248 sat_add_all_watched_literal_without_scoring(m, c);
3249
3250 m->clearned = arr;
3251 m->clearned->size = 0;
3252 return (ct);
3253}
3254
3255/**Function********************************************************************
3256
3257 Synopsis [ Make resolution graph ]
3258
3259 Description [ Make resolution graph :
3260 Store c as one of parents resolved to derive ct. ]
3261
3262
3263 SideEffects [ ]
3264
3265 SeeAlso [ ]
3266
3267******************************************************************************/
3268void
3269sat_make_resolution_graph(satClause_t *c, satClause_t *ct)
3270{
3271 ct->dependent = sat_array_alloc_insert(ct->dependent, (long)c);
3272}
3273
3274/**Function********************************************************************
3275
3276 Synopsis [ Delete dependencies of clauses ]
3277
3278 Description [ Delete dependencies of clauses ]
3279
3280 SideEffects [ ]
3281
3282 SeeAlso [ ]
3283
3284******************************************************************************/
3285void
3286sat_delete_dependencies_of_clause_array(satArray_t *arr)
3287{
3288long i;
3289satClause_t *c;
3290
3291 if (arr) {
3292 for (i = 0; i < arr->size; i++) {
3293 c = (satClause_t *)arr->space[i];
3294 if (c->dependent) {
3295 c->dependent->size = 0;
3296 }
3297 }
3298 }
3299}
3300
3301/**Function********************************************************************
3302
3303 Synopsis [ Check occurrence list of eliminated variables ]
3304
3305 Description [ Check occurrence list of eliminated variables ]
3306
3307 SideEffects [ Invariant : no clauses in the list of deleted clauses is left
3308 unwatched by any eliminated variable. ]
3309
3310 SeeAlso [ ]
3311
3312******************************************************************************/
3313void
3314sat_check_all_watched_list_of_eliminated_variables(satManager_t *m)
3315{
3316long i, j, index;
3317long v, lit, csize;
3318int satisfied;
3319satClause_t *c;
3320satArray_t *elimVars, *occur, *deleted;
3321
3322 /** Get eliminated variables **/
3323 elimVars = m->elimtable;
3324 for (i = 0; i < elimVars->size; i++) {
3325 v = elimVars->space[i];
3326 lit = v << 1;
3327
3328 /** 1. Mark clauses in positive occurrence list **/
3329 index = lit | 1;
3330 occur = m->wls[index];
3331 if (occur && occur->size == 0)
3332 fprintf(stdout, "WARNING : Empty occur list of eliminated Var %ld\n", v);
3333 else if (occur) {
3334 for (j = 0; j < occur->size; j++) {
3335 c = (satClause_t*)occur->space[j];
3336 if (!SATClauseVisited(c))
3337 c->size |= SATCVisited;
3338 }
3339 }
3340 /** 2. Mark clauses in negative occurrence list **/
3341 index = lit;
3342 occur = m->wls[index];
3343 if (occur && occur->size == 0)
3344 fprintf(stdout, "WARNING : Empty occur list of eliminated Var %ld\n", v);
3345 else if (occur) {
3346 for (j = 0; j < occur->size; j++) {
3347 c = (satClause_t*)occur->space[j];
3348 if (!SATClauseVisited(c))
3349 c->size |= SATCVisited;
3350 }
3351 }
3352 }
3353
3354 /** Check if all clauses deleted are either watched or satisfied **/
3355 deleted = m->deleted;
3356 for (i = 0; i < deleted->size; i++) {
3357 c = (satClause_t*)deleted->space[i];
3358 csize = SATSizeClause(c);
3359 satisfied = 0;
3360 if (!SATClauseVisited(c)) {
3361 for (j = 0; j < csize; j++) {
3362 lit = c->lits[j];
3363 if ((m->values[SATVar(lit)] ^ (lit&1)) == 1) {
3364 satisfied = 1;
3365 break;
3366 }
3367 }
3368 if (satisfied == 0) {
3369 fprintf(stdout, "ERROR : unsatisfied deleted clause\n");
3370 sat_print_clause(m, c);
3371 fprintf(stdout, "\n");
3372 }
3373 }
3374 }
3375}
3376
3377/**Function********************************************************************
3378
3379 Synopsis [ Utilities for Queue structure ]
3380
3381 Description [ Utilities for Queue structure ]
3382
3383 SideEffects [ ]
3384
3385 SeeAlso [ ]
3386
3387******************************************************************************/
3388satQueue_t *
3389sat_queue_init(long maxElements)
3390{
3391satQueue_t *Q;
3392
3393 Q = (satQueue_t *)malloc(sizeof(satQueue_t) + sizeof(long)*maxElements);
3394 if( Q == NULL )
3395 fprintf(stderr, " Queue Out of space!\n");
3396
3397 Q->max = maxElements;
3398 Q->size = 0;
3399 Q->first = 0;
3400 Q->last = 0;
3401 Q->elems[0] = 0;
3402 return Q;
3403}
3404
3405void
3406sat_queue_clear(satQueue_t *Q)
3407{
3408 Q->first = Q->last = 0;
3409}
3410
3411void
3412sat_queue_free(satQueue_t *Q)
3413{
3414 if (Q)
3415 free(Q);
3416}
3417
3418void
3419sat_queue_insert(satQueue_t *Q, long n)
3420{
3421long last, max;
3422
3423 max = Q->max;
3424 last = Q->last + 1;
3425 if (last % max == Q->first) {
3426 return;
3427 }
3428 Q->elems[Q->last] = n;
3429 Q->last = last % max;
3430 ++(Q->size);
3431}
3432
3433long
3434sat_queue_pop(satQueue_t *Q)
3435{
3436long n, first;
3437
3438 first = Q->first;
3439 if (first == Q->last) {
3440 fprintf(stderr, " Queue underflow!\n");
3441 return -1;
3442 }
3443
3444 n = Q->elems[first];
3445 Q->first = ++first % Q->max;
3446 --(Q->size);
3447 return n;
3448}
3449
3450void
3451sat_queue_print(satQueue_t *Q)
3452{
3453long i;
3454
3455 fprintf(stdout, " Queue contents : First(%ld) -> Last(%ld)\n", Q->first, Q->last);
3456 for (i=Q->first; i!=Q->last; ) {
3457 fprintf(stdout, " %6ld", Q->elems[i++]);
3458 i = i%(Q->max);
3459 if (i%15 == 0) {
3460 fprintf(stdout, "\n");
3461 }
3462 }
3463 fprintf(stdout, "\n");
3464}
Note: See TracBrowser for help on using the repository browser.