preface -...

36

Upload: lenguyet

Post on 07-Mar-2018

225 views

Category:

Documents


2 download

TRANSCRIPT

Many of the designations used by manufacturers and sellers to distinguish their products are claimedas trademarks. Where those designations appear in this book, and the publisher was aware of atrademark claim, the designations have been printed with initial capital letters or in all capitals.

The authors and publisher have taken care in the preparation of this book, but make no expressed orimplied warranty of any kind and assume no responsibility for errors or omissions. No liability isassumed for incidental or consequential damages in connection with or arising out of the use of theinformation or programs contained herein.

The publisher offers excellent discounts on this book when ordered in quantity for bulk purchases orspecial sales, which may include electronic versions and/or custom covers and content particular toyour business, training goals, marketing focus, and branding interests. For more information, pleasecontact:

U.S. Corporate and Government Sales(800) [email protected]

For sales outside the United States please contact:International [email protected]

Visit us on the Web: www.informit.com/aw

Library of Congress Cataloging-in-Publication Data

Stepanov, Alexander A.Elements of programming/Alexander Stepanov, Paul McJones.

p. cm.Includes bibliographical references and index.ISBN 0-321-63537-X (hardcover : alk. paper)1. Computer programming. 2. Computer algorithms. I. McJones, Paul. II. Title.

QA76.6.S726 2009005.1–dc22 2009007604

Copyright c© 2009 Pearson Education, Inc.

All rights reserved. Printed in the United States of America. This publication is protected bycopyright, and permission must be obtained from the publisher prior to any prohibited reproduction,storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical,photocopying, recording, or likewise. For information regarding permissions, write to:

Pearson Education, Inc.Rights and Contracts Department501 Boylston Street, Suite 900Boston, MA 02116Fax (617) 671-3447

ISBN-13: 978-0-321-63537-2ISBN-10: 0-321-63537-X

Text printed in the United States on recycled paper at Edwards Brothers in Ann Arbor, Michigan.First printing, June 2009

Preface

This book applies the deductive method to programming by affiliating programswith the abstract mathematical theories that enable them to work. Specification ofthese theories, algorithms written in terms of these theories, and theorems andlemmas describing their properties are presented together. The implementationof the algorithms in a real programming language is central to the book. Whilethe specifications, which are addressed to human beings, should, and even must,combine rigor with appropriate informality, the code, which is addressed to thecomputer, must be absolutely precise even while being general.

As with other areas of science and engineering, the appropriate foundation ofprogramming is the deductive method. It facilitates the decomposition of complexsystems into components with mathematically specified behavior. That, in turn, isa necessary precondition for designing efficient, reliable, secure, and economicalsoftware.

The book is addressed to those who want a deeper understanding of program-ming, whether they are full-time software developers, or scientists and engineers forwhom programming is an important part of their professional activity.

The book is intended to be read from beginning to end. Only by reading thecode, proving the lemmas, and doing the exercises can readers gain understanding ofthe material. In addition, we suggest several projects, some open-ended. While thebook is terse, a careful reader will eventually see the connections between its partsand the reasons for our choice of material. Discovering the architectural principlesof the book should be the reader’s goal.

We assume an ability to do elementary algebraic manipulations.1 We also assumefamiliarity with the basic vocabulary of logic and set theory at the level of undergrad-uate courses on discrete mathematics; Appendix A summarizes the notation thatwe use. We provide definitions of a few concepts of abstract algebra when they are

1. For a refresher on elementary algebra, we recommend Chrystal [1904].

ix

x Preface

needed to specify algorithms. We assume programming maturity and understandingof computer architecture2 and fundamental algorithms and data structures.3

We chose C++ because it combines powerful abstraction facilities with faithfulrepresentation of the underlying machine.4 We use a small subset of the languageand write requirements as structured comments. We hope that readers not alreadyfamiliar with C++ are able to follow the book. Appendix B specifies the subset of thelanguage used in the book.5 Wherever there is a difference between mathematicalnotation and C++, the typesetting and the context determine whether the mathe-matical or C++ meaning applies. While many concepts and programs in the bookhave parallels in STL (the C++ Standard Template Library), the book departs fromsome of the STL design decisions. The book also ignores issues that a real library,such as STL, has to address: namespaces, visibility, inline directives, and so on.

Chapter 1 describes values, objects, types, procedures, and concepts. Chapters2–5 describe algorithms on algebraic structures, such as semigroups and totally or-dered sets. Chapters 6–11 describe algorithms on abstractions of memory. Chapter 12describes objects containing other objects. The Afterword presents our reflectionson the approach presented by the book.

AcknowledgmentsWe are grateful to Adobe Systems and its management for supporting the Founda-tions of Programming course and this book, which grew out of it. In particular, GregGilley initiated the course and suggested writing the book; Dave Story and then BillHensler provided unwavering support. Finally, the book would not have been pos-sible without Sean Parent’s enlightened management and continuous scrutiny ofthe code and the text. The ideas in the book stem from our close collaboration,spanning almost three decades, with Dave Musser. Bjarne Stroustrup deliberatelyevolved C++ to support these ideas. Both Dave and Bjarne were kind enough tocome to San Jose and carefully review the preliminary draft. Sean Parent and BjarneStroustrup wrote the appendix defining the C++ subset used in the book. JonBrandt reviewed multiple drafts of the book. John Wilkinson carefully read thefinal manuscript, providing innumerable valuable suggestions.

2. We recommend Patterson and Hennessy [2007].3. For a selective but incisive introduction to algorithms and data structures, we recommend Tarjan

[1983].4. The standard reference is Stroustrup [2000].5. The code in the book compiles and runs under Microsoft Visual C++ 9 and g++ 4. This code,

together with a few trivial macros that enable it to compile, as well as unit tests, can be downloadedfrom www.elementsofprogramming.com.

Preface xi

The book has benefited significantly from the contributions of our editor, PeterGordon, our project editor, Elizabeth Ryan, our copy editor, Evelyn Pyle, and theeditorial reviewers: Matt Austern, Andrew Koenig, David Musser, Arch Robison,Jerry Schwarz, Jeremy Siek, and John Wilkinson.

We thank all the students who took the course at Adobe and an earlier course atSGI for their suggestions. We hope we succeeded in weaving the material from thesecourses into a coherent whole. We are grateful for comments from Dave Abrahams,Andrei Alexandrescu, Konstantine Arkoudas, John Banning, Hans Boehm,Angelo Borsotti, Jim Dehnert, John DeTreville, Boris Fomitchev, Kevlin Henney,Jussi Ketonen, Karl Malbrain, Mat Marcus, Larry Masinter, Dave Parent, DmitryPolukhin, Jon Reid, Mark Ruzon, Geoff Scott, David Simons, Anna Stepanov, TonyVan Eerd, Walter Vannini, Tim Winkler, and Oleg Zabluda.

Finally, we are grateful to all the people who taught us through their writingsor in person, and to the institutions that allowed us to deepen our understandingof programming.

Chapter 2

Transformations andTheir Orbits

This chapter defines a transformation as a unary regular function from a typeto itself. Successive applications of a transformation starting from an initial valuedetermine an orbit of this value. Depending only on the regularity of the transformationand the finiteness of the orbit, we implement an algorithm for determining orbitstructures that can be used in different domains. For example, it could be used todetect a cycle in a linked list or to analyze a pseudorandom number generator. Wederive an interface to the algorithm as a set of related procedures and definitions fortheir arguments and results. This analysis of an orbit-structure algorithm allows us tointroduce our approach to programming in the simplest possible setting.

