• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

pbori_routines_misc.h

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //*****************************************************************************
00143 //*****************************************************************************
00144 
00145 // include basic definitions
00146 #include "pbori_defs.h"
00147 
00148 // temprarily
00149 #include "CIdxVariable.h"
00150 
00151 // temprarily
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()) // No need for caching of constant nodes' degrees
00184     return 0;
00185  
00186   // Look whether result was cached before
00187   typename DegreeCacher::node_type result = cache.find(navi);
00188   if (result.isValid())
00189     return *result;
00190 
00191   // Get degree of then branch (contains at least one valid path)...
00192   size_type deg = dd_cached_degree(cache, navi.thenBranch()) + 1;
00193  
00194   // ... combine with degree of else branch
00195   deg = std::max(deg,  dd_cached_degree(cache, navi.elseBranch()) );
00196 
00197   // Write result to cache
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   // No need for caching of constant nodes' degrees
00214   if (bound == 0 || navi.isConstant())
00215     return 0;
00216  
00217   // Look whether result was cached before
00218   typename DegreeCacher::node_type result = cache.find(navi);
00219   if (result.isValid())
00220     return *result;
00221 
00222   // Get degree of then branch (contains at least one valid path)...
00223   size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224 
00225   // ... combine with degree of else branch
00226   if (bound > deg)              // if deg <= bound, we are already finished
00227     deg = std::max(deg,  dd_cached_degree(cache, navi.elseBranch(), bound) );
00228 
00229   // Write result to cache
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   // No need for caching of constant nodes' degrees
00214   if (bound == 0 || navi.isConstant())
00215     return 0;
00216  
00217   // Look whether result was cached before
00218   typename DegreeCacher::node_type result = cache.find(navi);
00219   if (result.isValid())
00220     return *result;
00221 
00222   // Get degree of then branch (contains at least one valid path)...
00223   size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224 
00225   // ... combine with degree of else branch
00226   if (bound > deg)              // if deg <= bound, we are already finished
00227     deg = std::max(deg,  dd_cached_degree(cache, navi.elseBranch(), bound) );
00228 
00229   // Write result to cache
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   // No need for caching of constant nodes' degrees
00214   if (bound == 0 || navi.isConstant())
00215     return 0;
00216  
00217   // Look whether result was cached before
00218   typename DegreeCacher::node_type result = cache.find(navi);
00219   if (result.isValid())
00220     return *result;
00221 
00222   // Get degree of then branch (contains at least one valid path)...
00223   size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224 
00225   // ... combine with degree of else branch
00226   if (bound > deg)              // if deg <= bound, we are already finished
00227     deg = std::max(deg,  dd_cached_degree(cache, navi.elseBranch(), bound) );
00228 
00229   // Write result to cache
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   // No need for caching of constant nodes' degrees
00214   if (bound == 0 || navi.isConstant())
00215     return 0;
00216  
00217   // Look whether result was cached before
00218   typename DegreeCacher::node_type result = cache.find(navi);
00219   if (result.isValid())
00220     return *result;
00221 
00222   // Get degree of then branch (contains at least one valid path)...
00223   size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224 
00225   // ... combine with degree of else branch
00226   if (bound > deg)              // if deg <= bound, we are already finished
00227     deg = std::max(deg,  dd_cached_degree(cache, navi.elseBranch(), bound) );
00228 
00229   // Write result to cache
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   // No need for caching of constant nodes' degrees
00214   if (bound == 0 || navi.isConstant())
00215     return 0;
00216  
00217   // Look whether result was cached before
00218   typename DegreeCacher::node_type result = cache.find(navi);
00219   if (result.isValid())
00220     return *result;
00221 
00222   // Get degree of then branch (contains at least one valid path)...
00223   size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224 
00225   // ... combine with degree of else branch
00226   if (bound > deg)              // if deg <= bound, we are already finished
00227     deg = std::max(deg,  dd_cached_degree(cache, navi.elseBranch(), bound) );
00228 
00229   // Write result to cache
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   // No need for caching of constant nodes' degrees
00214   if (bound == 0 || navi.isConstant())
00215     return 0;
00216  
00217   // Look whether result was cached before
00218   typename DegreeCacher::node_type result = cache.find(navi);
00219   if (result.isValid())
00220     return *result;
00221 
00222   // Get degree of then branch (contains at least one valid path)...
00223   size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224 
00225   // ... combine with degree of else branch
00226   if (bound > deg)              // if deg <= bound, we are already finished
00227     deg = std::max(deg,  dd_cached_degree(cache, navi.elseBranch(), bound) );
00228 
00229   // Write result to cache
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   // No need for caching of constant nodes' degrees
00214   if (bound == 0 || navi.isConstant())
00215     return 0;
00216  
00217   // Look whether result was cached before
00218   typename DegreeCacher::node_type result = cache.find(navi);
00219   if (result.isValid())
00220     return *result;
00221 
00222   // Get degree of then branch (contains at least one valid path)...
00223   size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224 
00225   // ... combine with degree of else branch
00226   if (bound > deg)              // if deg <= bound, we are already finished
00227     deg = std::max(deg,  dd_cached_degree(cache, navi.elseBranch(), bound) );
00228 
00229   // Write result to cache
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   // No need for caching of constant nodes' degrees
00214   if (bound == 0 || navi.isConstant())
00215     return 0;
00216  
00217   // Look whether result was cached before
00218   typename DegreeCacher::node_type result = cache.find(navi);
00219   if (result.isValid())
00220     return *result;
00221 
00222   // Get degree of then branch (contains at least one valid path)...
00223   size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224 
00225   // ... combine with degree of else branch
00226   if (bound > deg)              // if deg <= bound, we are already finished
00227     deg = std::max(deg,  dd_cached_degree(cache, navi.elseBranch(), bound) );
00228 
00229   // Write result to cache
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   // No need for caching of constant nodes' degrees
00214   if (bound == 0 || navi.isConstant())
00215     return 0;
00216  
00217   // Look whether result was cached before
00218   typename DegreeCacher::node_type result = cache.find(navi);
00219   if (result.isValid())
00220     return *result;
00221 
00222   // Get degree of then branch (contains at least one valid path)...
00223   size_type deg = dd_cached_degree(cache, navi.thenBranch(), bound - 1) + 1;
00224 
00225   // ... combine with degree of else branch
00226   if (bound > deg)              // if deg <= bound, we are already finished
00227     deg = std::max(deg,  dd_cached_degree(cache, navi.elseBranch(), bound) );
00228 
00229   // Write result to cache
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