可判定性與可識別性

上下文無關成員問題(the context-free membership problem)

給定一個上下文無關文法與一個字串,這個文法究竟能不能產生那個字串?這就是上下文無關語言的成員問題:A_CFG = {(G, w) : G 是一個能產生 w 的 CFG}。它其實是剖析問題的化身——「這個句子能不能由這些規則造出來?」——而它有一個保證會停機的答案,儘管一個粗心的作法可能會永遠嘗試越來越長的推導而停不下來。

天真地,你也許會不斷套用規則、希望抵達 w,但文法可以有「先把字串拉長、再縮短」的規則,因此推導可以無界地成長,盲目搜尋可能永不停止。乾淨的補救是把文法化為喬姆斯基正規形式(Chomsky normal form, CNF),其中每條規則都是 A -> BC 或 A -> a。在 CNF 中,長度為 n 的字串恰好由 2n - 1 步推導產生(n 至少為 1),所以只有有限多個推導要考慮,原則上你能全部檢查。實務上遠勝一籌的是 CYK 演算法(Cocke–Younger–Kasami):它填一張三角形的表,每格記錄「哪些變數能產生 w 的某個子字串」,由單一符號逐步往上建到越來越長的片段,最後檢查起始符號能否產生整個字串。CYK 在固定文法上以 O(n^3) 時間執行,且總會停機。

所以 A_CFG 是『可判定』的——上下文無關成員問題總能了結。這是剖析的演算法骨幹:每當編譯器或直譯器判定你的原始碼是否符合語言的文法,它就是在解這個問題的一個實例,而「程序會停機」這個保證,正是讓編譯器能可靠地回報「語法錯誤」或「沒問題」的依據。它也把上下文無關語言釘在了溫馴地圖上的位置:成員(這裡)與空語言(E_CFG)都可判定,儘管 CFG 的等價性與歧義性都不可判定。

對「平衡括號」文法與輸入 ()(),CYK 的表逐步建起:每一對 () 被辨識為一個平衡片段,接著兩個片段合併成整體。頂端那格顯示起始符號能產生 ()(),於是接受。對 )( 而言,表中從不讓起始符號涵蓋整個字串,於是拒絕——而無論哪種情形它都會停機。

CYK 填一張「哪些變數產生哪些子字串」的表——總會停機,O(n^3)。

盲目嘗試推導可能迴圈,因為文法可能先把字串拉長再縮短。化為 CNF 會把推導長度限住(2n-1 步),這正是成員問題可判定的原因;CYK 則高效地做到這件事。

又称
A_CFGCFL membershipdoes this grammar generate this stringis w in L(G)