Calculational Derivation of Pointer Algorithms from Tree Operations

Calculational Derivation of Pointer Algorithms from Tree Operations

Science of Computer ELSEVlER Scicncc of Computer Programming 33 (I 999) 22 1-260 tree Communicated by R. Backhouse; received 9 December !99Y. wce!\cd in misrd form .?I ,\ruI I WX -_I-.__ Abstract We describe an approach to the derivation of correct algorithms on tree-based pointer htruc- tures. The approach is based on enriching treea in a way that allows ~1s to model conmo~l~ used poi!lter manipulations on tree structurei. \vc provide I-L&Xplhich a!!ow rcctlrsivc function.\ on trees to be trawformed into imperative algorithms on enriched trees. lr addition. WY pwvidc ru!es which a!low algorithms on enriched trees to be mechnrically transformed into efficient pointer algorithms. Al! transformations are cotxctness-preservi~lg. A key point of ollr approach 1s that we avoid aliasing through the way I? which trees are enriched and through some s*m- pie syntactic restrictions on transformable programs. @ 1999 Elwvier Scirnce r3.V All riphta reserved. Kt~~wox/.c: Pointers; Trees: Correctcess; Refinement; Transrormation --- _____ _~_____ _.._ The derivation of correct algorithms ipvo?ving pointers is difficult. In particular, the potentially complex connections within pointer structures make it difficldt to regcon about the side effects of poirzter assignment. This is further complicated by having to reason about algorithmic structures including loops and recursion. Ir! this paper, we describe an approach that factors out and simplifies somr: of tllc:sc difficulties in the context of tree-based pointer structures. We view the derivation of algorithms on tree-based pointer structures as a,n instance of data refinement, that iq. the replacement of a,hstra.ct trees by concrete pointer structrl.res. Opcmtions on abstrxt trwc are more naturally described as applicative-style recursive functions, whereas onerations on pointer structures are more natural.ly descrjbcd as imperative algorithms. WC factor out the dificu!ties of the derivation of pointer implcmcn.tations by enriching abstract trers in a way that al!ows algorithms on them to be described in aa imperative f&inn. _ E-mall: tn.i.butlcr(iclecs.sotorl.ac.uk. 0167.6423/99i$ see fro~~t mattw @ 1999 Elwbipr Science I3 V 411 rights rrsrrvcd !?I[: SOlh7-64??(98)n0016-1 222 M. Butler/Science of Computer Programming 33 (1999) 221-260 Thus we can develop the necessary algorithmic structure before introducing the pointer data structures. We further simplify the derivation by providing a collection of pre- proved specialised refinement transformations. Abstract trees are enriched in two ways: with paths and with the *-tree (or arbitrary tree). Paths are used to access subtrees and, instead of descending a tree in a recursive manner, we simply extend a path giving a deeper subtree. Abstract paths are represented at the concrete level by pointers. The *-tree provides an elegant way of dealing with sharing that arises in intermediate stages of pointer structure manipulation. The *-tree allows us to avoid aliasing of pointer structures, thus removing many of the difficulties that usually arise when reasoning about pointer structures. We describe some operations on enriched trees and provide rules for transforming these into simple standard pointer operations. These rules are compositional and allow a correct pointer implementation to be mechanically calculated from an algorithm involving enriched trees. This still leaves a gap between the standard applicative-style descriptions of tree operations and imperative algorithms on enriched trees. To help bridge this gap, we provide a collection of rules that allow imperative algorithms on enriched trees to be calculated from standard descriptions of tree operations, In some cases, as will be made clear, the resulting programs require further refinement before the pointer- introduction transformations may be applied, which means that the full derivation path is not completely mechanical. The program derivation framework used in our approach is the rejinement calculus of Back, Morgan and Morris [2,14,16]. The refinement calculus is a formalisation of the stepwise refinement method of program construction. The required behaviour is specified as an abstract, possibly non-executable, program which is then refined by a series of correctness-preserving refinement transformations into an efficient, executable program. The programming notation used is Dijkstra’s guarded command language [S], extended with assertion statements {p} (assume predicate p holds at this point in the computation) and generaked assignments x :=x’Ip (assign to x a value x’ satisfying predicate p), In order to describe the scope of this paper more clearly, we introduce some defini- tions associated with trees. Assume that Item is some given type, then a (binary) tree of Item is defined as a recursive data type: Tree G E 1node(item x Tree x Tree). That is, a tree can be the empty tree or a node consisting of an item and a left and a right subtree. Typically, fi,mctions on trees are described as applicative-style recursive functions. For example, the diction member, which checks whether an item exists in an ordered tree, is defined in Fig. 1. The components of a node tree are accessed as follows: root(node(b,l,R)) G b left(node(b,l,R)) G L right(node(b,&R)) G R. A4 ButlerlScience of Computer Programming 33 (1999) 221-260 223 mem.ber(a, E) = false member(a,node(b, L, R)) = if a = b -+ true 0 a < b -+ member(a, L) 0 a > b -+ member(a, R) fi. Fig. 1. Applicative search function on binary trees. procedure Member(va1 t : Tree; val a : Item; ref x : Bool) 1 I[var m : Path l m := 0; do t/m # E A a # root(t/m) + if a < root(t/m) -+ m := m(left) 0 a > root(t/m) + m := m(right) fi od; z := (t/m # 6) Fig. 2. Imperative search procedure on binary trees. A path is a finite sequence of left or right moves leading to a subtree: Path + seq(left ( right). We write () for the empty path, (d) for the singleton path and rnlrnz for the concate- nation of paths ml and m2. The subtree of t reached by following path m is denoted t/m which is (partially) defined as follows: t/o &_t node(b,L,R)/(left)m AL/m node(b, L, R) /(right)m A R/m. The set of all paths of a tree is defined as follows: paths(e) 2 (01 paths(node(b,L,R)) A (0) U {(left)m(m E paths(L)} u {(rightjm 1m E paths(R)}. The Member procedure of Fig. 2 is a refinement of the statement x := member(a, t). ’ Here, the path m is continually extended in the appropriate direction until a node is reached that contains the item a or until the empty tree is reached. Given trees ti, t,, and path ltzi E paths(t;), ti[mi\tj] represents the tree ti with the subtree reached using rni replaced by tj: tl [O\tjl n tl node(b,L,R) [(left)mi\tj] 1 node(b,L[mi\tj],R) node(b,L,R) [(right)m;\t/] G node(b,L,R[mi\tj]). ’ The keyword vat indicates call-by-value parameters, while ref indicates call-by-reference. For tree t and item 0, t D h represents t with the item at the root replaced by b, and t[m D h] represents t with the item at the root of the subrree reached by path m replaced by 0: rt~de(u. L, R) D b 2 node(b,L, R) t[m D b] P t[m\(tjnz D b)]. The use of paths to access and manipulate subtrees is common in term-rewriting liter- ature [7]. 1.1. Scope und outline In this paper, we present pointer-introduction rules that transform an imperative al- gorithm or enriched trees into an algorithm on pointer structures. For example, the procedure in Fig. 2 is transformed into the pointer procedure in Fig. 3. These transfor- mations are presented in KWOstages: Section 3 describes transformations on operations that do not manipulaee the stmcmre of a rfee, while Section 6 describes transforma- tions on operations that do manipulate the scrucntre of a tree. These pointer-introduction transformations may be fully mechanised. The proof of soundness of these transforma- tions is outlined in Section 8. In addition, we present some rules that may be used to calculate algorithms on enriched trees, such as Fig. 2, from applicative-style recursive functions, such as Fig. 1. These rules are presented in two sections, Sections 4 and 7, to mirror the presentation of the pointer-introduction rransformations. Some of the ideas presented in this paper appear m an earlier paper [4]. However, that paper did not present a full pointer-introduction transformation mechanism, rather a set of rules that could be used to assist the transformation. These rules were many and complicated, making them difficult to remember and use. We have overcome this difficulty by providing a safe synractic transformation function that could easily be mechanised. Furthermore, that earlier paper did not deal with the transformation of applicative-style recursive functions on trees into algorithms on enriched trees. procedure Mernber(va1 p : Tree&r; val a : Itern; Pef x : Bool) & I[vm q : TreePtru q :I-- p; do q # nil A a # q^.root -+ if a < q*.root -+ q := q^.left 0 a > q^.root -+ q := q^.right fi oai I :- (q # nil) II. Fig. 3. Search procedure on pointer structures We do not claim to provide ai1 approach for dealing with any pointer algorithm. Rather our approach is most suited to algorithms that are narui-ally described in terms of recursive data structures such as lists and trees.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    40 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us