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}