<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'><id>tag:blogger.com,1999:blog-8082954141980125536</id><updated>2008-05-07T16:59:35.720-04:00</updated><title type='text'>research!rsc</title><link rel='alternate' type='text/html' href='http://research.swtch.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default?start-index=26&amp;max-results=25'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://research.swtch.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default'/><author><name>rsc</name><uri>http://www.blogger.com/profile/06357099531993534337</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-88388799571459136</id><published>2008-04-30T10:16:00.007-04:00</published><updated>2008-04-30T10:51:34.074-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='theory'/><category scheme='http://www.blogger.com/atom/ns#' term='brute force'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><title type='text'>Mel was Real</title><content type='html'>&lt;p class=pp&gt;Things have been pretty crazy around here, so no new posts recently, but this caught my attention.&lt;/p&gt;

&lt;p class=pp&gt;James Grimmelmann &lt;a href="http://laboratorium.net/archive/2008/04/28/a_few_facts_about_the_lgp30"&gt;reports&lt;/a&gt; a few interesting facts about the Librascope/Royal McBee LGP-30.  Specifically, &lt;a href="http://www.pbm.com/~lindahl/mel.html"&gt;Mel&lt;/a&gt; was real, and the hexadecimal digits were 0 1 2 3 4 5 6 7 8 9 &lt;i&gt;F G J K Q W&lt;/i&gt;!
&lt;/p&gt;

&lt;p class=pp&gt;I can't resist telling a story.  James is now a professor at the New York Law School, but he and I were fellow computer science students in college.  He was a TA for the undergraduate introductory theory course when I took it, and his duties included, among other more enjoyable tasks, grading the first problem set.  The &amp;ldquo;challenge&amp;rdquo; problem asked for a proof that in any group of six people, there is either a group of three that all know each other (a clique) or a group of three that all don't know each other (an anti-clique).  I didn't see how to prove it*, so I just wrote a simple C program to iterate over all 2&lt;sup&gt;15&lt;/sup&gt; possibilities and verify that the condition holds.  I wrote something about using brute force and attached the C program to the problem set.  This problem set was just a warm-up in proof techniques, but the course is all about what can and can't be computed by various systems.  The pinnacle result, of course, is Turing's proof that some problems are uncomputable and Cook's definition of NP-completeness.  In that light, my brute force proof ran against everything the course was trying to teach.&lt;/p&gt;

&lt;p class=pp&gt;James was the grader for that question.  Next to the comment about brute force, he wrote &amp;ldquo;Wait until the NP-completeness unit, Mr. Brute Force&amp;rdquo;  At the end, he added, &amp;ldquo;Very, very clever.  Such tricks will not avail you much where this course is headed.&amp;rdquo;  I didn't appreciate it then, but in hindsight I find it very funny.&lt;/p&gt;

&lt;p class=lp&gt;&lt;font size=-2&gt;* Truth be told, I still don't see how to prove it.  You're supposed to use the pigeonhole principle, and the details have been explained to me in the past, but I can never reconstruct them on demand.  The exhaustive search still feels easier, though perhaps less enlightening.&lt;/font&gt;&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://research.swtch.com/2008/04/mel-was-real.html' title='Mel was Real'/><link rel='related' href='http://laboratorium.net/archive/2008/04/28/a_few_facts_about_the_lgp30' title='Mel was Real'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8082954141980125536&amp;postID=88388799571459136' title='9 Comments'/><link rel='replies' type='application/atom+xml' href='http://research.swtch.com/feeds/88388799571459136/comments/default' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/88388799571459136'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/88388799571459136'/><author><name>rsc</name><uri>http://www.blogger.com/profile/09576271159839887762</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-6537452186467222437</id><published>2008-04-14T00:35:00.000-04:00</published><updated>2008-04-14T12:35:09.055-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='file systems'/><category scheme='http://www.blogger.com/atom/ns#' term='storage'/><category scheme='http://www.blogger.com/atom/ns#' term='Bell Labs'/><title type='text'>Backups, heal thyself</title><content type='html'>&lt;center&gt;
&lt;img src="http://bp0.blogger.com/_9P3HFEQk8wo/SANgnubxWhI/AAAAAAAAAGo/wUTNT0I9raE/s800/venti.jpg" border="0" alt="MIT venti server" /&gt;&lt;/center&gt;

&lt;p class=pp&gt;
Around 2000, Sean Quinlan and Sean Dorward built a content-addressed storage system called Venti.  Their paper, &amp;ldquo;&lt;a href="http://plan9.bell-labs.com/sys/doc/venti.pdf"&gt;&lt;b&gt;Venti: a new approach to archival storage&lt;/b&gt;&lt;/a&gt;&amp;rdquo; (PDF; also &lt;a href="http://plan9.bell-labs.com/sys/doc/venti.html"&gt;HTML&lt;/a&gt;), won best paper at the storage conference where it was presented.  Today's post is about how Venti can heal itself.
&lt;/p&gt;

&lt;p class=pp&gt;Venti names stored objects by their SHA1 hashes: you write a block, you get back the SHA1 hash.  You show up with a SHA1 hash, you can get the block.  Objects larger than a block are typically broken up into blocks and then stored in a tree.  Each pointer in the tree is the SHA-1 hash of the block it points to:&lt;/p&gt;

&lt;center&gt;
&lt;img src="http://bp1.blogger.com/_9P3HFEQk8wo/SAOBP-bxWiI/AAAAAAAAAGw/Dtv0X2jYqUo/s400/tree1.png" border="0" alt="Hash trees" /&gt;
&lt;/center&gt;

&lt;p class=lp&gt;Thus, if you've stored a big file (say, a disk image) and you change one block, only that one block and the (probably five or so) blocks that point at it actually change: the rest of the storage can be shared with the previous copy of the file.&lt;/p&gt;

&lt;p class=pp&gt;The primary benefit of using content-addressing is that duplicates get removed for free.  If two different people write the same data, Venti only stores the data once.  Or if one person archives the same data twice, Venti only stores the data once.  My research group at MIT runs a Venti server to store FFS disk images of its main file server.  Writing the same images over and over again only stores changed blocks, and if multiple people have the same giant files, they take up extra space on the file server itself, but not in Venti.  Our live file system usage is about 600GB, but the incremental backup cost in Venti is about 2 GB per night.  All our nightly backups going back to 2005 take up about 3 TB, or 1.7 TB compressed.&lt;/p&gt;

&lt;p class=pp&gt;
Another benefit of using content-addressing is that if the data goes bad, you notice.  You can check the SHA-1 hash of the data returned by a read to make sure it is the block you expected.  Clients can verify the data returned by the server, and the server can verify the data returned by its disks.  In fact the latter has been the bigger problem in Venti installations: disks go bad, and if you tend to notice more if you have checks like these.
&lt;/p&gt;

&lt;p class=pp&gt;
A few years ago, I wanted to download all the &lt;a href="http://plan9.bell-labs.com/who/seanq/p9trace.html"&gt;6 GB of file system traces&lt;/a&gt; used in the Venti paper.  Not all of the files downloaded correctly: a few were truncated too early.  It turned out that the Venti server now storing the traces at Bell Labs had some disk corruption, and the Venti server noticed because the SHA-1 hashes didn't match expectations.  No problem, just use the earlier Venti server that the data was copied from.  That server has had disk corruption too, some of it overlapping the bad blocks.  So there are still traces that can't be read.  Okay, well the traces were saved on backup tapes too.  Dig those up, and the backup tapes aren't complete either: still two trace files with missing blocks.  There are also backup tapes of the original file system blocks that were used to create the traces.  Those are actually readable, so we can regenerate the bad trace files and have a complete set again.
&lt;/p&gt;

&lt;p class=pp&gt;
Here's the fun part.  The original trace files were stored as a single Venti archive, a giant hash tree like the one pictured above that contains pointers to all the trace files.  Not all the files can be read out of the archive, since we have these pointers to missing blocks.  Creating a new archive holding just the two missing trace files &lt;i&gt;makes the old archive start working&lt;/i&gt;.
Now that Venti has blocks with the desired SHA1 hashes, the pointers to missing blocks
become pointers to existing blocks.  
Given the right raw materials, the broken archive healed automatically.&lt;/p&gt;

&lt;p class=pp&gt;
With a little engineering, you could create a typical incremental backup
system that didn't use hashes to identify duplicate blocks, and you'd probably
end up being within a factor of two as space-efficient as Venti.
For a long time I had this lingering fear that perhaps indexing by SHA-1 hash,
which is pretty expensive to implement efficiently, was overkill.
Watching that previously broken archive start working again
was the moment when I fully believed that Venti's was the right approach.&lt;/p&gt;

&lt;br&gt;
&lt;p class=lp&gt;
&lt;i&gt;Further reading&lt;/i&gt;.  The use of SHA1 specifically isn't really important: any strong collision-resistant hash function will do, though &lt;a href="http://www.usenix.org/events/hotos03/tech/henson.html"&gt;people&lt;/a&gt; &lt;a href="http://www.usenix.org/event/usenix06/tech/full_papers/black/black_html/index.html"&gt;disagree&lt;/a&gt; on the wisdom of this approach.  Remember that Venti is being used in situations where there are no adversaries: the main concern is an accidental collision.  The second paper just linked to summarizes:
&lt;blockquote&gt;
We conclude that it is certainly fine to use a 160-bit hash function like SHA1 or RIPEMD-160 with compare-by-hash. The chances of an accidental collision is about 2^-160. This is unimaginably small. You are roughly 2^90 times more likely to win a U.S. state lottery and be struck by lightning simultaneously than you are to encounter this type of error in your file system.
&lt;/blockquote&gt;
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://research.swtch.com/2008/04/backups-heal-thyself.html' title='Backups, heal thyself'/><link rel='related' href='http://plan9.bell-labs.com/sys/doc/venti.pdf' title='Backups, heal thyself'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8082954141980125536&amp;postID=6537452186467222437' title='5 Comments'/><link rel='replies' type='application/atom+xml' href='http://research.swtch.com/feeds/6537452186467222437/comments/default' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/6537452186467222437'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/6537452186467222437'/><author><name>rsc</name><uri>http://www.blogger.com/profile/09576271159839887762</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-1473564042324796034</id><published>2008-04-11T09:44:00.003-04:00</published><updated>2008-04-11T09:46:58.733-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='notation'/><category scheme='http://www.blogger.com/atom/ns#' term='Knuth'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><category scheme='http://www.blogger.com/atom/ns#' term='Bell Labs'/><title type='text'>Bi-quinary and other bases</title><content type='html'>&lt;p class=pp&gt;Doug McIlroy's talk on &lt;a href="http://research.swtch.com/2008/04/computing-history-at-bell-labs.html"&gt;History of Computing at Bell Labs&lt;/a&gt; mentioned that &lt;a href="http://en.wikipedia.org/wiki/George_Stibitz"&gt;George Stibitz&lt;/a&gt;'s relay-based
decimal calculators that stored digits in what he called bi-quinary: &amp;ldquo;Arithmetic was done in bi-quinary, a two out of five representation for decimal integers, and if there weren't exactly two out of five relays activated it would stop.&amp;rdquo;
This allowed a sequence of computing jobs to run unattended over the weekend: if the computer detected an error (not exactly two relays active in some digit), then it would stop the current job and start over.&lt;/p&gt;

&lt;p class=pp&gt;
McIlroy's description of the number system as being 5 bits 
differs from any of the representations given by the Wikipedia entries for &lt;a href="http://en.wikipedia.org/wiki/Bi-quinary_coded_decimal"&gt;bi-quinary coded decimal&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Biquinary"&gt;biquinary&lt;/a&gt;, which describe
a system that is basically unary: 5 bits to count 0 through 4 (only 1 bit on at a time) 
and two top bits: 01 = 0, 10 = 5.  Other historical summaries you can find online by searching for Stibitz and bi-quinary seem to back up Wikipedia.  In this version, bi-quinary was 1-of-2 plus 1-of-5, not 2-of-5.  In the 7-bit version, the bit positions are worth 5, 0, 4, 3, 2, 1, and 0, which isn't very interesting.
It's far more interesting to think about the 2-out-of-5 system.
&lt;/p&gt;

&lt;p class=pp&gt;
The valid codes in a 2-of-5 system like McIlroy described would be 00011, 00101, 00110, 01001, 01010, 01100, 10001, 10010, 10100, 11000.  
If you assign these the values 0 through 9, you can set up a system of linear equations and solve them to find the value of each of the five bit positions b4, b3, b2, b1, and b0.  The fact that 00011 = 0 means that b1 + b0 = 0.  The fact that 00110 - 00101 = 2 - 1 = 1 means that b1 - b0 = 1.  These two equalities imply b1 = ½ and b0 = -½.  Given that you can pick out the other bits fairly easily: from right to left the "places" are -½, ½, 1½, 3½, and 6½.  This works for 0 through 8 but then, sadly, fails for 9: 11000 = 6½ + 3½ = 10.  No other code assignment has a solution either (I  wrote a small program to try them all.)
&lt;/p&gt;

&lt;p class=pp&gt;
I guess that's why the 1-of-2 plus 1-of-5 form was more popular than 2-of-5: it was probably easier to design the arithmetic circuits if each bit could be assigned a particular value.
It's too bad, because 2-of-5 would have mathematical elegance on its side if it could be made to work.
&lt;/p&gt;

&lt;p class=pp&gt;
If you dig around, you can find other esoteric number representations:
&lt;a href="http://en.wikipedia.org/wiki/Negabinary"&gt;negabinary&lt;/a&gt; has base -2 (negative two),
so the positional values are 1, -2, 4, -8, and so on.
Thus 5 is 101 but 3 is 111 = 1-2+4.
Negabinary appears to have been first invented by Vittorio Grunwald in 1885.
It was used in a few experimental computers in the 1950s, but it didn't catch on.
Even weirder than negabinary numbers are the &lt;a href="http://en.wikipedia.org/wiki/Quater-imaginary_base"&gt;quater-imaginary numbers&lt;/a&gt;,
invented by a high school student named Donald Knuth in 1955.
Those use base 2&lt;i&gt;i&lt;/i&gt; (where &lt;i&gt;i&lt;/i&gt; is the imaginary square root of -1).
(Knuth is also responsible for the negabinary history.)
&lt;/p&gt;

&lt;p class=pp&gt;
Odder still are 
&lt;a href="http://en.wikipedia.org/wiki/Balanced_ternary"&gt;balanced ternary&lt;/a&gt; (ternary but digits are -1, 0, and 1)
and &lt;a href="http://en.wikipedia.org/wiki/Bubble_Babble"&gt;Bubble Babble&lt;/a&gt;,
but no discussion of interesting counting systems or high school math nerds would be
complete without mentioning &lt;a href="http://en.wikipedia.org/wiki/Finger_binary"&gt;counting
on your fingers in binary&lt;/a&gt;.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://research.swtch.com/2008/04/bi-quinary-and-other-bases.html' title='Bi-quinary and other bases'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8082954141980125536&amp;postID=1473564042324796034' title='2 Comments'/><link rel='replies' type='application/atom+xml' href='http://research.swtch.com/feeds/1473564042324796034/comments/default' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/1473564042324796034'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/1473564042324796034'/><author><name>rsc</name><uri>http://www.blogger.com/profile/09576271159839887762</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-6991105448754243186</id><published>2008-04-09T06:15:00.001-04:00</published><updated>2008-04-10T09:26:20.969-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='history'/><category scheme='http://www.blogger.com/atom/ns#' term='Bell Labs'/><title type='text'>Computing History at Bell Labs</title><content type='html'>&lt;p class=pp&gt;
In 1997, on his retirement from Bell Labs, Doug McIlroy gave a
fascinating talk about the &amp;ldquo;&lt;a href="http://cm.bell-labs.com/cm/cs/doug97.html"&gt;&lt;b&gt;History of Computing at Bell Labs&lt;/b&gt;&lt;/a&gt;.&amp;rdquo;
That page contains audio for the talk in Real Audio format (it &lt;i&gt;was&lt;/i&gt; 1997).
Almost ten years ago I transcribed the audio but never did anything with it.
The transcript is below.
&lt;/p&gt;

