Part II · Grammar as a Computational Object
Chapter 8
Admissibility Languages and the Product Construction
mixed The automata constructions are classical; the tight cost of constraints (factor |Q| attained; unbounded pruning) is proved here.
- Compile a regular expression over move symbols into a minimal deterministic automaton, and know the cost of each step.
- Resolve a language-constrained query on a structure by searching the product of the structure with the automaton.
- Prove that a constraint can multiply the cost of search by exactly and can also prune it to almost nothing.
- Explain why “search first, filter afterwards” is incorrect, and why enumerating walks is exponential.
- Describe what changes when the admissibility language is context-free.
8.1 From expression to automaton
An admissibility language is written as a regular expression over move symbols, such as (a b)* (a | ε) or (L | R)* U. The SDK compiles it by the classical three-stage pipeline:
- Thompson’s construction turns the expression into a nondeterministic automaton with -moves, with states for an expression of length .
- The subset construction turns it into a deterministic automaton whose states are sets of NFA states; in the worst case this is exponential in .
- Moore’s partition refinement merges states with the same future, giving the minimal DFA — unique up to renaming (Myhill–Nerode).
The language “the -th letter from the end is ”, , has an expression of length and a minimal DFA with states.
A DFA must remember the last letters: two different suffixes of length differ at some position , and appending further letters separates them (one is accepted, the other not). So at least states are needed, and the automaton tracking the last letters achieves it.
∎The SDK’s tests check the size for and check acceptance of every word up to length six against Python’s own regular-expression engine for a set of expressions:
from cgtsdk import compile_regex
for rx in ["a*", "(a b)* (a | ε)", "(L | R)* U", "(a | b)* a (a | b) (a | b)", "(a | b)* a (a | b) (a | b) (a | b) (a | b)"]:
d = compile_regex(rx)
print(f"{rx:44s} minimal DFA states = {d.size:3d} accepts 'a b a': {d.accepts('a b a'.split())}")
a* minimal DFA states = 1 accepts 'a b a': False
(a b)* (a | ε) minimal DFA states = 2 accepts 'a b a': True
(L | R)* U minimal DFA states = 2 accepts 'a b a': False
(a | b)* a (a | b) (a | b) minimal DFA states = 8 accepts 'a b a': True
(a | b)* a (a | b) (a | b) (a | b) (a | b) minimal DFA states = 32 accepts 'a b a': False
(The automata are partial: a missing transition means the word can no longer be accepted, so no “dead” state is counted.) The size of the minimal DFA is the grammar parameter that governs everything below.
Text alternative: type a regular expression over move symbols and a word; the widget compiles the minimal DFA with the same pipeline as the SDK, prints its transition table, and reports whether the word is admissible.
8.2 Searching under a constraint
Let with given by a DFA with partial . The constrained resolution problem is: given , compute , the set of elements reachable from by some admissible word. For a labelled graph this is the regular path query of Chapter 6.
The answer is found by searching the product : there is a product edge for each move with defined. Then iff some with is reachable from .
Let .
- (Upper bound; standard.) is computable in time and space.
- (A constraint can cost a factor and prune nothing.) For all and all coprime to there are a structure with elements and and a -state DFA such that unconstrained search from visits states, product search visits exactly , and equals the unconstrained answer.
- (A constraint can prune almost everything.) For every there are a structure with elements and a one-state DFA such that product search visits state, unconstrained search visits , and the answers differ.
(1) By induction on : and iff is reachable from along a product walk spelling . The product has at most vertices; each is expanded once, consulting for each letter ( in total) and inspecting each move of its first component once per state ( in total). This is the classical construction [Mendelzon & Wood 1995; Barrett et al. 2000].
(2) Take the directed cycle on with one label , , and , whose DFA is the -cycle on . The product move is , and the orbit of is , of size by the Chinese remainder theorem. Unconstrained search visits the vertices. For every target some satisfies and , so , the unconstrained answer.
(3) Take a star with centre and edges labelled to leaves, and . The product visits only and answers ; unconstrained search visits all vertices.
∎Part 1 is textbook material; parts 2 and 3 are elementary and quite possibly folklore, but together they state something that is rarely made explicit: a grammatical constraint is not a speedup. It changes the search space, in either direction, by up to the size of the automaton. Whether it helps depends jointly on the language and on the structure — exactly the claim of hypothesis H-005, which the experiments supported (CGT-H-005).
from cgtsdk import Cost, compile_regex
from cgtsdk.algorithms import product_reach
from cgtsdk.structures import GraphStructure
n = 101
cycle = GraphStructure(n, [(i, "a", (i + 1) % n) for i in range(n)])
for k in (1, 2, 5, 10):
rx = " ".join(["a"] * k) # words of length divisible by k: (a^k)*
reach, explored = product_reach(cycle, 0, compile_regex(f"({rx})*"), return_explored=True)
print(f"k={k:2d}: product states explored = {explored:4d} = n*k = {n*k:4d}; |answer| = {len(reach)}")
k= 1: product states explored = 101 = n*k = 101; |answer| = 101
k= 2: product states explored = 202 = n*k = 202; |answer| = 101
k= 5: product states explored = 505 = n*k = 505; |answer| = 101
k=10: product states explored = 1010 = n*k = 1010; |answer| = 101
On random labelled graphs (CGT-EXP-003) the measured ratio of explored product states to unconstrained states ranged from (language on a sparse graph) to exactly (walk length divisible by ): both extremes of the theorem occur in practice, not only on constructed inputs.
Text alternative: on an eight-vertex labelled graph, type a regular expression; the widget compiles its DFA, runs breadth-first search over (vertex, state) pairs, highlights the vertices of , and compares the number of explored product states with plain reachability — which explores up to times fewer states and gives a different answer whenever the constraint matters.
8.3 Two incorrect shortcuts
Two tempting alternatives to the product construction fail.
Search, then filter. Plain reachability forgets which label words lead to a vertex, so no filtering of its answer can recover . On the random graphs of the experiment, unconstrained search misreported up to about 15,600 of 20,000 vertices for restrictive languages (CGT-OBS-007). The constraint must be carried during the search.
Enumerate walks, then check the word. This is correct if walks up to length are enumerated — any longer accepted walk revisits a product state and can be shortened — but the number of walks grows exponentially. On a 12-vertex graph the experiment’s walk enumeration hit its cap of two million walks while the product had at most states. The product construction is, in effect, the sharing mechanism applied to walks: all walks reaching the same (vertex, state) pair are represented once.
8.4 Context-free admissibility
When is context-free — balanced parentheses for matched calls and returns, the Dyck language of Chapter 3 — the product is no longer a finite graph, and constrained reachability becomes CFL-reachability, the formulation behind interprocedural program analysis [Reps 1998; Yannakakis 1990]. It is solved by a dynamic program over pairs of vertices and nonterminals in time cubic in (with factors depending on the grammar) [Barrett et al. 2000]. Whether the factor- phenomenon of Theorem 8.2 has a precise context-free analogue — how the size of the grammar enters, and whether the bound is attained — is open (CGT-OPEN-008).
Compile (L | R)* U by hand: give the Thompson NFA, the subset DFA, and the minimal DFA. Explain in one sentence what language of tree navigations it describes.
Solution to Exercise 8.1
The minimal DFA has two states: a start state looping on and , and an accepting state reached by from , with no transitions out of . It describes any downward walk followed by exactly one step up — for example, “go to a node, then report its parent”.
In part 2 of Theorem 8.2, what happens when ? Compute the number of explored product states and the answer set.
Solution to Exercise 8.2
The orbit of has size , and , is solvable iff . So states are explored and the answer is the vertices divisible by .
Prove the shortening argument: if some walk from to has its label in , then some such walk has length less than .
Using the SDK, generate a random labelled graph with and average degree , and compare product-search sizes for a*, (a b)* c and “length divisible by 5”. Reproduce the qualitative pattern of CGT-EXP-003.
- Admissibility languages compile to minimal DFAs (Thompson, subset, Moore); determinization can cost states.
- Constrained resolution is search on the product , in time.
- A constraint can multiply the search space by exactly without changing the answer, or prune it to a single state (CGT-THM-001); measured ratios on random graphs span both extremes.
- Filtering an unconstrained search is incorrect; enumerating walks is exponential; the product shares all walks that reach the same (vertex, state) pair.
- Context-free admissibility leads to CFL-reachability, cubic in general; its cost-of-constraint theory is open.
References cited in this chapter
- Barrett et al. 2000 C. Barrett, R. Jacob, M. Marathe (2000). Formal-language-constrained path problems. SIAM Journal on Computing 30(3):809–837. doi:10.1137/S0097539798337716.
- Mendelzon & Wood 1995 A. O. Mendelzon, P. T. Wood (1995). Finding regular simple paths in graph databases. SIAM Journal on Computing 24(6):1235–1258.
- Reps 1998 T. Reps (1998). Program analysis via graph reachability. Information and Software Technology 40(11–12):701–726. doi:10.1016/S0950-5849(98)00093-7.
- Yannakakis 1990 M. Yannakakis (1990). Graph-theoretic methods in database theory. Proc. 9th ACM PODS, pp. 230–242. doi:10.1145/298514.298576.