PolyBoRi
COrderingFacade.h
Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //*****************************************************************************
00014 //*****************************************************************************
00015 
00016 #ifndef polybori_orderings_COrderingFacade_h_
00017 #define polybori_orderings_COrderingFacade_h_
00018 
00019 // include basic definitions
00020 #include <polybori/pbori_defs.h>
00021 
00022 #include <polybori/BoolePolynomial.h>
00023 #include <polybori/BooleMonomial.h>
00024 #include <polybori/BooleExponent.h>
00025 
00026 #include "COrderingBase.h"
00027 #include "COrderingTags.h"
00028 #include <polybori/iterators/COrderedIter.h>
00029 // include ordering tags
00030 #include <polybori/common/tags.h>
00031 #include "order_traits.h"
00032 // include polybori functionals
00033 #include <polybori/routines/pbori_func.h>
00034 
00035 BEGIN_NAMESPACE_PBORI
00036 
00042 template <class OrderType, class OrderTag>
00043 class COrderingFacade:
00044   public COrderingBase, 
00045   public COrderingTags<OrderTag>, public order_traits<OrderTag> { 
00046 
00048   typedef COrderingFacade self;
00049 
00051   typedef COrderingBase base_type;
00052 
00053 public:
00055   typedef self base;
00056 
00058   typedef OrderType order_type;
00059 
00061   typedef CCacheTypes::lead_tag<OrderTag> order_lead_tag;
00062   typedef COrderingTags<OrderTag> ordering_tags;
00064   COrderingFacade(): 
00065     base_type() { }
00066   
00068   COrderingFacade(const self& rhs): 
00069     base_type(rhs) { }
00070 
00072   ~COrderingFacade() { }
00073 
00074 
00076   poly_type leadFirst(const poly_type& poly) const {
00077 
00078     if(orderedStandardIteration())
00079       return poly;
00080     else 
00081       return lead(poly);
00082   }
00083 
00085   bool_type isLexicographical() const {
00086     return is_valid<typename ordering_tags::lex_property>::result;
00087   }
00088 
00090   bool_type orderedStandardIteration() const {
00091     return is_valid<typename ordering_tags::ordered_property>::result;
00092   }
00093 
00095   bool_type isSymmetric() const {
00096     return is_valid<typename ordering_tags::symmetry_property>::result;
00097   }
00098 
00100   bool_type isDegreeOrder() const {
00101     return is_valid<typename ordering_tags::degorder_property>::result;
00102   }
00103 
00105   bool_type isBlockOrder() const {
00106     return is_valid<typename ordering_tags::blockorder_property>::result;
00107   }
00108 
00110   bool_type isTotalDegreeOrder() const {
00111     return is_valid<typename ordering_tags::totaldegorder_property>::result;
00112   }
00113 
00115   bool_type isDegreeReverseLexicographical() const {
00116     return is_valid<typename ordering_tags::degrevlexorder_property>::result;
00117   }
00118 
00120   bool_type ascendingVariables() const {
00121     return is_valid<typename ordering_tags::ascending_property>::result;
00122   }
00123 
00125   bool_type descendingVariables() const {
00126     return is_valid<typename ordering_tags::descending_property>::result;
00127   }
00128 
00130   ordercode_type getOrderCode() const {
00131     return order_traits<OrderTag>::order_code;
00132   }
00133 
00135   ordercode_type getBaseOrderCode() const {
00136     return  order_traits<OrderTag>::baseorder_code;
00137   }
00138 
00141   bool_type lieInSameBlock(idx_type first, idx_type second) const {
00142     return inSameBlockInternal(first, second, 
00143                                typename ordering_tags::blockorder_property());
00144   }
00145 
00146 
00148   idx_type lastBlockStart() const {
00149     if (isBlockOrder()) {
00150       return *(blockEnd() - 2);
00151     }
00152     else if (isLexicographical()) {
00153       return CTypes::max_idx;
00154     }
00155     return 0;
00156   }
00157 
00158   // Initialize iterator corresponding to leading term
00159   ordered_iterator
00160   leadIteratorBegin(const poly_type& poly) const {
00161     return CGenericOrderedIter<order_type, navigator,
00162       monom_type>(poly.navigation(), poly.ring());
00163   }
00164 
00165   ordered_iterator
00166   leadIteratorEnd(const poly_type& poly) const {
00167     return CGenericOrderedIter<order_type, navigator, monom_type>(navigator(), poly.ring());
00168   }
00169 
00170   // Initialize iterator corresponding to leading term
00171   ordered_exp_iterator
00172   leadExpIteratorBegin(const poly_type& poly) const {
00173     return CGenericOrderedIter<order_type, navigator, exp_type>(poly.navigation(), poly.ring()); 
00174   }
00175 
00176   ordered_exp_iterator
00177   leadExpIteratorEnd(const poly_type& poly) const {
00178     return CGenericOrderedIter<order_type, navigator, exp_type>(navigator(), poly.ring());
00179   }
00180 
00181 protected:
00182 
00184   bool_type inSameBlockInternal(idx_type, idx_type,
00185                                 invalid_tag) const { // not a block order 
00186     return true;
00187   }
00188   
00190   bool_type inSameBlockInternal(idx_type first, idx_type second, 
00191                                 valid_tag) const { // is block order 
00192     // todo: throw here if first,second >=CTypes::max_idx
00193     if(PBORI_UNLIKELY(first > CTypes::max_idx || second > CTypes::max_idx || 
00194                 first < 0 || second < 0))
00195       throw std::runtime_error("Variable index out of range.");
00196 
00197     if (second < first)
00198       std::swap(first, second);
00199     
00200     block_iterator upper(blockBegin());
00201     while (first >= *upper)    // Note: convention, last element is max_idx
00202       ++upper;
00203     return (second < *upper);
00204   }
00205 
00206 };
00207 
00208 END_NAMESPACE_PBORI
00209 
00210 #endif