&lt;p class=pp&gt;
My favorite parts of the talk are the description of the bi-quinary decimal relay calculator
and the description of a team that spent over a year tracking down a race condition bug in
a missile detector (reliability was king: today you'd just stamp
&amp;ldquo;cannot reproduce&amp;rdquo; and send the report back).
But the whole thing contains many fantastic stories.
It's well worth the read or listen.
I also like his recollection of programming using cards: &amp;ldquo;It's the kind of thing you can be nostalgic about, but it wasn't actually fun.&amp;rdquo;
&lt;/p&gt;


&lt;p class=pp&gt;
For more information, Bernard D. Holbrook and W. Stanley Brown's 1982
technical report
&amp;ldquo;&lt;a href="http://cm.research.bell-labs.com/cm/cs/cstr/cstr99.html"&gt;A History of Computing Research at Bell Laboratories (1937-1975)&lt;/a&gt;&amp;rdquo;
covers the earlier history in more detail.
&lt;/p&gt;

&lt;br&gt;
&lt;br&gt;

&lt;p class=lp&gt;&lt;i&gt;Transcript of &amp;ldquo;&lt;a href="http://cm.bell-labs.com/cm/cs/doug97.html"&gt;History of Computing at Bell Labs:&lt;/a&gt;&amp;rdquo;&lt;/i&gt;&lt;/p&gt;

&lt;p class=pp&gt;
Computing at Bell Labs is certainly an outgrowth of the
&lt;a href="http://cm.bell-labs.com/cm/ms/history/history.html"&gt;mathematics department&lt;/a&gt;, which grew from that first hiring
in 1897, G A Campbell.  When Bell Labs was formally founded
in 1925, what it had been was the engineering department
of Western Electric.
When it was formally founded in 1925,
almost from the beginning there was a math department with Thornton Fry as the department head, and if you look at some of Fry's work, it turns out that
he was fussing around in 1929 with trying to discover
information theory.  It didn't actually gel until twenty years later with Shannon.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;1:10&lt;/span&gt;
Of course, most of the mathematics at that time was continuous.
One was interested in analyzing circuits and propagation.  And indeed, this is what led to the growth of computing in Bell Laboratories.  The computations could not all be done symbolically.  There were not closed form solutions.  There was lots of numerical computation done.
The math department had a fair stable of computers,
which in those days meant people. [laughter]&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;2:00&lt;/span&gt;
And in the late '30s, &lt;a href="http://en.wikipedia.org/wiki/George_Stibitz"&gt;George Stibitz&lt;/a&gt; had an idea that some of
the work that they were doing on hand calculators might be
automated by using some of the equipment that the Bell System
was installing in central offices, namely relay circuits.
He went home, and on his kitchen table, he built out of relays
a binary arithmetic circuit.  He decided that binary was really
the right way to compute.
However, when he finally came to build some equipment,
he determined that binary to decimal conversion and
decimal to binary conversion was a drag, and he didn't
want to put it in the equipment, and so he finally built
in 1939, a relay calculator that worked in decimal,
and it worked in complex arithmetic.
Do you have a hand calculator now that does complex arithmetic?
Ten-digit, I believe, complex computations: add, subtract,
multiply, and divide.
The I/O equipment was teletypes, so essentially all the stuff to make such
machines out of was there.
Since the I/O was teletypes, it could be remotely accessed,
and there were in fact four stations in the West Street Laboratories
of Bell Labs.  West Street is down on the left side of Manhattan.
I had the good fortune to work there one summer, right next to a
district where you're likely to get bowled over by rolling ?beads?&lt;!--&lt;span style="font-size: 0.7em;"&gt;4:09&lt;/span&gt;--&gt; hanging from racks or tumbling ?cabbages?&lt;!--&lt;span style="font-size: 0.7em;"&gt;4:16&lt;/span&gt;--&gt;.  The building is still there.  It's called &lt;a href="http://query.nytimes.com/gst/fullpage.html?res=950DE3DB1F38F931A35751C0A96F948260"&gt;Westbeth Apartments&lt;/a&gt;.  It's now an artist's colony.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;4:29&lt;/span&gt;
Anyway, in West Street, there were four separate remote stations from which the complex calculator could be accessed.  It was not time sharing.  You actually reserved your time on the machine, and only one of the four terminals worked at a time.
In 1940, this machine was shown off to the world at the AMS annual convention, which happened to be held in Hanover at Dartmouth that year, and mathematicians could wonder at remote computing, doing computation on an electromechanical calculator at 300 miles away.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;5:22&lt;/span&gt;
Stibitz went on from there to make a whole series of relay machines.  Many of them were made for the government during the war.  They were named, imaginatively, Mark I through Mark VI.
I have read some of his patents.  They're kind of fun.  One is a patent on conditional transfer. [laughter]  And how do you do a conditional transfer?
Well these gadgets were, the relay calculator was run from your fingers, I mean the complex calculator.
The later calculators, of course, if your fingers were a teletype, you could perfectly well feed a paper tape in,
because that was standard practice.  And these later machines were intended really to be run more from paper tape.
And the conditional transfer was this: you had two teletypes, and there's a code that says "time to read from the other teletype".  Loops were of course easy to do.  You take paper and [laughter; presumably Doug curled a piece of paper to form a physical loop].
These machines never got to the point of having stored programs.
But they got quite big.  I saw, one of them was here in 1954, and I did see it, behind glass, and if you've ever seen these machines in the, there's one in the Franklin Institute in Philadelphia, and there's one in the Science Museum in San Jose, you know these machines that drop balls that go wandering sliding around and turning battle wheels and ringing bells and who knows what.  It kind of looked like that.
It was a very quiet room, with just a little clicking of relays, which is what a central office used to be like.  It was the one air-conditioned room in Murray Hill, I think.  This machine ran, the Mark VI, well I think that was the Mark V, the Mark VI actually went to Aberdeen.
This machine ran for a good number of years, probably six, eight.
And it is said that it never made an undetected error. [laughter]&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;8:30&lt;/span&gt;
What that means is that it never made an error that it did not diagnose itself and stop.
Relay technology was very very defensive.  The telephone switching system had to work.  It was full of self-checking,
and so were the calculators, so were the calculators that Stibitz made.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;9:04&lt;/span&gt;
Arithmetic was done in bi-quinary, a two out of five representation for decimal integers, and if there weren't exactly two out of five relays activated it would stop.
This machine ran unattended over the weekends.  People would
bring their tapes in, and the operator would paste everybody's tapes together.
There was a beginning of job code on the tape and there was also a time indicator.
If the machine ran out of time, it automatically stopped and went to the next job.  If the machine caught itself in an error, it backed up to the current job and tried it again.
They would load this machine on Friday night, and on Monday morning, all the tapes, all the entries would be available on output tapes.&lt;/p&gt;

&lt;p class=pp&gt;Question: I take it they were using a different representation for loops
and conditionals by then.&lt;/p&gt;

&lt;p class=pp&gt;Doug: Loops were done actually by they would run back and forth across the tape now, on this machine.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;10:40&lt;/span&gt;
Then came the transistor in '48.
At Whippany, they actually had a transistorized computer, which was a respectable minicomputer, a box about this big, running in 1954, it ran from 1954 to 1956 solidly as a test run.
The notion was that this computer might fly in an airplane.
And during that two-year test run, one diode failed.
In 1957, this machine called &lt;a href="http://www.cedmagic.com/history/tradic-transistorized.html"&gt;TRADIC&lt;/a&gt;, did in fact fly in an airplane, but to the best of my knowledge, that machine was a demonstration machine.  It didn't turn into a production machine.
About that time, we started buying commercial machines.
It's wonderful to think about the set of different architectures that existed in that time.  The first machine we got was called a &lt;a href="http://www.columbia.edu/acis/history/cpc.html"&gt;CPC from IBM&lt;/a&gt;.  And all it was was a big accounting machine with a very special plugboard on the side that provided an interpreter for doing ten-digit decimal arithmetic, including
opcodes for the trig functions and square root.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;12:30&lt;/span&gt;
It was also not a computer as we know it today,
because it wasn't stored program, it had twenty-four memory locations as I recall, and it took its program instead of from tapes, from cards.  This was not a total advantage.  A tape didn't get into trouble if you dropped it on the floor.  [laughter].
CPC, the operator would stand in front of it, and there, you
would go through loops by taking cards out, it took human intervention, to take the cards out of the output of the card reader and put them in the ?top?&lt;!--&lt;span style="font-size: 0.7em;"&gt;13:10&lt;/span&gt;--&gt;.  I actually ran some programs on the CPC ?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;13:20&lt;/span&gt;--&gt;.  It's the kind of thing you can be nostalgic about, but it wasn't actually fun.
[laughter]&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;13:30&lt;/span&gt;
The next machine was an &lt;a href="http://www.columbia.edu/acis/history/650.html"&gt;IBM 650&lt;/a&gt;, and here, this was a stored program, with the memory being on drum.  There was no operating system for it.  It came with a manual: this is what the machine does.  And Michael Wolontis made an interpreter called the &lt;a href="http://hopl.murdoch.edu.au/showlanguage.prx?exp=6497&amp;language=Wolontis-Bell%20Interpreter"&gt;L1 interpreter&lt;/a&gt; for this machine, so you could actually program in, the manual told you how to program in binary, and L1 allowed you to give something like 10 for add and 9 for subtract, and program in decimal instead.  And of course that machine required interesting optimization, because it was a nice thing if the next program step were stored somewhere -- each program step had the address of the following step in it, and you would try to locate them around the drum so to minimize latency.  So there were all kinds of optimizers around, but I don't think Bell Labs made ?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;14:52&lt;/span&gt;--&gt; based on this called "soap" from Carnegie Mellon.  That machine didn't last very long.  Fortunately, a machine with core memory came out from IBM in about '56, the 704.  Bell Labs was a little slow in getting one, in '58.  Again, the machine came without an operating system.
In fact, but it did have Fortran, which really changed the world.
It suddenly made it easy to write programs.  But the way Fortran came from IBM, it came with a thing called the Fortran Stop Book.
This was a list of what happened, a diagnostic would execute the halt instruction, the operator would go read the panel lights and discover where the machine had stopped, you would then go look up in the stop book what that meant.
Bell Labs, with George Mealy and Glenn Hanson, made an operating system, and one of the things they did was to bring the stop book to heel.  They took the compiler, replaced all the stop instructions with jumps to somewhere, and allowed the program instead of stopping to go on to the next trial.
By the time I arrived at Bell Labs in 1958, this thing was running nicely.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;16:36&lt;/span&gt;
Bell Labs continued to be a major player in operating systems.
This was called BESYS.  BE was the share abbreviation for Bell Labs.  Each company that belonged to Share, which was the IBM users group, ahd a two letter abbreviation.  It's hard to imagine taking all the computer users now and giving them a two-letter abbreviation.  BESYS went through many generations, up to BESYS 5, I believe.  Each one with innovations.  IBM delivered a machine, the 7090, in 1960.  This machine had interrupts in it, but IBM didn't use them.  But BESYS did.  And that sent IBM back to the drawing board to make it work.  [Laughter]&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;17:48&lt;/span&gt;
Rob Pike:  It also didn't have memory protection.&lt;/p&gt;

&lt;p class=pp&gt;Doug: It didn't have memory protection either, and a lot of people actually got IBM to put memory protection in the 7090, so that one could leave the operating system resident in the presence of a wild program, an idea that the PC didn't discover until, last year or something like that.  [laughter]&lt;/p&gt;

&lt;p class=pp&gt;Big players then, &lt;a href="http://en.wikipedia.org/wiki/Richard_Hamming"&gt;Dick Hamming&lt;/a&gt;, a name that I'm sure everybody knows,
was sort of the numerical analysis guru, and a seer.
He liked to make outrageous predictions.  He predicted in 1960, that half of Bell Labs was going to be busy doing something with computers eventually.
?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;19:00&lt;/span&gt;--&gt; exaggerating some ?...? abstract in his thought.
He was wrong.
Half was a gross underestimate.  Dick Hamming retired twenty years ago, and just this June he completed his full twenty years term in the Navy, which entitles him again to retire from the Naval Postgraduate Institute in Monterey.  Stibitz, incidentally died, I think within the last year.
He was doing medical instrumentation at Dartmouth essentially, near the end.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;20:00&lt;/span&gt;
Various problems intrigued, besides the numerical problems, which in fact were stock in trade, and were the real justification for buying machines, until at least the '70s I would say.  But some non-numerical problems had begun to tickle the palette of the math department.  Even G A Campbell got interested in graph theory, the reason being he wanted to think of all the possible ways you could take the three wires and the various parts of the telephone and connect them together, and try permutations to see what you could do about reducing side ?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;21:03&lt;/span&gt;--&gt; by putting things into the various parts of the circuit, and devised every possibly way of connecting the telephone up.  And that was sort of the beginning of combinatorics at Bell Labs.  John Reardon, a mathematician parlayed this into a major subject.  Two problems which are now deemed as computing problems, have intrigued the math department for a very long time, and those are the minimum spanning tree problem, and the wonderfully ?comment about Joe Kruskal, laughter?&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;21:50&lt;/span&gt;
And in the 50s Bob Prim and Kruskal, who I don't think worked on the Labs at that point, invented algorithms for the minimum spanning tree.  Somehow or other, computer scientists usually learn these algorithms, one of the two at least, as Dijkstra's algorithm, but he was a latecomer.&lt;/p&gt;

