Armin Biere Institute for Formal Models and Verification Johannes Kepler University Linz

 

  Abstract—This paper serves as solver description for the SAT solvers Lingeling and its two parallel variants Treengeling and Plingeling, as well as for our new local search solver YalSAT entering the Competition 2014. For Lingeling and its variants we only list important differences to earlier version of these solvers as used in the SAT Competition 2013. For further information we refer to the solver description [1] of the SAT Competition 2013 or source code.
   
 

YALSAT

Recent SAT competitions witnessed a new generation of several efficient local search solvers including Sparrow [2] and ProbSAT [3], which surprisingly were able to solve some non-random instances.

Fascinated by this success and the simplicity of the ProbSAT solver [3] we started to implement Yet Another Local Search SAT Solver (YalSAT). At its core it implements several variants of ProbSAT’s algorithm and recent extensions [4].

These variants are selected randomly at restarts, scheduled by a reluctant doubling scheme (Luby).

 

Beside initializing the assignment at each restart with a randomly picked assignment among previously saved best assignments within one restart round, it is also possible to assign all variables to false, to true or to a random value.

译文:除了在每次重新启动时使用在一个重新启动轮内先前保存的最佳赋值中随机挑选的赋值来初始化赋值外,还可以将所有变量分配为false、true或随机值。

 

At each restart the submitted version further varies the base cbk for the exponential score distribution between either using the original base values of ProbSAT, where k is determined by the maximum length of the clause in the instance, or using the default of cbk = 2.

译文:在每次重新启动时,提交的版本会进一步改变指数分数分布的基准cbk,使用原始的ProbSAT基准值(其中k由实例中子句的最大长度决定),或者使用cbk = 2的默认值。

 

Then clause weights are either chosen to be the same for all clauses or are chosen as linear function depending on the clause length (with either larger clauses having larger weight or alternatively smaller clauses). The maximum weight is also picked randomly.

译文:然后将子句权重选择为对所有子句相同,或者根据子句长度选择为线性函数(较大的子句权重较大,或者较小的子句权重较小)。最大权值也是随机选取的。

With this set-up we were able to solve a surprisingly large number of satisfiable crafted instances from last year’s competition.译文:通过这种设置,我们能够解决去年比赛中大量令人满意的制作实例。

For uniform random instances YalSAT is supposed to work almost identical to last year’s version of ProbSAT。译文:对于统一随机实例,YalSAT应该与去年版本的ProbSAT运行起来几乎完全相同

   

 

代码sparrow.c v 2014 解读


 

 

/**
* sparrow.c v 2014
* This code is based on the code used in the SAT 2010 paper.
* The code is simplified and improved.
* Original code was based on gNovelty+ code, which seems
* to be strongly based on the walksat code by H. Kautz and B. Selmann
* Author: Adrian Balint
*/

   

一、基本函数原型和调用关系

 

二、基本数据成员

 
  1 #define MAXCLAUSELENGTH 20000 //maximum number of literals per clause
  2 #define STOREBLOCK  200000
  3 
  4 # undef LLONG_MAX
  5 #define LLONG_MAX  9223372036854775807
  6 #define BIGINT long long int
  7 #define MAXSCORE 300
  8 #define getScore(VAR) (score[VAR])
  9 #define setScore(VAR,VAL) (score[VAR]=VAL)
 10 #define adjScore(VAR,VAL) (score[VAR]+=VAL)
 11 
 12 #define incScore(VAR,CLS) (score[VAR]+=clauseWeight[CLS])
 13 #define decScore(VAR,CLS) (score[VAR]-=clauseWeight[CLS])
 14 #define BASECW 1 //base clause weight, when score used 1
 15 #define GETOCCPOS(L) (2*abs(L)-(L<0))  //文字-1对应标号1;文字+1对应2
 16 
 17 /*--------*/
 18 
 19 int (*pickClause)() = NULL;  //函数指针
 20 
 21 /*----Instance data (independent from assignment)----*/
 22 /** The numbers of variables. */
 23 int numVars;
 24 /** The number of clauses. */
 25 int numClauses;
 26 /** The number of literals. */
 27 int numLiterals;
 28 /** The value of the variables. The numbering starts at 1 and the possible values are 0 or 1. */
 29 char *atom;  //变元的赋值
 30 /** The clauses of the formula represented as: clause[clause_number][literal_number].
 31  * The clause and literal numbering start both at 0.*/
 32 int **clause;
 33 /**min and max clause length*/
 34 int maxClauseSize;
 35 int minClauseSize;
 36 /** The number of occurrence of each literal.*/
 37 int *numOccurrence;
 38 /** The clauses where each literal occurs. For literal i : occurrence[i+MAXATOMS][j] gives the clause =
 39  * the j'th occurrence of literal i.  */
 40 int **occurrence;
 41 int maxNumOccurences = 0; //maximum number of occurences for a literal

