[mathicgb] 28/393: Changed Reducer to only offer a higher level interface. Moved all its implementation stuff into TypicalReducer and made all 13 reducer classes derive from that instead (ugh). This is in preparation for F4 reduction which requires a significantly different representation than the current reducer classes.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:27 UTC 2015


This is an automated email from the git hooks/post-receive script.

dtorrance-guest pushed a commit to branch upstream
in repository mathicgb.

commit 88bd2d156f36b3d8a06fb532ae55011107268b6c
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Wed Sep 26 14:51:19 2012 +0200

    Changed Reducer to only offer a higher level interface. Moved all its implementation stuff into TypicalReducer and made all 13 reducer classes derive from that instead (ugh). This is in preparation for F4 reduction which requires a significantly different representation than the current reducer classes.
---
 Makefile.am                        |   3 +-
 src/mathicgb/BjarkeGeobucket2.cpp  |  26 ++---
 src/mathicgb/BjarkeGeobucket2.hpp  |  11 +-
 src/mathicgb/HashTourReducer.cpp   |  11 +-
 src/mathicgb/HashTourReducer.hpp   |   6 +-
 src/mathicgb/PolyGeoBucket.cpp     |  11 +-
 src/mathicgb/PolyGeoBucket.hpp     |   8 +-
 src/mathicgb/PolyHashReducer.cpp   |  14 +--
 src/mathicgb/PolyHashReducer.hpp   |  10 +-
 src/mathicgb/PolyHeap.cpp          |  13 +--
 src/mathicgb/PolyHeap.hpp          |   8 +-
 src/mathicgb/PolyReducer.cpp       |  12 +-
 src/mathicgb/PolyReducer.hpp       |  11 +-
 src/mathicgb/Reducer.cpp           | 225 +++----------------------------------
 src/mathicgb/Reducer.hpp           | 105 ++++++++---------
 src/mathicgb/ReducerDedup.hpp      |  20 ++--
 src/mathicgb/ReducerHash.hpp       |  25 ++---
 src/mathicgb/ReducerHashPack.hpp   |  11 +-
 src/mathicgb/ReducerNoDedup.hpp    |  16 ++-
 src/mathicgb/ReducerPack.hpp       |  20 ++--
 src/mathicgb/ReducerPackDedup.hpp  |  24 ++--
 src/mathicgb/TournamentReducer.cpp |  12 +-
 src/mathicgb/TournamentReducer.hpp |   6 +-
 src/mathicgb/TypicalReducer.cpp    | 195 ++++++++++++++++++++++++++++++++
 src/mathicgb/TypicalReducer.hpp    |  57 ++++++++++
 src/mathicgb/io-util.cpp           |  22 ----
 src/mathicgb/io-util.hpp           |   3 -
 src/test/poly-test.cpp             |  23 ++++
 28 files changed, 469 insertions(+), 439 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 4c42627..573ae1c 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -55,7 +55,8 @@ libmathicgb_la_SOURCES = src/mathicgb/BjarkeGeobucket2.cpp				\
   src/mathicgb/TournamentReducer.hpp src/mathicgb/SigSPairQueue.hpp		\
   src/mathicgb/SigSPairQueue.cpp src/mathicgb/SparseMatrix.hpp			\
   src/mathicgb/SparseMatrix.cpp src/mathicgb/QuadMatrixBuilder.hpp		\
-  src/mathicgb/QuadMatrixBuilder.cpp
+  src/mathicgb/QuadMatrixBuilder.cpp src/mathicgb/TypicalReducer.cpp	\
+  src/mathicgb/TypicalReducer.cpp
 
 # When making a distribution file, Automake knows to include all files
 # that are necessary to build the project. EXTRA_DIST specifies files
diff --git a/src/mathicgb/BjarkeGeobucket2.cpp b/src/mathicgb/BjarkeGeobucket2.cpp
index 267bac6..008b71b 100755
--- a/src/mathicgb/BjarkeGeobucket2.cpp
+++ b/src/mathicgb/BjarkeGeobucket2.cpp
@@ -6,18 +6,11 @@
 
 extern int tracingLevel;
 
