00001
00002
00014
00015
00016 #ifndef polybori_orderings_COrderingFacade_h_
00017 #define polybori_orderings_COrderingFacade_h_
00018
00019
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
00030 #include <polybori/common/tags.h>
00031 #include "order_traits.h"
00032
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
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
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 {
00186 return true;
00187 }
00188
00190 bool_type inSameBlockInternal(idx_type first, idx_type second,
00191 valid_tag) const {
00192
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)
00202 ++upper;
00203 return (second < *upper);
00204 }
00205
00206 };
00207
00208 END_NAMESPACE_PBORI
00209
00210 #endif