&lt;p class=pp&gt;Another pet was the traveling salesman.  There's been a long list of people at Bell Labs who played with that: Shen Lin and Ron Graham and David Johnson and dozens more, oh and ?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;22:50&lt;/span&gt;--&gt;.  And then another problem is the Steiner minimum spanning tree, where you're allowed to add points to the graph.  Every one of these problems grew, actually had a justification in telephone billing.  One jurisdiction or another would specify that the way you bill for a private line network was in one jurisdiction by the minimum spanning tree.  In another jurisdiction, by the traveling salesman route.  NP-completeness wasn't a word in the vocabulary of ?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;23:28&lt;/span&gt;--&gt; [laughter].  And the &lt;a href="http://en.wikipedia.org/wiki/Steiner_tree"&gt;Steiner problem&lt;/a&gt; came up because customers discovered they could beat the system by inventing offices in the middle of Tennessee that had nothing to do with their business, but they could put the office at a Steiner point and reduce their phone bill by adding to what the service that the Bell System had to give them.  So all of these problems actually had some justification in billing besides the fun.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;24:15&lt;/span&gt;
Come the 60s, we actually started to hire people for computing per se.  I was perhaps the third person who was hired with a Ph.D. to help take care of the computers and I'm told that the then director and head of the math department, Henry Boden, had said to his people, "yeah, you can hire this guy, instead of a real mathematician, but what's he gonna be doing in five years?" [laughter]&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;25:02&lt;/span&gt;
Nevertheless, we started hiring for real in about '67.  Computer science got split off from the math department.  I had the good fortune to move into the office that I've been in ever since then.  Computing began to make, get a personality of its own.  One of the interesting people that came to Bell Labs for a while was Hal Long.  Is his name well known?  [Pause]  One nod.  Hal Long was a philosopher and logician, and we got a letter from him in England out of the blue saying "hey you know, can I come and use your computers?  I have an idea about theorem proving."  There was theorem proving in the air in the late 50s, and it was mostly pretty thin stuff.  Obvious that the methods being proposed wouldn't possibly do anything more difficult than solve tic-tac-toe problems by enumeration.  Long had a notion that he could mechanically prove theorems in the style of Whitehead and Russell's great treatise Principia Mathematica in the early patr of the century.  He came here, learned how to program in machine language, and took all of Volume I of Principia Mathematica --
if you've ever hefted Principia, well that's about all it's good for, it's a real good door stop.  It's really big.  But it's theorem after theorem after theorem in propositional calculus.  Of course, there's a decision procedure for propositional calculus, but he was proving them more in the style of Whitehead and Russell.  And when he finally got them all coded and put them into the computer, he proved the entire contents of this immense book in eight minutes.
This was actually a neat accomplishment.  Also that was the beginning of all the language theory.  We hired people like &lt;a href="http://www1.cs.columbia.edu/~aho/"&gt;Al Aho&lt;/a&gt; and &lt;a href="http://infolab.stanford.edu/~ullman/"&gt;Jeff Ullman&lt;/a&gt;, who probed around every possible model of grammars, syntax, and all of the things that are now in the standard undergraduate curriculum, were pretty well nailed down here, on syntax and finite state machines and so on were pretty well nailed down in the 60s.  Speaking of finite state machines, in the 50s, both Mealy and Moore, who have two of the well-known models of finite state machines, were here.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;28:40&lt;/span&gt;
During the 60s, we undertook an enormous development project in the guise of research, which was &lt;a href="http://www.multicians.org/"&gt;MULTICS&lt;/a&gt;, and it was the notion of MULTICS was computing was the public utility of the future.  Machines were very expensive, and ?indeed?&lt;!--&lt;span style="font-size: 0.7em;"&gt;29:12&lt;/span&gt;--&gt; like you don't own your own electric generator, you rely on the power company to do generation for you, and it was seen that this was a good way to do computing -- time sharing -- and it was also recognized that shared data was a very good thing.  MIT pioneered this and Bell Labs joined in on the MULTICS project, and this occupied five years of system programming effort, until Bell Labs pulled out, because it turned out that MULTICS was too ambitious for the hardware at the time, and also with 80 people on it was not exactly a research project.  But, that led to various people who were on the project, in particular &lt;a href="http://en.wikipedia.org/wiki/Ken_Thompson"&gt;Ken Thompson&lt;/a&gt; -- right there -- to think about how to -- &lt;a href="http://netlib.bell-labs.com/who/dmr/"&gt;Dennis Ritchie&lt;/a&gt; and Rudd Canaday were in on this too -- to think about how you might make a pleasant operating system with a little less resources.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;30:30&lt;/span&gt;
And Ken found -- this is a story that's often been told, so I won't go into very much of unix -- Ken found an old machine cast off in the corner, the &lt;a href="http://en.wikipedia.org/wiki/GE-600_series"&gt;PDP-7&lt;/a&gt;, and put up this little operating system on it, and we had immense &lt;a href="http://en.wikipedia.org/wiki/GE-600_series"&gt;GE635&lt;/a&gt; available at the comp center at the time, and I remember as the department head, muscling in to use this little computer to be, to get to be Unix's first user, customer, because it was so much pleasanter to use this tiny machine than it was to use the big and capable machine in the comp center.  And of course the rest of the story is known to everybody and has affected all college campuses in the country.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;31:33&lt;/span&gt;
Along with the operating system work, there was a fair amount of language work done at Bell Labs.  Often curious off-beat languages.  One of my favorites was called &lt;a href="http://hopl.murdoch.edu.au/showlanguage.prx?exp=6937&amp;language=BLODI-B"&gt;Blodi&lt;/a&gt;, B L O D I, a block diagram compiler by Kelly and Vyssotsky.  Perhaps the most interesting early uses of computers in the sense of being unexpected, were those that came from the acoustics research department, and what the Blodi compiler was invented in the acoustic research department for doing digital simulations of sample data system.  DSPs are classic sample data systems,
where instead of passing analog signals around, you pass around streams of numerical values.  And Blodi allowed you to say here's a delay unit, here's an amplifier, here's an adder, the standard piece parts for a sample data system, and each one was described on a card, and with description of what it's wired to.  It was then compiled into one enormous single straight line loop for one time step.  Of course, you had to rearrange the code because some one part of the sample data system would feed another and produce really very efficient 7090 code for simulating sample data systems.
By in large, from that time forth, the acoustic department stopped making hardware.  It was much easier to do signal processing digitally than previous ways that had been analog&lt;!--?&lt;span style="font-size: 0.7em;"&gt;34:16&lt;/span&gt;--&gt;.  Blodi had an interesting property.  It was the only programming language I know where -- this is not my original observation, Vyssotsky said -- where you could take the deck of cards, throw it up the stairs, and pick them up at the bottom of the stairs, feed them into the computer again, and get the same program out.  Blodi had two, aside from syntax diagnostics, it did have one diagnostic when it would fail to compile, and that was "somewhere in your system is a loop that consists of all delays or has no delays" and you can imagine how they handled that.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;35:09&lt;/span&gt;
Another interesting programming language of the 60s was &lt;a href="http://www.knowltonmosaics.com/"&gt;Ken Knowlten&lt;/a&gt;'s &lt;a href="http://beflix.com/beflix.php"&gt;Beflix&lt;/a&gt;.  This was for making movies on something with resolution kind of comparable to 640x480, really coarse, and the
programming notion in here was bugs.  You put on your grid a bunch of bugs, and each bug carried along some data as baggage,
and then you would do things like cellular automata operations.  You could program it or you could kind of let it go by itself.  If a red bug is next to a blue bug then it turns into a green bug on the following step and so on.  &lt;span style="font-size: 0.7em;"&gt;36:28&lt;/span&gt;  He and Lillian Schwartz made some interesting abstract movies at the time.  It also did some interesting picture processing.  One wonderful picture of a reclining nude, something about the size of that blackboard over there, all made of pixels about a half inch high each with a different little picture in it, picked out for their density, and so if you looked at it close up it consisted of pickaxes and candles and dogs, and if you looked at it far enough away, it was a &lt;a href="http://blog.the-eg.com/2007/12/03/ken-knowlton-mosaics/"&gt;reclining nude&lt;/a&gt;.  That picture got a lot of play all around the country.&lt;/p&gt;

&lt;p class=pp&gt;Lorinda Cherry: That was with Leon, wasn't it?  That was with &lt;a href="http://design.osu.edu/carlson/history/lesson4.html#bell"&gt;Leon Harman&lt;/a&gt;.&lt;/p&gt;

&lt;p class=pp&gt;Doug: Was that Harman?&lt;/p&gt;

&lt;p class=pp&gt;Lorinda: ?...?&lt;/p&gt;

&lt;p class=pp&gt;Doug: Harman was also an interesting character.  He did more things than pictures.  I'm glad you reminded me of him.  I had him written down here.  Harman was a guy who among other things did a block diagram compiler for writing a handwriting recognition program.  I never did understand how his scheme worked, and in fact I guess it didn't work too well.  [laughter]
It didn't do any production ?things?&lt;!--&lt;span style="font-size: 0.7em;"&gt;37:58&lt;/span&gt;--&gt; but it was an absolutely
immense sample data circuit for doing handwriting recognition.
Harman's most famous work was trying to estimate the information content in a face.  And every one of these pictures which are a cliche now, that show a face digitized very coarsely, go back to Harman's &lt;a href="http://www.doubletakeimages.com/history.htm"&gt;first psychological experiments&lt;/a&gt;, when he tried to find out how many bits of picture he needed to try to make a face recognizable.  He went around and digitized about 256 faces from Bell Labs and did real psychological experiments asking which faces could be distinguished from other ones.  I had the good fortune to have one of the most distinguishable faces, and consequently you'll find me in freshman psychology texts through no fault of my own.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;39:15&lt;/span&gt;
Another thing going on the 60s was the halting beginning here of interactive computing.  And again the credit has to go to the acoustics research department, for good and sufficient reason.  They wanted to be able to feed signals into the machine, and look at them, and get them back out.  They bought yet another weird architecture machine called the &lt;a href="http://www.piercefuller.com/library/pb250.html"&gt;Packard Bell 250&lt;/a&gt;, where the memory elements were &lt;a href="http://en.wikipedia.org/wiki/Delay_line_memory"&gt;mercury delay lines&lt;/a&gt;.&lt;/p&gt;

&lt;p class=pp&gt;Question: Packard Bell?&lt;/p&gt;

&lt;p class=pp&gt;Doug: Packard Bell, same one that makes PCs today.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;40:10&lt;/span&gt;
They hung this off of the comp center 7090 and put in a scheme for quickly shipping jobs into the job stream on the 7090.  The Packard Bell was the real-time terminal that you could play with and repair stuff, ?...? off the 7090, get it back, and then you could play it.  From that grew some graphics machines also, built by ?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;40:41&lt;/span&gt;--&gt; et al.  And it was one of the old graphics machines
in fact that Ken picked up to build Unix on.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;40:55&lt;/span&gt;
Another thing that went on in the acoustics department was synthetic speech and music.  &lt;a href="http://csounds.com/mathews/index.html"&gt;Max Mathews&lt;/a&gt;, who was the the director of the department has long been interested in computer music.  In fact since retirement he spent a lot of time with Pierre Boulez in Paris at a wonderful institute with lots of money simply for making synthetic music.  He had a language called Music 5.  Synthetic speech or, well first of all simply speech processing was pioneered particularly by &lt;a href="http://en.wikipedia.org/wiki/John_Larry_Kelly,_Jr"&gt;John Kelly&lt;/a&gt;.  I remember my first contact with speech processing.  It was customary for computer operators, for the benefit of computer operators, to put a loudspeaker on the low bit of some register on the machine, and normally the operator would just hear kind of white noise.  But if you got into a loop, suddenly the machine would scream, and this signal could be used to the operator "oh the machines in a loop.  Go stop it and go on to the next job."  I remember feeding them an Ackermann's function routine once.  [laughter]  They were right.  It was a silly loop.  But anyway.  One day, the operators were ?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;42:48&lt;/span&gt;--&gt;.  The machine started singing.  Out of the blue.  ?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;42:54&lt;/span&gt;--&gt; from out of the blue.  [laughter]  And in a broad Texas accent, which was the recorded voice of John Kelly.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;43:14&lt;/span&gt;
However.  From there Kelly went on to do some speech synthesis.  Of course there's been a lot more speech synthesis work done since, by &lt;span style="font-size: 0.7em;"&gt;43:31&lt;/span&gt; folks like Cecil Coker, Joe Olive.  But they produced a record, which unfortunately I can't play because records are not modern anymore.  And everybody got one in the Bell Labs Record, which is a magazine, contained once a record from the acoustics department, with both speech and music and one very famous combination where the computer played and sang "A Bicycle Built For Two".&lt;/p&gt;

&lt;p class=pp&gt;?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;44:18&lt;/span&gt;--&gt;&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;44:32&lt;/span&gt;
At the same time as all this stuff is going on here, needless
to say computing is going on in the rest of the Labs.  it was about early 1960 when the math department lost its monopoly on computing machines and other people started buying them too, but for switching.  The first experiments with switching computers were operational in around 1960.  They were planned for several years prior to that; essentially as soon as the transistor was invented, the making of electronic rather than electromechanical switching machines was anticipated.  Part of the saga of the switching machines is cheap memory.  These machines had enormous memories -- thousands of words.  [laughter]  And it was said that the present worth of each word of memory that programmers saved across the Bell System was something like eleven dollars, as I recall.  And it was worthwhile to struggle to save some memory.  Also, programs were permanent.  You were going to load up the switching machine with switching program and that was going to run.  You didn't change it every minute or two.  And it would be cheaper to put it in read only memory than in core memory.  And there was a whole series of wild read-only memories, both tried and built.
The first experimental Essex System had a thing called the ?flying squat scoop store?&lt;!--&lt;span style="font-size: 0.7em;"&gt;46:44&lt;/span&gt;--&gt;
which was large photographic plates with bits on them and CRTs projecting on the plates and you would detect underneath on the photodetector whether the bit was set or not.  That was the program store of Essex.  The program store of the first ESS systems consisted of twisters, which I actually am not sure I understand to this day, but they consist of iron wire with a copper wire wrapped around them and vice versa.  There were also experiments with an IC type memory called the waffle iron.  Then there was a period when magnetic bubbles were all the rage.  As far as I know, although microelectronics made a lot of memory, most of the memory work at Bell Labs has not had much effect on ?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;48:13&lt;/span&gt;--&gt;.  Nice tries though.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;48:28&lt;/span&gt;
Another thing that folks began to work on was the application of (and of course, right from the start) computers to data processing.  When you owned equipment scattered through every street in the country, and you have a hundred million customers, and you have bills for a hundred million transactions a day, there's really some big data processing going on.  And indeed in the early 60s, AT&amp;T was thinking of making its own data processing computers solely for billing.  Somehow they pulled out of that, and gave all the technology to IBM, and one piece of that technology went into use in high end equipment called tractor tapes.  Inch wide magnetic tapes that would be used for a while.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;49:50&lt;/span&gt;
By in large, although Bell Labs has participated until fairly recently in data processing in quite a big way, AT&amp;T never really quite trusted the Labs to do it right because here is where the money is.  I can recall one occasion when during strike of temporary employees, a fill-in employee like from the
Laboratories and so on, lost a day's billing tape in Chicago.  And that was a million dollars.  And that's generally speaking the money people did not until fairly recently trust Bell Labs to take good care of money, even though they trusted the Labs very well to make extremely reliable computing equipment for switches.
The downtime on switches is still spectacular by any industry standards.  The design for the first ones was two hours down in 40 years, and the design was met.  Great emphasis on reliability and redundancy, testing.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;51:35&lt;/span&gt;
Another branch of computing was for the government.  The whole Whippany Laboratories [time check]
Whippany, where we took on contracts for the government particularly in the computing era in anti-missile defense, missile defense, and underwater sound.  Missile defense was a very impressive undertaking.  It was about in the early '63 time frame when it was estimated the amount of computation to do a reasonable job of tracking incoming missiles would be 30 M floating point operations a second.  In the day of the Cray that doesn't sound like a great lot, but it's more than your high end PCs can do.  And the machines were supposed to be reliable.  They designed the machines at Whippany, a twelve-processor multiprocessor, to no specs, enormously rugged, one watt transistors.  This thing in real life performed remarkably well.  There were sixty-five missile shots, tests across the Pacific Ocean ?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;53:18&lt;/span&gt;--&gt;  and Lorinda Cherry here actually sat there waiting for them to come in.  [laughter]  And only a half dozen of them really failed.  As a measure of the interest in reliability, one of them failed apparently due to processor error.  Two people were assigned to look at the dumps, enormous amounts of telemetry and logging information were taken during these tests, which are truly expensive to run.  Two people were assigned to look at the dumps.  A year later they had not found the trouble.  The team was beefed up.  They finally decided that there was a race condition in one circuit.  They then realized that this particular kind of race condition had not been tested for in all the simulations.  They went back and simulated the entire hardware system to see if its a remote possibility of any similar cases, found twelve of them, and changed the hardware.  But to spend over a year looking for a bug is a sign of what reliability meant.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;54:56&lt;/span&gt;
Since I'm coming up on the end of an hour, one could go on and on and on,&lt;/p&gt;

