# Section 8.5.4.2.1:
FLIST

###### class FLIST{ETP} < $FLISTS{ETP}

#### Formal Definitions

This class specifies features appropriate to the abstraction of a mutable list from which it sub-types. The sub-typing from $ELT_NIL permits the definition of creation for an empty list.

types
SAME = FLIST_ETP ;
FLIST_ETP = seq of ETP

This class implements lists of elements with mutable semantics. These may be viewed as extensible stacks. Like any list abstraction (eg linked lists) they serve as general container objects for holding collections of other objects. The requirement for this class is specified in order that implementations may provide a highly efficient list facility.

#### External specifications

The following features are required to be implemented for this class in accordance with the specification given in the class $FLISTS{} of which this is a sub-type :-

- create(contents : $RO_ARR{ETP}) : SAME
- array : $ARR{ETP}
- clear
- push(val : ETP) : SAME

The following features are required to be implemented for this class in accordance with the specification given in the class $LISTS{} of which $FLISTS{} is a sub-type :-

- create : SAME
- create(size : CARD) : SAME
- equals(other : $RO_ARR{ETP}) : BOOL
- count(val : ETP) : CARD
- insert_after(index : CARD, val : ETP) : SAME
- insert_before(index : CARD, val : ETP) : SAME
- insert_all_before(index : CARD, val : $CONTAINER{ETP}) : SAME
- insert_all_after(index : CARD, val : $CONTAINER{ETP}) : SAME

The following features are required to be implemented for this class in accordance with the specification given in the class $ARR{} of which $FLISTS{} is a sub-type :-

- aset(index : CARD, elem : ETP)
- set!(elem : ETP)

The following features are required to be implemented for this class in accordance with the specification given in the class $RO_ARR{} of which $FLISTS{} is a sub-type :-

- aget(index : CARD) : ETP)
- has_ind(val : CARD) : BOOL)
- ind! : CARD

The following features are required to be implemented for this class in accordance with the specification given in the class $CONTAINER{} of which $FLISTS{} is a sub-type :-

- contains(elem : ETP) : BOOL)
- is_empty : BOOL)

The following features are required to be implemented for this class in accordance with the specification given in $FILTERS of which $FLISTS{} is a sub-type :-

- count_if(predicate : ROUT{ETP} : BOOL) : CARD
- exists(predicate : ROUT{ETP} : BOOL) : BOOL
- exists(predicate : ROUT{ETP} : BOOL, out res : ETP) : BEEL
- not_exists(predicate : ROUT{ETP} : BOOL) : BOOL
- every(predicate : ROUT{ETP} : BOOL) : BOOL
- not_every(predicate : ROUT{ETP} : BOOL) : BOOL
- unique! : ETP
- filter!(predicate : ROUT{ETP} : BOOL) : ETP
- not_filter!(predicate : ROUT{ETP} : BOOL) : ETP

The following feature is required to be implemented for this class in accordance with the specification given in the class $COPY of which $FLISTS{} is a sub-type :-

- copy : SAME

The following features are required to be implemented for this class in accordance with the specification given in $ELT of which $FLISTS{} is a sub-type :-

- size : CARD
- elt! : $OB

The following features are required to be implemented for this class in accordance with the specifications given by inheritance in $STR of which $FLISTS{} is a sub-type :-

- str(lib : LIBCHARS) : STR
- str : STR

The following features are required to be implemented for this class in accordance with the specifications given by inheritance in $ELT_NIL of which this class is a sub-type :-

- elt_nil : ETP
- is_elt_nil : BOOL

#### create

This feature creates and returns a list of the elements for which the argument is a textual representation.

create | (
| str : STR
| ) : SAME

##### Formal Signature

create(src : STR, sep : CHAR) res : SAME

##### Pre-condition

pre (CHAR::is_space(sep) and sep <> LIBCHARS::char(LIBCHARS::Space(STR::index_lib(src))))
or not CHAR::is_control(sep)

##### Post-condition

post res(str(STR::index_lib(src), sep)) = src

This feature creates a new list, the elements of which are set to have the values represented in the string argument, the result having the size given by the number of elements in the src string.

#### create_from

This feature creates and returns a list of any kind of container which derives from the abstraction $ELT.

create_from | (
| container : $ELT{ETP}
| ) : SAME

##### Formal Signature

create_from(container : $ELT_T) res : SAME

##### Pre-condition

Since the argument is not an optional type, the pre-condition is vacuously true.

##### Post-condition

post size(res) = size(container)
and forall index in set inds res
container(index) = res(index)

This feature creates a new list, the elements of which are set to have the values of the elements in the given container in such a way that the order of elements in the sequence indexed for the result is the same as that of the argument.

#### create_empty_sized

This feature creates and returns a list of the required size all of the elements of which are nil.

create_empty_sized | (
| size : CARD
| ) : SAME

##### Formal Signature

create_empty_sized(size : CARD) res : SAME

##### Pre-condition

Since the argument is never negative, the pre-condition is vacuously true.

