Skip to content

Commit

Permalink
simplify intersection
Browse files Browse the repository at this point in the history
  • Loading branch information
breandan committed Jan 23, 2025
1 parent cc80242 commit 8e77aca
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 49 deletions.
72 changes: 36 additions & 36 deletions latex/thesis/content/Ch2_Formal_Language_Theory.tex
Original file line number Diff line number Diff line change
Expand Up @@ -166,52 +166,52 @@ \section{Parsing as matrix multiplication}\label{sec:matrix_parsing}
\hline
& $2^V$ & $\mathbb{Z}_2^{|V|}$ & $\mathbb{Z}_2^{|V|}\rightarrow\mathbb{Z}_2^{|V|}$\\\hline
$M_0$ & \begin{pmatrix}
\phantom{V} & \tiny{\{N\}} & & \\
& & \{N,O\} & \\
& & & \{N,O\} \\
& & &
\phantom{V} & \tiny{\{N\}} & & \\
& & \{N,O\} & \\
& & & \{N,O\} \\
& & &
\end{pmatrix} & \begin{pmatrix}
\phantom{V} & \ws\bs\ws\ws & & \\
& & \ws\bs\bs\ws & \\
& & & \ws\bs\bs\ws \\
& & &
\phantom{V} & \ws\bs\ws\ws & & \\
& & \ws\bs\bs\ws & \\
& & & \ws\bs\bs\ws \\
& & &
\end{pmatrix} & \begin{pmatrix}
\phantom{V} & V_{0, 1} & & \\
& & V_{1, 2} & \\
& & & V_{2, 3} \\
& & &
\phantom{V} & V_{0, 1} & & \\
& & V_{1, 2} & \\
& & & V_{2, 3} \\
& & &
\end{pmatrix} \\\hline
$M_1$ & \begin{pmatrix}
\phantom{V} & \tiny{\{N\}} & \varnothing & \\
& & \{N,O\} & \{L\} \\
& & & \{N,O\} \\
& & &
\phantom{V} & \tiny{\{N\}} & \varnothing & \\
& & \{N,O\} & \{L\} \\
& & & \{N,O\} \\
& & &
\end{pmatrix} & \begin{pmatrix}
\phantom{V} & \ws\bs\ws\ws & \ws\ws\ws\ws & \\
& & \ws\bs\bs\ws & \bs\ws\ws\ws \\
& & & \ws\bs\bs\ws \\
& & &
\phantom{V} & \ws\bs\ws\ws & \ws\ws\ws\ws & \\
& & \ws\bs\bs\ws & \bs\ws\ws\ws \\
& & & \ws\bs\bs\ws \\
& & &
\end{pmatrix} & \begin{pmatrix}
\phantom{V} & V_{0, 1} & V_{0, 2} & \\
& & V_{1, 2} & V_{1, 3} \\
& & & V_{2, 3} \\
& & &
\phantom{V} & V_{0, 1} & V_{0, 2} & \\
& & V_{1, 2} & V_{1, 3} \\
& & & V_{2, 3} \\
& & &
\end{pmatrix} \\\hline
\begin{tabular}{@{}c@{}}$M_2$\\$=$\\$M_\infty$\end{tabular} & \begin{pmatrix}
\phantom{V} & \tiny{\{N\}} & \varnothing & \{S\} \\
& & \{N,O\} & \{L\} \\
& & & \{N,O\} \\
& & &
\phantom{V} & \tiny{\{N\}} & \varnothing & \{S\} \\
& & \{N,O\} & \{L\} \\
& & & \{N,O\} \\
& & &
\end{pmatrix} & \begin{pmatrix}
\phantom{V} & \ws\bs\ws\ws & \ws\ws\ws\ws & \ws\ws\ws\bs \\
& & \ws\bs\bs\ws & \bs\ws\ws\ws \\
& & & \ws\bs\bs\ws \\
& & &
\phantom{V} & \ws\bs\ws\ws & \ws\ws\ws\ws & \ws\ws\ws\bs \\
& & \ws\bs\bs\ws & \bs\ws\ws\ws \\
& & & \ws\bs\bs\ws \\
& & &
\end{pmatrix} & \begin{pmatrix}
\phantom{V} & V_{0, 1} & V_{0, 2} & V_{0, 3} \\
& & V_{1, 2} & V_{1, 3} \\
& & & V_{2, 3} \\
& & &
\phantom{V} & V_{0, 1} & V_{0, 2} & V_{0, 3} \\
& & V_{1, 2} & V_{1, 3} \\
& & & V_{2, 3} \\
& & &
\end{pmatrix}\\\hline
\end{tabular}\\
}
Expand Down
30 changes: 18 additions & 12 deletions src/commonMain/kotlin/ai/hypergraph/kaliningraph/automata/FSA.kt
Original file line number Diff line number Diff line change
Expand Up @@ -200,42 +200,48 @@ open class FSA constructor(open val Q: TSA, open val init: Set<Σᐩ>, open val
val nStates = levFSA.numStates
val startIdx = cfg.bindex[START_SYMBOL]

// 2) Create dp array of parse trees
// 1) Create dp array of parse trees
val dp: Array<Array<Array<PTree?>>> = Array(nStates) { Array(nStates) { Array(cfg.nonterminals.size) { null } } }

// 3) Initialize terminal productions A -> a
// 2) Initialize terminal productions A -> a
for ((p, σ, q) in levFSA.allIndexedTxs1(cfg)) {
val Aidxs = cfg.bimap.TDEPS[σ]!!.map { cfg.bindex[it] }
for (Aidx in Aidxs) {
val newLeaf = PTree(root = "[$p~${cfg.bindex[Aidx]}~$q]", branches = PSingleton(σ))
dp[p][q][Aidx] = if (dp[p][q][Aidx] == null) newLeaf else dp[p][q][Aidx]!! + newLeaf
dp[p][q][Aidx] = newLeaf + dp[p][q][Aidx]
}
}

// 3) CYK + Floyd Warshall parsing
for (dist in 0 until nStates) {
for (p in 0 until (nStates - dist)) {
val q = p + dist

for ((Aidx, /*->*/ Bidx, Cidx) in cfg.tripleIntProds) {
// val splp = levFSA.SPLP(p, q).let { (it.first - 1)..(it.last + 2) }

val possibleProds = cfg.tripleIntProds
// .filter { // Potential optimization:
// val ntlb = cfg.parikhMap.ntLengthBounds[it.first]
// println("SPLP (${levFSA.stateLst[p]}, ${levFSA.stateLst[q]}): $splp / $ntlb")
// splp.overlaps(ntlb)
// }
for ((Aidx, /*->*/ Bidx, Cidx) in possibleProds) {
// Check all possible midpoint states r in the DAG from p to q
for (r in (levFSA.allPairs[p to q] ?: emptySet())) {
for (r in (levFSA.allPairs[p to q] ?: emptySet())) { // Sparse dot prod
val left = dp[p][r][Bidx]
val right = dp[r][q][Cidx]
if (left != null && right != null) {
val newTree = PTree("[$p~${cfg.bindex[Aidx]}~$q]", listOf(left to right))

if (dp[p][q][Aidx] == null) dp[p][q][Aidx] = newTree
else dp[p][q][Aidx] = dp[p][q][Aidx]!! + newTree
dp[p][q][Aidx] = newTree + dp[p][q][Aidx]
}
}
}
}
}

// 5) Gather final parse trees from dp[0][f][startIdx], for all final states f
val allParses = levFSA.finalIdxs.mapNotNull { f -> dp[0][f][startIdx] }
// 4) Gather final parse trees from dp[0][f][startIdx], for all final states f
val allParses = levFSA.finalIdxs.mapNotNull { q -> dp[0][q][startIdx] }

// 6) Combine them under a single "super‐root"
// 5) Combine them under a single "super‐root"
return if (allParses.isEmpty()) null
else PTree(START_SYMBOL, allParses.flatMap { forest -> forest.branches })
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ fun FSA.SPLP(a: STC, b: STC): IntRange {
else rng..manhattanDistance(a.coords(), b.coords())
}

fun FSA.SPLP(a: Int, b: Int): IntRange {
val rng = APSP[a to b]
return if (rng == null) Int.MAX_VALUE..Int.MAX_VALUE
else rng..manhattanDistance(stateLst[a].coords(), stateLst[b].coords())
}

fun SPLPArith(a: STC, b: STC): IntRange {
val (xdiff, ydiff) = (b.coords().first - a.coords().first) to (b.coords().second - a.coords().second)
val lp = manhattanDistance(a.coords(), b.coords())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PTree constructor(val root: String = ".ε", val branches: List<Π2A<PTree>
// override fun hashCode(): Int = hash
var ntIdx = -1

operator fun plus(other: PTree) = PTree(root, branches + other.branches)
operator fun plus(other: PTree?) = if (other == null) this else PTree(root, branches + other.branches)

val branchRatio: Pair<Double, Double> by lazy { if (branches.isEmpty()) 0.0 to 0.0 else
(branches.size.toDouble() + branches.sumOf { (l, r) -> l.branchRatio.first + r.branchRatio.first }) to
Expand Down

0 comments on commit 8e77aca

Please sign in to comment.