&lt;p class=pp&gt;Crowd: go on, go on. [laughter]&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;55:10&lt;/span&gt;
Doug: I think I'd like to end up by mentioning a few of the programs that have been written at Bell Labs that I think are most surprising.  Of course there are lots of grand programs that have been written.&lt;/p&gt;

&lt;p class=pp&gt;I already mentioned the block diagram compiler.&lt;/p&gt;

&lt;p class=pp&gt;Another really remarkable piece of work was &lt;a href="http://cm.bell-labs.com/cm/cs/doc/74/eqn.ps.gz"&gt;eqn&lt;/a&gt;, the equation
typesetting language, which has been imitated since, by Lorinda Cherry and Brian Kernighan.  The notion of taking an auditory syntax, the way people talk about equations, but only talk, this was not borrowed from any written notation before, getting the auditory one down on paper, that was very successful and surprising.&lt;/p&gt;

&lt;p class=pp&gt;Another of my favorites, and again Lorinda Cherry was in this one, with Bob Morris, was typo.  This was a program for finding spelling errors.  It didn't know the first thing about spelling.  It would read a document, measure its statistics, and print out the words of the document in increasing order of what it thought the likelihood of that word having come from the same statistical source as the document.  The words that did not come from the statistical source of the document were likely to be typos, and now I mean typos as distinct from spelling errors, where you actually hit the wrong key.  Those tend to be off the wall, whereas phonetic spelling errors you'll never find.  And this worked remarkably well.  Typing errors would come right up to the top of the list.  A really really neat program.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;57:50&lt;/span&gt;
Another one of my favorites was by Brenda Baker called &lt;a href="http://doi.acm.org/10.1145/800168.811545"&gt;struct&lt;/a&gt;, which took Fortran programs and converted them into a structured programming language called Ratfor, which was Fortran with C syntax.  This seemed like a possible undertaking, like something you do by the seat of the pants and you get something out.  In fact, folks at Lockheed had done things like that before.  But Brenda managed to find theorems that said there's really only one form, there's a canonical form into which you can structure a Fortran program, and she did this.  It took your Fortran program, completely mashed it, put it out perhaps in almost certainly a different order than it was in Fortran connected by GOTOs, without any GOTOs, and the really remarkable thing was that authors of the program who clearly knew the way they wrote it in the first place, preferred it after it had been rearranged by Brendan.  I was astonished at the outcome of that project.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;59:19&lt;/span&gt;
Another first that happened around here was by Fred Grampp, who got interested in computer security.  One day he decided he would make a program for sniffing the security arrangements on a computer, as a service: Fred would never do anything crooked.  [laughter]  This particular program did a remarkable job, and founded a whole minor industry within the company.  A department was set up to take this idea and parlay it, and indeed ever since there has been some improvement in the way computer centers are managed, at least until we got Berkeley Unix.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;60:24&lt;/span&gt;
And the last interesting program that I have time to mention is one by &lt;a href="http://research.microsoft.com/users/church/"&gt;Ken Church&lt;/a&gt;.  He was dealing with -- text processing has always been a continuing ?...?&lt;!--&lt;span style="font-size: 0.7em;"&gt;60:45&lt;/span&gt;--&gt; of the research, and in some sense it has an application to our business because we're handling speech, but he got into consulting with the department in North Carolina that has to translate manuals.  There are millions of pages of manuals in the Bell System and its successors, and ever since we've gone global, these things had to get translated into many languages.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;61:28&lt;/span&gt;
To help in this, he was making tools which would put up on the screen, graphed on the screen quickly a piece of text and its translation, because a translator, particularly a technical translator, wants to know, the last time we mentioned this word how was it translated.  You don't want to be creative in translating technical text.  You'd like to be able to go back into the archives and pull up examples of translated text.  And the neat thing here is the idea for how do you align texts in two languages.  You've got the original, you've got the translated one, how do you bring up on the screen, the two sentences that go together?  And the following scam worked beautifully.  This is on western languages.  &lt;span style="font-size: 0.7em;"&gt;62:33&lt;/span&gt;
Simply look for common four letter tetragrams, four letter combinations between the two and as best as you can, line them up as nearly linearly with the lengths of the two types as possible.  And this &lt;a href="http://acl.ldc.upenn.edu/W/W93/W93-0301.pdf"&gt;very simple idea&lt;/a&gt; works like storm.  Something for nothing.  I like that.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;63:10&lt;/span&gt;
The last thing is one slogan that sort of got started with Unix and is just rife within the industry now.  Software tools.  We were making software tools in Unix before we knew we were, just like the Molière character was amazed at discovering he'd been speaking prose all his life.  [laughter]  But then &lt;a href="http://www.amazon.com/-/dp/020103669X"&gt;Kernighan and Plauger&lt;/a&gt; came along and christened what was going on, making simple generally useful and compositional programs to do one thing and do it well and to fit together.  They called it software tools, made a book, wrote a book, and this notion now is abroad in the industry.  And it really did begin all up in the little attic room where you [points?] sat for many years writing up here.&lt;/p&gt;

&lt;p class=pp&gt; Oh I forgot to.  I haven't used any slides.  I've brought some, but I don't like looking at bullets and you wouldn't either, and I forgot to show you the one exhibit I brought, which I borrowed from Bob Kurshan.  When Bell Labs was founded, it had of course some calculating machines, and it had one wonderful computer.  This.  That was bought in 1918.  There's almost no other computing equipment from any time prior to ten years ago that still exists in Bell Labs.  This is an &lt;a href="http://infolab.stanford.edu/pub/voy/museum/pictures/display/2-5-Mechanical.html"&gt;integraph&lt;/a&gt;.  It has two styluses.  You trace a curve on a piece of paper with one stylus and the other stylus draws the indefinite integral here.  There was somebody in the math department who gave this service to the whole company, with about 24 hours turnaround time, calculating integrals.  Our recent vice president Arno Penzias actually did, he calculated integrals differently, with a different background.  He had a chemical balance, and he cut the curves out of the paper and weighed them.  This was bought in 1918, so it's eighty years old.  It used to be shiny metal, it's a little bit rusty now.  But it still works.&lt;/p&gt;

&lt;p class=pp&gt;&lt;span style="font-size: 0.7em;"&gt;66:30&lt;/span&gt;
Well, that's a once over lightly of a whole lot of things that have gone on at Bell Labs.  It's just such a fun place that one I said I just could go on and on.  If you're interested, there actually is a history written.  This is only one of about six volumes, &lt;a href="http://www.amazon.com/gp/product/0932764061"&gt;this&lt;/a&gt; is the one that has the mathematical computer sciences, the kind of things that I've mostly talked about here.  A few people have copies of them.  For some reason, the AT&amp;T publishing house thinks that because they're history they're obsolete, and they stopped printing them.  [laughter]&lt;/p&gt;

&lt;p class=pp&gt;Thank you, and that's all.&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://research.swtch.com/2008/04/computing-history-at-bell-labs.html' title='Computing History at Bell Labs'/><link rel='related' href='http://cm.bell-labs.com/cm/cs/doug97.html' title='Computing History at Bell Labs'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8082954141980125536&amp;postID=6991105448754243186' title='3 Comments'/><link rel='replies' type='application/atom+xml' href='http://research.swtch.com/feeds/6991105448754243186/comments/default' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/6991105448754243186'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/6991105448754243186'/><author><name>rsc</name><uri>http://www.blogger.com/profile/09576271159839887762</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-4022786913262539655</id><published>2008-04-04T12:38:00.002-04:00</published><updated>2008-04-04T12:44:39.659-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='theory'/><category scheme='http://www.blogger.com/atom/ns#' term='brute force'/><category scheme='http://www.blogger.com/atom/ns#' term='undecidability'/><title type='text'>Bigger Programs are Better, not Best</title><content type='html'>&lt;p class=pp&gt;
When computer scientists study algorithms, they are
interested in how much time or working space an algorithm
requires, as a function of the input size: quicksort
uses &lt;i&gt;O&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt; log &lt;i&gt;n&lt;/i&gt;) time, but only &lt;i&gt;O&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;) space.
For the most part, computer scientists don't study 
how much &lt;i&gt;code&lt;/i&gt; a problem requires.  In fact,
part of what it means to be an algorithm is that it can be
implemented as a fixed-size program that works regardless
of the input size.
Intuitively, though, bigger programs should
be able to do more than smaller programs.
&lt;/p&gt;

&lt;p class=pp&gt;
It is pretty easy to prove that bigger programs are better,
or at least that they can do more.
To start, we need to precisely define what we mean by
the size a program.  These kinds of discussions often
use Turing machines, but these days not many people are 
comfortable with Turing machines, so I'm going to use Scheme.
[&lt;a href="http://en.wikipedia.org/wiki/Irony_mark"&gt;؟&lt;/a&gt;]
&lt;/p&gt;

&lt;p class=pp&gt;
Let's define a Scheme program's &lt;i&gt;size&lt;/i&gt; to be the number of
left parentheses it contains.
We need to disallow arbitrarily large parenthesis-free expressions,
so that there are only a finite number of Scheme programs of a given size.
Let's limit functions to three arguments and 
integer literals to be numbers less than 100.
These requirements might make Scheme a little more verbose,
but they don't make it any less powerful.
Notice that these programs are just expressions that don't take any input.
&lt;/p&gt;

&lt;p class=pp&gt;
If we look at all the Scheme programs of a given size,
some of those programs evaluate to integers:
&lt;code&gt;(+ 1 (+ 2 3))&lt;/code&gt; has size 2 and evaluates to 6.
Let's define &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;) to be the largest integer that can be
produced by evaluating a Scheme program of size &lt;i&gt;n&lt;/i&gt;.
The example demonstrates that &lt;i&gt;B&lt;/i&gt;(3) is at least 6.
&lt;/p&gt;

&lt;p class=pp&gt;
The formal statement of the &amp;ldquo;bigger is better&amp;rdquo;
assertion is that &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;+1) &amp;gt; &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;) for any &lt;i&gt;n&lt;/i&gt;.
For any given &lt;i&gt;n&lt;/i&gt;, the definition of &lt;i&gt;B&lt;/i&gt; requires that
there be some Scheme program &lt;code&gt;e&lt;/code&gt; of size &lt;i&gt;n&lt;/i&gt; that 
evaluates to &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;).
Then &lt;code&gt;(+ 1 e)&lt;/code&gt; has size &lt;i&gt;n&lt;/i&gt;+1 and evaluates to 1+&lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;).
This demonstrates that &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;+1) is at least 1+&lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;), 
so &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;+1) &amp;gt; &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;).
&lt;/p&gt;

&lt;p class=pp&gt;
There you have it.  Bigger programs are better.
But it turns out that no matter how big a program
you write, it can't compute &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;).
&lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;) gets so big so fast that no fixed-size program can keep up.
We can prove this too.
&lt;/p&gt;

&lt;p class=pp&gt;
Consider any Scheme function &lt;code&gt;f&lt;/code&gt; that takes a single integer argument.
This is a lambda expression, not a standalone program like we've been
considering, but it still has some size &lt;i&gt;s&lt;/i&gt;.
Define &lt;i&gt;n&lt;/i&gt; = 2&lt;i&gt;s&lt;/i&gt;+1.
We can write a Scheme program &lt;code&gt;n1&lt;/code&gt;, also of size &lt;i&gt;s&lt;/i&gt;,
that computes 2&lt;i&gt;s&lt;/i&gt;+2 = &lt;i&gt;n&lt;/i&gt;+1.  The program looks like
&lt;code&gt;(+ 2 (+ 2 ... (+ 2 (+ 2 2)) ...))&lt;/code&gt;.
Now consider the Scheme program &lt;code&gt;(f n1)&lt;/code&gt;,
wihch has size &lt;i&gt;s&lt;/i&gt;+&lt;i&gt;s&lt;/i&gt;+1 = &lt;i&gt;n&lt;/i&gt;.
Since it has size &lt;i&gt;n&lt;/i&gt;, it cannot compute a number bigger than &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;).
The value of the argument to &lt;code&gt;f&lt;/code&gt; is &lt;i&gt;n&lt;/i&gt;+1, 
and &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;+1) &amp;gt; &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;), so
&lt;code&gt;f&lt;/code&gt; cannot be computing &lt;i&gt;B&lt;/i&gt;.
Essentially, &lt;i&gt;B&lt;/i&gt; grows faster than any function you can implement in Scheme.*
&lt;/p&gt;

&lt;p class=pp&gt;
There you have it.  The function &lt;i&gt;B&lt;/i&gt; cannot be computed.
Bigger has bested the computer.
&lt;/p&gt;

&lt;p class=pp&gt;
The original presentation of this result is
Tibor Rado's 1962 paper &amp;ldquo;&lt;a href="http://pdos.csail.mit.edu/~rsc/rado62beaver.pdf"&gt;&lt;b&gt;On Non-Computable Functions&lt;/b&gt;&lt;/a&gt;&amp;rdquo; (PDF, 320kB),
which appeared in the Bell System Technical Journal.
Rado used Turing machines, not Scheme programs,
and called the function &lt;i&gt;Σ&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;), not &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;).
He also defined a function &lt;i&gt;S&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;) which is the maximum
length of any computation by a Turing machine of size &lt;i&gt;n&lt;/i&gt;
that eventually stops.
Rado made a game of trying to make Turing machines
of a given size that ran for as long as possible (but stopped),
and he called it the &amp;ldquo;Busy Beaver game.&amp;rdquo;
&lt;/p&gt;

&lt;p class=pp&gt;
The function Σ is sometimes called the Busy Beaver function,
leading to a slew of papers by 
otherwise respectable computer scientists and mathematicians
&lt;a href="http://www.google.com/search?&amp;q=busy-beaver+turing+machine"&gt;about busy beavers&lt;/a&gt;.
In particular, a favorite pastime is to attempt to compute
&lt;i&gt;Σ&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;) and &lt;i&gt;S&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;) by hand, for small values of &lt;i&gt;n&lt;/i&gt;.
This requires analyzing all possible Turing machines
of the given size to figure out
whether each eventually stops, and if so, how long it runs 
and what number it prints.
&lt;/p&gt;

&lt;p class=pp&gt;
Using a computer to analyze the easy machines
and then doing the hard ones by hand,
Rado and his student Shen Lin
proved that &lt;i&gt;Σ&lt;/i&gt;(1) = 1, &lt;i&gt;S&lt;/i&gt;(1) = 1, &lt;i&gt;Σ&lt;/i&gt;(2) = 4, and &lt;i&gt;S&lt;/i&gt;(2) = 6
in their 1965 paper &amp;ldquo;&lt;a href="http://doi.acm.org.libproxy.mit.edu/10.1145/321264.321270"&gt;Computer Studies of Turing Machine Problems&lt;/a&gt;&amp;rdquo; (subscription required).
Lin proved in his Ph.D. thesis that &lt;i&gt;Σ&lt;/i&gt;(3) = 6 and &lt;i&gt;S&lt;/i&gt;(3) = 21.
In 1983, Allen Brady proved that &lt;i&gt;Σ&lt;/i&gt;(4) = 13 and &lt;i&gt;S&lt;/i&gt;(4) = 107.
&lt;/p&gt;

