-1
a) L = {1^i - 1^j = 1^(i-j) | i-j>=0, i,j>=0}  
b) L = {a^i b^j c^k | k!=i+j, i,j,k>=0  

I can't seem to figure out how to implement these procedures. I understand the concept, I just can't seem to work it out. Any help would be great! I've been staring at this stuff for approximately 6 hours, and have gotten nowhere.

Unheilig
  • 16,196
  • 193
  • 68
  • 98
Tiffany
  • 1
  • 2
  • Close voters: I know this question is (a) homework and (b) not a programming problem and (c) lacking any obvious attempt at a solution. However, it comes up over and over again with variations, and I'm trying to provide a canonical duplicate reference. If you feel that this isn't worth the effort, go ahead and close the question. – rici Oct 17 '15 at 04:19
  • Yes it is homework, but I honestly have been trying to figure this out. I've made several attempts, but none that pan out. – Tiffany Oct 17 '15 at 05:18

1 Answers1

1

There are really only a few tricks to solving problems like this, and the same ones come up over and over again. However, the only way to really get them into your head is to solve a few problems, so this answer won't actually solve the homework assignment in the OP. I hope it provides some ideas.

Context-free languages can be composed from other context free languages, and it doesn't really require much thought to see how to write the composition once you know what the composition is. In the following examples, I don't distinguish between non-terminals and context-free languages, because a non-terminal actually defines a context-free language. For example, if L1 and L2 are two CFGs, with productions

L1 → …
L2 → …

then the union L = L1∪ L2 is simply:

L → L1
L → L2
L1 → …
L2 → …

while the concatenation language M = L1L2 is:

M → L1 L2
L1 → …
L2 → …

Now, here are a couple of useful compositions. First, parenthetic balancing. Context-free languages can't count, except that they can count up and then count down. So (n[m]m)n is a context-free language, and it's easy to see that it can be composed by starting with

L1 = [m]m

and then defining

L2 = (nL1)n

using the following simple productions:

L1 → ε
L1 → ( L1 )
L2 → L1
L2 → [ L1 ]

I could have used a, b, c and d instead of the parentheses and brackets, but I think the intent is a bit clearer when you use parentheses.

So that's how to do equality counts. What about inequality? Let's start with a very simple language: the Kleene +. a+ is "one or more as", and the language is straightforward:

L → a
L → L a

Now consider {anbm | n ≠ m}. We can rewrite that as a union:

{anbm | n>m} ∪ {anbm | m>n}

since if m≠n then exactly one of m>n and n>m must be true.

Now look at {anbm | n>m}. Since n is strictly greater than m, we can rewrite anbm as am-nambm. But we don't really care what n-m is, just that it's at least one. So we can use the Kleene + to make am-nambm and that is obviously:

L1 → a
L1 → L1 a
L2 → ε
L2 → a L2 b
L → L1 L2 

The m>n case is very similar, and to get m≠n we just need to find the union of those two languages.

I hope all that was clear.

It's common to provide puzzles like this with odd little algebraic identities. To solve them, you just need to reduce the formulas to the small number of cases shown above, using decompositions like ai+j = aiaj, which is not exactly rocket science.

For example, another SO question asked about the language {anbmc2n+m | n,m > 0}.

Solving it is simple. First, we want to parenthetically match bm, so we need to rewrite c2n+m as cmc2n. That leaves us parenthetically matching an with c2n; to make the two repetition counts the same, we need to change c2n to ccn.

Having rewritten the original as anbmcmccn, it becomes clear that the language is:

L1 → ε
L1 → b L1 c
L2 → L1
L2 → a L1 cc

which is essentially identical to the parenthetic balancing example way at the top of this answer.

rici
  • 234,347
  • 28
  • 237
  • 341
  • For b) I've come up with: S -> A | X A -> B | C B -> Bc | aBc | C C -> Cc | bCc | λ X -> aY | Yb Y -> aY | Yb | aYb | Z Z -> bZc | λ Does that look right? – Tiffany Oct 18 '15 at 02:15
  • @Tifffany: It's clear that Z is b^n c^n. What language is Y? And X? C is b^n c^n c*, but what is B? (By the way, Since B -> C, there is not a lot of point writing both A -> B | A -> C. From A->B and B->C you can derive A->C. That means that A is identical to B, so one of them is redundant.) You should be able to write down the language for each non-terminal, which will make it clear that the end result is (or in this case is not) what you're looking for. – rici Oct 18 '15 at 06:10