Может ли Z3 найти регулярное выражение, удовлетворяющее некоторым примерам?

#regex #z3

Вопрос:

У меня есть набор таких строк:

{«01», «001», 000111″, 01111″}

Теперь мне интересно, могу ли я попросить Microsoft Z3 найти минимальное регулярное выражение, удовлетворяющее строкам. Например, выходные данные для этого конкретного набора должны быть примерно такими 0*1* .

Комментарии:

1. Зачем, учитывая фиксированное количество строк, пытаться получить регулярное выражение, сгенерированное машиной? сомнительно, что вы получите одно регулярное выражение, которое соответствует только этим строкам, например ^0(?:1(?:111)?|0(?:011)?1)$

2. На самом деле мне нужен минимальный.

3. @MojtabaValizadeh Какое понятие «минимального» вы имеете в виду? Существует много возможных определений (например, длина RE в виде строки или *-высота)?

4. @MartinBerger Длина RE в виде строки на этом этапе подходит.

Ответ №1:

В теории, да. На практике-да, но, вероятно, не так, как вы хотели. По крайней мере, пока нет.

Строго говоря, легко закодировать то, что вы хотите. Вот как вы бы закодировали проблему для нужного вам набора:

 (set-logic QF_S)
(set-option :produce-models true)

(define-fun re1 () RegLan (str.to_re "01"))
(define-fun re2 () RegLan (str.to_re "001"))
(define-fun re3 () RegLan (str.to_re "000111"))
(define-fun re4 () RegLan (str.to_re "01111"))
(define-fun re5 () RegLan (re.union re1 re2 re3 re4))
(check-sat)
(get-value (re5))
 

И действительно, z3 говорит:

 sat
((re5 (re.union (str.to_re "01")
          (re.union (str.to_re "001")
                    (re.union (str.to_re "000111") (str.to_re "01111"))))))
 

Но я слышу, как ты стонешь и говоришь: «Но это не то, чего я хочу!» И действительно, хотя это правильное решение, это, вероятно, не то, что вы хотели. Это ни в коем случае не «минимально» в каком-либо удовлетворительном смысле.

Чтобы действительно сделать то, что вам нужно, вы хотите иметь возможность записывать переменные, которые сами могут соответствовать регулярным выражениям. И действительно, SMTLib и, следовательно, z3 позволяют регулярным выражениям быть символическими. Подробности смотрите здесь: https://smtlib.cs.uiowa.edu/theories-UnicodeStrings.shtml. Однако вот прямая цитата с этой страницы о том, какие типы регулярных выражений разрешены:

Функция str.to_re позволяет писать символьные регулярные выражения, например, термины RegLan с подстроками, такими как (str.to_re x), где x-переменная. Такие термины обладают большей выразительной силой, чем регулярные выражения. Это сделано намеренно, для будущих разработок. Ограничение на фактические регулярные выражения будет наложено в логике, где str.to_re будет применим только к строковым константам.

И, насколько я знаю, пока нет SMT-решателя, включая z3, который поддерживал бы символические регулярные выражения. Вот простой эксперимент:

 (set-logic QF_S)
(declare-fun x () RegLan)
(assert (str.in_re "0" x))
(check-sat)
 

Когда я передаю это z3, я получаю:

 unknown
 

т. е. это действительно проблема, но z3 не может с ней справиться. Если вы передадите его в cvc4, он будет более громко говорить о проблеме:

 (error "Regular expression variables are not supported.")
 

Итак, подведем итог: то, что вы пытаетесь сделать, возможно в SMTLib, но в настоящее время оно не поддерживается ни одним решателем, по крайней мере, не так, как вы хотели бы, чтобы оно работало. Надеюсь, в будущем это может измениться, хотя я бы не стал задерживать дыхание.

Учитывая это, что вы можете сделать? Я думаю, что использовать для этого SMT-решатель-это немного перебор. Для каждой постоянной строки вы можете построить регулярное выражение, которое ее распознает. Превратите это в DFA. А затем возьмите союз всех этих DFA. Наконец, превратите его в минимальный DFA и считайте регулярное выражение, которое от него исходит. Это довольно большая работа, но она должна хорошо работать на практике, т. е. все части этой стратегии хорошо известны, как ее реализовать, и должны быть довольно дешевыми с точки зрения сложности выполнения.

Комментарии:

1. Каковы основные препятствия, мешающие решателям SMT поддерживать эту функцию?

2. Я не знаю о каких-либо процедурах принятия решений, которые существуют, когда r.e. может быть символическим. Отсутствие такого алгоритма заставило бы разработчиков SMT уклоняться от чисто эвристических подходов. Предполагая, что такого результата не существует, я бы сказал, что это было бы достойно исследований на уровне аспирантов по разработке такого алгоритма или демонстрации того, что его не существует.