PolyBoRi
|
00001 // -*- c++ -*- 00002 //***************************************************************************** 00013 //***************************************************************************** 00014 00015 #ifndef polybori_routines_pbori_func_h_ 00016 #define polybori_routines_pbori_func_h_ 00017 00018 // get polybori definitions 00019 #include <polybori/pbori_defs.h> 00020 00021 // get polybori properties 00022 #include <polybori/common/traits.h> 00023 00024 // get standard string and string stream functionality 00025 #include <string> 00026 #include <sstream> 00027 00028 00029 #ifdef PBORI_HAVE_TR1_UNORDERED_MAP 00030 # include <tr1/unordered_map> 00031 #else 00032 # ifdef PBORI_HAVE_UNORDERED_MAP 00033 # include <unordered_map> 00034 # else 00035 # ifdef PBORI_HAVE_HASH_MAP 00036 # include <ext/hash_map> 00037 # else 00038 # include <map> 00039 # endif 00040 # endif 00041 #endif 00042 00043 BEGIN_NAMESPACE_PBORI 00044 00047 template <class ListType, class ValueType = typename ListType::value_type > 00048 class push_back { 00049 public: 00050 00051 ListType 00052 operator()(ListType theList, const ValueType& elt) const { 00053 theList.push_back(elt); 00054 return theList; 00055 } 00056 }; 00057 00060 template <class RhsType, class LhsType = typename RhsType::idx_type > 00061 class change_idx { 00062 public: 00063 00064 RhsType operator() (const RhsType& rhs, const LhsType& lhs) const { 00065 return (rhs.change(lhs)); 00066 } 00067 00068 }; 00069 00072 template <class RhsType = void, 00073 class LhsType = typename pbori_traits<RhsType>::idx_type > 00074 class change_assign; 00075 00076 // default variant 00077 template <class RhsType, class LhsType> 00078 class change_assign { 00079 public: 00080 00081 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00082 return (rhs = rhs.change(lhs)); 00083 } 00084 00085 }; 00086 00087 // template specialization 00088 template<> 00089 class change_assign<void, pbori_traits<void>::idx_type> { 00090 public: 00091 00092 template <class RhsType, class LhsType> 00093 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00094 return (rhs = rhs.change(lhs)); 00095 } 00096 00097 }; 00098 00101 template <class RhsType, class LhsType = typename RhsType::idx_type> 00102 class subset1_assign { 00103 public: 00104 00105 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00106 00107 rhs = rhs.subset1(lhs); 00108 return rhs; 00109 } 00110 }; 00111 00114 template <class RhsType, class LhsType> 00115 class subset0_assign { 00116 public: 00117 00118 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00119 return (rhs = rhs.subset0(lhs)); 00120 } 00121 }; 00124 template <class RhsType, 00125 class LhsType = typename pbori_traits<RhsType>::idx_type > 00126 class unite_assign: 00127 public std::binary_function<RhsType&, const LhsType&, RhsType&> { 00128 00129 public: 00130 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00131 return (rhs = rhs.unite(lhs)); 00132 } 00133 }; 00134 00135 00136 // @class project_ith 00142 00143 template <unsigned int ITH, unsigned int NLEN = ITH> 00144 class project_ith; 00145 00148 template <unsigned int NLEN> 00149 class project_ith<0, NLEN> { 00150 00151 public: 00153 template <class ValueType> 00154 void operator() (const ValueType&, ...) const { } 00155 }; 00156 00159 template <unsigned int NLEN> 00160 class project_ith<1, NLEN> { 00161 00162 public: 00164 template <class ValueType> 00165 const ValueType& operator() (const ValueType& value, ...) const { 00166 return value; 00167 } 00168 00170 template <class ValueType> 00171 ValueType& operator() (ValueType& value, ...) const { 00172 return value; 00173 } 00174 }; 00175 00176 00179 template <unsigned int NLEN> 00180 class project_ith<2, NLEN> { 00181 00182 public: 00184 template <class FirstType, class ValueType> 00185 const ValueType& 00186 operator() (const FirstType&, const ValueType& value, ...) const { 00187 return value; 00188 } 00189 00191 template <class FirstType, class ValueType> 00192 ValueType& operator() (const FirstType&, ValueType& value, ...) const { 00193 return value; 00194 } 00195 }; 00196 00197 00200 template <unsigned int NLEN> 00201 class project_ith<3, NLEN> { 00202 00203 public: 00205 template <class FirstType, class SecondType, class ValueType> 00206 const ValueType& 00207 operator() (const FirstType&, const SecondType&, 00208 const ValueType& value, ...) const { 00209 return value; 00210 } 00211 00213 template <class FirstType, class SecondType, class ValueType> 00214 ValueType& operator() (const FirstType&, const SecondType&, 00215 ValueType& value, ...) const { 00216 return value; 00217 } 00218 }; 00219 00220 /* 00221 class print_all { 00222 public: 00223 00224 print_all(std::ostream& os_):os(os_){} 00225 00226 template<class Type> 00227 Type& operator()(Type& val){ 00228 std::copy(val.begin(), val.end(), 00229 std::ostream_iterator<typename Type::value_type>(os, ", ")); 00230 return val; 00231 } 00232 std::ostream& os; 00233 }; 00234 */ 00235 00238 class dummy_iterator { 00239 public: 00240 00242 typedef dummy_iterator self; 00243 00244 template <class Type> 00245 const self& operator=(const Type&) const { return *this;} 00246 00247 const self& operator*() const { return *this;} 00248 const self& operator++() const { return *this;} 00249 const self& operator++(int) const { return *this;} 00250 }; 00251 00252 template <> 00253 class pbori_traits<dummy_iterator>: 00254 public CTypes { 00255 }; 00256 00262 template <class IntType, IntType INTCONST, class ResultType = IntType> 00263 struct integral_constant { 00264 00265 typedef ResultType result_type; 00266 enum { result = INTCONST }; 00267 result_type operator()(...) const { return result; } 00268 }; 00269 00273 template <class BinaryOp, class FirstOp, class SecondOp> 00274 class binary_composition: 00275 public BinaryOp { 00276 00277 public: 00278 00280 00281 typedef BinaryOp base; 00282 typedef FirstOp first_op_type; 00283 typedef SecondOp second_op_type; 00285 00286 // Constructor 00287 binary_composition(const base& binop = base(), 00288 const first_op_type& unop1 = first_op_type(), 00289 const second_op_type& unop2 = second_op_type() ): 00290 base(binop), first_op(unop1), second_op(unop2) {} 00291 00293 typedef typename base::result_type result_type; 00294 00296 template <class FirstType, class SecondType> 00297 result_type operator()(const FirstType& first, 00298 const SecondType& second) const { 00299 return base::operator()(first_op(first), second_op(second)); 00300 } 00301 00303 template <class FirstType, class SecondType> 00304 result_type operator()(FirstType& first, 00305 const SecondType& second) const { 00306 return base::operator()(first_op(first), second_op(second)); 00307 } 00308 00310 template <class FirstType, class SecondType> 00311 result_type operator()(const FirstType& first, 00312 SecondType& second) const { 00313 return base::operator()(first_op(first), second_op(second)); 00314 } 00315 00316 protected: 00317 first_op_type first_op; 00318 second_op_type second_op; 00319 }; 00320 00324 template <class BinaryOp, class UnaryOperation> 00325 class symmetric_composition: 00326 public binary_composition<BinaryOp, UnaryOperation, UnaryOperation> { 00327 00328 public: 00329 00331 00332 typedef BinaryOp binary_op_type; 00333 typedef UnaryOperation unary_op_type; 00334 typedef binary_composition<binary_op_type, unary_op_type, unary_op_type> 00335 base; 00337 00338 // Constructor 00339 symmetric_composition(const binary_op_type& binop = binary_op_type(), 00340 const unary_op_type& unop = unary_op_type() ): 00341 base(binop, unop, unop) {} 00342 }; 00343 00346 template<class ValueType> 00347 class maximum_iteration { 00348 public: 00349 maximum_iteration(ValueType & init) : max(init){} 00350 00351 ValueType& operator()(const ValueType& val) const { 00352 return max = std::max(max, val); 00353 } 00354 00355 private: 00356 ValueType & max; 00357 }; 00358 00361 template <class DDType> 00362 class dd_add_assign { 00363 public: 00364 00365 DDType& operator()(DDType& lhs, const DDType& rhs) const { 00366 // several possible implementations 00367 return 00368 #if defined(PBORI_ADD_BY_OR) 00369 (lhs = (lhs.diff(rhs)).unite(rhs.diff(lhs))); 00370 00371 # elif defined(PBORI_ADD_BY_UNION) 00372 (lhs = lhs.unite(rhs).diff( lhs.intersect(rhs) ) ); 00373 # elif defined(PBORI_ADD_BY_EXTRA_XOR) || defined(PBORI_ADD_BY_XOR) 00374 (lhs = lhs.Xor(rhs)); 00375 #endif 00376 } 00377 }; 00378 00381 template <class DDType, class IdxType = typename DDType::idx_type> 00382 class times_indexed_var { 00383 public: 00384 00385 DDType& operator()(DDType& lhs, IdxType idx) const { 00386 00387 // get all terms not containing the variable with index idx 00388 DDType tmp( lhs.subset0(idx) ); 00389 00390 // get the complementary terms 00391 lhs = lhs.diff(tmp); 00392 00393 // construct polynomial terms 00394 dd_add_assign<DDType>()(lhs, tmp.change(idx)); 00395 00396 return lhs; 00397 } 00398 00399 }; 00400 00403 template <class DDType, class IdxType = typename DDType::idx_type> 00404 class append_indexed_divisor { 00405 public: 00406 00407 DDType& operator()(DDType& lhs, IdxType idx) const { 00408 00409 lhs = lhs.unite( lhs.change(idx) ); 00410 return lhs; 00411 } 00412 00413 }; 00414 00417 // template <class RhsType = void, 00418 // class LhsType = typename RhsType::value_type > 00419 // class inserts: 00420 // public std::binary_function<RhsType&, const LhsType&, RhsType&> { 00421 // public: 00422 00423 // RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00424 // rhs.insert(lhs); 00425 // return rhs; 00426 // } 00427 00428 // }; 00429 00430 00433 template <class RhsType = void, 00434 class LhsType = typename pbori_traits<RhsType>::idx_type > 00435 class inserts; 00436 00437 template <class RhsType, class LhsType> 00438 class inserts: 00439 public std::binary_function<RhsType&, const LhsType&, RhsType&> { 00440 public: 00441 00442 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00443 rhs.insert(lhs); 00444 return rhs; 00445 } 00446 }; 00447 00448 template <> 00449 class inserts<void, pbori_traits<void>::idx_type> { 00450 public: 00451 template <class RhsType, class LhsType> 00452 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00453 rhs.insert(lhs); 00454 return rhs; 00455 } 00456 }; 00457 00458 00461 template <class RhsType = void, 00462 class LhsType = typename pbori_traits<RhsType>::idx_type > 00463 class insert_assign; 00464 00465 template <class RhsType, class LhsType> 00466 class insert_assign: 00467 public std::binary_function<RhsType&, const LhsType&, RhsType&> { 00468 public: 00469 00470 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00471 rhs.insertAssign(lhs); 00472 return rhs; 00473 } 00474 }; 00475 00476 template <> 00477 class insert_assign<void, pbori_traits<void>::idx_type> { 00478 public: 00479 template <class RhsType, class LhsType> 00480 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00481 rhs.insertAssign(lhs); 00482 return rhs; 00483 } 00484 }; 00485 00486 00487 00490 template <class RhsType = void, 00491 class LhsType = typename pbori_traits<RhsType>::idx_type > 00492 class removes; 00493 00494 00495 template <class RhsType, class LhsType> 00496 class removes: 00497 public std::binary_function<RhsType&, const LhsType&, RhsType&> { 00498 public: 00499 00500 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00501 rhs.remove(lhs); 00502 return rhs; 00503 } 00504 }; 00505 00506 00507 template <> 00508 class removes<void, pbori_traits<void>::idx_type> { 00509 public: 00510 00511 template <class RhsType, class LhsType> 00512 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00513 rhs.remove(lhs); 00514 return rhs; 00515 } 00516 }; 00517 00520 template <class RhsType = void, 00521 class LhsType = typename pbori_traits<RhsType>::idx_type > 00522 class remove_assign; 00523 00524 00525 template <class RhsType, class LhsType> 00526 class remove_assign: 00527 public std::binary_function<RhsType&, const LhsType&, RhsType&> { 00528 public: 00529 00530 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00531 rhs.removeAssign(lhs); 00532 return rhs; 00533 } 00534 }; 00535 00536 00537 template <> 00538 class remove_assign<void, pbori_traits<void>::idx_type> { 00539 public: 00540 00541 template <class RhsType, class LhsType> 00542 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00543 rhs.removeAssign(lhs); 00544 return rhs; 00545 } 00546 }; 00547 00550 template <class ListType, class RhsType, class LhsType> 00551 class insert_second_to_list { 00552 public: 00553 00554 insert_second_to_list(ListType& theList__): 00555 theList(theList__) {}; 00556 00557 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const { 00558 theList.insert(lhs); 00559 return rhs; 00560 } 00561 00562 private: 00563 ListType& theList; 00564 }; 00565 00566 00570 template <class Type1, class Type2> 00571 class is_same_type; 00572 00573 template <class Type> 00574 class is_same_type<Type, Type>: 00575 public integral_constant<CTypes::bool_type, true> {}; 00576 00577 template <class Type1, class Type2> 00578 class is_same_type: 00579 public integral_constant<CTypes::bool_type, false> {}; 00580 00581 template <class Type> 00582 class is_valid: 00583 public is_same_type<Type, valid_tag> {}; 00584 00588 template <class Type1, class Type2, class ThenType, class ElseType> 00589 class on_same_type; 00590 00591 template <class Type, class ThenType, class ElseType> 00592 class on_same_type<Type, Type, ThenType, ElseType> { 00593 public: 00594 typedef ThenType type; 00595 }; 00596 00597 template <class Type1, class Type2, class ThenType, class ElseType> 00598 class on_same_type { 00599 public: 00600 typedef ElseType type; 00601 }; 00602 00603 00607 struct internal_tag {}; 00608 00612 template<class Type> 00613 struct type_tag {}; 00614 00615 template <class Type> 00616 class hashes { 00617 public: 00618 00619 typedef typename Type::hash_type hash_type; 00620 00621 hash_type operator() (const Type& rhs) const{ 00622 return rhs.hash(); 00623 } 00624 }; 00625 00626 template <class Type> 00627 class generate_index_map { 00628 00629 typedef typename Type::idx_type idx_type; 00630 public: 00632 00633 #ifdef PBORI_HAVE_TR1_UNORDERED_MAP 00634 typedef std::tr1::unordered_map<Type, idx_type, hashes<Type> > type; 00635 #else 00636 # ifdef PBORI_HAVE_UNORDERED_MAP 00637 typedef std::unordered_map<Type, idx_type, hashes<Type> > type; 00638 # else 00639 # ifdef PBORI_HAVE_HASH_MAP 00640 typedef __gnu_cxx::hash_map<Type, idx_type, hashes<Type> > type; 00641 # else 00642 typedef std::map<Type, idx_type> type; 00643 # endif 00644 # endif 00645 #endif 00646 }; 00647 00651 template <class ListType> 00652 class sizes_less: 00653 public std::binary_function<const ListType&, const ListType&, bool> { 00654 00655 public: 00656 bool operator()(const ListType& lhs, const ListType& rhs) const { 00657 return (lhs.size() < rhs.size()); 00658 } 00659 }; 00660 00664 template <class BiIterator> 00665 class reversed_iteration_adaptor { 00666 public: 00667 00669 typedef BiIterator iterator; 00670 00672 typedef reversed_iteration_adaptor<iterator> self; 00674 00675 typedef std::bidirectional_iterator_tag iterator_category; 00676 typedef typename std::iterator_traits<iterator>::difference_type 00677 difference_type; 00678 typedef typename std::iterator_traits<iterator>::pointer pointer; 00679 typedef typename std::iterator_traits<iterator>::reference reference; 00680 typedef typename std::iterator_traits<iterator>::value_type value_type; 00682 00684 reversed_iteration_adaptor(const iterator& iter): 00685 m_iter(iter) {} 00686 00688 00689 reference operator*() const { 00690 return *m_iter; 00691 } 00692 00694 self& operator++() { 00695 --m_iter; 00696 return *this; 00697 } 00698 00700 self& operator--() { 00701 ++m_iter; 00702 return *this; 00703 } 00704 00705 bool operator==(const self& rhs) const { 00706 return m_iter == rhs.m_iter; 00707 } 00708 00709 bool operator!=(const self& rhs) const { 00710 return m_iter != rhs.m_iter; 00711 } 00712 iterator get() const { 00713 return m_iter; 00714 } 00715 00716 protected: 00717 iterator m_iter; 00718 }; 00719 00720 00721 template <class DDType> 00722 class navigates: 00723 public std::unary_function<DDType, typename DDType::navigator> { 00724 public: 00726 typedef DDType dd_type; 00727 00729 typedef typename DDType::navigator navigator; 00730 00732 typedef std::unary_function<dd_type, navigator> base; 00733 00735 typename base::result_type operator()(const dd_type& rhs) const{ 00736 return rhs.navigation(); 00737 } 00738 00739 }; 00740 00741 00742 template <class ValueType> 00743 class default_value { 00744 public: 00745 typedef ValueType value_type; 00746 00747 value_type operator()(...) const{ 00748 return value_type(); 00749 } 00750 00751 }; 00752 00753 template <template<class> class BindType, class BinaryFunction, 00754 class ValueType, class ConstantOp> 00755 class constant_binder_base : 00756 public BindType<BinaryFunction>{ 00757 public: 00758 typedef BinaryFunction bin_op; 00759 typedef ConstantOp const_type; 00760 typedef BindType<bin_op> base; 00761 00762 typedef ValueType value_type; 00763 00764 constant_binder_base(const bin_op& op = bin_op()): base(op, const_type()()) {} 00765 }; 00766 00767 template <class BinaryFunction, class ConstantOp> 00768 class constant_binder2nd : 00769 public constant_binder_base<std::binder2nd, BinaryFunction, 00770 typename BinaryFunction::second_argument_type, 00771 ConstantOp> { 00772 }; 00773 00774 00775 template <class BinaryFunction, class ConstantOp> 00776 class constant_binder1st : 00777 public constant_binder_base<std::binder1st, BinaryFunction, 00778 typename BinaryFunction::first_argument_type, 00779 ConstantOp> { 00780 }; 00781 00782 template <template<class> class BindType, 00783 class BinaryFunction, class ValueType> 00784 class default_binder_base : 00785 public BindType<BinaryFunction>{ 00786 public: 00787 typedef BinaryFunction bin_op; 00788 typedef BindType<bin_op> base; 00789 00790 typedef ValueType value_type; 00791 00792 default_binder_base(const value_type& val): base(bin_op(), val) {} 00793 }; 00794 00795 template <class BinaryFunction> 00796 class default_binder2nd : 00797 public default_binder_base<std::binder2nd, BinaryFunction, 00798 typename BinaryFunction::second_argument_type> { 00799 public: 00800 typedef default_binder_base<std::binder2nd, BinaryFunction, 00801 typename BinaryFunction::second_argument_type> 00802 base; 00803 00804 default_binder2nd(const typename base::value_type& val): base(val) {} 00805 }; 00806 00807 00808 template <class BinaryFunction> 00809 class default_binder1st : 00810 public default_binder_base<std::binder1st, BinaryFunction, 00811 typename BinaryFunction::first_argument_type> { 00812 }; 00813 00814 // /** @class property_owner 00815 // * @brief defines generic base for properties 00816 // **/ 00817 // template <class ValidityTag> 00818 // class property_owner { 00819 // public: 00820 00821 // /// Set marker for validity 00822 // typedef typename 00823 // on_same_type<ValidityTag, valid_tag, valid_tag, invalid_tag>::type property; 00824 00825 // /// Generate Boolean member function 00826 // is_same_type<property, valid_tag> hasProperty; 00827 // }; 00828 00832 template <class ManagerType, 00833 class IdxType = typename ManagerType::idx_type, 00834 class VarNameType = typename ManagerType::const_varname_reference> 00835 class variable_name { 00836 public: 00837 typedef ManagerType manager_type; 00838 typedef IdxType idx_type; 00839 typedef VarNameType varname_type; 00840 00842 variable_name(const manager_type& mgr): m_mgr(mgr) {} 00843 00845 varname_type operator()(idx_type idx) const{ 00846 return m_mgr.getVariableName(idx); 00847 } 00848 00849 protected: 00851 const manager_type& m_mgr; 00852 }; 00853 00854 template <class MapType, class VariableType, class TermType, class NodeType> 00855 class mapped_new_node { 00856 public: 00857 typedef MapType map_type; 00858 typedef NodeType node_type; 00859 00860 typedef typename node_type::idx_type idx_type; 00861 00862 mapped_new_node(const map_type& the_map): m_map(the_map) {} 00863 00864 NodeType operator()(idx_type idx, 00865 const node_type& first, const node_type& second) const{ 00866 return ((TermType)VariableType(m_map[idx]))*first + second; 00867 } 00868 00869 00870 00871 private: 00872 const map_type& m_map; 00873 }; 00874 00875 00880 template <class NewType> 00881 struct pbori_base; 00882 00883 00884 00885 template <class DDType> 00886 class get_node { 00887 00888 public: 00889 typename DDType::node_type operator()(const DDType& rhs) const { 00890 return rhs.getNode(); 00891 } 00892 }; 00893 00894 // template<unsigned ErrorNumber = CUDD_INTERNAL_ERROR> 00895 // struct handle_error { 00896 // typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type; 00897 00898 // handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {} 00899 00900 // bool found(unsigned err) const { 00901 // if PBORI_UNLIKELY(err == ErrorNumber) { 00902 // m_errfunc(cudd_error_traits<ErrorNumber>()()); 00903 // return true; 00904 // } 00905 // return false; 00906 // } 00907 00908 // void operator()(unsigned err) const { 00909 // if PBORI_UNLIKELY(err == ErrorNumber) 00910 // m_errfunc(cudd_error_traits<ErrorNumber>()()); 00911 // else 00912 // reinterpret_cast<const handle_error<ErrorNumber - 1>&>(*this)(err); 00913 // } 00914 00915 // protected: 00916 // const errorfunc_type m_errfunc; 00917 // }; 00918 00919 00920 // template<> 00921 // struct handle_error<0> { 00922 // typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type; 00923 00924 // handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {} 00925 00926 // void operator()(unsigned err) const { 00927 // if PBORI_LIKELY(err == 0) 00928 // m_errfunc(cudd_error_traits<0>()()); 00929 // } 00930 // protected: 00931 // errorfunc_type m_errfunc; 00932 // }; 00933 00934 00935 END_NAMESPACE_PBORI 00936 00937 #endif