Skip to content

Commit

Permalink
speed up vestigial pruning
Browse files Browse the repository at this point in the history
  • Loading branch information
breandan committed Oct 13, 2023
1 parent bd5ad7e commit 047d8af
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ infix fun CFG.intersectLevFSA(fsa: FSA): CFG {
return (initFinal + transits + binaryProds + unitProds).joinToString("\n")
.parseCFG(normalize = false)
.also { println("∩-grammar has ${it.size} total productions") }
.removeVestigalProductions().normalForm.noNonterminalStubs
.dropVestigialProductions().normalForm.noNonterminalStubs
.also { println("∩-grammar has ${it.size} useful productions") }
.also { println("∩-grammar construction took: ${clock.elapsedNow().inWholeMilliseconds}ms") }
// .also { println(it.pretty) }
Expand Down Expand Up @@ -89,7 +89,7 @@ infix fun CFG.intersect(fsa: FSA): CFG {
return (initFinal + transits + binaryProds + unitProds).joinToString("\n")
.parseCFG(normalize = false)
.also { println("∩-grammar has ${it.size} total productions") }
.removeVestigalProductions().normalForm.noNonterminalStubs
.dropVestigialProductions().normalForm.noNonterminalStubs
.also { println("∩-grammar has ${it.size} useful productions") }
.also { println("∩-grammar construction took: ${clock.elapsedNow().inWholeMilliseconds}ms") }
// .also { println(it.pretty) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ val CFG.noNonterminalStubs: CFG by cache {
val CFG.noEpsilonOrNonterminalStubs: CFG by cache {
println("Disabling nonterminal stubs!")
filter { it.RHS.none { it.isNonterminalStubIn(this) } }
.filter { "ε" !in it.toString() }.toSet().removeVestigalProductions()
.filter { "ε" !in it.toString() }.toSet().dropVestigialProductions()
.also { rewriteHistory.put(it, freeze().let { rewriteHistory[it]!! + listOf(it)}) }
.also { it.blocked.addAll(blocked) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ val rewriteHistory = LRUCache<CFG, List<CFG>>()

// Recursively removes all productions from a synthetic CFG containing a
// dangling nonterminal, i.e., a nonterminal that does not produce any terminals.
fun CFG.removeVestigalProductions(
fun CFG.dropVestigialProductions(
criteria: (Σᐩ) -> Boolean = { it.first() == '[' && it.last() == ']' && it.count { it == ',' } == 2 }
): CFG {
val rw =
filter { it.RHS.all { !criteria(it) || it in nonterminals } }
.toSet().removeUselessSymbols()
val nts: Set<Σᐩ> = map { it.LHS }.toSet()
val rw = toMutableSet()
.apply { removeAll { !it.RHS.all { !criteria(it) || it in nts } } }
.removeUselessSymbols()

// println("Removed ${size - rw.size} vestigal productions.")

return if (rw.size == size) this else rw.removeVestigalProductions(criteria)
return if (rw.size == size) this else rw.dropVestigialProductions(criteria)
}

/**
Expand All @@ -47,7 +48,7 @@ fun CFG.normalize(): CFG =
// ./gradlew jvmTest --tests "ai.hypergraph.kaliningraph.sat.SATValiantTest.testTLArithmetic"
.generateNonterminalStubs()
// Should only need to run this on synthetic CFGs
.removeVestigalProductions()
.dropVestigialProductions()
.also { cnf -> rewriteHistory.put(cnf.freeze(), rewrites) }
}

Expand Down Expand Up @@ -180,7 +181,10 @@ fun CFG.refactorEpsilonProds(nlbls: Set<Σᐩ> = nullableNonterminals()): CFG =
fun CFG.removeUselessSymbols(
generating: Set<Σᐩ> = generatingSymbols(),
reachable: Set<Σᐩ> = reachableSymbols()
): CFG = partition { (s, _) -> s in generating intersect reachable }
): CFG =
toMutableSet().apply {
removeAll { (s, _) -> !(s in generating && s in reachable) }
}
// .also {
// println(
// it.second.joinToString("\n") { (l, r) ->
Expand All @@ -191,7 +195,7 @@ fun CFG.removeUselessSymbols(
// }
// )
// }
.first.toSet()
// .first.toSet()

fun CFG.equivalenceClass(from: Σᐩ): Set<Σᐩ> = unitReachability[from] ?: setOf(from)

Expand Down

0 comments on commit 047d8af

Please sign in to comment.