Evaluating the head of an empty list results in an undefined value. The specifications of Head and Tail show that Head evaluates the front of the list and Tail evaluates to the input list with its head removed. The specification of Head states that the head of a list created using Cons is either the value added to the list (if the initial list is empty) or is the same as the head of the initial list parameter to Cons . Adding an element to a list does not affect its head unless the list is empty. The value of the Tail operation is the list which is formed by taking the input list and removing its head. The definition of Tail shows how recursion is used in constructing algebraic specifications. The operation is defined on empty lists then recursively on non-empty lists with the recursion terminating when the empty list results. This is a very common technique to use when writing algebraic specifications. It is sometimes easier to understand recursive specifications by developing a short example. Say we have a list [5, 7] where 5 is the front of the list and 7 the end of the list. The operation Cons ([5, 7], 9) should return a list [5, 7, 9] and a Tail operation applied to this should return the list [7, 9]. The sequence of equations which results from substituting the parameters in the above specification with these values is: Tail ([5, 7, 9]) = Tail ( Cons ( [5, 7], 9)) = Cons ( Tail ([5, 7]), 9) = Cons ( Tail ( Cons (, 7)), 9) = Cons ( Cons ( Tail (), 7), 9) = Cons ( Cons ( Tail ( Cons (, 5)), 7), 9) = Cons ( Cons ([ Create ], 7), 9) = Cons (, 9) = [7, 9] The systematic rewriting of the axiom for Tail illustrates that it does indeed produce the anticipated result. The axiom for Head can be verified using a similar approach. 10.1.2 Primitive constructor operations
Algebraic Specification ©Ian Sommerville 1995 Version 1.0 April 25, 2000, 11:19 PM Page 10.8 When developing an algebraic specification, it is sometimes necessary to introduce additional constructor operations in addition to those identified as part of the interface specification. The interface constructors are then defined in terms of these more primitive operations. These additional primitive constructors may be required because it is difficult or impossible to define the inspection functions in terms of the interface functions. We can see an example of this in a binary tree specification with the identified interface functions as shown in Figure 10.5. It is impossible to specify the inspection operations ( Left, Data, Right , Is_empty, Contains ) in terms of the Add function. An extra function ( Build ) is therefore added to the specification to simplify their definition. There is no easy or automatic way to identify these functions. If you find it very difficult to specify inspection functions in terms of the identified constructors, this may mean that you have to think about the problem and try to identify a more primitive constructor operation.
You've reached the end of your free preview.
Want to read all 18 pages?
- Fall '17
- formal methods, Formal specification, Type system, Type theory