42 /** neighbourVar[i] contains the array with all variables that are in the same clause with variable i*/ 43 int **neighbourVar; //新增的表示变元同在一个子句中的关系信息 44 /*--------*/



45 46 /**----Assignment dependent data----*/ 47 /** The number of false clauses.*/ 48 int numFalse; 49 /** Array containing all clauses that are false. Managed as a list.*/ 50 int *falseClause; 51 /** whereFalse[i]=j tells that clause i is listed in falseClause at position j. */ 52 int *whereFalseOrCritVar; 53 /** The number of true literals in each clause. */ 54 unsigned short *numTrueLit; 55 //#ifdef XOR 56 /** whereFalse[i]=xor(all true literals of clause i)*/ 57 //int *whereFalse; 58 //#else 59 /** whereFalse[i]=j tells that for clause i the variable j is critically responsible for satisfying i.*/ 60 //int *whereFalse; 61 //#endif 62 63 /**score[i] tells how the overall weigths of the clauses will change if i is flipped*/ 64 int bestVar; 65 66 int *score; //新增 67 int *varLastChange; //新增 68 69 /*----Gradient variables----*/ 70 int gradient; //新增 71 /**number of decresing varaibles*/ 72 int numDecVar; //新增 73 /** decVar is a list of all variables that when flipped decrease the number of unsat clauses. */ 74 int *decVar; //新增 75 int *isCandVar; //新增 76 /*--------*/ 77 78 /*----Weighting variables----*/ 79 int sp; //smoothing probability 80 int *clauseWeight; //the weight of each clause 81 /*this saves the extra weight the variables gets in a weighted algorithm instantiation*/ 82 int numWeight; //the number of clauses with weight>1 83 int *weightedClause; //a list with all clauses with weight > 1 84 int *whereWeight; //whereWeight[i] = j tells that clause i is at position j in weightedClause 85 int updateW; 86 /*--------*/ 87 88 /**----Statistics variables----*/ 89 unsigned BIGINT statNumGWalks=0; 90 unsigned BIGINT statNumSmooth=0; //how often a smoothing has been done. 91 unsigned BIGINT statNumWeight=0; //how often a weighting has been done. 92 unsigned BIGINT statXOROps=0; 93 unsigned BIGINT statClSearch=0; 94 BIGINT statdec1=0,statdec2=0,statdec3=0;//0<-1 1<-2 2-<3 95 BIGINT statinc0=0,statinc1=0,statinc2=0;//0->1 1->2 2->3 96 /*--------*/ 97 98 /*----Sparrow variables----*/ 99 /** Look-up table for the exponential function within Sparrow. The values are computed in the initSparrowProbs method.*/ 100 double *scorePow; 101 102 /** contains the probabilities of the variables from an unsatisfied clause*/ 103 double *probs; 104 double c0, c1, inv_c3; 105 int c2, c3; 106 unsigned short randomC=1; //Whether to pick a random unsat clause or iterate with flip counter 107 int keep_assig=0; 108 /*--------*/ 109 110 /*----Input file variables----*/ 111 FILE *fp; 112 char *fileName; 113 /*---------*/ 114 115 /** Run time variables variables*/ 116 BIGINT seed; 117 BIGINT maxTries = LLONG_MAX; 118 BIGINT maxFlips = LLONG_MAX; 119 BIGINT flip; 120 int tryn; 121 BIGINT totalFlips=0, allowedFlips; 122 float timeOut = FLT_MAX; 123 int run = 1; 124 int printSol = 0; 125 double tryTime; 126 double totalTime = 0.; 127 long ticks_per_second; 128 int bestNumFalse; 129 //Sparrow parameters flags - indicates if the parameters were set on the command line 130 int c1_spec = 0, c2_spec = 0, c3_spec = 0, sp_spec = 0,sps_spec=0; 131 int randomCspec = 0; 132 int sparray[100]= {0,100,600,1000,900,600,800,600,0}; //original setting 133 //int sparray[1000]= {0,100,600,1000,900,600,800,700,1000}; //original setting 134 int num_sp = 9; 135 /*---------*/

 

   

