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