Σ* نظریه زبان‌ها و ماشین‌ها
جزوه جامع درس · دانشگاهی

نظریه زبان‌ها و ماشین‌ها

از الفبا و رشته تا زبان، گرامر و ماشین‌های حالت — تعریف‌ها و مثال‌های این جزوه، یک‌جا و مرحله‌به‌مرحله؛ همراه با نمودار، تمرینِ پاسخ‌دار و آزمون تعاملی.

DFA طول زوج · q₀ شروع و پایانی است · هر a یا b حالت را عوض می‌کند.

۱

الفبا، رشته و زبان

از نماد تا مجموعه‌ای از رشته‌ها · برگهٔ ۱۴

هر درس نظریهٔ زبان با سه پرسش ساده شروع می‌شود: نماد چیست، رشته چگونه ساخته می‌شود، و زبان چه چیزی است؟ پاسخ این سه پرسش، تمام فصل‌های بعدی را می‌سازد؛ چون گرامرها و ماشین‌ها چیزی جز ابزارِ تولید و تشخیص همین رشته‌ها نیستند.

تعریف ۱ · الفبا

الفبا چیست؟

الفبا مجموعه‌ای متناهی و ناتهی از نمادهاست که آن را با Σ نشان می‌دهیم. هر عضو الفبا یک «حرف» یا «نماد» است و هیچ ترتیبی هم روی آن‌ها لازم نیست.

Σ = { a, b }   |   Σ = { 0, 1 }   |   Σ = { a }
تعریف ۲ · رشته

رشته، دنباله‌ای متناهی از نمادها

رشته، دنباله‌ای متناهی از نمادهای الفباست. طول رشته را با |w| نشان می‌دهیم و رشتهٔ بدون هیچ نماد را رشتهٔ تهی می‌نامیم و با λ (یا ε) نمایش می‌دهیم.

|λ| = 0   ·   |abab| = 4   ·   a0b0 = λ

توجه کنید که λ یک رشته است، نه «هیچ چیز»؛ به همین دلیل می‌تواند عضو یک زبان باشد.

تعریف ۳ · زبان

زبان = مجموعه‌ای از رشته‌ها

زبان روی الفبای Σ، هر مجموعه‌ای از رشته‌های ساخته‌شده از حروف Σ است. پس زبان خودش یک «مجموعه» است و اعضایش «رشته» هستند:

L ⊆ Σ*   ⟺   L = { w | w ∈ Σ* }
تعریف ۴ · بستار ستاره‌ای الفبا

Σ* و Σ+

Σ* مجموعهٔ همهٔ رشته‌های متناهی روی Σ است، از جمله رشتهٔ تهی. اگر تنها رشتهٔ تهی را کنار بگذاریم، Σ+ به دست می‌آید:

Σ* = Σ0 ∪ Σ1 ∪ Σ2 ∪ …   ·   Σ+ = Σ* − { λ }

نمونهٔ الفبای یک‌حرفی

Σ = { a } ⟹ همهٔ رشته‌ها به شکل توانی از a هستند:

Σ* = { λ, a, a2, a3, …, an }

نمونهٔ الفبای دوحرفی

Σ = { a, b } ⟹ ترتیب حروف هم مهم است، پس ab ≠ ba:

Σ* = { λ, a, b, aa, ab, ba, bb, … }

چهار زبان نمونه از کلاس

در برگهٔ ۱۴ چهار زبان نوشته شد؛ هر کدام یک «الگو» را نشان می‌دهد که بعداً برایش گرامر یا ماشین می‌سازیم:

زبانتعریفنمایش گستردهویژگی
L₁{ ab, cd, ef }—متناهی؛ فقط سه رشته
L₂{ ab, bb, ba, abbb, bbb }—متناهی، بدون الگوی شمارشی
L₃{ anbn : n ≥ 0 }{ λ, ab, aabb, aaabbb, … }نامتناهی؛ تعداد a و b برابر
L₄{ a2nb2m+1 : n, m ≥ 0 }{ b, aab, bbb, aabbb, … }نامتناهی؛ a زوج‌بار و b فرد‌بار
دقت

یک نکتهٔ ظریف در برگه

گسترش نقل‌شده در یادداشت کلاس، {b, aa, a²b², …}، با تعریف این جدول هم‌خوان نیست. برای L₄ = {a2nb2m+1 : n,m≥0}، چند عضو درست عبارت‌اند از b، a²b و b³؛ اما aa و a²b² عضو آن نیستند. توانِ b باید فرد باشد.

کارت‌های مرور سریع

روی هر کارت کلیک کنید تا پاسخ را ببینید.

رشتهٔ تهی λ
طولش چند است؟
دنباله‌ای با صفر نماد؛ |λ| = 0 و برای هر رشتهٔ w داریم wλ = λw = w.
Σ*
چه چیزی را در خود دارد؟
همهٔ رشته‌های متناهی روی Σ، از جمله λ. پس همیشه نامتناهی است.
تفاوت Σ* و Σ+
فقط یک عضو
Σ+ = Σ* − {λ}؛ یعنی همه‌چیز جز رشتهٔ تهی.
زبان چیست؟
مجموعه یا رشته؟
زبان یک مجموعه است که اعضایش رشته هستند: L ⊆ Σ*.
۲

عملیات روی زبان‌ها

الحاق، توان، ستاره، مکمل و معکوس · برگهٔ ۱۵

چون زبان یک مجموعه است، اول از همه می‌توانیم عملیات مجموعه‌ای انجام دهیم: اجتماع، اشتراک، تفاضل و مکمل. اما یک عملیات مخصوص زبان‌ها هم داریم که روی رشته‌ها بنا شده است: الحاق. از الحاق، توان و بستار ساخته می‌شود و همین‌ها زبان‌های نامتناهی را از زبان‌های کوچک می‌سازند.

تعریف ۵ · الحاق

الحاق دو زبان

الحاق دو زبان، مجموعهٔ همهٔ رشته‌هایی است که از چسباندن یک رشته از زبان اول به یک رشته از زبان دوم ساخته می‌شوند:

L₁ · L₂ = { x y | x ∈ L₁ , y ∈ L₂ }

در دفتر کلاس، این عملیات با نماد × هم نوشته شده است: L₁ × L₂. ترتیب مهم است؛ L₁L₂ و L₂L₁ لزوماً یکی نیستند.

مثال ۱ · همان مثال کلاس

