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