Elements of Programming
This page intentionally left blank
Elements of Programming
Alexander StepanovPaul McJones
Upper Saddle River, NJ • Boston • Indianapolis • San FranciscoNew York • Toronto • Montreal • London • Munich • Paris • Madrid
Capetown • Sydney • Tokyo • Singapore • Mexico City
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.Fourth printing, January 2015
Contents
Preface ix
About the Authors xiii
1 Foundations 11.1 Categories of Ideas: Entity, Species, Genus 1
1.2 Values 2
1.3 Objects 4
1.4 Procedures 6
1.5 Regular Types 6
1.6 Regular Procedures 8
1.7 Concepts 10
1.8 Conclusions 14
2 Transformations and Their Orbits 152.1 Transformations 15
2.2 Orbits 18
2.3 Collision Point 21
2.4 Measuring Orbit Sizes 27
2.5 Actions 28
2.6 Conclusions 29
3 Associative Operations 313.1 Associativity 31
3.2 Computing Powers 33
v
vi Contents
3.3 Program Transformations 35
3.4 Special-Case Procedures 39
3.5 Parameterizing Algorithms 42
3.6 Linear Recurrences 43
3.7 Accumulation Procedures 46
3.8 Conclusions 47
4 Linear Orderings 494.1 Classification of Relations 49
4.2 Total and Weak Orderings 51
4.3 Order Selection 52
4.4 Natural Total Ordering 61
4.5 Clusters of Derived Procedures 62
4.6 Extending Order-Selection Procedures 63
4.7 Conclusions 63
5 Ordered Algebraic Structures 655.1 Basic Algebraic Structures 65
5.2 Ordered Algebraic Structures 70
5.3 Remainder 71
5.4 Greatest Common Divisor 76
5.5 Generalizing gcd 79
5.6 Stein gcd 81
5.7 Quotient 81
5.8 Quotient and Remainder for Negative Quantities 83
5.9 Concepts and Their Models 85
5.10 Computer Integer Types 87
5.11 Conclusions 88
6 Iterators 896.1 Readability 89
6.2 Iterators 90
6.3 Ranges 92
6.4 Readable Ranges 95
Contents vii
6.5 Increasing Ranges 103
6.6 Forward Iterators 106
6.7 Indexed Iterators 110
6.8 Bidirectional Iterators 111
6.9 Random-Access Iterators 113
6.10 Conclusions 114
7 Coordinate Structures 1157.1 Bifurcate Coordinates 115
7.2 Bidirectional Bifurcate Coordinates 119
7.3 Coordinate Structures 124
7.4 Isomorphism, Equivalence, and Ordering 124
7.5 Conclusions 131
8 Coordinates with Mutable Successors 1338.1 Linked Iterators 133
8.2 Link Rearrangements 134
8.3 Applications of Link Rearrangements 140
8.4 Linked Bifurcate Coordinates 143
8.5 Conclusions 148
9 Copying 1499.1 Writability 149
9.2 Position-Based Copying 151
9.3 Predicate-Based Copying 157
9.4 Swapping Ranges 164
9.5 Conclusions 168
10 Rearrangements 16910.1 Permutations 169
10.2 Rearrangements 172
10.3 Reverse Algorithms 174
10.4 Rotate Algorithms 178
10.5 Algorithm Selection 186
10.6 Conclusions 189
viii Contents
11 Partition and Merging 19111.1 Partition 191
11.2 Balanced Reduction 198
11.3 Merging 202
11.4 Conclusions 208
12 Composite Objects 20912.1 Simple Composite Objects 209
12.2 Dynamic Sequences 216
12.3 Underlying Type 222
12.4 Conclusions 225
Afterword 227
Appendix A Mathematical Notation 231
Appendix B Programming Language 233B.1 Language Definition 233
B.2 Macros and Trait Structures 240
Bibliography 243
Index 247
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. We thank John Banning,Bob English, Steven Gratton, Max Hailperin, Eugene Kirpichov, Alexei Nekrassov,Mark Ruzon, and Hao Song for finding errors in the first printing. We thank FosterBrereton, Gabriel Dos Reis, Ryan Ernst, Abraham Sebastian, Mike Spertus, HenningThielemann, and Carla Villoria Burgazzi for finding errors in the second printing.6
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.
6. See www.elementsofprogramming.com for the up-to-date errata.
This page intentionally left blank
About the Authors
Alexander Stepanov studied mathematics at Moscow State University from 1967to 1972. He has been programming since 1972: first in the Soviet Union and, afteremigrating in 1977, in the United States. He has programmed operating systems,programming tools, compilers, and libraries. His work on foundations of program-ming has been supported by GE, Brooklyn Polytechnic, AT&T, HP, SGI, andAdobe. In 1995 he received the Dr. Dobb’s Journal Excellence in ProgrammingAward for the design of the C++ Standard Template Library.
Paul McJones studied engineering mathematics at the University of California,Berkeley, from 1967 to 1971. He has been programming since 1967 in the areas ofoperating systems, programming environments, transaction processing systems, andenterprise and consumer applications. He has been employed by the University ofCalifornia, IBM, Xerox, Tandem, DEC, and Adobe. In 1982 he and his coauthorsreceived the ACM Programming Systems and Languages Paper Award for theirpaper “The Recovery Manager of the System R Database Manager.”
xiii
This page intentionally left blank
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 ⇒ fi(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 it collides withslow. 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)
{
// Precondition: (∃n ∈ DistanceType(F)) n ≥ 0 ∧ fn(x0) = fn(x1)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 The precondition of convergent point ensures termination.Implement an algorithm convergent point guarded for use when that pre-condition is not known to hold, but there is an element in common to theorbits of both x0 and x1.
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. [19 ], 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.
82
This page intentionally left blank
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, 40binary scale up nonnegative, 40bisection 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, 144modeled by type, 11
Module, 70MultiplicativeGroup, 68MultiplicativeMonoid, 67MultiplicativeSemigroup, 66
NonnegativeDiscreteArchimedeanSemiring,
Operation, 16OrderedAdditiveGroup, 70OrderedAdditiveMonoid, 70OrderedAdditiveSemigroup, 70Predicate, 15RandomAccessIterator, 113
refinement, 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
Mutable, 150
Readable, 90
Writable, 149
86
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, 40exchange 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, 40half-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, 13
mutable range, 151mutable bounded range property, 151mutable counted range property, 151mutable weak range property, 151mutative rearrangement, 172
Nnatural total ordering, < reserved for, 61negative, 40nil, 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, 40one, 40one-to-one transformation, 169
utable, 15M 0
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, 40postorder, 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, 40of 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, 107mutable, 151
partition point, 105partitioned, 105readable, 95size, 94strictly increasing, 103upper bound, 107writable, 150
reachabilityof bifurcate coordinate, 116in orbit, 18
reachable algorithm, 121
readable 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
Readable, 90
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, 40of 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, 40two-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, 4
writable range, 150writable bounded range property, 150writable counted range property, 150writable weak range property, 150write aliased property, 159
Zzero, 40
Writable, 149
Top Related