source: git/kernel/f5lists.cc @ c9193a

spielwiese
Last change on this file since c9193a was c9193a, checked in by Christian Eder, 15 years ago
fixed bug: zero reduction after top reduction git-svn-id: file:///usr/local/Singular/svn/trunk@11501 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 22.7 KB
Line 
1#include "mod2.h"
2
3#ifdef HAVE_F5
4#include "kutil.h"
5#include "structs.h"
6#include "omalloc.h"
7#include "polys.h"
8#include "p_polys.h"
9#include "ideals.h"
10#include "febase.h"
11#include "kstd1.h"
12#include "khstd.h"
13#include "kbuckets.h"
14#include "weight.h"
15#include "intvec.h"
16#include "pInline1.h"
17#include "f5gb.h"
18#include "f5data.h"
19#include "f5lists.h"
20
21/*
22====================================
23functions working on the class LNode
24====================================
25*/
26
27// generating new list elements (labeled / classical polynomial / LNode view)
28LNode::LNode() {
29    data                =   NULL;
30    next                =   NULL;
31    gPrevRedCheck       =   NULL;
32}
33 LNode::LNode(LPoly* lp) {
34    data                =   lp;
35    next                =   NULL;
36    gPrevRedCheck       =   NULL;
37}
38       
39LNode::LNode(LPoly* lp, LNode* l) {
40//Print("HIER LNODE\n");
41    data                =   lp;
42    next                =   l;
43    gPrevRedCheck       =   NULL;
44}
45
46LNode::LNode(poly t, int i, poly p, Rule* r, LNode* gPCheck) {
47LPoly* lp           =   new LPoly(t,i,p,r);
48data                =   lp;
49next                =   NULL;
50gPrevRedCheck       =   gPCheck;
51}
52       
53LNode::LNode(poly t, int i, poly p, Rule* r, LNode* gPCheck, LNode* l) {
54    LPoly* lp           =   new LPoly(t,i,p,r);
55    data                =   lp;
56    next                =   l;
57    gPrevRedCheck       =   gPCheck;
58}
59
60 LNode::LNode(LNode* ln) {
61    data                =   ln->getLPoly();
62    next                =   ln->getNext();
63    gPrevRedCheck       =   NULL;
64}
65       
66LNode::~LNode() {
67    //delete next;
68    delete gPrevRedCheck;
69    delete data;   
70}
71       
72// insert new elements to the list always at the end (labeled / classical polynomial view)
73// needed for list gPrev
74LNode* LNode::insert(LPoly* lp) {
75    //Print("INSERTION: \n");
76    //Print("LAST GPREV: ");
77    //pWrite(this->getPoly());
78LNode* newElement   =   new LNode(lp, NULL);
79    this->next          =   newElement;
80    return newElement;
81}
82       
83LNode* LNode::insert(poly t, int i, poly p, Rule* r) {
84    LNode* newElement   =   new LNode(t, i, p, r, NULL, NULL);
85    this->next          =   newElement;
86    return newElement;
87}
88
89// insert new elements to the list always in front (labeled / classical polynomial view)
90// needed for sPolyList
91LNode* LNode::insertSP(LPoly* lp) {
92    LNode* newElement   =   new LNode(lp, this);
93    //Print("INSERTED IN SPOLYLIST: ");
94    //pWrite(lp->getTerm());
95    return newElement;
96}
97       
98LNode* LNode::insertSP(poly t, int i, poly p, Rule* r) {
99    LNode* newElement   =   new LNode(t, i, p, r, NULL, this);
100     //Print("INSERTED IN SPOLYLIST: ");
101  //pWrite(t);
102return newElement;
103}
104// insert new elemets to the list w.r.t. increasing labels
105// only used for the S-polys to be reduced (TopReduction building new S-polys with higher label)
106LNode* LNode::insertByLabel(poly t, int i, poly p, Rule* r) {
107    //Print("ADDING SOLYS TO THE LIST\n");
108    //Print("new element: ");
109    //pWrite(t);
110       if(NULL == this || NULL == data) {
111        LNode* newElement   =   new LNode(t, i, p, r, NULL, this);
112        return newElement;
113    }
114    else {
115         //Print("tested element1: ");
116    //pWrite(this->getTerm());
117        if(-1 == pLmCmp(t,this->getTerm())) {
118            //Print("HIERDRIN\n");
119            LNode* newElement   =   new LNode(t, i, p, r, NULL, this);
120            //Print("%p\n",this);
121            //Print("%p\n",newElement->next);
122            return newElement;
123        }
124        else {
125            LNode* temp = this;
126            while(NULL != temp->next && NULL != temp->next->data) {
127                //Print("tested element: ");
128                //pWrite(temp->getTerm());
129 if(-1 == pLmCmp(t,temp->next->getTerm())) {
130                    LNode* newElement   =   new LNode(t, i, p, r, NULL, temp->next);
131                    temp->next          =   newElement;
132                    return this;
133                }
134                else {
135                    temp = temp->next;
136                    //Print("%p\n",temp);
137                    //Print("%p\n",temp->data);
138                   
139                    //Print("%p\n",temp->next);
140                }
141            }
142        //Print("HIER\n");
143            LNode* newElement   =   new LNode(t, i, p, r, NULL, temp->next);
144            temp->next          =   newElement;
145            return this;
146        }
147    }
148}
149
150// deletes the first elements of the list with the same degree
151// only used for the S-polys, which are already sorted by increasing degree by CList
152LNode*  LNode::deleteByDeg() {
153    return this;
154}
155
156// get next from current LNode
157LNode* LNode::getNext() {
158    return next;
159}
160
161// get the LPoly* out of LNode*
162LPoly* LNode::getLPoly() {
163    return data;
164}
165
166// get the data from the LPoly saved in LNode
167poly LNode::getPoly() {
168    return data->getPoly();
169}
170
171poly LNode::getTerm() {
172    return data->getTerm();
173}
174
175int LNode::getIndex() {
176    return data->getIndex();
177}
178
179Rule* LNode::getRule() {
180    return data->getRule();
181}
182
183LNode* LNode::getGPrevRedCheck() {
184    return gPrevRedCheck;
185}
186
187// set the data from the LPoly saved in LNode
188void LNode::setPoly(poly p) {
189    data->setPoly(p);
190}
191
192void LNode::setTerm(poly t) {
193    data->setTerm(t);
194}
195
196void LNode::setIndex(int i) {
197    data->setIndex(i);
198}
199
200void LNode::setGPrevRedCheck(LNode* l) {
201    gPrevRedCheck   =   l;
202}
203
204void LNode::setNext(LNode* l) {
205    next    =   l;
206}
207
208// test if for any list element the polynomial part of the data is equal to *p
209bool LNode::polyTest(poly* p) {
210    LNode* temp = new LNode(this);
211    while(NULL != temp) {
212        if(pComparePolys(temp->getPoly(),*p)) {
213            return 1;
214        }
215        temp = temp->next;
216    }
217    return 0;
218}
219
220LNode* LNode::getNext(LNode* l) {
221    return l->next;
222}
223
224// for debugging
225void LNode::print() {
226    LNode* temp = this;
227    Print("___________________List of S-polynomials______________________:\n");
228    Print("%p\n",this);
229    while(NULL != temp && NULL != temp->data) {
230        Print("Index: %d\n",temp->getIndex());
231        Print("Term: ");
232        pWrite(temp->getTerm());
233        Print("Poly: ");
234        pWrite(temp->getPoly());
235        Print("%p\n",temp->next);
236        temp = temp->next;
237    }
238    Print("_______________________________________________________________\n");
239}
240
241
242/*
243====================================
244functions working on the class LList
245====================================
246*/
247
248LList::LList() {
249    first   =   new LNode();
250    last    =   first;
251    length  =   0;
252}
253
254LList::LList(LPoly* lp) {
255    first   =   new LNode(lp);
256    last    =   first;
257    length  =   1;
258}
259
260LList::LList(poly t,int i,poly p,Rule* r) {
261    first   =   new LNode(t,i,p,r);
262    last    =   first;
263    length  =   1;
264} 
265
266LList::~LList() {
267    delete first;
268}
269
270// insertion at the end of the list, needed for gPrev
271void LList::insert(LPoly* lp) {
272    last = last->insert(lp);
273    //Print("NEW LAST GPREV: ");
274    //pWrite(last->getPoly());
275    length++;
276    //Print("LENGTH %d\n",length);
277}
278
279void LList::insert(poly t,int i, poly p, Rule* r) {
280    last = last->insert(t,i,p,r);
281    length++;
282    //Print("LENGTH %d\n",length);
283}
284
285// insertion in front of the list, needed for sPolyList
286void LList::insertSP(LPoly* lp) {
287    first = first->insertSP(lp);
288    length++;
289    //Print("LENGTH %d\n",length);
290}
291
292void LList::insertSP(poly t,int i, poly p, Rule* r) {
293    first = first->insertSP(t,i,p,r);
294    length++;
295    //Print("LENGTH %d\n",length);
296}
297
298
299void LList::insertByLabel(poly t, int i, poly p, Rule* r) {
300    first = first->insertByLabel(t,i,p,r);
301    length++;
302    //Print("LENGTH %d\n",length);
303}
304
305void LList::insertByLabel(LNode* l) {
306    first = first->insertByLabel(l->getTerm(),l->getIndex(),l->getPoly(),l->getRule());
307    length++;
308    //Print("LENGTH %d\n",length);
309}
310
311void LList::deleteByDeg() {
312    first = first->deleteByDeg();
313}
314
315bool LList::polyTest(poly* p) {
316    return first->polyTest(p);
317}
318
319LNode* LList::getFirst() {
320    return first;
321}
322
323LNode* LList::getLast() {
324    return last;
325}
326
327int LList::getLength() {
328    return length;
329}
330
331void LList::setFirst(LNode* l) {
332    LNode* temp =   first;
333    temp->setNext(NULL);
334    first       =   l;
335    length--;
336}
337
338void LList::print() {
339    first->print();
340}
341
342/*
343=======================================
344functions working on the class LTagNode
345=======================================
346*/
347LTagNode::LTagNode() {
348    data    =   NULL;
349    next    =   NULL;
350}
351
352LTagNode::LTagNode(LNode* l) {
353    data = l;
354    next = NULL;
355}
356       
357LTagNode::LTagNode(LNode* l, LTagNode* n) {
358    data = l;
359    next = n;
360}
361
362 LTagNode::~LTagNode() {
363    delete next;
364    delete data;   
365}
366       
367// declaration with first as parameter due to sorting of LTagList
368LTagNode* LTagNode::insert(LNode* l) {
369    LTagNode* newElement  = new LTagNode(l, this);
370    return newElement;
371}
372
373LNode* LTagNode::getLNode() {
374    return this->data;
375}
376
377LTagNode* LTagNode::getNext() {
378    return next;
379}
380
381// NOTE: We insert at the beginning of the list and length = i-1, where i is the actual index.
382//       Thus given actual index i and idx being the index of the LPoly under investigation
383//       the element on position length-idx is the right one
384LNode* LTagNode::get(int idx, int length) {
385    if(idx == 1) {
386        return NULL;
387    }
388    else {
389        int j;
390        LTagNode* temp = this; // last
391        for(j=1;j<=length-idx+1;j++) {
392            temp = temp->next;
393        }
394        return temp->data;
395    }
396}
397
398
399/*
400=======================================
401functions working on the class LTagList
402=======================================
403*/
404LTagList::LTagList() {
405    LTagNode* first =   new LTagNode();
406   
407    length          =   0;
408}
409
410LTagList::LTagList(LNode* l) {
411    LTagNode* first =   new LTagNode(l);
412    length          =   1;
413}
414
415// declaration with first as parameter in LTagNode due to sorting of LTagList
416void LTagList::insert(LNode* l) {
417    first   =   first->insert(l);
418    length++;
419}
420
421void LTagList::setFirstCurrentIdx(LNode* l) {
422    firstCurrentIdx =   l;
423}
424
425LNode* LTagList::get(int idx) {
426    return first->get(idx, length);
427}
428
429LNode* LTagList::getFirst() {
430    return first->getLNode();
431}
432
433LNode* LTagList::getFirstCurrentIdx() {
434    return firstCurrentIdx;
435}
436
437/*
438=====================================
439functions working on the class TopRed
440=====================================
441*/
442
443TopRed::TopRed() {
444    _completed  =   NULL;
445    _toDo       =   NULL;
446}
447
448TopRed::TopRed(LList* c, LList* t) {
449    _completed  =   c;
450    _toDo       =   t;
451}
452
453LList* TopRed::getCompleted() {
454    return _completed;
455}
456
457LList* TopRed::getToDo() {
458    return _toDo;
459}
460
461/*
462====================================
463functions working on the class CNode
464====================================
465*/
466
467CNode::CNode() {
468    data    =   NULL;   
469    next    =   NULL;   
470}
471
472CNode::CNode(CPair* c) {
473    data    =   c;   
474    next    =   NULL;   
475}
476
477CNode::CNode(CPair* c, CNode* n) {
478    data    =   c;   
479    next    =   n;   
480}
481
482CNode::~CNode() {
483    delete next;
484    delete data;
485}
486
487// insert sorts the critical pairs firstly by increasing total degree, secondly by increasing label
488// note: as all critical pairs have the same index here, the second sort is done on the terms of the labels
489// working only with linked, but not doubly linked lists due to memory usage we have to check the
490// insertion around the first element separately from the insertion around all other elements in the list
491CNode* CNode::insert(CPair* c, CNode* last) {
492    if(NULL == this->data) {
493        CNode* newElement   =   new CNode(c, this);
494        return newElement;
495    }
496    else {
497        poly u1 = ppMult_qq(c->getT1(),c->getLp1Term());
498        if( c->getDeg() < this->data->getDeg() ) { // lower degree than the first list element
499            CNode* newElement   =   new CNode(c, this);
500            return newElement;
501        }
502        if( c->getDeg() == this->data->getDeg() ) { // same degree than the first list element
503            if(1 != pLmCmp(u1,ppMult_qq(this->data->getT1(), this->data->getLp1Term()))) {
504                //pWrite(u1);
505                //Print("Multi-Term in CritPairs Sortierung altes Element: ");
506                //pWrite(ppMult_qq(this->data->getT1(),this->data->getLp1Term()));
507                CNode* newElement   =   new CNode(c, this);
508                return newElement;
509            }
510            else {
511                //Print("Insert Deg\n");
512                CNode* temp = this;
513                while(  NULL != temp->next->data ) {
514                    if(temp->next->data->getDeg() == c->getDeg() ) { 
515                        if(1 == pLmCmp(u1,ppMult_qq(temp->next->data->getT1(),temp->next->data->getLp1Term()))) {
516                            temp = temp->next;
517                        }
518                        else {
519                            CNode* newElement   =   new CNode(c, temp->next);
520                            temp->next          =   newElement;
521                            return this;
522                        } 
523                    }
524                    else {
525                        CNode* newElement   =   new CNode(c, temp->next);
526                        temp->next          =   newElement;
527                        return this;
528                    }
529                }
530                CNode* newElement   =   new CNode(c, last);
531                temp->next          =   newElement;
532                return this;
533            }
534        } // outer if-clause
535        if( c->getDeg() > this->data->getDeg() ) { // greater degree than the first list element
536            CNode* temp =   this;
537            while( NULL != temp->next->data ) {   
538                if( c->getDeg() < temp->next->data->getDeg() ) {
539                    CNode* newElement   =   new CNode(c, temp->next);
540                    temp->next          =   newElement;
541                    return this;
542                }
543                if( c->getDeg() == temp->next->data->getDeg() ) {
544                    if(1 != pLmCmp(u1,ppMult_qq(temp->next->data->getT1(),temp->next->data->getLp1Term()))) { 
545                        CNode* newElement   =   new CNode(c, temp->next);
546                        temp->next          =   newElement;
547                        return this;
548                    }
549                    else {
550                        temp = temp->next;
551                        while(  NULL != temp->next->data ) {
552                            if( temp->next->data->getDeg() == c->getDeg() ) { 
553                                if(1 == pLmCmp(u1,ppMult_qq(temp->next->data->getT1(),
554                                               temp->next->data->getLp1Term()))) {
555                                    temp = temp->next;
556                                }
557                                else {
558                                    CNode* newElement   =   new CNode(c, temp->next);
559                                    temp->next          =   newElement;
560                                    return this;
561                                } 
562                            }
563                            else {
564                                CNode* newElement   =   new CNode(c, temp->next);
565                                temp->next          =   newElement;
566                                return this;
567                            }
568                        }
569                        CNode* newElement   =   new CNode(c, last);
570                        temp->next          =   newElement;
571                        return this;
572                    }
573                }
574                if( c->getDeg() > temp->next->data->getDeg() ) {
575                    temp    =   temp->next;
576                }
577            }
578            CNode* newElement   =   new CNode(c, last);
579            temp->next          =   newElement;
580            return this;
581        }
582    }
583}
584
585// get the first elements from CList which by the above sorting have minimal degree
586CNode* CNode::getMinDeg() {
587    CNode* temp = this;
588    while( NULL != temp->data ) {
589        while(NULL != temp->next->data && temp->next->data->getDeg() == this->data->getDeg()) {
590            temp = temp->next;
591        }
592        CNode* returnCNode  =   temp->next;   
593        // every CList should end with a (NULL,NULL) element for a similar behaviour
594        // using termination conditions throughout the algorithm
595        temp->next          =   new CNode();
596        return returnCNode;
597    }
598    return NULL;
599}
600
601CPair* CNode::getData() {
602    return data;
603}
604
605CNode* CNode::getNext() {
606    return next;
607}
608
609LPoly* CNode::getAdLp1() {
610    return this->data->getAdLp1();
611}
612
613LPoly* CNode::getAdLp2() {
614    return this->data->getAdLp2();
615}
616
617poly CNode::getLp1Poly() {
618    return this->data->getLp1Poly();
619}
620
621poly CNode::getLp2Poly() {
622    return this->data->getLp2Poly();
623}
624
625poly CNode::getLp1Term() {
626    return this->data->getLp1Term();
627}
628
629poly CNode::getLp2Term() {
630    return this->data->getLp2Term();
631}
632
633int CNode::getLp1Index() {
634    return this->data->getLp1Index();
635}
636
637int CNode::getLp2Index() {
638    return this->data->getLp2Index();
639}
640
641poly CNode::getT1() {
642    return this->data->getT1();
643}
644
645poly* CNode::getAdT1() {
646    return this->data->getAdT1();
647}
648
649poly CNode::getT2() {
650    return this->data->getT2();
651}
652
653poly* CNode::getAdT2() {
654    return this->data->getAdT2();
655}
656
657Rule* CNode::getTestedRule() {
658    return this->data->getTestedRule();
659}
660
661// for debugging
662void CNode::print() {
663    CNode* temp = this;
664    Print("___________________List of critical pairs______________________:\n");
665    while(NULL != temp->data) {
666        Print("LP1 Index: %d\n",temp->getLp1Index());
667        Print("T1: ");
668        pWrite(temp->getT1());
669        Print("LP1 Term: ");
670        pWrite(temp->getLp1Term());
671        Print("LP1 Poly: ");
672        pWrite(temp->getLp1Poly());
673        Print("LP2 Index: %d\n",temp->getLp2Index());
674        Print("T2: ");
675        pWrite(temp->getT2());
676        Print("LP2 Term: ");
677        pWrite(temp->getLp2Term());
678        Print("LP2 Poly: ");
679        pWrite(temp->getLp2Poly());
680        Print("\n");
681        temp = temp->next;
682    }
683}
684
685/*
686====================================
687functions working on the class CList
688====================================
689*/
690// for initialization of CLists, last element alwas has data=NULL and next=NULL
691CList::CList() {
692    first   =   new CNode();
693    last    =   first;
694}
695
696CList::CList(CPair* c) {
697    first   =   new CNode(c);
698    last    =   first;
699}
700
701CList::~CList() {
702    delete first;
703}
704
705// insert sorts the critical pairs firstly by increasing total degree, secondly by increasing label
706// note: as all critical pairs have the same index here, the second sort is done on the terms of the labels
707void CList::insert(CPair* c) {
708    first = first->insert(c, last);
709}
710
711CNode* CList::getFirst() {
712    return first;
713}
714
715// get the first elements from CList which by the above sorting have minimal degree
716// returns the pointer on the first element of those
717CNode* CList::getMinDeg() {
718    CNode* temp     =   first;
719    first           =   first->getMinDeg();
720    return temp;
721}
722
723void CList::print() {
724    first->print();
725}
726
727/*
728====================================
729functions working on the class RNode
730====================================
731*/
732RNode::RNode() {
733    data    =   NULL;
734    next    =   NULL;
735}
736
737RNode::RNode(Rule* r) {
738    data    =   r;
739    next    =   NULL;
740}
741
742RNode::~RNode() {
743    delete  next;
744    delete  data;
745}
746
747RNode* RNode::insert(Rule* r) {
748    RNode* newElement   =   new RNode(r);
749    newElement->next    =   this;
750    return newElement;
751}
752
753RNode* RNode::insert(int i, poly t) {
754    Rule*   r           =   new Rule(i,t);
755    RNode* newElement   =   new RNode(r);
756    newElement->next    =   this;
757    return newElement;
758}
759
760RNode* RNode::getNext() {
761    return next;
762}   
763
764Rule* RNode::getRule() {
765    return data;
766}
767
768int RNode::getRuleIndex() {
769    return data->getIndex();
770}
771
772poly RNode::getRuleTerm() {
773    return data->getTerm();
774}
775
776/*
777====================================
778functions working on the class RList
779====================================
780*/
781RList::RList() {
782    first = new RNode();
783}
784
785RList::RList(Rule* r) {
786    first = new RNode(r);
787}
788
789void RList::insert(int i, poly t) {
790    first = first->insert(i,t);
791}
792
793void RList::insert(Rule* r) {
794    first = first->insert(r);
795}
796
797RNode* RList::getFirst() {
798    return first;
799}
800
801Rule* RList::getRule() {
802    return this->getRule();
803}
804
805/*
806=======================================
807functions working on the class RTagNode
808=======================================
809*/
810
811RTagNode::RTagNode() {
812    data = NULL;
813    next = NULL;
814}
815 
816RTagNode::RTagNode(RNode* r) {
817    data = r;
818    next = NULL;
819}
820       
821RTagNode::RTagNode(RNode* r, RTagNode* n) {
822    data = r;
823    next = n;
824}
825
826 RTagNode::~RTagNode() {
827    delete next;
828    delete data;   
829}
830       
831// declaration with first as parameter due to sorting of RTagList
832RTagNode* RTagNode::insert(RNode* r) {
833    //Print("Hier1\n");
834    RTagNode* newElement  = new RTagNode(r, this);
835    //Print("Hier2\n");
836    return newElement;
837}
838
839RNode* RTagNode::getRNode() {
840    return this->data;
841}
842
843// NOTE: We insert at the beginning of the list and length = i-1, where i is the actual index.
844//       Thus given actual index i and idx being the index of the LPoly under investigation
845//       the element on position length-idx+1 is the right one
846RNode* RTagNode::get(int idx, int length) {
847    if(idx==1 || idx==0) {
848        // NOTE: We set this NULL as putting it the last element in the list, i.e. the element having
849        //       RNode* = NULL would cost lots of iterations at each step of F5inc, with increasing
850        //       length of the list this should be prevented
851        return NULL;
852    }
853    else {
854        int j;
855        RTagNode* temp = this; 
856    //Print("\n\nHIER IN GET IDX\n");
857    //Print("FOR LOOP: %d\n",length-idx+1);   
858    for(j=1; j<=length-idx+1; j++) {
859            temp = temp->next;
860        }
861        return temp->data;
862    }
863}
864
865void RTagNode::set(RNode* r) {
866    this->data  =   r;
867}
868
869void RTagNode::print() {
870    RTagNode* temp  =   this;
871    Print("1. element: %d",getRNode()->getRule()->getIndex());
872    //pWrite(getRNode()->getRule()->getTerm());
873    temp    =   temp->next;
874    int i   =   2;
875    while(NULL != temp->getRNode()) {
876        Print("%d. element: %d",i,getRNode()->getRule()->getIndex());
877        //pWrite(getRNode()->getRule()->getTerm());
878        temp    =   temp->next;
879        i++;
880    }
881}
882/*
883=======================================
884functions working on the class LTagList
885=======================================
886*/
887
888RTagList::RTagList() {
889    RTagNode* first =   new RTagNode();
890    length          =   0;
891}
892
893RTagList::RTagList(RNode* r) {
894    RTagNode* first =   new RTagNode(r);
895    length          =   1;
896}
897
898// declaration with first as parameter in LTagNode due to sorting of LTagList
899void RTagList::insert(RNode* r) {
900    first = first->insert(r);
901    //Print("LENGTH:%d\n",length);
902    length = length +1;
903    //Print("LENGTH:%d\n",length);
904}
905
906RNode* RTagList::getFirst() {
907    return first->getRNode();
908}
909
910RNode* RTagList::get(int idx) {
911    return first->get(idx, length);
912}
913
914void RTagList::setFirst(RNode* r) {
915    first->set(r);
916}
917
918void RTagList::print() {
919    first->print();
920}
921
922int RTagList::getLength() {
923    return length;
924}
925#endif
Note: See TracBrowser for help on using the repository browser.