2.1 TransformationsWhile there are functions from any sequence of types to any type, particular classesof signatures commonly occur. In this book we frequently use two such classes:homogeneous predicates and operations. Homogeneous predicates are of the formT × · · · × T → bool; operations are functions of the form T × · · · × T → T. Whilethere are n-ary predicates and n-ary operations, we encounter mostly unary andbinary homogeneous predicates and unary and binary operations.

A predicate is a functional procedure returning a truth value:

Predicate(P) �FunctionalProcedure(P)

∧ Codomain(P) = bool

15

16 Transformations and Their Orbits

A homogeneous predicate is one that is also a homogeneous function:

HomogeneousPredicate(P) �Predicate(P)

∧ HomogeneousFunction(P)

A unary predicate is a predicate taking one parameter:

UnaryPredicate(P) �Predicate(P)

∧ UnaryFunction(P)

An operation is a homogeneous function whose codomain is equal to its domain:

Operation(Op) �HomogeneousFunction(Op)

∧ Codomain(Op) = Domain(Op)

Examples of operations:

int abs(int x) {

if (x < 0) return -x; else return x;

} // unary operation

double euclidean norm(double x, double y) {

return sqrt(x * x + y * y);

} // binary operation

double euclidean norm(double x, double y, double z) {

return sqrt(x * x + y * y + z * z);

} // ternary operation

Lemma 2.1 euclidean_norm(x, y, z) = euclidean_norm(euclidean_norm(x, y), z)

This lemma shows that the ternary version can be obtained from the binary ver-sion. For reasons of efficiency, expressiveness, and, possibly, accuracy, the ternaryversion is part of the computational basis for programs dealing with three-dimensional space.

2.1 Transformations 17

A procedure is partial if its definition space is a subset of the direct product ofthe types of its inputs; it is total if its definition space is equal to the direct prod-uct. We follow standard mathematical usage, where partial function includes totalfunction. We call partial procedures that are not total nontotal. Implementations ofsome total functions are nontotal on the computer because of the finiteness of therepresentation. For example, addition on signed 32-bit integers is nontotal.

A nontotal procedure is accompanied by a precondition specifying its definitionspace. To verify the correctness of a call of that procedure, we must determine thatthe arguments satisfy the precondition. Sometimes, a partial procedure is passed asa parameter to an algorithm that needs to determine at runtime the definition spaceof the procedural parameter. To deal with such cases, we define a definition-spacepredicate with the same inputs as the procedure; the predicate returns true if andonly if the inputs are within the definition space of the procedure. Before a nontotalprocedure is called, either its precondition must be satisfied, or the call must beguarded by a call of its definition-space predicate.

Exercise 2.1 Implement a definition-space predicate for addition on 32-bit signed integers.

This chapter deals with unary operations, which we call transformations:

Transformation(F) �Operation(F)

∧ UnaryFunction(F)∧ DistanceType : Transformation → Integer

We discuss DistanceType in the next section.Transformations are self-composable: f(x), f(f(x)), f(f(f(x))), and so on. The

definition space of f(f(x)) is the intersection of the definition space and result spaceof f. This ability to self-compose, together with the ability to test for equality, allowsus to define interesting algorithms.

When f is a transformation, we define its powers as follows:

fn(x) =

{x if n = 0,

fn−1(f(x)) if n > 0

18 Transformations and Their Orbits

To implement an algorithm to compute fn(x), we need to specify the require-ment for an integer type. We study various concepts describing integers in Chapter 5.For now we rely on the intuitive understanding of integers. Their models includesigned and unsigned integral types, as well as arbitrary-precision integers, with theseoperations and literals:

Specifications C++Sum + +

Difference − -

Product · *

Quotient / /

Remainder mod %

Zero 0 I(0)

One 1 I(1)

Two 2 I(2)

where I is an integer type.That leads to the following algorithm:

template<typename F, typename N>

requires(Transformation(F) && Integer(N))

Domain(F) power unary(Domain(F) x, N n, F f)

{

// Precondition: n ≥ 0 ∧ (∀i ∈ N) 0 < i ≤ n ⇒ fn(x) is definedwhile (n != N(0)) {

n = n - N(1);

x = f(x);

}

return x;

}

2.2 OrbitsTo understand the global behavior of a transformation, we examine the structureof its orbits: elements reachable from a starting element by repeated applicationsof the transformation. y is reachable from x under a transformation f if for somen ≥ 0, y = fn(x). x is cyclic under f if for some n ≥ 1, x = fn(x). x is terminalunder f if and only if x is not in the definition space of f. The orbit of x under atransformation f is the set of all elements reachable from x under f.

2.2 Orbits 19

Lemma 2.2 An orbit does not contain both a cyclic and a terminal element.

Lemma 2.3 An orbit contains at most one terminal element.

If y is reachable from x under f, the distance from x to y is the least number oftransformation steps from x to y. Obviously, distance is not always defined.

Given a transformation type F, DistanceType(F) is an integer type large enoughto encode the maximum number of steps by any transformation f ∈ F from oneelement of T = Domain(F) to another. If type T occupies k bits, there can be as manyas 2k values but only 2k − 1 steps between distinct values. Thus if T is a fixed-sizetype, an integral type of the same size is a valid distance type for any transformationon T. (Instead of using the distance type, we allow the use of any integer type inpower unary, since the extra generality does not appear to hurt there.) It is often thecase that all transformation types over a domain have the same distance type. In thiscase the type function DistanceType is defined for the domain type and defines thecorresponding type function for the transformation types.

The existence of DistanceType leads to the following procedure:

template<typename F>

requires(Transformation(F))

DistanceType(F) distance(Domain(F) x, Domain(F) y, F f)

{

// Precondition: y is reachable from x under f

typedef DistanceType(F) N;

N n(0);

while (x != y) {

x = f(x);

n = n + N(1);

}

return n;

}

Orbits have different shapes. An orbit of x under a transformation is

infinite if it has no cyclic or terminal elementsterminating if it has a terminal element

circular if x is cyclicρ-shaped if x is not cyclic, but its orbit contains a cyclic element

An orbit of x is finite if it is not infinite. Figure 2.1 illustrates the various cases.

20 Transformations and Their Orbits

Infinite

Terminating

Circular

ρ-shaped

Figure 2.1 Orbit Shapes.

The orbit cycle is the set of cyclic elements in the orbit and is empty for infiniteand terminating orbits. The orbit handle, the complement of the orbit cycle withrespect to the orbit, is empty for a circular orbit. The connection point is the firstcyclic element, and is the first element of a circular orbit and the first elementafter the handle for a ρ-shaped orbit. The orbit size o of an orbit is the number ofdistinct elements in it. The handle size h of an orbit is the number of elements inthe orbit handle. The cycle size c of an orbit is the number of elements in the orbitcycle.

Lemma 2.4 o = h + c

Lemma 2.5 The distance from any point in an orbit to a point in a cycleof that orbit is always defined.

Lemma 2.6 If x and y are distinct points in a cycle of size c,

c = distance(x, y, f) + distance(y, x, f)

Lemma 2.7 If x and y are points in a cycle of size c, the distance from x

to y satisfies

0 ≤ distance(x, y, f) < c

2.3 Collision Point 21

2.3 Collision PointIf we observe the behavior of a transformation, without access to its definition, wecannot determine whether a particular orbit is infinite: It might terminate or cycleback at any point. If we know that an orbit is finite, we can use an algorithm todetermine the shape of the orbit. Therefore there is an implicit precondition oforbit finiteness for all the algorithms in this chapter.

