00001
00002
00143
00144
00145
00146 #include "pbori_defs.h"
00147
00148
00149 #include "CIdxVariable.h"
00150
00151
00152 #include "CacheManager.h"
00153
00154 #include "CDDOperations.h"
00155
00156 BEGIN_NAMESPACE_PBORI
00157
00158 template<class Iterator>
00159 typename Iterator::value_type
00160 index_vector_hash(Iterator start, Iterator finish){
00161
00162 typedef typename Iterator::value_type value_type;
00163
00164 value_type vars = 0;
00165 value_type sum = 0;
00166
00167 while (start != finish){
00168 vars++;
00169 sum += ((*start)+1) * ((*start)+1);
00170 ++start;
00171 }
00172 return sum * vars;
00173 }
00174
00177 template <class DegreeCacher, class NaviType>
00178 typename NaviType::size_type
00179 dd_cached_degree(const DegreeCacher& cache, NaviType navi) {
00180
00181 typedef typename NaviType::size_type size_type;
00182
00183 if (navi.isConstant())
00184 return 0;
00185
00186
00187 typename DegreeCacher::node_type result = cache.find(navi);
00188 if (result.isValid())
00189 return *result;
00190
00191
00192 size_type deg = dd_cached_degree(cache, navi.thenBranch()) + 1;
00193
00194
00195 deg = std::max(deg, dd_cached_degree(cache, navi.elseBranch()) );
00196
00197
00198 cache.insert(navi, deg);
00199
00200 return deg;
00201 }
00202
00207 template <class DegreeCacher, class NaviType, class SizeType>
00208 typename NaviType::size_type
00209 dd_cached_degree(const DegreeCacher& cache, NaviType navi, SizeType bound) {
00210
00211 typedef typename NaviType::size_type size_type;
00212
00213
00214 if (bound == 0 || navi.isConstant())
00215 return 0;
00216
00217
00218 typename DegreeCacher::node_type result = cache.find(navi);
00219 if (result.isValid())
00220 return *result;
00221
00222
00223 size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224
00225
00226 if (bound > deg)
00227 deg = std::max(deg, dd_cached_degree(cache, navi.elseBranch(), bound) );
00228
00229
00230 cache.insert(navi, deg);
00231
00232 return deg;
00233 }
00234
00235 template <class Iterator, class NameGenerator,
00236 class Separator, class EmptySetType,
00237 class OStreamType>
00238 void
00239 dd_print_term(Iterator start, Iterator finish, const NameGenerator& get_name,
00240 const Separator& sep, const EmptySetType& emptyset,
00241 OStreamType& os){
00242
00243 if (start != finish){
00244 os << get_name(*start);
00245 ++start;
00246 }
00247 else
00248 os << emptyset();
00249
00250 while (start != finish){
00251 os << sep() << get_name(*start);
00252 ++start;
00253 }
00254 }
00255
00256 template <class TermType, class NameGenerator,
00257 class Separator, class EmptySetType,
00258 class OStreamType>
00259 void
00260 dd_print_term(const TermType& term, const NameGenerator& get_name,
00261 const Separator& sep, const EmptySetType& emptyset,
00262 OStreamType& os){
00263 dd_print_term(term.begin(), term.end(), get_name, sep, emptyset, os);
00264 }
00265
00266
00267 template <class Iterator, class NameGenerator,
00268 class Separator, class InnerSeparator,
00269 class EmptySetType, class OStreamType>
00270 void
00271 dd_print_terms(Iterator start, Iterator finish, const NameGenerator& get_name,
00272 const Separator& sep, const InnerSeparator& innersep,
00273 const EmptySetType& emptyset, OStreamType& os) {
00274
00275 if (start != finish){
00276 dd_print_term(*start, get_name, innersep, emptyset, os);
00277 ++start;
00278 }
00279
00280 while (start != finish){
00281 os << sep();
00282 dd_print_term(*start, get_name, innersep, emptyset, os);
00283 ++start;
00284 }
00285
00286 }
00287
00288
00289 template <class CacheType, class NaviType, class PolyType>
00290 PolyType
00198 cache.insert(navi, deg);
00199
00200 return deg;
00201 }
00202
00207 template <class DegreeCacher, class NaviType, class SizeType>
00208 typename NaviType::size_type
00209 dd_cached_degree(const DegreeCacher& cache, NaviType navi, SizeType bound) {
00210
00211 typedef typename NaviType::size_type size_type;
00212
00213
00214 if (bound == 0 || navi.isConstant())
00215 return 0;
00216
00217
00218 typename DegreeCacher::node_type result = cache.find(navi);
00219 if (result.isValid())
00220 return *result;
00221
00222
00223 size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224
00225
00226 if (bound > deg)
00227 deg = std::max(deg, dd_cached_degree(cache, navi.elseBranch(), bound) );
00228
00229
00230 cache.insert(navi, deg);
00231
00232 return deg;
00233 }
00234
00235 template <class Iterator, class NameGenerator,
00236 class Separator, class EmptySetType,
00237 class OStreamType>
00238 void
00239 dd_print_term(Iterator start, Iterator finish, const NameGenerator& get_name,
00240 const Separator& sep, const EmptySetType& emptyset,
00241 OStreamType& os){
00242
00243 if (start != finish){
00244 os << get_name(*start);
00245 ++start;
00246 }
00247 else
00248 os << emptyset();
00249
00250 while (start != finish){
00251 os << sep() << get_name(*start);
00252 ++start;
00253 }
00254 }
00255
00256 template <class TermType, class NameGenerator,
00257 class Separator, class EmptySetType,
00258 class OStreamType>
00259 void
00260 dd_print_term(const TermType& term, const NameGenerator& get_name,
00261 const Separator& sep, const EmptySetType& emptyset,
00262 OStreamType& os){
00263 dd_print_term(term.begin(), term.end(), get_name, sep, emptyset, os);
00264 }
00265
00266
00267 template <class Iterator, class NameGenerator,
00268 class Separator, class InnerSeparator,
00269 class EmptySetType, class OStreamType>
00270 void
00271 dd_print_terms(Iterator start, Iterator finish, const NameGenerator& get_name,
00272 const Separator& sep, const InnerSeparator& innersep,
00273 const EmptySetType& emptyset, OStreamType& os) {
00274
00275 if (start != finish){
00276 dd_print_term(*start, get_name, innersep, emptyset, os);
00277 ++start;
00278 }
00279
00280 while (start != finish){
00281 os << sep();
00282 dd_print_term(*start, get_name, innersep, emptyset, os);
00283 ++start;
00284 }
00285
00286 }
00287
00288
00289 template <class CacheType, class NaviType, class PolyType>
00290 PolyType
00198 cache.insert(navi, deg);
00199
00200 return deg;
00201 }
00202
00207 template <class DegreeCacher, class NaviType, class SizeType>
00208 typename NaviType::size_type
00209 dd_cached_degree(const DegreeCacher& cache, NaviType navi, SizeType bound) {
00210
00211 typedef typename NaviType::size_type size_type;
00212
00213
00214 if (bound == 0 || navi.isConstant())
00215 return 0;
00216
00217
00218 typename DegreeCacher::node_type result = cache.find(navi);
00219 if (result.isValid())
00220 return *result;
00221
00222
00223 size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224
00225
00226 if (bound > deg)
00227 deg = std::max(deg, dd_cached_degree(cache, navi.elseBranch(), bound) );
00228
00229
00230 cache.insert(navi, deg);
00231
00232 return deg;
00233 }
00234
00235 template <class Iterator, class NameGenerator,
00236 class Separator, class EmptySetType,
00237 class OStreamType>
00238 void
00239 dd_print_term(Iterator start, Iterator finish, const NameGenerator& get_name,
00240 const Separator& sep, const EmptySetType& emptyset,
00241 OStreamType& os){
00242
00243 if (start != finish){
00244 os << get_name(*start);
00245 ++start;
00246 }
00247 else
00248 os << emptyset();
00249
00250 while (start != finish){
00251 os << sep() << get_name(*start);
00252 ++start;
00253 }
00254 }
00255
00256 template <class TermType, class NameGenerator,
00257 class Separator, class EmptySetType,
00258 class OStreamType>
00259 void
00260 dd_print_term(const TermType& term, const NameGenerator& get_name,
00261 const Separator& sep, const EmptySetType& emptyset,
00262 OStreamType& os){
00263 dd_print_term(term.begin(), term.end(), get_name, sep, emptyset, os);
00264 }
00265
00266
00267 template <class Iterator, class NameGenerator,
00268 class Separator, class InnerSeparator,
00269 class EmptySetType, class OStreamType>
00270 void
00271 dd_print_terms(Iterator start, Iterator finish, const NameGenerator& get_name,
00272 const Separator& sep, const InnerSeparator& innersep,
00273 const EmptySetType& emptyset, OStreamType& os) {
00274
00275 if (start != finish){
00276 dd_print_term(*start, get_name, innersep, emptyset, os);
00277 ++start;
00278 }
00279
00280 while (start != finish){
00281 os << sep();
00282 dd_print_term(*start, get_name, innersep, emptyset, os);
00283 ++start;
00284 }
00285
00286 }
00287
00288
00289 template <class CacheType, class NaviType, class PolyType>
00290 PolyType
00198 cache.insert(navi, deg);
00199
00200 return deg;
00201 }
00202
00207 template <class DegreeCacher, class NaviType, class SizeType>
00208 typename NaviType::size_type
00209 dd_cached_degree(const DegreeCacher& cache, NaviType navi, SizeType bound) {
00210
00211 typedef typename NaviType::size_type size_type;
00212
00213
00214 if (bound == 0 || navi.isConstant())
00215 return 0;
00216
00217
00218 typename DegreeCacher::node_type result = cache.find(navi);
00219 if (result.isValid())
00220 return *result;
00221
00222
00223 size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224
00225
00226 if (bound > deg)
00227 deg = std::max(deg, dd_cached_degree(cache, navi.elseBranch(), bound) );
00228
00229
00230 cache.insert(navi, deg);
00231
00232 return deg;
00233 }
00234
00235 template <class Iterator, class NameGenerator,
00236 class Separator, class EmptySetType,
00237 class OStreamType>
00238 void
00239 dd_print_term(Iterator start, Iterator finish, const NameGenerator& get_name,
00240 const Separator& sep, const EmptySetType& emptyset,
00241 OStreamType& os){
00242
00243 if (start != finish){
00244 os << get_name(*start);
00245 ++start;
00246 }
00247 else
00248 os << emptyset();
00249
00250 while (start != finish){
00251 os << sep() << get_name(*start);
00252 ++start;
00253 }
00254 }
00255
00256 template <class TermType, class NameGenerator,
00257 class Separator, class EmptySetType,
00258 class OStreamType>
00259 void
00260 dd_print_term(const TermType& term, const NameGenerator& get_name,
00261 const Separator& sep, const EmptySetType& emptyset,
00262 OStreamType& os){
00263 dd_print_term(term.begin(), term.end(), get_name, sep, emptyset, os);
00264 }
00265
00266
00267 template <class Iterator, class NameGenerator,
00268 class Separator, class InnerSeparator,
00269 class EmptySetType, class OStreamType>
00270 void
00271 dd_print_terms(Iterator start, Iterator finish, const NameGenerator& get_name,
00272 const Separator& sep, const InnerSeparator& innersep,
00273 const EmptySetType& emptyset, OStreamType& os) {
00274
00275 if (start != finish){
00276 dd_print_term(*start, get_name, innersep, emptyset, os);
00277 ++start;
00278 }
00279
00280 while (start != finish){
00281 os << sep();
00282 dd_print_term(*start, get_name, innersep, emptyset, os);
00283 ++start;
00284 }
00285
00286 }
00287
00288
00289 template <class CacheType, class NaviType, class PolyType>
00290 PolyType
00198 cache.insert(navi, deg);
00199
00200 return deg;
00201 }
00202
00207 template <class DegreeCacher, class NaviType, class SizeType>
00208 typename NaviType::size_type
00209 dd_cached_degree(const DegreeCacher& cache, NaviType navi, SizeType bound) {
00210
00211 typedef typename NaviType::size_type size_type;
00212
00213
00214 if (bound == 0 || navi.isConstant())
00215 return 0;
00216
00217
00218 typename DegreeCacher::node_type result = cache.find(navi);
00219 if (result.isValid())
00220 return *result;
00221
00222
00223 size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224
00225
00226 if (bound > deg)
00227 deg = std::max(deg, dd_cached_degree(cache, navi.elseBranch(), bound) );
00228
00229
00230 cache.insert(navi, deg);
00231
00232 return deg;
00233 }
00234
00235 template <class Iterator, class NameGenerator,
00236 class Separator, class EmptySetType,
00237 class OStreamType>
00238 void
00239 dd_print_term(Iterator start, Iterator finish, const NameGenerator& get_name,
00240 const Separator& sep, const EmptySetType& emptyset,
00241 OStreamType& os){
00242
00243 if (start != finish){
00244 os << get_name(*start);
00245 ++start;
00246 }
00247 else
00248 os << emptyset();
00249
00250 while (start != finish){
00251 os << sep() << get_name(*start);
00252 ++start;
00253 }
00254 }
00255
00256 template <class TermType, class NameGenerator,
00257 class Separator, class EmptySetType,
00258 class OStreamType>
00259 void
00260 dd_print_term(const TermType& term, const NameGenerator& get_name,
00261 const Separator& sep, const EmptySetType& emptyset,
00262 OStreamType& os){
00263 dd_print_term(term.begin(), term.end(), get_name, sep, emptyset, os);
00264 }
00265
00266
00267 template <class Iterator, class NameGenerator,
00268 class Separator, class InnerSeparator,
00269 class EmptySetType, class OStreamType>
00270 void
00271 dd_print_terms(Iterator start, Iterator finish, const NameGenerator& get_name,
00272 const Separator& sep, const InnerSeparator& innersep,
00273 const EmptySetType& emptyset, OStreamType& os) {
00274
00275 if (start != finish){
00276 dd_print_term(*start, get_name, innersep, emptyset, os);
00277 ++start;
00278 }
00279
00280 while (start != finish){
00281 os << sep();
00282 dd_print_term(*start, get_name, innersep, emptyset, os);
00283 ++start;
00284 }
00285
00286 }
00287
00288
00289 template <class CacheType, class NaviType, class PolyType>
00290 PolyType
00198 cache.insert(navi, deg);
00199
00200 return deg;
00201 }
00202
00207 template <class DegreeCacher, class NaviType, class SizeType>
00208 typename NaviType::size_type
00209 dd_cached_degree(const DegreeCacher& cache, NaviType navi, SizeType bound) {
00210
00211 typedef typename NaviType::size_type size_type;
00212
00213
00214 if (bound == 0 || navi.isConstant())
00215 return 0;
00216
00217
00218 typename DegreeCacher::node_type result = cache.find(navi);
00219 if (result.isValid())
00220 return *result;
00221
00222
00223 size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224
00225
00226 if (bound > deg)
00227 deg = std::max(deg, dd_cached_degree(cache, navi.elseBranch(), bound) );
00228
00229
00230 cache.insert(navi, deg);
00231
00232 return deg;
00233 }
00234
00235 template <class Iterator, class NameGenerator,
00236 class Separator, class EmptySetType,
00237 class OStreamType>
00238 void
00239 dd_print_term(Iterator start, Iterator finish, const NameGenerator& get_name,
00240 const Separator& sep, const EmptySetType& emptyset,
00241 OStreamType& os){
00242
00243 if (start != finish){
00244 os << get_name(*start);
00245 ++start;
00246 }
00247 else
00248 os << emptyset();
00249
00250 while (start != finish){
00251 os << sep() << get_name(*start);
00252 ++start;
00253 }
00254 }
00255
00256 template <class TermType, class NameGenerator,
00257 class Separator, class EmptySetType,
00258 class OStreamType>
00259 void
00260 dd_print_term(const TermType& term, const NameGenerator& get_name,
00261 const Separator& sep, const EmptySetType& emptyset,
00262 OStreamType& os){
00263 dd_print_term(term.begin(), term.end(), get_name, sep, emptyset, os);
00264 }
00265
00266
00267 template <class Iterator, class NameGenerator,
00268 class Separator, class InnerSeparator,
00269 class EmptySetType, class OStreamType>
00270 void
00271 dd_print_terms(Iterator start, Iterator finish, const NameGenerator& get_name,
00272 const Separator& sep, const InnerSeparator& innersep,
00273 const EmptySetType& emptyset, OStreamType& os) {
00274
00275 if (start != finish){
00276 dd_print_term(*start, get_name, innersep, emptyset, os);
00277 ++start;
00278 }
00279
00280 while (start != finish){
00281 os << sep();
00282 dd_print_term(*start, get_name, innersep, emptyset, os);
00283 ++start;
00284 }
00285
00286 }
00287
00288
00289 template <class CacheType, class NaviType, class PolyType>
00290 PolyType
00198 cache.insert(navi, deg);
00199
00200 return deg;
00201 }
00202
00207 template <class DegreeCacher, class NaviType, class SizeType>
00208 typename NaviType::size_type
00209 dd_cached_degree(const DegreeCacher& cache, NaviType navi, SizeType bound) {
00210
00211 typedef typename NaviType::size_type size_type;
00212
00213
00214 if (bound == 0 || navi.isConstant())
00215 return 0;
00216
00217
00218 typename DegreeCacher::node_type result = cache.find(navi);
00219 if (result.isValid())
00220 return *result;
00221
00222
00223 size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224
00225
00226 if (bound > deg)
00227 deg = std::max(deg, dd_cached_degree(cache, navi.elseBranch(), bound) );
00228
00229
00230 cache.insert(navi, deg);
00231
00232 return deg;
00233 }
00234
00235 template <class Iterator, class NameGenerator,
00236 class Separator, class EmptySetType,
00237 class OStreamType>
00238 void
00239 dd_print_term(Iterator start, Iterator finish, const NameGenerator& get_name,
00240 const Separator& sep, const EmptySetType& emptyset,
00241 OStreamType& os){
00242
00243 if (start != finish){
00244 os << get_name(*start);
00245 ++start;
00246 }
00247 else
00248 os << emptyset();
00249
00250 while (start != finish){
00251 os << sep() << get_name(*start);
00252 ++start;
00253 }
00254 }
00255
00256 template <class TermType, class NameGenerator,
00257 class Separator, class EmptySetType,
00258 class OStreamType>
00259 void
00260 dd_print_term(const TermType& term, const NameGenerator& get_name,
00261 const Separator& sep, const EmptySetType& emptyset,
00262 OStreamType& os){
00263 dd_print_term(term.begin(), term.end(), get_name, sep, emptyset, os);
00264 }
00265
00266
00267 template <class Iterator, class NameGenerator,
00268 class Separator, class InnerSeparator,
00269 class EmptySetType, class OStreamType>
00270 void
00271 dd_print_terms(Iterator start, Iterator finish, const NameGenerator& get_name,
00272 const Separator& sep, const InnerSeparator& innersep,
00273 const EmptySetType& emptyset, OStreamType& os) {
00274
00275 if (start != finish){
00276 dd_print_term(*start, get_name, innersep, emptyset, os);
00277 ++start;
00278 }
00279
00280 while (start != finish){
00281 os << sep();
00282 dd_print_term(*start, get_name, innersep, emptyset, os);
00283 ++start;
00284 }
00285
00286 }
00287
00288
00289 template <class CacheType, class NaviType, class PolyType>
00290 PolyType
00198 cache.insert(navi, deg);
00199
00200 return deg;
00201 }
00202
00207 template <class DegreeCacher, class NaviType, class SizeType>
00208 typename NaviType::size_type
00209 dd_cached_degree(const DegreeCacher& cache, NaviType navi, SizeType bound) {
00210
00211 typedef typename NaviType::size_type size_type;
00212
00213
00214 if (bound == 0 || navi.isConstant())
00215 return 0;
00216
00217
00218 typename DegreeCacher::node_type result = cache.find(navi);
00219 if (result.isValid())
00220 return *result;
00221
00222
00223 size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224
00225
00226 if (bound > deg)
00227 deg = std::max(deg, dd_cached_degree(cache, navi.elseBranch(), bound) );
00228
00229
00230 cache.insert(navi, deg);
00231
00232 return deg;
00233 }
00234
00235 template <class Iterator, class NameGenerator,
00236 class Separator, class EmptySetType,
00237 class OStreamType>
00238 void
00239 dd_print_term(Iterator start, Iterator finish, const NameGenerator& get_name,
00240 const Separator& sep, const EmptySetType& emptyset,
00241 OStreamType& os){
00242
00243 if (start != finish){
00244 os << get_name(*start);
00245 ++start;
00246 }
00247 else
00248 os << emptyset();
00249
00250 while (start != finish){
00251 os << sep() << get_name(*start);
00252 ++start;
00253 }
00254 }
00255
00256 template <class TermType, class NameGenerator,
00257 class Separator, class EmptySetType,
00258 class OStreamType>
00259 void
00260 dd_print_term(const TermType& term, const NameGenerator& get_name,
00261 const Separator& sep, const EmptySetType& emptyset,
00262 OStreamType& os){
00263 dd_print_term(term.begin(), term.end(), get_name, sep, emptyset, os);
00264 }
00265
00266
00267 template <class Iterator, class NameGenerator,
00268 class Separator, class InnerSeparator,
00269 class EmptySetType, class OStreamType>
00270 void
00271 dd_print_terms(Iterator start, Iterator finish, const NameGenerator& get_name,
00272 const Separator& sep, const InnerSeparator& innersep,
00273 const EmptySetType& emptyset, OStreamType& os) {
00274
00275 if (start != finish){
00276 dd_print_term(*start, get_name, innersep, emptyset, os);
00277 ++start;
00278 }
00279
00280 while (start != finish){
00281 os << sep();
00282 dd_print_term(*start, get_name, innersep, emptyset, os);
00283 ++start;
00284 }
00285
00286 }
00287
00288
00289 template <class CacheType, class NaviType, class PolyType>
00290 PolyType
00198 cache.insert(navi, deg);
00199
00200 return deg;
00201 }
00202
00207 template <class DegreeCacher, class NaviType, class SizeType>
00208 typename NaviType::size_type
00209 dd_cached_degree(const DegreeCacher& cache, NaviType navi, SizeType bound) {
00210
00211 typedef typename NaviType::size_type size_type;
00212
00213
00214 if (bound == 0 || navi.isConstant())
00215 return 0;
00216
00217
00218 typename DegreeCacher::node_type result = cache.find(navi);
00219 if (result.isValid())
00220 return *result;
00221
00222
00223 size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224
00225
00226 if (bound > deg)
00227 deg = std::max(deg, dd_cached_degree(cache, navi.elseBranch(), bound) );
00228
00229
00230 cache.insert(navi, deg);
00231
00232 return deg;
00233 }
00234
00235 template <class Iterator, class NameGenerator,
00236 class Separator, class EmptySetType,
00237 class OStreamType>
00238 void
00239 dd_print_term(Iterator start, Iterator finish, const NameGenerator& get_name,
00240 const Separat