۲ رشته × ۴ رشته = ۸ رشته

L₁ = { a, ba } L₂ = { aa, bb, bc, ba }
aabbbcba
aaaaabbabcaba
babaaababbbabcbaba

حاصل الحاق، هشت رشته است:

L₁L₂ = { aaa, abb, abc, aba, baaa, babb, babc, baba }

توان، ستاره و پلاس

تعریف ۶ · توان

Lⁿ

توان صفر هر زبان، مجموعهٔ شامل رشتهٔ تهی است و هر توان بعدی، الحاق زبان با خودش:

L0 = { λ }
L1 = L
L2 = L · L
Ln = L · Ln−1
تعریف ۷ · بستارها

L* و L+

ستارهٔ کلینی، اجتماع همهٔ توان‌ها از صفر است؛ پلاس از یک شروع می‌شود:

L+ = L1 ∪ L2 ∪ L3 ∪ …
L* = L0 ∪ L1 ∪ L2 ∪ …
نتیجهٔ مهم:   L* = L+ ∪ { λ }
تعریف ۸ · مکمل

مکمل نسبت به Σ*

مکمل یک زبان، همهٔ رشته‌های روی الفبا که در آن زبان نیستند. دقت کنید مکمل همیشه نسبت به Σ* گرفته می‌شود، نه نسبت به زبان دیگر:

L̄ = Σ* − L
تعریف ۹ · معکوس

Lᴿ

معکوس زبان، مجموعهٔ معکوسِ همهٔ رشته‌های آن است. مثلاً اگر L = {anbn} باشد:

LR = { bnan : n ≥ 0 }
خواص پرکاربرد

چهار اتحاد که باید حفظ باشند

  1. خنثی بودن λ در الحاق: برای هر رشتهٔ w داریم wλ = λw = w. به همین دلیل L·{λ} = L.
  2. معکوس الحاق جابه‌جا می‌شود: (L₁L₂)R = L₂R L₁R — اول معکوسِ تکهٔ دوم، بعد تکهٔ اول.
  3. معکوس و ستاره: (L*)R = (LR)*.
  4. معکوس اجتماع: (L₁ ∪ L₂)R = L₁R ∪ L₂R.
هشدار رایج

L⁰ = {λ} است، نه ∅

تهی‌بودنِ زبان با داشتنِ رشتهٔ تهی یکی نیست: ∅ ≠ {λ}. بنابراین L0 = {λ} برای هر زبانی، حتی L = ∅. در نتیجه ∅* = {λ} ولی ∅+ = ∅.

آزمایشگاه زبان

عملیات را انتخاب کنید تا نتیجه روی همان دو زبان کلاس، زنده ساخته شود.

L₁ = { a, ba }
L₂ = { aa, bb, bc, ba }
۳

گرامر و زبان گرامر

تولید رشته با قاعده · برگه‌های ۱۶ تا ۱۸

تا اینجا زبان را «مجموعه» دیدیم. حالا می‌خواهیم زبان را تولید کنیم: گرامر دستگاهی است که با چند قاعدهٔ جای‌گذاری، از یک نماد شروع به رشته‌های زبان می‌رسد.

تعریف ۱۰ · گرامر

گرامر، یک چهارتایی

G = ( V , T , S , P )
  • V — مجموعهٔ غیرپایانی‌ها (متغیرها)؛ همان نمادهایی که باید جای‌گذاری شوند.
  • T — مجموعهٔ پایانی‌ها؛ حروفی که در رشتهٔ نهایی می‌مانند (V ∩ T = ∅).
  • S — نماد شروع؛ ریشهٔ اشتقاق و عضوی از V.
  • P — مجموعهٔ قواعد به شکل x → y با x ∈ (V ∪ T)* V (V ∪ T)* و y ∈ (V ∪ T)*.

قید مهم: سمت چپ باید دست‌کم یک غیرپایانی داشته باشد؛ سمت راست می‌تواند تهی باشد. بنابراین S → λ مجاز است، ولی جای‌گذاریِ صرفِ یک نماد پایانی مثل a → b قاعدهٔ این گرامر نیست.

تعریف ۱۱ · اشتقاق

⇒ و ⇒*

اگر با یک قاعده، بخشی از رشتهٔ فعلی را جای‌گذاری کنیم، می‌نویسیم u ⇒ v. اگر چند گام (شامل صفر گام) لازم باشد، u ⇒* v می‌نویسیم.

S ⇒ aSb ⇒ aaSbb ⇒ aabb
تعریف ۱۲ · زبان گرامر

L(G)

زبانِ گرامر، مجموعهٔ همهٔ رشته‌های پایانی است که از S قابل اشتقاق‌اند:

L(G) = { w ∈ T* : S ⇒* w }
مثال ۲ · گرامر کلاسیک

ساخت {aⁿbⁿ}

V = { S }T = { a, b }S → aSb | λ

هر بار که قاعدهٔ S → aSb اعمال شود، یک a به چپ و یک b به راست اضافه می‌شود؛ پس تعدادشان همیشه برابر می‌ماند. با S → λ اشتقاق تمام می‌شود:

  • S ⇒ λ ⟹ λ
  • S ⇒ aSb ⇒ aλb  ⟹  ab
  • S ⇒ aSb ⇒ aaSbb ⇒ aabb
  • S ⇒ aSb ⇒ aaSbb ⇒ aaaSbbb ⇒ aaabbb

در نتیجه، زبان گرامر چنین است:

L(G) = { λ, ab, aabb, aaabbb, … } = { anbn : n ≥ 0 }
درخت اشتقاق رشتهٔ aabb از S با قاعدهٔ S به a S b، سپس دوباره S به a S b، و در پایان S به رشتهٔ تهی تبدیل می‌شود. برگ‌ها از چپ به راست a، a، لامبدا، b، b هستند. S aSb aSb λ
برگ‌ها از چپ به راست: a · a · λ · b · b؛ چون λ تهی است، حاصل aabb می‌شود.
مثال ۳ · گرامر متقارن

گرامر رشته‌های متعادل

S → SSS → aSb | bSaS → λ

این گرامر زبان رشته‌هایی را می‌سازد که تعداد a و b در آن‌ها برابر است. قاعدهٔ S → SS اجازهٔ کنار هم گذاشتن دو رشتهٔ متعادل را می‌دهد و دو قاعدهٔ دیگر، تعادل را حفظ می‌کنند.

