enumsets.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 
------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand        --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute  and/or modify it under the terms of the GNU Library General --
-- Public  License (LGPL)  as published  by the  Free  Software  Foundation; --
-- either version 2 of the license, or (at your option) any later version.   --
-- This  library  is distributed  in the  hope that it will  be  useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details.       --
-- The license text is also available from:  Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     --
-------------->  Please email comments to <bug-sather@gnu.org>  <--------------


abstract class $ENUM_SET < $IS_EQ, $IMMUTABLE

abstract class $ENUM_SET < $IS_EQ, $IMMUTABLE is -- This abstraction is of an arbitrary bit set whose size in bits is known. -- Version 1.0 Sep 99. Copright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 29 Sep 99 kh Original size : CARD ; --The number of bits which constitute the set. num_bits : NUM_BITS ; -- Provided that asize is not greater than NUM_BITS::asize this returns -- the set in the lowest size bits of the result - other bits being clear. -- If the pre-condition is not satisfied then the result is undefined. end ; -- $ENUM_SET

abstract class $ENUM_SET{TYP, ITP < $ENUMS{ITP}} < $ENUM_SET, $IS_LT{TYP}

abstract class $ENUM_SET{TYP, ITP < $ENUMS{ITP}} < $ENUM_SET, $IS_LT{TYP} is -- This abstraction is designed to handle arbitrary bit sets whose size -- in bits is determined by the element type ELEM which must be an -- enumeration. -- Version 1.3 Jan 97. Copright K Hopper,U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 12 Jun 96 kh Original -- 10 Dec 96 kh Minor changes for Sather 1.1 & portability -- 3 Jan 97 kh Converted to cardinals. -- 29 Sep 99 kh Changed inheritance -- NOTE The logical relations specify equality and sub-setting respectively. empty : SAME ; -- The empty set! is_empty : BOOL ; -- This returns true if and only if self is the empty set. plus(item : ITP) : SAME ; plus(other : TYP) : SAME ; minus(other : TYP) : SAME ; times(other : TYP) : SAME ; div(other : TYP ) : SAME ; -- Set operations -- -- union, difference, intersection, symmetric difference -- contains(item : ITP) : BOOL ; -- Set membership operation. end ; -- $ENUM_SET

partial class ENUM_SET{T,ELEM} < $ENUM_SET{T,ELEM}

