PolyBoRi
NextSpoly.h
Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //*****************************************************************************
00014 //*****************************************************************************
00015 
00016 #ifndef polybori_groebner_NextSpoly_h_
00017 #define polybori_groebner_NextSpoly_h_
00018 
00019 // include basic definitions
00020 #include "groebner_defs.h"
00021 #include "ReductionStrategy.h"
00022 
00023 BEGIN_NAMESPACE_PBORIGB
00024 
00030 class NextSpoly {
00031 public:
00032 
00033   NextSpoly(ReductionStrategy& gen, PairStatusSet& status):
00034     m_gen(gen), m_status(status) {}
00035 
00036   Polynomial operator()(const Pair& act_pair) {
00037     return compute(act_pair, act_pair.extract(m_gen));
00038   }
00039 
00040 protected:
00041   Polynomial compute(const Pair& act_pair, const Polynomial& result) {
00042     if (act_pair.getType() == IJ_PAIR)
00043       return compute(act_pair.ijPair(), result);
00044     else
00045       if (act_pair.getType() == VARIABLE_PAIR)
00046         return compute(act_pair.variablePair(), result);
00047     
00048     return result;
00049   }
00050 
00051   Polynomial compute(const IJPairData& ij, const Polynomial& res) {
00052     int i = ij.i, j = ij.j;
00053     replacePair(i, j);
00054     m_status.setToHasTRep(ij.i, ij.j);
00055     if ((i != ij.i) || (ij.j != j)){
00056       m_status.setToHasTRep(i,j);
00057       return spoly(m_gen[i].p, m_gen[j].p);
00058     }
00059     return res;
00060   }
00061 
00062   Polynomial compute(const VariablePairData& vp, const Polynomial& res) {
00063     m_gen(vp.i).vPairCalculated.insert(vp.v);
00064     return (!res.isZero() && (res.lead() == m_gen[vp.i].lead)?
00065             res + m_gen[vp.i].p: res);
00066   }
00067 
00068   void replacePair(int& first, int& second) {
00069     MonomialSet m =
00070       m_gen.leadingTerms.divisorsOf(m_gen[first].leadExp.LCM(m_gen[second].leadExp));
00071     
00072     replacePair(m.expBegin(), m.expEnd(), first, second);
00073   }
00074 
00075   template <class Iterator>
00076   void replacePair(Iterator start, Iterator finish, int& first, int& second) {
00077     std::pair<int, int> original(first, second);
00078     while(start != finish)
00079       replaceGenerators(m_gen.index(*start++), original, first, second);
00080   }
00081 
00082 private:
00083   void replaceGenerators(int index, std::pair<int, int> original,
00084                          int& first, int& second) const {
00085 
00086     if ((index != original.first) && (index != original.second)) {
00087       replaceGenerator(index, original.first, first);
00088       replaceGenerator(index, original.second, second);    
00089     }
00090     PBORI_ASSERT(first != second);
00091   }
00092 
00093   void replaceGenerator(int next, int original, int& current) const {
00094     if (m_status.hasTRep(next, original) &&
00095         (m_gen[current].weightedLength > m_gen[next].weightedLength) &&
00096         (m_gen[next].ecart() <= m_gen[original].ecart()))
00097       current = next;
00098   }
00099 
00100   ReductionStrategy& m_gen;
00101   PairStatusSet& m_status;
00102 };
00103 
00104 END_NAMESPACE_PBORIGB
00105 
00106 #endif /* polybori_groebner_NextSpoly_h_ */