برای نمونه، رشتهٔ a⁴b²a⁵b⁸a ده a و ده b دارد و با این گرامر قابل تولید است. طرحِ یک اشتقاق (با استفاده از کنارهم‌گذاری و جفت‌سازی) چنین است:

S ⇒ SS ⇒* a²Sb²S ⇒* a²SSb²S ⇒* a⁴b²a⁵b⁸a

رشتهٔ b⁵a²b³a⁶ هم ۸ a و ۸ b دارد و این گرامر آن را می‌پذیرد؛ رد کردنش اشتباه است. پنج بار S → bSa بدهید و بخش میانیِ a²b³a = (aabb)(ba) را با S → SS بسازید. در این گرامر، برابریِ تعداد a و b هم لازم است و هم کافی؛ ترتیب دلخواه این دو حرف با قواعد پوشش داده می‌شود.

نکته

درخت اشتقاق چه می‌گوید؟

درخت اشتقاق، همان اشتقاق است ولی بدون ترتیب؛ هر گرهٔ داخلی یک غیرپایانی است و فرزندانش، سمت راست قاعده‌ای که اعمال شده. برگ‌ها (از چپ به راست) رشتهٔ نهایی را می‌سازند. اگر برگ‌های یک درخت را جابه‌جا کنیم، ممکن است رشتهٔ نامعتبر بسازیم — به همین دلیل ترتیب فرزندان مهم است.

گرامرنویسی: چهار تمرین کلاس

صورت مسئله همیشه یکی است: «زبان داده شده، گرامر بساز.» روش کار: الگوی شمارش را پیدا کن، برای هر «حافظه» یک غیرپایانی بگذار، و با قواعد، الگو را بازتولید کن.

زبان: { bn a bm : n, m ≥ 0 }

S → A a A
A → bA | λ

دو نسخهٔ A، قبل و بعد از a، هر تعداد b تولید می‌کنند. دو رخدادِ A مستقل از هم بازنویسی می‌شوند؛ به‌کاربردن یک نام برای هر دو، تعداد bهای دو طرف را برابر نمی‌کند. مثلاً S ⇒ AaA ⇒ baA ⇒ babb هم مجاز است.

ساده‌ترین راه، دو غیرپایانی برای «زوج» و «فرد» است:

S → a E | b S
E → a S | b E | λ

S یعنی «تا اینجا تعداد a زوج است» (حالت شروع و غیرقابل‌پایان) و E یعنی «فرد است» (با قاعدهٔ λ قابل‌پایان). هر a وضعیت را جابه‌جا می‌کند و b آن را تغییر نمی‌دهد. در دفتر هم ایدهٔ «اضافه‌کردن aها جفت‌جفت» آمده بود؛ همان ایده، اینجا به شکل دو حالت نوشته شده است.

S → aSb | Sb | b

قاعدهٔ aSb یک a و یک b اضافه می‌کند؛ Sb تنها b اضافه می‌کند و قاعدهٔ پایهٔ S → b وجودِ حداقل یک b اضافی را تضمین می‌کند. اگر قاعدهٔ پایه λ بود، زبانِ نادرستِ m≥n (شامل λ) تولید می‌شد.

S → aSb | λ

همان گرامر مثال ۲؛ ساده‌ترین نمونهٔ زبان «غیرمنظم» که با گرامر ساخته می‌شود ولی با هیچ DFAای قابل تشخیص نیست (در فصل‌های بعد ثابت می‌شود).

۴

ماشین متناهی معین (DFA)

پذیرنده‌ای که هیچ انتخابی ندارد · برگهٔ ۱۹

گرامر زبان را تولید می‌کرد؛ ماشین آن را تشخیص می‌دهد. DFA ماشینی است که ورودی را حرف‌به‌حرف می‌خواند، در هر لحظه دقیقاً در یک حالت است، و در پایان یا پذیرش را اعلام می‌کند یا رد را. کلمهٔ «معین» یعنی برای هر حالت و هر حرف، دقیقاً یک مقصد وجود دارد.

تعریف ۱۳ · DFA

پنج‌تایی ماشین

M = ( Q , Σ , δ , q₀ , F )
Q — مجموعهٔ متناهی حالت‌ها
Σ — الفبای ورودی
δ : Q × Σ → Q — تابع انتقال (کامل و یک‌مقداری)
q₀ ∈ Q — حالت شروع
F ⊆ Q — مجموعهٔ حالت‌های پایانی
δ* — تعمیم δ به رشته‌ها

تابع انتقال توسعه‌یافته:
δ*(q, λ) = q و δ*(q, wa) = δ( δ*(q, w), a ). رشتهٔ w پذیرفته می‌شود اگر و تنها اگر δ*(q₀, w) ∈ F.

مثال ۴

رشته‌های با طول زوج

دو حالت کافی است: «تا اینجا طول زوج است» و «طول فرد است». هر حرف، حالت را عوض می‌کند:

DFA تشخیص رشته‌های با طول زوج q₀ شروع و پایانی است؛ با a یا b به q₁ می‌رود و با a یا b دوباره به q₀ بازمی‌گردد.
q₀ شروع و پایانی است: λ طول صفر دارد و پذیرفته می‌شود؛ q₁ فرد و غیرپایانی است.
Q = { q₀, q₁ } , F = { q₀ }
حالتab
→ * q₀q₁q₁
q₁q₀q₀
مثال ۵ · همان نمودار کلاس

شمارش تعداد a به پیمانهٔ ۴

برای شرط «باقی‌ماندهٔ تعداد a بر ۴ صفر باشد»، به چهار حالت نیاز داریم: باقی‌ماندهٔ ۰، ۱، ۲ و ۳. هر a حالت را یک قدم جلو می‌برد و هر b حالت را نگه می‌دارد:

DFA شمارش تعداد a به پیمانهٔ چهار از q₀ با هر a به q₁، q₂، q₃ و دوباره q₀ می‌رویم؛ در هر حالت b یک حلقه دارد. q₀ تنها حالت پایانی است.
q₀ پایانی است (باقی‌ماندهٔ صفر)؛ q₃ با a به q₀ برمی‌گردد

قاعدهٔ کلی: برای شمردنِ تعداد a به پیمانهٔ k، k حالت لازم است؛ برای دو شرط هم‌زمان (مثل زوج بودن a و زوج بودن b) حالت‌ها حاصل‌ضرب می‌شوند: 2 × 2 = 4.