三、函数解析

1.parsefile

 
  1 void parseFile() {
  2     register int i, j;
  3     int lit, r, clauseSize;
  4     int tatom;
  5     char c;
  6     int totalOcc=0;
  7     long filePos;
  8     int numNeighbours, cla, var;
  9     int *clptr;
 10     fp = NULL;
 11     fp = fopen(fileName, "r");
 12     if (fp == NULL) {
 13         fprintf(stderr, "c Error: Not able to open the file: %s", fileName);
 14         exit(-1);
 15     }
 16 
 17     // Start scanning the header and set numVars and numClauses
 18     for (;;) {
 19         c = fgetc(fp);
 20         if (c == 'c') //comment line - skip content
 21             do {
 22                 c = fgetc(fp); //read the complete comment line until a eol is detected.
 23             } while ((c != '\n') && (c != EOF));
 24         else if (c == 'p') { //p-line detected
 25             if ((fscanf(fp, "%*s %d %d", &numVars, &numClauses))) //%*s should match with "cnf"
 26                 break;
 27             break;
 28         } else {
 29             fprintf(stderr, "c No parameter line found! Computing number of atoms and number of clauses from file!\n");
 30             r = fseek(fp, -1L, SEEK_CUR); //try to unget c
 31             if (r == -1) {
 32                 fprintf(stderr, "c Error: Not able to seek in file: %s", fileName);
 33                 exit(-1);
 34             }
 35             filePos = ftell(fp);
 36             if (r == -1) {
 37                 fprintf(stderr, "c Error: Not able to obtain position in file: %s", fileName);
 38                 exit(-1);
 39             }
 40 
 41             numVars = 0;
 42             numClauses = 0;
 43             for (; fscanf(fp, "%i", &lit) == 1;) {
 44                 if (lit == 0)
 45                     numClauses++;
 46                 else {
 47                     tatom = abs(lit);
 48                     if (tatom > numVars)
 49                         numVars = tatom;
 50                 }
 51             }
 52             fprintf(stderr, "c scanned numVars: %d numClauses: %d\n", numVars, numClauses);
 53 
 54             r = fseek(fp, filePos, SEEK_SET); //try to rewind the file to the beginning of the formula
 55             if (r == -1) {
 56                 fprintf(stderr, "c Error: Not able to seek in file: %s", fileName);
 57                 exit(-1);
 58             }
 59 
 60             break;
 61         }
 62     }
 63     // Finished scanning header.
 64     //allocating memory to use!
 65     allocateMemory();
 66     maxClauseSize = 0;
 67     minClauseSize = MAXCLAUSELENGTH;
 68     int *numOccurrenceT = (int*) malloc(sizeof(int) * (numLiterals + 1));
 69 
 70     int freeStore = 0;
 71     int *tempClause = 0;
 72 
 73     for (i = 0; i < numLiterals + 1; i++) {
 74         numOccurrence[i] = 0;
 75         numOccurrenceT[i] = 0;
 76     }
 77 
 78     for (i = 1; i <= numClauses; i++) {
 79             if (freeStore < MAXCLAUSELENGTH) {
 80                 tempClause = (int*) malloc(sizeof(int) * STOREBLOCK);
 81                 freeStore = STOREBLOCK;
 82             }
 83             clause[i] = tempClause;
 84             clauseSize = 0;
 85             do {
 86                 r = fscanf(fp, "%i", &lit);
 87                 if (lit != 0) {
 88                     clauseSize++;
 89                     *tempClause++ = lit;
 90                     numOccurrenceT[GETOCCPOS(lit)]++;
 91                     if (numOccurrenceT[GETOCCPOS(lit)] > maxNumOccurences)
 92                         maxNumOccurences = numOccurrenceT[GETOCCPOS(lit)];
 93                     totalOcc++;
 94                 } else {
 95                     *tempClause++ = 0; //0 sentinel as literal!
 96                 }
 97                 freeStore--;
 98             } while (lit != 0);
 99             if (clauseSize > maxClauseSize)
100                 maxClauseSize = clauseSize;
101             if (clauseSize < minClauseSize)
102                 minClauseSize = clauseSize;
103         }
104 
105 
106     occurrence[0] = (int*) malloc(sizeof(int) * (totalOcc + numLiterals+2));
107         int occpos=0;
108         for (i = 0; i < numLiterals + 1; i++) {
109             occurrence[i] = (occurrence[0]+occpos);
110             occpos+=numOccurrenceT[i] + 1;
111         }
112 
113         for (i = 1; i <= numClauses; i++) {
114             j = 0;
115             while ((lit = clause[i][j])) {
116                 occurrence[GETOCCPOS(lit)][numOccurrence[GETOCCPOS(lit)]++] = i;
117                 j++;
118             }
119         }
120         //end occurrence array with a sentinel
121         for (lit=1;lit<=numVars;lit++){
122             occurrence[GETOCCPOS(lit)][numOccurrence[GETOCCPOS(lit)]] = 0;
123             occurrence[GETOCCPOS(-lit)][numOccurrence[GETOCCPOS(-lit)]] = 0;
124         }
125 
126     //Now the maximum size of a clause is determined!
127     probs = (double*) malloc(sizeof(double) * (maxClauseSize + 1));
128 
129     //Constructing the neighbor array from the occurrence-arrays .
130     freeStore = 0;
131     int *tempNeighbour = 0;
132     int isNeighbour[numVars + 1]; //isNeighbour[j]=i means that j is a neighbor-var of i.
133     int *occptr;
134     for(i = 1; i <= numVars; i++)
135     isNeighbour[i] = 0;
136     for (i = 1; i <= numVars; i++) {
137         numNeighbours = 0;
138         //first take a look at all positive occurrences of i
139         //for (j = 0; j < numOccurrence[GETOCCPOS(i)]; j++) {
140         occptr = &occurrence[GETOCCPOS(i)][0];
141         while ((cla = *occptr)){
142             //cla = occurrence[GETOCCPOS(i)][j];
143             clptr = &clause[cla][0];
144             while ((var = abs(*clptr))) {
145                 if ((isNeighbour[var] != i) && (var != i)) { //if it is not all ready marked as a neighbor of i mark it.
146                     isNeighbour[var] = i;
147                     numNeighbours++;
148                 }
149                 clptr++;
150             }
151             occptr++;
152         }
153         //then take a look at all negative occurrence of i
154         //for (j = 0; j < numOccurrence[GETOCCPOS(-i)]; j++) {
155         occptr = &occurrence[GETOCCPOS(-i)][0];
156         while ((cla = *occptr)){
157             //cla = occurrence[GETOCCPOS(-i)][j];
158             clptr = &clause[cla][0];
159             while ((var = abs(*clptr))) {
160                 if ((isNeighbour[var] != i) && (var != i)) { //if it is not all ready marked as a neighbor of i mark it.
161                     isNeighbour[var] = i;
162                     numNeighbours++;
163                 }
164                 clptr++;
165             }
166             occptr++;
167         }
168         if (freeStore < numNeighbours + 1) {
169             tempNeighbour = (int*) malloc(sizeof(int) * STOREBLOCK);
170             freeStore = STOREBLOCK;
171         }
172         neighbourVar[i] = tempNeighbour;
173         freeStore -= numNeighbours + 1;
174         if (numNeighbours >= 1) {
175             for (j = 1; j <= numVars; j++) {
176                 if (isNeighbour[j] == i) {
177                     *(tempNeighbour++) = j;
178                     numNeighbours--;
179                     if (numNeighbours == 0) {
180                         *(tempNeighbour++) = 0;
181                         break;
182                     }
183                 }
184             }
185         } else
186             *(tempNeighbour++) = 0;
187     }
188     free(numOccurrenceT);
189     fclose(fp);
190 
191 }

 

   

 