-BjarkeGeobucket2::BjarkeGeobucket2(const PolyRing *R0)
-  : Reducer(),
-    mRing(*R0),
-    mHashTableOLD(R0,10),
-    mHeap(GeoConfiguration(*R0,4,1)),
-    mHashTable(BjarkeGeobucket2Configuration(*R0),10)
-{
-  //std::cerr << "Creating geobucket2" << std::endl;
-}
-
-BjarkeGeobucket2::~BjarkeGeobucket2()
-{
+BjarkeGeobucket2::BjarkeGeobucket2(const PolyRing *R0):
+  mRing(*R0),
+  mHashTableOLD(R0, 10),
+  mHeap(GeoConfiguration(*R0, 4, 1)),
+  mHashTable(BjarkeGeobucket2Configuration(*R0), 10) {
 }
 
 void BjarkeGeobucket2::insert(Poly::const_iterator first, 
@@ -79,7 +72,7 @@ void BjarkeGeobucket2::insert(monomial multiplier, const Poly *g1)
   mHeap.getConfiguration().resetComparisons();
 }
 
-bool BjarkeGeobucket2::findLeadTerm(const_term &result)
+bool BjarkeGeobucket2::leadTerm(const_term &result)
 {
   while (!mHeap.empty())
     {
@@ -101,7 +94,7 @@ void BjarkeGeobucket2::value(Poly &result)
 // keep extracting lead term until done
 {
   const_term t;
-  while (findLeadTerm(t))
+  while (leadTerm(t))
     {
       result.appendTerm(t.coeff, t.monom);
       mHeap.pop();
@@ -112,7 +105,7 @@ void BjarkeGeobucket2::value(Poly &result)
 void BjarkeGeobucket2::resetReducer()
 {
   const_term t;
-  while (findLeadTerm(t))
+  while (leadTerm(t))
     {
       mHeap.pop();
     }
@@ -122,7 +115,8 @@ void BjarkeGeobucket2::resetReducer()
 
 size_t BjarkeGeobucket2::getMemoryUse() const
 {
-  size_t result = mHashTableOLD.getMemoryUse();
+  size_t result = TypicalReducer::getMemoryUse();
+  result += mHashTableOLD.getMemoryUse();
   result += mHeap.getMemoryUse();
   result += mHashTable.memoryUse();
   return result;
diff --git a/src/mathicgb/BjarkeGeobucket2.hpp b/src/mathicgb/BjarkeGeobucket2.hpp
old mode 100644
new mode 100755
index a22cd01..2438bca
--- a/src/mathicgb/BjarkeGeobucket2.hpp
+++ b/src/mathicgb/BjarkeGeobucket2.hpp
@@ -4,7 +4,7 @@
 #define _bjarkeGeoBucket_h_
 
 #include <mathic.h>
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 #include "PolyHashTable.hpp"
 
 class GeoConfiguration {
@@ -67,22 +67,21 @@ private:
   const PolyRing &mRing;
 };
 
-class BjarkeGeobucket2 : public Reducer {
+class BjarkeGeobucket2 : public TypicalReducer {
 public:
   BjarkeGeobucket2(const PolyRing *R);
-  ~BjarkeGeobucket2();
 
   virtual std::string description() const { return "bjarke geo buckets"; }
 
   void insertTail(const_term multiplier, const Poly *f);
   void insert(monomial multiplier, const Poly *f);
 
-  bool findLeadTerm(const_term &result);
-  void removeLeadTerm();
+  virtual bool leadTerm(const_term &result);
+  virtual void removeLeadTerm();
 
   void value(Poly &result); // keep extracting lead term until done
 
-  size_t getMemoryUse() const;
+  virtual size_t getMemoryUse() const;
 
   void dump() const; // Used for debugging
 
diff --git a/src/mathicgb/HashTourReducer.cpp b/src/mathicgb/HashTourReducer.cpp
old mode 100644
new mode 100755
index c06c814..032e576
--- a/src/mathicgb/HashTourReducer.cpp
+++ b/src/mathicgb/HashTourReducer.cpp
@@ -8,7 +8,6 @@
 extern int tracingLevel;
 
 HashTourReducer::HashTourReducer(const PolyRing& ring):
-  Reducer(),
   mRing(ring),
   mLeadTerm(0, mRing.allocMonomial()),
   mLeadTermKnown(false),
@@ -99,7 +98,7 @@ void HashTourReducer::MultipleWithPos::destroy(const PolyRing& ring) {
   this->~MultipleWithPos();
 }
 
-bool HashTourReducer::findLeadTerm(const_term& result)
+bool HashTourReducer::leadTerm(const_term& result)
 {
   if (mLeadTermKnown) {
     result = mLeadTerm;
@@ -155,7 +154,7 @@ void HashTourReducer::removeLeadTerm()
 {
   if (!mLeadTermKnown) {
     const_term dummy;
-    findLeadTerm(dummy);
+    leadTerm(dummy);
   }
   mLeadTermKnown = false;
 }
@@ -183,7 +182,7 @@ void HashTourReducer::insertEntry(MultipleWithPos* entry) {
 void HashTourReducer::value(Poly &result)
 {
   const_term t;
-  while (findLeadTerm(t)) {
+  while (leadTerm(t)) {
     result.appendTerm(t.coeff, t.monom);
     removeLeadTerm();
   }
@@ -201,7 +200,9 @@ void HashTourReducer::resetReducer()
 
 size_t HashTourReducer::getMemoryUse() const
 {
-  return mQueue.getMemoryUse() +
+  return
+    TypicalReducer::getMemoryUse() +
+    mQueue.getMemoryUse() +
     mPool.getMemoryUse() +
     mHashTable.getMemoryUse();
 }
diff --git a/src/mathicgb/HashTourReducer.hpp b/src/mathicgb/HashTourReducer.hpp
old mode 100644
new mode 100755
index aea3fbb..8953679
--- a/src/mathicgb/HashTourReducer.hpp
+++ b/src/mathicgb/HashTourReducer.hpp
@@ -3,12 +3,12 @@
 #ifndef _hash_tour_reducer_h_
 #define _hash_tour_reducer_h_
 
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 #include "PolyHashTable.hpp"
 #include <mathic.h>
 #include <memtailor.h>
 
-class HashTourReducer : public Reducer {
+class HashTourReducer : public TypicalReducer {
 public:
   HashTourReducer(const PolyRing& R);
   virtual ~HashTourReducer();
@@ -20,7 +20,7 @@ public:
   virtual void insertTail(const_term multiplier, const Poly *f);
   virtual void insert(monomial multiplier, const Poly *f);
 
-  virtual bool findLeadTerm(const_term &result);
+  virtual bool leadTerm(const_term& result);
   virtual void removeLeadTerm();
 
   virtual void value(Poly &result); // keep extracting lead term until done
diff --git a/src/mathicgb/PolyGeoBucket.cpp b/src/mathicgb/PolyGeoBucket.cpp
old mode 100644
new mode 100755
index 2bd0e00..a6cf60a
--- a/src/mathicgb/PolyGeoBucket.cpp
+++ b/src/mathicgb/PolyGeoBucket.cpp
@@ -8,11 +8,8 @@ const size_t heap_size[GEOHEAP_SIZE] = {4, 16, 64, 256, 1024, 4096,
                                16777216, 67108864, 268435456,
                                1073741824};
 
-PolyGeoBucket::PolyGeoBucket(const PolyRing *R0)
-  : Reducer(),
-    R(R0),
-    top_of_heap(-1),
-    lead(-1)
+PolyGeoBucket::PolyGeoBucket(const PolyRing *R0): 
+  R(R0), top_of_heap(-1), lead(-1)
 {
   int i;
   for (i=0; i<GEOHEAP_SIZE; i++)
@@ -184,7 +181,7 @@ void PolyGeoBucket::insert(monomial multiplier, const Poly *f)
   insert(a);
 }
 
-bool PolyGeoBucket::findLeadTerm(const_term &result)
+bool PolyGeoBucket::leadTerm(const_term &result)
 {
   if (lead == -1 && !computeLeadTerm()) return false;
   result.coeff = heap[lead].first.getCoefficient();
@@ -246,7 +243,7 @@ size_t PolyGeoBucket::getMemoryUse() const
   // size includes: each poly in the heap, as well as the
   // size of the heap itself
   size_t result =
-    Reducer::getMemoryUse() +
+    TypicalReducer::getMemoryUse() +
     sizeof(heap_record) * GEOHEAP_SIZE;
   for (int i=0; i<GEOHEAP_SIZE; ++i)
     if (heap[i].poly != 0)
diff --git a/src/mathicgb/PolyGeoBucket.hpp b/src/mathicgb/PolyGeoBucket.hpp
old mode 100644
new mode 100755
index 11b3037..ea95cab
--- a/src/mathicgb/PolyGeoBucket.hpp
+++ b/src/mathicgb/PolyGeoBucket.hpp
@@ -3,11 +3,11 @@
 #ifndef _polyGeoBucket_h_
 #define _polyGeoBucket_h_
 
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 
 #define GEOHEAP_SIZE 15
 
-class PolyGeoBucket : public Reducer {
+class PolyGeoBucket : public TypicalReducer {
 public:
   PolyGeoBucket(const PolyRing *R);
   ~PolyGeoBucket();
@@ -17,8 +17,8 @@ public:
   void insertTail(const_term multiplier, const Poly *f);
   void insert(monomial multiplier, const Poly *f);
 
-  bool findLeadTerm(const_term &result);
-  void removeLeadTerm();
+  virtual bool leadTerm(const_term& result);
+  virtual void removeLeadTerm();
 
   void value(Poly &result); // keep extracting lead term until done
   void resetReducer();
diff --git a/src/mathicgb/PolyHashReducer.cpp b/src/mathicgb/PolyHashReducer.cpp
old mode 100644
new mode 100755
index 8af435b..076c916
--- a/src/mathicgb/PolyHashReducer.cpp
+++ b/src/mathicgb/PolyHashReducer.cpp
@@ -5,10 +5,8 @@
 #include "stdinc.h"
 #include "PolyHashReducer.hpp"
 
-PolyHashReducer::PolyHashReducer(const PolyRing *R0)
-  : Reducer(),
-    R_(R0),
-    H_(R0,15)
+PolyHashReducer::PolyHashReducer(const PolyRing *R0):
+  R_(R0), H_(R0,15)
 {
   f_ = new HashPoly;
   f_iter_ = f_->begin();
@@ -119,7 +117,7 @@ void PolyHashReducer::insert(monomial multiplier, const Poly *g1)
   f_iter_ = f_->begin();
 }
 
-bool PolyHashReducer::findLeadTerm(const_term &result)
+bool PolyHashReducer::leadTerm(const_term &result)
 {
   while (f_iter_ != f_->end())
     {
@@ -143,7 +141,7 @@ void PolyHashReducer::value(Poly &result)
 {
   const_term t;
   for ( ; f_iter_ != f_->end(); ++f_iter_)
-    if (findLeadTerm(t))
+    if (leadTerm(t))
       result.appendTerm(t.coeff, t.monom);
   resetReducer();
 }
@@ -151,7 +149,7 @@ void PolyHashReducer::value(Poly &result)
 size_t PolyHashReducer::getMemoryUse() const
 {
   return
-    Reducer::getMemoryUse() +
+    TypicalReducer::getMemoryUse() +
     H_.getMemoryUse() +
     f_->capacity() * sizeof(PolyHashTable::node *);
 }
@@ -160,7 +158,7 @@ void PolyHashReducer::resetReducer()
 {
   const_term t;
   for ( ; f_iter_ != f_->end(); ++f_iter_)
-    findLeadTerm(t);
+    leadTerm(t);
 
   delete f_;
   f_ = new HashPoly;
diff --git a/src/mathicgb/PolyHashReducer.hpp b/src/mathicgb/PolyHashReducer.hpp
old mode 100644
new mode 100755
index 5213371..749be06
--- a/src/mathicgb/PolyHashReducer.hpp
+++ b/src/mathicgb/PolyHashReducer.hpp
@@ -3,10 +3,10 @@
 #ifndef _polyHashReducer_h_
 #define _polyHashReducer_h_
 
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 #include "PolyHashTable.hpp"
 
-class PolyHashReducer : public Reducer {
+class PolyHashReducer : public TypicalReducer {
 public:
   PolyHashReducer(const PolyRing *R);
 
@@ -17,13 +17,13 @@ public:
   void insertTail(const_term multiplier, const Poly *f);
   void insert(monomial multiplier, const Poly *f);
 
-  bool findLeadTerm(const_term &result);
-  void removeLeadTerm();
+  virtual bool leadTerm(const_term &result);
+  virtual void removeLeadTerm();
 
   void value(Poly &result); // keep extracting lead term until done
   void dump() const;
 
-  size_t getMemoryUse() const;
+  virtual size_t getMemoryUse() const;
 
 protected:
   virtual void resetReducer();
diff --git a/src/mathicgb/PolyHeap.cpp b/src/mathicgb/PolyHeap.cpp
old mode 100644
new mode 100755
index 7ff2338..d904c06
--- a/src/mathicgb/PolyHeap.cpp
+++ b/src/mathicgb/PolyHeap.cpp
@@ -10,11 +10,8 @@ extern int tracingLevel;
 
 size_t PolyHeap::stats_static_n_compares = 0;
 
-PolyHeap::PolyHeap(const PolyRing *R_)
-  : Reducer(),
-    R(R_),
-    heapCompare(R_),
-    lead_is_computed(false)
+PolyHeap::PolyHeap(const PolyRing *R_):
+  R(R_), heapCompare(R_), lead_is_computed(false)
 {
   stats_static_n_compares = 0;
 }
@@ -125,7 +122,7 @@ bool PolyHeap::computeLeadTerm()
   return lead_is_computed; // will be false if could not compute
 }
 
-bool PolyHeap::findLeadTerm(const_term &result)
+bool PolyHeap::leadTerm(const_term &result)
 {
   if (!lead_is_computed && !computeLeadTerm()) return false;
   result = lead_term;
@@ -141,7 +138,7 @@ void PolyHeap::removeLeadTerm()
 void PolyHeap::value(Poly &result)
 {
   const_term t;
-  while (findLeadTerm(t))
+  while (leadTerm(t))
     {
       result.appendTerm(t.coeff, t.monom);
       lead_is_computed = false;
@@ -152,7 +149,7 @@ void PolyHeap::value(Poly &result)
 size_t PolyHeap::getMemoryUse() const
 {
   return
-    Reducer::getMemoryUse() +
+    TypicalReducer::getMemoryUse() +
     terms_.capacity() * sizeof(heap_term);
 }
 
diff --git a/src/mathicgb/PolyHeap.hpp b/src/mathicgb/PolyHeap.hpp
old mode 100644
new mode 100755
index edfec7f..dbfdebd
--- a/src/mathicgb/PolyHeap.hpp
+++ b/src/mathicgb/PolyHeap.hpp
@@ -3,7 +3,7 @@
 #ifndef _polyHeap_h_
 #define _polyHeap_h_
 
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 
 struct heap_term {
   monomial actual;  // multiplier * *first
@@ -19,7 +19,7 @@ public:
   bool operator()(heap_term &a, heap_term &b);
 };
 
-class PolyHeap : public Reducer {
+class PolyHeap : public TypicalReducer {
 public:
   PolyHeap(const PolyRing *R);
   ~PolyHeap() {}
@@ -29,8 +29,8 @@ public:
   void insertTail(const_term multiplier, const Poly *f);
   void insert(monomial multiplier, const Poly *f);
 
-  bool findLeadTerm(const_term &result);
-  void removeLeadTerm();
+  virtual bool leadTerm(const_term& result);
+  virtual void removeLeadTerm();
 
   void value(Poly &result); // keep extracting lead term until done
   void dump() const;
diff --git a/src/mathicgb/PolyReducer.cpp b/src/mathicgb/PolyReducer.cpp
old mode 100644
new mode 100755
index 4d3c239..a5431f1
--- a/src/mathicgb/PolyReducer.cpp
+++ b/src/mathicgb/PolyReducer.cpp
@@ -3,10 +3,8 @@
 #include "stdinc.h"
 #include "PolyReducer.hpp"
 
-PolyReducer::PolyReducer(const PolyRing *R0)
-  : Reducer(),
-    R(R0),
-    mMemUsage(0)
+PolyReducer::PolyReducer(const PolyRing *R0):
+  R(R0), mMemUsage(0)
 {
   f = new Poly(R);
   f_iter = f->begin();
@@ -68,7 +66,7 @@ void PolyReducer::insert(monomial multiplier, const Poly *g1)
     mMemUsage = fmem;
 }
 
-bool PolyReducer::findLeadTerm(const_term &result)
+bool PolyReducer::leadTerm(const_term &result)
 {
   if (f_iter != f->end())
     {
@@ -107,6 +105,10 @@ void PolyReducer::dump() const
 {
 }
 
+size_t PolyReducer::getMemoryUse() const {
+  return mMemUsage;
+}
+
 // Local Variables:
 // compile-command: "make -C .. "
 // indent-tabs-mode: nil
diff --git a/src/mathicgb/PolyReducer.hpp b/src/mathicgb/PolyReducer.hpp
old mode 100644
new mode 100755
index 23989f2..0de2c5d
--- a/src/mathicgb/PolyReducer.hpp
+++ b/src/mathicgb/PolyReducer.hpp
@@ -3,9 +3,9 @@
 #ifndef _polyReducer_h_
 #define _polyReducer_h_
 
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 
-class PolyReducer : public Reducer {
+class PolyReducer : public TypicalReducer {
 public:
   PolyReducer(const PolyRing *R);
 
@@ -16,13 +16,14 @@ public:
   void insertTail(const_term multiplier, const Poly *f);
   void insert(monomial multiplier, const Poly *f);
 
-  bool findLeadTerm(const_term &result);
-  void removeLeadTerm();
+  virtual bool leadTerm(const_term& result);
+  virtual void removeLeadTerm();
 
   void value(Poly &result); // keep extracting lead term until done
   void dump() const;
 
-  size_t getMemoryUse() const { return mMemUsage; } // this one reports high water usage
+  virtual size_t getMemoryUse() const;
+
 protected:
   void resetReducer();
 
diff --git a/src/mathicgb/Reducer.cpp b/src/mathicgb/Reducer.cpp
old mode 100644
new mode 100755
index fd1871f..3ceb388
--- a/src/mathicgb/Reducer.cpp
+++ b/src/mathicgb/Reducer.cpp
@@ -1,14 +1,11 @@
-// Copyright 2011 Michael E. Stillman
-
-#include <iostream>
 #include "stdinc.h"
 #include "Reducer.hpp"
+
 #include "PolyHeap.hpp"
 #include "PolyGeoBucket.hpp"
 #include "PolyReducer.hpp"
 #include "PolyHashReducer.hpp"
 #include "BjarkeGeobucket2.hpp"
-#include "GroebnerBasis.hpp"
 #include "TournamentReducer.hpp"
 #include "HashTourReducer.hpp"
 #include "ReducerPack.hpp"
@@ -16,11 +13,24 @@
 #include "ReducerNoDedup.hpp"
 #include "ReducerDedup.hpp"
 #include "ReducerHash.hpp"
+
 #include "ReducerHashPack.hpp"
+
+#include "GroebnerBasis.hpp"
+#include <iostream>
 #include <algorithm>
 
 extern int tracingLevel;
 
+Reducer::Reducer():
+  stats_maxsize(0),
+  stats_maxsize_live(0),
+  stats_n_inserts(0),
+  stats_n_compares(0) {}
+
+Reducer::~Reducer() {
+}
+
 std::auto_ptr<Reducer> Reducer::makeReducer(
   ReducerType type,
   PolyRing const& ring
@@ -173,19 +183,7 @@ void Reducer::displayReducerTypes(std::ostream &o)
   o << "  24   Geobucket.Hashed.Packed" << std::endl;
 }
 
-///////////////////////////
-// ReducerPack //////////
-///////////////////////////
-
-///////////////////////////
-// Reducer NoDedup/Dedup //
-///////////////////////////
-
-
-///////////////////////
-// Reducer ////////////
-/////////////////////// 
-
+// Todo: can't this be machine generated?
 Reducer::Stats::Stats():
   reductions(0),
   singularReductions(0),
@@ -193,198 +191,7 @@ Reducer::Stats::Stats():
   steps(0),
   maxSteps(0) {}
 
-Reducer::Reducer():
-  stats_maxsize(0),
-  stats_maxsize_live(0),
-  stats_n_inserts(0),
-  stats_n_compares(0) {}
-
-void Reducer::reset()
-{
-  mArena.freeAllAllocs();
-  resetReducer();
-}
-
-size_t Reducer::getMemoryUse() const {
-  return mArena.getMemoryUse();
-}
-
-Poly* Reducer::regularReduce(
-  const_monomial sig,
-  const_monomial multiple,
-  size_t basisElement,
-  const GroebnerBasis& basis)
-{
-  const PolyRing& ring = basis.ring();
-  ++mSigStats.reductions;
-
-  monomial tproduct = ring.allocMonomial(mArena);
-  monomial u = ring.allocMonomial(mArena);
-  ring.monomialMult(multiple, basis.getLeadMonomial(basisElement), tproduct);
-
-  size_t reducer = basis.regularReducer(sig, tproduct);
-  if (reducer == static_cast<size_t>(-1)) {
-    ++mSigStats.singularReductions;
-    mArena.freeAllAllocs();
-    return 0; // singular reduction: no regular top reduction possible
-  }
-
-  ring.monomialDivide(tproduct, basis.getLeadMonomial(reducer), u);
-
-  coefficient coef;
-  ring.coefficientSet(coef, 1);
-  insertTail(const_term(coef, multiple), &basis.poly(basisElement));
-
-  ASSERT(ring.coefficientIsOne(basis.getLeadCoefficient(reducer)));
-  ring.coefficientFromInt(coef, -1);
-  insertTail(const_term(coef, u), &basis.poly(reducer));
-  basis.basis().usedAsReducer(reducer);
-
-  Poly* result = new Poly(&ring);
-
-  unsigned long long steps = 2; // number of steps in this reduction
-  for (const_term v; findLeadTerm(v); ++steps) {
-    ASSERT(v.coeff != 0);
-    reducer = basis.regularReducer(sig, v.monom);
-    if (reducer == static_cast<size_t>(-1)) { // no reducer found
-      result->appendTerm(v.coeff, v.monom);
-      removeLeadTerm();
-    } else { // reduce by reducer
-      basis.basis().usedAsReducer(reducer);
-      monomial mon = ring.allocMonomial(mArena);
-      ring.monomialDivide(v.monom, basis.getLeadMonomial(reducer), mon);
-      ring.coefficientDivide(v.coeff, basis.getLeadCoefficient(reducer), coef);
-      ring.coefficientNegateTo(coef);
-      removeLeadTerm();
-      insertTail(const_term(coef, mon), &basis.poly(reducer));
-    }
-  }
-  result->makeMonic();
-
-  mSigStats.steps += steps;
-  mSigStats.maxSteps = std::max(mSigStats.maxSteps, steps);
-  if (result->isZero())
-    ++mSigStats.zeroReductions;
-
-  reset();
-  return result;
-}
-
-std::auto_ptr<Poly> Reducer::classicReduce(const Poly& poly, const PolyBasis& basis) {
-  monomial identity = basis.ring().allocMonomial(mArena);
-  basis.ring().monomialSetIdentity(identity);
-  insert(identity, &poly);
-
-  return classicReduce(basis);
-}
-
-std::auto_ptr<Poly> Reducer::classicTailReduce(const Poly& poly, const PolyBasis& basis) {
-  ASSERT(&poly.ring() == &basis.ring());
-  ASSERT(!poly.isZero());
-  term identity;
-  identity.monom = basis.ring().allocMonomial(mArena);
-  basis.ring().monomialSetIdentity(identity.monom);
-  basis.ring().coefficientSetOne(identity.coeff);
-  insertTail(identity, &poly);
-
-  std::auto_ptr<Poly> result(new Poly(&basis.ring()));
-  result->appendTerm(poly.getLeadCoefficient(), poly.getLeadMonomial());
-
-  return classicReduce(result, basis);
-}
-
-std::auto_ptr<Poly> Reducer::classicReduceSPoly(
-  const Poly& a,
-  const Poly& b,
-  const PolyBasis& basis
-) {
-  const PolyRing& ring = basis.ring();
-
-  monomial lcm = ring.allocMonomial();
-  ring.monomialLeastCommonMultiple
-    (a.getLeadMonomial(), b.getLeadMonomial(), lcm);
-
-  // insert tail of multiple of a
-  monomial multiple1 = ring.allocMonomial();
-  ring.monomialDivide(lcm, a.getLeadMonomial(), multiple1);
-  coefficient plusOne;
-  ring.coefficientSet(plusOne, 1);
-  insertTail(const_term(plusOne, multiple1), &a);
-
-  // insert tail of multiple of b
-  monomial multiple2 = ring.allocMonomial();
-  ring.monomialDivide(lcm, b.getLeadMonomial(), multiple2);
-  coefficient minusOne = plusOne;
-  ring.coefficientNegateTo(minusOne);
-  insertTail(const_term(minusOne, multiple2), &b);
-
-  std::auto_ptr<Poly> reduced = classicReduce(basis);
-  ring.freeMonomial(lcm);
-  ring.freeMonomial(multiple1);
-  ring.freeMonomial(multiple2);
-  return reduced;
-}
-
-std::auto_ptr<Poly> Reducer::classicReduce
-    (std::auto_ptr<Poly> result, const PolyBasis& basis) {
-  const PolyRing& ring = basis.ring();
-  ASSERT(&result->ring() == &ring);
-  ++mClassicStats.reductions;
-
-  if (tracingLevel > 100)
-    std::cerr << "Classic reduction begun." << std::endl;
-
-  coefficient coef;
-  unsigned long long steps = 1; // number of steps in this reduction
-  for (const_term v; findLeadTerm(v); ++steps) {
-    if (tracingLevel > 100) {
-      std::cerr << "from reducer queue: ";
-      basis.ring().monomialDisplay(std::cerr, v.monom);
-      std::cerr << std::endl;
-    }
-
-    size_t reducer = basis.divisor(v.monom);
-    if (reducer == static_cast<size_t>(-1)) { // no reducer found
-      ASSERT(result->isZero() ||
-        basis.order().signatureCompare(v.monom, result->backMonomial()) == LT);
-      result->appendTerm(v.coeff, v.monom);
-      removeLeadTerm();
-    } else { // reduce by reducer
-      basis.usedAsReducer(reducer);
-      monomial mon = ring.allocMonomial(mArena);
-      ring.monomialDivide(v.monom, basis.leadMonomial(reducer), mon);
-      ring.coefficientDivide(v.coeff, basis.leadCoefficient(reducer), coef);
-      ring.coefficientNegateTo(coef);
-      removeLeadTerm();
-      insertTail(const_term(coef, mon), &basis.poly(reducer));
-
-      if (tracingLevel > 100) {
-        std::cerr << "Reducing by basis element " << reducer << ": ";
-        basis.poly(reducer).display(std::cerr);
-        std::cerr << std::endl;
-        std::cerr << "multiplied by: " << coef << "  *  ";
-        basis.ring().monomialDisplay(std::cerr, mon);
-        std::cerr << std::endl;
-      }
-    }
-  }
-  result->makeMonic();
-
-  mClassicStats.steps += steps;
-  mClassicStats.maxSteps = std::max(mClassicStats.maxSteps, steps);
-  if (result->isZero())
-    ++mClassicStats.zeroReductions;
-
-  if (tracingLevel > 100)
-    std::cerr << "Classic reduction done." << std::endl;
-
-  reset();
-  return result;
-}
-
-std::auto_ptr<Poly> Reducer::classicReduce(const PolyBasis& basis) {
-  std::auto_ptr<Poly> result(new Poly(&basis.ring()));
-  return classicReduce(result, basis);
+void Reducer::dump() const {
 }
 
 // Local Variables:
diff --git a/src/mathicgb/Reducer.hpp b/src/mathicgb/Reducer.hpp
old mode 100644
new mode 100755
index 1a99981..2376adc
--- a/src/mathicgb/Reducer.hpp
+++ b/src/mathicgb/Reducer.hpp
@@ -17,6 +17,37 @@ todo: consider changing name of findLeadTerm to leadTerm.
 */
 class Reducer {
 public:
+  virtual ~Reducer();
+
+  // ***** Methods that do reduction
+
+  /** Clasically reduces poly by the basis elements of basis. The reduction
+    is classic in that no signatures are taken into account. */
+  virtual std::auto_ptr<Poly> classicReduce
+  (const Poly& poly, const PolyBasis& basis) = 0;
+
+  /** Clasically reduces poly by the basis elements of basis, except that the
+   lead term is not reduced. The reduction is classic in that no signatures
+   are taken into account. */
+  virtual std::auto_ptr<Poly> classicTailReduce
+  (const Poly& poly, const PolyBasis& basis) = 0;
+
+  /** Clasically reduces the S-polynomial between a and b. */
+  virtual std::auto_ptr<Poly> classicReduceSPoly
+  (const Poly& a, const Poly& b, const PolyBasis& basis) = 0;
+
+  /** Regular reduce multiple*basisElement in signature sig by the
+    basis elements in basis. Returns null (0) if multiple*basisElement
+    is not regular top reducible -- this indicates a singular
+    reduction. */
+  virtual Poly* regularReduce(
+    const_monomial sig,
+    const_monomial multiple,
+    size_t basisElement,
+    const GroebnerBasis& basis) = 0;
+
+  // ***** Kinds of reducers and creating a Reducer 
+
   enum ReducerType {
     Reducer_PolyHeap,
     Reducer_PolyGeoBucket,
@@ -48,6 +79,18 @@ public:
     Reducer_Geobucket_Hashed_Packed
   };
 
+  static std::auto_ptr<Reducer> makeReducer
+    (ReducerType t, PolyRing const& ring);
+
+  static std::auto_ptr<Reducer> makeReducerNullOnUnknown
+    (ReducerType t, PolyRing const& ring);
+
+  static ReducerType reducerType(int typ);
+  static void displayReducerTypes(std::ostream &o);
+
+
+  // ***** Obtaining statistics about the reduction process
+
   struct Stats {
     Stats();
 
@@ -69,63 +112,18 @@ public:
     unsigned long long maxSteps;
   };
 
-  Reducer();
-  virtual ~Reducer() {}
-
-  static ReducerType reducerType(int typ);
-  static void displayReducerTypes(std::ostream &o);
-
   Stats sigStats() const {return mSigStats;}
   Stats classicStats() const {return mClassicStats;}
 
-  void reset();
 
-  virtual std::string description() const = 0;
-  virtual void insertTail(const_term multiplier, const Poly *f) = 0;
-  virtual void insert(monomial multiplier, const Poly *f) = 0;
-
-  virtual bool findLeadTerm(const_term &result) = 0;
-  virtual void removeLeadTerm() = 0;
-
-  virtual void dump() const {}
+  // ***** Miscellaneous
 
+  virtual std::string description() const = 0;
   virtual size_t getMemoryUse() const = 0;
-
-  // Regular reduce multiple*basisElement in signature sig by the
-  // basis elements in basis.
-  //
-  // Returns null (0) if multiple*basisElement is not regular top
-  // reducible. This indicates a singular reduction.
-  Poly* regularReduce(
-    const_monomial sig,
-    const_monomial multiple,
-    size_t basisElement,
-    const GroebnerBasis& basis);
-
-  // Clasically reduces poly by the basis elements of basis. The reduction
-  // is classic in that no signatures are taken into account.
-  std::auto_ptr<Poly> classicReduce(const Poly& poly, const PolyBasis& basis);
-
-  // Clasically reduces poly by the basis elements of basis, except that the
-  // lead term is not reduced. The reduction is classic in that no signatures
-  // are taken into account.
-  std::auto_ptr<Poly> classicTailReduce(const Poly& poly, const PolyBasis& basis);
-
-  // Clasically reduces the S-polynomial between a and b.
-  std::auto_ptr<Poly> classicReduceSPoly
-    (const Poly& a, const Poly& b, const PolyBasis& basis);
-
-  static std::auto_ptr<Reducer> makeReducer
-    (ReducerType t, PolyRing const& ring);
-  static std::auto_ptr<Reducer> makeReducerNullOnUnknown
-    (ReducerType t, PolyRing const& ring);
+  virtual void dump() const;
 
 protected:
-  std::auto_ptr<Poly> classicReduce(const PolyBasis& basis);
-  std::auto_ptr<Poly> classicReduce
-    (std::auto_ptr<Poly> partialResult, const PolyBasis& basis);
-
-  virtual void resetReducer() = 0;
+  Reducer();
 
   size_t stats_maxsize;
   size_t stats_maxsize_live;
@@ -134,17 +132,8 @@ protected:
 
   Stats mSigStats;
   Stats mClassicStats;
-  memt::Arena mArena;
 };
 
-#if 0
-template<typename Queue, bool Deduplicate> class ReducerPacked;  // *,(0,1),1, although Dup and DeDup have 
-  // different Entry types...
-template<typename Queue, bool Deduplicate> class ReducerNotPacked;  // *,(0,1),0
-template<typename Queue> class ReducerHashedNotPacked;  // *,2,0
-template<typename Queue> class ReducerHashedPacked;  // *,2,1
-#endif
-
 #endif
 
 // Local Variables:
diff --git a/src/mathicgb/ReducerDedup.hpp b/src/mathicgb/ReducerDedup.hpp
old mode 100644
new mode 100755
index 5a91f60..46f08fa
--- a/src/mathicgb/ReducerDedup.hpp
+++ b/src/mathicgb/ReducerDedup.hpp
@@ -6,13 +6,13 @@
 #include <memtailor.h>
 #include <mathic.h>
 
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
 
 template<template<typename ConfigType> class Queue> class ReducerDedup;
 
 template<template<typename> class Queue>
-class ReducerDedup : public Reducer {
+class ReducerDedup : public TypicalReducer {
 public:
   ReducerDedup(const PolyRing& R);
   virtual ~ReducerDedup();
@@ -24,7 +24,7 @@ public:
   virtual void insertTail(const_term multiplier, const Poly *f);
   virtual void insert(monomial multiplier, const Poly *f);
 
-  virtual bool findLeadTerm(const_term &result);
+  virtual bool leadTerm(const_term &result);
   virtual void removeLeadTerm();
 
   virtual size_t getMemoryUse() const;
@@ -62,12 +62,10 @@ private:
 
 template<template<typename> class Q>
 ReducerDedup<Q>::ReducerDedup(const PolyRing& ring):
-  Reducer(),
   mRing(ring),
   mLeadTerm(0, mRing.allocMonomial()),
   mLeadTermKnown(false),
-  mQueue(Configuration(ring))
-{
+  mQueue(Configuration(ring)) {
 }
 
 template<template<typename> class Q>
@@ -128,7 +126,7 @@ void ReducerDedup<Q>::insert(monomial multiple, const Poly* poly)
 }
 
 template<template<typename> class Q>
-bool ReducerDedup<Q>::findLeadTerm(const_term& result)
+bool ReducerDedup<Q>::leadTerm(const_term& result)
 {
   if (mLeadTermKnown) {
     result = mLeadTerm;
@@ -164,7 +162,7 @@ void ReducerDedup<Q>::removeLeadTerm()
 {
   if (!mLeadTermKnown) {
     const_term dummy;
-    findLeadTerm(dummy);
+    leadTerm(dummy);
   }
   mLeadTermKnown = false;
 }
@@ -173,14 +171,14 @@ template<template<typename> class Q>
 void ReducerDedup<Q>::resetReducer()
 {
   MonomialFree freeer(mRing);
-  //mQueue.forAll(freeer);
-  //  mQueue.clear();
+  mQueue.forAll(freeer);
+  mQueue.clear();
 }
 
 template<template<typename> class Q>
 size_t ReducerDedup<Q>::getMemoryUse() const
 {
-  return mQueue.getMemoryUse();
+  return TypicalReducer::getMemoryUse() + mQueue.getMemoryUse();
 }
 
 
diff --git a/src/mathicgb/ReducerHash.hpp b/src/mathicgb/ReducerHash.hpp
old mode 100644
new mode 100755
index a08e4ca..1673ce1
--- a/src/mathicgb/ReducerHash.hpp
+++ b/src/mathicgb/ReducerHash.hpp
@@ -6,14 +6,14 @@
 #include <memtailor.h>
 #include <mathic.h>
 
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
 #include "PolyHashTable.hpp"
 
 template<template<typename ConfigType> class Queue> class ReducerHash;
 
 template<template<typename> class Queue>
-class ReducerHash : public Reducer {
+class ReducerHash : public TypicalReducer {
 public:
   ReducerHash(const PolyRing &ring);
   ~ReducerHash();
@@ -25,7 +25,7 @@ public:
   void insertTail(const_term multiplier, const Poly *f);
   void insert(monomial multiplier, const Poly *f);
 
-  bool findLeadTerm(const_term &result);
+  virtual bool leadTerm(const_term& result);
   void removeLeadTerm();
 
   size_t getMemoryUse() const;
@@ -66,13 +66,11 @@ private:
 };
 
 template<template<typename> class Q>
-ReducerHash<Q>::ReducerHash(const PolyRing &ring)
-  : Reducer(),
-    mRing(ring),
-    mHashTable(&ring,10),
-    mQueue(Configuration(ring)),
-    mNodeCount(0)
-{
+ReducerHash<Q>::ReducerHash(const PolyRing &ring):
+  mRing(ring),
+  mHashTable(&ring,10),
+  mQueue(Configuration(ring)),
+  mNodeCount(0) {
 }
 
 template<template<typename> class Q>
@@ -132,7 +130,7 @@ void ReducerHash<Q>::insert(monomial multiplier, const Poly *g1)
 }
 
 template<template<typename> class Q>
-bool ReducerHash<Q>::findLeadTerm(const_term &result)
+bool ReducerHash<Q>::leadTerm(const_term &result)
 {
   ASSERT(mNodeCount == mHashTable.getNodeCount());
   while (!mQueue.empty())
@@ -161,7 +159,7 @@ void ReducerHash<Q>::resetReducer()
 {
   ASSERT(mNodeCount == mHashTable.getNodeCount());
   const_term t;
-  while (findLeadTerm(t))
+  while (leadTerm(t))
     {
       mQueue.pop();
       mNodeCount--;
@@ -175,7 +173,8 @@ void ReducerHash<Q>::resetReducer()
 template<template<typename> class Q>
 size_t ReducerHash<Q>::getMemoryUse() const
 {
-  size_t result = mHashTable.getMemoryUse();
+  size_t result = TypicalReducer::getMemoryUse();
+  result += mHashTable.getMemoryUse();
   result += mQueue.getMemoryUse();
   return result;
 }
diff --git a/src/mathicgb/ReducerHashPack.hpp b/src/mathicgb/ReducerHashPack.hpp
old mode 100644
new mode 100755
index f7399c6..e5dd061
--- a/src/mathicgb/ReducerHashPack.hpp
+++ b/src/mathicgb/ReducerHashPack.hpp
@@ -6,14 +6,14 @@
 #include <mathic.h>
 #include <memtailor.h>
 
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
 #include "PolyHashTable.hpp"
 
 template<template<typename ConfigType> class Queue> class ReducerHashPack;
 
 template<template<typename> class Queue>
-class ReducerHashPack : public Reducer {
+class ReducerHashPack : public TypicalReducer {
 public:
   ReducerHashPack(const PolyRing& R);
   virtual ~ReducerHashPack();
@@ -25,7 +25,7 @@ public:
   virtual void insertTail(const_term multiplier, const Poly *f);
   virtual void insert(monomial multiplier, const Poly *f);
 
-  virtual bool findLeadTerm(const_term &result);
+  virtual bool leadTerm(const_term &result);
   virtual void removeLeadTerm();
 
   virtual size_t getMemoryUse() const;
@@ -73,7 +73,6 @@ private:
 
 template<template<typename> class Q>
 ReducerHashPack<Q>::ReducerHashPack(const PolyRing& ring):
-  Reducer(),
   mRing(ring),
   mLeadTerm(0, mRing.allocMonomial()),
   mLeadTermKnown(false),
@@ -173,7 +172,7 @@ void ReducerHashPack<Q>::MultipleWithPos::destroy(const PolyRing& ring) {
 }
 
 template<template<typename> class Q>
-bool ReducerHashPack<Q>::findLeadTerm(const_term& result)
+bool ReducerHashPack<Q>::leadTerm(const_term& result)
 {
   if (mLeadTermKnown) {
     result = mLeadTerm;
@@ -230,7 +229,7 @@ void ReducerHashPack<Q>::removeLeadTerm()
 {
   if (!mLeadTermKnown) {
     const_term dummy;
-    findLeadTerm(dummy);
+    leadTerm(dummy);
   }
   mLeadTermKnown = false;
 }
diff --git a/src/mathicgb/ReducerNoDedup.hpp b/src/mathicgb/ReducerNoDedup.hpp
old mode 100644
new mode 100755
index f4fdd3a..630d5d5
--- a/src/mathicgb/ReducerNoDedup.hpp
+++ b/src/mathicgb/ReducerNoDedup.hpp
@@ -6,13 +6,13 @@
 #include <memtailor.h>
 #include <mathic.h>
 
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
 
 template<template<typename ConfigType> class Queue> class ReducerNoDedup;
 
 template<template<typename> class Queue>
-class ReducerNoDedup : public Reducer {
+class ReducerNoDedup : public TypicalReducer {
 public:
   ReducerNoDedup(const PolyRing& R);
   virtual ~ReducerNoDedup();
@@ -24,7 +24,7 @@ public:
   virtual void insertTail(const_term multiplier, const Poly *f);
   virtual void insert(monomial multiplier, const Poly *f);
 
-  virtual bool findLeadTerm(const_term &result);
+  virtual bool leadTerm(const_term &result);
   virtual void removeLeadTerm();
 
   virtual size_t getMemoryUse() const;
@@ -56,12 +56,10 @@ private:
 
 template<template<typename> class Q>
 ReducerNoDedup<Q>::ReducerNoDedup(const PolyRing& ring):
-  Reducer(),
   mRing(ring),
   mLeadTerm(0, mRing.allocMonomial()),
   mLeadTermKnown(false),
-  mQueue(Configuration(ring))
-{
+  mQueue(Configuration(ring)) {
 }
 
 template<template<typename> class Q>
@@ -122,7 +120,7 @@ void ReducerNoDedup<Q>::insert(monomial multiple, const Poly* poly)
 }
 
 template<template<typename> class Q>
-bool ReducerNoDedup<Q>::findLeadTerm(const_term& result)
+bool ReducerNoDedup<Q>::leadTerm(const_term& result)
 {
   if (mLeadTermKnown) {
     result = mLeadTerm;
@@ -158,7 +156,7 @@ void ReducerNoDedup<Q>::removeLeadTerm()
 {
   if (!mLeadTermKnown) {
     const_term dummy;
-    findLeadTerm(dummy);
+    leadTerm(dummy);
   }
   mLeadTermKnown = false;
 }
@@ -174,7 +172,7 @@ void ReducerNoDedup<Q>::resetReducer()
 template<template<typename> class Q>
 size_t ReducerNoDedup<Q>::getMemoryUse() const
 {
-  return mQueue.getMemoryUse();
+  return TypicalReducer::getMemoryUse() + mQueue.getMemoryUse();
 }
 
 
diff --git a/src/mathicgb/ReducerPack.hpp b/src/mathicgb/ReducerPack.hpp
old mode 100644
new mode 100755
index 747a1d5..ae497ee
--- a/src/mathicgb/ReducerPack.hpp
+++ b/src/mathicgb/ReducerPack.hpp
@@ -6,15 +6,11 @@
 #include <memtailor.h>
 #include <mathic.h>
 
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
 
-/**
-
-todo: consider changing name of findLeadTerm to leadTerm.
-*/
 template<template<typename> class Queue>
-class ReducerPack : public Reducer {
+class ReducerPack : public TypicalReducer {
 public:
   ReducerPack(const PolyRing& ring);
   virtual ~ReducerPack();
@@ -26,7 +22,7 @@ public:
   virtual void insertTail(const_term multiplier, const Poly* f);
   virtual void insert(monomial multiplier, const Poly* f);
 
-  virtual bool findLeadTerm(const_term& result);
+  virtual bool leadTerm(const_term& result);
   virtual void removeLeadTerm();
 
   virtual size_t getMemoryUse() const;
@@ -79,7 +75,6 @@ extern int tracingLevel;
 
 template<template<typename> class Q>
 ReducerPack<Q>::ReducerPack(const PolyRing& ring):
-  Reducer(),
   mRing(ring),
   mLeadTerm(0, mRing.allocMonomial()),
   mLeadTermKnown(false),
@@ -175,7 +170,7 @@ void ReducerPack<Q>::MultipleWithPos::destroy(const PolyRing& ring) {
 }
 
 template<template<typename> class Q>
-bool ReducerPack<Q>::findLeadTerm(const_term& result)
+bool ReducerPack<Q>::leadTerm(const_term& result)
 {
   if (mLeadTermKnown) {
     result = mLeadTerm;
@@ -223,7 +218,7 @@ void ReducerPack<Q>::removeLeadTerm()
 {
   if (!mLeadTermKnown) {
     const_term dummy;
-    findLeadTerm(dummy);
+    leadTerm(dummy);
   }
   mLeadTermKnown = false;
 }
@@ -239,7 +234,10 @@ void ReducerPack<Q>::resetReducer()
 template<template<typename> class Q>
 size_t ReducerPack<Q>::getMemoryUse() const
 {
-  return mQueue.getMemoryUse() + mPool.getMemoryUse();
+  return
+    TypicalReducer::getMemoryUse() +
+    mQueue.getMemoryUse() +
+    mPool.getMemoryUse();
 }
 
 #endif
diff --git a/src/mathicgb/ReducerPackDedup.hpp b/src/mathicgb/ReducerPackDedup.hpp
old mode 100644
new mode 100755
index f011c5e..6594e93
--- a/src/mathicgb/ReducerPackDedup.hpp
+++ b/src/mathicgb/ReducerPackDedup.hpp
@@ -6,11 +6,11 @@
 #include <memtailor.h>
 #include <mathic.h>
 
-#include "Reducer.hpp"
+#include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
 
 template<template<typename> class Queue>
-class ReducerPackDedup : public Reducer {
+class ReducerPackDedup : public TypicalReducer {
 public:
   ReducerPackDedup(const PolyRing& ring);
   virtual ~ReducerPackDedup();
@@ -22,7 +22,7 @@ public:
   virtual void insertTail(const_term multiplier, const Poly* f);
   virtual void insert(monomial multiplier, const Poly* f);
 
-  virtual bool findLeadTerm(const_term& result);
+  virtual bool leadTerm(const_term& result);
   virtual void removeLeadTerm();
 
   virtual size_t getMemoryUse() const;
@@ -90,13 +90,11 @@ extern int tracingLevel;
 
 template<template<typename> class Q>
 ReducerPackDedup<Q>::ReducerPackDedup(const PolyRing& ring):
-  Reducer(),
   mRing(ring),
   mLeadTerm(0, mRing.allocMonomial()),
   mLeadTermKnown(false),
   mQueue(Configuration(ring)),
-  mPool(sizeof(MultipleWithPos))
-{
+  mPool(sizeof(MultipleWithPos)) {
 }
 
 template<template<typename> class Q>
@@ -202,7 +200,7 @@ void ReducerPackDedup<Q>::MultipleWithPos::destroy(const PolyRing& ring) {
 }
 
 template<template<typename> class Q>
-bool ReducerPackDedup<Q>::findLeadTerm(const_term& result)
+bool ReducerPackDedup<Q>::leadTerm(const_term& result)
 {
   if (mLeadTermKnown) {
     result = mLeadTerm;
@@ -279,7 +277,7 @@ void ReducerPackDedup<Q>::removeLeadTerm()
 {
   if (!mLeadTermKnown) {
     const_term dummy;
-    findLeadTerm(dummy);
+    leadTerm(dummy);
   }
   mLeadTermKnown = false;
 }
@@ -288,15 +286,17 @@ template<template<typename> class Q>
 void ReducerPackDedup<Q>::resetReducer()
 {
   MonomialFree freeer(mRing);
-  // todo: uncomment when all queues have forAll and clear.
-  //mQueue.forAll(freeer);
-  //  mQueue.clear();
+  mQueue.forAll(freeer);
+  mQueue.clear();
 }
 
 template<template<typename> class Q>
 size_t ReducerPackDedup<Q>::getMemoryUse() const
 {
-  return mQueue.getMemoryUse() + mPool.getMemoryUse();
+  return
+    TypicalReducer::getMemoryUse() +
+    mQueue.getMemoryUse() +
+    mPool.getMemoryUse();
 }
 
 #endif
diff --git a/src/mathicgb/TournamentReducer.cpp b/src/mathicgb/TournamentReducer.cpp
old mode 100644
new mode 100755
index deb85cd..a244698
--- a/src/mathicgb/TournamentReducer.cpp
+++ b/src/mathicgb/TournamentReducer.cpp
@@ -8,7 +8,6 @@
 extern int tracingLevel;
 
 TournamentReducer::TournamentReducer(const PolyRing& ring):
-  Reducer(),
   mRing(ring),
   mLeadTerm(0, mRing.allocMonomial()),
   mLeadTermKnown(false),
@@ -99,7 +98,7 @@ void TournamentReducer::MultipleWithPos::destroy(const PolyRing& ring) {
   this->~MultipleWithPos();
 }
 
-bool TournamentReducer::findLeadTerm(const_term& result)
+bool TournamentReducer::leadTerm(const_term& result)
 {
   if (mLeadTermKnown) {
     result = mLeadTerm;
@@ -145,7 +144,7 @@ void TournamentReducer::removeLeadTerm()
 {
   if (!mLeadTermKnown) {
     const_term dummy;
-    findLeadTerm(dummy);
+    leadTerm(dummy);
   }
   mLeadTermKnown = false;
 }
@@ -153,7 +152,7 @@ void TournamentReducer::removeLeadTerm()
 void TournamentReducer::value(Poly &result)
 {
   const_term t;
-  while (findLeadTerm(t)) {
+  while (leadTerm(t)) {
     result.appendTerm(t.coeff, t.monom);
     removeLeadTerm();
   }
@@ -169,7 +168,10 @@ void TournamentReducer::resetReducer()
 
 size_t TournamentReducer::getMemoryUse() const
 {
-  return mQueue.getMemoryUse() + mPool.getMemoryUse();
+  return
+    TypicalReducer::getMemoryUse() +
+    mQueue.getMemoryUse() +
+    mPool.getMemoryUse();
 }
 
 void TournamentReducer::dump() const
diff --git a/src/mathicgb/TournamentReducer.hpp b/src/mathicgb/TournamentReducer.hpp
old mode 100644
new mode 100755
index 0e39e10..5879517
--- a/src/mathicgb/TournamentReducer.hpp
+++ b/src/mathicgb/TournamentReducer.hpp
@@ -3,11 +3,11 @@
 #ifndef _tournament_reducer_h_
 #define _tournament_reducer_h_
 
+#include "TypicalReducer.hpp"
 #include <mathic.h>
 #include <memtailor.h>
-#include "Reducer.hpp"
 
-class TournamentReducer : public Reducer {
+class TournamentReducer : public TypicalReducer {
 public:
   TournamentReducer(const PolyRing& R);
   virtual ~TournamentReducer();
@@ -17,7 +17,7 @@ public:
   virtual void insertTail(const_term multiplier, const Poly *f);
   virtual void insert(monomial multiplier, const Poly *f);
 
-  virtual bool findLeadTerm(const_term &result);
+  virtual bool leadTerm(const_term &result);
   virtual void removeLeadTerm();
 
   virtual void value(Poly &result); // keep extracting lead term until done
diff --git a/src/mathicgb/TypicalReducer.cpp b/src/mathicgb/TypicalReducer.cpp
new file mode 100755
index 0000000..c04f061
--- /dev/null
+++ b/src/mathicgb/TypicalReducer.cpp
@@ -0,0 +1,195 @@
+#include "stdinc.h"
+#include "TypicalReducer.hpp"
+
+#include "GroebnerBasis.hpp"
+#include "PolyBasis.hpp"
+
+extern int tracingLevel;
+
+void TypicalReducer::reset()
+{
+  mArena.freeAllAllocs();
+  resetReducer();
+}
+
+size_t TypicalReducer::getMemoryUse() const {
+  return mArena.getMemoryUse();
+}
+
+Poly* TypicalReducer::regularReduce(
+  const_monomial sig,
+  const_monomial multiple,
+  size_t basisElement,
+  const GroebnerBasis& basis)
+{
+  const PolyRing& ring = basis.ring();
+  ++mSigStats.reductions;
+
+  monomial tproduct = ring.allocMonomial(mArena);
+  monomial u = ring.allocMonomial(mArena);
+  ring.monomialMult(multiple, basis.getLeadMonomial(basisElement), tproduct);
+
+  size_t reducer = basis.regularReducer(sig, tproduct);
+  if (reducer == static_cast<size_t>(-1)) {
+    ++mSigStats.singularReductions;
+    mArena.freeAllAllocs();
+    return 0; // singular reduction: no regular top reduction possible
+  }
+
+  ring.monomialDivide(tproduct, basis.getLeadMonomial(reducer), u);
+
+  coefficient coef;
+  ring.coefficientSet(coef, 1);
+  insertTail(const_term(coef, multiple), &basis.poly(basisElement));
+
+  ASSERT(ring.coefficientIsOne(basis.getLeadCoefficient(reducer)));
+  ring.coefficientFromInt(coef, -1);
+  insertTail(const_term(coef, u), &basis.poly(reducer));
+  basis.basis().usedAsReducer(reducer);
+
+  Poly* result = new Poly(&ring);
+
+  unsigned long long steps = 2; // number of steps in this reduction
+  for (const_term v; leadTerm(v); ++steps) {
+    ASSERT(v.coeff != 0);
+    reducer = basis.regularReducer(sig, v.monom);
+    if (reducer == static_cast<size_t>(-1)) { // no reducer found
+      result->appendTerm(v.coeff, v.monom);
+      removeLeadTerm();
+    } else { // reduce by reducer
+      basis.basis().usedAsReducer(reducer);
+      monomial mon = ring.allocMonomial(mArena);
+      ring.monomialDivide(v.monom, basis.getLeadMonomial(reducer), mon);
+      ring.coefficientDivide(v.coeff, basis.getLeadCoefficient(reducer), coef);
+      ring.coefficientNegateTo(coef);
+      removeLeadTerm();
+      insertTail(const_term(coef, mon), &basis.poly(reducer));
+    }
+  }
+  result->makeMonic();
+
+  mSigStats.steps += steps;
+  mSigStats.maxSteps = std::max(mSigStats.maxSteps, steps);
+  if (result->isZero())
+    ++mSigStats.zeroReductions;
+
+  reset();
+  return result;
+}
+
+std::auto_ptr<Poly> TypicalReducer::classicReduce(const Poly& poly, const PolyBasis& basis) {
+  monomial identity = basis.ring().allocMonomial(mArena);
+  basis.ring().monomialSetIdentity(identity);
+  insert(identity, &poly);
+
+  return classicReduce(basis);
+}
+
+std::auto_ptr<Poly> TypicalReducer::classicTailReduce(const Poly& poly, const PolyBasis& basis) {
+  ASSERT(&poly.ring() == &basis.ring());
+  ASSERT(!poly.isZero());
+  term identity;
+  identity.monom = basis.ring().allocMonomial(mArena);
+  basis.ring().monomialSetIdentity(identity.monom);
+  basis.ring().coefficientSetOne(identity.coeff);
+  insertTail(identity, &poly);
+
+  std::auto_ptr<Poly> result(new Poly(&basis.ring()));
+  result->appendTerm(poly.getLeadCoefficient(), poly.getLeadMonomial());
+
+  return classicReduce(result, basis);
+}
+
+std::auto_ptr<Poly> TypicalReducer::classicReduceSPoly(
+  const Poly& a,
+  const Poly& b,
+  const PolyBasis& basis
+) {
+  const PolyRing& ring = basis.ring();
+
+  monomial lcm = ring.allocMonomial();
+  ring.monomialLeastCommonMultiple
+    (a.getLeadMonomial(), b.getLeadMonomial(), lcm);
+
+  // insert tail of multiple of a
+  monomial multiple1 = ring.allocMonomial();
+  ring.monomialDivide(lcm, a.getLeadMonomial(), multiple1);
+  coefficient plusOne;
+  ring.coefficientSet(plusOne, 1);
+  insertTail(const_term(plusOne, multiple1), &a);
+
+  // insert tail of multiple of b
+  monomial multiple2 = ring.allocMonomial();
+  ring.monomialDivide(lcm, b.getLeadMonomial(), multiple2);
+  coefficient minusOne = plusOne;
+  ring.coefficientNegateTo(minusOne);
+  insertTail(const_term(minusOne, multiple2), &b);
+
+  std::auto_ptr<Poly> reduced = classicReduce(basis);
+  ring.freeMonomial(lcm);
+  ring.freeMonomial(multiple1);
+  ring.freeMonomial(multiple2);
+  return reduced;
+}
+
+std::auto_ptr<Poly> TypicalReducer::classicReduce
+    (std::auto_ptr<Poly> result, const PolyBasis& basis) {
+  const PolyRing& ring = basis.ring();
+  ASSERT(&result->ring() == &ring);
+  ++mClassicStats.reductions;
+
+  if (tracingLevel > 100)
+    std::cerr << "Classic reduction begun." << std::endl;
+
+  coefficient coef;
+  unsigned long long steps = 1; // number of steps in this reduction
+  for (const_term v; leadTerm(v); ++steps) {
+    if (tracingLevel > 100) {
+      std::cerr << "from reducer queue: ";
+      basis.ring().monomialDisplay(std::cerr, v.monom);
+      std::cerr << std::endl;
+    }
+
+    size_t reducer = basis.divisor(v.monom);
+    if (reducer == static_cast<size_t>(-1)) { // no reducer found
+      ASSERT(result->isZero() ||
+        basis.order().signatureCompare(v.monom, result->backMonomial()) == LT);
+      result->appendTerm(v.coeff, v.monom);
+      removeLeadTerm();
+    } else { // reduce by reducer
+      basis.usedAsReducer(reducer);
+      monomial mon = ring.allocMonomial(mArena);
+      ring.monomialDivide(v.monom, basis.leadMonomial(reducer), mon);
+      ring.coefficientDivide(v.coeff, basis.leadCoefficient(reducer), coef);
+      ring.coefficientNegateTo(coef);
+      removeLeadTerm();
+      insertTail(const_term(coef, mon), &basis.poly(reducer));
+
+      if (tracingLevel > 100) {
+        std::cerr << "Reducing by basis element " << reducer << ": ";
+        basis.poly(reducer).display(std::cerr);
+        std::cerr << std::endl;
+        std::cerr << "multiplied by: " << coef << "  *  ";
+        basis.ring().monomialDisplay(std::cerr, mon);
+        std::cerr << std::endl;
+      }
+    }
+  }
+  result->makeMonic();
+
+  mClassicStats.steps += steps;
+  mClassicStats.maxSteps = std::max(mClassicStats.maxSteps, steps);
+  if (result->isZero())
+    ++mClassicStats.zeroReductions;
+
+  if (tracingLevel > 100)
+    std::cerr << "Classic reduction done." << std::endl;
+
+  reset();
+  return result;
+}
+
+std::auto_ptr<Poly> TypicalReducer::classicReduce(const PolyBasis& basis) {
+  std::auto_ptr<Poly> result(new Poly(&basis.ring()));
+  return classicReduce(result, basis);
+}
diff --git a/src/mathicgb/TypicalReducer.hpp b/src/mathicgb/TypicalReducer.hpp
new file mode 100755
index 0000000..95bfb22
--- /dev/null
+++ b/src/mathicgb/TypicalReducer.hpp
@@ -0,0 +1,57 @@
+#ifndef MATHICGB_TYPICAL_REDUCER_GUARD
+#define MATHICGB_TYPICAL_REDUCER_GUARD
+
+#include "Reducer.hpp"
+#include "Poly.hpp"
+#include "PolyRing.hpp"
+class GroebnerBasis;
+class PolyBasis;
+
+/** Uses the template method pattern (not C++ templates) to implement
+  reduction with some steps left to sub-classes.
+
+  The template method pattern defines an algorithm that calls several
+  virtual methods. Sub-classes can then redefine those methods to
+  change some parts of the algorithm without recoding the whole
+  thing. The word "template" here has nothing to do with C++
+  templates. See http://en.wikipedia.org/wiki/Template_method_pattern
+*/
+class TypicalReducer : public Reducer {
+public:
+  virtual Poly* regularReduce(
+    const_monomial sig,
+    const_monomial multiple,
+    size_t basisElement,
+    const GroebnerBasis& basis);
+
+  virtual std::auto_ptr<Poly> classicReduce
+  (const Poly& poly, const PolyBasis& basis);
+
+  virtual std::auto_ptr<Poly> classicTailReduce
+  (const Poly& poly, const PolyBasis& basis);
+
+  virtual std::auto_ptr<Poly> classicReduceSPoly
+    (const Poly& a, const Poly& b, const PolyBasis& basis);
+
+protected:
+  // These are the methods that sub-classes define in order to carry
+  // out sub-steps in the reduction.
+  virtual void insertTail(const_term multiplier, const Poly *f) = 0;
+  virtual void insert(monomial multiplier, const Poly *f) = 0;
+  virtual bool leadTerm(const_term& result) = 0;
+  virtual void removeLeadTerm() = 0;
+  virtual void resetReducer() = 0;
+
+  virtual size_t getMemoryUse() const;
+
+  // Sub-classes can use this
+  memt::Arena mArena;
+
+private:
+  void reset();
+  std::auto_ptr<Poly> classicReduce(const PolyBasis& basis);
+  std::auto_ptr<Poly> classicReduce
+    (std::auto_ptr<Poly> partialResult, const PolyBasis& basis);
+};
+
+#endif
diff --git a/src/mathicgb/io-util.cpp b/src/mathicgb/io-util.cpp
index f3713cc..196edc5 100755
--- a/src/mathicgb/io-util.cpp
+++ b/src/mathicgb/io-util.cpp
@@ -134,28 +134,6 @@ std::string toString(Ideal *I)
   return o.str();
 }
 
-std::auto_ptr<Poly> multIdealByPolyReducer(int typ, const Ideal& ideal, const Poly& g)
-{
-  const PolyRing& R = ideal.ring();
-  std::auto_ptr<Reducer> H = Reducer::makeReducer(static_cast<Reducer::ReducerType>(typ), R);
-  for (Poly::const_iterator i = g.begin(); i != g.end(); ++i) {
-    monomial mon = R.allocMonomial();
-    R.monomialCopy(i.getMonomial(), mon);
-    int x = R.monomialGetComponent(mon);
-    R.monomialChangeComponent(mon, 0);
-    std::auto_ptr<Poly> h(ideal.getPoly(x)->copy());
-    h->multByCoefficient(i.getCoefficient());
-    H->insert(mon, h.release());
-  }
-  std::auto_ptr<Poly> result(new Poly(&R));
-  const_term t;
-  while (H->findLeadTerm(t)) {
-    result->appendTerm(t.coeff, t.monom);
-    H->removeLeadTerm();
-  }
-  return result;
-}
-
 void output(std::ostream &o, const PolyBasis &I)
 {
   for (size_t i = 0; i < I.size(); i++)
diff --git a/src/mathicgb/io-util.hpp b/src/mathicgb/io-util.hpp
old mode 100644
new mode 100755
index b6ce176..fa2df95
--- a/src/mathicgb/io-util.hpp
+++ b/src/mathicgb/io-util.hpp
@@ -29,9 +29,6 @@ std::string toString(const Poly *);
 std::auto_ptr<Ideal> idealParseFromString(std::string str);
 std::auto_ptr<Poly> polyParseFromString(const PolyRing *R, const std::string &s);
 
-std::auto_ptr<Poly> multIdealByPolyReducer(int typ, const Ideal& I, const Poly& g);
-
-
 void output(std::ostream &o, const PolyBasis &I);
 
 #endif
diff --git a/src/test/poly-test.cpp b/src/test/poly-test.cpp
index 7a950f3..119b714 100755
--- a/src/test/poly-test.cpp
+++ b/src/test/poly-test.cpp
@@ -685,6 +685,28 @@ TEST(Poly,lead) {
 // Test reducer code /////////
 //////////////////////////////
 
+std::auto_ptr<Poly> multIdealByPolyReducer(int typ, const Ideal& ideal, const Poly& g)
+{
+  const PolyRing& R = ideal.ring();
+  std::auto_ptr<Poly> poly(new Poly(&R));
+  std::auto_ptr<Reducer> H = Reducer::makeReducer(static_cast<Reducer::ReducerType>(typ), R);
+  for (Poly::const_iterator i = g.begin(); i != g.end(); ++i) {
+    monomial mon = R.allocMonomial();
+    R.monomialCopy(i.getMonomial(), mon);
+    int x = R.monomialGetComponent(mon);
+    R.monomialChangeComponent(mon, 0);
+    std::auto_ptr<Poly> h(ideal.getPoly(x)->copy());
+    h->multByTerm(i.getCoefficient(), mon);
+    R.monomialSetIdentity(mon);
+
+    size_t ncmps;
+    Poly* sum =
+      Poly::add(&R, h->begin(), h->end(), poly->begin(), poly->end(), ncmps); 
+    poly.reset(sum);
+  }
+  return poly;
+}
+
 void testPolyReducer(
   Reducer::ReducerType reducerType,
   const Ideal& ideal,
@@ -706,6 +728,7 @@ void testPolyReducer(
   EXPECT_EQ(ans, toString(h.get())) << "Reducer type " << reducerType;
 }
 
+/// @todo: this is no longer a test of a reducer. What to do this this test?
 TEST(Reducer, insert) {
   // plan: read an ideal, and another poly
   //  use this last poly to determine what to add to the heap

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mathicgb.git



More information about the debian-science-commits mailing list