There is, of course, a naive algorithm that stores every element visited andchecks at every step whether the new element has been previously encountered.Even if we could use hashing to speed up the search, such an algorithm still wouldrequire linear storage and would not be practical in many applications. However,there is an algorithm that requires only a constant amount of storage.

The following analogy helps to understand the algorithm. If a fast car and aslow one start along a path, the fast one will catch up with the slow one if and only ifthere is a cycle. If there is no cycle, the fast one will reach the end of the path beforethe slow one. If there is a cycle, by the time the slow one enters the cycle, the fastone will already be there and will catch up eventually. Carrying our intuition fromthe continuous domain to the discrete domain requires care to avoid the fast oneskipping past the slow one.1

The discrete version of the algorithm is based on looking for a point where fastmeets slow. The collision point of a transformation f and a starting point x is theunique y such that

y = fn(x) = f2n+1(x)

and n ≥ 0 is the smallest integer satisfying this condition. This definition leads toan algorithm for determining the orbit structure that needs one comparison of fastand slow per iteration. To handle partial transformations, we pass a definition-spacepredicate to the algorithm:

template<typename F, typename P>

requires(Transformation(F) && UnaryPredicate(P) &&

Domain(F) == Domain(P))

Domain(F) collision point(const Domain(F)& x, F f, P p)

{

// Precondition: p(x) ⇔ f(x) is definedif (!p(x)) return x;

1. Knuth [1997, page 7] attributes this algorithm to Robert W. Floyd.

22 Transformations and Their Orbits

Domain(F) slow = x; // slow = f0(x)Domain(F) fast = f(x); // fast = f1(x)

// n ← 0 (completed iterations)while (fast != slow) { // slow = fn(x) ∧ fast = f2n+1(x)

slow = f(slow); // slow = fn+1(x) ∧ fast = f2n+1(x)if (!p(fast)) return fast;

fast = f(fast); // slow = fn+1(x) ∧ fast = f2n+2(x)if (!p(fast)) return fast;

fast = f(fast); // slow = fn+1(x) ∧ fast = f2n+3(x)// n ← n + 1

}

return fast; // slow = fn(x) ∧ fast = f2n+1(x)// Postcondition: return value is terminal point or collision point

}

We establish the correctness of collision point in three stages: (1) verifyingthat it never applies f to an argument outside the definition space; (2) verifyingthat if it terminates, the postcondition is satisfied; and (3) verifying that it alwaysterminates.

While f is a partial function, its use by the procedure is well defined, since themovement of fast is guarded by a call of p. The movement of slow is unguarded,because by the regularity of f, slow traverses the same orbit as fast, so f is alwaysdefined when applied to slow.

The annotations show that if, after n ≥ 0 iterations, fast becomes equal toslow, then fast = f2n+1(x) and slow = fn(x). Moreover, n is the smallest suchinteger, since we checked the condition for every i < n.

If there is no cycle, p will eventually return false because of finiteness. If thereis a cycle, slow will eventually reach the connection point (the first element in thecycle). Consider the distance d from fast to slow at the top of the loop when slow

first enters the cycle: 0 ≤ d < c. If d = 0, the procedure terminates. Otherwise thedistance from fast to slow decreases by 1 on each iteration. Therefore the procedurealways terminates; when it terminates, slow has moved a total of h + d steps.

The following procedure determines whether an orbit is terminating:

template<typename F, typename P>

requires(Transformation(F) && UnaryPredicate(P) &&

Domain(F) == Domain(P))

bool terminating(const Domain(F)& x, F f, P p)

2.3 Collision Point 23

{

// Precondition: p(x) ⇔ f(x) is definedreturn !p(collision point(x, f, p));

}

Sometimes we know either that the transformation is total or that the orbit isnonterminating for a particular starting element. For these situations it is useful tohave a specialized version of collision point:

template<typename F>

requires(Transformation(F))

Domain(F)

collision point nonterminating orbit(const Domain(F)& x, F f)

{

Domain(F) slow = x; // slow = f0(x)Domain(F) fast = f(x); // fast = f1(x)

// n ← 0 (completed iterations)while (fast != slow) { // slow = fn(x) ∧ fast = f2n+1(x)

slow = f(slow); // slow = fn+1(x) ∧ fast = f2n+1(x)fast = f(fast); // slow = fn+1(x) ∧ fast = f2n+2(x)fast = f(fast); // slow = fn+1(x) ∧ fast = f2n+3(x)

// n ← n + 1}

return fast; // slow = fn(x) ∧ fast = f2n+1(x)// Postcondition: return value is collision point

}

In order to determine the cycle structure—handle size, connection point, andcycle size—we need to analyze the position of the collision point.

When the procedure returns the collision point

fn(x) = f2n+1(x)

n is the number of steps taken by slow, and 2n + 1 is the number of steps taken byfast.

n = h + d

24 Transformations and Their Orbits

where h is the handle size and 0 ≤ d < c is the number of steps taken by slow

inside the cycle. The number of steps taken by fast is

2n + 1 = h + d + qc

where q ≥ 0 is the number of full cycles completed by fast when slow enters thecycle. Since n = h + d,

2(h + d) + 1 = h + d + qc

Simplifying gives

qc = h + d + 1

Let us represent h modulo c:

h = mc + r

with 0 ≤ r < c. Substitution gives

qc = mc + r + d + 1

or

d = (q − m)c − r − 1

0 ≤ d < c implies

q − m = 1

so

d = c − r − 1

and r + 1 steps are needed to complete the cycle.Therefore the distance from the collision point to the connection point is

e = r + 1

In the case of a circular orbit h = 0, r = 0, and the distance from the collisionpoint to the beginning of the orbit is

e = 1

2.3 Collision Point 25

Circularity, therefore, can be checked with the following procedures:

template<typename F>

requires(Transformation(F))

bool circular nonterminating orbit(const Domain(F)& x, F f)

{

return x == f(collision point nonterminating orbit(x, f));

}

template<typename F, typename P>

requires(Transformation(F) && UnaryPredicate(P) &&

Domain(F) == Domain(P))

bool circular(const Domain(F)& x, F f, P p)

{

// Precondition: p(x) ⇔ f(x) is definedDomain(F) y = collision point(x, f, p);

return p(y) && x == f(y);

}

We still don’t know the handle size h and the cycle size c. Determining thelatter is simple once the collision point is known: Traverse the cycle and count thesteps.

To see how to determine h, let us look at the position of the collision point:

fh+d(x) = fh+c−r−1(x) = fmc+r+c−r−1(x) = f(m+1)c−1(x)

Taking h + 1 steps from the collision point gets us to the point f(m+1)c+h(x), whichequals fh(x), since (m + 1)c corresponds to going around the cycle m + 1 times. Ifwe simultaneously take h steps from x and h + 1 steps from the collision point, wemeet at the connection point. In other words, the orbits of x and 1 step past thecollision point converge in exactly h steps, which leads to the following sequenceof algorithms:

template<typename F>

requires(Transformation(F))

Domain(F) convergent point(Domain(F) x0, Domain(F) x1, F f)

{

while (x0 != x1) {

26 Transformations and Their Orbits

x0 = f(x0);

x1 = f(x1);

}

return x0;

}

template<typename F>

requires(Transformation(F))

Domain(F)

connection point nonterminating orbit(const Domain(F)& x, F f)

