File: list.h

package info (click to toggle)
singular 1%3A4.0.3-p3%2Bds-5
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 33,040 kB
  • ctags: 19,347
  • sloc: cpp: 271,589; ansic: 13,500; lisp: 4,242; yacc: 1,656; lex: 1,377; makefile: 1,264; perl: 632; sh: 467; python: 233; xml: 182
file content (303 lines) | stat: -rw-r--r-- 8,369 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
// list.h


// The classes "list" and "list_iterator" are designed for the special needs
// of Buchberger's algorithm; it is not recommendable to use them for
// more general purposes.
// "list" implements a simply linked list of binomials (or, more exactly,
// pointers on binomials).
// A list_iterator is not much more than a pointer to a list element, but using
// iterators instead of pointers makes the code of Buchberger's algorithm much
// easier to read.

// The delegation of tasks to this classes and the realization of some
// functions are quite special.
// So is the insertion of list elements the task of the class list, while the
// deletion is delegated to the iterator class. The reason is the simple:
// Elements are almost always inserted at the beginning of a list (except
// from the case of an ordered list), but can be deleted from an arbitrary
// place (this is necessary e.g. if a binomial is reduced to zero during
// Buchberger's algorithm).

// For efficiency reasons, the iterator operations are not secure. They do
// not check if the iterator really references a list element or if it has
// reached the end of the list. To assert this, use the is_at_end()-test.

// I have designed an own iterator class instead of taking pointers for
// iteration as lists members for flexibility reasons:
// Buchberger's algorithm requires to form pairs of binomials (or, for
// testing criteria to discard S-Pairs, even triples). So we need up to
// three pointers to iterate over the generator lists. The advantage of the
// iterator class is simply that the programmer does not have to keep
// in mind the lists over which he is actually iterating.
// This was very helpful for me during the implementation of Buchberger's
// algorithm (especially for the implementation of
// SUPPORT_DRIVEN_METHODS_EXTENDED where many lists have to be considered).


// There are two different implementations of the class list:
// - If SL_LIST is set, we use a simply linked list.
//   The insert operations are very efficient because we have to set very
//   few pointers. But the deletion of an element is a dangerous operation
//   because it moves the following element (not the binomial, but the struct)
//   to another storage place.
// - If DL_LIST is set, we use a doubly linked list.
//   This shows to be considerably slower, but it is easier to use



#ifndef LIST_H
#define LIST_H



#define DL_LIST
// possibilities:
// SL_LIST
// DL_LIST



#include "binomial__term_ordering.h"




////////////////////////////// struct element ///////////////////////////////




typedef struct Element
{
  binomial *entry;
  struct Element *next;


#ifdef DL_LIST

  struct Element *previous;

#endif  // DL_LIST


  // flags needed by the ideal implementation to speed up Buchberger's
  // algorithm
  BOOLEAN done;
  BOOLEAN head_reduced;

} element;




/////////////////////////// class list ////////////////////////////////////




class list
{



private:


  element *start;
  // pointer to the beginning



public:


// constructors and destructor

  list();
  // Creates an "empty" list (with a dummy element for a user friendly
  // iterator class, see the comments in list.cc).

  list(const list&);
  // copy-constructor

  ~list();
  // destructor



// inserting

  list& insert(binomial&);
  list& copy_insert(const binomial&);
  // These operations insert a binomial at the beginning of the list:
  // insert does this by placing pointers on it, copy_insert by copying the
  // binomial.
  // The first operation is dangerous; but the consequent use of the
  // combination insert - extract_element (cf. class list_iterator) instead of
  // copy_insert - delete_element is very important for the performance of
  // Buchberger's algorithm.

  list& _insert(binomial&);
  list& _copy_insert(const binomial&);
  // A little more efficient insert function for list that do not use
  // the 3 flags - these are not set.
  // It is not more efficient to implement these simpler lists as an own class.

  list& ordered_insert(binomial&, const term_ordering&);
  list& ordered_copy_insert(const binomial&, const term_ordering&);
  // These operations insert a binomial according to the given term ordering
  // into a list. (The list should be ordered by the same term ordering.)
  // To insert elements, we use a simple linear search.

  list& _ordered_insert(binomial&, const term_ordering&);
  list& _ordered_copy_insert(const binomial&, const term_ordering&);
  // A little more efficient ordered_insert function for list that do not use
  // the 3 flags - these are not set.



// output

  void print() const;
  void ordered_print(const term_ordering&) const;
  // Writes the list to the standard output medium.
  // The first routine writes the list elements as they are oredred in
  // the list.
  // The second one writes them in increasing order with respect to the
  // argument term ordering; the list has not to be ordered before and
  // will not be ordered after. This routine is essentially written to
  // compare Grbner bases.

  void print(FILE* output) const;
  void ordered_print(FILE* output, const term_ordering&) const;
  // Writes the list to the referenced file which has to be opened for
  // writing before.

  void print(ofstream&) const;
  void ordered_print(ofstream&, const term_ordering&) const;
  // Writes the list to the given ofstream.

  void format_print(ofstream&) const;
  void ordered_format_print(ofstream&, const term_ordering&) const;
  // Writes the list to the given ofstream in the format needed by the
  // IP-algorithms.

  friend class list_iterator;

};




///////////////////// class list_iterator ////////////////////////////////




class list_iterator
{



private:

  element* actual;



public:



// constructors and destructor

  list_iterator();
  // Sets actual to NULL.

  list_iterator(list& l);
  // Sets a list_iterator to the beginning of l.

  list_iterator(list_iterator& iter);
  // Sets a list iterator to the same position as iter.

  ~list_iterator();
  // destructor



// object information

  BOOLEAN element_is_marked_done() const;
  // Returns the "done"-component of the referenced element.

  BOOLEAN element_is_marked_head_reduced() const;
  // Returns the "head_reduced"-component of the referenced element.

  BOOLEAN is_at_end() const;
  // Returns TRUE iff the iterator is at the end of "its" list
  // (especially if the iterator references no list).



// assignment

  list_iterator& set_to_list(const list& l);
  // Sets the iterator to the beginning of l.

  list_iterator& operator=(const list_iterator& iter);
  // Sets the iterator to the same element as iter.

  list_iterator& next();
  // Sets the iterator to the next entry.



// comparison

  int operator==(const list_iterator& iter) const;
  int operator!=(const list_iterator& iter) const;
  // These operators verifie if actual references the same element
  // as iter.actual.

  int next_is(const list_iterator& iter) const;
  // Checks if actual->next references the same element as iter.actual.
  // This check is needed in very special situations (two iterators reference
  // subsequent elements of a list, and the first is deleted; then the
  // iterator referencing the second before deletion references freed memory
  // after deletion, cf. the implementation of delete and extract).



// manipulation of list elements

  // All this operations could be declared as const because they do not
  // change the "actual" pointer. For suggestive reasons, this is not done
  // because they change the referenced list element.

  binomial& get_element();
  // Returns the referenced binomial.

  list_iterator& delete_element();
  // Deletes the referenced binomial.

  list_iterator& extract_element();
  // Only resets pointers so that the refenced binomial is no longer found
  // when iterating over the list.

  list_iterator& mark_element_done();
  // Sets the "done"-component of the referenced element to TRUE.

  list_iterator& mark_element_undone();
  // Sets the "done"-component of the referenced element to FALSE.

  list_iterator& mark_element_head_reduced();
  // Sets the "head_reduced"-component of the referenced element to TRUE.

  list_iterator& mark_element_head_unreduced();
  // Sets the "head_reduced"-component of the referenced element to FALSE.

};


#endif  // list.h