##### Post-condition

post size(res) = count
and forall index in set inds res
res(index) = elt_nil(res(index))

This feature creates a new list, the elements of which are set to have the value elt_nil.

#### build

This feature creates and returns a list of the elements from the cursor given, taking the start argument as the character which is expected as the first non-space character in the buffer and the finish argument as the non-space element in the buffer which closes the list source in the buffer.

build | (
| cursor : STR_CURSOR,
| start : CHAR,
| finish : CHAR
| ) : SAME

##### Formal Signature

build(cursor : STR_CURSOR, start : CHAR, finish : CHAR) res : SAME

##### Pre-condition

pre (CHAR::is_print(start) and not CHAR::is_space(start))
and (CHAR::is_print(finish)
and not CHAR::is_space(finish))
and (STR_CURSOR::remaining(cursor) >= 2
and let buff : seq of CHAR be st buff = STR_CURSOR::buffer(cursor) in
forall idx1, idx2 in set inds buff | (idx1 <> idx2
and exists idx1 & buff(idx1) = start and exists idx2 & buff(idx2) = finish) & idx2 > idx1)

##### Post-condition

post res(str(STR::index_lib(src), sep)) = src

This feature creates a new list, the elements of which are set to have the values represented in the string argument, the result having the size given by the number of elements in the src string.

#### pop

This feature provides a conventional stack operation for the list, successive calls returning items in LIFO order.

pop | : ETP

##### Formal Signature

pop(self : SAME) res : [ETP]

##### Pre-condition

This is vacuously true since the list itself is required to exist by the definition of this feature.

##### Post-condition

post ((loc~ = 0)
and (res = nil))
or ((res = [loc])
and (loc + 1 = loc~))

This routine removes the element at the head of the list and returns the object removed.

#### top

This feature provides a conventional stack operation for the list, always returning the item at the head of it.

top | : ETP

##### Formal Signature

top(self : SAME) res : [ETP]

##### Pre-condition

This is vacuously true since the list itself is required to exist by the definition of this feature.

##### Post-condition

post ((loc~ = 0)
and (res = nil))
or ((res = [loc - 1])
and (loc = loc~))

This routine returns the element at the head of the list.

#### reset

This feature provides a mechanism for re-using, rather than re-creating a mutable list.

reset

##### Formal Signature

reset(self : SAME)

##### Pre-condition

This is vacuously true since the list itself is required to exist by the definition of this feature.

##### Post-condition

post (loc = 0)

This routine resets the list to be the empty list.

#### index_of

This feature returns the index of the first occurrence of the given element in the list.

index_of | (
| elem : ETP
| ) : CARD

##### Formal Signature

index_of(self : SAME, elt : ETP) res : CARD

##### Pre-condition

Since the arguments are not optional this is vacuously true.

##### Post-condition

