ТАФЯ. Лабораторная работа 1
.docxМИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ,
СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное бюджетное образовательное учреждение высшего образования «Санкт-Петербургский государственный университет
телекоммуникаций им. проф. М. А. Бонч-Бруевича»
(СПбГУТ)
Факультет инфокоммуникационных сетей и систем
Кафедра программной инженерии и вычислительной техники
ЛАБОРАТОРНАЯ РАБОТА №1
по дисциплине «Теория алгоритмов и формальных языков»
студенты гр. ИКПИ-93 |
_______________ |
Смирнов Д.А. Тюришев М.А. Цыганков М.А. Козлов Н.С. |
|
|
|
ассистент каф. ПИиВТ |
_______________ |
Марочкина А. В. |
Санкт-Петербург
2022
ПОСТАНОВКА ЗАДАЧИ
Необходимо написать программу, выводящую на экран одно случайное слово языка и несколько слов языка.
ХОД РАБОТЫ
Код разработанной программы на языке Python приведен в таблице 1.
Таблица 1. Код разработанной программы
main.py |
import collections import itertools import random def generate(start: str, rules: list) -> str: """ Генерирует (порождает) слова языка, не допуская дубликатов слов Может зациклиться, если rules не строит язык: {S -> S}, {F -> aFa} и др. :param start: исходное слово (обычно: S) :param rules: правила перевода """ # убираем пустой символ в исходном слове, если есть start = start.replace('ε', '') if start.islower(): # если нетерминальных символов нет, то возврат исходного слова yield start else: # если есть хотя бы один нетерминальный символ, то пробуем правила перевода # убираем из правил перевода пустой символ, если есть rules = [(from_.replace('ε', ''), to_.replace('ε', '')) for from_, to_ in rules] q = collections.deque([start]) # очередь слов generated_words = {start} # множество слов: и с терминальными, и с нетерминальными символами while q: # q может стать пустым, если грамматика строит конечный язык word = q.popleft() # получаем и удаляем первый элемент списка слов for from_, to_ in rules: # перебираем все правила перевода from_ в to_ len_from_ = len(from_) # получаем длину from_ # перебираем все вхождения from_ в word position = word.find(from_) while position != -1: # формируем новое слово, имея i вхождение from_ в word new_word = word[:position] + to_ + word[position + len_from_:] if new_word not in generated_words: # если слово не было ещё сгенерировано generated_words.add(new_word) # добавляем в множество сгенерированных if new_word.islower(): # если в new_word все символы терминальные yield new_word # возвращаем new_word и продолжаем цикл else: # если в new_word хотя бы один символ нетерминальный q.append(new_word) # добавляем новое слово в очередь position = word.find(from_, position + 1) # ищем следующее вхождение def generate_all(start: str, rules: list, max_words: int) -> list: """ Генерирует (порождает) max_words слов языка Может зациклиться, если rules не строит язык: {S -> S}, {F -> aFa} и др. :param start: исходное слово (обычно: S) :param rules: правила перевода :param max_words: максимальное число слов языка :return: список max_words слов языка """ return list(itertools.islice(generate(start, rules), max_words)) def generate_any(start: str, rules: list, max_words: int) -> list: """ Генерирует (порождает) max_words слов языка и возвращает любое из них Может зациклиться, если rules не строит язык: {S -> S}, {F -> aFa} и др. :param start: исходное слово (обычно: S) :param rules: правила перевода :param max_words: максимальное число слов языка :return: любое из max_words слов языка """ return random.choice(generate_all(start, rules, max_words))
|
def main(): # Правила перевода v_rules = [ # Вариант 1 [ ('S', 'AA'), ('A', 'aAb'), ('A', 'ab') ] start = 'S' max_words = 50 for n, rules in enumerate(v_rules, 1): print(f"{n} вариант") # Генерация максимум max_words слов языка words = generate_all(start, rules, max_words) n_words = len(words) print(f'Слова языка ({n_words}):', words) # Генерация максимум max_words слов языка и возврат любого из них any_word = generate_any(start, rules, max_words) print(f'Любое из слов языка (до {n_words}):', any_word, end='\n\n') if __name__ == '__main__': main()
|
|
Программа выводит на экран максимум 50 слов и одно случайное слово для каждого варианта.
Запуск программы продемонстрирован на рисунке 1.
Рисунок 1. Запуск программы и вывод результата
Можно ли по любой грамматике без ограничений определить, конечно ли число слов в ней или нет? Нельзя, существует так называемая проблема остановки (англ. Halting problem):
Даны описание процедуры и её начальные входные данные. Требуется определить: завершится ли когда-либо выполнение процедуры с этими данными; либо, что процедура всё время будет работать без остановки.
Алан Тьюринг доказал в 1936 году, что проблема остановки неразрешима на машине Тьюринга. Другими словами, не существует общего алгоритма решения этой проблемы.
Именно по этой причине разработанная программа может зациклиться, если грамматика не строит язык. Например, в случае языков {𝑆 → 𝑎𝑆} и {𝑆 → 𝑎𝐴, 𝐴 → 𝐹𝑆, 𝐹 → 𝑡}.
Вывод программы |
1 вариант Слова языка (50): ['abab', 'aabbab', 'abaabb', 'aaabbbab', 'aabbaabb', 'abaaabbb', 'aaaabbbbab', 'aaabbbaabb', 'aabbaaabbb', 'abaaaabbbb', 'aaaaabbbbbab', 'aaaabbbbaabb', 'aaabbbaaabbb', 'aabbaaaabbbb', 'abaaaaabbbbb', 'aaaaaabbbbbbab', 'aaaaabbbbbaabb', 'aaaabbbbaaabbb', 'aaabbbaaaabbbb', 'aabbaaaaabbbbb', 'abaaaaaabbbbbb', 'aaaaaaabbbbbbbab', 'aaaaaabbbbbbaabb', 'aaaaabbbbbaaabbb', 'aaaabbbbaaaabbbb', 'aaabbbaaaaabbbbb', 'aabbaaaaaabbbbbb', 'abaaaaaaabbbbbbb', 'aaaaaaaabbbbbbbbab', 'aaaaaaabbbbbbbaabb', 'aaaaaabbbbbbaaabbb', 'aaaaabbbbbaaaabbbb', 'aaaabbbbaaaaabbbbb', 'aaabbbaaaaaabbbbbb', 'aabbaaaaaaabbbbbbb', 'abaaaaaaaabbbbbbbb', 'aaaaaaaaabbbbbbbbbab', 'aaaaaaaabbbbbbbbaabb', 'aaaaaaabbbbbbbaaabbb', 'aaaaaabbbbbbaaaabbbb', 'aaaaabbbbbaaaaabbbbb', 'aaaabbbbaaaaaabbbbbb', 'aaabbbaaaaaaabbbbbbb', 'aabbaaaaaaaabbbbbbbb', 'abaaaaaaaaabbbbbbbbb', 'aaaaaaaaaabbbbbbbbbbab', 'aaaaaaaaabbbbbbbbbaabb', 'aaaaaaaabbbbbbbbaaabbb', 'aaaaaaabbbbbbbaaaabbbb', 'aaaaaabbbbbbaaaaabbbbb'] Любое из слов языка (до 50): aabbab
|
ЗАКЛЮЧЕНИЕ
В результате выполнения лабораторной работы мы написали программу, выводящую на экран одно случайное слово языка и несколько слов языка.
