OKlibrary  0.2.1.6
satz215.2.c
Go to the documentation of this file.
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 }