Skip to content

Commit

Permalink
speed up ptree matrix fixpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
breandan committed Jul 15, 2024
1 parent f247409 commit 2a6807b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,30 @@ class PTree(val root: String = ".ε", val branches: List<Π2A<PTree>> = listOf()
}

fun CFG.startPTree(tokens: List<String>) = //measureTimedValue {
initPForestMat(tokens).seekFixpoint().diagonals.last()[0][START_SYMBOL]
// initPForestMat(tokens).seekFixpoint().diagonals.last()[0][START_SYMBOL]
//}.also { println("Took ${it.duration} to compute parse forest") }.value
initPTreeListMat(tokens).seekFixpoint().diagonals.last()[0][bindex[START_SYMBOL]]

// Instead of defining a special case, we instead represent the unit production
// as a left child whose sibling is empty like so: Left child to Right child
fun PSingleton(v: String): List<Π2A<PTree>> = listOf(PTree(v) to PTree())

fun CFG.initPTreeListMat(tokens: List<String>): UTMatrix<List<PTree?>> =
UTMatrix(
ts = tokens.map { token ->
val ptreeList = MutableList<PTree?>(nonterminals.size) { null }
(if (token != HOLE_MARKER) bimap[listOf(token)] else unitNonterminals)
.associateWith { nt ->
if (token != HOLE_MARKER) PSingleton(token)
else bimap.UNITS[nt]?.map {
println("$token -> $it")
PSingleton(it) }?.flatten() ?: listOf()
}.forEach { (k, v) -> ptreeList[bindex[k]] = PTree(k, v) }
ptreeList
}.toTypedArray(),
algebra = ptreeListAlgebra
)

fun CFG.initPForestMat(tokens: List<String>): UTMatrix<PForest> =
UTMatrix(
ts = tokens.map { token ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,30 @@ fun fastJoin(/**[vindex]*/vidx: Array<ℤⁿ>, left: Blns, right: Blns): Blns {
return result
}

fun <T> fastGenericJoin(
/**[vindex]*/vidx: Array<ℤⁿ>, strMap: List<Σᐩ>,
left: List<T?>, right: List<T?>,
t: (List<Pair<T, T>>, Σᐩ) -> T
): List<T?> {
if (left.isEmpty() || right.isEmpty()) return listOf()

val result = MutableList<T?>(vidx.size) { null }
for ((i, indexArray) in vidx.withIndex()) {
var j = 0
val rt = strMap[i]
val ls = mutableListOf<Pair<T, T>>()
while (j < indexArray.size) {
val (l, r) = left[indexArray[j]] to right[indexArray[j + 1]]
if (l != null && r != null) ls += l to r
j += 2
}

if (ls.isNotEmpty()) result[i] = t(ls, rt)
}

return result
}

// if (left.isEmpty() || right.isEmpty()) booleanArrayOf()
// else vindex.map { it.any { (B, C) -> left[B] and right[C] } }.toBooleanArray()

Expand All @@ -163,6 +187,12 @@ fun union(left: Blns, right: Blns): Blns {
return result
}

fun ptreeUnion(left: List<PTree?>, right: List<PTree?>): List<PTree?> =
List(left.size) { i ->
if (left[i] == null || right[i] == null) left[i] ?: right[i]
else PTree(left[i]!!.root, left[i]!!.branches + right[i]!!.branches)
}

val CFG.bitwiseAlgebra: Ring<Blns> by cache {
vindex.let {
Ring.of(
Expand All @@ -173,6 +203,16 @@ val CFG.bitwiseAlgebra: Ring<Blns> by cache {
}
}

val CFG.ptreeListAlgebra: Ring<List<PTree?>> by cache {
vindex.let {
Ring.of(
nil = List(nonterminals.size) { null },
plus = { x, y -> ptreeUnion(x, y) },
times = { x, y -> fastGenericJoin(it, bindex.indexedNTs, x, y) { ls, rt -> PTree(rt, ls) } }
)
}
}

// Like bitwiseAlgebra, but with nullable bitvector literals for free variables
val CFG.satLitAlgebra: Ring<Blns?> by cache {
vindex.let {
Expand Down

0 comments on commit 2a6807b

Please sign in to comment.