00001
00002
00003
00004 #include "bddint.h"
00005
00006
00007 static
00008 int
00009 cmu_bdd_assoc_eq(cmu_bdd_manager bddm, bdd *p, bdd *q)
00010 {
00011 bdd_indexindex_type i;
00012
00013 for (i=0; i < bddm->maxvars; ++i)
00014 if (p[i+1] != q[i+1])
00015 return (0);
00016 return (1);
00017 }
00018
00019
00020 static
00021 int
00022 check_assoc(cmu_bdd_manager bddm, bdd *assoc_info, int pairs)
00023 {
00024 bdd_check_array(assoc_info);
00025 if (pairs)
00026 while (assoc_info[0] && assoc_info[1])
00027 {
00028 if (cmu_bdd_type_aux(bddm, assoc_info[0]) != BDD_TYPE_POSVAR)
00029 {
00030 cmu_bdd_warning("check_assoc: first element in pair is not a positive variable");
00031 return (0);
00032 }
00033 assoc_info+=2;
00034 }
00035 return (1);
00036 }
00037
00038
00039
00040
00041
00042
00043 int
00044 cmu_bdd_new_assoc(cmu_bdd_manager bddm, bdd *assoc_info, int pairs)
00045 {
00046 long i;
00047 assoc_list p, *q;
00048 bdd f;
00049 bdd *assoc;
00050 bdd_indexindex_type j;
00051 long last;
00052
00053 if (!check_assoc(bddm, assoc_info, pairs))
00054 return (-1);
00055 assoc=(bdd *)mem_get_block((SIZE_T)((bddm->maxvars+1)*sizeof(bdd)));
00056
00057 for (i=0; i < bddm->maxvars; ++i)
00058 assoc[i+1]=0;
00059 if (pairs)
00060 for (i=0; (f=assoc_info[i]) && assoc_info[i+1]; i+=2)
00061 {
00062 BDD_SETUP(f);
00063 assoc[BDD_INDEXINDEX(f)]=assoc_info[i+1];
00064 }
00065 else
00066 for (i=0; (f=assoc_info[i]); ++i)
00067 {
00068 BDD_SETUP(f);
00069 assoc[BDD_INDEXINDEX(f)]=BDD_ONE(bddm);
00070 }
00071
00072 for (p=bddm->assocs; p; p=p->next)
00073 if (cmu_bdd_assoc_eq(bddm, p->va.assoc, assoc))
00074 {
00075 mem_free_block((pointer)assoc);
00076 p->refs++;
00077 return (p->id);
00078 }
00079
00080 for (q= &bddm->assocs, p= *q, i=0; p && p->id == i; q= &p->next, p= *q, ++i);
00081 p=(assoc_list)BDD_NEW_REC(bddm, sizeof(struct assoc_list_));
00082 p->id=i;
00083 p->next= *q;
00084 *q=p;
00085 p->va.assoc=assoc;
00086 last= -1;
00087 if (pairs)
00088 for (i=0; (f=assoc_info[i]) && assoc_info[i+1]; i+=2)
00089 {
00090 BDD_SETUP(f);
00091 j=BDD_INDEXINDEX(f);
00092 if ((long)bddm->indexes[j] > last)
00093 last=bddm->indexes[j];
00094 }
00095 else
00096 for (i=0; (f=assoc_info[i]); ++i)
00097 {
00098 BDD_SETUP(f);
00099 j=BDD_INDEXINDEX(f);
00100 if ((long)bddm->indexes[j] > last)
00101 last=bddm->indexes[j];
00102 }
00103 p->va.last=last;
00104 p->refs=1;
00105
00106 if (pairs)
00107 for (i=0; assoc_info[i] && (f=assoc_info[i+1]); i+=2)
00108 {
00109 BDD_SETUP(f);
00110 BDD_INCREFS(f);
00111 }
00112 return (p->id);
00113 }
00114
00115
00116 static
00117 int
00118 bdd_flush_id_entries(cmu_bdd_manager bddm, cache_entry p, pointer closure)
00119 {
00120 int (*flush_fn)(cmu_bdd_manager, cache_entry, pointer);
00121
00122 flush_fn=bddm->op_cache.flush_fn[TAG(p)];
00123 if (flush_fn)
00124 return ((*flush_fn)(bddm, CACHE_POINTER(p), closure));
00125 return (0);
00126 }
00127
00128
00129
00130
00131
00132 void
00133 cmu_bdd_free_assoc(cmu_bdd_manager bddm, int assoc_id)
00134 {
00135 bdd_indexindex_type i;
00136 bdd f;
00137 assoc_list p, *q;
00138
00139 if (bddm->curr_assoc_id == assoc_id)
00140 {
00141 bddm->curr_assoc_id= -1;
00142 bddm->curr_assoc= &bddm->temp_assoc;
00143 }
00144 for (q= &bddm->assocs, p= *q; p; q= &p->next, p= *q)
00145 if (p->id == assoc_id)
00146 {
00147 p->refs--;
00148 if (!p->refs)
00149 {
00150
00151 for (i=0; i < bddm->vars; ++i)
00152 if ((f=p->va.assoc[i+1]))
00153 {
00154 BDD_SETUP(f);
00155 BDD_DECREFS(f);
00156 }
00157
00158 bdd_flush_cache(bddm, bdd_flush_id_entries, (pointer)((long)assoc_id));
00159 *q=p->next;
00160 mem_free_block((pointer)(p->va.assoc));
00161 BDD_FREE_REC(bddm, (pointer)p, sizeof(struct assoc_list_));
00162 }
00163 return;
00164 }
00165 cmu_bdd_warning("cmu_bdd_free_assoc: no variable association with specified ID");
00166 }
00167
00168
00169
00170
00171
00172
00173
00174 void
00175 cmu_bdd_augment_temp_assoc(cmu_bdd_manager bddm, bdd *assoc_info, int pairs)
00176 {
00177 long i;
00178 bdd_indexindex_type j;
00179 bdd f;
00180 long last;
00181
00182 if (check_assoc(bddm, assoc_info, pairs))
00183 {
00184 last=bddm->temp_assoc.last;
00185 if (pairs)
00186 for (i=0; (f=assoc_info[i]) && assoc_info[i+1]; i+=2)
00187 {
00188 BDD_SETUP(f);
00189 j=BDD_INDEXINDEX(f);
00190 if ((long)bddm->indexes[j] > last)
00191 last=bddm->indexes[j];
00192 if ((f=bddm->temp_assoc.assoc[j]))
00193 {
00194 BDD_SETUP(f);
00195 BDD_DECREFS(f);
00196 }
00197 f=assoc_info[i+1];
00198 BDD_RESET(f);
00199 bddm->temp_assoc.assoc[j]=f;
00200
00201 BDD_INCREFS(f);
00202 }
00203 else
00204 for (i=0; (f=assoc_info[i]); ++i)
00205 {
00206 BDD_SETUP(f);
00207 j=BDD_INDEXINDEX(f);
00208 if ((long)bddm->indexes[j] > last)
00209 last=bddm->indexes[j];
00210 if ((f=bddm->temp_assoc.assoc[j]))
00211 {
00212 BDD_SETUP(f);
00213 BDD_DECREFS(f);
00214 }
00215 bddm->temp_assoc.assoc[j]=BDD_ONE(bddm);
00216 }
00217 bddm->temp_assoc.last=last;
00218 }
00219 }
00220
00221
00222
00223
00224
00225
00226
00227 void
00228 cmu_bdd_temp_assoc(cmu_bdd_manager bddm, bdd *assoc_info, int pairs)
00229 {
00230 long i;
00231 bdd f;
00232
00233
00234 for (i=0; i < bddm->vars; ++i)
00235 {
00236 if ((f=bddm->temp_assoc.assoc[i+1]))
00237 {
00238 BDD_SETUP(f);
00239 BDD_DECREFS(f);
00240 }
00241 bddm->temp_assoc.assoc[i+1]=0;
00242 }
00243 bddm->temp_assoc.last= -1;
00244 cmu_bdd_augment_temp_assoc(bddm, assoc_info, pairs);
00245 }
00246
00247
00248
00249
00250
00251
00252 int
00253 cmu_bdd_assoc(cmu_bdd_manager bddm, int assoc_id)
00254 {
00255 int old_assoc;
00256 assoc_list p;
00257
00258 old_assoc=bddm->curr_assoc_id;
00259 if (assoc_id != -1)
00260 {
00261 for (p=bddm->assocs; p; p=p->next)
00262 if (p->id == assoc_id)
00263 {
00264 bddm->curr_assoc_id=p->id;
00265 bddm->curr_assoc= &p->va;
00266 return (old_assoc);
00267 }
00268 cmu_bdd_warning("cmu_bdd_assoc: no variable association with specified ID");
00269 }
00270 bddm->curr_assoc_id= -1;
00271 bddm->curr_assoc= &bddm->temp_assoc;
00272 return (old_assoc);
00273 }