Friday, April 15, 2011

Regular Expressions and State Machines

I recently found out that some of my colleagues did not know (much) about regular expressions or state machines.  These are amazingly useful concepts that I use on a daily basis, so I thought I'd try to set down everything you need to know about these subjects in one page (or thereabouts).

Regular Expressions for Searching

The most common use of regular expressions is for searching through text files.  For example, if I wanted to search my source code for all class definitions that include the word 'Collection' in their class names, I would search on the following regular expression: 'class .*Collection'.  This is read as "the word class, followed by a space, followed by zero or more of (*) any character (.), followed by the word Collection".  That is, most characters are interpreted literally in a regular expression, but some are treated specially (e.g., '.' and '*').

Here's the typical core grammar of regular expressions (I use a, b, c to denote non-special characters and x, y, z to denote arbitrary regular expressions):
  • a -- the regular expression matching the (non-special) character 'a';
  • xy -- the regular expression matching x followed by y;
  • (x) -- the regular expression matching x (it is sometimes useful to treat a complex regular expression as a single item);
  • x|y -- the regular expression matching x or y;
  • x* -- the regular expression matching zero or more instances of x;
  • nil -- the regular expression matching the empty string (which in practice is just written as the empty string, rather than 'nil').
So, for example, the regular expression '(aa|bb)*c' matches any sequence of aa or bb pairs, followed by a c.  That is, the language recognised by '(aa|bb)*c' consists of the strings {c, aac, bbc, aaaac, aabbc, bbaac, bbbbc, ...}.

