TonitaN / FormalLanguageTheory

Slides and tasks for theory of formal languages course BMSTU IU9 (in Russian)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Л.Р.№2

TonitaN opened this issue · comments

Командам необходимо завести репозитории проектов. Парсер делает капитан, остальные задачи как-то распределяются между участниками проекта. Тестировщик будет только у Чиполлино. Интегратора у команды КК не будет.

В трансформационном моноиде в вводе в первой строчке вводится начальное состояние, множество конечных состояний, но не вводится множество промежуточных состояний (не начальных и не конечных). Нормально ли это?

Да, нормально. Остальные состояния извлекаются из системы переходов. Если состояние есть, а переходов по нему нет, то такое состояние имеет смысл, только если оно начальное (и определяет хоть что-то, если оно ещё и конечное).

У группы С++, скорее всего, не будет возможности найти реализацию ЛР номер 2 в индивидуальных вариантах этого года, потому что все, кто пишут на С++, собрались в групповой проект. Поэтому, если они решат расширять функционал этими лабами, стоимость задач совмещения для них повышена с 2 баллов до 6 баллов (но эти баллы получает только интегратор, который и вынужден будет писать соответствующую реализацию).

Рекорд: сдача в день официальной выдачи лабы.
Просто оставлю здесь

Если кто-то из групп таки передумал делать общий проект, то писать об этом нужно здесь, но только по согласованию с другими участниками группы. Кроме того, всё-таки нужно выбрать капитанов, если какие-то группы ещё остались в живых.

С интеграцией с предыдущим курсом как-то печально :( То ли дистант вас меньше зацепил, то ли благодаря первопроходцам в первой лабе с самого начала удачнее выбрали структуры данных, но я не могу порекомендовать из питоновских или С-работ по решению регулярных выражений почти что ни одну: все они по-рефальски переписывают строки, вместо того чтобы работать с объектами "регулярное уравнение". То есть встраивать эти работы получится только через файл, либо переписывать по-своему. Мне кажется, второе проще.

P.S. - А вот ваши работы я с удовольствием рекомендую следующему курсу, причём это касается целого ряда ЯП. Кое-какие баги - это мелочь, по сравнению с перестройкой общей структуры данных.

Один возможный вариант для питонистов здесь. Там же замечательное описание алгоритма.

Команда "Чайнхона"💨🍎🍏 (8 участников). Язык программирования: Python
Репозиторий: https://github.com/Postlog/TFL-Lab-2
Список участников:

Чтобы не бегать по всем репозиториям проектов (кстати, распределения ролей в третьей группе пока не вижу), сообщу здесь.

Любой баг во вспомогательных модулях группового проекта сильно бьёт по всем остальным, поэтому прошу не забывать о юнит-тестировании с прозрачным логгированием, и желательно сделать отдельный модуль для этого.

Команда "Комплексные козырьки" (7 участников). Язык программирования: Lua
Репозиторий: https://github.com/Qmask26/converter_team_project
Список участников:

Хотел уточнить, нужно ли в парсере обрабатывать возможный некорректный ввод, например несоответствие синтаксису, использование необъявленных переменных, неверное название функций и пр.? Или же подразумевается, что ввод всегда корректный?

Да, надо (только у КК я этого требовать не буду, т.к. у них капитан перегружен ещё одной задачей). Не обязательно с указанием строки и токена, где обнаружена ошибка, но с обработкой исключения точно.

Я всё-таки считаю, что желательно иметь абстрактную структуру язык, кроме регексов и автоматов. Например, у автомата тоже логично иметь алфавит (это упростит работу с некоторыми преобразованиями, такими как моноидальные, работа с ловушкой или построение отрицания), но алфавит - это всё-таки характеристика именно языка, а не автомата.
Заметим, что в системе преобразований почти никакие преобразования не меняют именно язык (и поэтому все свойства языка, известные к тому времени, как производится преобразование, наследуются). Исключения: Reverse, Complement (меняют язык, но не алфавит); а также пары Annote-DeAnnote, Linearize-DeLinearize (меняют и язык, и алфавит).

commented

Хотелось бы немного уточнить по поводу роли тайпчекера:

  1. Нужно проверять тип входных данных для всех операций всех остальных участников команды?
  2. Правильно ли я понимаю, что для динамической проверки операции необходимо дождаться её реализации?
  3. При динамическое проверке операции тайпчекер взаимодействует с кодом написавшего ее и по итогу их работ получится смесь их кода, верно?
  1. Статический режим тайпчека включается по флагу запуска, проверка происходит после синтаксического разбора, но до исполнения. Он более консервативен (т.е. может завернуть с ошибкой вполне корректную последовательность преобразований), но зато его можно реализовывать сразу после парсера. Опционально можно добавить режим слабой статической типизации: различающей только регексы, числа и автоматы, но не проверяющей на детерминированность - она будет отсеивать только заведомо ошибочные программы и эффективно сочетаться с динамическим тайпчеком.
  2. То, что конкретный метод не должен принимать, например, вместо ДКА - НКА (наоборот - конечно же допустимо), нужно проверять автору метода, а не тайпчекеру. Тайпчекер только обрабатывает результат этой проверки. Заметим, что в режиме статической типизации этого вообще не нужно проверять никому, поэтому включенный флаг статической проверки позволяет выключить все проверки на корректность входных данных алгоритмов в процессе исполнения. А вот проверка на единичные действия (т.е. такие, которые ничего не меняют), в динамическом режиме выполняется уже только тайпчекером. И она взаимодействует не с частными алгоритмами, а только с главным - кэширует результат предыдущих действий (как именно, продумать - ваша задача) и сравнивает с результатом исполнения очередного шага преобразований.

При статическом тайпчеке самое интересное - это продумать свойства алгебры преобразований, т.е. понять, какие последовательности действий будут точно бесполезны. Легко понять, что Determinize - идемпотент, но является ли единицей Reverse.Reverse (спойлер - не всегда) или Complement.Complement (спойлер - зависит от внутреннего представления автомата)?
Поэтому некоторые методы анализа автоматов (например, проверка определённых свойств автомата, влияющих на вышеуказанное) - это также предпочтительно ваша задача (исключение - опять же группа КК, где на капитане навешено и без этого слишком много).

Вопрос по трансформационному моноиду: когда мы перебираем все слова длины k, как обрабатывать те из них, которые не обрабатываются автоматом (например после удаления состояний-ловушек)?

Если они вообще не обрабатываются (т.е. нет ни одной пары состояний, которые бы переводились друг в друга таким словом), то это класс эквивалентности с пустым множеством переходов. Вполне легитимный представитель классов эквивалентности :)

