source: vis_dev/vis-2.3/src/sat/satInterface.c @ 31

Last change on this file since 31 was 14, checked in by cecile, 13 years ago

vis2.3

File size: 17.7 KB
Line 
1/**CFile***********************************************************************
2
3  FileName    [satInterface.c]
4
5  PackageName [sat]
6
7  Synopsis    [Routines for various decision heuristics.]
8
9  Author      [HoonSang Jin]
10
11  Copyright [ This file was created at the University of Colorado at
12  Boulder.  The University of Colorado at Boulder makes no warranty
13  about the suitability of this software for any purpose.  It is
14  presented on an AS IS basis.]
15
16
17******************************************************************************/
18
19#include "satInt.h"
20
21static char rcsid[] UNUSED = "$Id: satInterface.c,v 1.20 2009/04/11 18:26:37 fabio Exp $";
22
23/*---------------------------------------------------------------------------*/
24/* Constant declarations                                                     */
25/*---------------------------------------------------------------------------*/
26
27/**AutomaticStart*************************************************************/
28
29/*---------------------------------------------------------------------------*/
30/* Static function prototypes                                                */
31/*---------------------------------------------------------------------------*/
32
33
34/**AutomaticEnd***************************************************************/
35
36
37/*---------------------------------------------------------------------------*/
38/* Definition of exported functions                                          */
39/*---------------------------------------------------------------------------*/
40/**Function********************************************************************
41
42  Synopsis    [Set option for unsat core generation]
43
44  Description [Set option for unsat core generation]
45
46  SideEffects []
47
48  SeeAlso     []
49
50******************************************************************************/
51void sat_SetOptionForUP(satManager_t * cm)
52{
53  cm->option->includeLevelZeroLiteral = 1;
54  cm->option->minimizeConflictClause = 0;
55  cm->option->clauseDeletionHeuristic = 0;
56  cm->dependenceTable = st_init_table(st_ptrcmp, st_ptrhash);
57  cm->anteTable = st_init_table(st_numcmp, st_numhash);
58  cm->fp = fopen(cm->option->unsatCoreFileName, "w");
59}
60
61/**Function********************************************************************
62
63  Synopsis    [Read CNF]
64
65  Description [Read CNF]
66
67  SideEffects []
68
69  SeeAlso     []
70
71******************************************************************************/
72int
73sat_ReadCNF(satManager_t *cm, char *filename)
74{
75FILE *fin;
76satArray_t *clauseArray;
77char line[16384], word[1024], *lp;
78int nVar, nCl, nArg;
79int i, id, sign;
80long v;
81int begin;
82 long cls_idx;
83
84  if(!(fin = fopen(filename, "r"))) {
85    fprintf(cm->stdOut, "%s ERROR : Can't open CNF file %s\n",
86            cm->comment, filename);
87    return(0);
88  }
89
90  //Bing: for unsat core
91  if(cm->option->coreGeneration)
92    sat_SetOptionForUP(cm);
93
94  begin = 0;
95  clauseArray = sat_ArrayAlloc(1024);
96  while(fgets(line, 16384, fin)) {
97    lp = sat_RemoveSpace(line);
98    if(lp[0] == '\n')   continue;
99    if(lp[0] == '#')    continue;
100    if(lp[0] == 'c')    continue;
101    if(lp[0] == 'p') {
102      nArg = sscanf(line, "p cnf %d %d", &nVar, &nCl);
103      if(nArg < 2) {
104        fprintf(cm->stdErr, "ERROR : Unable to read the number of variables and clauses from CNF file %s\n", filename);
105        fclose(fin);
106        sat_ArrayFree(clauseArray);
107        return(0);
108      }
109      begin = 1;
110
111      for(i=1; i<=nVar; i++) {
112        v = sat_CreateNode(cm, 2, 2);
113        SATflags(v) |= CoiMask;
114        SATvalue(v) = 2;
115      }
116
117      cm->initNumVariables = nVar;
118      cm->variableArray = ALLOC(satVariable_t, cm->initNumVariables+1);
119      memset(cm->variableArray, 0, sizeof(satVariable_t) * (cm->initNumVariables+1));
120      continue;
121    }
122    else if(begin == 0) continue;
123
124    clauseArray->num = 0;
125    while(1) {
126      lp = sat_RemoveSpace(lp);
127      lp = sat_CopyWord(lp, word);
128
129      if(strlen(word)) {
130        id = atoi(word);
131        sign = 1;
132
133        if(id != 0) {
134          if(id < 0) {
135            id = -id;
136            sign = 0;
137          }
138          sat_ArrayInsert(clauseArray, (id*satNodeSize + sign));
139        }
140        else {
141          if(clauseArray->num == 1) {
142            v = clauseArray->space[0];
143            sat_ArrayInsert(cm->unitLits, SATnot(v));
144            cm->initNumClauses++;
145            cm->initNumLiterals += clauseArray->num;
146            //Bing: for unsat core
147            if(cm->option->coreGeneration){
148              cls_idx = sat_AddUnitClause(cm, clauseArray);
149              if(cm->option->coreGeneration){
150                v = SATnormalNode(v);
151                st_insert(cm->anteTable,(char *)v,(char *)cls_idx);
152              }
153            }
154          }
155          else {
156            sat_AddClause(cm, clauseArray);
157            cm->initNumClauses++;
158            cm->initNumLiterals += clauseArray->num;
159          }
160          break;
161        }
162      }
163    }
164  }
165  if(cm->initNumClauses == 0) {
166    fprintf(cm->stdOut, "%s ERROR : CNF is not valid\n", cm->comment);
167    return(0);
168  }
169
170  if(cm->initNumClauses != nCl) {
171    fprintf(cm->stdOut, "%s WARNING : wrong number of clauses\n", cm->comment);
172  }
173
174  fclose(fin);
175  sat_ArrayFree(clauseArray);
176
177  return(1);
178}
179
180/**Function********************************************************************
181
182  Synopsis    [Read CNF from Array]
183
184  Description [Read CNF from Array]
185
186  SideEffects []
187
188  SeeAlso     []
189
190******************************************************************************/
191int
192sat_ReadCNFFromArray(
193        satManager_t *cm,
194        satArray_t *cnfArray,
195        st_table *mappedTable)
196{
197satArray_t *clauseArray;
198int nVar, nCl;
199int i;
200long tv, v, c, *space;
201
202  if(cnfArray == 0) {
203    fprintf(cm->stdOut, "%s ERROR : Can't find CNF array \n", cm->comment);
204    return(0);
205  }
206
207  nVar = 0;
208  nCl = 0;
209  for(i=1; i<cnfArray->num; i++) {
210    v = cnfArray->space[i];
211    if(v <= 0)  nCl++;
212    else {
213      v = SATnormalNode(v);
214      if(v > nVar)      nVar = v;
215    }
216  }
217  nVar = nVar / satNodeSize;
218  for(i=1; i<=nVar; i++) {
219    v = sat_CreateNode(cm, 2, 2);
220    SATflags(v) |= CoiMask;
221    SATvalue(v) = 2;
222  }
223
224  cm->initNumVariables = nVar;
225  cm->variableArray = ALLOC(satVariable_t, cm->initNumVariables+1);
226  memset(cm->variableArray, 0, sizeof(satVariable_t) * (cm->initNumVariables+1));
227
228  clauseArray = sat_ArrayAlloc(1024);
229  for(i=0, space=cnfArray->space; i<cnfArray->num; i++, space++){
230    if(*space <= 0) {
231      space++;
232      i++;
233      if(i>=cnfArray->num)
234        break;
235      clauseArray->num = 0;
236      while(*space > 0) {
237        v = (*space);
238        sat_ArrayInsert(clauseArray, SATnot(v));
239        i++;
240        space++;
241      }
242
243      /**
244       * If clause is blocking clause then it has clause index in it.
245       **/
246      tv = *space;
247
248      if(clauseArray->num > 1)
249        c = sat_AddClause(cm, clauseArray);
250      else {
251        c = sat_AddUnitClause(cm, clauseArray);
252        if(cm->option->coreGeneration) {
253          st_insert(cm->anteTable,(char *)(long)(SATnormalNode(v)),(char *)(long)c);
254        }
255      }
256      if(clauseArray->num == 1)
257        sat_ArrayInsert(cm->unitLits, (v));
258
259      if(tv < -1) { /* this is blocking clause */
260        st_insert(mappedTable, (char *)c, (char *)(-tv));
261      }
262
263      cm->initNumClauses++;
264      cm->initNumLiterals += clauseArray->num;
265      i--;
266      space--;
267    }
268  }
269  sat_ArrayFree(clauseArray);
270
271
272  return(1);
273}
274
275/**Function********************************************************************
276
277  Synopsis    [Write CNF from Array]
278
279  Description [Write CNF from Array]
280
281  SideEffects []
282
283  SeeAlso     []
284
285******************************************************************************/
286int
287sat_WriteCNFFromArray(satArray_t *cnfArray, char *filename)
288{
289FILE *fin;
290int nVar, nCl;
291int i ;
292long v, *space;
293
294  if(cnfArray == 0) {
295    fprintf(stdout, "ERROR : Can't find CNF array \n");
296    return(0);
297  }
298
299  if(!(fin=fopen(filename, "w"))) {
300    fprintf(stdout, "ERROR : Can't find file %s\n", filename);
301    return(0);
302  }
303
304  nVar = 0;
305  nCl = 0;
306  for(i=1; i<cnfArray->num; i++) {
307    v = cnfArray->space[i];
308    if(v <= 0)  nCl++;
309    else {
310      v = SATnormalNode(v);
311      if(v > nVar)      nVar = v;
312    }
313  }
314  nVar = nVar / satNodeSize;
315
316  fprintf(fin, "p cnf %d %d\n", nVar, nCl);
317
318  for(i=0, space=cnfArray->space; i<cnfArray->num; i++, space++){
319    if(*space <= 0) {
320      space++;
321      i++;
322      if(i>=cnfArray->num)
323        break;
324
325      while(*space > 0) {
326        v = (*space);
327        if(SATisInverted(v))    v = -(SATnodeID(v));
328        else                    v = SATnodeID(v);
329        fprintf(fin, "%ld ", v);
330        i++;
331        space++;
332      }
333      fprintf(fin, "0\n");
334
335      i--;
336      space--;
337    }
338  }
339  fclose(fin);
340
341  return(1);
342}
343/**Function********************************************************************
344
345  Synopsis    [Copy word from lp to word]
346
347  Description [Copy word from lp to word and lp moved to next word.]
348
349  SideEffects []
350
351  SeeAlso     []
352
353******************************************************************************/
354char *
355sat_CopyWord(char *lp, char *word)
356{
357char *wp;
358
359  for(wp = word; ; lp++, wp++) {
360    if((*lp == ' ') || (*lp == '\t') || (*lp == '\n'))  break;
361    *wp = *lp;
362  }
363  *wp = '\0';
364  return(lp);
365}
366
367/**Function********************************************************************
368
369  Synopsis    [skip space and return the beginning of word ]
370
371  Description [skip space and return the beginning of word ]
372
373  SideEffects []
374
375  SeeAlso     []
376
377******************************************************************************/
378char *
379sat_RemoveSpace(char *line)
380{
381int i;
382
383  for(i=0; ; i++) {
384    if(line[i] == ' ')          continue;
385    else if(line[i] == '\t')    continue;
386    return(&(line[i]));
387  }
388}
389
390
391/**Function********************************************************************
392
393  Synopsis    [Write CNF file under partial assignment]
394
395  Description [Write CNF file under partial assignment.
396                If a literal in a clause is satisfied then the clause is
397                ignored. If a literal in a clause is unsatisfied then the
398                literal is ignored.]
399
400  SideEffects []
401
402  SeeAlso     []
403
404******************************************************************************/
405void
406sat_WriteCNFWithPartialAssignment(satManager_t *cm, char *filename)
407{
408int nVars, nCls, j;
409int size, satisfied;
410int inverted, value;
411long *plit, v, tv, tsize, i;
412FILE *fout;
413
414  nVars = 0;
415  nCls = 0;
416  tsize = (cm->beginConflict == 0) ? cm->nodesArraySize : cm->beginConflict;
417  for(i=satNodeSize; i<tsize; i+=satNodeSize) {
418    if(SATleftChild(i) == 2 && SATrightChild(i) == 2)   continue;
419    if(!(SATflags(i) & IsCNFMask))      {
420      if(!(SATflags(i) & CoiMask))      continue;
421      fprintf(cm->stdOut, "Warning : current implementation can't take care of AIG node\n");
422      continue;
423    }
424    if(SATreadInUse(i) == 0)    continue;
425
426    size = SATnumLits(i);
427    satisfied = 0;
428    plit = (long *)SATfirstLit(i);
429    for(j=0; j<size; j++, plit++) {
430      v = SATgetNode(*plit);
431      inverted = SATisInverted(v);
432      v = SATnormalNode(v);
433      value = SATvalue(v) ^ inverted;
434      if(value == 1) {
435        satisfied = 1;
436        break;
437      }
438      if(v > nVars)     nVars = v;
439    }
440    if(satisfied)       continue;
441
442    nCls++;
443  }
444  nVars /= satNodeSize;
445
446  if(!(fout = fopen(filename, "w"))) {
447    fprintf(cm->stdOut, "%s ERROR : Can't open file %s\n",
448            cm->comment, filename);
449    exit(0);
450  }
451
452  fprintf(fout, "p cnf %d %d\n", nVars, nCls);
453  tsize = (cm->beginConflict == 0) ? cm->nodesArraySize : cm->beginConflict;
454  for(i=satNodeSize; i<tsize; i+=satNodeSize) {
455    if(SATleftChild(i) == 2 && SATrightChild(i) == 2)   continue;
456    if(!(SATflags(i) & IsCNFMask))      {
457      if(!(SATflags(i) & CoiMask))      continue;
458      continue;
459    }
460    if(SATreadInUse(i) == 0)    continue;
461
462    satisfied = 0;
463    size = SATnumLits(i);
464    plit = (long *)SATfirstLit(i);
465    for(j=0; j<size; j++, plit++) {
466      v = SATgetNode(*plit);
467      inverted = SATisInverted(v);
468      v = SATnormalNode(v);
469      value = SATvalue(v) ^ inverted;
470      if(value == 1) {
471        satisfied = 1;
472        break;
473      }
474    }
475    if(satisfied)       continue;
476
477    plit = (long *)SATfirstLit(i);
478    for(j=0; j<size; j++, plit++) {
479      v = SATgetNode(*plit);
480      inverted = SATisInverted(v);
481      v = SATnormalNode(v);
482      value = SATvalue(v) ^ inverted;
483      if(value < 2) {
484        continue;
485      }
486      tv = SATnodeID(v);
487      fprintf(fout, "%ld ", inverted ? -tv : tv);
488    }
489    fprintf(fout, "0\n");
490  }
491  fclose(fout);
492}
493/**Function********************************************************************
494
495  Synopsis    [ Write CNF ]
496
497  Description [ Write CNF ]
498
499  SideEffects []
500
501  SeeAlso     []
502
503******************************************************************************/
504void
505sat_WriteCNF(satManager_t *cm, char *filename)
506{
507FILE *fout;
508long i, tv, *plit, size, j;
509int csize, inverted;
510int nVar, nCl;
511long left, right;
512
513  if(!(fout = fopen(filename, "w"))) {
514    fprintf(cm->stdOut, "%s ERROR : Can't open file %s\n",
515            cm->comment, filename);
516    exit(0);
517  }
518
519  nVar = cm->initNumVariables;
520  nCl = 0;
521  size = (cm->beginConflict == 0) ? cm->nodesArraySize : cm->beginConflict;
522  for(i=satNodeSize; i<size; i+=satNodeSize) {
523    if(SATleftChild(i) == 2 && SATrightChild(i) == 2)   continue;
524    if(SATflags(i) & IsCNFMask) {
525      if(SATreadInUse(i) == 0)  continue;
526      nCl++;
527      continue;
528    }
529    if(!(SATflags(i) & CoiMask))        continue;
530    nCl += 3;
531  }
532  sat_CountUnitLiteralClauses(cm, cm->assertion, &nCl);
533  sat_CountUnitLiteralClauses(cm, cm->unitLits, &nCl);
534  sat_CountUnitLiteralClauses(cm, cm->auxObj, &nCl);
535  sat_CountUnitLiteralClauses(cm, cm->obj, &nCl);
536
537  fprintf(fout, "p cnf %d %d\n", nVar, nCl);
538
539  sat_PrintUnitLiteralClauses(cm, cm->assertion, fout);
540  sat_PrintUnitLiteralClauses(cm, cm->unitLits, fout);
541  sat_PrintUnitLiteralClauses(cm, cm->auxObj, fout);
542  sat_PrintUnitLiteralClauses(cm, cm->obj, fout);
543
544  size = (cm->beginConflict == 0) ? cm->nodesArraySize : cm->beginConflict;
545  for(i=satNodeSize; i<size; i+=satNodeSize) {
546    if(SATleftChild(i) == 2 && SATrightChild(i) == 2)   continue;
547    if(SATflags(i) & IsCNFMask) {
548      csize = SATnumLits(i);
549      plit = (long*)SATfirstLit(i);
550      for(j=0; j<csize; j++, plit++) {
551         tv = SATgetNode(*plit);
552         inverted = SATisInverted(tv);
553         tv = SATnormalNode(tv);
554         tv = SATnodeID(tv);
555         fprintf(fout, "%ld ", inverted ? -tv : tv);
556      }
557      fprintf(fout, "0\n");
558      continue;
559    }
560    if(!(SATflags(i) & CoiMask))        continue;
561
562
563    left = SATleftChild(i);
564    inverted = SATisInverted(left);
565    left = SATnormalNode(left);
566    left = SATnodeID(left);
567    left = inverted ? -left : left;
568
569    right = SATrightChild(i);
570    inverted = SATisInverted(right);
571    right = SATnormalNode(right);
572    right = SATnodeID(right);
573    right = inverted ? -right : right;
574
575    j = SATnodeID(i);
576
577    fprintf(fout, "%ld %ld %ld 0\n", -left, -right, j);
578    fprintf(fout, "%ld %ld 0\n", left, -j);
579    fprintf(fout, "%ld %ld 0\n", right, -j);
580  }
581
582  fclose(fout);
583}
584
585/**Function********************************************************************
586
587  Synopsis    [ Write CNF ]
588
589  Description [ Write CNF ]
590
591  SideEffects []
592
593  SeeAlso     []
594
595******************************************************************************/
596void
597sat_WriteCNFWithPointer(satManager_t *cm, FILE *fout)
598{
599long i, j, size, tv, *plit;
600int csize, inverted;
601int nVar, nCl;
602long left, right;
603
604  nVar = cm->initNumVariables;
605  nCl = 0;
606  size = (cm->beginConflict == 0) ? cm->nodesArraySize : cm->beginConflict;
607  for(i=satNodeSize; i<size; i+=satNodeSize) {
608    if(SATleftChild(i) == 2 && SATrightChild(i) == 2)   continue;
609    if(SATflags(i) & IsCNFMask) {
610      if(SATreadInUse(i) == 0)  continue;
611      nCl++;
612      continue;
613    }
614    if(!(SATflags(i) & CoiMask))        continue;
615    nCl += 3;
616  }
617  sat_CountUnitLiteralClauses(cm, cm->assertion, &nCl);
618  sat_CountUnitLiteralClauses(cm, cm->unitLits, &nCl);
619  sat_CountUnitLiteralClauses(cm, cm->auxObj, &nCl);
620  sat_CountUnitLiteralClauses(cm, cm->obj, &nCl);
621
622  fprintf(fout, "p cnf %d %d\n", nVar, nCl);
623
624  sat_PrintUnitLiteralClauses(cm, cm->assertion, fout);
625  sat_PrintUnitLiteralClauses(cm, cm->unitLits, fout);
626  sat_PrintUnitLiteralClauses(cm, cm->auxObj, fout);
627  sat_PrintUnitLiteralClauses(cm, cm->obj, fout);
628
629  size = (cm->beginConflict == 0) ? cm->nodesArraySize : cm->beginConflict;
630  for(i=satNodeSize; i<size; i+=satNodeSize) {
631    if(SATleftChild(i) == 2 && SATrightChild(i) == 2)   continue;
632    if(SATflags(i) & IsCNFMask) {
633      csize = SATnumLits(i);
634      plit = (long*)SATfirstLit(i);
635      for(j=0; j<csize; j++, plit++) {
636         tv = SATgetNode(*plit);
637         inverted = SATisInverted(tv);
638         tv = SATnormalNode(tv);
639         tv = SATnodeID(tv);
640         fprintf(fout, "%ld ", inverted ? -tv : tv);
641      }
642      fprintf(fout, "0\n");
643      continue;
644    }
645    if(!(SATflags(i) & CoiMask))        continue;
646
647
648    left = SATleftChild(i);
649    inverted = SATisInverted(left);
650    left = SATnormalNode(left);
651    left = SATnodeID(left);
652    left = inverted ? -left : left;
653
654    right = SATrightChild(i);
655    inverted = SATisInverted(right);
656    right = SATnormalNode(right);
657    right = SATnodeID(right);
658    right = inverted ? -right : right;
659
660    j = SATnodeID(i);
661
662    fprintf(fout, "%ld %ld %ld 0\n", -left, -right, j);
663    fprintf(fout, "%ld %ld 0\n", left, -j);
664    fprintf(fout, "%ld %ld 0\n", right, -j);
665  }
666
667}
668/**Function********************************************************************
669
670  Synopsis    [ Count the number of unit literal clauses ]
671
672  Description [ Count the number of unit literal clauses ]
673
674  SideEffects []
675
676  SeeAlso     []
677
678******************************************************************************/
679void
680sat_CountUnitLiteralClauses(
681        satManager_t *cm,
682        satArray_t *arr,
683        int *nCl)
684{
685int i, count;
686long v;
687
688  if(arr == 0)  return;
689  count = 0;
690  for(i=0; i<arr->num; i++) {
691    v = arr->space[i];
692    if(v == 1)  count++;
693  }
694
695  *nCl += arr->num - count;
696}
697
698/**Function********************************************************************
699
700  Synopsis    [ Print unit literal clauses ]
701
702  Description [ Print unit literal clauses ]
703
704  SideEffects []
705
706  SeeAlso     []
707
708******************************************************************************/
709void
710sat_PrintUnitLiteralClauses(
711        satManager_t *cm,
712        satArray_t *arr,
713        FILE *fout)
714{
715int i, inverted;
716long v;
717
718  if(arr == 0)  return;
719  for(i=0; i<arr->num; i++) {
720    v = arr->space[i];
721    if(v == 1)  continue;
722    inverted = SATisInverted(v);
723    v = SATnormalNode(v);
724    v = SATnodeID(v);
725    fprintf(fout, "%ld 0\n", inverted ? -v : v);
726  }
727}
Note: See TracBrowser for help on using the repository browser.