شبیه‌ساز زنده

ماشین زیر رشته‌هایی را می‌پذیرد که تعداد a در آن‌ها بخش‌پذیر بر ۳ باشد. رشته‌ای بنویسید و مسیر اجرا را ببینید:

DFA بخش‌پذیری تعداد a بر سه q₀ حالت شروع و پذیرش است. a، q₀ را به q₁، q₁ را به q₂ و q₂ را به q₀ می‌برد؛ b حالت را تغییر نمی‌دهد.

فقط حروف a و b خوانده می‌شوند.

حالتبا aبا bپایانی؟
→ q₀q₁q₀بله؛ باقی‌ماندهٔ صفر
q₁q₂q₁خیر
q₂q₀q₂خیر
اشتباه رایج

حالت مرده را فراموش نکنید

در DFA تابع δ باید برای هر حالت و هر حرف تعریف شده باشد. اگر در طراحی به حالتی رسیدید که ادامه دادن بی‌فایده است (مثلاً رشته دیگر قابل پذیرش نیست)، یک حالت مرده بگذارید که همهٔ حروف را به خودش برگرداند. نبودن حالت مرده یعنی ماشین ناقص است، نه هوشمندتر.

۵

ماشین متناهی نامعین (NFA)

حق انتخاب و پرش بی‌مصرف · برگه‌های ۲۰، ۸ تا ۱۱

دانشجو اولین بار وقتی NFA را می‌بیند می‌پرسد: «مگر ماشین می‌تواند چند راه را هم‌زمان برود؟» پاسخ: در مدل بله؛ در پیاده‌سازی نه. NFA یک ابزار طراحی است: نوشتن‌اش آسان‌تر است و بعداً به DFA تبدیل می‌شود.

تعریف ۱۴ · NFA

پنج‌تایی با تابع انتقال مجموعه‌ای

M = ( Q , Σ , δ , q₀ , F )   ·   δ : Q × (Σ ∪ {λ}) → 2Q

تفاوت اصلی با DFA در هم‌دامنه است: خروجی δ یک مجموعه از حالت‌ها است، نه یک حالت. پس برای یک حرف ممکن است صفر، یک یا چند مقصد وجود داشته باشد.

پذیرش در NFA: رشتهٔ w پذیرفته می‌شود اگر دست‌کم یک مسیر محاسباتی به حالت پایانی برسد:

L(M) = { w ∈ Σ* : δ*(q₀, w) ∩ F ≠ ∅ }
تفاوت ۱

چند مقصد برای یک حرف

در حالت q₂ با خواندن a هم می‌توان به q₄ رفت و هم به q₅؛ ماشین هر دو راه را «حدس می‌زند» و اگر یکی به پذیرش برسد، کافی است.

تفاوت ۲

گذار λ (تهی)

NFA می‌تواند بدون مصرف نماد از حالتی به حالت دیگر بپرد. این کار مدل‌سازی «انتخاب آزاد» را ساده می‌کند؛ DFA گذار λ ندارد، اما می‌تواند همان زبان را پس از تبدیل بپذیرد.

مثال ۶ · ساخت با λ

سه حالت برای {aⁿ : n ≥ 1} ∪ {bᵐaᵏ : m,k ≥ 0}

از حالت شروع دو راه داریم: مستقیم با a به حالت پایانی (شاخهٔ aⁿ)، یا با λ به حالت میانی، خواندن هر تعداد b و بعد با یک λ دیگر به حالت پایانی:

NFA با دو گذار تهی λ q₀ با λ به q₁ و با a مستقیماً به q₂ می‌رود؛ q₁ روی b حلقه دارد و با λ به q₂ می‌رسد؛ q₂ روی a حلقه دارد و پایانی است.
q₀ با λ به q₁ می‌رود، q₁ حلقهٔ b دارد، و با λ به q₂ می‌رسد؛ کمان پایین شاخهٔ مستقیم a است

چون m = k = 0 هم مجاز است، رشتهٔ تهی با مسیرِ دو گذار λ پذیرفته می‌شود. دقت: اجتماعِ عنوان در واقع همان b* a* است، چون {aⁿ:n≥1} ⊆ {bᵐaᵏ:m,k≥0}؛ شاخهٔ مستقیم a فقط یک مسیر جایگزینِ اضافی است، نه زبانی تازه.

توضیح تکمیلی

بستار λ (λ-closure)

برای اجرای دقیق NFA، از هر حالت مجموعه‌ای از حالت‌ها را نگه می‌داریم. بستار λ یک حالت، همهٔ حالت‌هایی است که با صفر یا چند گذار λ از آن قابل دسترسی‌اند (خود حالت هم داخل مجموعه است). قاعدهٔ اجرا: اول بستار λ حالت فعلی را بگیر، بعد برای حرف بعدی δ را اعمال کن و باز بستار λ نتیجه را بگیر.

DFA یا NFA؟

ویژگیDFANFA
تابع انتقالδ : Q × Σ → Qδ : Q × (Σ ∪ {λ}) → 2Q
تعداد مقصد برای یک حرفدقیقاً یکیصفر، یکی یا چندتا
گذار بدون مصرف نمادندارددارد (λ)
مسیر محاسباتییکتاممکن است چندتا
سختی طراحیبیشترکمتر (انعطاف بالا)
قدرت بیانیکسان — هر NFA یک DFA هم‌ارز دارد
پیوند مفهومی · تکمیل آموزشی

زبان منظم چیست و ماشین متناهی چه کاری نمی‌تواند بکند؟

زبانی منظم است اگر یک DFA (یا به‌طور معادل یک NFA) آن را بپذیرد. عبارت‌های منظم نیز دقیقاً همین خانواده را توصیف می‌کنند: برای نمونه (ab)* و b*a* منظم‌اند؛ اجتماع، الحاق و ستارهٔ زبان‌های منظم هم منظم می‌مانند.

اما {anbn:n≥0} منظم نیست: ماشین با تعداد حالت‌های ثابت نمی‌تواند تعداد نامحدود aها را نگه دارد و سپس همان تعداد b را تطبیق دهد. گرامر S→aSb|λ آن را تولید می‌کند، ولی هیچ DFA/NFAای آن را نمی‌پذیرد. بنابراین «برای هر گرامر، DFA بساز» درست نیست؛ تبدیلِ بخش بعد فقط برای NFA است.

