1 #ifndef CoCoA_JBDatastructure_H
2 #define CoCoA_JBDatastructure_H
3 
4 //   Copyright (c)  2015 Mario Albert
5 
6 //   This file is part of the source of CoCoALib, the CoCoA Library.
7 
8 //   CoCoALib is free software: you can redistribute it and/or modify
9 //   it under the terms of the GNU General Public License as published by
10 //   the Free Software Foundation, either version 3 of the License, or
11 //   (at your option) any later version.
12 
13 //   CoCoALib is distributed in the hope that it will be useful,
14 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //   GNU General Public License for more details.
17 
18 //   You should have received a copy of the GNU General Public License
19 //   along with CoCoALib.  If not, see <http://www.gnu.org/licenses/>.
20 
21 #include <list>
22 #include "CoCoA/SparsePolyOps-RingElem.H"
23 //#include "CoCoA/SparsePolyRing.H" // from SparsePolyOps-RingElem.H
24 
25 namespace CoCoA {
26   namespace Involutive {
27 
28     //forward Declaration
29     class JanetIterator;
30 
31     /****************************************************************************************************************************/
32     /* This class stores the JanetTriple. It contains the myPolynomial
33      * p, its ancestor, and its already prolonged variables
34      */
35     /*****************************************************************************************************************************/
36     class JanetTriple {
37     public:
38       /**
39        * The constructor of the JanetTriple.
40        * @param pol a RingElem for the polynomial
41        * @param anc a PPMonoid for the ancestor
42        * The JanetTriple doesn't contain any already prolonged variables
43        **/
JanetTriple(ConstRefRingElem pol,ConstRefPPMonoidElem anc)44       JanetTriple(ConstRefRingElem pol, ConstRefPPMonoidElem anc)
45           : myPolynomial(pol),
46             myAncestor(anc),
47             myAlreadyProlongedVars(NumIndets(owner(pol)), false)
48       {
49       }
50 
51       /**
52        * The constructor of the JanetTriple.
53        * @param pol a RingElem for the polynomial
54        * The ancestor is the LPP of polynomial.
55        * The JanetTriple doesn't contain any already prolonged variables
56        **/
JanetTriple(ConstRefRingElem pol)57       JanetTriple(ConstRefRingElem pol)
58           : myPolynomial(pol),
59             myAncestor(LPP(pol)),
60             myAlreadyProlongedVars(NumIndets(owner(pol)), false)
61       {
62       }
63 
64       /** The constructor of the JanetTriple
65        *	@param pol the new polynomial
66        *	@param anc the new ancestor
67        *	@param nm the already prolonged variables as std::vector<bool>
68        */
JanetTriple(ConstRefRingElem pol,ConstRefPPMonoidElem anc,std::vector<bool> nm)69       JanetTriple(ConstRefRingElem pol, ConstRefPPMonoidElem anc, std::vector<bool> nm)
70           : myPolynomial(pol),
71             myAncestor(anc),
72             myAlreadyProlongedVars(nm)
73       {
74       }
75 
76       /**
77        * This function changes the polynomial of the JanetTriple
78        * @param pol the new polynomial
79        */
mySetPol(ConstRefRingElem pol)80       inline void mySetPol(ConstRefRingElem pol) {
81         CoCoA_ASSERT(LPP(myPolynomial) == LPP(pol));
82         myPolynomial = pol;
83       }
84 
85       /**
86        * This function changes the ancestor of the JanetTriple
87        * @param anc the the ancestor
88        */
mySetAnc(ConstRefPPMonoidElem anc)89       inline void mySetAnc(ConstRefPPMonoidElem anc) {
90         myAncestor = anc;
91       }
92 
93       /**
94        * This function sets a already prolonged variable
95        * @param index is the index of the variable which was already prolonged
96        * If the variable is already prolonged, nothing will happen
97        */
myVarIsProlonged(const long & index)98       inline void myVarIsProlonged(const long& index) {
99         myAlreadyProlongedVars[index] = true;
100       }
101 
102       /**
103        * This function sets a already prolonged variable to not prolonged
104        * @param index becomes not prolonged
105        * If the variable is not prolonged, nothing will happen
106        */
myVarIsNotProlonged(const long & index)107       inline void myVarIsNotProlonged(const long& index) {
108         myAlreadyProlongedVars[index] = false;
109       }
110 
111       /**
112        * LPP of myPolynomial
113        */
myGetLppPol()114       ConstRefPPMonoidElem myGetLppPol() const {
115         return static_cast<const SparsePolyRingBase*>(owner(myPolynomial).myRawPtr())->myLPP(raw(myPolynomial));
116         // return const_cast<SparsePolyRingBase*>(owner(myPolynomial))->myLPP(raw(myPolynomial));
117         // return AsSparsePolyRing(owner(myPolynomial))->myLPP(raw(myPolynomial));
118       }
119 
120       /**
121        * This function returns the current polynomial as RingElem
122        */
myGetPol()123       inline RingElem& myGetPol() {
124         return myPolynomial;
125       }
126 
myGetPol()127       inline const RingElem& myGetPol() const {
128         return myPolynomial;
129       }
130 
131       /**
132        *This function returns a pointer to the current polynomial
133        */
myGetPolPtr()134       inline RingElem* myGetPolPtr() {
135         return &myPolynomial;
136       }
137 
myGetPolPtr()138       inline const RingElem* myGetPolPtr() const {
139         return &myPolynomial;
140       }
141       /**
142        * This function returns the current ancestor as PPMonoidElem
143        */
myGetAnc()144       inline const PPMonoidElem& myGetAnc() const {
145         return myAncestor;
146       }
147 
148       /**
149        * This function checks if a variable is already prolonged
150        * @param index is the index of the variable which shall be checked
151        * returns true if the variable is already prolonged
152        */
IamProlonged(const long & index)153       inline bool IamProlonged(const long& index) const {
154         return myAlreadyProlongedVars[index];
155       }
156 
157       /**
158        * This function sets all variables to not already prolonged
159        */
160       void myClearProlongedVars();
161 
162     private:
163       friend struct isLower;
164       friend struct IsLowerLPP;
165       friend class TQSets;
166 
167       /**
168        * The polynomial of the Janet-Triple.
169        */
170       RingElem myPolynomial;
171 
172       /**
173        * The ancestor of the polynomial.
174        */
175       PPMonoidElem myAncestor;
176 
177       /**
178        * The already prolonged variables of the polynomial
179        */
180       std::vector<bool> myAlreadyProlongedVars;
181 
182     };
183 
184     typedef std::list<JanetTriple>::iterator nodeData;
185 
186 #if __cplusplus <= 199711L
187     class JanetHandle;
188 #else
189     class JanetNodeBase;
190     typedef std::shared_ptr<JanetNodeBase> JanetHandle;
191 #endif
192     /****************************************************************************************************************************/
193     /*
194      * The JanetNode are the nodes in the JanetTree. It's the father
195      * class of two different node types. In the father-class we store
196      * the varDistance and the degDistance to the next node and
197      * define some virtual functions for the child-classes (We have to
198      * do this because we use a Handle-Class to store the JanetNodes in
199      * std::lists.
200      */
201     class JanetNodeBase {
202     public:
203 
204       /**
205        * This function clone the JanetNode. You need this function for
206        * the class JanetHandle.
207        */
myClone()208       virtual inline JanetNodeBase* myClone() const {
209         CoCoA_ERROR("You don't have the permisson to deal with JanetNodes, maybe there is a mistake in the datastructure",
210                     "myClone");
211         return new JanetNodeBase(*this);
212       }
213 
214       /**
215        * Virtual destructor (further informations: C++ Primer)
216        */
~JanetNodeBase()217       virtual ~JanetNodeBase() {
218       }
219 
220       /**
221        * This function returns the degree-distance to the next
222        * degree-node
223        */
myGetDisNextDeg()224       inline long myGetDisNextDeg() const {
225         return myDisNextDeg;
226       }
227 
228       /**
229        * This function returns the variable-distance to the next
230        * variable-node
231        */
myGetDisNextVar()232       inline long myGetDisNextVar() const {
233         return myDisNextVar;
234       }
235 
236       /**
237        * This function sets the degree-distance to the next degree-node
238        * @param dis is the new degree-distance
239        */
mySetDisNextDeg(const long & dis)240       inline void mySetDisNextDeg(const long& dis) {
241         myDisNextDeg = dis;
242       }
243 
244       /**
245        * This function sets the variable-distance to the next
246        * variable-node
247        * @param dis is the new variable-distance
248        * maybe protected and a new virtual function so that JanetLeafNodeImpl can't
249        * set another distance
250        */
mySetDisNextVar(const long & dis)251       inline void mySetDisNextVar(const long& dis) {
252         myDisNextVar = dis;
253       }
254 
255       /**
256        * only a virtual function. You need this function in the class
257        * JanetInternalNode
258        */
myNextVarArm()259       virtual inline std::list<JanetHandle>* myNextVarArm() {
260         CoCoA_ERROR("You don't have the permisson to deal with JanetNodes, maybe there is a mistake in the datastructure",
261                     "myNextVarArm");  //??remove in the final version??
262         return nullptr;
263       }
264 
265       /**
266        * only a virtual function. You need this function in both child
267        * classes
268        */
IamLeafNode()269       virtual inline bool IamLeafNode() {
270         return false;
271       }
272 
273       /**
274        * only a virtual function. You need this function in the class
275        * JanetInternalNode
276        * Warnings because I don't use nextArm
277        */
mySetNextVarArm(const std::list<JanetHandle> &)278       virtual inline void mySetNextVarArm(const std::list<JanetHandle>& /*NextArm*/) {
279         CoCoA_ERROR("You don't have the permisson to deal with JanetNodes, maybe there is a mistake in the datastructure",
280                     "mySetNextVarArm");
281       }
282 
283     protected:
284       /**
285        * The constructor of the JanetNode. The constructor is proteced
286        * because the user shall not use this class
287        * @param deg set the distance to the next degree-node
288        * @param var set the distance to the next var-node
289        * @param newTriple set the JanetTriple in the node
290        */
JanetNodeBase(const long & deg,const long & var)291       JanetNodeBase(const long& deg, const long& var)
292           : myDisNextDeg(deg),
293             myDisNextVar(var) {
294       }
295 
296       /**
297        * the degree-distance to the next degree-node in the
298        * JanetTree. If the distance is zero there is no next
299        * degree-node in the JanetTree
300        */
301       long myDisNextDeg;
302 
303       /**
304        * the variable-distance to the next variable-node in the
305        * JanetTree. If the distance is zero there is no next
306        * variable-node in the JanetTree
307        */
308       long myDisNextVar;
309     };
310 
311     /***********************************************************************************************************************************/
312     /** \brief A child-class of JanetNode. In the JanetTree this class
313      * represents the leaf nodes
314      *
315      * The class represents the leaf nodes in the JanetTree. The class
316      * contains the variables disNextDeg and disNextVar from the
317      * father-class JanetNode and a JanetTriple as nodeData
318      */
319     class JanetLeafNodeImpl : public JanetNodeBase {
320     public:
321       /**
322        * The constructor of the JanetLeafNode
323        * @param newTriple is the triple of the JanetLeafNode
324        * disNextVar and disNextDeg is set to zero
325        */
JanetLeafNodeImpl(const nodeData newTriple)326       JanetLeafNodeImpl(const nodeData newTriple)
327           : JanetNodeBase(0, 0),
328             myTriple(newTriple)  //, triple(newTriple)
329       {
330       }
331 
332       /**
333        * This function clones the JanetNode. You need this function for
334        * the class JanetHandle.
335        */
myClone()336       inline JanetLeafNodeImpl* myClone() const {
337         return new JanetLeafNodeImpl(*this);
338       }
339 
340       /**
341        *This function returns a pointer on the JanetTriple.
342        */
myGetTriplePtr()343       inline JanetTriple* myGetTriplePtr() {
344         return &(*myTriple);
345       }
346 
myGetTriple()347       inline JanetTriple& myGetTriple() {
348         return *myTriple;
349       }
350 
myGetTripleListPointer()351       inline nodeData myGetTripleListPointer() {
352         return myTriple;
353       }
354 
355       /**
356        * This function returns always true. It checks if the node is a
357        * leafNode
358        */
IamLeafNode()359       inline bool IamLeafNode() {
360         return true;
361       }
362 
363       /**
364        * only dummy function which we don't need in this class. We
365        * return an empty arm
366        */
myNextVarArm()367       inline std::list<JanetHandle>* myNextVarArm() {
368         CoCoA_ERROR(
369             "You don't have the permisson to deal with arms in JanetLeafNodes, maybe there is a mistake in the datastructure",
370             "myNextVarArm");  //??maybe remove this in the final version??
371         return nullptr;
372       }
373 
374       /**
375        * only dummy function which we don't need in this class. If it
376        * isn't a leaf node then it set's a new arm
377        * !!WARNING because we don't need nextArm!!
378        */
mySetNextVarArm(const std::list<JanetHandle> &)379       inline void mySetNextVarArm(const std::list<JanetHandle>& /*NextArm*/) {
380         CoCoA_ERROR(
381             "You don't have the permisson to deal with arms JanetLeafNodes, maybe there is a mistake in the datastructure",
382             "mySetNextVarArm");
383       }
384 
385     private:
386       /**
387        *Stores the data for the leaf nodes. It is an iterator of a list
388        *where we store the janet triples.
389        */
390       nodeData myTriple;
391     };
392 
393     /***********************************************************************************************************************************/
394     /** \brief A child-class of JanetNode. In the JanetTree this class
395      * represent the internal nodes
396      *
397      * The class represents the internal nodes in the JanetTree. The
398      * class contains the data of the janetsubtree in var direction
399      */
400     class JanetInternalNodeImpl : public JanetNodeBase {
401     public:
402 
403       /**
404        * the constructor of the class JanetInternalNode. It initializes
405        * an empty arm of the JanetTree. The arm represents the
406        * degree-direction in the next variable
407        */
JanetInternalNodeImpl()408       JanetInternalNodeImpl(/*const SparsePolyRing& polyRing*/)
409           : JanetNodeBase(0, 0),
410             myArm() {
411       }
412 
413       /**
414        * This function clones the JanetInternalNode. You need this function for
415        * the class JanetHandle.
416        */
myClone()417       inline JanetInternalNodeImpl* myClone() const {
418         return new JanetInternalNodeImpl(*this);
419       }
420 
421       /**
422        * This function returns a pointer to the degree-arm in the next
423        * variable
424        */
myNextVarArm()425       inline std::list<JanetHandle>* myNextVarArm() {
426         return &myArm;
427       }
428 
429       /**
430        * This function checks if there is a node which is a leafNode and returns
431        * false because it is an internal node
432        */
IamLeafNode()433       inline bool IamLeafNode() {
434         return false;
435       }
436 
437       /**
438        * This function replaces the next degree-arm with a new one
439        */
mySetNextVarArm(const std::list<JanetHandle> & NextArm)440       inline void mySetNextVarArm(const std::list<JanetHandle>& NextArm) {
441         myArm = NextArm;
442       }
443 
444     private:
445 
446       /**
447        * The list where we store the next nodes in var direction
448        */
449       std::list<JanetHandle> myArm;
450 
451     };
452 
453 
454     /**************************************************************************************************************************************/
455     /**
456      * \brief a Handle-Class for the JanetNodes. Therefore we can
457      * construct a list of different JanetNodes
458      *
459      * With this class we can construct a list of different
460      * JanetNodes. It defines several constructers, a destructor and
461      * overload the following operators: "*", "->"
462      * The class uses reference-counting of pointers
463      * Template: C++ Primer
464      */
465 #if __cplusplus <= 199711L
466     class JanetHandle {
467     public:
468       /**
469        * The default constructer. It constructs a null-pointer and
470        * initializes the counter with one
471        * useless?
472        */
JanetHandle()473       JanetHandle()
474           : myPtr(nullptr),
475             myUse(new long(1)) {
476       }
477 
478       /**
479        * Another constructor which constructs a Handle with a JanetNode.
480        * @param node is pointed by the Handle
481        * Here we use the clone()-functions of the JanetNode and we initzialize the
482        * reference counter with one
483        */
JanetHandle(const JanetNodeBase & node)484       JanetHandle(const JanetNodeBase& node)
485           : myPtr(node.myClone()),
486             myUse(new long(1)) {
487       }
488 
JanetHandle(JanetNodeBase * NodePtr)489       JanetHandle(JanetNodeBase* NodePtr)
490           : myPtr(NodePtr),
491             myUse(new long(1)) {
492       }
493 
494       /**
495        * The copy-constructor
496        **/
JanetHandle(const JanetHandle & handle)497       JanetHandle(const JanetHandle& handle)
498           : myPtr(handle.myPtr),
499             myUse(handle.myUse) {
500         ++(*myUse);
501       }
502 
503       /**
504        * The destructor. It uses the function decrUse()
505        **/
~JanetHandle()506       ~JanetHandle() {
507         myDecrUse();
508       }
509 
510       /*
511        * The assignment operator
512        */
513       JanetHandle& operator=(const JanetHandle& rhs) {
514         ++*rhs.myUse;
515         myDecrUse();
516         myPtr = rhs.myPtr;
517         myUse = rhs.myUse;
518         return *this;
519       }
520 
521       /**
522        * This function overloads the "->"-operator (implicit inline)
523        */
524       JanetNodeBase* operator->() const {
525         if (!myPtr)
526           CoCoA_ERROR("unbound JanetHandle", "operator->");
527         return myPtr;
528       }
529 
530       /**
531        * This function overloads the "*"-operator (implicit inline)
532        */
533       JanetNodeBase& operator*() const {
534         if (myPtr == nullptr)
535           CoCoA_ERROR("unbound JanetHandle", "operator*");
536         return *myPtr;
537       }
538 
get()539       JanetNodeBase* get() const {
540         return myPtr;
541       }
542 
543     private:
544       /**
545        * the "really" destructor. If the reference-counter is unequal to
546        * zero it only decreases the counter. If the counter is zero it
547        * deletes the object.
548        */
549       void myDecrUse();
550 
551       /**
552        * Pointer to the JanetNode
553        */
554       JanetNodeBase *myPtr;
555       /**
556        * Pointer to the counter
557        */
558       long *myUse;
559     };
560 #endif
561     /*************************************************************************************************************************************/
562     /**
563      * \brief The JanetTree.
564      *
565      * This class stores only the beginning of the tree. The rest of the
566      * tree is stored in the JanetInternalNodes
567      */
568 
569     class JanetTree {
570     public:
571       /**
572        * The constructor. The constructor initializes a list with one Element. The element is a JanetInternalNode.
573        * @param deg is the beginning degree of the tree
574        * @param var is the beginning variable of the tree
575        */
JanetTree(const SparsePolyRing & PolyRing,const long & deg,const long & var)576       JanetTree(const SparsePolyRing& PolyRing, const long& deg, const long& var)
577           : myArm(),
578             myBeginDeg(deg),
579             myBeginVar(var),
580             myPolyRing(PolyRing)
581       {
582         myArm.push_back(JanetHandle(new JanetInternalNodeImpl()));
583       }
584 
JanetTree(const SparsePolyRing & PolyRing)585       JanetTree(const SparsePolyRing& PolyRing)
586           : myArm(),
587             myBeginDeg(0),
588             myBeginVar(0),
589             myPolyRing(PolyRing)
590       {
591         myArm.push_back(JanetHandle(new JanetInternalNodeImpl()));
592       }
593 
594       /**
595        * Returns the whole rootArm as std::list<JanetHandle>
596        * JanetIterator needs this function
597        */
myGetRootArm()598       inline std::list<JanetHandle>* myGetRootArm() {
599         return &myArm;
600       }
601 
602       /**
603        * Same as above, but readonly
604        */
myGetRootArm()605       inline std::list<JanetHandle>* myGetRootArm() const {
606         return const_cast<std::list<JanetHandle> *>(&myArm);
607       }
608 
609       /**
610        * Returns the beginning degree of the tree
611        */
myGetBeginDeg()612       inline long myGetBeginDeg() const {
613         return myBeginDeg;
614       }
615 
616       /**
617        *Returns the beginning variable of the tree
618        */
myGetBeginVar()619       inline long myGetBeginVar() const {
620         return myBeginVar;
621       }
622 
623       /**
624        *Returns the polyRing of the tree
625        */
myGetPolyRing()626       inline const SparsePolyRing& myGetPolyRing() const {
627         return myPolyRing;
628       }
629 
630       /**
631        *Deletes the content of the tree, but not the tree itself.
632        *Attention: the polyRing remains!
633        */
myDelete()634       inline void myDelete() {
635         myArm.clear();
636         myArm.push_back(JanetHandle(new JanetInternalNodeImpl()));
637       }
638 
639       /**
640        * myJInsertWithoutProlong insert the JanetTriple ps into the JanetTree JTree but doesn't perform any prolongations
641        * @param JTree the JanetTree where we insert the triple
642        * @param ps    the Itertor to the triple which we want to insert
643        */
644       void myInsert(const nodeData& ps);
645 
646 
647       void myJTailNormalForm(RingElem& elem);
648 
649       void myJHeadNormalForm(RingElem& elem);
650 
651       void myJFullNormalForm(RingElem& elem);
652 
653       // TODO: Buggy!!!!!!!
654       // TODO: Remove me, it is only used three times in easier usecases!
655       /**
656        * Delete the current JanetTree and add the new JanetTree
657        * @param tree the new JanetTree
658        * Only works if current Tree is empty!!!
659        */
660       void myAddAtBegin(JanetTree& tree);
661 
662       JanetTriple* myJDivisor(ConstRefPPMonoidElem w) const;
663 
664       /**
665        * Check whether the PPMonidElem is at the tree
666        */
667       bool IamInternalNode(ConstRefPPMonoidElem w) const;
668 
669       /**
670        * Insert a JanetTriple onto the tree i.e. a part of the tree will be deleted
671        * It returns the iterators of the deleted nodes
672        */
673       std::vector<nodeData> myInsertInTreeStructure(const nodeData& triple);
674 
675       /**
676        * Check whether the JanetTree is empty
677        * @return true if the JanetTree is empty
678        */
IamEmpty()679       inline bool IamEmpty() const
680       {
681         return myArm.empty();
682       }
683 
684       /**
685        * myOneLeafTree create a JanetTree from w (with starting variable i) to ps
686        * @param  ps is an iterator to a JanetTriple
687        * @param  i  is the starting variable
688        * @param  w  is the starting monomial
689        * @return returns the JanetTree which is beginning in m and ending in ps
690        */
691       static JanetTree OneLeafTree(const SparsePolyRing& polyRing, const std::list<JanetTriple>::iterator& ps, long i,
692                                    PPMonoidElem w);
693     private:
694       /**
695        * The first degree arm of the JanetTree
696        */
697       std::list<JanetHandle> myArm;
698 
699       /**
700        * The beginning degree of the JanetTree
701        */
702       long myBeginDeg;
703 
704       /**
705        * The beginning variable of the JanetTree
706        */
707       long myBeginVar;
708 
709       /**
710        * The polyRing of the Tree
711        */
712       // const SparsePolyRing myPolyRing;
713       SparsePolyRing myPolyRing;
714 
715       /**
716        * only declaration, there isn't a definition because we can't
717        * copy the tree
718        * Nobody shall use this operator, therefore private
719        */
720       // JanetTree& operator=(const JanetTree &);
721     };
722 
723     /*************************************************************************************************************************************/
724     /**
725      * \brief With an object of JanetIterator we can navigate through
726      * the JanetTreẹ
727      *
728      * I try to programm this class similar to the STL (because of the
729      * tree-structure I had to add some extra functionalities)
730      *
731      * After thinking about it: I guess, the only similarity is the name ;-)
732      */
733     class JanetIterator {
734     public:
735 
736       /**
737        * The constructor of the JanetIterator
738        * @param tree is the JanetTree where the Iterator navigates through
739        */
JanetIterator(const JanetTree & tree)740       JanetIterator(const JanetTree &tree)
741           : myCurTree(&tree),
742             myCurArm(tree.myGetRootArm()),
743             myMonomial(NumIndets(tree.myGetPolyRing())),
744             myCurVar(tree.myGetBeginVar()) {
745         // myCurTree = &tree;
746         myCurIter = myCurArm->begin();
747         myMonomial[myCurVar] = tree.myGetBeginDeg();
748       }
749 
750       /**
751        * Changes the type of node
752        * @param triple is the new Triple in the LeafNode
753        *
754        * Changes any kind of node in a leaf node.  This function deletes
755        * all the nodes behind the current node
756        */
757       void myChangeToLeafNode(const nodeData triple);
758 
759       /**
760        * This function sets the iterator on the next degree-node and
761        * returns the degree-distance.  If it returns 0 then there is no
762        * next node
763        */
764       long myNextDeg();
765 
766       /**
767        * This function set the iterator on the next variable-node and
768        * returns the variable-distance.  If it returns 0 then there is no
769        * next node
770        */
771       long myNextVar();
772 
773       /**
774        * This function returns the current degree of the current
775        * variable on which the iterator points
776        */
myCurrentDeg()777       inline long myCurrentDeg() const {
778         return myMonomial[myCurVar];
779       }
780 
781       /**
782        * This function returns the current variable on which the iterator points
783        */
myCurrentVar()784       inline long myCurrentVar() const {
785         return myCurVar;
786       }
787 
788       /**
789        * This function sets a new variable-node. This node is an
790        * internal-node
791        *
792        * If there is another node in this direction, this node lies
793        * behind the new node.  If the variable-distance of
794        * the next node is lower or equal to dis then
795        * this node will be deleted
796        *
797        * If the current node is a leaf Node we change this node
798        * into an internal node
799        *
800        * @param dis is the variable distance between the current
801        * and the new node
802        */
803       void mySetNextVar(long dis);
804 
805       /**
806        * This function sets a new degree-node. This node is an
807        * internal-node
808        *
809        * If there is another node in this direction then the new  node lies
810        * between the current node and this node.  If the degree-distance of
811        * the next node is lower or equal to dis
812        * this node will be deleted and the new node will be inserted.
813        *
814        * ?? There is an assertion where we check if it isn't a leaf Node ??
815        *
816        * @param dis is the degree distance between the current node and
817        * the new node
818        */
819       void mySetNextDeg(long dis);
820 
821       /**
822        * This function connects two JanetTrees
823        *
824        * tree is appended on the current postion of the
825        * iterator in deg-direction. The tree will be copied after this position in degree
826        * direction.
827        *
828        * ?? WARNING: NO TESTS IF THE CONNECTION MAKES SENSE ??
829        * Shall I warn?
830        *
831        * @param tree is the JanetTree which shall be connect with the current tree
832        */
833       void myConnectJanetTreeDeg(JanetTree& tree);
834 
835       /**
836        * Checks if current Node is a leaf node
837        */
IamLeafNode()838       inline bool IamLeafNode() const {
839         return (*myCurIter)->IamLeafNode();
840       }
841 
842       /**
843        * This function sets a nonMultiplicative variable
844        *
845        * This functions sets the varibale only if we are in a leaf
846        * node. Then it returns true. If we are in a internal node
847        * we do nothing and return false
848        *
849        * @param index is the index of the variable which we want to set
850        */
851       bool IamSetNM(const long &index);
852 
853       /**
854        * This function returns the current polynomial of the current
855        * JanetTriple as RingElem
856        */
myGetPol()857       inline const RingElem& myGetPol() const {
858         CoCoA_ASSERT(IamLeafNode());
859         JanetLeafNodeImpl* node(dynamic_cast<JanetLeafNodeImpl*>(myCurIter->get()));
860         CoCoA_ASSERT(node != nullptr);
861 
862         return node->myGetTriple().myGetPol();
863       }
864 
865       /**
866        * This function returns the current ancestor of the current
867        * JanetTriple as PPMonoidElem
868        */
myGetAnc()869       inline PPMonoidElem myGetAnc() const {
870         CoCoA_ASSERT(IamLeafNode());
871         JanetLeafNodeImpl* node(dynamic_cast<JanetLeafNodeImpl*>(myCurIter->get()));
872         CoCoA_ASSERT(node != nullptr);
873 
874         return node->myGetTriple().myGetAnc();
875       }
876 
877       /**
878        * This function checks if a variable is already prolonged
879        *
880        * If the variable is prolonged we return true
881        * otherwise false
882        *
883        * @param index: The variable with the index which we test
884        */
IamProlonged(const long & index)885       inline bool IamProlonged(const long &index) const {
886         CoCoA_ASSERT(IamLeafNode());
887         JanetLeafNodeImpl* node(dynamic_cast<JanetLeafNodeImpl*>(myCurIter->get()));
888         CoCoA_ASSERT(node != nullptr);
889 
890         return node->myGetTriple().IamProlonged(index);
891       }
892 
893       /**
894        * The iterator returns to the beginning of the JanetTree
895        */
896       void myReturnToBegin();
897 
898       /**
899        * This function checks if current node is a leaf node
900        */
IamLeafNode()901       inline bool IamLeafNode(){
902         return (*myCurIter)->IamLeafNode();
903       }
904 
905       /**
906        * This function returns the distance to the next degNode. If
907        * there is no deg node the function returns zero
908        */
myDisNextDeg()909       inline long myDisNextDeg() const {
910         return (*myCurIter)->myGetDisNextDeg();
911       }
912 
913       /**
914        * This function returns the distance to the next varNode. If
915        * there is no deg node the function returns zero
916        */
myDisNextVar()917       inline long myDisNextVar() const {
918         return (*myCurIter)->myGetDisNextVar();
919       }
920 
921       /**
922        * The iterator jumps to the previous degNode. If there is no
923        * previous degNode this function returns the current node
924        */
925       long myPrevDeg();
926 
927       /**
928        *Returns the current monomial
929        */
myGetMonomial()930       inline PPMonoidElem myGetMonomial() const {
931         return PPMonoidElem(PPM(myCurTree->myGetPolyRing()), myMonomial);
932       }
933 
934       /**
935        * Returns the highest Iterator starting from current node
936        *
937        */
938       JanetIterator myGotoHighestNode();
939 
940       std::vector<nodeData> myAllNodesAboveMeIncludingMe() const;
941     private:
942 
943       /**
944        * A pointer to the tree on which the iterator works
945        */
946       const JanetTree* myCurTree;
947 
948       /**
949        * A pointer on the arm on which the iterator is working at the
950        * moment
951        */
952       std::list<JanetHandle>* myCurArm;
953 
954       /**
955        * The iterator which points at the current node
956        */
957       std::list<JanetHandle>::iterator myCurIter;
958 
959       /**
960        * The current monomial which we have at the current position
961        */
962       std::vector<long> myMonomial;
963 
964       /**
965        * The current variable
966        */
967       long myCurVar;
968 
969     };
970 
971     /*
972      * This class contains the Janet Tree and a list of JanetTriples
973      * The Janet Tree contains iterators to this list
974      * The class couples the Janet Tree to a corresponding list of JanetTriples
975      */
976     class JanetContainer {
977     public:
978       /*
979        * Constructor: It takes the polynomial ring of the Janet Tree and initializes
980        * a new tree with the same polynomial ring. After that it inserts all triples
981        * from list. Beside the polynomial ring we do not use the JanetTree
982        */
JanetContainer(const JanetTree & tree,const std::list<JanetTriple> & list)983       JanetContainer(const JanetTree& tree, const std::list<JanetTriple>& list)
984           : myTree(tree.myGetPolyRing())
985       {
986         myList.insert(myList.begin(), list.begin(), list.end());
987         myInitializeTreeFromList();
988       }
989 
990       /*
991        * Constructor: It initializes a new tree with the polynomial ring. After
992        * that it inserts all triples from list.
993        */
JanetContainer(const SparsePolyRing & ring,const std::list<JanetTriple> & list)994       JanetContainer(const SparsePolyRing& ring, const std::list<JanetTriple>& list)
995           : myTree(ring)
996       {
997         myList.insert(myList.begin(), list.begin(), list.end());
998         myInitializeTreeFromList();
999       }
1000 
1001       /*
1002        * Constructor: It initializes an empty tree with the given polynomial ring.
1003        */
JanetContainer(const SparsePolyRing & ring)1004       JanetContainer(const SparsePolyRing& ring)
1005           : myTree(ring)
1006       {
1007       }
1008 
1009       /*
1010        * Copy Constructor
1011        */
JanetContainer(const JanetContainer & orig)1012       JanetContainer(const JanetContainer& orig)
1013           : myTree(orig.myGetPolyRing())
1014       {
1015         myList.insert(myList.begin(), orig.myList.begin(), orig.myList.end());
1016         myInitializeTreeFromList();
1017       }
1018 
1019       /*
1020        * Returns an iterator to the begin of the internal list
1021        */
myListBegin()1022       std::list<JanetTriple>::iterator myListBegin()
1023       {
1024         return myList.begin();
1025       }
1026 
1027       /*
1028        * Returns a const_iterator to the begin of the internal list
1029        */
myListBegin()1030       std::list<JanetTriple>::const_iterator myListBegin() const
1031       {
1032         return myList.begin();
1033       }
1034 
1035       /*
1036        * Returns an iterator to the end of the internal list
1037        */
myListEnd()1038       std::list<JanetTriple>::iterator myListEnd()
1039       {
1040         return myList.end();
1041       }
1042 
1043       /*
1044        * Returns a const_iterator to the end of the internal list
1045       */
myListEnd()1046       std::list<JanetTriple>::const_iterator myListEnd() const
1047       {
1048         return myList.end();
1049       }
1050 
1051       /*
1052        * Returns a const reference to the internal JanetTree
1053        */
myGetTree()1054       const JanetTree& myGetTree() const
1055       {
1056         return myTree;
1057       }
1058 
1059       /*
1060        * It changes the basis to the list given by the iterators
1061        */
1062       void myChangeBasis(std::list<JanetTriple>::const_iterator newListBegin,
1063                          std::list<JanetTriple>::const_iterator newListEnd);
1064 
1065       /*
1066        * Returns the polynomial ring of the janet tree
1067        */
myGetPolyRing()1068       const SparsePolyRing& myGetPolyRing() const
1069       {
1070         return myTree.myGetPolyRing();
1071       }
1072       /*
1073        * Checks if the container represents a constant ideal
1074        */
IamConstant()1075       inline bool IamConstant() const
1076       {
1077         return IsConstant(myList.front().myGetPol());
1078       }
1079 
1080     private:
1081 
1082       std::list<JanetTriple> myList;
1083       JanetTree myTree;
1084 
1085       /*
1086        * This method inserts all elements from myList into myTree.
1087        * Attention: It does not clear myTree before inserting.
1088        */
1089       void myInitializeTreeFromList();
1090 
1091     };
1092   } // end of namespace Involutive
1093 }  // end of namespace CoCoa
1094 #endif
1095