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

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

cusp added

File size: 115.8 KB
Line 
1/**CFile***********************************************************************
2
3  FileName    [sat.c]
4
5  PackageName [sat]
6
7  Synopsis    [Routines for sat function.]
8
9  Author      [Hoonsang Jin, 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
45#include <setjmp.h>
46#include <signal.h>
47#include <string.h>
48#include <stdlib.h>
49#include <zlib.h>
50#include "sat.h"
51#include "util.h"
52
53#define STATS
54#define HS_INDEX 6
55#define LINEBUFSIZE 327680 
56
57static char rcsid[] UNUSED = "$Id $";
58static jmp_buf timeOutEnv;
59static int CirCUsTimeOut;       
60static long alarmLapTime;
61
62#ifndef HAVE_LIBGMP
63
64int
65main(int argc, char ** argv)
66{
67char * filename = 0;
68int timeout = -1;
69int i;
70satArray_t *sat_options;
71
72  sat_options = sat_array_alloc(3);
73  for (i = 0; i < 3; i++) 
74    sat_array_insert(sat_options, 0);
75
76  fprintf(stdout, "c %s (compiled %s)\n", 
77          CUR_VER,  DateReadFromDateString(CUR_DATE));
78
79  if (argc <= 2) { 
80    if (argc < 2 || !strcmp (argv[1], "-h")) {
81      goto usage;
82    } 
83    filename = strdup(argv[1]);
84    sat_main(filename, timeout, sat_options);
85    return 0;   
86  }
87 
88  for (i = 1; i < argc; i++) {
89    if (!strcmp (argv[i], "-cnf")) {
90     
91      filename = strdup(argv[i+1]);
92     
93    } else if (!strcmp (argv[i], "-t")) {
94     
95      timeout = atoi(argv[i+1]);     
96     
97    } else if (!strcmp (argv[i], "-quiet")) {
98
99      sat_options->space[0] = 1;
100     
101    } else if (!strcmp (argv[i], "-velim")) {
102
103      sat_options->space[1] = 1;
104     
105    } else if (!strcmp (argv[i], "-distill")) {
106
107      sat_options->space[2] = 1;
108     
109    } else if (i == 1) {
110
111      filename = strdup(argv[i]);
112     
113    }
114  }
115
116  if (!filename)   goto usage;
117
118  /* e.g. cusp -cnf file */
119  sat_main(filename, timeout, sat_options);
120 
121  return 0;
122
123usage:
124  (void) fprintf(stderr, "USAGE: cusp [-h] [problem] <input-file> [problem-options] [-t <seconds>]\n\n");
125  (void) fprintf(stderr, "-h            print the command usage\n\n");
126  (void) fprintf(stderr, "PROBLEM:\n\n");
127  (void) fprintf(stderr, "  -cnf        Propositional Satisfiability (default)\n\n");
128  (void) fprintf(stderr, "CNF-OPTIONS:\n\n");
129  (void) fprintf(stderr, "  -quiet      suppress printing solution (default 0)\n");
130  (void) fprintf(stderr, "  -velim      preprocessing: variable elimination (default 0)\n");
131  (void) fprintf(stderr, "  -distill    preprocessing: clause distillation (default 0)\n");
132  (void) fprintf(stderr, "\n");
133
134  return 1;
135}
136#endif
137
138int
139sat_main(char * filename, int timeout, satArray_t* options)
140{
141satManager_t *m;
142long btime, etime;
143
144  btime = util_cpu_time();
145  m = sat_init_manager();
146  m->allSat = 0;
147  if (timeout > 0) {
148    CirCUsTimeOut = timeout;
149    (void) signal(SIGALRM, (void(*)(int))TimeOutHandle);
150    (void) alarm(CirCUsTimeOut);
151    if (setjmp(timeOutEnv) > 0) {
152      (void) fprintf(stdout,
153                "c CirCUs : timeout occurred after %d seconds.\n", CirCUsTimeOut);
154      alarm(0);
155      etime = util_cpu_time();
156      m->solveTime = (double)(etime - btime) / 1000.0;
157      sat_report_result(m);
158      free(filename);
159      return 1;
160    }
161  }
162
163   
164  if (options->space[0]) {      /* supress printing solution */
165    m->printModel = 0; 
166  }
167  else {
168    m->printModel = 1; 
169  }
170  if (options->space[1]) {      /* preprocess variable elimination */
171    m->simplify = 1;
172    m->grow = 0;
173    m->nIteratePreprocess = 3;
174  }
175  if (options->space[2]) {      /* preprocess clause distillation */
176    m->distill = 1; 
177  }
178 
179  if(sat_read_cnf(m, filename) == 0) 
180    goto gotoEnd;
181
182  if(m->status == 0) {
183    sat_report_result(m);
184    goto gotoEnd;
185  }
186
187  etime = util_cpu_time();
188  m->readTime = (double)(etime - btime) / 1000.0;
189
190  if (m->simplify)
191    sat_eliminate_var_main(m);
192
193  if(m->status == 2) {
194    sat_circus_solve(m);
195    if(m->status == 1) {
196      if (m->simplify)
197        sat_extend_model(m);
198      sat_verify(m);
199    }
200  }
201
202  etime = util_cpu_time();
203  m->solveTime = (double)(etime - btime) / 1000.0;
204
205  sat_report_result(m);
206
207  if(m->coreGeneration && m->status == 0) {
208    sat_generate_unsat_core_main(m);
209    sat_print_unsat_core(m, filename);
210  }
211
212gotoEnd:;
213   
214  free(filename);
215  sat_free_manager(m);
216  return 0;
217} 
218
219void
220TimeOutHandle(void)
221{
222  int seconds = (int) ((util_cpu_ctime() - alarmLapTime) / 1000);
223
224  if (seconds < CirCUsTimeOut) {
225    unsigned slack = (unsigned) (CirCUsTimeOut - seconds);
226    (void) signal(SIGALRM, (void(*)(int)) TimeOutHandle);
227    (void) alarm(slack);
228  } else {
229    longjmp(timeOutEnv, 1);
230  }
231} 
232
233void 
234sat_circus_solve(satManager_t *m)
235{
236double nConflicts;
237long iter, i;
238
239  if(m->status != 2)    return; 
240
241  if (m->simplify == 0)
242    sat_simplify(m);
243
244  if(m->status != 2)    return; 
245
246  if(m->allSat == 0) {
247    for(i=1; i<=m->nVars; i++) {
248      if(m->values[i] == 2)
249        sat_heap_insert(m, m->variableHeap, i);
250    }
251  }
252
253  if (m->distill)
254    sat_distill_clauses_with_preprocessing(m);
255
256  sat_print_cnf(m, 0);
257 
258  nConflicts = m->restartFirst;
259  m->reduceClausesThresh = (m->clauses->size + m->learned->size) * m->learnedSizeFactor;
260  if(m->reduceClausesThresh < 2000)     m->reduceClausesThresh = 2000;
261  m->reduceClausesThresh = (m->reduceClausesThresh + m->learned->size) > 5000 ? 5000 : m->reduceClausesThresh;
262
263#ifdef STATS
264  fprintf(stdout, "============================[ Search Statistics ]==============================\n");
265  fprintf(stdout, "| Conflicts |          ORIGINAL         |          LEARNT          | Progress |\n");
266  fprintf(stdout, "|           |    Vars  Clauses Literals |    Limit  Clauses Lit/Cl |          |\n");
267  fprintf(stdout, "===============================================================================\n");
268#endif
269 
270  iter = 0;
271  m->preTotalLearnedCl = m->nTotalLearnedClauses;
272  m->preTotalLearnedLit = m->nTotalLearnedLits;
273  m->preJumpCl = m->nTotalLearnedClauses;
274
275  while(m->status == 2) {
276
277#ifdef STATS
278    fprintf(stdout, "| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n", 
279            (int)m->nTotalLearnedClauses, (int)m->variableHeap->size, 
280            (int)m->clauses->size, (int)m->nCurClauseLits, 
281            (int)m->reduceClausesThresh, (int)m->learned->size, 
282            (double)m->nCurLearnedLits/m->learned->size, 
283            m->progress*100); 
284    fflush(stdout);
285#endif
286    sat_dpll(m, (long)nConflicts);
287   
288#ifdef LUBY_RESTART
289    sat_generate_next_restart_bound(m);
290    nConflicts = m->restartFirst * m->restartInc;
291    m->preLearnedPos = m->learned->size;
292#else
293    nConflicts *= m->restartInc;
294    m->reduceClausesThresh *= m->learnedSizeInc;
295#endif
296
297    iter++;
298  }
299
300#ifdef STATS
301  fprintf(stdout, "| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n", 
302            (int)m->nTotalLearnedClauses, (int)m->variableHeap->size, 
303            (int)m->clauses->size, (int)m->nCurClauseLits, 
304            (int)m->reduceClausesThresh, (int)m->learned->size, 
305            (double)m->nCurLearnedLits/m->learned->size, 
306            m->progress*100); 
307    fflush(stdout);
308    fprintf(stdout, "===============================================================================\n"); 
309#endif
310
311}
312
313void
314sat_generate_next_restart_bound(satManager_t *m)
315{
316int pvalue;
317
318#ifdef LUBY_RESTART
319  pvalue = 1;
320  pvalue = (pvalue << m->restartIndex);
321  if(m->restartInc == pvalue) {
322    m->restartIndex++;
323    m->restartInc = 1;
324  }
325  else {
326    m->restartInc = (m->restartInc << 1);
327  }
328
329#endif
330  return;
331}
332
333void
334sat_estimate_progress(satManager_t *m)
335{
336double progress;
337double f;
338long i, level;
339long beg, end;
340
341  progress = 0;
342  f = 1.0/m->nVars;
343  level = m->decisionStackSeperator->size;
344  level = level>10?10:level;
345  for(i=0; i<level; i++) {
346    beg = i==0 ? 0 : m->decisionStackSeperator->space[i-1];
347    end = i==level ? m->stackPos : m->decisionStackSeperator->space[i];
348    progress += pow(f, (double)i) * (end-beg);
349  }
350
351  progress = progress/m->nVars;
352  if(m->progress < progress)    m->progress = progress;
353  return;
354}
355
356
357satClause_t *
358sat_add_theory_conflict_clause(satManager_t *m, satArray_t *learned)
359{
360satClause_t *c;
361
362  if(learned->size == 1) {
363    c = sat_new_clause(learned, 1);
364    m->learned = sat_array_insert(m->learned, (long)c);
365    sat_enqueue_check(m, learned->space[0], c);
366    m->nCurLearnedLits ++; m->nCurLearnedClauses++;
367    m->nTotalLearnedLits ++; m->nTotalLearnedClauses++;
368  }
369  else {
370    c = sat_new_clause(learned, 1);
371    m->learned = sat_array_insert(m->learned, (long)c);
372    sat_add_watched_literal(m, c);
373    sat_update_clause_activity(m, c);
374    sat_enqueue_check(m, learned->space[0], c);
375/**
376    sat_print_clause_simple(m, c);
377    fprintf(stdout, "\n");
378    fprintf(stdout, " size of learned %d ", m->nCurLearnedLits);
379    fprintf(stdout, " %d ", (int)m->stackPos);
380    fprintf(stdout, " %10g\n", m->varInc);
381    sat_print_clauses(m, m->learned);
382**/
383  }
384
385#if 0
386  sat_print_clause(m, c);
387  fprintf(stdout, "\n");
388  fflush(stdout);
389#endif
390  return(c);
391}
392
393satClause_t *
394sat_add_blocking_clause(satManager_t *m, satArray_t *learned)
395{
396satClause_t *c;
397long level, tmp, i, j, lit, v, levelLitIndex;
398
399  level = SATCurLevel(m);
400  levelLitIndex = 0;
401  for(i=j=0; i<learned->size; i++) {
402    lit = learned->space[i];
403    v = lit >> 1;
404    if(m->levels[v] != 0) {
405      if(m->levels[v] == level) 
406        levelLitIndex = j;
407      learned->space[j++] = lit;
408    }
409  }
410  learned->size -= (i-j);
411  tmp = learned->space[0];
412  learned->space[0] = learned->space[levelLitIndex];
413  learned->space[levelLitIndex] = tmp;
414
415  if(learned->size == 1) {
416    c = sat_new_clause(learned, 2);
417    m->blocking = sat_array_insert(m->blocking, (long)c);
418    m->nCurLearnedLits ++; m->nCurLearnedClauses++;
419    m->nTotalLearnedLits ++; m->nTotalLearnedClauses++;
420  }
421  else {
422    c = sat_new_clause(learned, 2);
423    m->blocking = sat_array_insert(m->blocking, (long)c);
424    /*    sat_update_clause_activity(m, c); */
425    sat_add_watched_literal(m, c);
426/**
427    sat_print_clause_simple(m, c);
428    fprintf(stdout, "\n");
429    fprintf(stdout, " size of learned %d ", m->nCurLearnedLits);
430    fprintf(stdout, " %d ", (int)m->stackPos);
431    fprintf(stdout, " %10g\n", m->varInc);
432    sat_print_clauses(m, m->learned);
433**/
434  }
435  m->nCurBlockingLits += learned->size;
436  m->nCurBlockingClauses++;
437  m->nTotalBlockingLits += learned->size;
438  m->nTotalBlockingClauses++;
439  return(c);
440}
441
442void
443sat_add_blocking_clause_for_theorem_prover(satManager_t *m, satArray_t *arr)
444{
445satClause_t *c;
446long level, tmp, i, j, lit, v, levelLitIndex;
447long bLevel, nMarks, iLit;
448
449  level = SATCurLevel(m);
450  levelLitIndex = 0;
451  nMarks = 0;
452  bLevel = 0;
453  for(i=j=0; i<arr->size; i++) {
454    lit = arr->space[i];
455    v = lit >> 1;
456    if(m->levels[v] == 0)
457      continue;
458    if(m->levels[v] == level) {
459      levelLitIndex = j;
460      nMarks++;
461    }
462    else if(m->levels[v] > bLevel) {
463      bLevel = m->levels[v];
464    }
465    arr->space[j++] = lit;
466  }
467  arr->size -= (i-j);
468  tmp = arr->space[0];
469  arr->space[0] = arr->space[levelLitIndex];
470  arr->space[levelLitIndex] = tmp;
471 
472#if 0
473  fprintf(stdout, "Blocking clause generated nMarks %ld bLevel %ld\n", nMarks, bLevel);
474  sat_print_clause_array(m, arr);
475  fprintf(stdout, "\n");
476#endif
477  c = sat_new_clause(arr, 2);
478  if(nMarks > 1) {
479    bLevel = sat_conflict_analysis(m, c);
480    /** add a conflict clause if on-the-fly subsumption 
481     *  replaced a clause with the newly found conflict clause.
482     **/
483    if (m->clearned->size > 0) {
484      if(c->dependent)
485        free(c->dependent);
486      free(c);
487      sat_undo(m, bLevel);
488      c = sat_add_learned_clause(m, m->clearned);
489    }
490#if 0
491    fprintf(stdout, "Result of conflict analysis bLevel %ld\n", bLevel);
492    sat_print_clause(m, c);
493    fprintf(stdout, "\n");
494#endif
495  }
496  else {
497    sat_undo(m, bLevel);
498
499    m->blocking = sat_array_insert(m->blocking, (long)c);
500    iLit = (c->lits[0]);
501    if(arr->size == 1) {
502      sat_enqueue_check(m, iLit, 0);
503    }
504    else {
505      sat_add_watched_literal(m, c);
506      sat_enqueue_check(m, iLit, c);
507    }
508    m->nCurBlockingLits += arr->size;
509    m->nCurBlockingClauses++;
510    m->nTotalBlockingLits += arr->size;
511    m->nTotalBlockingClauses++;
512  }
513}
514
515satClause_t *
516sat_add_theory_clause(satManager_t *m, satArray_t *learned)
517{
518satClause_t *c;
519/* long level, tmp, i, lit, v; */
520
521/**
522  if(learned->size == 1) {
523    c = sat_new_clause(learned, 1);
524  }
525  else {
526    level = SATCurLevel(m);
527    for(i=0; i<learned->size; i++) {
528      lit = learned->space[i];
529      v = lit>>1;
530      if(m->levels[v] == level) {
531        tmp = learned->space[0];
532        learned->space[0] = learned->space[i];
533        learned->space[i] = tmp;
534        break;
535      }
536    }
537**/
538/**
539  if(learned->size == 2) {
540    c = sat_add_clause(m, learned, 4);
541  }
542  else {
543  **/
544
545    c = sat_new_clause(learned, 4);
546#ifdef SMT_ADD_THEORY
547    if (m->enableAddTheoryClause) {
548      m->theory = sat_array_insert(m->theory, (long)c);
549      sat_add_watched_literal(m, c);
550      sat_update_clause_activity(m, c);
551    }
552#endif
553 /* } */
554
555  return(c);
556}
557
558#if 1
559void
560sat_dpll(satManager_t *m, long nConflicts)
561{
562long bLevel, lit;
563long previousStackPointer;
564long nLearnedClauses;
565satClause_t *conflicting, *c;
566
567  m->nRestarts++;
568  m->nCurConflicts = 0;
569  previousStackPointer = 0; 
570
571  while(1) {
572    conflicting = sat_implication(m);
573    if(conflicting) {
574      m->nConflicts++; m->nCurConflicts++;
575      if(SATCurLevel(m) == 0) {
576        if(m->coreGeneration) {
577          m->nullClause = conflicting;
578        }
579        m->status = 0;
580        return;
581      }
582
583      nLearnedClauses = m->learned->size;
584      bLevel = sat_conflict_analysis(m, conflicting);
585
586      /** add a conflict clause if on-the-fly subsumption 
587       *  replaced a clause with the newly found conflict clause.
588       **/
589      if (m->clearned->size > 0) {
590        sat_undo(m, bLevel);
591
592        previousStackPointer = m->stackPos;
593
594        c = sat_add_learned_clause(m, m->clearned);
595        if(m->coreGeneration)
596          sat_make_dependent_graph(m, c);
597      }
598      else {
599        if (m->learned->size > nLearnedClauses) {
600          sat_undo(m, bLevel);
601          previousStackPointer = m->stackPos;
602        }
603        else {
604          /* stackPos was increased at the conflict analysis */
605          previousStackPointer = m->stackPos - 1;       
606        }
607      }
608      sat_update_variable_decay(m);
609      sat_update_clause_decay(m);
610     
611      if(m->maxContiguousLevel > m->maxContiguousLimit) {
612        nConflicts = m->nCurConflicts;
613        m->mcla[m->maxContiguousLevel]++;
614        if(m->maxContiguousLevel >= HS_INDEX)
615          m->mclaTotal++;
616        m->maxContiguousLevel = 0;
617      }
618      sat_calculate_restart_bound_new(m);
619
620    }
621    else {
622      if(nConflicts >= 0 && m->nCurConflicts >= nConflicts) {
623        sat_estimate_progress(m);
624        sat_undo(m, 0);
625        return;
626      }
627      if(SATCurLevel(m) == 0 && m->enableSimplify) {
628        previousStackPointer = 0;
629        sat_simplify(m);
630        if(m->status != 2)      return;
631      }
632      if(m->reduceClausesThresh >= 0 && 
633        m->learned->size-m->stackPos-m->n2LitClauses>= m->reduceClausesThresh) {
634        sat_reduce_learned_clauses(m);
635      }
636#ifdef HAVE_LIBGMP
637      if(m->allSat) {
638        if(smt_get_size_of_atomic_variable(m)<<2 < m->theory->size) {
639          sat_reduce_theory_clauses(m);
640        }
641
642        if((m->reduceClausesThresh>>4) < m->blocking->size) {
643          sat_reduce_blocking_clauses(m);
644        }
645        /**
646         * 1. send information of implied variables to theory solver
647         * 2. call thoery solver with partial assignment
648         *    then check feasibility of theory
649         *    if conflict happens then find explanation
650         *    otherwise do theory propagation.
651         * 3. If conflict occurs put explanation into CNF database
652         **/
653        int flag;
654       
655        flag = smt_call_theory_solver(m, previousStackPointer);
656        if(flag == 2 && m->status == 0) {
657          /** UNSATISFIABLE **/
658          return;
659        } else if(flag == 3) {
660          /** bound computed in level 0 **/
661          m->status = 3;
662          return;
663        } else if(flag == 4) {
664          /** bound computed in level 0 and theory prop **/
665          previousStackPointer = m->stackPos;
666          return;
667        }
668        if(flag == 1) {
669          previousStackPointer = m->stackPos;
670          continue;
671        }
672        else if(flag == 2) {
673          /** -1 is required because there is implied literal **/
674          previousStackPointer = m->stackPos-1;
675          continue;
676        }
677      }
678#else
679      if (previousStackPointer) previousStackPointer = 0; /* HK : dummy assignment */
680#endif
681      sat_decide_polarity_new(m);
682      /* nLearned = m->learned->size*4;
683      sat_decide_restart(m, (long)nLearned);
684      */
685      m->nDecisions++;
686      lit = sat_make_decision(m);
687     
688      if(lit == 0){
689#ifdef HAVE_LIBGMP
690        int flag;
691        if(m->allSat) {
692          flag = smt_call_theory_solver(m, previousStackPointer);
693          if(flag >= 2 && m->status == 0) {
694            /** UNSATISFIABLE **/
695            return;
696          }
697          if(flag == 1) {
698           previousStackPointer = m->stackPos;
699            continue;
700          }
701          else if(flag >= 2) {
702            previousStackPointer = m->stackPos-1;
703            continue;
704          }
705        }
706#endif
707        m->status = 1;
708        return;
709      }
710
711      m->decisionStackSeperator = 
712          sat_array_insert(m->decisionStackSeperator, m->stackPos);
713      previousStackPointer = m->stackPos;
714      sat_enqueue(m, lit, 0);
715    }
716  }
717}
718#endif
719
720void
721sat_calculate_restart_bound_new(satManager_t *m)
722{
723  double ht_divide_ratio;
724  int hs_index;
725  int he_index;
726  int te_index;
727  int i;
728  double slope;
729  double n=0, yaxis=0, sumx=0, sumx2=0, sumxy=0, sumy=0, sumy2=0;
730  double xaxis;
731  int ttotal;
732
733  if(m->enableFrequentRestart == 0) {
734    m->maxContiguousLimit = 256;
735    return;
736  }
737  if(m->mclaTotal < 128)        return;
738  ht_divide_ratio = 0.90;
739  hs_index = HS_INDEX;
740  he_index = m->maxContiguousLimit+1;
741  if(m->mcla[he_index] > 5) {
742    ttotal = m->mcla[he_index]; 
743    while(ttotal>1) {
744      m->mcla[he_index] = ttotal/2;
745      ttotal = ttotal - ttotal/2;
746      he_index++;
747    }
748    m->mcla[he_index] = ttotal;
749  }
750
751  while(1) {
752    if(m->mcla[he_index] > 0)   break;
753    he_index--; 
754  }
755  n = 0;
756  for(i=hs_index; i<=he_index; i++) {
757    if(m->mcla[i] == 0) continue;
758    yaxis = log(m->mcla[i]);
759/**
760    if(m->mcla[i] == 0) yaxis = 0;
761    else yaxis = log(m->mcla[i]);
762**/
763    sumx += i;
764    sumx2 += i*i;
765    sumxy += i*yaxis;
766    sumy += yaxis;
767    sumy2 += yaxis*yaxis;
768    n = n+1;
769  }
770/**
771**/
772  xaxis = (n*sumx2 - sqrt(sumx));
773/**
774  fprintf(stdout, "xaxis %f\n", xaxis);
775  fprintf(stdout, "slope %f\n", n*sumxy - sumx*sumy);
776  fprintf(stdout, "yaxis %f\n", sumy*sumx2 - sumx*sumxy);
777**/
778  slope = (n*sumxy - sumx*sumy)/xaxis;
779  yaxis = (sumy*sumx2 - sumx*sumxy)/xaxis;
780  xaxis = (-yaxis)/slope;
781
782/**
783  fprintf(stdout, "n %f sumxy %f sumx %f sumy %f sqrt(sumx) %f\n", n, sumxy, sumx, sumy, sqrt(sumx));
784  for(i=hs_index; i<=he_index; i++) {
785    fprintf(stdout, "%4d ", m->mcla[i]);
786  }
787  fprintf(stdout, "\n");
788  for(i=hs_index; i<=he_index; i++) {
789    fprintf(stdout, "%.2f ", log(m->mcla[i]));
790  }
791  fprintf(stdout, "\n");
792  fprintf(stdout, "slope %f y %f x %f\n", slope, yaxis, (double)xaxis);
793**/
794#if 1
795  if(m->maxContiguousLimit/2 < xaxis)
796    te_index = xaxis;
797  else 
798    te_index = m->maxContiguousLimit;
799#endif
800  if(xaxis < 0) {
801    te_index = m->maxContiguousLimit * 1.2;
802  }
803  if(te_index < 10)
804    m->maxContiguousLimit = 10;
805    else if(te_index < 256) { // 50 at 07.20
806    m->maxContiguousLimit = (double)(te_index-hs_index)*ht_divide_ratio + hs_index;
807  }
808  /*fprintf(stdout, "Bound == %d (%d %d) %f\n", m->maxContiguousLimit,
809   * hs_index, te_index, xaxis); */
810  fflush(stdout);
811 
812  memset(m->mcla, 0, sizeof(int)*m->mclaSize);
813  m->mclaTotal = 0;
814  m->maxContiguousData[0] = 0;
815  m->maxContiguousData[1] = 0;
816  m->maxContiguousData[2] = 0;
817  m->maxContiguousData[3] = 0;
818  m->maxContiguousData[4] = 0;
819  m->maxContiguousData[5] = 0;
820}
821
822
823
824
825
826void
827sat_decide_polarity(satManager_t *m) 
828{
829double avgLit;
830long nLearnedClauses;
831long nLearnedLits;
832long limit;
833
834  limit = (m->reduceClausesThresh>>6);
835  limit = limit>256 ? 256 : limit;
836  limit = limit<64 ? 64 : limit;
837  nLearnedClauses = m->nTotalLearnedClauses-m->preTotalLearnedCl;
838  if(nLearnedClauses > limit) {
839/**
840    if(m->polarityMode == 2)   
841      m->polarityMode = 0;
842**/
843    nLearnedLits = m->nTotalLearnedLits-m->preTotalLearnedLit;
844    avgLit = (double)nLearnedLits/(double)nLearnedClauses;
845    /**
846    if(preAvgLit < avgLit) {
847      m->defaultSign = m->defaultSign ^ 1;
848      m->polarityMode++;
849      m->polarityMode = m->polarityMode%3;
850    }
851    **/
852    if(m->preLit+2 < avgLit) {
853      m->defaultSign = m->defaultSign ^ 1;
854      m->nPolarityChange++;
855    }
856    /**
857    fprintf(stdout, "average jump %10.1f average level %10.1f DEFAULT %d\n",
858            avgJump, avgLevel, m->defaultSign);
859    fflush(stdout);
860    **/
861
862    /**
863    if(avgJump < 2)
864      sat_change_search_direction(m);
865    **/
866
867    m->preLit = avgLit;
868    m->preTotalLearnedCl = m->nTotalLearnedClauses;
869    m->preTotalLearnedLit = m->nTotalLearnedLits;
870  }
871}
872
873void
874sat_decide_polarity_new(satManager_t *m) 
875{
876double avgLit;
877long nLearnedClauses;
878long nLearnedLits;
879
880  nLearnedClauses = m->nTotalLearnedClauses-m->preTotalLearnedCl;
881  if(nLearnedClauses > m->polarityChangeLimit) {
882    nLearnedLits = m->nTotalLearnedLits-m->preTotalLearnedLit;
883    avgLit = (double)nLearnedLits/(double)nLearnedClauses;
884
885    if((m->preLit+2.0000000001) < avgLit) {
886      m->defaultSign = m->defaultSign ^ 1;
887      m->nPolarityChange++;
888    }
889    m->preLit = avgLit;
890    m->preTotalLearnedCl = m->nTotalLearnedClauses;
891    m->preTotalLearnedLit = m->nTotalLearnedLits;
892    m->polarityChangeLimit = (double)m->polarityChangeLimit * 1.6;
893    if(m->polarityChangeLimit > 256)
894      m->polarityChangeLimit = 64;
895  }
896}
897
898void
899sat_decide_restart(satManager_t *m, long nLearned) 
900{
901double avgJump, avgLevel;
902long nLearnedClauses;
903long limit, levelLimit;
904long implePerDecision;
905long maxLevel;
906
907  limit = nLearned>>6;
908  limit = limit<64 ? 64 : limit;
909
910  nLearnedClauses = m->nTotalLearnedClauses-m->preJumpCl;
911/**
912  if(nLearnedClauses > limit && m->decisionStackSeperator->size > 8) {
913**/
914  if(nLearnedClauses > limit) {
915    if(m->decisionStackSeperator->size < 2) {
916      m->preJumpCl = m->nTotalLearnedClauses;
917      m->nJump = 0;
918      m->nLevel = 0;
919      return;
920    }
921    implePerDecision = m->stackPos-m->decisionStackSeperator->space[0];
922    implePerDecision = implePerDecision/(m->decisionStackSeperator->size+1);
923    implePerDecision = implePerDecision == 0 ? 1 : implePerDecision;
924    maxLevel = m->variableHeap->size/implePerDecision;
925    levelLimit = maxLevel>>3;
926
927    avgJump = (double)m->nJump/(double)nLearnedClauses;
928    avgLevel = (double)m->nLevel/(double)nLearnedClauses;
929
930/**
931    fprintf(stdout, "%d %d %d %10g %10g\n",
932            (int)implePerDecision, (int)maxLevel, (int)levelLimit,
933            avgJump, avgLevel);
934**/
935
936    levelLimit = levelLimit<4 ? 4 : levelLimit;
937
938    if(avgJump<2 && avgLevel>(levelLimit)) {
939      sat_estimate_progress(m);
940      sat_undo(m, 0);
941      m->nForceRestart++;
942    }
943    else if(avgJump<1.5) {
944      sat_estimate_progress(m);
945      sat_undo(m, 0);
946      m->nForceRestart++;
947    }
948#if 0
949    if(avgJump<2.5 && avgLevel>(levelLimit)) {
950      sat_estimate_progress(m);
951      sat_undo(m, 0);
952      m->nForceRestart++;
953    }
954    else if(avgJump<2.0 && avgLevel>(levelLimit<<1)) {
955      sat_estimate_progress(m);
956      sat_undo(m, 0);
957      m->nForceRestart++;
958    }
959    else if(avgJump<1.5 && avgLevel>(levelLimit<<2)) {
960      sat_estimate_progress(m);
961      sat_undo(m, 0);
962      m->nForceRestart++;
963    }
964#endif
965    m->preJumpCl = m->nTotalLearnedClauses;
966    m->nJump = 0;
967    m->nLevel = 0;
968  }
969  return;
970}
971
972long 
973sat_make_decision(satManager_t *m)
974{
975long next, lit, v;
976long index;
977
978
979  next = 0;
980  if(m->useRandom && 
981     sat_drand(m) < m->randomFrequency && 
982     m->variableHeap->size != 0) {
983    index = (long)(sat_drand(m) * m->variableHeap->size);
984    next = m->variableHeap->heap[index];
985    if(next > 0 && m->values[next] == 2)        m->nRandomDecisions++;
986  }
987
988  if(m->usePreviousDecisionHistory) {
989    while(m->previousDecisionHistory->size) {
990      m->nTHistoryDecisions++;
991      lit = m->previousDecisionHistory->space[m->previousDecisionHistory->size-1];
992      v = lit>>1;
993      if(m->values[v] == 2) {
994        m->previousDecisionHistory->size--;
995        m->nHistoryDecisions++;
996        return(lit^1);
997      }
998      m->previousDecisionHistory->size--;
999    }
1000  }
1001
1002  while(next==0 || m->values[next] != 2) {
1003    if(m->variableHeap->size == 0) {
1004      next = 0;
1005      break;
1006    }
1007    else 
1008      next = sat_heap_remove_min(m, m->variableHeap);
1009  }
1010  /**
1011  if(m->polarityMode == 2) {
1012    m->defaultSign = m->defaultSign ^ 1;
1013  }
1014  **/
1015  lit = next == 0 ? 0 : ((next<<1) + m->defaultSign);
1016
1017  return(lit);
1018}
1019
1020double
1021sat_drand(satManager_t *m)
1022{
1023long q;
1024
1025  m->randomSeed *= 1389796;
1026  q = (long)(m->randomSeed/ 2147483647);
1027  m->randomSeed -= (double)q * 2147483647;
1028  return(m->randomSeed/2147483647);
1029}
1030
1031void
1032sat_change_search_direction(satManager_t *m)
1033{
1034long i, csize, lit, v, size;
1035satArray_t *learned;
1036satClause_t *c;
1037
1038  sat_sort_clause_array(m->learned, compare_sort_learned);
1039  learned = m->learned;
1040  size = learned->size/2;
1041  for(i=0; i<size; i++) {
1042    c = (satClause_t *)learned->space[i];
1043    csize = SATSizeClause(c);
1044    lit = c->lits[0];
1045    v = lit>>1;
1046    if(csize > 2 && 
1047       !((m->values[v]^SATSign(lit)) == 1)) {
1048      sat_update_variable_activity(m, v);
1049    }
1050  }
1051}
1052
1053void
1054sat_reduce_learned_clauses(satManager_t *m)
1055{
1056long i, j, k;
1057double limit;
1058long v, size, csize;
1059satClause_t *c;
1060satArray_t *learned;
1061
1062  m->nReduceClauses++;
1063  limit = m->clauseInc / (double)m->learned->size;
1064
1065  learned = m->learned;
1066
1067  sat_sort_clause_array(m->learned, compare_sort_learned);
1068
1069  for(k=learned->size-1; k>=0; k--) {
1070    c = (satClause_t *)learned->space[k];
1071    csize = SATSizeClause(c);
1072    if(csize > 2)
1073      break;
1074  }
1075  m->n2LitClauses = learned->size - k;
1076
1077  size = k>>1;
1078  for(i=j=0; i<size; i++) {
1079    c = (satClause_t *)learned->space[i];
1080    csize = SATSizeClause(c);
1081    v = (c->lits[0]>>1);
1082    if(csize > 2 && 
1083       !(m->antes[v] == c && (m->values[v]^SATSign(c->lits[0])) == 1)) {
1084      if(m->coreGeneration) {
1085        m->deleted = sat_array_insert(m->deleted, (long)c);
1086        sat_delete_watched_literal(m, c);
1087      }
1088      else 
1089        sat_delete_clause(m, c);
1090    }
1091    else
1092      learned->space[j++] = learned->space[i];
1093  }
1094
1095  size = k;
1096  for(; i<size; i++) {
1097    c = (satClause_t *)learned->space[i];
1098    csize = SATSizeClause(c);
1099    v = (c->lits[0]>>1);
1100    if(csize > 2 && 
1101       !(m->antes[v] == c && (m->values[v]^SATSign(c->lits[0])) == 1) &&
1102       c->info.activity < limit)       
1103      if(m->coreGeneration) {
1104        m->deleted = sat_array_insert(m->deleted, (long)c);
1105        sat_delete_watched_literal(m, c);
1106      }
1107      else 
1108        sat_delete_clause(m, c);
1109    else
1110      learned->space[j++] = learned->space[i];
1111  }
1112
1113  size = learned->size;
1114  for(; i<size; i++) {
1115    learned->space[j++] = learned->space[i];
1116  }
1117
1118  learned->size -= (i-j);
1119  m->reduceClausesThresh = (double)m->reduceClausesThresh * m->learnedSizeInc;
1120
1121}
1122
1123void
1124sat_reduce_blocking_clauses(satManager_t *m)
1125{
1126long i, j, k;
1127double limit;
1128long v, size, csize;
1129satClause_t *c;
1130satArray_t *learned;
1131
1132  limit = m->clauseInc / (double)m->blocking->size;
1133  learned = m->blocking;
1134
1135#if 0
1136  k = learned->size;
1137  size = k;
1138  for(i=j=0; i<size; i++) {
1139    c = (satClause_t *)learned->space[i];
1140    csize = SATSizeClause(c);
1141    v = (c->lits[0]>>1);
1142    if(csize > 2 &&
1143       !(m->antes[v] == c && (m->values[v]^SATSign(c->lits[0])) == 1) &&
1144       c->info.activity < limit) {     
1145      if(m->coreGeneration) {
1146        m->deleted = sat_array_insert(m->deleted, (long)c);
1147        sat_delete_watched_literal(m, c);
1148      }
1149      else
1150        sat_delete_clause(m, c);
1151    }
1152    else
1153      learned->space[j++] = learned->space[i];
1154  }
1155#endif
1156
1157#if 1
1158  k = learned->size;
1159  size = (k>>1);
1160  for(i=j=0; i<size; i++) {
1161    c = (satClause_t *)learned->space[i];
1162    csize = SATSizeClause(c);
1163    v = (c->lits[0]>>1);
1164    if(csize > 2 && 
1165       !(m->antes[v] == c && (m->values[v]^SATSign(c->lits[0])) == 1)) {
1166      if(m->coreGeneration) {
1167        m->deleted = sat_array_insert(m->deleted, (long)c);
1168        sat_delete_watched_literal(m, c);
1169      }
1170      else 
1171        sat_delete_clause(m, c);
1172    }
1173    else
1174      learned->space[j++] = learned->space[i];
1175  }
1176
1177  size = k;
1178  for(; i<size; i++) {
1179    c = (satClause_t *)learned->space[i];
1180    csize = SATSizeClause(c);
1181    v = (c->lits[0]>>1);
1182    if(csize > 2 && 
1183       !(m->antes[v] == c && (m->values[v]^SATSign(c->lits[0])) == 1) &&
1184       c->info.activity < limit)       
1185      if(m->coreGeneration) {
1186        m->deleted = sat_array_insert(m->deleted, (long)c);
1187        sat_delete_watched_literal(m, c);
1188      }
1189      else 
1190        sat_delete_clause(m, c);
1191    else
1192      learned->space[j++] = learned->space[i];
1193  }
1194#endif
1195
1196  size = learned->size;
1197  for(; i<size; i++) {
1198    learned->space[j++] = learned->space[i];
1199  }
1200
1201  learned->size -= (i-j);
1202  /**
1203  fprintf(stdout, "reduced clause %d out of %d\n", i-j, k);
1204  fprintf(stdout, "current learned lit %d ", m->nCurLearnedLits);
1205  fprintf(stdout, "%10g\n",  m->clauseInc);
1206  **/
1207}
1208
1209int 
1210compare_sort_variable_id(const void *x1, const void *y1)
1211{
1212long x, y;
1213  x = (long)x1; x = x>>1;
1214  y = (long)y1; y = y>>1;
1215  return(x < y);
1216}
1217
1218int 
1219compare_sort_learned(const void *x1, const void *y1)
1220{
1221satClause_t *x, *y;
1222  x = (satClause_t *)x1;
1223  y = (satClause_t *)y1;
1224  return(SATSizeClause((x)) > 2 && 
1225        ( SATSizeClause((y)) <= 2 || (x)->info.activity < (y)->info.activity));
1226}
1227
1228int 
1229compare_sort_theory(const void *x1, const void *y1)
1230{
1231satClause_t *x, *y;
1232  x = (satClause_t *)x1;
1233  y = (satClause_t *)y1;
1234  return((x)->info.activity < (y)->info.activity);
1235}
1236
1237int 
1238compare_sort_block(const void *x1, const void *y1)
1239{
1240satClause_t *x, *y;
1241  x = (satClause_t *)x1;
1242  y = (satClause_t *)y1;
1243  return((x)->info.activity > (y)->info.activity);
1244}
1245
1246void
1247sat_reduce_theory_clauses(satManager_t *m)
1248{
1249long i, j;
1250double limit;
1251long v, size;
1252/** long csize; **/
1253satClause_t *c;
1254satArray_t *theory;
1255
1256
1257  sat_sort_clause_array(m->theory, compare_sort_theory);
1258
1259  theory = m->theory;
1260
1261  limit = 0;
1262  limit = m->clauseInc / (double)m->theory->size;
1263  limit = 1;
1264  size = (theory->size>>1);
1265
1266  for(i=j=0; i<size; i++) {
1267    c = (satClause_t *)theory->space[i];
1268    /**csize = SATSizeClause(c);**/
1269    v = (c->lits[0]>>1);
1270    /**
1271    if(csize > 2 &&
1272       !(m->antes[v] == c && (m->values[v]^SATSign(c->lits[0])) == 1))
1273       **/
1274    if(!(m->antes[v] == c && (m->values[v]^SATSign(c->lits[0])) == 1))
1275      sat_delete_clause(m, c);
1276    else
1277      theory->space[j++] = theory->space[i];
1278  }
1279
1280  size = theory->size;
1281  for(; i<size; i++) {
1282    c = (satClause_t *)theory->space[i];
1283    /**csize = SATSizeClause(c);**/
1284    v = (c->lits[0]>>1);
1285    /**
1286    if(csize > 2 &&
1287       !(m->antes[v] == c && (m->values[v]^SATSign(c->lits[0])) == 1) &&
1288       c->info.activity < limit)       
1289       **/
1290    if(!(m->antes[v] == c && (m->values[v]^SATSign(c->lits[0])) == 1) &&
1291       c->info.activity < limit)       
1292      sat_delete_clause(m, c);
1293    else
1294      theory->space[j++] = theory->space[i];
1295  }
1296
1297  theory->size -= (i-j);
1298  /**
1299  fprintf(stdout, "reduced theory clauses %d\n", i-j);
1300  fprintf(stdout, "current learned lit %d ", m->nCurLearnedLits);
1301  fprintf(stdout, "%10g\n",  m->clauseInc);
1302  **/
1303}
1304
1305
1306
1307int
1308sat_is_redundant_lit(satManager_t *m, long oLit, long absLevel)
1309{
1310satArray_t *cclearned, *redundant;
1311satClause_t *c;
1312int top, i, j;
1313long v, csize, lit;
1314
1315  if(m->coreGeneration) return(0);
1316
1317  c = 0;
1318  redundant = m->redundant;
1319  redundant->size = 0;
1320  m->temp->size = 0;
1321  redundant = sat_array_insert(redundant, oLit);
1322  cclearned = m->cclearned;
1323  top = cclearned->size;
1324
1325  if(m->coreGeneration) 
1326    m->temp = sat_array_insert(m->temp, (long)m->antes[oLit>>1]);
1327  while(redundant->size > 0) {
1328    redundant->size--;
1329    c = m->antes[(redundant->space[redundant->size])>>1];
1330    csize = SATSizeClause(c);
1331    for(i=0; i<csize; i++) {
1332      lit = c->lits[i];
1333      v = lit>>1;
1334      if(!m->marks[v] && m->levels[v] > 0) {
1335        if(m->antes[v] != 0 && (sat_abstract_level(m, v) & absLevel)) {
1336          m->marks[v] = 1;
1337          redundant = sat_array_insert(redundant, lit);
1338          cclearned = sat_array_insert(cclearned, lit);
1339          if(m->coreGeneration) 
1340            m->temp = sat_array_insert(m->temp, (long)m->antes[lit>>1]);
1341        }
1342        else {
1343          for(j=top; j<cclearned->size; j++) 
1344            m->marks[(cclearned->space[j]>>1)] = 0;
1345          cclearned->size = top;
1346          m->cclearned = cclearned;
1347          m->redundant = redundant;
1348          m->temp->size = 0;
1349          return(0);
1350        }
1351      }
1352    }
1353  }
1354  m->cclearned = cclearned;
1355  if(m->coreGeneration) {
1356    for(j=0; j<m->temp->size; j++) 
1357      c = (satClause_t *)m->temp->space[j];
1358      m->dependent = sat_array_insert(m->dependent, (long)c);
1359  }
1360  m->redundant = redundant;
1361  m->temp->size = 0;
1362  return(1);
1363}
1364
1365int
1366sat_minimize_conflict(satManager_t *m, long v, int depth)
1367{
1368int level, res;
1369  if(!m->minimizeConflict) return(0);
1370
1371  if(m->removable[v])   return 1;
1372  if(m->unremovable[v]) return 0;
1373  if(depth && m->marks[v])      return 1;
1374  if(m->antes[v] == 0)  return 0;
1375
1376  level = m->levels[v];
1377  if(level == 0 && !m->includeLevelZero)        return 0;
1378  if(depth++ > m->minimizeConflictLimit)        return 0;
1379
1380  res = 0;
1381  long lit = (m->values[v] == 0) ? (v<<1)+1 : (v<<1);
1382  {
1383    satClause_t *c = m->antes[v];
1384    int csize = SATSizeClause(c);
1385    int i;
1386    for(i=0; i<csize; i++) { 
1387      long other = c->lits[i];
1388      if(lit == other)  continue;
1389      long u = other>>1; 
1390      if(m->marks[u])   continue;
1391      if(m->removable[u])       continue;
1392      if(m->unremovable[u])return 0;
1393      if(m->levels[u] == 0 && !m->includeLevelZero)     continue;
1394    }
1395    for(i=0; i<csize; i++) { 
1396      long other = c->lits[i];
1397      if(lit == other)  continue;
1398      long u = other>>1; 
1399      if(m->marks[u])   continue;
1400      if(m->removable[u])       continue;
1401      if(m->unremovable[u])return 0;
1402      if(m->levels[u] == 0 && !m->includeLevelZero)     continue;
1403      if(!sat_minimize_conflict(m, u, depth))   return 0;
1404    }
1405    res = 1;
1406  }
1407  m->removable[v] = res;
1408  m->unremovable[v] = res^1;
1409  /** add variable to stack for cleaning up **/
1410  m->seen = sat_array_insert(m->seen, v);
1411  return res;
1412}
1413
1414void
1415sat_cleanup_for_minimize_conflict(satManager_t *m, satArray_t *arr)
1416{
1417  int i;
1418  for(i=0; i<arr->size; i++) {
1419    long v = arr->space[i];
1420    m->marks[v] = 0;
1421    m->removable[v] = 0;
1422    m->unremovable[v] = 0;
1423  }
1424  arr->size = 0;
1425}
1426
1427
1428long
1429sat_conflict_analysis(satManager_t *m, satClause_t *conflicting)
1430{
1431long nMarks, i, j, maxI;
1432long tWidth, mMarks;
1433long width, depth;
1434long nEdges, nVertex;
1435long lit, cLit, bLevel, tLit;
1436long *pLit;
1437long v, csize, preV, tv;
1438long level, nReduction;
1439long mInc, mIncRef, mIncV, mEdges;
1440long firstIter;
1441long pre_size;
1442long fromBeginning;
1443long nAllMarks, nResolventLits;
1444long nDistilled, nLevelZeros, abstract;
1445int subsumptionCheck, mSelectNextIncV;
1446int binary;
1447satClause_t *c;
1448satClause_t *oc;
1449satArray_t *clearned, *cclearned;
1450satClause_t *resolvent;
1451#ifdef OLD_OCI
1452satArray_t *arr;
1453#endif
1454
1455  nDistilled = 0;
1456  nAllMarks = 0;
1457  nLevelZeros = 0;
1458  mSelectNextIncV = 0;
1459  m->resolvents->size = 0;
1460  subsumptionCheck = m->subsumeInConflict;
1461  resolvent = (subsumptionCheck ? conflicting : 0);
1462
1463  clearned = m->clearned;
1464  clearned->size = 0;
1465  clearned = sat_array_insert(clearned, 0);
1466  m->dependent->size = 0;
1467  i = m->stackPos - 1;
1468  bLevel = lit = 0;
1469  nMarks = mMarks = 0;
1470  nEdges = nVertex = 0;
1471  tWidth = 0;
1472  mInc = 0;
1473  mIncV = 0;
1474  mIncRef = 0;
1475  mEdges = 0;
1476  preV = tv = 0;
1477  oc = conflicting;
1478  m->previousDecisionHistory->size = 0;
1479  firstIter = 0;
1480  pre_size = 0;
1481  fromBeginning = 0;
1482  binary = 0;
1483
1484  do {
1485    nResolventLits = nAllMarks;
1486    nLevelZeros = 0;
1487
1488    c = conflicting;
1489   
1490    if(m->coreGeneration)
1491      m->dependent = sat_array_insert(m->dependent, (long)c);
1492
1493    if(SATClauseLearned(c) || SATClauseBlock(c))
1494      sat_update_clause_activity(m, c);
1495
1496    mIncRef = clearned->size;
1497
1498    csize = SATSizeClause(c);
1499    j=(lit == 0)?0:1;
1500    pLit = &(c->lits[j]);
1501    for(; j<csize; j++) { 
1502      cLit = *pLit++;
1503      v = cLit >> 1;
1504      if(m->levels[v] == SATCurLevel(m))
1505        nEdges++;
1506
1507      if(!m->marks[v]) {
1508        if((m->includeLevelZero==0 && m->levels[v]>0) || m->includeLevelZero==1) {
1509
1510          m->marks[v] = 1;
1511           
1512          nAllMarks++;
1513          sat_update_variable_activity(m, v);
1514          if(m->levels[v] >= SATCurLevel(m)) {
1515            nMarks++;
1516          }
1517          else {
1518            clearned = sat_array_insert(clearned, cLit);
1519            if(m->levels[v] > bLevel)
1520              bLevel = m->levels[v];
1521          }
1522        }
1523        else if (m->includeLevelZero==0 && m->levels[v]==0) 
1524          nLevelZeros++;
1525      }
1526
1527    }
1528 
1529    /** Subsumption check in conflict analysis **/
1530    if (subsumptionCheck && firstIter > 0) {
1531      if (resolvent > 0 && (nResolventLits == nAllMarks)) {
1532        /* previous resolvent is subsumed by current resolvent */
1533
1534      #ifdef OLD_OCI
1535        sat_strengthen_clause_in_conflict_analysis(m, resolvent, 0);
1536        if (nMarks > 1) {
1537          oc = resolvent;
1538          nEdges = nVertex = tWidth = 0;
1539        }
1540      #else
1541        sat_queue_insert(m->satQueue, (long)resolvent);
1542        m->resolvents = sat_array_insert(m->resolvents, tv);
1543      #endif
1544 
1545        if ((csize - nLevelZeros) > nAllMarks) {
1546          /* delete the antecedent, when antecednet is also subsumed */
1547          m->nEliminatedClsInConflict++;
1548          m->nEliminatedLitsInConflict += csize;
1549       
1550        #ifdef OLD_OCI
1551          arr = SATClauseLearned(c) ? m->learned : m->clauses;
1552          sat_array_delete_elem(arr, (long)c);
1553          sat_delete_clause(m, c);
1554        #else
1555          if (SATClauseOriginal(resolvent) || !SATClauseOriginal(c)) {
1556            sat_queue_insert(m->satQueue, (long)c);
1557            m->resolvents = sat_array_insert(m->resolvents, 0);
1558          }
1559          else {
1560            sat_queue_insert(m->satQueue, (long)c);
1561            m->resolvents = sat_array_insert(m->resolvents, tv);
1562          } 
1563        #endif
1564        }
1565        m->depthOfOTS += nVertex; 
1566        nDistilled++;
1567      }
1568      else if ((csize - nLevelZeros) > nAllMarks) {
1569        /* antecedent is subsumed by current resolvent */
1570        nDistilled++;
1571        m->depthOfOTS += nVertex; 
1572        resolvent = c;
1573         
1574    #ifdef OLD_OCI
1575        sat_strengthen_clause_in_conflict_analysis(m, resolvent, 0);
1576        if (nMarks > 1) {
1577          oc = resolvent;
1578          nEdges = nVertex = tWidth = 0;
1579        }
1580    #else
1581        sat_queue_insert(m->satQueue, (long)resolvent);
1582        m->resolvents = sat_array_insert(m->resolvents, tv);
1583    #endif
1584      }
1585      else 
1586        resolvent = 0;
1587    }
1588
1589    firstIter++;
1590    tWidth += nMarks;
1591    nVertex++;
1592    mMarks = (nMarks > mMarks) ? nMarks : mMarks;
1593
1594    preV = tv;
1595    while(i>=0 && !(m->marks[(m->decisionStack[i--])>>1]));
1596    lit = m->decisionStack[i+1];
1597    tv = lit>>1; 
1598    conflicting = m->antes[tv];
1599    m->marks[tv] = 0;
1600    nMarks--;
1601    nAllMarks--;
1602 
1603    if(clearned->size-mIncRef >= mInc) { 
1604      mInc = clearned->size-mIncRef;
1605      mIncV = preV;
1606      mEdges = nEdges;
1607    }
1608   
1609  } while(nMarks > 0);
1610
1611  m->depthOfConflict += nVertex;
1612  m->nDistillInConflict += nDistilled;
1613 
1614  clearned->space[0] = lit^1;
1615  tLit = lit;
1616 
1617  cclearned = m->cclearned;
1618  cclearned->size = 0;
1619
1620  nReduction = 0;
1621  if(clearned->size == 1) 
1622    bLevel = 0;
1623  else {
1624    /** minimize conflict learned clause **/
1625    m->cclearned = cclearned = sat_array_copy(clearned, m->cclearned);
1626    for(i=j=1; i<clearned->size; i++) {
1627      lit = clearned->space[i];
1628      v = lit >> 1;
1629      if(m->antes[v] == 0 || !sat_minimize_conflict(m, v, 0)) 
1630        clearned->space[j++] = lit;
1631    }
1632    clearned->size -= (i-j);
1633    nReduction = (i-j);
1634    sat_cleanup_for_minimize_conflict(m, m->seen);
1635
1636    maxI = 1; 
1637    for(i=2; i<clearned->size; i++) 
1638      if(m->levels[(clearned->space[i]>>1)] > m->levels[(clearned->space[maxI]>>1)])
1639        maxI = i;
1640    lit = clearned->space[maxI];
1641    clearned->space[maxI] = clearned->space[1];
1642    clearned->space[1] = lit;
1643    bLevel = m->levels[lit>>1];
1644
1645    #ifdef OLD_OCI
1646    if (resolvent > 0) {
1647      lit = clearned->space[1];
1648      if (resolvent->lits[1] != lit) { 
1649        sat_array_delete_elem(m->wls[((resolvent->lits[1])^1)], (long)resolvent);
1650        m->wls[(lit^1)] = sat_array_alloc_insert(m->wls[(lit^1)], (long)resolvent); 
1651      }
1652      for (i=1; i<clearned->size; i++) {
1653        lit = clearned->space[i];
1654        resolvent->lits[i] = lit;       
1655      }
1656      resolvent->size = (clearned->size << SATCsizeShift) | (resolvent->size & SATCMask); 
1657    }
1658    #endif
1659  }
1660
1661  cclearned = m->cclearned;
1662  for(j=0; j<cclearned->size; j++)
1663    m->marks[(cclearned->space[j]>>1)] = 0;
1664
1665/**
1666  for(j=1; j<clearned->size; j++)
1667    if(m->levels[(clearned->space[j]>>1)] > 0)
1668      sat_update_variable_activity(m, (clearned->space[j]>>1));
1669**/
1670
1671
1672  m->clearned = clearned;
1673  m->cclearned = cclearned;
1674
1675  m->nJump += m->decisionStackSeperator->size - bLevel;
1676  m->nLevel += m->decisionStackSeperator->size;
1677
1678  width = (long)((double)tWidth/(double)nVertex+0.5)+1;
1679  depth = (long)((double)nEdges/(double)width+ 0.5);
1680  level = m->decisionStackSeperator->size;
1681
1682  v = clearned->space[0]>>1;
1683  if(m->antes[v] != 0)  m->nFirstUip++;
1684
1685  if(m->coreGeneration == 0) {
1686 
1687#if 0 
1688  if(depth > 20 && width < 4 ) {
1689    if (resolvent == 0 || nReduction > 0)
1690      m->tlearned = sat_array_copy(m->clearned, m->tlearned);
1691    sat_conflict_analysis_strong(m, oc, m->clearned->size*3/2, nVertex>>1);
1692    m->nAuxConflictAnalysis++;
1693    if (resolvent == 0 || nReduction > 0)
1694      m->clearned = sat_array_copy(m->tlearned, m->clearned);
1695  }
1696#endif
1697
1698#if 0 
1699  if(depth > 5 && mIncV && mInc>5 && mInc > clearned->size/3 && mEdges > nEdges/2) {
1700    if (resolvent == 0 || nReduction > 0)
1701      m->tlearned = sat_array_copy(m->clearned, m->tlearned);
1702    sat_conflict_analysis_supplemental(m, oc, mIncV, clearned->size*2/3);
1703    m->nAuxConflictAnalysis++;
1704    if (resolvent == 0 || nReduction > 0)
1705      m->clearned = sat_array_copy(m->tlearned, m->clearned);
1706  }
1707#endif
1708  }
1709
1710  if(SATClauseBlock(oc))
1711    oc->info.activity = 0;
1712
1713  /** Subsumption check in conflict analysis **/
1714  if (subsumptionCheck) {
1715    sat_strengthen_set_of_clauses_in_conflict_analysis(m);
1716 
1717    if (resolvent > 0) {
1718      if (nReduction > 0) {
1719        abstract = 0;
1720        lit = clearned->space[1];
1721        if (resolvent->lits[1] != lit) { 
1722          sat_array_delete_elem(m->wls[((resolvent->lits[1])^1)], (long)resolvent);
1723          m->wls[(lit^1)] = sat_array_alloc_insert(m->wls[(lit^1)], (long)resolvent); 
1724        }
1725        resolvent->size = (clearned->size << SATCsizeShift) | (resolvent->size & SATCMask); 
1726       
1727        abstract |= 1 << (SATVar(resolvent->lits[0]) & 31);
1728        for (i=1; i<clearned->size; i++) {
1729          lit = clearned->space[i];
1730          resolvent->lits[i] = lit;     
1731          abstract |= 1 << (SATVar(lit) & 31);
1732        }
1733        if (!SATClauseLearned(resolvent)) 
1734          resolvent->info.abstract = abstract;
1735      } 
1736      m->nOmittedConflictClauses++;
1737      m->nOmittedConflictLits += m->clearned->size;
1738
1739      /** For unit conflict clause, we may need to move the clause
1740       *  strengthened to unit literal into the array of original
1741       *  clauses if the clause is a learned clause.
1742       **/
1743      m->clearned->size = 0;
1744      sat_undo(m, bLevel);
1745      sat_enqueue_check(m, resolvent->lits[0], resolvent);
1746    } 
1747  } 
1748
1749  m->conflictLevels[(int)m->nConflicts%5] = m->decisionStackSeperator->size;
1750  double alevel = ( (double)(m->conflictLevels[0]+m->conflictLevels[1]+m->conflictLevels[2]+m->conflictLevels[3]+m->conflictLevels[4]-m->decisionStackSeperator->size) / 4.0);
1751  double glevel = alevel - m->decisionStackSeperator->size;
1752  if(-3.0<glevel && glevel<3.0 && m->decisionStackSeperator->size-bLevel < 9 ) {
1753    m->maxContiguousLevel++;
1754  }
1755  else {
1756    if(m->maxContiguousDataCollect) {
1757      if(m->mclaSize <= m->maxContiguousLevel) {
1758        m->mcla = (int *)realloc((int *)m->mcla, sizeof(int)*(m->mclaSize<<1));
1759        memset(&m->mcla[m->mclaSize], 0, sizeof(int)*m->mclaSize);
1760        m->mclaSize = (m->mclaSize<<1);
1761      }
1762      m->mcla[m->maxContiguousLevel]++;
1763      m->maxContiguousLevelTotal += m->maxContiguousLevel;
1764      m->maxContiguousLevelCount ++;
1765      if(m->maxContiguousLevel >= HS_INDEX)
1766        m->mclaTotal++;
1767    }
1768    m->maxContiguousLevel = 0;
1769  }
1770
1771/**  if(m->tempUnitClauses->size > 0) {
1772    bLevel = 0;
1773    sat_undo(m, bLevel);
1774    for(i=0; i<m->tempUnitClauses->size; i++) {
1775      c = (satClause_t *)m->tempUnitClauses->space[i];
1776      sat_enqueue_check(m, c->lits[0], c);
1777    }
1778    m->tempUnitClauses->size = 0;
1779  }
1780**/
1781  return(bLevel);
1782}
1783
1784
1785void
1786sat_conflict_analysis_strong(satManager_t *m, satClause_t *conflicting, long sLimit, long implLimit)
1787{
1788long nMarks, i, j;
1789long tWidth, mMarks;
1790long nEdges, nVertex;
1791
1792long lit, cLit;
1793long absLevel, v, csize;
1794long implL, implR;
1795satClause_t *c;
1796satArray_t *clearned, *cclearned;
1797
1798  clearned = m->clearned;
1799  clearned->size = 0;
1800  clearned = sat_array_insert(clearned, 0);
1801  clearned = sat_array_insert(clearned, 0);
1802  m->dependent->size = 0;
1803  i = m->stackPos - 1;
1804  lit = 0;
1805  nMarks = mMarks = 0;
1806  nEdges = nVertex = 0;
1807  tWidth = 0;
1808  implL = implLimit*5/10;
1809  implR = implLimit*15/10;
1810 
1811
1812  do {
1813    c = conflicting;
1814
1815    if(m->coreGeneration)
1816      m->dependent = sat_array_insert(m->dependent, (long)c);
1817
1818    csize = SATSizeClause(c);
1819    for(j=(lit == 0)?0:1; j<csize; j++) {
1820      cLit = c->lits[j];
1821      v = cLit >> 1;
1822      if(m->levels[v] == SATCurLevel(m))
1823        nEdges++;
1824      /**
1825      if(!m->marks[v] && m->levels[v]>0) {
1826        m->marks[v] = 1;
1827        if(m->levels[v] >= SATCurLevel(m))
1828          nMarks++;
1829        else {
1830          clearned = sat_array_insert(clearned, cLit);
1831        }
1832      }
1833      **/
1834
1835      if(!m->marks[v]) {
1836        if((m->includeLevelZero==0 && m->levels[v]>0) || m->includeLevelZero==1) {
1837          m->marks[v] = 1;
1838          if(m->levels[v] >= SATCurLevel(m))
1839            nMarks++;
1840          else {
1841            clearned = sat_array_insert(clearned, cLit);
1842          }
1843        }
1844      }
1845    }
1846    tWidth += nMarks;
1847    nVertex++;
1848    mMarks = (nMarks > mMarks) ? nMarks : mMarks;
1849
1850    while(!(m->marks[(m->decisionStack[i--])>>1]));
1851    lit = m->decisionStack[i+1];
1852    v = lit>>1; 
1853    conflicting = m->antes[v];
1854    m->marks[v] = 0;
1855    nMarks--;
1856
1857   
1858    if(implL < nVertex && nVertex < implR && clearned->size < sLimit && nMarks == 1) {
1859      if(m->coreGeneration) 
1860        m->dependent = sat_array_insert(m->dependent, (long)conflicting);
1861
1862      clearned->space[1] = lit^1;
1863      while(!(m->marks[(m->decisionStack[i--])>>1]));
1864      lit = m->decisionStack[i+1];
1865      v = lit>>1; 
1866      m->marks[v] = 0;
1867      nMarks--;
1868      clearned->space[0] = lit^1;
1869      m->depthOfStrong += nVertex;
1870    }
1871    else if(clearned->size >= sLimit) {
1872      do{
1873        while(!(m->marks[(m->decisionStack[i--])>>1]));
1874        lit = m->decisionStack[i+1];
1875        v = lit>>1; 
1876        m->marks[v] = 0;
1877        nMarks--;
1878      }while(nMarks>0);
1879    }
1880  } while(nMarks > 0);
1881
1882  if(clearned->size >= sLimit || clearned->space[0] == 0) {
1883    m->clearned = clearned;
1884    for(j=0; j<clearned->size; j++)
1885      m->marks[(clearned->space[j]>>1)] = 0;
1886    return;
1887  }
1888
1889  cclearned = m->cclearned;
1890  cclearned->size = 0;
1891
1892  if(clearned->size == 1);
1893  else {
1894    /** minimize conflict learned clause **/
1895    absLevel = 0; 
1896    for(i=1; i<clearned->size; i++)
1897      absLevel |= sat_abstract_level(m, (clearned->space[i])>>1);
1898    m->cclearned = cclearned = sat_array_copy(clearned, m->cclearned);
1899    for(i=j=1; i<clearned->size; i++) {
1900      lit = clearned->space[i];
1901      v = lit >> 1;
1902      if(m->includeLevelZero && m->levels[v] == 0)
1903        clearned->space[j++] = lit;
1904      else if(m->antes[v] == 0 || !sat_is_redundant_lit(m, lit, absLevel))
1905        clearned->space[j++] = lit;
1906    }
1907    clearned->size -= (i-j);
1908  }
1909
1910  cclearned = m->cclearned;
1911  for(j=0; j<cclearned->size; j++)
1912    m->marks[(cclearned->space[j]>>1)] = 0;
1913
1914
1915  m->clearned = clearned;
1916  m->cclearned = cclearned;
1917
1918  if(sLimit > clearned->size) {
1919    c = sat_new_clause(m->clearned, 1);
1920    m->learned = sat_array_insert(m->learned, (long)c);
1921    sat_add_watched_literal(m, c);
1922   
1923    m->nAuxLearnedClauses++;
1924    m->nAuxLearnedLits += SATSizeClause(c);
1925
1926    if(m->coreGeneration)
1927      sat_make_dependent_graph(m, c);
1928
1929/**
1930    if(m->preJump <3)
1931    sat_update_clause_activity(m, c);
1932**/
1933  }
1934
1935  return;
1936}
1937
1938void
1939sat_conflict_analysis_supplemental(satManager_t *m, satClause_t *conflicting, long refV, long sLimit)
1940{
1941long nMarks, i, j;
1942long tWidth, mMarks;
1943long nEdges, nVertex;
1944long lit, cLit;
1945long absLevel, v, csize;
1946satClause_t *c;
1947satArray_t *clearned, *cclearned;
1948
1949  clearned = m->clearned;
1950  clearned->size = 0;
1951  clearned = sat_array_insert(clearned, 0);
1952  clearned = sat_array_insert(clearned, 0); 
1953  m->dependent->size = 0;
1954  i = m->stackPos - 1;
1955  lit = 0;
1956  nMarks = mMarks = 0;
1957  nEdges = nVertex = 0;
1958  tWidth = 0;
1959
1960 
1961  do {
1962    c = conflicting;
1963    if(m->coreGeneration)
1964      m->dependent = sat_array_insert(m->dependent, (long)c);
1965
1966    csize = SATSizeClause(c);
1967    for(j=(lit == 0)?0:1; j<csize; j++) {
1968      cLit = c->lits[j];
1969      v = cLit >> 1;
1970      if(m->levels[v] == SATCurLevel(m))
1971        nEdges++;
1972      /**
1973      if(!m->marks[v] && m->levels[v]>0) {
1974        m->marks[v] = 1;
1975        if(m->levels[v] >= SATCurLevel(m))
1976          nMarks++;
1977        else {
1978          clearned = sat_array_insert(clearned, cLit);
1979        }
1980      }
1981      **/
1982      if(!m->marks[v]) {
1983        if((m->includeLevelZero==0 && m->levels[v]>0) || m->includeLevelZero==1) {
1984          m->marks[v] = 1;
1985          if(m->levels[v] >= SATCurLevel(m))
1986            nMarks++;
1987          else {
1988            clearned = sat_array_insert(clearned, cLit);
1989          }
1990        }
1991      }
1992    }
1993    tWidth += nMarks;
1994    nVertex++;
1995    mMarks = (nMarks > mMarks) ? nMarks : mMarks;
1996
1997    while(!(m->marks[(m->decisionStack[i--])>>1]));
1998    lit = m->decisionStack[i+1];
1999    v = lit>>1; 
2000    conflicting = m->antes[v];
2001    m->marks[v] = 0;
2002    nMarks--;
2003
2004
2005    if(refV == v) {
2006      clearned->space[0] = lit^1;
2007      do{
2008        if(m->coreGeneration) 
2009          m->dependent = sat_array_insert(m->dependent, (long)conflicting);
2010        while(!(m->marks[(m->decisionStack[i--])>>1]));
2011        lit = m->decisionStack[i+1];
2012        v = lit>>1; 
2013        m->marks[v] = 0;
2014        nMarks--;
2015        conflicting = m->antes[v];
2016        if (nMarks > 0) 
2017          clearned = sat_array_insert(clearned, lit^1);
2018        else
2019          clearned->space[1] = lit^1;
2020
2021      }while(nMarks>0);
2022      m->depthOfStrong += nVertex; 
2023    }
2024  } while(nMarks > 0);
2025
2026  /**
2027  if(clearned->size >= sLimit) {
2028    m->clearned = clearned;
2029    for(j=0; j<clearned->size; j++)
2030      m->marks[(clearned->space[j]>>1)] = 0;
2031    return;
2032  }
2033  **/
2034
2035
2036  cclearned = m->cclearned;
2037  cclearned->size = 0;
2038
2039  if(clearned->size == 1); 
2040  else {
2041    /** minimize conflict learned clause **/
2042    absLevel = 0; 
2043    for(i=1; i<clearned->size; i++)
2044      absLevel |= sat_abstract_level(m, (clearned->space[i])>>1);
2045    m->cclearned = cclearned = sat_array_copy(clearned, m->cclearned);
2046    for(i=j=1; i<clearned->size; i++) {
2047      lit = clearned->space[i];
2048      v = lit >> 1;
2049      if(m->includeLevelZero && m->levels[v] == 0)
2050        clearned->space[j++] = lit;
2051      else if(m->antes[v] == 0 || !sat_is_redundant_lit(m, lit, absLevel))
2052        clearned->space[j++] = lit;
2053    }
2054    clearned->size -= (i-j);
2055  }
2056
2057  cclearned = m->cclearned;
2058  for(j=0; j<cclearned->size; j++)
2059    m->marks[(cclearned->space[j]>>1)] = 0;
2060
2061
2062  m->clearned = clearned;
2063  m->cclearned = cclearned;
2064
2065  if(sLimit > clearned->size) {
2066    c = sat_new_clause(m->clearned, 1);
2067    m->learned = sat_array_insert(m->learned, (long)c);
2068    sat_add_watched_literal(m, c);
2069
2070    m->nAuxLearnedClauses++;
2071    m->nAuxLearnedLits += SATSizeClause(c);
2072
2073    if(m->coreGeneration)
2074      sat_make_dependent_graph(m, c);
2075
2076/**
2077    if(m->preJump <3)
2078      sat_update_clause_activity(m, c);
2079**/
2080  }
2081
2082  return;
2083}
2084
2085void
2086sat_check_marks(satManager_t *m)
2087{
2088long i;
2089
2090  for(i=0; i<=m->nVars; i++) {
2091    if(m->marks[i] != 0) {
2092      fprintf(stdout, "Variable %d@%d is marked\n", (int)i, (int)m->levels[i]);
2093    }
2094  }
2095  fflush(stdout);
2096
2097}
2098
2099void
2100sat_conflict_analysis_for_literal(satManager_t *m, long target)
2101{
2102long nMarks, i, j, ti;
2103long tWidth, mMarks;
2104long width, depth;
2105long nEdges, nVertex;
2106long lit, cLit, bLevel, tLit;
2107long absLevel, v, csize;
2108long level;
2109satClause_t *c;
2110/** satClause_t *oc; **/
2111satClause_t *conflicting;
2112satArray_t *clearned, *cclearned;
2113
2114  clearned = m->clearned;
2115  clearned->size = 0;
2116  clearned = sat_array_insert(clearned, 0);
2117  i = m->stackPos - 1;
2118  bLevel = lit = 0;
2119  nMarks = 0;
2120  tWidth = 0;
2121  mMarks = 0;
2122  nEdges = 0;
2123  nVertex = 0;
2124
2125  clearned = sat_array_insert(clearned, target);
2126  conflicting = m->antes[target>>1];
2127  /**oc = conflicting; **/
2128 
2129  do {
2130    c = conflicting;
2131
2132    csize = SATSizeClause(c);
2133    for(j=(lit == 0)?0:1; j<csize; j++) {
2134      cLit = c->lits[j];
2135      v = cLit >> 1;
2136      if(m->levels[v] == SATCurLevel(m))
2137        nEdges++;
2138      if(!m->marks[v] && m->levels[v]>0) {
2139        m->marks[v] = 1;
2140        if(m->levels[v] >= SATCurLevel(m))
2141          nMarks++;
2142        else {
2143          clearned = sat_array_insert(clearned, cLit);
2144          if(m->levels[v] > bLevel)
2145            bLevel = m->levels[v];
2146        }
2147      }
2148    }
2149    tWidth += nMarks;
2150    nVertex++;
2151    mMarks = (nMarks > mMarks) ? nMarks : mMarks;
2152
2153    while(!(m->marks[(m->decisionStack[i--])>>1]));
2154    lit = m->decisionStack[i+1];
2155    v = lit>>1; 
2156    conflicting = m->antes[v];
2157    m->marks[v] = 0;
2158    nMarks--;
2159  } while(nMarks > 0);
2160  clearned->space[0] = lit^1;
2161  tLit = lit;
2162  ti = i;
2163
2164 
2165  cclearned = m->cclearned;
2166  cclearned->size = 0;
2167
2168  if(clearned->size == 1) 
2169    bLevel = 0;
2170  else {
2171    /** minimize conflict learned clause **/
2172    absLevel = 0; 
2173    for(i=1; i<clearned->size; i++)
2174      absLevel |= sat_abstract_level(m, (clearned->space[i])>>1);
2175    m->cclearned = cclearned = sat_array_copy(clearned, m->cclearned);
2176    for(i=j=1; i<clearned->size; i++) {
2177      lit = clearned->space[i];
2178      v = lit >> 1;
2179      if(m->antes[v] == 0 || !sat_is_redundant_lit(m, lit, absLevel))
2180        clearned->space[j++] = lit;
2181    }
2182    clearned->size -= (i-j);
2183  }
2184
2185  cclearned = m->cclearned;
2186  for(j=0; j<cclearned->size; j++)
2187    m->marks[(cclearned->space[j]>>1)] = 0;
2188
2189  m->clearned = clearned;
2190  m->cclearned = cclearned;
2191
2192  width = (long)((double)tWidth/(double)nVertex+0.5)+1;
2193  depth = (long)((double)nEdges/(double)width+ 0.5);
2194
2195  if(depth>10 && width > 7 &&
2196     m->clearned->size<(long)((double)m->nCurLearnedLits/m->learned->size)) {
2197/**
2198  if(sat_check_complementary(depth, m->clearned->size, (double)m->nCurLearnedLits/m->learned->size)) {
2199**/
2200    c = sat_new_clause(m->clearned, 1);
2201    m->learned = sat_array_insert(m->learned, (long)c);
2202    sat_add_watched_literal(m, c);
2203/**
2204    sat_update_clause_activity(m, c);
2205**/
2206  }
2207
2208  level = m->decisionStackSeperator->size;
2209  if(m->antes[tLit>>1] != 0) {
2210    if(ti-m->decisionStackSeperator->space[level-1] > nVertex<<1) {
2211      /**
2212      fprintf(stdout, "mmarks %d, twidth %d, nEdges %d\n", mMarks, tWidth, nEdges);
2213      fprintf(stdout, "width %d, depth %d\n", width, depth);
2214      sat_print_dot_for_implication_graph(m, oc, m->decisionStackSeperator->size, 0);
2215      **/
2216      sat_conflict_analysis_for_literal(m, tLit);
2217    }
2218  }
2219
2220  return;
2221}
2222
2223int
2224sat_check_complementary(int depth, int nLits, double avg)
2225{
2226double diff;
2227double refDepth;
2228/*double y; HK*/
2229
2230
2231  if(depth < 5) return(0);
2232  diff = (double)nLits - avg;
2233
2234  if(diff > avg)        return(0);
2235
2236  refDepth = 10;
2237
2238  if(diff>0) {
2239    if(depth < refDepth)        return(0);
2240    if(nLits < avg*1.5) return(1);
2241    else                return(0);
2242    /*y = refDepth*8/avg * diff - refDepth; HK */
2243  }
2244  else {
2245    if(depth > refDepth)        return(1);
2246    if(nLits < 4)       return(1);
2247    else                return(0);
2248  }
2249  /*if(depth > y)       return(1);
2250  else          return(0); HK */
2251}
2252
2253long
2254sat_abstract_level(satManager_t *m, long v)
2255{
2256  return( 1<<((m->levels[v]) & 31));
2257}
2258
2259satClause_t *
2260sat_implication(satManager_t *m)
2261{
2262satClause_t *conflicting, *c;
2263satArray_t *wl;
2264satClause_t **i, **j, **end;
2265long lit, iLit, first;
2266long csize, k;
2267long nProps;
2268
2269  nProps = 0;
2270  conflicting = 0;
2271
2272  while(m->curPos < m->stackPos) {
2273    lit = m->decisionStack[m->curPos++];
2274    wl = m->wls[lit];
2275
2276    if(wl == 0) continue;
2277    nProps++;
2278
2279    for(i = j = (satClause_t **)&(wl->space[0]), end = i + wl->size; i != end;) {
2280      c = *i++;
2281
2282      /** It can be implemented using conditional assignment **/
2283      iLit = lit ^ 1;
2284
2285      if(c->lits[0] == iLit)
2286        c->lits[0] = c->lits[1], c->lits[1] = iLit;
2287
2288      first = c->lits[0];
2289      if((m->values[first>>1]^SATSign(first)) == 1) {
2290        *j++ = c;
2291      }
2292      else {
2293        csize = SATSizeClause(c);
2294        for(k=2; k<csize; k++) {
2295          if((m->values[c->lits[k]>>1] ^ SATSign(c->lits[k])) != 0) {
2296            c->lits[1] = c->lits[k];
2297            c->lits[k] = iLit;
2298            m->wls[(c->lits[1]^1)] = 
2299                sat_array_alloc_insert(m->wls[(c->lits[1]^1)], (long)c);
2300            sat_verify_watched_literal(m, c);
2301            goto foundWatch;
2302          }
2303        }
2304
2305        *j++ = c;
2306        if((m->values[first>>1]^SATSign(first)) == 0) {
2307          conflicting = c;
2308          m->curPos = m->stackPos;
2309          while(i<end)  *j++ = *i++;
2310        }
2311        else {
2312          sat_enqueue(m, first, c);
2313        }
2314      }
2315foundWatch:;
2316    }
2317    wl->size -= i-j;
2318  }
2319  m->nImplications += nProps;
2320  m->simpDBProps -= nProps;
2321  return(conflicting);
2322}
2323
2324
2325void
2326sat_undo(satManager_t *m, long level)
2327{
2328long i, v;
2329satHeap_t *h;
2330
2331  if(SATCurLevel(m) > level) {
2332    if(m->usePreviousDecisionHistory && level != 0 && SATCurLevel(m)-level < 5) {
2333      for(i=SATCurLevel(m); i>level; i--) {
2334        v = m->decisionStack[m->decisionStackSeperator->space[i-1]];
2335        m->previousDecisionHistory = sat_array_insert(m->previousDecisionHistory, v); 
2336      }
2337    }
2338    h = m->variableHeap;
2339    for(i=m->stackPos-1; i>=m->decisionStackSeperator->space[level]; i--) {
2340      v = m->decisionStack[i] >> 1;
2341      m->values[v] = 2;
2342      m->levels[v] = -1; /* redundant undo **/
2343
2344      if(h->indices[v] < 0) /* a variable is not in heap **/
2345        sat_heap_insert(m, m->variableHeap, v);
2346    }
2347    m->curPos = m->decisionStackSeperator->space[level];
2348    m->stackPos = m->curPos;
2349    m->decisionStackSeperator->size = level; 
2350  }
2351  if(level == -1) {
2352    m->decisionStackSeperator->size = 0; 
2353    m->stackPos = 0;
2354  }
2355#ifdef HAVE_LIBGMP
2356  if(m->allSat)
2357    smt_theory_undo(m);
2358#endif
2359}
2360
2361void
2362sat_simplify(satManager_t *m)
2363{
2364satClause_t *c;
2365/*int limitVars;*/
2366long limitVars;
2367
2368  assert(SATCurLevel(m) == 0);
2369
2370  if(m->coreGeneration == 1 || m->enableSimplify == 0) 
2371    return;
2372
2373  c = sat_implication(m);
2374  if(c) {
2375    m->status = 0;
2376    return;
2377  }
2378
2379/**
2380  fprintf(stdout, "%d %d\n", m->simpDBAssigns, m->simpDBProps);
2381  if(m->stackPos == m->simpDBAssigns || m->simpDBProps > 0)
2382    return;
2383**/
2384/**
2385 **/
2386  limitVars = m->nVars / 100;
2387  if(limitVars == 0) limitVars = 1;
2388  if(m->stackPos - m->preLevelZeroStackPos < limitVars || m->simpDBProps > 0) 
2389    return;
2390 
2391  m->nSimplify++;
2392  sat_remove_satisfied_clauses(m, m->learned);
2393  sat_remove_satisfied_clauses(m, m->clauses);
2394  sat_remove_satisfied_clauses(m, m->blocking);
2395 
2396  sat_heap_remove_var_assigned_level_zero(m, m->variableHeap);
2397
2398  m->preLevelZeroStackPos = m->stackPos;
2399
2400  m->simpDBAssigns = m->stackPos;
2401  m->simpDBProps = m->nCurClauseLits + m->nCurLearnedLits;
2402
2403  m->preJumpCl = m->nTotalLearnedClauses;
2404  m->nJump = 0;
2405  m->nLevel = 0;
2406}
2407
2408void
2409sat_remove_satisfied_clauses(satManager_t *m, satArray_t *arr)
2410{
2411long i, j, k, satisfied;
2412long csize, lit, v;
2413satClause_t *c;
2414
2415  for(i=j=0; i<arr->size; i++) {
2416    c = (satClause_t *)arr->space[i];
2417    satisfied = 0;
2418    csize = SATSizeClause(c);
2419    if(csize == 1)      {
2420      arr->space[j++] = arr->space[i];
2421      continue;
2422    }
2423    for(k=0; k<csize; k++) {
2424      lit = c->lits[k];
2425      v = lit>>1;
2426      if((m->values[v] ^ (lit&1)) == 1) {
2427        satisfied = 1;
2428        break;
2429      }
2430    }
2431
2432    if(satisfied) sat_delete_clause(m, c);
2433    else          arr->space[j++] = arr->space[i];
2434  }
2435  arr->size -= (i-j);
2436/**
2437  fprintf(stdout, "%d simplified\n", i-j);
2438**/
2439}
2440
2441satManager_t *
2442sat_init_manager()
2443{
2444satManager_t *m;
2445
2446   m = (satManager_t *)malloc(sizeof(satManager_t));
2447   memset(m, 0, sizeof(satManager_t));
2448
2449   m->status = 2;
2450   m->nRestarts = 0;
2451   m->nFirstUip = 0;;
2452
2453   m->varDecay = 1.0/0.95;
2454   m->clauseDecay = 1.0/0.999;
2455   m->varInc = 1.0;
2456   m->clauseInc = 1.0;
2457
2458   m->randomSeed = 91648253;
2459   m->randomFrequency = 0.02;
2460
2461#ifdef LUBY_RESTART
2462   m->restartFirst = 256;
2463   m->restartInc = 1;
2464#endif
2465#ifndef LUBY_RESTART
2466   m->restartFirst = 100;
2467   m->restartInc = 1.5;
2468#endif
2469   m->learnedSizeFactor = (double)1/(double)3;
2470   m->learnedSizeInc = 1.1;
2471   m->polarityChangeLimit = 64;
2472
2473   m->simpDBAssigns = -1;
2474   m->simpDBProps = 0;
2475
2476   m->buildBridge = 1;
2477   m->useRandom = 1;
2478   m->defaultSign = 1;
2479   m->polarityMode = 1;
2480   m->preJump = 3;
2481   m->coreGeneration = 0;
2482   m->includeLevelZero = 0;
2483   m->enableSimplify = 1;
2484
2485   m->usePreviousDecisionHistory = 0;
2486   
2487   m->enableAddTheoryClause = 1;
2488   m->enableOptimizeClause = 0;
2489   
2490   if(m->coreGeneration) {
2491     m->includeLevelZero = 1;
2492     m->enableSimplify = 0;
2493   }
2494
2495#ifdef CirCUsCNF
2496   m->allSat = 0;
2497#endif
2498#ifdef CirCUsALLSAT
2499   m->allSat = 1;
2500#endif
2501   m->checkSubsumption = 0;
2502   if (!m->allSat)
2503     m->subsumeInConflict = 1; 
2504   return(m);
2505}
2506
2507
2508void
2509sat_create_database(satManager_t *m)
2510{
2511long nVars;
2512long i;
2513
2514    m->curPos = 0;
2515    m->stackPos = 0;
2516    m->clauses = sat_array_alloc(1024);
2517    m->learned = sat_array_alloc(1024);
2518    m->blocking = sat_array_alloc(1024);
2519    m->theory = sat_array_alloc(1024);
2520    m->deleted = sat_array_alloc(1024);
2521    m->shortClauses = sat_array_alloc(1024);
2522    m->previousDecisionHistory = sat_array_alloc(1024);
2523    m->seen = sat_array_alloc(16);
2524    m->tempUnitClauses = sat_array_alloc(16);
2525
2526    nVars = m->nVars+1;
2527
2528    m->activity = (double *)malloc(sizeof(double)*nVars);
2529    m->values = (char *)malloc(sizeof(char)*nVars);
2530    m->marks = (char *)malloc(sizeof(char)*nVars);
2531    m->visits = (char *)malloc(sizeof(char)*nVars);
2532    m->pure = (char *)malloc(sizeof(char)*nVars);
2533#ifdef CHECK_EQUIVALENCE_RELATION
2534    m->dummy = (char *)malloc(sizeof(char)*nVars);
2535    m->equi = (char *)malloc(sizeof(char)*nVars);
2536    m->maps = (long *)malloc(sizeof(long)*nVars);
2537#endif
2538
2539    m->levels = (long *)malloc(sizeof(long)*nVars);
2540    m->decisionStack = (long *)malloc(sizeof(long)*nVars);
2541    m->antes = (satClause_t **)malloc(sizeof(satClause_t *)*(nVars));
2542     
2543    m->mclaSize = 1024;
2544    m->mcla = (int *)malloc(sizeof(int)*(m->mclaSize));
2545    memset(m->mcla, 0, sizeof(int)*m->mclaSize);
2546
2547
2548    for(i=0; i<nVars; i++) {
2549      m->activity[i] = 0;
2550      m->marks[i] = 0;
2551      m->visits[i] = 0;
2552      m->pure[i] = 0;
2553      m->decisionStack[i] = 0;
2554      m->antes[i] = 0;
2555      m->levels[i] = -1;
2556      m->values[i] = 2; 
2557
2558#ifdef CHECK_EQUIVALENCE_RELATION
2559      m->dummy[i] = 0;
2560      m->equi[i] = 0;
2561      m->maps[i] = 0;
2562#endif
2563    }
2564
2565    m->wls = (satArray_t **)malloc(sizeof(satArray_t *)*(nVars<<1));
2566    for(i=0; i<(nVars<<1); i++) m->wls[i] = 0;
2567
2568    m->decisionStackSeperator = sat_array_alloc(1024);
2569    m->clearned = sat_array_alloc(16);
2570    m->tlearned = sat_array_alloc(16);
2571    m->cclearned = sat_array_alloc(16);
2572    m->redundant = sat_array_alloc(16);
2573    m->dependent = sat_array_alloc(16);
2574    m->temp = sat_array_alloc(16);
2575
2576    m->variableHeap = sat_heap_init(m, sat_compare_activity);
2577
2578#ifdef SATELITE
2579    if(m->checkSubsumption) {
2580      m->subsumptionQueue = sat_queue_alloc(m->nClauses);
2581      m->elimOrderArray = (long *)malloc(sizeof(long)*nVars);
2582      memset(m->elimOrderArray, 0, sizeof(long)*nVars);
2583      m->elimClauses = (satArray_t **)malloc(sizeof(satArray_t*)*nVars);
2584      memset(m->elimClauses, 0, sizeof(satArray_t *)*nVars);
2585      m->occurrence = (satArray_t **)malloc(sizeof(satArray_t*)*(nVars));
2586      memset(m->occurrence, 0, sizeof(satArray_t *)*nVars);
2587    }
2588#endif
2589
2590    m->resolvents = sat_array_alloc(16);
2591    m->satQueue = sat_queue_init(m->nClauses << 2); 
2592    if(m->simplify || m->distill || m->subsumeInConflict) {
2593     
2594      m->clausesHistogram = (long *)malloc(sizeof(long)*13);
2595      for (i = 0; i < 13; i++) m->clausesHistogram[i] = 0;
2596
2597      m->elimtable = sat_array_alloc(4);
2598      m->candidates = sat_array_alloc(16);
2599     
2600      m->litMarks = (char *)malloc(sizeof(char)*(nVars<<1));
2601      m->scores = (long *)malloc(sizeof(long)*(nVars<<1));
2602      for(i=0; i<(nVars<<1); i++) {
2603        m->litMarks[i] = 0;
2604        m->scores[i] = 0;
2605      }
2606
2607      m->equi = (char *)malloc(sizeof(char)*nVars);
2608      m->maps = (long *)malloc(sizeof(long)*nVars);
2609      m->bvars = (char *)malloc(sizeof(char)*nVars);
2610      for(i=0; i<nVars; i++) {
2611        m->equi[i] = 0;
2612        m->maps[i] = 0;
2613        m->bvars[i] = 0;
2614      }
2615      vel_heap_init(m, nVars);
2616    }
2617}
2618
2619void
2620sat_resize_database(satManager_t *m, int numVariables)
2621{
2622long nVars, prenVars;
2623long i;
2624
2625    if(m->nVars > numVariables)  return;
2626
2627    prenVars = m->nVars;
2628    m->nVars = numVariables;
2629    nVars = m->nVars+1;
2630
2631    m->activity = (double *)realloc((double *)m->activity, sizeof(double)*nVars);
2632    m->values = (char *)realloc((char *)m->values, sizeof(char)*nVars);
2633    m->marks = (char *)realloc((char *)m->marks, sizeof(char)*nVars);
2634    m->visits = (char *)realloc((char *)m->visits, sizeof(char)*nVars);
2635    m->pure = (char *)realloc((char *)m->pure, sizeof(char)*nVars);
2636#ifdef CHECK_EQUIVALENCE_RELATION
2637    m->dummy = (char *)realloc((char *)m->dummy, sizeof(char)*nVars);
2638    m->equi = (char *)realloc((char *)m->equi, sizeof(char)*nVars);
2639    m->maps = (long *)realloc((long *)m->maps, sizeof(long)*nVars);
2640#endif
2641
2642    m->levels = (long *)realloc((long *)m->levels, sizeof(long)*nVars);
2643    m->decisionStack = (long *)realloc((long *)m->decisionStack, sizeof(long)*nVars);
2644    m->antes = (satClause_t **)realloc((satClause_t **)m->antes, sizeof(satClause_t *)*(nVars));
2645
2646    for(i=prenVars+1; i<nVars; i++) {
2647      m->activity[i] = 0;
2648      m->marks[i] = 0;
2649      m->visits[i] = 0;
2650      m->pure[i] = 0;
2651      m->decisionStack[i] = 0;
2652      m->antes[i] = 0;
2653      m->levels[i] = -1;
2654      m->values[i] = 2; 
2655#ifdef CHECK_EQUIVALENCE_RELATION
2656      m->dummy[i] = 0;
2657      m->equi[i] = 0;
2658      m->maps[i] = 0;
2659#endif
2660    }
2661
2662    m->wls = (satArray_t **)realloc((satArray_t **)m->wls, sizeof(satArray_t *)*(nVars<<1));
2663    for(i=((prenVars+1)<<1); i<(nVars<<1); i++) m->wls[i] = 0;
2664
2665    sat_heap_resize(m, m->variableHeap, prenVars);
2666}
2667
2668
2669void
2670sat_free_manager(satManager_t *m)
2671{
2672long size, i;
2673satArray_t *arr;
2674
2675  sat_free_clause_array(m->learned);
2676  if(m->learned) free(m->learned);
2677  sat_free_clause_array(m->clauses);
2678  if(m->clauses) free(m->clauses);
2679  sat_free_clause_array(m->blocking);
2680  if(m->blocking) free(m->blocking);
2681  sat_free_clause_array(m->theory);
2682  if(m->theory) free(m->theory);
2683  sat_free_clause_array(m->deleted);
2684  if(m->deleted) free(m->deleted);
2685  if(m->shortClauses) free(m->shortClauses);
2686
2687
2688  sat_heap_free(m->variableHeap);
2689  m->variableHeap = 0;
2690 
2691  if(m->activity)       free(m->activity);
2692  if(m->values)         free(m->values);
2693  if(m->marks)          free(m->marks);
2694  if(m->visits)         free(m->visits);
2695  if(m->dummy)          free(m->dummy);
2696  if(m->equi)           free(m->equi);
2697  if(m->maps)           free(m->maps);
2698  if(m->levels)         free(m->levels);
2699  if(m->decisionStack)  free(m->decisionStack);
2700  if(m->seen)           free(m->seen);
2701
2702  if(m->wls) {
2703    size = m->nVars+1;
2704    size = size<<1;
2705    for(i=0; i<size; i++) {
2706      arr = m->wls[i];
2707      if(arr)   free(arr);
2708    }
2709    free(m->wls);
2710  }
2711
2712  if(m->antes)  free(m->antes);
2713
2714  if(m->decisionStackSeperator) free(m->decisionStackSeperator);
2715  if(m->clearned)       free(m->clearned);
2716  if(m->tlearned)       free(m->tlearned);
2717  if(m->cclearned)      free(m->cclearned);
2718  if(m->redundant)      free(m->redundant);
2719  if(m->dependent)      free(m->dependent);
2720  if(m->pure)           free(m->pure);
2721  if(m->temp)           free(m->temp);
2722  if(m->explanation)    free(m->explanation);
2723  if(m->previousDecisionHistory) free(m->previousDecisionHistory);
2724
2725  if(m->clausesHistogram)       free(m->clausesHistogram); 
2726  vel_heap_free(m);
2727  if(m->satQueue)       sat_queue_free(m->satQueue);
2728  if(m->scores)         free(m->scores);
2729  if(m->candidates)     free(m->candidates);
2730  if(m->resolvents)     free(m->resolvents);
2731  if(m->litMarks)       free(m->litMarks);
2732  if(m->elimtable)      free(m->elimtable);
2733  if(m->bvars)          free(m->bvars); 
2734  free(m);
2735}
2736
2737void
2738sat_free_clause_array(satArray_t *arr)
2739{
2740long i;
2741satClause_t *c;
2742
2743  if(arr) {
2744    for(i=0; i<arr->size; i++) {
2745      c = (satClause_t *)arr->space[i];
2746      if(c->dependent) free(c->dependent);
2747      free(c);
2748    }
2749  }
2750}
2751
2752int
2753sat_read_cnf(satManager_t *m, char *filename)
2754{
2755FILE *fin;       
2756char *gzcmd;
2757
2758char line[LINEBUFSIZE], word[1024], *lp;
2759int nArg, begin, flength;
2760long id, sign, nCl;
2761long i;
2762int nPure;
2763satArray_t *clauseArray;
2764satClause_t *c;
2765
2766  flength = strlen(filename);
2767  if (strcmp(filename+flength-3, ".gz") == 0) {
2768    fprintf(stdout, "Reading compressed CNF file %s ...\n", filename);
2769
2770    gzcmd = (char *)malloc(sizeof(char)*(flength + 6));
2771    strcpy(gzcmd, "zcat ");
2772    strcat(gzcmd, filename);
2773    if(!(fin = popen(gzcmd, "r"))) {
2774      fprintf(stderr, "ERROR : Can't open CNF file %s\n", 
2775            filename);
2776      free(gzcmd);
2777      return(0);
2778    }
2779    free(gzcmd);
2780  }
2781  else if(!(fin = fopen(filename, "r"))) {
2782    fprintf(stderr, "ERROR : Can't open CNF file %s\n", 
2783            filename);
2784    return(0);
2785  } 
2786 
2787  begin = nCl = 0;
2788  clauseArray = sat_array_alloc(1024);
2789 
2790  while(fgets(line, sizeof line, fin)) {
2791    lp = sat_remove_space(line);
2792    if(lp[0] == '\n')   continue;
2793    if(lp[0] == '#')    continue;
2794    if(lp[0] == 'c')    continue;
2795    if(lp[0] == 'p') {
2796      nArg = sscanf(line, "p cnf %ld %ld", &(m->nVars), &(m->nClauses));
2797      if(nArg < 2) {
2798        fprintf(stderr, "ERROR : Unable to read the number of variables and clauses from CNF file %s\n", filename);
2799        pclose(fin);
2800        free(clauseArray);
2801        return(0);
2802      }
2803      begin = 1;
2804
2805      sat_create_database(m);
2806      continue;
2807    }
2808    else if(begin == 0) continue;
2809
2810    clauseArray->size = 0;
2811    while(1) {
2812      lp = sat_remove_space(lp);
2813      lp = sat_copy_word(lp, word);
2814
2815      if(strlen(word)) {
2816        id = atoi(word);
2817        sign = 1;
2818
2819        if(id != 0) {
2820          sign = (id<0) ? 1 : 0;
2821          id = (id<0) ? -id : id;
2822          if(id>m->nVars) {
2823            fprintf(stdout, "ERROR : variable index %d exceed max variable index\n", (int)id);
2824            pclose(fin);
2825            free(clauseArray);
2826            return(0);
2827          }
2828          clauseArray = sat_array_insert(clauseArray, ((id<<1) + sign));
2829        }
2830        else {
2831          c = sat_add_clause(m, clauseArray, 0);
2832          if (m->clauses->size > nCl) {
2833            sat_init_variable_activity(m, c);
2834            nCl++;
2835          }
2836          clauseArray->size = 0;
2837        }
2838      }
2839      else if(fgets(line, LINEBUFSIZE, fin)){
2840        lp = &line[0];
2841        if(lp[0] == '\n')       break;
2842        if(lp[0] == '#')        break;
2843        if(lp[0] == 'c')        break;
2844      }
2845      else {
2846        break;
2847      }
2848    } 
2849  }
2850 
2851  if(begin == 0) {
2852    fprintf(stderr, "c ERROR : Can't read CNF file %s\n", filename);
2853    free(clauseArray);
2854    return(0);
2855  }
2856
2857  if(m->nClauses != nCl) {
2858    fprintf(stdout, "WARNING : wrong number of clauses %d(%d)\n", (int)m->nClauses, (int)nCl);
2859  }
2860 
2861  nPure = 0;
2862  if(!m->allSat) {
2863    for(i=1; i<=m->nVars; i++) {
2864      if(m->pure[i] == 1) {
2865        sat_enqueue_check(m, i<<1, 0);
2866        nPure++;
2867      }
2868      else if(m->pure[i] == 2) {
2869        sat_enqueue_check(m, (i<<1)+1, 0);
2870        nPure++;
2871      }
2872    }
2873  }
2874
2875
2876  pclose(fin);
2877  free(clauseArray);
2878
2879  return(1);
2880}
2881
2882void
2883sat_init_variable_activity(satManager_t *m, satClause_t *c)
2884{
2885long csize, i, lit;
2886
2887  if(c == 0)    return;
2888  csize = SATSizeClause(c);
2889  for(i=0; i<csize; i++) {
2890    lit = c->lits[i];
2891    m->activity[lit>>1] += 1.0/(double)csize;
2892  }
2893}
2894satClause_t *
2895sat_add_learned_clause(satManager_t *m, satArray_t *learned)
2896{
2897satClause_t *c;
2898
2899  if(learned->size == 1) {
2900/**
2901    c = sat_new_clause(learned, 1);
2902    m->learned = sat_array_insert(m->learned, (long)c);
2903    sat_enqueue_check(m, learned->space[0], c);
2904    m->nCurLearnedLits ++; m->nCurLearnedClauses++;
2905    m->nTotalLearnedLits ++; m->nTotalLearnedClauses++;
2906**/
2907    c = sat_add_clause(m, learned, 0);
2908  }
2909  else {
2910    c = sat_new_clause(learned, 1);
2911    m->learned = sat_array_insert(m->learned, (long)c);
2912    sat_add_watched_literal(m, c);
2913    sat_update_clause_activity(m, c);
2914    sat_enqueue_check(m, learned->space[0], c);
2915  }
2916  return(c);
2917}
2918
2919satClause_t *
2920sat_add_clause(satManager_t *m, satArray_t *arr, long learned)
2921{
2922long lit, v; 
2923int csize, i;
2924satClause_t *c;
2925
2926  if(arr->size == 1) {
2927    lit = arr->space[0];
2928    if(learned == 1) {
2929      m->nCurLearnedLits ++; m->nCurLearnedClauses++;
2930      m->nTotalLearnedLits ++; m->nTotalLearnedClauses++;
2931      learned = 0;
2932    }
2933    else if(learned == 0) {
2934      m->nCurClauseLits ++;
2935      m->nTotalClauseLits ++; 
2936    }
2937 
2938    c = sat_new_clause(arr, learned); /* original clause */
2939    sat_mark_for_pure_lits(m, c);
2940    if(learned) 
2941      m->learned = sat_array_insert(m->learned, (long)c);
2942    else 
2943      m->clauses = sat_array_insert(m->clauses, (long)c);
2944    sat_enqueue_check(m, lit, c);
2945  }
2946  else {
2947    c = sat_new_clause(arr, learned); /* original clause */
2948    sat_sort_clause_literal(c); 
2949    if (sat_compress_clause(m, c)) {
2950      free(c);
2951      return 0;
2952    } 
2953    sat_mark_for_pure_lits(m, c);
2954    if(learned)
2955      m->learned = sat_array_insert(m->learned, (long)c);
2956    else 
2957      m->clauses = sat_array_insert(m->clauses, (long)c);
2958    sat_add_watched_literal(m, c);
2959  }
2960
2961#ifdef SATELITE
2962  if(m->checkSubsumption && learned == 0) {
2963    sat_queue_insert(m->subsumptionQueue, (long)c);
2964    csize = SATSizeClause(c);
2965    for(i=0; i<csize; i++) {
2966      lit = c->lits[i];
2967      v = lit>>1;
2968      m->occurrence[v] = sat_array_insert(m->occurrence[v], (long)c);
2969      m->nOccurrence[lit]++;
2970      m->visits[v] = 1;
2971
2972      /** What is this for ? HOONSANG **/
2973      if(m->eliminateHeap->indices[v] > 0)
2974        sat_heap_up(m, m->eliminateHeap, m->eliminateHeap->indices[v]);
2975    }
2976  }
2977#endif
2978
2979  if (m->simplify && learned == 0) {
2980    sat_queue_insert(m->satQueue, (long)c);
2981    sat_add_all_watched_literal(m, c);
2982    sat_update_clauses_statistics(m, c);
2983    csize = SATSizeClause(c);
2984    m->nLits += SATSizeClause(c);
2985    for(i=0; i<csize; i++) {
2986      lit = c->lits[i];
2987      v = lit >> 1;
2988
2989      /** restricted to boolean variables
2990       ** given by Sateen
2991       */
2992      if (m->allSat == 1 && m->bvars[v] == 0) 
2993        continue;
2994
2995      if(m->varElimHeap->indices[v] >= 0)
2996        vel_heap_down(m, m->varElimHeap->indices[v]);
2997      else 
2998        vel_heap_insert(m, v);
2999    }
3000  }
3001
3002  if(arr->size > 1)
3003    return(c);
3004  else
3005    return(0);
3006}
3007
3008/**
3009 *  if value of pure is 0 then no occurence of variable
3010 *     value of pureis 1 then it is positive pure literal
3011 *     value of pureis 2 then it is negative pure literal
3012 *     value of pureis 3 then it is not pure literal
3013 **/
3014void
3015sat_mark_for_pure_lits(satManager_t *m, satClause_t *c)
3016{
3017long csize, i;
3018long lit, sign, v, value;
3019
3020  csize = SATSizeClause(c);
3021  for(i=0; i<csize; i++) {
3022    lit = c->lits[i];
3023    sign = lit&1;
3024    v = lit>>1;
3025    value = (sign == 0) ? 1 : 2;
3026    m->pure[v] |= value;
3027  }
3028}
3029
3030
3031satClause_t *
3032sat_add_clause_only(satManager_t *m, satArray_t *arr, long learned)
3033{
3034long lit, iLit, pLit;
3035long i, j;
3036satClause_t *c;
3037
3038  sat_literal_array_sort(arr);
3039  pLit = 0;
3040  for(i=j=0; i<arr->size; i++) {
3041    lit = arr->space[i];
3042    iLit = (pLit ^ 1);
3043    if(lit == iLit) /* trivially satisfied */
3044      return(0);
3045    else if(((m->values[lit>>1]) ^ (SATSign(lit))) != 0 && lit != pLit) {
3046      pLit = lit;
3047      arr->space[j++] = pLit;
3048    }
3049  }
3050  arr->size -= (i-j);
3051
3052  if(arr->size == 1) {
3053    lit = arr->space[0];
3054    sat_enqueue(m, lit, 0);
3055    return(0);
3056  }
3057  else {
3058    c = sat_new_clause(arr, learned); /* original clause */
3059    sat_add_watched_literal(m, c);
3060    return(c);
3061  }
3062}
3063
3064void
3065sat_print_variables(satManager_t *m)
3066{
3067long i;
3068
3069  for(i=0; i<=m->nVars; i++) {
3070    fprintf(stdout, "%d(%d)(%10g)\n", (int)i, (int)m->values[i], m->activity[i]);
3071  }
3072}
3073
3074void
3075sat_print_clauses(satManager_t *m, satArray_t *learned)
3076{
3077satClause_t *c;
3078int i;
3079
3080  for(i=0; i<learned->size; i++) {
3081    c = (satClause_t *)learned->space[i];
3082    fprintf(stdout, "%f ", c->info.activity);
3083    sat_print_clause_simple(m, c);
3084    fprintf(stdout, "\n");
3085  }
3086}
3087
3088void
3089sat_delete_clause(satManager_t *m, satClause_t *c)
3090{
3091  /**
3092  fprintf(stdout, "%f ", c->info.activity);
3093  sat_print_clause_simple(m, c);
3094  fprintf(stdout, "\n");
3095  **/
3096
3097  sat_delete_watched_literal(m, c);
3098  if(c->dependent)
3099    free(c->dependent);
3100  free(c);
3101}
3102
3103void
3104sat_delete_watched_literal(satManager_t *m, satClause_t *c)
3105{
3106long index, learned, size;
3107
3108  index = (c->lits[0])^1;
3109  if (m->wls[index] && m->wls[index]->size)
3110    sat_array_delete_elem(m->wls[index], (long)c);
3111
3112  index = (c->lits[1])^1;
3113  if (m->wls[index] && m->wls[index]->size)
3114    sat_array_delete_elem(m->wls[index], (long)c);
3115
3116  learned = c->size & 1;
3117  size = SATSizeClause(c);
3118  if(learned)   {
3119    m->nCurLearnedLits -= size;
3120    m->nCurLearnedClauses--;
3121  }
3122  else          m->nCurClauseLits -= size;
3123}
3124
3125void
3126sat_add_watched_literal(satManager_t *m, satClause_t *c)
3127{
3128long index, learned, size;
3129satArray_t *arr;
3130
3131  index = (c->lits[0])^1;
3132  arr = m->wls[index];
3133  m->wls[index] = sat_array_alloc_insert(arr, (long)c);
3134
3135  index = (c->lits[1])^1;
3136  arr = m->wls[index];
3137  m->wls[index] = sat_array_alloc_insert(arr, (long)c);
3138
3139  learned = c->size & 1;
3140  size = SATSizeClause(c);
3141
3142  if(learned)   {
3143    m->nCurLearnedLits += size;
3144    m->nCurLearnedClauses++;
3145    m->nTotalLearnedLits += size;
3146    m->nTotalLearnedClauses++;
3147  }
3148  else {
3149    m->nCurClauseLits += size;
3150    m->nTotalClauseLits += size;
3151  }
3152}
3153
3154satClause_t *
3155sat_new_clause(satArray_t *arr, long learned)
3156{
3157satClause_t *c;
3158int i;
3159long abstract;
3160
3161  c = (satClause_t *)malloc(sizeof(satClause_t) + sizeof(long)*arr->size);
3162  c->size = (arr->size << SATCsizeShift) | learned;
3163  for(i=0; i<arr->size; i++)    {
3164    assert(arr->space[i] != 0);
3165    c->lits[i] = arr->space[i];
3166  }
3167  c->info.activity = 0;
3168  if(learned == 0) {
3169    abstract = 0;
3170    for(i=0; i<arr->size; i++)
3171      abstract |= 1 << (SATVar(arr->space[i]) & 31);
3172    c->info.abstract = abstract;
3173  }
3174  c->dependent = 0;
3175  return(c);
3176}
3177
3178/** Seperate sat_enqueue and sat_enqueue_check **/
3179void
3180sat_enqueue(satManager_t *m, long lit, satClause_t *ante)
3181{ 
3182long var;
3183 
3184  assert(lit>1);
3185  var = SATVar(lit);
3186  m->values[var] = (char)(!SATSign(lit));
3187  m->levels[var] = SATCurLevel(m);
3188  m->antes[var] = ante;
3189  m->decisionStack[m->stackPos++] = lit;
3190}
3191
3192void
3193sat_enqueue_check(satManager_t *m, long lit, satClause_t *ante)
3194{ 
3195long var;
3196 
3197  assert(lit>1);
3198  var = SATVar(lit);
3199  if(m->values[var] == 2)       {
3200    m->values[var] = (char)(!SATSign(lit));
3201    m->levels[var] = SATCurLevel(m);
3202    m->antes[var] = ante;
3203    m->decisionStack[m->stackPos++] = lit;
3204  }
3205  else {
3206    if(m->values[var] != (char)(!SATSign(lit))) {
3207      m->status = 0;
3208    }
3209  }
3210}
3211
3212char *
3213sat_copy_word(char *lp, char *word)
3214{
3215char *wp;
3216
3217  for(wp = word; ; lp++, wp++) {
3218    if((*lp == ' ') || (*lp == '\t') || (*lp == '\n'))  break;
3219    *wp = *lp;
3220  }
3221  *wp = '\0';
3222  return(lp);
3223}
3224
3225char *
3226sat_remove_space(char *line)
3227{
3228int i;
3229
3230  for(i=0; ; i++) {
3231    if(line[i] == ' ')          continue;
3232    else if(line[i] == '\t')    continue;
3233    return(&(line[i]));
3234  }
3235}
3236
3237void
3238sat_update_variable_activity(satManager_t *m, long v)
3239{
3240long  i;
3241
3242  if((m->activity[v] += m->varInc) > 1e100) {
3243    for(i=0; i<=m->nVars; i++)
3244      m->activity[i] *= 1e-100;
3245    m->varInc *= 1e-100;
3246  }
3247
3248  if(m->variableHeap->indices[v] > 0)
3249    sat_heap_up(m, m->variableHeap, m->variableHeap->indices[v]);
3250}
3251
3252void
3253sat_update_clause_activity(satManager_t *m, satClause_t *c)
3254{
3255long  i;
3256satArray_t *learned;
3257
3258  learned = 0;
3259  if((c->info.activity += m->clauseInc) > 1e20) {
3260    if(c->size&SATCLearned)     learned = m->learned;
3261    else if(c->size&SATCBlocking)learned = m->blocking;
3262    else if(c->size&SATCTheory) learned = m->theory;
3263    for(i=0; i<learned->size; i++) {
3264      c = (satClause_t *)learned->space[i];
3265      c->info.activity *= 1e-20;
3266    }
3267    m->clauseInc *= 1e-20;
3268  }
3269}
3270void
3271sat_update_variable_decay(satManager_t *m)
3272{
3273  m->varInc *= m->varDecay;
3274}
3275
3276void
3277sat_update_clause_decay(satManager_t *m)
3278{
3279  m->clauseInc *= m->clauseDecay;
3280}
3281
3282char *
3283DateReadFromDateString(
3284  char * datestr)
3285{
3286  static char result[25];
3287  char        day[10];
3288  char        month[10];
3289  char        zone[10];
3290  char       *at;
3291  int         date;
3292  int         hour;
3293  int         minute;
3294  int         second;
3295  int         year;
3296
3297  if (sscanf(datestr, "%s %s %2d %2d:%2d:%2d %s %4d",
3298             day, month, &date, &hour, &minute, &second, zone, &year) == 8) {
3299    if (hour >= 12) {
3300      if (hour >= 13) hour -= 12;
3301      at = "PM";
3302    }
3303    else {
3304      if (hour == 0) hour = 12;
3305      at = "AM";
3306    }
3307    (void) sprintf(result, "%d-%3s-%02d at %d:%02d %s", 
3308                   date, month, year % 100, hour, minute, at);
3309    return result;
3310  }
3311  else {
3312    return datestr;
3313  }
3314}
3315
3316/**Function********************************************************************
3317
3318  Synopsis    [ Reports memory usage ]
3319
3320  Description [ Reports memory usage ]
3321
3322  SideEffects [ ]
3323
3324  SeeAlso     [ ]
3325
3326******************************************************************************/
3327long
3328sat_mem_used(int field)
3329{
3330char name[256];
3331FILE *in;
3332pid_t pid;
3333long value;
3334
3335  pid = getpid();
3336  sprintf(name, "/proc/%d/statm", pid);
3337  in = fopen(name, "rb");
3338  if (in == 0)  return 0;
3339
3340  for ( ; field >= 0; field--)
3341    if (fscanf(in, "%ld", &value) != 1) {
3342      fprintf(stderr, "Can't get MEM usage!\n");
3343      return 0;
3344    } 
3345  fclose(in);
3346
3347  value *= getpagesize();
3348  return value;
3349}
3350
3351
3352void
3353sat_verify(satManager_t *m)
3354{
3355long i, j, csize, lit;
3356satArray_t *clauses;
3357satClause_t *c;
3358int satisfied;
3359
3360  clauses = m->clauses;
3361  for(i=0; i<clauses->size; i++) {
3362    c = (satClause_t *)clauses->space[i];
3363    csize = SATSizeClause(c);
3364    satisfied = 0;
3365    for(j=0; j<csize; j++) {
3366      lit = c->lits[j];
3367      if((m->values[lit>>1] ^ (lit&1)) == 1) {
3368        satisfied = 1;
3369        break;
3370      }
3371    }
3372    if(satisfied == 0) {
3373      fprintf(stdout, "ERROR : unsatisfied claues\n");
3374      sat_print_clause(m, c);
3375      fprintf(stdout, "\n");
3376    }
3377  }
3378
3379  clauses = m->deleted;
3380  for(i=0; i<clauses->size; i++) {
3381    c = (satClause_t *)clauses->space[i];
3382    csize = SATSizeClause(c);
3383    satisfied = 0;
3384    for(j=0; j<csize; j++) {
3385      lit = c->lits[j];
3386      if((m->values[lit>>1] ^ (lit&1)) == 1) {
3387        satisfied = 1;
3388        break;
3389      }
3390    }
3391    if(satisfied == 0) {
3392      fprintf(stdout, "ERROR : unsatisfied claues\n");
3393      sat_print_clause(m, c);
3394      fprintf(stdout, "\n");
3395    }
3396  } 
3397}
3398
3399void
3400sat_print_database(satManager_t *m)
3401{
3402long i;
3403satClause_t *c;
3404satArray_t *arr;
3405
3406  fprintf(stdout, "==========================\n");
3407  fprintf(stdout, " Current CNF Clauses\n");
3408  fprintf(stdout, "==========================\n");
3409
3410  arr = m->clauses;
3411  for(i=0; i<arr->size; i++) {
3412    c = (satClause_t *)arr->space[i];
3413    sat_print_clause(m, c);
3414    fprintf(stdout, "\n");
3415  }
3416
3417  arr = m->learned;
3418  for(i=0; i<arr->size; i++) {
3419    c = (satClause_t *)arr->space[i];
3420    sat_print_clause(m, c);
3421    fprintf(stdout, "\n");
3422  }
3423
3424  fprintf(stdout, "\n");
3425}
3426
3427void
3428sat_print_clause(satManager_t *m, satClause_t *c)
3429{
3430long i, csize, lit;
3431 
3432  csize = SATSizeClause(c);
3433  fprintf(stdout, "%d %f (", (int) c->size&SATCTypeMask, c->info.activity);
3434  for(i=0; i<csize; i++) {
3435    lit = c->lits[i];
3436    sat_print_literal(m, lit, 0);
3437    fprintf(stdout, " ");
3438    if(i!=0 && (i%10)==0)
3439      fprintf(stdout, "\n");
3440  }
3441  fprintf(stdout, ")");
3442  fflush(stdout);
3443}
3444
3445void
3446sat_print_clause_array(satManager_t *m, satArray_t *learned)
3447{
3448long i, lit;
3449 
3450  for(i=0; i<learned->size; i++) {
3451    lit = learned->space[i];
3452    sat_print_literal(m, lit, 0);
3453    fprintf(stdout, " ");
3454    if(i!=0 && (i%10)==0)
3455      fprintf(stdout, "\n");
3456  }
3457  fprintf(stdout, ")");
3458  fflush(stdout);
3459}
3460
3461void
3462sat_print_short_clause(satManager_t *m, satClause_t *c, FILE *fp)
3463{
3464long i, csize, lit;
3465
3466  if(fp == 0)   fp = stdout;
3467  csize = SATSizeClause(c);
3468  fprintf(fp, "%d %f (", (int) c->size&SATCTypeMask, c->info.activity);
3469  for(i=0; i<csize; i++) {
3470    lit = c->lits[i];
3471    sat_print_literal(m, lit, fp);
3472    fprintf(fp, " ");
3473    if(i!=0 && (i%10)==0)
3474      fprintf(fp, "\n");
3475  }
3476  fprintf(fp, ")");
3477  fflush(fp);
3478}
3479
3480void
3481sat_print_clause_simple(satManager_t *m, satClause_t *c)
3482{
3483long i, csize, lit;
3484long v;
3485 
3486  csize = SATSizeClause(c);
3487  for(i=0; i<csize; i++) {
3488    lit = c->lits[i];
3489    v = lit>>1;
3490    fprintf(stdout, "%c%d:%c", 
3491                   lit&1 ? '-' : ' ',
3492                   (int)v,
3493                   m->values[v]==1 ? '1' : (m->values[v]==0 ? '0' : 'x'));
3494    fprintf(stdout, " ");
3495  }
3496  fflush(stdout);
3497}
3498
3499void
3500sat_print_literal(satManager_t *m, long lit, FILE *fp)
3501{
3502long v;
3503 
3504  if(fp == 0)   fp = stdout;
3505  v = lit>>1;
3506  fprintf(fp, "%c%d:%c@%d", 
3507                   lit&1 ? '-' : ' ',
3508                   (int)v,
3509                   m->values[v]==1 ? '1' : (m->values[v]==0 ? '0' : 'x'),
3510                   (int)m->levels[v]);
3511  fflush(fp);
3512}
3513
3514void
3515sat_report_result(satManager_t *m)
3516{
3517double nConflicts;
3518
3519  if(m == 0)    return;
3520
3521  fprintf(stdout, "CNF read time  : %10g \n", m->readTime);
3522  fprintf(stdout, "CNF solve time : %10g \n", m->solveTime);
3523  fprintf(stdout, "Memory usage : %10g MB\n", sat_mem_used(0)/1048576.0);
3524  fprintf(stdout, "Restart : %ld\n", m->nRestarts);
3525  fprintf(stdout, "Decisions : random(%0.f), heuristic(%0.f), history(%0.f/%0.f)\n", 
3526          m->nRandomDecisions, m->nDecisions,
3527          m->nHistoryDecisions, m->nTHistoryDecisions
3528          );
3529  fprintf(stdout, "Implications : %0.f\n", m->nImplications); 
3530  fprintf(stdout, "Forced Restart : %0.f\n", m->nForceRestart); 
3531  fprintf(stdout, "Polarity Change : %0.f\n", m->nPolarityChange); 
3532  fprintf(stdout, "Learned clasues  : %0.f out of %0.f\n", 
3533          m->nCurLearnedClauses, m->nTotalLearnedClauses);
3534  fprintf(stdout, "Learned literals : %0.f out of %0.f\n", 
3535          m->nCurLearnedLits, m->nTotalLearnedLits);
3536  if(m->allSat) {
3537    fprintf(stdout, "Blocking clasues  : %0.f out of %0.f\n", 
3538          m->nCurBlockingClauses, m->nTotalBlockingClauses);
3539    fprintf(stdout, "Blocking literals : %0.f out of %0.f\n", 
3540          m->nCurBlockingLits, m->nTotalBlockingLits);
3541  }
3542  fprintf(stdout, "Number of first UIP : %ld out of %0.f\n", 
3543          m->nFirstUip, m->nTotalLearnedClauses);
3544  fprintf(stdout, "Number of simplify : %d\n", m->nSimplify); 
3545  nConflicts = m->nTotalLearnedClauses + m->nOmittedConflictClauses;
3546 
3547  fprintf(stdout, "Number of conflicts : %ld\n", (long)nConflicts); 
3548  if (m->nTotalLearnedClauses > 0) {
3549    fprintf(stdout, "Resolution steps per conflict : %ld\n", (long)(m->depthOfConflict /m->nConflicts)); 
3550    if (m->nDistillInConflict)
3551      fprintf(stdout, "Resolution steps per OCI: %ld\n", (long)m->depthOfOTS/m->nDistillInConflict); 
3552    if (m->nAuxConflictAnalysis)
3553      fprintf(stdout, "Resolution steps per additional conflict: %ld\n", (long)m->depthOfStrong/m->nAuxConflictAnalysis); 
3554   }
3555    fprintf(stdout, "Strengthened clauses due to OCI: %ld\n", m->nDistillInConflict);
3556    fprintf(stdout, "Eliminated clasues due to OCI: %ld\n", m->nEliminatedClsInConflict);
3557    fprintf(stdout, "Eliminated literals due to OCI: %ld\n", m->nEliminatedLitsInConflict);
3558    fprintf(stdout, "Saved conflict clasues: %ld\n", m->nOmittedConflictClauses);
3559    fprintf(stdout, "Saved conflict literals: %ld\n", m->nOmittedConflictLits);
3560    fprintf(stdout, "Additional conflict clauses: %ld\n", m->nAuxLearnedClauses);
3561    fprintf(stdout, "Additional conflict literals: %ld\n", m->nAuxLearnedLits);
3562    fprintf(stdout, "Additional conflict analysis: %ld\n", m->nAuxConflictAnalysis);
3563
3564  if (m->allSat == 0) {
3565    if(m->status == 0) fprintf(stdout, "UNSATISFIABLE\n");
3566    else if(m->status == 1) {
3567      fprintf(stdout, "SATISFIABLE\n");
3568      if (m->printModel)
3569        sat_print_assignment(m);
3570    }
3571  }
3572}
3573
3574void 
3575sat_print_assignment(satManager_t *m)
3576{
3577int value;
3578long i;
3579
3580  fprintf(stdout, "v ");       
3581  for(i=1; i<=m->nVars; i++) {
3582    value = m->values[i];
3583    if (value >= 2)
3584      fprintf(stdout, "c WARNING : No assignment on %d!\n", (int)i);
3585    else
3586      fprintf(stdout, "%c%ld ", value ? ' ':'-', i);
3587
3588    if (i % 10 == 0) {
3589      fprintf(stdout, "\nv "); 
3590    }       
3591  }
3592  fprintf(stdout, "0 \n");     
3593}
3594
3595void
3596sat_print_implication_graph(satManager_t *m, long level)
3597{
3598satArray_t *seperator;
3599satClause_t *ante;
3600long *stack;
3601long bi, ei, lit, v, i;
3602
3603  seperator = m->decisionStackSeperator;
3604  stack = m->decisionStack;
3605  if(seperator->size < level) {
3606    fprintf(stdout, "ERROR : level %d has been assigned\n", (int)level);
3607    return;
3608  }
3609
3610  if(level == 0)bi = 0;
3611  else          bi = seperator->space[level-1];
3612  ei = (seperator->size==level) ? m->stackPos : seperator->space[level];
3613 
3614  lit = stack[bi];
3615  v = lit>>1;
3616  fprintf(stdout, "++++++++++++++++++++++++++++++++\n");
3617  fprintf(stdout, "* Level %d ", (int)level); 
3618  sat_print_literal(m, v<<1, 0);
3619  fprintf(stdout, "\n");
3620  fprintf(stdout, "++++++++++++++++++++++++++++++++\n");
3621
3622  for(i=bi+1; i<ei; i++) {
3623    lit = stack[i];
3624    v = lit>>1;
3625    ante = m->antes[v];
3626    sat_print_literal(m, v<<1, 0);
3627    fprintf(stdout, "<= ");
3628    if(ante->size & SATCTheory) 
3629      fprintf(stdout, "THEORY ");
3630    if(ante)
3631      sat_print_clause(m, ante);
3632    else
3633      fprintf(stdout, "NO ANTECEDENT\n");
3634
3635    fprintf(stdout, "\n");
3636  }
3637  fflush(stdout);
3638}
3639
3640void
3641sat_print_short_implication_graph(satManager_t *m, long level)
3642{
3643satArray_t *seperator;
3644satClause_t *ante;
3645long *stack;
3646long bi, ei, lit, v, i;
3647char name[1024];
3648FILE *fp;
3649
3650  seperator = m->decisionStackSeperator;
3651  stack = m->decisionStack;
3652  if(seperator->size < level) {
3653    fprintf(stdout, "ERROR : level %d has been assigned\n", (int)level);
3654    return;
3655  }
3656
3657  bi = seperator->space[level-1];
3658  ei = (seperator->size==level) ? m->stackPos : seperator->space[level];
3659
3660 
3661  lit = stack[bi];
3662  v = lit>>1;
3663
3664  sprintf(name, "%d_%d_%d.txt", (int)level, (int)v, (int)m->nDecisions);
3665  fp = fopen(name, "w");
3666 
3667
3668  fprintf(fp, "++++++++++++++++++++++++++++++++\n");
3669  fprintf(fp, "* Level %d ", (int)level); 
3670  sat_print_literal(m, v<<1, fp);
3671  fprintf(fp, "\n");
3672  fprintf(fp, "++++++++++++++++++++++++++++++++\n");
3673
3674  for(i=bi+1; i<ei; i++) {
3675    lit = stack[i];
3676    v = lit>>1;
3677    ante = m->antes[v];
3678    sat_print_literal(m, v<<1, fp);
3679    fprintf(fp, "<= ");
3680    if(ante) {
3681      if(ante->size & SATCTheory) 
3682        fprintf(fp, "THEORY ");
3683      sat_print_short_clause(m, ante, fp);
3684    }
3685    else {
3686      fprintf(fp, "ERROR: no antecedent ");
3687    }
3688
3689    fprintf(fp, "\n");
3690  }
3691  fflush(fp);
3692  fclose(fp);
3693}
3694
3695void
3696sat_print_dot_for_implication_graph(
3697        satManager_t *m,
3698        satClause_t *c,
3699        long level,
3700        int iAllLevel)
3701{
3702char name[1024];
3703FILE *fp;
3704satArray_t *seperator;
3705satClause_t *ante;
3706long *stack;
3707long bi, ei, lit, v, i, j;
3708long nlit, nv;
3709long visit, csize;
3710int blueColor;
3711
3712  blueColor = 0;
3713  visit = 0;
3714  if(c) {
3715    visit = 1;
3716    csize = SATSizeClause(c);
3717    for(i=0; i<csize; i++) {
3718      lit = c->lits[i];
3719      v = lit>>1;
3720      if(m->levels[v] == level) {
3721        m->visits[v] = visit;
3722      }
3723    }
3724  }
3725
3726  seperator = m->decisionStackSeperator;
3727  stack = m->decisionStack;
3728  if(seperator->size < level) {
3729    fprintf(stdout, "ERROR : level %d has been assigned\n", (int)level);
3730    return;
3731  }
3732
3733  bi = seperator->space[level-1];
3734  ei = (seperator->size==level) ? m->stackPos : seperator->space[level];
3735  lit = stack[bi];
3736  v = lit>>1;
3737  sprintf(name, "%d_%d_%d_%d.dot", (int)level, (int)v, (int)m->nDecisions, iAllLevel);
3738  fp = fopen(name, "w");
3739  fprintf(fp, "digraph \"AndInv\" {\n  rotate=90;\n");
3740  fprintf(fp, "  margin=0.5;\n  label=\"AndInv\";\n");
3741  fprintf(fp, "  size=\"10,7.5\";\n  ratio=\"fill\";\n");
3742
3743  bi++;
3744  for(i=ei-1; i>=bi; i--) {
3745    lit = stack[i];
3746    v = lit>>1;
3747    if(m->visits[v] != visit)   continue;
3748
3749    ante = m->antes[v];
3750
3751    if(ante->size & SATCTheory) {
3752      blueColor = 1;
3753    }
3754
3755    csize = SATSizeClause(ante);
3756    for(j=0; j<csize; j++) {
3757      nlit = ante->lits[j];
3758      nv = nlit>>1;
3759
3760      if(nv == v) continue;
3761       
3762      if(m->levels[nv] == level) {
3763        m->visits[nv] = visit;
3764        if(blueColor) {
3765          fprintf(fp,"%d -> %d [color = blue];\n", (int)nv, (int)v);
3766          blueColor = 0;
3767        }
3768        else
3769          fprintf(fp,"%d -> %d [color = red];\n", (int)nv, (int)v);
3770      }
3771      else if(iAllLevel)
3772        fprintf(fp,"%d.%d -> %d [color = black];\n", (int)nv, (int)m->levels[nv], (int)v);
3773
3774    }
3775  }
3776  fprintf(fp, "}\n");
3777  fclose(fp);
3778
3779  if(visit) {
3780    for(i=ei-1; i>=bi; i--) {
3781      v = (stack[i]>>1);
3782      m->visits[v] = 0;
3783    }
3784  }
3785
3786}
3787
3788void
3789sat_print_cnf(satManager_t *m, long iter)
3790{
3791long nCl, i;
3792char filename[1024];
3793FILE *fp;
3794satArray_t *arr;
3795/*satClause_t *c; HK */
3796
3797  arr = m->clauses;
3798  nCl = 0;
3799  for(i=0; i<arr->size; i++) {
3800    /*c = (satClause_t *)arr->space[i]; HK */
3801    nCl++;
3802  }
3803  arr = m->learned;
3804  for(i=0; i<arr->size; i++) {
3805    /* c = (satClause_t *)arr->space[i]; HK */
3806    nCl++;
3807  }
3808
3809  sprintf(filename, "tmp%d.cnf", (int)iter);
3810  fp = fopen(filename, "w");
3811  fprintf(fp, "p cnf %d %d\n", (int)m->nVars, (int)nCl);
3812  sat_print_clause_in_dimacs(fp, m->clauses);
3813  sat_print_clause_in_dimacs(fp, m->learned);
3814
3815  fclose(fp);
3816}
3817
3818void
3819sat_print_clause_in_dimacs(FILE *fp, satArray_t *arr)
3820{
3821long i, j, v, lit, csize;
3822satClause_t *c;
3823
3824  for(i=0; i<arr->size; i++) {
3825    c = (satClause_t *)arr->space[i];
3826    csize = SATSizeClause(c);
3827    for(j=0; j<csize; j++) {
3828      lit = c->lits[j];
3829      v = lit>>1;
3830      v = lit&1 ? -v : v;
3831      fprintf(fp, "%d ", (int)v);
3832    }
3833    fprintf(fp, "0\n");
3834  }
3835}
3836
3837void
3838sat_print_cnf_less_than(FILE *fp, satArray_t *arr, long limit)
3839{
3840long i, j, v, lit, csize;
3841satClause_t *c;
3842
3843  for(i=0; i<arr->size; i++) {
3844    c = (satClause_t *)arr->space[i];
3845    csize = SATSizeClause(c);
3846    if(csize < limit)   {
3847      for(j=0; j<csize; j++) {
3848        lit = c->lits[j];
3849        v = lit>>1;
3850        v = lit&1 ? -v : v;
3851        fprintf(fp, "%d ", (int)v);
3852      }
3853      fprintf(fp, "0\n");
3854    }
3855  }
3856}
3857
3858void
3859sat_make_dependent_graph(satManager_t *m, satClause_t *c)
3860{
3861#if 0 
3862  if(c->dependent && c->dependent->size > 0) {
3863    fprintf(stdout, "ERROR\n");
3864  }
3865#endif
3866  c->dependent = sat_array_copy(m->dependent, 0);
3867}
3868
3869void
3870sat_get_dependent_clauses(satManager_t *m, satClause_t *c)
3871{
3872long csize, i;
3873long *pLit, cLit, v;
3874satClause_t *ante;
3875
3876  csize = SATSizeClause(c);
3877  pLit = &(c->lits[0]);
3878  for(i=0; i<csize; i++) {
3879    cLit = *pLit++;
3880    v = cLit >> 1;
3881    ante = m->antes[v];
3882
3883    if(ante->size & SATCVisited)        continue;
3884    ante->size = ante->size | SATCVisited;
3885    m->dependent = sat_array_insert(m->dependent, (long)ante);
3886    sat_get_dependent_clauses(m, ante);
3887  }
3888 
3889}
3890
3891void
3892sat_generate_unsat_core_main(satManager_t *m)
3893{
3894satArray_t *dependent; /*, *arr; */
3895satClause_t *c, *conflicting;
3896long i; /*, j, lit, tv, nMarks */
3897/* long pSize, cLit, *pLit, v, csize; */
3898
3899 
3900/**
3901  conflicting = m->nullClause;
3902  m->dependent->size = 0;
3903  conflicting->size = conflicting->size | SATCVisited;
3904  m->dependent = sat_array_insert(m->dependent, (long)conflicting);
3905  sat_get_dependent_clauses(m, conflicting);
3906  dependent = m->dependent;
3907  for(i=0; i<dependent->size; i++) {
3908    c = (satClause_t *)dependent->space[i];
3909    c->size = c->size - SATCVisited;
3910  }
3911  sat_undo(m, -1);
3912  arr = m->clauses;
3913  for(i=0; i<arr->size; i++) {
3914    c = (satClause_t *)arr->space[i];
3915    csize = SATSizeClause(c);
3916    if(csize == 1) {
3917      sat_enqueue(m, c->lits[0], c);
3918    }
3919  }
3920  arr = m->learned;
3921  for(i=0; i<arr->size; i++) {
3922    c = (satClause_t *)arr->space[i];
3923    csize = SATSizeClause(c);
3924    if(csize == 1) {
3925      sat_enqueue(m, c->lits[0], c);
3926    }
3927  }
3928  m->nullClause = sat_implication(m);
3929  m->decisionStackSeperator =
3930          sat_array_insert(m->decisionStackSeperator, m->stackPos);
3931          **/
3932
3933
3934  conflicting = m->nullClause;
3935  m->dependent->size = 0;
3936  conflicting->size = conflicting->size | SATCVisited;
3937  m->dependent = sat_array_insert(m->dependent, (long)conflicting);
3938  sat_get_dependent_clauses(m, conflicting);
3939  dependent = m->dependent;
3940  for(i=0; i<dependent->size; i++) {
3941    c = (satClause_t *)dependent->space[i];
3942    c->size = c->size - SATCVisited;
3943  }
3944
3945#if 0
3946  i = m->stackPos - 1;
3947  tv = 0;
3948  nMarks = 0;
3949  lit = 0;
3950  if(m->coreGeneration)
3951    m->dependent = sat_array_insert(m->dependent, (long)conflicting);
3952  do {
3953    c = conflicting;
3954
3955
3956    csize = SATSizeClause(c);
3957    j=(lit == 0)?0:1;
3958    pLit = &(c->lits[j]);
3959
3960    for(; j<csize; j++) {
3961      cLit = *pLit++;
3962      v = cLit >> 1;
3963      if(!m->marks[v]) {
3964        m->marks[v] = 1;
3965        if(m->levels[v] >= SATCurLevel(m))
3966          nMarks++;
3967      }
3968    }
3969    while(i>=0 && !(m->marks[(m->decisionStack[i--])>>1]));
3970    if(i < -1) break;
3971    lit = m->decisionStack[i+1];
3972    tv = lit>>1;
3973    conflicting = m->antes[tv];
3974
3975    if(m->coreGeneration)
3976      m->dependent = sat_array_insert(m->dependent, (long)conflicting);
3977    m->marks[tv] = 0;
3978    nMarks--;
3979  } while(nMarks > 0 && i>=0);
3980#endif
3981
3982  dependent = m->dependent;
3983  for(i=0; i<dependent->size; i++) {
3984    c = (satClause_t *)dependent->space[i];
3985    if(c->size & SATCVisited)   continue;
3986
3987    c->size = c->size | SATCVisited;
3988    sat_generate_unsat_core(m, c);
3989  }
3990}
3991
3992
3993void
3994sat_check_clause_flag(satManager_t *m)
3995{
3996satArray_t *arr;
3997satClause_t *c;
3998long i;
3999
4000  arr = m->clauses;
4001  for(i=0; i<arr->size; i++) {
4002    c = (satClause_t *)arr->space[i];
4003    if(!(c->size & SATCVisited))        continue;
4004    fprintf(stdout, "%d ", (int) c->size & SATCVisited);
4005    sat_print_clause(m, c);
4006    fprintf(stdout, "\n");
4007  }
4008
4009  arr = m->learned;
4010  for(i=0; i<arr->size; i++) {
4011    c = (satClause_t *)arr->space[i];
4012    if(!(c->size & SATCVisited))        continue;
4013    fprintf(stdout, "%d ", (int) c->size & SATCVisited);
4014    sat_print_clause(m, c);
4015    fprintf(stdout, "\n");
4016  }
4017}
4018
4019void
4020sat_generate_unsat_core(satManager_t *m, satClause_t *cl)
4021{
4022satArray_t *dependent;
4023satClause_t *c;
4024long i;
4025
4026  dependent = cl->dependent;
4027  if(dependent == 0)    return;
4028
4029  for(i=0; i<dependent->size; i++) {
4030    c = (satClause_t *)dependent->space[i];
4031    if(c->size & SATCVisited)   continue;
4032
4033    c->size = c->size | SATCVisited;
4034    sat_generate_unsat_core(m, c);
4035  }
4036}
4037
4038satArray_t *
4039sat_generate_unsat_core_clauses_index_array(satManager_t *m)
4040{
4041satArray_t *clauses, *coreArray;
4042long i;
4043satClause_t *c;
4044
4045  coreArray = sat_array_alloc(1024);
4046 
4047  clauses = m->clauses;
4048  for(i=0; i<clauses->size; i++) {
4049    c = (satClause_t *)clauses->space[i];
4050    if(c->size & SATCVisited) 
4051      coreArray = sat_array_insert(coreArray, i);
4052  }
4053
4054  return(coreArray);
4055}
4056
4057int
4058sat_print_unsat_core(satManager_t *m, char *cnfFilename)
4059{
4060FILE *fp;
4061long i, j, nClauses, lit;
4062long csize;
4063char *filename;
4064satClause_t *c;
4065satArray_t *clauses;
4066
4067  filename = malloc(sizeof(char)*(strlen(cnfFilename)+6));
4068  sprintf(filename, "%s.core", cnfFilename);
4069  if(!(fp = fopen(filename, "w"))) {
4070    fprintf(stderr, "ERROR : Can't open CNF file %s\n", 
4071            filename);
4072    return(0);
4073  }
4074
4075  nClauses = 0;
4076  clauses = m->clauses;
4077  for(i=0; i<clauses->size; i++) {
4078    c = (satClause_t *)clauses->space[i];
4079    if(c->size & SATCVisited) nClauses++;
4080  }
4081
4082  fprintf(fp, "p cnf %d %d\n", (int) m->nVars, (int) nClauses);
4083  for(i=0; i<clauses->size; i++) {
4084    c = (satClause_t *)clauses->space[i];
4085    if(!(c->size & SATCVisited)) continue;
4086    csize = SATSizeClause(c);
4087    for(j=0; j<csize; j++) {
4088      lit = c->lits[j];
4089      fprintf(fp, "%d ", lit&1 ? (int) -(lit>>1) : (int) (lit>>1));
4090    }
4091    fprintf(fp, "0\n");
4092  }
4093  fclose(fp);
4094  free(filename);
4095  return(1);
4096}
4097
4098void
4099sat_print_dependent_clauses(satManager_t *m, satClause_t *c)
4100{
4101long i;
4102satArray_t *dep;
4103satClause_t *d;
4104
4105  fprintf(stdout, "++++++++++++++++++++++++++++++++++++\n");
4106  sat_print_clause(m, c);
4107  fprintf(stdout, "\n");
4108  fprintf(stdout, "++++++++++++++++++++++++++++++++++++\n");
4109  dep = c->dependent;
4110  if(dep == 0)  return;
4111
4112  for(i=0; i<dep->size; i++) {
4113    d = (satClause_t *)dep->space[i];
4114    sat_print_clause(m, d);
4115    fprintf(stdout, "\n");
4116  }
4117}
4118
4119void
4120sat_print_dependent_graph(satManager_t *m)
4121{
4122satArray_t *arr;
4123satClause_t *c;
4124long i;
4125
4126  arr = m->learned;
4127  for(i=0; i<arr->size; i++) {
4128    c = (satClause_t *)arr->space[i];
4129    sat_print_dependent_clauses(m, c);
4130  }
4131}
4132
4133void
4134sat_check_dependent_clauses(satClause_t *c)
4135{
4136long i;
4137satArray_t *dep;
4138satClause_t *d;
4139
4140  dep = c->dependent;
4141  if(dep == 0)  return;
4142
4143  for(i=0; i<dep->size; i++) {
4144    d = (satClause_t *)dep->space[i];
4145    if(d->size>1000){
4146      fprintf(stdout, "ERROR\n");
4147    } 
4148  }
4149}
4150
4151void
4152sat_check_dependent_graph(satManager_t *m)
4153{
4154satArray_t *arr;
4155satClause_t *c;
4156long i;
4157
4158  arr = m->learned;
4159  for(i=0; i<arr->size; i++) {
4160    c = (satClause_t *)arr->space[i];
4161    sat_check_dependent_clauses(c);
4162  }
4163}
4164
4165int
4166sat_compare_activity(void *activity, const void *xx, const void * yy)
4167{
4168double *a;
4169long x, y;
4170
4171  x = (long) xx;
4172  y = (long) yy;
4173   
4174  a = (double *)activity;
4175  return(a[x] > a[y]);
4176}
4177
4178
4179
4180#ifdef SatELite
4181
4182int
4183sat_eliminate_clauses(satManager_t *m)
4184{
4185int cnt;
4186long next;
4187
4188  if(m->checkSubsumption == 0)
4189    return(0);
4190
4191  while(sat_queue_size(m->subsumptionQueue) > 0 || m->eliminateHeap->size > 0) {
4192    if(!sat_backward_subsumption_check(m))
4193      return(0);
4194    for(cnt = 0; m->eliminateHeap->size > 0; cnt++) {
4195      next = sat_heap_remove_min(m, m->eliminateHeap);
4196
4197      if(!sat_eliminate_variable(m, next))
4198        return(0);
4199    }
4200    /** add touched clauses into subsumption queue **/
4201    sat_collect_subsumption_candidiates(m);
4202  }
4203
4204  /** free data structure for eliminating clauses **/
4205  sat_free_data_for_eliminating_clause(m);
4206
4207  return(1);
4208  /** need add function for variable ordering **/
4209}
4210
4211void
4212sat_free_data_for_eliminating_clause(satManager_t *m)
4213{
4214int i;
4215satArray_t *cArr;
4216
4217  sat_queue_free(m->subsumptionQueue);
4218  m->subsumptionQueue = 0;
4219  sat_heap_free(m->eliminateHeap);
4220
4221  free(m->visits);
4222  m->visits = 0;
4223
4224  free(m->nOccurrence);
4225  m->nOccurrence = 0;
4226
4227  for(i=0; i<m->nVars; i++) {
4228    cArr = m->occurrence[i];
4229    free(cArr);
4230  }
4231  free(m->occurrence);
4232  m->occurrence = 0;
4233}
4234
4235void
4236sat_collect_subsumption_candidiates(satManager_t *m)
4237{
4238int i, j, mask;
4239satArray_t *cArr;
4240satClause_t *c;
4241
4242  for(i=0; i<m->nVars; i++) {
4243    if(m->visits[i]) {
4244      m->visits[i] = 0;
4245      sat_cleanup_occurrence_array(m, i);
4246      cArr = m->occurrence[i];
4247      for(j=0; j<cArr->size; j++) {
4248        c = (satClause_t *)cArr->space[j];
4249        /** To avoid putting same clauses into subsumption queue */
4250        if((c->size & SATCVisited2) == 0) {
4251          sat_queue_insert(m->subsumptionQueue, (long)c); 
4252          c->size = c->size | SATCVisited2;
4253        }
4254      }
4255    }
4256  }
4257
4258  mask = ~SATCVisited2 & ~SATCVisited;
4259  for(i=m->subsumptionQueue->first; i<m->subsumptionQueue->arr->size; i++) {
4260    c = (satClause_t *)m->subsumptionQueue->arr->space[i];
4261    c->size = c->size & mask;
4262  }
4263
4264}
4265
4266int
4267sat_eliminate_variable(satManager_t *m, long v)
4268{
4269int csize, i, j;
4270int count;
4271long lit;
4272satArray_t *cArr;
4273satClause_t *c;
4274satArray_t *lphase[2];
4275/** need to figure out what is asymmVar check **/
4276
4277  if(m->values[v] != 2) return(1);
4278  sat_cleanup_occurrence_array(m, v);
4279  cArr = m->occurrence[v];
4280
4281  /** need to skip when there are too many clauses **/
4282 
4283  /** split the occurrence into positive and negative **/
4284  /** 0 : pos, 1: neg **/
4285  lphase[0] = sat_array_alloc(1024);
4286  lphase[1] = sat_array_alloc(1024);
4287  for(i=0; i<cArr->size; i++) {
4288    c = (satClause_t *)cArr->space[i];
4289    csize = SATSizeClause(c);
4290    for(j=0; j<csize; j++) {
4291      lit = c->lits[j];
4292      if(lit>>1 == v) { 
4293        lphase[lit&1] = sat_array_insert(lphase[lit&1], (long)c);
4294        break;
4295      }
4296    }
4297  }
4298  /** Count the number of clauses increased after variable elimination **/
4299  count = 0;
4300  for(i=0; i<lphase[0]->size; i++) {
4301    for(j=0; j<lphase[1]->size; j++) {
4302      if(!sat_resolvent_is_tautology((satClause_t *)lphase[0]->space[i], (satClause_t *)lphase[1]->space[j], v)) {
4303        count++;
4304        if(count >cArr->size) {
4305          free(lphase[0]);
4306          free(lphase[1]);
4307          return(1);
4308        }
4309      }
4310    }
4311  }
4312  /** Remove and store original clause **/
4313  m->elimOrderArray[v] = m->elimOrder++;
4314  for(i=0; i<cArr->size; i++) {
4315    if(m->elimClauses[v] == 0)
4316      m->elimClauses[v] = sat_array_alloc(cArr->size);
4317    c = (satClause_t *)cArr->space[i];
4318    m->elimClauses[v] = sat_array_insert(m->elimClauses[v], (long)c);
4319    sat_delete_clause_for_cs(m, c);
4320  }
4321  /** free cArr */
4322  free(cArr);
4323  m->occurrence[v] = 0;
4324
4325  /** Generate resolvent **/
4326  for(i=0; i<lphase[0]->size; i++) {
4327    for(j=0; j<lphase[1]->size; j++) {
4328      m->clearned->size = 0;
4329      m->clearned = sat_generate_resolvent((satClause_t *)lphase[0]->space[i], (satClause_t *)lphase[1]->space[j], v, m->clearned);
4330      if(m->clearned->size)
4331        c = sat_add_clause(m, m->clearned, 0);
4332    }
4333  }
4334 
4335  free(lphase[0]);
4336  free(lphase[1]);
4337  return(sat_backward_subsumption_check(m));
4338}
4339
4340int
4341sat_resolvent_is_tautology(satClause_t *_c1, satClause_t *_c2, long v) 
4342{
4343int c1_small;
4344satClause_t *c1, *c2;
4345int i, j, c1size, c2size;
4346long lit1, lit2;
4347
4348  c1_small = SATSizeClause(_c1) < SATSizeClause(_c2);
4349  c1 = c1_small ? _c2 : _c1;
4350  c2 = c1_small ? _c1 : _c2;
4351
4352  c1size = SATSizeClause(c1);
4353  c2size = SATSizeClause(c2);
4354  for(i=0; i<c2size; i++) {
4355    lit2 = c2->lits[i];
4356    if(lit2>>1 == v)    continue;
4357    for(j=0; j<c2size; j++) {
4358      lit1 = c1->lits[j];
4359      if((lit1>>1) == (lit2>>1)) {
4360        if(lit1 == (lit2^1)) 
4361          return(0);
4362        else 
4363          goto next;
4364      }
4365    }
4366    next:;
4367  }
4368  return 1;
4369}
4370
4371satArray_t *
4372sat_generate_resolvent(satClause_t *_c1, satClause_t *_c2, long v, satArray_t *resolvent)
4373{
4374int c1_small;
4375satClause_t *c1, *c2;
4376int i, j, c1size, c2size;
4377long lit1, lit2;
4378
4379  c1_small = SATSizeClause(_c1) < SATSizeClause(_c2);
4380  c1 = c1_small ? _c2 : _c1;
4381  c2 = c1_small ? _c1 : _c2;
4382
4383  c1size = SATSizeClause(c1);
4384  c2size = SATSizeClause(c2);
4385  for(i=0; i<c2size; i++) {
4386    lit2 = c2->lits[i];
4387    if(lit2>>1 == v)    continue;
4388    for(j=0; j<c2size; j++) {
4389      lit1 = c1->lits[j];
4390      if((lit2>>1) == (lit1>>1)) {
4391        if(lit2 == (lit1^1)) {
4392          resolvent->size = 0;
4393          return(resolvent);
4394        }
4395        else {
4396          goto next;
4397        }
4398      }
4399    }
4400    resolvent = sat_array_insert(resolvent, lit1);
4401    next:;
4402  }
4403
4404  for(i=0; i<c2size; i++) {
4405    lit2 = c2->lits[j];
4406    if(lit2>>1 != v)
4407      resolvent = sat_array_insert(resolvent, lit1);
4408  }
4409 
4410  return(resolvent);
4411
4412}
4413
4414void
4415sat_cleanup_occurrence_array(satManager_t *m, long v)
4416{
4417int i, j;
4418satArray_t *arr;
4419satClause_t *c;
4420
4421  arr = m->occurrence[v];
4422  for(i=j=0; i<arr->size; i++) {
4423    c = (satClause_t *)arr->space[i];
4424    /**
4425    tmp = ((c->size & SATCVisited) == 0) ? (arr->space[j++] = arr->space[i], 1) : 1;
4426    **/
4427    if((c->size & SATCVisited) == 0)
4428      arr->space[j++] = arr->space[i];
4429  }
4430
4431  arr->size -= (i-j);
4432  m->occurrence[v] = arr;
4433}
4434
4435int
4436sat_backward_subsumption_check(satManager_t *m)
4437{
4438int i, j;
4439long lit, best, v, csize;
4440satClause_t *c, *ct;
4441satArray_t *cArr;
4442
4443  while(sat_queue_size(m->subsumptionQueue)> 0 || m->bsAssigns < m->stackPos) {
4444    if(sat_queue_size(m->subsumptionQueue) == 0 && m->bsAssigns < m->stackPos) {
4445      lit = m->decisionStack[m->bsAssigns++];
4446      m->clearned->size = 1;
4447      m->clearned->space[0] = lit;
4448      c = sat_new_clause(m->clearned, 0);
4449      sat_queue_insert(m->subsumptionQueue, (long)c);
4450    }
4451    c = (satClause_t *)sat_queue_pop(m->subsumptionQueue);
4452    if(c->size & SATCVisited)   continue;
4453
4454    best = (c->lits[0])>>1;
4455    csize = SATSizeClause(c);
4456    for(i=1; i<csize; i++) {
4457      lit = c->lits[i];
4458      v = lit>>1;
4459      if(m->occurrence[v]->size < m->occurrence[best]->size)
4460        best = v;
4461    }
4462   
4463    sat_cleanup_occurrence_array(m, best);
4464    cArr = m->occurrence[best];
4465    for(i=0; i<cArr->size; i++) {
4466      if(c->size & SATCVisited) break;
4467      ct = (satClause_t *)cArr->space[i];
4468      if(!(ct->size & SATCVisited) && ct != c) {
4469        lit = sat_subsumption_check(m, c, ct);
4470        if(lit == 0) {
4471          m->nSubsumedClauses++;
4472          sat_delete_clause_for_cs(m, ct);
4473        }
4474        else if(lit>0) {
4475          m->nSubsumedDeletedLiterals++;
4476          if(!sat_strengthen_clause(m, ct, lit^1))
4477            return(0);
4478          if((lit>>1) == best)
4479            j--;
4480        }
4481
4482      }
4483    }
4484  }
4485  return(1);
4486}
4487
4488void
4489sat_delete_literal_from_clause(satClause_t *c, long lit)
4490{
4491int i, csize;
4492long abstract;
4493long tlit;
4494 
4495  csize = SATSizeClause(c);
4496  abstract = 0;
4497  for(i=0; i<csize && c->lits[i] != lit; i++) {
4498    tlit = c->lits[i];
4499    if(tlit == lit)     break;
4500    abstract |= 1 << (SATVar(tlit) & 31);
4501  }
4502  csize--;
4503  for(; i<csize; i++)  {
4504    tlit = c->lits[i+1];
4505    abstract |= 1 << (SATVar(tlit) & 31);
4506    c->lits[i] = tlit;
4507  }
4508  c->info.abstract = abstract;
4509  c->size = (csize << SATCsizeShift) | (c->size & SATCMask);
4510}
4511
4512int
4513sat_strengthen_clause(satManager_t *m, satClause_t *c, long lit)
4514{
4515long tlit;
4516int csize;
4517int index;
4518satArray_t *arr;
4519satClause_t *conflicting;
4520
4521  sat_queue_insert(m->subsumptionQueue, (long)c);
4522  if(c->lits[0] == lit || c->lits[1] == lit) {
4523    csize = SATSizeClause(c);
4524    if(csize == 2) {
4525      sat_delete_clause_for_cs(m, c);
4526      sat_delete_literal_from_clause(c, lit);     
4527    }
4528    else {
4529      sat_delete_literal_from_clause(c, lit);     
4530      /** delete clasue c from watched literal of lit **/
4531      sat_array_delete_elem(m->wls[lit^1], (long)c);
4532
4533      /** add clause c to watched literal of tlit **/
4534      tlit = c->lits[1];
4535      index = (tlit)^1;
4536      arr = m->wls[index];
4537      m->wls[index] = sat_array_alloc_insert(arr, (long)c);
4538    }
4539  }
4540  else {
4541    sat_delete_literal_from_clause(c, lit);     
4542  }
4543
4544  sat_array_delete_elem(m->occurrence[lit>>1], (long)c);
4545  m->nOccurrence[lit]--; 
4546  if(m->elimOrderArray[lit>>1] == 0) /** if variable is not eliminated **/
4547    sat_heap_update(m, m->eliminateHeap, lit>>1);
4548 
4549  csize = SATSizeClause(c);
4550  if(csize != 1) return(1);
4551
4552  sat_enqueue_check(m, c->lits[0], 0);
4553  conflicting = sat_implication(m);
4554  if(conflicting)       {
4555    m->status = 0;
4556    return(0);
4557  }
4558 
4559  return(1);
4560}
4561
4562void
4563sat_delete_clause_for_cs(satManager_t *m, satClause_t *c)
4564{
4565long j, csize, lit;
4566
4567  csize = SATSizeClause(c);
4568  for(j=0; j<csize; j++) {
4569    lit = c->lits[j]; 
4570    m->nOccurrence[lit]--; 
4571    if(m->elimOrderArray[lit>>1] == 0) /** if variable is not eliminated **/
4572      sat_heap_update(m, m->eliminateHeap, lit>>1);
4573  }
4574
4575  sat_delete_watched_literal(m, c);
4576  if(c->dependent)
4577    free(c->dependent);
4578}
4579
4580
4581long
4582sat_subsumption_check(satManager_t *n, satClause_t *c, satClause_t *ct)
4583{
4584long lit;
4585int i, j;
4586
4587  if((SATSizeClause(ct) < SATSizeClause(c)) ||
4588     (c->info.abstract & ~ct->info.abstract)) 
4589    return(-1);
4590
4591  lit = 0;
4592  for(i=0; i<SATSizeClause(c); i++) {
4593    for(j=0; j<SATSizeClause(ct); j++) {
4594      if(c->lits[i] == ct->lits[j])     goto cond;
4595      else if(lit == 0 && c->lits[i] == ~ct->lits[j]) {
4596        lit = c->lits[i];
4597        goto cond;
4598      }
4599    }
4600    return(-1);
4601    cond:;
4602  }
4603  return(lit);
4604}
4605#endif
4606
4607#ifdef CHECK_EQUIVALENCE_RELATION
4608void
4609sat_clean_up_equi_job(satManager_t *m, satArray_t *save0)
4610{
4611long j, lit, v;
4612
4613  for(j=0; j<save0->size; j++) {
4614    lit = save0->space[j];
4615    v = lit>>1;
4616    m->dummy[v] = 1;
4617    m->equi[v] = 0;
4618  }
4619
4620  j = m->decisionStackSeperator->space[0];
4621  for(; j<m->stackPos; j++) {
4622    lit = m->decisionStack[j];
4623    v = lit>>1;
4624    m->dummy[v] = 1;
4625    m->equi[v] = 0;
4626  }
4627}
4628
4629satClause_t *
4630sat_check_equivalent_relation_aux(satManager_t *m)
4631{
4632satClause_t *conflicting, *c;
4633satArray_t *wl;
4634satClause_t **i, **j, **end;
4635long lit, iLit, first;
4636long csize, k;
4637
4638  conflicting = 0;
4639
4640  while(m->curPos < m->stackPos) {
4641    lit = m->decisionStack[m->curPos++];
4642    wl = m->wls[lit];
4643
4644    if(wl == 0) continue;
4645
4646    for(i = j = (satClause_t **)&(wl->space[0]), end = i + wl->size; i != end;) {
4647      c = *i++;
4648
4649      iLit = lit ^ 1;
4650      if(c->lits[0] == iLit)
4651        c->lits[0] = c->lits[1], c->lits[1] = iLit;
4652
4653      first = c->lits[0];
4654      if((m->values[first>>1]^SATSign(first)) == 1) {
4655        *j++ = c;
4656      }
4657      else {
4658        csize = SATSizeClause(c);
4659        for(k=2; k<csize; k++) {
4660          if((m->values[c->lits[k]>>1] ^ SATSign(c->lits[k])) != 0) {
4661            c->lits[1] = c->lits[k];
4662            c->lits[k] = iLit;
4663            m->wls[(c->lits[1]^1)] = 
4664                sat_array_alloc_insert(m->wls[(c->lits[1]^1)], (long)c);
4665            goto foundWatch;
4666          }
4667        }
4668
4669        *j++ = c;
4670        if((m->values[first>>1]^SATSign(first)) == 0) {
4671          conflicting = c;
4672          m->curPos = m->stackPos;
4673          while(i<end)  *j++ = *i++;
4674        }
4675        else {
4676          sat_enqueue(m, first, c);
4677          m->equi[first>>1] += m->values[first>>1] + 4;
4678        }
4679      }
4680foundWatch:;
4681    }
4682    wl->size -= i-j;
4683  }
4684  return(conflicting);
4685}
4686void
4687sat_check_equivalent_relation(satManager_t *m)
4688{
4689long i, j, k;
4690long lit, v;
4691long sSize;
4692long nEqui, nPos, nNeg;
4693long mapping;
4694long size;
4695satClause_t *c;
4696satArray_t *save0, *qArr;
4697satArray_t *candidate;
4698satHeap_t *h;
4699
4700  h = m->variableHeap;
4701  size = m->nVars * 5 / 100;
4702  candidate = sat_array_alloc(size);
4703  i=0;
4704  while(i<size) {
4705    v = sat_heap_remove_min(m, m->variableHeap);
4706    candidate = sat_array_insert(candidate, v);
4707    i++;
4708  }
4709
4710  save0 = sat_array_alloc(1024);
4711  qArr = sat_array_alloc(1024);
4712  nPos = nNeg = nEqui = 0;
4713
4714/**
4715  for(i=1; i<=m->nVars; i++) {
4716**/
4717  for(k=0; k<candidate->size; k++) {
4718    i = candidate->space[k];
4719    if(m->values[i] < 2)  continue;
4720    if(m->dummy[i])  continue;
4721
4722    save0->size = 0;
4723    qArr->size = 0;
4724    m->decisionStackSeperator = 
4725          sat_array_insert(m->decisionStackSeperator, m->stackPos);
4726    sat_enqueue(m, (i<<1)+1, 0);
4727    c = sat_check_equivalent_relation_aux(m);
4728    if(c) {
4729      sat_clean_up_equi_job(m, save0);
4730      sat_undo(m, 0);
4731      sat_enqueue(m, (i<<1), 0);
4732      c = sat_implication(m);
4733      if(c)     {
4734        m->status = 0;
4735        return;
4736      }
4737      continue;
4738    }
4739    sSize = m->stackPos-m->decisionStackSeperator->space[0];
4740    save0 = sat_array_realloc(save0, sSize);
4741    memcpy(&(save0->space[0]), &(m->decisionStack[m->decisionStackSeperator->space[0]]), sizeof(long)*sSize);
4742    save0->size = sSize;
4743    sat_undo(m, 0);
4744
4745    m->decisionStackSeperator = 
4746          sat_array_insert(m->decisionStackSeperator, m->stackPos);
4747    sat_enqueue(m, (i<<1), 0);
4748    c = sat_check_equivalent_relation_aux(m);
4749    if(c) {
4750      sat_clean_up_equi_job(m, save0);
4751      sat_undo(m, 0);
4752      sat_enqueue(m, (i<<1)+1, 0);
4753      c = sat_implication(m);
4754      if(c)     {
4755        m->status = 0;
4756        return;
4757      }
4758      continue;
4759    }
4760
4761    j = m->decisionStackSeperator->space[0];
4762    for(; j<m->stackPos; j++) {
4763      lit = m->decisionStack[j];
4764      v = lit>>1;
4765      if(m->equi[v] < 8)        continue;
4766      if(m->equi[v] == 8) {
4767        qArr = sat_array_insert(qArr, ((v<<1) + 1));
4768        nNeg++;
4769/**
4770        fprintf(stdout, "%d is always '0' regardless of variable %d\n", (int)v, (int)i);
4771           set variable to 0
4772**/
4773      }
4774      else if(m->equi[v] == 10) {
4775        qArr = sat_array_insert(qArr, (v<<1));
4776        nPos++;
4777/**
4778        fprintf(stdout, "%d is always '1' regardless of variable %d\n", (int)v, (int)i);
4779          set variable to 1
4780**/
4781      }
4782      else {
4783        if(m->values[i] == m->values[v])m->maps[v] = i;
4784        else                            m->maps[v] = -i;
4785        nEqui++;
4786/**
4787        fprintf(stdout, "equivalence relation between %d and %d\n", (int)i, (int)v);
4788          equivalence relation between i, v
4789          to identify more details, check values...
4790**/
4791      }
4792    }
4793
4794
4795    sat_clean_up_equi_job(m, save0);
4796    sat_undo(m, 0);
4797
4798    for(j=0; j<qArr->size; j++) {
4799      lit = qArr->space[j];
4800      sat_enqueue(m, lit, 0);
4801    }
4802    if(qArr->size) {
4803      j = m->stackPos;
4804      c = sat_implication(m);
4805      if(c)     {
4806        m->status = 0;
4807        return;
4808      }
4809    }
4810  }
4811
4812  memset(m->dummy, 0, sizeof(char)*(m->nVars+1));
4813  free(save0);
4814  free(qArr);
4815
4816  for(i=0; i<candidate->size; i++) {
4817    v = candidate->space[i];
4818    if(h->indices[v] < 0 && m->values[v] == 2) 
4819      sat_heap_insert(m, m->variableHeap, v);
4820  }
4821  free(candidate);
4822
4823  fprintf(stdout, "%d %d %d equivalent cases are detected\n", (int)nPos, (int)nNeg, (int)nEqui);
4824  if(nEqui) {
4825    for(i=1; i<=m->nVars; i++) {
4826      mapping = sat_get_mapped_index(m, i);
4827      m->maps[i] = mapping;
4828    }
4829    sat_update_equivalent_class(m, m->clauses, 0);
4830    sat_update_equivalent_class(m, m->learned, 1);
4831  }
4832}
4833
4834void
4835sat_update_equivalent_class(satManager_t *m, satArray_t *arr, long learned)
4836{
4837satClause_t *c, *nc;
4838long i, csize, j;
4839long k;
4840long v, nv, sign, nvsign;
4841long lit;
4842long nModified;
4843long modified;
4844satArray_t *litArr;
4845 
4846  litArr = sat_array_alloc(1024);
4847  nModified = 0;
4848  for(i=j=0; i<arr->size; i++) {
4849    c = (satClause_t *)arr->space[i];
4850    csize = SATSizeClause(c);
4851    modified = 0;
4852    for(k=0; k<csize; k++) {
4853      lit = c->lits[k];
4854      sign = lit&1;
4855      v = lit>>1;
4856      nv = m->maps[v];
4857      if(v != nv) {
4858        modified = 1;
4859        break;
4860      }
4861    }
4862
4863    if(modified) {
4864      litArr->size = 0;
4865      for(k=0; k<csize; k++) {
4866        lit = c->lits[k];
4867        sign = lit&1;
4868        v = lit>>1;
4869        nv = m->maps[v];
4870        if(v != nv) {
4871          nvsign = (nv<0) ? 1 : 0;
4872          nv = (nv<0) ? -nv : nv;
4873          litArr = sat_array_insert(litArr, (nv<<1) + (nvsign^sign));
4874        }
4875        else {
4876          litArr = sat_array_insert(litArr, lit);
4877        }
4878      }
4879      nc = sat_add_clause_only(m, litArr, learned);
4880      if(nc) {
4881        arr->space[j++] = (long)nc;
4882        nModified++;
4883      }
4884      sat_delete_clause(m, c);
4885    }
4886    else 
4887      arr->space[j++] = arr->space[i];
4888  }
4889  arr->size -= (i-j);
4890/**
4891  fprintf(stdout, "%d were modified and %d were satisfied\n", nModified, (i-j));
4892**/
4893  free(litArr);
4894}
4895
4896long
4897sat_get_mapped_index(satManager_t *m, long index)
4898{
4899long mapping;
4900
4901  mapping = m->maps[index];
4902  if(index == mapping)  return(m->maps[index]);
4903  if(mapping < 0)       return(-(sat_get_mapped_index(m, -mapping)));
4904  else                  return(sat_get_mapped_index(m, mapping));
4905}
4906
4907#endif
Note: See TracBrowser for help on using the repository browser.