00001
00002
00003
00004 #include "bddint.h"
00005
00006
00007 static
00008 bdd
00009 bdd_restrict_step(cmu_bdd_manager bddm, bdd f, bdd_indexindex_type g_indexindex, bdd h, long op)
00010 {
00011 bdd temp1, temp2;
00012 bdd result;
00013
00014 BDD_SETUP(f);
00015 if (BDD_INDEX(bddm, f) > bddm->indexes[g_indexindex])
00016 {
00017
00018 BDD_TEMP_INCREFS(f);
00019 return (f);
00020 }
00021 if (BDD_INDEXINDEX(f) == g_indexindex)
00022 {
00023
00024 result=(h == BDD_ONE(bddm) ? BDD_THEN(f) : BDD_ELSE(f));
00025 {
00026 BDD_SETUP(result);
00027 BDD_TEMP_INCREFS(result);
00028 return (result);
00029 }
00030 }
00031 if (bdd_lookup_in_cache2(bddm, op, BDD_OUTPOS(f), h, &result))
00032 return (BDD_IS_OUTPOS(f) ? result : BDD_NOT(result));
00033 temp1=bdd_restrict_step(bddm, BDD_THEN(f), g_indexindex, h, op);
00034 temp2=bdd_restrict_step(bddm, BDD_ELSE(f), g_indexindex, h, op);
00035 result=bdd_find(bddm, BDD_INDEXINDEX(f), temp1, temp2);
00036 if (BDD_IS_OUTPOS(f))
00037 bdd_insert_in_cache2(bddm, op, f, h, result);
00038 else
00039 bdd_insert_in_cache2(bddm, op, BDD_NOT(f), h, BDD_NOT(result));
00040 return (result);
00041 }
00042
00043
00044 static
00045 bdd
00046 cmu_bdd_compose_step(cmu_bdd_manager bddm, bdd f, bdd_indexindex_type g_indexindex, bdd h, long op)
00047 {
00048 bdd_indexindex_type top_indexindex;
00049 bdd f1, f2;
00050 bdd h1, h2;
00051 bdd temp1, temp2;
00052 bdd result;
00053
00054 BDD_SETUP(f);
00055 BDD_SETUP(h);
00056
00057 if (BDD_IS_CONST(h))
00058 return (bdd_restrict_step(bddm, f, g_indexindex, h, op));
00059 if (BDD_INDEX(bddm, f) > bddm->indexes[g_indexindex])
00060 {
00061
00062 BDD_TEMP_INCREFS(f);
00063 return (f);
00064 }
00065 if (bdd_lookup_in_cache2(bddm, op, BDD_OUTPOS(f), h, &result))
00066 return (BDD_IS_OUTPOS(f) ? result : BDD_NOT(result));
00067 if (BDD_INDEXINDEX(f) == g_indexindex)
00068 {
00069
00070 bddm->op_cache.cache_level++;
00071 result=cmu_bdd_ite_step(bddm, h, BDD_THEN(f), BDD_ELSE(f));
00072 bddm->op_cache.cache_level--;
00073 }
00074 else
00075 {
00076 BDD_TOP_VAR2(top_indexindex, bddm, f, h);
00077 BDD_COFACTOR(top_indexindex, f, f1, f2);
00078 BDD_COFACTOR(top_indexindex, h, h1, h2);
00079 temp1=cmu_bdd_compose_step(bddm, f1, g_indexindex, h1, op);
00080 temp2=cmu_bdd_compose_step(bddm, f2, g_indexindex, h2, op);
00081 result=bdd_find(bddm, top_indexindex, temp1, temp2);
00082 }
00083 if (BDD_IS_OUTPOS(f))
00084 bdd_insert_in_cache2(bddm, op, f, h, result);
00085 else
00086 bdd_insert_in_cache2(bddm, op, BDD_NOT(f), h, BDD_NOT(result));
00087 return (result);
00088 }
00089
00090
00091
00092
00093 bdd
00094 cmu_bdd_compose_temp(cmu_bdd_manager bddm, bdd f, bdd g, bdd h)
00095 {
00096 BDD_SETUP(g);
00097 return (cmu_bdd_compose_step(bddm, f, BDD_INDEXINDEX(g), h, OP_COMP+BDD_INDEXINDEX(g)));
00098 }
00099
00100
00101
00102
00103
00104 bdd
00105 cmu_bdd_compose(cmu_bdd_manager bddm, bdd f, bdd g, bdd h)
00106 {
00107 if (bdd_check_arguments(3, f, g, h))
00108 {
00109 BDD_SETUP(f);
00110 BDD_SETUP(g);
00111 if (cmu_bdd_type_aux(bddm, g) != BDD_TYPE_POSVAR)
00112 {
00113 cmu_bdd_warning("cmu_bdd_compose: second argument is not a positive variable");
00114 BDD_INCREFS(f);
00115 return (f);
00116 }
00117 FIREWALL(bddm);
00118 RETURN_BDD(cmu_bdd_compose_step(bddm, f, BDD_INDEXINDEX(g), h, OP_COMP+BDD_INDEXINDEX(g)));
00119 }
00120 return ((bdd)0);
00121 }
00122
00123
00124 bdd
00125 cmu_bdd_substitute_step(cmu_bdd_manager bddm, bdd f, long op, bdd (*ite_fn)(cmu_bdd_manager, bdd, bdd, bdd), var_assoc subst)
00126 {
00127 bdd g;
00128 bdd temp1, temp2;
00129 bdd result;
00130 bdd_index_type g_index;
00131
00132 BDD_SETUP(f);
00133 if ((long)BDD_INDEX(bddm, f) > subst->last)
00134 {
00135 BDD_TEMP_INCREFS(f);
00136 return (f);
00137 }
00138 if (bdd_lookup_in_cache1(bddm, op, BDD_OUTPOS(f), &result))
00139 return (BDD_IS_OUTPOS(f) ? result : BDD_NOT(result));
00140 g=subst->assoc[BDD_INDEXINDEX(f)];
00141
00142 if (g == BDD_ONE(bddm))
00143 return (cmu_bdd_substitute_step(bddm, BDD_THEN(f), op, ite_fn, subst));
00144 if (g == BDD_ZERO(bddm))
00145 return (cmu_bdd_substitute_step(bddm, BDD_ELSE(f), op, ite_fn, subst));
00146 temp1=cmu_bdd_substitute_step(bddm, BDD_THEN(f), op, ite_fn, subst);
00147 temp2=cmu_bdd_substitute_step(bddm, BDD_ELSE(f), op, ite_fn, subst);
00148 if (!g)
00149 g=BDD_IF(bddm, f);
00150 {
00151 BDD_SETUP(g);
00152 BDD_SETUP(temp1);
00153 BDD_SETUP(temp2);
00154 if (g == BDD_IF(bddm, g) &&
00155 (g_index=BDD_INDEX(bddm, g)) < BDD_INDEX(bddm, temp1) &&
00156 g_index < BDD_INDEX(bddm, temp2))
00157
00158 result=bdd_find(bddm, BDD_INDEXINDEX(g), temp1, temp2);
00159 else
00160 {
00161
00162 bddm->op_cache.cache_level++;
00163 result=(*ite_fn)(bddm, g, temp1, temp2);
00164 BDD_TEMP_DECREFS(temp1);
00165 BDD_TEMP_DECREFS(temp2);
00166 bddm->op_cache.cache_level--;
00167 }
00168 }
00169 if (BDD_IS_OUTPOS(f))
00170 bdd_insert_in_cache1(bddm, op, f, result);
00171 else
00172 bdd_insert_in_cache1(bddm, op, BDD_NOT(f), BDD_NOT(result));
00173 return (result);
00174 }
00175
00176
00177
00178
00179
00180 bdd
00181 cmu_bdd_substitute(cmu_bdd_manager bddm, bdd f)
00182 {
00183 long op;
00184
00185 if (bdd_check_arguments(1, f))
00186 {
00187 FIREWALL(bddm);
00188 if (bddm->curr_assoc_id == -1)
00189 op=bddm->temp_op--;
00190 else
00191 op=OP_SUBST+bddm->curr_assoc_id;
00192 RETURN_BDD(cmu_bdd_substitute_step(bddm, f, op, cmu_bdd_ite_step, bddm->curr_assoc));
00193 }
00194 return ((bdd)0);
00195 }