&lt;p class=pp&gt;
Rona Machlin and Quentin Stout summarized the situation
nicely in their 1990 paper &amp;ldquo;&lt;a href="http://www.eecs.umich.edu/~qstout/abs/busyb.html"&gt;The Complex Behavior Of Simple Machines&lt;/a&gt;:&amp;rdquo;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p class=lp&gt;
 Brady predicted that there
 will never be a proof of the values of &lt;i&gt;Σ&lt;/i&gt;(5) and &lt;i&gt;S&lt;/i&gt;(5).
 We are just slightly more optimistic, and are
 lead to recast a parable due to Erdös (who spoke
 in the context of determining Ramsey numbers):
 suppose a vastly superior alien force lands and announces
 that they will destroy the planet unless we provide
 a value of the S function, along with a proof of its 
 correctness.  If they ask for &lt;i&gt;S&lt;/i&gt;(5) we should put all
 of our mathematicians, computer scientists, and
 computers to the task, but if they ask for &lt;i&gt;S&lt;/i&gt;(6) we should
 immediately attack because the task is hopeless.
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p class=pp&gt;
Michiel Wijers has a &lt;a href="http://www.win.tue.nl/~wijers/bb-index.htm"&gt;good bibliography&lt;/a&gt;.
Allen Brady has recently been
exploring &lt;a href="http://www.cse.unr.edu/~al/BusyBeaver.html"&gt;ternary
Turing machines&lt;/a&gt;.
&lt;/p&gt;
&lt;br&gt;

&lt;p class=lp&gt;
&lt;span style="font-size: 0.8em"&gt;* It doesn't matter that we used Scheme and Rado used Turing machines,
because Scheme can simulate a Turing machine and vice versa.
In fact, so far no feasible computational model has yet been found
that can't be simulated by a Turing machine (or, by extension, by Scheme).
The &lt;a href="http://en.wikipedia.org/wiki/Church-Turing_thesis"&gt;Church-Turing
thesis&lt;/a&gt; is the name for the hypothesis that anything we would
reasonably consider computable can be computed by a Turing machine
(or lambda calculus or a general-recursive function, both of which are equivalent).
The exact details of what you can do with a given size differs
from model to model, but the net result is the same:
even a Turing machine can't compute our Scheme-based &lt;i&gt;B&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;).
The result would work for any modern programming language,
but Scheme makes the proofs particularly elegant.&lt;/span&gt;
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://research.swtch.com/2008/04/bigger-programs-are-better-not-best.html' title='Bigger Programs are Better, not Best'/><link rel='related' href='http://pdos.csail.mit.edu/%7Ersc/rado62beaver.pdf' title='Bigger Programs are Better, not Best'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8082954141980125536&amp;postID=4022786913262539655' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://research.swtch.com/feeds/4022786913262539655/comments/default' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/4022786913262539655'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/4022786913262539655'/><author><name>rsc</name><uri>http://www.blogger.com/profile/09576271159839887762</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-4899162289618563697</id><published>2008-04-02T07:09:00.003-04:00</published><updated>2008-04-02T07:15:17.035-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='recursion'/><category scheme='http://www.blogger.com/atom/ns#' term='Knuth'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><title type='text'>Alphabetical Order</title><content type='html'>&lt;p class=lp&gt;A reading from the &lt;a href="http://www-cs-faculty.stanford.edu/~knuth/taocp.html"&gt;&lt;b&gt;Book of Knuth, Chapter 6&lt;/b&gt;&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p class=lp&gt;The use of alphabetic order for entire words seems to be a much later invention;  it is something we might think is obvious, yet it has to be taught to children, and at some point in history it was necessary to teach to adults.  Several lists from about  300 B.C. have been found on the Aegean Islands, giving the names of people in certain religious cults; these lists have been alphabetized, but only by first letter, thus representing only the first pass of a left-to-right radix sort.  Some Greek papyri from the years A.D. 134-135 contain fragments of ledgers that show the names of taxpayers alphabetized by the first two letters.  Apollonius Sophista used alphabetical order on the first two letters, and often on subsequent letters, in his lengthy concordance of Homer's poetry (first century A.D.). A few examples of more perfect alphabetization are known, notably Galen's &lt;i&gt;Hippocratic Glosses&lt;/i&gt; (c. 200), but they are very rare.  Words were arranged by their first letter only in the &lt;i&gt;Etymologiarum&lt;/i&gt; of St. Isidorus (c. 630, Book x); and the &lt;i&gt;Corpus Glossary&lt;/i&gt; (c. 725) used only the first two letters of each word. The latter two works were perhaps the largest nonnumerical files of data to be compiled during the Middle Ages.&lt;/p&gt;  &lt;p class=pp&gt;It is not until Giovanni di Genoa's &lt;i&gt;Catholicon&lt;/i&gt; (1286) that we find a specific description of true alphabetical order.  In his preface, Giovanni explained that&lt;/p&gt;  
&lt;center&gt;&lt;table&gt; &lt;tr&gt;&lt;td align=right&gt;&lt;/td&gt;&lt;td width=5&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td width=5&gt;&lt;/td&gt;&lt;td align=left&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;i&gt;amo&lt;/i&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;precedes &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;i&gt;bibo&lt;/i&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;i&gt;abeo&lt;/i&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;precedes &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;i&gt;adeo&lt;/i&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;i&gt;amatus&lt;/i&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;precedes &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;i&gt;amor&lt;/i&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;i&gt;imprudens&lt;/i&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;precedes &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;i&gt;impudens&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;i&gt;iustica&lt;/i&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;precedes &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;i&gt;iustus&lt;/i&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;i&gt;polisintheton&lt;/i&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;precedes &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;i&gt;polissenus&lt;/i&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;/center&gt;  &lt;p class=lp&gt;(thereby giving examples of situations in which the ordering is determined by the 1st, 2nd, ..., 6th letters), &amp;ldquo;and so on in like manner.&amp;rdquo;  He remarked that strenuous effort was required to device these rules. &amp;ldquo;I beg of you, therefore, good reader, do not scorn this great labor of  mine and this order as something worthless.&amp;rdquo;&lt;/p&gt;  &lt;p class=pp&gt;A detailed study of the development of alphabetic order, up to the time printing was invented, has been made by Lloyd W. Daly [&lt;i&gt;Collection Latomus&lt;/i&gt; &lt;b&gt;90&lt;/b&gt; (1967), 100 pages]. He found some interesting old manuscripts that were evidently used as worksheets while sorting words by their first letters (see pages 89-90 of his monograph).&lt;/p&gt;  &lt;p class=pp&gt;The first dictionary of English, Robert Cawdrey's &lt;i&gt;Table Alphabeticall&lt;/i&gt; (London, 1604),  contains the following instructions:&lt;/p&gt;  &lt;blockquote&gt;&lt;p class=lp&gt; Nowe if the word, which thou art desirous to finde, beginne with (a) then looke in the beginning of this Table, but if with (v) looke toward the end.  Again, if they word beginne with (ca) looke in the beginning of the letter (c) but if with (cu) then looke toward the end of that letter.  And so on of all the rest.  &amp;amp;c.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p class=lp&gt;Cawdrey seems to have been teaching &lt;i&gt;himself&lt;/i&gt; how to alphabetize as he prepared  his dictionary; numerous misplaced words appear on the first few pages, but the alphabetic order in the last part is not as bad.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p class=lp&gt;Volume 3 / &lt;i&gt;Sorting and Searching&lt;/i&gt;, 2nd Ed., p. 421&lt;/p&gt; &lt;p class=pp&gt;I've written &lt;a href="http://research.swtch.com/2008/02/elegance-and-power.html"&gt;before&lt;/a&gt; about how thinking recursively, something most of us take for granted, is in fact something that must be taught (or discovered).   I wonder if alphabetical order took so long to catch on because it is a recursive procedure.&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://research.swtch.com/2008/04/alphabetical-order.html' title='Alphabetical Order'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8082954141980125536&amp;postID=4899162289618563697' title='2 Comments'/><link rel='replies' type='application/atom+xml' href='http://research.swtch.com/feeds/4899162289618563697/comments/default' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/4899162289618563697'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/4899162289618563697'/><author><name>rsc</name><uri>http://www.blogger.com/profile/09576271159839887762</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-3668767728352742358</id><published>2008-03-14T10:09:00.006-04:00</published><updated>2008-03-15T14:05:39.328-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data structures'/><category scheme='http://www.blogger.com/atom/ns#' term='bit twiddling'/><title type='text'>Using Uninitialized Memory for Fun and Profit</title><content type='html'>&lt;p class=lp&gt;
This is the story of a clever trick that's been around for
at least 35 years, in which array values can be left
uninitialized and then read during normal operations,
yet the code behaves correctly no matter what garbage
is sitting in the array.
Like the best programming tricks, this one is the right tool for the 
job in certain situations.
The sleaziness of uninitialized data
access is offset by performance improvements:
some important operations change from linear 
to constant time.
&lt;/p&gt;

&lt;p class=pp&gt;
Alfred Aho, John Hopcroft, and Jeffrey Ullman's 1974 book 
&lt;i&gt;The Design and Analysis of Computer Algorithms&lt;/i&gt;
hints at the trick in an exercise (Chapter 2, exercise 2.12):
&lt;/p&gt;

&lt;blockquote&gt;
Develop a technique to initialize an entry of a matrix to zero
the first time it is accessed, thereby eliminating the &lt;i&gt;O&lt;/i&gt;(||&lt;i&gt;V&lt;/i&gt;||&lt;sup&gt;2&lt;/sup&gt;) time
to initialize an adjacency matrix.
&lt;/blockquote&gt;

&lt;p class=lp&gt;
Jon Bentley's 1986 book &lt;a href="http://www.cs.bell-labs.com/cm/cs/pearls/"&gt;&lt;i&gt;Programming Pearls&lt;/i&gt;&lt;/a&gt; expands
on the exercise (Column 1, exercise 8; &lt;a href="http://www.cs.bell-labs.com/cm/cs/pearls/sec016.html"&gt;exercise 9&lt;/a&gt; in the Second Edition):
&lt;/p&gt;

&lt;blockquote&gt;
One problem with trading more space for less time is that 
initializing the space can itself take a great deal of time.
Show how to circumvent this problem by designing a technique
to initialize an entry of a vector to zero the first time it is
accessed.  Your scheme should use constant time for initialization
and each vector access; you may use extra space proportional
to the size of the vector.  Because this method reduces 
initialization time by using even more space, it should be
considered only when space is cheap, time is dear, and 
the vector is sparse.
&lt;/blockquote&gt;

&lt;p class=lp&gt;
Aho, Hopcroft, and Ullman's exercise talks about a matrix and 
Bentley's exercise talks about a vector, but for now let's consider
just a simple set of integers.
&lt;/p&gt;

&lt;p class=pp&gt;
One popular representation of a set of &lt;i&gt;n&lt;/i&gt; integers ranging
from 0 to &lt;i&gt;m&lt;/i&gt; is a bit vector, with 1 bits at the
positions corresponding to the integers in the set.
Adding a new integer to the set, removing an integer
from the set, and checking whether a particular integer
is in the set are all very fast constant-time operations
(just a few bit operations each).
Unfortunately, two important operations are slow:
iterating over all the elements in the set 
takes time &lt;i&gt;O&lt;/i&gt;(&lt;i&gt;m&lt;/i&gt;), as does clearing the set.
If the common case is that 
&lt;i&gt;m&lt;/i&gt; is much larger than &lt;i&gt;n&lt;/i&gt;
(that is, the set is only sparsely
populated) and iterating or clearing the set 
happens frequently, then it could be better to
use a representation that makes those operations
more efficient.  That's where the trick comes in.
&lt;/p&gt;

&lt;p class=pp&gt;
Preston Briggs and Linda Torczon's 1993 paper,
&amp;ldquo;&lt;a href="http://citeseer.ist.psu.edu/briggs93efficient.html"&gt;&lt;b&gt;An Efficient Representation for Sparse Sets&lt;/b&gt;&lt;/a&gt;,&amp;rdquo;
describes the trick in detail.
Their solution represents the sparse set using an integer
array named &lt;code&gt;dense&lt;/code&gt; and an integer &lt;code&gt;n&lt;/code&gt;
that counts the number of elements in &lt;code&gt;dense&lt;/code&gt;.
The &lt;i&gt;dense&lt;/i&gt; array is simply a packed list of the elements in the
set, stored in order of insertion.
If the set contains the elements 5, 1, and 4, then &lt;code&gt;n = 3&lt;/code&gt; and
&lt;code&gt;dense[0] = 5&lt;/code&gt;, &lt;code&gt;dense[1] = 1&lt;/code&gt;, &lt;code&gt;dense[2] = 4&lt;/code&gt;:
&lt;/p&gt;

&lt;center&gt;
&lt;img src="http://bp2.blogger.com/_9P3HFEQk8wo/R9f1Wk5blBI/AAAAAAAAAGA/4bMoSK1-H14/s400/sparse0.png" /&gt;
&lt;/center&gt;

&lt;p class=pp&gt;
Together &lt;code&gt;n&lt;/code&gt; and &lt;code&gt;dense&lt;/code&gt; are
enough information to reconstruct the set, but this representation
is not very fast.
To make it fast, Briggs and Torczon
add a second array named &lt;code&gt;sparse&lt;/code&gt;
which maps integers to their indices in &lt;code&gt;dense&lt;/code&gt;.
Continuing the example,
&lt;code&gt;sparse[5] = 0&lt;/code&gt;, &lt;code&gt;sparse[1] = 1&lt;/code&gt;, 
&lt;code&gt;sparse[4] = 2&lt;/code&gt;.
Essentially, the set is a pair of arrays that point at
each other:
&lt;/p&gt;

&lt;center&gt;
&lt;img src="http://bp0.blogger.com/_9P3HFEQk8wo/R9f1XE5blCI/AAAAAAAAAGI/nqY6ebL-DsQ/s400/sparse0b.png" /&gt;
&lt;/center&gt;

&lt;p class=pp&gt;
Adding a member to the set requires updating both of these arrays:
&lt;/p&gt;

&lt;pre class=indent&gt;
add-member(i):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dense[n] = i
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sparse[i] = n
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n++
&lt;/pre&gt;

&lt;p class=lp&gt;
It's not as efficient as flipping a bit in a bit vector, but it's 
still very fast and constant time. 
&lt;/p&gt;

&lt;p class=pp&gt;
To check whether &lt;code&gt;i&lt;/code&gt; is in the set, you verify that
the two arrays point at each other for that element:
&lt;/p&gt;

&lt;pre class=indent&gt;
is-member(i):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return sparse[i] &amp;lt; n &amp;&amp; dense[sparse[i]] == i
&lt;/pre&gt;

&lt;p class=lp&gt;
If &lt;code&gt;i&lt;/code&gt; is not in the set, then &lt;i&gt;it doesn't matter what &lt;code&gt;sparse[i]&lt;/code&gt; is set to&lt;/i&gt;:
either &lt;code&gt;sparse[i]&lt;/code&gt;
will be bigger than &lt;code&gt;n&lt;/code&gt; or it will point at a value in 
&lt;code&gt;dense&lt;/code&gt; that doesn't point back at it.
Either way, we're not fooled.  For example, suppose &lt;code&gt;sparse&lt;/code&gt;
actually looks like:
&lt;/p&gt;

