PolyBoRi
pbori_func.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 //*****************************************************************************
150 //*****************************************************************************
151 
152 // get polybori definitions
153 #include "pbori_defs.h"
154 
155 // get polybori properties
156 #include "pbori_traits.h"
157 
158 // get standard string and string stream functionality
159 #include <string>
160 #include <sstream>
161 
162 
163 // get map/hash_map functionality from stl/stl-ext
164 #define HAVE_HASH_MAP 1
165 #ifdef HAVE_HASH_MAP
166 # include <ext/hash_map>
167 #else
168 # include <map>
169 #endif
170 
171 #ifndef pbori_func_h_
172 #define pbori_func_h_
173 
175 
178 template <class ListType, class ValueType = typename ListType::value_type >
179 class push_back {
180 public:
181 
182  ListType
183  operator()(ListType theList, const ValueType& elt) const {
184  theList.push_back(elt);
185  return theList;
186  }
187 };
188 
191 template <class RhsType, class LhsType = typename RhsType::idx_type >
192 class change_idx {
193 public:
194 
195  RhsType operator() (const RhsType& rhs, const LhsType& lhs) const {
196  return (rhs.change(lhs));
197  }
198 
199 };
200 
203 template <class RhsType = void,
204  class LhsType = typename pbori_traits<RhsType>::idx_type >
205 class change_assign;
206 
209 template <class RhsType, class LhsType>
211 public:
212 
213  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
214  return (rhs.changeAssign(lhs));
215  }
216 
217 };
218 
221 template<>
222 class change_assign<void, pbori_traits<void>::idx_type> {
223 public:
224 
225  template <class RhsType, class LhsType>
226  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
227  return (rhs.changeAssign(lhs));
228  }
229 
230 };
231 
234 template <class RhsType, class LhsType = typename RhsType::idx_type>
236 public:
237 
238  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
239  (rhs.subset1Assign(lhs));
240  return rhs;
241  }
242 };
243 
246 template <class RhsType, class LhsType>
248 public:
249 
250  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
251  return (rhs.subset0Assign(lhs));
252  }
253 };
256 template <class RhsType,
257  class LhsType = typename pbori_traits<RhsType>::idx_type >
259  public std::binary_function<RhsType&, const LhsType&, RhsType&> {
260 
261 public:
262  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
263  return (rhs.uniteAssign(lhs));
264  }
265 };
266 
267 
268 // @class project_ith
274 
275 template <unsigned int ITH, unsigned int NLEN = ITH>
277 
280 template <unsigned int NLEN>
281 class project_ith<0, NLEN> {
282 
283 public:
285  template <class ValueType>
286  void operator() (const ValueType&, ...) const { }
287 };
288 
291 template <unsigned int NLEN>
292 class project_ith<1, NLEN> {
293 
294 public:
296  template <class ValueType>
297  const ValueType& operator() (const ValueType& value, ...) const {
298  return value;
299  }
300 
302  template <class ValueType>
303  ValueType& operator() (ValueType& value, ...) const {
304  return value;
305  }
306 };
307 
308 
311 template <unsigned int NLEN>
312 class project_ith<2, NLEN> {
313 
314 public:
316  template <class FirstType, class ValueType>
317  const ValueType&
318  operator() (const FirstType&, const ValueType& value, ...) const {
319  return value;
320  }
321 
323  template <class FirstType, class ValueType>
324  ValueType& operator() (const FirstType&, ValueType& value, ...) const {
325  return value;
326  }
327 };
328 
329 
332 template <unsigned int NLEN>
333 class project_ith<3, NLEN> {
334 
335 public:
337  template <class FirstType, class SecondType, class ValueType>
338  const ValueType&
339  operator() (const FirstType&, const SecondType&,
340  const ValueType& value, ...) const {
341  return value;
342  }
343 
345  template <class FirstType, class SecondType, class ValueType>
346  ValueType& operator() (const FirstType&, const SecondType&,
347  ValueType& value, ...) const {
348  return value;
349  }
350 };
351 
352 /*
353 class print_all {
354 public:
355 
356  print_all(std::ostream& os_):os(os_){}
357 
358  template<class Type>
359  Type& operator()(Type& val){
360  std::copy(val.begin(), val.end(),
361  std::ostream_iterator<typename Type::value_type>(os, ", "));
362  return val;
363  }
364  std::ostream& os;
365 };
366 */
367 
371 public:
372 
374  typedef dummy_iterator self;
375 
376  template <class Type>
377  const self& operator=(const Type&) const { return *this;}
378 
379  const self& operator*() const { return *this;}
380  const self& operator++() const { return *this;}
381  const self& operator++(int) const { return *this;}
382 };
383 
384 template <>
386  public CTypes {
387 };
388 
394 template <class IntType, IntType INTCONST, class ResultType = IntType>
396 
397  typedef ResultType result_type;
398  result_type operator()(...) const { return INTCONST; }
399 };
400 
404 template <class BinaryOp, class FirstOp, class SecondOp>
406  public BinaryOp {
407 
408 public:
409 
411 
412  typedef BinaryOp base;
413  typedef FirstOp first_op_type;
414  typedef SecondOp second_op_type;
416 
417  // Constructor
418  binary_composition(const base& binop = base(),
419  const first_op_type& unop1 = first_op_type(),
420  const second_op_type& unop2 = second_op_type() ):
421  base(binop), first_op(unop1), second_op(unop2) {}
422 
424  typedef typename base::result_type result_type;
425 
427  template <class FirstType, class SecondType>
428  result_type operator()(const FirstType& first,
429  const SecondType& second) const {
430  return base::operator()(first_op(first), second_op(second));
431  }
432 
434  template <class FirstType, class SecondType>
435  result_type operator()(FirstType& first,
436  const SecondType& second) const {
437  return base::operator()(first_op(first), second_op(second));
438  }
439 
441  template <class FirstType, class SecondType>
442  result_type operator()(const FirstType& first,
443  SecondType& second) const {
444  return base::operator()(first_op(first), second_op(second));
445  }
446 
447 protected:
450 };
451 
455 template <class BinaryOp, class UnaryOperation>
457  public binary_composition<BinaryOp, UnaryOperation, UnaryOperation> {
458 
459 public:
460 
462 
464  typedef UnaryOperation unary_op_type;
468 
469  // Constructor
471  const unary_op_type& unop = unary_op_type() ):
472  base(binop, unop, unop) {}
473 };
474 
477 template<class ValueType>
479 public:
480  maximum_iteration(ValueType & init) : max(init){}
481 
482  ValueType& operator()(const ValueType& val) const {
483  return max = std::max(max, val);
484  }
485 
486 private:
487  ValueType & max;
488 };
489 
492 template <class DDType>
494 public:
495 
496  DDType& operator()(DDType& lhs, const DDType& rhs) const {
497  // several possible implementations
498  return
499 #ifdef PBORI_ADD_BY_ITE
500  lhs.iteAssign(lhs.diff(rhs), rhs);
501 
502 # elif defined(PBORI_ADD_BY_OR)
503  (lhs = (lhs.diff(rhs)).unite(rhs.diff(lhs)));
504 
505 # elif defined(PBORI_ADD_BY_UNION)
506  (lhs = lhs.unite(rhs).diff( lhs.intersect(rhs) ) );
507 # elif defined(PBORI_ADD_BY_EXTRA_XOR) || defined(PBORI_ADD_BY_XOR)
508  (lhs = lhs.Xor(rhs));
509 #endif
510  }
511 };
512 
515 template <class DDType, class IdxType = typename DDType::idx_type>
517 public:
518 
519  DDType& operator()(DDType& lhs, IdxType idx) const {
520 
521  // get all terms not containing the variable with index idx
522  DDType tmp( lhs.subset0(idx) );
523 
524  // get the complementary terms
525  lhs.diffAssign(tmp);
526 
527  // construct polynomial terms
528  dd_add_assign<DDType>()(lhs, tmp.change(idx));
529 
530  return lhs;
531  }
532 
533 };
534 
537 template <class DDType, class IdxType = typename DDType::idx_type>
539 public:
540 
541  DDType& operator()(DDType& lhs, IdxType idx) const {
542 
543  lhs.uniteAssign( lhs.change(idx) );
544  return lhs;
545  }
546 
547 };
548 
551 // template <class RhsType = void,
552 // class LhsType = typename RhsType::value_type >
553 // class inserts:
554 // public std::binary_function<RhsType&, const LhsType&, RhsType&> {
555 // public:
556 
557 // RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
558 // rhs.insert(lhs);
559 // return rhs;
560 // }
561 
562 // };
563 
564 
567 template <class RhsType = void,
568  class LhsType = typename pbori_traits<RhsType>::idx_type >
569 class inserts;
570 
571 template <class RhsType, class LhsType>
572 class inserts:
573  public std::binary_function<RhsType&, const LhsType&, RhsType&> {
574 public:
575 
576  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
577  rhs.insert(lhs);
578  return rhs;
579  }
580 };
581 
582 template <>
583 class inserts<void, pbori_traits<void>::idx_type> {
584 public:
585 template <class RhsType, class LhsType>
586  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
587  rhs.insert(lhs);
588  return rhs;
589  }
590 };
591 
592 
595 template <class RhsType = void,
596  class LhsType = typename pbori_traits<RhsType>::idx_type >
597 class insert_assign;
598 
599 template <class RhsType, class LhsType>
601  public std::binary_function<RhsType&, const LhsType&, RhsType&> {
602 public:
603 
604  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
605  rhs.insertAssign(lhs);
606  return rhs;
607  }
608 };
609 
610 template <>
611 class insert_assign<void, pbori_traits<void>::idx_type> {
612 public:
613 template <class RhsType, class LhsType>
614  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
615  rhs.insertAssign(lhs);
616  return rhs;
617  }
618 };
619 
620 
621 
624 template <class RhsType = void,
625  class LhsType = typename pbori_traits<RhsType>::idx_type >
626 class removes;
627 
628 
629 template <class RhsType, class LhsType>
630 class removes:
631  public std::binary_function<RhsType&, const LhsType&, RhsType&> {
632 public:
633 
634  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
635  rhs.remove(lhs);
636  return rhs;
637  }
638 };
639 
640 
641 template <>
642 class removes<void, pbori_traits<void>::idx_type> {
643 public:
644 
645  template <class RhsType, class LhsType>
646  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
647  rhs.remove(lhs);
648  return rhs;
649  }
650 };
651 
654 template <class RhsType = void,
655  class LhsType = typename pbori_traits<RhsType>::idx_type >
656 class remove_assign;
657 
658 
659 template <class RhsType, class LhsType>
661  public std::binary_function<RhsType&, const LhsType&, RhsType&> {
662 public:
663 
664  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
665  rhs.removeAssign(lhs);
666  return rhs;
667  }
668 };
669 
670 
671 template <>
672 class remove_assign<void, pbori_traits<void>::idx_type> {
673 public:
674 
675  template <class RhsType, class LhsType>
676  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
677  rhs.removeAssign(lhs);
678  return rhs;
679  }
680 };
681 
684 template <class ListType, class RhsType, class LhsType>
686 public:
687 
688  insert_second_to_list(ListType& theList__):
689  theList(theList__) {};
690 
691  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
692  theList.insert(lhs);
693  return rhs;
694  }
695 
696 private:
697  ListType& theList;
698 };
699 
700 
704 template <class Type1, class Type2>
705 class is_same_type;
706 
707 template <class Type>
708 class is_same_type<Type, Type>:
709  public integral_constant<CTypes::bool_type, true> {};
710 
711 template <class Type1, class Type2>
713  public integral_constant<CTypes::bool_type, false> {};
714 
715 
719 template <class Type1, class Type2, class ThenType, class ElseType>
720 class on_same_type;
721 
722 template <class Type, class ThenType, class ElseType>
723 class on_same_type<Type, Type, ThenType, ElseType> {
724 public:
725  typedef ThenType type;
726 };
727 
728 template <class Type1, class Type2, class ThenType, class ElseType>
730 public:
731  typedef ElseType type;
732 };
733 
734 
738 struct internal_tag {};
739 
743 template<class Type>
744 struct type_tag {};
745 
746 template <class Type>
747 class hashes {
748 public:
749 
750  typedef typename Type::hash_type hash_type;
751 
752  hash_type operator() (const Type& rhs) const{
753  return rhs.hash();
754  }
755 };
756 
757 template <class Type>
758 class lm_hashes {
759 public:
760 
761  typedef typename Type::hash_type hash_type;
762 
763  hash_type operator() (const Type& rhs) const{
764  return rhs.lmHash();
765  }
766 };
767 
768 template <class Type>
770 
771  typedef typename Type::idx_type idx_type;
772 public:
774 #ifdef HAVE_HASH_MAP
775  typedef __gnu_cxx::hash_map<Type, idx_type, hashes<Type> > type;
776 #else
777  typedef std::map<Type, idx_type> type;
778 #endif
779 };
780 
784 template <class ListType>
786  public std::binary_function<const ListType&, const ListType&, bool> {
787 
788 public:
789  bool operator()(const ListType& lhs, const ListType& rhs) const {
790  return (lhs.size() < rhs.size());
791  }
792 };
793 
797 template <class BiIterator>
799 public:
800 
802  typedef BiIterator iterator;
803 
807 
808  typedef std::bidirectional_iterator_tag iterator_category;
809  typedef typename std::iterator_traits<iterator>::difference_type
811  typedef typename std::iterator_traits<iterator>::pointer pointer;
812  typedef typename std::iterator_traits<iterator>::reference reference;
813  typedef typename std::iterator_traits<iterator>::value_type value_type;
815 
818  m_iter(iter) {}
819 
821 
823  return *m_iter;
824  }
825 
827  self& operator++() {
828  --m_iter;
829  return *this;
830  }
831 
833  self& operator--() {
834  ++m_iter;
835  return *this;
836  }
837 
838  bool operator==(const self& rhs) const {
839  return m_iter == rhs.m_iter;
840  }
841 
842  bool operator!=(const self& rhs) const {
843  return m_iter != rhs.m_iter;
844  }
845  iterator get() const {
846  return m_iter;
847  }
848 
849 protected:
851 };
852 
853 
854 template <class DDType>
855 class navigates:
856  public std::unary_function<DDType, typename DDType::navigator> {
857 public:
859  typedef DDType dd_type;
860 
862  typedef typename DDType::navigator navigator;
863 
865  typedef std::unary_function<dd_type, navigator> base;
866 
868  typename base::result_type operator()(const dd_type& rhs) const{
869  return rhs.navigation();
870  }
871 
872 };
873 
874 
875 template <class ValueType>
877 public:
878  typedef ValueType value_type;
879 
880  value_type operator()(...) const{
881  return value_type();
882  }
883 
884 };
885 
886 template <template<class> class BindType, class BinaryFunction,
887  class ValueType, class ConstantOp>
889  public BindType<BinaryFunction>{
890 public:
891  typedef BinaryFunction bin_op;
892  typedef ConstantOp const_type;
893  typedef BindType<bin_op> base;
894 
895  typedef ValueType value_type;
896 
897  constant_binder_base(const bin_op& op = bin_op()): base(op, const_type()()) {}
898 };
899 
900 template <class BinaryFunction, class ConstantOp>
902  public constant_binder_base<std::binder2nd, BinaryFunction,
903  typename BinaryFunction::second_argument_type,
904  ConstantOp> {
905 };
906 
907 
908 template <class BinaryFunction, class ConstantOp>
910  public constant_binder_base<std::binder1st, BinaryFunction,
911  typename BinaryFunction::first_argument_type,
912  ConstantOp> {
913 };
914 
915 template <template<class> class BindType,
916  class BinaryFunction, class ValueType>
918  public BindType<BinaryFunction>{
919 public:
920  typedef BinaryFunction bin_op;
921  typedef BindType<bin_op> base;
922 
923  typedef ValueType value_type;
924 
925  default_binder_base(const value_type& val): base(bin_op(), val) {}
926 };
927 
928 template <class BinaryFunction>
930  public default_binder_base<std::binder2nd, BinaryFunction,
931  typename BinaryFunction::second_argument_type> {
932 public:
933  typedef default_binder_base<std::binder2nd, BinaryFunction,
934  typename BinaryFunction::second_argument_type>
936 
937  default_binder2nd(const typename base::value_type& val): base(val) {}
938 };
939 
940 
941 template <class BinaryFunction>
943  public default_binder_base<std::binder1st, BinaryFunction,
944  typename BinaryFunction::first_argument_type> {
945 };
946 
947 // /** @class property_owner
948 // * @brief defines generic base for properties
949 // **/
950 // template <class ValidityTag>
951 // class property_owner {
952 // public:
953 
954 // /// Set marker for validity
955 // typedef typename
956 // on_same_type<ValidityTag, valid_tag, valid_tag, invalid_tag>::type property;
957 
958 // /// Generate Boolean member function
959 // is_same_type<property, valid_tag> hasProperty;
960 // };
961 
965 template <class ManagerType,
966  class IdxType = typename ManagerType::idx_type,
967  class VarNameType = typename ManagerType::const_varname_reference>
969 public:
970  typedef ManagerType manager_type;
971  typedef IdxType idx_type;
972  typedef VarNameType varname_type;
973 
975  variable_name(const manager_type& mgr): m_mgr(mgr) {}
976 
979  return m_mgr.getName(idx);
980  }
981 
982 protected:
985 };
986 
987 template <class MapType, class VariableType, class TermType, class NodeType>
989 public:
990  typedef MapType map_type;
991  typedef NodeType node_type;
992 
993  typedef typename node_type::idx_type idx_type;
994 
995  mapped_new_node(const map_type& the_map): m_map(the_map) {}
996 
997  NodeType operator()(idx_type idx,
998  const node_type& first, const node_type& second) const{
999  return ((TermType)VariableType(m_map[idx]))*first + second;
1000  }
1001 
1002 
1003 
1004 private:
1005  const map_type& m_map;
1006 };
1007 
1008 
1013 template <class NewType>
1014 struct pbori_base;
1015 
1016 
1017 
1018 template <class DDType>
1019 class get_node {
1020 
1021 public:
1022  typename DDType::node_type operator()(const DDType& rhs) const {
1023  return rhs.getNode();
1024  }
1025 };
1026 
1027 template<unsigned ErrorNumber = CUDD_INTERNAL_ERROR>
1029  typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type;
1030 
1031  handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {}
1032 
1033  bool found(unsigned err) const {
1034  if UNLIKELY(err == ErrorNumber) {
1035  m_errfunc(cudd_error_traits<ErrorNumber>()());
1036  return true;
1037  }
1038  return false;
1039  }
1040 
1041  void operator()(unsigned err) const {
1042  if UNLIKELY(err == ErrorNumber)
1043  m_errfunc(cudd_error_traits<ErrorNumber>()());
1044  else
1045  reinterpret_cast<const handle_error<ErrorNumber - 1>&>(*this)(err);
1046  }
1047 
1048 protected:
1050 };
1051 
1052 
1053 template<>
1054 struct handle_error<0> {
1055  typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type;
1056 
1057  handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {}
1058 
1059  void operator()(unsigned err) const {
1060  if LIKELY(err == 0)
1061  m_errfunc(cudd_error_traits<0>()());
1062  }
1063 protected:
1065 };
1066 
1067 
1069 
1070 #endif