00001
00002
00098
00099
00100 #ifndef pbori_algorithms_h_
00101 #define pbori_algorithms_h_
00102
00103
00104 #include <numeric>
00105
00106
00107 #include "pbori_defs.h"
00108
00109
00110 #include "pbori_algo.h"
00111
00112
00113 #include "BoolePolynomial.h"
00114 #include "BooleMonomial.h"
00115 #include "CGenericIter.h"
00116
00117
00118 BEGIN_NAMESPACE_PBORI
00119
00122 inline BoolePolynomial
00123 spoly(const BoolePolynomial& first, const BoolePolynomial& second){
00124
00125 BooleMonomial lead1(first.lead()), lead2(second.lead());
00126
00127 BooleMonomial prod = lead1;
00128 prod *= lead2;
00129
00130 return ( first * (prod / lead1) ) + ( second * (prod / lead2) );
00131 }
00132
00133 template <class NaviType, class LowerIterator, class ValueType>
00134 ValueType
00135 lower_term_accumulate(NaviType navi,
00136 LowerIterator lstart, LowerIterator lfinish,
00137 ValueType init) {
00138 assert(init.isZero());
00140 if (lstart == lfinish){
00141 return init;
00142 }
00143
00144 if (navi.isConstant())
00145 return (navi.terminalValue()? (ValueType)init.ring().one(): init);
00146
00147 assert(*lstart >= *navi);
00148
00149 ValueType result;
00150 if (*lstart > *navi) {
00151
00152 ValueType reselse =
00153 lower_term_accumulate(navi.elseBranch(), lstart, lfinish, init);
00154
00155
00156
00157
00158
00159
00160
00161
00162 result = BooleSet(*navi, navi.thenBranch(), reselse.navigation(),
00163 init.ring());
00164 }
00165 else {
00166 assert(*lstart == *navi);
00167 ++lstart;
00168 BooleSet resthen =
00169 lower_term_accumulate(navi.thenBranch(), lstart, lfinish, init).diagram();
00170
00171 result = resthen.change(*navi);
00172 }
00173
00174 return result;
00175 }
00176
00177
00178 template <class UpperIterator, class NaviType, class ValueType>
00179 ValueType
00180 upper_term_accumulate(UpperIterator ustart, UpperIterator ufinish,
00181 NaviType navi, ValueType init) {
00182
00183
00184
00185
00186
00187
00188
00189 if (ustart == ufinish)
00190 return init.ring().one();
00191
00192 while (*navi < *ustart)
00193 navi.incrementElse();
00194 ++ustart;
00195 NaviType navithen = navi.thenBranch();
00196 ValueType resthen = upper_term_accumulate(ustart, ufinish, navithen, init);
00197
00198
00199 if (navithen == resthen.navigation())
00200 return BooleSet(navi, init.ring());
00201
00202 return BooleSet(*navi, resthen.navigation(), navi.elseBranch(), init.ring());
00203 }
00204
00206 template <class UpperIterator, class NaviType, class LowerIterator,
00207 class ValueType>
00208 ValueType
00209 term_accumulate(UpperIterator ustart, UpperIterator ufinish, NaviType navi,
00210 LowerIterator lstart, LowerIterator lfinish, ValueType init) {
00211
00212
00213 if (lstart == lfinish)
00214 return upper_term_accumulate(ustart, ufinish, navi, init);
00215
00216 if (ustart == ufinish)
00217 return init.ring().one();
00218
00219 while (*navi < *ustart)
00220 navi.incrementElse();
00221 ++ustart;
00222
00223
00224 if (navi.isConstant())
00225 return BooleSet(navi, init.ring());
00226
00227 assert(*lstart >= *navi);
00228
00229 ValueType result;
00230 if (*lstart > *navi) {
00231 ValueType resthen =
00232 upper_term_accumulate(ustart, ufinish, navi.thenBranch(), init);
00233 ValueType reselse =
00234 lower_term_accumulate(navi.elseBranch(), lstart, lfinish, init);
00235
00236 result = BooleSet(*navi, resthen.navigation(), reselse.navigation(),
00237 init.ring());
00238 }
00239 else {
00240 assert(*lstart == *navi);
00241 ++lstart;
00242 BooleSet resthen = term_accumulate(ustart, ufinish, navi.thenBranch(),
00243 lstart, lfinish, init).diagram();
00244
00245 result = resthen.change(*navi);
00246 }
00247
00248 return result;
00249 }
00250
00251
00252
00253
00256 template <class InputIterator, class ValueType>
00257 ValueType
00258 term_accumulate(InputIterator first, InputIterator last, ValueType init) {
00259
00260 #ifdef PBORI_ALT_TERM_ACCUMULATE
00261 if(last.isOne())
00262 return upper_term_accumulate(first.begin(), first.end(),
00263 first.navigation(), init) + ValueType(1);
00264
00265 ValueType result = term_accumulate(first.begin(), first.end(),
00266 first.navigation(),
00267 last.begin(), last.end(), init);
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 assert(result == std::accumulate(first, last, init) );
00281
00282 return result;
00283
00284 #else
00285
00288 if(first.isZero())
00289 return typename ValueType::dd_type(init.diagram().manager(),
00290 first.navigation());
00291
00292 ValueType result = upper_term_accumulate(first.begin(), first.end(),
00293 first.navigation(), init);
00294 if(!last.isZero())
00295 result += upper_term_accumulate(last.begin(), last.end(),
00296 last.navigation(), init);
00297
00298 assert(result == std::accumulate(first, last, init) );
00299
00300 return result;
00301 #endif
00302 }
00303
00304
00305
00306 template <class CacheType, class NaviType, class SetType>
00307 SetType
00308 dd_mapping(const CacheType& cache, NaviType navi, NaviType map, SetType init) {
00309
00310 if (navi.isConstant())
00311 return cache.generate(navi);
00312
00313 while (*map < *navi) {
00314 assert(!map.isConstant());
00315 map.incrementThen();
00316 }
00317
00318 assert(*navi == *map);
00319
00320 NaviType cached = cache.find(navi, map);
00321
00322
00323 if (cached.isValid())
00324 return SetType(cached, cache.ring());
00325
00326 SetType result =
00327 SetType(*(map.elseBranch()),
00328 dd_mapping(cache, navi.thenBranch(), map.thenBranch(), init),
00329 dd_mapping(cache, navi.elseBranch(), map.thenBranch(), init)
00330 );
00331
00332
00333
00334 cache.insert(navi, map, result.navigation());
00335
00336 return result;
00337 }
00338
00339
00340 template <class PolyType, class MapType>
00341 PolyType
00342 apply_mapping(const PolyType& poly, const MapType& map) {
00343
00344 CCacheManagement<typename CCacheTypes::mapping>
00345 cache(poly.diagram().manager());
00346
00347 return dd_mapping(cache, poly.navigation(), map.navigation(),
00348 typename PolyType::set_type());
00349 }
00350
00351
00352 template <class MonomType, class PolyType>
00353 PolyType
00354 generate_mapping(MonomType& fromVars, MonomType& toVars, PolyType init) {
00355
00356 if(fromVars.isConstant()) {
00357 assert(fromVars.isOne() && toVars.isOne());
00358 return fromVars;
00359 }
00360
00361 MonomType varFrom = fromVars.firstVariable();
00362 MonomType varTo = toVars.firstVariable();
00363 fromVars.popFirst();
00364 toVars.popFirst();
00365 return (varFrom * generate_mapping(fromVars, toVars, init)) + varTo;
00366 }
00367
00368 template <class PolyType, class MonomType>
00369 PolyType
00370 mapping(PolyType poly, MonomType fromVars, MonomType toVars) {
00371
00372 return apply_mapping(poly, generate_mapping(fromVars, toVars, PolyType()) );
00373 }
00374
00375
00376
00377 END_NAMESPACE_PBORI
00378
00379 #endif // pbori_algorithms_h_