Я шукаю граматику, залежну від контексту, яка описує наступну мову: .
У мене проблеми з тим, що немає таких правил, як дозволено, і тому я не можу розміщувати жодних нетермінальних, що вказують на "середину" слова. Чи є якась хитрість до проблеми?
Я шукаю граматику, залежну від контексту, яка описує наступну мову: .
У мене проблеми з тим, що немає таких правил, як дозволено, і тому я не можу розміщувати жодних нетермінальних, що вказують на "середину" слова. Чи є якась хитрість до проблеми?
Відповіді:
Дійсно, є простий трюк, який дозволяє додавати додаткову інформацію на певну позицію: просто замініть букву, що прилягає до позиції, і позначте її інформацією, а також оригінальним листом.
У вашому прикладі є нетермінальний для середини, але оскільки її неможливо видалити, вона також вважається звичайною літерою. Таким чином, у нас є два примірники і для позначення замінених букв. Наприкінці деривації маркери повинні бути замінені їхнім буквеним змістом, простими виробництвами, як-от.
У більшості випадків застосування потрібно виконати в кінці процесу отримання. У деяких конструкціях це не потрібно "приурочувати": колизникає занадто рано, деривація не може знайти належну позицію і процес не зупиниться успішно. В інших випадках потрібен вид контролю. Це іноді робиться шляхом введення нетерміналу як сигналу, який рухається по буквах. Знову ж, цей сигнал також повинен нести термінал, інакше у вас виникнуть ті самі проблеми.
Переміщення інформації легко в так званих монотонних граматиках ( з ) за допомогою таких правил , яку можна розглядати як перестрибуючи . Для правильних контекстно-чутливих граматик потрібно розділити це на три етапи:. у кожному виробництві одна літера змінюється у відповідному контексті. Потрібно досить фантазії, щоб цей процес не взаємодіяв з іншими частинами походження. Наприклад, що відбувається, коли на останньому кроці спочатку бере участь в іншому етапі виведення?
Це може не спрацювати з дуже короткими словами, коли інформації більше, ніж позицій. Найпростіше рішення - ігнорувати короткі рядки у вашій конструкції та генерувати їх окремо.
Коротка відповідь за замовчуванням: придумайте LBA, який приймає мову, і використовуйте моделювання, яке використовується для підтвердження того, що контекстно-залежні граматики та LBA визначають один і той же набір мов. Але це, звичайно, не те, що ти шукаєш.
У цьому конкретному випадку спробуйте продумати правильну лінійну граматику для двічі, один для лівої та один для правої половини. Все, що вам потрібно забезпечити, щоб обидві граматики виходили «синхронно».
Це можна зробити, поміняючи навколо контрольного маркера. Тобто ліва граматика підбирає правило, формує придатний контрольний маркер і передає його правильній граматиці. Права граматика бачить контрольний маркер і виконує правило придатності. Зауважте, що ви також можете реалізувати двосторонній зв’язок таким чином, але це не потрібно.
Існує одна проблема з контекстно-залежними граматиками: вони ніколи не можуть видаляти нетермінали (за винятком якщо в мові порожнє слово). Тому ми повинні створити лише стільки нетерміналів, скільки нам буде потрібно; жоден не може бути зайвим.
Один із способів досягти цього - використовувати той самий трюк, що і для певних доказів щодо LBA: генеруйте всі нетермінали, які вам знадобляться спочатку , тобто підготуйте "стрічку". Пізніше "рухайтесь" на цій стрічці. Тільки "в кінці" замініть всі нетермінали на клеми.
Тож нехай з (конструкція легко поширюється на більші алфавіти) та , задані наступними правилами.
є правилами генерації «стрічки». Зверніть увагу, що капелюх позначає "положення голови" та індексипозначають, до якої половини слова належить нетермінальний. Короткі слова генеруються таким чином, щоб зберегти деякі правила нижче. Тепер нам потрібні правила для отримання одного символу в лівій частині:
для усіх . Зверніть увагу, як ми використовуємо верхній індекс, щоб перенести згенерований символ праворуч. і є "кінцевими" нетерміналами, які використовуються лише для переміщення маркера управління навколо та отримання терміналів пізніше. Крім того, зауважте, що друге правило використовується (тільки) для останнього символу правої половини.
Для переміщення несучої в праву половину ми повинні пройти повз обох залишилися і вже створено :
для усіх . Тепер, як тільки переносник досягне правого керуючого маркера, ми повинні імітувати правило, яке використовується зліва:
для усіх . Зауважте, що перше правило використовується для першого символу правої половини, а останнє правило може використовуватися лише для самого останнього символу, інакше виведення ніколи не припиняється. Тепер нам потрібні лише правила закінчення
для усіх і ми зробили. Ці правила теж можна застосувати лише після того, як зроблено все (зліва), інакше виведення не припиниться.
Зауважте, що ця граматика неоднозначна. Не тільки може(безпечно) застосовувати будь-де ліворуч від лівої "голови" в будь-який час, але також може бути одночасно декілька перевезень. Оскільки вони ніколи не можуть наздогнати один одного, правильний порядок підтримується.
Одне зауваження слід зробити ще: вище граматика не є контекстно-залежною, оскільки багато правил змінюють обидва символи зліва. Це не дозволено для контекстно-залежних граматик. На щастя, ми можемо змоделювати будь-яке правило форми
від
тому ми хороші і можемо працювати з меншими граматиками. Показати, що втручання між декількома подібними моделюваннями не шкодить, залишається як вправа.
Чи бачите ви, як поширити це на ? Це також працює? Чи можете ви використовувати одну і ту ж конструкцію для будь-якої для регулярних ?
Хоча я не знаю, як виглядатиме граматика, залежна від контексту, ви можете обійти проблему із символом наступним чином.
Ви знаєте, що ваші сполучені слова повинна бути не менше довжини . Отже, ви можете їх просто "кодувати"-правила вашої граматики за такими правилами, як:
Хоча я ще не можу побачити загальне рішення, тому що, на мій погляд, здається, що ліва сторона ваших граматичних правил потенційно може бути довільною, тому що я думаю, ви б спробували врахувати префікси якось у ваших правилах.