2.init()

 
 1 void init() {
 2     static int initialized=0;
 3     register int i;
 4     int critLit = 0, lit;
 5     int *clptr;
 6     ticks_per_second = sysconf(_SC_CLK_TCK);
 7     statNumGWalks = 0; //how often a gradient walk was done
 8     statNumSmooth = 0; //how often a smoothing has been done.
 9     statNumWeight = 0; //how often a smoothing has been done.
10     statXOROps = 0;
11     statClSearch=0;
12     numFalse = 0;
13     numWeight = 0;
14 
15     for (i = 1; i <= numVars; i++) {
16         if ((!keep_assig)||(!initialized)){//new assigment should be generated
17             atom[i] = rand() % 2;
18         }
19         score[i] = 0;
20         varLastChange[i] = -1; //-1 means never changed
21     }
22     initialized = !initialized;
23     //pass trough all clauses and apply the assignment previously generated
24     for (i = 1; i <= numClauses; i++) {
25         clptr = & clause[i][0];
26         numTrueLit[i] = 0;
27         whereWeight[i] = -1;
28         whereFalseOrCritVar[i] = 0;
29         while ((lit = *clptr)) {
30             if (atom[abs(lit)] == (lit > 0)) {
31                 numTrueLit[i]++;
32                 critLit = lit;
33 #ifdef XOR
34                 whereFalseOrCritVar[i] ^= abs(lit);
35 #endif
36             }
37             clptr++;
38         }
39         if (numTrueLit[i] == 1) {
40             //if the clause has only one literal that causes it to be sat,
41             //then this var. will break the sat of the clause if flipped.
42 #ifndef XOR
43             whereFalseOrCritVar[i] = abs(critLit);
44 #endif
45             score[abs(critLit)]--;
46         } else if (numTrueLit[i] == 0) {
47             //add this clause to the list of unsat caluses.
48             falseClause[numFalse] = i;
49             whereFalseOrCritVar[i] = numFalse;
50             numFalse++;
51 
52             //if the clause is unsat fliping any variable from it will make it sat
53             //-> increase the score of all variables within this clause
54             clptr = & clause[i][0];
55             while ((lit = *clptr)) {
56                 score[abs(lit)]++;
57                 clptr++;
58             }
59         }
60         clauseWeight[i] = BASECW;
61     }
62     numDecVar = 0;
63     //add all variables that are decreasing to the list of decreasing variables.
64     for (i = 1; i <= numVars; i++)
65         if (getScore(i) > 0) {
66             decVar[numDecVar] = i;
67             numDecVar++;
68             isCandVar[i] = 1;
69         } else {
70             isCandVar[i] = 0;
71         }
72 }

 

   

 

