1 /* $Id: lset.c,v 1.5 1994/06/24 10:30:24 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
18 /* A 'long' set is represented as a linear list of 'elemholder'
19 * records. Every such record contains a pointer to an element
20 * of the set and to the next elemholder. An empty set is
21 * represented as a null pointer.
22 * An element of a long set must be of some pointer type or,
23 * in any case, must have the size of a pointer. Note that
24 * the strict typing rules are not obeyed here.
25 * This package implements the usual operations on sets.
26 * The name of every operation is preceeded by a 'L' to
27 * distinguish it from the operation on 'compact' (bitvector)
28 * sets with a similar name.
43 /* Search the list to see if x is an element of s */
44 while (s != (elem_p) 0) {
58 /* add x to a set. Note that the set is given as in-out
59 * parameter, because it may be changed.
64 if (!Lis_elem(x,*s_p)) {
65 t = newelem(); /* allocate a new elemholder */
67 t->e_next = *s_p; /* insert it at the head of the list */
77 /* Remove x from a set. If x was not an element of
78 * the set, nothing happens.
81 register elem_p *epp, ep;
86 while ((ep = *epp) != (elem_p) 0) {
87 if (ep->e_elem == x) {
99 /* The operations first, next and elem can be used to iterate
100 * over a set. For example:
101 * for (i = Lfirst(s); i != (Lindex) 0; i = Lnext(i,s) {
106 * 'for all elements x of s do'
115 /* Note that an index for long sets is just
116 * a pointer to an elemholder.
126 assert(i != (Lindex) 0);
142 /* Join two sets, assign the result to the second set
143 * and delete the first set (i.e. the value of the
144 * first set becomes undefined).
147 register elem_p *epp, ep;
150 /* First all elements of s1 that are also an element of s2
151 * are removed from the s1 list. The two resulting lists
152 * (for s1 and s2) are linked (s1 first).
153 * Note the usage of epp, which points to a pointer that
154 * points to the next elemholder record of the list.
159 while ((ep = *epp) != (elem_p) 0) {
160 if (Lis_elem(ep->e_elem,s2)) {
161 /* remove an element */
168 *epp = s2; /* last record of s1 (or s1 itself) now points
169 * to first record of s2.
178 register elem_p ep, next;
180 for (ep = s; ep != (elem_p) 0; ep = next) {
187 bool Lis_subset(s1,s2)
190 /* See if s1 is a subset of s2 */
194 for (i = Lfirst(s1); i != (Lindex) 0; i = Lnext(i,s1)) {
195 if (!Lis_elem(Lelem(i),s2)) return FALSE;
204 /* Compute the number of elements of a set */
210 for (ep = s; ep != (elem_p) 0; ep = ep->e_next) {