In practice, the language of regular expressions is extended with plenty of syntactic sugar.  Here are some standard extensions:
  • x+ -- the regular expression matching one or more instances of x (i.e., x+ = xx*);
  • x? -- the regular expression matching zero or one instance of x (i.e., x? = (x|nil);
  • [abc] -- the regular expression matching any of the characters a, b, or c;
  • [a-f] -- the regualar expression matching any of the characters in the range a..f;
  • [^abc] -- the regular expression matching any character that is not a, b, or c;
  • [^a-f] -- the regular expression matching any character that is not in the range a..f;
  • ^ -- the regular expression matching the start of a line of text;
  • \$ -- the regular expression matching the end of a line of text;
  • \a -- the regular expression matching the escape sequence a (e.g., \* matches a literal *, \t matches a tab character, \( matches an open parenthesis, etc.)
There are many more (see, e.g., http://msdn.microsoft.com/en-us/library/az24scfc(v=VS.100).aspx for the .NET 4 regular expression language).

Learning these is easy and really, really useful!

State Machines

Imagine a machine with a set of lights.  Each light is called a state and the machine is called a state machine.  When the machine is started, it always starts with a particular light on (all other lights are off); this is the start state.

The machine takes as input a sequence of symbols of some type (e.g., characters, GUI events, messages, whatever you like.).  As each symbol is read by the machine, which light is shining changes depending on which light was shining just before the new symbol was read and on what particular symbol was just read in.  For example, if the machine is in state 3, say (i.e., light number three is on) and the next symbol read in is a 'q', then light 3 might turn off and light 7 might come one (i.e., reading a 'q' when in state 3 causes the machine to change to state 7).  The machine has a transition rule like this for every possible input for every possible state.

Each of the lights on the machine is either red or green.  The green lights denote accepting states and the red lights denote non-accepting states.  If the input sequence finishes with the machine showing a green light, then the input sequence was accepted by the state machine.  Otherwise the input sequence was not accepted.

The language accepted by the state machine is the set of input sequences that leave it in an accepting state.  In fact, every regular expression has a corresponding state machine and vice versa -- they are two ways of describing the same thing!

For example, here's a state machine to match our earlier pattern (aa|bb)*c:

State Input Next state
s1 [start] a s2
b s3
c s4
(...) s5
s2 a s1
(...) s5
s3 b s1
(...) s5
s4 [accepting] (...) s5
s5 [error] (...) s5

Observe the inclusion of an error state (s5) which, like the Hotel California, you can never leave. This state just ensures that the state machine never enters an accepting state once the input has differed from the pattern we are trying to match.

[Aside: the fancy name for what I've just described is a deterministic finite automaton or DFA.]

Deterministic and Non-deterministic State Machines

The state machine described above is deterministic, meaning it is only ever in one state and each state transition is defined entirely by the current state and the next symbol to be read.  This is a very useful notion for designing programs that have to process sequences.

One can also imagine a nondeterministic state machine.  Such a machine would works like this: at any point, any collection of lights can be on (i.e., the machine could be in any one of these states given the input so far). The transition rules are relaxed so that each state can have multiple possible successors for each input, plus have the option of having successor states that can be reached without consuming any input at all.  For example, the transition rules for state 3 might say "move to state 7 after reading a 'q' or move to state 8 after reading a 'q' or move to state 9 without reading anything".  So, for our non-deterministic state machine, if light 3 is one of the lights that is currently on, then light 9 must also be on (because it is a "no input" successor to 3); also, if a 'q' is read next, then both lights 7 and 8 will come on.

Why is this idea useful?  Well, here's the magic: you can always turn a non-deterministic state machine into a deterministic state machine (how this magic happens is a little beyond the scope of this article, but the starting point is to imagine every possible subset of lights on the non-deterministic state machine as corresponding to a single state on the equivalent deterministic state machine).

It's easy to see how to construct a deterministic state machine that handles simple sequences of symbols or repetition of simple sequences, the tricky bit is handling alternation (i.e., regular expressions of the form x|y).  The easiest way of constructing a state machine to match x|y is to construct a non-deterministic state machine from the two state machines for recognising x and y (hopefully you can imagine how this might be done without too much difficulty), then we can turn that into a deterministic state machine.

In practice, textual regular expressions are typically just compiled into representations of their non-deterministic state machines and the matching algorithm simulates all possible state transitions at each point.  This is actually quite effective, since the cost of searching a string of m characters with an n state machine is just O(mn) (and typically much less).

What Can't Regular Expressions Match?

Roughly speaking, regular expressions can't match any pattern that requires counting to arbitrarily large numbers.  For example, you can't write a regular expression that checks whether the parentheses ( ) in a program are properly balanced, because a program can contain any number of parentheses.  

[What follows is for extra credit.]

There is something called the pumping lemma, which says that for any state machine with n states that accepts some input of length n or more symbols, then that input can be written somehow as xyz (where y is a non-empty sequence and the length of xy is at most n) and the machine must also accept all patterns of the form xy*z (i.e., the machine had to go through at least one loop while recognising the y part in xyz).  

How does this relate to counting patterns?  Well, let's say we did claim to have a state machine with 4 states that matched all and only programs with properly balanced parentheses.  Now consider the balanced input sequence '((((a))))', which our state machine duly accepts.  The pumping lemma tells us that this must be decomposable as some xyz where y is non-empty and the length of xy is at most 4.  Well, we only have four possibilities for x and y here -- it doesn't matter which one we end up with.  Let's say the answer happens to be x = '(((' and y = '(' -- leaving z = 'a))))'.  The pumping lemma says that our machine must accept all strings of the form xy*z, which clearly includes just xz, namely '(((a))))', which is clearly not balanced!  Therefore our claim must be wrong: our 7 state machine does not match all and only well balanced programs.  Since there is nothing in our argument that really depends on the 4 states starting point, the same thing must be true for any number of states that a parenthesis-matching state machine might have.  Therefore, there is no regular expression (or state machine) that matches all and only well balanced programs.  If you don't believe me, I encourage you to have a go at designing such a state machine!

I find all this stuff really rather beautiful.

What About Counting Support in Modern Regular Expressions?


Modern textual regular expressions usually include some support for counting, such as x{40,70} meaning "between 40 and 70 instances of the pattern x".  This functionality comes at a cost: since the size of the equivalent ordinary regular expressions for these "counting" patterns quickly grows out of hand, they are implemented using backtracking pattern matchers.  These are exponentially slower than non-deterministic state machines and it is easy to construct pathological search patterns that will cause these matching algorithms to take forever.

Further Reading


Here is a brilliant paper on implementing regular expression matchers.

Thursday, March 24, 2011

Bayes' Theorem

I recently read this beautiful explanation of Bayes’ theorem.  I’d always thought it was a statement of philosophy, but it isn’t: it comes from plain old probabilities.

The formula for the conditional probability of A being true given that B is true is

P(A | B) = P(A & B) / P(B)

That is, the proportion of things that are A that are in B is equal to the fraction of the proportion of things that are A and B over the proportion of things that are B (I like to think of these things in terms of Venn diagrams).

We can rearrange the above to get

P(A & B) = P(A | B).P(B)

Now for Bayes’ theorem: let’s write H for our hypothesis and E for our evidence.  We want to know how seeing the evidence E affects the probability of our hypothesis H being true.  From the first rule above we have

P(H | E) = P(H & E) / P(E)

Now we can apply the second rule to P(H & E) to get

P(H | E) = P(E | H).P(H) / P(E)

Et voila!  No magic at all.

As an aside, the raven paradox has convinced me that Bayesianism is philosophically superior to frequentism.

Monday, January 10, 2011

Debugging WCF

I'm relatively new to the world of Microsoft foundation libraries.  For the most part I am impressed, but I cannot understand the idea of development libraries doing their best to hide errors from you unless you first speak the magic rites (I would have thought there ought to be magic rites to cause error hiding, not the other way around).  Anyway, WCF -- Windows Communications Foundation -- is a pretty good RPC system which has this property.  To turn on tracing so you can debug your application, follow this advice:
After some Live Searching (i was actually googling, but let’s make Microsoft think at least someone outside of Redmond uses Live Search) i discovered that you can enable WCF tracing. Bingo! Why didn’t Juval Lowy’s book mention this? It’s supposed to be the WCF Bible…. Oh well, thanks to Google, i mean Live Search, we now know how to enable WCF’s tracing:

  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="wcfTraceListener" type="System.Diagnostics.XmlWriterTraceListener"initializeData="WcfTrace.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

You can also use the Service Configuration Editor tool which is available in the Windows SDK, but spare yourself the pain of that tool and just copy/paste this xml in your config file.
Now run the service again, and do whatever it was that triggered the weird client-side exception. After the exception occurred, open the WcfTrace.svclog file with either an editor (it’s not very readable though) or with the Microsoft Service Trace Viewer tool (which is not too bad actually).

Thursday, December 09, 2010

Mark Twain

A Plan for the Improvement of English Spelling
by Mark Twain


For example, in Year 1 that useless letter "c" would be dropped to be replased either by "k" or "s", and likewise "x" would no longer be part of the alphabet. The only kase in which "c" would be retained would be the "ch" formation, which will be dealt with later. Year 2 might reform "w" spelling, so that "which" and "one" would take the same konsonant, wile Year 3 might well abolish "y" replasing it with "i" and Iear 4 might fiks the "g/j" anomali wonse and for all. Jenerally, then, the improvement would kontinue iear bai iear with Iear 5 doing awai with useless double konsonants, and Iears 6-12 or so modifaiing vowlz and the rimeining voist and unvoist konsonants. Bai Iear 15 or sou, it wud fainali bi posibl tu meik ius ov thi ridandant letez "c", "y" and "x" -- bai now jast a memori in the maindz ov ould doderez -- tu riplais "ch", "sh", and "th" rispektivli. Fainali, xen, aafte sam 20 iers ov orxogrefkl riform, wi wud hev a lojikl, kohirnt speling in ius xrewawt xe Ingliy-spiking werld.

Tuesday, November 16, 2010

.NET: IEnumerable is *not* lazy

Just spent ten minutes working this one out.

If you have a variable

IEnumerable<Foo> SomeFoos = [...LINQ expression returning an enumerable...];

and then do this

foreach (var foo in SomeFoos) { [...update foo...] }

you will almost certainly not see any changes in the values in SomeFoos.  Why not?  Because each time you iterate through SomeFoos, the enumerator is run again, quite possibly recreating each item.

A solution is to force each item in SomeFoos to be manifested once.  For example,

List<Foo> SomeFoos = [...LINQ expression returning an enumerable...].ToList();

Now things will work as expected.

[N.B.  When I say "laziness", I refer to the standard functional programming practice of replacing an evaluated thunk with the result, thereby avoiding any repeated processing effort on subsequent reads of the thunk.]

Thursday, November 11, 2010

WPF: Making ListBoxItems stretch the width of the ListBox

This is unbelievably hard for something which must be universally desired.

By default, ListBoxItems occupy the width required by their contents, not by the width of the containing ListBox.  This causes your optimistically formatted columns in each ListBox to fail to align.

Instead, add this in the Resources section:


<Style x:Key="StretchingListBoxItemStyle" TargetType="ListBoxItem">
  <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>


and add ItemContainerStyle="{StaticResource StretchingListBoxItemStyle}" to your ListBox attributes.

Strewth.

Friday, October 01, 2010

Making things stretch in WPF

I quote from a StackOverflow reply by one Matt Hamilton:
There are also some properties you can set to force a control to fill its available space when it would otherwise not do so. For example, you can say:
HorizontalContentAlignment="Stretch"
... to force the contents of a control to stretch horizontally. Or you can say:
HorizontalAlignment="Stretch"
... to force the control itself to stretch horizontally to fill its parent.
That should come in handy in future.

Thursday, September 30, 2010

Synchronization in .NET: ManualResetEvents and Monitors

I recently needed to simultaneously wake an arbitrary number of waiting threads, each waiting on some condition.  My first approach was to have a shared ManualResetEvent, a subclass of EventWaitHandle with the property that "Once it has been signaled, ManualResetEvent remains signaled until it is manually reset. That is, calls to WaitOne return immediately." (MSDN docs.)  [.NET also has AutoResetEvents, but with these only one waiting thread is woken when the event is signalled.]

The idiom I was using was this: I had a global ManualResetEvent called WakeUp; threads waiting on the condition would call WakeUp.WaitOne() (causing them to sleep until...); a thread identifying the waking condition would call WakeUp.Set(); WakeUp.Reset().  My reading of the MSDN documentation is that the call to Set() should wake all waiting threads, while the call to Reset() should reset the event handle for the next wake-up signal.

Tragically, this did not work and my program would randomly flounder.  If I added a delay between the Set() and Reset() calls, the likelihood of floundering reduced, but wasn't eliminated -- and, besides, that is too disgraceful a hack to contemplate for more than a moment.

The right solution was to use a Monitor.  The idiom here is as follows:

For Threads Waiting On Some Condition


Monitor.Enter(SyncObj);
while (!condition) { Monitor.Wait(SyncObj); }
Monitor.Exit(SyncObj);


which can be abbreviated to


lock (SyncObj) {
  while (!condition) { Monitor.Wait(SyncObj); }
}

For Threads Establishing Some Condition


Monitor.Enter(SyncObj);
// Establish condition.
Monitor.PulseAll(SyncObj);
Monitor.Exit(SyncObj);


which can be abbreviated to


lock (SyncObj) {
  // Establish condition.
  Monitor.PulseAll(SyncObj);
}


Peace at last...  (For the curious, in this particular application it would not have been sensible to set up a separate event handle for each condition, which is what one would normally do.)

Wednesday, September 22, 2010

State Machine Compiler

I've just read about SMC, an open source state-machine compiler targetting multiple languages, including C#.  I can see this coming in rather handy.

Monday, September 13, 2010

Trouble with nulls

Following a conversation with a colleague, I have decided to put to paper what I think is wrong with nulls.

Essentially, this: to the compiler, null means "uninitialised".  It is the default value given to references.

As programmers, however, we invariably overload null with other meanings, such as "the empty list", "the empty string", "the unspecified option", and so forth.

This is bad, because I want the tools (compiler, debugger, etc.) to tell me the difference between "I have forgotten to initialise this variable" and "I have put the wrong value in this variable".

As it is, I end up with a bastardised mixture of meanings in my code requiring a lot of checking that would otherwise be redundant.

Maybe code contracts will be able to clean up this mess...

Monday, September 06, 2010

Equality in C#

Here is a good article on the subject.

I wish, I wish, I wish that C# had ditched nulls and default reference equality; that's such a 1960s resource limited way of thinking.  Equality should mean structural equality by default; one should have to explicitly ask for reference equality or nullable types.

Oh well, here's the summary:

  • Implement IEquatable.Equals(T).
    • Remember to check for null and reference equality.
  • Override object.Equals(object).
  • object.Equals(object, object) does what you expect by first testing for nulls and reference equality.
  • Override object.GetHashCode.
  • If you implement == (reference equality by default), also implement !=.
  • Implement the == and != operators for value types to avoid the need for boxing.

Wednesday, September 01, 2010

WPF and XAML

WPF is Windows Presentation Foundation.  It seems like a first class framework to me.

XAML is Microsoft's eXtensible Application Markup Language.  It is a way of describing user interfaces in XML.  It is rich and powerful.

But, why, in the name of all that is holy, is it not composable?!  For the life of me, I cannot understand why a fragment X works as expected in context Y, but not in context Z.  Nor does the documentation I have been wading through (as in, trying to make progress through the Augean stables) been of any help.  The whole of the net is filled with anecdotal solutions to common problems with, so far, not one whit of a general set of principles to help guide one through the quagmire of UI development using XAML.  I am giving serious consideration to not using it on my next project, but rather coding everything up directly in C#.  I would put money on this being vastly more productive.

I have just ordered a book on the subject that sounds as though it will explain things to my satisfaction ("Applications = Code + Markup" by Charles Petzold, who is apparently something of a luminary).  Of course, this being a modern programming book it doubles as a keep-fit device, weighing in at something over 1000 pages.

Tuesday, August 10, 2010

PowerTab for PowerShell

PowerShell is excellent.

The default command line environment was obviously written by a bunch of monkeys (who on Earth wants to block select rectangles of text rather than lines of text?).

PowerTab is a module that goes some way towards fixing the woeful keep-tabbing-until-you-hit-the-completion-you-want tab-completion behaviour.

Thursday, August 05, 2010

Dates and Times and Timezones and .NET

Yesterday I learned something about parsing dates and times.  I was trying to get a .NET application to process date/time strings of the form "2010-08-04T16:30:00 CEST" using DateTime.TryParse.  This approach didn't work because .NET doesn't grok timezone strings like "CEST" (Central European Summer Time).

My first thought was that since CEST is defined as UTC+2 (i.e., Universal Coordinated Time plus two hours), I could rewrite these date/time strings as "2010-08-04T16:30:00+02:00", which DateTime.TryParse can handle (note that the timezone delta on the end must be subtracted from the preceding date/time to obtain UTC).  My attempts to tackle this were stymied by the fact that timezone names are not unique.  For example, CST can mean either Central Summer Time or Central Standard Time, and that's just in Australia!

So, to conclude, for the love of all that is holy, don't use timezone names in your date/time strings.  Use attached UTC deltas instead.

[For those who are wondering, as I did, the difference between UTC and GMT is never allowed to exceed 0.9s; UTC is atomic clock time with some leap seconds added here and there; GMT is not.]

Thursday, July 29, 2010

DNS Problems with Blizzard's StarCraft II Patch Installer

After much anticipation, my copy of StarCraft II arrived in the post yesterday.  I installed it.  I ran it.  It immediately started downloading a patch.  Ten megabytes later, I lost all internet connectivity.  Again, again, and a-bloody-gain.  Now, it turns out I had recently upgraded to Windows 7, a thing of beauty, which automatically ran a network diagnostic tool and reported that there was a problem with the DNS service.  Hmm, thinks I, maybe iiNet (who are my otherwise rather good ISP) have cocked up their DNS server.  After a bit of resettery, I discover that Google have a publically available DNS server (8.8.8.8).  I add this as the backup DNS server and, lo and behold, glorious sustained connectivity.

Having shared this with you, I am now about to abandon society and join the StarCraftiverse for some time.  Adieu.

Friday, June 25, 2010

Changing Jobs!

After nine excellent years at the University of Melbourne, I'm leaving to take up a new position as a senior software engineer at an IT firm in the heart of Melbourne.  I'll miss working with everyone at the University, but I'm also very excited about the new challenge.  The chaps here had a whip-round and bought me a 1997 Speyside single malt.  FANTASTIC!  This bottle is what I believe is cask strength, at nearly 60% alchohol, and will have to be approached with caution.

Farewell drinks tonight!