source: git/kernel/f5lists.cc @ 338842d

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