نماذج الحوسبة المقيَّدة { #restrictedchap }
نماذج الحوسبة المقيَّدة
- ترى أن اكتمال تورينج ليس دائمًا شيئًا جيدًا.
- مثال آخر على صيغة رسمية تتوقف دائمًا: القواعد النحوية الخالية من السياق (context-free grammars) و_حساب لامدا المصنَّف ببساطة_ (simply typed calculus).
- لمّة الضخّ (pumping lemma) للدوال غير الخالية من السياق.
- أمثلة على خصائص دلالية (semantic properties) قابلة للحساب وغير قابلة للحساب، لكل من التعبيرات النمطية العادية والقواعد النحوية الخالية من السياق.
"كل الأسر السعيدة متشابهة؛ وكل أسرة تعيسة تعيسة بطريقتها الخاصة", ليو تولستوي (مطلع كتاب "آنا كارينينا").
لقد رأينا أن كثيرًا من نماذج الحوسبة متكافئة بحسب تورينج (Turing equivalent)، بما في ذلك آلات تورينج، وبرامج NAND-TM/NAND-RAM، ولغات البرمجة المعيارية مثل C/Python/Javascript، فضلًا عن نماذج أخرى مثل حساب لامدا وحتى لعبة الحياة. ووجه الأمر المقابل هو أن نظرية Rice (مبرهنة — نظرية رايس) تتحقق أيضًا بالنسبة لجميع هذه النماذج، أي أن أي خاصية دلالية لبرامج أي نموذج من هذه النماذج هي غير قابلة للحساب.
إن عدم قابلية الحساب لمسألة التوقف (halting) ولغيرها من مسائل التحديد الدلالي في النماذج المتكافئة بحسب تورينج هو ما يحفّز على صياغة نماذج حوسبة مقيَّدة (restricted computational models) تكون (أ) قوية بما يكفي لالتقاط مجموعة من الدوال المفيدة لتطبيقات معينة، لكنها (ب) ضعيفة بما يكفي بحيث ما زالت نستطيع حل مسائل التحديد الدلالي عليها. في هذا الفصل نناقش عدة أمثلة من هذا النوع.
يمكننا استخدام النماذج الحوسبة المقيَّدة (restricted computational models) لتجاوز قيود مثل عدم قابلية مسألة التوقف (Halting problem) ونظرية Rice للحساب. هذه النماذج تستطيع حساب مجموعة فرعية مقيَّدة من الدوال فحسب، لكنها تتيح لنا الإجابة على بعض الأسئلة الدلالية (semantic questions) حول البرامج على الأقل.

اكتمال تورينج بوصفه خللًا
لقد رأينا أن النماذج أو الأنظمة الحوسبية التي تبدو بسيطة قد يتبيّن أنها كاملة بحسب تورينج (Turing complete). تسرد هذه الصفحة عدة أمثلة لصيغ رسمية (formalisms) تبيّن "عرضًا" أنها كاملة بحسب تورينج، بما في ذلك لغات يُفترض أنها محدودة مثل المعالج المسبق للغة C، وCSS، و(أشكال معيّنة من) SQL، وإعدادات sendmail، فضلًا عن ألعاب مثل Minecraft وSuper Mario ولعب البطاقات "Magic: The Gathering". وليست اكتمالية تورينج شيئًا جيدًا دائمًا، فهي تعني أن هذه الصيغ الرسمية تستطيع أن تنتج سلوكًا معقّدًا إلى حد غير محدود. على سبيل المثال، صيغة postscript (سابقة لـ PDF) هي لغة برمجة كاملة بحسب تورينج، الغرض منها وصف مستندات للطباعة. وتتيح القوة التعبيرية لـ postscript أوصافًا قصيرة لصور شديدة التعقيد، لكنها أيضًا أنتجت بعض المفاجآت السيئة، مثل الهجمات الموصوفة في هذه الصفحة، والتي تتراوح من استخدام الحلقات اللانهائية هجومًا لحجب الخدمة، إلى الوصول إلى نظام ملفات الطابعة.
مثال — اختراق The DAO
نشأ مثال حديث مثير للاهتمام على مخاطر اكتمالية تورينج في سياق العملة الرقمية Ethereum. السمة المميِّزة لهذه العملة هي القدرة على تصميم "العقود الذكية" (smart contracts) باستخدام لغة برمجة تعبيرية (وهي على وجه الخصوص كاملة بحسب تورينج). في اقتصادنا "الذي يشغّله البشر" اليوم، قد يوقّع Alice وBob عقدًا يتفقان فيه على أنه إذا حدث الشرط X فسيستثمران معًا في شركة Charlie. يسمح Ethereum لـ Alice وBob بإنشاء مشروع مشترك يجمعان فيه أموالهما في حساب واحد تحكمه برنامج ما يقرّر تحت أي ظروف يصرف الأموال منه. على سبيل المثال، يمكن تخيّل قطعة شيفرة تتفاعل بين Alice وBob وبين برنامج يعمل في سيارة Bob، وتسمح لـ Alice باستئجار سيارة Bob دون أي تدخل بشري أو أي تكلفة إدارية.
وتستخدم Ethereum تحديدًا لغة البرمجة الكاملة بحسب تورينج solidity، التي صياغتها شبيهة بـ JavaScript. وكان أبرز ما في Ethereum تجربة عُرفت باسم "المنظمة اللامركزية ذاتية الإدارة" (Decentralized Autonomous Organization) أو The DAO. كانت الفكرة إنشاء عقد ذكي ينشئ صندوق استثمار رأس مال مغامر لامركزيًا يعمل ذاتيًا، بلا مديرين بشريين، حيث يقرر المساهمون فرص الاستثمار. كانت The DAO في حينه أنجح عملية جمع تمويل جماعي (crowdfunding) في التاريخ. وفي ذروتها كانت The DAO تساوي 150 مليون دولار، أي أكثر من عشرة في المئة من حجم سوق Ethereum الكلي. والاستثمار في The DAO (أو الدخول في أي "عقد ذكي" آخر) يعني تسليم أموالك لتُدار بواسطة برنامج حاسوبي؛ أي بمعنى آخر "الشيفرة هي القانون"، أو بكلمات The DAO التي وصفت نفسها بها: "The DAO وُلدت من شيفرة حاسوبية غير قابلة للتغيير، ولا يمكن إيقافها، ولا يمكن دحضها". للأسف، يتبيّن أنه (كما رأينا في الشمولية وغياب قابلية الحساب) فهم سلوك برامج الحاسوب أمر صعب حقًا. تمكّن أحد المخترقين (أو ربما، كما يقول بعضهم، مستثمر ماهر) من صياغة مدخل جعل شيفرة The DAO تدخل في حلقة تكرارية لا نهائية تحوّل فيها الأموال باستمرار إلى حساب المخترق، بحيث سحب من The DAO نحو 60 مليون دولار. ورغم أن هذه العملية كانت "قانونية" بالمعنى أنها امتثلت لشيفرة العقد الذكي، فإنها لم تكن بوضوح ما قصده البشر الذين كتبوا هذه الشيفرة. واجه مجتمع Ethereum صعوبة في الاستجابة لهذا الهجوم. حاول بعضهم نهج "روبن هود" باستخدام الثغرة نفسها لتفريغ أموال The DAO في حساب آمن، لكن ذلك لم يحقق سوى نجاح محدود. وفي النهاية، قرر مجتمع Ethereum أن الشيفرة يمكن أن تكون قابلة للتغيير، وقابلة للإيقاف، وقابلة للدحض. وتحديدًا، اتفق مشرفو Ethereum والعُدّناء (miners) على "تشعّب قاسٍ" (hard fork)، ويُعرف أيضًا بـ"الإنقاذ" (bailout)، لإعادة التاريخ إلى ما قبل تنفيذ المخترق لعمليته. عارض بعض أعضاء المجتمع بشدة هذا القرار، فأنشئت عملة بديلة اسمها Ethereum Classic تحفظ التاريخ الأصلي.
القواعد النحوية الخالية من السياق
إذا كنت قد كتبت برنامجًا من قبل، فقد جرّبت خطأً نحويًا (syntax error). وربما جرّبت أيضًا أن يدخل برنامجك في حلقة لا نهائية. أما الأقل احتمالًا فهو أن يُدخل المُصرِّف (compiler) أو المُفسِّر (interpreter) نفسه في حلقة لا نهائية وهو يحاول تحديد ما إذا كان برنامجك يحتوي على خطأ نحوي.
عندما يصمّم شخص لغة برمجة، عليه أن يحدّد صيغتها النحوية (syntax). أي أن المصمّم يقرّر أي السلاسل تقابل برامج صحيحة وأيها لا يقابلها (أي: أي السلاسل تحتوي على خطأ نحوي). ولضمان أن يتوقف المُصرِّف أو المُفسِّر دائمًا عند الفحص بحثًا عن الأخطاء النحوية، لا يستخدم مصمّمو اللغات عادةً آلية عامة كاملة بحسب تورينج للتعبير عن صيغتها النحوية. بل يستخدمون بدلًا من ذلك نموذج حوسبة مقيَّد. ومن أكثر الخيارات شيوعًا لمثل هذه النماذج هي القواعد النحوية الخالية من السياق.
لشرح القواعد النحوية الخالية من السياق، لنبدأ بمثال نموذجي. لنفكّر في الدالة التي تأخذ كمدخل سلسلة فوق الأبجدية وتُعيد إذا وفقط إذا كانت السلسلة تمثّل تعبيرًا حسابيًا صحيحًا. وبصورة حدسية، نبني التعبيرات بتطبيق عملية مثل ,, أو على تعبيرات أصغر، أو بإحاطتها بأقواس، حيث تتطابق "الحالة الأساسية" مع التعبيرات التي هي أرقام فحسب. وبدقة أكبر، يمكننا تقديم التعريفات التالية:
-
الرقم (digit) هو أحد الرموز .
-
العدد (number) هو تسلسل من الأرقام. (وللبساطة نُسقط الشرط القاضي بأن لا يبدأ التسلسل بصفر، وإن كان من غير الصعب تشفيره في قاعدة نحوية خالية من السياق أيضًا.)
-
العملية (operation) هي إحدى
-
التعبير (expression) إمّا أن يكون على الشكل "number"، أو على الشكل "sub-expression1 operation sub-expression2"، أو على الشكل "(sub-expression1)"، حيث يكون "sub-expression1" و"sub-expression2" تعبيرين بدورهما. (لاحظ أن هذا تعريف تعاودي (recursive).)
القاعدة النحوية الخالية من السياق (CFG) هي طريقة رسمية لتحديد مثل هذه الشروط. وتتألف قاعدة CFG من مجموعة من القواعد التي تخبرنا كيف نولّد السلاسل من مكوّنات أصغر. وفي المثال أعلاه، إحدى القواعد هي: "إذا كان و تعبيرين صحيحين، فإن هو أيضًا تعبير صحيح"؛ ويمكننا كذلك كتابة هذه القاعدة بالاختصار . وكما في المثال أعلاه، فإن قواعد أي قاعدة نحوية خالية من السياق غالبًا ما تكون تعاودية: فالقاعدة تُعرِّف التعبيرات الصحيحة في ضوء نفسها. لنعرّف الآن القواعد النحوية الخالية من السياق تعريفًا رسميًا:
تعريف — القاعدة النحوية الخالية من السياق
لتكن مجموعة ما منتهية. القاعدة النحوية الخالية من السياق (CFG) فوق هي ثلاثية بحيث:
-
، وتُعرف بـ_المتغيّرات_ (variables)، هي مجموعة منفصلة عن .
-
وتُعرف بـ_المتغيّر الابتدائي_ (initial variable).
-
هي مجموعة من القواعد (rules). كل قاعدة زوج حيث و. وكثيرًا ما نكتب القاعدة على الصورة ونقول إن السلسلة يمكن اشتقاقها (can be derived) من المتغيّر .
مثال — قاعدة نحوية خالية من السياق للتعبيرات الحسابية
يمكن صياغة المثال أعلاه لتعبيرات حسابية سليمة رسميًا بالقاعدة النحوية الخالية من السياق التالية:
-
الأبجدية هي
-
المتغيّرات هي .
-
القواعد هي المجموعة التي تحتوي القواعد الـ التالية:
-
القواعد الـ: ، و، و، و.
-
القواعد الـ: ،، .
-
القاعدة .
-
القاعدة .
-
القاعدة .
-
القاعدة .
-
القاعدة .
-
-
المتغيّر الابتدائي هو
يستعمل الناس اصطلاحات كتابة متعددة مختلفة لكتابة القواعد النحوية الخالية من السياق.
ومن أشيع هذه الاصطلاحات هو صيغة Backus–Naur.
في هذا الاصطلاح نكتب قاعدة من الشكل (حيث متغيّر و سلسلة) على الصورة <v> := a.
ولو كان لدينا عدة قواعد من الشكل ، و، و، فيمكننا ضمّها في <v> := a|b|c.
(وبعبارة أخرى نقول إن يمكن أن تشتقّ إمّا أو أو .)
ولنأخذ مثلًا، وصف Backus-Naur للقاعدة النحوية الخالية من السياق في مثال — قاعدة نحوية خالية من السياق للتعبيرات الحسابية هو كالآتي (باستخدام مقابلات ASCII للعمليات):
operation := +|-|*|/
digit := 0|1|2|3|4|5|6|7|8|9
number := digit|digit number
expression := number|expression operation expression|(expression)
ومثال آخر على قاعدة نحوية خالية من السياق هو قاعدة "الأقواس المتطابقة" (matching parentheses)، ويمكن تمثيلها بصيغة Backus-Naur كما يلي:
match := ""|match match|(match)
يمكن توليد سلسلة فوق الأبجدية (,) من هذه القاعدة (حيث match هو التعبير الابتدائي و"" يقابل السلسلة الفارغة) إذا وفقط إذا كانت تتألّف من مجموعة أقواس متطابقة.
وبالمقابل، وطبقًا لـ لمّة — مطابقة الأقواس، لا يوجد تعبير نمطي عادي يطابق سلسلة إذا وفقط إذا كانت تحتوي على تسلسل صحيح من الأقواس المتطابقة.
القواعد النحوية الخالية من السياق بوصفها نموذج حوسبة
يمكننا أن نفكّر في قاعدة نحوية خالية من السياق فوق الأبجدية على أنها تعرّف دالة تُسقط كل سلسلة في إلى أو بحسب ما إذا كانت يمكن توليدها بقواعد هذه القاعدة النحوية أم لا. لنصوغ الآن هذا التعريف رسميًا.
تعريف — اشتقاق سلسلة من قاعدة نحوية
إذا كانت قاعدة نحوية خالية من السياق فوق ، فإننا لكل سلسلتين نقول إن يمكن اشتقاقها في خطوة واحدة من ، ويُرمز لذلك بـ ، إذا أمكننا الحصول على من بتطبيق إحدى قواعد . أي أن تُحصل من باستبدال ظهور واحد للمتغيّر في بالسلسلة ، حيث قاعدة من قواعد .
ونقول إن يمكن اشتقاقها من ، ويُرمز لذلك بـ ، إذا أمكن اشتقاقها بعدد محدود من الخطوات. أي إذا وُجدت بحيث .
ونقول إن مُطابَقة (matched) بواسطة إذا كان بالإمكان اشتقاق من المتغيّر الابتدائي (أي إذا كان ). ونعرّف الدالة المحسوبة بواسطة بأنها الخريطة بحيث إذا وفقط إذا كانت مُطابَقة بواسطة . وتكون الدالة خالية من السياق (context free) إذا كان لبعض قاعدة CFG من الشكل .[1]
قد لا يكون واضحًا في البداية أن الخريطة قابلة للحساب، غير أنه يتبيّن أن الأمر كذلك.
مبرهنة — القواعد النحوية الخالية من السياق تتوقف دائمًا
لكل قاعدة CFG فوق ، الدالة قابلة للحساب.
وكالمعتاد نقتصر على القواعد النحوية فوق ، وإن كان البرهان يمتد إلى أي أبجدية منتهية .
برهان
سنكتفي بعرض مخطط البرهان. نبدأ بملاحظة مفادها أننا نستطيع تحويل كل قاعدة CFG إلى نسخة مكافئة في الصيغة النمطية لتشومسكي (Chomsky normal form)، حيث إمّا أن تكون كل القواعد على الشكل لمتغيّرات ، أو على الشكل لمتغيّر ورمز ، بالإضافة على القاعدة المحتملة حيث هو المتغيّر الابتدائي.
والفكرة وراء هذا التحويل هي ببساطة إضافة متغيّرات جديدة عند الحاجة، فمثلًا يمكننا ترجمة قاعدة مثل إلى القواعد الثلاث ، و، و.
وباستخدام الصيغة النمطية لتشومسكي نحصل على خوارزمية تعاودية طبيعية لحساب ما إذا كان ، بمعطى قاعدة وسلسلة . ونكتفي ببسط تجريب جميع الاحتمالات لقاعدة الأولى المستخدَمة في مثل هذا الاشتقاق، ثم جميع الطرق الممكنة لتقسيم على صورة سَلسَلة . وإذا خمّنّا القاعدة والتقسيم على نحو صحيح، فإن الأمر ينحصر في الفحص عمّا إذا كان و، وهو أمر يمكن إنجازه تعاوديًا (لأنه يتعلق بسلسلات أقصر). أما الحالات الأساسية (base cases) فهي عندما تكون فارغة أو رمزًا مفردًا، ويمكن معالجتها بسهولة.
ملاحظة — شجرات التحليل
بينما نركّز على مهمة إقرير القرار (deciding) بشأن ما إذا كانت قاعدة CFG تطابق سلسلة ما، فإن خوارزمية حساب تقدّم في الحقيقة معلومات أكثر من ذلك. أي أنها، عند مدخلها سلسلة ، إن كان ، تُنتج تسلسل القواعد التي يمكن تطبيقها ابتداءً من الرأس للحصول على السلسلة النهائية . ويمكننا أن نفكّر في هذه القواعد على أنها تحدّد شجرة يكون جذرها (root)، وتُقابل المصارف (أو الأوراق (leaves)) بها السلاسل الفرعية من التي نحصل عليها بالقواعد التي لا متغيّر في عنصرها الثاني. وتُعرف هذه الشجرة باسم شجرة التحليل (parse tree) الخاصة بـ ، وهي غالبًا ما تقدّم معلومات مفيدة جدًا عن بنية .
وكثيرًا ما تكون الخطوة الأولى في مُصرِّف أو مُفسِّر لغة برمجة هي محلّل (parser) يحوّل الشيفرة المصدرية إلى شجرة التحليل (المعروفة أيضًا بـشجرة الصياغة المجردة). وهناك أيضًا أدوات تستطيع تحويل وصف لقاعدة نحوية خالية من السياق تلقائيًا إلى خوارزمية تحليل تحسب شجرة التحليل لسلسلة معطاة. (وفعلًا يمكن استعمال الخوارزمية التعاودية أعلاه لتحقيق ذلك، لكن هناك نسخًا أكثر كفؤًا بكثير، ولا سيما للقواعد التي لها أشكال معيّنة، وكثيرًا ما يحرص مصمّمو لغات البرمجة على ضمان أن تكون لغاتهم ذات هذه القواعد الأكثر كفؤًا.)
قوة القواعد النحوية الخالية من السياق
القواعد النحوية الخالية من السياق قادرة على التقاط كل تعبير نمطي عادي:
مبرهنة — القواعد النحوية الخالية من السياق والتعبيرات النمطية العادية
ليكن تعبيرًا نمطيًا عاديًا فوق ، عندئذ توجد قاعدة CFG فوق بحيث .
برهان
نبرهن على النظرية بالاستقراء على طول . وإذا كان تعبيرًا من طول بت واحد، فإن أو ، وفي هذه الحالة نترك للقارئ أن يتحقق من وجود قاعدة CFG (بديهية) تحسبه. وإلا فإنا نقع في إحدى الحالات التالية: الحالة 1: ، أو الحالة 2: ، أو الحالة 3: ، وفي كل الحالات يكون تعبيرين نمطيين عاديين أقصر. وبفرض الاستقراء، يمكننا تعريف قاعدتين نحويتين و تحسبان على الترتيب و. وبإعادة تسمية المتغيّرات، يمكننا أيضًا أن نفترض دون فقدان عموميات أن و منفصلتان.
في الحالة 1، يمكننا تعريف القاعدة الجديدة كما يلي: نضيف متغيّرًا ابتدائيًا جديدًا والقاعدة . وفي الحالة 2، يمكننا تعريف القاعدة الجديدة كما يلي: نضيف متغيّرًا ابتدائيًا جديدًا والقاعدتين و . أما الحالة 3 فهي الحالة الوحيدة التي تستعمل التعاود (recursion). وكما في السابق نضيف متغيّرًا ابتدائيًا جديدًا ، لكننا نضيف الآن القاعدتين (أي السلسلة الفارغة)، ونضيف أيضًا، لكل قاعدة من الشكل ، القاعدة إلى .
ونترك للقارئ يتحقق كتمرين (تمرين جيد جدًا!) أن القواعد النحوية التي ننتجها في الحالات الثلاث جميعها تلتقط الدالة نفسها التي يلتقطها التعبير الأصلي.
يتبيّن أن قواعد CFG أقوى secara صارم من التعبيرات النمطية العادية. وبخاصة، كما رأينا، فإن دالة "الأقواس المتطابقة" يمكن حسابها بقاعدة نحوية خالية من السياق، في حين أنه، كما هو مبين في لمّة — مطابقة الأقواس، لا يمكن حسابها بالتعبيرات النمطية العادية. وهذا مثال آخر:
تمرين محلول — قاعدة نحوية خالية من السياق للسلاسل المتناظرة
لتكن الدالة المعرَّفة في تمرين محلول — المتناظرات ليست منتظمة حيث إذا وفقط إذا كان على الشكل . عندئذ يمكن حساب بقاعدة نحوية خالية من السياق
الحل
يمكن وصف قاعدة بسيطة تحسب باصطلاح Backus–Naur:
start := ; | 0 start 0 | 1 start 1
ويمكن البرهان بالاستقراء أن هذه القاعدة تولّد بالضبط السلاسل التي تحقق .
ومثال أكثر إثارة للاهتمام هو حساب السلاسل من الشكل التي ليست متناظرة:
تمرين محلول — غير المتناظرات
برهن على وجود قاعدة نحوية خالية من السياق تحسب حيث إذا كان ولكن .
الحل
باستعمال اصطلاح Backus–Naur يمكننا وصف قاعدة من هذا النوع كما يلي
palindrome := ; | 0 palindrome 0 | 1 palindrome 1
different := 0 palindrome 1 | 1 palindrome 0
start := different | 0 start | 1 start | start 0 | start 1
وبعبارة أخرى، فإن هذا يعني أننا يمكننا تمييز سلسلة تحقق بأنها على الشكل التالي
حيث سلاسل اعتباطية و.
ومن ثم يمكننا توليد سلسلة من هذا النوع بأن نولّد أولًا سلسلة متناظرة (المتغيّر palindrome)، ثم نضيف على أحد الجانبين و على الجانب المقابل لنحصل على شيء ليس متناظرًا (المتغيّر different)، ثم يمكننا إضافة عدد اعتباطي من و على أي من الطرفين (المتغيّر start).
قيود القواعد النحوية الخالية من السياق (اختياري)
رغم أن القواعد النحوية الخالية من السياق أقوى من التعبيرات النمطية العادية، فإن هناك بعض اللغات البسيطة التي لا تلتقطها القواعد النحوية الخالية من السياق. وإحدى الأدوات لإظهار ذلك هي نظيرةُ "لمّة الضخّ" (pumping lemma) بالنسبة للقواعد النحوية الخالية من السياق (مبرهنة — مبرهنة الضخّ):
مبرهنة — لمّة الضخّ الخالية من السياق
لتكن قاعدة CFG فوق ، عندئذ يوجد عددان بحيث لكل مع ، إذا كان فإن بحيث ، و، و لكل .
توقّف وتأمّل
إن لمّة الضخّ الخالية من السياق أعقد في صياغتها حتى من نظيرتها العادية، لكن يمكنك تذكّرها على أنها تقول ما يلي: "إذا طابقت قاعدة ما سلسلة طويلة بما يكفي، فلا بد أن يكون هناك متغيّر يتكرّر في الاشتقاق."
برهان
سنكتفي بعرض مخطط البرهان. الفكرة أنه إذا كان مجموع عدد الرموز في قواعد القاعدة النحوية هو ، فإن الطريقة الوحيدة للحصول على مع هي استعمال التعاود. أي أنه لا بد من وجود متغيّر بحيث نستطيع أن نشتقّ من القيمة لبعض السلسلتين ، ثم نشتقّ لاحقًا من بعض السلسلة بحيث تكون سلسلة فرعية من (بعبارة أخرى، لبعض ). وإذا أخذنا المتغيّر الذي يحقق هذا الشرط بأقل عدد من خطوات الاشتقاق، فيمكننا أن نضمن أن على الأكثر يساوي ثابتًا ما يعتمد على ، ويمكننا أن نضع مساويًا لذلك الثابت (ويكفي ، لأننا لن نحتاج إلى أكثر من تطبيقًا للقواعد، وكل تطبيق من هذا النوع يمكن أن يزيد السلسلة بما لا يتجاوز من الرموز).
وبالتالي، بحكم تعريف القاعدة النحوية، يمكننا تكرار الاشتقاق لاستبدال السلسلة الفرعية في بـ لكل مع الاحتفاظ بخاصية أن مُخرَج ما زال يساوي واحدًا. وبما أن سلسلة فرعية من ، يمكننا كتابة ، ونكون مضمونين أن مُطابَق بالقاعدة النحوية لكل .
باستعمال مبرهنة — لمّة الضخّ الخالية من السياق يمكن أن نبيّن أن الدالة البسيطة حتى المعرَّفة كما يلي: ليست خالية من السياق. (وبالمقابل، فإن الدالة المعرَّفة بـ إذا وفقط إذا كان لبعض و هي دالة خالية من السياق؛ هل ترى لماذا؟)
تمرين محلول — المساواة ليست خالية من السياق
لتكن الدالة التي تحقق إذا وفقط إذا كان لبعض . عندئذ ليست خالية من السياق.
الحل
سنستعمل لمّة الضخّ الخالية من السياق. ولنفرض، طلبًا للتناقض، أنه توجد قاعدة نحوية تحسب ، ولتكن الثابت المستحصل عليه من مبرهنة — لمّة الضخّ الخالية من السياق.
لنأخذ السلسلة ، ونكتبها على الصورة وفقًا لـ مبرهنة — لمّة الضخّ الخالية من السياق، بحيث وبحيث . وطبقًا لـ مبرهنة — لمّة الضخّ الخالية من السياق، ينبغي أن يتحقق أن . غير أنه يمكن، بتحليل الحالات، أن نبيّن أن هذا يناقض.
أولًا، ما لم تكن على يسار الفاصل و على يمينه، فإن إسقاط و سيجعل الجزءين مختلفين على وجه اليقين. لكن إذا كان الحال أن على اليسار و على اليمين، فمن شرط نعرف أن سلسلة من الأصفار فقط و سلسلة من الآحاد فقط. وإذا أسقطنا و، فإن أحدهما غير فارغ، ومن ثم نحصل على أن عدد الأصفار على اليسار أقل من عددها على اليمين، أو أن عدد الآحاد على اليمين أقل من عددها على اليسار. وفي الحالتين نحصل على ، فنحقق التناقض المطلوب.
الخصائص الدلالية للغراتم الخالية من السياق
وكما في حالة التعبيرات النمطية العادية، فإن قيود القواعد النحوية الخالية من السياق توفّر لنا بعض المزايا. فمثلًا، مسألة فراغية القواعد النحوية الخالية من السياق قابلة لإصدار القرار:
مبرهنة — فراغية قواعد CFG قابلة لإصدار القرار
توجد خوارزمية، تعطى كمدخل قاعدة نحوية خالية من السياق ، تُخرج إذا وفقط إذا كانت هي دالة الصفر الثابت.
يصير البرهان أوضح إذا حوّلنا القاعدة النحوية إلى الصيغة النمطية لتشومسكي كما في مبرهنة — القواعد النحوية الخالية من السياق تتوقف دائمًا. وبمعطى قاعدة ، يمكننا أن نعرّف تعاوديًا متغيّرًا غير طرفيًا بأنه غير فارغ (non-empty) إذا كانت هناك قاعدة من الشكل ، أو كانت هناك قاعدة من الشكل حيث كل من و غير فارغ. عندئذ تكون القاعدة النحوية غير فارغة إذا وفقط إذا كان المتغيّر الابتدائي غير فارغ.
برهان
نفترض أن القاعدة النحوية في الصيغة النمطية لتشومسكي كما في مبرهنة — القواعد النحوية الخالية من السياق تتوقف دائمًا. وننظر في الإجراء التالي لوسم المتغيّرات بأنها "غير فارغة":
-
نبدأ بوسم جميع المتغيّرات التي تظهر في قاعدة من الشكل بأنها غير فارغة.
-
ثم نواصل وسم بأنه غير فارغ إذا كان يظهر في قاعدة من الشكل حيث كل من كان قد وُسم قبل ذلك.
نستمر على هذا النحو حتى لا نستطيع وسم أي متغيّر إضافي. ثم نُعلن أن القاعدة النحوية فارغة إذا وفقط إذا لم يوسم . ولكي نرى لماذا هذه خوارزمية صحيحة، لاحظ أن إذا وُسم متغيّر بأنه "غير فارغ" فهناك بعض السلسلة التي يمكن اشتقاقها من . ومن جهة أخرى، إذا لم يوسم ، فإن كل تسلسل اشتقاقات من سيحتوي دائمًا على متغيّر لم يستبدل برموز من الأبجدية. ومن ثم بخاصة تكون هي دالة الصفر الكلّي إذا وفقط إذا لم يوسم المتغيّر الابتدائي بأنه "غير فارغ".
عدم قابلية حساب تكافؤ القواعد النحوية الخالية من السياق (اختياري)
تشبيهًا بالتعبيرات النمطية العادية، ربما كان من أملنا الحصول على خوارزمية لتقرير ما إذا كانت قاعدتان نحويتان خاليتان من السياق معطيتان متكافئتين. للأسف، لا حظ في ذلك. يتبيّن أن مسألة التكافؤ للقواعد النحوية الخالية من السياق غير قابلة للحساب. وهذا نتيجة مباشرة للنظرية التالية:
مبرهنة — كتمال قواعد CFG غير قابل للحساب
لكل مجموعة ، لتكن الدالة التي، مع مدخل قاعدة نحوية خالية من السياق فوق ، تُخرج إذا وفقط إذا كانت تحسب دالة الواحد الثابتة. عندئذ توجد أبجدية منتهية ما بحيث غير قابلة للحساب.
مبرهنة — كتمال قواعد CFG غير قابل للحساب يستلزم فورًا أن التكافؤ للقواعد النحوية الخالية من السياق غير قابل للحساب، لأن حساب "كتمال" قاعدة فوق أبجدية ما يقابل الفحص عمّا إذا كانت تكافئ القاعدة النحوية . ولاحظ أن مبرهنة — كتمال قواعد CFG غير قابل للحساب ومبرهنة — فراغية قواعد CFG قابلة لإصدار القرار معًا يستلزمان أن القواعد النحوية الخالية من السياق، بخلاف التعبيرات النمطية العادية، غير مغلقة تحت التكملة. (هل ترى لماذا؟) ولأننا نستطيع ترميز كل عنصر من باستعمال بت (وهذا الترميز المنتهي يمكن إنجازه بسهولة داخل قاعدة نحوية) فإن مبرهنة — كتمال قواعد CFG غير قابل للحساب يستلزم أن الكتمال غير قابل للحساب أيضًا بالنسبة للقواعد فوق الأبجدية الثنائية.
نبرهن على النظرية بالاختزال من مسألة التوقف (Halting problem). ولنحقق ذلك نستعمل مفهوم التكوينات (configurations) لبرامج NAND-TM، كما هو معرَّف في تعريف — تكوين آلة تورينج.. وتذكّر أن تكوين برنامج هو سلسلة ثنائية تُرمِّز كل المعلومات عن البرنامج في التكرار الحالي.
نعرِّف لتكون إضافة إلى بعض رموز الفاصل، ونعرِّف لتكون الدالة التي تُسقط كل سلسلة إلى إذا وفقط إذا كانت لا تُرمِّز تسلسل تكوينات يطابق تاريخ توقف صحيحًا لحساب على المدخل الفارغ.
وقلب البرهان هو أن نبيّن أن خالية من السياق. وبمجرد أن نفعل ذلك نرى أن تتوقف على المدخل الفارغ إذا وفقط إذا كان لكل . ولإثبات ذلك، سنُرمِّز القائمة بطريقة خاصة تجعلها قابلة لإصدار القرار بواسطة قاعدة نحوية خالية من السياق. وتحديدًا سنعكس كل السلاسل ذات الأرقام الفردية.
برهان
سنكتفي بعرض مخطط البرهان. سنبيّن أنه إذا استطعنا حساب أمكّننا حل مسألة ، وقد ثُبت في مبرهنة — التوقّف دون مدخل أنها غير قابلة للحساب. ولتكن آلة تورينج مدخل لـ . وسنستعمل مفهوم التكوينات (configurations) لآلة تورينج، كما هو معرَّف في تعريف — تكوين آلة تورينج..
وتذكّر أن تكوين آلة تورينج على المدخل يلتقط الحالة الكاملة لـ عند بعض نقاط الحساب. وتفاصيل التكوينات ليست مهمة إلى هذا الحد، لكن ما عليك تذكّره هو:
-
يمكن ترميز التكوين بسلسلة ثنائية .
-
التكوين الابتدائي (initial) لـ على المدخل هو سلسلة ثابتة ما.
-
سيحمل تكوين التوقف (halting configuration) القيمة في حالة معيّنة (يمكن "قراءتها" منه بسهولة).
-
إذا كان تكوينًا عند خطوة ما من الحساب، فإننا نرمّز بـ التكوين عند الخطوة التالية. و سلسلة تتفق مع في جميع الإحداثيات عدا عدد ثابت منها (تلك التي تُرمِّز الموضع المقابل لموضع الرأس والموضعين المجاورين له). وعلى تلك الإحداثيات يمكن حساب قيمة بدالة منتهية ما.
سنجعل الأبجدية . و_تاريخ الحساب_ (computation history) لـ على المدخل هو سلسلة تقابل قائمة (أي أن تسبق كتلة ذات رقم زوجي، و تسبق كتلة ذات رقم فردي) بحيث إذا كان زوجيًا تكون هي السلسلة التي تُرمِّز تكوين على المدخل في بداية تكراره -th، وإذا كان فرديًا يكون الأمر كذلك باستثناء أن السلسلة معكوسة. (أي أن، من أجل فردي، تُرمِّز تكوين على المدخل في بداية تكراره -th.) وعكس الكتل ذات الأرقام الفردية هو حيلة تقنية تضمن أن الدالة التي سنعرّفها أدناه تكون خالية من السياق.
ولنعرّف الآن كما يلي:
وسنبيّن الدعوى التالية:
الدعوى: خالية من السياق.
والدعوى تستلزم النظرية. وبما أن تتوقف على إذا وفقط إذا كان هناك تاريخ حساب صحيح، فإن هي دالة الواحد الثابتة إذا وفقط إذا كانت لا تتوقف على . وبخاصة، هذا يتيح لنا اختزال تحديد ما إذا كانت تتوقف على في تحديد ما إذا كانت القاعدة النحوية المقابلة لـ كاملة.
ولننتقل الآن إلى برهان الدعوى. لن نبيّن كل التفاصيل، لكن النقطة الأساسية هي أن إذا تحققت واحدة على الأقل من الشروط الثلاثة التالية:
-
ليست على الصيغة الصحيحة، أي أنها ليست من الشكل .
-
تحتوي على سلسلة فرعية من الشكل بحيث
-
تحتوي على سلسلة فرعية من الشكل بحيث
وبما أن الدوال الخالية من السياق مغلقة تحت عملية OR، فإن الدعوى تتبع إذا بيّنا أننا نستطيع التحقق من الشروط 1 و2 و3 بواسطة قاعدة نحوية خالية من السياق.
بالنسبة للشرط 1 فالأمر بسيط جدًا: فحص أن هي على الصيغة الصحيحة يمكن إنجازه باستعمال تعبير نمطي عادي. وبما أن التعبيرات النمطية العادية مغلقة تحت النفي، فإن هذا يعني أن فحص أن ليست على هذه الصيغة يمكن أيضًا إنجازه بتعبير نمطي عادي، وبالتالي بقاعدة نحوية خالية من السياق.
أما الشرطان 2 و3 فيتبعان بواسطة استدلال مشابه جدًا للاستدلال الذي يبيّن أن الدالة التي تحقق إذا وفقط إذا كان خالية من السياق؛ انظر تمرين محلول — غير المتناظرات. فبعد كل شيء، فإن دالة لا تعدّل مدخلها إلا في عدد ثابت من المواضع. ونترك استكمال التفاصيل تمرينًا للقارئ. وبما أن إذا وفقط إذا كانت تحقق أحد الشروط 1 أو 2 أو 3، وبما أنه يمكن اختبار الشروط الثلاثة جميعها بواسطة قاعدة نحوية خالية من السياق، فإن هذا يُكمل برهان الدعوى وبالتالي النظرية.
ملخّص الخصائص الدلالية للتعبيرات النمطية العادية والقواعد النحوية الخالية من السياق
ولتلخيص القول، يمكننا كثيرًا أن نُبدِّل القوة التعبيرية (expressiveness) للنموذج بـ_قابليته للتحليل_ (amenability to analysis). فإذا أخذنا في الحسبان نماذج حوسبة غير كاملة بحسب تورينج، فإننا نستطيع أحيانًا تجاوز نظرية Rice والإجابة على أسئلة دلالية معينة عن البرامج في مثل هذه النماذج. وفيما يلي ملخّص لبعض ما هو معروف عن الأسئلة الدلالية بالنسبة للنماذج المختلفة التي رأيناها.
---
caption: 'Computability of semantic properties'
alignment: ''
table-width: ''
id: semantictable
---
_Model_, **Halting**, **Emptiness**, **Equivalence**
_Regular expressions_, Computable, Computable,Computable
_Context free grammars_, Computable, Computable, Uncomputable
_Turing-complete models_, Uncomputable, Uncomputable, Uncomputable
خلاصة
- عدم قابلية مسألة التوقف للنماذج العامة للحساب هو ما يحفّز على تعريف نماذج الحوسبة المقيَّدة.
- في بعض النماذج المقيَّدة يمكننا الإجابة على أسئلة دلالية (semantic)، مثل: هل ينتهي برنامج معطى؟ وهل يحسب برنامجان الدالة نفسها؟
- التعبيرات النمطية العادية نموذج حوسبة مقيَّد غالبًا ما يكون مفيدًا في التعبير عن مهام مطابقة السلاسل. يمكننا اختبار ما إذا كان تعبير ما يطابق سلسلة بكفاءة، وكذلك الإجابة عن أسئلة مثل التوقف والتكافؤ.
- القواعد النحوية الخالية من السياق نموذج حوسبة أقوى، لكنه مع ذلك ليس كاملًا بحسب تورينج. مسألة التوقف للقواعد النحوية الخالية من السياق قابلة للحساب، في حين أن التكافؤ غير قابل للحساب.
التمارين
تمرين — خصائص الإغلاق للدوال الخالية من السياق
لنفترض أن خاليتان من السياق. بالنسبة لكل تعريف من تعريفات الدالة التالية، برهن إما على أن خالية من السياق دائمًا، أو أعطِ مثالًا مضادًا لدالتين نمطيتين عاديتين يجعلان ليست خالية من السياق.
-
.
-
-
.
-
حيث هو عكس : من أجل .
-
-
-
تمرين
برهن على أن الدالة التي تحقق إذا وفقط إذا كان قوة للعدد اثنين ليست خالية من السياق.
تمرين — صياغة لغات البرمجة
لنفكّر في الصياغة التالية لـ"لغة برمجة" يمكن كتابة شيفرتها المصدرية باستعمال مجموعة محارف ASCII:
-
تُحصل المتغيّرات (variables) على تسلسل من الحروف والأرقام والشرطات، لكن لا يمكن أن تبدأ برقم.
-
التعبير البرمجي (statement) هو إمّا على الشكل
foo = bar;حيثfooوbarمتغيّرات، أو على الشكلIF (foo) BEGIN ... ENDحيث...هي قائمة تضم عبارة برمجية واحدة أو أكثر، يحتمل أن تفصل بينها أسطر جديدة.
والبرنامج (program) في لغتنا هو ببساطة تسلسل من العبارات البرمجية (قد تفصل بينها أسطر جديدة أو مسافات).
-
لتكن الدالة التي، معطى سلسلة , تُخرج إذا وفقط إذا كانت تقابل ترميز ASCII لمعرّف متغيّر صحيح. برهن على أن نمطية عادية.
-
لتكن الدالة التي، معطى سلسلة , تُخرج إذا وفقط إذا كانت هي ترميز ASCII لبرنامج صحيح بلغتنا. برهن على أن خالية من السياق. (لا يلزمك تحديد القاعدة النحوية الرسمية الكاملة لـ ، لكن عليك أن تُبيّن أن قاعدة من هذا النوع موجودة.)
-
برهن على أن ليست عادية نمطيًا. انظر الحاشية للتلميح[2]
ملاحظات مرجعية
وكما في حالة التعبيرات النمطية العادية، تتوفر موارد كثيرة تتناول القواعد النحوية الخالية من السياق بتفصيل كبير. فالفصل 2 من [@SipserBook] يحتوي على أمثلة كثيرة للقواعد النحوية الخالية من السياق وخصائصها. وهناك أيضًا مواقع مثل Grammophone حيث يمكنك إدخال قواعد نحوية ومعرفة السلاسل التي تولّدها، فضلًا عن بعض الخصائص التي تحقّقها.
وتُستعمل صفة "الخلية من السياق" للقواعد النحوية الخالية من السياق لأن قاعدة من الشكل تعني أننا نستطيع دائمًا استبدال بالسلسلة ، بغضّ النظر عن السياق (context) الذي تظهر فيه . وبشكل أعم، ربما أردنا النظر في الحالات التي تعتمد فيها قواعد الاستبدال على السياق. وهذا ينشئ مفهوم القواعد العامة (أو "النوع 0") (general (aka "Type 0") grammars) التي تسمح بقواعد من الشكل حيث كل من و سلسلتان فوق . والفكرة أنه إذا أردنا مثلًا فرض الشرط بأن لا نطبّق قاعدة مثل إلا عندما تكون محاطة بثلاثة أصفار على كل جانب، فيمكننا فعل ذلك بإضافة قاعدة من الشكل (ويمكننا بالطبع إضافة شروط أكثر عمومية بكثير). وللأسف، يأتي هذا العمومية بثمن - فالقواعد العامة كاملة بحسب تورينج، وبالتالي فإن مسألة التوقف الخاصة بها غير قابلة للحساب. أي أنه لا توجد خوارزمية تستطيع تحديد، لكل قاعدة عامة وسلسلة ، ما إذا كانت القاعدة تولّد أم لا.
و[تسلسل تشومسكي] (Chomsky Hierarchy) هو تسلسل هرمي للقواعد النحوية، يبدأ من أقل القواعد تقييدًا (وأقواها) وهي قواعد النوع 0 التي تقابل اللغات المُعدودة تكراريًا (recursively enumerable) (انظر تمرين — قابلة للعد التكراري)، وصولًا إلى أكثر القواعد تقييدًا وهي قواعد النوع 3 التي تقابل اللغات النمطية العادية. وتقابل اللغات الخالية من السياق قواعد النوع 2. وقواعد النوع 1 هي القواعد النحوية الحسّاسة للسياق (context sensitive grammars). وهذه أقوى من القواعد النحوية الخالية من السياق لكنها مع ذلك أضعف من آلات تورينج. وبخاصة، فإن الدوال/اللغات المقابلة للقواعد الحسّاسة للسياق تكون دائمًا قابلة للحساب، بل fact أنها يمكن حسابها بواسطة [آلات محدودة خطيًا] (https://en.wikipedia.org/wiki/Linear_bounded_automaton) وهي خوارزميات غير حتمية تستهلك من المساحة. ولهذا السبب فإن صف الدوال/اللغات المقابلة للقواعد الحسّاسة للسياق يُعرف أيضًا بـ ؛ ونناقش التعقيد المقيّد بالمساحة في الحساب المقيّد بالمساحة). وفي حين أن نظرية Rice تستلزم أننا لا نستطيع حساب أي خاصية دلالية غير تافهة لقواعد النوع 0، فإن الوضع أعقد بالنسبة لأنواع القواعد الأخرى: فبعض الخصائص الدلالية يمكن تحديدها وبعضها لا يمكن، بحسب موقع القاعدة في التسلسل الهرمي.
وكما في حالة تعريف — مطابقة تعبير نمطي، يمكننا أيضًا استعمال اصطلاح اللغة (language) بدلًا من اصطلاح الدالة (function)، ونقول إن لغة خالية من السياق إذا كانت الدالة التي تحقق إذا وفقط إذا كان خالية من السياق. ↩︎
حاول أن ترى إن كنت تستطيع "تضمين" دالة تشبه في لتتمكن من استعمال برهان مشابه. وطبعًا، لكي تكون الدالة غير عادية نمطيًا، ليس عليها أن تستعمل رموز أقواس حرفية بالضرورة. ↩︎