Регулярные выражения Эквивалентность - PullRequest
15 голосов
/ 18 февраля 2009

Есть ли способ узнать, эквивалентны ли два произвольных регулярных выражения? Выглядит как сложная проблема для меня, но может быть какой-то механизм упрощения DFA или что-то?

Ответы [ 4 ]

10 голосов
/ 18 февраля 2009

Чтобы проверить эквивалентность, вы можете вычислить минимальные DFA для выражений и сравнить их.

10 голосов
/ 18 февраля 2009

Проверяемость равенства является одним из классических свойств регулярных выражений. (N.B. Это не так, если вы действительно говорите о регулярных выражениях Perl или о каком-либо технически нерегулярном суперязыке.)

Превратите свои RE в обобщенные конечные автоматы A и B, затем создайте новый автомат A-B, такой, что принимающие состояния A имеют нулевые переходы в начальные состояния B, а принимающие состояния B инвертированы. Это дает вам автомат, который принимает все строки, принятые A, за исключением всех строк, принятых B.

Сделайте то же самое для B-A, и уменьшите оба до чистых FA. Если у FA нет принимающих состояний, доступных из начального состояния, то она принимает пустой язык. Если вы можете показать, что A-B и B-A пусты, вы показали, что A = B.

Edit Хех, я не могу поверить, что никто не заметил там гигантскую ошибку - преднамеренную, конечно: -p

Автоматы A-B, как описано, будут принимать те строки, первая половина которых принята A, а вторая половина не принята B. Построение требуемого A-B является немного более сложным процессом. Я не могу думать об этом из головы, но я знаю, что это хорошо определено (и, вероятно, включает в себя создание состояний, представляющих продукты принимающих состояний в A и неприемлемых состояний в B).

2 голосов
/ 18 февраля 2009

Это действительно зависит от того, что вы подразумеваете под регулярными выражениями. Как отмечали другие авторы, сокращение обоих выражений до минимального DFA должно работать, но оно работает только для чистых регулярных выражений.

Некоторые конструкции, используемые в реальных библиотеках регулярных выражений (в частности, обратные ссылки), дают им возможность выражать языки, которые не являются регулярными, поэтому алгоритм DFA для них не будет работать. Например, регулярное выражение: ([a-z]*) \1 соответствует двойному вхождению того же слова, разделенного пробелом (a a и b b, но не b a или a b). Это не может быть признано конечным автоматом вообще.

1 голос
/ 18 февраля 2009

Эти две темы Perlmonks обсуждают этот вопрос (в частности, читайте ответы блочхэдов):

...