Output-Sensitive Construction of CDAWGs from BWT-Runs


Abstract

The compact directed acyclic word graph (CDAWG) of a string can be viewed in two equivalent ways: as the edge-compacted DAWG of the string, and as the DAG obtained from the suffix tree by merging the nodes whose subtrees are isomorphic. By exploiting these two views in opposite directions, we show how to build, for the (reversed) input string of length \(n\), the CDAWG with \(e_{\mathrm{L}}\) edges in \(O(e_{\mathrm{L}}\log n\log(n/r))\) time with \(O(r\log(n/r)+e_{\mathrm{L}})\) words of working space, provided that the fully functional compressed suffix tree of Gagie, Navarro, and Prezza of size \(O(r\log(n/r))\) is available. Here, \(r\) denotes the number of BWT-runs of the input string.

1 Introduction↩︎

The directed acyclic word graph (DAWG) of a string is the smallest automaton recognizing all substrings of the string [1]. Its edge-compacted version is the compact directed acyclic word graph (CDAWG) [2]. Equivalently, the CDAWG can be obtained from the suffix tree [3] by merging the nodes whose subtrees are isomorphic. This second view is particularly useful algorithmically: a CDAWG node can be identified by a suffix-tree subtree-equivalence class, while its represented strings are maximal repeats [4]. Thus their size can be much smaller than the text length for highly repetitive strings.

A second classical ingredient is the Weiner-link structure of the suffix tree [3]. A Weiner link prepends a character to the represented string. Under reversal, such left extensions become ordinary edges in the DAWG of the reversed string.

Another well-studied measure of repetitiveness is the number \(r\) of equal-letter runs in the Burrows-Wheeler transform (BWT). The r-index and the fully functional compressed suffix tree of Gagie, Navarro, and Prezza [5] provide suffix-array and suffix-tree functionality in BWT-run bounded space. Nishimoto and Tabei’s r-enum [6] showed that several characteristic substrings, including maximal repeats, can be enumerated in \(O(r)\) words of working space by traversing all right-maximal repeats through Weiner links. Kimura and I [7] subsequently reduced the traversal time to \(O(n)\) by using the move data structure for constant-time LF-mapping.

In this paper, we present an output-sensitive construction of CDAWGs from BWT-run bounded primitives. Since the maximal repeats are the nodes of the CDAWG, our algorithm can be seen as a generalization and extension of the aforementioned r-enum algorithms. Namely, our algorithm starts from the empty string and traverses Weiner links, in the spirit of r-enum. Hard and soft Weiner links play different conceptual roles. A hard Weiner link leads to a right-maximal locus and is therefore the same kind of step that r-enum uses for maximal-repeat discovery; in our setting, it also represents a primary DAWG edge under string reversal. A soft Weiner link, on the other hand, is not needed merely to enumerate maximal repeats, but it is needed for CDAWG construction because it represents a secondary DAWG edge under string reversal. Thus processing soft Weiner links is one essential difference from r-enum. Computationally, both cases are then handled by the same closure routine: for each left extension \(aw\) of a maximal repeat, we compute the right closure \(q=\overrightarrow{aw}\) and then \(h=\overleftarrow{q}=\overleftrightarrow{aw}\) by a doubling-then-binary-search procedure on suffix-array intervals. The algorithm uses \(\mathsf{key}(h)\) as the target key, and equal target keys are merged according to the suffix-tree subtree-equivalence criterion of Narisawa et al. [4].