۶

هم‌ارزی NFA و DFA

قضیه، اثبات سازنده و ساخت زیرمجموعه‌ای · برگه‌های ۱۲ تا ۱۶
تعریف ۱۵ · هم‌ارزی

هم‌ارزی در سطح زبان، نه ساختار

دو ماشین هم‌ارزند اگر زبان یکسانی را بپذیرند؛ حتی اگر حالت‌ها و یال‌هایشان کاملاً متفاوت باشد:

MD ≡ MN  ⟺  L(MD) = L(MN)
قضیه

برای هر NFA یک DFA وجود دارد

اگر L زبان پذیرفته‌شده توسط NFAی MN = (QN, Σ, δN, q₀, FN) باشد، آنگاه DFAیی مانند MD = (QD, Σ, δD, S₀, FD) وجود دارد که L = L(MD).

ایدهٔ اثبات: کافی است روشی سازنده بدهیم. حالت‌های DFA، مجموعه‌هایی از حالت‌های NFA هستند؛ چون تعداد زیرمجموعه‌های یک مجموعهٔ متناهی، متناهی است، ماشین حاصل هم متناهی است.

الگوریتم ساخت زیرمجموعه‌ای، گام‌به‌گام

  1. شروع: حالت آغازین DFA را S₀ = closureλ({q₀}) بگیرید. اگر گذار λ نداریم، همان {q₀} است.
  2. یال‌گذاری: برای هر مجموعه‌حالت S و هر حرف a∈Σ، ابتدا مقصدها را اجتماع بگیرید و سپس بستار λ را حساب کنید: δD(S,a) = closureλ(⋃q∈S δN(q,a)).
  3. حالت جدید: اگر مجموعهٔ حاصل قبلاً در GD نبود، آن را به‌عنوان یک حالت تازه اضافه کنید (و صف کار را ادامه دهید).
  4. پایانی‌ها: هر مجموعه‌حالت که دست‌کم یک حالت پایانیِ NFA را در خود دارد، در DFA پایانی است.
  5. تکمیل: اگر برای یک حرف مجموعهٔ مقصد تهی شد، ∅ را حالت مرده بگذارید و گذارهای آن را به خودش برگردانید تا DFA کامل شود.
مثال ۷ · مثال کامل کلاس

سه حالت NFA ← هفت حالت DFA

NFA زیر را در نظر بگیرید (الفبای {0,1}، حالت پایانی q₁):

NFA سه‌حالته برای ساخت زیرمجموعه‌ای q₀ شروع است و روی 0 حلقه می‌زند؛ با 0 یا 1 به q₁ می‌رود. q₁ تنها حالت پایانی است و با 0 یا 1 به q₂ می‌رود. q₂ روی 1 حلقه می‌زند.
NFA نمونه؛ q₁ تنها حالت پایانی است
δN01
→ q₀{q₀,q₁}{q₁}
* q₁{q₂}{q₂}
q₂∅{q₂}

حالا همان گام‌ها را اجرا می‌کنیم. حالت شروع {q₀} است؛ با 0 به {q₀,q₁} و با 1 به {q₁} می‌رویم و همین‌طور ادامه می‌دهیم:

حالت DFA01پایانی؟
→ {q₀} = A{q₀,q₁} = B{q₁} = Cخیر
{q₀,q₁} = B{q₀,q₁,q₂} = D{q₁,q₂} = Eبله
{q₁} = C{q₂} = F{q₂} = Fبله
{q₀,q₁,q₂} = D{q₀,q₁,q₂} = D{q₁,q₂} = Eبله
{q₁,q₂} = E{q₂} = F{q₂} = Fبله
{q₂} = F∅ = G{q₂} = Fخیر
∅ = G (مرده)GGخیر

نتیجه: هفت حالت. حالت G = ∅ همان حالت مرده است؛ در تخته کلاس آن را q₃ نامیده بودند. حالت‌های پایانی DFA دقیقاً آن‌هایی هستند که q₁ را در خود دارند: B, C, D, E.

چرا کار می‌کند؟

ایدهٔ اثبات در یک خط

با استقرا روی طول رشته ثابت می‌شود که حالتِ DFA پس از خواندن w، دقیقاً برابر مجموعهٔ همهٔ حالت‌هایی است که NFA می‌تواند پس از خواندن w در آن‌ها باشد. پس شرطِ پذیرش در DFA دقیقاً معادلِ ناتهی بودن اشتراک مجموعهٔ حالت‌های NFA با F است و زبان یکی می‌شود.

۷

کمینه‌سازی DFA

روال علامت‌گذاری و ادغام حالت‌ها · برگه‌های ۱۷ تا ۲۸

دو ماشین می‌توانند زبان یکسانی را بپذیرند ولی یکی ۲۰ حالت داشته باشد و دیگری ۴ حالت. کمینه‌سازی یعنی پیدا کردن کوچک‌ترین DFA هم‌ارز. چرا مهم است؟ چون هر حالت یعنی حافظه، و هر یال یعنی منطق؛ ماشین کوچک‌تر هم ارزان‌تر است هم قابل‌فهم‌تر.

تعریف ۱۶ · ادغام‌پذیری

دو حالت چه وقت یکی می‌شوند؟

دو حالت qi و qj ادغام‌پذیرند اگر برای هر رشتهٔ ممکن، هر دو یا هر دو پذیرفته شوند یا هر دو رد شوند:

∀w ∈ Σ* :   δ*(qi, w) ∈ F  ⟺  δ*(qj, w) ∈ F

و ادغام‌ناپذیرند (قابل تمیز) اگر دست‌کم یک رشته پیدا شود که یکی را بپذیرد و دیگری را رد کند:

∃w ∈ Σ* :   ( δ*(qi,w) ∈ F ∧ δ*(qj,w) ∉ F ) ∨ ( … برعکس )
روال علامت‌گذاری

