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