&lt;center&gt;
&lt;img src="http://bp2.blogger.com/_9P3HFEQk8wo/R9f1Xk5blDI/AAAAAAAAAGQ/1CQpUE-qxRg/s400/sparse1.png" /&gt;
&lt;/center&gt;

&lt;p class=lp&gt;
&lt;code&gt;Is-member&lt;/code&gt; knows to ignore
members of sparse that point past &lt;code&gt;n&lt;/code&gt; or that
point at cells in &lt;code&gt;dense&lt;/code&gt; that don't point back,
ignoring the grayed out entries:

&lt;center&gt;
&lt;img src="http://bp2.blogger.com/_9P3HFEQk8wo/R9f1Xk5blEI/AAAAAAAAAGY/8Kn2v9GAtdw/s400/sparse2.png" /&gt;
&lt;/center&gt;

&lt;p class=pp&gt;
Notice what just happened:
&lt;code&gt;sparse&lt;/code&gt; can have &lt;i&gt;any arbitrary values&lt;/i&gt; in
the positions for integers not in the set, 
those values actually get used during membership
tests, and yet the membership test behaves correctly!
(This would drive &lt;a href="http://valgrind.org/"&gt;valgrind&lt;/a&gt; nuts.)
&lt;/p&gt;

&lt;p class=pp&gt;
Clearing the set can be done in constant time:
&lt;/p&gt;
&lt;pre class=indent&gt;
clear-set():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n = 0
&lt;/pre&gt;

&lt;p class=lp&gt;
Zeroing &lt;code&gt;n&lt;/code&gt; effectively clears 
&lt;code&gt;dense&lt;/code&gt; (the code only ever accesses
entries in dense with indices less than &lt;code&gt;n&lt;/code&gt;), and
&lt;code&gt;sparse&lt;/code&gt; can be uninitialized, so there's no 
need to clear out the old values.
&lt;/p&gt;

&lt;p class=pp&gt;
This sparse set representation has one more trick up its sleeve:
the &lt;code&gt;dense&lt;/code&gt; array allows an 
efficient implementation of set iteration.
&lt;/p&gt;

&lt;pre class=indent&gt;
iterate():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for(i=0; i&amp;lt;n; i++)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yield dense[i]
&lt;/pre&gt;

&lt;p class=pp&gt;
Let's compare the run times of a bit vector 
implementation against the sparse set:
&lt;/p&gt;
&lt;center&gt;
&lt;table&gt;
&lt;tr&gt;
  &lt;td&gt;&lt;i&gt;Operation&lt;/i&gt;
  &lt;td align=center width=10&gt;
  &lt;td align=center&gt;&lt;i&gt;Bit Vector&lt;/i&gt;
  &lt;td align=center width=10&gt;
  &lt;td align=center&gt;&lt;i&gt;Sparse set&lt;/i&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;is-member
  &lt;td&gt;
  &lt;td align=center&gt;&lt;i&gt;O&lt;/i&gt;(1)
  &lt;td&gt; 
  &lt;td align=center&gt;&lt;i&gt;O&lt;/i&gt;(1)
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;add-member
  &lt;td&gt;
  &lt;td align=center&gt;&lt;i&gt;O&lt;/i&gt;(1)
  &lt;td&gt;
  &lt;td align=center&gt;&lt;i&gt;O&lt;/i&gt;(1)
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;clear-set
  &lt;td&gt;&lt;td align=center&gt;&lt;i&gt;O&lt;/i&gt;(&lt;i&gt;m&lt;/i&gt;)
  &lt;td&gt;&lt;td align=center&gt;&lt;i&gt;O&lt;/i&gt;(1)
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;iterate
  &lt;td&gt;&lt;td align=center&gt;&lt;i&gt;O&lt;/i&gt;(&lt;i&gt;m&lt;/i&gt;)
  &lt;td&gt;&lt;td align=center&gt;&lt;i&gt;O&lt;/i&gt;(&lt;i&gt;n&lt;/i&gt;)
&lt;/tr&gt;
&lt;/table&gt;
&lt;/center&gt;

&lt;p class=lp&gt;
The sparse set is as fast or faster than bit vectors for
every operation.  The only problem is the space cost:
two words replace each bit.
Still, there are times when the speed differences are enough
to balance the added memory cost.
Briggs and Torczon point out that liveness sets used 
during register allocation inside a compiler are usually
small and are cleared very frequently, making sparse sets the
representation of choice.
&lt;/p&gt;

&lt;p class=pp&gt;
Another situation where sparse sets are the better choice
is work queue-based graph traversal algorithms.
Iteration over sparse sets visits elements
in the order they were inserted (above, 5, 1, 4),
so that new entries inserted during the iteration
will be visited later in the same iteration.
In contrast, iteration over bit vectors visits elements in
integer order (1, 4, 5), so that new elements inserted
during traversal might be missed, requiring repeated
iterations.
&lt;/p&gt;

&lt;p class=pp&gt;
Returning to the original exercises, it is trivial to change
the set into a vector (or matrix) by making &lt;code&gt;dense&lt;/code&gt;
an array of index-value pairs instead of just indices.
Alternately, one might add the value to the &lt;code&gt;sparse&lt;/code&gt;
array or to a new array.
The relative space overhead isn't as bad if you would have been
storing values anyway.
&lt;/p&gt;

&lt;p class=pp&gt;
Briggs and Torczon's paper implements additional set
operations and examines performance speedups from
using sparse sets inside a real compiler.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://research.swtch.com/2008/03/using-uninitialized-memory-for-fun-and.html' title='Using Uninitialized Memory for Fun and Profit'/><link rel='related' href='http://citeseer.ist.psu.edu/briggs93efficient.html' title='Using Uninitialized Memory for Fun and Profit'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8082954141980125536&amp;postID=3668767728352742358' title='19 Comments'/><link rel='replies' type='application/atom+xml' href='http://research.swtch.com/feeds/3668767728352742358/comments/default' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/3668767728352742358'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/3668767728352742358'/><author><name>rsc</name><uri>http://www.blogger.com/profile/09576271159839887762</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-2288629476712959755</id><published>2008-03-12T08:01:00.003-04:00</published><updated>2008-03-12T11:50:04.137-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data structures'/><category scheme='http://www.blogger.com/atom/ns#' term='bit twiddling'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><title type='text'>Rotating Hashes</title><content type='html'>&lt;p class=lp&gt;
Long ago, before hash tables (aka scatter storage files) 
were a fundamental data type like &lt;code&gt;int&lt;/code&gt;,
programmers had to implement them by hand.  (Nowadays, manually-implemented
hash tables are rarely seen outside of historical reenactments like undergraduate
algorithms classes and C programs.)
Back then, there was fierce debate about how to handle hash collisions. 
&lt;/p&gt;

&lt;p class=pp&gt;
One option, called direct chaining, makes each table slot a linked list head,
and then all the entries that hash to that slot are kept in the linked list
pointed to by the slot.  (Bonus points if you reorder the lists using the
&lt;a href="http://www.nist.gov/dads/HTML/movefront.html"&gt;move to front heuristic&lt;/a&gt;.)
&lt;/p&gt;

&lt;p class=pp&gt;
Another option, called linear scanning or open addressing, is to try table entry &lt;i&gt;h&lt;/i&gt;, and then if
that is full, try &lt;i&gt;h&lt;/i&gt;+1, &lt;i&gt;h&lt;/i&gt;+2, and so on until an empty slot is found.
This only works well if the table is sized so that it has some large
fraction (say, 1/4) of unused slots.
&lt;/p&gt;

&lt;p class=pp&gt;
Direct chaining and linear scanning are still the most common 
collision resolution methods, but in the 1960s, more were explored.
Still another option is to use non-linear scanning, so that each
data item produces a sequence of hash values &lt;i&gt;h&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;, &lt;i&gt;h&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;, &lt;i&gt;h&lt;/i&gt;&lt;sub&gt;3&lt;/sub&gt;, and those
table slots are tried in turn.  Two objects with the same &lt;i&gt;h&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt; won't necessarily 
have the same &lt;i&gt;h&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;, unlike in linear scanning.  But hashing is a relatively
slow operation.  Is it worth the time and code to compute all those extra hash
functions?
&lt;/p&gt;

&lt;p class=pp&gt;
This sets the stage for Doug McIlroy's 1963 &lt;b&gt;&lt;a href="http://doi.acm.org/10.1145/358141.358146"&gt;letter to the Communications
of the ACM Pracniques page&lt;/a&gt;&lt;/b&gt;, describing a trick by Vic Vyssotsky:
&lt;/p&gt;

&lt;blockquote&gt;
A VARIANT METHOD OF FILE SEARCHING&lt;br&gt;&lt;br&gt;

&lt;p class=pp&gt;I would like to publicize a trick due to V. A. Vyssotsky for improving 
the efficiency of scatter storage files.&lt;/p&gt;

&lt;p class=pp&gt;
Vyssotsky's idea, used in a remarkably short and elegant code for
the IBM 7090, is to continue random searching after the first probe fails:
&lt;/p&gt;

&lt;p class=lp&gt;
 (1) From a data item, compute a pseudo-random address in the file.&lt;br&gt;
 (2) If the item is in this place, or if the place is empty, the job is done.&lt;br&gt;
 (3) If another item is there, probe again with a new address computed by
     another pseudo-random function, until the stock of pseudo-random functions
     has been exhausted.&lt;br&gt;
 (4) As a last resort, when all pseudo-random functions are exhausted, do a 
     linear search of the whole file for the item or a hole, whichever comes first.
&lt;/p&gt;

&lt;p class=pp&gt;
In Vyssotsky's program, the later random functions are trivially obtained from
the first one.  He computes an &lt;i&gt;n&lt;/i&gt;-bit function of which only the first
&lt;i&gt;m&lt;/i&gt; bits are used as an address.  Later, random addresses are obtained by rotating
the same &lt;i&gt;n&lt;/i&gt; bits.  After &lt;i&gt;n&lt;/i&gt; probes he gives up and resorts to linear search.
&lt;/p&gt;

&lt;p class=pp&gt;
More familiar methods of scatter storage employ chaning or linear search for
later probes.  Chaining is the most efficient method in terms of average number
of probes per item but pays a price in storage space for the chaining information.
Linear search is expensive in time.  Table I, comparing average number of probes
per item for these methods, is based on popular uniformity and independence assumptions:
&lt;/p&gt;

&lt;center&gt;
TABLE I.  Average Number of Probes per Item
&lt;table cellspacing=5&gt;
&lt;tr&gt;
  &lt;td align=center&gt;&lt;i&gt;&lt;font size=-1&gt;Load Factor&lt;/font&gt;&lt;/i&gt;
  &lt;td align=center&gt;&lt;i&gt;&lt;font size=-1&gt;Chaining [1]&lt;/font&gt;&lt;/i&gt;
  &lt;td align=center&gt;&lt;i&gt;&lt;font size=-1&gt;Linear Search [2]&lt;/font&gt;&lt;/i&gt;
  &lt;td align=center&gt;&lt;i&gt;&lt;font size=-1&gt;Random Search&lt;/font&gt;&lt;/i&gt;
&lt;tr&gt;
  &lt;td align=center&gt;p
  &lt;td align=center&gt;1 + p/2
  &lt;td align=center&gt;1 + ½p/(1-p)
  &lt;td align=center&gt;-p&lt;sup&gt;-1&lt;/sup&gt; log(1-p)
&lt;tr&gt;
  &lt;td align=center&gt;.50
  &lt;td align=center&gt;1.25
  &lt;td align=center&gt;1.5
  &lt;td align=center&gt;1.39
&lt;tr&gt;
  &lt;td align=center&gt;.75
  &lt;td align=center&gt;1.38
  &lt;td align=center&gt;2.5
  &lt;td align=center&gt;1.83
&lt;tr&gt;
  &lt;td align=center&gt;.90
  &lt;td align=center&gt;1.45
  &lt;td align=center&gt;5.5
  &lt;td align=center&gt;2.56
&lt;/table&gt;
&lt;/center&gt;

&lt;p class=pp&gt;
Chaining and random search have a clear edge.  If storage requirements permit, 
chaining is superior.  Vyssotsky's random search pays an attractively low time
penalty to achieve ultimate storage utilization in pressing situations.
&lt;/p&gt;

&lt;p class=pp&gt;
A typical 7090 application used a file of two-word items.
Chaining would add an extra word or, with extra coding 
complexity to handle items of nonintegral word length, 
an extra half word per item.  Table II compares lookup times
for various file schemes given a certain amount of storage:
&lt;/p&gt;

&lt;center&gt;
TABLE II.  Lookup Times for Various File Schemes
&lt;table cellspacing=5&gt;
&lt;tr&gt;
  &lt;td align=center&gt;&lt;i&gt;&lt;font size=-1&gt;Load Factor with&lt;br&gt;3-word items&lt;/font&gt;&lt;/i&gt;
  &lt;td align=center&gt;&lt;i&gt;&lt;font size=-1&gt;Chaining&lt;br&gt;3-word&lt;/font&gt;&lt;/i&gt;
  &lt;td align=center&gt;&lt;i&gt;&lt;font size=-1&gt;Chaining&lt;br&gt;2½-word&lt;/font&gt;&lt;/i&gt;
  &lt;td align=center&gt;&lt;i&gt;&lt;font size=-1&gt;Linear&lt;br&gt;2-word&lt;/font&gt;&lt;/i&gt;
  &lt;td align=center&gt;&lt;i&gt;&lt;font size=-1&gt;Random&lt;br&gt;2-word&lt;/font&gt;&lt;/i&gt;
&lt;tr&gt;
  &lt;td align=center&gt;0.6
  &lt;td align=center&gt;1.3
  &lt;td align=center&gt;1.25
  &lt;td align=center&gt;1.33
  &lt;td align=center&gt;1.30
&lt;tr&gt;
  &lt;td align=center&gt;0.8
  &lt;td align=center&gt;1.4
  &lt;td align=center&gt;1.33
  &lt;td align=center&gt;1.57
  &lt;td align=center&gt;1.49
&lt;tr&gt;
  &lt;td align=center&gt;1.0
  &lt;td align=center&gt;1.5
  &lt;td align=center&gt;1.42
  &lt;td align=center&gt;2.00
  &lt;td align=center&gt;1.65
&lt;tr&gt;
  &lt;td align=center&gt;1.2
  &lt;td align=center&gt;overflow
  &lt;td align=center&gt;1.50
  &lt;td align=center&gt;3.00
  &lt;td align=center&gt;2.01
&lt;tr&gt;
  &lt;td align=center&gt;1.4
  &lt;td align=center&gt;overflow
  &lt;td align=center&gt;overflow
  &lt;td align=center&gt;6.00
  &lt;td align=center&gt;2.90
&lt;/table&gt;
&lt;/center&gt;

&lt;p class=pp&gt;
References:
&lt;/p&gt;

&lt;p class=lp&gt;
1. Johnson, L. R.  Indirect chaining method for addressing on secondary keys.  &lt;i&gt;Comm. ACM 4&lt;/i&gt; (1961), 218-223.
&lt;/p&gt;

