map_incl.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>  <--------------


partial class RO_MAP_INCL{KEY,ETP}

partial class RO_MAP_INCL{KEY,ETP} is -- This partial class implements the common features of read-only maps. -- Version 1.3 Nov 87. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 18 Jul 94 hk Original -- 9 Apr 96 bg Revision for Sather 1.1 -- 4 Apr 97 kh Changed for INT to CARD -- 10 Nov 98 kh Rewritten for 1.2, added pre/post conditions include CONTAINER{TUP{KEY,ETP}} ; private stub has_ind( elem : KEY ) : BOOL ; -- This predicate returns true if and only if self contains an element -- which is element equal to elem. stub size : CARD ; -- This returns the number of elements in the map stub copy : SAME ; -- This routine must return an exact copy of self. stub aget( index : KEY ) : ETP ; -- This routine returns the element indicated by the given index. stub insert( elem :TUP{KEY,ETP} ) : SAME ; -- This routine returns a new map identical to self and including -- the given element. stub delete( elem :TUP{KEY,ETP} ) : SAME ; -- This routine returns a new map identical to self except for an -- element which is element equal to elem. stub ind! : KEY ; -- This iter yields the indices of the map in sequence. stub elt! : TUP{KEY,ETP} ; -- This iter yields the elements of the map in sequence. stub target! : ETP ; -- This iter yields the mapped values of the map in sequence. create( arg : $ELT{TUP{KEY,ETP}} ) : SAME is -- This creation routine returns a new read-only map which contains -- the elements given in the argument. res : SAME := create ; loop res := res.insert(arg.elt!) end ; return res end ; array : ARRAY{TUP{KEY,ETP}} pre ~void(self) post (result.size = size) -- and the elements are equal! is -- This routine returns the elements of self as a one-dimensional array. res : ARRAY{TUP{KEY,ETP}} := ARRAY{TUP{KEY,ETP}}::create(size) ; loop res.set!(elt!) end ; return res end ; is_empty : BOOL is -- This predicate returns true is and only if the size of the map is -- zero - there are no elements! return size = 0 end ; contains( elem : TUP{KEY,ETP} ) : BOOL pre ~void(self) post true is -- This predicate returns true if and only if the given element is in -- the map. loop loc_elem : TUP{KEY,ETP} := elt! ; if elt_eq(loc_elem,elem) then return true end end ; return false end ; has( key : KEY, elem : ETP ) : BOOL pre ~void(self) post true is -- This predicate returns true if and only if the given key/element pair -- is in the map. return contains(TUP{KEY,ETP}::create(key,elem)) end ; equals( other : $RO_BAG{TUP{KEY,ETP}} ) : BOOL pre ~void(self) and ~void(other) post true is -- This routine returns true if and only if all of the elements of self -- and other when taken correspondingly are equal. if other.size /= size then return false end ; loop if ~contains(other.elt!) then return false end end ; return true end ; is_subset_of( arg : $RO_BAG{TUP{KEY,ETP}} ) : BOOL pre ~void(self) and ~void(arg) post true is -- This predicate returns true if and only if self is a subset of arg. -- For elements that occur multiple times, the number of occurences of the -- element in 'arg' must be greater than or equal to the number of occurences -- in self. loop loc_elem : TUP{KEY,ETP} := elt! ; if ~arg.contains(loc_elem) then return false end end ; return true end ; count( val : TUP{KEY,ETP} ) : CARD pre ~void(self) post (contains(val) and (result = 1)) or (result = 0) is -- This routines returns the number of elements in self which are -- elt_eq to elem. if contains(val) then return 1 else return 0 end end ; n_targets( key : KEY ) : CARD pre ~void(self) post (result = 0) or (result = 1) is -- This routine returns the number of targets associated with the given -- key. res : CARD := 0 ; loop discard : ETP := target!(key) ; res := res + 1 end ; return res end ; n_ind : CARD pre ~void(self) post (result = size) is -- This routine returns the number of keys in self (which is for a map -- equal to the number of elements in the map)! return size end ; n_unique : CARD pre ~void(self) post (result <= size) is -- This routine returns the number of unique pairs in self - less than -- or equal to size! res : CARD := 0 ; loop discard : TUP{KEY,ETP} := unique! ; res := res + 1 end ; return res end ; add( elem : TUP{KEY,ETP} ) : VMULTIMAP{KEY,ETP} pre ~void(self) post (result.size = size + 1) is -- This routine returns a new map which is identical to self except for -- the insertion of the argument element. res : VMULTIMAP{KEY,ETP} := VMULTIMAP{KEY,ETP}::create(self) ; return res.add(elem) end ; add( key : KEY, elem : ETP ) : VMULTIMAP{KEY,ETP} pre ~void(self) post (result.size = size + 1) is -- This routine returns a new map which is identical to self except for -- the insertion of the argument element. The result is identical to that -- produced by the routine above! return add(TUP{KEY,ETP}::create(key,elem)) end ; insert( key : KEY, elem : ETP ) : SAME pre ~void(self) post (result.size >= size) and (result.size <= (size + 1)) is -- This routine inserts the element elem into the map. If the key is -- already present then this amounts to replacing that entry by the new -- mapping. return insert(TUP{KEY,ETP}::create(key,elem)) end ; delete( key : KEY, elem : ETP ) : SAME pre ~void(self) post (result.size <= size) and (result.size >= (size - 1)) is -- This routine returns a new map containing all of the elements of self -- except for the given mapping (if present!). return delete(TUP{KEY,ETP}::create(key,elem)) end ; delete_ind( key : KEY ) : SAME pre ~void(self) post (result.size <= size) and (result.size >= (size - 1)) is -- This routine returns a new map in which any occurences of the tuple -- (k,_) has been deleted. if has_ind(key) then loc_elem : ETP := aget(key) ; return delete(key,loc_elem) else return self end end ; delete_all( elem : TUP{KEY,ETP} ) : SAME pre ~void(self) post (result.size <= size) and (result.size >= (size - 1)) is -- This routine is a renaming of the above delete operation for a map, -- when there are no duplicate keys! return delete(elem.t1,elem.t2) end ; delete_all( key : KEY, elem : ETP ) : SAME pre ~void(self) post (result.size <= size) and (result.size >= (size - 1)) is -- This routine is a renaming of the above delete operation for a map, -- when there are no duplicate keys! return delete(TUP{KEY,ETP}::create(key,elem)) end ; concat( arg : $ELT{TUP{KEY,ETP}} ) : VMULTIMAP{KEY,ETP} pre ~void(self) and ~void(arg) post (result.size = size + arg.size) is -- This routine returns a multimap containing all the elements of self -- and 'arg'. For elements that occur multiple times, the result contains -- the sum of the number of occurences in self and 'arg'. res : VMULTIMAP{KEY,ETP} := VMULTIMAP{KEY,ETP}::create(self) ; loop res := res.add(arg.elt!) end ; return res end ; union( arg : $RO_BAG{TUP{KEY,ETP}} ) : VMULTIMAP{KEY,ETP} pre ~void(self) post (result.size <= (size + arg.size)) is -- This routine returns a new multimap which is the union of self and -- arg. Where multiple elements occur for one key then the larger of the two -- counts is stored in the resultant multimap. res : VMULTIMAP{KEY,ETP} := VMULTIMAP{KEY,ETP}::create(self) ; loop arg_elt : TUP{KEY,ETP} := arg.elt! ; if ~res.contains(arg_elt) then res := res.add(arg_elt) else if arg.count(arg_elt) > res.count(arg_elt) then res := res.add(arg_elt) end end end ; return res end ; union( arg : $RO_MAP{KEY,ETP} ) : SAME pre ~void(self) post (result.size <= (size + arg.size)) is -- This routine returns a map which is the union of self and arg. res : SAME := copy ; loop res := res.insert(arg.elt!) end ; return res end ; intersection( arg : $RO_BAG{TUP{KEY,ETP}} ) : VMULTIMAP{KEY,ETP} pre ~void(self) and ~void(arg) post (result.size <= (size + arg.size)) is -- This routine returns a multimap containing the elements common to -- self and 'arg'. For elements that occur multiple times, the result -- contains the minimum number of occurrences in either self or 'arg'. res : VMULTIMAP{KEY,ETP} := VMULTIMAP{KEY,ETP}::create(self) ; num_to_delete : CARD ; loop loc_elem : TUP{KEY,ETP} := unique! ; if count(loc_elem) > arg.count(loc_elem) then num_to_delete := count(loc_elem) - arg.count(loc_elem) ; loop num_to_delete.times! ; res := res.delete(loc_elem) end end end ; return res end ; intersection( arg : $RO_MAP{KEY,ETP} ) : SAME pre ~void(self) and ~void(arg) post (result.size <= (size + arg.size)) is -- This routine returns a map which contains the elements common to self -- and arg. res : SAME := copy ; loop loc_elem : TUP{KEY,ETP} := elt! ; if ~arg.contains(loc_elem) then res := res.delete(loc_elem) end end ; return res end ; diff( arg : $RO_BAG{TUP{KEY,ETP}} ) : SAME pre ~void(self) post (result.size <= size) is -- This routine returns a new map which contains the elements of self -- which are not in arg. res : SAME := copy ; loop loc_elem : TUP{KEY,ETP} := arg.elt! ; if contains(loc_elem) then res := res.delete(loc_elem) end end ; return res end ; sym_diff( arg : $RO_MAP{KEY,ETP} ) : SAME pre ~void(self) post (result.size <= (size + arg.size)) is -- This routine returns a map containing all the elements of self and -- arg which are in one, but not the other, map. loc_union : SAME := union(arg) ; loc_intersect : SAME := intersection(arg) ; return loc_union.diff(loc_intersect) end ; target!( once key : KEY ) : ETP pre ~void(self) post (result = aget(key)) -- or it has quit! is -- This iter yields the single element value associated with the given -- map key. if has_ind(key) then yield aget(key) end end ; pair! : TUP{KEY,ETP} pre ~void(self) post has_ind(result.t1) and (aget(result.t1) = result.t2) is -- This iter yields all of the elements of self in an implementation- -- dependent order. loop yield elt! end end ; unique! : TUP{KEY,ETP} pre ~void(self) post has_ind(result.t1) and (aget(result.t1) = result.t2) is -- This iter yields all of the elements of self in an implementation- -- dependent order. It is a synonym for elt! loop yield elt! end end ; end ; -- RO_MAP_INCL{KEY,ETP}