چهار گام تا جدول کامل

  1. پاک‌سازی: حالت‌های غیرقابل دسترس را حذف کنید — حالت‌هایی که از q₀ هیچ مسیری به آن‌ها نیست. (برگهٔ ۲۰: در یک ماشین چهارحالته، q₁ هیچ یال ورودی نداشت و حذف شد.)
  2. علامت اولیه: هر جفت (پایانی، غیرپایانی) را ادغام‌ناپذیر علامت بزنید؛ چون رشتهٔ λ آن‌ها را از هم جدا می‌کند.
  3. انتشار: اگر δ(p,a) = pa و δ(q,a) = qa و جفت (pa, qa) قبلاً علامت خورده، جفت (p,q) را هم علامت بزنید.
  4. تکرار: گام ۳ را تا وقتی هیچ جفت تازه‌ای علامت نمی‌خورد تکرار کنید؛ جفت‌های بی‌علامتِ باقی‌مانده، هم‌ارزند و کلاس‌های ادغام را می‌سازند.

تعداد جفت‌های نامرتب برای n حالت: n(n−1)/2 — همان تعداد خانه‌های جدول مثلثی.

مثال ۸ · مثال کلاس

پنج حالت ← چهار حالت

ماشین زیر را با حالت‌های q₀ … q₄ و حالت‌های پایانی {q₂, q₄} در نظر بگیرید:

حالت01
→ q₀q₁q₃
q₁q₂q₄
* q₂q₁q₄
q₃q₂q₄
* q₄q₄q₄

جدول علامت‌گذاری:

q₀q₁q₂q₃q₄
q₀✗✗✗✗
q₁✗✓✗
q₂✗✗
q₃✗
q₄
✗ ادغام‌ناپذیر✓ ادغام‌پذیر
DFA کمینهٔ چهارحالته q₀ با 0 یا 1 به q₁,₃ می‌رود؛ q₁,₃ با 0 به q₂ و با 1 به q₄؛ q₂ با 0 به q₁,₃ و با 1 به q₄؛ q₄ با 0 یا 1 در خودش می‌ماند. q₂ و q₄ پایانی‌اند.
M̂ چهارحالته: q₁ و q₃ در یک حالت ادغام شده‌اند

چرا q₁ و q₃ ادغام‌پذیرند؟ هر دو غیرپایانی‌اند، با 0 به q₂ و با 1 به q₄ می‌روند؛ یعنی رفتار آیندهٔ آن‌ها دقیقاً یکسان است.

مثال ۹ · مثال دوم

پنج حالت ← دو حالت

در این ماشین سه حالت q₁, q₂, q₃ پایانی‌اند. برای آنکه ادغام فقط به شکل وابسته نباشد، جدولِ انتقالِ نمونهٔ زیر را هم بررسی کنید؛ همهٔ پنج حالت از q₀ قابل دسترس‌اند:

حالت01
→ q₀q₁q₂
* q₁q₂q₄
* q₂q₃q₀
* q₃q₁q₄
q₄q₃q₁

در هر دو حالتِ غیرپایانی، هر ورودی به یک حالت پایانی می‌رسد؛ در سه حالت پایانی، 0 داخل کلاس پایانی می‌ماند و 1 به کلاس غیرپایانی می‌رود. پس دو کلاس هم‌ارزی داریم:

q₀q₁q₂q₃q₄
q₀✗✗✗✓
q₁✓✓✗
q₂✓✗
q₃✗
q₄
کلاس‌ها: {q₀,q₄} و {q₁,q₂,q₃}
DFA کمینهٔ دوحالته حالت آغازین q₀,₄ با 0 یا 1 به کلاس پایانی q₁,₂,₃ می‌رود؛ کلاس پایانی با 0 در خودش می‌ماند و با 1 به کلاس آغازین برمی‌گردد.
ماشین دوحالته: کلاس شروع و کلاس پایانی
روال کاهش

از کلاس‌ها به ماشین جدید

  1. هر کلاس هم‌ارزی، یک حالت از M̂ می‌شود.
  2. اگر δ(qi, a) = qj در ماشین اولیه باشد، از کلاس qi با حرف a به کلاس qj یال می‌کشیم.
  3. کلاسی که q₀ را در خود دارد، حالت شروع است.
  4. کلاسی که دست‌کم یک حالت پایانی دارد، حالت پایانی است.
  5. فقط حالت‌های غیرقابل‌دسترس را حذف کنید؛ نداشتن یال ورودی به‌تنهایی دلیل حذف نیست (حالت شروع ممکن است یال ورودی نداشته باشد).

نتیجهٔ تئوریک: ماشین حاصل کمینه است و هر دو حالت آن، قابل تمیزدادن‌اند.

۸

بانک تمرین و پاسخ

تمرین‌های کتاب (ص ۳۳–۴۲) و کلاس · با پاسخ کوتاه

تمرین‌های کتاب در دو فصل تقسیم می‌شوند: فصل ۲ (زبان‌ها و گرامرها، تمرین ۱ تا ۲۳) و فصل ۳ (کاربردها، تمرین ۱ تا ۹). در این بخش، تمرین‌های کلیدی با پاسخ کوتاه آمده‌اند؛ بقیه برای تمرین شخصی در کتاب موجودند.

کاربرد · شکل ۹.۱ کتاب

جمع‌کنندهٔ دودویی: دو حالت، یک بیت نقلی

جمع دو عدد دودویی (بیت‌به‌بیت، از کم‌ارزش‌ترین بیت) فقط به یک چیز نیاز دارد: «آیا از جمع قبلی نقلی داشتیم؟» پس دو حالت کافی است: بدون نقلی و با نقلی.

حالت(0,0)(0,1) یا (1,0)(1,1)
بدون نقلیخروجی 0 → بدون نقلیخروجی 1 → بدون نقلیخروجی 0 → با نقلی
با نقلیخروجی 1 → بدون نقلیخروجی 0 → با نقلیخروجی 1 → با نقلی

این مثال نشان می‌دهد نظریهٔ زبان فقط «ریاضیات انتزاعی» نیست؛ همان منطقی که یک DFA دوحالته توصیف می‌کند، داخل یک مدار جمع‌کننده هم هست.

دستهٔ ۱ · عملیات و خواص زبان‌ها

استقرا روی n: پایه n=0 که |λ|=0؛ گام: |un+1| = |unu| = |un| + |u| = n|u| + |u|.

تعریف بازگشتی: aR=a و (wa)R = a wR. اثبات با استقرا روی طول v؛ برای v=λ بدیهی و برای v=wa داریم (uwa)R = a(uw)R = a wR uR = (wa)RuR.

استقرا روی طول w؛ گام: (wa)R = a wR پس ((wa)R)R = (a wR)R = (wR)R a = wa.