&lt;p class=lp&gt;
2. Schay, G. and Spruth, W. G.  Analysis of a file addressing method.  &lt;i&gt;Comm. ACM 5&lt;/i&gt; (1962), 459-462.
&lt;/p&gt;&lt;br&gt;

&lt;p class=lp&gt;
M. D. McIlroy&lt;br&gt;
&lt;i&gt;Bell Telephone Laboratories, Inc.&lt;br&gt;
Murray Hill, N. J.&lt;/i&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p class=lp&gt;(Posting may be intermittent for the rest of March.)&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://research.swtch.com/2008/03/rotating-hashes.html' title='Rotating Hashes'/><link rel='related' href='http://doi.acm.org/10.1145/358141.358146' title='Rotating Hashes'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8082954141980125536&amp;postID=2288629476712959755' title='5 Comments'/><link rel='replies' type='application/atom+xml' href='http://research.swtch.com/feeds/2288629476712959755/comments/default' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/2288629476712959755'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/2288629476712959755'/><author><name>rsc</name><uri>http://www.blogger.com/profile/09576271159839887762</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-4724086904328707635</id><published>2008-02-29T10:40:00.007-05:00</published><updated>2008-02-29T10:52:06.689-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='theory'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><title type='text'>Leaping Years and Drawing Lines</title><content type='html'>&lt;p class=lp&gt;
Some of the earliest mathematics was invented to design calendars.
Since the Earth rotates around its axis about 365.25 times per 
revolution around the sun, some years in a solar calendar need to be 365 days long and
others 366 days long in order to keep the calendar in sync with the sun.
The key challenge in designing a calendar is to find a
pattern of short and long years that achieve the desired approximation.
The Julian calendar uses the simple pattern of one leap
year every four years.
The Islamic calendar, which syncs against the moon, needs to have
years approximating 354.37 days per year.  To do this, it inserts
11 leap years over a 30 year cycle.
&lt;/p&gt;

&lt;p class=pp&gt;
Bresenham's algorithm chooses which pixels to
use when drawing a bitmap representation of a line. 
The basic idea, for a mostly horizontal line that angles upward,
is to move left to right, one pixel at a time, moving upward when
the distance between the actual y and the pixel-approximate y has grown too large.
&lt;/p&gt;

&lt;pre class=indent&gt;
drawline(dx, dy)    /* mostly horizontal line, upward line */
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x = 0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y = 0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error = 0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while (x &lt; dx || y &lt; dy)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drawpoint(x, y);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x++;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (x*(dy/dx) - y &gt; 0.5)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y++;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drawpoint(x, y);
&lt;/pre&gt;

&lt;p class=lp&gt;
For example, drawing a line 30 pixels long and 12 pixels high produces
&lt;/p&gt;

&lt;center&gt;
&lt;img class=center src="http://bp0.blogger.com/_9P3HFEQk8wo/R8gnyU7JrpI/AAAAAAAAAFI/1l_DLxf1wl4/s800/30x12.png" /&gt;
&lt;/center&gt;

&lt;p class=pp&gt;
In their 2004 paper &amp;ldquo;&lt;b&gt;&lt;a href="http://emr.cs.uiuc.edu/~reingold/bresenham.pdf"&gt;Line Drawing,
Leap Years, and Euclid&lt;/a&gt;&lt;/b&gt;&amp;rdquo; (PDF), 
Mitchell Harris and Edward Reingold show that the problem of choosing a leap year
pattern is a generalized version of Bresenham's line drawing problem.
This is surprising, but makes intuitive sense when you realize that both
are concerned with computing an integer approximation to a rational fraction
as evenly as possible.
Leap year computations are basically drawing a line with
slope 1/365.25 (or 1/364.37): each pixel is a day, and its y coordinate
determines which year it belongs to.
&lt;/p&gt;

&lt;p class=pp&gt;
Harris and Reingold go on to show that Euclid's algorithm can compute leap year patterns!
Euclid's algorithm usually computes the greatest common divisor of two numbers:
&lt;/p&gt;

&lt;pre class=indent&gt;
gcd(u, v)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while (u != v)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (u &gt; v)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;u = u mod v;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;v = v mod u;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return u;
&lt;/pre&gt;

&lt;p class=lp&gt;
The connection is that if you're trying to draw a line &lt;i&gt;dx&lt;/i&gt; by &lt;i&gt;dy&lt;/i&gt;
but &lt;i&gt;dx&lt;/i&gt; and &lt;i&gt;dy&lt;/i&gt; have some common divisor &lt;i&gt;d&lt;/i&gt;, then the Bresenham algorithm
will simply emit the pattern for a line &lt;i&gt;dx/d&lt;/i&gt; by &lt;i&gt;dy/d&lt;/i&gt;, &lt;i&gt;d&lt;/i&gt; times.
The example shown above can be viewed as two 15x6 lines, three 10x4 lines, or six 5x2 lines:
&lt;/p&gt;

&lt;center&gt;
&lt;img class=center src="http://bp3.blogger.com/_9P3HFEQk8wo/R8gnyE7JroI/AAAAAAAAAFA/3qdMECA84C4/s800/euclid.png" /&gt;
&lt;/center&gt;

&lt;p class=lp&gt;
Euclid's algorithm gives the largest possible &lt;i&gt;d&lt;/i&gt;, and you can adapt the algorithm to
build the associated repeating pattern while it computes &lt;i&gt;d&lt;/i&gt;.
&lt;/p&gt;

&lt;p class=pp&gt;
In &lt;a href="http://www-cs-faculty.stanford.edu/~knuth/taocp.html#vol2"&gt;Volume 2&lt;/a&gt;,
Donald Knuth calls it
&amp;ldquo;the granddaddy of all algorithms, because it is the oldest nontrivial algorithm that has survived to the present day.&amp;rdquo;  It also seems to have some famous children.
&lt;/p&gt;

&lt;br /&gt;
&lt;p class=lp&gt;&lt;i&gt;Further reading&lt;/i&gt;:&lt;/p&gt;

&lt;p class=pp&gt;
Bresenham described his algorithm in his 1965 paper 
&amp;ldquo;&lt;a href="http://www.research.ibm.com/journal/sj/041/ibmsjIVRIC.pdf"&gt;Algorithm for computer control of a digital plotter&lt;/a&gt;&amp;rdquo;
&lt;/p&gt;

&lt;p class=pp&gt;
Godfried Toussaint's 2005 paper
&amp;ldquo;&lt;a href="http://cgm.cs.mcgill.ca/~godfried/publications/banff.pdf"&gt;The Euclidean algorithm generates traditional musical rhythms&lt;/a&gt;&amp;rdquo;
shows yet another pattern connection, this time to rhythms.
&lt;/p&gt;

&lt;p class=pp&gt;
The Gregorian calendar is an evolved version of the Julian calendar and
can't be viewed as a Bresenham line.  However, 
Jeffrey Shallit's 1994 paper
&amp;ldquo;&lt;a href="http://www.emis.de/cgi-bin/zmen/ZMATH/en/zmath.html?first=1&amp;maxdocs=3&amp;type=pdf&amp;an=0823.11043&amp;format=complete"&gt;Pierce expansions and rules for the determination of leap years&lt;/a&gt;&amp;rdquo; shows how to compute leap years
using &lt;a href="http://mathworld.wolfram.com/PierceExpansion.html"&gt;Pierce expansions&lt;/a&gt;,
and this model can generate the Gregorian calendar too.
&lt;/p&gt;

&lt;p class=pp&gt;
Edward Reingold and Nashum Dershowitz are the experts on calendar algorithms.
Their pair of papers
1990 &lt;a href="http://emr.cs.uiuc.edu/~reingold/calendar.ps"&gt;Calendrical Calculations&lt;/a&gt; and
1993 &lt;a href="http://emr.cs.uiuc.edu/~reingold/calendar2.ps"&gt;Calendrical Calculations, II: Three Historical Calendars&lt;/a&gt;
gives algorithms (and Lisp code) for essentially any date-related computation you might want to do.
They expanded upon these papers in their books
&lt;a href="http://emr.cs.iit.edu/home/reingold/calendar-book/second-edition/index.html"&gt;Calendrical Calculations: The Millennium Edition&lt;/a&gt; and
&lt;a href="http://emr.cs.iit.edu/home/reingold/calendar-book/tables/index.html"&gt;Calendrical Tabulations: 1900-2200&lt;/a&gt;.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://research.swtch.com/2008/02/leaping-years-and-drawing-lines.html' title='Leaping Years and Drawing Lines'/><link rel='related' href='http://emr.cs.uiuc.edu/~reingold/bresenham.pdf' title='Leaping Years and Drawing Lines'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8082954141980125536&amp;postID=4724086904328707635' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://research.swtch.com/feeds/4724086904328707635/comments/default' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/4724086904328707635'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/4724086904328707635'/><author><name>rsc</name><uri>http://www.blogger.com/profile/09576271159839887762</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-7063226233147331082</id><published>2008-02-27T11:42:00.006-05:00</published><updated>2008-02-27T11:51:17.646-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><category scheme='http://www.blogger.com/atom/ns#' term='Bell Labs'/><title type='text'>Face the Nation</title><content type='html'>&lt;p class=pp&gt;
&amp;ldquo;&lt;a href="http://research.swtch.com/2008/02/hideous-name.html"&gt;The Hideous Name&lt;/a&gt;&amp;rdquo; makes mention
of a face server, perhaps the first user-level file system.
The face server's main purpose was to provide faces for
&lt;i&gt;vismon&lt;/i&gt;, which showed a face for each message in a
user's (electronic) mail box.  
Vismon is described in Rob Pike and Dave Presotto's 1985 Usenix
paper &amp;ldquo;&lt;a href="http://mailglance.com/facethenation.html"&gt;&lt;b&gt;Face the Nation&lt;/b&gt;&lt;/a&gt;.&amp;rdquo;
&lt;/p&gt;

&lt;center&gt;
&lt;a href=http://bp2.blogger.com/_9P3HFEQk8wo/R8WUpA4bCiI/AAAAAAAAAE4/KeFVQfO34UY/s1600-h/vismon.png&gt;
&lt;img src=http://bp2.blogger.com/_9P3HFEQk8wo/R7vAJg4bChI/AAAAAAAAAEU/-8oIpfpR9h4/s400/vismon1.png&gt;
&lt;/a&gt;
&lt;/center&gt;

&lt;p class=lp&gt;
(The appearance of grey scale is due only to the image being shrunk. 
Click on the image for the full-size version.)
This example shows the time, system load, a graph of
cpu time, faces for the five most recent emails, and the names
of the two most recent senders.
&lt;/p&gt;

&lt;p class=pp&gt;
The &lt;a href="http://www.brouhaha.com/~eric/retrocomputing/att/5620/"&gt;AT&amp;T 5620 Retrocomputing&lt;/a&gt; page contains a 
file tree used in the commercially distributed system, including the face set:
&lt;/p&gt;

&lt;center&gt;
&lt;img src="http://am.lcs.mit.edu/~rsc/faces.png" /&gt; 
&lt;/center&gt;

