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

Last change on this file since 74 was 12, checked in by cecile, 13 years ago

cusp added

File size: 84.8 KB
RevLine 
[12]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.