45 lines
1.1 KiB
Python
45 lines
1.1 KiB
Python
"""rwr² — Translate k-OA to k-ORE (Algorithm 3, arXiv 1004.2372).
|
|
|
|
rwr²(G):
|
|
1: compute a marking H of G
|
|
2: return strip(rwr²₁(H))
|
|
"""
|
|
|
|
from .marking import mark_koa
|
|
from .rwr0 import rwr0
|
|
from .grammar import (
|
|
Concat, Alt, Plus, Optional, Star, Symbol, Epsilon, Empty,
|
|
)
|
|
|
|
|
|
def strip(node):
|
|
"""Remove k-ORE markers: Symbol('a_i') → Symbol('a')."""
|
|
if isinstance(node, Symbol):
|
|
value = node.value
|
|
if '_' in value:
|
|
base = value.rsplit('_', 1)[0]
|
|
return Symbol(base)
|
|
return node
|
|
if isinstance(node, (Epsilon, Empty)):
|
|
return node
|
|
if isinstance(node, (Plus, Optional, Star)):
|
|
return type(node)(strip(node.child))
|
|
if isinstance(node, (Concat, Alt)):
|
|
return type(node)([strip(child) for child in node.parts])
|
|
return node
|
|
|
|
|
|
def rwr_sq(G):
|
|
"""
|
|
|———— Algorithm 3: rwr² ————|
|
|
Require: k-OA G
|
|
Ensure: k-ORE r with L(G) ⊆ L(r)
|
|
|
|
1: H ← marking of G
|
|
2: return strip(rwr²₁(H))
|
|
"""
|
|
H = mark_koa(G)
|
|
result = rwr0(H)
|
|
if result is None or isinstance(result, Empty):
|
|
return None
|
|
return strip(result)
|