PolyBoRi
LLReduction.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 //*****************************************************************************
14 //*****************************************************************************
15 
16 #ifndef polybori_groebner_LLReduction_h_
17 #define polybori_groebner_LLReduction_h_
18 
19 // include basic definitions
20 #include "groebner_defs.h"
21 
23 
28 template <bool have_redsb, bool single_call_for_noredsb,
29  bool fast_multiplication>
30 class LLReduction {
31 public:
32 
33  template<class RingType>
34  LLReduction(const RingType& ring): cache_mgr(ring) {}
35 
39 
40  return dd_multiply<fast_multiplication>(cache_mgr_type(p.ring()),
41  p.navigation(), q.navigation(),
42  BoolePolynomial(p.ring()));
43  }
44 
45  Polynomial operator()(const Polynomial& p, MonomialSet::navigator r_nav);
46 
47 protected:
48  typedef PBORI::CacheManager<CCacheTypes::ll_red_nf> cache_mgr_type;
50 };
51 
52 
53 template <bool have_redsb, bool single_call_for_noredsb, bool fast_multiplication>
55 LLReduction<have_redsb, single_call_for_noredsb,
56  fast_multiplication>::operator() (const Polynomial& p,
57  MonomialSet::navigator r_nav) {
58 
59  if PBORI_UNLIKELY(p.isConstant()) return p;
60 
61  MonomialSet::navigator p_nav=p.navigation();
62  idx_type p_index=*p_nav;
63 
64  while((*r_nav)<p_index) {
65  r_nav.incrementThen();
66  }
67 
68  if PBORI_UNLIKELY(r_nav.isConstant())
69  return p;
70 
71  MonomialSet::navigator cached = cache_mgr.find(p_nav, r_nav);
72 
73  if PBORI_LIKELY(cached.isValid())
74  return MonomialSet(cache_mgr.generate(cached));
75 
76  Polynomial res(0, p.ring());
77 
78  Polynomial p_nav_else(cache_mgr.generate(p_nav.elseBranch()));
79  Polynomial p_nav_then(cache_mgr.generate(p_nav.thenBranch()));
80 
81  if ((*r_nav) == p_index){
82  Polynomial r_nav_else(cache_mgr.generate(r_nav.elseBranch()));
83 
84  if ((!have_redsb) && single_call_for_noredsb) {
85  res = operator()(p_nav_else + multiply(r_nav_else, p_nav_then),
86  r_nav.thenBranch());
87  }
88  else {
89  Polynomial tmp1 = operator()(p_nav_else, r_nav.thenBranch());
90  Polynomial tmp2 = operator()(p_nav_then, r_nav.thenBranch());
91 
92  Polynomial tmp( have_redsb? r_nav_else:
93  operator()(r_nav_else, r_nav.thenBranch()) );
94  res = tmp1 + multiply(tmp, tmp2);
95  }
96  }
97  else{
98  PBORI_ASSERT((*r_nav)>p_index);
99  res = MonomialSet( p_index,
100  operator()(p_nav_then, r_nav).diagram(),
101  operator()(p_nav_else, r_nav).diagram());
102 
103  }
104 
105  cache_mgr.insert(p_nav, r_nav, res.navigation());
106  return res;
107 }
108 
110 
111 #endif /* polybori_LLReduction_h_ */