The final specifications document for any mid-sized project should at least cover:
Note that the specifications must be as detailed and complete as possible - think of the specifications as a contract you are agreeing to fulfill, if they aren't precise then there can be major arguments later as to whether or not your software is acceptable and complete.
Performance and reliability specifications should also be expressed in a measurable form: e.g.
For example, in developing a bank ATM system, viewpoints might include:
Reference: the viewpoint name Attributes: relevant viewpoint information (e.g. PIN number, account number) Events: describing how the system reacts in terms of events as seen from the current viewpoint (e.g. start transaction select service cancel transaction) Services: list of services available from this viewpoint (e.g. cash withdrawal, balance inquiry)
Reference: the service name Rationale: why the service is provided Specification: list of service specifications Viewpoints: list of viewpoints which access this service NF requirements: non-functional requirements (performance and constraints) Provider: which system objects are responsible for providing the service
DISPLAY INTRUCTIONS AND GET USER ID/PIN | |id,pin | DISPLAY INSTRUCTIONS AND GET REQUEST | |id,pin,request-type | ANALYZE REQUEST / | \ id,pin,withdraw/ |error \id,pin,balance-request etc.
Action name: Plain text description: Inputs for action: Outputs from action: Source of input data: Destination of output data: Requirements/pre-requisites to action: Side-effects of action:
The behavior of the function must create the difference between the two.
(A > B) and (C < D)
2 2 2 exists i, j, k in M..N: i = j + k
2 forall i in 1..10 : A[i] = i
One common method for this is through the ' symbol, e.g.: when we use parameter i in a predicate, i' represents the value of i after the function has completed, whereas i represents the value of i before the function has been started
function Halve (N : integer) : real; Pre-condition: N > 0 Post-condition: Halve (N) = N / 2
procedure Init (var A : array [1..100] of integer); Pre-condition: true Post-condition: forall i in 1..100: A'[i] = i
procedure SquareNeg (var A : array [5..10] of integer); Pre-condition: exists i in 5..10: A[i] < 0 Post-condition: forall i in 5..10: ((A[i] >= 0) and (A'[i] = A[i])) or ((A[i] < 0) and (A'[i] = A[i] * A[i]))
function Search (A : array [1..100] of integer; K : integer) : integer; Pre-condition: exists i in 1..100: A[i] = K Post-condition: (A'[Search (A, K)] = K) and (A' = A)
Error: (Search (A, K) = 0) and (A' = A)
imports <list of specification names>
<informal description of the adt and its operations>
<operation signatures setting out the operation names and the types
of the parameters to the operations defined over the adt>
<axioms defining the operations over the adt>
imports Integer
Arrays are collections of elements of generic type Elem. They have a lower and upper bound (see operations First, Last) Individual elements are accessed by their numeric index. Create takes the array bounds as parameters and creates the array, initializing the values to Undefined. Assign creates a new array which is the same as its input. Eval reveals the value of a specified element (Undefined if the access is outside the array bounds)
Create(Integer,Integer)->Array Assign(Array,Integer,Elem)->Array First(Array)->Integer Last(Array)->Integer Eval(Array,Integer)->Elem
First(Create(x,y)) = x First(Assign(a, n, v)) = First(a) Last(Create(x,y)) = y Last(Assign(a, n, v)) = Last(a) Eval(Create(x,y), n) = Undefined Eval(Assign(a, n, v), m) = Undefined if First(a) > m or Last(a) < m v if m == n Eval(a, m) otherwise
imports: Integer, Boolean
Defines an adt representing a Cartesian coordinate. Operations defined on Coord are X and Y, which evaluate the x and y attributes of an entity and Eq which compares two entities for equality.
Create(Integer,Integer)->Coord X(Coord)->Integer Y(Coord)->Integer Eq(Coord,Coord)->Boolean
X(Create(x,y)) = x Y(Create(x,y)) = y Eq(Create(x1,y1),Create(x2,y2)) = ((x1==x2) and (y1 == y2))
imports Integer
Defines a list where elements are added at the end and removed from the front. Create brings an empty list into existence Cons creates a new list with an added member Length evaluates the list size Head removes the front element of the list Tail creates a list by removing the head from its input list
Create->List Cons(List,Elem)->List Tail(List)->List Head(List)->Elem Length(List)->Integer
Head(Create)=Undefined Head(Cons(L,v)) = v if L == Create Head(L) otherwise Length(Create) = 0 Length(Cons(L,v)) = Length(L) + 1 Tail(Create) = Create Tail(Cons(L,v)) = Create if L == Create Cons(Tail(L),v) otherwise
New_List enriches List imports Integer, Boolean
New_List defines an extended form of list, inheriting the operations and properties of List and adding two new operations: - Add adds an element to the front of the list - Member determines if an element is present in the list
Add(New_List,Elem)->New_List Member(New_List,Elem)->Boolean
Add(Create,v) = Cons(Create, v) Member(Create,v) = False Member(Add(L,v),v1) = True if (v == v1) or Member(L,v1) == True False otherwise Member(Cons(L,v),v1) = True if (v == v1) or Member(L,v1) == True False otherwise Head(Add(L,v)) == v Tail(Add(L,v)) == L Length(Add(L,v)) = Length(L) + 1
i.e. we specify the data associated with a schema, and define the set of rules the data must obey
contents: N capacity: NI.e. the container can never hold more than it's capacity
contents <= capacity
light: {off, on} reading: N danger_level: Ni.e. the light is a low-level warning, it comes on when the "reading" drops below the critical level
light == on iff reading <= danger_level
Container IndicatorThe storage tank is composed of a container, with volume 5000 units, and an indicator, with the danger level set at 50.
reading = contents capacity = 5000 danger_level = 50
The contents in one context are the same as the reading in the other context
This format allows the reuse of components specified earlier
DStorage_Tank amount?: NOverfill: operation when too large an amount is entered (an error message is printed out)
contents + amount? <= capacity contents' = contents + amount?
XStorage_Tank amount?: N r!: seq CharFill: the fill operation, covering both possible cases
capacity < contents + amount? r! = "Insufficient tank capacity: Fill cancelled"
Fill_OK V Overfill