OKlibrary
0.2.1.6
|
00001 /* Copyright 2001 Chu Min Li 00002 Satz215 is free software; you can redistribute it and/or modify it 00003 under the terms of the GNU General Public License as published by 00004 the Free Software Foundation and included in the OKlibrary; 00005 either version 3 of the License, or any later version. */ 00006 00019 /****************************************************************************/ 00020 /* Satz214 + Detection of implied literals suggested by Daniel Le Berre */ 00021 /* */ 00022 /* Maintained by Chu Min LI (cli@laria.u-picardie.fr) */ 00023 /* LaRIA, Universite de Picardie Jules Verne */ 00024 /* March 2001 */ 00025 /****************************************************************************/ 00026 00027 /* Version Satz215.1.c last modified the 25 sept. 2001. 00028 Now only up to 10*INIT_NB_CLAUSE ternary resolvents can be 00029 added into the formule in the preprocessing */ 00030 00031 /* Version Satz215.2.c last modified the 18 Oct. 2001. 00032 my_type is defined to be int 00033 redundant literal suppression and tautology clause detection 00034 in -s option (in build_simple_sat_instance) 00035 */ 00036 00037 #include <stdio.h> 00038 #include <stdlib.h> 00039 #include <limits.h> 00040 #include <stdbool.h> 00041 00042 #include <sys/times.h> 00043 #include <unistd.h> 00044 00045 typedef signed int my_type; 00046 typedef unsigned int my_unsigned_type; 00047 00049 #ifndef WORD_LENGTH 00050 # define WORD_LENGTH 100 00051 #endif 00052 00053 #define TRUE 1 00054 #define FALSE 0 00055 #define NONE -1 00056 00057 #define WEIGTH 5 00058 #define T 10 00059 00060 #define EXITCODE_PARAMETER_FAILURE 100 00061 #define EXITCODE_INPUT_ERROR 101 00062 #define EXITCODE_VERIFICATION_FAILED 102 00063 #define EXITCODE_SAT 10 00064 #define EXITCODE_UNSAT 20 00065 00066 #ifndef MAX_NUMBER_VARIABLES 00067 # define MAX_NUMBER_VARIABLES 200000 00068 #endif 00069 00070 #ifndef MAX_NUMBER_CLAUSES 00071 # define MAX_NUMBER_CLAUSES 800000 00072 #endif 00073 00074 #ifndef MAX_CLAUSE_LENGTH 00075 # define MAX_CLAUSE_LENGTH 1000 00076 #endif 00077 00078 00079 /* The tables of variables and clauses are statically allocated. Set macros 00080 MAX_NUMBER_CLAUSES, MAX_NUMBER_CLAUSES for compilation if necessary. 00081 */ 00082 #define tab_variable_size MAX_NUMBER_VARIABLES 00083 #define tab_clause_size MAX_NUMBER_CLAUSES 00084 00085 #define tab_unitclause_size \ 00086 ((tab_clause_size/4<2000) ? 2000 : tab_clause_size/4) 00087 #define my_tab_variable_size \ 00088 ((tab_variable_size/2<1000) ? 1000 : tab_variable_size/2) 00089 #define my_tab_clause_size \ 00090 ((tab_clause_size/2<2000) ? 2000 : tab_clause_size/2) 00091 #define my_tab_unitclause_size \ 00092 ((tab_unitclause_size/2<1000) ? 1000 : tab_unitclause_size/2) 00093 #define tab_literal_size 2*tab_variable_size 00094 #define double_tab_clause_size 2*tab_clause_size 00095 #define positive(literal) literal<NB_VAR 00096 #define negative(literal) literal>=NB_VAR 00097 #define get_var_from_lit(negative_literal) negative_literal-NB_VAR 00098 #define RESOLVANT_LENGTH 3 00099 #define RESOLVANT_SEARCH_THRESHOLD 5000 00100 #define complement(lit1, lit2) \ 00101 ((lit1<lit2) ? lit2-lit1 == NB_VAR : lit1-lit2 == NB_VAR) 00102 #define pop(stack) stack[--stack ## _fill_pointer] 00103 #define push(item, stack) stack[stack ## _fill_pointer++] = item 00104 #define satisfiable() CLAUSE_STACK_fill_pointer == NB_CLAUSE 00105 00106 #define NEGATIVE 0 00107 #define POSITIVE 1 00108 #define PASSIVE 0 00109 #define ACTIVE 1 00110 #define MAX_NODE_NUMBER 6000 00111 00112 struct node { 00113 int clause; 00114 struct node *next; 00115 }; 00116 00117 struct ressource { 00118 struct node *pnode; 00119 struct ressource *next; 00120 }; 00121 00122 int CLAUSE_NODES_pointer=MAX_NODE_NUMBER; 00123 00124 struct node *CLAUSE_NODES; 00125 struct ressource *ressources=NULL; 00126 00127 struct node *allocate_node() { 00128 struct ressource *pressource; 00129 if (CLAUSE_NODES_pointer == MAX_NODE_NUMBER) { 00130 CLAUSE_NODES = (struct node *)malloc(MAX_NODE_NUMBER * sizeof(struct node)); 00131 CLAUSE_NODES_pointer = 0; 00132 pressource= (struct ressource *)malloc(sizeof (struct ressource)); 00133 pressource->next = ressources; 00134 ressources=pressource; 00135 pressource->pnode = CLAUSE_NODES; 00136 } 00137 return &(CLAUSE_NODES[CLAUSE_NODES_pointer++]); 00138 } 00139 00140 void free_ressources() { 00141 struct ressource *pressource; 00142 while (ressources != NULL) { 00143 free(ressources->pnode); 00144 pressource = ressources; 00145 ressources = ressources->next; 00146 free(pressource); 00147 } 00148 } 00149 00150 struct node *node_neg_in[tab_variable_size]; 00151 struct node *node_pos_in[tab_variable_size]; 00152 struct node *in_resolv[tab_literal_size]; 00153 00154 int *neg_in[tab_variable_size]; 00155 int *pos_in[tab_variable_size]; 00156 my_type var_current_value[tab_variable_size]; 00157 my_type var_rest_value[tab_variable_size]; 00158 my_type var_state[tab_variable_size]; 00159 00160 int saved_clause_stack[tab_variable_size]; 00161 int saved_managedclause_stack[tab_variable_size]; 00162 my_unsigned_type nb_neg_clause_of_length2[tab_variable_size]; 00163 my_unsigned_type nb_neg_clause_of_length3[tab_variable_size]; 00164 my_unsigned_type nb_pos_clause_of_length2[tab_variable_size]; 00165 my_unsigned_type nb_pos_clause_of_length3[tab_variable_size]; 00166 00167 int reduce_if_negative_nb[tab_variable_size]; 00168 int reduce_if_positive_nb[tab_variable_size]; 00169 00170 int *sat[tab_clause_size]; 00171 my_type clause_state[tab_clause_size]; 00172 my_type clause_length[tab_clause_size]; 00173 00174 int VARIABLE_STACK_fill_pointer = 0; 00175 int CLAUSE_STACK_fill_pointer = 0; 00176 int UNITCLAUSE_STACK_fill_pointer = 0; 00177 int MANAGEDCLAUSE_STACK_fill_pointer = 0; 00178 00179 int VARIABLE_STACK[tab_variable_size]; 00180 int CLAUSE_STACK[tab_clause_size]; 00181 int UNITCLAUSE_STACK[tab_unitclause_size]; 00182 int MANAGEDCLAUSE_STACK[tab_clause_size]; 00183 00184 int TESTED_VAR_STACK[tab_variable_size]; 00185 int TESTED_VAR_STACK_fill_pointer=0; 00186 00187 int NB_VAR; 00188 int NB_CLAUSE; 00189 int INIT_NB_CLAUSE; 00190 my_type R = 3; 00191 00192 typedef unsigned long StatisticsCount; 00193 StatisticsCount NB_UNIT=0, NB_MONO=0, NB_BRANCHE=0, NB_BACK=0; 00194 00195 #define double_tab_clause_size 2*tab_clause_size 00196 00197 struct var_node { 00198 int var; 00199 int weight; 00200 struct var_node *next; 00201 }; 00202 00203 #define VAR_NODES1_nb 6 00204 int VAR_NODES1_index=0; 00205 struct var_node VAR_NODES1[10*VAR_NODES1_nb]; 00206 struct var_node *VAR_FOR_TEST1=NULL; 00207 00208 struct var_node *allocate_var_node1() { 00209 return &VAR_NODES1[VAR_NODES1_index++]; 00210 } 00211 00212 int test_flag[tab_variable_size]; 00213 00214 int MAX_REDUCED; 00215 int T_SEUIL; 00216 int H_SEUIL; 00217 00218 long NB_SECOND_SEARCH=0; 00219 long NB_SECOND_FIXED = 0; 00220 00221 void remove_clauses(register int *clauses) { 00222 register int clause; 00223 for(clause=*clauses; clause!=NONE; clause=*(++clauses)) { 00224 if (clause_state[clause] == ACTIVE) { 00225 clause_state[clause] = PASSIVE; 00226 push(clause, CLAUSE_STACK); 00227 } 00228 } 00229 } 00230 00231 int manage_clauses(register int *clauses) { 00232 register int clause; 00233 for(clause=*clauses; clause!=NONE; clause=*(++clauses)) { 00234 if (clause_state[clause] == ACTIVE) { 00235 switch (clause_length[clause]) { 00236 case 1: return FALSE; 00237 case 2: push(clause, UNITCLAUSE_STACK); 00238 push(clause, MANAGEDCLAUSE_STACK); 00239 clause_length[clause]--; break; 00240 default: clause_length[clause]--; 00241 push(clause, MANAGEDCLAUSE_STACK); 00242 } 00243 } 00244 } 00245 return TRUE; 00246 } 00247 00248 void simple_manage_clauses(register int *clauses) { 00249 register int clause; 00250 for(clause=*clauses; clause!=NONE; clause=*(++clauses)) { 00251 if (clause_state[clause] == ACTIVE) { 00252 switch (clause_length[clause]) { 00253 case 2: push(clause, UNITCLAUSE_STACK); 00254 push(clause, MANAGEDCLAUSE_STACK); 00255 clause_length[clause]--; break; 00256 default: clause_length[clause]--; 00257 push(clause, MANAGEDCLAUSE_STACK); 00258 } 00259 } 00260 } 00261 } 00262 00263 void my_simple_manage_clauses(register int *clauses) { 00264 register int clause; 00265 for(clause=*clauses; clause!=NONE; clause=*(++clauses)) { 00266 if (clause_state[clause] == ACTIVE) { 00267 switch (clause_length[clause]) { 00268 case 2: push(clause, UNITCLAUSE_STACK); 00269 clause_length[clause]--; break; 00270 default: clause_length[clause]--; 00271 push(clause, MANAGEDCLAUSE_STACK); 00272 } 00273 } 00274 } 00275 } 00276 00277 int my_manage_clauses(register int *clauses) { 00278 register int clause; 00279 for(clause=*clauses; clause!=NONE; clause=*(++clauses)) { 00280 if (clause_state[clause] == ACTIVE) { 00281 switch (clause_length[clause]) { 00282 case 1: return FALSE; 00283 case 2: push(clause, UNITCLAUSE_STACK); 00284 clause_length[clause]--; break; 00285 default: clause_length[clause]--; 00286 push(clause, MANAGEDCLAUSE_STACK); 00287 } 00288 } 00289 } 00290 return TRUE; 00291 } 00292 00293 void print_values(int nb_var) { 00294 FILE* fp_out; 00295 int i; 00296 fp_out = fopen("satx.sol", "w"); 00297 for (i=0; i<nb_var; i++) { 00298 if (var_current_value[i] == 1) 00299 fprintf(fp_out, "%d ", i+1); 00300 else 00301 fprintf(fp_out, "%d ", 0-i-1); 00302 } 00303 fprintf(fp_out, "\n"); 00304 fclose(fp_out); 00305 } 00306 00307 int backtracking() { 00308 int var, index; 00309 00310 UNITCLAUSE_STACK_fill_pointer = 0; 00311 ++NB_BACK; 00312 00313 do { 00314 var = pop(VARIABLE_STACK); 00315 if (var_rest_value[var] == NONE) 00316 var_state[var] = ACTIVE; 00317 else { 00318 for (index = saved_clause_stack[var]; 00319 index < CLAUSE_STACK_fill_pointer; 00320 index++) 00321 clause_state[CLAUSE_STACK[index]] = ACTIVE; 00322 CLAUSE_STACK_fill_pointer = saved_clause_stack[var]; 00323 00324 for (index = saved_managedclause_stack[var]; 00325 index < MANAGEDCLAUSE_STACK_fill_pointer; 00326 index++) 00327 clause_length[MANAGEDCLAUSE_STACK[index]]++; 00328 MANAGEDCLAUSE_STACK_fill_pointer = saved_managedclause_stack[var]; 00329 00330 var_current_value[var] = var_rest_value[var]; 00331 var_rest_value[var] = NONE; 00332 push(var, VARIABLE_STACK); 00333 if (var_current_value[var]==FALSE) { 00334 simple_manage_clauses(pos_in[var]); 00335 remove_clauses(neg_in[var]); 00336 } 00337 else { 00338 simple_manage_clauses(neg_in[var]); 00339 remove_clauses(pos_in[var]); 00340 } 00341 return TRUE; 00342 } 00343 } while (VARIABLE_STACK_fill_pointer != 0); 00344 return FALSE; 00345 } 00346 00347 00348 /* test if the new clause is redundant or subsompted by another */ 00349 #define OLD_CLAUSE_REDUNDANT 77 00350 #define NEW_CLAUSE_REDUNDANT 7 00351 00352 int smaller_than(int lit1, int lit2) { 00353 return ((lit1<NB_VAR) ? lit1 : lit1-NB_VAR) < 00354 ((lit2<NB_VAR) ? lit2 : lit2-NB_VAR); 00355 } 00356 00357 my_type redundant(int *new_clause, int *old_clause) { 00358 int lit1, lit2, old_clause_diff=0, new_clause_diff=0; 00359 00360 lit1=*old_clause; lit2=*new_clause; 00361 while ((lit1 != NONE) && (lit2 != NONE)) { 00362 if (smaller_than(lit1, lit2)) { 00363 lit1=*(++old_clause); old_clause_diff++; 00364 } 00365 else 00366 if (smaller_than(lit2, lit1)) { 00367 lit2=*(++new_clause); new_clause_diff++; 00368 } 00369 else 00370 if (complement(lit1, lit2)) { 00371 return FALSE; /* old_clause_diff++; new_clause_diff++; j1++; j2++; */ 00372 } 00373 else { 00374 lit1=*(++old_clause); lit2=*(++new_clause); 00375 } 00376 } 00377 if ((lit1 == NONE) && (old_clause_diff == 0)) 00378 /* la nouvelle clause est redondante ou subsumee */ 00379 return NEW_CLAUSE_REDUNDANT; 00380 if ((lit2 == NONE) && (new_clause_diff == 0)) 00381 /* la old clause est redondante ou subsumee */ 00382 return OLD_CLAUSE_REDUNDANT; 00383 return FALSE; 00384 } 00385 00386 my_type get_resolvant(int *clause1, int *clause2, int *resolvant) { 00387 int lit1, lit2, nb_diff1=0, nb_diff2=0, 00388 nb_iden=0, nb_opps=0, j1=0, j2=0, j, limited_length; 00389 00390 while (((lit1=clause1[j1])!=NONE) && ((lit2=clause2[j2]) != NONE)) { 00391 if (complement(lit1, lit2)) { 00392 j1++; j2++; nb_opps++; 00393 } 00394 else 00395 if (lit1 == lit2) { 00396 j1++; j2++; nb_iden++; 00397 } 00398 else 00399 if (smaller_than(lit1, lit2)) { 00400 nb_diff1++; j1++; 00401 } 00402 else { 00403 nb_diff2++; j2++; 00404 } 00405 } 00406 if (nb_opps ==1) { 00407 if (clause1[j1] ==NONE) { 00408 for (; clause2[j2]!= NONE; j2++) nb_diff2++; 00409 } 00410 else { 00411 for (; clause1[j1]!= NONE; j1++) nb_diff1++; 00412 } 00413 if ((j1==1) || (j2==1)) limited_length=RESOLVANT_LENGTH; 00414 else 00415 if ((j1==2) && (j2==2)) limited_length=1; 00416 else 00417 if (j1<j2) limited_length=((j1<RESOLVANT_LENGTH) ? j1 : RESOLVANT_LENGTH); 00418 else limited_length=((j2<RESOLVANT_LENGTH) ? j2 : RESOLVANT_LENGTH); 00419 00420 if (nb_diff1 + nb_diff2 + nb_iden <= limited_length) { 00421 j1=0; j2=0; j=0; 00422 while (((lit1 = clause1[j1])!=NONE) && ((lit2 = clause2[j2]) != NONE)) { 00423 if (lit1 == lit2) { 00424 resolvant[j] = lit1; j1++; j2++; j++; 00425 } 00426 else 00427 if (smaller_than(lit1, lit2)) { 00428 resolvant[j] = lit1; j1++; j++; 00429 } 00430 else 00431 if (smaller_than(lit2, lit1)) { 00432 resolvant[j] = lit2; j2++; j++; 00433 } 00434 else { 00435 j1++; j2++; 00436 } 00437 } 00438 if (clause1[j1] ==NONE) while ((resolvant[j++] = clause2[j2++]) != NONE); 00439 else while ((resolvant[j++] = clause1[j1++]) != NONE); 00440 if (j==0) return NONE; 00441 if (nb_diff2==0) return 2; /* clause1 is redundant */ 00442 return TRUE; 00443 } 00444 } 00445 return FALSE; 00446 } 00447 00448 void remove_link(int clause) { 00449 int lit; 00450 int *lits; 00451 struct node *pnode1, *pnode2, *pnode; 00452 00453 lits = sat[clause]; 00454 00455 for (lit=*lits; lit != NONE; lit=*(++lits)) { 00456 pnode = (positive(lit) ? node_pos_in[lit] : 00457 node_neg_in[get_var_from_lit(lit)]); 00458 if (pnode == NULL) return; 00459 if (pnode->clause == clause) { 00460 if (positive(lit)) node_pos_in[lit] = pnode->next; 00461 else node_neg_in[get_var_from_lit(lit)] = pnode->next; 00462 } 00463 else 00464 for (pnode1 = pnode, pnode2 = pnode->next; 00465 pnode2 != NULL; pnode2=pnode2->next) { 00466 if (pnode2->clause == clause) { 00467 pnode1->next = pnode2->next; 00468 break; 00469 } 00470 else 00471 pnode1 = pnode2; 00472 } 00473 } 00474 } 00475 00476 void set_link(int clause) { 00477 int lit; 00478 int *lits; 00479 struct node *pnode; 00480 00481 lits = sat[clause]; 00482 for (lit=*lits; lit != NONE; lit=*(++lits)) { 00483 pnode = allocate_node(); 00484 pnode->clause = clause; 00485 if (positive(lit)) { 00486 pnode->next = node_pos_in[lit]; 00487 node_pos_in[lit] = pnode; 00488 } 00489 else { 00490 pnode->next = node_neg_in[get_var_from_lit(lit)]; 00491 node_neg_in[get_var_from_lit(lit)] = pnode; 00492 } 00493 } 00494 } 00495 00496 void set_link_for_resolv(int resolv) { 00497 int lit, *lits; 00498 struct node *pnode; 00499 lits=sat[resolv]; 00500 for (lit=*lits; lit != NONE; lit=*(++lits)) { 00501 pnode = allocate_node(); 00502 pnode->clause = resolv; 00503 pnode->next=in_resolv[lit]; 00504 in_resolv[lit]=pnode; 00505 } 00506 } 00507 00508 void remove_link_for_resolv(int resolv) { 00509 int lit, *lits; 00510 struct node *pnode1, *pnode2, *pnode; 00511 00512 lits = sat[resolv]; 00513 for (lit=*lits; lit != NONE; lit=*(++lits)) { 00514 pnode = in_resolv[lit]; 00515 if (pnode == NULL) return; 00516 if (pnode->clause == resolv) 00517 in_resolv[lit] = pnode->next; 00518 else 00519 for (pnode1 = pnode, pnode2 = pnode->next; 00520 pnode2 != NULL; pnode2=pnode2->next) { 00521 if (pnode2->clause == resolv) { 00522 pnode1->next = pnode2->next; 00523 break; 00524 } 00525 else 00526 pnode1 = pnode2; 00527 } 00528 } 00529 } 00530 00531 int INVOLVED_CLAUSE_STACK[tab_clause_size]; 00532 int INVOLVED_CLAUSE_STACK_fill_pointer=0; 00533 int CLAUSE_INVOLVED[tab_clause_size]; 00534 00535 int already_present(int *resolvant) { 00536 int lit, *lits, clause, length=0, i; 00537 struct node *pnode; 00538 lits=resolvant; 00539 for (lit=*lits; lit != NONE; lit=*(++lits)) { 00540 length++; 00541 for (pnode=in_resolv[lit]; pnode != NULL; pnode=pnode->next) { 00542 clause=pnode->clause; 00543 CLAUSE_INVOLVED[clause]++; 00544 if (CLAUSE_INVOLVED[clause]==1) 00545 push(clause, INVOLVED_CLAUSE_STACK); 00546 if (clause_length[clause]==CLAUSE_INVOLVED[clause]) { 00547 for(i=0; i<INVOLVED_CLAUSE_STACK_fill_pointer; i++) 00548 CLAUSE_INVOLVED[INVOLVED_CLAUSE_STACK[i]]=0; 00549 INVOLVED_CLAUSE_STACK_fill_pointer=0; 00550 return NEW_CLAUSE_REDUNDANT; 00551 } 00552 } 00553 } 00554 for(i=0; i<INVOLVED_CLAUSE_STACK_fill_pointer; i++) { 00555 clause=INVOLVED_CLAUSE_STACK[i]; 00556 if ((length==CLAUSE_INVOLVED[clause]) && (length<clause_length[clause])){ 00557 clause_state[clause] = PASSIVE; 00558 remove_link(clause); 00559 remove_link_for_resolv(clause); 00560 } 00561 CLAUSE_INVOLVED[clause]=0; 00562 } 00563 INVOLVED_CLAUSE_STACK_fill_pointer=0; 00564 return FALSE; 00565 } 00566 00567 int OLD_CLAUSE_SUPPRESED; 00568 #define ACTIVE2 2 00569 00570 int search_redundence(int *lits) { 00571 int lit, is_red; 00572 int *old_lits, *new_lits; 00573 struct node *pnode, *pnode1; 00574 00575 /* if lits is unit, all clauses in the pnode list become redundant and 00576 will be deleted, so that pnode=pnode->next is not good */ 00577 new_lits = lits; OLD_CLAUSE_SUPPRESED=FALSE; 00578 for (lit=*lits; lit != NONE; lit=*(++lits)) { 00579 for (pnode = (positive(lit) ? node_pos_in[lit] : 00580 node_neg_in[get_var_from_lit(lit)]); 00581 pnode != NULL; pnode = pnode1) { 00582 pnode1=pnode->next; 00583 old_lits = sat[pnode->clause]; 00584 is_red = redundant(new_lits, old_lits); 00585 if (is_red == OLD_CLAUSE_REDUNDANT) { 00586 /* printf("old clause %d is redundant\n", 00587 pnode->clause); 00588 */ 00589 OLD_CLAUSE_SUPPRESED=TRUE; 00590 clause_state[pnode->clause] = PASSIVE; 00591 remove_link(pnode->clause); 00592 } 00593 else 00594 if (is_red == NEW_CLAUSE_REDUNDANT) { 00595 return NEW_CLAUSE_REDUNDANT; 00596 } 00597 } 00598 } 00599 return OLD_CLAUSE_SUPPRESED; 00600 } 00601 00602 int add_resolvant(int *lits) { 00603 int j, lit, is_red, resolvant[RESOLVANT_LENGTH+1]; 00604 my_type is_res; 00605 int *old_lits, *new_lits, *res; 00606 struct node *pnode, *pnode1; 00607 00608 /* if lits is unit, all clauses in the pnode list become redundant and 00609 will be deleted, so that pnode=pnode->next is not good */ 00610 new_lits = lits; 00611 for (lit=*lits; lit != NONE; lit=*(++lits)) 00612 for (pnode = (positive(lit) ? 00613 node_neg_in[lit] : 00614 node_pos_in[get_var_from_lit(lit)]); 00615 pnode != NULL; pnode = pnode1) { 00616 pnode1=pnode->next; 00617 old_lits = sat[pnode->clause]; 00618 is_res = get_resolvant(new_lits, old_lits, resolvant); 00619 if (is_res == NONE) return NONE; 00620 if (is_res != FALSE) { 00621 is_red=search_redundence(resolvant); 00622 if (is_red != NEW_CLAUSE_REDUNDANT) { 00623 if (already_present(resolvant) == FALSE) { 00624 res=(int *)malloc((RESOLVANT_LENGTH+1)*sizeof(int)); 00625 if (OLD_CLAUSE_SUPPRESED==TRUE) 00626 clause_state[NB_CLAUSE]=ACTIVE2; 00627 else 00628 clause_state[NB_CLAUSE]=ACTIVE; 00629 j=0; 00630 while ((res[j]=resolvant[j]) != NONE) ++j; 00631 if (j==0) return NONE; 00632 sat[NB_CLAUSE] = res; 00633 set_link_for_resolv(NB_CLAUSE); 00634 clause_length[NB_CLAUSE++]=j; 00635 } 00636 /* new_lits is redundant by resolvant */ 00637 if (is_res == 2) return 2; 00638 } 00639 } 00640 } 00641 return TRUE; 00642 } 00643 00644 int* copy_clauses(struct node *node_in) { 00645 int j=0, *in; struct node *pnode; 00646 00647 pnode=node_in; 00648 while (pnode != NULL) { 00649 if (clause_state[pnode->clause]==ACTIVE) j++; 00650 pnode = pnode->next; 00651 } 00652 in = (int *)malloc((j+1)*sizeof(int)); 00653 j=0; pnode=node_in; 00654 while (pnode != NULL) { 00655 if (clause_state[pnode->clause]==ACTIVE) { 00656 in[j] = pnode->clause; j++; 00657 } 00658 pnode = pnode->next; 00659 } 00660 in[j] = NONE; 00661 return in; 00662 } 00663 00664 int unitclause_process(); 00665 00666 00667 my_type build_sat_instance(char* const input_file) { 00668 FILE* const fp_in=fopen(input_file, "r"); 00669 if (fp_in==NULL) return FALSE; 00670 00671 {char ch=getc(fp_in); 00672 while (ch!='p') { 00673 while (ch!='\n') ch=getc(fp_in); 00674 ch=getc(fp_in); 00675 } 00676 } 00677 00678 { 00679 char word2[WORD_LENGTH]; 00680 fscanf(fp_in, "%s%d%d", word2, &NB_VAR, &NB_CLAUSE); 00681 } 00682 if (NB_VAR > MAX_NUMBER_VARIABLES) { 00683 fprintf(stderr, "ERROR: Parameter lines says maximal variable index is %d,\n" 00684 " but MAX_NUMBER_VARIABLES = %d.\n", NB_VAR, MAX_NUMBER_VARIABLES); 00685 return FALSE; 00686 } 00687 if (NB_CLAUSE > MAX_NUMBER_CLAUSES) { 00688 fprintf(stderr, "ERROR: Parameter lines says the clause-number is %d,\n" 00689 " but MAX_NUMBER_CLAUSES = %d.\n", NB_CLAUSE, MAX_NUMBER_CLAUSES); 00690 return FALSE; 00691 } 00692 00693 for (int i=0; i<NB_CLAUSE; ++i) { 00694 int lits[MAX_CLAUSE_LENGTH+1]; 00695 fscanf(fp_in, "%d", &lits[0]); 00696 int length=0; 00697 while (length <= MAX_CLAUSE_LENGTH && lits[length] != 0) 00698 fscanf(fp_in, "%d", &lits[++length]); 00699 if (length > MAX_CLAUSE_LENGTH) { 00700 fprintf(stderr, "ERROR: A clause-line contains more than MAX_CLAUSE_LENGTH = %d literals.\n", MAX_CLAUSE_LENGTH); 00701 return FALSE; 00702 } 00703 00704 char tautologie = FALSE; 00705 /* test if some literals are redundant and sort the clause */ 00706 for (int ii=0; ii<length-1; ++ii) { 00707 int lit = lits[ii]; 00708 for (int jj=ii+1; jj<length; ++jj) { 00709 if (abs(lit)>abs(lits[jj])) { 00710 const int lit1=lits[jj]; lits[jj]=lit; lit=lit1; 00711 } 00712 else 00713 if (lit == lits[jj]) { 00714 lits[jj--] = lits[--length]; lits[length] = 0; 00715 printf("literal %d is redundant in clause %d\n", lit, i); 00716 } 00717 else 00718 if (abs(lit) == lits[jj]) { 00719 tautologie = TRUE; break; 00720 } 00721 } 00722 if (tautologie == TRUE) break; 00723 else lits[ii] = lit; 00724 } 00725 if (tautologie == FALSE) { 00726 lits[length] = 0; 00727 sat[i] = (int *)malloc((length+1)*sizeof(int)); 00728 int j=0; 00729 while (lits[j] != 0) { 00730 if (lits[j] > 0) sat[i][j] = lits[j]-1; 00731 else sat[i][j] = abs(lits[j]) + NB_VAR -1; 00732 ++j; 00733 } 00734 sat[i][j] = NONE; 00735 clause_length[i] = length; 00736 clause_state[i] = ACTIVE; 00737 /* static_clause_length[i] = length; 00738 */ 00739 } 00740 else {i--; NB_CLAUSE--;} 00741 } 00742 fclose(fp_in); 00743 00744 for (int i=0; i<NB_VAR; ++i) { 00745 node_neg_in[i] = NULL; 00746 node_pos_in[i] = NULL; 00747 var_state[i]=ACTIVE; 00748 } 00749 00750 INIT_NB_CLAUSE= NB_CLAUSE; 00751 00752 for(int i=0; i<NB_CLAUSE; ++i) set_link_for_resolv(i); 00753 00754 for(int i=0; i<tab_clause_size; ++i) 00755 CLAUSE_INVOLVED[INVOLVED_CLAUSE_STACK[i]]=0; 00756 INVOLVED_CLAUSE_STACK_fill_pointer=0; 00757 00758 for(int i=0; i<NB_CLAUSE; ++i) { 00759 remove_link_for_resolv(i); 00760 int* plit = sat[i]; 00761 const int length = clause_length[i]; 00762 if (length==1) push(i, UNITCLAUSE_STACK); 00763 if (search_redundence(plit) != NEW_CLAUSE_REDUNDANT) { 00764 if ((i<INIT_NB_CLAUSE*10) || 00765 (length<3) || 00766 (clause_state[i]==ACTIVE2)) { 00767 const char is_res = add_resolvant(plit); 00768 if (is_res == NONE) return NONE; 00769 else 00770 if (is_res == 2) clause_state[i] = PASSIVE; 00771 else 00772 {set_link(i); clause_state[i] = ACTIVE;} 00773 } 00774 else clause_state[i] = PASSIVE; 00775 } 00776 else clause_state[i] = PASSIVE; 00777 } 00778 for(int i=0; i<NB_VAR; ++i) { 00779 neg_in[i]=copy_clauses(node_neg_in[i]); 00780 pos_in[i]=copy_clauses(node_pos_in[i]); 00781 } 00782 free_ressources(); 00783 if (unitclause_process()==NONE) return NONE; 00784 int NB_CLAUSE1 = 0; 00785 for (int i=0; i<NB_CLAUSE; ++i) 00786 if (clause_state[i] == ACTIVE) ++NB_CLAUSE1; 00787 NB_CLAUSE = NB_CLAUSE1; 00788 00789 return TRUE; 00790 } 00791 00792 00793 int verify_solution() { 00794 int i, lit, *lits, clause_truth; 00795 00796 for (i=0; i<NB_CLAUSE; i++) { 00797 clause_truth = FALSE; 00798 lits = sat[i]; 00799 for(lit=*lits; lit!=NONE; lit=*(++lits)) 00800 if (((negative(lit)) && 00801 (var_current_value[get_var_from_lit(lit)] == FALSE)) || 00802 ((positive(lit)) && 00803 (var_current_value[lit] == TRUE)) ) { 00804 clause_truth = TRUE; 00805 break; 00806 } 00807 if (clause_truth == FALSE) return FALSE; 00808 } 00809 00810 return TRUE; 00811 } 00812 00813 long NB_SEARCH = 0; long NB_FIXED = 0; 00814 00815 int unitclause_process() { 00816 int var, unitclause, lit, *lits, unitclause_position; 00817 00818 for (unitclause_position = 0; 00819 unitclause_position < UNITCLAUSE_STACK_fill_pointer; 00820 unitclause_position++) { 00821 unitclause = UNITCLAUSE_STACK[unitclause_position]; 00822 if (clause_state[unitclause] == ACTIVE) { 00823 ++NB_UNIT; 00824 lits = sat[unitclause]; 00825 for(lit=*lits; lit!=NONE; lit=*(++lits)) { 00826 if (positive(lit)) { 00827 var = lit; 00828 if (var_state[var] == ACTIVE) { 00829 var_current_value[var] = TRUE; 00830 var_rest_value[var] = NONE; 00831 if (manage_clauses(neg_in[var])==TRUE) { 00832 var_state[var] = PASSIVE; 00833 push(var, VARIABLE_STACK); 00834 remove_clauses(pos_in[var]); 00835 break; 00836 } 00837 else { 00838 return NONE; 00839 } 00840 } 00841 } 00842 else { 00843 var = get_var_from_lit(lit); 00844 if (var_state[var] == ACTIVE) { 00845 var_current_value[var] = FALSE; 00846 var_rest_value[var] = NONE; 00847 if (manage_clauses(pos_in[var])== TRUE) { 00848 var_state[var] = PASSIVE; 00849 push(var, VARIABLE_STACK); 00850 remove_clauses(neg_in[var]); 00851 break; 00852 } 00853 else { 00854 return NONE; 00855 } 00856 } 00857 } 00858 } 00859 } 00860 } 00861 UNITCLAUSE_STACK_fill_pointer = 0; 00862 return TRUE; 00863 } 00864 00865 int get_nb_clauses(int var) { 00866 return ((nb_neg_clause_of_length2[var] + 00867 nb_pos_clause_of_length2[var]) * WEIGTH) + 00868 nb_neg_clause_of_length3[var] + 00869 nb_pos_clause_of_length3[var]; 00870 } 00871 00872 int get_resolvant_nb(int saved_managedclause_fill_pointer) { 00873 int *lits; 00874 int lit, var, i, clause, resolvant_nb=0; 00875 00876 for (i=saved_managedclause_fill_pointer; 00877 i<MANAGEDCLAUSE_STACK_fill_pointer; i++) { 00878 clause = MANAGEDCLAUSE_STACK[i]; 00879 if (clause_length[clause] == 2) { 00880 lits = sat[clause]; 00881 for(lit=*lits; lit!=NONE; lit=*(++lits)) { 00882 if (positive(lit)) { 00883 var = lit; 00884 if (var_state[var] == ACTIVE) 00885 resolvant_nb += (nb_neg_clause_of_length2[var] * WEIGTH) 00886 +nb_neg_clause_of_length3[var]; 00887 } 00888 else { 00889 var = get_var_from_lit(lit); 00890 if (var_state[var] == ACTIVE) 00891 resolvant_nb += (nb_pos_clause_of_length2[var] * WEIGTH) 00892 +nb_pos_clause_of_length3[var]; 00893 } 00894 } 00895 } 00896 } 00897 return resolvant_nb; 00898 } 00899 00900 void reset_context(int saved_var_stack_fill_pointer, 00901 int saved_managedclause_fill_pointer) { 00902 int i; 00903 00904 for (i=0; i<UNITCLAUSE_STACK_fill_pointer; i++) 00905 clause_length[UNITCLAUSE_STACK[i]]++; 00906 UNITCLAUSE_STACK_fill_pointer = 0; 00907 00908 for (i=saved_var_stack_fill_pointer; 00909 i<VARIABLE_STACK_fill_pointer; i++) 00910 var_state[VARIABLE_STACK[i]] = ACTIVE; 00911 VARIABLE_STACK_fill_pointer = saved_var_stack_fill_pointer; 00912 00913 for (i=saved_managedclause_fill_pointer; 00914 i<MANAGEDCLAUSE_STACK_fill_pointer; i++) 00915 clause_length[MANAGEDCLAUSE_STACK[i]]++; 00916 MANAGEDCLAUSE_STACK_fill_pointer = 00917 saved_managedclause_fill_pointer; 00918 } 00919 00920 int branch(); 00921 00922 int examine1(int tested_var) { 00923 int generating_fixed_variables_if_positif, 00924 generating_fixed_variables_if_negatif, 00925 saved_var_stack_fill_pointer, 00926 saved_managedclause_fill_pointer; 00927 00928 saved_var_stack_fill_pointer=VARIABLE_STACK_fill_pointer; 00929 saved_managedclause_fill_pointer= 00930 MANAGEDCLAUSE_STACK_fill_pointer; 00931 00932 var_current_value[tested_var] = TRUE; 00933 var_state[tested_var] = PASSIVE; 00934 push(tested_var, VARIABLE_STACK); 00935 my_simple_manage_clauses(neg_in[tested_var]); 00936 00937 generating_fixed_variables_if_positif = branch(); 00938 00939 if (generating_fixed_variables_if_positif == NONE) { 00940 reset_context(saved_var_stack_fill_pointer, 00941 saved_managedclause_fill_pointer); 00942 var_current_value[tested_var] = FALSE; 00943 var_rest_value[tested_var] = NONE; 00944 var_state[tested_var] = PASSIVE; 00945 push(tested_var, VARIABLE_STACK); 00946 simple_manage_clauses(pos_in[tested_var]); 00947 remove_clauses(neg_in[tested_var]); 00948 return NONE; 00949 } 00950 else { 00951 reduce_if_positive_nb[tested_var] = 00952 get_resolvant_nb(saved_managedclause_fill_pointer); 00953 reset_context(saved_var_stack_fill_pointer, 00954 saved_managedclause_fill_pointer); 00955 } 00956 var_current_value[tested_var] = FALSE; 00957 00958 var_state[tested_var] = PASSIVE; 00959 push(tested_var, VARIABLE_STACK); 00960 my_simple_manage_clauses(pos_in[tested_var]); 00961 00962 generating_fixed_variables_if_negatif = branch(); 00963 00964 if (generating_fixed_variables_if_negatif == NONE) { 00965 reset_context(saved_var_stack_fill_pointer, 00966 saved_managedclause_fill_pointer); 00967 simple_manage_clauses(neg_in[tested_var]); 00968 var_current_value[tested_var] = TRUE; 00969 var_rest_value[tested_var] = NONE; 00970 var_state[tested_var] = PASSIVE; 00971 push(tested_var, VARIABLE_STACK); 00972 remove_clauses(pos_in[tested_var]); 00973 return NONE; 00974 } 00975 else { 00976 reduce_if_negative_nb[tested_var] = 00977 get_resolvant_nb(saved_managedclause_fill_pointer); 00978 reset_context(saved_var_stack_fill_pointer, 00979 saved_managedclause_fill_pointer); 00980 } 00981 push(tested_var, TESTED_VAR_STACK); 00982 return TRUE; 00983 } 00984 00985 int examine(int tested_var) { 00986 int generating_fixed_variables_if_positif = 0, 00987 generating_fixed_variables_if_negatif = 0, 00988 saved_var_stack_fill_pointer, 00989 saved_managedclause_fill_pointer; 00990 00991 saved_var_stack_fill_pointer=VARIABLE_STACK_fill_pointer; 00992 saved_managedclause_fill_pointer= 00993 MANAGEDCLAUSE_STACK_fill_pointer; 00994 00995 var_current_value[tested_var] = TRUE; 00996 00997 var_state[tested_var] = PASSIVE; 00998 push(tested_var, VARIABLE_STACK); 00999 my_simple_manage_clauses(neg_in[tested_var]); 01000 01001 generating_fixed_variables_if_positif = branch(); 01002 reduce_if_positive_nb[tested_var]= 01003 MANAGEDCLAUSE_STACK_fill_pointer- 01004 saved_managedclause_fill_pointer; 01005 reset_context(saved_var_stack_fill_pointer, 01006 saved_managedclause_fill_pointer); 01007 01008 if (generating_fixed_variables_if_positif == NONE) { 01009 var_current_value[tested_var] = FALSE; 01010 var_rest_value[tested_var] = NONE; 01011 var_state[tested_var] = PASSIVE; 01012 push(tested_var, VARIABLE_STACK); 01013 simple_manage_clauses(pos_in[tested_var]); 01014 remove_clauses(neg_in[tested_var]); 01015 return NONE; 01016 } 01017 01018 var_current_value[tested_var] = FALSE; 01019 01020 var_state[tested_var] = PASSIVE; 01021 push(tested_var, VARIABLE_STACK); 01022 my_simple_manage_clauses(pos_in[tested_var]); 01023 01024 generating_fixed_variables_if_negatif = branch(); 01025 reduce_if_negative_nb[tested_var]= 01026 MANAGEDCLAUSE_STACK_fill_pointer- 01027 saved_managedclause_fill_pointer; 01028 reset_context(saved_var_stack_fill_pointer, 01029 saved_managedclause_fill_pointer); 01030 01031 if (generating_fixed_variables_if_negatif == NONE) { 01032 simple_manage_clauses(neg_in[tested_var]); 01033 var_current_value[tested_var] = TRUE; 01034 var_rest_value[tested_var] = NONE; 01035 var_state[tested_var] = PASSIVE; 01036 push(tested_var, VARIABLE_STACK); 01037 remove_clauses(pos_in[tested_var]); 01038 return NONE; 01039 } 01040 push(tested_var, TESTED_VAR_STACK); 01041 return TRUE; 01042 } 01043 01044 int get_nb(int saved_managedclause_fill_pointer) { 01045 int i, clause, *lits, lit, var, nb=0; 01046 01047 for(i=saved_managedclause_fill_pointer; 01048 i<MANAGEDCLAUSE_STACK_fill_pointer; i++) { 01049 clause=MANAGEDCLAUSE_STACK[i]; 01050 if (clause_length[clause] == 2) { 01051 lits = sat[clause]; 01052 for(lit=*lits; lit!=NONE; lit=*(++lits)) { 01053 if (negative(lit)) { 01054 var=get_var_from_lit(lit); 01055 if (var_state[var] == ACTIVE) { 01056 nb+=nb_pos_clause_of_length2[var]; 01057 } 01058 } 01059 else { 01060 var=lit; 01061 if (var_state[var] == ACTIVE) { 01062 nb+=nb_neg_clause_of_length2[var]; 01063 } 01064 } 01065 } 01066 } 01067 } 01068 return nb; 01069 } 01070 01071 int examine2(int tested_var) { 01072 int generating_fixed_variables_if_positif = 0, 01073 generating_fixed_variables_if_negatif = 0, 01074 saved_var_stack_fill_pointer, 01075 saved_managedclause_fill_pointer; 01076 01077 saved_var_stack_fill_pointer=VARIABLE_STACK_fill_pointer; 01078 saved_managedclause_fill_pointer= 01079 MANAGEDCLAUSE_STACK_fill_pointer; 01080 01081 var_current_value[tested_var] = TRUE; 01082 01083 var_state[tested_var] = PASSIVE; 01084 push(tested_var, VARIABLE_STACK); 01085 my_simple_manage_clauses(neg_in[tested_var]); 01086 generating_fixed_variables_if_positif = branch(); 01087 01088 if (generating_fixed_variables_if_positif == NONE) { 01089 reset_context(saved_var_stack_fill_pointer, 01090 saved_managedclause_fill_pointer); 01091 var_current_value[tested_var] = FALSE; 01092 var_rest_value[tested_var] = NONE; 01093 var_state[tested_var] = PASSIVE; 01094 push(tested_var, VARIABLE_STACK); 01095 simple_manage_clauses(pos_in[tested_var]); 01096 remove_clauses(neg_in[tested_var]); 01097 return NONE; 01098 } 01099 else { 01100 reduce_if_positive_nb[tested_var]= 01101 get_nb(saved_managedclause_fill_pointer); 01102 reset_context(saved_var_stack_fill_pointer, 01103 saved_managedclause_fill_pointer); 01104 } 01105 01106 01107 var_current_value[tested_var] = FALSE; 01108 01109 var_state[tested_var] = PASSIVE; 01110 push(tested_var, VARIABLE_STACK); 01111 my_simple_manage_clauses(pos_in[tested_var]); 01112 generating_fixed_variables_if_negatif = branch(); 01113 01114 if (generating_fixed_variables_if_negatif == NONE) { 01115 reset_context(saved_var_stack_fill_pointer, 01116 saved_managedclause_fill_pointer); 01117 simple_manage_clauses(neg_in[tested_var]); 01118 var_current_value[tested_var] = TRUE; 01119 var_rest_value[tested_var] = NONE; 01120 var_state[tested_var] = PASSIVE; 01121 push(tested_var, VARIABLE_STACK); 01122 remove_clauses(pos_in[tested_var]); 01123 return NONE; 01124 } 01125 else { 01126 reduce_if_negative_nb[tested_var]= 01127 get_nb(saved_managedclause_fill_pointer); 01128 reset_context(saved_var_stack_fill_pointer, 01129 saved_managedclause_fill_pointer); 01130 } 01131 01132 push(tested_var, TESTED_VAR_STACK); 01133 return TRUE; 01134 } 01135 01136 int IMPLIED_LITS_fill_pointer=0; 01137 int IMPLIED_LITS[tab_variable_size]; 01138 int LIT_IMPLIED[tab_variable_size]; 01139 01140 int branch() { 01141 int var, lit, *lits, unitclause, unitclause_position; 01142 NB_SEARCH++; 01143 for (unitclause_position = 0; 01144 unitclause_position != UNITCLAUSE_STACK_fill_pointer; 01145 unitclause_position++) { 01146 unitclause = UNITCLAUSE_STACK[unitclause_position]; 01147 if (clause_state[unitclause] == ACTIVE) { 01148 lits = sat[unitclause]; 01149 for(lit=*lits; lit!=NONE; lit=*(++lits)) { 01150 if (positive(lit)) { 01151 var = lit; 01152 if (var_state[var] == ACTIVE) { 01153 var_current_value[var] = TRUE; 01154 if (my_manage_clauses(neg_in[var]) == TRUE) { 01155 if (LIT_IMPLIED[lit]==0) push(lit, IMPLIED_LITS); 01156 LIT_IMPLIED[lit]++; 01157 var_state[var] = PASSIVE; 01158 push(var, VARIABLE_STACK); 01159 break; 01160 } 01161 else { 01162 NB_FIXED++; 01163 return NONE; 01164 } 01165 } 01166 } 01167 else { 01168 var = get_var_from_lit(lit); 01169 if (var_state[var] == ACTIVE) { 01170 var_current_value[var] = FALSE; 01171 if (my_manage_clauses(pos_in[var]) == TRUE) { 01172 if (LIT_IMPLIED[lit]==0) push(lit, IMPLIED_LITS); 01173 LIT_IMPLIED[lit]++; 01174 var_state[var] = PASSIVE; 01175 push(var, VARIABLE_STACK); 01176 break; 01177 } 01178 else { 01179 NB_FIXED++; 01180 return NONE; 01181 } 01182 } 01183 } 01184 } 01185 } 01186 } 01187 return MANAGEDCLAUSE_STACK_fill_pointer; 01188 } 01189 01190 int satisfy_literal(int lit) { 01191 int var; 01192 if (positive(lit)) { 01193 if (var_state[lit]==ACTIVE) { 01194 if (manage_clauses(neg_in[lit])==FALSE) return NONE; 01195 var_current_value[lit] = TRUE; 01196 var_rest_value[lit]=NONE; 01197 var_state[lit] = PASSIVE; 01198 push(lit, VARIABLE_STACK); 01199 remove_clauses(pos_in[lit]); 01200 } 01201 else 01202 if (var_current_value[lit]==FALSE) return NONE; 01203 } 01204 else { 01205 var = get_var_from_lit(lit); 01206 if (var_state[var]==ACTIVE) { 01207 if (manage_clauses(pos_in[var])==FALSE) return NONE; 01208 var_current_value[var] = FALSE; 01209 var_rest_value[var]=NONE; 01210 var_state[var] = PASSIVE; 01211 push(var, VARIABLE_STACK); 01212 remove_clauses(neg_in[var]); 01213 } 01214 else 01215 if (var_current_value[var]==TRUE) return NONE; 01216 } 01217 if (unitclause_process()==NONE) 01218 return NONE; 01219 else return FALSE; 01220 } 01221 01222 int treat_implied_lits() { 01223 int i, lit; 01224 for (i=0; i<IMPLIED_LITS_fill_pointer; i++) { 01225 lit=IMPLIED_LITS[i]; 01226 if (LIT_IMPLIED[lit]==2) 01227 if (satisfy_literal(lit)==NONE) 01228 return NONE; 01229 } 01230 return TRUE; 01231 } 01232 01233 int get_complement(int lit) { 01234 if (positive(lit)) return lit+NB_VAR; 01235 else return lit-NB_VAR; 01236 } 01237 01238 int insert_var_if_necessary1(int var) { 01239 int weight, nb; 01240 struct var_node *pvar_node, *pvar_node1, *pvar_node2; 01241 01242 weight=reduce_if_positive_nb[var]*reduce_if_negative_nb[var]*1024 01243 + reduce_if_positive_nb[var] 01244 + reduce_if_negative_nb[var]+1; 01245 01246 if ((VAR_FOR_TEST1==NULL) || 01247 ((VAR_FOR_TEST1 != NULL) && (weight>VAR_FOR_TEST1->weight))) { 01248 pvar_node=allocate_var_node1(); 01249 pvar_node->var=var; pvar_node->weight=weight; 01250 pvar_node->next=VAR_FOR_TEST1; VAR_FOR_TEST1=pvar_node; 01251 } 01252 else { 01253 nb=1; pvar_node1=VAR_FOR_TEST1; pvar_node2=pvar_node1->next; 01254 while (nb<VAR_NODES1_nb) { 01255 if ((pvar_node2==NULL) || 01256 ((pvar_node2!=NULL) && (weight>pvar_node2->weight))) { 01257 pvar_node=allocate_var_node1(); 01258 pvar_node->var=var; pvar_node->weight=weight; 01259 pvar_node->next=pvar_node1->next; pvar_node1->next=pvar_node; 01260 break; 01261 } 01262 nb++; pvar_node1=pvar_node2; pvar_node2=pvar_node1->next; 01263 } 01264 } 01265 return TRUE; 01266 } 01267 01268 int branch1() { 01269 int var, lit, *lits, unitclause, unitclause_position; 01270 NB_SEARCH++; 01271 for (unitclause_position = 0; 01272 unitclause_position != UNITCLAUSE_STACK_fill_pointer; 01273 unitclause_position++) { 01274 unitclause = UNITCLAUSE_STACK[unitclause_position]; 01275 if (clause_state[unitclause] == ACTIVE) { 01276 lits = sat[unitclause]; 01277 for(lit=*lits; lit!=NONE; lit=*(++lits)) { 01278 if (positive(lit)) { 01279 var = lit; 01280 if (var_state[var] == ACTIVE) { 01281 var_current_value[var] = TRUE; 01282 if (my_manage_clauses(neg_in[var]) == TRUE) { 01283 //if (LIT_IMPLIED[lit]==0) push(lit, IMPLIED_LITS); 01284 //LIT_IMPLIED[lit]+=5; 01285 var_state[var] = PASSIVE; 01286 push(var, VARIABLE_STACK); 01287 break; 01288 } 01289 else { 01290 NB_FIXED++; 01291 return NONE; 01292 } 01293 } 01294 } 01295 else { 01296 var = get_var_from_lit(lit); 01297 if (var_state[var] == ACTIVE) { 01298 var_current_value[var] = FALSE; 01299 if (my_manage_clauses(pos_in[var]) == TRUE) { 01300 //if (LIT_IMPLIED[lit]==0) push(lit, IMPLIED_LITS); 01301 //LIT_IMPLIED[lit]+=5; 01302 var_state[var] = PASSIVE; 01303 push(var, VARIABLE_STACK); 01304 break; 01305 } 01306 else { 01307 NB_FIXED++; 01308 return NONE; 01309 } 01310 } 01311 } 01312 } 01313 } 01314 } 01315 return MANAGEDCLAUSE_STACK_fill_pointer; 01316 } 01317 01318 01319 int further_examin_var_if_positive(int var) { 01320 int lit, nb_reduced_clauses_if_further_positif, 01321 saved_var_stack_fill_pointer, 01322 saved_managedclause_fill_pointer; 01323 01324 saved_var_stack_fill_pointer=VARIABLE_STACK_fill_pointer; 01325 saved_managedclause_fill_pointer= 01326 MANAGEDCLAUSE_STACK_fill_pointer; 01327 01328 var_current_value[var] = TRUE; 01329 var_state[var] = PASSIVE; 01330 push(var, VARIABLE_STACK); 01331 my_simple_manage_clauses(neg_in[var]); 01332 NB_SECOND_SEARCH++; 01333 nb_reduced_clauses_if_further_positif = branch1(); 01334 reset_context(saved_var_stack_fill_pointer, 01335 saved_managedclause_fill_pointer); 01336 01337 if (nb_reduced_clauses_if_further_positif == NONE) { 01338 NB_SECOND_FIXED++; 01339 var_current_value[var] = FALSE; 01340 var_state[var] = PASSIVE; 01341 push(var, VARIABLE_STACK); 01342 my_simple_manage_clauses(pos_in[var]); 01343 if (branch() == NONE) return NONE; 01344 lit=get_complement(var); 01345 if (LIT_IMPLIED[lit]==0) push(lit, IMPLIED_LITS); 01346 LIT_IMPLIED[lit]++; 01347 } 01348 else NB_SEARCH--; 01349 return TRUE; 01350 } 01351 01352 int further_examin_var_if_negative(int var) { 01353 int nb_reduced_clauses_if_further_negatif, 01354 saved_var_stack_fill_pointer, 01355 saved_managedclause_fill_pointer; 01356 01357 saved_var_stack_fill_pointer=VARIABLE_STACK_fill_pointer; 01358 saved_managedclause_fill_pointer= 01359 MANAGEDCLAUSE_STACK_fill_pointer; 01360 01361 var_current_value[var] = FALSE; 01362 var_state[var] = PASSIVE; 01363 push(var, VARIABLE_STACK); 01364 my_simple_manage_clauses(pos_in[var]); 01365 NB_SECOND_SEARCH++; 01366 nb_reduced_clauses_if_further_negatif = branch1(); 01367 reset_context(saved_var_stack_fill_pointer, 01368 saved_managedclause_fill_pointer); 01369 01370 if (nb_reduced_clauses_if_further_negatif == NONE) { 01371 NB_SECOND_FIXED++; 01372 var_current_value[var] = TRUE; 01373 var_state[var] = PASSIVE; 01374 push(var, VARIABLE_STACK); 01375 my_simple_manage_clauses(neg_in[var]); 01376 if (branch() == NONE) return NONE; 01377 if (LIT_IMPLIED[var]==0) push(var, IMPLIED_LITS); 01378 LIT_IMPLIED[var]++; 01379 } 01380 else NB_SEARCH--; 01381 return TRUE; 01382 } 01383 01384 int further_examin(int saved_managedclause_fill_pointer) { 01385 int var, i, *lits, lit, clause; 01386 01387 for(i=saved_managedclause_fill_pointer; 01388 i<MANAGEDCLAUSE_STACK_fill_pointer; i++) { 01389 clause=MANAGEDCLAUSE_STACK[i]; 01390 if (clause_length[clause] == 2) { 01391 lits = sat[clause]; 01392 for(lit=*lits; lit!=NONE; lit=*(++lits)) { 01393 if (positive(lit)) { 01394 var = lit; 01395 if ((var_state[var] == ACTIVE) && 01396 (test_flag[var] < NB_SEARCH)) { 01397 test_flag[var] = NB_SEARCH; 01398 if (nb_neg_clause_of_length2[var]>0) { 01399 if (further_examin_var_if_positive(var)==NONE) { 01400 MAX_REDUCED=-1; 01401 return NONE; 01402 } 01403 } 01404 } 01405 } 01406 else { 01407 var = get_var_from_lit(lit); 01408 if ((var_state[var] == ACTIVE) && 01409 (test_flag[var] < NB_SEARCH)) { 01410 test_flag[var] = NB_SEARCH; 01411 if (nb_pos_clause_of_length2[var]>0) { 01412 if (further_examin_var_if_negative(var)==NONE) { 01413 MAX_REDUCED=-1; 01414 return NONE; 01415 } 01416 } 01417 } 01418 } 01419 } 01420 } 01421 } 01422 return TRUE; 01423 } 01424 01425 int further_testable(const int saved_managedclause_fill_pointer) { 01426 if ((MANAGEDCLAUSE_STACK_fill_pointer - saved_managedclause_fill_pointer > T_SEUIL) && 01427 (MANAGEDCLAUSE_STACK_fill_pointer - saved_managedclause_fill_pointer > MAX_REDUCED)) { 01428 MAX_REDUCED = MANAGEDCLAUSE_STACK_fill_pointer - saved_managedclause_fill_pointer; 01429 return TRUE; 01430 } 01431 return FALSE; 01432 } 01433 01434 int examine3(const int tested_var) { 01435 int generating_if_positif, generating_if_negatif, 01436 saved_var_stack_fill_pointer, 01437 saved_managedclause_fill_pointer; 01438 01439 saved_var_stack_fill_pointer=VARIABLE_STACK_fill_pointer; 01440 saved_managedclause_fill_pointer= 01441 MANAGEDCLAUSE_STACK_fill_pointer; 01442 01443 var_current_value[tested_var] = TRUE; 01444 01445 var_state[tested_var] = PASSIVE; 01446 push(tested_var, VARIABLE_STACK); 01447 my_simple_manage_clauses(neg_in[tested_var]); 01448 generating_if_positif = branch(); 01449 reduce_if_positive_nb[tested_var]= 01450 MANAGEDCLAUSE_STACK_fill_pointer-saved_managedclause_fill_pointer; 01451 01452 if ((generating_if_positif == NONE) || 01453 ((further_testable(saved_managedclause_fill_pointer)==TRUE) 01454 && (further_examin(saved_managedclause_fill_pointer)==NONE))) { 01455 reset_context(saved_var_stack_fill_pointer, 01456 saved_managedclause_fill_pointer); 01457 var_current_value[tested_var] = FALSE; 01458 var_rest_value[tested_var] = NONE; 01459 var_state[tested_var] = PASSIVE; 01460 push(tested_var, VARIABLE_STACK); 01461 simple_manage_clauses(pos_in[tested_var]); 01462 remove_clauses(neg_in[tested_var]); 01463 return NONE; 01464 } 01465 else { 01466 reset_context(saved_var_stack_fill_pointer, 01467 saved_managedclause_fill_pointer); 01468 } 01469 01470 var_current_value[tested_var] = FALSE; 01471 01472 var_state[tested_var] = PASSIVE; 01473 push(tested_var, VARIABLE_STACK); 01474 my_simple_manage_clauses(pos_in[tested_var]); 01475 01476 generating_if_negatif = branch(); 01477 reduce_if_negative_nb[tested_var]= 01478 MANAGEDCLAUSE_STACK_fill_pointer-saved_managedclause_fill_pointer; 01479 01480 if ((generating_if_negatif == NONE) || 01481 ((further_testable(saved_managedclause_fill_pointer)==TRUE) 01482 && (further_examin(saved_managedclause_fill_pointer)==NONE))) { 01483 reset_context(saved_var_stack_fill_pointer, 01484 saved_managedclause_fill_pointer); 01485 simple_manage_clauses(neg_in[tested_var]); 01486 var_current_value[tested_var] = TRUE; 01487 var_rest_value[tested_var] = NONE; 01488 var_state[tested_var] = PASSIVE; 01489 push(tested_var, VARIABLE_STACK); 01490 remove_clauses(pos_in[tested_var]); 01491 return NONE; 01492 } 01493 else { 01494 reset_context(saved_var_stack_fill_pointer, 01495 saved_managedclause_fill_pointer); 01496 } 01497 push(tested_var, TESTED_VAR_STACK); 01498 return TRUE; 01499 } 01500 01501 int get_neg_clause_nb(const int var) { 01502 my_type neg_clause3_nb = 0, neg_clause2_nb = 0; 01503 const int* clauses = neg_in[var]; 01504 01505 for(int clause=*clauses; clause!=NONE; clause=*(++clauses)) 01506 if (clause_state[clause] == ACTIVE) 01507 if (clause_length[clause] == 2) ++neg_clause2_nb; 01508 else ++neg_clause3_nb; 01509 01510 nb_neg_clause_of_length2[var] = neg_clause2_nb; 01511 nb_neg_clause_of_length3[var] = neg_clause3_nb; 01512 return neg_clause2_nb + neg_clause3_nb; 01513 } 01514 01515 int get_pos_clause_nb(const int var) { 01516 01517 my_type pos_clause3_nb = 0, pos_clause2_nb = 0; 01518 int *clauses, clause; 01519 clauses = pos_in[var]; 01520 01521 for(clause=*clauses; clause!=NONE; clause=*(++clauses)) { 01522 if (clause_state[clause] == ACTIVE) { 01523 if (clause_length[clause] == 2) 01524 pos_clause2_nb++; 01525 else 01526 pos_clause3_nb++; 01527 } 01528 } 01529 nb_pos_clause_of_length2[var] = pos_clause2_nb; 01530 nb_pos_clause_of_length3[var] = pos_clause3_nb; 01531 return pos_clause2_nb + pos_clause3_nb; 01532 } 01533 01534 int choose_and_instantiate_variable_in_clause() { 01535 int var, chosen_var=NONE; 01536 long i, posi, nega; 01537 unsigned long nb_clauses, max_nb_clauses = 0; 01538 my_type pos2, neg2; 01539 01540 ++NB_BRANCHE; 01541 TESTED_VAR_STACK_fill_pointer=0; 01542 VAR_FOR_TEST1=NULL; VAR_NODES1_index=0; MAX_REDUCED=-1; 01543 01544 for (var = 0; var < NB_VAR; var++) { 01545 if (var_state[var] == ACTIVE) { 01546 reduce_if_negative_nb[var]=0; 01547 reduce_if_positive_nb[var]=0; 01548 01549 if (get_neg_clause_nb(var) == 0) { 01550 ++NB_MONO; 01551 var_current_value[var] = TRUE; 01552 var_rest_value[var] = NONE; 01553 var_state[var] = PASSIVE; 01554 push(var, VARIABLE_STACK); 01555 remove_clauses(pos_in[var]); 01556 } 01557 else 01558 if (get_pos_clause_nb(var) == 0) { 01559 ++NB_MONO; 01560 var_current_value[var] = FALSE; 01561 var_rest_value[var] = NONE; 01562 var_state[var] = PASSIVE; 01563 push(var, VARIABLE_STACK); 01564 remove_clauses(neg_in[var]); 01565 } 01566 else { 01567 pos2 = nb_pos_clause_of_length2[var]; 01568 neg2 = nb_neg_clause_of_length2[var]; 01569 if ((neg2>0) && (pos2>0) && ((neg2+pos2)>3) ) { 01570 for(i=0; i<IMPLIED_LITS_fill_pointer; i++) 01571 LIT_IMPLIED[IMPLIED_LITS[i]]=0; 01572 IMPLIED_LITS_fill_pointer=0; 01573 if (examine3(var) == NONE) { 01574 if (unitclause_process() == NONE) return NONE; 01575 } 01576 else 01577 if (treat_implied_lits()==NONE) return NONE; 01578 } 01579 } 01580 } 01581 } 01582 if (TESTED_VAR_STACK_fill_pointer < T) { 01583 TESTED_VAR_STACK_fill_pointer=0; 01584 for (var=0; var<NB_VAR; var++) 01585 if (var_state[var] == ACTIVE) { 01586 pos2 = nb_pos_clause_of_length2[var]; 01587 neg2 = nb_neg_clause_of_length2[var]; 01588 if ((neg2>0) && (pos2 > 0) && 01589 ((neg2 > 1) || (pos2 > 1) ) ) { 01590 for(i=0; i<IMPLIED_LITS_fill_pointer; i++) 01591 LIT_IMPLIED[IMPLIED_LITS[i]]=0; 01592 IMPLIED_LITS_fill_pointer=0; 01593 if (examine2(var) == NONE) { 01594 if (unitclause_process() == NONE) return NONE; 01595 } 01596 else 01597 if (treat_implied_lits()==NONE) return NONE; 01598 } 01599 } 01600 01601 if (TESTED_VAR_STACK_fill_pointer < T) { 01602 TESTED_VAR_STACK_fill_pointer = 0; 01603 for (var=0; var<NB_VAR; var++) 01604 if (var_state[var] == ACTIVE) { 01605 for(i=0; i<IMPLIED_LITS_fill_pointer; i++) 01606 LIT_IMPLIED[IMPLIED_LITS[i]]=0; 01607 IMPLIED_LITS_fill_pointer=0; 01608 if (examine1(var) == NONE) { 01609 if (unitclause_process() == NONE) return NONE; 01610 } 01611 else 01612 if (treat_implied_lits()==NONE) return NONE; 01613 } 01614 } 01615 } 01616 for (i=0; i<TESTED_VAR_STACK_fill_pointer; i++) { 01617 var=TESTED_VAR_STACK[i]; 01618 if (var_state[var] == ACTIVE) { 01619 posi=reduce_if_positive_nb[var]; 01620 nega=reduce_if_negative_nb[var]; 01621 nb_clauses = posi*nega*128 + posi + nega +1; 01622 if (nb_clauses > max_nb_clauses) { 01623 chosen_var = var; 01624 max_nb_clauses = nb_clauses; 01625 } 01626 } 01627 } 01628 01629 if (chosen_var == NONE) return FALSE; 01630 var_state[chosen_var] = PASSIVE; 01631 saved_clause_stack[chosen_var] = CLAUSE_STACK_fill_pointer; 01632 saved_managedclause_stack[chosen_var] = MANAGEDCLAUSE_STACK_fill_pointer; 01633 push(chosen_var, VARIABLE_STACK); 01634 var_current_value[chosen_var] = TRUE; 01635 var_rest_value[chosen_var] = FALSE; 01636 simple_manage_clauses(neg_in[chosen_var]); 01637 remove_clauses(pos_in[chosen_var]); 01638 return TRUE; 01639 } 01640 01641 01642 void reset_all() { 01643 int index; 01644 01645 UNITCLAUSE_STACK_fill_pointer = 0; NB_BACK=0; NB_BRANCHE=0; 01646 NB_MONO=0; NB_UNIT=0; NB_SEARCH=0; NB_FIXED=0; 01647 NB_SECOND_SEARCH=0; NB_SECOND_FIXED=0; 01648 for (index=0; index<VARIABLE_STACK_fill_pointer; index++) 01649 var_state[VARIABLE_STACK[index]] = ACTIVE; 01650 VARIABLE_STACK_fill_pointer = 0; 01651 01652 for (index = 0; index < CLAUSE_STACK_fill_pointer; index++) 01653 clause_state[CLAUSE_STACK[index]] = ACTIVE; 01654 CLAUSE_STACK_fill_pointer = 0; 01655 01656 for (index = 0; index < MANAGEDCLAUSE_STACK_fill_pointer; index++) 01657 clause_length[MANAGEDCLAUSE_STACK[index]]++; 01658 MANAGEDCLAUSE_STACK_fill_pointer = 0; 01659 } 01660 01661 void dpl() { 01662 reset_all(); 01663 for(int var=0; var<NB_VAR; ++var) test_flag[var]=0; 01664 do { 01665 if (UNITCLAUSE_STACK_fill_pointer==0) 01666 if (choose_and_instantiate_variable_in_clause()==NONE) backtracking(); 01667 if (unitclause_process()==NONE) backtracking(); 01668 } while ((VARIABLE_STACK_fill_pointer != 0) && (!(satisfiable()))); 01669 } 01670 01671 01672 int main(const int argc, char* const argv[]) { 01673 if (argc!=2) { 01674 printf("Usage format: \"satz215 input_instance\"\n"); 01675 return EXITCODE_PARAMETER_FAILURE; 01676 } 01677 char saved_input_file[WORD_LENGTH]; 01678 for (int i=0; i<WORD_LENGTH; ++i) saved_input_file[i]=argv[1][i]; 01679 01680 struct tms* a_tms = malloc(sizeof(struct tms)); 01681 times(a_tms); 01682 const clock_t begintime = a_tms->tms_utime; 01683 01684 int exit_value; 01685 switch (build_sat_instance(argv[1])) { 01686 case FALSE: printf("Input file error.\n"); return EXITCODE_INPUT_ERROR; 01687 case TRUE: 01688 VARIABLE_STACK_fill_pointer=0; 01689 CLAUSE_STACK_fill_pointer = 0; 01690 MANAGEDCLAUSE_STACK_fill_pointer = 0; 01691 T_SEUIL= NB_VAR/6; 01692 H_SEUIL=3*T/2; 01693 dpl(); 01694 break; 01695 case NONE: 01696 exit_value = EXITCODE_UNSAT; 01697 break; 01698 } 01699 times(a_tms); 01700 const clock_t endtime = a_tms->tms_utime; 01701 01702 const bool sat_decision = satisfiable(); 01703 printf("s "); 01704 if (sat_decision) { 01705 exit_value = EXITCODE_SAT; 01706 printf("SATISFIABLE"); 01707 if (verify_solution()) print_values(NB_VAR); 01708 else { 01709 exit_value = EXITCODE_VERIFICATION_FAILED; 01710 printf ("**** Solution verification failed! ****\n"); 01711 } 01712 } 01713 else { 01714 exit_value = EXITCODE_UNSAT; 01715 printf ("UNSATISFIABLE"); 01716 } 01717 printf("\n"); 01718 const int diff_c = NB_CLAUSE-INIT_NB_CLAUSE; 01719 const long EPS = sysconf(_SC_CLK_TCK); 01720 const double elapsed = (double)(endtime-begintime)/EPS; 01721 printf("c sat_status %d\n" 01722 "c number_of_variables %u\n" 01723 "c initial_number_of_clauses %u\n" 01724 "c reddiff_number_of_clauses %d\n" 01725 "c running_time(sec) %1.2f\n" 01726 "c number_of_nodes %lu\n" 01727 "c number_of_binary_nodes %lu\n" 01728 "c number_of_pure_literals %lu\n" 01729 "c number_of_1-reductions %lu\n" 01730 "c number_of_2-look-ahead %lu\n" 01731 "c number_of_2-reductions %lu\n" 01732 "c number_of_3-look-ahead %lu\n" 01733 "c number_of_3-reductions %lu\n" 01734 "c file_name %s\n", 01735 sat_decision, NB_VAR, INIT_NB_CLAUSE, diff_c, elapsed, NB_BRANCHE, 01736 NB_BACK, NB_MONO, NB_UNIT, NB_SEARCH, NB_FIXED, NB_SECOND_SEARCH, 01737 NB_SECOND_FIXED, saved_input_file); 01738 01739 {FILE* fp_time; 01740 if (! (fp_time = fopen("satz215_timetable", "r"))) { 01741 fp_time = fopen("satz215_timetable", "w"); 01742 fprintf(fp_time, " rn rc t sat nds r1 r2 pls file bnds r2la r3 r3la dc\n"); 01743 } 01744 fclose(fp_time); 01745 } 01746 FILE* const fp_time = fopen("satz215_timetable", "a"); 01747 fprintf(fp_time, "%d %d %1.2f %d %lu %lu %lu %lu \"%s\" %lu %lu %lu %lu %d\n", 01748 NB_VAR, INIT_NB_CLAUSE, elapsed, sat_decision, NB_BRANCHE, NB_UNIT, 01749 NB_FIXED, NB_MONO, saved_input_file, NB_BACK, NB_SEARCH, NB_SECOND_FIXED, 01750 NB_SECOND_SEARCH, diff_c); 01751 fclose(fp_time); 01752 return exit_value; 01753 }