3. smooth2()

 
 1 void  smooth2() { //for all weighted !!!satisfied!!! clauses decrease the score by 1
 2     register int i, c, var;
 3     for (i = 0; i < numWeight; i++) {
 4         c = weightedClause[i];
 5         if (numTrueLit[c] > 0) {
 6             if (--clauseWeight[c] == BASECW) { //remove from the list of weighted clauses
 7                 numWeight--;
 8                 weightedClause[i] = weightedClause[numWeight];
 9                 whereWeight[weightedClause[i]] = i;
10                 whereWeight[c] = -1;
11                 i--;
12             }
13             if (numTrueLit[c] == 1) {
14                 var = whereFalseOrCritVar[c];
15                 //clause lost one weight and whereFalse had this weight as negative, so we have to add one to the weigth of var
16                 adjScore(var, 1);
17                 if ((getScore(var) > 0) && (!isCandVar[var]) && (varLastChange[var] < flip - 1)) {
18                     isCandVar[var] = 1;
19                     decVar[numDecVar] = var;
20                     numDecVar++;
21                 }
22             }
23         }
24     }
25     statNumSmooth++;
26 }

 

   

 

4. updateWeights()

 
 1 void  updateWeights() { //for all unsat clauses increase the weight by 1.
 2     statNumWeight++;
 3     int i, j;
 4     int c, var;
 5     for (i = 0; i < numFalse; i++) {
 6         c = falseClause[i];
 7         clauseWeight[c]++;
 8         if ((whereWeight[c] == -1) && (clauseWeight[c] > BASECW)) { //add to the list of weigthedClause
 9             weightedClause[numWeight] = c;
10             whereWeight[c] = numWeight;
11             numWeight++;
12         }
13         j = 0;
14         while ((var = abs(clause[c][j]))) {
15             score[var]++;
16             if ((!isCandVar[var]) && (getScore(var) > 0) && (varLastChange[var] < flip - 1)) {
17                 isCandVar[var] = 1;
18                 decVar[numDecVar] = var;
19                 numDecVar++;
20             }
21             j++;
22         }
23     }
24 }

 

   

 

