home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / languages / obrn-a_1.5_lib.lha / oberon-a / source2.lha / Source / Library / Sets.mod < prev    next >
Encoding:
Text File  |  1995-01-26  |  10.8 KB  |  474 lines

  1. (*************************************************************************
  2.  
  3.      $RCSfile: Sets.mod $
  4.   Description: A general module for handling sets of all sizes.
  5.  
  6.    Created by: fjc (Frank Copeland)
  7.     $Revision: 1.3 $
  8.       $Author: fjc $
  9.         $Date: 1995/01/26 00:40:27 $
  10.  
  11.   Copyright © 1994-1995, Frank Copeland.
  12.   This file is part of the Oberon-A Library.
  13.   See Oberon-A.doc for conditions of use and distribution.
  14.  
  15. *************************************************************************)
  16.  
  17. <* STANDARD- *> <* MAIN- *>
  18. <*$ LongVars+ ClearVars- StackChk- ReturnChk-*>
  19.  
  20. MODULE Sets;
  21.  
  22. (**
  23. ** This module serves a number of purposes. It first of all attempts to
  24. ** provide a portable interface to the non-standard set variants used by
  25. ** a number of Oberon compilers. It also implements a Set class to handle
  26. ** sets of any arbitrary size. This is based on an example in Mössenböck's
  27. ** "Object-oriented Programming in Oberon-2". Finally, it provides an
  28. ** extension of the Set class that emulates Modula-2's SET OF CHAR.
  29. *)
  30.  
  31. (**
  32. ** Portable set variants.
  33. **
  34. ** The following types are aliases intended to provide a portable
  35. ** interface to the non-standard set types provided by many Oberon
  36. ** compilers.
  37. **
  38. ** The problem is this: Oberon defines only one set type, which is
  39. ** typically implemented as the "natural" word size of the host machine.
  40. ** However, many compilers provide set variants in different sizes. The
  41. ** logical type hierarchy is LONGSET <- SET <- SHORTSET, with LONGSET
  42. ** being 32 bits, SET 16 bits and SHORTSET 8 bits. Unfortunately, the
  43. ** Oakwood Report and the defacto standard OP2 compiler do not provide
  44. ** for variants, and use 32 bits for SET types. Oberon-A follows this
  45. ** standard by making SET 32 bits, but it also provides 16 and 8 bit
  46. ** variants, which makes it incompatible with other compilers that use the
  47. ** LONGSET/SET/SHORTSET system.
  48. **
  49. ** The objective of this module is to provide a portable interface to
  50. ** such set variants that can be used with different compilers. The
  51. ** implementation will vary depending on the compiler being used, and if a
  52. ** particular sized set is not provided it must be emulated.
  53. *)
  54.  
  55. IMPORT SYSTEM;
  56.  
  57. TYPE
  58.  
  59.   SET8  *= SYSTEM.BYTESET;
  60.   SET16 *= SYSTEM.WORDSET;
  61.   SET32 *= SET;
  62.  
  63.  
  64. (**
  65. ** The Set type defines a class that can be used to create and manage sets
  66. ** of any arbitrary size. It is based directly on an example in chapter
  67. ** 4.3 of "Object-oriented Programming in Oberon-2".
  68. *)
  69.  
  70. CONST setSize = MAX (SET) + 1;
  71.  
  72. TYPE
  73.  
  74.   Set *= RECORD
  75.     max -: INTEGER; (* Largest element allowed *)
  76.     val : POINTER TO ARRAY OF SET;
  77.   END; (* Set *)
  78.  
  79.  
  80. (**
  81. ** The CharSet class extends the Set class to allow for sets of ASCII
  82. ** characters, emulating the SET OF CHAR type that was possible in most
  83. ** Modula-2s.
  84. *)
  85.  
  86. TYPE
  87.  
  88.   CharSet *= RECORD (Set) END;
  89.  
  90.  
  91. (**
  92. ** The following procedures implement the basic set operations:
  93. **
  94. **   - assigning the empty set : s := {}      -> Clear? (s)
  95. **   - assigning a set value   : s := s1      -> Copy? (s, s1)
  96. **   - including an element    : INCL (s, i)  -> Incl? (s, i)
  97. **   - excluding an element    : EXCL (s, i)  -> Excl? (s, i)
  98. **   - set union               : s := s1 + s2 -> s := Add? (s1, s2)
  99. **   - set difference          : s := s1 - s2 -> s := Subtract? (s1, s2)
  100. **   - set intersection        : s := s1 * s2 -> s := Intersect? (s1, s2)
  101. **   - symmetric differnece    : s := s1 / s2 -> s := SymDiff? (s1, s2)
  102. **   - set membership          : i IN s       -> In? (s, i)
  103. **
  104. ** Three versions of each procedure are provided, one for each set type.
  105. ** Most of these procedures may seem unnecessary, as they are implemented
  106. ** directly using normal set operations. However, when using a compiler
  107. ** that does not provide any or all of the set variants as extensions, the
  108. ** operations must be implemented using other types, such as SYSTEM.BYTE.
  109. ** The procedures allow code using this module to be ported to such a
  110. ** compiler without change, as the details of the implementation are
  111. ** wrapped in a procedure interface.
  112. **
  113. ** Type conversion functions are also provided:
  114. **
  115. **   - 8 bit  -> 16 bit : Long8()
  116. **   - 16 bit -> 32 bit : Long16()
  117. **   - 16 bit -> 8 bit  : Short16()
  118. **   - 32 bit -> 16 bit : Short32()
  119. *)
  120.  
  121. PROCEDURE Clear8 * ( VAR s : SET8 );
  122. BEGIN (* Clear8 *)
  123.   s := {}
  124. END Clear8;
  125.  
  126.  
  127. PROCEDURE Copy8 * ( VAR s1 : SET8; s2 : SET8 );
  128. BEGIN (* Copy8 *)
  129.   s1 := s2
  130. END Copy8;
  131.  
  132.  
  133. PROCEDURE Incl8 * ( VAR s : SET8; i : INTEGER );
  134. BEGIN (* Incl8 *)
  135.   INCL (s, i)
  136. END Incl8;
  137.  
  138.  
  139. PROCEDURE Excl8 * ( VAR s : SET8; i : INTEGER );
  140. BEGIN (* Excl8 *)
  141.   EXCL (s, i)
  142. END Excl8;
  143.  
  144.  
  145. PROCEDURE Add8 * ( s1, s2 : SET8 ) : SET8;
  146. BEGIN (* Add8 *)
  147.   RETURN s1 + s2
  148. END Add8;
  149.  
  150.  
  151. PROCEDURE Subtract8 * ( s1, s2 : SET8 ) : SET8;
  152. BEGIN (* Subtract8 *)
  153.   RETURN s1 - s2
  154. END Subtract8;
  155.  
  156.  
  157. PROCEDURE Intersect8 * ( s1, s2 : SET8 ) : SET8;
  158. BEGIN (* Intersect8 *)
  159.   RETURN s1 * s2
  160. END Intersect8;
  161.  
  162.  
  163. PROCEDURE SymDiff8 * ( s1, s2 : SET8 ) : SET8;
  164. BEGIN (* SymDiff8 *)
  165.   RETURN s1 / s2
  166. END SymDiff8;
  167.  
  168.  
  169. PROCEDURE In8 * ( s1 : SET8; i : INTEGER ) : BOOLEAN;
  170. BEGIN (* In8 *)
  171.   RETURN i IN s1
  172. END In8;
  173.  
  174.  
  175. PROCEDURE Clear16 * ( VAR s : SET16 );
  176. BEGIN (* Clear16 *)
  177.   s := {}
  178. END Clear16;
  179.  
  180.  
  181. PROCEDURE Copy16 * ( VAR s1 : SET16; s2 : SET16 );
  182. BEGIN (* Copy16 *)
  183.   s1 := s2
  184. END Copy16;
  185.  
  186.  
  187. PROCEDURE Incl16 * ( VAR s : SET16; i : INTEGER );
  188. BEGIN (* Incl16 *)
  189.   INCL (s, i)
  190. END Incl16;
  191.  
  192.  
  193. PROCEDURE Excl16 * ( VAR s : SET16; i : INTEGER );
  194. BEGIN (* Excl16 *)
  195.   EXCL (s, i)
  196. END Excl16;
  197.  
  198.  
  199. PROCEDURE Add16 * ( s1, s2 : SET16 ) : SET16;
  200. BEGIN (* Add16 *)
  201.   RETURN s1 + s2
  202. END Add16;
  203.  
  204.  
  205. PROCEDURE Subtract16 * ( s1, s2 : SET16 ) : SET16;
  206. BEGIN (* Subtract16 *)
  207.   RETURN s1 - s2
  208. END Subtract16;
  209.  
  210.  
  211. PROCEDURE Intersect16 * ( s1, s2 : SET16 ) : SET16;
  212. BEGIN (* Intersect16 *)
  213.   RETURN s1 * s2
  214. END Intersect16;
  215.  
  216.  
  217. PROCEDURE SymDiff16 * ( s1, s2 : SET16 ) : SET16;
  218. BEGIN (* SymDiff16 *)
  219.   RETURN s1 / s2
  220. END SymDiff16;
  221.  
  222.  
  223. PROCEDURE In16 * ( s1 : SET16; i : INTEGER ) : BOOLEAN;
  224. BEGIN (* In16 *)
  225.   RETURN i IN s1
  226. END In16;
  227.  
  228.  
  229. PROCEDURE Clear32 * ( VAR s : SET32 );
  230. BEGIN (* Clear32 *)
  231.   s := {}
  232. END Clear32;
  233.  
  234.  
  235. PROCEDURE Copy32 * ( VAR s1 : SET32; s2 : SET32 );
  236. BEGIN (* Copy32 *)
  237.   s1 := s2
  238. END Copy32;
  239.  
  240.  
  241. PROCEDURE Incl32 * ( VAR s : SET32; i : INTEGER );
  242. BEGIN (* Incl32 *)
  243.   INCL (s, i)
  244. END Incl32;
  245.  
  246.  
  247. PROCEDURE Excl32 * ( VAR s : SET32; i : INTEGER );
  248. BEGIN (* Excl32 *)
  249.   EXCL (s, i)
  250. END Excl32;
  251.  
  252.  
  253. PROCEDURE Add32 * ( s1, s2 : SET32 ) : SET32;
  254. BEGIN (* Add32 *)
  255.   RETURN s1 + s2
  256. END Add32;
  257.  
  258.  
  259. PROCEDURE Subtract32 * ( s1, s2 : SET32 ) : SET32;
  260. BEGIN (* Subtract32 *)
  261.   RETURN s1 - s2
  262. END Subtract32;
  263.  
  264.  
  265. PROCEDURE Intersect32 * ( s1, s2 : SET32 ) : SET32;
  266. BEGIN (* Intersect32 *)
  267.   RETURN s1 * s2
  268. END Intersect32;
  269.  
  270.  
  271. PROCEDURE SymDiff32 * ( s1, s2 : SET32 ) : SET32;
  272. BEGIN (* SymDiff32 *)
  273.   RETURN s1 / s2
  274. END SymDiff32;
  275.  
  276.  
  277. PROCEDURE In32 * ( s1 : SET32; i : INTEGER ) : BOOLEAN;
  278. BEGIN (* In32 *)
  279.   RETURN i IN s1
  280. END In32;
  281.  
  282.  
  283. PROCEDURE Long8 * ( s : SET8 ) : SET16;
  284. BEGIN (* Long8 *)
  285.   RETURN LONG (s)
  286. END Long8;
  287.  
  288.  
  289. PROCEDURE Long16 * ( s : SET16 ) : SET32;
  290. BEGIN (* Long16 *)
  291.   RETURN LONG (s)
  292. END Long16;
  293.  
  294.  
  295. PROCEDURE Short16 * ( s : SET16 ) : SET8;
  296. BEGIN (* Short16 *)
  297.   RETURN SHORT (s)
  298. END Short16;
  299.  
  300.  
  301. PROCEDURE Short32 * ( s : SET32 ) : SET16;
  302. BEGIN (* Short32 *)
  303.   RETURN SHORT (s)
  304. END Short32;
  305.  
  306.  
  307. <*$IndexChk-*>
  308.  
  309. PROCEDURE (VAR s : Set) Init * ( max : INTEGER );
  310. BEGIN (* Init *)
  311.   s.max := max;
  312.   NEW (s.val, (max + setSize) DIV setSize)
  313. END Init;
  314.  
  315.  
  316. PROCEDURE (VAR s : Set) CopyTo * ( VAR s1 : Set );
  317.   VAR i : INTEGER;
  318. BEGIN (* CopyTo *)
  319.   s1.Init (s.max);
  320.   FOR i := 0 TO s.max DIV setSize DO s1.val [i] := s.val [i] END
  321. END CopyTo;
  322.  
  323.  
  324. PROCEDURE (VAR s : Set) Clear *;
  325.   VAR i : INTEGER;
  326. BEGIN (* Clear *)
  327.   FOR i := 0 TO s.max DIV setSize DO s.val [i] := {} END
  328. END Clear;
  329.  
  330.  
  331. PROCEDURE (VAR s : Set) Incl * ( x : INTEGER );
  332. BEGIN (* Incl *)
  333.   IF (x > 0) & (x <= s.max) THEN
  334.     INCL (s.val [x DIV setSize], x MOD setSize)
  335.   END
  336. END Incl;
  337.  
  338.  
  339. PROCEDURE (VAR s : Set) InclRange * ( x, y : INTEGER );
  340.   VAR i : INTEGER;
  341. BEGIN (* InclRange *)
  342.   IF y < x THEN i := x; x := y; y := i END;
  343.   IF x < 0 THEN x := 0 END; IF y > s.max THEN y := s.max END;
  344.   FOR i := x TO y DO
  345.     INCL (s.val [i DIV setSize], i MOD setSize)
  346.   END
  347. END InclRange;
  348.  
  349.  
  350. PROCEDURE (VAR s : Set) Excl * ( x : INTEGER );
  351. BEGIN (* Excl *)
  352.   IF (x > 0) & (x <= s.max) THEN
  353.     EXCL (s.val [x DIV setSize], x MOD setSize)
  354.   END
  355. END Excl;
  356.  
  357.  
  358. PROCEDURE (VAR s : Set) ExclRange * ( x, y : INTEGER );
  359.   VAR i : INTEGER;
  360. BEGIN (* ExclRange *)
  361.   IF y < x THEN i := x; x := y; y := i END;
  362.   IF x < 0 THEN x := 0 END; IF y > s.max THEN y := s.max END;
  363.   FOR i := x TO y DO
  364.     EXCL (s.val [i DIV setSize], i MOD setSize)
  365.   END
  366. END ExclRange;
  367.  
  368.  
  369. PROCEDURE (VAR s : Set) Contains * ( x : INTEGER ) : BOOLEAN;
  370. BEGIN (* Contains *)
  371.   RETURN (x > 0) & (x <= s.max)
  372.          & (x MOD setSize IN s.val [x DIV setSize])
  373. END Contains;
  374.  
  375.  
  376. PROCEDURE (VAR s : Set) Add * ( VAR s1 : Set );
  377.   VAR i, max : INTEGER;
  378. BEGIN (* Add *)
  379.   max := s.max; IF s1.max < max THEN max := s1.max END;
  380.   FOR i := 0 TO max DIV setSize DO
  381.     s.val [i] := s.val [i] + s1.val [i]
  382.   END
  383. END Add;
  384.  
  385.  
  386. PROCEDURE (VAR s : Set) Subtract * ( VAR s1 : Set );
  387.   VAR i, max : INTEGER;
  388. BEGIN (* Subtract *)
  389.   max := s.max; IF s1.max < max THEN max := s1.max END;
  390.   FOR i := 0 TO max DIV setSize DO
  391.     s.val [i] := s.val [i] - s1.val [i]
  392.   END
  393. END Subtract;
  394.  
  395.  
  396. PROCEDURE (VAR s : Set) Intersect * ( VAR s1 : Set );
  397.   VAR i, max : INTEGER;
  398. BEGIN (* Intersect *)
  399.   max := s.max; IF s1.max < max THEN max := s1.max END;
  400.   FOR i := 0 TO max DIV setSize DO
  401.     s.val [i] := s.val [i] * s1.val [i]
  402.   END
  403. END Intersect;
  404.  
  405.  
  406. PROCEDURE (VAR s : Set) SymDiff * ( VAR s1 : Set );
  407.   VAR i, max : INTEGER;
  408. BEGIN (* SymDiff *)
  409.   max := s.max; IF s1.max < max THEN max := s1.max END;
  410.   FOR i := 0 TO max DIV setSize DO
  411.     s.val [i] := s.val [i] / s1.val [i]
  412.   END
  413. END SymDiff;
  414.  
  415.  
  416. PROCEDURE (VAR s : CharSet) Init * ( max : INTEGER );
  417. BEGIN (* Init *)
  418.   s.Init^ (ORD (MAX (CHAR)))
  419. END Init;
  420.  
  421.  
  422. PROCEDURE (VAR s : CharSet) InclCh * ( ch : CHAR );
  423. BEGIN (* InclCh *)
  424.   s.Incl^ (ORD (ch))
  425. END InclCh;
  426.  
  427.  
  428. PROCEDURE (VAR s : CharSet) InclChRange * ( ch1, ch2 : CHAR );
  429. BEGIN (* InclChRange *)
  430.   s.InclRange^ (ORD (ch1), ORD (ch2))
  431. END InclChRange;
  432.  
  433.  
  434. PROCEDURE (VAR s : CharSet) InclStr * ( str : ARRAY OF CHAR );
  435.   VAR i : INTEGER; ch : CHAR;
  436. BEGIN (* InclStr *)
  437.   i := 0;
  438.   LOOP
  439.     ch := str [0]; IF ch = 0X THEN EXIT END;
  440.     s.Incl^ (ORD (ch)); INC (i)
  441.   END
  442. END InclStr;
  443.  
  444.  
  445. PROCEDURE (VAR s : CharSet) ExclCh * ( ch : CHAR );
  446. BEGIN (* ExclCh *)
  447.   s.Excl^ (ORD (ch))
  448. END ExclCh;
  449.  
  450.  
  451. PROCEDURE (VAR s : CharSet) ExclChRange * ( ch1, ch2 : CHAR );
  452. BEGIN (* ExclChRange *)
  453.   s.ExclRange^ (ORD (ch1), ORD (ch2))
  454. END ExclChRange;
  455.  
  456.  
  457. PROCEDURE (VAR s : CharSet) ExclStr * ( str : ARRAY OF CHAR );
  458.   VAR i : INTEGER; ch : CHAR;
  459. BEGIN (* ExclStr *)
  460.   i := 0;
  461.   LOOP
  462.     ch := str [0]; IF ch = 0X THEN EXIT END;
  463.     s.Excl^ (ORD (ch)); INC (i)
  464.   END
  465. END ExclStr;
  466.  
  467.  
  468. PROCEDURE (VAR s : CharSet) ContainsCh * ( ch : CHAR ) : BOOLEAN;
  469. BEGIN (* ContainsCh *)
  470.   RETURN s.Contains^ (ORD (ch))
  471. END ContainsCh;
  472.  
  473. END Sets.
  474.