1 (* ==================================================================== *)
3 (* VarSet Module for the Gardens Point Component Pascal Compiler. *)
4 (* Implements operations on variable length bitsets. *)
5 (* Copyright (c) John Gough 1999, 2000. *)
7 (* ==================================================================== *)
15 (* ============================================================ *)
20 (* ============================================================ *)
23 VarSet
* = POINTER TO RECORD
24 vars
: POINTER TO ARRAY OF SET;
28 (* ============================================================ *)
29 (* ======= Implementation of VarSet abstract data type ======= *)
30 (* ============================================================ *)
32 PROCEDURE newSet
*(size
: INTEGER) : VarSet
;
38 IF size
= 0 THEN len
:= 1 ELSE len
:= (size
+ iMax
) DIV bits
END;
43 (* ======================================= *)
45 PROCEDURE newUniv
*(size
: INTEGER) : VarSet
;
54 tmp
.vars
[idx
] := {0 .. iMax
};
55 INC(idx
); DEC(rem
,bits
);
57 tmp
.vars
[idx
] := {0 .. (rem
-1)};
61 (* ======================================= *)
63 PROCEDURE newEmpty
*(size
: INTEGER) : VarSet
;
68 FOR idx
:= 0 TO LEN(tmp
.vars^
)-1 DO tmp
.vars
[idx
] := {} END;
72 (* ======================================= *)
74 PROCEDURE (self
: VarSet
)newCopy
*() : VarSet
,NEW;
78 tmp
:= newSet(self
.size
);
79 FOR idx
:= 0 TO LEN(tmp
.vars
)-1 DO tmp
.vars
[idx
] := self
.vars
[idx
] END;
83 (* ======================================= *)
85 PROCEDURE (self
: VarSet
)cardinality
*() : INTEGER,NEW;
86 BEGIN RETURN self
.size
END cardinality
;
88 (* ============================================================ *)
90 PROCEDURE (self
: VarSet
)includes
*(elem
: INTEGER) : BOOLEAN, NEW;
92 RETURN (elem
< self
.size
) &
93 ((elem
MOD bits
) IN self
.vars
[elem
DIV bits
]);
96 (* ============================================================ *)
98 PROCEDURE (self
: VarSet
)Incl
*(elem
: INTEGER),NEW;
100 INCL(self
.vars
[elem
DIV bits
], elem
MOD bits
);
103 (* ======================================= *)
105 PROCEDURE (self
: VarSet
)InclSet
*(add
: VarSet
),NEW;
108 ASSERT(self
.size
= add
.size
);
109 FOR i
:= 0 TO LEN(self
.vars
)-1 DO
110 self
.vars
[i
] := self
.vars
[i
] + add
.vars
[i
];
114 (* ============================================================ *)
116 PROCEDURE (self
: VarSet
)Excl
*(elem
: INTEGER),NEW;
118 EXCL(self
.vars
[elem
DIV bits
], elem
MOD bits
);
121 (* ======================================= *)
123 PROCEDURE (self
: VarSet
)ExclSet
*(sub
: VarSet
),NEW;
126 ASSERT(self
.size
= sub
.size
);
127 FOR i
:= 0 TO LEN(self
.vars
)-1 DO
128 self
.vars
[i
] := self
.vars
[i
] - sub
.vars
[i
];
132 (* ============================================================ *)
134 PROCEDURE (self
: VarSet
)isUniv
*() : BOOLEAN, NEW;
135 VAR i
,r
: INTEGER; s
: SET;
137 i
:= 0; r
:= self
.size
;
139 IF self
.vars
[i
] # {0 .. iMax
} THEN RETURN FALSE
END;
142 RETURN self
.vars
[i
] = {0 .. (r
-1)};
145 (* ============================================================ *)
147 PROCEDURE (self
: VarSet
)isEmpty
*() : BOOLEAN, NEW;
150 IF self
.size
<= 32 THEN RETURN self
.vars
[0] = {} END;
151 FOR i
:= 0 TO LEN(self
.vars
)-1 DO
152 IF self
.vars
[i
] # {} THEN RETURN FALSE
END;
157 (* ============================================================ *)
159 PROCEDURE (self
: VarSet
)not
*() : VarSet
, NEW;
168 tmp
.vars
[idx
] := {0 .. iMax
} - self
.vars
[idx
];
169 INC(idx
); DEC(rem
,bits
);
171 tmp
.vars
[idx
] := {0 .. (rem
-1)} - self
.vars
[idx
];
175 (* ======================================= *)
177 PROCEDURE (self
: VarSet
)Neg
*(),NEW;
184 self
.vars
[idx
] := {0 .. iMax
} - self
.vars
[idx
];
185 INC(idx
); DEC(rem
,bits
);
187 self
.vars
[idx
] := {0 .. (rem
-1)} - self
.vars
[idx
];
190 (* ============================================================ *)
192 PROCEDURE (self
: VarSet
)cup
*(rhs
: VarSet
) : VarSet
,NEW;
196 ASSERT(self
.size
= rhs
.size
);
197 tmp
:= newSet(self
.size
);
198 FOR i
:= 0 TO LEN(self
.vars
)-1 DO
199 tmp
.vars
[i
] := self
.vars
[i
] + rhs
.vars
[i
];
204 (* ======================================= *)
206 PROCEDURE (self
: VarSet
)Union
*(rhs
: VarSet
),NEW;
211 (* ============================================================ *)
213 PROCEDURE (self
: VarSet
)cap
*(rhs
: VarSet
) : VarSet
,NEW;
217 ASSERT(self
.size
= rhs
.size
);
218 tmp
:= newSet(self
.size
);
219 FOR i
:= 0 TO LEN(self
.vars
)-1 DO
220 tmp
.vars
[i
] := self
.vars
[i
] * rhs
.vars
[i
];
225 (* ======================================= *)
227 PROCEDURE (self
: VarSet
)Intersect
*(rhs
: VarSet
),NEW;
230 ASSERT(self
.size
= rhs
.size
);
231 FOR i
:= 0 TO LEN(self
.vars
)-1 DO
232 self
.vars
[i
] := self
.vars
[i
] * rhs
.vars
[i
];
236 (* ============================================================ *)
238 PROCEDURE (self
: VarSet
)xor
*(rhs
: VarSet
) : VarSet
,NEW;
242 ASSERT(self
.size
= rhs
.size
);
243 tmp
:= newSet(self
.size
);
244 FOR i
:= 0 TO LEN(self
.vars
)-1 DO
245 tmp
.vars
[i
] := self
.vars
[i
] / rhs
.vars
[i
];
250 (* ======================================= *)
252 PROCEDURE (self
: VarSet
)SymDiff
*(rhs
: VarSet
),NEW;
255 ASSERT(self
.size
= rhs
.size
);
256 FOR i
:= 0 TO LEN(self
.vars
)-1 DO
257 self
.vars
[i
] := self
.vars
[i
] / rhs
.vars
[i
];
261 (* ============================================================ *)
263 PROCEDURE (self
: VarSet
)Diagnose
*(),NEW;
271 FOR i
:= 0 TO self
.size
-1 DO
272 chr
:= CHR(i
MOD 10 + ORD('
0'
));
273 IF self
.includes(i
) THEN
278 IF (chr
= '
9'
) & (i
< lim
) THEN
279 IF j
< 6 THEN INC(j
) ELSE Console
.WriteLn
; j
:= 0 END;
286 (* ============================================================ *)
287 END VarSets
. (* ============================================== *)
288 (* ============================================================ *)