5.pickVar()

 
 1 void pickVar() {
 2     register int i, j;
 3     int var;
 4     int bestScore = -numClauses;
 5     double probAge = 1.0, baseAge;
 6     int varChanged = -1;
 7     int scoreVar;
 8     int *clptr;
 9     int rClause; //randomly choosen clause.
10     //g2Wsat part - the greedy part - if there is a variable that decreases the number of variables then choose the best one.
11 
12     if (numDecVar > 0) {
13         //find the variable with the best score, and the following variable with same score.
14         for (i = 0; i < numDecVar; i++) {
15             var = decVar[i];
16             scoreVar = getScore(var);
17             if (scoreVar > 0) {
18                 if (bestScore < scoreVar) {
19                     bestScore = scoreVar;
20                     bestVar = var;
21                     varChanged = varLastChange[var];
22                 } else if (bestScore == scoreVar) //found one with the same score
23                     if (varLastChange[var] < varChanged) { //check if it is younger
24                         bestVar = var; //this var being younger is chosen.
25                         varChanged = varLastChange[var];
26                     }
27             } else {
28                 numDecVar--;
29                 decVar[i] = decVar[numDecVar];
30                 //whereDecVar[decVar[numDecVar]]=i;
31                 isCandVar[var] = 0;
32                 i--;
33             }
34         }
35     }
36 
37     if (bestScore != -numClauses) {
38         statNumGWalks++;
39     } else {
40         //new probability distribution replacing adaptNovelty+
41         //a variable is YOUNG if it was flipped not long time ago
42         //a variable is OLD if it was flipped long ago in the past, or not at all
43         rClause = falseClause[pickClause()];
44         double sumProb = 0;
45         i = 0;
46         clptr = &clause[rClause][0];
47         while ((var = abs(*clptr))) {
48             scoreVar = getScore(var);
49             if (scoreVar < -300) //has to be limited because the score is weighted
50                 probs[i] = scorePow[300];
51             else {
52                 if (scoreVar > 0) {
53                     probs[i] = 1.0;
54                 } else {
55                     probs[i] = scorePow[abs(scoreVar)];
56                 }
57             }
58             baseAge = (double) (flip - varLastChange[var]) * inv_c3;
59             for (j = 0, probAge = 1.0; j < c2; j++)
60                 probAge *= baseAge;
61             probAge += 1.0;
62             probs[i] *= probAge;
63             sumProb += probs[i];
64             i++;
65             clptr++;
66         }
67         double randPosition = (double) (rand()) / (RAND_MAX+1.0) * sumProb;
68         for (i = i-1; i!=0; i--) {
69             sumProb -= probs[i];
70             if (sumProb <= randPosition)
71                 break;
72         }
73 
74 
75         bestVar = abs(clause[rClause][i]);
76 
77         if (sp < 1000) {
78             if (rand() % 1000 < sp)
79                 smooth2();
80         else
81             updateWeights();
82         }
83     }
84     return;
85 }

 

   

 

