proving a language is not context-free
Think of it as an adversary game you must win no matter how your opponent plays. You claim a language L is NOT context-free. The opponent insists it is, and so (by the pumping lemma) hands you a pumping constant p. Your job is to produce a single string in L, long enough, that the opponent can split FIVE ways however they like — yet every legal split, once pumped, leaves the language. If you can always win, no valid pumping decomposition exists, so L cannot be context-free.
The recipe has fixed moves. Step 1: assume L is context-free and let p be its (unknown) pumping constant. Step 2: choose ONE clever string z in L whose length is at least p — pick it so the structure is rigid (a common choice for a^n b^n c^n is z = a^p b^p c^p). Step 3: consider EVERY way to write z = u v x y z' with |v y| >= 1 and |v x y| <= p. The bound |v x y| <= p is your friend: the short window v x y can straddle at most two of the three letter-blocks, so pumping cannot raise all three counts together. Step 4: in each case pump (usually i = 2) and show the result leaves L. Since no split survives, contradiction — L is not context-free.
Two classic targets beyond a^n b^n c^n sharpen the technique. The COPY language ww = { w w : w in {a,b}* } is not context-free — the two halves cannot be matched by one stack, which works last-in-first-out (so it naturally matches REVERSED pairs like w w^R, not forward copies). And { a^i b^j c^k : i <= j <= k } is not context-free — pumping breaks one of the inequalities. When the plain lemma is awkward (because the opponent has a 'safe' split you cannot rule out), reach for Ogden's lemma or for intersection with a regular language to first isolate a cleaner core.
Prove a^n b^n c^n is not context-free: take z = a^p b^p c^p. Any split with |v x y| <= p means v x y touches at most two of the three blocks, so pumping to i = 2 increases at most two of the counts. The three counts are no longer equal, so the pumped string leaves the language. No split survives — contradiction.
The |vxy| <= p bound forces v x y to miss at least one block, so pumping unbalances the counts.
You must rule out EVERY split, not just one convenient one — that is where beginners slip. And remember it only proves NON-membership in the CFL family; it cannot certify context-freeness.