00001
00002
00014
00015
00016 #ifndef polybori_groebner_MinimalLeadingTerms_h_
00017 #define polybori_groebner_MinimalLeadingTerms_h_
00018
00019
00020 #include "groebner_defs.h"
00021
00022 BEGIN_NAMESPACE_PBORIGB
00023
00029 class MinimalLeadingTerms:
00030 public MonomialSet {
00031
00032 typedef MonomialSet base;
00033 typedef MinimalLeadingTerms self;
00034
00035 public:
00036 template <class Type>
00037 MinimalLeadingTerms(const Type& value): base(value) { }
00038
00040 MonomialSet update(const Monomial& lm) {
00041
00042 MonomialSet divisors(divisorsOf(lm));
00043 if(divisors.isZero())
00044 return cleanup(lm);
00045
00046 return (divisors == lm.set()? lm.ring().zero(): lm.set());
00047 }
00048
00049 private:
00050 self& operator=(const self& rhs) {
00051 return static_cast<self&>(static_cast<base&>(*this) = rhs);
00052 }
00053
00054 MonomialSet cleanup(const Monomial& lm) {
00055 MonomialSet removed(multiplesOf(lm).diff(lm.set()));
00056
00057 PBORI_ASSERT(removed.intersect(*this).intersect(lm.set()).isZero());
00058 PBORI_ASSERT(assertion(lm, removed.expBegin(),removed.expEnd()));
00059
00060 *this = diff(removed).unite(lm.set());
00061 return removed;
00062 }
00063
00064 bool assertion(const Monomial& lm,
00065 MonomialSet::exp_iterator start,
00066 MonomialSet::exp_iterator finish) const {
00067 while (start != finish) {
00068 if ( (*start) == lm.exp() || !start->reducibleBy(lm.exp()) )
00069 return false;
00070 ++start;
00071 }
00072 return true;
00073 }
00074 };
00075
00076 END_NAMESPACE_PBORIGB
00077
00078 #endif