bag_incl.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
---------------------------> Sather 1.1 source file <--------------------------
-- Author: Benedict A. Gomes <gomes@samosa.ICSI.Berkeley.EDU>
-- Copyright (C) 1995, International Computer Science Institute
-- $Id: bag_incl.sa,v 1.7 1996/06/01 21:36:15 gomes Exp $
--
-- COPYRIGHT NOTICE: This code is provided WITHOUT ANY WARRANTY
-- and is subject to the terms of the SATHER LIBRARY GENERAL PUBLIC
-- LICENSE contained in the file: Sather/Doc/License of the
-- Sather distribution. The license is also available from ICSI,
-- 1947 Center St., Suite 600, Berkeley CA 94704, USA.
partial class BAG_INCL{E}
partial class BAG_INCL{E} is
-- Partial class for read-only sets that implements other functions
-- in terms of has and elt!
-- Until we get partial classes, include using:
-- include BAG_INCL{E} has->, elt!->,unique!->;
include COMPARE{E};
-- --------- CORE FEATURES (must define) ---------
stub has(e:E): BOOL;
-- Return true if the bag has the element "e"
stub elt!: E;
-- Yield successive elements of the bag
stub unique!: E;
-- Yield unique elements of the bag (i.e. as if it were a set)
stub count(e: E): INT;
-- Return the number of times the element "e" occurs in the bag
stub insert(e:E);
-- Insert "e" into the bag
stub copy: SAME;
-- Return a copy of the bag
-- ------ Initialization/Duplication -------
private internal_create: SAME is return #BAG{E} end;
-- Default create. Called internally
-- ------ Access/Measurement -------------
size: INT is
i ::= 0; loop discard ::= elt!; i := i + 1; end;
return i;
end;
is_empty: BOOL pre ~void(self) is
-- Do not do size=0. Finding size may require iteration
-- through all elements - quite wasteful for just "is_empty"
loop e ::= elt!; return false; end;
return true;
end;
-- ------ Queries/Comparison --------------
equals(a:$RO_BAG{E}): BOOL
pre ~void(self) and ~void(a)
is
if size /= a.size then return false end;
loop e::=unique!; if count(e) /= a.count(e) then return false end end;
return true
end;
is_subset(a: $RO_BAG{E}): BOOL
-- Returns true, if 'a' has all elements with higher occurences
-- as self.
pre ~void(self) and ~void(a)
is
loop e ::= unique!; if count(e) > a.count(e) then return false end end;
return true
end;
-- ------ Conversion ----------------------
as_array: ARRAY{E} is
res ::= #ARRAY{E}(size);
loop res.set!(elt!) end;
return res;
end;
str: STR is
-- Prints out a string version of the array of the components
-- that are under $STR
res ::= #FSTR("{");
loop res := res+",".separate!(elt_str(elt!)); end;
res := res + "}";
return(res.str);
end;
-- ------ Basic Operations ----------------
union(a: $RO_BAG{E}): SAME
-- Returns a set containing all elements being contained in
-- the sets. The properties of the result are the ones from
-- the first set.
-- Neither of the sets may be void.
pre ~void(self) and ~void(a)
is
res ::= copy;
loop res.insert(a.elt!) end;
return res
end;
intersection(a: $RO_BAG{E}): SAME
-- Returns a set containing all elements being contained in
-- both sets. The properties of the result are the ones from
-- the first set.
-- Neither of the sets may be void.
pre ~void(self) and ~void(a)
is
res ::= internal_create;
loop
e ::= elt!;
if a.has(e) then res.insert(e) end
end;
return res
end;
difference(a:$RO_BAG{E}): SAME
-- Returns a set containing all elements being contained in
-- self but not in a. The properties of the result are the ones
-- from the first set.
-- Neither of the sets may be void.
pre ~void(self) and ~void(a)
is
res ::= internal_create;
loop
e ::= elt!;
if ~a.has(e) then res.insert(e) end
end;
return res
end;
is_disjoint(a:$RO_BAG{E}): BOOL
-- Returns 'true' if all elements of 'self' are not contained
-- in 'a' and vice versa.
-- Neither may be void.
pre ~void(self) and ~void(a)
is
loop if has(a.elt!) then return false end end;
loop if a.has(elt!) then return false end end;
return true
end;
count_if(test:ROUT{E}:BOOL):INT is
-- The number of elements which satisfy `test'.
-- Self may be void.
r::=0;
loop if test.call(elt!) then r:=r+1 end end;
return r
end;
index_of(e: E):INT is
-- Return index of leftmost element of self which is equal to "e"
-- or -1 if there is none.
i ::= 0;
loop r ::= elt!;
if elt_eq(e,r) then return i end;
i := i + 1;
end;
return -1;
end;
some(test:ROUT{E}:BOOL):BOOL is
-- True if some element of self satisfies `test'.
-- Self may be void.
loop if test.call(elt!) then return true end end;
return false
end;
every(test:ROUT{E}:BOOL):BOOL is
-- True if every element of self satisfies `test'.
-- Self may be void.
loop if ~test.call(elt!) then return false end end;
return true
end;
notany(test:ROUT{E}:BOOL):BOOL is
-- True if none of the elements of self satisfies `test'.
-- Self may be void.
loop if test.call(elt!) then return false end end;
return true
end;
notevery(test:ROUT{E}:BOOL):BOOL is
-- True if not every element of self satisfies `test'.
-- Self may be void.
loop if ~test.call(elt!) then return true end end;
return false
end;
-- ------------------- Implementation ------------------
private elt_str(e: E): STR is
-- Return a string representing the element "e"
typecase e
when $STR then return e.str else return "Unprintable Element" end;
end;
end;