partial class ENUM_SET{T,ELEM} < $ENUM_SET{T,ELEM} is -- This generic implementation includes all of the operations which -- are common to all kinds of bit-set. -- NOTE This implementation treats the first set element as the first in -- the array -- ie in little-endian octet order!! -- Version 1.4 Mar 00. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 12 Jun 96 kh Original -- 10 Dec 96 kh Minor changes for Sather 1.1 & portability -- 3 Jan 97 kh Converted Octets/bits!. -- 18 Sep 97 kh Now AVAL{BIT} -- 24 Mar 00 kh Renamed from BIT_SET private include AVAL{BIT} ; include COMPARABLE ; include BINARY ; --private const asize : CARD := ((ELEM::cardinality + OCTET::Octet_Bits - 1)/ -- OCTET::Octet_Bits) * OCTET::Octet_Bits ; private const asize : CARD := 32 ; --!!!!!!!!!TEMPORARY FUDGE!!!!!!!!-- const size : CARD := ELEM::cardinality ; -- This calculation ensures that the storage used is an exact multiple -- of octets in order to permit simple file storage, manipulation as a whole, -- etc! full : SAME is -- This routine returns a set in which all elements have been set. me : SAME ; loop index : CARD := size.times! ; me.aset(index,setbit) end ; return me end ; build(cursor : BIN_CURSOR) : SAME pre ~void(cursor) and (cursor.remaining >= (size / OCTET::Octet_Bits)) post true is --This routine creates a new value, taking the required number of -- octets from the given cursor string. me : SAME ; count : CARD := cursor.get_item.card ; outdex : CARD := 0 ; loop count.times! ; oct : OCTET := cursor.get_item ; loop index : CARD := 0.upto!(OCTET::Octet_Bits - 1) ; if oct.set(index) then me.aset(outdex + index,setbit) end end ; outdex := outdex + OCTET::Octet_Bits end ; return me end ; create(raw_bits : NUM_BITS) : SAME is -- Make a set out of the size least significant bits of the argument. me : SAME ; -- Presumed set to all unset bits. count : CARD := size.min(raw_bits.asize) ; loop index : CARD := 0.upto!(count - 1) ; me.aset(index,raw_bits.aget(index)) end ; return me end ; create(one : ELEM) : SAME is -- Make a set out of the single value argument. me : SAME ; -- Presumed set to all unset bits. bit : CARD := one.enum - ELEM::offset ; me.aset(bit,setbit) ; return me end ; create(list : ARRAY{ELEM}) : SAME is -- Make a set out of the values in the array. me : SAME ; -- assume all bits unset! loop bit : CARD := list.elt!.enum - ELEM::offset ; me.aset(bit,setbit) end ; return me end ; empty : SAME is -- Return the empty set! me : SAME ; -- all bits unset! return me end ; binstr : BINSTR pre true post result.size >= size / OCTET::Octet_Bits is --This merely returns the bits of the set as a bitstring (eg for filing). res : BINSTR := BINSTR::create ; outdex : CARD := 0 ; count : CARD := size ; loop oct : OCTET := OCTET::create ; loop index : CARD := 0.upto!(OCTET::Octet_Bits - 1) ; if count = 0 then if index > 0 then res := res + oct end ; return res.reverse end ; count := count - 1 ; oct := oct.alter(index,aget(outdex + index)) end ; res := res + oct ; outdex := outdex + OCTET::Octet_Bits end ; return res.reverse end ; num_bits : NUM_BITS pre size <= NUM_BITS::asize post true is --This routine returns the bits of the set as the least significant -- size bits of the result. res : NUM_BITS ; loop index : CARD := 0.upto!(size - 1) ; res.aset(index,aget(index)) end ; return res end ; plus(item : ELEM) : SAME pre true post result.contains(item) is --This routine provides the facility to add an individual value to the -- set. Note that it does not matter if it is already present! res : SAME := self ; bit : CARD := item.enum - ELEM::offset ; res.aset(bit,setbit) ; return res end ; plus(other : T) : SAME pre true post ((result - other) >= self) is -- This routine provides the set union operation. res : SAME := empty ; loop index : CARD := 0.upto!(asize - 1) ; if [index].set or other[index].set then res.aset(index,setbit) end end ; return res end ; minus(other : T) : SAME pre true post (result <= self) is --This routine is the set difference operation. res : SAME := self ; loop index : CARD := 0.upto!(asize - 1) ; if other[index].set then res.aset(index,clearbit) end end ; return res end ; times(other : T) : SAME pre true post (result <= self) and (result <= other) is --This operation is the set intersection operation. res : SAME := empty ; loop index : CARD := 0.upto!(asize - 1) ; if [index].set and other[index].set then res.aset(index,setbit) end end ; return res end ; div(other : T ) : SAME pre true post (result * self = self) and (result * other = other) is --This routine is the set symmetric difference operation. res : SAME := empty ; loop index : CARD := 0.upto!(asize - 1) ; if ([index].set and ~other[index].set) or (~[index].set and other[index].set) then res.aset(index,setbit) end end ; return res end ; is_eq(other : SAME) : BOOL is --This predicate returns true if and only if the two sets have -- identical contents. loop if aelt! /= other.aelt! then return false end end ; return true end ; is_leq(other : SAME) : BOOL is --This predicate returns true if and only if self is a simple sub-set -- of other. loop if aelt!.set and ~other.aelt!.set then return false end end ; return true end ; is_lt(other : SAME) : BOOL is -- This predicate returns true if self is a proper sub-set of other. return is_leq(other) and ~is_eq(other) end ; is_empty : BOOL is -- This predicate returns true if and only if self is the empty set. return self = empty end ; contains(try : ELEM) : BOOL is -- This is the set membership predicate for self. True is returned -- if and only if try is a member of self. bit : CARD := try.enum - ELEM::offset ; return [bit].set end ; str(lib : LIBCHARS) : STR pre ~void(lib) post (result.size >= 2) -- the braces of an empty set! is --The string representation of the set value using the given repertoire -- and encoding. res : STR := STR::create(lib) + lib.Left_Brace.char ; loc_sep : STR := STR::create(lib) + lib.Comma.char ; loop val : CARD := 1.for!(size) - 1 ; if [val].set then res := res + loc_sep.separate!(ELEM::create(val + ELEM::offset).str(lib)) end end ; return res + lib.Right_Brace.char end ; str : STR pre true post (result.size >= 2) -- the braces of an empty set! is --The string representation of the set value using the default library -- and character repertoire and encoding. return str(LIBCHARS::default) end ; fmt(format : ANCHORED_DESCR,lib : LIBCHARS) : STR pre ~void(lib) and ~void(format) post (result.size >= 2) -- the braces of an empty set! is --This routine returns the formatted string as described by the format -- descriptor. res : STR := str(lib) ; if format.leading > res.size then res := format.filler.str.repeat(format.leading - res.size) + res end ; if format.trailing > 0 then res := res + format.filler.str.repeat(format.trailing) end ; return res end ; fmt(format : ANCHORED_DESCR) : STR pre ~void(format) post (result.size >= 2) -- the braces of an empty set! is --This routine returns the formatted string expected to be in the -- given lib chars culture. return fmt(format,LIBCHARS::default) end ; end ; -- ENUM_SET{T,ELEM}