00001
00002
00003
00004 #include "bddint.h"
00005
00006
00007 static
00008 void
00009 bdd_mark_bdd(bdd f)
00010 {
00011 int curr_marking, this_marking;
00012
00013 BDD_SETUP(f);
00014 curr_marking=BDD_MARK(f);
00015 this_marking=(1 << TAG(f));
00016 if (curr_marking & this_marking)
00017 return;
00018 BDD_MARK(f)=curr_marking | this_marking;
00019 if (BDD_IS_CONST(f))
00020 return;
00021 bdd_mark_bdd(BDD_THEN(f));
00022 bdd_mark_bdd(BDD_ELSE(f));
00023 }
00024
00025
00026 static
00027 int
00028 bdd_count_no_nodes(bdd f)
00029 {
00030 BDD_SETUP(f);
00031 return (BDD_MARK(f) > 0);
00032 }
00033
00034
00035 static
00036 int
00037 bdd_count_nodes(bdd f)
00038 {
00039 int mark;
00040
00041 BDD_SETUP(f);
00042 mark=BDD_MARK(f);
00043 return (((mark & 0x1) != 0)+((mark & 0x2) != 0));
00044 }
00045
00046
00047 static
00048 int (*(counting_fns[]))(bdd)=
00049 {
00050 bdd_count_no_nodes,
00051 bdd_count_nodes,
00052 };
00053
00054
00055 static
00056 long
00057 cmu_bdd_size_step(bdd f, int (*count_fn)(bdd))
00058 {
00059 long result;
00060
00061 BDD_SETUP(f);
00062 if (!BDD_MARK(f))
00063 return (0l);
00064 result=(*count_fn)(f);
00065 if (!BDD_IS_CONST(f))
00066 result+=cmu_bdd_size_step(BDD_THEN(f), count_fn)+cmu_bdd_size_step(BDD_ELSE(f), count_fn);
00067 BDD_MARK(f)=0;
00068 return (result);
00069 }
00070
00071
00072
00073
00074
00075
00076 long
00077 cmu_bdd_size(cmu_bdd_manager bddm, bdd f, int negout)
00078 {
00079 bdd g;
00080
00081 if (bdd_check_arguments(1, f))
00082 {
00083 g=BDD_ONE(bddm);
00084 {
00085 BDD_SETUP(g);
00086 BDD_MARK(g)=0;
00087 }
00088 bdd_mark_bdd(f);
00089 return (cmu_bdd_size_step(f, counting_fns[!negout]));
00090 }
00091 return (0l);
00092 }
00093
00094
00095
00096
00097
00098 long
00099 cmu_bdd_size_multiple(cmu_bdd_manager bddm, bdd* fs, int negout)
00100 {
00101 long size;
00102 bdd *f;
00103 bdd g;
00104
00105 bdd_check_array(fs);
00106 g=BDD_ONE(bddm);
00107 {
00108 BDD_SETUP(g);
00109 BDD_MARK(g)=0;
00110 }
00111 for (f=fs; *f; ++f)
00112 bdd_mark_bdd(*f);
00113 size=0l;
00114 for (f=fs; *f; ++f)
00115 size+=cmu_bdd_size_step(*f, counting_fns[!negout]);
00116 return (size);
00117 }
00118
00119
00120 static
00121 void
00122 cmu_bdd_profile_step(cmu_bdd_manager bddm, bdd f, long *level_counts, int (*count_fn)(bdd))
00123 {
00124 BDD_SETUP(f);
00125 if (!BDD_MARK(f))
00126 return;
00127 if (BDD_IS_CONST(f))
00128 level_counts[bddm->vars]+=(*count_fn)(f);
00129 else
00130 {
00131 level_counts[BDD_INDEX(bddm, f)]+=(*count_fn)(f);
00132 cmu_bdd_profile_step(bddm, BDD_THEN(f), level_counts, count_fn);
00133 cmu_bdd_profile_step(bddm, BDD_ELSE(f), level_counts, count_fn);
00134 }
00135 BDD_MARK(f)=0;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144 void
00145 cmu_bdd_profile(cmu_bdd_manager bddm, bdd f, long *level_counts, int negout)
00146 {
00147 bdd_index_type i;
00148 bdd g;
00149
00150 for (i=0; i <= bddm->vars; ++i)
00151 level_counts[i]=0l;
00152 if (bdd_check_arguments(1, f))
00153 {
00154 g=BDD_ONE(bddm);
00155 {
00156 BDD_SETUP(g);
00157 BDD_MARK(g)=0;
00158 }
00159 bdd_mark_bdd(f);
00160 cmu_bdd_profile_step(bddm, f, level_counts, counting_fns[!negout]);
00161 }
00162 }
00163
00164
00165
00166
00167
00168 void
00169 cmu_bdd_profile_multiple(cmu_bdd_manager bddm, bdd *fs, long *level_counts, int negout)
00170 {
00171 bdd_index_type i;
00172 bdd *f;
00173 bdd g;
00174
00175 bdd_check_array(fs);
00176 for (i=0; i <= bddm->vars; ++i)
00177 level_counts[i]=0l;
00178 g=BDD_ONE(bddm);
00179 {
00180 BDD_SETUP(g);
00181 BDD_MARK(g)=0;
00182 }
00183 for (f=fs; *f; ++f)
00184 bdd_mark_bdd(*f);
00185 for (f=fs; *f; ++f)
00186 cmu_bdd_profile_step(bddm, *f, level_counts, counting_fns[!negout]);
00187 }
00188
00189
00190 static
00191 void
00192 bdd_highest_ref_step(cmu_bdd_manager bddm, bdd f, hash_table h)
00193 {
00194 long *hash_result;
00195 long f_index;
00196
00197 BDD_SETUP(f);
00198 if (BDD_IS_CONST(f))
00199 return;
00200 f_index=BDD_INDEX(bddm, f);
00201 if ((hash_result=(long *)bdd_lookup_in_hash_table(h, BDD_THEN(f))))
00202 {
00203 if (*hash_result > f_index)
00204 *hash_result=f_index;
00205 }
00206 else
00207 {
00208 bdd_insert_in_hash_table(h, BDD_THEN(f), (pointer)&f_index);
00209 bdd_highest_ref_step(bddm, BDD_THEN(f), h);
00210 }
00211 if ((hash_result=(long *)bdd_lookup_in_hash_table(h, BDD_ELSE(f))))
00212 {
00213 if (*hash_result > f_index)
00214 *hash_result=f_index;
00215 }
00216 else
00217 {
00218 bdd_insert_in_hash_table(h, BDD_ELSE(f), (pointer)&f_index);
00219 bdd_highest_ref_step(bddm, BDD_ELSE(f), h);
00220 }
00221 }
00222
00223
00224 static
00225 void
00226 bdd_dominated_step(cmu_bdd_manager bddm, bdd f, long *func_counts, hash_table h)
00227 {
00228 long *hash_result;
00229
00230 hash_result=(long *)bdd_lookup_in_hash_table(h, f);
00231 if (*hash_result >= 0)
00232 func_counts[*hash_result]-=2;
00233 if (*hash_result > -2)
00234 {
00235 BDD_SETUP(f);
00236 *hash_result= -2;
00237 if (!BDD_IS_CONST(f))
00238 {
00239 bdd_dominated_step(bddm, BDD_THEN(f), func_counts, h);
00240 bdd_dominated_step(bddm, BDD_ELSE(f), func_counts, h);
00241 }
00242 }
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 void
00254 cmu_bdd_function_profile(cmu_bdd_manager bddm, bdd f, long *func_counts)
00255 {
00256 long i;
00257 bdd_index_type j;
00258 hash_table h;
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 cmu_bdd_profile(bddm, f, func_counts, 0);
00272 if (bdd_check_arguments(1, f))
00273 {
00274
00275
00276 for (j=0; j < bddm->vars; ++j)
00277 if (!func_counts[j])
00278 func_counts[j]=1;
00279 else
00280 func_counts[j]<<=1;
00281 h=bdd_new_hash_table(bddm, sizeof(long));
00282
00283
00284
00285 i= -1;
00286 bdd_insert_in_hash_table(h, f, (pointer)&i);
00287 bdd_highest_ref_step(bddm, f, h);
00288
00289
00290 bdd_dominated_step(bddm, f, func_counts, h);
00291 cmu_bdd_free_hash_table(h);
00292
00293 for (i=bddm->vars-1, j=i+1; i>= 0; --i)
00294 if (func_counts[i] != 1)
00295 {
00296 func_counts[i]=(func_counts[i] >> 1)+func_counts[j];
00297 j=i;
00298 }
00299 else
00300 func_counts[i]=0;
00301 }
00302 }
00303
00304
00305
00306
00307
00308 void
00309 cmu_bdd_function_profile_multiple(cmu_bdd_manager bddm, bdd *fs, long *func_counts)
00310 {
00311 long i;
00312 bdd_index_type j;
00313 bdd *f;
00314 long *hash_result;
00315 hash_table h;
00316
00317 bdd_check_array(fs);
00318
00319 cmu_bdd_profile_multiple(bddm, fs, func_counts, 0);
00320 for (j=0; j < bddm->vars; ++j)
00321 if (!func_counts[j])
00322 func_counts[j]=1;
00323 else
00324 func_counts[j]<<=1;
00325 h=bdd_new_hash_table(bddm, sizeof(long));
00326 for (f=fs; *f; ++f)
00327 bdd_highest_ref_step(bddm, *f, h);
00328 i= -1;
00329 for (f=fs; *f; ++f)
00330 if ((hash_result=(long *)bdd_lookup_in_hash_table(h, *f)))
00331 *hash_result= -1;
00332 else
00333 bdd_insert_in_hash_table(h, *f, (pointer)&i);
00334 for (f=fs; *f; ++f)
00335 bdd_dominated_step(bddm, *f, func_counts, h);
00336 cmu_bdd_free_hash_table(h);
00337 for (i=bddm->vars-1, j=i+1; i>= 0; --i)
00338 if (func_counts[i] != 1)
00339 {
00340 func_counts[i]=(func_counts[i] >> 1)+func_counts[j];
00341 j=i;
00342 }
00343 else
00344 func_counts[i]=0;
00345 }