00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 #include "espresso.h"
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 static pcover reduce_gasp(F, D)
00042 pcover F, D;
00043 {
00044     pcube p, last, cunder, *FD;
00045     pcover G;
00046 
00047     G = new_cover(F->count);
00048     FD = cube2list(F, D);
00049 
00050     
00051     foreach_set(F, last, p) {
00052         cunder = reduce_cube(FD, p);
00053         if (setp_empty(cunder)) {
00054             fatal("empty reduction in reduce_gasp, shouldn't happen");
00055         } else if (setp_equal(cunder, p)) {
00056             SET(cunder, PRIME);                 
00057             G = sf_addset(G, p);                
00058         } else {
00059             RESET(cunder, PRIME);               
00060             G = sf_addset(G, cunder);
00061         }
00062         if (debug & GASP) {
00063             printf("REDUCE_GASP: %s reduced to %s\n", pc1(p), pc2(cunder));
00064         }
00065         free_cube(cunder);
00066     }
00067 
00068     free_cubelist(FD);
00069     return G;
00070 }
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 pcover expand_gasp(F, D, R, Foriginal)
00081 INOUT pcover F;
00082 IN pcover D;
00083 IN pcover R;
00084 IN pcover Foriginal;
00085 {
00086     int c1index;
00087     pcover G;
00088 
00089     
00090     G = new_cover(10);
00091     for(c1index = 0; c1index < F->count; c1index++) {
00092         expand1_gasp(F, D, R, Foriginal, c1index, &G);
00093     }
00094     G = sf_dupl(G);
00095     G = expand(G, R,  FALSE);      
00096     return G;
00097 }
00098 
00099 
00100 
00101 
00102 
00103 
00104 void expand1_gasp(F, D, R, Foriginal, c1index, G)
00105 pcover F;               
00106 pcover D;               
00107 pcover R;               
00108 pcover Foriginal;       
00109 int c1index;            
00110 pcover *G;
00111 {
00112     register int c2index;
00113     register pcube p, last, c2under;
00114     pcube RAISE, FREESET, temp, *FD, c2essential;
00115     pcover F1;
00116 
00117     if (debug & EXPAND1) {
00118         printf("\nEXPAND1_GASP:    \t%s\n", pc1(GETSET(F, c1index)));
00119     }
00120 
00121     RAISE = new_cube();
00122     FREESET = new_cube();
00123     temp = new_cube();
00124 
00125     
00126     R->active_count = R->count;
00127     foreach_set(R, last, p) {
00128         SET(p, ACTIVE);
00129     }
00130     
00131     F->active_count = F->count;
00132     foreachi_set(F, c2index, c2under) {
00133         if (c1index == c2index || TESTP(c2under, PRIME)) {
00134             F->active_count--;
00135             RESET(c2under, ACTIVE);
00136         } else {
00137             SET(c2under, ACTIVE);
00138         }
00139     }
00140 
00141     
00142     (void) set_copy(RAISE, GETSET(F, c1index));
00143     (void) set_diff(FREESET, cube.fullset, RAISE);
00144 
00145     
00146     essen_parts(R, F, RAISE, FREESET);
00147 
00148     
00149     essen_raising(R, RAISE, FREESET);
00150 
00151     
00152     foreachi_set(F, c2index, c2under) {
00153         if (TESTP(c2under, ACTIVE)) {
00154             
00155             if (setp_implies(c2under, RAISE) ||
00156               feasibly_covered(R, c2under, RAISE, temp)) {
00157                 
00158                 
00159 
00160 
00161 
00162                 
00163                 F1 = sf_save(Foriginal);
00164                 (void) set_copy(GETSET(F1, c1index), GETSET(F, c1index));
00165 
00166                 
00167                 FD = cube2list(F1, D);
00168                 c2essential = reduce_cube(FD, GETSET(F1, c2index));
00169                 free_cubelist(FD);
00170                 sf_free(F1);
00171 
00172                 
00173                 if (feasibly_covered(R, c2essential, RAISE, temp)) {
00174                     (void) set_or(temp, RAISE, c2essential);
00175                     RESET(temp, PRIME);         
00176                     *G = sf_addset(*G, temp);
00177                 }
00178                 set_free(c2essential);
00179             }
00180         }
00181     }
00182 
00183     free_cube(RAISE);
00184     free_cube(FREESET);
00185     free_cube(temp);
00186 }
00187 
00188 
00189 pcover irred_gasp(F, D, G)
00190 pcover F, D, G;                 
00191 {
00192     if (G->count != 0)
00193         F = irredundant(sf_append(F, G), D);
00194     else
00195         free_cover(G);
00196     return F;
00197 }
00198 
00199 
00200 
00201 pcover last_gasp(F, D, R, cost)
00202 pcover F, D, R;
00203 cost_t *cost;
00204 {
00205     pcover G, G1;
00206 
00207     EXECUTE(G = reduce_gasp(F, D), GREDUCE_TIME, G, *cost);
00208     EXECUTE(G1 = expand_gasp(G, D, R, F), GEXPAND_TIME, G1, *cost);
00209     free_cover(G);
00210     EXECUTE(F = irred_gasp(F, D, G1), GIRRED_TIME, F, *cost);
00211     return F;
00212 }
00213 
00214 
00215 
00216 pcover super_gasp(F, D, R, cost)
00217 pcover F, D, R;
00218 cost_t *cost;
00219 {
00220     pcover G, G1;
00221 
00222     EXECUTE(G = reduce_gasp(F, D), GREDUCE_TIME, G, *cost);
00223     EXECUTE(G1 = all_primes(G, R), GEXPAND_TIME, G1, *cost);
00224     free_cover(G);
00225     EXEC(G = sf_dupl(sf_append(F, G1)), "NEWPRIMES", G);
00226     EXECUTE(F = irredundant(G, D), IRRED_TIME, F, *cost);
00227     return F;
00228 }