PolyBoRi
|
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