h_set.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> <--------------
class H_SET_IMPL{ELT} < $SET{ELT}
class H_SET_IMPL{ELT} < $SET{ELT} is
-- This class is an implementation of sets using dynamic hash tables.
-- This implementation is also able to deal with objects which are equal
-- but not the same.
-- Version 1.2 Nov 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 9 Apr 96 bv Original
-- 3 Apr 97 kh Changed for CARD instead of INT
-- 12 Nov 98 kh Revised for 1.2, added pre/post conditions.
private include DYNAMIC_BUCKET_TABLE{ELT,BUCKET{ELT}}
map_copy -> copy,
create -> create ;
create_from(
arr : ARRAY{ELT}
) : SAME is
-- This routine returns a set created from the given array of values.
return create(arr)
end ;
contains(
elem : ELT
) : BOOL
pre ~void(self)
post true
is
-- This predicate returns true if and only if elem is contained in self.
loop
if elt_key_eq(bucket(hash(elem)).list!.item,elem) then
return true
end
end ;
return false
end ;
size : CARD
pre ~void(self)
post (result = n_inds)
is
-- This routine returns the count of the elements in the set.
return n_inds
end ;
clear
pre ~void(self)
post (size = 0)
is
-- This routine iteratively deletes all of the elements from self.
--
-- NOTE This is not particularly efficient - rewriting may be able to improve
-- performance - but it must nevertheless be possible to separate
-- iteration and modification!
elts : ARRAY{ELT} := ARRAY{ELT}::create(n_inds) ;
loop
elts.set!(elt!)
end ;
loop
delete(elts.elt!)
end
end ;
insert(
elem : ELT
)
pre ~void(self)
post contains(elem)
is
-- This routine inserts the given element in the set.
hash_num : CARD := hash(elem) ;
loop -- to check if already there!
loc_item : ELT := bucket(hash_num).list!.item ;
if elt_key_eq(loc_item,elem) then
return
end
end ;
set_bucket(hash_num, BUCKET{ELT}::create(elem,bucket(hash_num))) ;
n_inds := n_inds + 1 ;
update_insert
end ;
insert_replace(
elem : ELT
) : ELT
pre ~void(self)
post contains(elem)
is
-- This routine inserts a new element to replace an old one which is
-- returned. If there was no old element then the same item is returned.
old : ELT ;
hash_num : CARD := hash(elem) ;
firstbkt : BUCKET{ELT} := bucket(hash_num) ;
loop
bkt : BUCKET{ELT} := firstbkt.list! ;
old := bkt.item ;
if elt_key_eq(old,elem) then
bkt.item(elem) ;
return old
end
end ;
set_bucket(hash_num,BUCKET{ELT}::create(elem,firstbkt)) ;
n_inds := n_inds + 1 ;
update_insert ;
return elem
end ;
insert_replace(
elem : ELT
)
pre ~void(self)
post contains(elem)
is
-- This routine inserts/replaces the given element in self without
-- returning the value of the element replaced.
dummy : ELT := insert_replace(elem)
end ;
delete_and_return(
elem : ELT
) : ELT
pre ~void(self)
post ~contains(result)
is
-- This routine removes an element from the set, returning the one
-- deleted. If there was nothing to delete then void (or ELT::nil) is
-- returned.
hash_num : CARD := hash(elem) ;
bkt : BUCKET{ELT} := bucket(hash_num) ;
prev : BUCKET{ELT} := bkt ; -- to give it a class!
prev := void ;
loop
until!(void(bkt)
or elt_key_eq(bkt.item,elem)) ;
prev := bkt ;
bkt := bkt.next
end ;
if void(bkt) then
return void
end ;
res : ELT := bkt.item ;
if void(prev) then
set_bucket(hash_num,bkt.next)
else
prev.next(bkt.next)
end ;
n_inds := n_inds - 1 ;
update_delete ;
return res
end ;
delete(
elem : ELT
)
pre ~void(self)
post ~contains(elem)
is
-- This routine deletes the given element without returning the item
-- deleted.
discard : ELT := delete_and_return(elem)
end ;
get(
elem : ELT
) : ELT
pre ~void(self)
post contains(elem)
or (result = elt_key_nil)
is
-- This routine returns the element of the set which is elt_eq to elem
-- or if no such element exists elt_key_nil
loop
item : ELT := bucket(hash(elem)).list!.item ;
if elt_key_eq(item,elem) then
return item
end
end ;
return elt_key_nil
end ;
elt! : ELT
pre ~void(self)
post contains(result)
is
-- This iter yields all of the elements of the set in an arbitrary order.
loop
bkt : BUCKET{ELT} := bucket(0.upto!(bound + split_pos - 1)) ;
loop
yield bkt.list!.item
end
end
end ;
end ; -- H_SET_IMPL{ELT}
class VSET{ETP} < $VSET{ETP}
class VSET{ETP} < $VSET{ETP} is
-- This class implements a set with value semantics. All modifying
-- operations return a new object, thus eliminating the possibility of
-- aliassing problems
-- Version 1.1 Nov 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 9 Apr 96 bg Originl for 1.2
-- 12 Nov 98 kh Refined, added pre/post conditions.
include RO_SET_INCL{ETP}
size -> ;
include H_SET_IMPL{ETP}
insert -> private insert,
delete -> private delete,
clear -> private clear,
insert_replace -> private insert_replace ;
is_eq(
anything : $OB
) : BOOL is
-- This predicate returns true if and only if self and anything have
-- the same value.
typecase anything
when $RO_BAG{ETP} then
if size /= anything.size then
return false
end ;
loop
elem : ETP := anything.unique! ;
if count(elem) /= anything.count(elem) then
return false
end
end ;
return true
else
return false
end
end ;
insert(
elem : ETP
) : SAME
pre true -- ??????? check copy preconditions
post result.contains(elem)
is
-- This routine inserts the given element in a copy of self before
-- returning the result.
res : SAME := copy ;
res.insert(elem) ;
return res
end ;
delete(
elem : ETP
) : SAME
pre true -- ??????? check copy preconditions
post ~result.contains(elem)
is
-- This routine inserts the given element in a copy of self before
-- returning the result.
res : SAME := copy ;
res.delete(elem) ;
return res
end ;
hash : CARD
pre true -- irrespective of value
post true -- irrespective of result
is
-- This routine returns a hash value based upon all of the values of
-- the members of the set.
res : NUM_BITS := NUM_BITS::create ;
loop
loc_hash : CARD := elt_hash(elt!) ;
if res.card = 0 then
res := NUM_BITS::create(loc_hash)
else
res := res.convolve(NUM_BITS::create(loc_hash))
end
end ;
return res.card
end ;
end ; -- VSET
class SET{ELT} < $SET{ELT}
class SET{ELT} < $SET{ELT} is
-- This class implements the mathematical set abstraction using the hash
-- set and generic set routines.
-- Version 1.2 Nov 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 9 Apr 96 bv Original
-- 3 Apr 97 kh Changed for style
include H_SET_IMPL{ELT} ;
include SET_INCL{ELT}
clear->,
size -> ;
end ; -- SET{ELT}