post let list : seq of ETP be st list = self in
(elt not in set dom list
and res = nil
or let head ^ tail = list be st
elt not in set dom head
and tail(1) = elt
in res = len head

This feature searches the list from the beginning to find the first occurrence (if any) of the given element in the list. If the search was successful then the index where it was found is returned, otherwise CARD::nil.

#### append

This feature returns the result of appending the argument list to self.

append | (
| list : SAME
| ) : SAME

##### Formal Signature

append(self : SAME, list : SAME) res : SAME

##### Pre-condition

Since the arguments are not optional this is vacuously true.

##### Post-condition

post res = copy(self) ^ list

This routine appends the given list to the end of a copy of self and returns the result. Self may be void; list must not be the same as self unless it is void!

#### concat

This feature returns the result of appending the argument list to self destructively and should therefore be faster than append above.

concat | (
| list : SAME
| ) : SAME

##### Formal Signature

concat(self : SAME, list : SAME) res : SAME

##### Pre-condition

Since the arguments are not optional this is vacuously true.

##### Post-condition

post res = self ^ list

This routine appends the given list to the end of self and returns the result. Self may be void; list must not be the same as self unless it is void!

sublist( beg, num : CARD ) : SAME pre ~void(self) and (beg <= (loc - 1)) and (num <= (loc - beg)) post (result.size = num) -- and (result[0] = [beg]) is -- This routine returns a sublist of num entries starting at beg. -- Self may not be void. to_reverse pre true post (self.size = initial(self.size)) -- (initial([0]) = [size - 1]) is -- This routine sets self to be rearranged in the reverse order of -- elements. fill( elem : ETP ) pre ~void(self) post true -- should be every(bind(_.elt_eq(elem))) is -- This routine fills all elements of the list with the given element -- value. inds : ARRAY{CARD} pre ~void(self) post ((result.size = size) and (result[size - 1] = (size - 1))) is -- This routine produces an array containing the same number of elements -- as self, the individual elements of which contain a value corresponding -- to their index. delete( index : CARD ) : SAME pre ~void(self) and (index <= (loc - 1)) post (result.loc = (initial(loc) - 1)) is -- This routine returns the result of deleting the indexed element from -- self. delete_elt( elem : ETP ) : SAME pre ~void(self) and contains(elem) post (result.loc = (initial(loc) - 1)) is -- This routine returns the result of deleting the given element from -- self. delete_ordered( index : CARD ) : SAME pre ~void(self) and (index <= (loc - 1)) post (result.loc = (initial(loc) - 1)) is -- This routine returns the result of deleting the indexed element from -- self in such a way as to preserve the order of the list. delete_elt_ordered( elem : ETP ) : SAME pre ~void(self) and contains(elem) post (result.loc = (initial(loc) - 1)) is -- This routine returns the result of deleting the given element from -- self in such a way as to preserve the order of the list.

#### elt!

This iter version and the one following complement the one inherited by this abstraction. This permits the first element yielded to be the element indexed by the start argument.

elt! | (
once | start : CARD
| ) : ELT

##### Formal Signature

Note that the formal name of the iter has been changed to replace the exclamation mark iter symbol to a name acceptable to vdm tools.

elt_iter2(self : SAME, start : CARD) res : ELT

##### Pre-condition

Since the iter may quit if start is not in the domain of indices of self, the pre-condition is vacuously true.

##### Post-condition

This post-condition makes use of the history concept from vdm++ (see the vdm dialect notes).

post history = history~ ^ [res]
and res = self(len history + start)

##### Quit condition

For quit actions see the specification of the quit statement.

errs QUIT : (len history + start) = len self -> quit

This iter yields the elements of self in order beginning with the element at the given starting index.

#### elt!

This iter version specifies both the element to yield first and the number of elements to be yielded.

elt! | (
once | start : CARD
once | num : CARD
| ) : ELT

##### Formal Signature

Note that the formal name of the iter has been changed to replace the exclamation mark iter symbol to a name acceptable to vdm tools.

elt_iter3(self : SAME, start : CARD, num : CARD) res : ELT

##### Pre-condition

Since the iter may quit if start is not in the domain of indices of self, the pre-condition is vacuously true.

##### Post-condition

This post-condition makes use of the history concept from vdm++ (see the vdm dialect notes).

post history = history~ ^ [res]
and res = self(len history + start)

##### Quit condition

For quit actions see the specification of the quit statement.

errs QUIT : (len history = num)
or (len history + start) = len self -> quit

This iter yields num elements of self in order beginning with the element at the given starting index.

#### elt!

This final version of the elt! iter specifies the element to yield first, the number of elements to be yielded and the index interval between the elements to be yielded.

elt! | (
once | start : CARD
once | num : CARD
once | step : INT
| ) : ELT

##### Formal Signature

Note that the formal name of the iter has been changed to replace the exclamation mark iter symbol to a name acceptable to vdm tools.

elt_iter3(self : SAME, start : CARD, num : CARD, step : INT) res : ELT

##### Pre-condition

Since the iter may quit if start is not in the domain of indices of self, the pre-condition is vacuously true.

##### Post-condition

This post-condition makes use of the history concept from vdm++ (see the vdm dialect notes).

post history = history~ ^ [res]
and res = self(len history + start)

##### Quit condition

For quit actions see the specification of the quit statement.

errs QUIT : (len history = num)
or (len history + start) = len self -> quit

This iter yields num elements of self in order beginning with the element at the given starting index, each element yielded being at an interval step (which may be negative) from the previous element yielded.

#### str

This is a specialised version of the text string representation routine which specifies the character which is to be treated as the separator between list elements in the text.

str | (
| lib : LIBCHARS
| sep : CHAR
| ) : STR

##### Formal Signature

str(self : SAME, lib : LIBCHARS, sep : CHAR) res : STR

##### Pre-condition

Since there is a representation of an empty list - as {}, the pre-condition is vacuously true.

##### Post-condition

postself = create(res,sep)

This feature returns a text string consisting of the textual representation of each list element separated by the given character sep, enclosed in braces.

### Set-like Features

The remaining features of this class provide facilities for set-like operations on mutable lists. These are defined as a convenience where occasional use of such a feature on a list is required.

An implementation is required to provide the features above in as efficient a manner as possible. The set-like feature efficiency must be subordinate in this context (see, however, the class FSET{ELT}).

union( list : SAME ) : SAME pre true post (result.size <= (size + list.size)) is -- This routine returns a new list containing the elements in the union -- of self and list. Self may be void. intersect( list : SAME ) : SAME pre true post (result.size <= list.size) is -- This routine returns a new list containing the elements which are -- in both self and list. Self may be void. difference( list : SAME ) : SAME pre true post (result.size <= size) is -- This routine returns a new list containing the elements of self -- which are not in list. Self may be void. sym_difference( list : SAME ) : SAME pre true post (result.size <= (size + list.size)) is -- This routine returns a new list containing the elements in self or in -- list but not in both. Self may be void.

| Language Index |  | Library Index |  | Container Index

Comments or enquiries should be made to Keith Hopper. Page last modified: Monday, 26 February 2001. |