{

return convergent point(

x,

f(collision point nonterminating orbit(x, f)),

f);

}

template<typename F, typename P>

requires(Transformation(F) && UnaryPredicate(P) &&

Domain(F) == Domain(P))

Domain(F) connection point(const Domain(F)& x, F f, P p)

{

// Precondition: p(x) ⇔ f(x) is definedDomain(F) y = collision point(x, f, p);

if (!p(y)) return y;

return convergent point(x, f(y), f);

}

Lemma 2.8 If the orbits of two elements intersect, they have the samecyclic elements.

Exercise 2.2 Design an algorithm that determines, given a transforma-tion and its definition-space predicate, whether the orbits of two elementsintersect.

Exercise 2.3 For convergent point to work, it must be called with elementswhose distances to the convergent point are equal. Implement an algorithmconvergent point guarded for use when that is not known to be the case, butthere is an element in common to the orbits of both.

2.4 Measuring Orbit Sizes 27

2.4 Measuring Orbit SizesThe natural type to use for the sizes o, h, and c of an orbit on type T would be aninteger count type large enough to count all the distinct values of type T. If a type T

occupies k bits, there can be as many as 2k values, so a count type occupying k bitscould not represent all the counts from 0 to 2k. There is a way to represent thesesizes by using distance type.

An orbit could potentially contain all values of a type, in which case o mightnot fit in the distance type. Depending on the shape of such an orbit, h and c wouldnot fit either. However, for a ρ-shaped orbit, both h and c fit. In all cases each ofthese fits: o − 1 (the maximum distance in the orbit), h − 1 (the maximum distancein the handle), and c − 1 (the maximum distance in the cycle). That allows us toimplement procedures returning a triple representing the complete structure of anorbit, where the members of the triple are as follows:

Case m0 m1 m2Terminating h − 1 0 terminal element

Circular 0 c − 1 x

ρ-shaped h c − 1 connection point

template<typename F>

requires(Transformation(F))

triple<DistanceType(F), DistanceType(F), Domain(F)>

orbit structure nonterminating orbit(const Domain(F)& x, F f)

{

typedef DistanceType(F) N;

Domain(F) y = connection point nonterminating orbit(x, f);

return triple<N, N, Domain(F)>(distance(x, y, f),

distance(f(y), y, f),

y);

}

template<typename F, typename P>

requires(Transformation(F) &&

UnaryPredicate(P) && Domain(F) == Domain(P))

triple<DistanceType(F), DistanceType(F), Domain(F)>

orbit structure(const Domain(F)& x, F f, P p)

{

// Precondition: p(x) ⇔ f(x) is defined

28 Transformations and Their Orbits

typedef DistanceType(F) N;

Domain(F) y = connection point(x, f, p);

N m = distance(x, y, f);

N n(0);

if (p(y)) n = distance(f(y), y, f);

// Terminating: m = h − 1 ∧ n = 0// Otherwise: m = h ∧ n = c − 1return triple<N, N, Domain(F)>(m, n, y);

}

Exercise 2.4 Derive formulas for the count of different operations (f, p,equality) for the algorithms in this chapter.

Exercise 2.5 Use orbit structure nonterminating orbit to determine the av-erage handle size and cycle size of the pseudorandom number generatorson your platform for various seeds.

2.5 ActionsAlgorithms often use a transformation f in a statement like

x = f(x);

Changing the state of an object by applying a transformation to it defines anaction on the object. There is a duality between transformations and the correspond-ing actions: An action is definable in terms of a transformation, and vice versa:

void a(T& x) { x = f(x); } // action from transformation

and

T f(T x) { a(x); return x; } // transformation from action

Despite this duality, independent implementations are sometimes more effi-cient, in which case both action and transformation need to be provided. Forexample, if a transformation is defined on a large object and modifies only partof its overall state, the action could be considerably faster.

Exercise 2.6 Rewrite all the algorithms in this chapter in terms of actions.

2.6 Conclusions 29

Project 2.1 Another way to detect a cycle is to repeatedly test a singleadvancing element for equality with a stored element while replacing thestored element at ever-increasing intervals. This and other ideas are de-scribed in Sedgewick, et al. [1979], Brent [1980], and Levy [1982]. Imple-ment other algorithms for orbit analysis, compare their performance fordifferent applications, and develop a set of recommendations for selectingthe appropriate algorithm.

2.6 ConclusionsAbstraction allowed us to define abstract procedures that can be used in differentdomains. Regularity of types and functions is essential to make the algorithms work:fast and slow follow the same orbit because of regularity. Developing nomenclatureis essential (e.g., orbit kinds and sizes). Affiliated types, such as distance type, needto be precisely defined.

Index

→ (function), 231− (additive inverse), in additive group, 67∧ (and), 231− (difference)

in additive group, 67in cancellable monoid, 72of integers, 18of iterator and integer, 111of iterators, 93

× (direct product), 231∈ (element), 231= (equality), 7

for array k, 212for pair, 210

� (equals by definition), 12, 231⇔ (equivalent), 231∃ (exists), 231∀ (for all), 231> (greater), 62≥ (greater or equal), 62⇒ (implies), 231[ ] (index)

for array k, 211for bounded range, 214

=/ (inequality), 7, 62∩ (intersection), 231< (less), 62

for array k, 212natural total ordering, 61for pair, 210

≤ (less or equal), 62�→ (maps to), 231¬ (not), 231∨ (or), 231an (power of associative operation), 32fn (power of transformation), 17≺ (precedes), 95

� (precedes or equal), 95· (product)

of integers, 18in multiplicative semigroup, 66in semimodule, 69

