VIS

src/sat/satDecision.c

Go to the documentation of this file.
00001 
00019 #include "satInt.h"
00020 
00021 static char rcsid[] UNUSED = "$Id: satDecision.c,v 1.28 2009/04/11 18:26:37 fabio Exp $";
00022 static  satManager_t *SatCm;
00023 
00024 /*---------------------------------------------------------------------------*/
00025 /* Constant declarations                                                     */
00026 /*---------------------------------------------------------------------------*/
00027 
00030 /*---------------------------------------------------------------------------*/
00031 /* Static function prototypes                                                */
00032 /*---------------------------------------------------------------------------*/
00033 
00034 static int ScoreCompare(const void * node1, const void * node2);
00035 
00039 /*---------------------------------------------------------------------------*/
00040 /* Definition of exported functions                                          */
00041 /*---------------------------------------------------------------------------*/
00042 
00043 
00055 satLevel_t *
00056 sat_MakeDecision(satManager_t *cm)
00057 {
00058 satLevel_t *d;
00059 int value;
00060 long v;
00061 satStatistics_t *stats;
00062 
00063   d = SATgetDecision(cm->currentDecision);
00064 
00065   if(cm->queue->size)
00066     return(d);
00067 
00068   d = sat_AllocLevel(cm);
00069 
00070   v = 0;
00071   v = sat_DecisionBasedOnBDD(cm, d);
00072 
00073   if(v == 0)
00074     v = sat_DecisionBasedOnLatestConflict(cm, d);
00075 
00076   if(v == 0)
00077     v = sat_DecisionBasedOnScore(cm, d);
00078 
00079   if(v == 0)
00080     return(0);
00081 
00082 
00083   stats = cm->each;
00084 
00085   stats->nDecisions++;
00086 
00087   value = !(SATisInverted(v));
00088   v = SATnormalNode(v);
00089   d->decisionNode = v;
00090   d->nConflict = cm->each->nConflictCl;
00091 
00092   SATvalue(v) = value;
00102   SATmakeImplied(v, d);
00103 
00104   sat_Enqueue(cm->queue, v);
00105   SATflags(v) |= InQueueMask;
00106 
00107   return(d);
00108 }
00109 
00110 
00122 long
00123 sat_DecisionBasedOnLatestConflict(
00124         satManager_t *cm,
00125         satLevel_t *d)
00126 {
00127 satOption_t *option;
00128 satStatistics_t *stats;
00129 satLiteralDB_t *literals;
00130 satVariable_t *var;
00131 int size, limit;
00132 long *plit, *tplit;
00133 long v, lit, tv, maxV;
00134 int tsize, count;
00135 int inverted, value;
00136 int i, j, satisfied;
00137 int tmpScore, maxScore;
00138 
00139   option = cm->option;
00140   stats = cm->each;
00141 
00142   if(!(option->decisionHeuristic & LATEST_CONFLICT_DECISION))
00143     return(0);
00144 
00152   if(cm->currentTopConflict == 0)
00153     return(0);
00154 
00155   literals = cm->literals;
00156   size = literals->last - literals->begin;
00157 
00158   limit = MAXINT;
00159   if(option->maxConflictForDecision > 0)
00160     limit = option->maxConflictForDecision;
00161 
00162   count = cm->currentTopConflictCount;
00163   tv = -(*(cm->currentTopConflict));
00164   tsize = SATnumLits(tv);
00165   tplit = (long*)SATfirstLit(tv);
00166   plit = tplit + tsize;
00167 
00168   for(i=plit-literals->begin; i>=0; i--, plit--) {
00170     if(count > limit)   break;
00171 
00172     lit = *plit;
00173     if(lit < 0) {
00174       tv = -lit;
00175 
00176       if(!(SATflags(tv) & IsConflictMask))
00177         return(0);
00178 
00179       if(plit < (long*)SATfirstLit(tv))
00180         continue;
00181 
00182       count++;
00183 
00184       if(option->skipSatisfiedClauseForDecision) {
00185         tsize = SATnumLits(tv);
00186         tplit = (long *)SATfirstLit(tv);
00187         satisfied = 0;
00188         maxScore = -1;
00189         maxV = 0;
00190         for(j=0; j<tsize; j++, tplit++) {
00191           v = SATgetNode(*tplit);
00192           inverted = SATisInverted(v);
00193           v = SATnormalNode(v);
00194           value = SATvalue(v) ^ inverted;
00195           if(value == 1) {
00196             satisfied = 1;
00197             break;
00198           }
00199           else if(value == 0) {
00200             continue;
00201           }
00202           var = SATgetVariable(v);
00203           tmpScore = (var->scores[0] >= var->scores[1]) ? var->scores[0] : var->scores[1];
00204           if(tmpScore > maxScore) {
00205             maxScore = tmpScore;
00206             maxV = v;
00207           }
00208         }
00209         if(satisfied) {
00210           i = i - tsize - 1;
00211           plit = plit - tsize -1;
00212         }
00213         else {
00214           var = SATgetVariable(maxV);
00215           value = (var->scores[0] >= var->scores[1]) ? 0 : 1;
00216 
00217           cm->currentTopConflict = (long*)SATfirstLit(tv) + SATnumLits(tv);
00218           cm->currentTopConflictCount = count;
00219 
00220           stats = cm->each;
00221           stats->nLatestConflictDecisions++;
00222           return(maxV ^ !value);
00223         }
00224       }
00225       continue;
00226     }
00227     else if(lit == 0)
00228       continue;
00229 
00230     v = SATgetNode(lit);
00231     inverted = SATisInverted(v);
00232     v = SATnormalNode(v);
00233     value = SATvalue(v) ^ inverted;
00234 
00235     if(value >= 2) {
00236       var = SATgetVariable(v);
00237       value = (var->conflictLits[0] >= var->conflictLits[1]) ? 0 : 1;
00238 
00239       cm->currentTopConflict = (long*)SATfirstLit(tv) + SATnumLits(tv);
00240       cm->currentTopConflictCount = count;
00241 
00242       stats = cm->each;
00243       stats->nLatestConflictDecisions++;
00244       return(v ^ !value);
00245     }
00246   }
00247   return(0);
00248 }
00249 
00265 void
00266 sat_CheckDecisonVariableArray(
00267         satManager_t *cm)
00268 {
00269 satArray_t *orderedVariableArray;
00270 int size, i;
00271 long v;
00272 
00273   orderedVariableArray = cm->orderedVariableArray;
00274   size = orderedVariableArray->num;
00275   for(i=0; i<cm->currentVarPos; i++) {
00276     v = orderedVariableArray->space[i];
00277     if(SATvalue(v) > 1) {
00278       fprintf(stdout, " ERROR : wrong current variable pos %d at %d\n",
00279               cm->currentVarPos, i);
00280     }
00281   }
00282 }
00283 
00295 long
00296 sat_DecisionBasedOnScore(
00297         satManager_t *cm,
00298         satLevel_t *d)
00299 {
00300 int size, i;
00301 long v;
00302 int value;
00303 satVariable_t *var;
00304 satArray_t *orderedVariableArray;
00305 satStatistics_t *stats;
00306 satOption_t *option;
00307 
00308 
00309   option = cm->option;
00310   orderedVariableArray = cm->orderedVariableArray;
00311   size = orderedVariableArray->num;
00312 
00313   for(i=cm->currentVarPos; i<size; i++) {
00314     v = orderedVariableArray->space[i];
00315     if(SATvalue(v) < 2) continue;
00316 
00317     var = SATgetVariable(v);
00318     value = (var->scores[0] >= var->scores[1]) ? 0 : 1;
00319 
00320     stats = cm->each;
00321     if((var->scores[0]+var->scores[1]) < 1) {
00322       stats->nLowScoreDecisions++;
00323     }
00324 
00325 
00326     if((option->decisionHeuristic & DVH_DECISION))
00327       stats->nDVHDecisions++;
00328     else
00329       stats->nVSIDSDecisions++;
00330 
00331     cm->currentVarPos = i;
00332     d->currentVarPos = i;
00333 
00334     return(v ^ !value);
00335   }
00336 
00337   return(0);
00338 }
00339 
00351 long
00352 sat_DecisionBasedOnBDD(
00353         satManager_t *cm,
00354         satLevel_t *d)
00355 {
00356 satArray_t *arr;
00357 long nv, v;
00358 
00359   if(cm->assignByBDD == 0)
00360     return(0);
00361 
00362   arr = cm->assignByBDD;
00363   if(arr->num == 0)
00364     return(0);
00365 
00375   while(arr->num) {
00376     v = arr->space[arr->num-1];
00377     nv = SATnormalNode(v);
00378     arr->num--;
00379     if(SATvalue(nv) > 1)
00380       return(v);
00381   }
00382   return(0);
00383 }
00384 
00385 
00386 long
00387 sat_DecisionBasedOnShrink(
00388         satManager_t *cm)
00389 {
00390 satArray_t *arr;
00391 long nv, v;
00392 
00393   if(cm->shrinkArray == 0)
00394     return(0);
00395 
00396   arr = cm->shrinkArray;
00397   if(arr->num == 0)
00398     return(0);
00399 
00400   while(arr->num) {
00401     v = arr->space[arr->num-1];
00402     nv = SATnormalNode(v);
00403     arr->num--;
00404     if(SATvalue(nv) > 1)
00405       return(v);
00406   }
00407   return(0);
00408 }
00409 
00410 
00422 void
00423 sat_UpdateScore(
00424         satManager_t *cm)
00425 {
00426 satArray_t *one, *tmp;
00427 satArray_t *ordered;
00428 satVariable_t *var;
00429 int size, i;
00430 long v;
00431 int value;
00432 
00433   ordered = cm->orderedVariableArray;
00434 
00435   one = sat_ArrayAlloc(ordered->num);
00436   tmp = sat_ArrayAlloc(ordered->num);
00437 
00438   size = ordered->num;
00439   for(i=0; i<size; i++) {
00440     v = ordered->space[i];
00441 
00442     if(SATvalue(v) < 2 && SATlevel(v) == 0)
00443       continue;
00444 
00445     var = SATgetVariable(v);
00446     var->scores[0] = (var->scores[0]>>1) + var->litsCount[0] - var->lastLitsCount[0];
00447     var->scores[1] = (var->scores[1]>>1) + var->litsCount[1] - var->lastLitsCount[1];
00448     var->lastLitsCount[0] = var->litsCount[0];
00449     var->lastLitsCount[1] = var->litsCount[1];
00450 
00451 
00452     if((var->scores[0] + var->scores[1]) < 1) {
00453       sat_ArrayInsert(one, v);
00454     }
00455     else {
00456       value = (var->scores[0] > var->scores[1]) ? var->scores[0] : var->scores[1];
00457       sat_ArrayInsert(tmp, v);
00458       sat_ArrayInsert(tmp, value);
00459     }
00460   }
00461 
00462   SatCm = cm;
00463   qsort(tmp->space, (tmp->num)>>1, sizeof(long)*2, ScoreCompare);
00464 
00465   ordered->num = 0;
00466   size = tmp->num;
00467   for(i=0; i<size; i++) {
00468     v = tmp->space[i];
00469     sat_ArrayInsert(ordered, v);
00470     var = SATgetVariable(v);
00471     var->pos = (i>>1);
00472     i++;
00473   }
00474 
00475   size = one->num;
00476   for(i=0; i<size; i++) {
00477     v = one->space[i];
00478     var = SATgetVariable(v);
00479     var->pos = ordered->num;
00480     sat_ArrayInsert(ordered, v);
00481   }
00482 
00483   sat_ArrayFree(one);
00484   sat_ArrayFree(tmp);
00485 
00486   cm->orderedVariableArray = ordered;
00487   cm->currentVarPos = 0;
00488 
00489   for(i=1; i<cm->currentDecision; i++) {
00490     cm->decisionHead[i].currentVarPos = 0;
00491   }
00492 
00493   if(cm->option->verbose > 3)
00494     sat_PrintScore(cm);
00495 
00496 }
00497 
00498 
00510 void
00511 sat_UpdateDVH(
00512         satManager_t *cm,
00513         satLevel_t *d,
00514         satArray_t *clauseArray,
00515         int bLevel,
00516         long unitLit)
00517 {
00518 satArray_t *ordered;
00519 satLevel_t *td;
00520 satVariable_t *var, *tvar, *ttvar;
00521 int score, tscore, ttscore;
00522 int value;
00523 long v;
00524 int gap, i, insert;
00525 
00526 
00527   ordered = cm->orderedVariableArray;
00528 
00529   unitLit = SATnormalNode(unitLit);
00530   gap = cm->currentDecision - bLevel;
00531   td = SATgetDecision(bLevel+1);
00532 
00533   if(gap <= 1) {
00535   }
00536   var = SATgetVariable(unitLit);
00537   tvar = SATgetVariable(td->decisionNode);
00538 
00539   score = (var->scores[1] > var->scores[0]) ? var->scores[1] : var->scores[0];
00540   tscore = (tvar->scores[1] > tvar->scores[0]) ? tvar->scores[1] : tvar->scores[0];
00541 
00542   if(score >= tscore)   {
00543     return;
00544   }
00545 
00546   tscore += 1;
00547 
00548   value = SATvalue(unitLit);
00549   if(value == 0)var->scores[1] = tscore;
00550   else          var->scores[0] = tscore;
00551 
00552   ordered = cm->orderedVariableArray;
00553   insert = 0;
00554   for(i=var->pos; i>=1; i--) {
00555     v = ordered->space[i-1];
00556     ttvar = SATgetVariable(v);
00557     ttscore = (ttvar->scores[1] > ttvar->scores[0]) ? ttvar->scores[1] : ttvar->scores[0];
00558     if(tscore > ttscore && i>1) {
00559       ttvar->pos = i;
00560       ordered->space[i] = v;
00561       continue;
00562     }
00563 
00564     var->pos = i;
00565     ordered->space[i] = unitLit;
00566     insert = 1;
00567     break;
00568   }
00569 
00570   if(insert == 0) {
00571     var->pos = i;
00572     ordered->space[0] = unitLit;
00573   }
00574 
00575   for(i=d->level; i>0; i--) {
00576     td = SATgetDecision(i);
00577     if(td->currentVarPos < var->pos)
00578       break;
00579     td->currentVarPos = var->pos;
00580   }
00581   cm->currentVarPos = td->currentVarPos;
00582 
00583 }
00584 
00596 void
00597 sat_CheckOrderedVariableArray(satManager_t *cm)
00598 {
00599 satArray_t *ordered;
00600 satVariable_t *var;
00601 int i;
00602 long v;
00603 
00604   ordered = cm->orderedVariableArray;
00605   for(i=0; i<ordered->num; i++) {
00606     v = ordered->space[i];
00607     var = SATgetVariable(v);
00608     if(i != var->pos) {
00609       fprintf(cm->stdOut, "Error : wrong variable position %d %d in ordered array\n", i, var->pos);
00610 
00611     }
00612   }
00613 }
00614 
00626 void
00627 sat_InitScore(satManager_t *cm)
00628 {
00629 int objExist;
00630 int j, inverted;
00631 long *plit, v, nv, i;
00632 int size;
00633 int count0, count1;
00634 satArray_t *ordered, *newOrdered;
00635 satVariable_t *var;
00636 
00637   ordered = cm->orderedVariableArray;
00638   if(ordered == 0)
00639     ordered = sat_ArrayAlloc(cm->initNumVariables);
00640   else
00641     ordered->num = 0;
00642   cm->orderedVariableArray = ordered;
00643 
00644   objExist = 0;
00653   for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize) {
00654     v = i;
00655     if((SATflags(v) & IsBDDMask)) {
00656       continue;
00657     }
00658     if((SATflags(v) & IsCNFMask)) {
00659       size = SATnumLits(v);
00660       plit = (long*)SATfirstLit(v);
00661       for(j=0; j<size; j++, plit++) {
00662         nv = SATgetNode(*plit);
00663         inverted = !(SATisInverted(nv));
00664         nv = SATnormalNode(nv);
00665         var = SATgetVariable(nv);
00666         var->litsCount[inverted]++;
00667       }
00668       continue;
00669     }
00670     if(!(SATflags(v) & CoiMask))        continue;
00671     if(!(SATflags(v) & VisitedMask) && objExist)        continue;
00672 
00673     if(SATvalue(v) != 2 && SATlevel(v) == 0)    continue;
00674 
00675     count0 = count1 = SATnFanout(v);
00676     if(count0 == 0 && SATleftChild(v) == 2 && SATrightChild(v) == 2) {
00677       count0 = 0;
00678       count1 = 0;
00679     }
00680     else if(SATleftChild(v) != 2) {
00681       count0 += 2;
00682       count1++;
00683     }
00684     else {
00685       count0 += 3;
00686       count1 += 3;
00687     }
00688 
00689     var = SATgetVariable(v);
00690     var->litsCount[0] += count0;
00691     var->litsCount[1] += count1;
00692 
00693     sat_ArrayInsert(ordered, v);
00694   }
00695 
00696   //Bing:
00697   if(cm->unitLits){
00698     for(i=0; i<cm->unitLits->num; i++) {
00699       v = cm->unitLits->space[i];
00700       v = SATnormalNode(v);
00701       SATflags(v) |= NewMask;
00702     }
00703   }
00704 
00705   if(cm->assertion) {
00706     for(i=0; i<cm->assertion->num; i++) {
00707       v = cm->assertion->space[i];
00708       v = SATnormalNode(v);
00709       SATflags(v) |= NewMask;
00710     }
00711   }
00712 
00713   newOrdered = sat_ArrayAlloc((ordered->num) * 2);
00714   size = ordered->num;
00715   for(i=0; i<size; i++) {
00716     v = ordered->space[i];
00717     var = SATgetVariable(v);
00718     var->scores[0] = var->lastLitsCount[0] = var->litsCount[0];
00719     var->scores[1] = var->lastLitsCount[1] = var->litsCount[1];
00720 
00721     if(SATflags(v) & NewMask);
00722     else if(var->scores[0] == 0 && var->scores[1] == 0 && !(SATflags(v) & NewMask)) {
00723       sat_ArrayInsert(cm->pureLits, (v));
00724     }
00725     else if(var->scores[0] == 0 && !(SATflags(v) & NewMask)) {
00726       sat_ArrayInsert(cm->pureLits, (v));
00727     }
00728     else if(var->scores[1] == 0 && !(SATflags(v) & NewMask)) {
00729       sat_ArrayInsert(cm->pureLits, SATnot(v));
00730     }
00731     else {
00732       sat_ArrayInsert(newOrdered, v);
00733       sat_ArrayInsert(newOrdered, (var->scores[0] > var->scores[1]) ? var->scores[0] : var->scores[1]);
00734     }
00735   }
00736 
00737   //Bing:
00738   if(cm->unitLits){
00739     for(i=0; i<cm->unitLits->num; i++) {
00740       v = cm->unitLits->space[i];
00741       v = SATnormalNode(v);
00742       SATflags(v) &= ResetNewMask;
00743     }
00744   }
00745 
00746   if(cm->assertion) {
00747     for(i=0; i<cm->assertion->num; i++) {
00748       v = cm->assertion->space[i];
00749       v = SATnormalNode(v);
00750       SATflags(v) &= ResetNewMask;
00751     }
00752   }
00753 
00754   cm->orderedVariableArray = ordered;
00755   size = newOrdered->num;
00756   qsort(newOrdered->space, size>>1, sizeof(long)*2, ScoreCompare);
00757 
00758   cm->currentVarPos = 0;
00759   ordered->num = 0;
00760   for(i=0; i<size; i++) {
00761     v = newOrdered->space[i];
00762     var = SATgetVariable(v);
00763     var->pos = (i>>1);
00764     sat_ArrayInsert(ordered, v);
00765     i++;
00766   }
00767 
00768   sat_ArrayFree(newOrdered);
00769 
00777   if(cm->option->verbose > 3)
00778     sat_PrintScore(cm);
00779 }
00780 
00792 void
00793 sat_InitScoreForMixed(satManager_t *cm)
00794 {
00795 int j, inverted;
00796 long *plit, v, nv, i;
00797 int size;
00798 int count0, count1;
00799 satArray_t *ordered, *newOrdered;
00800 satVariable_t *var;
00801 
00802   ordered = cm->orderedVariableArray;
00803   if(ordered == 0)
00804     ordered = sat_ArrayAlloc(cm->initNumVariables);
00805   else
00806     ordered->num = 0;
00807   cm->orderedVariableArray = ordered;
00808 
00818   for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize) {
00819     v = i;
00820     if((SATflags(v) & IsBDDMask)) {
00821       continue;
00822     }
00823     if((SATflags(v) & IsCNFMask)) {
00824       size = SATnumLits(v);
00825       plit =(long*) SATfirstLit(v);
00826       for(j=0; j<size; j++, plit++) {
00827         nv = SATgetNode(*plit);
00828         inverted = !(SATisInverted(nv));
00829         nv = SATnormalNode(nv);
00830         var = SATgetVariable(nv);
00831         var->litsCount[inverted]++;
00832       }
00833       continue;
00834     }
00835     if(!(SATflags(v) & CoiMask))        continue;
00840     if(SATvalue(v) != 2 && SATlevel(v) == 0)    continue;
00841 
00842     count0 = count1 = SATnFanout(v);
00843     if(count0 == 0 && SATleftChild(v) == 2 && SATrightChild(v) == 2) {
00844       count0 = 0;
00845       count1 = 0;
00846     }
00847     else if(SATleftChild(v) != 2) {
00848       count0 += 2;
00849       count1++;
00850     }
00851     else {
00852       count0 += 3;
00853       count1 += 3;
00854     }
00855 
00856     var = SATgetVariable(v);
00857     var->litsCount[0] += count0;
00858     var->litsCount[1] += count1;
00859 
00860     sat_ArrayInsert(ordered, v);
00861   }
00862 
00863   for(i=0; i<cm->unitLits->num; i++) {
00864     v = cm->unitLits->space[i];
00865     v = SATnormalNode(v);
00866     SATflags(v) |= NewMask;
00867   }
00868   if(cm->assertion) {
00869     for(i=0; i<cm->assertion->num; i++) {
00870       v = cm->assertion->space[i];
00871       v = SATnormalNode(v);
00872       SATflags(v) |= NewMask;
00873     }
00874   }
00875 
00876   newOrdered = sat_ArrayAlloc((ordered->num) * 2);
00877   size = ordered->num;
00878   for(i=0; i<size; i++) {
00879     v = ordered->space[i];
00880     var = SATgetVariable(v);
00881     var->scores[0] = var->lastLitsCount[0] = var->litsCount[0];
00882     var->scores[1] = var->lastLitsCount[1] = var->litsCount[1];
00883 
00884     if(SATflags(v) & NewMask);
00885     else if(var->scores[0] == 0 && var->scores[1] == 0 && !(SATflags(v) & NewMask)) {
00886       sat_ArrayInsert(cm->pureLits, (v));
00887     }
00888     else if(var->scores[0] == 0 && !(SATflags(v) & NewMask)) {
00889       sat_ArrayInsert(cm->pureLits, (v));
00890     }
00891     else if(var->scores[1] == 0 && !(SATflags(v) & NewMask)) {
00892       sat_ArrayInsert(cm->pureLits, SATnot(v));
00893     }
00894     else {
00895       sat_ArrayInsert(newOrdered, v);
00896       sat_ArrayInsert(newOrdered, (var->scores[0] > var->scores[1]) ? var->scores[0] : var->scores[1]);
00897     }
00898   }
00899 
00900   for(i=0; i<cm->unitLits->num; i++) {
00901     v = cm->unitLits->space[i];
00902     v = SATnormalNode(v);
00903     SATflags(v) &= ResetNewMask;
00904   }
00905   if(cm->assertion) {
00906     for(i=0; i<cm->assertion->num; i++) {
00907       v = cm->assertion->space[i];
00908       v = SATnormalNode(v);
00909       SATflags(v) &= ResetNewMask;
00910     }
00911   }
00912 
00913   cm->orderedVariableArray = ordered;
00914   size = newOrdered->num;
00915   qsort(newOrdered->space, size>>1, sizeof(long)*2, ScoreCompare);
00916 
00917   cm->currentVarPos = 0;
00918   ordered->num = 0;
00919   for(i=0; i<size; i++) {
00920     v = newOrdered->space[i];
00921     var = SATgetVariable(v);
00922     var->pos = (i>>1);
00923     sat_ArrayInsert(ordered, v);
00924     i++;
00925   }
00926 
00927   sat_ArrayFree(newOrdered);
00928 
00936   if(cm->option->verbose > 3)
00937     sat_PrintScore(cm);
00938 
00939 }
00951 static int
00952 ScoreCompare(
00953   const void * node1,
00954   const void * node2)
00955 {
00956 int v1;
00957 int v2;
00958 int s1, s2;
00959 
00960   v1 = *(int *)(node1);
00961   v2 = *(int *)(node2);
00962   s1 = *((int *)(node1) + 1);
00963   s2 = *((int *)(node2) + 1);
00970   if(s1 == s2) {
00971     return(v1 > v2);
00972   }
00973   return(s1 < s2);
00974 }