روش: رشته را از چپ به راست به بلوک‌های ab / aa / baa بشکنید. هر رشته‌ای که دقیقاً به ۴ بلوک تقسیم شود، در L⁴ هم هست. مثلاً ab·ab·aa·baa = ababaabaa و ab·aa·aa·baa = abaaaabaa هر دو در L⁴ (و طبعاً در L*) هستند؛ رشته‌هایی که باقی‌مانده یا بلوک نامعتبر دارند، بیرون می‌مانند.

همهٔ رشته‌ها جز aa و bb؛ یعنی L̄ = {λ, a, b, ab, ba} ∪ {w : |w| ≥ 3}. توجه کنید که λ هم در مکمل است، چون در L نیست.

چون L ∪ L̄ = Σ* و Σ* نامتناهی است. اگر هر دو متناهی بودند، اجتماعشان متناهی می‌شد؛ تناقض.

خیر. فرض کنیم L* = L̄* = S. چون L ∪ L̄ = Σ* و هر دو زیرمجموعهٔ S هستند، نتیجه می‌شود S = Σ*. حالا حرف a ∈ Σ را در نظر بگیرید: برای اینکه a ∈ L̄* باشد و طولش یک است، باید خودش عضو L̄ باشد (الحاق دو رشتهٔ ناتهی طول ≥ ۲ می‌دهد). همین استدلال برای همهٔ حروف نشان می‌دهد Σ ⊆ L̄، پس هیچ حرفی در L نیست و رشته‌های تک‌حرفی در L* نیستند؛ اما L* = Σ* بود. تناقض.

عضویت دوطرفه: هر w ∈ (L₁L₂)R به شکل (xy)R = yRxR با x∈L₁, y∈L₂ است، پس در L₂RL₁R است؛ عکس آن هم مشابه.

هر عضو (L*)* الحاق چند رشته از L* است و هر رشتهٔ L* خودش الحاق چند رشته از L است؛ پس کل عبارت الحاق چند رشته از L است و در L* قرار دارد. عکس آن بدیهی است (L* ⊆ (L*)*).

دستهٔ ۲ · گرامرها

دقیقاً یک a:   S → A a A , A → bA | λ
حداقل یک a:   S → A a A , A → aA | bA | λ
حداکثر سه a:   S → A | A a A | A a A a A | A a A a A a A , A → bA | λ
حداقل سه a:   S → A a A a A a A , A → aA | bA | λ

در هر مورد A نقش «هر تعداد b (و در حالت‌های حداقلی، a اضافی)» را دارد.

هر دور، یک ab تولید می‌کند و در پایان λ می‌گیرد: L = (ab)*. گرامر جایگزین ساده: S → abS | λ.

این گرامر هیچ قاعدهٔ خاتمه‌ای ندارد: A و B همیشه باقی می‌مانند؛ پس L(G)=∅. برای ساخت طول‌های فرد، گرامر درستِ نمونه S → a | aaS است و {a,aaa,aaaaa,…} را می‌سازد.

L₁: S → aSb | Sb | b
L₂: S → aSb | λ
L₃: S → aA , A → aAb | λ
L₄: S → aSb | aaa

برای L₁L₂ و L₁∪L₂ و ستاره‌ها، می‌توان از گرامرهای ترکیبی استفاده کرد؛ مثلاً L₁L₂ با دو نماد شروع مجزا و قاعدهٔ S → S₁S₂ ساخته می‌شود (به شرط جدا بودن غیرپایانی‌ها).

S → aaaS | λ
S → aSa | bSb | aa | bb

مرکز رشته، دو حرف یکسان است؛ سپس هر دو طرف قرینه اضافه می‌شود.

این گرامر رشته‌هایی را می‌سازد که با حذف جفت‌های متقارن a…b یا b…a به یک a تنها می‌رسند؛ به‌عبارت دیگر ساختار تودرتویی دارند که در مرکز آن یک a است و تعداد a یکی بیشتر از b است. مثال‌ها: a, aab, baa, aaabb, abaab. «aba» در این گرامر تولید نمی‌شود، هرچند تعداد a آن یکی بیشتر است.

ابتدا E → aEbE | bEaE | λ را برای همهٔ رشته‌های با تعداد برابر a و b بسازید. برای اختلافِ دقیقاً یک: S → EaE؛ برای اختلافِ مثبتِ دلخواه: P → EaE | EaP. بلوک‌های E تعادل دارند و هر a میان آن‌ها اختلاف را یک واحد زیاد می‌کند.

برای اجازه‌دادنِ c در هر جای رشته، گرامرِ تعادل را این‌طور گسترش دهید: E → aEbE | bEaE | cE | λ. سپس برای اختلاف دقیقاً یک S → EaE و برای اختلاف مثبت P → EaE | EaP را به کار ببرید؛ c هیچ اثری بر اختلاف a و b ندارد.

S→aSb|ab|λ و S→aAb|ab , A→aAb|λ هم‌ارز نیستند: اولی λ را هم می‌سازد و زبانش {anbn: n≥0} است؛ دومی تنها n≥1 را می‌سازد. اگر S→λ را به دومی اضافه کنیم، هم‌ارز می‌شوند. اما S→aSb|bSa|SS|a با S→aSb|bSa|a هم‌ارز نیستند: اولی با SS رشته‌های بیشتری (مثل aa) می‌سازد.

دستهٔ ۳ · ماشین‌ها

دو حالت؛ هر حرف حالت را عوض می‌کند و حالت شروع، پایانی است (طول صفر زوج است).

چهار حالت به‌صورت زوج (زوج/فرد a، زوج/فرد b)؛ فقط حالتی که a فرد و b زوج است پایانی است. تعداد حالت‌ها = حاصل‌ضرب دو شمارنده = ۲×۲.

همان ماشین مثال ۶: q₀ با λ به q₁ (حلقهٔ b)، q₁ با λ به q₂ (پایانی، حلقهٔ a)، و کمان مستقیم a از q₀ به q₂.

سه حالت: q₀ (شروع و پایانی) --a--> q₁ --b--> q₂؛ از q₂ با λ به q₀ برگردید تا بلوک ab تمام شود؛ یا با c به q₀ برگردید تا بلوک abc کامل شود. q₀ شروع و پایانی است، پس λ هم در ستاره پذیرفته می‌شود.

مثال ۷ بخش ۶: هفت حالت شامل حالت مرده؛ حالت‌های پایانی هر مجموعه‌ای که q₁ را دارد.

