|
Archive:
Subtopics:
Comments disabled |
Thu, 13 Aug 2026
The road to epsilon-zero: Productive programs and well-founded orders
Previously:
Previously we saw how to interpret the difficult-seeming ordinal !!ω^ω!! as a particular ordering of the set of finite sequences of numbers, revealing what seemed like a scary monster as gentle and straightforward. Now we're going to take a sidetrack into one of my favorite topics, computation with infinite lists. I wrote about this for The Perl Journal in 1997 and then it turned into chapter 6 of Higher-Order Perl and here we are again. Gosh! it just keeps coming back. Like John the Baptist. Infinite listsSuppose you have an infinite set of strings — we'll call this set !!S!! for the rest of the article — and you want a program to print them all out. Of course the program can't exactly print them all out, because it will only run for a finite amount of time. But there are more and less useful ways for the program to try. For each string that the program is supposed to print, we should at least be able to guarantee that the the program will print it, eventually, if we just wait long enough. If this is true then we'll say that the program is “productive”. Here's a productive program to print the base-10 numerals for all the positive integers:
What would a non-productive program look like? Here's an example of a non-productive program to print the base-10 numerals for all the positive integers:
This one tries to print all the odd numbers first, and then all the even numbers. Obviously that doesn't work because it never finishes with the odd numbers. If you were to sit around waiting for the number !!14!!, you'd wait forever. Whereas with the first program, whatever number you are waiting for, even if it is very very big, it will come out eventually. That's what I meant when I said there are more and less useful ways for a program to try to print an infinite set. The first one never finishes, true, but the way in which it never finishes is much more useful than the way in which the second one never finishes. Okay, that was a silly example. But there are less silly examples. Printing strings in sorted orderA productive program is always semidecidable: if a user wants to know if some particular string !!s!! is in !!S!!, and they wait long enough, !!s!! will come out and they have the answer. But if !!s!! isn't in !!S!!, they never find that out! They just wait and wait, wondering if it will come out, and never getting a definitive answer. If we can get a productive program to produce its strings in sorted order, we can make a better guarantee. The program will be decidable: the user will eventually get an answer, whether or not !!s\in S!!. If !!s\in S!! the productive program will eventually produce !!s!!, and the user can stop watching. But if !!s\notin S!!, the program must eventually produce a string that comes after !!s!! in sorted order, and they can quit then. And the program must eventually produce some string that comes after !!s!!, because, being productive, it eventually produces every string in !!S!!. (What if there is no string in !!S!! that comes after !!s!! in sorted order? This can only happen if !!S!! is finite, so the program will certainly halt on its own, and when it does that user has their answer.) Not every program is productiveThe non-productive program I showed above is silly, but productivity isn't something you can always guarantee, if you want the data in sorted order. Some orders work, and some don't. The conventional order for strings, implemented by Python's
For example, consider the set of all strings that are made up of
either all
Notice that this list is not in lexicographic order, because in
lexicographic order, the string There is no productive program to print this set in lexicographic order. Why not? Because in lexicographic order the list begins like this:
and the program never gets around to printing any of the strings with
The problems with lexicographic order are even worse than this example shows. Consider this set of strings:
Notice again: not lexicographic order, because If you're trying to print out an ordered, infinite list of strings, lexicographic order just won't do. Lexicographic order isn't well-foundedIn an earlier article in this series we talked about “well-founded” orders. In a well-founded order, every set of items has a first item, if it has any at all. Writing a productive program for a well-founded order is easy:
As we saw, the conventional lexicographic order is not well-founded for strings. Some sets simply don't have a lexicographically first element. So in circumstances where we might be handling infinite data streams, we often prefer a different string ordering, almost as simple and considerably better-behaved. Shortlex orderYou already know this one, although perhaps not by that name. It's
nothing more than the order we use for regular numerals like
Hey, wait, why did If you name your files after numbers, then when the computer lists them in lexicographic order, they won't be in numeric order. Numeric order isn't lexicographic. But numerals, in shortlex order are in numeric order, and of course it's trivial to print all possible numerals in numeric order. The rule to compare two strings in shortlex order is:
Compare the shortness first, and use lexicographic comparison as a tiebreaker. Hence “short” + “lex”. Consider what this means for numerals. Here's a list of binary numerals from !!0!! to !!15!!:
It looks strange because it's in lexicographic order — all the numerals that begin with If we want to print all binary numerals in lexicographic order, we're out of luck. The list starts like this:
and we never get to printing any of the numerals starting with In shortlex order, it's what we expect. We get the numeral for every number, and in numeric order:
Unlike lexicographic order, the shortlex order is well-founded. Remember that “well-founded” means that every set of strings has a first element. But in lexicographic order, this set of binary numerals has no first element:
In shortlex order there's no problem. There can't be, because shortlex order is numeric order, and if numeric order wasn't well-founded there wouldn't be a productive program to print all the numerals in order, which of course there is. The infinite lists that we couldn't put into lexicographic order before give us no trouble in shortlex order. In fact, I listed both in shortlex order already:
For strings, shortlex order is well-founded, which means that every set of strings contains a first element. Here's why: Consider some set !!S!! and some string !!s\in S!!. The string !!s!! has a length !!\ell!!. Consider the set !!E!! of strings that come before !!s!!. The set !!E!! must be finite because every string that comes before !!s!! in shortlex order has length less than or equal to !!\ell!!, and there are only a finite number of such strings. If !!E!! is empty, then !!s!! itself is the first string in !!S!!. If !!E!! is not empty, then, being finite, it must have a first element. (Just sort !!E!!.) This first element is the first string in !!S!!. Done. Wait, why are there are only a finite number of strings with length less than or equal to !!\ell!!? Well, there are only a finite number of strings of length !!0!!. (There's only one.) And there are only a finite number of strings of length !!1!!: If the character set contains !!n!! symbols, there are only !!n!! with length !!1!!. Similarly there are only !!n^2!! strings of length !!2!!, and so on. Since there are only a finite number with each length up to !!\ell!!, we just add up this finite list of finite numbers and the sum is finite. And since every string in !!E!! has length no more than !!\ell!!, the number of strings in !!E!! is at most this finite number. Coming next: Shortlex order is well-founded on sequences of ordinals. [Other articles in category /math/ordinals] permanent link |