Вопрос по трансформационному моноиду: можно ли иметь класс эквивалентности для пустого слова?

Пустое слово по классике в трансформационный моноид не включают. Т.е. рассматриваются слова, начиная с однобуквенных. Поэтому при анализе автомата (построение классов эквивалентности уже относительно языка) пустое слово можно рассмотреть отдельно. Если же уже в трансформационном моноиде нашёлся класс эквивалентности, содержащие не пустые слова и переводящий все состояния автомата в себя, то рассматривать отдельно пустое слово уже не надо - оно очевидно принадлежит именно этому классу.

Господа (и товарищи) капитаны команд (@Postlog , @Qmask26 , @StarikTenger). Кто пользуется системами менеджмента проектов - просьба кинуть скриншоты текущего распределения задач в темы "График проекта".

Похоже, кое-кто сумел придумать свой собственный алгоритм вложения языков регулярок ^_^ Надеюсь, автор расскажет о нём в эту субботу на семинаре. Ведь расскажет же, @theElusiveJoe?

Привет младшим от старших (трансформационный моноид).

Готов чёртов BFS (упрощение регулярок) от @Lasadaf (в том числе на Rust) - надеюсь, скоро в доступе.

Хорошее замечание от Даши Емельяненко. Синтаксическое правило <regex> ::= (<regex><binary><regex>) понимаем всегда как требующее двух непустых аргументов, если операция - пустая (т.е. конкатенация). Иначе получается взрыв единиц в свободном моноиде (всякое выражение в нескольких скобках можно понимать экспоненциально многими разными способами).

@UsefulTornado первый, кто сделал дополнительное задание в своём варианте (трансформационный моноид). @Postlog , рекомендую обратить внимание.

Инфиксы регулярки на Haskell - тут.

На lua теперь есть превосходная трансформация TRS (но в приватном репозитории, если у кого-то в команде @Qmask26 будет в ней необходимость, обращайтесь к @p0rtale). Также инфиксы регулярок у @Espenario (с очень опасной близостью некоторых кусков кода к рефалу )) ) и трансформация TRS у @nOmeep.

Контрольный смотр групповых проектов

Зная себя, я уверена, что первая же моя попытка протестировать групповые проекты собственноручно кончится каким-нибудь взрывом или поломкой. Безусловно, это я ещё сделаю, но перед РК дополнительный стресс не нужен никому. Поэтому поступим так: вы можете показать мне тот функционал, что считаете нужным, после контрольной. В каждой группе есть не занятые на контест, вот кому-нибудь из них и нужно делегировать смотр (прежде всего, это касается @Qmask26 и @StarikTenger, которым почти наверняка будет не до того, чтобы демонстрировать промежуточную сборку). @Postlog может в принципе и сам всё показать, после того как сдаст работу.

Бить не буду, штрафовать баллами не буду, но можем обсудить, какие возникли сложности, и попробовать понять, как и преодолевать. Просьба отнестись спокойно.

Раздача дополнительных баллов по индивидуальным вариантам

Вариант 0 (переписывание по пользовательским правилам)

Оказался трудным с точки зрения выбора порядка правил (BFS), а некоторым не очень поддалась унификация. У каждой реализации нашлись свои нюансы, причём разные. Как тут не вспомнить гоголевское "Если бы губы Никанора Ивановича да приставить к носу Ивана Кузьмича ... А теперь — поди подумай!"