&lt;p class=lp&gt;
(The mailbox with the tail, labeled &lt;i&gt;md&lt;/i&gt;, is actually &lt;i&gt;mailer-daemon&lt;/i&gt;, but
that label didn't fit.)
&lt;/p&gt;

&lt;p class=pp&gt;
The faces include Brian Kernighan (bwk), Dennis Ritchie (dmr), Ken Thompson (ken), and Rob Pike (rob).
Curiously, Peter Weinberger's face is missing.  It was featured 
prominently in the paper and in &lt;a href="http://www.spinroot.com/pico/pjw.html"&gt;many other contexts&lt;/a&gt;, including water towers.
It is also used as the default &amp;ldquo;unknown&amp;rdquo; icon in &lt;i&gt;vismon&lt;/i&gt;.
Here it is in its two &lt;i&gt;vismon&lt;/i&gt; instantiations:
&lt;/p&gt;

&lt;center&gt;
&lt;img src=http://bp1.blogger.com/_9P3HFEQk8wo/R7u_tQ4bCgI/AAAAAAAAAEM/EMDSTbAGNd4/s400/pjw.png&gt;
&lt;/center&gt;

&lt;p class=pp&gt;
The spirit of vismon lives on in Plan 9's &lt;i&gt;&lt;a href="http://plan9.bell-labs.com/plan9/screenshot.html"&gt;faces&lt;/a&gt;&lt;/i&gt; (née &lt;i&gt;seemail&lt;/i&gt;),
Unix's &lt;i&gt;&lt;a href="http://faces.sourceforge.net/"&gt;faces&lt;/a&gt;&lt;/i&gt;, 
and OS X's &lt;a href="http://mailglance.com/index.html"&gt;MailGlance&lt;/a&gt;, among &lt;a href="http://www.cs.indiana.edu/ftp/faces/index.html"&gt;others&lt;/a&gt;.
&lt;/p&gt;

&lt;p class=pp&gt;
Vismon also inspired in 1987 the creation of the 
Usenix &lt;a href="http://www.metron.com/FaceSaver/"&gt;FaceSaver&lt;/a&gt; project.
Digging around in the archives you can find pictures of luminaries such as
&lt;a href="http://www.toad.com/facesaver/loukatz/gif/mckusick@berkeley.edu.gif"&gt;Kirk McKusick&lt;/a&gt;, 
&lt;a href="http://www.toad.com/facesaver/loukatz/gif/dmr@research.att.com.gif"&gt;Dennis Ritchie&lt;/a&gt;, 
&lt;a href="http://www.toad.com/facesaver/loukatz/gif/henry@zoo.toronto.edu.gif"&gt;Henry Spencer&lt;/a&gt;,
and
&lt;a href="http://www.toad.com/facesaver/loukatz/gif/lwall@jpl-devvax.jpl.nasa.gov.gif"&gt;Larry Wall&lt;/a&gt;.
&lt;/p&gt;

&lt;p class=pp&gt;
The &lt;a href="http://www.cs.indiana.edu/picons/ftp/index.html"&gt;Picons Archive&lt;/a&gt; has even &lt;a href="http://www.cs.indiana.edu/picons/ftp/demo/index.html"&gt;more pictures&lt;/a&gt;.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://research.swtch.com/2008/02/face-nation.html' title='Face the Nation'/><link rel='related' href='http://mailglance.com/facethenation.html' title='Face the Nation'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8082954141980125536&amp;postID=7063226233147331082' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://research.swtch.com/feeds/7063226233147331082/comments/default' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/7063226233147331082'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/7063226233147331082'/><author><name>rsc</name><uri>http://www.blogger.com/profile/06357099531993534337</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-5834085271483479195</id><published>2008-02-25T10:54:00.001-05:00</published><updated>2008-02-26T13:48:16.137-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><category scheme='http://www.blogger.com/atom/ns#' term='physics'/><title type='text'>Permissive Access Links</title><content type='html'>&lt;p class=lp&gt;In 2004, Steve Bellovin gave a talk at Usenix Security speculating about
permissive access links (PALs), the (supposedly impossible to bypass) locks that protect nuclear weapons.
He repeated the talk in 2006 at the general Usenix.
In Bellovin's talk, &amp;ldquo;&lt;b&gt;&lt;a href="http://www.usenix.org/events/usenix06/tech/mp3/bellovin.mp3"&gt;Nuclear Weapons, Permissive Action Links, and the History of Public Key Cryptography&lt;/a&gt;&lt;/b&gt;&amp;rdquo; (MP3; also &lt;a href="http://www.usenix.org/events/usenix06/tech/slides/bellovin_2006.pdf"&gt;PDF&lt;/a&gt; and &lt;a href="http://64.233.169.104/search?q=cache:_gevj9vbdqsJ:www.usenix.org/events/usenix06/tech/slides/bellovin_2006.pdf"&gt;HTML&lt;/a&gt;), 
he says that &amp;ldquo;Bypassing a PAL should be, as one weapons designer graphically put it,
about as complex as performing a tonsillectomy while entering the patient
from the wrong end.&amp;rdquo;
But how do they work?
Are there lessons that apply to building other kinds of secure systems?
He touches on these questions, but in the end, it's mostly speculation.
Even so, it's a fascinating talk.
&lt;/p&gt;

&lt;p class=pp&gt;
He does tease out a few interesting &lt;a href="http://www.cs.columbia.edu/~smb/nsam-160/"&gt;historical details&lt;/a&gt;.
In particular, &lt;a href="http://www.cs.columbia.edu/~smb/nsam-160/pg1.html"&gt;National Security Action Memorandum 160&lt;/a&gt;,
signed by President Kennedy, has been claimed by former NSA insiders
to be the impetus for the NSA's invention of public key cryptography.
There is no evidence that public key cryptography ended up being used in
PALs, but it's possible that digital signatures were invented in direct
response to the requirement that, after a weapon was launched,
it be possible to determine who authorized the launch.
It's also possible that public key cryptography was invented and used
to transmit the PAL codes securely.
&lt;/p&gt;

&lt;p class=pp&gt;
Other interesting facts.  The U.S. offered PALs to the Soviets (presumably to keep weapons from
falling into other hands), but they turned them down.
For years after the initial U.S. PAL deployments,
the launch codes were all set to 00000000.  
The bandwidth of the
&lt;strike&gt;extra-long frequency&lt;/strike&gt; &lt;a href="http://en.wikipedia.org/wiki/Extremely_low_frequency
"&gt;extremely low frequency&lt;/a&gt; (ELF) communication
link to submerged submarines is 1 bit/minute.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://research.swtch.com/2008/02/permissive-access-links.html' title='Permissive Access Links'/><link rel='related' href='http://www.usenix.org/events/usenix06/tech/mp3/bellovin.mp3' title='Permissive Access Links'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8082954141980125536&amp;postID=5834085271483479195' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://research.swtch.com/feeds/5834085271483479195/comments/default' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/5834085271483479195'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8082954141980125536/posts/default/5834085271483479195'/><author><name>rsc</name><uri>http://www.blogger.com/profile/06357099531993534337</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8082954141980125536.post-1041966606904372796</id><published>2008-02-22T09:22:00.000-05:00</published><updated>2008-02-22T09:23:16.504-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='notation'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='coroutines'/><category scheme='http://www.blogger.com/atom/ns#' term='math'/><title type='text'>Elegance and Power</title><content type='html'>&lt;p class=lp&gt;These are the most elegant programs I've ever seen.&lt;/p&gt;

&lt;p class=pp&gt;
A power series is an infinite-degree polynomial.  For example,&lt;/p&gt;
&lt;br&gt;
&lt;center&gt;
&lt;img src="http://bp1.blogger.com/_9P3HFEQk8wo/R7N21Q4bCZI/AAAAAAAAADU/RZN1LkuSslw/s800/expx.png" border="0" alt="e^x = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \frac{x^4}{4!} + \cdots" id="BLOGGER_PHOTO_ID_5166603854960855442" /&gt;
&lt;/center&gt;
&lt;br&gt;
&lt;p class=lp&gt;
Computation and manipulation of power series has a long and distinguished history as a test of so-called stream processing systems, which manipulate (arbitrarily long finite prefixes of) infinite streams.  In the 1970s, Gilles Kahn and David MacQueen used power series as an unpublished test of their &lt;a href="http://pdos.csail.mit.edu/~rsc/kahn77parallel.pdf"&gt;coroutine-based stream-processing system&lt;/a&gt;.  Hal Abelson and Gerald Sussman devote &lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html#%_sec_3.5"&gt;Section 3.5&lt;/a&gt; of their well-known 1985 textbook &lt;a href="http://mitpress.mit.edu/sicp/"&gt;Structure and Interpretation of Computer Programs&lt;/a&gt; to stream processing, although only a single exercise mentions power series.  In the late 1980s, Doug McIlroy explored power series processing in the context of Rob Pike's concurrent programming language Newsqueak.  He published the work in his 1990 paper &amp;ldquo;&lt;a href="http://swtch.com/~rsc/thread/squint.pdf"&gt;Squinting at Power Series&lt;/a&gt;&amp;rdquo; (the Newsqueak interpreter is named &lt;i&gt;squint&lt;/i&gt;).
&lt;/p&gt;

&lt;p class=pp&gt;
Stream processing requires lazy evaluation to keep computations finite.  All of these implementations built frameworks for lazy evaluation atop other building blocks: concurrent processes (Kahn and MacQueen, McIlroy) or first-class functions (Abelson and Sussman).  It's only natural, then, to consider what the implementations would look like in a language with explicit support and encouragement for lazy evaluation, a language like Haskell.  McIlroy revisited the topic in the context of Haskell in his 1998 Functional Pearl, &amp;ldquo;&lt;a href="http://www.cs.dartmouth.edu/~doug/pearl.ps.gz"&gt;&lt;b&gt;Power Series, Power Serious&lt;/b&gt;&lt;/a&gt;&amp;rdquo; (gzipped PS).
&lt;/p&gt;

&lt;p class=pp&gt;
Symbolic manipulations can represent a power series as just a list of integer coefficients.  Mathematically, this is equivalent to writing the polynormial in Horner form, which repeatedly factors &lt;i&gt;x&lt;/i&gt; out of the remainder of the polynomial: &lt;i&gt;F&lt;/i&gt; = &lt;i&gt;f&lt;/i&gt;&lt;sub&gt;0&lt;/sub&gt; + &lt;i&gt;x&lt;/i&gt;&lt;i&gt;F&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;, or in Haskell, &lt;code&gt;(f:fs)&lt;/code&gt; (= &lt;code&gt;f&lt;/code&gt; + &lt;i&gt;x&lt;/i&gt;&amp;nbsp;&lt;code&gt;fs&lt;/code&gt;).
&lt;/p&gt;
&lt;br&gt;
&lt;center&gt;
&lt;img src="http://bp2.blogger.com/_9P3HFEQk8wo/R7N3qg4bCcI/AAAAAAAAADs/w_9s57Tiifo/s800/expx1.png" /&gt;&lt;/center&gt;
&lt;br&gt;
&lt;p class=lp&gt;
In this form, &lt;i&gt;e&lt;sup&gt;x&lt;/sup&gt;&lt;/i&gt; is &lt;code&gt;[1, 1, 1%2, 1%6, 1%24, 1%120, ...]&lt;/code&gt;.
&lt;/p&gt;

&lt;p class=pp&gt;As a simple example, McIlroy's addition and multiplication implementations mimic the usual rules:&lt;/p&gt;
&lt;br style="line-height: 0.5em;"&gt;
&lt;!-- &lt;img style="margin-top: 0.5em; margin-bot: 0.5em" src="http://bp3.blogger.com/_9P3HFEQk8wo/R7N4aw4bCdI/AAAAAAAAAD0/gXZyhsudRE0/s800/add.png" /&gt; --&gt;
&lt;p class=lp&gt;(&lt;i&gt;f&lt;/i&gt;&lt;sub&gt;&lt;i&gt;0&lt;/i&gt;&lt;/sub&gt; + &lt;i&gt;x&lt;/i&gt;&lt;i&gt;F&lt;/i&gt;&lt;sub&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sub&gt;) + (&lt;i&gt;g&lt;/i&gt;&lt;sub&gt;&lt;i&gt;0&lt;/i&gt;&lt;/sub&gt; + &lt;i&gt;x&lt;/i&gt;&lt;i&gt;G&lt;/i&gt;&lt;sub&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sub&gt;) = (&lt;i&gt;f&lt;/i&gt;&lt;sub&gt;&lt;i&gt;0&lt;/i&gt;&lt;/sub&gt; + &lt;i&gt;g&lt;/i&gt;&lt;sub&gt;&lt;i&gt;0&lt;/i&gt;&lt;/sub&gt;) + &lt;i&gt;x&lt;/i&gt;(&lt;i&gt;F&lt;/i&gt;&lt;sub&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sub&gt; + &lt;i&gt;G&lt;/i&gt;&lt;sub&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sub&gt;)&lt;/p&gt;
&lt;br class=half&gt;
&lt;pre class=indent&gt;&amp;nbsp;&amp;nbsp;(f:fs) + (g:gs) = f+g : fs+gs&lt;/pre&gt;
&lt;br&gt;
&lt;!--
&lt;img style="margin-top: 0.5em; margin-bot: 0.5em" src="http://bp0.blogger.com/_9P3HFEQk8wo/R7N22A4bCbI/AAAAAAAAADk/TTERdD0Egzs/s800/mul.png" /&gt;
--&gt;
&lt;p class=lp&gt;(&lt;i&gt;f&lt;/i&gt;&lt;sub&gt;&lt;i&gt;0&lt;/i&gt;&lt;/sub&gt; + &lt;i&gt;x&lt;/i&gt;&lt;i&gt;F&lt;/i&gt;&lt;sub&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sub&gt;) (&lt;i&gt;g&lt;/i&gt;&lt;sub&gt;&lt;i&gt;0&lt;/i&gt;&lt;/sub&gt; + &lt;i&gt;x&lt;/i&gt;&lt;i&gt;G&lt;/i&gt;&lt;sub&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sub&gt;) = &lt;i&gt;f&lt;/i&gt;&lt;sub&gt;&lt;i&gt;0&lt;/i&gt;&lt;/sub&gt;&lt;i&gt;g&lt;/i&gt;&lt;sub&gt;&lt;i&gt;0&lt;/i&gt;&lt;/sub&gt; + &lt;i&gt;x&lt;/i&gt;(&lt;i&gt;f&lt;/i&gt;&lt;sub&gt;&lt;i&gt;0&lt;/i&gt;&lt;/sub&gt;&lt;i&gt;G&lt;/i&gt;&lt;sub&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sub&gt; + &lt;i&gt;g&lt;/i&gt;&lt;sub&gt;&lt;i&gt;0&lt;/i&gt;&lt;/sub&gt;&lt;i&gt;F&lt;/i&gt;&lt;sub&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sub&gt;) + &lt;i&gt;x&lt;/i&gt;&lt;sup&gt;2&lt;/sup&gt;(&lt;i&gt;F&lt;/i&gt;&lt;sub&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sub&gt;&lt;i&gt;G&lt;/i&gt;&lt;sub&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sub&gt;)
&lt;/p&gt;
&lt;br class=half&gt;
&lt;pre class=indent&gt;{- (f:fs) * (g:gs) = (f*g : 0) + (0 : f.*gs + g.*fs) + (0 : 0 : fs*gs) -}
&amp;nbsp;&amp;nbsp;&amp;nbsp;(f:fs) * (g:gs) = f*g : (f.*gs + g.*fs + (0 : fs*gs))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c .* (f:fs) = c.*f : c.*fs
&lt;/pre&gt;
&lt;p class=lp&gt;The commented-out definition is a more literal, but less efficient, translation of the equation.&lt;/p&gt;

&lt;p class=pp&gt;
Haskell's pattern matching and operator overloading are responsible for the elegance of the presentation, but it is lazy evaluation that is responsible for the elegance of the computation.  The underlying lazy computation mechanism (whether provided directly, as in Haskell, or via other primitives, as in Scheme and Newsqueak) takes care of all the bookkeeping necessary to compute only the terms needed.
&lt;/p&gt;

&lt;p class=pp&gt;
McIlroy implements derivative and integral operators as well.  Both rely on a helper function to keep track of the leading multiplicative constant:&lt;/p&gt;
&lt;br&gt;
&lt;pre class=indent&gt;
deriv (f:fs) = (deriv1 fs 1) where
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;deriv1 (g:gs) n = n*g : (deriv1 gs (n+1))

integral fs = 0 : (int1 fs 1) where
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int1 (g:gs) n = g/n : (int1 gs (n+1))
&lt;/pre&gt;
&lt;br&gt;
&lt;p class=lp&gt;These definitions enable elegant definitions of the power series for &lt;i&gt;exp&lt;/i&gt;, &lt;i&gt;sin&lt;/i&gt;, and &lt;i&gt;cos&lt;/i&gt;:&lt;/p&gt;
&lt;br&gt;
&lt;pre class=indent&gt;expx = 1 + (integral expx)

sinx = integral cosx
cosx = 1 - (integral sinx)&lt;/pre&gt;
&lt;br&gt;
&lt;p class=lp&gt;
To me, these three &lt;strike&gt;equations&lt;/strike&gt; programs are beautifully elegant, almost magical.
&lt;/p&gt;

&lt;p class=pp&gt;
When learning recursion in an introductory programming course (or induction in an introductory math course), it is common to feel like there's no actual work going on: one case just got rewritten in terms of others.  The base cases, of course, provide the foundation on which the others are built.  Learning to determine which base cases are necessary given the recursive steps is the key to being comfortable with recursion.  Only then can you see that the program or proof is structurally sound.
&lt;/p&gt;

&lt;p class=pp&gt;
The recursion in the definitions above gives me the same introductary queasiness, because it is hard to see the base cases.  Upon closer inspection, the base case is in the expansion of &lt;code&gt;integral&lt;/code&gt;, which begins with a constant zero term, making it possible to determine the first term in each of those series without further recursion.  Having the first term makes it possible to find the second term, and so on.
&lt;/p&gt;

&lt;p class=pp&gt;
For me, understanding why they work only enhances the beauty of these programs.
&lt;/p&gt;

&lt;p class=pp&gt;
McIlroy continues the theme in his 2000 ICFP paper &amp;ldquo;&lt;a href="http://www.cs.dartmouth.edu/~doug/music.ps.gz"&gt;The Music of Streams&lt;/a&gt;&amp;rdquo; (gzipped PS), which contains even more examples but fewer programs.
&lt;/pp&gt;

&lt;p class=pp&gt;
I've extracted &lt;a href="http://swtch.com/powser.hs"&gt;runnable code from the paper&lt;/a&gt;.  McIlroy maintains &lt;a href="http://www.cs.dartmouth.edu/~doug/powser.html"&gt;equivalent code&lt;/a&gt;. McIlroy's version uses these shorter versions of &lt;code&gt;integral&lt;/code&gt; and &lt;code&gt;deriv&lt;/code&gt;, which will delight Haskell aficionados:
&lt;/p&gt;
&lt;br&gt;
&lt;pre class=indent&gt;int fs = 0 : zipWith (/) fs [1..]
diff (_:ft) = zipWith (*) ft [1..]&lt;/pre&gt;
&lt;br&gt;
&lt;p class=lp&gt;
For the numerical computing aficionados, there is a one-line
implementation of power series reversion:
&lt;/p&gt;
&lt;br&gt;
&lt;pre class=indent&gt;revert (0:ft) = rs where rs = 0 : 1/(ft#rs)&lt;/pre&gt;
&lt;br&gt;
&lt;p class=lp&gt;
(For comparison, Donald Knuth devotes Section 4.7 of &lt;a href="http://www-cs-faculty.stanford.edu/~knuth/taocp.html#vol2"&gt;Volume 2&lt;/a&gt;, about 10 pages, to the manipulation 