carl  24.04
Computer ARithmetic Library
Reductor.h
Go to the documentation of this file.
1 /**
2  * @file: Reductor.h
3  * @author: Sebastian Junges
4  *
5  * @since July 11, 2013
6  */
7 
8 #pragma once
9 
10 #include "Ideal.h"
11 #include "ReductorEntry.h"
14 
15 namespace carl
16 {
17 
18 /**
19  * @ingroup gb
20  * Class with the settings for the reduction algorithm.
21  */
22 template<class Polynomial>
24 {
25 public:
26 
28  using Entry = EntryType*;
30 
32  {
33  return Polynomial::OrderedBy::compare(e1->getLead(), e2->getLead());
34  }
35 
36  static bool cmpLessThan(CompareResult res)
37  {
38  return res == CompareResult::LESS;
39  }
40  static const bool supportDeduplicationWhileOrdering = false;
41 
42  static bool cmpEqual(CompareResult res)
43  {
44  return res == CompareResult::EQUAL;
45  }
46 
47  /**
48  * should only be called if the compare result was EQUAL
49  * eliminate duplicate leading monomials
50  * @param e1 upper entry
51  * @param e2 lower entry
52  * @return true if e1->lt is cancelled
53  */
54  static bool deduplicate(Entry e1, Entry e2)
55  {
56  assert( *(e1->getLead()) == *(e2->getLead()));
57  return e1->addCoefficient(e2->getLead().getCoeff());
58  }
59 
60  static const bool fastIndex = true;
61 };
62 
63 /**
64  * A dedicated algorithm for calculating the remainder of a polynomial modulo a set of other polynomials.
65  * @ingroup gb
66  */
67 template<typename InputPolynomial, typename PolynomialInIdeal, template <class> class Datastructure = carl::Heap, template <typename Polynomial> class Configuration = ReductorConfiguration>
68 class Reductor
69 {
70 
71 protected:
72  using Order = typename InputPolynomial::OrderedBy;
73  using EntryType = typename Configuration<InputPolynomial>::EntryType;
74  using Coeff = typename InputPolynomial::CoeffType;
75 private:
77  Datastructure<Configuration<InputPolynomial>> mDatastruct;
78  std::vector<Term<Coeff>> mRemainder;
81 public:
82  Reductor(const Ideal<PolynomialInIdeal>& ideal, const InputPolynomial& f) :
83  mIdeal(ideal), mDatastruct(Configuration<InputPolynomial>()), mReductionOccured(false)
84  {
85  insert(f, Term<Coeff>(Coeff(1)));
86  if(InputPolynomial::Policy::has_reasons)
87  {
88  mReasons = f.getReasons();
89  }
90 
91  }
92 
93  Reductor(const Ideal<PolynomialInIdeal>& ideal, const Term<Coeff>& f) :
94  mIdeal(ideal), mDatastruct(Configuration<InputPolynomial>())
95  {
96  insert(f);
97  }
98 
99  virtual ~Reductor() = default;
100 
101  /**
102  * The basic reduce routine on a priority queue.
103  * @return
104  */
105  bool reduce()
106  {
107  while(!mDatastruct.empty())
108  {
109  typename Configuration<InputPolynomial>::Entry entry;
110  Term < Coeff > leadingTerm;
111  // Find a leading term.
112  do
113  {
114  // get actual leading term
115  entry = mDatastruct.top();
116  leadingTerm = entry->getLead();
117  CARL_LOG_TRACE("carl.gb.reductor", "Intermediate leading term: " << leadingTerm);
118  assert(!is_zero(leadingTerm));
119  // update the data structure.
120  // only insert non-empty polynomials.
121  if(!updateDatastruct(entry)) break;
122  typename Configuration<InputPolynomial>::Entry newentry = mDatastruct.top();
123  while(entry != newentry && Term<Coeff>::monomialEqual(leadingTerm, (newentry->getLead())))
124  {
125  assert(!newentry->empty());
126  leadingTerm = Term<Coeff>(leadingTerm.coeff() + newentry->getLead().coeff(), leadingTerm.monomial());
127  if(!updateDatastruct(newentry)) break;
128  newentry = mDatastruct.top();
129  }
130  }
131  while(is_zero(leadingTerm) && !mDatastruct.empty());
132  // Done finding leading term.
133  //std::cout << "Leading term: " << *leadingTerm << std::endl;
134  // We have found the leading term..
135  if(is_zero(leadingTerm))
136  {
137  assert(mDatastruct.empty());
138  //then the datastructure is empty, we are done.
139  return true;
140  }
141  //std::cout << "Look for divisor.." << std::endl;
142 
143  //find a suitable reductor and the corresponding factor.
145  // check if the reduction succeeded.
146  if(divres.success())
147  {
148  mReductionOccured = true;
149  if(PolynomialInIdeal::Policy::has_reasons)
150  {
151  mReasons.calculateUnion(divres.mDivisor->getReasons());
152  }
153  if(divres.mDivisor->nr_terms() > 1)
154  {
155  insert(divres.mDivisor->tail(true), divres.mFactor);
156  }
157  }
158  else
159  {
160  CARL_LOG_DEBUG("carl.gb.reductor", "Not reducible: " << leadingTerm);
161  mRemainder.push_back(leadingTerm);
162  return false;
163  }
164  }
165  return true;
166  }
167 
168  /**
169  * Gets the flag which indicates that a reduction has occurred (p -> p' with p' != p)
170  * @return the value of the flag
171  */
173  {
174  return mReductionOccured;
175  }
176 
177  /**
178  * Uses the ideal to reduce a polynomial as far as possible.
179  * @return
180  */
181  InputPolynomial fullReduce()
182  {
183  //std::cout << "start full reduce" << std::endl;
184  // TODO:
185  // Do simple reductions first.
186  while(!reduce())
187  {
188  // std::cout << "done reducing" << std::endl;
189  // no operation.
190  }
191  // TODO check whether this is sorted.
192  InputPolynomial result(std::move(mRemainder), true, false);
193  if(InputPolynomial::Policy::has_reasons)
194  {
195  result.setReasons(mReasons);
196  mReasons.clear();
197  }
198  //std::cout << "done full reduce" << std::endl;
199  return result;
200 
201  }
202 
203 
204 private:
205 
206 
207 
208 
209  /**
210  * A small routine which updates the underlying data structure for the polynomial which is reduced.
211  * @param entry
212  * @return
213  */
214  inline bool updateDatastruct(EntryType* entry)
215  {
216  assert(!mDatastruct.empty());
217  if(is_zero(entry->getTail()))
218  {
219  mDatastruct.pop();
220  delete entry;
221  if(mDatastruct.empty()) return false;
222  }
223  else
224  {
225  entry->removeLeadingTerm();
226  assert(!entry->empty());
227  mDatastruct.decreaseTop(entry);
228  }
229  return true;
230  }
231 
232  void insert(const InputPolynomial& g, const Term<Coeff>& fact)
233  {
234  if(!is_zero(g))
235  {
236  CARL_LOG_TRACE("carl.gb.reductor", "Insert polynomial: " << g << " * " << fact);
237  mDatastruct.push(new EntryType(fact, g));
238  }
239  }
240 
241  void insert(const Term<Coeff>& g)
242  {
243  assert(g.getCoeff() != 0);
244  mDatastruct.push(new EntryType(g));
245  }
246 
247 
248  //Origins mOrigins;
249 };
250 
251 
252 }
This file has been extracted from mathic.
#define CARL_LOG_TRACE(channel, msg)
Definition: carl-logging.h:44
#define CARL_LOG_DEBUG(channel, msg)
Definition: carl-logging.h:43
carl is the main namespace for the library.
signed compare(const BasicConstraint< Pol > &_constraintA, const BasicConstraint< Pol > &_constraintB)
Compares _constraintA with _constraintB.
Definition: Comparison.h:25
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Definition: Interval.h:1453
CompareResult
Definition: CompareResult.h:12
Term< typename Polynomial::CoeffType > mFactor
const Polynomial *const mDivisor
DivisionLookupResult< Polynomial > getDivisor(const Term< typename Polynomial::CoeffType > &t) const
Definition: Ideal.h:75
Class with the settings for the reduction algorithm.
Definition: Reductor.h:24
static bool deduplicate(Entry e1, Entry e2)
should only be called if the compare result was EQUAL eliminate duplicate leading monomials
Definition: Reductor.h:54
static CompareResult compare(Entry e1, Entry e2)
Definition: Reductor.h:31
static const bool fastIndex
Definition: Reductor.h:60
static bool cmpLessThan(CompareResult res)
Definition: Reductor.h:36
static const bool supportDeduplicationWhileOrdering
Definition: Reductor.h:40
static bool cmpEqual(CompareResult res)
Definition: Reductor.h:42
A dedicated algorithm for calculating the remainder of a polynomial modulo a set of other polynomials...
Definition: Reductor.h:69
std::vector< Term< Coeff > > mRemainder
Definition: Reductor.h:78
virtual ~Reductor()=default
Datastructure< Configuration< InputPolynomial > > mDatastruct
Definition: Reductor.h:77
const Ideal< PolynomialInIdeal > & mIdeal
Definition: Reductor.h:76
void insert(const Term< Coeff > &g)
Definition: Reductor.h:241
InputPolynomial fullReduce()
Uses the ideal to reduce a polynomial as far as possible.
Definition: Reductor.h:181
typename Configuration< InputPolynomial >::EntryType EntryType
Definition: Reductor.h:73
bool mReductionOccured
Definition: Reductor.h:79
BitVector mReasons
Definition: Reductor.h:80
typename InputPolynomial::OrderedBy Order
Definition: Reductor.h:72
Reductor(const Ideal< PolynomialInIdeal > &ideal, const Term< Coeff > &f)
Definition: Reductor.h:93
bool reductionOccured()
Gets the flag which indicates that a reduction has occurred (p -> p' with p' != p)
Definition: Reductor.h:172
typename InputPolynomial::CoeffType Coeff
Definition: Reductor.h:74
Reductor(const Ideal< PolynomialInIdeal > &ideal, const InputPolynomial &f)
Definition: Reductor.h:82
bool updateDatastruct(EntryType *entry)
A small routine which updates the underlying data structure for the polynomial which is reduced.
Definition: Reductor.h:214
bool reduce()
The basic reduce routine on a priority queue.
Definition: Reductor.h:105
void insert(const InputPolynomial &g, const Term< Coeff > &fact)
Definition: Reductor.h:232
An entry in the reduction polynomial.
Definition: ReductorEntry.h:25
bool addCoefficient(const Coeff &coeffToBeAdded)
Definition: ReductorEntry.h:96
const Term< Coeff > & getLead() const
Definition: ReductorEntry.h:66
Coefficient & coeff()
Get the coefficient.
Definition: Term.h:80
Monomial::Arg & monomial()
Get the monomial.
Definition: Term.h:91
BitVector & calculateUnion(const BitVector &rhs)
Definition: BitVector.h:100
void clear()
Definition: BitVector.h:27
A heap priority queue.
Definition: Heap.h:42