At this point, we’ve seen a fair bit about regular languages, and we’ve gone through the introduction to context free languages. We know one way of showing that a language is regular or context free: if you can write a (regular/context free) grammar for a language, then that language is necessarily (regular/context free). But… what if we have a language that we suspect is not regular?
Suppose, for example, that we have a context free grammar for a language. The fact that we specified it using a context free grammar doesn’t mean that the language requires a context-free grammar. Sometimes it’s easier to write things with a CFG, even if it’s possible to write them with a regular grammar. We suspect that it really can’t be done using a regular grammar – but we’re not sure. Just because we think that we can’t write a regular grammar for the language doesn’t mean anything. It’s possible that we’re wrong – that there’s some way of writing an alternative grammar that’s regular. So.. how can we actually show that a language isn’t regular? (Or stepping up a level, that a language isn’t context free?)
There’s a clever tool called the pumping lemma, which we can use to show that a language isn’t regular. (And there’s a variation of it that can be used to show that a language isn’t context free.) What it does is exploit a simple property of a regular language in a way that allows us to use it to show that a language isn’t regular.
One of the fundamental limits of a regular language is that it can’t have deep patterns. It’s built one terminal symbol at a time, from left to right, without being able to look back at context. That’s essentially the process that we’re going to exploit. What the pumping lemma says is: given a language , if we take any string in above a grammar-specific minimum length, then that string will consist of three parts – a prefix (a), a center (b), and a suffix (c). If the string is in , then any string that repeats the center part any number of times will also be part of . So we can pump the language: will be in ; will be in the language; will be in the language, and so on. If we can find any string in where there’s no pumpable center, then isn’t regular.
Let’s make it more formal, so that we can be precise. We need one quick notational thing – we’ll write the length of string as . With that, the pumping lemma says:
If is a regular language, then there exists an integer that depends solely on the structure of , such that for every string , if , can be described in terms of substrings , , and such that:
Now, how do we use this? Let’s look at how it works on the canonical example of a non-regular language: – a string which has a string of s, followed by the same number of s.
Let’s assume that this language is regular. We know that there must be some integer , and that for anything longer than , some part of any string longer than must be pumpable.
So, let’s take the string . By the pumping lemma, we know that sum of the lengths of the prefix and the middle of the string have to be less than or equal to . So the prefix, , is any sequence of s; we’ll say it’s length is where ; and the middle, has to be a sequence of at least one – it’s s, and . That is, we’ve broken the string into .
So if the language is regular, then we must be able to say that is in the language. So must be in the language. If we simplify that, must be in the language. But s than s. That means that the language can’t be regular, because pumping it produced a string that’s not in the language.
One thing to be aware of – a mistake I made far too often in my first class that covered this – is that the fact that a language is pumpable does not mean that the language is regular. All regular languages are pumpable, but not all pumpable languages are regular. If you can’t pump a language, you’ve proved it’s not regular. But the fact that you can pump it doesn’t tell you anything. If you want to prove that a language is regular, you have to either show a regular grammar, a regular expression, or a FSA that describes the language.
The regular language pumping lemma that I showed above is really easy to use. It takes a bit of practice to get comfortable choosing the basic structure of a string to pump – but the proofs are pretty much always as short as the one above. For context free languages, the basic concept is similar: you exploit the structure of the class of languages to find a structure that can be repeated – and then you show that your language of interest doesn’t contain that sort of repetitive structure. But since CFLs are a lot more expressive, and can describe more complex structures, the repetitive structure that you exploit is, similarly, more complicated.
The context free pumping lemma says:
If is a context-free language, then there exists some integer suth that for any string , , can be divided into substrings such that:
So… Instead of just having a prefix, a middle, and a suffix, we’ve now got five subtrings. There are two repeated parts, instead of just one, and there can be something in between them. And we’re pumping repetitions of both the front and the back. So if , then , and , and so on.
It is more complicated than the regular language pumping lemma, but it’s still not awful. And proofs in it end up looking very much like the proofs with the regular language pumping lemma. For example, we could look at the language , which is a canonical example of a non-context-free language. The proof of that ends up being nearly exactly the same as the proof for for the context free languages. We set up the string so that both and must be 2s. Then we pump it, and show that we end up with more 2s than 3s.