6.flipAtom()

 
  1 void flipAtom() {
  2     int var;
  3     int *ocptr; //occurrence pointer
  4     int *clptr; //clause pointer
  5     int tClause; //temporary clause variable
  6     int xMakesSat; //tells which literal of x will make the clauses where it appears sat.
  7     if (atom[bestVar] == 1)
  8         xMakesSat = -bestVar; //if x=1 then all clauses containing -x will be made sat after fliping bestVar
  9     else
 10         xMakesSat = bestVar; //if x=0 then all clauses containing x will be made sat after fliping bestVar
 11 
 12     atom[bestVar] = 1 - atom[bestVar];
 13     //all Neighbours of x with score>0 are considered candVars without taking into account if they are in decVar or not.
 14     //trough this mechanism we can avoid that a variable that was fliped and increased the number of false variable is added to the
 15     //decVar array - this variable is not promissing.
 16 
 17     clptr=&neighbourVar[bestVar][0];
 18     while ((var = abs(*clptr))) {
 19         isCandVar[var] = (getScore(var) > 0);
 20         clptr++;
 21     }
 22 
 23     //1. all clauses that contain the literal xMakesSat will become SAT, if they where not already sat.
 24     ocptr=&occurrence[GETOCCPOS(xMakesSat)][0];
 25     while ((tClause = *ocptr)) {
 26         //tClause = occurrence[xMakesSat + numVars][i];
 27         //if the clause is unsat it will become SAT so it has to be removed from the list of unsat-clauses.
 28         if (numTrueLit[tClause] == 0) {
 29             //remove from unsat-list
 30             falseClause[whereFalseOrCritVar[tClause]] = falseClause[--numFalse]; //overwrite this clause with the last clause in the list.
 31             whereFalseOrCritVar[falseClause[numFalse]] = whereFalseOrCritVar[tClause];
 32             whereFalseOrCritVar[tClause] = 0;
 33 #ifndef XOR
 34             whereFalseOrCritVar[tClause] = bestVar; //this variable is now critically responsible for satisfying tClause
 35 #endif
 36             //adapt the scores of the variables
 37             //the score of x has to be decreased by one because x is critical and will break this clause if fliped.
 38             decScore(bestVar, tClause);
 39             //the scores of all variables from tClause have to be decreased by one because tClause is not UNSAT any more
 40             //j = 0;
 41             statinc0++;
 42             clptr= &clause[tClause][0];
 43             while ((var = abs(*clptr))) {
 44                 decScore(var, tClause);
 45                 //j++;
 46                 clptr++;
 47             }
 48         } else {
 49             //if the clause is satisfied by only one literal then the score has to be increased by one for this var.
 50             //because fliping this variable will no longer break the clause
 51             if (numTrueLit[tClause] == 1) {
 52                 incScore(whereFalseOrCritVar[tClause], tClause);
 53                 statinc1++;
 54             }
 55         }
 56         //if the number of numTrueLit[tClause]>=2 then nothing will change in the scores
 57         numTrueLit[tClause]++; //the number of true Lit is increased.
 58         statinc2++;
 59 #ifdef XOR
 60         whereFalseOrCritVar[tClause] ^= bestVar;
 61 #endif
 62         ocptr++;
 63     }
 64 
 65     //2. all clauses that contain the literal -xMakesSat=0 will not be longer satisfied by variable x.
 66     //all this clauses contained x as a satisfying literal
 67     //i = 0;
 68     ocptr=&occurrence[GETOCCPOS(-xMakesSat)][0];
 69     while ((tClause = *ocptr)) {
 70 #ifdef XOR
 71         whereFalseOrCritVar[tClause] ^= bestVar;
 72 #endif
 73         if (numTrueLit[tClause] == 1) { //then xMakesSat=1 was the satisfying literal.
 74             //this clause gets unsat.
 75             falseClause[numFalse] = tClause;
 76             whereFalseOrCritVar[tClause] = numFalse;
 77             numFalse++;
 78             //the score of x has to be increased by one because it is not breaking any more for this clause.
 79             incScore(bestVar, tClause);
 80             statdec1++;
 81             //the scores of all variables have to be increased by one ; inclusive x because flipping them will make the clause again sat
 82 
 83             clptr = &clause[tClause][0];
 84             while ((var = abs(*clptr))) {
 85                 incScore(var, tClause);
 86                 clptr++;
 87             }
 88         } else if (numTrueLit[tClause] == 2) { //find which literal is true and make it critical and decrease its score
 89             statdec2++;
 90 #ifdef XOR
 91             decScore(whereFalseOrCritVar[tClause],tClause);
 92 #else
 93             clptr = &clause[tClause][0];
 94             while ((var = abs(*clptr))) {
 95                 statClSearch++;
 96                 if (((*clptr > 0) == atom[var])) { //x can not be the var anymore because it was flipped //&&(xMakesSat!=var)
 97                     whereFalseOrCritVar[tClause] = var;
 98                     decScore(var, tClause);
 99                     break;
100                 }
101                 clptr++;
102             }
103 #endif
104         }
105         numTrueLit[tClause]--;
106         statdec3++;
107         ocptr++;
108     }
109 
110     //acoordant to G2WSAT only the scores of variables within neighbourVar[x] have changed.
111     clptr= &neighbourVar[bestVar][0];
112     while ((var = *clptr)) {
113         if ((getScore(var) > 0) && (!isCandVar[var])) { //is not in the list of decreasing variables
114             //add to decVar
115             decVar[numDecVar] = var;
116             //whereDecVar[var]=numDecVar;
117             numDecVar++;
118         }
119         clptr++;
120     }
121 }

 

   

 

