Debería ser posible usar Automa.jl para construir un DFA y recorrerlo aleatoriamente. Automa utiliza una sintaxis más simple que PCRE, por lo que el lenguaje que puede describir en realidad debería ser regular.
Rápidamente reuní lo siguiente, basado principalmente en el código en dot.jl
:
julia> function rand_re(machine::Automa.Machine)
out = IOBuffer()
node = machine.start
while true
if node.state ∈ machine.final_states
(rand() ≤ 1 / (length(node.edges) + 1)) && break
end
edge, node = rand(node.edges)
label = rand(collect(edge.labels))
print(out, Char(label))
end
return String(take!(out))
end
rand_re (generic function with 1 method)
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a6bbb"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a9b"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a3aa"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a1a"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a5ba"
La advertencia es que Automa utiliza conjuntos codificados en bytes para las etiquetas de borde, por lo que se debe tener más cuidado cuando escribo Char(label)
.
Como los estados finales aún pueden tener bordes salientes, elegí tratar la detención y cada borde con probabilidad uniforme. Creo que esto probablemente tendrá el efecto de que términos potencialmente infinitos serán muy cortos o muy largos; google "muestreadores de Boltzmann" sobre cómo resolver eso (¡no debe confundirse con el muestreo de una distribución de Boltzmann!), pero la solución es matemáticamente complicada.
T
o queF
exista si la suma de subconjuntos existe. Si su generador de expresiones regulares de PCRE funciona en tiempo polinómico, felicidades ha demostrado que P = NP.