Когда проблема кажется непреодолимой, решение часто заключается в том, чтобы публично объявить о том, насколько сложна, по вашему мнению, проблема. Тогда вы сразу поймете, что проблема тривиальна, и вы только что заставили себя выглядеть идиотом - и это в основном то, где я сейчас нахожусь; -)
Как предложено в вопросе, чтобы лексически упорядочить два автомата, мне нужно рассмотреть две вещи. Два набора возможных первых токенов и два набора возможных хвостов. Хвосты могут быть представлены как конечные автоматы и могут быть получены из оригинальных автоматов.
Так что алгоритм сравнения рекурсивный - сравните голову, если у вас другой результат, если тот же самый, то рекурсивно сравните хвост.
Проблема заключается в бесконечной последовательности, необходимой для доказательства эквивалентности регулярных грамматик в целом. Если во время сравнения пара автоматов повторяется, что эквивалентно паре, которую вы проверяли ранее, вы доказали эквивалентность и можете прекратить проверку. В природе конечных автоматов это должно происходить за конечное число шагов.
Проблема в том, что у меня все еще проблема в той же форме. Чтобы определить мои критерии завершения, мне нужно сравнить мою пару автоматов со всеми прошлыми парами автоматов, которые произошли во время сравнения. От этого у меня болит голова.
Также оказалось, что эта статья актуальна, но, вероятно, только уводит меня так далеко. Обычные языки могут формировать группу с помощью оператора конкатенации, и левый смежный класс связан с заголовком: все, что я рассматривал.
Причина, по которой я идиот, заключается в том, что я навязывал слишком строгое условие завершения, и я должен был это знать, потому что это не так уж необычно - проблема с алгоритмами автоматов WRT.
Мне не нужно останавливаться на первом повторении пары автоматов. Я могу продолжать, пока не найду более легко обнаруживаемое повторение - такое, которое имеет некоторую структурную эквивалентность, а также логическую эквивалентность. До тех пор, пока мой алгоритм «извлекать хвост из автомата» вменяемый (и особенно если я минимизирую и выполняю другие очистки на каждом этапе), я не буду генерировать бесконечную последовательность эквивалентных, но отличающихся друг от друга пар автоматов во время сравнения. Единственными источниками вариаций в структуре являются исходные два автомата и алгоритм хвостовых автоматов, оба из которых конечны.
Суть в том, что если я сравниваю слишком много лексических терминов, это не имеет большого значения - я все равно получу правильный результат, и хотя я закончу работу чуть позже, я все равно завершу работу за конечное время.
Это должно означать, что я могу использовать ненадежное обнаружение повторения (допуская некоторые ложные отрицания), используя хэш или упорядоченное сравнение, чувствительное к структуре автоматов. Это более простая проблема, чем сравнение, не зависящее от структуры, и я думаю, что это ключ, который мне нужен.
Конечно, все еще существует проблема производительности. Линейный поиск с использованием стандартного алгоритма эквивалентности может быть более быстрым подходом, основанным на проблемах, связанных с этим. Конечно, я ожидаю, что это сравнение будет менее эффективным тестом эквивалентности, чем существующие алгоритмы, так как оно выполняет больше работы - лексическое упорядочение неэквивалентных случаев. Реальная проблема заключается в общей эффективности поиска по ключу, и, вероятно, потребуется некоторый анализ, вызывающий головную боль. Я надеюсь, что тот факт, что неэквивалентные автоматы будут стремиться сравнивать быстро (обнаруживая разницу в первых нескольких шагах, как традиционные сравнения строк), сделает это практическим подходом.
Кроме того, если я достигну точки, где я подозреваю эквивалентность, я мог бы использовать стандартный алгоритм эквивалентности для проверки. Если эта проверка не удалась, я просто продолжаю сравнивать порядок, в котором я остановился, без необходимости проверять повторение хвостового языка - я знаю, что найду разницу в конечном числе шагов.