جدول جفت‌ها را بسازید، جفت‌های پایانی/غیرپایانی را علامت بزنید، انتشار دهید و کلاس‌ها را ادغام کنید. دو مثال کامل در بخش ۷ حل شده است.

۹

جمع‌بندی، جدول نمادها و آزمون

همه‌چیز در یک نگاه

جدول نمادها

نمادمعنییادآوری
Σالفبامجموعهٔ متناهی و ناتهی از نمادها
Σ*بستار ستاره‌ای الفباهمهٔ رشته‌ها، شامل λ
λرشتهٔ تهی|λ| = 0
L* / L+بستار زبانL* = L+ ∪ {λ}
L̄مکمل زبانΣ* − L
Lᴿمعکوس زبان(L₁L₂)ᴿ = L₂ᴿL₁ᴿ
G=(V,T,S,P)گرامرV غیرپایانی، T پایانی
δتابع انتقالDFA: به Q؛ NFA: به 2Q
Fحالت‌های پایانیدر DFA: δ*(q₀,w) ∈ F
M̂ماشین کاهش‌یافتهحاصل کمینه‌سازی

شش اشتباه رایج

۱. L⁰ = ∅

نه! L⁰ = {λ}. تهی‌بودن زبان با داشتن رشتهٔ تهی فرق دارد.

۲. δ ناقص

در DFA برای هر حالت و هر حرف باید یک مقصد داشته باشیم؛ حالت مرده را جا نیندازید.

۳. پذیرش در NFA

کافی است یک مسیر به پایانی برسد: δ*(q₀,w) ∩ F ≠ ∅، نه اینکه همهٔ مسیرها برسند.

۴. حالت پایانی در تبدیل

هر مجموعه‌حالت که دست‌کم یک حالت پایانی NFA را دارد، پایانی است.

۵. فراموش‌کردن حذف حالت غیرقابل دسترس

قبل از علامت‌گذاری، حالت‌هایی که از q₀ مسیر ندارند را حذف کنید.

۶. λ در DFA

DFA گذار λ ندارد؛ اگر جایی λ دیدید، ماشین NFA است (یا باید تبدیل شود).

آزمون کوتاه

پاسخ درست را انتخاب کنید؛ بازخورد فوری می‌گیرید.

۱) اگر L = {a, ab} باشد، L² کدام است؟
A {aa, aab, aba}
B {aa, ab, abab}
C {aa, aab, aba, abab}
D {a, ab, aab}

پاسخ: C {aa, aab, aba, abab} — L² = {aa, aab, aba, abab}؛ هر عضو L با هر عضو L الحاق می‌شود.

۲) برای هر زبان L، مقدار L⁰ چیست؟
A ∅
B {λ}
C L
D {λ, a}

پاسخ: B {λ} — توان صفر هر زبان، مجموعهٔ شامل رشتهٔ تهی است.

۳) گرامر S → aSb | λ چه زبانی می‌سازد؟
A {aⁿbⁿ : n ≥ 0}
B {aⁿbᵐ : n,m ≥ 0}
C {(ab)ⁿ : n ≥ 0}
D {wwᴿ}

پاسخ: A {aⁿbⁿ : n ≥ 0} — هر بار یک a به چپ و یک b به راست اضافه می‌شود، پس تعدادشان برابر می‌ماند.

۴) DFA کمینه‌ای که رشته‌های با «تعداد a بخش‌پذیر بر ۳» را می‌پذیرد چند حالت دارد؟
A ۲
B ۴
C ۳
D ۶

پاسخ: C ۳ — برای شمردن به پیمانهٔ ۳، سه حالت (باقی‌ماندهٔ ۰، ۱، ۲) لازم است.

۵) کدام جمله دربارهٔ NFA درست است؟
A تابع انتقال آن به Q می‌رود و یکتاست
B تابع انتقال آن به 2Q می‌رود و λ هم مجاز است
C قدرت بیان بیشتری از DFA دارد
D نمی‌تواند حالت پایانی داشته باشد

پاسخ: B تابع انتقال آن به 2 Q می‌رود و λ هم مجاز است — در NFA خروجی δ مجموعه‌ای از حالت‌هاست (2^Q) و ممکن است چند مقصد یا λ داشته باشد.

۶) در ساخت زیرمجموعه‌ای، هر حالت DFA نمایندهٔ چیست؟
A یک حرف از الفبا
B یک رشته از زبان
C یک یال از گراف
D مجموعه‌ای از حالت‌های NFA

پاسخ: D مجموعه‌ای از حالت‌های NFA — حالت‌های DFA در ساخت زیرمجموعه‌ای، مجموعه‌هایی از حالت‌های NFA هستند و کلاس‌های هم‌ارزی در کمینه‌سازی، حالت‌های ماشین جدید را می‌سازند.

نقشهٔ منابع

هر بخش از کدام برگه‌های دست‌نویس یا صفحه‌های کتاب ساخته شده است:

بخشمنبعموضوع
۱برگهٔ ۱۴زبان، الفبا، Σ* و Σ+
۲برگهٔ ۱۵الحاق، توان، ستاره، مکمل، معکوس
۳برگه‌های ۱۶–۱۸گرامر، اشتقاق، گرامرنویسی
۴برگهٔ ۱۹ + تختهٔ ۱۰–۱۱DFA و طراحی ماشین
۵برگهٔ ۲۰ + تختهٔ ۸–۱۱NFA، گذار λ
۶تختهٔ ۱۲–۱۶قضیهٔ هم‌ارزی و ساخت زیرمجموعه‌ای
۷برگه‌های ۱۷–۲۸کمینه‌سازی و دو مثال کامل
۸صفحه‌های ۳۳–۴۲ کتابتمرین‌های فصل ۲ و ۳
چک‌لیست مرور

قبل از آزمون، این هفت مورد را بتوانید بی‌مکث بگویید

  1. تفاوت زبان، رشته و الفبا در یک جمله.
  2. تفاوت L* و L+ و جای λ.
  3. ساخت گرامر برای {aⁿbⁿ} و {aⁿbᵐ : m>n}.
  4. طراحی DFA برای «تعداد a بخش‌پذیر بر k».
  5. تفاوت هم‌دامنهٔ δ در DFA و NFA.
  6. چهار گام ساخت زیرمجموعه‌ای.
  7. سه گام روال علامت‌گذاری در کمینه‌سازی.