1 //   Copyright (c)  2018  John Abbott, Anna Bigatti
2 
3 //   This file is part of the source of CoCoALib, the CoCoA Library.
4 
5 //   CoCoALib is free software: you can redistribute it and/or modify
6 //   it under the terms of the GNU General Public License as published by
7 //   the Free Software Foundation, either version 3 of the License, or
8 //   (at your option) any later version.
9 
10 //   CoCoALib is distributed in the hope that it will be useful,
11 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //   GNU General Public License for more details.
14 
15 //   You should have received a copy of the GNU General Public License
16 //   along with CoCoALib.  If not, see <http://www.gnu.org/licenses/>.
17 
18 
19 // Source code for RingWeylImpl
20 
21 #include "CoCoA/DistrMPolyClean.H"
22 
23 #include "CoCoA/BigIntOps.H"
24 #include "CoCoA/MatrixForOrdering.H"
25 #include "CoCoA/MatrixOps.H"
26 #include "CoCoA/OpenMath.H"
27 #include "CoCoA/PPMonoid.H"
28 #include "CoCoA/PPMonoidEv.H"
29 #include "CoCoA/PPOrdering.H"
30 #include "CoCoA/RingDistrMPolyClean.H"
31 #include "CoCoA/RingHom.H"
32 #include "CoCoA/RingWeyl.H"
33 #include "CoCoA/TmpGReductor.H"
34 #include "CoCoA/TmpUniversalInvolutiveBasisContainer.H"
35 #include "CoCoA/assert.H"
36 #include "CoCoA/convert.H"
37 #include "CoCoA/ideal.H"
38 #include "CoCoA/matrix.H"
39 #include "CoCoA/symbol.H"
40 #include "CoCoA/utils.H"
41 
42 #include <memory>
43 using std::unique_ptr;
44 #include <iostream>
45 using std::ostream;
46 using std::endl;   // just for debugging
47 //#include <vector>
48 using std::vector;
49 
50 
51 
52 namespace CoCoA
53 {
54 
55   class RingExtAlgImpl: public SparsePolyRingBase  //???? should be NCRingBase  non-commutative!!!
56   {
57 
58   public:
59     //    RingWeylImpl(const ring& CoeffRing, long NumIndets, const std::vector<long>& ElimIndets);
60     RingExtAlgImpl(const ring& CoeffRing, const std::vector<symbol>& names);
61     ~RingExtAlgImpl();
62 
63   private: // data members of RingWeyl
64     const SparsePolyRing myReprRing;
65 //    long myNumTrueIndetsValue;
66     std::unique_ptr<RingElem> myZeroPtr;  ///< Every ring stores its own zero.
67     std::unique_ptr<RingElem> myOnePtr;   ///< Every ring stores its own one.
68     std::vector<RingElem> myIndetVector;
69 //    std::vector<RingElem> myDerivationVector;
70 
71   private:
72     int myCoeffProdPP(PPMonoidElemConstRawPtr rawpp1, PPMonoidElemConstRawPtr rawpp2) const;
73 
74   public:
75     //----------------------------------------------------------------------
76     // Functions which every ring must implement:
77     //----------------------------------------------------------------------
78     virtual bool IamCommutative() const;
79     virtual bool3 IamIntegralDomain3(bool) const;
80     virtual bool IamTrueGCDDomain() const;
81     virtual ConstRefRingElem myZero() const;
82     virtual ConstRefRingElem myOne() const;
83     using RingBase::myNew;    // disable warnings of overloading
84     using RingBase::myAssign; // disable warnings of overloading
85     using PolyRingBase::myIndets;    // disable warnings of overloading
86     virtual RingElemRawPtr myNew() const;
87     virtual RingElemRawPtr myNew(const MachineInt& n) const;
88     virtual RingElemRawPtr myNew(const BigInt& N) const;
89     virtual RingElemRawPtr myNew(ConstRawPtr rawcopy) const;
90     virtual void myDelete(RawPtr rawx) const;                             // destroys x (incl all resources)
91     virtual void mySwap(RawPtr rawx, RawPtr rawy) const;                  // swap(x, y)
92     virtual void myAssign(RawPtr rawlhs, ConstRawPtr rawx) const;         // lhs = x
93     virtual void myAssign(RawPtr rawlhs, const MachineInt& n) const;      // lhs = n
94     virtual void myAssign(RawPtr rawlhs, const BigInt& N) const;          // lhs = N
95     virtual void myAssignZero(RawPtr rawlhs) const;                       // lhs = 0
96     virtual void myRecvTwinFloat(RawPtr rawlhs, ConstRawPtr rawx) const;
97     virtual void myNegate(RawPtr rawlhs, ConstRawPtr rawx) const;         // lhs = -x
98     virtual void myAdd(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const;        // lhs = x+y
99     virtual void mySub(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const;        // lhs = x-y
100     //    virtual void myMul(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const;        // lhs = x*y
101     //    virtual void myDiv(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const;        // lhs = x/y
102     virtual bool myIsDivisible(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const;// lhs = x/y, if divisible
103     virtual bool myIsInvertible(ConstRawPtr rawx) const;                                // true iff x is invertible
104     //    virtual bool myIsPrintAtom(ConstRawPtr rawx) const;
105     virtual void myGcd(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const;  // not a TrueGCDDomain
106     virtual void myPowerSmallExp(RawPtr rawlhs, ConstRawPtr rawx, long n) const;// lhs = x^n, n>1, x not -1,0,1
107     virtual void mySymbols(std::vector<symbol>& SymList) const;   // appends ring's symbols to SymList
108     virtual void myOutput(std::ostream& out, ConstRawPtr rawx) const;      // out << x
109     using PolyRingBase::myOutputSelf; // disable warnings of overloading
110     //    virtual void myOutputSelf(OpenMathOutput& OMOut) const;                // OMOut << R
myImplDetails()111     virtual std::string myImplDetails() const {return "RingWeyl";}
112     virtual void myOutput(OpenMathOutput& OMOut, ConstRawPtr rawx) const;  // OMOut << x
113     virtual bool myIsZero(ConstRawPtr rawx) const;                         // x == 0
114     virtual bool myIsOne(ConstRawPtr rawx) const;                          // x == 1
115     virtual bool myIsMinusOne(ConstRawPtr rawx) const;                     // x == -1
116     //    virtual bool myIsZeroAddMul: use default definition
117     virtual bool myIsEqual(ConstRawPtr rawx, ConstRawPtr rawy) const;      // x == y
118 
119     virtual ideal myIdealCtor(const std::vector<RingElem>& gens) const;
120 
121     virtual RingHom myCompose(const RingHom& phi, const RingHom& theta) const; // phi(theta(...))
122 
123 
124     /*----------------------------------------------------------------------
125      Member functions every PolyRing must have
126      in addition to those of RingBase.
127     ----------------------------------------------------------------------*/
128     virtual long myNumIndets() const;
129     virtual const ring& myCoeffRing() const;
130     virtual const std::vector<RingElem>& myIndets() const;
131     virtual void myIndetPower(RawPtr rawf, long var, long exp) const;
132 
133     ///@name Simple functions on polynomials
134     //@{
135     virtual long myNumTerms(ConstRawPtr rawf) const;
136     virtual bool myIsConstant(ConstRawPtr rawf) const;
137     virtual bool myIsIndet(long& index, ConstRawPtr rawf) const;
138     virtual bool myIsMonomial(ConstRawPtr rawf) const;
139     virtual long myStdDeg(ConstRawPtr rawf) const;
140     virtual long myDeg(ConstRawPtr rawf, long var) const;
141     virtual RingElemAlias myLC(ConstRawPtr rawf) const;
142     virtual void myContent(RawPtr rawcontent, ConstRawPtr rawf) const;
143     virtual void myRemoveBigContent(RawPtr rawf) const;
144     virtual void myMulByCoeff(RawPtr rawf, ConstRawPtr rawc) const; ///< WEAK EXCEPTION GUARANTEE
145     virtual bool myDivByCoeff(RawPtr rawf, ConstRawPtr rawc) const; ///< WEAK EXCEPTION GUARANTEE
146     virtual void myDeriv(RawPtr rawlhs, ConstRawPtr rawf, ConstRawPtr rawx) const; ///< lhs = deriv(f, x)
147     //@}
148 
149 //     friend const RingElem& indet(const RingWeyl& RW, long var);
150 //     friend const RingElem& derivation(const RingWeyl& RW, long var);
151 
152     virtual RingHom myHomCtor(const ring& codomain, const RingHom& CoeffHom, const std::vector<RingElem>& IndetImages) const;
153 
154     //----------------------------------------------------------------------
155     // Functions which every SparsePolyRing must implement:
156     //----------------------------------------------------------------------
157 
158     virtual const PPMonoid& myPPM() const;
159 
160     ///@name   Functions for creating/building polynomials
161     //@{
162     virtual RingElem myMonomial(ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const;
163     virtual SparsePolyIter myBeginIter(ConstRawPtr rawf) const;
164     virtual SparsePolyIter myEndIter(ConstRawPtr rawf) const;
165 
166     virtual void myPushFront(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const;
167     virtual void myPushBack(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const;
168     virtual void myPushFront(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const;
169     virtual void myPushBack(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const;
170     //@}
171 
172     ///@name Special functions on polynomials needed for implementing Buchberger's Algorithm
173     //@{
174 //     virtual void myWDeg(degree& d, ConstRawPtr rawf) const;
175 //     virtual int myCmpWDeg(ConstRawPtr rawf, ConstRawPtr rawg) const;
176     virtual ConstRefPPMonoidElem myLPP(ConstRawPtr rawf) const;
177     virtual void myMulByPP(RawPtr rawf, PPMonoidElemConstRawPtr rawpp) const;
178     virtual bool myIsZeroAddLCs(RawPtr rawf, RawPtr rawg) const; ///< f+=LM(g); g-=LM(g); assumes LPP(f)==LPP(g); returns LC(f)+LC(g)==0
179     virtual void myMoveLMToFront(RawPtr rawf, RawPtr rawg) const;
180     virtual void myMoveLMToBack(RawPtr rawf, RawPtr rawg) const;
181     virtual void myDeleteLM(RawPtr rawf) const; // ????? right interface
182     virtual void myDivLM(RawPtr rawlhs, ConstRawPtr rawf, ConstRawPtr rawg) const; ///< lhs=div(LM(f),LM(g)); assumes f!=0,g!=0
183     virtual int  myCmpLPP(ConstRawPtr rawf, ConstRawPtr rawg) const; ///< cmp(LPP(f),LPP(g)); assumes f!=0,g!=0
184     virtual void myAddClear(RawPtr rawf, RawPtr rawg) const; ///< f+=g; g=0;
185     virtual void myAppendClear(RawPtr rawf, RawPtr rawg) const; ///< f+=g; g=0; appends g to f with no checks
186 
187     virtual void myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg) const; ///<  f += LM(h)*g
188     virtual void myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg, SkipLMFlag) const; ///<  f += LM(h)*g
189     virtual void myReductionStep(RawPtr rawf, ConstRawPtr rawg) const;
190     // ??? aggiungere coefficiente
191     virtual void myReductionStepGCD(RawPtr rawf, ConstRawPtr rawg, RingElem& FScale) const;
192     // should it all be in ReductionStep ??? ANNA
193     //@}
194 
195 
196     /////////////////////
197     // >>> WARNING <<< //
198     /////////////////////
199     // DO NOT USE THE HOM CLASS -- I have not checked it
200   private: // HomImpl class: overwrite some implementations of SparsePolyRing functions
201     class HomImpl: public SparsePolyRingBase::HomImpl
202     {
203     public:
204       HomImpl(const SparsePolyRing& domain, const ring& codomain, const RingHom& CoeffHom, const std::vector<RingElem>& IndetImages);
205     };
206 
207   private: // Ideal class: overwrite some implementations of SparsePolyRing functions
208     class IdealImpl: public SparsePolyRingBase::IdealImpl
209     {
210     public:
211       IdealImpl(const SparsePolyRing& P, const std::vector<RingElem>& gens);
212       // default copy ctor is OK
213       virtual void myReduceMod(RingElemRawPtr rawr) const; // r elem of R, where I is ideal in R
214       virtual bool IhaveElem(RingElemConstRawPtr rawr) const;
215       virtual void myIntersect(const ideal&);
216       virtual void myColon(const ideal&);
217       virtual bool myDivMod(RingElemRawPtr rawlhs, RingElemConstRawPtr rawnum, RingElemConstRawPtr rawden) const; // result is true iff quot exists & is unique; if true set lhs = num/den modulo I
218 
219       virtual void myTestIsMaximal() const;
220       virtual void myTestIsPrimary() const;
221       virtual void myTestIsPrime() const;
222       virtual void myTestIsRadical() const;
223       virtual const std::vector<RingElem>& myGBasis(const CpuTimeLimit& CheckForTimeOut) const;
224     };
225   };
226 
227   //----------------------------------------------------------------------
228 
229   // std::vector<symbol> WANAMES(long NumIndets)
230   // {
231   //   vector<symbol> ans = SymbolRange("x", 0, NumIndets-1);
232   //   vector<symbol> d   = SymbolRange("d", 0, NumIndets-1);
233   //   ans.insert(ans.end(), d.begin(), d.end());
234   //   return ans;
235   // }
236 
237   // std::vector<symbol> WANAMES(const std::vector<symbol>& names)
238   // {
239   //   vector<symbol> ans=names;
240   //   const long NumNames = len(names);
241   //   ans.reserve(2*NumNames);
242   //   for ( long i=0 ; i < NumNames ; ++i )
243   //   {
244   //     if ( NumSubscripts(names[i])!=0 )
245   //       CoCoA_THROW_ERROR("names must have no subscripts",
246   //                   "WANAMES(const vector<symbol>& names)");
247   //     ans.push_back(symbol("d"+head(names[i])));
248   //   }
249   //   return ans;
250   // }
251 
252 
RingExtAlgImpl(const ring & CoeffRing,const std::vector<symbol> & VarNames)253   RingExtAlgImpl::RingExtAlgImpl(const ring& CoeffRing, const std::vector<symbol>& VarNames):
254     myReprRing(NewPolyRing(CoeffRing, VarNames))
255 //    myNumTrueIndetsValue(len(WANames)/2)
256   {
257 //    const long NumTrueIndets=len(WANames)/2;
258     CoCoA_ASSERT(IsCommutative(CoeffRing));
259     myRefCountInc();  // this is needed for exception cleanliness, in case one of the lines below throws
260     myZeroPtr.reset(new RingElem(ring(this)));
261     myOnePtr.reset(new RingElem(ring(this), 1));
262     myIndetVector.resize(NumIndets(myReprRing), *myZeroPtr);
263     //    myDerivationVector.resize(myNumIndetsValue, *myZeroPtr);
264     //    for (long i=0; i < myNumIndetsValue; ++i)
265 //    myIndetVector.resize(NumIndets(myReprRing), *myZeroPtr);
266     vector<long> expv(NumIndets(myReprRing));
267 
268     for (long i=0; i < NumIndets(myReprRing); ++i)
269     {
270       expv[i] = 1;
271       myPushFront(raw(myIndetVector[i]), raw(one(CoeffRing)), expv);
272       expv[i] = 0;
273     }
274     myRefCountZero(); // otherwise it is 2 + NumIndets and won't be destroyed
275   }
276 
277 
~RingExtAlgImpl()278   RingExtAlgImpl::~RingExtAlgImpl()
279   {}
280 
281 
282 //   inline const RingExtAlgImpl* RingWeyl::operator->() const
283 //   {
284 //     return static_cast<const RingExtAlgImpl*>(myRingPtr());
285 //   }
286 
287 
288 //   inline WeylPoly& ring_weyl::AsWeylPoly(RawPtr rawx) const
289 //   {
290 //     return *x.WeylPolyPtr;
291 //     //    return *static_cast<ring_weyl::WeylPoly*>(x.WeylPolyPtr);
292 //   }
293 
294 
295 //   inline const WeylPoly& ring_weyl::AsWeylPoly(ConstRawPtr rawx) const
296 //   {
297 //     return *x.WeylPolyPtr;
298 //     //    return *static_cast<ring_weyl::WeylPoly*>(x.WeylPolyPtr);
299 //   }
300 
301 
302 //   RingWeyl::RingWeyl(const RingExtAlgImpl* RingPtr):
303 //       SparsePolyRing(RingPtr)
304 //   {}
305 
306 
307   //----------------------------------------------------------------------
308   // Functions which every ring must implement:
309   //----------------------------------------------------------------------
310 
IamCommutative()311   bool RingExtAlgImpl::IamCommutative() const
312   {
313     return myNumIndets() == 0; // we are assuming the coeff ring is commutative
314   }
315 
316 
IamIntegralDomain3(bool QuickMode)317   bool3 RingExtAlgImpl::IamIntegralDomain3(bool QuickMode) const
318   {
319     if (myNumIndets() > 0) return false3;
320     return myReprRing->IamIntegralDomain3(QuickMode); //??? I think this is right
321   }
322 
323 
IamTrueGCDDomain()324   bool RingExtAlgImpl::IamTrueGCDDomain() const
325   {
326     return false; // I have no clue how to compute GCDs even if they do exist
327   }
328 
329 
myZero()330   ConstRefRingElem RingExtAlgImpl::myZero() const
331   {
332     return *myZeroPtr;
333   }
334 
335 
myOne()336   ConstRefRingElem RingExtAlgImpl::myOne() const
337   {
338     return *myOnePtr;
339   }
340 
341 
myNew()342   RingElemRawPtr RingExtAlgImpl::myNew() const
343   {
344     return myReprRing->myNew();
345   }
346 
347 
myNew(const MachineInt & n)348   RingElemRawPtr RingExtAlgImpl::myNew(const MachineInt& n) const
349   {
350     return myReprRing->myNew(n);
351   }
352 
353 
myNew(const BigInt & N)354   RingElemRawPtr RingExtAlgImpl::myNew(const BigInt& N) const
355   {
356     return myReprRing->myNew(N);
357   }
358 
359 
myNew(ConstRawPtr rawcopy)360   RingElemRawPtr RingExtAlgImpl::myNew(ConstRawPtr rawcopy) const
361   {
362     return myReprRing->myNew(rawcopy);
363   }
364 
365 
myDelete(RawPtr rawx)366   void RingExtAlgImpl::myDelete(RawPtr rawx) const
367   {
368     myReprRing->myDelete(rawx);
369   }
370 
371 
mySwap(RawPtr rawx,RawPtr rawy)372   void RingExtAlgImpl::mySwap(RawPtr rawx, RawPtr rawy) const
373   {
374     myReprRing->mySwap(rawx, rawy);
375   }
376 
377 
myAssign(RawPtr rawlhs,ConstRawPtr rawx)378   void RingExtAlgImpl::myAssign(RawPtr rawlhs, ConstRawPtr rawx) const
379   {
380     myReprRing->myAssign(rawlhs, rawx);
381   }
382 
383 
myAssign(RawPtr rawlhs,const MachineInt & n)384   void RingExtAlgImpl::myAssign(RawPtr rawlhs, const MachineInt& n) const
385   {
386     myReprRing->myAssign(rawlhs, n);
387   }
388 
389 
myAssign(RawPtr rawlhs,const BigInt & N)390   void RingExtAlgImpl::myAssign(RawPtr rawlhs, const BigInt& N) const
391   {
392     myReprRing->myAssign(rawlhs, N);
393   }
394 
395 
myAssignZero(RawPtr rawlhs)396   void RingExtAlgImpl::myAssignZero(RawPtr rawlhs) const
397   {
398     myReprRing->myAssignZero(rawlhs);
399   }
400 
401 
myRecvTwinFloat(RawPtr rawlhs,ConstRawPtr rawx)402   void RingExtAlgImpl::myRecvTwinFloat(RawPtr rawlhs, ConstRawPtr rawx) const
403   {
404     CoCoA_ASSERT(!IsExact(myReprRing));
405     myReprRing->myRecvTwinFloat(rawlhs, rawx);
406   }
407 
myNegate(RawPtr rawlhs,ConstRawPtr rawx)408   void RingExtAlgImpl::myNegate(RawPtr rawlhs, ConstRawPtr rawx) const
409   {
410     myReprRing->myNegate(rawlhs, rawx);
411   }
412 
413 
myAdd(RawPtr rawlhs,ConstRawPtr rawx,ConstRawPtr rawy)414   void RingExtAlgImpl::myAdd(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const
415   {
416     myReprRing->myAdd(rawlhs, rawx, rawy);
417   }
418 
419 
mySub(RawPtr rawlhs,ConstRawPtr rawx,ConstRawPtr rawy)420   void RingExtAlgImpl::mySub(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const
421   {
422     myReprRing->mySub(rawlhs, rawx, rawy);
423   }
424 
425 
426   //??? ANNA: I believe the general implementation in SparsePolyRing works for RingWeyl
427 //   void RingExtAlgImpl::myMul(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const
428 //   {
429 //     if (myReprRing->myIsZero(x) || myReprRing->myIsZero(y)) { myReprRing->myAssignZero(rawlhs); return; }
430 //     RingElem f(myReprRing);
431 //     myReprRing->myAssign(raw(f), rawx);
432 //     ConstRefRingElem g(myReprRing, rawy);
433 // //    std::clog<<"f="<<f<<std::endl;
434 // //    std::clog<<"g="<<g<<std::endl;
435 //     RingElem ans(myReprRing); // compute answer in a temporary for exception safety
436 //     while (!CoCoA::IsZero(f))
437 //     {
438 //       RingElem LMf(myReprRing);
439 //       myMoveLMToFront(raw(LMf), raw(f));
440 //       PPMonoidElem LPPf = LPP(LMf);
441 //       RingElem LMfg(g);
442 //       myMulByPP(raw(LMfg), raw(LPPf));
443 // //      std::clog<<"LMf="<<LMf<<std::endl;
444 // //      std::clog<<"LMfg="<<LMfg<<std::endl;
445 //       myReprRing->myMulByCoeff(raw(LMfg), raw(LC(LMf))); //????UGLY!!!!
446 //       ans += LMfg;
447 //     }
448 //     mySwap(rawlhs, raw(ans));// really an assignment -- is this safe????
449 //   }
450 
451 
452 //   void RingExtAlgImpl::myDiv(RawPtr /*rawlhs*/, ConstRawPtr /*rawx*/, ConstRawPtr /*rawy*/) const
453 //   {
454 //     CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::myDiv");
455 //     return;//???
456 // //     bool OK;                                            // Two lines o/w compiler complains that
457 // //     OK = CoCoA::WeylDiv(AsDMPI(rawlhs), AsDMPI(x), AsDMPI(y)); // OK is unused when debugging is off.
458 // //     CoCoA_ASSERT(OK);
459 //   }
460 
461 
myIsDivisible(RawPtr,ConstRawPtr,ConstRawPtr)462   bool RingExtAlgImpl::myIsDivisible(RawPtr /*rawlhs*/, ConstRawPtr /*rawx*/, ConstRawPtr /*rawy*/) const
463   {
464     CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::myIsDivisible");
465     return false;
466 //    return CoCoA::WeylDiv(AsDMPI(rawlhs), AsDMPI(x), AsDMPI(y));
467   }
468 
469 
myIsInvertible(ConstRawPtr)470   bool RingExtAlgImpl::myIsInvertible(ConstRawPtr /*rawx*/) const
471   {
472     CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::myIsInvertible");  //??? d[1]*x[1] = 1
473     return false;//???
474   }
475 
476 
477 //   bool RingExtAlgImpl::myIsPrintAtom(ConstRawPtr rawx) const
478 //   {
479 //     return myReprRing->myIsPrintAtom(rawx);  //??? default always false
480 //   }
481 
482 
myGcd(RawPtr,ConstRawPtr,ConstRawPtr)483   void RingExtAlgImpl::myGcd(RawPtr /*rawlhs*/, ConstRawPtr /*rawx*/, ConstRawPtr /*rawy*/) const
484   {
485     CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::myGcd");
486   }
487 
488 
myPowerSmallExp(RawPtr rawlhs,ConstRawPtr rawx,long n)489   void RingExtAlgImpl::myPowerSmallExp(RawPtr rawlhs, ConstRawPtr rawx, long n) const
490   {
491     // Assert that we have a genuinely non-trivial case.
492     CoCoA_ASSERT(n > 1);
493     CoCoA_ASSERT(!myIsZero(rawx) && !myIsOne(rawx) && !myIsMinusOne(rawx));
494 
495     mySequentialPower(rawlhs, rawx, n); // probably better than myBinaryPower, I guess.
496   }
497 
498 
mySymbols(std::vector<symbol> & SymList)499   void RingExtAlgImpl::mySymbols(std::vector<symbol>& SymList) const
500 { //??? ANNA: which symbols are in a RingExtAlgImpl??
501     myReprRing->mySymbols(SymList);
502   }
503 
504 
myOutput(std::ostream & out,ConstRawPtr rawx)505   void RingExtAlgImpl::myOutput(std::ostream& out, ConstRawPtr rawx) const
506   {
507     if (!out) return;  // short-cut for bad ostreams
508     myReprRing->myOutput(out, rawx);
509   }
510 
511 
512 //   void RingExtAlgImpl::myOutputSelf(std::ostream& out) const
513 //   {
514 //     out << "RingExtAlgImpl(" << CoeffRing(myReprRing) << ", " << NumIndets(myReprRing) << ")";
515 //     //?????????  WHAT ABOUT THE ORDERING AND GRADING????
516 //   }
517 
518 
519 //   void RingExtAlgImpl::myOutputSelf(OpenMathOutput& OMOut) const
520 //   {
521 //     OMOut->mySendApplyStart();
522 //     OMOut << OpenMathSymbol("polyd", "poly_ring_d"); //??? weyl?
523 //     OMOut << CoeffRing(myReprRing);
524 //     OMOut << NumIndets(myReprRing); //???? losing the ordering and grading info here!!!
525 //     OMOut->mySendApplyEnd();
526 //   }
527 
528 
myOutput(OpenMathOutput & OMOut,ConstRawPtr rawx)529   void RingExtAlgImpl::myOutput(OpenMathOutput& OMOut, ConstRawPtr rawx) const
530   {
531     myReprRing->myOutput(OMOut, rawx);
532   }
533 
534 
myIsZero(ConstRawPtr rawx)535   bool RingExtAlgImpl::myIsZero(ConstRawPtr rawx) const
536   {
537     return myReprRing->myIsZero(rawx);
538   }
539 
540 
myIsOne(ConstRawPtr rawx)541   bool RingExtAlgImpl::myIsOne(ConstRawPtr rawx) const
542   {
543     return myReprRing->myIsOne(rawx);
544   }
545 
546 
myIsMinusOne(ConstRawPtr rawx)547   bool RingExtAlgImpl::myIsMinusOne(ConstRawPtr rawx) const
548   {
549     return myReprRing->myIsMinusOne(rawx);
550   }
551 
552 
553   // bool RingExtAlgImpl::myIsZeroAddMul(RawPtr rawlhs, ConstRawPtr rawy, ConstRawPtr rawz) const; // use default definition
554 
555 
myIsEqual(ConstRawPtr rawx,ConstRawPtr rawy)556   bool RingExtAlgImpl::myIsEqual(ConstRawPtr rawx, ConstRawPtr rawy) const
557   {
558     return myReprRing->myIsEqual(rawx, rawy);
559   }
560 
561 
myCompose(const RingHom &,const RingHom & theta)562   RingHom RingExtAlgImpl::myCompose(const RingHom& /*phi*/, const RingHom& theta) const
563   {
564     CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::compose");
565     return theta; // just to keep compiler quiet
566   }
567 
568   //----------------------------------------------------------------------
569 
570 //   long NumIndets(const RingWeyl& RW)
571 //   {
572 //     return RW->myNumIndets();
573 //   }
574 
575   //----------------------------------------------------------------------
576   // Functions which every PolyRing must implement
577   //----------------------------------------------------------------------
578 
myNumIndets()579   long RingExtAlgImpl::myNumIndets() const
580   {
581     return myReprRing->myNumIndets();
582   }
583 
584 
myCoeffRing()585   const ring& RingExtAlgImpl::myCoeffRing() const
586   {
587     return myReprRing->myCoeffRing();
588   }
589 
590 
myIndets()591   const std::vector<RingElem>& RingExtAlgImpl::myIndets() const
592   {
593     return myIndetVector;
594   }
595 
596 
myIndetPower(RawPtr rawf,long var,long exp)597   void RingExtAlgImpl::myIndetPower(RawPtr rawf, long var, long exp) const
598   {
599     myReprRing->myIndetPower(rawf, var, exp);
600   }
601 
602 
myNumTerms(ConstRawPtr rawx)603   long RingExtAlgImpl::myNumTerms(ConstRawPtr rawx) const
604   {
605     return myReprRing->myNumTerms(rawx);
606   }
607 
608 
myIsConstant(ConstRawPtr rawf)609   bool RingExtAlgImpl::myIsConstant(ConstRawPtr rawf) const
610   {
611     return myReprRing->myIsConstant(rawf);
612   }
613 
614 
myIsIndet(long & index,ConstRawPtr rawf)615   bool RingExtAlgImpl::myIsIndet(long& index, ConstRawPtr rawf) const
616   {
617     return myReprRing->myIsIndet(index, rawf);
618   }
619 
620 
myIsMonomial(ConstRawPtr rawf)621   bool RingExtAlgImpl::myIsMonomial(ConstRawPtr rawf) const
622   {
623     return myReprRing->myIsMonomial(rawf);
624   }
625 
626 
myStdDeg(ConstRawPtr rawf)627   long RingExtAlgImpl::myStdDeg(ConstRawPtr rawf) const
628   {
629     return myReprRing->myStdDeg(rawf);
630   }
631 
632 
myDeg(ConstRawPtr rawf,long var)633   long RingExtAlgImpl::myDeg(ConstRawPtr rawf, long var) const
634   {
635     CoCoA_ASSERT(!myIsZero(rawf));
636     return myReprRing->myDeg(rawf, var);//????????
637   }
638 
639 
myLC(ConstRawPtr rawf)640   RingElemAlias RingExtAlgImpl::myLC(ConstRawPtr rawf) const
641   {
642     CoCoA_ASSERT(!myIsZero(rawf));
643     return myReprRing->myLC(rawf);//???????????
644   }
645 
646 
myContent(RawPtr rawdest,ConstRawPtr rawf)647   void RingExtAlgImpl::myContent(RawPtr rawdest, ConstRawPtr rawf) const
648   {
649     myReprRing->myContent(rawdest, rawf);
650   }
651 
652 
myRemoveBigContent(RawPtr rawf)653   void RingExtAlgImpl::myRemoveBigContent(RawPtr rawf) const
654   {
655     myReprRing->myRemoveBigContent(rawf);
656   }
657 
658 
myMulByCoeff(RawPtr rawf,ConstRawPtr rawc)659   void RingExtAlgImpl::myMulByCoeff(RawPtr rawf, ConstRawPtr rawc) const // WEAK EXCEPTION GUARANTEE
660   {
661     myReprRing->myMulByCoeff(rawf, rawc);
662   }
663 
664 
myDivByCoeff(RawPtr rawf,ConstRawPtr rawc)665   bool RingExtAlgImpl::myDivByCoeff(RawPtr rawf, ConstRawPtr rawc) const // WEAK EXCEPTION GUARANTEE
666   {
667     return myReprRing->myDivByCoeff(rawf, rawc);
668   }
669 
670 
myDeriv(RawPtr,ConstRawPtr,ConstRawPtr)671   void RingExtAlgImpl::myDeriv(RawPtr /*rawlhs*/, ConstRawPtr /*rawf*/, ConstRawPtr /*rawx*/) const
672   {
673     CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::myDeriv");
674   }
675 
676 
myHomCtor(const ring &,const RingHom &,const std::vector<RingElem> &)677   RingHom RingExtAlgImpl::myHomCtor(const ring& /*codomain*/, const RingHom& /*CoeffHom*/, const std::vector<RingElem>& /*IndetImages*/) const
678   {
679     CoCoA_THROW_ERROR("DOES NOT EXIST", "RingExtAlgImpl::myHomCtor");
680     return IdentityHom(myReprRing); // just to keep compiler quiet
681   }
682 
683 
684 
685   //----------------------------------------------------------------------
686   // Functions which every SparsePolyRing must implement:
687   //----------------------------------------------------------------------
688 
myPPM()689   const PPMonoid& RingExtAlgImpl::myPPM() const
690   {
691     return myReprRing->myPPM();
692   }
693 
694 
myMonomial(ConstRawPtr rawc,PPMonoidElemConstRawPtr rawpp)695   RingElem RingExtAlgImpl::myMonomial(ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const
696   {
697     RingElem ans(ring(this));
698     RingElem m = myReprRing->myMonomial(rawc, rawpp);
699     mySwap(raw(ans), raw(m));
700     return ans;
701   }
702 
703 
myBeginIter(ConstRawPtr rawf)704   SparsePolyIter RingExtAlgImpl::myBeginIter(ConstRawPtr rawf) const
705   {
706     return myReprRing->myBeginIter(rawf);
707   }
708 
709 
myEndIter(ConstRawPtr rawf)710   SparsePolyIter RingExtAlgImpl::myEndIter(ConstRawPtr rawf) const
711   {
712     return myReprRing->myEndIter(rawf);
713   }
714 
715 
myPushFront(RawPtr rawf,ConstRawPtr rawc,const std::vector<long> & expv)716   void RingExtAlgImpl::myPushFront(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const
717   {
718     myReprRing->myPushFront(rawf, rawc, expv);//???  how many elements does expv have???
719   }
720 
721 
myPushBack(RawPtr rawf,ConstRawPtr rawc,const std::vector<long> & expv)722   void RingExtAlgImpl::myPushBack(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const
723   {
724     myReprRing->myPushBack(rawf, rawc, expv);//???  how many elements does expv have???
725   }
726 
727 
myPushFront(RawPtr rawf,ConstRawPtr rawc,PPMonoidElemConstRawPtr rawpp)728   void RingExtAlgImpl::myPushFront(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const
729   {
730     myReprRing->myPushFront(rawf, rawc, rawpp);
731   }
732 
733 
myPushBack(RawPtr rawf,ConstRawPtr rawc,PPMonoidElemConstRawPtr rawpp)734   void RingExtAlgImpl::myPushBack(RawPtr rawf, ConstRawPtr rawc, PPMonoidElemConstRawPtr rawpp) const
735   {
736     myReprRing->myPushBack(rawf, rawc, rawpp);
737   }
738 
739 
myLPP(ConstRawPtr rawf)740   ConstRefPPMonoidElem RingExtAlgImpl::myLPP(ConstRawPtr rawf) const
741   {
742     CoCoA_ASSERT(!myIsZero(rawf));
743     return myReprRing->myLPP(rawf);
744   }
745 
746 
myCoeffProdPP(PPMonoidElemConstRawPtr rawpp1,PPMonoidElemConstRawPtr rawpp2)747     int RingExtAlgImpl::myCoeffProdPP(PPMonoidElemConstRawPtr rawpp1, PPMonoidElemConstRawPtr rawpp2) const
748       {
749         const PPMonoid& PParith = PPM(myReprRing);
750         if (!PParith->myIsCoprime(rawpp1, rawpp2)) return 0;
751         const int n = NumIndets(PParith);
752         vector<long> expv(n);
753         PParith->myExponents(expv, rawpp1);
754         vector<long> Rcount(n);
755         for (int i=0; i < n; ++i)
756         {
757           if (expv[i] == 0) continue;
758           for (int j=0; j <= i; ++j)
759             ++Rcount[j];
760         }
761         PParith->myExponents(expv, rawpp2);
762         int count = 0;
763         for (int i=0; i < n; ++i)
764           if (expv[i] > 0)
765             count += Rcount[i];
766         if ((count&1) == 1) return -1;
767         return 1;
768       }
769 
770   // f = pp*f  NOTE: pp is on the LEFT and f is on the RIGHT
myMulByPP(RawPtr rawf,PPMonoidElemConstRawPtr rawpp)771   void RingExtAlgImpl::myMulByPP(RawPtr rawf, PPMonoidElemConstRawPtr rawpp) const
772   {
773     if (myReprRing->myIsZero(rawf)) return;
774 
775     RingElem g(myReprRing);
776 //    myReprRing->myAssign(raw(g), rawf);
777 //???    std::clog<<"Alias(f)="<<g<<std::endl;
778 //    const long nvars = myNumIndets();
779     const PPMonoid& PParith = PPM(myReprRing);
780     PPMonoidElem ProdPP(PParith);
781     for (SparsePolyIter it = myReprRing->myBeginIter(rawf); !IsEnded(it); ++it)
782     {
783       const int PPcoeff = myCoeffProdPP(rawpp, raw(PP(it)));
784       if (PPcoeff == 0) continue;
785       const RingElem c = PPcoeff*coeff(it);
786       PParith->myMul(raw(ProdPP), rawpp, raw(PP(it)));
787       PushBack(g, c, ProdPP);
788     }
789 
790     mySwap(rawf, raw(g));// really an assignment -- is this safe????
791   }
792 
793 
myIsZeroAddLCs(RawPtr rawf,RawPtr rawg)794   bool RingExtAlgImpl::myIsZeroAddLCs(RawPtr rawf, RawPtr rawg) const
795   {
796     return myReprRing->myIsZeroAddLCs(rawf, rawg);
797   }
798 
799 
myMoveLMToFront(RawPtr rawf,RawPtr rawg)800   void RingExtAlgImpl::myMoveLMToFront(RawPtr rawf, RawPtr rawg) const
801   {
802     CoCoA_ASSERT(!myIsZero(rawg));
803     myReprRing->myMoveLMToFront(rawf, rawg);
804   }
805 
806 
myMoveLMToBack(RawPtr rawf,RawPtr rawg)807   void RingExtAlgImpl::myMoveLMToBack(RawPtr rawf, RawPtr rawg) const
808   {
809     CoCoA_ASSERT(!myIsZero(rawg));
810     myReprRing->myMoveLMToBack(rawf, rawg);
811   }
812 
813 
myDeleteLM(RawPtr rawf)814   void RingExtAlgImpl::myDeleteLM(RawPtr rawf) const
815   {
816     CoCoA_ASSERT(!myIsZero(rawf));
817     myReprRing->myDeleteLM(rawf);
818   }
819 
820 
myDivLM(RawPtr rawlhs,ConstRawPtr rawf,ConstRawPtr rawg)821   void RingExtAlgImpl::myDivLM(RawPtr rawlhs, ConstRawPtr rawf, ConstRawPtr rawg) const
822   {
823     CoCoA_ASSERT(!myIsZero(rawf) && !myIsZero(rawg));
824     myReprRing->myDivLM(rawlhs, rawf, rawg);
825   }
826 
827 
myCmpLPP(ConstRawPtr rawf,ConstRawPtr rawg)828   int  RingExtAlgImpl::myCmpLPP(ConstRawPtr rawf, ConstRawPtr rawg) const
829   {
830     CoCoA_ASSERT(!myIsZero(rawf) && !myIsZero(rawg));
831     return myReprRing->myCmpLPP(rawf, rawg);
832   }
833 
834 
myAddClear(RawPtr rawf,RawPtr rawg)835   void RingExtAlgImpl::myAddClear(RawPtr rawf, RawPtr rawg) const
836   {
837     myReprRing->myAddClear(rawf, rawg);
838   }
839 
840 
myAppendClear(RawPtr rawf,RawPtr rawg)841   void RingExtAlgImpl::myAppendClear(RawPtr rawf, RawPtr rawg) const
842   {
843     myReprRing->myAppendClear(rawf, rawg);
844   }
845 
846 
myAddMulLM(RawPtr rawf,ConstRawPtr rawh,ConstRawPtr rawg)847   void RingExtAlgImpl::myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg) const //???? delete me???
848   {
849     myAddMulLM(rawf, rawh, rawg, DontSkipLMg);
850   }
851 
852 
myAddMulLM(RawPtr rawf,ConstRawPtr rawh,ConstRawPtr rawg,SkipLMFlag skip)853   void RingExtAlgImpl::myAddMulLM(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg, SkipLMFlag skip) const
854   {
855     CoCoA_ASSERT(myNumTerms(rawh)==1);
856     RingElem prod(ring(this), myNew(rawg));
857     myMulByCoeff(raw(prod), raw(myLC(rawh)));
858     myMulByPP(raw(prod), raw(myLPP(rawh)));
859     myReprRing->myAddMulLM(rawf, raw(myOne()), raw(prod), skip);
860   }
861 
862 
myReductionStep(RawPtr rawf,ConstRawPtr rawg)863   void RingExtAlgImpl::myReductionStep(RawPtr rawf, ConstRawPtr rawg) const
864   {
865     PPMonoidElem q = myLPP(rawf)/myLPP(rawg);
866     RingElem c = -myLC(rawf)/myLC(rawg); //    RingElem c = -LC(repf)/LC(repg);
867     RingElem qg(myReprRing); myReprRing->myAssign(raw(qg), rawg); // qg is copy of rawg
868     myMulByPP(raw(qg), raw(q));  // qg = q * g  //??? should we use myAddMul
869     myMulByCoeff(raw(qg), raw(c));
870     myAdd(rawf, rawf, raw(qg)); //  repf += qg;
871 
872 
873 /*
874 //???    ConstRefRingElem aliasg(ring(this), rawg);
875 //???    std::clog<<"g="<<aliasg<<std::endl;
876     PPMonoidElem LPPf = myReprRing->myLPP(f);
877     PPMonoidElem LPPg = myReprRing->myLPP(g);
878     PPMonoidElem q = LPPf/LPPg; // quotient exists
879     RingElem LCf(CoeffRing(myReprRing));
880     CoeffRing(myReprRing)->myAssign(raw(LCf), myReprRing->myRawLC(f));
881     RingElem LCg(CoeffRing(myReprRing));
882     CoeffRing(myReprRing)->myAssign(raw(LCg), myReprRing->myRawLC(g));
883     RingElem c = -LCf/LCg;
884 ///    RingElem c(myCoeffRing());
885 ///    myCoeffRing()->myDiv(raw(c), myReprRing->myRawLC(f), myReprRing->myRawLC(g));
886     RingElem g1(myReprRing);
887 //???    std::clog<<"ReductionStep: q="<<q<<std::endl;
888 //???    std::clog<<"ReductionStep: c="<<c<<std::endl;
889     myReprRing->myAssign(raw(g1), rawg);
890 //???    std::clog<<"ReductionStep: g="<<g1<<std::endl;
891     myMul(raw(g1), raw(q));  // g1 = q*g;
892     myReprRing->myMulByCoeff(raw(g1), raw(c));
893 //???    std::clog<<"ReductionStep: prod="<<g1<<std::endl;
894     {
895 //???      ConstRefRingElem aliasf(ring(this),f);
896 //???      std::clog<<"REDUCING f="<<aliasf<<std::endl;
897 //???      std::clog<<"REDN by  g="<<aliasg<<std::endl;
898       myAdd(f, f, raw(g1));
899 //???    std::clog<<"RESULT is  "<<aliasf<<std::endl<<std::endl;
900     }
901 */
902   }
903 
904 
myReductionStepGCD(RawPtr,ConstRawPtr,RingElem &)905   void RingExtAlgImpl::myReductionStepGCD(RawPtr /*rawf*/, ConstRawPtr /*rawg*/, RingElem& /*fscale*/) const
906   {
907     CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::ReductionStepGCD");
908   }
909 
910 
911   //---------------------------------------------------------------------------
912   // Functions to do with RingExtAlgImpl::HomImpl
913 
914 
HomImpl(const SparsePolyRing & domain,const ring & codomain,const RingHom & CoeffHom,const std::vector<RingElem> & IndetImages)915   RingExtAlgImpl::HomImpl::HomImpl(const SparsePolyRing& domain, const ring& codomain, const RingHom& CoeffHom, const std::vector<RingElem>& IndetImages):
916     SparsePolyRingBase::HomImpl(domain, codomain, CoeffHom, IndetImages)
917   {
918     CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::HomImpl::HomImpl");
919   }
920 
921 
922 
923   //---------------------------------------------------------------------------
924   // Functions for the class RingExtAlgImpl::IdealImpl
925 
926   // inheritance is delicate here: this function is **necessary**
myIdealCtor(const std::vector<RingElem> & gens)927   ideal RingExtAlgImpl::myIdealCtor(const std::vector<RingElem>& gens) const
928   {
929     return ideal(new IdealImpl(SparsePolyRing(this), gens)); //??? ugly ???
930   }
931 
932 
IdealImpl(const SparsePolyRing & P,const std::vector<RingElem> & gens)933   RingExtAlgImpl::IdealImpl::IdealImpl(const SparsePolyRing& P, const std::vector<RingElem>& gens):
934     SparsePolyRingBase::IdealImpl(P, gens)
935   {}
936 
937 
myTestIsMaximal()938   void RingExtAlgImpl::IdealImpl::myTestIsMaximal() const
939   { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::IdealImpl::myTestIsMaximal()"); }
940 
941 
myTestIsPrimary()942   void RingExtAlgImpl::IdealImpl::myTestIsPrimary() const
943   { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::IdealImpl::myTestIsPrimary()"); }
944 
945 
myTestIsPrime()946   void RingExtAlgImpl::IdealImpl::myTestIsPrime() const
947   { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::IdealImpl::myTestIsPrime()"); }
948 
949 
myTestIsRadical()950   void RingExtAlgImpl::IdealImpl::myTestIsRadical() const
951   { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::IdealImpl::myTestIsRadical()"); }
952 
953 
myReduceMod(RingElemRawPtr)954   void RingExtAlgImpl::IdealImpl::myReduceMod(RingElemRawPtr /*rawr*/) const
955   { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::WeylIdeal::IdealImpl::myReduceMod"); }
956 
957 
IhaveElem(RingElemConstRawPtr)958   bool RingExtAlgImpl::IdealImpl::IhaveElem(RingElemConstRawPtr /*rawr*/) const
959   {
960     CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::WeylIdeal::IhaveElem");
961     return false; /* just to keep compiler quiet */
962   }
963 
964 
myIntersect(const ideal &)965   void RingExtAlgImpl::IdealImpl::myIntersect(const ideal& /*J*/)
966   { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::WeylIdeal::myIntersect"); }//???
967 
968 
myColon(const ideal &)969   void RingExtAlgImpl::IdealImpl::myColon(const ideal& /*J*/)
970   { CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::WeylIdeal::myColon"); }//???
971 
972 
myDivMod(RingElemRawPtr,RingElemConstRawPtr,RingElemConstRawPtr)973   bool RingExtAlgImpl::IdealImpl::myDivMod(RingElemRawPtr /*rawlhs*/, RingElemConstRawPtr /*rawnum*/, RingElemConstRawPtr /*rawden*/) const
974   {
975     CoCoA_THROW_ERROR(ERR::NYI, "RingExtAlgImpl::WeylIdeal::myDivMod");
976     return false; /* just to keep compiler quiet */
977   }
978 
979 
myGBasis(const CpuTimeLimit & CheckForTimeout)980   const std::vector<RingElem>& RingExtAlgImpl::IdealImpl::myGBasis(const CpuTimeLimit& CheckForTimeout) const
981   {
982     if (IhaveGBasis()) return myGBasisValue;
983     CoCoA_ASSERT(myGBasisValue.empty());
984     vector<RingElem> GensList, GBList;
985     GensList.insert(GensList.end(), myGensValue.begin(), myGensValue.end());
986     bool IsHomog=false;
987     bool IsSatAlg=false;
988     GRingInfo GRI(myP, IsHomog, IsSatAlg, NewDivMaskEvenPowers(), CheckForTimeout);
989     GBCriteria criteria(GBCriteria::DontUseCoprime, GBCriteria::UseGM,
990                         GBCriteria::UseBack, GBCriteria::DontUseDiv);
991     GReductor GR(GRI, GensList,
992                  GReductor::AffineAlg,
993                  Reductors::DontUseBorel, GReductor::DontUseDynamicAlg,
994                  criteria);
995     GR.myDoGBasis();
996     //    GR.myDoAFFGBasis();
997     GR.myGBasis(GBList);
998     myGBasisValue.insert(myGBasisValue.end(), GBList.begin(), GBList.end());
999     IhaveGBasisValue = true;
1000     return myGBasisValue;
1001   }
1002 
1003 
1004   //----------------------------------------------------------------------
1005   // Pseudo-ctors for (sparse) polynomial rings.
1006 
1007 
NewExtAlgebra(const ring & CoeffRing,long NumIndets)1008   SparsePolyRing NewExtAlgebra(const ring& CoeffRing, long NumIndets)
1009   {
1010     return SparsePolyRing(new RingExtAlgImpl(CoeffRing, SymbolRange("x",1,NumIndets)));
1011   }
1012 
1013 
NewExtAlgebra(const ring & CoeffRing,const std::vector<symbol> & names)1014   SparsePolyRing NewExtAlgebra(const ring& CoeffRing, const std::vector<symbol>& names)
1015   {
1016     return SparsePolyRing(new RingExtAlgImpl(CoeffRing, names));
1017   }
1018 
1019 
1020 //   const RingElem& indet(const RingWeyl& RW, long var)
1021 //   {
1022 //     if (var > CoCoA::NumIndets(RW)) CoCoA_THROW_ERROR("Indeterminate index too large", "indet(RW,var)");
1023 //     return RW->myIndetVector[var];
1024 //   }
1025 
1026 
1027 //   const RingElem& derivation(const RingWeyl& RW, long var)
1028 //   {
1029 //     if (var > CoCoA::NumIndets(RW)) CoCoA_THROW_ERROR("Indeterminate index too large", "derivation(RW,var)");
1030 //     return RW->myDerivationVector[var];
1031 //   }
1032 
1033 
1034 } // end of namespace CoCoA
1035 
1036 // #error "JUNK AFTER THIS LINE"
1037 // ?????????????????????????????????????????????????????????????????????????????
1038 // #include <algorithm>
1039 // #include <vector>
1040 // #include <iostream>
1041 
1042 // using std::max;
1043 // using std::swap;
1044 // using std::vector;
1045 // using std::ostream;
1046 // using std::endl;   // just for debugging
1047 
1048 
1049 // #include "CoCoA/deriv.H"
1050 // #include "CoCoA/ring_weyl.H"
1051 
1052 // namespace  // unnamed, for file local functions
1053 // {
1054 
1055 //   using namespace CoCoA;
1056 
1057 
1058 // //----------------------------------------------------------------------
1059 
1060 
1061 // //  // f = pp*g where the product is in the Weyl algebra
1062 // //  void act(RingElem& f, const RingElem& pp, const RingElem& g)
1063 // //  {
1064 // //    ASSERT(IsPolyRing(owner(f)));
1065 // //    const PolyRing& P = PolyRing::owner(f);
1066 // //    ASSERT(&owner(g) == &P && &owner(pp) == &P);
1067 // //    ASSERT(!IsZero(pp) && NumTerms(pp) == 1);
1068 // //    //  std::clog<<"entered ucha's action" << endl;
1069 // //    //  std::clog << "pp=" << pp << endl;
1070 // //    f = g;
1071 // //    if (IsZero(f)) return;
1072 // //    const long nvars = NumIndets(P);
1073 
1074 // //    vector<long> expv(nvars);
1075 // //    PPM(P).exponents(expv, raw(LPP(pp)));
1076 
1077 // //    for (long var = nvars/2; var < nvars; ++var)
1078 // //    {
1079 // //      //    std::clog << "doing D var=" << var << endl;
1080 // //      const long n = expv[var];
1081 // //      //    std::clog << "order = " << n << endl;
1082 // //      RingElem derf = f;
1083 // //      f *= P.IndetPower(var, n);
1084 // //      for (long i=1; i <= n; ++i)
1085 // //      {
1086 // //        derf = deriv(derf, var-nvars/2);
1087 // //        f += binomial(n, i)*derf*P.IndetPower(var, n-i); // *IndetPower(h, 2*i); // for homog case
1088 // //        std::clog<<"binomial("<<n<<","<<i<<")="<<binomial(n,i)<<std::endl;
1089 // //      }
1090 // //    }
1091 // //    { // f *= var^deg(pp, var); for the early vars
1092 // //      for (long var = nvars/2; var < nvars; ++var)
1093 // //        expv[var] = 0;
1094 // //      PPMonoid::elem qq(PPM(P), expv);
1095 // //      f *= P.monomial(RingElem(CoeffRing(P), 1), qq);
1096 // //    }
1097 // //  }
1098 // //----------------------------------------------------------------------
1099 // } // end of unnamed namespace
1100 
1101 
1102 // namespace CoCoA
1103 // {
1104 
1105 
1106 
1107 
1108 //   RingExtAlgImpl::ring_weyl(const AbstractRing& R, const PPMonoid& PPM):
1109 //     myCoeffRing(R),
1110 //     myPPM(PPM),
1111 //     myWeylPolyPool(sizeof(WeylPoly), "RingExtAlgImpl::myWeylPolyPool"),
1112 //     myNumIndets(NumIndets(PPM)),
1113 //     myOrdvWords(OrdvWords(ordering(PPM))),
1114 //     mySummandSize(sizeof(WeylPoly::summand) + sizeof(int)*(myOrdvWords-1)),
1115 //     mySummandPool(mySummandSize, "RingExtAlgImpl::mySummandPool")
1116 //   {
1117 //     myNumPolys = 0;
1118 //     myZero = new RingElem(*this);
1119 //     myIndetVector.resize(myNumIndets, RingElem(*this));
1120 //     vector<long> expv(myNumIndets);
1121 //     RingElem one(myCoeffRing, 1);
1122 //     for (long i=0; i < myNumIndets; ++i)
1123 //     {
1124 //       expv[i] = 1;
1125 //       PushFront(raw(myIndetVector[i]), raw(one), expv);
1126 //       expv[i] = 0;
1127 //     }
1128 //   }
1129 
1130 
1131 //   RingExtAlgImpl::~ring_weyl()
1132 //   {
1133 //     myIndetVector.clear();
1134 //     delete myZero;
1135 //     ASSERT(myNumPolys == 0);
1136 //   }
1137 
1138 
1139 //   void RingExtAlgImpl::MakeWritable(RawPtr rawx) const
1140 //   {
1141 //     if (x.WeylPolyPtr->myRefCount == 1) return;
1142 //     --x.WeylPolyPtr->myRefCount;
1143 //     WeylPoly* copy = static_cast<WeylPoly*>(myWeylPolyPool.alloc(sizeof(WeylPoly)));
1144 //     const WeylPoly* orig = x.WeylPolyPtr;
1145 //     x.WeylPolyPtr = copy;
1146 //     copy->myRefCount = 1;
1147 //     copy->mySummands = nullptr;
1148 //     copy->myEnd = &copy->mySummands;
1149 //     for (const WeylPoly::summand* it = orig->mySummands; it != nullptr; it = it->myNext)
1150 //     {
1151 //       // more or less hand inlined body of PushBack -- NB using PushBack is "circular"
1152 //       *copy->myEnd = CopySummand(it);
1153 //       copy->myEnd = &((*copy->myEnd)->myNext);
1154 //     }
1155 
1156 //     ///  myCoeffRing.init(copy->myDenom);
1157 // //    new (&copy->myLC) RingElem(myCoeffRing, AbstractRing::elem::ALIAS);
1158 //   }
1159 
1160 
1161 //   inline WeylPoly::summand* RingExtAlgImpl::AllocSummand() const
1162 //   {
1163 //     return static_cast<WeylPoly::summand*>(mySummandPool.alloc(mySummandSize));
1164 //   }
1165 
1166 
1167 //   WeylPoly::summand* RingExtAlgImpl::InitSummand(WeylPoly::summand* ptr) const
1168 //   {
1169 //     myCoeffRing.init(ptr->myCoeff);
1170 //     ptr->myNext = nullptr;
1171 //     ptr->myModulePosn = 0;
1172 //     return ptr;
1173 //   }
1174 
1175 
1176 //   WeylPoly::summand* RingExtAlgImpl::InitSummand(WeylPoly::summand* ptr, ConstRawPtr rawc, const vector<long>& expv) const
1177 //   {
1178 //     myCoeffRing.init(ptr->myCoeff, c);
1179 //     ptr->myNext = nullptr;
1180 //     ptr->myModulePosn = 0;
1181 //     ordering(myPPM).ComputeOrdv(ptr->myOrdv, &expv[0]); // &expv[0] converts vector<T> to T*
1182 //     return ptr;
1183 //   }
1184 
1185 
1186 //   WeylPoly::summand* RingExtAlgImpl::CopySummand(const WeylPoly::summand* original) const
1187 //   {
1188 //     WeylPoly::summand* copy = AllocSummand();
1189 //     copy->myNext = nullptr;
1190 //     myCoeffRing.init(copy->myCoeff, original->myCoeff);
1191 //     copy->myModulePosn = original->myModulePosn;
1192 //     for (long i=0; i < myOrdvWords; ++i)
1193 //       copy->myOrdv[i] = original->myOrdv[i];
1194 //     return copy;
1195 //   }
1196 
1197 
1198 //   void RingExtAlgImpl::SetSummandMOrdv(WeylPoly::summand* dest, const WeylPoly::summand* src) const
1199 //   {
1200 //     dest->myModulePosn = src->myModulePosn;
1201 //     for (long i=0; i < myOrdvWords; ++i)
1202 //       dest->myOrdv[i] = src->myOrdv[i];
1203 //   }
1204 
1205 
1206 //   void RingExtAlgImpl::DeleteSummands(WeylPoly::summand* ptr) const
1207 //   {
1208 //     WeylPoly::summand* next;
1209 //     while (ptr != 0)
1210 //     {
1211 //       next = ptr->myNext;
1212 //       myCoeffRing.kill(ptr->myCoeff);
1213 //       mySummandPool.free(ptr, mySummandSize);
1214 //       ptr = next;
1215 //     }
1216 //   }
1217 
1218 
1219 //   bool RingExtAlgImpl::EqualSummands(const WeylPoly::summand& lhs, const WeylPoly::summand& x) const
1220 //   {
1221 //     if (lhs.myModulePosn != x.myModulePosn) return false;
1222 //     const PPOrdering::OrdvElem* const lordv = lhs.myOrdv;
1223 //     const PPOrdering::OrdvElem* const rordv = x.myOrdv;
1224 //     for (long i = 0; i < myOrdvWords; ++i)
1225 //       if (lordv[i] != rordv[i]) return false;
1226 //     return myCoeffRing.IsEqual(lhs.myCoeff, x.myCoeff);
1227 //   }
1228 
1229 
1230 //   inline void RingExtAlgImpl::MulOrdv(PPOrdering::OrdvElem* ov, const PPOrdering::OrdvElem* ov1, const PPOrdering::OrdvElem* ov2) const
1231 //   {
1232 //     for (long i=0; i < myOrdvWords; ++i)
1233 //       ov[i] = ov1[i]+ov2[i];
1234 //   }
1235 
1236 
1237 //   inline void RingExtAlgImpl::DivOrdv(PPOrdering::OrdvElem* ov, const PPOrdering::OrdvElem* ov1, const PPOrdering::OrdvElem* ov2) const
1238 //   {
1239 //     for (long i=0; i < myOrdvWords; ++i)
1240 //       ov[i] = ov1[i]-ov2[i];
1241 //   }
1242 
1243 
1244 
1245 
1246 //   long RingExtAlgImpl::NumIndets() const
1247 //   {
1248 //     return myNumIndets;
1249 //   }
1250 
1251 
1252 //   const AbstractRing& RingExtAlgImpl::CoeffRing() const
1253 //   {
1254 //     return myCoeffRing;
1255 //   }
1256 
1257 
1258 //   const PPMonoid& RingExtAlgImpl::PPM() const
1259 //   {
1260 //     return myPPM;
1261 //   }
1262 
1263 
1264 //   long RingExtAlgImpl::NumTerms(ConstRawPtr rawx) const
1265 //   {
1266 //     long nsummands = 0;
1267 //     for (const WeylPoly::summand* it = AsWeylPoly(rawx).mySummands; it != nullptr; it = it->myNext) ++nsummands;
1268 //     return nsummands;
1269 //   }
1270 
1271 
1272 //   PolyIter RingExtAlgImpl::BeginIter(AbstractRing::RawPtr rawx) const
1273 //   {
1274 //     return PolyIter(*this, &AsWeylPoly(rawx).mySummands);
1275 //   }
1276 
1277 
1278 //   PolyIter RingExtAlgImpl::EndIter(AbstractRing::RawPtr rawx) const
1279 //   {
1280 //     return PolyIter(*this, AsWeylPoly(rawx).myEnd);
1281 //   }
1282 
1283 
1284 //   const RingElem& RingExtAlgImpl::indet(long var) const
1285 //   {
1286 //     ASSERT(var < myNumIndets);
1287 //     return myIndetVector[var];
1288 //   }
1289 
1290 
1291 //   RingElem RingExtAlgImpl::IndetPower(long var, long n) const
1292 //   {
1293 //     ASSERT(0 <= var && var < myNumIndets);
1294 //     return monomial(CoCoA::IndetPower(myPPM, var, n));
1295 //   }
1296 
1297 
1298 //   RingElem RingExtAlgImpl::monomial(const RingElem& c, const PPMonoid::alias& pp) const
1299 //   {
1300 //     vector<long> expv(myNumIndets);
1301 //     myPPM.exponents(expv, raw(pp));
1302 //     RingElem ans(*this);
1303 //     PushFront(raw(ans), raw(c), expv);
1304 //     return ans;
1305 //   }
1306 
1307 
1308 //   RingElem RingExtAlgImpl::monomial(const PPMonoid::alias& pp) const
1309 //   {
1310 //     RingElem c(myCoeffRing, 1);
1311 //     vector<long> expv(myNumIndets);
1312 //     myPPM.exponents(expv, raw(pp));
1313 //     RingElem ans(*this);
1314 //     PushFront(raw(ans), raw(c), expv);
1315 //     return ans;
1316 //   }
1317 
1318 
1319 //   RingElem RingExtAlgImpl::monomial(const RingElem& c) const
1320 //   {
1321 //     vector<long> expv(myNumIndets);
1322 //     RingElem ans(*this);
1323 //     PushFront(raw(ans), raw(c), expv);
1324 //     return ans;
1325 //   }
1326 
1327 
1328 //   long RingExtAlgImpl::deg(ConstRawPtr rawf) const
1329 //   {
1330 //     if (IsZero(f)) CoCoA_THROW_ERROR("RingExtAlgImpl::deg: cannot compute degree of zero polynomial");
1331 //     if (GradingDim(myPPM) > 0)
1332 //       return ordering(myPPM).deg(AsWeylPoly(f).mySummands->myOrdv); //// BUG????  "valid" only if grading dim == 1
1333 //     //    return ???; the vector in Z^0 -- ring not graded!!!
1334 //     return -1;//??????????  BUG BUG INCOMPLETE
1335 //   }
1336 
1337 
1338 //   int RingExtAlgImpl::deg(ConstRawPtr rawf, long var) const
1339 //   {
1340 //     if (IsZero(f)) CoCoA_THROW_ERROR("RingExtAlgImpl::deg: cannot compute degree of zero polynomial");
1341 //     long d = 0;
1342 //     for (WeylPoly::summand* it = AsWeylPoly(f).mySummands; it != nullptr; it = it->myNext)
1343 //       d = max(d, ordering(myPPM).exponent(it->myOrdv, var));
1344 //     return d;
1345 //   }
1346 
1347 
1348 // //    int RingExtAlgImpl::deg(ConstRawPtr rawf, const PPGrading& G) const
1349 // //    {
1350 // //      if (IsZero(f)) CoCoA_THROW_ERROR("RingExtAlgImpl::deg: cannot compute degree of zero polynomial");
1351 // //      int d = 0;
1352 // //      for (WeylPoly::summand* it = AsWeylPoly(f).mySummands; it != nullptr; it = it->myNext)
1353 // //        d = max(d, deg(it, G)); // CANNOT JUST USE MAX HERE!!  MUST USE LEX MAX FOR VECTORS
1354 // //      return d;
1355 // //    }
1356 
1357 
1358 
1359 //   const RingElem RingExtAlgImpl::LC(ConstRawPtr rawf) const
1360 //   {
1361 //     ASSERT(!IsZero(f));
1362 // //    if (IsZero(f)) return ::zero(myCoeffRing);
1363 //     return RingElem(myCoeffRing, AsWeylPoly(f).mySummands->myCoeff);
1364 // //    AsWeylPoly(f).myLC.reseat(AsWeylPoly(f).mySummands->myCoeff);
1365 // //    return AsWeylPoly(f).myLC;
1366 //   }
1367 
1368 
1369 //   AbstractRing::RawPtr RingExtAlgImpl::RawLC(RawPtr rawf) const
1370 //   {
1371 //     MakeWritable(f);//?????????
1372 //     ASSERT(!IsZero(f));
1373 //     return AsWeylPoly(f).mySummands->myCoeff;
1374 //   }
1375 
1376 
1377 //   const AbstractRing::RawPtr RingExtAlgImpl::RawLC(ConstRawPtr rawf) const
1378 //   {
1379 //     ASSERT(!IsZero(f));
1380 //     return AsWeylPoly(f).mySummands->myCoeff;
1381 //   }
1382 
1383 
1384 //   RingElem RingExtAlgImpl::content(ConstRawPtr rawf) const
1385 //   {
1386 //     ASSERT(::IsTrueGCDDomain(myCoeffRing));
1387 //     ASSERT(!IsZero(f));
1388 //     RingElem cont(myCoeffRing);
1389 //     for (WeylPoly::summand* it = AsWeylPoly(f).mySummands; it != nullptr; it = it->myNext)
1390 //       myCoeffRing.gcd(raw(cont), raw(cont), it->myCoeff);  // be clever if cont == 1??
1391 //     return cont;
1392 //   }
1393 
1394 
1395 
1396 //   void RingExtAlgImpl::MoveLMToFront(RawPtr rawf, RawPtr rawg) const
1397 //   {
1398 //     ASSERT(!IsZero(g));
1399 //     ASSERT(f.WeylPolyPtr->myRefCount == 1);
1400 //     //    ASSERT(g.WeylPolyPtr->myRefCount == 1);
1401 //     //    MakeWritable(f);//????????
1402 //     MakeWritable(g);//????????
1403 //     WeylPoly& G = AsWeylPoly(g);
1404 //     WeylPoly::summand* ltg = G.mySummands;
1405 //     G.mySummands = G.mySummands->myNext;
1406 //     if (G.mySummands == nullptr) G.myEnd = &(G.mySummands);
1407 //     PushFront(f, ltg);
1408 //   }
1409 
1410 
1411 //   void RingExtAlgImpl::DeleteLM(RawPtr rawf) const
1412 //   {
1413 //     ASSERT(!IsZero(f));
1414 //     //    ASSERT(f.WeylPolyPtr->myRefCount == 1);
1415 //     MakeWritable(f);//????????
1416 //     WeylPoly& F = AsWeylPoly(f);
1417 //     WeylPoly::summand* old_ltf = F.mySummands;
1418 //     F.mySummands = old_ltf->myNext;
1419 //     if (F.mySummands == nullptr) F.myEnd = &F.mySummands;
1420 //     old_ltf->myNext = nullptr;
1421 //     DeleteSummands(old_ltf);
1422 //   }
1423 
1424 
1425 //   void RingExtAlgImpl::AddMul(RawPtr rawf, const WeylPoly::summand* s, ConstRawPtr rawg, bool SkipLM) const
1426 //   {
1427 // ////    std::clog << "AddMul: Doing funny product of the following two polys" << endl;
1428 // ////    output(std::clog, rawg);
1429 //     ASSERT(f.WeylPolyPtr->myRefCount == 1);
1430 //     //    MakeWritable(f);
1431 
1432 //     RingElem ppg(*this);
1433 //     assign(raw(ppg), rawg);
1434 //     vector<long> expv(myNumIndets);
1435 //     ordering(myPPM).ComputeExpv(&expv[0], s->myOrdv);
1436 // ////    std::clog << "expv: "; for (int i=0; i<myNumIndets;++i) std::clog << expv[i] << "  "; std::clog << endl;
1437 //     for (long var = myNumIndets/2; var < myNumIndets; ++var)
1438 //     {
1439 //       const long n = expv[var];
1440 //       if (n == 0) continue;
1441 // ////      std::clog << "AddMul: doing D variable with index " << n << endl;
1442 //       RingElem der(*this);
1443 //       assign(raw(der), raw(ppg));
1444 // //      ppg *= IndetPower(var, n);  CANNOT DO THIS --> INFINITE RECURSION
1445 //       {
1446 //         PlainMul(raw(ppg),raw(ppg),raw(IndetPower(var, n)));
1447 //       }
1448 // //      mul(raw(ppg), raw(ppg), raw(IndetPower(var, n)));
1449 //       for (long i=1; i <= n; ++i)
1450 //       {
1451 //         deriv(raw(der), raw(der), var-myNumIndets/2);
1452 // ////        std::clog << "der(" << i << ")="; output(std::clog, raw(der)); std::clog << endl;
1453 // //        ppg += binomial(n, i)*der*IndetPower(var, n-i); // *IndetPower(h, 2*i); // for homog case
1454 //         {
1455 //           vector<long> expv2(myNumIndets);
1456 //           expv2[var] = n-i;
1457 //           RingElem shift(*this);
1458 //           PushBack(raw(shift), raw(RingElem(myCoeffRing, binomial(n, i))), expv2);
1459 //           RingElem tmp(*this);
1460 //           PlainMul(raw(tmp), raw(shift), raw(der));
1461 // ////          std::clog << "AddMul: adding "; output(std::clog, raw(tmp)); std::clog << endl;
1462 //           add(raw(ppg),raw(ppg),raw(tmp));
1463 //         }
1464 //       }
1465 //     }
1466 //     { // f *= var^deg(pp, var); for the early vars
1467 //       for (long var = myNumIndets/2; var < myNumIndets; ++var)
1468 //         expv[var] = 0;
1469 //       PPMonoid::elem qq(myPPM, expv);
1470 //       RingElem c(myCoeffRing);
1471 //       myCoeffRing.assign(raw(c), s->myCoeff);
1472 //       PlainMul(raw(ppg), raw(ppg), raw(monomial(c, qq)));
1473 // ///      f *= P.monomial(RingElem(CoeffRing(P), 1), qq);
1474 //     }
1475 // ////    std::clog << "AddMul: OUTPUT "; output(std::clog, raw(ppg)); std::clog << endl;
1476 //     add(f, f, raw(ppg));
1477 //   }
1478 
1479 
1480 //   void RingExtAlgImpl::AddMul2(RawPtr rawf, ConstRawPtr rawh, ConstRawPtr rawg, bool SkipLM) const //???? delete me???
1481 //   {                                                 //???
1482 //     AddMul(f, (AsWeylPoly(h).mySummands), rawg, SkipLM);     //???
1483 //   }                                                 //???
1484 
1485 //   void RingExtAlgImpl::PlainMul(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const
1486 //   {
1487 //     if (NumTerms(x) > NumTerms(y)) { PlainMul(lhs, rawy, rawx); return; }
1488 
1489 //     RingElem ans(*this);
1490 
1491 //     for (const WeylPoly::summand* xterm = AsWeylPoly(x).mySummands; xterm; xterm = xterm->myNext)
1492 //       PlainAddMul(raw(ans), xterm, rawy, false);//?????
1493 
1494 //     swap(raw(ans), lhs); // really an assignment
1495 //   }
1496 //   void RingExtAlgImpl::PlainAddMul(RawPtr rawf, const WeylPoly::summand* s, ConstRawPtr rawg, bool SkipLM) const
1497 //   {
1498 // //    ASSERT(f.DMPIPtr->myRefCount == 1);
1499 //     //    MakeWritable(f);
1500 // //          std::clog << "\nF := "; output(std::clog,f);
1501 // //          std::clog<<";\nG := "; output(std::clog,g);
1502 // //          std::clog<<endl;
1503 // //          std::clog<<"s = ";
1504 // //          myCoeffRing.output(std::clog, s->myCoeff);
1505 // //          std::clog<<"x^(";
1506 // //          for(long i=0;i<myOrdvWords;++i)std::clog<<s->myOrdv[i]<<" ";
1507 // //          std::clog<<")"<<endl;
1508 //     const AbstractRing& R = myCoeffRing;
1509 //     typedef WeylPoly::summand summand;
1510 //     const summand* g_smnd = AsWeylPoly(g).mySummands;
1511 //     if (SkipLM)    g_smnd = g_smnd->myNext;
1512 //     summand** f_prev = &(AsWeylPoly(f).mySummands);
1513 //     summand*  f_smnd = *f_prev;
1514 
1515 //     summand* tmp_smnd = InitSummand(AllocSummand()); // just sets coeff = 0
1516 
1517 //     int CMP=0;
1518 
1519 //     //    bool qIsOne = (myPPM.cmp(q, tmpPP)==0);
1520 //     bool qIsOne = false;
1521 
1522 //     for (; f_smnd != nullptr && g_smnd != nullptr; g_smnd = g_smnd->myNext)
1523 //     {
1524 //       if (qIsOne)
1525 //         while (f_smnd != nullptr && (CMP=ordering(myPPM).CmpOrdvs(f_smnd->myOrdv,g_smnd->myOrdv)) >0)
1526 //           f_smnd = *(f_prev = &f_smnd->myNext);
1527 //       else
1528 //       {
1529 //         MulOrdv(tmp_smnd->myOrdv, s->myOrdv, g_smnd->myOrdv);
1530 //         while (f_smnd != nullptr && (CMP=ordering(myPPM).CmpOrdvs(f_smnd->myOrdv,tmp_smnd->myOrdv)) >0)
1531 //           f_smnd = *(f_prev = &f_smnd->myNext);
1532 //       }
1533 //       if (f_smnd == nullptr)
1534 //       {
1535 //         R.mul(tmp_smnd->myCoeff, s->myCoeff, g_smnd->myCoeff);
1536 //         PushBack(f, tmp_smnd);
1537 //         tmp_smnd = InitSummand(AllocSummand());
1538 //         g_smnd = g_smnd->myNext;
1539 //         break;
1540 //       }
1541 //       if (CMP == 0)
1542 //       {
1543 //         if (R.IsZeroAddMul(f_smnd->myCoeff, s->myCoeff, g_smnd->myCoeff))
1544 //           RemoveSmnd(f, f_prev);  // f_prev = f_prev;
1545 //         else
1546 //           f_prev = &f_smnd->myNext;
1547 //         f_smnd = *f_prev;
1548 //       }
1549 //       else // (CMP < 0)
1550 //       {
1551 //         R.mul(tmp_smnd->myCoeff, s->myCoeff, g_smnd->myCoeff);
1552 //         InsertSmnd(f, tmp_smnd, f_prev);
1553 //         tmp_smnd = InitSummand(AllocSummand());
1554 //         f_prev = &(*f_prev)->myNext;
1555 //         // f_smnd = f_smnd;
1556 //       }
1557 //     }
1558 //     for (;g_smnd != nullptr; g_smnd = g_smnd->myNext)
1559 //     {
1560 //       MulOrdv(tmp_smnd->myOrdv, s->myOrdv, g_smnd->myOrdv);
1561 //       R.mul(tmp_smnd->myCoeff, s->myCoeff, g_smnd->myCoeff);
1562 //       PushBack(f, tmp_smnd);
1563 //       tmp_smnd = InitSummand(AllocSummand());
1564 //     }
1565 //     DeleteSummands(tmp_smnd); // next ptr will be zero (set by InitSummand)
1566 // //      std::clog << "AddMul: produced f=";output(std::clog,f);std::clog<<endl;
1567 // //      std::clog << "------------------------------------------------------"<<endl;
1568 
1569 //   }
1570 
1571 
1572 
1573 
1574 
1575 //   void RingExtAlgImpl::ReductionStep(RawPtr rawf, ConstRawPtr rawg) const
1576 //   {
1577 //  //             std::clog << "\nRingExtAlgImpl::reduce" << endl;
1578 // //              std::clog << "\nF := "; output(std::clog,f);
1579 // //              std::clog<<";\nG := "; output(std::clog,g);
1580 // //              std::clog<<";"<<endl;
1581 //     ASSERT(&g!=&f);
1582 //     const AbstractRing& R = myCoeffRing;
1583 //     const WeylPoly::summand* g_smnd = AsWeylPoly(g).mySummands;
1584 //     const WeylPoly::summand* f_smnd = AsWeylPoly(f).mySummands;
1585 //     WeylPoly::summand* tmp_smnd = InitSummand(AllocSummand()); // just sets coeff = 0
1586 
1587 //     DivOrdv(tmp_smnd->myOrdv, f_smnd->myOrdv, g_smnd->myOrdv);
1588 //     R.div(tmp_smnd->myCoeff, f_smnd->myCoeff, g_smnd->myCoeff);
1589 //     R.negate(tmp_smnd->myCoeff, tmp_smnd->myCoeff);
1590 
1591 //  //             std::clog<<"--  S := ";
1592 // //              myCoeffRing.output(std::clog, tmp_smnd->myCoeff);
1593 // //              std::clog<<"x^(";
1594 // //              for(long i=0;i<myOrdvWords;++i)std::clog<<tmp_smnd->myOrdv[i]<<" ";
1595 // //              std::clog<<")"<<endl;
1596 
1597 //     DeleteLM(f);
1598 //     AddMul(f, tmp_smnd, g, true /*SkipLM*/);
1599 
1600 //     DeleteSummands(tmp_smnd); // next ptr will be zero (set by InitSummand)
1601 //  //             std::clog << "H := "; output(std::clog,f);
1602 // //              std::clog << ";\n--------------------------------------------------"<<endl;
1603 //  }
1604 
1605 
1606 //   void RingExtAlgImpl::AddClear(RawPtr rawf, RawPtr rawg) const
1607 //   {
1608 //     ASSERT(f.WeylPolyPtr->myRefCount == 1);
1609 //     //    MakeWritable(f);
1610 //     MakeWritable(g);
1611 //     // input polynomial are copied
1612 //     //if (g.WeylPolyPtr->myRefCount != 1)
1613 //     //      std::clog << "AddClear: g.myRefCount == " << g.WeylPolyPtr->myRefCount << endl;
1614 //     const AbstractRing& R = myCoeffRing;
1615 //     typedef WeylPoly::summand summand;
1616 //     WeylPoly& F = AsWeylPoly(f);
1617 //     WeylPoly& G = AsWeylPoly(g);
1618 //     summand*  g_smnd = G.mySummands;
1619 //     summand** f_prev = &(F.mySummands);
1620 //     summand*  f_smnd = *f_prev;
1621 //     int CMP=0;
1622 //     ASSERT(*(G.myEnd)==nullptr);//BUG HUNTING  ???
1623 
1624 //     //    std::clog << "input f = "; output(std::clog, f) ;std::clog << endl;
1625 //     while ( f_smnd!=nullptr && g_smnd!=nullptr )
1626 //     {
1627 //       while (f_smnd!=nullptr &&
1628 //              (CMP=ordering(myPPM).CmpOrdvs(f_smnd->myOrdv,g_smnd->myOrdv)) >0)
1629 //         f_smnd = *(f_prev = &f_smnd->myNext);
1630 //       if (f_smnd == nullptr)  break;
1631 //       //std::clog <<   "(AddClear error: should never happen for Basic Reduction)" << endl;
1632 //       G.mySummands = G.mySummands->myNext;
1633 //       g_smnd->myNext = nullptr;
1634 //       if (CMP == 0)
1635 //       {
1636 //         R.add(f_smnd->myCoeff, f_smnd->myCoeff, g_smnd->myCoeff);
1637 //         if (R.IsZero(f_smnd->myCoeff))
1638 //           RemoveSmnd(f, f_prev);
1639 //         DeleteSummands(g_smnd);
1640 //       }
1641 //       else // (CMP < 0)
1642 //       {
1643 //         InsertSmnd(f, g_smnd, f_prev);
1644 //         f_prev = &(*f_prev)->myNext;
1645 //       }
1646 //       f_smnd = *f_prev;
1647 //       g_smnd = G.mySummands;
1648 //     }
1649 //     if (G.mySummands!=nullptr)
1650 //     {
1651 //       *(F.myEnd) = G.mySummands;
1652 //       F.myEnd = G.myEnd;
1653 //       G.mySummands = nullptr;
1654 //     }
1655 //     G.myEnd = &G.mySummands;
1656 //     //    if (rare) {std::clog << "f2 = "; output(std::clog, f) ;std::clog << endl;}
1657 //   }
1658 
1659 
1660 //   void RingExtAlgImpl::AppendClear(RawPtr rawf, RawPtr rawg) const
1661 //   {
1662 //     ASSERT(f.WeylPolyPtr->myRefCount == 1);
1663 //     //    MakeWritable(f);
1664 //     MakeWritable(g);
1665 //     // input polynomial are copied
1666 //     //if (g.WeylPolyPtr->myRefCount != 1)
1667 //     //      std::clog << "AppendClear: g.myRefCount == " << g.WeylPolyPtr->myRefCount << endl;
1668 //     WeylPoly& F = AsWeylPoly(f);
1669 //     WeylPoly& G = AsWeylPoly(g);
1670 //     if (G.mySummands!=nullptr)
1671 //     {
1672 //       *(F.myEnd) = G.mySummands;
1673 //       F.myEnd = G.myEnd;
1674 //       G.mySummands = nullptr;
1675 //     }
1676 //     G.myEnd = &G.mySummands;
1677 //     //    if (rare) {std::clog << "f2 = "; output(std::clog, f) ;std::clog << endl;}
1678 //   }
1679 
1680 
1681 //   int  RingExtAlgImpl::CmpLPP(ConstRawPtr rawf, ConstRawPtr rawg) const
1682 //   {
1683 //     ASSERT(!IsZero(f));
1684 //     ASSERT(!IsZero(g));
1685 //     return ordering(myPPM).CmpOrdvs(AsWeylPoly(f).mySummands->myOrdv,AsWeylPoly(g).mySummands->myOrdv);
1686 //   }
1687 
1688 
1689 //   void RingExtAlgImpl::DivLM(RawPtr rawlhs, ConstRawPtr rawf, ConstRawPtr rawg) const
1690 //   {
1691 //     //    std::clog << "DivLM" << endl;
1692 //     const AbstractRing& R = myCoeffRing;
1693 //     typedef WeylPoly::summand summand;
1694 //     const summand* f_smnd = AsWeylPoly(f).mySummands;
1695 //     const summand* g_smnd = AsWeylPoly(g).mySummands;
1696 //     MakeWritable(lhs);
1697 //     assign(lhs,0);
1698 //     summand* SpareSummand = InitSummand(AllocSummand());
1699 //     R.div(SpareSummand->myCoeff, f_smnd->myCoeff, g_smnd->myCoeff);
1700 //     DivOrdv(SpareSummand->myOrdv, f_smnd->myOrdv, g_smnd->myOrdv);
1701 //     PushBack(lhs, SpareSummand);
1702 //   }
1703 
1704 
1705 //   void RingExtAlgImpl::mul(RawPtr rawf, const PPMonoid::elem& pp) const
1706 //   {
1707 //     //    bool qIsOne = (myPPM.cmp(q, tmpPP)==0);
1708 //     MakeWritable(f);
1709 //     std::vector<long> v(myNumIndets);
1710 //     myPPM.exponents(v, raw(pp));
1711 
1712 //     WeylPoly::summand* f_smnd = AsWeylPoly(f).mySummands;
1713 //     WeylPoly::summand* s = InitSummand(AllocSummand());
1714 
1715 //     ordering(myPPM).ComputeOrdv(s->myOrdv, &v[0]); // &v[0] converts vector<T> to T*
1716 
1717 //     for (; f_smnd != nullptr ; f_smnd = f_smnd->myNext)
1718 //       MulOrdv(f_smnd->myOrdv, f_smnd->myOrdv, s->myOrdv);
1719 //   }
1720 
1721 
1722 //   void RingExtAlgImpl::PushFront(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const
1723 //   {
1724 //     if (CoeffRing().IsZero(c)) return;
1725 //     MakeWritable(f);
1726 //     WeylPoly::summand* t = AllocSummand();
1727 //     InitSummand(t, c, expv);
1728 //     t->myNext = f.WeylPolyPtr->mySummands;
1729 //     if (f.WeylPolyPtr->mySummands == nullptr) f.WeylPolyPtr->myEnd = &t->myNext;
1730 //     f.WeylPolyPtr->mySummands = t;
1731 //   }
1732 
1733 
1734 //   void RingExtAlgImpl::PushBack(RawPtr rawf, ConstRawPtr rawc, const std::vector<long>& expv) const
1735 //   {
1736 //     if (CoeffRing().IsZero(c)) return;
1737 //     MakeWritable(f);
1738 //     WeylPoly::summand* t = AllocSummand();
1739 //     InitSummand(t, c, expv);
1740 //     *(f.WeylPolyPtr->myEnd) = t;
1741 //     f.WeylPolyPtr->myEnd = &t->myNext;
1742 //   }
1743 
1744 
1745 //   void RingExtAlgImpl::PushFront(RawPtr rawx, WeylPoly::summand* t) const
1746 //   {
1747 //     MakeWritable(x);
1748 //     WeylPoly& f = AsWeylPoly(x);
1749 //     t->myNext = f.mySummands;
1750 //     f.mySummands = t;
1751 //     if (f.myEnd == &f.mySummands) f.myEnd = &t->myNext;
1752 //   }
1753 
1754 
1755 //   void RingExtAlgImpl::PushBack(RawPtr rawx, WeylPoly::summand* t) const
1756 //   {
1757 //     MakeWritable(x);
1758 //     WeylPoly& f = AsWeylPoly(x);
1759 //     *f.myEnd = t;
1760 //     f.myEnd = &t->myNext;
1761 //   }
1762 
1763 
1764 //   void RingExtAlgImpl::RemoveSmnd(RawPtr rawx, WeylPoly::summand** prev_link) const
1765 //   {
1766 //     ASSERT(x.WeylPolyPtr->myRefCount == 1);
1767 //     //    MakeWritable(x);
1768 //     WeylPoly::summand* tmp = *prev_link;
1769 //     ASSERT(tmp != 0);
1770 //     if (tmp->myNext==nullptr) // f.myEnd == &(tmp->myNext)
1771 //     {
1772 //       WeylPoly& f = AsWeylPoly(x);
1773 //       f.myEnd = prev_link;
1774 //     }
1775 //     *prev_link = tmp->myNext;
1776 //     tmp->myNext = nullptr;
1777 //     DeleteSummands(tmp);
1778 //   }
1779 
1780 
1781 //   void RingExtAlgImpl::InsertSmnd(RawPtr rawx, WeylPoly::summand* s, WeylPoly::summand** prev_link) const
1782 //   {
1783 //     ASSERT(x.WeylPolyPtr->myRefCount == 1);
1784 //     //    MakeWritable(x);
1785 //     WeylPoly& f = AsWeylPoly(x);
1786 //     s->myNext = (*prev_link);
1787 //     (*prev_link) = s;
1788 //     if (f.myEnd == prev_link) f.myEnd = &(s->myNext);
1789 //   }
1790 
1791 
1792 //   PPMonoid::elem RingExtAlgImpl::LPP(ConstRawPtr rawf) const
1793 //   {
1794 //     ASSERT(!IsZero(f));
1795 //     return PPMonoid::elem(PPM(), PPMonoid::elem::FromOrdv, AsWeylPoly(f).mySummands->myOrdv);
1796 //   }
1797 
1798 
1799 //   bool RingExtAlgImpl::IsZeroAddLCs(RawPtr rawf, RawPtr rawg) const
1800 //   {
1801 //     ASSERT(!IsZero(f) && !IsZero(g));
1802 //     ASSERT( CmpLPP(f,g) == 0);
1803 //     WeylPoly& F = AsWeylPoly(f);
1804 //     WeylPoly& G = AsWeylPoly(g);
1805 //     ASSERT(F.myRefCount==1 && G.myRefCount==1);
1806 //     myCoeffRing.add(F.mySummands->myCoeff, F.mySummands->myCoeff, G.mySummands->myCoeff);
1807 //     DeleteLM(g);
1808 //     if (!myCoeffRing.IsZero(F.mySummands->myCoeff)) return false;
1809 //     DeleteLM(f);
1810 //     return true;
1811 //   }
1812 
1813 
1814 //   void RingExtAlgImpl::deriv(RawPtr rawdest, ConstRawPtr rawf, long var) const
1815 //   {
1816 //     const WeylPoly& F = AsWeylPoly(f);
1817 //     RingElem ans(*this);
1818 //     vector<long> expv(myNumIndets);
1819 //     for (WeylPoly::summand* i=F.mySummands; i; i = i->myNext)
1820 //     {
1821 //       ordering(myPPM).ComputeExpv(&expv[0], i->myOrdv);
1822 //       if (expv[var] == 0) continue;
1823 //       RingElem c(myCoeffRing, expv[var]);
1824 //       if (CoCoA::IsZero(c)) continue;
1825 //       myCoeffRing.mul(raw(c), raw(c), i->myCoeff);
1826 //       if (CoCoA::IsZero(c)) continue;
1827 //       --expv[var];
1828 //       PushBack(raw(ans), raw(c), expv);
1829 //     }
1830 //     swap(raw(ans), dest);
1831 //   }
1832 
1833 
1834 //   void RingExtAlgImpl::negate(RawPtr rawlhs, ConstRawPtr rawx) const
1835 //   {
1836 //     if (lhs.WeylPolyPtr == x.WeylPolyPtr)
1837 //     {
1838 //       MakeWritable(lhs);
1839 //       typedef WeylPoly::summand summand;
1840 //       //      std::clog << "-- negate"; output(std::clog, lhs); std::clog << endl;
1841 //       for (summand* smnd = AsWeylPoly(lhs).mySummands; smnd!=nullptr; smnd=smnd->myNext )
1842 //         myCoeffRing.negate(smnd->myCoeff, smnd->myCoeff);
1843 //       //      std::clog << "-> negate"; output(std::clog, lhs); std::clog << endl;
1844 //     }
1845 //     else
1846 //       std::clog << "RingExtAlgImpl::negate: not yet implemented" << endl;
1847 //   }
1848 
1849 
1850 //   void RingExtAlgImpl::add(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const
1851 //   {
1852 //     const AbstractRing& R = myCoeffRing;
1853 //     RawValue ans;
1854 //     //    ans.WeylPolyPtr = static_cast<WeylPoly*>(myWeylPolyPool.alloc(sizeof(WeylPoly)));
1855 //     init(ans);
1856 //     ///    WeylPoly& sum = AsWeylPoly(ans);
1857 //     typedef WeylPoly::summand summand;
1858 //     const summand* gterm = AsWeylPoly(x).mySummands;
1859 //     const summand* hterm = AsWeylPoly(y).mySummands;
1860 //     summand* SpareSummand = InitSummand(AllocSummand()); // just sets coeff = 0
1861 //     while (gterm != null && hterm != nullptr)
1862 //     {
1863 //       const int cmp = ordering(myPPM).CmpOrdvs(gterm->myOrdv, hterm->myOrdv);
1864 
1865 //       if (cmp < 0)
1866 //       {
1867 // 	summand* hcopy = CopySummand(hterm);
1868 // 	PushBack(ans, hcopy);
1869 // 	hterm = hterm->myNext;
1870 // 	continue;
1871 //       }
1872 
1873 //       if (cmp > 0)
1874 //       {
1875 // 	summand* gcopy = CopySummand(gterm);
1876 // 	PushBack(ans, gcopy);
1877 // 	gterm = gterm->myNext;
1878 // 	continue;
1879 //       }
1880 
1881 //       // Must have cmp == 0 here.
1882 //       // The leading PPs are the same, so we must sum the coeffs.
1883 //       R.add(SpareSummand->myCoeff, gterm->myCoeff, hterm->myCoeff);
1884 //       if (!R.IsZero(SpareSummand->myCoeff))
1885 //       {
1886 // 	SetSummandMOrdv(SpareSummand, gterm); // set module posn and PP
1887 // 	PushBack(ans, SpareSummand);
1888 // 	SpareSummand = InitSummand(AllocSummand());// just sets coeff = 0
1889 //       }
1890 //       gterm = gterm->myNext;
1891 //       hterm = hterm->myNext;
1892 //     }
1893 //     while (gterm != nullptr)
1894 //     {
1895 //       summand* gcopy = CopySummand(gterm);
1896 //       PushBack(ans, gcopy);
1897 //       gterm = gterm->myNext;
1898 //     }
1899 //     while (hterm != nullptr)
1900 //     {
1901 //       summand* hcopy = CopySummand(hterm);
1902 //       PushBack(ans, hcopy);
1903 //       hterm = hterm->myNext;
1904 //     }
1905 //     DeleteSummands(SpareSummand); // next ptr will be zero (set by InitSummand)
1906 //     swap(lhs, ans); // really an assignment
1907 //     kill(ans);
1908 //   }
1909 
1910 
1911 //   void RingExtAlgImpl::sub(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const
1912 //   {
1913 //     // This code copied from RingExtAlgImpl::add...
1914 
1915 //     const AbstractRing& R = myCoeffRing;
1916 //     RawValue ans;
1917 //     //    ans.WeylPolyPtr = static_cast<WeylPoly*>(myWeylPolyPool.alloc(sizeof(WeylPoly)));
1918 //     init(ans);
1919 //     ///    WeylPoly& sum = AsWeylPoly(ans);
1920 //     typedef WeylPoly::summand summand;
1921 //     const summand* gterm = AsWeylPoly(x).mySummands;
1922 //     const summand* hterm = AsWeylPoly(y).mySummands;
1923 //     summand* SpareSummand = InitSummand(AllocSummand()); // just sets coeff = 0
1924 //     while (gterm != nullptr && hterm != nullptr)
1925 //     {
1926 //       const int ord = ordering(myPPM).CmpOrdvs(gterm->myOrdv, hterm->myOrdv);
1927 
1928 //       if (ord < 0)
1929 //       {
1930 // 	summand* hcopy = CopySummand(hterm);
1931 // 	R.negate(hcopy->myCoeff, hcopy->myCoeff);
1932 // 	//	sum.push_front(hcopy);
1933 // 	PushBack(ans, hcopy);
1934 // 	hterm = hterm->myNext;
1935 // 	continue;
1936 //       }
1937 
1938 //       if (ord > 0)
1939 //       {
1940 // 	summand* gcopy = CopySummand(gterm);
1941 // 	//	sum.push_front(gcopy);
1942 // 	PushBack(ans, gcopy);
1943 // 	gterm = gterm->myNext;
1944 // 	continue;
1945 //       }
1946 
1947 //       // The leading PPs are the same, so we must sum the coeffs.
1948 //       R.sub(SpareSummand->myCoeff, gterm->myCoeff, hterm->myCoeff);
1949 //       if (!R.IsZero(SpareSummand->myCoeff))
1950 //       {
1951 // 	SetSummandMOrdv(SpareSummand, gterm); // set module posn and PP
1952 // 	//	sum.push_front(SpareSummand);
1953 // 	PushBack(ans, SpareSummand);
1954 // 	SpareSummand = InitSummand(AllocSummand());// just sets coeff = 0
1955 //       }
1956 //       gterm = gterm->myNext;
1957 //       hterm = hterm->myNext;
1958 //     }
1959 //     while (gterm != nullptr)
1960 //     {
1961 //       summand* gcopy = CopySummand(gterm);
1962 //       //      sum.push_front(gcopy);
1963 //       PushBack(ans, gcopy);
1964 //       gterm = gterm->myNext;
1965 //     }
1966 //     while (hterm != nullptr)
1967 //     {
1968 //       summand* hcopy = CopySummand(hterm);
1969 //       //      sum.push_front(hcopy);
1970 //       R.negate(hcopy->myCoeff, hcopy->myCoeff);
1971 //       PushBack(ans, hcopy);
1972 //       hterm = hterm->myNext;
1973 //     }
1974 //     DeleteSummands(SpareSummand); // next ptr will be zero (set by InitSummand)
1975 //     /// NO LONGER NEEDED    sum.reverse();
1976 //     swap(lhs, ans); // really an assignment
1977 //     kill(ans);
1978 //   }
1979 
1980 
1981 //   void RingExtAlgImpl::mul(RawPtr rawlhs, ConstRawPtr rawx, ConstRawPtr rawy) const
1982 //   {
1983 // // NO!! NOT COMMUTATIVE!!    if (NumTerms(x) > NumTerms(y)) { mul(lhs, y, x); return; }
1984 
1985 // ////    std::clog << "MUL on "; output(std::clog, x); std::clog << " and "; output(std::clog, y); std::clog << endl;
1986 //     RingElem ans(*this);
1987 
1988 //     for (const WeylPoly::summand* xterm = AsWeylPoly(x).mySummands; xterm; xterm = xterm->myNext)
1989 //       AddMul(raw(ans), xterm, y, false);//?????
1990 
1991 //     swap(raw(ans), lhs); // really an assignment
1992 //   }
1993 
1994 
1995 
1996 
1997 
1998 // RCS header/log in the next few lines
1999 // $Header: /Volumes/Home_1/cocoa/cvs-repository/CoCoALib-0.99/src/AlgebraicCore/RingExtAlg.C,v 1.14 2020/06/17 15:49:26 abbott Exp $
2000 // $Log: RingExtAlg.C,v $
2001 // Revision 1.14  2020/06/17 15:49:26  abbott
2002 // Summary: Changed CoCoA_ERROR into CoCoA_THROW_ERROR
2003 //
2004 // Revision 1.13  2020/02/12 09:01:47  bigatti
2005 // -- changed myTestIsMaximal etc to return void (and consequences)
2006 //
2007 // Revision 1.12  2020/02/11 16:56:41  abbott
2008 // Summary: Corrected last update (see redmine 969)
2009 //
2010 // Revision 1.11  2020/02/11 16:12:19  abbott
2011 // Summary: Added some checks for bad ostream (even to mem fns myOutput); see redmine 969
2012 //
2013 // Revision 1.10  2019/10/15 11:54:08  abbott
2014 // Summary: Changed 0 into nullptr (where appropriate)
2015 //
2016 // Revision 1.9  2019/03/04 16:16:07  abbott
2017 // Summary: Changed auto_ptr into unique_ptr
2018 //
2019 // Revision 1.8  2018/06/27 08:50:39  abbott
2020 // Summary: Revised to work with new CpuTimeLimit
2021 //
2022 // Revision 1.7  2018/05/25 09:24:46  abbott
2023 // Summary: Major redesign of CpuTimeLimit (many consequences)
2024 //
2025 // Revision 1.6  2018/05/18 12:15:56  bigatti
2026 // -- renamed IntOperations --> BigIntOps
2027 //
2028 // Revision 1.5  2018/05/17 15:41:33  bigatti
2029 // -- renamed MatrixOperations --> MatrixOps
2030 //
2031 // Revision 1.4  2018/04/18 14:31:23  abbott
2032 // Summary: Added some missing returns (in NYI fns)
2033 //
2034 // Revision 1.3  2018/03/29 09:36:40  bigatti
2035 // -- added member functions myTestIsRadical, myTestIsPrimary and flags
2036 //
2037 // Revision 1.2  2018/03/20 11:38:08  bigatti
2038 // -- changed iAm***Test --> myTestIs***;  and it returns bool
2039 //
2040 // Revision 1.1  2018/01/31 10:01:29  abbott
2041 // Summary: Added new files RingExtAlg (exterior algebra)
2042 //
2043 //
2044