證明一個語言不是上下文無關(proving not context-free)
把它想成一場你無論對手怎麼出招都必須贏的對抗賽。你主張語言 L「不」是上下文無關。對手堅稱它是,於是(依幫浦引理)給你一個幫浦常數 p。你的任務是拿出一個 L 中夠長的字串,讓對手隨意切成「五」段——而每一種合法切法一經抽取就離開語言。若你總能贏,就不存在合法的抽取分解,所以 L 不可能是上下文無關。
這套食譜有固定的步驟。第一步:假設 L 是上下文無關,令 p 為它(未知)的幫浦常數。第二步:挑「一個」聰明的字串 z 屬於 L,其長度至少為 p——挑得讓結構僵硬(對 a^n b^n c^n 常選 z = a^p b^p c^p)。第三步:考慮「每一種」把 z 寫成 z = u v x y z' 且滿足 |v y| >= 1 與 |v x y| <= p 的方式。界限 |v x y| <= p 是你的朋友:短窗口 v x y 至多橫跨三個字母塊中的兩個,所以抽取不可能同時抬高三個個數。第四步:在每一種情形下抽取(通常取 i = 2),顯示結果離開 L。既然沒有切法存活,矛盾——L 不是上下文無關。
除了 a^n b^n c^n 之外,兩個經典目標能磨利技巧。複製語言 ww = { w w : w 屬於 {a,b}* }「不」是上下文無關——一個堆疊無法比對兩半,因為堆疊是後進先出的(所以它天然比對的是「反轉」配對如 w w^R,而非順向複製)。而 { a^i b^j c^k : i <= j <= k }「不」是上下文無關——抽取會破壞其中一個不等式。當原始引理不好使(因為對手有一個你排除不掉的「安全」切法),就改用 Ogden 引理,或先用與正規語言取交集來隔離出更乾淨的核心。
證明 a^n b^n c^n 不是上下文無關:取 z = a^p b^p c^p。任何滿足 |v x y| <= p 的切法都表示 v x y 至多碰到三個塊中的兩個,所以抽取到 i = 2 至多增加其中兩個個數。三個個數不再相等,所以抽取後的字串離開語言。沒有切法存活——矛盾。
|vxy| <= p 的界限逼得 v x y 至少漏掉一個塊,所以抽取使個數失衡。
你必須排除「每一種」切法、而不只是一個方便的——這正是初學者出錯之處。並且記得它只能證明「不」屬於 CFL 家族;它無法認證上下文無關性。