partial class MAP_INCL{KEY,ETP}

partial class MAP_INCL{KEY,ETP} is -- This partial class implements the non read-only features common to -- maps specified in $MAP{KEY,ETP}. -- -- Routine/iter stubs must be replaced by real function in any descendant -- that actually implements the abstraction. Particular implementations may -- replace also some of the non-stub operations by substantially more -- efficient versions, that make use of properties of the actual -- implementation. -- Version 1.1 Nov 98. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 12 Oct 96 bg New for Sather 1.2 -- 10 Nov 98 kh Original for 1.2, added pre/post conditions include RO_MAP_INCL{KEY,ETP} ; stub aset( key : KEY, elem : ETP ) ; -- This routine sets the element indicated by the given key to the new -- value. stub delete( key : KEY ) ; -- This routine sets the element indicated by the given key to the new -- value. as_value : VMAP{KEY,ETP} pre ~void(self) post ~void(result) is -- This routine returns the value map associated with self. return VMAP{KEY,ETP}::create(self) end ; delete( elem : TUP{KEY,ETP} ) : SAME pre ~void(self) post ~result.contains(elem) is -- This routine returns a new map from which the given element has been -- deleted. res : SAME := copy ; res.delete(elem.t1) ; return res end ; to_union( arg : $ELT{TUP{KEY,ETP}} ) pre ~void(self) and ~void(arg) post true -- ?????????? is -- This routine converts self to be the map which is the union of -- the initial value of self and the value of arg. loop loc_elem : TUP{KEY,ETP} := arg.elt! ; if ~contains(loc_elem) then [loc_elem.t1] := loc_elem.t2 end end end ; to_intersection( arg : $RO_MAP{KEY,ETP} ) pre ~void(self) and ~void(arg) post true -- ?????????? is -- This routine converts self to be the mathematical intersection of -- the initial value of self and arg. loop loc_elem : TUP{KEY,ETP} := arg.elt! ; if ~contains(loc_elem) then delete(loc_elem.t1) end end end ; to_diff( arg : $ELT{TUP{KEY,ETP}} ) pre ~void(self) and ~void(arg) post true -- ?????????? is -- This routine converts this map to be the mathematical difference of -- the initial value of self and arg. loop loc_elem : TUP{KEY,ETP} := arg.elt! ; if contains(loc_elem) then delete(loc_elem.t1) end end end ; to_sym_diff( arg : $ELT{TUP{KEY,ETP}} ) pre ~void(self) and ~void(arg) post true -- ???????????????? is -- This routine converts self to be the map which is the symmetrical -- difference of the initial value of self and arg. loop loc_elem : TUP{KEY,ETP} := arg.elt! ; if contains(loc_elem) then delete(loc_elem.t1) else [loc_elem.t1] := loc_elem.t2 end end end ; end ; -- MAP_INCL