/ (quotient), of integers, 18[f, l] (range, closed bounded), 94[[f, n]] (range, closed weak or counted), 94[f, l) (range, half-open bounded), 94[[f, n|) (range, half-open weak or

counted), 94⊂ (subset), 231+ (sum)

in additive semigroup, 66of integers, 18of iterator and integer, 92

∪ (union), 231

Aabs algorithm, 16, 71absolute value, properties, 71abstract entity, 1abstract genus, 2abstract procedure, 13

overloading, 43abstract species, 2accumulation procedure, 46accumulation variable

elimination, 39introduction, 35

action, 28acyclic descendants of bifurcate coordinate,

116additive inverse (−), in additive group, 67AdditiveGroup concept, 67AdditiveMonoid concept, 67AdditiveSemigroup concept, 66

247

248 Index

address, 4abstracted by iterator, 89

add to counter algorithm, 199advance tail machine, 135algorithm. See machine

abs, 16, 71add to counter, 199all, 97bifurcate compare, 131bifurcate compare nonempty, 130bifurcate equivalent, 129bifurcate equivalent nonempty, 128bifurcate isomorphic, 126bifurcate isomorphic nonempty, 125circular, 25circular nonterminating orbit, 25collision point, 22collision point nonterminating orbit, 23combine copy, 160combine copy backward, 162combine linked nonempty, 138combine ranges, 196compare strict or reflexive, 57–58complement, 50complement of converse, 50connection point, 26connection point nonterminating orbit, 26convergent point, 26converse, 50copy, 152copy backward, 155copy bounded, 153copy if, 158copy n, 154copy select, 158count if, 97, 98cycle from, 173cycle to, 173distance, 19euclidean norm, 16exchange values, 164fast subtractive gcd, 78fibonacci, 46find, 96find adjacent mismatch, 103find adjacent mismatch forward, 106, 135find backward if, 112find if, 97

find if not unguarded, 102find if unguarded, 101find last, 136find mismatch, 102find n, 101find not, 97for each, 96for each n, 101gcd, 80height, 122height recursive, 118increment, 91is left successor, 119is right successor, 120k rotate from permutation indexed, 180k rotate from permutation random

access, 180largest doubling, 75lexicographical compare, 129lexicographical equal, 127lexicographical equivalent, 127lexicographical less, 130lower bound n, 109lower bound predicate, 108median 5, 61memory-adaptive, 177merge copy, 163merge copy backward, 163merge linked nonempty, 141merge n adaptive, 206merge n with buffer, 202none, 97not all, 97orbit structure, 28orbit structure nonterminating orbit, 27partitioned at point, 191partition bidirectional, 194partition copy, 160partition copy n, 160partition linked, 140partition point, 107partition point n, 107partition semistable, 192partition single cycle, 194partition stable iterative, 201partition stable n, 197partition stable n adaptive, 197partition stable n nonempty, 197

Index 249

algorithm. See machine (cont.)partition stable singleton, 196partition stable with buffer, 195partition trivial, 198phased applicator, 147potential partition point, 191power, 42power accumulate, 41power accumulate positive, 41power left associated vs. power 0, 34power right associated, 33power unary, 18predicate source, 140quotient remainder, 85quotient remainder nonnegative, 82quotient remainder nonnegative iterative,

83reachable, 121reduce, 99reduce balanced, 200reduce nonempty, 99reduce nonzeroes, 100relation source, 141remainder, 84remainder nonnegative, 74remainder nonnegative iterative, 75reverse append, 139, 140reverse bidirectional, 175reverse copy, 156reverse copy backward, 156reverse indexed, 186reverse n adaptive, 178reverse n bidirectional, 175reverse n forward, 177reverse n indexed, 175reverse n with buffer, 176reverse swap ranges, 167reverse swap ranges bounded, 167reverse swap ranges n, 168reverse with temporary buffer, 187, 225rotate, 187rotate bidirectional nontrivial, 182rotate cycles, 181rotate forward annotated, 183rotate forward nontrivial, 184rotate forward step, 184rotate indexed nontrivial, 181rotate nontrivial, 188

rotate partial nontrivial, 185rotate random access nontrivial, 181rotate with buffer backward nontrivial,

186rotate with buffer nontrivial, 185select 0 2, 53, 63select 0 3, 54select 1 2, 54select 1 3, 55select 1 3 ab, 55select 1 4, 56, 59select 1 4 ab, 56, 59select 1 4 ab cd, 56, 58select 2 3, 54select 2 5, 60select 2 5 ab, 60select 2 5 ab cd, 59slow quotient, 73slow remainder, 72some, 97sort linked nonempty n, 142sort n, 207sort n adaptive, 207sort n with buffer, 203split copy, 158split linked, 137subtractive gcd, 78subtractive gcd nonzero, 77swap, 224swap basic, 223swap ranges, 165swap ranges bounded, 166swap ranges n, 166terminating, 23transpose operation, 201traverse, 123traverse nonempty, 118traverse phased rotating, 148traverse rotating, 146underlying ref, 224upper bound n, 109upper bound predicate, 109weight, 122weight recursive, 117weight rotating, 147

aliased property, 150aliased write-read, 150aliased write-write, 159

250 Index

all algorithm, 97ambiguous value type, 3amortized complexity, 219and (∧), 231annihilation property, 68annotation variable, 183ArchimedeanGroup concept, 83ArchimedeanMonoid concept, 72area of object, 227Aristotle, 77Arity type attribute, 11array, varieties, 220–221array k type, 210Artin, Emil, 13assignment, 7

for array k, 211for pair, 210

associative operation, 31, 98power of (an), 32

associative property, 31exploited by power, 33partially associative, 98of permutation composition, 170

asymmetric property, 50attribute, 1auxiliary computation during recursion, 176Axiom of Archimedes, 72, 73

Bbackward movement in range, 112BackwardLinker concept, 134backward offset property, 161basic singly linked list, 218begin

for array k, 211for bounded range, 214for Linearizable, 213

behavioral equality, 3, 228BidirectionalBifurcateCoordinate concept,

119–120BidirectionalIterator concept, 111BidirectionalLinker concept, 134BifurcateCoordinate concept, 115bifurcate compare algorithm, 131bifurcate compare nonempty algorithm, 130bifurcate equivalent algorithm, 129bifurcate equivalent nonempty algorithm,

128

bifurcate isomorphic algorithm, 126bifurcate isomorphic nonempty algorithm,

125BinaryOperation concept, 31binary scale down nonnegative, 41binary scale up nonnegative, 41bisection technique, 107Bolzano, Bernard, 107bounded integer type, 87bounded range, 93bounded range property, 93bounded range type, 214Brandt, Jon, 193

CCancellableMonoid concept, 72cancellation in monoid, 72categories of ideas, 1Cauchy, Augustin Louis, 107circular algorithm, 25circular array, 220circular doubly linked list, 218circular singly linked list, 218circular nonterminating orbit algorithm, 25closed bounded range ([f, l]), 94closed interval, 231closed weak or counted range ([[f, n]]), 94clusters of derived procedures, 62codomain, 10Codomain type function, 11Collins, George, 13collision point of orbit, 21collision point algorithm, 22collision point nonterminating orbit

algorithm, 23combine copy algorithm, 160combine copy backward algorithm, 162combine linked nonempty algorithm, 138combine ranges algorithm, 196common-subexpression elimination, 35commutative property, 66CommutativeRing concept, 69CommutativeSemiring concept, 68compare strict or reflexive algorithm,

57–58complement algorithm, 50complement of converse of relation, 50complement of relation, 50

Index 251

complement of converse algorithm, 50complement of converse property, 104complexity

amortized, 219of empty, 213of indexing of a sequence, 213of regular operations, 227of source, 90of successor, 92

composite object, 215composition

of permutations, 170of transformations, 17, 32

computational basis, 6concept, 11

AdditiveGroup, 67AdditiveMonoid, 67AdditiveSemigroup, 66ArchimedeanGroup, 83ArchimedeanMonoid, 72BackwardLinker, 134BidirectionalBifurcateCoordinate, 119–120BidirectionalIterator, 111BidirectionalLinker, 134BifurcateCoordinate, 115BinaryOperation, 31CancellableMonoid, 72CommutativeRing, 69CommutativeSemiring, 68consistent, 87DiscreteArchimedeanRing, 86DiscreteArchimedeanSemiring, 85EmptyLinkedBifurcateCoordinate, 144EuclideanMonoid, 77EuclideanSemimodule, 80EuclideanSemiring, 79examples from C++ and STL, 11ForwardIterator, 106ForwardLinker, 133FunctionalProcedure, 11HalvableMonoid, 74HomogeneousFunction, 12HomogeneousPredicate, 16IndexedIterator, 110Integer, 18, 40Iterator, 91Linearizable, 213LinkedBifurcateCoordinate, 144

modeled by type, 11Module, 70MultiplicativeGroup, 68MultiplicativeMonoid, 67MultiplicativeSemigroup, 66NonnegativeDiscreteArchimedeanSemiring,

86Operation, 16OrderedAdditiveGroup, 70OrderedAdditiveMonoid, 70OrderedAdditiveSemigroup, 70Predicate, 15RandomAccessIterator, 113refinement, 11Regular, 11Relation, 49relational concept, 69Ring, 69Semimodule, 69Semiring, 68Sequence, 216TotallyOrdered, 62Transformation, 17type concept, 11UnaryFunction, 12UnaryPredicate, 16univalent, 86useful, 87weakening, 11

concept dispatch, 106, 187concept schema

composite object, 216coordinate structure, 124

concept tag type, 187concrete entity, 1concrete genus, 2concrete species, 2connectedness of composite object, 215connection point of orbit, 20connection point algorithm, 26connection point nonterminating orbit

algorithm, 26connectors, 229consistency of concept’s axioms, 87constant-size sequence, 216constructor, 7container, 213convergent point algorithm, 26

252 Index

converse algorithm, 50converse of relation, 50coordinate structure

bifurcate coordinate, 115of composite object, 215concept schema, 124iterator, 89

copy algorithm, 152copy constructor, 8

for array k, 211for pair, 210

copy of object, 5copying rearrangement, 172copy backward algorithm, 155copy backward step machine, 154copy bounded algorithm, 153copy if algorithm, 158copy n algorithm, 154copy select algorithm, 158copy step machine, 152counted range property, 93counter machine type, 200count down machine, 153count if algorithm, 97, 98cycle detection intuition, 21cycle in a permutation, 171cycle of orbit, 20cycle size, 20cycle from algorithm, 173cycle to algorithm, 173cyclic element under transformation, 18cyclic permutation, 171

DDAG (directed acyclic graph), 116datum, 2de Bruijn, N. G., 74default constructor, 8

for array k, 211for pair, 209

default ordering, 62default total ordering, 62

importance of, 228definition space, 9definition-space predicate, 17dependence of axiom, 86deref, 150derived relation, 50

descendant of bifurcatecoordinate, 116

destructor, 7for pair, 210

difference (−)in additive group, 67in cancellable monoid, 72of integers, 18of iterator and integer, 111of iterators, 93

DifferenceType type function, 113direct product (×), 231directed acyclic graph, 116DiscreteArchimedeanRing concept, 86DiscreteArchimedeanSemiring concept, 85discreteness property, 85disjoint property, 134disjointness of composite object, 216distance algorithm, 19distance in orbit, 19DistanceType type function, 17, 91distributive property, holds for semiring,

68divisibility on an Archimedean monoid,

76division, 68domain, 10Domain type function, 12double-ended array, 220doubly linked list, 218–219Dudzinski, Krzysztof, 206dummy node doubly linked list, 218Dydek, Andrzej, 206dynamic-size sequence, 216

Eefficient computational basis, 6element (∈), 231eliminating common subexpression, 35empty

for array k, 212for bounded range, 214for Linearizable, 213

empty coordinate, 144empty range, 95EmptyLinkedBifurcateCoordinate

concept, 144end

Index 253

for array k, 211for bounded range, 214for Linearizable, 213

entity, 1equality

=, 7=/ , 62for array k, 212behavioral, 3, 228equal for Regular, 127for objects, 5for pair, 210for regular type, 7representational, 3, 228structural, 228for uniquely represented type, 3for value type, 3

equals by definition (�), 12, 231equational reasoning:, 4equivalence class, 51equivalence property, 51equivalent (⇔), 231equivalent coordinate collections, 126erasure in a sequence, 217Euclidean function, 79EuclideanMonoid concept, 77EuclideanSemimodule concept, 80EuclideanSemiring concept, 79euclidean norm algorithm, 16even, 41exchange values algorithm, 164exists (∃), 231expressive computational basis, 6

Ffast subtractive gcd algorithm, 78fibonacci algorithm, 46Fibonacci sequence, 45find algorithm, 96find adjacent mismatch algorithm, 103find adjacent mismatch forward algorithm,

106, 135find backward if algorithm, 112find if algorithm, 97find if not, 97find if not unguarded algorithm, 102find if unguarded algorithm, 101find last algorithm, 136

find mismatch algorithm, 102find n algorithm, 101find not algorithm, 97finite order, under associative operation, 32finite set, 171first-last singly linked list, 218fixed point of transformation, 170fixed-size sequence, 216Floyd, Robert W., 21for all (∀), 231ForwardIterator concept, 106ForwardLinker concept, 133forward offset property, 162for each algorithm, 96for each n algorithm, 101Frobenius, Georg Ferdinand, 32from-permutation, 172function, 2

→, 231on abstract entities, 2on values, 3

function object, 9, 96, 236functional procedure, 9FunctionalProcedure concept, 11

Ggarbage collection, 230Gaussian integers, 40

Stein’s algorithm, 81gcd, 76

Stein, 81subtractive, 76

gcd algorithm, 80genus, 2global state, 6goto statement, 148greater (>), 62greater or equal (≥), 62greatest common divisor (gcd), 76group, 67

of permutations, 170

Hhalf nonnegative, 41half-open bounded range ([f, l)), 94half-open interval, 231half-open weak or counted range ([[f, n|)), 94HalvableMonoid concept, 74

254 Index

handle of orbit, 20handle size, 20header of composite object, 217height algorithm, 122height of bifurcate coordinate (DAG), 116height recursive algorithm, 118Ho, Wilson, 182Hoare, C. A. R., 195homogeneous functional procedure, 10HomogeneousFunction concept, 12HomogeneousPredicate concept, 16

Iideas, categories of, 1identity

of concrete entity, 1of object, 5

identity element, 65identity token, 5identity transformation, 170identity element property, 65implies (⇒), 231inconsistency of concept, 87increasing range, 103increasing counted range property, 105increasing range property, 105increment algorithm, 91independence of proposition, 86index ([ ])

for array k, 211for bounded range, 214

index permutation, 172index of segmented array, 221indexed iterator

equivalent to random-access iterator, 113IndexedIterator concept, 110inequality ( =/ ), 7

standard definition, 62inorder, 118input object, 6input/output object, 6InputType type function, 11insertion in a sequence, 217Integer concept, 18, 40interpretation, 2intersection (∩), 231interval, 231into transformation, 169

invariant, 148loop, 37recursion, 36

inverse of permutation, 170, 171inverse operation property, 66isomorphic coordinate sets, 124isomorphic types, 86is left successor algorithm, 119is right successor algorithm, 120iterator adapter

for bidirectional bifurcate coordinates,project, 124

random access from indexed, 114reverse from bidirectional, 112underlying type, 224

Iterator concept, 91iterator invalidation in array, 221IteratorConcept type function, 187IteratorType type function, 133, 134, 213

KKislitsyn, Sergei, 55k rotate from permutation indexed

algorithm, 180k rotate from permutation random access

algorithm, 180

LLagrange, J.-L., 107Lakshman, T. K., 159largest doubling algorithm, 75less (<), 62

for array k, 212for bounded range, 215less for TotallyOrdered, 130natural total ordering, 61for pair, 210

less or equal (≤), 62lexicographical compare algorithm, 129lexicographical equal algorithm, 127lexicographical equivalent algorithm, 127lexicographical less algorithm, 130limit in a range, 95linear ordering, 52Linearizable concept, 213link rearrangement, 134

on lists, 219linked iterator, 133

Index 255

linked structures, forward vs. bidirectional,219

LinkedBifurcateCoordinate concept, 144linker object, 133linker to head machine, 139linker to tail machine, 135links, reversing, 145list

doubly linked, 218singly linked, 218

Lo, Raymond, 182load, 4local part of composite object, 217local state, 6locality of reference, 143loop invariant, 37lower bound, 107lower bound n algorithm, 109lower bound predicate algorithm, 108

Mmachine, 120

advance tail, 135copy backward step, 154copy step, 152count down, 153linker to head, 139linker to tail, 135merge n step 0, 205merge n step 1, 205reverse copy backward step, 156reverse copy step, 155reverse swap step, 166swap step, 165traverse step, 121tree rotate, 145

maps to ( �→), 231marking, 118Mauchly, John W., 107median 5 algorithm, 61memory, 4memory-adaptive algorithm, 177merge, stability, 203mergeable property, 203merge copy algorithm, 163merge copy backward algorithm, 163merge linked nonempty algorithm, 141merge n adaptive algorithm, 206

merge n step 0 machine, 205merge n step 1 machine, 205merge n with buffer algorithm, 202mod (remainder), 18model, partial, 70models, 11Module concept, 70monoid, 67multipass traversal, 106MultiplicativeGroup concept, 68MultiplicativeMonoid concept, 67MultiplicativeSemigroup concept, 66multiset, 227Musser, David, 13mutable range, 151mutable bounded range property, 151mutable counted range property, 151mutable weak range property, 151mutative rearrangement, 172

Nnatural total ordering, < reserved for, 61negative, 41nil, 134Noether, Emmy, 13noncircularity of composite object, 216none algorithm, 97NonnegativeDiscreteArchimedeanSemiring

concept, 86nontotal procedure, 17not (¬), 231not all algorithm, 97not overlapped property, 157not overlapped backward property, 155not overlapped forward property, 153not write overlapped property, 159null link, 218

Oobject, 4

area, 227equality, 5starting address, 216state, 4

object type, 4odd, 41one, 41one-to-one transformation, 169

256 Index

onto transformation, 169open interval, 231Operation concept, 16or (∨), 231orbit, 18–20orbit structure algorithm, 28orbit structure nonterminating orbit

algorithm, 27OrderedAdditiveGroup concept, 70OrderedAdditiveMonoid concept, 70OrderedAdditiveSemigroup concept, 70ordering, linear, 52ordering-based rearrangement, 172output object, 6overloading, 43, 133, 144own state, 6ownership, of parts by composite

object, 216

Ppair type, 11, 209parameter passing, 9part of composite object, 215–219partial model, 70partial procedure, 17partial (usage convention), 232partially formed object state, 7partially associative property, 98partition algorithm, origin of, 195partition point, 105

lower and upper bounds, 107partition rearrangement, semistable, 192partitioned property, 105partitioned range, 105partitioned at point algorithm, 191partition bidirectional algorithm, 194partition copy algorithm, 160partition copy n algorithm, 160partition linked algorithm, 140partition point algorithm, 107partition point n algorithm, 107partition semistable algorithm, 192partition single cycle algorithm, 194partition stable iterative algorithm, 201partition stable n algorithm, 197partition stable n adaptive algorithm, 197partition stable n nonempty

algorithm, 197

partition stable singleton algorithm, 196partition stable with buffer algorithm, 195partition trivial algorithm, 198permanently placed part of composite object,

217permutation, 170

composition, 170cycle, 171cyclic, 171from, 172index, 172inverse, 170, 171product of its cycles, 171reverse, 174rotation, 178to, 172transposition, 171

permutation group, 170phased applicator algorithm, 147pivot, 205position-based rearrangement, 172positive, 41postorder, 118potential partition point algorithm, 191power

of associative operation (an), 32powers of same element commute, 32of transformation (fn), 17

power algorithm, 42operation count, 34

power accumulate algorithm, 41power accumulate positive algorithm, 41power right associated algorithm, 33power unary algorithm, 18precedence preserving link rearrangement,

135precedes (≺), 95precedes or equal (�), 95precondition, 13predecessor

of integer, 41of iterator, 111

Predicate concept, 15predicate-based rearrangement, 172predicate source algorithm, 140prefix of extent, 220preorder, 118prime property, 14

Index 257

procedure, 6abstract, 13functional, 9nontotal, 17partial, 17total, 17

product (·)of integers, 18in multiplicative semigroup, 66in semimodule, 69

program transformationaccumulation-variable elimination, 39accumulation-variable introduction, 35common-subexpression elimination, 35enabled by regular types, 35forward to backward iterators, 112relaxing precondition, 38strengthening precondition, 38strict tail-recursive, 37tail-recursive form, 35

projectabstracting platform-specific copy

algorithms, 164algorithms for bidirectional bifurcate

algorithms, 123axioms for random-access iterator, 113benchmark and composite algorithm for

rotate, 189concepts for bounded binary

integers, 87coordinate structure concept, 131cross-type operations, 14cycle-detection algorithms, 29dynamic-sequences benchmark, 222dynamic-sequences implementation, 222dynamic-sequences interfaces, 222floating-point nonassociativity, 42isomorphism, equivalence, and ordering

using tree rotate, 148iterator adapter for bidirectional bifurcate

coordinates, 124linear recurrence sequences, 47minimum-comparison stable sorting and

merging, 61nonhalvable Archimedean monoids, 75order-selection stability, 61reallocation strategy for single-extent

arrays, 221

searching for a subsequence within asequence, 114

setting for Stein gcd, 81sorting library, 208underlying type used in major library, 225

projection regularity, 216proper underlying type, 223properly partial object state, 5properly partial value type, 2property

aliased, 150annihilation, 68associative, 31asymmetric, 50backward offset, 161bounded range, 93commutative, 66complement of converse, 104counted range, 93discreteness, 85disjoint, 134distributive, 68equivalence, 51forward offset, 162identity element, 65identity element, 65increasing counted range, 105increasing range, 105inverse operation, 66mergeable, 203mutable bounded range, 151mutable counted range, 151mutable weak range, 151notation, 14not overlapped, 157not overlapped backward, 155not overlapped forward, 153not write overlapped, 159partially associative, 98partitioned, 105prime, 14readable bounded range, 95readable counted range, 96readable tree, 123readable weak range, 96reflexive, 50regular unary function, 14relation preserving, 103

258 Index

property (cont.)strict, 50strictly increasing counted range, 105strictly increasing range, 104symmetric, 50total ordering, 51transitive, 49tree, 117trichotomy, 51weak trichotomy, 51weak ordering, 52weak range, 92writable bounded range, 150writable counted range, 150writable weak range, 150write aliased, 159

proposition, independence of, 86pseudopredicate, 136pseudorelation, 137pseudotransformation, 91

Qquotient (/), of integers, 18quotient

in Euclidean semimodule, 80in Euclidean semiring, 79

QuotientType type function, 72quotient remainder algorithm, 85quotient remainder nonnegative algorithm,

82quotient remainder nonnegative iterative

algorithm, 83

Rrandom-access iterator, equivalent to indexed

iterator, 113RandomAccessIterator concept, 113range

backward movement, 112closed bounded ([f, l]), 94closed weak or counted ([[f, n]]), 94empty, 95half-open bounded ([f, l)), 94half-open weak or counted ([[f, n|)), 94increasing, 103limit, 95lower bound, 107

mutable, 151partition point, 105partitioned, 105readable, 95size, 94strictly increasing, 103upper bound, 107writable, 150

reachabilityof bifurcate coordinate, 116in orbit, 18

reachable algorithm, 121readable range, 95readable bounded range property, 95readable counted range property, 96readable tree property, 123readable weak range property, 96rearrangement, 172

bin-based, 172copying, 172link, 134mutative, 172ordering-based, 172position-based, 172reverse, 174rotation, 179

recursion invariant, 36reduce algorithm, 99reduce balanced algorithm, 200reduce nonempty algorithm, 99reduce nonzeroes algorithm, 100reduction, 98reference counting, 230refinement of concept, 11reflexive property, 50Regular concept, 11

and program transformation, 35regular function on value type, 3regular type, 6–8regularity, 216, 217regular unary function property, 14Relation concept, 49relational concept, 69relationship, 229relation preserving property, 103relation source algorithm, 141relaxing precondition, 38remainder

Index 259

algorithm, 84in Euclidean semimodule, 80in Euclidean semiring, 79

remainder (mod), of integers, 18remainder nonnegative algorithm, 74remainder nonnegative iterative algorithm,

75remote part of composite object, 217representation, 2representational equality, 3, 228requires clause, 13

syntax, 240resources, 4result space, 10returning useful information, 87, 96, 97,

101–103, 106, 112, 152, 153, 159,163, 174, 179, 182, 211

reverse rearrangement, 174reverse append algorithm, 139, 140reverse bidirectional algorithm, 175reverse copy algorithm, 156reverse copy backward algorithm, 156reverse copy backward step machine, 156reverse copy step machine, 155reverse indexed algorithm, 186reverse n adaptive algorithm, 178reverse n bidirectional algorithm, 175reverse n forward algorithm, 177reverse n indexed algorithm, 175reverse n with buffer algorithm, 176reverse swap ranges algorithm, 167reverse swap ranges bounded

algorithm, 167reverse swap ranges n algorithm, 168reverse swap step machine, 166reverse with temporary buffer algorithm,

187, 225reversing links, 145Rhind Mathematical Papyrus

division, 73power, 33

Ring concept, 69rotate algorithm, 187rotate bidirectional nontrivial

algorithm, 182rotate cycles algorithm, 181rotate forward annotated algorithm,

183

rotate forward nontrivial algorithm, 184rotate forward step algorithm, 184rotate indexed nontrivial algorithm, 181rotate nontrivial algorithm, 188rotate partial nontrivial algorithm, 185rotate random access nontrivial algorithm,

181rotate with buffer backward nontrivial

algorithm, 186rotate with buffer nontrivial algorithm, 185rotation

permutation, 178rearrangement, 179

Sschema, concept, 124Schreier, Jozef, 55Schwarz, Jerry, 150segmented array, 221segmented index, 221select 0 2 algorithm, 53, 63select 0 3 algorithm, 54select 1 2 algorithm, 54select 1 3 algorithm, 55select 1 3 ab algorithm, 55select 1 4 algorithm, 56, 59select 1 4 ab algorithm, 56, 59select 1 4 ab cd algorithm, 56, 58select 2 3 algorithm, 54select 2 5 algorithm, 60select 2 5 ab algorithm, 60select 2 5 ab cd algorithm, 59semi (usage convention), 232semigroup, 66Semimodule concept, 69Semiring concept, 68semistable partition rearrangement, 192sentinel, 101Sequence concept, 216

extent-based models, 219linked models, 219

set, 231single-ended array, 220single-extent array, 220single-extent index, 221single-pass traversal, 91singly linked list, 218sink, 149

260 Index

sizefor array k, 212for bounded range, 214for Linearizable, 213

size of an orbit, 20size of a range, 94SizeType type function, 213slanted index, 221slow quotient algorithm, 73slow remainder algorithm, 72snapshot, 1some algorithm, 97sort linked nonempty n algorithm, 142sort n algorithm, 207sort n adaptive algorithm, 207sort n with buffer algorithm, 203source, 90space complexity, memory adaptive,

177species

abstract, 2concrete, 2

splicing link rearrangement, 219split copy algorithm, 158split linked algorithm, 137stability, 52

of merge, 203of partition, 192of sort, 204of sort on linked range, 142

stability index, 53Standard Template Library, xstarting address, 4, 216state of object, 4Stein, Josef, 81Stein gcd, 81STL, xstore, 4strengthened relation, 53strengthening precondition, 38strict property, 50strict tail-recursive, 37strictly increasing range, 103strictly increasing counted range property,

105strictly increasing range property, 104structural equality, 228subpart of composite object, 216

subset (⊂), 231subtraction, in additive group, 67subtractive gcd algorithm, 78subtractive gcd nonzero algorithm, 77successor

definition space on range, 94of integer, 41of iterator, 91

sum (+)in additive semigroup, 66of integers, 18of iterator and integer, 92

swap algorithm, 224swap basic algorithm, 223swap ranges algorithm, 165swap ranges bounded algorithm, 166swap ranges n algorithm, 166swap step machine, 165symmetric complement of a relation, 52symmetric property, 50

Ttail-recursive form, 35technique. See program transformation

auxiliary computation during recursion, 176memory-adaptive algorithm, 177operation–accumulation procedure duality,

47reduction to constrained subproblem, 54returning useful information, 87, 96, 97,

101–103, 106, 112, 152, 153, 159, 163,174, 179, 182, 211

transformation–action duality, 28useful variations of an interface, 38

temporary buffer type, 187terminal element under transformation, 18terminating algorithm, 23three-valued compare, 63Tighe, Joseph, 179to-permutation, 172total object state, 5total procedure, 17total value type, 2TotallyOrdered concept, 62total ordering property, 51trait class, 240transformation, 17

composing, 17, 32

Index 261

cyclic element, 18fixed point of, 170identity, 170into, 169of program. See program transformationone-to-one, 169onto, 169orbit, 18power of (fn), 17terminal element, 18

Transformation concept, 17transitive property, 49transpose operation algorithm, 201transposition, 171traversal

multipass, 106single-pass, 91of tree, recursive, 119

traverse algorithm, 123traverse nonempty algorithm, 118traverse phased rotating algorithm, 148traverse rotating algorithm, 146traverse step machine, 121tree property, 117tree rotate machine, 145trichotomy law, 51triple type, 11trivial cycle, 171twice, 41two-pointer header doubly linked list, 218type

array k, 210bounded range, 214computational basis, 6counter machine, 200isomorphism, 86models concept, 11pair, 11, 209regular, 6temporary buffer, 187triple, 11underlying iterator, 225visit, 118

type attribute, 10Arity, 11

type concept, 11type constructor, 11type function, 11

Codomain, 11DifferenceType, 113DistanceType, 17, 91Domain, 12implemented via trait class, 240InputType, 11IteratorConcept, 187IteratorType, 133, 134, 213QuotientType, 72SizeType, 213UnderlyingType, 223ValueType, 90, 149, 213WeightType, 115

Uunambiguous value type, 3UnaryFunction concept, 12UnaryPredicate concept, 16underlying type, 164, 223

iterator adapters, 224proper, 223

UnderlyingType type function, 223underlying iterator type, 225underlying ref algorithm, 224union (∪), 231uniquely represented object type, 5uniquely represented value type, 2univalent concept, 86upper bound, 107upper bound n algorithm, 109upper bound predicate algorithm, 109useful variations of an interface, 38usefulness of concept, 87

Vvalue, 2value type, 2

ambiguous, 3properly partial, 2regular function on, 3total, 2uniquely represented, 2

ValueType type function, 90, 149, 213visit type, 118

Wweak (usage convention), 232weak-trichotomy law, 51

262 Index

weakening of concept, 11weak ordering property, 52weak range property, 92weight algorithm, 122WeightType type function, 115weight recursive algorithm, 117weight rotating algorithm, 147well-formed object, 5well-formed value, 2

words in memory, 4writable range, 150writable bounded range property, 150writable counted range property, 150writable weak range property, 150write aliased property, 159

Xzero, 41