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}