কনটেক্সট-ফ্রি ল্যাঙ্গুয়েজের ক্লোজার প্রপার্টি
এই পাঠে যা শিখবেন
- CFL কোন কোন অপারেশনের নিচে ক্লোজড — ইউনিয়ন, কনক্যাটেনেশন, ক্লিনি স্টার — ও প্রতিটির গ্রামার-কম্বিনেশন প্রমাণ
- কেন ইন্টারসেকশন ও কমপ্লিমেন্টের নিচে CFL ক্লোজড নয় — একটি কনক্রিট, কোড-ভেরিফায়েড কাউন্টার-এক্সাম্পল
- De Morgan's law দিয়ে কীভাবে ইন্টারসেকশন-নন-ক্লোজার থেকে কমপ্লিমেন্ট-নন-ক্লোজার সরাসরি অনুসরণ করে
- কেন CFL রেগুলার ল্যাঙ্গুয়েজের সাথে ইন্টারসেকশনের নিচে তবুও ক্লোজড — PDA×DFA প্রোডাক্ট
১ · CFL যেসব অপারেশনের নিচে ক্লোজড
ক্লোজার প্রপার্টিClosure Propertyএকটি নির্দিষ্ট অপারেশন কোনো ভাষা-শ্রেণির (যেমন CFL) সদস্যদের ওপর প্রয়োগ করলে ফলাফলও সেই একই শ্রেণিতে থাকে কি না, তা যাচাই করে। প্রশ্ন করে — একটি নির্দিষ্ট অপারেশন CFL-এর ওপর প্রয়োগ করলে ফলাফলও কি নিশ্চিতভাবে CFL হয়? M4-এর CFG-কম্বিনেশন টেকনিক দিয়ে সরাসরি প্রমাণ করা যায় CFL তিনটি অপারেশনের নিচে ক্লোজড —
- ইউনিয়ন: $L_1, L_2$ এর জন্য CFG $G_1=(V_1,\Sigma,R_1,S_1)$, $G_2=(V_2,\Sigma,R_2,S_2)$ থাকলে, একটি নতুন স্টার্ট সিম্বল $S$ যোগ করে $S \to S_1 \mid S_2$ রুল দিয়ে কম্বাইন্ড গ্রামার বানানো যায় — $L(G) = L_1 \cup L_2$।
- কনক্যাটেনেশন: একইভাবে $S \to S_1S_2$ — $L(G) = L_1L_2 = \{xy : x\in L_1, y\in L_2\}$।
- ক্লিনি স্টার: $S \to S_1S \mid \varepsilon$ — $L(G) = L_1^*$।
তিনটি ক্ষেত্রেই কৌশলটি একই — আলাদা গ্রামারের স্টার্ট সিম্বলগুলোকে একটি নতুন রুল দিয়ে জোড়া লাগানো, ঠিক যেভাবে L11-এ regex-কম্পোনেন্ট কম্বাইন করা হয়েছিল। যেহেতু $V_1, V_2$ ডিসজয়েন্ট রাখা যায় (দরকার হলে ভেরিয়েবল রিনেম করে), কম্বাইন্ড গ্রামারটি বৈধ থাকে।
২ · কেন ইন্টারসেকশন ও কমপ্লিমেন্টের নিচে CFL ক্লোজড নয়
এখানেই CFL রেগুলার ল্যাঙ্গুয়েজ (M3/L12) থেকে গুরুত্বপূর্ণভাবে আলাদা হয়ে যায়। রেগুলার ল্যাঙ্গুয়েজের ইন্টারসেকশন ক্লোজার DFA-প্রোডাক্ট কনস্ট্রাকশন দিয়ে প্রমাণ হয়েছিল — কিন্তু PDA-দের জন্য একই কৌশল খাটে না, কারণ দুটো PDA-এর স্ট্যাক একসাথে ট্র্যাক করতে গেলে একটিমাত্র স্ট্যাকের প্রয়োজন হয়, যা সাধারণভাবে সম্ভব নয়।
$L_1 = \{a^nb^nc^m : n,m \geq 0\}$ — সহজ CFG দিয়ে তৈরি (প্রথমে সমান a-b জোড়া, তারপর যেকোনো সংখ্যক c)।
$L_2 = \{a^mb^nc^n : n,m \geq 0\}$ — একইভাবে সহজ CFG (প্রথমে যেকোনো সংখ্যক a, তারপর সমান b-c জোড়া)।
দুটোই আলাদাভাবে সরল, unambiguous CFG দিয়ে জেনারেট করা যায় — উভয়েই CFL। কিন্তু
$L_1 \cap L_2 = \{a^nb^nc^n : n \geq 0\}$ — ঠিক সেই ভাষা যা
L26-এর পাম্পিং লেমা প্রয়োগ করে
context-free নয় বলে প্রমাণিত হয়েছে। সুতরাং দুটো CFL-এর ইন্টারসেকশন CFL না-ও হতে পারে —
CFL ইন্টারসেকশনের নিচে সাধারণভাবে ক্লোজড নয়।
কমপ্লিমেন্ট: De Morgan's law থেকে সরাসরি অনুসরণ করে — $L_1 \cap L_2 = \overline{\overline{L_1} \cup \overline{L_2}}$। যদি CFL কমপ্লিমেন্টের নিচে ক্লোজড হতো, তাহলে উপরের ইউনিয়ন-ক্লোজার (§১) এর সাথে মিলিয়ে CFL ইন্টারসেকশনের নিচেও ক্লোজড হয়ে যেত — কিন্তু আমরা এইমাত্র দেখলাম সেটা সত্যি নয়। সুতরাং, বিপরীতক্রমে (contrapositive), CFL কমপ্লিমেন্টের নিচে ক্লোজড হতে পারে না — একটি পরিষ্কার, পরোক্ষ (indirect) প্রমাণ যা আগে থেকে প্রতিষ্ঠিত সত্য পুনরায় ব্যবহার করে।
৩ · ব্যতিক্রম — রেগুলার ল্যাঙ্গুয়েজের সাথে ইন্টারসেকশন এখনও কাজ করে
যদিও CFL সাধারণ ইন্টারসেকশনের নিচে ক্লোজড নয়, একটি গুরুত্বপূর্ণ, ব্যবহারিকভাবে দরকারি বিশেষ ক্ষেত্র আছে — একটি CFL-কে যদি একটি রেগুলার ল্যাঙ্গুয়েজM2-M3-এ প্রতিষ্ঠিত, DFA/NFA দিয়ে চেনা ভাষার শ্রেণি-এর সাথে ইন্টারসেক্ট করা হয়, তাহলে ফলাফল আবারও CFL হয়। কারণ — একটি PDA (CFL-এর জন্য) এবং একটি DFA (রেগুলার ভাষার জন্য) একসাথে চালানো যায় — M3/L12-এর DFA-প্রোডাক্ট কনস্ট্রাকশনের সরাসরি সম্প্রসারণ — DFA-এর ফাইনাইট স্টেট সেট শুধু PDA-এর স্টেট সেটের সাথে মাল্টিপ্লাই হয় (স্ট্যাক অপরিবর্তিত থাকে, শুধু একটি স্ট্যাকই দরকার হয়) — accept হয় যখন উভয় কম্পোনেন্ট accept করে।
৪ · কোড: কাউন্টার-এক্সাম্পল কোড দিয়ে যাচাই
নিচের কোডে $L_1=\{a^nb^nc^m\}$ ও $L_2=\{a^mb^nc^n\}$-এর জন্য আলাদা CFG বানিয়ে, প্রতিটি একটি length bound পর্যন্ত জেনারেট করে, তাদের SET ইন্টারসেকশন হিসাব করে, এবং নিশ্চিত করা হচ্ছে ফলাফল ঠিক $\{a^nb^nc^n\}$-এর সাথে মিলে যায় — একটি জেনুইন, কোড-ভেরিফায়েড প্রমাণ, কোনো hardcoded ফলাফল নয়।
# CFL ইন্টারসেকশন-নন-ক্লোজারের কনক্রিট প্রমাণ
# G1: {a^n b^n c^m} -- আগে সমান a-b জোড়া, তারপর স্বাধীনভাবে c
# G2: {a^m b^n c^n} -- আগে স্বাধীনভাবে a, তারপর সমান b-c জোড়া
from collections import deque
def is_variable(sym, grammar):
return sym in grammar
def generate_language_up_to_length(grammar, start, max_length):
"""L17-স্টাইলের BFS ডেরিভেশন-সার্চ -- প্রতিটি সেন্টেনশিয়াল ফর্মের
বামতম ভেরিয়েবল এক্সপ্যান্ড করে, টার্মিনাল-কাউন্ট max_length ছাড়ালে prune করে।"""
results = set()
seen_forms = {(start,)}
queue = deque([(start,)])
while queue:
form = queue.popleft()
idx = next((i for i, s in enumerate(form) if is_variable(s, grammar)), None)
if idx is None:
s = ''.join(form)
if len(s) <= max_length:
results.add(s)
continue
var = form[idx]
for production in grammar[var]:
new_form = form[:idx] + tuple(production) + form[idx + 1:]
terminal_count = sum(1 for s in new_form if not is_variable(s, grammar))
if terminal_count > max_length:
continue
if new_form not in seen_forms:
seen_forms.add(new_form)
queue.append(new_form)
return results
G1 = { # {a^n b^n c^m : n,m >= 0}
'S': [('A', 'C')],
'A': [('a', 'A', 'b'), ()],
'C': [('c', 'C'), ()],
}
G2 = { # {a^m b^n c^n : n,m >= 0}
'S': [('A', 'B')],
'A': [('a', 'A'), ()],
'B': [('b', 'B', 'c'), ()],
}
MAXLEN = 9
L1 = generate_language_up_to_length(G1, 'S', MAXLEN)
L2 = generate_language_up_to_length(G2, 'S', MAXLEN)
intersection = L1 & L2 # আসল SET ইন্টারসেকশন
def is_anbncn(s): # L26-এর মেম্বারশিপ চেক -- CFG থেকে নয়, সরাসরি প্যাটার্ন-চেক
if len(s) % 3 != 0:
return False
n = len(s) // 3
return s == 'a' * n + 'b' * n + 'c' * n
expected = {s for s in (('a'*n + 'b'*n + 'c'*n) for n in range(0, MAXLEN // 3 + 1)) if len(s) <= MAXLEN}
print("L1 = {a^n b^n c^m} up to length", MAXLEN, "-- মোট", len(L1), "টি স্ট্রিং")
print("L2 = {a^m b^n c^n} up to length", MAXLEN, "-- মোট", len(L2), "টি স্ট্রিং")
print()
print("L1 ∩ L2 =", sorted(intersection, key=lambda s: (len(s), s)))
print("expected a^n b^n c^n =", sorted(expected, key=lambda s: (len(s), s)))
print()
print("সব intersection স্ট্রিং সত্যিই a^n b^n c^n প্যাটার্নের?", all(is_anbncn(s) for s in intersection))
print("L1 ∩ L2 == {a^n b^n c^n} ঠিক মিলে গেছে?", intersection == expected)
L1 ও L2 প্রতিটি স্বাধীনভাবে জেনারেট করা হয়েছে তাদের নিজস্ব CFG থেকে, কোনো
hardcoded তালিকা নয়। intersection হলো Python-এর আসল & সেট-অপারেটর দিয়ে হিসাব করা
SET ইন্টারসেকশন — এবং সেটি সত্যিই ঠিক $\{a^nb^nc^n\}$-এর সাথে মিলে যায়, যা L26-এর পাম্পিং লেমা দিয়ে
non-context-free প্রমাণিত। এটাই কনক্রিট প্রমাণ যে দুটো CFL-এর ইন্টারসেকশন CFL হওয়ার কোনো গ্যারান্টি নেই।
CFL ইউনিয়ন, কনক্যাটেনেশন ও ক্লিনি স্টারের নিচে ক্লোজড (গ্রামার-কম্বিনেশন দিয়ে সহজে প্রমাণযোগ্য), কিন্তু ইন্টারসেকশন বা কমপ্লিমেন্টের নিচে সাধারণভাবে ক্লোজড নয় — একটি কনক্রিট কাউন্টার-এক্সাম্পল ($\{a^nb^nc^m\} \cap \{a^mb^nc^n\} = \{a^nb^nc^n\}$) তা প্রমাণ করে। তবে CFL রেগুলার ল্যাঙ্গুয়েজের সাথে ইন্টারসেকশনের নিচে এখনও ক্লোজড — PDA×DFA প্রোডাক্ট কনস্ট্রাকশন দিয়ে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ রেগুলার ল্যাঙ্গুয়েজের ইন্টারসেকশন-ক্লোজার প্রমাণে ব্যবহৃত DFA-প্রোডাক্ট কনস্ট্রাকশন কেন সরাসরি দুটো PDA-এর জন্য কাজ করে না?
DFA-প্রোডাক্ট কনস্ট্রাকশনে দুটো DFA-এর স্টেট জোড়া বানিয়ে একটি নতুন, বৈধ DFA তৈরি করা যায় — কারণ DFA-এর মেমোরি শুধু একটি ফাইনাইট স্টেট (কোনো স্ট্যাক নেই)। কিন্তু দুটো PDA-এর ক্ষেত্রে, প্রতিটির নিজস্ব, স্বাধীন আনবাউন্ডেড স্ট্যাক আছে — একটি "প্রোডাক্ট PDA" বানাতে হলে দুটো স্বাধীন স্ট্যাক একসাথে ট্র্যাক করতে হবে, কিন্তু একটি PDA-এর সংজ্ঞাতেই আছে মাত্র একটি স্ট্যাক — দুটো স্বাধীন স্ট্যাককে একটি স্ট্যাকে সাধারণভাবে এনকোড করা সম্ভব নয় (এটাই আসলে কেন দুটো স্ট্যাক থাকলে গণনাশক্তি টুরিং-মেশিন সমতুল্য হয়ে যায়, M8-এ দেখা যাবে)।
প্র ০২ যদি $L_1$ ও $L_2$ দুটোই রেগুলার হতো (শুধু CFL নয়), তাহলে কি তাদের ইন্টারসেকশন নিয়ে ভিন্ন উত্তর হতো?
হ্যাঁ — যদি $L_1, L_2$ দুটোই রেগুলার হয়, তাহলে M3/L12 অনুযায়ী তাদের ইন্টারসেকশন সবসময় রেগুলার (এবং তাই CFL-ও, যেহেতু প্রতিটি রেগুলার ভাষা একটি CFL-ও বটে, চমস্কি হায়ারার্কির নেস্টেড সাবসেট সম্পর্ক অনুযায়ী)। এই পাঠের কাউন্টার-এক্সাম্পল কাজ করে কারণ $L_1, L_2$ CFL হলেও রেগুলার নয় — CFL-এর "অতিরিক্ত ক্ষমতা" (PDA-এর স্ট্যাক) ঠিক সেই কারণেই ইন্টারসেকশন-ক্লোজার হারানোর মূল উৎস।
প্র ০৩ De Morgan's law ব্যবহার করে কমপ্লিমেন্ট-নন-ক্লোজার প্রমাণ করা কেন "পরোক্ষ" (indirect) একটি প্রমাণ কৌশল?
কারণ এটি সরাসরি একটি কাউন্টার-এক্সাম্পল স্ট্রিং বা ভাষা তৈরি করে দেখায় না যে কমপ্লিমেন্ট ক্লোজড নয় — বরং ইতিমধ্যে প্রতিষ্ঠিত দুটো সত্য (ইউনিয়ন ক্লোজড, ইন্টারসেকশন ক্লোজড নয়) এবং একটি লজিক্যাল আইডেন্টিটি (De Morgan's law) একসাথে মিলিয়ে সিদ্ধান্তে পৌঁছায়। যদি কমপ্লিমেন্ট ক্লোজড হতো, ইউনিয়ন-ক্লোজার (যা সত্য) এবং De Morgan's law (যা সবসময় সত্য) মিলিয়ে ইন্টারসেকশন-ক্লোজারও সত্য হতে বাধ্য হতো — কিন্তু সেটা মিথ্যা প্রমাণিত (§২) — তাই মূল অনুমান (কমপ্লিমেন্ট ক্লোজড) মিথ্যা হতেই হবে। এই কৌশলটি প্রুফ বাই কন্ট্রাডিকশনের (L03) একটি প্রয়োগ।
অনুশীলন
-
চিন্তা করুন: উপরের কোডে
G1ওG2-এর একটি কম্বাইন্ড ইউনিয়ন গ্রামার ($S \to S_1 \mid S_2$) বানালে সেই গ্রামারটি কি CFL জেনারেট করবে? আপনার উত্তর §১-এর যুক্তির সাথে মিলিয়ে দেখুন।হ্যাঁ, অবশ্যই — ইউনিয়ন CFL-এর নিচে সবসময় ক্লোজড (§১), তাই $L_1 \cup L_2$ সবসময়ই একটি CFL হবে, তাদের পৃথক গ্রামার যত জটিলই হোক না কেন। এখানে যেটা ক্লোজড নয় তা হলো ইন্টারসেকশন, ইউনিয়ন নয় — এই দুটো ভিন্ন অপারেশন গুলিয়ে ফেলা একটি সাধারণ ভুল।
-
পরীক্ষা করুন: উপরের কোডে
MAXLENবাড়িয়ে (যেমন ১২ বা ১৫) Run চেপে দেখুন —L1 ∩ L2 == expectedকি তখনওTrueথাকে? এটি কেন প্রত্যাশিত?হ্যাঁ,
MAXLENযত বড় করা হোক, ইন্টারসেকশন সবসময় ঠিক $a^nb^nc^n$-এর সাথে মিলবে — কারণ $L_1 \cap L_2$-এর সংজ্ঞাগত (definitional) প্রমাণই বলে দেয় ফলাফল ঠিক $\{a^nb^nc^n : n \geq 0\}$, যেকোনো length bound-এর জন্য। বড়MAXLENশুধু আরও বেশি $n$-এর মান পরীক্ষা করে দেখায়, তবে গণনার সময় (BFS-এর স্টেট স্পেস) বাড়ে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পরবর্তী পাঠ: CFL-এর ডিসিশন প্রপার্টি পাঠ ২৮ মেম্বারশিপ, এম্পটিনেস, ফাইনাইটনেস ডিসাইডেবল হলেও ইকুইভ্যালেন্স কেন undecidable — CYK অ্যালগরিদমসহ।
- পূর্ববর্তী পাঠ: CFL-এর জন্য পাম্পিং লেমা পাঠ ২৬ $a^nb^nc^n$ কেন context-free নয় — এই পাঠের কাউন্টার-এক্সাম্পলের ভিত্তি সেখানেই প্রমাণিত হয়েছে।
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৬টি পাঠ M7-এ কনটেক্সট-সেনসিটিভ গ্রামার ও সম্পূর্ণ চমস্কি হায়ারার্কি তুলনা আসছে।