- О проекте
- Сборка и запуск
- Генерация случайных тестов
- Синтаксис входных данных
- Функции преобразователя
Если останутся вопросы по функциональности, задайте их здесь
Принцип работы — на вход даётся файл с операциями над объектами, на выходе генерируется latex-файл с подробным описанием выполненных преобразований.
ВАЖНО! Для корректного составления latex-файла нужно поставить Graphviz, чтобы в
системе поддерживалась команда dot. Без этого не будет работать генерация изображений автоматов.
Если в системе поддерживается команда pdflatex, то тогда сразу будет генерироваться отчет в виде pdf-документа. Если
нет, необходимо установить Latex.
Сборка осуществляется через cmake. В wiki есть пример, как можно собрать.
Для запуска надо перейти в корневую папку проекта и там запустить собранное приложение. Пример на windows:
.\build\apps\InterpreterApp\Debug\InterpreterApp
В качестве опционального аргумента указывается путь к файлу с командами (по умолчанию test.txt).
Для удобства тестирования был создан генератор входных данных.
Его запуск на windows:
.\build\apps\InputGeneratorApp\Debug\InputGeneratorApp
В файле apps\InputGeneratorApp\src\main.cpp можно поменять параметры генерируемых тестов:
TG.generate_task(3, 5, false, false);
где 1 аргумент - количество операций, 2 аргумент - максимальное количество функций в последовательности.
Интерпретатор поддерживает следующие типы:
- Regex — регулярное выражение (с операциями '|' и '*')
- NFA — недетерминированный конечный автомат
- DFA — детерминированный конечный автомат
- PrefixGrammar - префиксная грамматика
- BRefRegex - расширенные регулярные выражения с обратными ссылками
- MFA - конечный автомат с памятью
- Int
- String
- Boolean
- OptionalBool
- AmbiguityValue - мера неоднозначности
(Может принимать одно из 4-х значений: Unambiguous, Almost unambiguous, Polynomially ambiguous, Exponentially ambiguous) - Array - правила переписывания
- Regex. Записываются в фигурных скобках. Пример:
{a*(b|c)*} - RandomRegex. Символ
*. на место которого подставляются генерируемые регулярные выражения в верификаторе - Array. Правила переписывания. Пример:
[[{a} {b}]](означаетa -> b) - Function. Название и список аргументов через пробел. Пример:
Glushkov {ab|a} - Function sequence. Последовательное применение функций справа-налево. Пример:
Annote.Glushkov.DeAnnote {a} - Int. Целое число. Пример:
8 - Variable - переменная. Примеры:
A,N1,N2 - Expression. Function sequence, Int, Regex или Variable
Для функций и последовательностей функций должны выполняться соответствия типов. Больше про типы функций - ниже в разделе Функции преобразователя.
В каждой строчке записана ровно одна команда. Поддерживаются команды пяти типов:
-
declaration
Присвоение переменной значения. Если в конце стоит!!, выражение логируется в latex.
Синтаксис:
<varaible> = <expression> '!!'?
Пример:A = Complement.Annote (Glushkov {a*}) !! B = States.Reverse A -
test
Аргументы:
1. НКА или регулярное выражение (язык 1)
2. регулярное выражение — тестовый сет (язык 2)
3. натуральное число — шаг итерации в сете
Подробнее про то, как работает — см. в презентации.
Синтаксис:
Test <expression> <expression> <int>
Пример:Test {(aa)*} {a*} 3 Test (Glushkov {(aa)*}) {a*} 1 -
predicate
Булева функция, записанная одной строчкой. Будет логироваться в любом случае.
Синтаксис:
<function> <expression>+
Пример:
Equiv (Antimirov {ab|a}) (Glushkov {ab|a}) -
verify
Аргументы:
1. Предикат (с конструкцией*, на место которой подставляются сгенерированные регулярные выражения)
2. (опциональный) натуральное число — количество тестов
Синтаксис:
Verify <expression> <int>?
Пример:Verify (Equal (Ambiguity.Glushkov.Arden.Glushkov *) (Ambiguity.Glushkov *)) -
set
Аргументы:
1. Имя флага:
-weak_type_comparison— устанавливает эквивалентность типовDFAиNFA, т.е. допускает на входNFAдля функций, требующихDFА
TODO:
-log_theory— добавляет теоретический блок к функциям в отчете
-auto_remove_trap_states— отвечает за удаление ловушек
2. Значение флага:true/false
Синтаксис:
Set <flagName> <true/false>
* NFA здесь можно понимать как FA, для которого не обязан быть включённым флаг детерминизма.
Преобразования со сменой класса:
Thompson: Regex -> NFA— строит автомат Томпсона по регулярному выражениюAntimirov: Regex -> NFAGlushkov: Regex -> NFAIlieYu: Regex -> NFA— follow-автоматArden: NFA -> Regex— строит регулярное выражение по автоматуPrefixGrammar: NFA -> PrefixGrammar— возвращает префиксную грамматику для НКАPGtoNFA: PrefixGrammar -> NFA— преобразует префиксную грамматику в НКА
Преобразования внутри класса
Над регулярными выражениями:
Linearize: Regex -> Regex— размечает буквы в регулярном выражении, как в алгоритме ГлушковаDeLinearize: Regex -> Regex— снимает разметку LinearizeDeAnnote: Regex -> Regex— снимает разметку Annote
TODO:Disambiguate: Regex -> Regex— для 1-однозначных языков возвращает 1-однозначное регулярное выражение, для остальных возвращает данное на вход
Над конечными автоматами:
Determinize: NFA -> DFA— детерминизация без добавления состояния-ловушкиMinimize: NFA -> DFA— минимизация без добавления состояния-ловушкиDeterminize+: NFA -> DFA— детерминизация с добавлением состояния-ловушкиMinimize+: NFA -> DFA— минимизация с добавлением состояния-ловушкиRemoveTrap: DFA -> DFA- удаление состояний-ловушекReverse: NFA -> NFA— обращение ("переворачивает" автомат)Complement: DFA -> DFA— дополнениеRemEps: NFA -> NFA— удаление ε-правилMergeBisim: NFA -> NFA— объединение эквивалентных по бисимуляции состоянийAnnote: NFA -> DFA— навешивает разметку на все буквы в автомате, стоящие на недетерминированных переходахDeAnnote: NFA -> NFA— снимает разметку AnnoteDeLinearize: NFA -> NFA— снимает разметку LinearizeIntersect: (NFA, NFA) -> NFA— пересечение языковUnion: (NFA, NFA) -> NFA— объединение языковDifference: (NFA, NFA) -> NFA— разность языков
Многосортные функции
-
States: NFA -> Int— возвращает количество состояний в автомате -
ClassCard: NFA -> Int— число классов эквивалентности в трансформационном моноиде -
ClassLength: NFA -> Int— самое длинное слово в классе эквивалентности трансформационного моноида -
MyhillNerode: NFA -> Int— возвращает число классов эквивалентности по Майхиллу–Нероуду -
GlaisterShallit: NFA -> Int— определяет нижнюю границу количества состояний в НКА для языка -
Ambiguity: NFA -> AmbiguityValue— определяет меру неоднозначности автомата. Если число путей, по которым распознается слово (длины от минимальной до$s^2$ ) растёт быстрее, чем полином степени |s|, где s — число состояний НКА, то автомат экспоненциально неоднозначен. Если число путей растёт медленнее, чем линейная функция, то автомат почти однозначен (либо однозначен, если путь всегда один). Иначе автомат полиномиально неоднозначен.
TODO: -
PumpLength: Regex -> Int— возвращает длину накачки языка Normalize: (Regex, Array) -> RegexNormalize: (Regex, FileName) -> Regex
Предикаты
Для регулярных выражений:
Subset: (Regex, Regex) -> Boolean— проверяет вложенность второго языка в первыйEquiv: (Regex, Regex) -> Boolean— проверяет, описывают ли регулярные выражения один языкOneUnambiguity: Regex -> Boolean— проверяет, является ли регулярное выражение 1-однозначным. Регулярное выражение является 1-однозначным, если возможно однозначно определить, какая позиция символа в регулярном выражении должна соответствовать символу во входном слове, не заглядывая за пределы этого символа во входном слове.Equal: (Regex, Regex) -> Boolean— проверяет буквальное равенство регулярных выражений (как строк, с учетом альтернатив)
Для конечных автоматов:
Bisimilar: (NFA, NFA) -> Boolean— проверяет бисимилярность автоматовEquiv: (NFA, NFA) -> Boolean— проверяет, описывают ли автоматы один языкEqual: (NFA, NFA) -> Boolean— проверяет буквальное равенство автоматовSubset: (NFA, NFA) -> Boolean— проверяет вложенность второго языка в первыйMinimal: DFA -> Boolean— проверяет, минимален ли детерминированный автоматMinimal: NFA -> OptionalBool— проверяет, минимален ли недетерминированный автоматDeterministic: NFA -> Boolean— проверяет автомат на детерминированностьOneUnambiguity: NFA -> Boolean— проверяет, является ли язык 1-однозначным. 1-однозначный язык - это язык, описываемый 1-однозначным регулярным выражением.
TODO:SemDet: NFA -> Boolean— проверяет, является ли автомат семантически детерминированным. Язык состояния q — это {w | q→wqf} Семантическая детерминированность означает, что для всякой неоднозначности q i →aqj1, ..., qi→aqjk существует такое состояние qjs, что языки всех qjt (1 ⩽ t ⩽ k) вкладываются в его язык.
Многосортные:
Equal: (Int, Int) -> BooleanEqual: (Boolean, Boolean) -> BooleanEqual: (AmbiguityValue, AmbiguityValue) -> Boolean
Методы регулярных выражений с обратными ссылками:
MFA: BRefRegex -> MFAMFAexpt: BRefRegex -> MFAReverse: BRefRegex -> BRefRegexIsAcreg: BRefRegex -> Boolean
Методы MFA:
RemEps: MFA -> MFAAddTrap: MFA -> MFAComplement: MFA -> MFADeterministic: MFA -> BooleanBisimilar: (MFA, MFA) -> OptionalBoolAction: MFA -> NFASymbolic: MFA -> NFAActionBisimilar: (MFA, MFA) -> BooleanSymbolicBisimilar: (MFA, MFA) -> BooleanEqual: (MFA, MFA) -> BooleanMergeBisim: MFA -> MFAEqual: (BRefRegex, BRefRegex) -> Boolean
Метод Test
Test: (Regex|NFA, Regex, Int) -> таблица — порождает слова, принадлежащие второму языку (2 аргумент), раскрывая каждую
итерацию Клини начиная с 0 (пустого слова) и увеличивая с каждым разом на заданное значение (3 аргумент). Если в
регулярном выражении (для 2 языка) присутствуют альтернативы, то выбирается 1ая из них.
То есть
a*b c шагом 2 раскрывается в ряд: b, aab, aaaab ...
(a*b)*c c шагом 1 раскрывается в ряд: c, abc, aabaabc ...
Возвращает таблицу, в которой указаны результаты проверки на принадлежность каждого из порожденных слов первому языку (1
аргумент).
Завершает тестирование, когда сделано более 12 шагов, либо парсинг входной строки занимает больше 3 минут.
Верификатор гипотез
Verify: (Boolean, Int?) -> Int - принимает на вход набор действий, содержащий единственный предикат. Строится сет
тестов, размер которого определяет 2й аргумент (значение по умолчанию - 20). В выражение на место конструкции *
подставляются случайные регулярные выражения.
В результатах тестирования выделяется доля тестов с положительным значением предиката, и примеры кейсов, когда гипотеза
не выполнилась.
Дополнительно о некоторых функциях и требованиях к входным данным можно почитать в файле.
Успехов!