Наиболее стабильны оказались @p0rtale, @pugprogram, @Lasadaf : +1 балл всем. И ещё посмотрим, как проявятся по этой части групповые проекты...

Вариант 1 (подрегулярки)

Чуда не случилось: +2 @theElusiveJoe. Однозначно самая быстрая и точная реализация, которую очень хотелось, но так и не удалось поймать на багах. забудем о недетерминированном Брзозовски, т.к. он создаёт веселье только в допчасти

Вариант 2 (моноиды)

@UsefulTornado первый и единственный, кто понял, в чём фишка с минимальностью, и как это связано со структурой трансформационного моноида. За что получает +1. По скорости он тоже лидирует, но @Ankalot отстал ненамного, поэтому +1 получают оба. Если в группах кто-то сможет их превзойти, то тоже получит бонус.

Поощрения группам

Чиполлино

@StarikTenger +2 @dak151449 +3 @xendalm +2 @shevchenkokk +1 @mathhyyn +1

Комплексные козырьки

@Qmask26 +1 и ещё +2 пусть сам решит кому раздать, т.к. народ частично прячется на мнимой полуоси

Интеграторов пока не смотрела.

Сейчас стяну с репозиториев групповые проекты и именно в таком формате буду проверять (т.е. дальнейшие наработки уже пойдут с учётом просрочки). На зачёт не обязателен полностью весь функционал, но если в основном функционале найдутся жесткие баги, не поставлю, пока соответствующий участник их не исправит. За хорошую реализацию (почти) всего функционала будут дополнительные баллы (небольшие, но приятные), особенно кто ещё не был поощрён. Также я решила, что бонус +2 за плюсы распространяется и на групповой проект, т.к. получилось весьма много по KLoC.

Следующая проверка групп будет только в четверг вечером. Не волнуйтесь, все хорошие реализации бонусом отмечу (и штрафа не будет у тех, кто уже почти всё сделал на той неделе, но не мог влиться в главную ветку из-за того, что не было сделано что-то у других). Но пожалуйста, убедитесь, что весь актуальный код - в главной ветке.

Вопрос по бисимуляции: вся команда получает +3 балла за реализацию бисимуляции на луа?

Да, этот бонус сохраняется, и сами разбирайтесь, кому распределить. У вас ещё +4 за Ардена, но с учётом недоделанных других функций (метода test, неоднозначности и аннотирования), от них остаётся 1.

Здравствуйте! Вопрос по SemDet. Похоже я слишком буквально понял то как надо применять производную для построения языка состояний. Можете подсказать как следует образовывать язык состояний? В текущей реализации я использовал регулярку из brzozovski_derivative(Lua), полученной по пути из начального состояния к рассматриваемому состоянию, как определение языка. Такой подход в большинстве случаев дает идентичные регулярки при рассмотрении неопределенности.

Я тоже сегодня думала об этом, и поняла, что это - проблема ТЗ. Способ с производными работает для языков состояний детерминированных автоматов, либо для семантически детерминированных НКА )) Из-за чего возник порочный круг. Для семантически недетерминированных НКА для порождения языка состояний надо было строить НКА со сдвинутым стартовым состоянием. Возможно, там ещё можно как-то через производные Антимирова, но это смотреть надо. Поэтому реализация семантического детерминизма вам засчитывается как правильная, и доделывать её не обязательно, а НКА-корректную реализацию SemDet мне самой потом интересно будет сделать.

Добрый вечер! Антонина Николаевна, а что делать группе, которая ещё не выложила семантический детерминизм?

Ну у этой группы и так штраф -2 за просрок, поэтому можете его не делать.

@artem-yadr , ответ про SemDet оказался совсем простым: алгоритм работает верно, если перед поиском префиксов и взятием производных разметить автомат с помощью метода Annote, а после получения языка состояния разметку снять. В вашей реализации разметок нет, поэтому там исправить это будет сложнее (придётся пересоздавать автоматы со сдвинутым стартовым состоянием). Что я тоже обязательно попробую!

Значит нужно будет переделать SemDet? Просто помимо реализации Annote встает вопрос с интеграцией его в проект, что в перспективе будет довольно болезненным процессом. А вот про то как сдвигать стартовые состояния и как это поможет мне не совсем ясно. Может быть мне удастся вставить костыль имитирующий annote и решить проблему таким образом.

Не надо переделывать - я же сказала, что по SemDet зачёт. Вопрос тут содержательный, а не зачётный - и вы им можете вообще не заниматься, - вас я упомянула лишь потому, что вы спрашивали, как это должно работать. С Annote я уже поняла, что не ваш вариант - это у тех, кто на плюсах, так исправить будет просто, из-за титанической работы по рефакторингу от @xendalm. Со сдвигом стартового ещё проверить нужно, как оно будет работать - и это не ваша задача. Вы со своей - той, что в ТЗ - по факту справились.