1 /* $Id: cset.c,v 1.4 1994/06/24 10:29:32 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".
19 /* A set over a range of integers from 1 to N may be represented
20 * as a 'compact' set. Such a set is represented as a 'bitvector'
21 * record, containing the size of the set (i.e. N) and a row
22 * of words (the bitvector itself). An integer J (1 <= J <= N) is
23 * an element of the set iff the J-th bit of the vector is a '1'.
24 * Any redundant bits in the last word are garanteed to be zero bits.
25 * This package implements the usual operations on sets.
26 * The name of every operation is preceede by a 'C' to
27 * distinguish it from the operation on 'long' (list)
28 * sets whth a similar name.
32 /* The two arithmetic operations 'divide by wordlength' and
33 * 'modulo wordlength' can be performed very efficiently
34 * if the word length (of the source machine) is 16.
45 s = newbitvect(DIVWL(n-1) + 1);
58 assert(x>0 && x <= s->v_size);
60 mask = (1 << MODWL(x-1));
61 if ((s->v_bits[n] & mask) == 0) {
79 assert(x>0 && x <= s->v_size);
81 mask = (1 << MODWL(x-1));
95 assert(x>0 && x <= s->v_size);
97 mask = (1 << MODWL(x-1));
98 s->v_bits[n] &= ~mask;
103 /* The operations first, next and elem can be used to iterate
104 * over a set. For example:
105 * for (i = Cfirst(s); i != (Cindex) 0; i = Cnext(i,s) {
110 * 'for all elements x of s do'
113 * The implementation of first and next is not very fast.
114 * It could be made much more efficient (at the price of a
115 * higher complexity) by not using 'is_elem'.
116 * Iteration over a bitvector, however, is not supposed to
117 * be used very often.
123 return Cnext((Cindex) 0,s);
133 for (n = i+1; n <= s->v_size; n++) {
153 /* Two sets are joined by or-ing their bitvectors,
162 assert(s1->v_size == s2->v_size);
163 n = DIVWL(s1->v_size -1); /* #words -1 */
164 for (i = 0; i <= n; i++) {
165 s2->v_bits[i] |= s1->v_bits[i];
174 /* Two sets are intersected by and-ing their bitvectors,
183 assert(s1->v_size == s2->v_size);
184 n = DIVWL(s1->v_size -1); /* #words -1 */
185 for (i = 0; i <= n; i++) {
186 s2->v_bits[i] &= s1->v_bits[i];
194 oldbitvect(s,DIVWL(s->v_size - 1) + 1);
198 bool Cis_subset(s1,s2)
201 /* See if s1 is a subset of s2 */
205 assert(s1->v_size == s2->v_size);
206 if (s1->v_size == 0) return TRUE;
207 for (i = 0; i <= DIVWL(s1->v_size-1); i++) {
208 if ((s1->v_bits[i] & ~(s2->v_bits[i])) != 0) {
223 assert (s != (cset) 0);
224 for (i = 0; i <= DIVWL(s->v_size-1); i++) {
237 assert (s1->v_size == s2->v_size);
238 for (i = 0; i <= DIVWL(s1->v_size-1); i++) {
239 s2->v_bits[i] = s1->v_bits[i];
251 assert (s1->v_size == s2->v_size);
252 for (i = 0; i <= DIVWL(s1->v_size-1); i++) {
253 s2->v_bits[i] &= ~(s1->v_bits[i]);
263 assert (s1->v_size == s2->v_size);
264 for (i = 0; i <= DIVWL(s1->v_size-1); i++) {
265 if (s1->v_bits[i] != s2->v_bits[i]) return FALSE;
273 register short n, cnt;
276 for (n = 1; n <= s->v_size; n++) {