sat相关的集中文件格式类型说明
DIMACS
File formatThe benchmark file format will be in a simplified version of the DIMACS format:c
|
|
网址: http://www.satcompetition.org/2009/format-benchmarks2009.html |
|
drup
|
||
2007, 2009, and 2011. |
Citing this work
If you would like to reference DRUP or DRUP-trim in a publication, please cite the following paper: Heule, M.J.H., Hunt, Jr., W.A., and Wetzler, N. Trimming while checking clausal proofs. Formal Methods in Computer-Aided Design (FMCAD). IEEE (2013) 181-188 |
Downloads
We implemented two checkers for (D)RUP proofs:
patch -p1 < DRUPglucose.patch or for Minisat patch -p1 < DRUPminisat.patch After applying the patch, one can output a DRUP proof as follows: ./glucose FORMULA PROOF or for Minisat ./minisat FORMULA PROOF |
Usage
To make the executable, download the file above and compile it: gcc drup-trim.c -O2 -o drup-trim To run the checker: ./drup-trim FORMULA PROOF [CORE] with FORMULA being a CNF formula in DIMACS format and PROOF a proof for FORMULA in the DRUP format (see details below). Additionally one can specify a file CORE containing the unsatisfiable core in DIMACS format. |
Example
Below, a brief description of the DRUP format based on an example formula. The spacing in the examples is to improve readability. Consider the following formula in the DIMACS format. |
p cnf 4 8 1 2 -3 0 -1 -2 3 0 2 3 -4 0 -2 -3 4 0 1 3 4 0 -1 -3 -4 0 -1 2 4 0 1 -2 -4 0
A compact RUP proof for the above formula is: |
1 2 0 1 0 2 0 0
The method of deriving the redundant clauses in the proof is not important. It might be by resolution or some other means. It is only necessary that the soundness of the redundant clauses can be verified by a procedure called REVERSE UNIT-PROPAGATION (RUP for short). In the discussion, clauses are delimited by square brackets. Suppose that F is the input formula and R_1, ..., R_r are the redundant clauses that have been produced by the solver, with R_r = [] (the empty clause). The sequence R_1, ..., R_r is an RUP refutation of F if and only if: For each i from 1 through r, steps 1--3 below derive []:
One important disadvantage of checking RUP proofs is the cost to verify a proof. To counter this disadvantage, we propose the DRUP format (delete reverse unit propagation). The DRUP format extends the RUP format by allowing it to express clause elimination information within the proof format. |
1 2 0 d 1 2 -3 0 1 0 d 1 2 0 d 1 3 4 0 d 1 -2 -4 0 2 0 0
Apart from the redundant RUP clauses, a DRUP proof may contain lines with a 'd' prefix. These lines refer to clauses (original or learned) that can be deleted without influencing the proof checking. In the above example, all the deleted clauses are subsumed by added RUP clauses. In practice, however, the clauses that one wants to include in a DRUP proof are the clauses that are removed while reducing the (learned) clause database. |
1 /*************************************************************************************[drup-trim.c] 2 Copyright (c) 2013, Marijn Heule, Nathan Wetzler, Anton Belov 3 Last edit, December 4, 2013 4 5 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 6 associated documentation files (the "Software"), to deal in the Software without restriction, 7 including without limitation the rights to use, copy, modify, merge, publish, distribute, 8 sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 9 furnished to do so, subject to the following conditions: 10 11 The above copyright notice and this permission notice shall be included in all copies or 12 substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 15 NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 16 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 18 OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 **************************************************************************************************/ 20 21 #includedrup-trim.c22 #include 23 #include 24 #include 25 26 #define TIMEOUT 20000 27 #define BIGINIT 1000000 28 #define INIT 8 29 #define END 0 30 #define UNSAT 0 31 #define SAT 1 32 #define EXTRA 2 33 #define MARK 3 34 #define ERROR -1 35 36 struct solver { FILE *inputFile, *proofFile, *coreFile, *lemmaFile, *traceFile; 37 int *DB, nVars, nClauses, timeout, mask, delete, *falseStack, *false, *forced, 38 *processed, *assigned, count, *base, *used, *max, *delinfo; 39 struct timeval start_time; 40 long mem_used, start, time, adsize, adlemmas, *reason, lemmas, arcs; }; 41 42 long **wlist; 43 long *adlist; 44 int *buffer; // ANTON: to be used as local buffer in parse() and verify() 45 46 #define ASSIGN(a) { S->false[-(a)] = 1; *(S->assigned++) = -(a); } 47 #define ADD_WATCH(l,m) { if (S->used[(l)] + 1 == S->max[(l)]) { S->max[(l)] *= 1.5; \ 48 wlist[(l)] = (long *) realloc(wlist[(l)], sizeof(long) * S->max[(l)]); } \ 49 wlist[(l)][ S->used[(l)]++ ] = (m); wlist[(l)][ S->used[(l)] ] = END; } 50 51 // +ANTON: convenience method for printing clauses 52 inline void printClause(int* clause) 53 { 54 while(*clause) { printf("%d ", *clause++); } 55 printf("0\n"); 56 } 57 // -ANTON 58 59 inline void addWatch (struct solver* S, int* clause, int index) { 60 int lit = clause[ index ]; 61 if (S->used[lit] + 1 == S->max[lit]) { S->max[lit] *= 1.5; 62 wlist[lit] = (long*) realloc(wlist[lit], sizeof(long) * S->max[lit]); } 63 wlist[lit][ S->used[lit]++ ] = ((long) (((clause) - S->DB)) << 1) + S->mask; 64 wlist[lit][ S->used[lit] ] = END; } 65 66 inline void removeWatch (struct solver* S, int* clause, int index) { 67 int lit = clause[index]; long *watch = wlist[lit]; 68 for (;;) { 69 int* _clause = S->DB + (*(watch++) >> 1); 70 if (_clause == clause) { 71 watch[-1] = wlist[lit][ --S->used[lit] ]; 72 wlist[lit][ S->used[lit] ] = END; return; } } } 73 74 inline void markWatch (struct solver* S, int* clause, int index, int offset) { 75 long* watch = wlist[ clause[ index ] ]; 76 for (;;) { 77 int *_clause = (S->DB + (*(watch++) >> 1) + (long) offset); 78 if (_clause == clause) { watch[-1] |= 1; return; } } } 79 80 inline void markClause (struct solver* S, int* clause, int index) { 81 //printf("marking clause: "); printClause(clause); // ANTON 82 S->arcs++; 83 if (S->traceFile) fprintf(S->traceFile, "%i ", clause[index - 1] >> 1); 84 if ((clause[index - 1] & 1) == 0) { 85 clause[index - 1] |= 1; 86 if (S->lemmaFile) { 87 *(S->delinfo++) = S->time; 88 *(S->delinfo++) = (int) (clause - S->DB) + index; } 89 if (clause[1 + index] == 0) return; 90 markWatch (S, clause, index, -index); 91 markWatch (S, clause, 1 + index, -index); } 92 while (*clause) S->false[ *(clause++) ] = MARK; } 93 94 void analyze (struct solver* S, int* clause) { // Mark all clauses involved in conflict 95 //printf("entering analyze()\n"); // ANTON 96 markClause (S, clause, 0); 97 while (S->assigned > S->falseStack) { 98 int lit = *(--S->assigned); 99 if ((S->false[ lit ] == MARK) && 100 (S->reason[ abs(lit) ]) ) 101 markClause (S, S->DB+S->reason[ abs(lit) ], -1); 102 S->false[ lit ] = (S->assigned < S->forced); } 103 if (S->traceFile) fprintf(S->traceFile, "0\n"); 104 S->processed = S->assigned = S->forced; } 105 106 int propagate (struct solver* S) { // Performs unit propagation 107 int *start[2], check = 0; 108 int i, lit, _lit = 0; long *watch, *_watch; 109 start[0] = start[1] = S->processed; 110 flip_check:; 111 check ^= 1; 112 while (start[check] < S->assigned) { // While unprocessed false literals 113 lit = *(start[check]++); // Get first unprocessed literal 114 if (lit == _lit) watch = _watch; 115 else watch = wlist[ lit ]; // Obtain the first watch pointer 116 while (*watch != END) { // While there are watched clauses (watched by lit) 117 if ((*watch & 1) != check) { 118 watch++; continue; } 119 int *clause = S->DB + (*watch / 2); // Get the clause from DB 120 if (S->false[ -clause[0] ] || 121 S->false[ -clause[1] ]) { 122 watch++; continue; } 123 if (clause[0] == lit) clause[0] = clause[1]; // Ensure that the other watched literal is in front 124 for (i = 2; clause[i]; ++i) // Scan the non-watched literals 125 if (S->false[ clause[i] ] == 0) { // When clause[j] is not false, it is either true or unset 126 clause[1] = clause[i]; clause[i] = lit; // Swap literals 127 ADD_WATCH (clause[1], *watch); // Add the watch to the list of clause[1] 128 *watch = wlist[lit][ --S->used[lit] ]; // Remove pointer 129 wlist[lit][ S->used[lit] ] = END; 130 goto next_clause; } // Goto the next watched clause 131 clause[1] = lit; watch++; // Set lit at clause[1] and set next watch 132 if (!S->false[ clause[0] ]) { // If the other watched literal is falsified, 133 ASSIGN (clause[0]); // A unit clause is found, and the reason is set 134 S->reason[abs(clause[0])] = ((long) ((clause)-S->DB)) + 1; 135 if (!check) { 136 start[0]--; _lit = lit; _watch = watch; 137 goto flip_check; } } 138 else { analyze(S, clause); return UNSAT; } // Found a root level conflict -> UNSAT 139 next_clause: ; } } // Set position for next clause 140 if (check) goto flip_check; 141 S->processed = S->assigned; 142 return SAT; } // Finally, no conflict was found 143 144 int verify (struct solver *S) { 145 long ad, d = 0; 146 int flag, check, size; 147 int *clause; 148 int *lemmas = (S->DB + S->lemmas); 149 int *last = lemmas; 150 int *end = lemmas; 151 int checked = S->adlemmas; 152 int *delstack; 153 154 S->time = lemmas[-1]; 155 if (S->lemmaFile) { 156 delstack = (int *) malloc (sizeof(int) * S->count * 2); 157 S->delinfo = delstack; } 158 159 if (S->traceFile) fprintf(S->traceFile, "%i 0 ", S->count); 160 161 if (S->processed < S->assigned) 162 if (propagate (S) == UNSAT) { 163 printf("c got UNSAT propagating in the input instance\n"); 164 goto postprocess; 165 } 166 S->forced = S->processed; 167 168 for (;;) { 169 flag = size = 0; 170 S->time = lemmas[-1]; 171 clause = lemmas; 172 173 do { 174 ad = adlist[ checked++ ]; d = ad & 1; 175 int* c = S->DB + (ad >> 1); 176 if (d && c[1]) { 177 if (S->reason[ abs(c[0]) ] - 1 == (ad >> 1) ) continue; 178 removeWatch(S, c, 0); 179 removeWatch(S, c, 1); } 180 } 181 while (d); 182 183 while (*lemmas) { 184 int lit = *(lemmas++); 185 if ( S->false[ -lit ]) flag = 1; 186 if (!S->false[ lit ]) { 187 if (size <= 1) { 188 lemmas[ -1 ] = clause[ size ]; 189 clause[ size ] = lit; } 190 buffer[ size++ ] = lit; } } 191 192 if (clause[1]) { 193 addWatch (S, clause, 0); 194 addWatch (S, clause, 1); } 195 196 lemmas += EXTRA; 197 198 if (flag ) adlist[ checked - 1 ] = 0; 199 if (flag ) continue; // Clause is already satisfied 200 if (size == 0) { printf("c conflict claimed, but not detected\n"); return SAT; } 201 202 if (size == 1) { 203 ASSIGN (buffer[0]); S->reason[abs(buffer[0])] = ((long) ((clause)-S->DB)) + 1; 204 S->forced = S->processed; 205 if (propagate (S) == UNSAT) goto start_verification; } 206 207 if (((long) (lemmas - S->DB)) >= S->mem_used) break; // Reached the end of the proof without a conflict; 208 } 209 210 printf("c no conflict\n"); 211 return SAT; 212 213 start_verification:; 214 printf("c parsed formula and detected empty clause; start verification\n"); 215 216 S->forced = S->processed; 217 lemmas = clause - EXTRA; 218 219 for (;;) { 220 size = 0; 221 clause = lemmas + EXTRA; 222 223 do { 224 ad = adlist[ --checked ]; 225 d = ad & 1; 226 int* c = S->DB + (ad >> 1); 227 if (d && c[1]) { 228 if (S->reason[ abs(c[0]) ] - 1 == (ad >> 1)) continue; 229 addWatch(S, c, 0); 230 addWatch(S, c, 1); } 231 } 232 while (d); 233 234 S->time = clause[-1]; 235 236 if (clause[1]) { 237 removeWatch(S, clause, 0); 238 removeWatch(S, clause, 1); } 239 240 if (ad == 0) goto next_lemma; 241 242 while (*clause) { 243 int lit = *(clause++); 244 if ( S->false[ -lit ]) flag = 1; 245 if (!S->false[ lit ]) 246 buffer[ size++ ] = lit; } 247 248 if (flag && size == 1) { 249 do { S->false[*(--S->forced)] = 0; } 250 while (*S->forced != -buffer[0]); 251 S->processed = S->assigned = S->forced; } 252 253 if (S->time & 1) { 254 int i; 255 struct timeval current_time; 256 gettimeofday(¤t_time, NULL); 257 int seconds = (int) (current_time.tv_sec - S->start_time.tv_sec); 258 if (seconds > S->timeout) printf("s TIMEOUT\n"), exit(0); 259 260 if (S->traceFile) { 261 fprintf(S->traceFile, "%lu ", S->time >> 1); 262 for (i = 0; i < size; ++i) fprintf(S->traceFile, "%i ", buffer[i]); 263 fprintf(S->traceFile, "0 "); } 264 265 for (i = 0; i < size; ++i) { ASSIGN(-buffer[i]); S->reason[abs(buffer[i])] = 0; } 266 if (propagate (S) == SAT) return SAT; } 267 268 clause = lemmas + EXTRA; 269 270 next_lemma:; 271 272 if (lemmas + EXTRA == last) break; 273 while (*(--lemmas)); } 274 275 postprocess:; 276 int marked, count = 0; 277 lemmas = S->DB + S->start; 278 while (lemmas + EXTRA <= last) { 279 if (*(lemmas++) & 1) count++; 280 while (*lemmas++); } 281 printf("c %i of %i clauses in core\n", count, S->nClauses); 282 283 // print the core clauses to coreFile in DIMACS format 284 if (S->coreFile) { 285 fprintf(S->coreFile, "p cnf %i %i\n", S->nVars, count); 286 lemmas = S->DB + S->start; 287 while (lemmas + EXTRA <= last) { 288 marked = *(lemmas++) & 1; 289 while (*lemmas) { 290 if (marked) fprintf(S->coreFile, "%i ", *lemmas); 291 lemmas++; } 292 293 if (marked) fprintf(S->coreFile, "0\n"); 294 lemmas++; } 295 fclose(S->coreFile); } 296 297 // print the core lemmas to lemmaFile in DRUP format 298 if (S->lemmaFile) S->delinfo -= 2; 299 int lcount = 0; count = 0; 300 while (lemmas + EXTRA <= end) { 301 lcount++; 302 S->time = *lemmas; 303 marked = *(lemmas++) & 1; 304 if (marked) count++; 305 while (*lemmas) { 306 if (marked && S->lemmaFile) 307 fprintf(S->lemmaFile, "%i ", *lemmas); 308 lemmas++; } 309 lemmas++; 310 311 if (S->lemmaFile == NULL) continue; 312 if (marked) fprintf(S->lemmaFile, "0\n"); 313 314 while (*S->delinfo == S->time) { 315 clause = S->DB + S->delinfo[1]; 316 fprintf(S->lemmaFile, "d "); 317 while (*clause) fprintf(S->lemmaFile, "%i ", *(clause++)); 318 fprintf(S->lemmaFile, "0\n"); 319 S->delinfo -= 2; } 320 } 321 printf("c %i of %i lemmas in core using %lu resolution steps\n", count, lcount, S->arcs); 322 323 // print the resolution graph to traceFile in trace-check format 324 if (S->traceFile) { 325 lemmas = S->DB + S->start; 326 while (lemmas + EXTRA <= last) { 327 marked = *(lemmas++) & 1; 328 if (marked) fprintf(S->traceFile, "%i ", lemmas[-1] >> 1); 329 while (*lemmas) { 330 if (marked) fprintf(S->traceFile, "%i ", *lemmas); 331 lemmas++; } 332 if (marked) fprintf(S->traceFile, "0 0\n"); 333 lemmas++; } 334 fclose(S->traceFile); } 335 336 return UNSAT; } 337 338 unsigned int getHash (int* marks, int mark, int* input, int size) { 339 unsigned int i, sum = 0, prod = 1, xor = 0; 340 for (i = 0; i < size; ++i) { 341 prod *= input[i]; 342 sum += input[i]; 343 xor ^= input[i]; 344 marks[ input[i] ] = mark; } 345 346 return (1023 * sum + prod ^ (31 * xor)) % BIGINIT; } 347 348 long matchClause (struct solver* S, long *clauselist, int listsize, int* marks, int mark, int* input, int size) { 349 int i, matchsize; 350 for (i = 0; i < listsize; ++i) { 351 int *clause = S->DB + clauselist[ i ]; 352 matchsize = 0; 353 while (*clause) { 354 if (marks[ *clause ] != mark) goto match_next; 355 matchsize++; 356 clause++; } 357 358 if (size == matchsize) { 359 long result = clauselist[ i ]; 360 clauselist[ i ] = clauselist[ --listsize ]; 361 return result; } 362 363 match_next:; 364 } 365 printf("c error: could not match deleted clause "); 366 for (i = 0; i < size; ++i) printf("%i ", input[i]); 367 printf("\ns MATCHING ERROR\n"); 368 exit(0); 369 return 0; 370 } 371 372 int parse (struct solver* S) { 373 int tmp; 374 int del, mark, *marks; 375 long **hashTable; 376 int *hashUsed, *hashMax; 377 378 do { tmp = fscanf (S->inputFile, " cnf %i %i \n", &S->nVars, &S->nClauses); // Read the first line 379 if (tmp > 0 && tmp != EOF) break; tmp = fscanf (S->inputFile, "%*s\n"); } // In case a commment line was found 380 while (tmp != 2 && tmp != EOF); // Skip it and read next line 381 int nZeros = S->nClauses, in, out, n = S->nVars; 382 383 // ANTON: the buffer will be re-used in verify(); main() should free() 384 if ((buffer = (int*)malloc(S->nVars * sizeof(int))) == NULL) return ERROR; 385 386 S->mem_used = 0; // The number of integers allocated in the DB 387 388 long size; 389 long DBsize = S->mem_used + BIGINIT; 390 S->DB = (int*) malloc(DBsize * sizeof(int)); 391 if (S->DB == NULL) { free(buffer); return ERROR; } 392 393 S->arcs = 0; 394 S->count = 1; 395 S->adsize = 0; 396 S->falseStack = (int*) malloc((n + 1) * sizeof(int)); // Stack of falsified literals -- this pointer is never changed 397 S->forced = S->falseStack; // Points inside *falseStack at first decision (unforced literal) 398 S->processed = S->falseStack; // Points inside *falseStack at first unprocessed literal 399 S->assigned = S->falseStack; // Points inside *falseStack at last unprocessed literal 400 S->reason = (long*) malloc(( n + 1) * sizeof(long)); // Array of clauses 401 S->used = (int *) malloc((2 * n + 1) * sizeof(int )); S->used += n; // Labels for variables, non-zero means false 402 S->max = (int *) malloc((2 * n + 1) * sizeof(int )); S->max += n; // Labels for variables, non-zero means false 403 S->false = (int *) malloc((2 * n + 1) * sizeof(int )); S->false += n; // Labels for variables, non-zero means false 404 405 int i; for (i = 1; i <= n; ++i) { S->reason[i] = 0; 406 S->falseStack[i] = 0; 407 S->false[i] = S->false[-i] = 0; 408 S->used [i] = S->used [-i] = 0; 409 S->max [i] = S->max [-i] = INIT; } 410 411 wlist = (long**) malloc (sizeof(long*) * (2*n+1)); wlist += n; 412 413 for (i = 1; i <= n; ++i) { wlist[ i] = (long*) malloc (sizeof(long) * S->max[ i]); wlist[ i][0] = END; 414 wlist[-i] = (long*) malloc (sizeof(long) * S->max[-i]); wlist[-i][0] = END; } 415 416 int admax = BIGINIT; 417 adlist = (long*) malloc(sizeof(long) * admax); 418 419 marks = (int*) malloc (sizeof(int) * (2*n+1)); marks += n; 420 for (i = 1; i <= n; i++) marks[i] = marks[-i] = 0; 421 mark = 0; 422 423 hashTable = (long**) malloc (sizeof (long*) * BIGINIT); 424 hashUsed = (int * ) malloc (sizeof (int ) * BIGINIT); 425 hashMax = (int * ) malloc (sizeof (int ) * BIGINIT); 426 for (i = 0; i < BIGINIT; i++) { 427 hashUsed [ i ] = 0; 428 hashMax [ i ] = INIT; 429 hashTable[ i ] = (long*) malloc (sizeof(long) * hashMax[i]); } 430 431 int fileSwitchFlag = 0; 432 size = 0; 433 S->start = S->mem_used; 434 while (1) { 435 int lit = 0; tmp = 0; 436 fileSwitchFlag = nZeros <= 0; 437 438 if (size == 0) { 439 if (!fileSwitchFlag) tmp = fscanf (S->inputFile, " d %i ", &lit); 440 else tmp = fscanf (S->proofFile, " d %i ", &lit); 441 if (tmp == EOF && !fileSwitchFlag) fileSwitchFlag = 1; 442 del = tmp > 0; } 443 444 if (!lit) { 445 if (!fileSwitchFlag) tmp = fscanf (S->inputFile, " %i ", &lit); // Read a literal. 446 else tmp = fscanf (S->proofFile, " %i ", &lit); 447 if (tmp == EOF && !fileSwitchFlag) fileSwitchFlag = 1; } 448 if (tmp == EOF && fileSwitchFlag) break; 449 if (abs(lit) > n) { printf("c illegal literal %i due to max var %i\n", lit, n); exit(0); } 450 if (!lit) { 451 unsigned int hash = getHash (marks, ++mark, buffer, size); 452 if (del) { 453 if (S->delete) { 454 long match = matchClause (S, hashTable[hash], hashUsed[hash], marks, mark, buffer, size); 455 hashUsed[hash]--; 456 if (S->adsize == admax) { admax *= 1.5; 457 adlist = (long*) realloc (adlist, sizeof(long) * admax); } 458 adlist[ S->adsize++ ] = (match << 1) + 1; } 459 del = 0; size = 0; continue; } 460 461 if (S->mem_used + size + EXTRA > DBsize) { 462 DBsize = (DBsize * 3) >> 1; 463 S->DB = (int *) realloc(S->DB, DBsize * sizeof(int)); } 464 int *clause = &S->DB[S->mem_used + 1]; 465 clause[-1] = 2 * S->count; S->count++; 466 for (i = 0; i < size; ++i) { clause[ i ] = buffer[ i ]; } clause[ i ] = 0; 467 S->mem_used += size + EXTRA; 468 469 if (hashUsed[hash] == hashMax[hash]) { hashMax[hash] *= 1.5; 470 hashTable[hash] = (long *) realloc(hashTable[hash], sizeof(long*) * hashMax[hash]); } 471 hashTable[ hash ][ hashUsed[hash]++ ] = (long) (clause - S->DB); 472 473 if (S->adsize == admax) { admax *= 1.5; 474 adlist = (long*) realloc (adlist, sizeof(long) * admax); } 475 adlist[ S->adsize++ ] = ((long) (clause - S->DB)) << 1; 476 477 if (nZeros == S->nClauses) S->base = clause; // change if ever used 478 if (!nZeros) S->lemmas = (long) (clause - S->DB); // S->lemmas is no longer pointer 479 if (!nZeros) S->adlemmas = S->adsize - 1; 480 481 if (nZeros > 0) { 482 if (!size || ((size == 1) && S->false[ clause[0] ])) // Check for empty clause or conflicting unit 483 return UNSAT; // If either is found return UNSAT; ANTON: memory leak here 484 else if (size == 1) { // Check for a new unit 485 if (!S->false[ -clause[0] ]) { 486 S->reason[abs(clause[0])] = ((long) ((clause)-S->DB)) + 1; 487 ASSIGN (clause[0]); } } // Directly assign new units 488 else { addWatch (S, clause, 0); addWatch (S, clause, 1); } 489 } 490 else if (!size) break; // Redundant empty clause claimed 491 size = 0; --nZeros; } // Reset buffer 492 else buffer[ size++ ] = lit; } // Add literal to buffer 493 494 S->DB = (int *) realloc(S->DB, S->mem_used * sizeof(int)); 495 496 for (i = 0; i < BIGINIT; i++) free(hashTable[i]); 497 free(hashTable); 498 free(hashUsed); 499 free(hashMax); 500 free(marks - S->nVars); 501 502 return SAT; } 503 504 void freeMemory(struct solver *S) { 505 free(S->DB); 506 free(S->falseStack); 507 free(S->reason); 508 free(adlist); 509 int i; for (i = 1; i <= S->nVars; ++i) { free(wlist[i]); free(wlist[-i]); } 510 free(S->used - S->nVars); 511 free(S->max - S->nVars); 512 free(S->false - S->nVars); 513 free(wlist - S->nVars); 514 if (buffer != 0) { free(buffer); } 515 return; 516 } 517 518 int main (int argc, char** argv) { 519 struct solver S; 520 521 S.inputFile = NULL; 522 S.proofFile = stdin; 523 S.coreFile = NULL; 524 S.lemmaFile = NULL; 525 S.traceFile = NULL; 526 S.timeout = TIMEOUT; 527 S.mask = 0; 528 S.delete = 1; 529 gettimeofday(&S.start_time, NULL); 530 531 int i, tmp = 0; 532 for (i = 1; i < argc; i++) { 533 if (argv[i][0] == '-') { 534 if (argv[i][1] == 'h') { 535 printf("usage: drup-trim [INPUT] [ ] [ "); 536 printf("where "); 537 printf(" -h print this command line option summary\n"); 538 printf(" -c CORE prints the unsatisfiable core to the file CORE\n"); 539 printf(" -l LEMMAS prints the core lemmas to the file LEMMAS\n"); 540 printf(" -r TRACE resolution graph in TRACECHECK format\n\n"); 541 printf(" -ttime limit in seconds (default %i)\n ", TIMEOUT); 542 printf(" -u default unit propatation (i.e., no core-first)\n"); 543 printf(" -p run in plain mode (i.e., ignore deletion information)\n\n"); 544 printf("and input and proof are specified as follows\n\n"); 545 printf(" INPUT input file in DIMACS format\n"); 546 printf(" PROOF proof file in DRUP format (stdin if no argument)\n\n"); 547 exit(0); 548 } 549 if (argv[i][1] == 'c') S.coreFile = fopen (argv[++i], "w"); 550 else if (argv[i][1] == 'l') S.lemmaFile = fopen (argv[++i], "w"); 551 else if (argv[i][1] == 'r') S.traceFile = fopen (argv[++i], "w"); 552 else if (argv[i][1] == 't') S.timeout = atoi(argv[++i]); 553 else if (argv[i][1] == 'u') S.mask = 1; 554 else if (argv[i][1] == 'p') S.delete = 0; 555 } 556 else { 557 tmp++; 558 if (tmp == 1) { 559 S.inputFile = fopen (argv[1], "r"); 560 if (S.inputFile == NULL) { 561 printf("c error opening \"%s\".\n", argv[i]); 562 return 1; } } 563 564 else if (tmp == 2) { 565 S.proofFile = fopen (argv[2], "r"); 566 if (S.proofFile == NULL) { 567 printf("c error opening \"%s\".\n", argv[i]); 568 return 1; } } 569 } 570 } 571 if (tmp == 1) printf("c reading proof from stdin\n"); 572 573 int parseReturnValue = parse(&S); 574 575 fclose (S.inputFile); 576 fclose (S.proofFile); 577 int sts = ERROR; 578 if (parseReturnValue == ERROR) printf("s MEMORY ALLOCATION ERROR\n"); 579 else if (parseReturnValue == UNSAT) printf("s TRIVIAL UNSAT\n"); 580 else if ((sts = verify (&S)) == UNSAT) printf("s VERIFIED\n"); 581 else printf("s NOT VERIFIED\n") ; 582 freeMemory(&S); 583 return (sts != UNSAT); // 0 on success, 1 on any failure 584 }
1 // rup-forward.c last edit: March 17, 2013 2 3 #includerup-forward.c4 5 #define END -9 6 #define MEM_MAX 1000000000 7 #define UNSAT 0 8 #define SAT 1 9 10 struct solver { FILE *file; int *DB, nVars, nClauses, mem_used, *falseStack, *false, *first, 11 *forced, *processed, *assigned; FILE *proofFile; }; 12 13 #define ASSIGN(a) { S->false[-(a)] = 1; *(S->assigned++) = -(a); } 14 #define ADD_WATCH(l,m) { S->DB[(m)] = S->first[(l)]; S->first[(l)] = (m); } 15 16 int* getMemory (struct solver *S, int mem_size) { 17 if (S->mem_used + mem_size > MEM_MAX) printf("Out of Memory\n"); 18 int *store = (S->DB + S->mem_used); 19 S->mem_used += mem_size; 20 return store; } 21 22 int* addClause (struct solver *S, int* input, int size) { 23 if (size > 1) { ADD_WATCH (input[0], S->mem_used); ADD_WATCH (input[1], S->mem_used + 1); } 24 int i, *clause = getMemory (S, size + 3) + 2; 25 for (i = 0; i < size; ++i) { clause[ i ] = input[ i ]; } clause[ i ] = 0; 26 return clause; } 27 28 int propagate (struct solver* S) { // Performs unit propagation 29 while (S->processed < S->assigned) { // While unprocessed false literals 30 int lit = *(S->processed++); // Get first unprocessed literal 31 int* watch = &S->first[ lit ]; // Obtain the first watch pointer 32 while (*watch != END) { // While there are watched clauses (watched by lit) 33 int i, *clause = (S->DB + *watch + 1); // Get the clause from DB 34 if (!clause[-2]) clause++; // Set the pointer to the first literal in the clause 35 if (clause[0] == lit) clause[0] = clause[1]; // Ensure that the other watched literal is in front 36 for (i = 2; clause[i]; ++i) // Scan the non-watched literals 37 if (S->false[ clause[i] ] == 0) { // When clause[j] is not false, it is either true or unset 38 clause[1] = clause[i]; clause[i] = lit; // Swap literals 39 int store = *watch; // Store the old watch 40 *watch = S->DB[ *watch ]; // Remove the watch from the list of lit 41 ADD_WATCH (clause[1], store); // Add the watch to the list of clause[1] 42 goto next_clause; } // Goto the next watched clause 43 clause[1] = lit; watch = (S->DB + *watch); // Set lit at clause[1] and set next watch 44 if ( S->false[ -clause[0] ]) continue; // If the other watched literal is satisfied continue 45 if (!S->false[ clause[0] ]) { // If the other watched literal is falsified, 46 ASSIGN (clause[0]); } // A unit clause is found, and the reason is set 47 else return UNSAT; // Found a root level conflict -> UNSAT 48 next_clause: ; } } // Set position for next clause 49 return SAT; } // Finally, no conflict was found 50 51 int verify (struct solver *S) { 52 int buffer [S->nVars]; 53 54 if (propagate (S) == UNSAT) return UNSAT; S->forced = S->processed; 55 56 for (;;) { 57 start:; 58 int flag = 0, size = 0, tmp = 0, lit; 59 printf("checking: "); 60 while (tmp >= 0) { 61 tmp = fscanf (S->proofFile, " %i ", &lit); // Read a literal. 62 if (!lit) break; 63 if ( S->false[ -lit ]) flag = 1; 64 if (!S->false[ lit ]) { 65 printf("%i ", lit); 66 buffer[ size++ ] = lit; } } // Assign literal and add literal to buffer 67 68 if (flag) goto start; 69 70 int i; for (i = 0; i < size; ++i) ASSIGN(-buffer[i]); 71 if (propagate (S) == SAT) return SAT; 72 printf("verified\n"); 73 74 while (S->assigned > S->forced) S->false[ (*(--S->assigned)) ] = 0; 75 S->processed = S->forced; 76 77 if (size == 1) { ASSIGN (buffer[0]); if (propagate (S) == UNSAT) return UNSAT; S->forced = S->processed; } 78 else addClause (S, buffer, size); 79 } 80 return SAT; } 81 82 int parse (struct solver* S) { 83 int tmp, lines; 84 do { tmp = fscanf (S->file, " p cnf %i %i \n", &S->nVars, &S->nClauses); // Read the first line 85 if (tmp > 0 && tmp != EOF) break; tmp = fscanf (S->file, "%*s\n"); } // In case a commment line was found 86 while (tmp != 2 && tmp != EOF); // Skip it and read next line 87 int nZeros = S->nClauses, buffer [S->nVars], size = 0, n = S->nVars; // Make a local buffer 88 89 S->mem_used = 0; // The number of integers allocated in the DB 90 S->falseStack = getMemory (S, n+1); // Stack of falsified literals -- this pointer is never changed 91 S->forced = S->falseStack; // Points inside *falseStack at first decision (unforced literal) 92 S->processed = S->falseStack; // Points inside *falseStack at first unprocessed literal 93 S->assigned = S->falseStack; // Points inside *falseStack at last unprocessed literal 94 S->false = getMemory (S, 2*n+1); S->false += n; // Labels for variables, non-zero means false 95 S->first = getMemory (S, 2*n+1); S->first += n; // Offset of the first watched clause 96 S->DB[ S->mem_used++ ] = 0; // Make sure there is a 0 before the clauses are loaded. 97 98 int i; for (i = 1; i <= n; ++i) { S->false[i] = S->false[-i] = 0; S->first[i] = S->first[-i] = END; } 99 100 while (nZeros > 0) { 101 int lit, *clause; tmp = fscanf (S->file, " %i ", &lit); // Read a literal. 102 if (!lit) { clause = addClause (S, buffer, size); // Add clause to data_base 103 if (!size || ((size == 1) && S->false[ clause[0] ])) // Check for empty clause or conflicting unit 104 return UNSAT; // If either is found return UNSAT 105 if ((size == 1) && !S->false[ -clause[0] ]) { // Check for a new unit 106 ASSIGN (clause[0]); } // Directly assign new units 107 size = 0; --nZeros; } // Reset buffer 108 else buffer[ size++ ] = lit; } // Add literal to buffer 109 110 return SAT; } 111 112 int memory[ MEM_MAX ]; 113 114 int main (int argc, char** argv) { 115 struct solver S; S.DB = memory; 116 S.file = fopen (argv[1], "r"); 117 if (S.file == NULL) { 118 printf("Error opening \"%s\".\n", argv[1]); 119 return 0; 120 } 121 S.proofFile = fopen (argv[2], "r"); 122 if (S.proofFile == NULL) { 123 printf("Error opening \"%s\".\n", argv[2]); 124 fclose (S.file); 125 return 0; 126 } 127 if (parse (&S) == UNSAT) printf("s TRIVIAL UNSAT\n"); 128 else if (verify (&S) == UNSAT) printf("s VERIFIED\n"); 129 else printf("s NOT VERIFIED\n") ; 130 fclose (S.file); 131 fclose (S.proofFile); 132 return 0; 133 }
drat
DRAT-trim is a satisfiability proof checking and trimming utility designed to validate proofs for all known satisfiability solving and preprocessing techniques. DRAT-trim can also emit trimmed formulas, optimized proofs, and TraceCheck+ dependency graphs. 详细信息见网址:https://www.cs.utexas.edu/~marijn/drat-trim/ 1 /************************************************************************************[drat-trim.c] 2 Copyright (c) 2014 Marijn Heule and Nathan Wetzler, The University of Texas at Austin. 3 Copyright (c) 2015-2018 Marijn Heule, The University of Texas at Austin. 4 Last edit, October 30, 2018 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 7 associated documentation files (the "Software"), to deal in the Software without restriction, 8 including without limitation the rights to use, copy, modify, merge, publish, distribute, 9 sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 10 furnished to do so, subject to the following conditions: 11 12 The above copyright notice and this permission notice shall be included in all copies or 13 substantial portions of the Software. 14 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 16 NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 19 OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 **************************************************************************************************/ 21 22 #includedrat-trim.c Core-first Unit PropagationThe unit propagation routine of DRAT-trim has been modified to give preference to clauses marked as necessary, which further reduces the number of "necessary" clauses. Dependency GraphsDRAT-trim also produces a dependency graph in the TraceCheck+ format. This format is a derivative of the TraceCheck resolution graph format, but allows for stronger dependencies. Dependency GraphsDRAT-trim also produces a dependency graph in the TraceCheck+ format. This format is a derivative of the TraceCheck resolution graph format, but allows for stronger dependencies. Optmized ProofsDRAT-trim can optionally produce optimized proofs conataining a subset of the input lemmas and extra deletion information gained during backward checking. Deletion InformationDRAT-trim is based on the DRAT (Deletion Resolution Asymmetric Tautology) proof format which includes lemma deletion instructions that can greatly reduce proof checking time. Trimmed FormulasTrimmed formulas can optionally be emitted from DRAT-trim. These are ordered subsets of the original formula where unnecessary clauses have been omitted. One application of this output is preprocessing for Minimal Unsatisfiable Subset (MUS) extractors. RAT ChecksDRAT-trim is an improvement over its predecessor DRUP-trim because it allows for a stronger form of redundancy, RAT. This check permits all known techniques including extended resolution, blocked clause addition, bounded variable addition, extended learning, and many more. |
|
求解器Relaxed_LCMDCBDL_newTech中涉及到的属性与函数:
FILE* drup_file; template static inline void binDRUP_strengthen(const Clause& c, Lit l, FILE* drup_file) static inline void binDRUP_flush(FILE* drup_file) |
|
bool Solver::simplifyLearnt_core() | |
bool Solver::simplifyLearnt_tier2() | |
bool Solver::addClause_(vec |
|
void Solver::removeClause(CRef cr) | |
lbool Solver::search(int& nof_conflicts) //在学习子句生成后 | |
solve_函数中当得到UNSAT结果后,有如下代码: if (drup_file && status == l_False) binDRUP_flush(drup_file); |
|
bool SimpSolver::addClause_(vec bool SimpSolver::strengthenClause(CRef cr, Lit l) |
|