Let \(T=\$S\#\) be the input string, and let \(r\) be the number of BWT-runs of \(T\). Let \(e_{\mathrm{L}}\) be the number of left-extensions of maximal repeats in \(T\). We show that the CDAWG topology of \(S^R\$\) can be constructed in \(O(e_{\mathrm{L}}\log n\log(n/r))\) time using \(O(r\log(n/r)+e_{\mathrm{L}})\) words of working space. Here \(e_{\mathrm{L}}\) is measured on the forward working string \(T\), whereas the output CDAWG is for the reversed string \(S^R\$\); equivalently, \(e_{\mathrm{L}}(T)=e_{\mathrm{R}}(T^R)\), and the final marker deletion affects only a single edge from the node for \(\varepsilon\). This bound is obtained by combining our output-sensitive Weiner-link traversal with the fully functional compressed suffix tree of Gagie, Navarro, and Prezza [5]. We also compute the metadata needed to represent edge labels without expanding them explicitly within the claimed bounds, following the CDAWG-grammar framework of Belazzougui and Cunial [8], [9].

2 Preliminaries↩︎

Strings. Let \(\Sigma\) be an alphabet. An element of \(\Sigma\) is called a character, and an element of \(\Sigma^*\) is called a string. For a string \(S\), let \(|S|\) denote its length. The empty string is denoted by \(\varepsilon\). For any \(1\leq i\leq |S|\), \(S[i]\) denotes the \(i\)-th character of \(S\). For any \(1\leq i\leq j\leq |S|\), \(S[i..j]\) denotes the substring of \(S\) that begins at position \(i\) and ends at position \(j\). For convenience, let \(S[i..j]=\varepsilon\) if \(i>j\). Let \(S^R=S[|S|]\cdots S[1]\) denote the reversed string of \(S\).

A string \(w\) occurs in \(S\) iff \(w\in\mathsf{Substr}(S)\). Let \(\mathsf{occ}_S(w)\) denote the number of occurrences of \(w\) in \(S\). We use two special characters \(\$\) and \(\#\) that do not belong to the input alphabet and occur only when explicitly introduced.

Maximal repeats and CDAWGs. For a substring \(w\) of \(S\), let \(\mathsf{LChar}_S(w)\) and \(\mathsf{RChar}_S(w)\) be the sets of characters that occur immediately to the left and to the right of an occurrence of \(w\), respectively. A substring \(w\) is left-maximal if \(|\mathsf{LChar}_S(w)|\ge 2\), right-maximal if \(|\mathsf{RChar}_S(w)|\ge 2\), and a maximal repeat if it is both left-maximal and right-maximal. Let \(\mathsf{MRep}(S)\) be the set of maximal repeats of \(S\). We define \[e_{\mathrm{L}}(S)=\sum_{w\in\mathsf{MRep}(S)} |\mathsf{LChar}_S(w)|, \qquad e_{\mathrm{R}}(S)=\sum_{w\in\mathsf{MRep}(S)} |\mathsf{RChar}_S(w)|.\] Thus \(e_{\mathrm{L}}(S)\) and \(e_{\mathrm{R}}(S)\) are the numbers of left- and right-extensions of maximal repeats in \(S\), respectively. Since \(\mathsf{MRep}(S^R)=\{w^R\mid w\in\mathsf{MRep}(S)\}\) holds for any string \(S\), the CDAWG of \(S^R\) naturally represents left-extensions of maximal repeats of \(S\); in particular, \(e_{\mathrm{R}}(S^R)=e_{\mathrm{L}}(S)\). For a substring \(x\) of \(S\), the right-closure \(\overrightarrow{x}\) is the shortest right-maximal string \(y\) such that \(x\) is a prefix of \(y\) and \(\mathsf{occ}_S(x)=\mathsf{occ}_S(y)\). The left-closure \(\overleftarrow{x}\) is defined symmetrically. We write \(\overleftrightarrow{x}=\overleftarrow{\overrightarrow{x}}\). For substrings with at least two occurrences, applying both closures yields maximal repeats.

The DAWG of \(S\), denoted \(\mathsf{DAWG}(S)\), is the smallest automaton recognizing the substrings of \(S\) [1]. The CDAWG of \(S\), denoted \(\mathrm{CDAWG}(S)\), is obtained by compacting non-branching paths of the DAWG [2]. We use the standard correspondence that CDAWG nodes, except for the sink, are represented by maximal repeats. For a CDAWG node \(v\), let \(\mathsf{str}(v)\) denote the longest string represented by \(v\). The outgoing edges from the node corresponding to a maximal repeat \(w\) are in one-to-one correspondence with the right-extensions of \(w\); consequently, the number of CDAWG edges leaving maximal-repeat nodes is \(e_{\mathrm{R}}(S)\). We also use the suffix-tree characterization of CDAWGs. If one considers the suffix tree of \(S\), then merging loci whose rooted subtrees are isomorphic yields the CDAWG of \(S\) [2]. Thus the node-identification rule for CDAWG nodes can be expressed without referring to the DAWG edges themselves: two nodes are identified exactly when their suffix-tree subtrees have the same branching structure and edge labels. Following the work by Narisawa et al. [4], our algorithm uses this characterization as the rule for deciding which intermediate endpoints are to be merged.

A Weiner link [3] in the suffix tree prepends a character: it maps the locus of \(w\) to the locus of \(aw\), when such a locus exists. Under string reversal, the left extension \(aw\) of \(w\) corresponds to the right extension \(w^Ra\) of \(w^R\). Consequently, hard and soft Weiner links on the suffix-tree side of \(S\) correspond to primary and secondary edges, respectively, of \(\mathsf{DAWG}(S^R)\) in the terminology of Blumer et al. [1], [2]. After compacting the DAWG edges of \(S^R\), one obtains \(\mathrm{CDAWG}(S^R)\). This is the directionality exploited in this paper: we traverse Weiner links on the forward string, but the edge representations added by the algorithm are interpreted as DAWG/CDAWG edges of the reversed string.

Suffix array primitives in BWT-run bounds. Let \(S\) be a string of length \(n\). The suffix array, inverse suffix array, and LCP array of \(S\) are denoted by \(\mathsf{SA}\), \(\mathsf{ISA}\), and \(\mathsf{LCP}\), respectively. For two text positions \(i,j\), \(\mathsf{LCE}(i,j)\) denotes the length of the longest common prefix of suffixes \(S[i..n]\) and \(S[j..n]\). For a substring \(w\) of \(S\), let \(\mathsf{range}(w)=[L_w,R_w]\) denote its suffix-array interval. We assume access to a fully functional compressed suffix-tree interface that supports exactly the primitives used by the algorithm: \(\mathsf{SA}\), \(\mathsf{ISA}\), \(\mathsf{LCP}\), \(\mathsf{LCE}\), LF-mapping, BWT range-distinct queries, and the suffix-tree navigation needed for the subtree-equivalence test. For a string \(S\), let \(s_{\mathsf{GNP}}(S)\) be the number of words used by this black-box representation, and let \(t_{\mathsf{GNP}}(S)\) be an upper bound on the time for any one of these required primitives. With the fully functional compressed suffix tree of Gagie, Navarro, and Prezza [5], these primitives can be supported with \(s_{\mathsf{GNP}}(S)=O(r\log(n/r))\) words and \(t_{\mathsf{GNP}}(S)=O(\log(n/r))\) time, where \(n=|S|\) and \(r\) is the number of runs in the BWT of \(S\).

3 Construction Framework↩︎

Let \(S\) be the input string and let \(T=\$S\#\) be the working string, where \(\$\) and \(\#\) are fresh characters. After constructing the left-oriented topology for \(T\), we reverse all edges and delete the unique edge from the node for \(\varepsilon\) whose label begins with \(\#\), obtaining \(\mathrm{CDAWG}(S^R\$)\). Our construction framework is given in Algorithm 1.

Figure 1: Left-oriented construction on T=\$S\#

In the sequel, we briefly describe our algorithm.

For a substring \(x\) of \(T\), let \(\mathsf{range}(x)=[L_x,R_x]\) be its suffix-array interval. We represent a suffix-tree locus of string depth \(d\) and interval \([L,R]\) by the key \(\mathsf{key}([L,R],d)\). For a maximal repeat \(w\in\mathsf{MRep}(T)\), we write \(\mathsf{key}(w)=\mathsf{key}([L_w,R_w],|w|)\). This representation is unique for maximal repeats; in particular, \(\mathsf{key}(\varepsilon)=\mathsf{key}([1,n],0)\) represents the node for \(\varepsilon\). The sink is not represented by an interval-depth key.

CDAWG nodes are obtained by merging suffix-tree loci whose rooted subtrees are isomorphic [2], [4]. Our construction performs this merging by assigning the same canonical key to edge targets that represent the same maximal-repeat node. Hard links are the maximal-repeat-discovery steps familiar from r-enum and give primary DAWG edges after reversal, whereas soft links are additionally needed to output secondary DAWG edges. Algorithmically, both cases use the same rule: for a left extension \(aw\) of a maximal repeat \(w\), the added edge representation has source \(\mathsf{key}(w)\) and has either the sink as its target, if \(aw\) is unique, or the canonical key \(\mathsf{key}(h)\), where \(h=\overleftrightarrow{aw}\).

An edge representation whose target is a maximal-repeat node is a tuple \((\mathsf{key}(w),\mathsf{key}(h),a,m,d)\), where \(w\in\mathsf{MRep}(T)\), \(a\in\mathsf{LChar}_T(w)\), \(h=\overleftrightarrow{aw}\), \(m=|\overrightarrow{aw}|\), and \(d=|h|-m\). The values \(m\) and \(d\) are part of the edge-label representation after reversing the orientation. An edge representation whose target is the sink stores the information needed to represent its suffix-tail label.

All interval operations are implemented by a black-box fully functional compressed suffix tree for \(T\), which supports \(\mathsf{SA}\), \(\mathsf{ISA}\), \(\mathsf{LCP}\), \(\mathsf{LCE}\), LF-mapping, BWT range-distinct queries, and the suffix-tree navigation needed for subtree-equivalence tests. The time and space bounds of this interface are denoted by \(t_{\mathsf{GNP}}(T)\) and \(s_{\mathsf{GNP}}(T)\), respectively. The number of processed left extensions is \(O(e_{\mathrm{L}}(T))\), where \(e_{\mathrm{L}}(T)\) denotes the number of left-extensions of maximal repeats in \(T\). The formal computation of \(\overrightarrow{aw}\) and \(\overleftarrow{\overrightarrow{aw}}\) is given in the next section.

4 Traversing Maximal Repeats↩︎

This section gives the interval operations used in Algorithm 1. Throughout this section, all suffix-array intervals are taken with respect to the working string \(T\) of length \(n\).

4.1 Enumerating one-step left extensions↩︎

Let \(w\in\mathsf{MRep}(T)\) and let \(\mathsf{range}(w)=[L_w,R_w]\). A BWT range-distinct query on \([L_w,R_w]\) returns the triples \[(a,p_a,q_a)\] such that the occurrences of \(w\) preceded by \(a\) correspond to the BWT subrange \([p_a,q_a]\). Applying LF-mapping gives \[\mathsf{range}(aw)=[\mathsf{LF}(p_a),\mathsf{LF}(q_a)].\] Thus every left-extension of \(w\) is enumerated once, and no other character is enumerated. If this interval is a singleton, then \(aw\) has a unique occurrence and the corresponding edge has the sink as its target.

Assume henceforth that \([L,R]=\mathsf{range}(aw)\) satisfies \(L<R\). Let \[q=\overrightarrow{aw}\] be the right-closure of \(aw\). Its string depth is the common prefix length of all suffixes in the interval \([L,R]\). For suffix-array intervals, this value is obtained from the two lexicographically extreme suffixes, and hence \[|q|=\mathsf{LCE}(\mathsf{SA}[L],\mathsf{SA}[R]).\] We denote this value by \(m\).

4.2 Testing a candidate left growth↩︎

It remains to compute \(\overleftarrow{q}\). For an integer \(d\geq 0\), define \[i_d=\mathsf{SA}[L]-d,\qquad j_d=\mathsf{SA}[R]-d.\] If \(i_d<1\) or \(j_d<1\), then \(d\) is invalid. Otherwise put \[\alpha_d=\min\{\mathsf{ISA}[i_d],\mathsf{ISA}[j_d]\},\qquad \beta_d=\max\{\mathsf{ISA}[i_d],\mathsf{ISA}[j_d]\},\] and the candidate length is \(m+d\). Thus \(\alpha_d\) and \(\beta_d\) are the suffix-array ranks of the two leaves obtained by moving \(d\) characters to the left from the leftmost and rightmost leaves of \(\mathsf{range}(q)=[L,R]\). We define the predicate \(\mathsf{Valid}(L,R,m,d)\) to be true iff the following two conditions hold: \[\mathsf{LCE}(\mathsf{SA}[\alpha_d],\mathsf{SA}[\beta_d])\geq m+d,\] \[\beta_d-\alpha_d=R-L.\] The first condition checks, by one LCE query, whether the two shifted boundary leaves share the candidate string of length \(m+d\). The second condition checks that these two shifted leaves still span exactly \(R-L+1\) suffix-array positions, i.e., the occurrence count of \(q\) is preserved. No LCE query against the outside neighbors of \([\alpha_d,\beta_d]\) is needed in this left-growth test.

Lemma 1. For every \(d\geq 0\), \(\mathsf{Valid}(L,R,m,d)\) holds iff all occurrences of \(q\) can be extended by the same length-\(d\) string to the left. If it holds, then the resulting string has suffix-array interval \([\alpha_d,\beta_d]\).

Proof. Suppose first that \(\mathsf{Valid}(L,R,m,d)\) holds. Let \(x\) be the common prefix of length \(m+d\) of the two suffixes \(T[i_d..n]\) and \(T[j_d..n]\). Since suffix-array intervals are contiguous, every suffix whose rank lies between \(\alpha_d\) and \(\beta_d\) also has prefix \(x\). By \(\beta_d-\alpha_d=R-L\), this gives exactly \(R-L+1\) suffixes. Removing the first \(d\) characters from these occurrences of \(x\) yields \(R-L+1\) distinct occurrences of \(q\). Since \(\mathsf{range}(q)=[L,R]\) has exactly \(R-L+1\) occurrences, these are all occurrences of \(q\). Hence every occurrence of \(q\) is preceded by the same length-\(d\) string. Moreover, no suffix outside \([\alpha_d,\beta_d]\) can have prefix \(x\), since that would yield an additional occurrence of \(q\) after deleting the first \(d\) characters. Thus \([\alpha_d,\beta_d]\) is the suffix-array interval of the resulting string.

Conversely, suppose all occurrences of \(q\) are extended by the same length-\(d\) string to the left, and let \(x\) be the resulting string of length \(m+d\). Prepending the same string to all suffixes in \([L,R]\) preserves their lexicographic order. Hence the suffixes starting at \(i_d\) and \(j_d\), obtained from the leftmost and rightmost leaves of \([L,R]\), are the leftmost and rightmost suffixes in the interval of \(x\). Therefore they have LCE at least \(m+d\), and their ranks satisfy \(\beta_d-\alpha_d=R-L\). Thus \(\mathsf{Valid}(L,R,m,d)\) holds. 0◻ ◻

Proof. If all occurrences of \(q\) share a common left extension of length \(d\), then they also share every shorter prefix of that extension. Hence validity is monotone. The maximum valid \(d^*\) is exactly the largest common left extension that preserves the occurrence set of \(q\), which is the definition of the left-closure. 0◻ ◻

By Corollary 1, \(d^*\) can be found by exponential search followed by binary search. Since \(d^*\leq n\), this requires \(O(\log n)\) evaluations of \(\mathsf{Valid}\). This is the common left-closure search performed after the right closure \(q=\overrightarrow{aw}\) has been computed. For the edge representation added for the extension \(aw\) when its target is a maximal-repeat node, the algorithm stores the two lengths \(m=|\overrightarrow{aw}|\) and \(d^*\). These values are later used, after reversing the orientation, to compute the offset and length values of the corresponding CDAWG edge label.

Lemma 2. For every maximal repeat \(w\in\mathsf{MRep}(T)\) and every left-extension character \(a\in\mathsf{LChar}_T(w)\) such that \(aw\) has at least two occurrences, the interval operations above compute the suffix-array interval and string depth of \(\overleftrightarrow{aw}\).

Proof. The BWT range-distinct query enumerates exactly the subrange of occurrences of \(w\) preceded by \(a\), and LF-mapping transforms this subrange into \(\mathsf{range}(aw)\). Since \(aw\) has at least two occurrences, this interval is non-singleton. The common prefix length of all suffixes in this interval is the LCE of the two extreme suffixes, and hence the algorithm obtains \(|\overrightarrow{aw}|\) correctly. Corollary 1 then gives the maximum left growth preserving the same occurrence set, and therefore the suffix-array interval and string depth of \(\overleftarrow{\overrightarrow{aw}}=\overleftrightarrow{aw}\). 0◻ ◻

4.3 Cost of one extension↩︎

Each evaluation of \(\mathsf{Valid}\) uses a constant number of accesses to \(\mathsf{SA}\), \(\mathsf{ISA}\), and \(\mathsf{LCE}\). Together with LF-mapping and range-distinct enumeration, the right- and left-closure computations for one left extension of a maximal repeat take \(O(\log n)\) primitive operations, and hence \(O(\log n\cdot t_{\mathsf{GNP}}(T))\) time under the compressed suffix-tree interface for the working string \(T\).

Lemma 3. Over all maximal repeats processed by Algorithm 1, the interval computations for their left extensions take \(O(e_{\mathrm{L}}(T)\log n\cdot t_{\mathsf{GNP}}(T))\) time and use \(O(e_{\mathrm{L}}(T))\) additional words for the added edge representations.

Proof. The number of added edge representations is \(O(e_{\mathrm{L}}(T))\) by the definition of \(e_{\mathrm{L}}(T)\). For each representation whose target is a maximal-repeat node, Lemma 2 and the preceding paragraph show that the right and left closures are computed using \(O(\log n)\) primitive operations. Each primitive costs \(t_{\mathsf{GNP}}(T)\) time, and each such edge representation stores a constant number of keys and length values. 0◻ ◻

5 From Weiner Links to CDAWG Edges↩︎

This section interprets the edge representations computed in Section 4 as CDAWG edges. We use two classical characterizations: CDAWGs are obtained by compacting DAWGs [1], [2], and equivalently by merging suffix-tree loci whose rooted subtrees are isomorphic [4]. Our construction uses these characterizations in opposite orientations.

Let the forward working string be \(T\). We traverse Weiner links [3] in the suffix tree of \(T\). Under reversal, a left extension \(aw\) of \(w\) becomes a right extension \(w^Ra\) of \(w^R\). Hence a Weiner link on the suffix-tree side of \(T\) corresponds to an edge of the DAWG of \(T^R\).

Lemma 4. Let \(w\) be a suffix-tree locus of \(T\), and suppose that the Weiner link by a character \(a\) leads to the locus of \(aw\). Then, in the reversed string \(T^R\), this link corresponds to the DAWG edge labeled \(a\) from the node containing \(w^R\) to the node containing \(w^Ra\). Moreover, hard Weiner links correspond to primary DAWG edges of \(T^R\), and soft Weiner links correspond to secondary DAWG edges of \(T^R\).

Proof. The first statement follows from reversal: an occurrence of \(aw\) in \(T\) is the reversal of an occurrence of \(w^Ra\) in \(T^R\), so prepending \(a\) in \(T\) is appending \(a\) in \(T^R\). The hard/soft distinction is exactly the distinction between edges whose destinations are represented by explicit nodes and those whose destinations lie inside compacted paths, i.e., the primary/secondary distinction of Blumer et al. [1], [2]. 0◻ ◻

The compaction rule is decided on the forward suffix-tree side. For a maximal repeat \(w\) and a left-extension \(aw\), Section 4 computes \[q=\overrightarrow{aw}, \qquad h=\overleftarrow{q}=\overleftrightarrow{aw}.\] The right closure \(q\) is obtained from the Weiner-link destination \(aw\) by extending it to the right while preserving its occurrence set. Then \(h=\overleftarrow{q}\) gives the maximal-repeat node used as the non-sink target.

Figure 2: Illustration of the interval computation for a soft Weiner link from a maximal repeat w. The link by a first reaches the locus of aw, and its right closure is q=\overrightarrow{aw} with \mathsf{range}(aw)=\mathsf{range}(q)=[L,R]. The maximal-repeat node h=\overleftarrow{q}=\overleftrightarrow{aw} is found by the left-closure search. Along the valid part of this search, the SA-interval width remains R-L+1; after the maximal left growth, the next candidate left extension ch, where c is determined by shifting the boundary leaves one more position to the left, no longer preserves this width. This failure is detected by the validity test on the two leaves obtained by shifting the leftmost and rightmost leaves of [L,R].

Lemma 5. Let \(w\in\mathsf{MRep}(T)\) and \(a\in\mathsf{LChar}_T(w)\), and assume that \(aw\) has at least two occurrences. Let \(q=\overrightarrow{aw}\) and \(h=\overleftrightarrow{aw}\). Then the node for \(h\) is the maximal-repeat node reached from the Weiner-link destination \(aw\) after merging suffix-tree loci with isomorphic rooted subtrees. Consequently, two added edge representations whose targets are maximal-repeat nodes have the same final target node iff their canonical keys \(\mathsf{key}(h)\) are equal.

Proof. The string \(q=\overrightarrow{aw}\) is obtained by extending \(aw\) to the right as long as all occurrences have the same next character. Thus the path from the locus of \(aw\) to the locus of \(q\) is unary and preserves the starting positions of the occurrences. Hence this part is precisely the non-branching part that is contracted when passing from the DAWG edge to the compact CDAWG edge.

Let \(h=\overleftarrow{q}\), and write \(h=zq\) with \(d=|z|\). By the definition of left closure, every occurrence of \(q\) starts at some position \(p\) iff there is an occurrence of \(h\) starting at \(p-d\). Moreover, after the loci \(q\) and \(h\) are consumed, the remaining suffixes are identical: \[T[p+|q|..]=T[(p-d)+|h|..].\] Therefore the rooted suffix-tree subtree below the locus of \(q\) is label-isomorphic to the rooted suffix-tree subtree below the locus of \(h\). Since \(q\) is right-maximal and the left closure is maximal, \(h\) is both left- and right-maximal, and hence \(h\in\mathsf{MRep}(T)\).

By the suffix-tree characterization of CDAWGs [4], the loci reached from \(aw\) through the unary path to \(q\) and then through the above subtree-isomorphic shift to \(h\) belong to the same CDAWG node. Our construction uses the maximal-repeat locus \(h\) for this CDAWG node. Maximal repeats have unique suffix-array intervals and string depths, so equality of canonical keys is equivalent to equality of the strings \(h\), and hence to equality of final target nodes. 0◻ ◻

Thus hard and soft Weiner links correspond to primary and secondary DAWG edges, respectively, by Lemma 4. For CDAWG construction, the algorithm computes \(h=\overleftrightarrow{aw}\) for every non-unique left extension and uses \(\mathsf{key}(h)\) as the target key, while unique extensions go to the sink. The algorithm does not explicitly build either the suffix tree or the DAWG.

5.1 Merging edge representations into CDAWG edges↩︎

After the algorithm has added all edge representations, it sorts all canonical keys that occur as sources or non-sink targets. Each distinct key receives one node identifier; edges whose target is the sink keep the sink as their target. Finally, for \(T=\$S\#\), reversing the orientation gives the corresponding topology for \(T^R=\#S^R\$\).

Lemma 6. Every edge representation added by the algorithm corresponds to a left extension of a maximal repeat of \(T\), and every left-oriented CDAWG edge arising from such a left extension is represented by some added edge representation.

Proof. The algorithm processes each discovered maximal repeat \(w\), including \(\varepsilon\). The BWT range-distinct query on \(\mathsf{range}(w)\) returns exactly the characters in \(\mathsf{LChar}_T(w)\) with their occurrence subranges. Hence every added edge representation is generated from some pair \((w,a)\). If \(\mathsf{range}(aw)\) is a singleton, its target is the sink; otherwise Lemma 2 computes \(h=\overleftrightarrow{aw}\) and the algorithm uses \(\mathsf{key}(h)\) as the target key. Conversely, every left-oriented CDAWG edge arising from a left extension of a maximal repeat comes from such a pair and is therefore enumerated. 0◻ ◻

Lemma 7. After sorting and merging equal canonical keys, the added edge representations form the left-oriented CDAWG topology of \(T\).

Proof. By Lemma 6, each edge representation is added for a Weiner-link step from a maximal repeat. Unique extensions target the sink. For every other target, Lemma 5 shows that the algorithm computes the maximal-repeat node \(h=\overleftrightarrow{aw}\) reached after merging suffix-tree loci with isomorphic rooted subtrees. Hard and soft Weiner links correspond to primary and secondary DAWG edges, respectively, but both cases use this same target-key computation. By the suffix-tree characterization [4], these maximal-repeat nodes are exactly the CDAWG nodes. Since maximal repeats have unique suffix-array intervals and depths, two non-sink targets represent the same CDAWG node iff their canonical keys are equal. Thus sorting the canonical keys and merging equal keys identifies exactly the non-sink CDAWG nodes, while all edges whose target is the sink keep the sink as their target. 0◻ ◻

Lemma 8. Let \(T=\$S\#\). Reversing the left-oriented topology of \(T\) and deleting the unique edge from the node for \(\varepsilon\) whose label begins with \(\#\) yields \(\mathrm{CDAWG}(S^R\$)\).

Proof. Reversal transforms left extensions in \(T\) into DAWG edges of \(T^R=\#S^R\$\). Hence Lemmas 4 and 7 give the CDAWG topology of \(T^R\). The marker \(\#\) occurs only at the first position of \(T^R\), so every substring containing \(\#\) is a unique prefix and is not a maximal repeat. Thus the only edge containing \(\#\) is the unique edge from the node for \(\varepsilon\) spelling the prefix beginning with \(\#\). Removing it leaves the CDAWG of \(S^R\$\). 0◻ ◻

5.2 Compact representation of edge labels↩︎

It remains to associate compact edge-label representations with the edges obtained after merging equal canonical keys. We compute the information needed for label extraction in the CDAWG-grammar framework of Belazzougui and Cunial [8], [9], without storing edge labels explicitly.

Consider a left-oriented edge representation whose target is a maximal-repeat node and that was added for the left-extension of a maximal repeat \(w_\ell\) by a character \(a\). Let \(q_\ell=\overrightarrow{aw_\ell}\) where \(|q_\ell|=m\), and let \(d\) be the additional left growth used to obtain \(h_\ell=\overleftarrow{q_\ell}=\overleftrightarrow{aw_\ell}\). After reversing orientation, the corresponding right-oriented edge has source \(u=w_\ell^R\) and target \(v=h_\ell^R\). If \(h_\ell=zaw_\ell y\), then \(v=y^R u a z^R\). Therefore the edge-label representation of the reversed edge \(\gamma\) stores \(\gamma.\mathsf{left}=|y|=m-|w_\ell|-1\) and \(\gamma.\mathsf{right}=1+d\).

Lemma 9. For every edge representation whose target is a maximal-repeat node and that remains after merging equal canonical keys, the stored values \(\gamma.\mathsf{left}\) and \(\gamma.\mathsf{right}\) satisfy \(\mathsf{str}(v)=x_\gamma\mathsf{str}(u)y_\gamma\), where \(|x_\gamma|=\gamma.\mathsf{left}\) and \(|y_\gamma|=\gamma.\mathsf{right}\). Consequently, the compact edge label is \(y_\gamma\).

Proof. The left-oriented endpoint has the form \(h_\ell=zaw_\ell y\), where the middle factor \(aw_\ell\) is the raw Weiner destination, \(y\) is the right growth used to obtain \(q_\ell=\overrightarrow{aw_\ell}\), and \(z\) is the additional left growth used to obtain \(h_\ell=\overleftarrow{q_\ell}\). Since \(|q_\ell|=m\), we have \(|y|=m-|w_\ell|-1\), and since \(d=|z|\), reversing \(h_\ell\) gives \(v=y^R w_\ell^R a z^R\). Thus \(x_\gamma=y^R\) and \(y_\gamma=az^R\), proving the claimed lengths and the label formula. 0◻ ◻

For every maximal-repeat target node \(v\), the incoming edges to \(v\) are sorted by increasing \(\gamma.\mathsf{left}\). The rank of an incoming edge is its position in this order. Hence \(\gamma.\mathsf{left}\) can be recovered from \((v,\gamma.\mathsf{rank})\) by storing an array \[\mathsf{LeftByRank}_v[\gamma.\mathsf{rank}]=\gamma.\mathsf{left}.\] Together with \(\gamma.\mathsf{right}\), this gives the information needed to recover the compact label from \(\mathsf{str}(v)\) and \(\mathsf{str}(u)\) without explicitly storing the label.

Edges whose target is the sink use suffix-tail edge-label representations, each requiring \(O(1)\) words.

The additional level-ancestor structure used by Belazzougui and Cunial [9] can be built within the same output-size bound. Their structure supports prefix extraction of each edge label in linear time in the prefix length, and is built on the spanning tree of the CDAWG with edge directions reversed. After the edges have been ordered as above, this tree is obtained by choosing, for every node except the sink in the reversed orientation, its first outgoing edge. Hence the tree has \(O(|V|)\) edges, where \(V\) is the node set of the CDAWG, and the standard level-ancestor structure is constructed in linear time and space [10]. Since \(|V|=O(e_{\mathrm{L}})\), this preprocessing is within the claimed bound.

Lemma 10. The edge-label representations stored by the algorithm encode exactly the compact labels of the edges of \(\mathrm{CDAWG}(S^R\$)\).

Proof. For edges whose targets are maximal-repeat nodes, Lemma 9 shows that \(\gamma.\mathsf{left}\) and \(\gamma.\mathsf{right}\) identify the compact label \(y_\gamma\). Sorting incoming edges by \(\gamma.\mathsf{left}\) and storing \(\mathsf{LeftByRank}_v\) allows \(\gamma.\mathsf{left}\) to be recovered from the target and incoming rank, as required by the Belazzougui–Cunial representation. Edges whose target is the sink use suffix-tail edge-label representations. The unique edge from the node for \(\varepsilon\) whose label begins with \(\#\) is deleted by Lemma 8. Hence the remaining edge-label representations encode exactly the edge labels of \(\mathrm{CDAWG}(S^R\$)\) without expanding them. 0◻ ◻

5.3 Correctness and complexity↩︎

Theorem 1. Let \(T=\$S\#\), let \(n=|T|\), and let \(e_{\mathrm{L}}=e_{\mathrm{L}}(T)\). Suppose that the fully functional compressed suffix-tree interface for \(T\) occupies \(s_{\mathsf{GNP}}(T)\) words and supports each required primitive in \(t_{\mathsf{GNP}}(T)\) time. Then the algorithm constructs \(\mathrm{CDAWG}(S^R\$)\) in \(O(e_{\mathrm{L}}\log n\cdot t_{\mathsf{GNP}}(T))\) time using \(O(s_{\mathsf{GNP}}(T)+e_{\mathrm{L}})\) working space.

Proof. By Lemmas 27, the traversal produces exactly the edge representations of the left-oriented CDAWG topology of \(T\), up to the final merging of canonical keys. Lemma 8 converts this topology into \(\mathrm{CDAWG}(S^R\$)\), and Lemma 10 proves correctness of the compact edge-label representations.

Lemma 3 bounds the total time for right- and left-closure computations and canonical-key computation by \(O(e_{\mathrm{L}}\log n\cdot t_{\mathsf{GNP}}(T))\). The remaining subtree-equivalence operations use the navigation primitives included in the black-box interface and are charged to the added edge representations. The final sorting and merging step handles \(O(e_{\mathrm{L}})\) canonical keys and takes \(O(e_{\mathrm{L}}\log e_{\mathrm{L}})\) time, which is bounded by \(O(e_{\mathrm{L}}\log n)\) and is absorbed by the preceding bound. The compressed suffix-tree interface uses \(s_{\mathsf{GNP}}(T)\) words of space, while the added edge representations, keys, and edge-label representations use \(O(e_{\mathrm{L}})\) additional words. 0◻ ◻

Corollary 2. Let \(T=\$S\#\), let \(n=|T|\), let \(r\) be the number of BWT-runs of \(T\), and let \(e_{\mathrm{L}}=e_{\mathrm{L}}(T)\). Using the fully functional compressed suffix tree of Gagie, Navarro, and Prezza, the algorithm constructs \(\mathrm{CDAWG}(S^R\$)\) in \(O(e_{\mathrm{L}}\log n\log(n/r))\) time using \(O(r\log(n/r)+e_{\mathrm{L}})\) words of working space.

Proof. For the primitive set used in the proof of Theorem 1—namely \(\mathsf{SA}\), \(\mathsf{ISA}\), \(\mathsf{LCP}\), \(\mathsf{LCE}\), LF-mapping, BWT range-distinct queries, and the suffix-tree navigation needed for the subtree-equivalence test—the representation of Gagie, Navarro, and Prezza gives \(s_{\mathsf{GNP}}(T)=O(r\log(n/r))\) words and \(t_{\mathsf{GNP}}(T)=O(\log(n/r))\) time. Substituting these bounds into Theorem 1 gives the claim. 0◻ ◻

6 Concluding Remarks↩︎

We presented an output-sensitive construction of the CDAWG of a length-\(n\) string with \(e_{\mathrm{L}}\) edges from BWT-run bounded primitives, which runs in \(O(e_{\mathrm{L}}\log n\log(n/r))\) time with \(O(r\log(n/r)+e_{\mathrm{L}})\) working space. A key point is that the construction goes beyond maximal-repeat enumeration: hard Weiner links discover maximal-repeat nodes, while soft Weiner links are also processed because they correspond to secondary DAWG edges under reversal. Together with existing CDAWG-based edge-label extraction and pattern-matching machinery, the constructed representation can serve as a bridge between BWT-run bounded indexes and CDAWG-based compressed string processing.

Acknowledgements↩︎

This work was supported by JSPS KAKENHI Grant Numbers JP26K02980 (HA), JP23K24808, JP23K18466 (SI).

References↩︎

[1]
Blumer, A., Blumer, J., Haussler, D., Ehrenfeucht, A., Chen, M.T., Seiferas, J.: The smallest automaton recognizing the subwords of a text. Theoretical Computer Science 40, 31–55 (1985).
[2]
Blumer, A., Blumer, J., Haussler, D., McConnell, R.M., Ehrenfeucht, A.: Complete inverted files for efficient text retrieval and analysis. Journal of the ACM 34(3), 578–595 (1987).
[3]
Weiner, P.: Linear pattern matching algorithms. In: 14th Annual Symposium on Switching and Automata Theory. pp. 1–11. IEEE Computer Society (1973).
[4]
Narisawa, K., Hiratsuka, H., Inenaga, S., Bannai, H., Takeda, M.: Efficient computation of substring equivalence classes with suffix arrays. Algorithmica 79(2), 291–318 (2017).
[5]
Gagie, T., Navarro, G., Prezza, N.: Fully functional suffix trees and optimal text searching in BWT-runs bounded space. Journal of the ACM 67(1), 2:1–2:54 (2020).
[6]
Nishimoto, T., Tabei, Y.: R-enum: Enumeration of characteristic substrings in BWT-runs bounded space. In: 32nd Annual Symposium on Combinatorial Pattern Matching, CPM 2021. Leibniz International Proceedings in Informatics, vol. 191, pp. 21:1–21:21. Schloss Dagstuhl–Leibniz-Zentrum für Informatik (2021).
[7]
Kimura, K., I, T.: R-enum revisited: Speedup and extension for context-sensitive repeats and net frequencies. In: CPM 2026. vol. 369, pp. 10:1–10:14. Schloss Dagstuhl–Leibniz-Zentrum für Informatik (2026).
[8]
Belazzougui, D., Cunial, F.: Representing the suffix tree with the CDAWG. In: 28th Annual Symposium on Combinatorial Pattern Matching, CPM 2017. Leibniz International Proceedings in Informatics, vol. 78, pp. 7:1–7:13. Schloss Dagstuhl–Leibniz-Zentrum für Informatik (2017).
[9]
Belazzougui, D., Cunial, F.: Fast label extraction in the CDAWG. In: String Processing and Information Retrieval, SPIRE 2017. Lecture Notes in Computer Science, vol. 10508, pp. 161–175. Springer (2017).
[10]
Bender, M.A., Farach-Colton, M.: The level ancestor problem simplified. Theor. Comput. Sci. 321(1), 5–12 (2004).