7.main()

 
 1 int main(int argc, char *argv[]) {
 2     tryTime = 0.;
 3     parseParameters(argc, argv);
 4     setCpuLimit();
 5     parseFile();
 6     printFormulaProperties();
 7     setupSparrowParameters(); //call only after parsing file!!!
 8     //Initialize the look up table of Sparrow
 9     initSparrow();
10     setupSignalHandler();
11     printSolverParameters();
12     srand(seed);
13 
14     allowedFlips = maxFlips;
15 
16     for (tryn = 0; tryn < maxTries; tryn++) {
17         init();
18         bestNumFalse = numClauses;
19         if (use_luby) {
20             maxFlips = luby() * luby_base;
21             sp = sparray[tryn%num_sp];
22             //fprintf(stderr, "c sp= %4d next restart after %4lld * %6d = %7lld flips\n", sp, maxFlips / luby_base, luby_base, maxFlips);
23         }
24         for (flip = 1; flip <= maxFlips; flip++) {
25             if (numFalse == 0)
26                 break;
27             pickVar();
28             flipAtom();
29             varLastChange[bestVar] = flip;
30             printStatsEndFlip(); //update bestNumFalse
31             totalFlips++;
32             if (totalFlips >= allowedFlips){
33                 maxTries = 0;
34                 break;
35             }
36 
37         }
38         tryTime = elapsed_seconds();
39         totalTime += tryTime;
40         if (numFalse == 0) {
41             if (!checkAssignment()) {
42                 fprintf(stderr, "c ERROR the assignment is not valid!");
43                 printf("c UNKNOWN");
44                 return 0;
45             } else {
46                 printEndStatistics();
47                 printf("s SATISFIABLE\n");
48                 if (printSol == 1)
49                     printSolution1line();
50                 return 10;
51             }
52         } else{;
53             //fprintf(stderr,"c UNKNOWN best(%4d) current(%4d) (%-15.5fsec)\n", bestNumFalse, numFalse, tryTime);
54         }
55     }
56     fprintf(stderr,"c UNKNOWN best(%4d) current(%4d) (%-15.5fsec)\n", bestNumFalse, numFalse, tryTime);
57     printEndStatistics();
58     if (maxTries > 1)
59         fprintf(stderr, "c %-30s: %-8.3fsec\n", "Mean time per try", totalTime / (double) tryn);
60     return 0;
61 }

 

   

 

posted on 2020-09-06 21:03  海阔凭鱼跃越  阅读(307)  评论(0)    收藏  举报