<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Fabulous Adventures In Coding : Rarefied Heights</title><link>http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx</link><description>Tags: Rarefied Heights</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>What's the difference between covariance and assignment compatibility?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/30/what-s-the-difference-between-covariance-and-assignment-compatibility.aspx</link><pubDate>Mon, 30 Nov 2009 14:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9923199</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>18</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9923199.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9923199</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I've written a lot about this already, but I think one particular point bears repeating.&lt;/P&gt;
&lt;P&gt;As we're getting closer to shipping C# 4.0, I'm seeing a lot of documents, blogs, and so on, attempting to explain what "covariant" means. This is a tricky word to define in a way that is actually meaningful to people who haven't already got degrees in category theory, but it can be done. And I think it's important to avoid defining a word to mean something other than its actual meaning.&lt;/P&gt;
&lt;P&gt;A number of those documents have led with something like:&lt;/P&gt;
&lt;P&gt;"Covariance is the ability to assign an expression of a more specific type to a variable of a less specific type. For example, consider a method M that returns a Giraffe. You can assign the result of M to a variable of type Animal, because Animal is a less specific type that is compatible with Giraffe. Methods in C# are 'covariant' in their return types, which is why when you create a covariant interface, it is indicated with the keyword 'out' -- the returned value comes 'out' of the method."&lt;/P&gt;
&lt;P&gt;But that's &lt;STRONG&gt;not at all&lt;/STRONG&gt; what covariance means. That's describing "assignment compatibility" -- the ability to assign a value of a more specific type to a storage of a compatible, less specific type is called "assignment compatibility" because the two types are compatible for the purposes of verifying legality of assignments.&lt;/P&gt;
&lt;P&gt;So what does covariance mean then?&lt;/P&gt;
&lt;P&gt;First off, we need to work out precisely what the adjective "covariant" applies to. I'm going to get more formal for a bit here, but try to keep it understandable.&lt;/P&gt;
&lt;P&gt;Let's start by not even considering types. Let's think about integers. (And here I am speaking of actual mathematical integers, not of the weird behaviour of 32-bit integers in unchecked contexts.) Specifically, we're going to think about the ≤ relation on integers, the "less than or equal to" relation. (Recall that of course a "relation" is a function which takes two things and returns a bool which indicates whether the given relationship holds or does not hold.)&lt;/P&gt;
&lt;P&gt;Now let's think about a projection on integers. What is a projection? A projection is a function which takes a single integer and returns a new integer. So, for example, z → z + z is a projection; call it D for "double".&amp;nbsp; So are z → 0 - z, N for "negate" and z → z * z, S for "square".&lt;/P&gt;
&lt;P&gt;Now, here's an interesting question. Is it always the case that (x ≤ y) = (D(x) ≤ D(y))?&amp;nbsp; Yes, it is. If x is less than y, then twice x is less than twice y. If x is equal to y then twice x is equal to twice y. And if x is greater than y, then twice x is greater than twice y. The projection D preserves the direction of size.&lt;/P&gt;
&lt;P&gt;What about N? Is it always the case that (x ≤ y) = (N(x) ≤ N(y))?&amp;nbsp; Clearly not. 1 ≤ 2 is true, but -1 ≤ -2 is false. But we notice that the reverse is always true!&amp;nbsp; (x ≤ y) = (N(y) ≤ N(x)). The projection N reverses the direction of size.&lt;/P&gt;
&lt;P&gt;What about S? Is it always the case that (x ≤ y) = (S(x) ≤ S(y))? No. -1 ≤ 0 is true, but S(-1) ≤ S(0) is false. What about the opposite? Is it always the case that (x ≤ y) = (S(y) ≤ S(x)) ? Again, no. 1 ≤ 2 is true, but S(2) ≤ S(1) is false. The projection S does not preserve the direction of size, and nor does it reverse it. &lt;/P&gt;
&lt;P&gt;The projection D is "covariant" -- it preserves the ordering relationship on integers. The projection N is "contravariant". It reverses the ordering relationship on integers. The projection S does neither; it is "invariant".&lt;/P&gt;
&lt;P&gt;Now I hope it is more clear exactly what is covariant or contravariant. The integers themselves are not variant, and the "less than" relationship is not variant. It's &lt;STRONG&gt;the projection&lt;/STRONG&gt; that is covariant or contravariant -- the rule for taking an old integer and making a new one out of it.&lt;/P&gt;
&lt;P&gt;So now lets abandon integers and think about reference types. Instead of the ≤ relation on integers, we have the ≤ relation on reference types. A reference type X is smaller than (or equal to) a reference type Y if a value of type X can be stored in a variable of type Y. That is, if X is "assignment compatible" with Y.&lt;/P&gt;
&lt;P&gt;Now consider a projection from types to types. Say, the projection "T goes to IEnumerable&amp;lt;T&amp;gt;".&amp;nbsp; That is, we have a projection that takes a type, say, Giraffe, and gives you back a new type, IEnumerable&amp;lt;Giraffe&amp;gt;. Is that projection covariant in C# 4?&amp;nbsp; Yes. It preserves the direction of ordering. A Giraffe may be assigned to a variable of type Animal, and therefore an sequence of Giraffes may be assigned to a variable that can hold a sequence of Animals.&lt;/P&gt;
&lt;P&gt;We can think of generic types as "blueprints" that produce constructed types. Let's take the projection that takes a type T and produces IEnumerable&amp;lt;T&amp;gt; and simply call that projection "IEnumerable&amp;lt;T&amp;gt;". We can understand from context when we say "IEnumerable&amp;lt;T&amp;gt; is covariant" what we mean is "the projection which takes a reference type T and produces a reference type IEnumerable&amp;lt;T&amp;gt; is a covariant projection". And since IEnumerable&amp;lt;T&amp;gt; only has one type parameter, it is clear from the context that we mean that the parameter to the projection is T. After all, it is a lot shorter to say "IEnumerable&amp;lt;T&amp;gt; is covariant" than that other mouthful.&lt;/P&gt;
&lt;P&gt;So now we can define covariance, contravariance and invariance. A generic type I&amp;lt;T&amp;gt; is &lt;STRONG&gt;covariant&lt;/STRONG&gt; (in T) if construction with reference type arguments &lt;STRONG&gt;preserves&lt;/STRONG&gt; the direction of assignment compatibility. It is &lt;STRONG&gt;contravariant&lt;/STRONG&gt; (in T) if it &lt;STRONG&gt;reverses&lt;/STRONG&gt; the direction of assignment compatibility. And it is &lt;STRONG&gt;invariant&lt;/STRONG&gt; if it does neither. And by that, we simply are saying in a concise way that the &lt;STRONG&gt;projection&lt;/STRONG&gt; which takes a T and produces I&amp;lt;T&amp;gt; is a covariant/contravariant/invariant projection.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;UPDATE: My close personal friend (and fellow computer geek)&amp;nbsp;Jen notes that in the Twilight series of novels, the so-called "werewolves" (who are not transformed by the full moon and therefore not actually werewolves) maintain their rigid social ordering in both wolf and human form; the projection from human to wolf is covariant in the social-ordering relation. She also notes that in high school, programming language geeks are at the bottom of the social order, but the projection to adulthood catapults them to the top of the social order, and therefore, growing up is contravariant. I am somewhat skeptical of the latter claim; the former, I'll take your word for it. I suppose the question of how social order works amongst teenage werewolves who are computer geeks is a subject for additional research. Thanks Jen!&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923199" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx">C# 4.0</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/What_2700_s+The+Difference_3F00_/default.aspx">What's The Difference?</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/werewolves/default.aspx">werewolves</category></item><item><title>Five-Dollar Words For Programmers, Part Three: Homoiconic</title><link>http://blogs.msdn.com/ericlippert/archive/2009/03/23/five-dollar-words-for-programmers-part-three-homoiconic.aspx</link><pubDate>Mon, 23 Mar 2009 23:33:42 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9502480</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>24</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9502480.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9502480</wfw:commentRss><description>&lt;div class="mine"&gt; &lt;p&gt;Jeff Atwood was kind enough to once more &lt;a href="http://www.codinghorror.com/blog/archives/001244.html"&gt;give me the shout-out in his blog the other day&lt;/a&gt;. Thanks Jeff!&lt;/p&gt; &lt;p&gt;This inspires me to continue my series on five-dollar words for programmers. Here’s one that I only learned relatively recently, when I helped write the code that translates a lambda expression into an expression tree which represents the content of the lambda: &lt;strong&gt;&lt;a href="http://en.wikipedia.org/wiki/Homoiconic"&gt;homoiconic&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb397951.aspx"&gt;&lt;img title="Expression Trees" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 10px 0px 0px; border-right-width: 0px" height="240" alt="Expression Trees" src="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/FiveDollarWordsForProgrammersPartThreeHo_BE81/Expression%20Trees_3.png" width="260" align="left" border="0"&gt;&lt;/a&gt; A language is said to be &lt;strong&gt;homoiconic&lt;/strong&gt; if the &lt;strong&gt;representation&lt;/strong&gt; of the program can be seen as a &lt;strong&gt;data structure&lt;/strong&gt; expressible in that language. With expression lambdas being convertible to expression trees (which can then be compiled into code at runtime), C# 3.0 is &lt;em&gt;somewhat&lt;/em&gt; homoiconic. But it pales in comparison to, say, LISP, where pretty much everything you can do in the language you can also represent as structurally isomophic data.&lt;/p&gt; &lt;p&gt;Something I personally would like to see more of in C# in the future is greater homoiconicity. We could extend expression trees to statement trees, declaration trees, program trees, and so on. This series of steps would enable increasingly powerful and interesting &lt;strong&gt;metaprogramming scenarios&lt;/strong&gt;. &lt;/p&gt; &lt;p&gt;C# suffers from the lack of a metalanguage. We absolutely do not want to go towards the horrible and primitive metaprogramming language exemplified by the C preprocessor language. We already have a great language, C#, so why not use C# as a metalanguage? Wouldn’t it be nice to &lt;strong&gt;make C# its own metalanguage&lt;/strong&gt;? And once we do that, then we get into some truly strange loops, where we could use those data structures in the compiler implementation itself!&lt;/p&gt; &lt;p&gt;This is a long way off and might never happen, but a guy can dream.&lt;/p&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9502480" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Big+Words/default.aspx">Big Words</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category></item><item><title>Path Finding Using A* in C# 3.0, Part Four</title><link>http://blogs.msdn.com/ericlippert/archive/2007/10/10/path-finding-using-a-in-c-3-0-part-four.aspx</link><pubDate>Wed, 10 Oct 2007 17:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5250978</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/5250978.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=5250978</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Finally we are ready to translate our pseudocode into C# 3.0.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;What do we need to make the algorithm run?&amp;nbsp;We need a start node, a destination node, a function which tells us the exact distance between two neighbours, and a function which tells us the estimated distance between the last node on a proposed path and the destination node. &lt;/P&gt;
&lt;P&gt;We also need the ability to take any node and get a list of its neighbours. We'll represent that by an interface:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;interface IHasNeighbours&amp;lt;N&amp;gt;&amp;nbsp; &lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerable&amp;lt;N&amp;gt; Neighbours { get; }&lt;BR&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Recall that the pseudocode looked like this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;closed = {}&lt;BR minmax_bound="true"&gt;q = emptyqueue;&lt;BR minmax_bound="true"&gt;q.enqueue(0.0, makepath(start))&lt;BR minmax_bound="true"&gt;while q is not empty&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p = q.dequeueCheapest&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if closed contains p.last then continue;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if p.last == destination then return p&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; closed.add(p.last)&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach n in p.last.neighbours&amp;nbsp;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newpath = p.continuepath(n)&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; q.enqueue(newpath.TotalCost + estimateCost(n, destination), newpath)&lt;BR minmax_bound="true"&gt;return null&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;And now we're all set. The translation from pseudocode to real code is quite straightforward:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;static public Path&amp;lt;Node&amp;gt; FindPath&amp;lt;Node&amp;gt;(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Node start, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Node destination, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;Node, Node, double&amp;gt; distance, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Func&amp;lt;Node, double&amp;gt; estimate)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; where Node : IHasNeighbours&amp;lt;Node&amp;gt;&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var closed = new HashSet&amp;lt;Node&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var queue = new PriorityQueue&amp;lt;double, Path&amp;lt;Node&amp;gt;&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; queue.Enqueue(0, new Path&amp;lt;Node&amp;gt;(start));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (!queue.IsEmpty)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var path = queue.Dequeue();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&amp;nbsp;(closed.Contains(path.LastStep))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; continue;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (path.LastStep.Equals(destination))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return path;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; closed.Add(path.LastStep);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach(Node n in path.LastStep.Neighbours)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; double d = distance(path.LastStep, n);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var newPath = path.AddStep(n, d);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; queue.Enqueue(newPath.TotalCost + estimate(n), newPath);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return null;&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;You might wonder why we check to see if the current-best-path ends in a "closed" node after the dequeue,&amp;nbsp;rather than testing that before we do the enqueue. Think about it this way: suppose we take the best path off the queue,&amp;nbsp;note that&amp;nbsp;its end&amp;nbsp;node is "closed" so that we don't come back to it, and put all of its extensions on the queue. There might be a number of other paths which end in that node presently on the queue. All of them must be, by definition, worse than the&amp;nbsp;path we just took off the priority queue. We should therefore not even consider them as possbilities anymore. If we happen to put more paths with that property on the queue, that's unfortunate. But when we eventually get to them we'll discard them automatically so its not a big deal.&lt;/P&gt;
&lt;P mce_keep="true"&gt;A nice property of the A* algorithm is that it finds the optimal path in a reasonable amount of time provided that:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;the estimating function never overestimates the distance to the goal. (Think about what happens if the estimating function sometimes overestimates the distance; if the optimal path is one of the ones overestimated then it will possibly not make it to the front of the priority queue before a nonoptimal solution is found.)&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;calling the estimating function does not take very long.&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;One way to ensure that the estimating function never overestimates the distance is to always estimate zero. If you do so then this becomes Dijkstra's algorithm. However, the better your estimating function can get without going over (this really should have been called the "The Price Is Right" algorithm...) the faster this will identify the truly optimal path.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Unfortunately, the space complexity of this algorithm can be really quite high on complicated graphs. There are more complex versions of this algorithm which can deal with the space complexity, but I'm not going to go there.&lt;/P&gt;
&lt;P mce_keep="true"&gt;I have a nice example of using A* to find the shortest path around a lake (but not the &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2004/12/15/whidbey-island-and-bagel-mathematics.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2004/12/15/whidbey-island-and-bagel-mathematics.aspx"&gt;longest shortest path&lt;/A&gt;!) but I'm not going to post it here until Orcas ships. I'll just put up the whole project file at that time and you can check it out all at once.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Next time: at long last, Eric talks about variance in C#.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5250978" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/AStar/default.aspx">AStar</category></item><item><title>Path Finding Using A* in C# 3.0, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2007/10/08/path-finding-using-a-in-c-3-0-part-three.aspx</link><pubDate>Mon, 08 Oct 2007 17:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5250741</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/5250741.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=5250741</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;In order to make the A* algorithm work we need to get the lowest-estimated-cost-path-discovered-so-far out of the list of paths under consideration. The standard data structure for doing so is called a “priority queue”. Priority queues are so-called because they are typically used to store a list of jobs where each job has an associated priority. &lt;/P&gt;
&lt;P&gt;Now, there’s a bit of a semantic problem with priority queues in that we typically think of “priority 1” as being &lt;EM&gt;higher&lt;/EM&gt; priority than “priority 2”, even though 1 is a &lt;EM&gt;smaller&lt;/EM&gt; number than 2. Fortunately for us, that is &lt;EM&gt;exactly&lt;/EM&gt; what we want in this case; the “highest priority” path is the one with the &lt;EM&gt;least&lt;/EM&gt; estimated cost. &lt;/P&gt;
&lt;P&gt;There are lots of ways to implement priority queues – I have a nice example of an immutable priority queue that I’ll probably blog about at some point, but for now, let’s go with an old-fashioned mutable priority queue.&lt;/P&gt;
&lt;P&gt;A priority queue can be implemented as list of sub-queues with the list sorted in priority order. The implementation is pretty straightforward:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class PriorityQueue&amp;lt;P, V&amp;gt;&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private SortedDictionary&amp;lt;P, Queue&amp;lt;V&amp;gt;&amp;gt; list = new SortedDictionary&amp;lt;P, Queue&amp;lt;V&amp;gt;&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Enqueue(P priority, V value)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Queue&amp;lt;V&amp;gt; q;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!list.TryGetValue(priority, out q))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; q = new Queue&amp;lt;V&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; list.Add(priority, q);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; q.Enqueue(value);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public V Dequeue()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // will throw if there isn’t any first element!&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var pair = list.First();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var v = pair.Value.Dequeue();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pair.Value.Count == 0) // nothing left of the top priority.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; list.Remove(pair.Key);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return v;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool IsEmpty&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return !list.Any(); }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We could implement &lt;SPAN class=code&gt;IEnumerable&amp;lt;V&amp;gt;&lt;/SPAN&gt;, a &lt;SPAN class=code&gt;Peek&lt;/SPAN&gt; operation, etc, but this is all we need for A*, so let’s not go crazy here.&lt;/P&gt;
&lt;P&gt;Next time: now we have all the parts we need to implement A*, so let's do it already.&lt;BR&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5250741" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/AStar/default.aspx">AStar</category></item><item><title>Path Finding Using A* in C# 3.0, Part Two</title><link>http://blogs.msdn.com/ericlippert/archive/2007/10/04/path-finding-using-a-in-c-3-0-part-two.aspx</link><pubDate>Thu, 04 Oct 2007 17:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5250440</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>25</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/5250440.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=5250440</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;In order to &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/10/02/path-finding-using-a-in-c-3-0.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/10/02/path-finding-using-a-in-c-3-0.aspx"&gt;implement the A* algorithm in C# 3.0&lt;/A&gt; I am going to need to implement some custom data structures. Today we’ll consider how to implement the “path”.&lt;/P&gt;
&lt;P&gt;You’ll notice in my description of the algorithm that the only operations we perform on paths are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Make a new path consisting of a single node.&lt;/LI&gt;
&lt;LI&gt;Make a new path by adding a new node onto the end of an existing path.&lt;/LI&gt;
&lt;LI&gt;Fetch the last element on the path.&lt;/LI&gt;
&lt;LI&gt;Get the total cost of a path.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;This cries out to me “Eric! A path is an immutable stack!” &lt;/P&gt;
&lt;P&gt;A mutable stack like &lt;SPAN class=code&gt;System.Collections.Generic.Stack&amp;lt;T&amp;gt;&lt;/SPAN&gt; is clearly not suitable. We want to be able to take an existing path and create new paths from it for all of the neighbours of its last element, but &lt;STRONG&gt;pushing a new node onto the standard stack modifies the stack&lt;/STRONG&gt;. We’d have to make copies of the stack before pushing it, which is silly because then we’d be duplicating all of its contents unnecessarily.&lt;/P&gt;
&lt;P&gt;Immutable stacks do not have this problem. Pushing onto an immutable stack merely creates a brand-new stack which links to the old one as its tail. Since the stack is immutable, there is no danger of some other code coming along and messing with the tail contents. You can keep on using the old stack to your heart’s content.&lt;/P&gt;
&lt;P&gt;ASIDE: &lt;STRONG&gt;Immutable data structures are the way of the future in C#. &lt;/STRONG&gt;It is much easier to reason about a data structure if you know that it will never change. Since they cannot be modified, they are automatically threadsafe. Since they cannot be modified, you can maintain a stack of past “snapshots” of the structure, and suddenly undo-redo implementations become trivial. On the down side, they do tend to chew up memory, but hey, that’s what garbage collection was invented for, so don’t sweat it. I’ll be talking more about programming using immutable data structures in this space over the next few months.&lt;/P&gt;
&lt;P&gt;Let’s make an immutable stack of nodes which tracks the total cost of the whole path. Later on, we’ll see that we need to enumerate the nodes of this thing, so we’ll do a trivial implementation of &lt;SPAN class=code&gt;IEnumerable&lt;/SPAN&gt; while we’re at it. And since we don’t know exactly what a node will look like, let’s make the thing generic:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class Path&amp;lt;Node&amp;gt; : IEnumerable&amp;lt;Node&amp;gt;&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Node LastStep { get; private set; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Path&amp;lt;Node&amp;gt; PreviousSteps { get; private set; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public double TotalCost { get; private set; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Path(Node lastStep, Path&amp;lt;Node&amp;gt; previousSteps, double totalCost)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LastStep = lastStep;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PreviousSteps = previousSteps;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TotalCost = totalCost;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Path(Node start) : this(start, null, 0) {}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Path&amp;lt;Node&amp;gt; AddStep(Node step, double stepCost)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new Path&amp;lt;Node&amp;gt;(step, this, TotalCost + stepCost);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IEnumerator&amp;lt;Node&amp;gt; GetEnumerator()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (Path&amp;lt;Node&amp;gt; p = this; p != null; p = p.PreviousSteps)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return p.LastStep;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerator IEnumerable.GetEnumerator()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this.GetEnumerator();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Well, that was painless. Next time: implementing the priority queue.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5250440" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/AStar/default.aspx">AStar</category></item><item><title>Path Finding Using A* in C# 3.0, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2007/10/02/path-finding-using-a-in-c-3-0.aspx</link><pubDate>Wed, 03 Oct 2007 02:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5249654</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/5249654.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=5249654</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;As we get into the home stretch for the Orcas release I’ve been spending a little time lately just playing around implementing some “classic” algorithms and data structures in C#. The one I implemented today is the famous A* algorithm. &lt;/P&gt;
&lt;P&gt;Surely you’ve played games like Age of Empires. You know the kind of games I mean. There are a bunch of little dudes walking around a map containing barriers (mountains, walls, etc) and somehow the game’s pseudo-intelligence finds the shortest possible path for the guys to walk from point A to point B. Most games do this with a surprisingly straightforward algorithm.&lt;/P&gt;
&lt;P&gt;Suppose you’ve got a bunch of “nodes”. Say, intersections in a city. Each node has a bunch of “neighbours” – intersections that can be immediately reached by locomoting down a particular street involved in the intersection. Each “edge” (ie, street) between nodes has a “cost” – the amount of time it takes to travel from one node to the neighbour on that street. Perhaps the cost is based on its length, traffic density, etc.&lt;/P&gt;
&lt;P&gt;A “path from A to B” consists of a list of nodes starting with A, ending with B, where every step along the path is from neighbour to neighbour. The total cost of a path is obviously the sum of all the costs of every transition from neighbour to neighbour on the path.&lt;/P&gt;
&lt;P&gt;Let’s start by considering a really stupid, awful, buggy path finding algorithm, and then we’ll make it better.&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;q = emptyqueue&lt;BR&gt;q.enqueue(makepath(start))&lt;BR&gt;while q is not empty&lt;BR&gt;&amp;nbsp; &amp;nbsp; p = q.dequeue&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if p.last == destination then return p&lt;BR&gt;&amp;nbsp; &amp;nbsp; foreach n in p.last.neighbours&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; q.enqueue(p.continuepath(n))&lt;BR&gt;// failed to find path.&lt;BR&gt;return null&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;What’s wrong with this picture?&lt;/P&gt;
&lt;P&gt;Well, suppose we have&amp;nbsp;four nodes,arranged like this: A &amp;lt;--&amp;gt; C &amp;lt;--&amp;gt; D &amp;lt;--&amp;gt; B. Does this algorithm find the obvious path from A to B?&lt;/P&gt;
&lt;P&gt;Run the code in your head: it starts by putting the path “A” on the queue. Then it takes it off and puts “A-C” on the queue. Then it takes it off and puts “A-C-A” and “A-C-D” on the queue. Then it takes “A-C-A” off the queue and puts “A-C-A-C” on the queue... OK, eventually we get there, but we seem to be spending a lot of time going in circles.&amp;nbsp; And if D does not actually connect to B, if you can't get there from here, then we really &lt;EM&gt;do&lt;/EM&gt; go into an infinite loop.&lt;/P&gt;
&lt;P&gt;Clearly this is all screwed up.&amp;nbsp; We need to disallow paths which loop back on themselves, because those are clearly not going to be the best possible path. We're at best&amp;nbsp;wasting time looking at them, and at worst going into an infinite loop that chews up all the memory in the system. &lt;/P&gt;
&lt;P&gt;Let’s fix that up. We’ll create a “closed” set, ie, the set of “nodes we have already considered, so do not loop back to them.”&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;closed = {}&lt;BR&gt;q = emptyqueue;&lt;BR&gt;q.enqueue(makepath(start))&lt;BR&gt;while q is not empty&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p = q.dequeue&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if closed contains p.last then continue&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if p.last == destination then return p&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; closed.add(p.last)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach n in p.last.neighbours&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; q.enqueue(p.continuepath(n))&lt;BR&gt;return null&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This is &lt;EM&gt;better&lt;/EM&gt;, in that it actually terminates in a finite amount of time. But my goodness, is this algorithm ever slow. Essentially the algorithm is “At every intersection, check to see if you're at your destination. If not, pick a direction – any direction! - and walk as far as you can like that without revisiting your steps. If you ever run out of options, backtrack until you get to an intersection that goes somewhere you haven’t tried yet. Keep doing that until either you get to your destination or you have tried every possible intersection.”&lt;/P&gt;
&lt;P&gt;I guarantee you that if you try that in a reasonably sized city, you will not get from point A to point B in any kind of reasonable time. And when you do succeed, the path which you come up with may well be absolutely crazy. Obviously this is not how people navigate between points in cities. &lt;/P&gt;
&lt;P&gt;The problem is that we are picking which neighbour to try next essentially at random. We can do better than that. &lt;STRONG&gt;We want to direct our search so that the path we spend most of our time concentrating on is the path which is most likely to lead us to the goal.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Now, that sounds like a bit of a chicken-and-egg problem. Finding the best path is precisely what we are trying to do, so how can we determine which path is the one we want to be concentrating on?&lt;/P&gt;
&lt;P&gt;We shall have to guess. We will rank all potential paths based on the sum of two factors: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;First, what is the total cost of each potential path so far? This is &lt;EM&gt;known&lt;/EM&gt;.&lt;/LI&gt;
&lt;LI&gt;Second, what is the estimated cost of getting from the end of each potential path to the goal? This is a &lt;EM&gt;guess&lt;/EM&gt;.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;And now our algorithm becomes:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;closed = {}&lt;BR&gt;q = emptyqueue;&lt;BR&gt;q.enqueue(0.0, makepath(start))&lt;BR&gt;while q is not empty&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; p = q.dequeueCheapest&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if closed contains p.last then continue;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if p.last == destination then return p&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; closed.add(p.last)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach n in p.last.neighbours&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newpath = p.continuepath(n)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; q.enqueue(newpath.TotalCost + estimateCost(n, destination), newpath)&lt;BR&gt;return null&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;which is the famous A* algorithm! Surprisingly straightforward, eh?&lt;/P&gt;
&lt;P&gt;Next time: actually implementing this thing in C# 3.0.&lt;BR&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5249654" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/AStar/default.aspx">AStar</category></item><item><title>What exactly does 'lifted' mean?</title><link>http://blogs.msdn.com/ericlippert/archive/2007/06/27/what-exactly-does-lifted-mean.aspx</link><pubDate>Wed, 27 Jun 2007 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3523924</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/3523924.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=3523924</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;(Note: all type placeholders &lt;SPAN class=code&gt;S&lt;/SPAN&gt;, &lt;SPAN class=code&gt;T&lt;/SPAN&gt;, &lt;SPAN class=code&gt;U&lt;/SPAN&gt; that I mention in this article are non-nullable value types.)&lt;/P&gt;
&lt;P&gt;I got a question the other day from a reader who had been taking a close look at the C# 2.0 standard. He noticed that when we talk about nullables in the standard we talk about "lifting", but we do so inconsistently. To summarize what the standard says:&lt;/P&gt;
&lt;P&gt;1) For every equality and relational operator that compares an &lt;SPAN class=code&gt;S&lt;/SPAN&gt; to a &lt;SPAN class=code&gt;T&lt;/SPAN&gt; and returns a &lt;SPAN class=code&gt;bool&lt;/SPAN&gt; there is a corresponding &lt;STRONG&gt;lifted&lt;/STRONG&gt; operator that compares an &lt;SPAN class=code&gt;S?&lt;/SPAN&gt; to a &lt;SPAN class=code&gt;T?&lt;/SPAN&gt; and returns a &lt;SPAN class=code&gt;bool. &lt;/SPAN&gt;It returns &lt;SPAN class=code&gt;false&lt;/SPAN&gt; if either argument is &lt;SPAN class=code&gt;null&lt;/SPAN&gt;. (With the additional exception that&amp;nbsp;if one argument to an equality operator is the null literal then the result may be determined by checking if the nullable term has a value.)&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;&lt;/SPAN&gt;2) For the unary operators &lt;SPAN class=code&gt;+ ++ - -- ! ~&lt;/SPAN&gt; where the operator takes an &lt;SPAN class=code&gt;S&lt;/SPAN&gt; and returns a &lt;SPAN class=code&gt;T&lt;/SPAN&gt; there is a corresponding &lt;STRONG&gt;lifted&lt;/STRONG&gt; operator that takes an &lt;SPAN class=code&gt;S?&lt;/SPAN&gt; and returns a &lt;SPAN class=code&gt;T?&lt;/SPAN&gt;. It returns &lt;SPAN class=code&gt;null&lt;/SPAN&gt; if its argument is &lt;SPAN class=code&gt;null&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;3) For the binary operators &lt;SPAN class=code&gt;+ - * / % &amp;amp; | ^ &amp;lt;&amp;lt; &amp;gt;&amp;gt;&lt;/SPAN&gt;, where the operator takes an &lt;SPAN class=code&gt;S&lt;/SPAN&gt; and a &lt;SPAN class=code&gt;T&lt;/SPAN&gt; and returns a &lt;SPAN class=code&gt;U&lt;/SPAN&gt; there is a corresponding &lt;STRONG&gt;lifted&lt;/STRONG&gt; operator that takes an &lt;SPAN class=code&gt;S?&lt;/SPAN&gt; and a &lt;SPAN class=code&gt;T?&lt;/SPAN&gt; and returns a &lt;SPAN class=code&gt;U?&lt;/SPAN&gt;. It returns &lt;SPAN class=code&gt;null&lt;/SPAN&gt; if either argument is &lt;SPAN class=code&gt;null&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;4) For user-defined conversions from &lt;SPAN class=code&gt;S&lt;/SPAN&gt; to &lt;SPAN class=code&gt;T&lt;/SPAN&gt;, there is a corresponding &lt;STRONG&gt;lifted&lt;/STRONG&gt; user-defined conversion from &lt;SPAN class=code&gt;S?&lt;/SPAN&gt; to &lt;SPAN class=code&gt;T?&lt;/SPAN&gt;. It returns &lt;SPAN class=code&gt;null&lt;/SPAN&gt; if the argument is &lt;SPAN class=code&gt;null&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;5) For built-in conversions from &lt;SPAN class=code&gt;S&lt;/SPAN&gt; to &lt;SPAN class=code&gt;T&lt;/SPAN&gt;, there are corresponding &lt;STRONG&gt;nullable&lt;/STRONG&gt; conversions:&lt;BR&gt;5.1) from &lt;SPAN class=code&gt;S?&lt;/SPAN&gt; to &lt;SPAN class=code&gt;T?&lt;/SPAN&gt;, which returns &lt;SPAN class=code&gt;null&lt;/SPAN&gt; if the argument is &lt;SPAN class=code&gt;null&lt;/SPAN&gt;.&lt;BR&gt;5.2) from &lt;SPAN class=code&gt;S&lt;/SPAN&gt; to &lt;SPAN class=code&gt;T?&lt;/SPAN&gt;, which never returns &lt;SPAN class=code&gt;null&lt;/SPAN&gt;, and &lt;BR&gt;5.3) an explicit-only conversion from &lt;SPAN class=code&gt;S?&lt;/SPAN&gt; to &lt;SPAN class=code&gt;T&lt;/SPAN&gt; which throws if the argument is &lt;SPAN class=code&gt;null&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;Why does the standard call out that the conversions in (5) are "nullable" but not "lifted"? Everything else is "lifted"!&lt;/P&gt;
&lt;P&gt;This is a bit of a mess I'm afraid.&lt;/P&gt;
&lt;P&gt;I talked to &lt;A class="" href="http://blogs.msdn.com/madst/default.aspx" mce_href="http://blogs.msdn.com/madst/default.aspx"&gt;Dr. T&lt;/A&gt; (AKA Mads Torgersen, the C# language PM) about this. He defined for me precisely what mathematicians mean by “lifted”.&lt;/P&gt;
&lt;P&gt;Suppose we've got a function &lt;SPAN class=math&gt;f&lt;/SPAN&gt; which maps values from a set &lt;SPAN class=math&gt;A&lt;/SPAN&gt; into a set &lt;SPAN class=math&gt;B&lt;/SPAN&gt;. That is &lt;SPAN class=math&gt;f:A→B&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;Suppose further that &lt;SPAN class=code&gt;null&lt;/SPAN&gt; is not a member of either &lt;SPAN class=math&gt;A&lt;/SPAN&gt; or &lt;SPAN class=math&gt;B&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;Now consider the sets &lt;SPAN class=math&gt;A' = A ∪ { null }&lt;/SPAN&gt; and &lt;SPAN class=math&gt;B' = B ∪ { null }&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;We define the "lifted function" &lt;SPAN class=math&gt;f'&lt;/SPAN&gt; as &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=math&gt;f':A'→B'&lt;/SPAN&gt; such that &lt;SPAN class=math&gt;f'(x) = f(x)&lt;/SPAN&gt; for all &lt;SPAN class=math&gt;x ∈ A &lt;/SPAN&gt;and &lt;SPAN class=math&gt;f'(null) = null&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Similarly, if we had a two-argument function &lt;SPAN class=math&gt;f: A × B → C&lt;/SPAN&gt;, we would define &lt;SPAN class=math&gt;f': A' × B' → C'&lt;/SPAN&gt; as &lt;SPAN class=math&gt;f'(x,y) = f(x,y)&lt;/SPAN&gt; for all &lt;SPAN class=math&gt;(x,y) ∈ A × B&lt;/SPAN&gt; and &lt;SPAN class=math&gt;null&lt;/SPAN&gt; if either &lt;SPAN class=math&gt;x&lt;/SPAN&gt; or &lt;SPAN class=math&gt;y&lt;/SPAN&gt; is &lt;SPAN class=math&gt;null&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;What we’re getting at here is that “lifted” means “takes nulls, always agrees with the unlifted version when arguments are not null, maps everything else onto null”.&lt;/P&gt;
&lt;P&gt;Now you probably see why I said this was a bit of a mess. By the mathematician's definition, (1) is incorrectly called "lifted", (2), (3), and (4) are correctly called "lifted", (5.1) is incorrectly NOT called "lifted", and (5.2) and (5.3) are correctly not called "lifted". Of course we can choose to define what "lifted" means &lt;EM&gt;in C#&lt;/EM&gt; any way we like, but it would be nice if&amp;nbsp;our definition&amp;nbsp;agreed with convention and was used consistently!&lt;/P&gt;
&lt;P&gt;I regret the confusion. I do not believe there is any particular sensible reason for these inconsistencies. Rather, the details were changed so many times over the years as the nullable feature was developed that these sorts of subtle problems crept into the spec and were never expunged. Though of course all of us have as a goal that the standard be a model of clarity and permanence, it is fundamentally a working, evolving, imperfect document; these kinds of things will happen. Hopefully in the next version of the standard some of these sorts of details will be tidied up.&lt;/P&gt;
&lt;P&gt;I hope that answers the question!&lt;BR&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3523924" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Mathematics/default.aspx">Mathematics</category></item><item><title>Lambda Expressions vs. Anonymous Methods, Part Five</title><link>http://blogs.msdn.com/ericlippert/archive/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five.aspx</link><pubDate>Wed, 28 Mar 2007 17:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1956384</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/1956384.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=1956384</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/03/26/lambda-expressions-vs-anonymous-methods-part-four.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/03/26/lambda-expressions-vs-anonymous-methods-part-four.aspx"&gt;Last time&lt;/A&gt; I demonstrated that the compiler could have to do an exponential number of bindings in order to determine whether there was a unique best overload resolution for a function call that takes a lambda. Some of you may have wondered whether we simply were not being clever enough in the compiler. Perhaps there is some way to optimize this problem so that the unique solution is found in less than exponential time. &lt;/P&gt;
&lt;P&gt;As it turns out, the question of whether there is a clever way to do this in C# 3.0&amp;nbsp;is equivalent to solving the most famous unsolved problem in computer science. That is a problem which has stumped generations of the finest minds in academia,&amp;nbsp;and is widely believed to be unsolvable, so I don't feel &lt;EM&gt;particularly&lt;/EM&gt; bad about not solving this one myself. &lt;/P&gt;
&lt;P&gt;Consider the following &lt;EM&gt;slight&lt;/EM&gt; revision of the set of overloads I sketched out last time:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class MainClass&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class T{}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class F{}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; delegate void DT(T t);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; delegate void DF(F f);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void M(DT dt)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.WriteLine("true");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dt(new T());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void M(DF df)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.WriteLine("false");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; df(new F());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static T Or(T a1, T a2){return new T();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static T Or(T a1, F a2){return new T();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static T Or(F a1, T a2){return new T();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static F Or(F a1, F a2){return new F();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static T And(T a1, T a2){return new T();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static F And(T a1, F a2){return new F();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static F And(F a1, T a2){return new F();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static F And(F a1, F a2){return new F();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static F Not(T a){return new F();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static T Not(F a){return new T();}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void MustBeT(T t){}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void Main()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Introduce enough variables and then&amp;nbsp;encode any Boolean predicate:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;eg,&amp;nbsp;here we encode (!x3) &amp;amp; ((!x1) &amp;amp; ((x1 | x2) &amp;amp; (x2 | x3)))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; M(x1=&amp;gt;M(x2=&amp;gt;M(x3=&amp;gt;MustBeT(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; And(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Not(x3),&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; And(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Not(x1),&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; And(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Or(x1, x2),&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Or(x2, x3))))))));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This expression&amp;nbsp;&lt;I&gt;makes the compiler solve the &lt;A class="" href="http://en.wikipedia.org/wiki/Boolean_satisfiability_problem" mce_href="http://en.wikipedia.org/wiki/Boolean_satisfiability_problem"&gt;Boolean satisfiability problem&lt;/A&gt;&lt;/I&gt; (aka "SAT"). If SAT has a unique solution then the program compiles and produces the unique solution. If it has more than one solution then compilation fails with an ambiguity error. If it has no solution then the program fails with the error that &lt;SPAN class=code&gt;MustBeT&lt;/SPAN&gt; has an &lt;SPAN class=code&gt;F&lt;/SPAN&gt; argument. But no matter how you slice it, the compiler must solve SAT. &lt;/P&gt;
&lt;P&gt;Determining whether a given predicate has a set of valuations for its variables which make it true is an &lt;A class="" href="http://en.wikipedia.org/wiki/NP-complete" mce_href="http://en.wikipedia.org/wiki/NP-complete"&gt;NP-complete&lt;/A&gt; problem; actually &lt;EM&gt;finding&lt;/EM&gt; the set of valuations is an &lt;A class="" href="http://en.wikipedia.org/wiki/NP-hard" mce_href="http://en.wikipedia.org/wiki/NP-hard"&gt;NP-hard&lt;/A&gt; problem. Therefore, &lt;EM&gt;overload resolution in C# 3.0&amp;nbsp;is at the very least NP-hard&lt;/EM&gt;. There is no known polynomial-time algorithm for any NP-complete or NP-hard problem and it is widely believed that there is none to be found, though that conjecture has yet to be proven. So our dream of fast lambda type analysis in C# 3.0&amp;nbsp;is almost certainly doomed, at least as long as we have the current rules for overload resolution. &lt;/P&gt;
&lt;P&gt;Does this really matter in practice? As I mentioned last time, hopefully not. Other languages also have this issue. When I ran an early&amp;nbsp;draft of this post&amp;nbsp;past him, &lt;A class="" href="http://research.microsoft.com/~emeijer/" mce_href="http://research.microsoft.com/~emeijer/"&gt;Erik Meijer&lt;/A&gt; immeditely pointed out that the &lt;A class="" href="http://en.wikipedia.org/wiki/ML_programming_language" mce_href="http://en.wikipedia.org/wiki/ML_programming_language"&gt;ML&lt;/A&gt; type inference system has &lt;A class="" href="http://portal.acm.org/citation.cfm?id=96748&amp;amp;coll=portal&amp;amp;dl=ACM" mce_href="http://portal.acm.org/citation.cfm?id=96748&amp;amp;coll=portal&amp;amp;dl=ACM"&gt;similar worst cases&lt;/A&gt;, and the &lt;A class="" href="http://en.wikipedia.org/wiki/Haskell_%28programming_language%29" mce_href="http://en.wikipedia.org/wiki/Haskell_%28programming_language%29"&gt;Haskell&lt;/A&gt; type inference system is even worse. Apparently in Haskell you can encode a Turing machine into the type system and make the compiler run it! In practice these sorts of problems do not arise in real-world code in any of these languages, so I am not too worried about it for C# 3.0. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1956384" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Overload+Resolution/default.aspx">Overload Resolution</category></item><item><title>Every Number Is Special In Its Own Special Way</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/28/every-number-is-special-in-it-s-own-special-way.aspx</link><pubDate>Tue, 28 Nov 2006 21:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1166651</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>28</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/1166651.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=1166651</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I got a question recently about where in the .NET framework the "special numbers" were defined. The questioner was actually asking about the &lt;SPAN class=code&gt;Double.NaN&lt;/SPAN&gt;, &lt;SPAN class=code&gt;Double.PositiveInfinity&lt;/SPAN&gt;, etc, special values for floating point numbers. Of course there are other "special numbers" defined by the framework, such as &lt;SPAN class=code&gt;Math.PI&lt;/SPAN&gt;. &lt;/P&gt;
&lt;P&gt;The question was easily answered but it got me thinking, which, as we know, is usually trouble. &lt;/P&gt;
&lt;P&gt;Clearly zero is a very special number, being the first natural number. &lt;/P&gt;
&lt;P&gt;One is pretty special too, being the multiplicative identity. &lt;/P&gt;
&lt;P&gt;Two is the only even prime. &lt;/P&gt;
&lt;P&gt;Three is the lowest odd prime... &lt;/P&gt;
&lt;P&gt;Clearly lots of numbers are special. This led me to propose the following theorem: &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Theorem:&lt;/B&gt; &lt;I&gt;Every&lt;/I&gt; natural number (0, 1, 2, ...) is a special number. &lt;/P&gt;
&lt;P&gt;&lt;B&gt;Proof:&lt;/B&gt; &lt;/P&gt;
&lt;P&gt;Let’s posit that the set of nonspecial natural numbers is nonempty, and deduce a contradiction. &lt;/P&gt;
&lt;P&gt;If there exists a nonspecial natural number then there must be a &lt;I&gt;lowest&lt;/I&gt; nonspecial natural number. &lt;/P&gt;
&lt;P&gt;What an unusual property! The lowest nonspecial natural number! &lt;/P&gt;
&lt;P&gt;Whatever number has that unusual property must be kinda... special. &lt;/P&gt;
&lt;P&gt;Therefore the lowest nonspecial natural number is special. &lt;/P&gt;
&lt;P&gt;Therefore, if the set of nonspecial natural numbers is nonempty then it contains a special number. &lt;/P&gt;
&lt;P&gt;That is clearly nonsensical, therefore the set of nonspecial natural numbers is empty. &lt;/P&gt;
&lt;P&gt;Therefore all natural numbers are special, QED. &lt;/P&gt;
&lt;P&gt;And yet I can't find anything special about 7920687935872092847630945767548023. But it must be special somehow! 
&lt;P&gt;Extending the proof show that all real numbers are special is left as an exercise for the reader. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1166651" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Floating+Point+Arithmetic/default.aspx">Floating Point Arithmetic</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Mathematics/default.aspx">Mathematics</category></item><item><title>Regular Expressions From Scratch, Part Twelve: Superposition of States</title><link>http://blogs.msdn.com/ericlippert/archive/2006/01/20/regular-expressions-from-scratch-part-twelve-superposition-of-states.aspx</link><pubDate>Fri, 20 Jan 2006 22:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:515471</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/515471.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=515471</wfw:commentRss><description>&lt;div class="mine"&gt;

&lt;P&gt;
Happy New Year everyone.  Over the break I had a wonderful time reconnecting with my friends and family. 
And of course I came back to a huge pile of work!  We're going through the flaws that were discovered in
C# 2.0 too late in the cycle to risk fixing, and some of them illustrate interesting corner cases in
the language.  
But those will have to wait, as we've still got a lot of ground to cover before I'm done this crazy long
series on regular expressions.
&lt;/P&gt;
&lt;P&gt;
To summarize the story so far: we've defined alphabets and languages over those alphabets. 
We've shown how to create a special "regular expression" alphabet and language for any given alphabet. 
We've also come up with a rule that associates a language with a regular expression. This language is the
set of strings which "matches" the regular expression.
&lt;/P&gt;
&lt;P&gt;
We've determined that there are deterministic finite state computers which consume one character of a string
at a time that can "recognize" strings from some regular languages.  We've also determined that there are
"nondeterministic" finite automata that somehow "magically" figure out which rules to apply at any time to
match a string.
&lt;/P&gt;
&lt;P&gt;
We've also shown that any NFA that has rules that act on more than one character can be turned into an equivalent
NFA which only has single-character or no-character transitions.
&lt;/P&gt;
&lt;P&gt;
What we would like to do is show the following three facts: first, that every NFA is equivalent to a DFA. 
Second, that every DFA/NFA recognizes a regular language. And third, that every regular language has a DFA/NFA
that recognizes it.
&lt;/P&gt;
&lt;P&gt;
We've still got a ways to go to show that first result.  Rather than prove the general result, which will
be tedious, I'll just go through an example and hope that it is illustrative enough to convince you that
we could give this treatment to any NFA.
&lt;/P&gt;
&lt;P&gt;
 
Let M be an NFA with alphabet 
{&lt;span class="code"&gt;a&lt;/span&gt;,
&lt;span class="code"&gt;b&lt;/span&gt;}, states {1, 2, 3, 4}, start state is 1, and the set of acceptable states is {4}. 
We'll assume that we've already eliminated all the multi-character rules and have a set of rules as follows:
&lt;/P&gt;
&lt;P&gt;
(1, e) &amp;#x2192; 2&lt;br&gt;
(1, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; 3&lt;br&gt;
(2, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 1&lt;br&gt;
(2, e) &amp;#x2192; 3&lt;br&gt;
(2, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 4&lt;br&gt;
(3, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; 4
&lt;/P&gt;
&lt;P&gt;

This NFA accepts the language 
&lt;span class="code"&gt;a&lt;/span&gt;*(
&lt;span class="code"&gt;bb&lt;/span&gt;
&amp;#X222A;
&lt;span class="code"&gt;b&lt;/span&gt;
&amp;#X222A;
&lt;span class="code"&gt;a&lt;/span&gt;
), and as you can see, we've got lots of empty and ambiguous rules.
&lt;/P&gt;
&lt;P&gt;

Here's the trick:  given an NFA with 4 states like this one, we can find a DFA which is equivalent to this 
guy that has 2&lt;SUP&gt;4&lt;/SUP&gt; = 16 states or fewer.  
We can think of the NFA as at any time living in a "superstate" that consists of all of the states that it 
COULD be in right now.
&lt;/P&gt;
&lt;P&gt;
Let me try to explain that a little better.  
We start in state 1, right?  
But since 
(1, e) &amp;#x2192; 2 and
(2, e) &amp;#x2192; 3, we could also be starting in states 2 or 3 before we process any input.

Let's create a new automaton with a start state that represents the concept 
"right now M could be in states 1, 2, or 3."  
We'll call that state 123x, which is one big symbol, not a string of four symbols.  
In our new automaton, the start state is 123x.
&lt;/P&gt;
&lt;P&gt;
We're trying to write a DFA here, so there needs to be a rule for every input and every state:
&lt;/P&gt;
&lt;P&gt;
(123x, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; ?&lt;br&gt;
(123x, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; ?
&lt;/P&gt;
&lt;P&gt;
Look at the original automaton.  
When we were in states 1, 2 or 3, what were the possible state transitions for 
&lt;span class="code"&gt;a&lt;/span&gt;?  
The only ones were 
(2, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 1
and 
(2, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 4.

But we're not finished! Again, we need to consider what could happen from states 1 and 4 if we processed the 
"empty string" transition rules.  
Since (1, e) &amp;#x2192; 2 and (2, e) &amp;#x2192; 3, we could end up in state 1, 2, 3 or 4.  Let's create a new state
called 1234 for our DFA and finish off that rule:
&lt;/P&gt;
&lt;P&gt;
(123x, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 1234
&lt;/P&gt;
&lt;P&gt;
Now do the same analysis for (123x, &lt;span class="code"&gt;b&lt;/span&gt;) and we'll see that in the original automaton,
the only possible resulting states starting in 1, 2 or 3, and processing a  
&lt;span class="code"&gt;b&lt;/span&gt; are 3 and 4.  Add another new state:
&lt;P&gt;
&lt;p&gt;
(123x, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; xx34
&lt;/P&gt;
&lt;P&gt;
Are we done? No. We've added two more states, 1234 and xx34, so we need to figure out the state transitions for 
them too, which we do by the same process.  We discover that
&lt;/P&gt;
&lt;P&gt;
(1234, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 1234&lt;br&gt;
(1234, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; xx34&lt;br&gt;
(xx34, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; ?&lt;br&gt;
(xx34, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; xxx4
&lt;/P&gt;

Uh oh.  There are no state transitions in the original NFA that start in states 3 or 4 and take an 
&lt;span class="code"&gt;a&lt;/span&gt;.  Remember that in that case we assume that the NFA goes into a special
"reject" state.  Let's call the reject state xxxx.
&lt;/P&gt;
&lt;P&gt;
We now have two more new states to work out the transitions for. If we're in the reject state, we 
stay in the reject state, and we see from the original NFA that there are no transitions out of state
4, so we can round out our list with:

&lt;/P&gt;
&lt;P&gt;
(xx34, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; xxxx&lt;br&gt;
(xxxx, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; xxxx&lt;br&gt;
(xxxx, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; xxxx&lt;br&gt;
(xxx4, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; xxxx&lt;br&gt;
(xxx4, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; xxxx
&lt;/P&gt;
&lt;P&gt;

Since 4 was the acceptable state in the original NFA, any "superstate" that contains 4 must be an acceptable state.  
So our new DFA is a machine M&lt;SUB&gt;2&lt;/SUB&gt; with 

alphabet {&lt;span class="code"&gt;a&lt;/span&gt;}, 
&lt;span class="code"&gt;b&lt;/span&gt;}, states {1234, 123x, xx34, xxx4, xxxx}, 
start state is 123x, and the set of acceptable states is {1234, xx34, xxx4}.  The rules are
&lt;/P&gt;
&lt;P&gt;
(1234, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 1234&lt;br&gt;
(1234, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; xx34&lt;br&gt;
(123x, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 1234&lt;br&gt;
(123x, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; xx34&lt;br&gt;
(xx34, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; xxxx&lt;br&gt;
(xx34, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; xxx4&lt;br&gt;
(xxx4, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; xxxx&lt;br&gt;
(xxx4, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; xxxx&lt;br&gt;
(xxxx, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; xxxx&lt;br&gt;
(xxxx, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; xxxx
&lt;/P&gt;

This DFA accepts the language 
&lt;span class="code"&gt;a&lt;/span&gt;*(
&lt;span class="code"&gt;bb&lt;/span&gt;
&amp;#X222A;
&lt;span class="code"&gt;b&lt;/span&gt;
&amp;#X222A;
&lt;span class="code"&gt;a&lt;/span&gt;
), so we've found an equivalent DFA to our NFA.

We've turned an NFA with four states and five rules into an equivalent DFA with five states and ten rules.  
We did well -- you can find NFAs that require 2&lt;SUP&gt;n&lt;/SUP&gt; new states, where n is the number of NFA states.  
An NFA with a thousand states could require 2&lt;SUP&gt;1000&lt;/SUP&gt; states to represent as a DFA! 
2&lt;SUP&gt;1000&lt;/SUP&gt; is a finite, albeit rather large number.  
But it's not &lt;i&gt;that&lt;/i&gt; big. Clearly we could build a 2&lt;SUP&gt;1000&lt;/SUP&gt; state machine with only 1000 bits to 
store the state information.  
It's the &lt;i&gt;state transition rules&lt;/i&gt; that are the pain to work out!
&lt;/P&gt;
&lt;p&gt;
Using the techniques from this and the previous entry we can turn any NFA into an equivalent DFA, so NFAs are
really not magic at all. They're just a convenient way to talk about DFAs.
&lt;/P&gt; 
&lt;P&gt;
Now, obviously what I've done here isn't a proof; one example does not a proof make.  
But the proof is both tedious and complicated, so I'm going to skip it.  
The key result here is that we can stop saying "deterministic finite automaton" and 
"nondeterministic finite automaton" and just start saying "finite automaton", because they're essentially the 
same thing.
&lt;/P&gt;
&lt;P&gt;
Now that we know that we can use NFAs with impunity, we can try to answer questions such as:
&lt;/P&gt; 
&lt;P&gt;
Is every regular language recognizable by a finite automaton?
&lt;/P&gt;
&lt;P&gt;
Are there any FAs that recognize irregular languages?
&lt;/P&gt;
&lt;P&gt;
Tune in next time to find out!
&lt;/P&gt;
&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=515471" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Regular+Expressions/default.aspx">Regular Expressions</category></item><item><title>Regular Expressions From Scratch, Part Eleven: Eliminating Multi-Symbol Rules</title><link>http://blogs.msdn.com/ericlippert/archive/2005/12/22/regular-expressions-from-scratch-part-eleven-eliminating-multi-symbol-rules.aspx</link><pubDate>Thu, 22 Dec 2005 18:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:504393</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/504393.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=504393</wfw:commentRss><description>
&lt;div class="mine"&gt;

&lt;P&gt;
The story so far: we have deterministic and nondeterministic finite automata.  
DFAs follow a rigid, fully specified set of rules which, on any string, yield either an accept 
or reject state after exactly as many moves as the string has characters.  
NFAs, on the other hand, are poorly specified.  
They somehow magically are able to choose which rules to apply given 
the input to find a path that yields an accept state, if one exists.
&lt;/P&gt;
&lt;P&gt;
NFA magic buys us a lot, but at the high price that we can now no longer easily see a 
clear relationship between this magic box and a computer we could actually build.  
We need to get back to reality.  
Here is the &lt;I&gt;amazing result&lt;/I&gt; that I'm going to try to justify in your minds:
&lt;/P&gt;
&lt;P&gt;
&lt;B&gt;&lt;I&gt;Every&lt;/I&gt; NFA is equivalent to some DFA. 
Even better: given a description of an NFA, we can construct a description of an equivalent DFA.
&lt;/B&gt;
&lt;/P&gt;
&lt;P&gt;
In other words, NFA magic doesn't buy us any extra power - no NFA can recognize a language 
that some DFA cannot also recognize.
&lt;/P&gt;
&lt;P&gt;
This is excellent news, because it means that we can describe and reason about machines using short, convenient, 
vague nondeterministic notation, but still have confidence that we could build a fully deterministic 
machine that did exactly the same job.
&lt;/P&gt;
&lt;P&gt;
But how the heck are we going to motivate that amazing result?
&lt;/P&gt;
&lt;P&gt;One step at a time.  
We're going to take some NFAs and make simple transformations that gradually turn them
into different but equivalent NFAs, and eventually one of those NFAs will actually be a DFA.
Rather than giving a full formal proof, which would be tedious and boring, I'm going to rely 
on the sketch being convincing enough that you believe me that we can take any NFA and turn it into a DFA.
Maybe later in this series we'll actually write some C# code that implements the transformation.
&lt;/P&gt;
&lt;P&gt;
The magical bits that we need to remove are: rules can have multiple characters in state transitions,
rules can have "empty" state transitions, rules can have ambiguous state transitions, there can be
situations for which no stated rule applies, and there's a magical 'crash' state. 
Once we eliminate all those weirdnesses, we'll be left with a DFA.
&lt;/P&gt;
&lt;P&gt;
Step one: Any NFA that has rules that have multiple-character state transitions is 
equivalent to some NFA that has only single-character or empty-string transitions. 
&lt;/P&gt;
&lt;P&gt;
We can get rid of the multiple-character transitions by adding one new state for each extra character.
Recall our previous example:
&lt;/P&gt;
&lt;P&gt;
Alphabet: S = {&lt;span class="code"&gt;a&lt;/span&gt;, &lt;span class="code"&gt;b&lt;/span&gt;}&lt;BR&gt;
States: K = {0}&lt;BR&gt;
Start: s = 0&lt;BR&gt;
Acceptable: F = {0}
&lt;/P&gt;
&lt;P&gt;Rules:&lt;/P&gt;
(0,&lt;span class="code"&gt;ab&lt;/span&gt;) &amp;#x2192; 0&lt;br&gt;
(0,&lt;span class="code"&gt;aba&lt;/span&gt;) &amp;#x2192; 0
&lt;/P&gt;
&lt;P&gt;
Suppose we added three new (non-acceptable) states, 1, 2 and 3.
You agree I hope that the first rule is equivalent to these two rules:
&lt;/P&gt;
&lt;P&gt;
(0,&lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 1&lt;br&gt;
(1,&lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; 0
&lt;/P&gt;
&lt;P&gt;
And the second rule is equivalent to these three rules:
&lt;/P&gt;
&lt;P&gt; 
(0,&lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 2&lt;br&gt;
(2,&lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; 3&lt;br&gt;
(3,&lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 0&lt;br&gt;
&lt;/P&gt;
&lt;P&gt;
We never need to add more than a finite number of new states or rules, so the new machine is always still an NFA.
&lt;/P&gt;
&lt;P&gt;
Throw away the original two rules and hey presto, we have an equivalent NFA where every rule only 
has a zero or one-symbol string.  
Multi-symbol transition rules are no longer 
magical; we can eliminate them easily.
&lt;/P&gt;
&lt;P&gt;
This example above has no empty-string transitions.  
Next time we'll pick another example that has empty string transitions and one-character transitions, 
and then show that we can turn something that looks like that into a DFA.
&lt;/P&gt;
&lt;P&gt;
"Next time" will likely be in the new year, as I am heading back to my ancestral home for the next week to
visit friends and relatives during this festive holiday season.  
I hope all of you have a fun and safe holiday; thanks for reading and we'll see you in 2006.
&lt;/P&gt;

&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=504393" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Regular+Expressions/default.aspx">Regular Expressions</category></item><item><title>Regular Expressions From Scratch, Part Ten: Magic!</title><link>http://blogs.msdn.com/ericlippert/archive/2005/12/19/regular-expressions-from-scratch-part-ten-magic.aspx</link><pubDate>Mon, 19 Dec 2005 18:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:502866</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/502866.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=502866</wfw:commentRss><description>
&lt;div class="mine"&gt;

&lt;P&gt;
Let's recap the story so far.
&lt;/P&gt;
Starting only with basic set theory, sequences, symbols and numbers, we've defined alphabets, languages,
regular expressions, and the mapping between regular expressions and regular languages.
We've also defined deterministic finite automata as machines that take in strings one character at a time, 
change their internal state to one of a finite set according to strict rules, 
and end up in either an accept or reject state as output.
&lt;/P&gt;
&lt;P&gt;
Where we're going with this is towards unification of these two concepts.
We want to show that for every DFA there's a regexp, and vice versa.
But to get there is going to take some magic.
&lt;/P&gt;

&lt;P&gt;
The trouble with DFAs is that they're kind of a pain to specify. 
You have an alphabet with, say, a hundred symbols, and you have, say, fifty states.
You need to come up with a state transition rule for 100 x 50 = 5000 possible combinations.
Since most of those will likely be transitions to rejection states anyway, that's majorly boring.
&lt;/P&gt;
&lt;P&gt;
I'm hereby declaring that we have &lt;B&gt;nondeterministic finite automata&lt;/B&gt;.
An NFA works just like a DFA, except that the "rules" for determining the state transitions can be 
&lt;B&gt;ambiguous and weird&lt;/B&gt;.
We'll write an NFA like this:
&lt;/P&gt;
&lt;P&gt;
Let M&lt;SUB&gt;1&lt;/SUB&gt; be an NFA such that:
&lt;/P&gt;
&lt;P&gt;
Alphabet: S = {&lt;span class="code"&gt;a&lt;/span&gt;, &lt;span class="code"&gt;b&lt;/span&gt;}&lt;BR&gt;
States: K = {0, 1, 2}&lt;BR&gt;
Start: s = 0&lt;BR&gt;
Acceptable: F = {0}
&lt;/P&gt;
&lt;P&gt;
Rules:
&lt;/P&gt;
&lt;P&gt;
(0,&lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 1&lt;br&gt;
(1,&lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; 2&lt;br&gt;
(2,&lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 0&lt;br&gt;
(2,e) &amp;#x2192; 0
&lt;/P&gt;

&lt;P&gt;
Notice that we're not specifying the six rules we ought to be, and one of those rules is a transition on an 
"empty input"!
This last rule means that if we are in state 2, we can go to state 0 "for free", without consuming any characters.
&lt;/P&gt;
&lt;P&gt;We say that M&lt;SUB&gt;1&lt;/SUB&gt; accepts a string if there is &lt;I&gt;any&lt;/I&gt; way to make it eventually 
yield an acceptable state with no more input.
For example, suppose we start with &lt;span class="code"&gt;ababa&lt;/span&gt;:
&lt;/P&gt;
&lt;P&gt;
(0, &lt;span class="code"&gt;ababa&lt;/span&gt;) &amp;#x2192; 
(1, &lt;span class="code"&gt;baba&lt;/span&gt;) &amp;#x2192;
(2, &lt;span class="code"&gt;aba&lt;/span&gt;) &amp;#x2192;
(0, &lt;span class="code"&gt;aba&lt;/span&gt;) &amp;#x2192;
(1, &lt;span class="code"&gt;ba&lt;/span&gt;) &amp;#x2192;
(2, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192;
(0, e) 
&lt;/P&gt;
&lt;P&gt;is one path to an acceptable state. Even though &lt;/P&gt;
&lt;P&gt;
(0, &lt;span class="code"&gt;ababa&lt;/span&gt;) &amp;#x2192; 
(1, &lt;span class="code"&gt;baba&lt;/span&gt;) &amp;#x2192;
(2, &lt;span class="code"&gt;aba&lt;/span&gt;) &amp;#x2192;
(0, &lt;span class="code"&gt;ba&lt;/span&gt;) 
gets us stuck in a state that we can go no further in, that's OK.
NFAs are magic.
If there exists &lt;I&gt;any&lt;/I&gt; path such that 
(0, &lt;span class="code"&gt;ababa&lt;/span&gt;) &amp;#x2D92; (0, e)
then the NFA will find it and end in an accepting state.
&lt;B&gt;The fact that some nonsensical or rejecting paths exist doesn't matter if an accepting path exists.&lt;/B&gt; 
Only if every possible path either ends in a rejecting state, or leaves us unable to find any applicable rule,
does the NFA reject the string.
&lt;/P&gt;
&lt;P&gt;
In fact, this machine accepts the regular language 
&lt;span class="code"&gt;(ab&amp;#x222A;aba)*&lt;/span&gt;
&lt;/P&gt;
&lt;p&gt;
(Recall that I am being sloppy about parenthesizing. 
This isn't a "real" regular expression but you get the point that when I say that I mean 
L(&lt;span class="code"&gt;((ab)&amp;#x222A;((ab)a))*&lt;/span&gt;) I'm sure.)
&lt;/P&gt;
&lt;P&gt;
We've got lots of magic already, so let's add more.
We'll say that a rule can consume any number of matching symbols that it wants.
&lt;/P&gt;
&lt;P&gt;
Let M&lt;sub&gt;2&lt;/sub&gt; be an NFA such that:&lt;/P&gt;
&lt;P&gt;
Alphabet: S = {&lt;span class="code"&gt;a&lt;/span&gt;, &lt;span class="code"&gt;b&lt;/span&gt;}&lt;BR&gt;
States: K = {0}&lt;BR&gt;
Start: s = 0&lt;BR&gt;
Acceptable: F = {0}
&lt;/P&gt;
&lt;P&gt;Rules:&lt;/P&gt;
(0,&lt;span class="code"&gt;ab&lt;/span&gt;) &amp;#x2192; 0&lt;br&gt;
(0,&lt;span class="code"&gt;aba&lt;/span&gt;) &amp;#x2192; 0
&lt;/P&gt;
&lt;P&gt;
This machine clearly accepts 
&lt;span class="code"&gt;(ab&amp;#x222A;aba)*&lt;/span&gt;
except for the fact that it is now totally &lt;i&gt;unclear&lt;/i&gt; what we mean by "accepts" vs. "rejects" in
a machine with only one state! How does it reject anything?
&lt;/P&gt;
&lt;P&gt;
Let's assume that NFAs have a magic implicit "crash" state which means "For this input I was unable to find any
path that did not end in a state where I lacked a rule telling me what to do next."  
The crash state is always a rejecting state.
&lt;/P&gt;
&lt;P&gt;
Clearly M&lt;sub&gt;1&lt;/sub&gt; and M&lt;sub&gt;2&lt;/sub&gt; accept the same language.
Let's make up a word for that relationship.
&lt;/P&gt;
&lt;P&gt;
&lt;B&gt;Definition 15:&lt;/B&gt; Two machines are &lt;B&gt;equivalent&lt;/B&gt; if they both accept exactly the same language.
&lt;/P&gt;
&lt;P&gt;
Next time: Can we in fact build a device which does magic?
&lt;/P&gt;
&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=502866" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Regular+Expressions/default.aspx">Regular Expressions</category></item><item><title>Regular Expressions From Scratch, Part Nine: A Dream of a Machine</title><link>http://blogs.msdn.com/ericlippert/archive/2005/12/15/regular-expressions-from-scratch-part-nine-a-dream-of-a-machine.aspx</link><pubDate>Thu, 15 Dec 2005 18:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:501683</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/501683.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=501683</wfw:commentRss><description>&lt;DIV class="mine"&gt;

&lt;P&gt;I want to come up with the &lt;I&gt;simplest possible device&lt;/I&gt; that can identify whether a given string is a 
member of a given regular language. 
We need some kind of computer, but to make it easy to analyze, I want to put as many restrictions upon it
as possible.
For example, I want there to be very limited memory storage, I want to process only one character at a time, and so on.
&lt;/P&gt;
&lt;P&gt;Definition 14&lt;/B&gt;: A &lt;B&gt;deterministic finite automaton&lt;/B&gt; (DFA) is an idealized machine. 
It has an input &lt;B&gt;tape&lt;/B&gt; with a finite string written down on it in a given alphabet.
The tape is exactly as long as the string. 
The DFA has a finite number of distinct &lt;B&gt;states&lt;/B&gt; that it can be in. 
A DFA can be in only one state at a time, called the &lt;B&gt;current state&lt;/B&gt;. 
The DFA always starts in a particular state called the &lt;B&gt;start state&lt;/B&gt;. 
The DFA reads the string from left to right, one symbol at a time.
There is no backtracking allowed.
Each new symbol on the input tape may cause the machine to change the current state, 
but this choice can only be based on the current symbol and current state, and the
rules for how that choice is made must be specified in advance and cannot change.
Every state is either an &lt;B&gt;acceptable state&lt;/B&gt; or an &lt;B&gt;unacceptable state&lt;/B&gt;. 
When the machine is done reading the string, if it is in an acceptable state then the 
machine &lt;B&gt;accepts&lt;/B&gt; the string, otherwise it &lt;B&gt;rejects&lt;/B&gt; it.
&lt;/P&gt;
&lt;P&gt;
I think you'll agree that this is a very limiting set of restrictions to place upon a computer.
&lt;/P&gt;
&lt;P&gt;
We'll write down DFAs like this example:
&lt;/P&gt;
&lt;P&gt;Let M be a DFA such that:&lt;BR&gt;
Alphabet: S = {&lt;span class="code"&gt;a&lt;/span&gt;, &lt;span class="code"&gt;b&lt;/span&gt;}&lt;BR&gt;
States: K = {0, 1}&lt;BR&gt;
Start: s = 0&lt;BR&gt;
Acceptable: F = {1}
&lt;/P&gt;

&lt;P&gt;
Every DFA has rules for determining what the state transitions are, one rule for every possible combination of states and symbols. 
For example, M might have rules:
&lt;/P&gt;
&lt;P&gt;
&lt;TABLE FRAME="box"&gt;
&lt;THEAD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;current state&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;current input&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;new state&lt;/span&gt;&lt;/TD&gt;
&lt;/THEAD&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="mine"&gt;0&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;a&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;1&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="mine"&gt;0&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;b&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;1&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="mine"&gt;1&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;a&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;0&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="mine"&gt;1&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;b&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;1&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TABLE&gt;
&lt;/P&gt;
&lt;P&gt;
Note that there MUST be a rule for every combination of K and S.
Since it will get cumbersome to write out these tables constantly I'm going to declare a new notation:
&lt;/P&gt;
(0, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 1&lt;BR&gt;
(0, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; 1&lt;BR&gt;
(1, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 0&lt;BR&gt;
(1, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; 1&lt;BR&gt;
&lt;/P&gt;
&lt;P&gt;
The arrow is read as "yields".
&lt;/P&gt;
&lt;P&gt;
Consider the action of M on a tape containing &lt;span class="code"&gt;aab&lt;/span&gt;.
The machine uses these rules in this order:
&lt;/P&gt;
&lt;P&gt;
(0, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 1&lt;BR&gt;
(1, &lt;span class="code"&gt;a&lt;/span&gt;) &amp;#x2192; 0&lt;BR&gt;
(0, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; 1&lt;BR&gt;
&lt;/P&gt;
&lt;P&gt;
The string is accepted because we've run out of string and we're in an acceptable state.
&lt;/P&gt;

&lt;P&gt;
Since any set of strings is a language, the set of strings which a machine M accepts forms a language.
We can construct a finite sequence of sets (alphabet, states, transition rules, etc) that exactly characterizes M, 
so we can build a function L which maps M onto the language which M accepts. 
Call the language L(M).
&lt;/P&gt;
&lt;P&gt;
Convince yourself that in the case above, L(M) = 
{ (&lt;span class="code"&gt;a&lt;/span&gt;(&lt;span class="code"&gt;aa&lt;/span&gt;)*)
&amp;#x222A;
(((&lt;span class="code"&gt;a&lt;/span&gt; &amp;#x222A; 
&lt;span class="code"&gt;b&lt;/span&gt;)*&lt;span class="code"&gt;b&lt;/span&gt;)
(&lt;span class="code"&gt;aa&lt;/span&gt;)*) }

 - 
that is, the regular language where every string is either an odd number of 
&lt;span class="code"&gt;a&lt;/span&gt;s or any string ending in a
&lt;span class="code"&gt;b&lt;/span&gt; followed by an even number of 
&lt;span class="code"&gt;a&lt;/span&gt;s.
&lt;/P&gt;

&lt;P&gt;
This idea of listing the rules used by the machine is pretty good, but it requires
us to mentally keep track of how far along the input tape the machine is.
Also, there's some redundancy there, since obviously the state of the next line is
going to be the same as the new state of the current line.  
I'm therefore going to change the notation I use to describe how a machine is working.
For the example above we'd say in our new notation&lt;/P&gt;
&lt;P&gt;
(0, &lt;span class="code"&gt;aab&lt;/span&gt;) &amp;#x2192; 
(1, &lt;span class="code"&gt;ab&lt;/span&gt;) &amp;#x2192; 
(0, &lt;span class="code"&gt;b&lt;/span&gt;) &amp;#x2192; 
(1, e)
&lt;/P&gt;
&lt;P&gt;
Clearly this is the very definition of a mechanical process. 
It's going to get tedious to write out all of the steps in more complex machines.
Let me declare a new "super arrow", which means "yields eventually".
&lt;/P&gt;
&lt;P&gt;
(0, &lt;span class="code"&gt;aab&lt;/span&gt;) &amp;#x21D2; 
(1, e)
&lt;/P&gt;
&lt;P&gt;
I'll use the super arrow to mean "yields in zero or more steps".
Maybe one, maybe a thousand, but some finite number of steps.
&lt;/P&gt;
&lt;P&gt;
What's the point of a DFA?
It's pretty much the simplest thing we can possibly call a computer.
It's got input and output and storage, but is very limited.
The input, sure, it can be as long or as short as you want.
But the output and the storage consists of a single "register" which can only hold one of a finite number of states.
In our example today, we've got only a &lt;i&gt;single bit&lt;/i&gt; of storage and four rules, and we can already accept a fairly complex
language.
&lt;/P&gt;
&lt;P&gt;
If we can reason about the limits of a DFA then we can determine whether a machine with finite storage 
is buff enough to recognize any interesting languages. 
Today's machine recognizes a regular language, and that's a start.
&lt;/P&gt;
&lt;P&gt;
Next time, we'll add a little magic to a DFA.
&lt;/P&gt;

&lt;/div&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=501683" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Regular+Expressions/default.aspx">Regular Expressions</category></item><item><title>Regular Expressions From Scratch, Part Eight: The Diagonal Argument</title><link>http://blogs.msdn.com/ericlippert/archive/2005/12/12/regular-expressions-from-scratch-part-eight-the-diagonal-argument.aspx</link><pubDate>Mon, 12 Dec 2005 18:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:499587</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/499587.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=499587</wfw:commentRss><description>&lt;div class="mine"&gt;

&lt;P&gt;
As we know, each regular expression is associated with a language by our function L. 
We also determined last time that we could list all members of S* and R in order first by length and then
by alphabetical order.
Here's a weird question: is the nth string in S*'s alphabetical ordering a member of the language 
associated with the nth alphabetical regular expression?
&lt;/P&gt;
&lt;P&gt;
Let's make a table and see if we can discern any pattern.
&lt;/P&gt;
&lt;P&gt;
&lt;TABLE FRAME="box"&gt;
&lt;THEAD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;s&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;r&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;s in L(r)?&lt;/span&gt;&lt;/TD&gt;
&lt;/THEAD&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="mine"&gt;e&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;a&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;no&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="code"&gt;a&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;b&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;no&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="code"&gt;b&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;&amp;#x00D8;&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;no&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="code"&gt;aa&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;a*&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;yes&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="code"&gt;ab&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;b*&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;no&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="code"&gt;ba&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;&amp;#x00D8;*&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;no&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="code"&gt;bb&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;a**&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;no&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="code"&gt;aaa&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;b**&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;no&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="code"&gt;aab&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;&amp;#x00D8;**&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;no&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;span class="code"&gt;aba&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="code"&gt;(aa)&lt;/span&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;span class="mine"&gt;no&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TABLE&gt;
&lt;/p&gt;
&lt;P&gt;
We could continue this table forever, of course, and it seems that sometimes, pretty much at random, 
we're going to get a match.
Matches might not be very often, but they will happen from time to time.
As it turns out, it doesn't really matter whether we can come up with some pattern here.
All that matters is that we can answer the question definitively for every possible entry.
&lt;/P&gt;
&lt;P&gt;
Now define the language D such that
D = { w in S* such that w has "no" in the column above }
&lt;/P&gt;
&lt;P&gt;
D = {e, 
&lt;span class="code"&gt;a&lt;/span&gt;,
&lt;span class="code"&gt;b&lt;/span&gt;,
&lt;span class="code"&gt;ab&lt;/span&gt;,
&lt;span class="code"&gt;ba&lt;/span&gt;,
&lt;span class="code"&gt;bb&lt;/span&gt;,
&lt;span class="code"&gt;aaa&lt;/span&gt;,
&lt;span class="code"&gt;aab&lt;/span&gt;,
&lt;span class="code"&gt;aba&lt;/span&gt;,
&lt;span class="code"&gt;abb&lt;/span&gt;, &amp;#x2026; }

&lt;/P&gt;
&lt;P&gt;This is a weird but perfectly well-defined property.
Given &lt;I&gt;any&lt;/I&gt; string we can determine very quickly whether it is a member of D or not. 
Just figure out where on the table it is, compute the nth regular expression, 
and see if it is a member of that regular language. If it is not, then it is in D.
&lt;/P&gt;
&lt;P&gt;
Is there any regular expression that specifies the language D?
&lt;/P&gt;
&lt;P&gt;
Which one would it be?
We've got a &lt;I&gt;complete alphabetical list&lt;/I&gt; of regular expressions, so let's just go down the list.
By our definition of D, clearly it can't be &lt;I&gt;any&lt;/I&gt; of them. 
If the third column is "yes" then the nth regexp matches a string not in D. 
If it is "no" then the nth regexp fails to match a string in D. 
Therefore there is no such regular expression that matches everything in D. 
Therefore D is not a regular language.
&lt;/P&gt;
&lt;P&gt;
By a similar argument we can show that for every nonempty alphabet there exists a language which is not regular.
&lt;/P&gt;
&lt;P&gt;
That's a pretty unlikely example of an irregular language though.
Later we'll see that many perfectly normal languages are not regular, including, ironically enough, 
the regular expression language itself.
&lt;/P&gt;
&lt;P&gt;
Remember that the reason why we came up with regular expressions in the first place is because
we wanted a concise way to characterize languages using short, simple expressions.  
We of course could come up with other mechanical means to cleverly map between strings in one 
alphabet and languages in another, but ultimately it wouldn't do us much good if our aim is to
capture all possible languages. 
The diagonal argument above doesn't depend upon any special features of regular expressions; 
it applies to &lt;i&gt;any&lt;/i&gt; function that maps strings onto languages.
&lt;/P&gt;
&lt;P&gt;
&lt;B&gt;No language description system which maps finite strings onto languages can describe every language.&lt;/B&gt;
&lt;/P&gt;
&lt;P&gt;This is a stunning result; there are languages which we cannot characterize in any finite number 
of symbols, no matter how clever we are with our symbolic manipulations! 
&lt;/P&gt;
&lt;P&gt;
It's simply a fundamental fact that the definition of "language" we've chosen - 
an arbitrary set of finite strings - affords an immense number of possible results, 
more immense than the number of strings in any description language you'd care to name. 
Some - infinitely many - will be indefinable.
&lt;/P&gt;
&lt;P&gt;
You might have noticed a bit of a hand-wave in today's entry: I've made the claim that we can easily
take a regular expression and determine if a string is in its regular language. 
Over the next few entries we'll justify that claim by building some simple abstract machines that can
make this determination.
&lt;/P&gt;

&lt;/DIV&gt;
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=499587" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Regular+Expressions/default.aspx">Regular Expressions</category></item><item><title>Regular Expressions From Scratch, Part Seven: Listing All Members Of A Language In Order</title><link>http://blogs.msdn.com/ericlippert/archive/2005/12/08/regular-expressions-from-scratch-part-seven-listing-all-members-of-a-language-in-order.aspx</link><pubDate>Thu, 08 Dec 2005 18:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:499573</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/499573.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=499573</wfw:commentRss><description>&lt;div class="mine"&gt;

&lt;P&gt;
Regular languages are by definition those languages which can be described by a regular expression. 
It should be clear from the definition that the union of any finite number of regular languages is a 
regular language, the concatenation of any finite number of regular languages is a regular language, 
and the Kleene Closure of any regular language is a regular language.
&lt;/P&gt;
&lt;P&gt;
That's rather a lot of languages. Are &lt;I&gt;all&lt;/I&gt; languages regular languages?
&lt;/P&gt;
&lt;P&gt;
We should have a strong intuition that regular languages are a very limited subset of all languages.
It seems like it would be hard to come up with a finite regular expression that, say, matches the language 
{w is in &lt;span class="code"&gt;1&lt;/span&gt;* such that there are a prime number of 
&lt;span class="code"&gt;1&lt;/span&gt;s in w}.
&lt;/P&gt;
&lt;P&gt;
But we can do better than intuition.
There are many interesting ways to prove that there exists at least one non-regular language.
Over the next couple entries we'll find a non-regular language by using a clever trick. 
The first thing we'll need to do is enumerate every member of a language.
&lt;/P&gt;
&lt;P&gt;
It doesn't really matter how we enumerate the language, as long as we guarantee that we eventually
hit every member of the language. 
Here's one way to do such an enumeration.
&lt;/P&gt;
&lt;P&gt;
Consider an alphabet, say S = {&lt;span class="code"&gt;a&lt;/span&gt;,
&lt;span class="code"&gt;b&lt;/span&gt;}.
We can enumerate all the strings of S* first by length and then by alphabetical order.
Of course, we'll need to define an order for our alphabet, but since alphabets are by definition finite
sets, we can choose any old order. 
In general, for alphabets consisting of Roman alphabet characters and numbers we'll use the standard
alphabetical ordering we're all used to.
We'll start with the one zero-length string, then the two one-symbol strings, then the four two-symbol strings, and so on:
&lt;/P&gt;
&lt;P&gt;
e,
&lt;span class="code"&gt;a&lt;/span&gt;,
&lt;span class="code"&gt;b&lt;/span&gt;,
&lt;span class="code"&gt;aa&lt;/span&gt;,
&lt;span class="code"&gt;ab&lt;/span&gt;,
&lt;span class="code"&gt;ba&lt;/span&gt;,
&lt;span class="code"&gt;bb&lt;/span&gt;,
&lt;span class="code"&gt;aaa&lt;/span&gt;,
&lt;span class="code"&gt;aab&lt;/span&gt;,
&lt;span class="code"&gt;aba&lt;/span&gt;,
&lt;span class="code"&gt;abb&lt;/span&gt;, &amp;#x2026;
&lt;/P&gt;

&lt;P&gt;
(A commenter correctly pointed out that there are languages which cannot be easily enumerated in this 
way, but my coming argument does not rely upon an alphabetical ordering.  
All we need is some schema for enumerating a language which guarantees that we eventually get all of them.)
&lt;/P&gt;
&lt;P&gt;
Consider R, the regular expression language of S. 
We can enumerate it too, first by length and then by alphabetical order. 
Let's say that alphabetical order of R is 
&lt;span class="code"&gt;* ( ) a b &amp;#x00D8; &amp;#x222A;&lt;/span&gt;
just to pick an arbitrary ordering for the symbols. 
We can then enumerate R in the same way like this:
&lt;/P&gt;
&lt;P&gt;
&lt;span class="code"&gt;a&lt;/span&gt;,
&lt;span class="code"&gt;b&lt;/span&gt;,
&lt;span class="code"&gt;&amp;#x00D8;&lt;/span&gt;,
&lt;span class="code"&gt;a*&lt;/span&gt;,
&lt;span class="code"&gt;b*&lt;/span&gt;,
&lt;span class="code"&gt;&amp;#x00D8;*&lt;/span&gt;,
&lt;span class="code"&gt;a**&lt;/span&gt;,
&lt;span class="code"&gt;b**&lt;/span&gt;,
&lt;span class="code"&gt;&amp;#x00D8;**&lt;/span&gt;,
&lt;span class="code"&gt;(aa)&lt;/span&gt;,
&lt;span class="code"&gt;(ab)&lt;/span&gt;,
&lt;span class="code"&gt;(a&amp;#x00D8;)&lt;/span&gt;,
&lt;span class="code"&gt;(ba)&lt;/span&gt;,
&lt;span class="code"&gt;(bb)&lt;/span&gt;,
&lt;span class="code"&gt;(b&amp;#x00D8;)&lt;/span&gt;,
&lt;span class="code"&gt;(&amp;#x00D8;a)&lt;/span&gt;,
&lt;span class="code"&gt;(&amp;#x00D8;b)&lt;/span&gt;,
&lt;span class="code"&gt;(&amp;#x00D8;&amp;#x00D8;)&lt;/span&gt;, &amp;#x2026;
&lt;/P&gt;
&lt;P&gt;
Of course we are leaving out any strings which are not in R, such as
&lt;span class="code"&gt;*&lt;/span&gt; or 
&lt;span class="code"&gt;))(&lt;/span&gt;.
&lt;/P&gt;
&lt;P&gt;
Next time we'll use the fact that we can make both these lists to show that a non-regular language exists.
&lt;/P&gt;

&lt;/div&gt;


&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=499573" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx">Rarefied Heights</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Regular+Expressions/default.aspx">Regular Expressions</category></item></channel></rss>