diff --git a/src/commonMain/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillel.kt b/src/commonMain/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillel.kt index faac46ad..c2ac3ecc 100644 --- a/src/commonMain/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillel.kt +++ b/src/commonMain/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillel.kt @@ -4,11 +4,13 @@ import ai.hypergraph.kaliningraph.types.* import kotlin.math.absoluteValue import kotlin.time.TimeSource -infix fun FSA.intersectLevFSA(cfg: CFG) = cfg.intersectLevFSA(this) +infix fun FSA.intersectLevFSA(cfg: CFG) = cfg.freeze().intersectLevFSAP(this) // http://www.cs.umd.edu/~gasarch/BLOGPAPERS/cfg.pdf#page=2 // https://browse.arxiv.org/pdf/2209.06809.pdf#page=5 -infix fun CFG.intersectLevFSA(fsa: FSA): CFG { +infix fun CFG.intersectLevFSA(fsa: FSA): CFG = freeze().intersectLevFSAP(fsa) + +private infix fun CFG.intersectLevFSAP(fsa: FSA): CFG { var clock = TimeSource.Monotonic.markNow() val initFinal = (fsa.init * fsa.final).map { (q, r) -> "START -> [$q,START,$r]" } @@ -82,6 +84,7 @@ fun List<Σᐩ>.postProcess() = .also { println("∩-grammar has ${it.size} total productions") } .dropVestigialProductions().normalForm.noNonterminalStubs .also { println("∩-grammar has ${it.size} useful productions") } + .freeze() // .also { println(it.pretty) } // .also { println(it.size) } @@ -110,7 +113,7 @@ fun CFG.dropVestigialProductions( // val reachable = reachableSymbols() val rw = toMutableSet() .apply { removeAll { prod -> prod.RHS.any { criteria(it) && it !in nts } } } - .removeUselessSymbols() + .freeze().removeUselessSymbols() println("Removed ${size - rw.size} vestigial productions.") diff --git a/src/commonMain/kotlin/ai/hypergraph/kaliningraph/parsing/Normalization.kt b/src/commonMain/kotlin/ai/hypergraph/kaliningraph/parsing/Normalization.kt index 82548707..23247856 100644 --- a/src/commonMain/kotlin/ai/hypergraph/kaliningraph/parsing/Normalization.kt +++ b/src/commonMain/kotlin/ai/hypergraph/kaliningraph/parsing/Normalization.kt @@ -212,7 +212,7 @@ fun CFG.genSym(from: Set<Σᐩ> = terminalUnitProductions.map { it.LHS }.toSet() val t = nextGenerating.first() nextGenerating.remove(t) allGenerating += t - nextGenerating += (bimap.TDEPS[t]?: emptyList()) + nextGenerating += (bimap.TDEPS[t] ?: emptyList()) .filter { it !in allGenerating && it !in nextGenerating } } while (nextGenerating.isNotEmpty()) diff --git a/src/commonTest/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillelTest.kt b/src/commonTest/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillelTest.kt index daf3ffc3..d9c2b50a 100644 --- a/src/commonTest/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillelTest.kt +++ b/src/commonTest/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillelTest.kt @@ -192,12 +192,14 @@ class BarHillelTest { @Test fun testPythonBarHillel() { val gram = Grammars.seq2parsePythonCFG.noEpsilonOrNonterminalStubs - val levBall = makeLevFSA("- NUMBER + NEWLINE", 2, gram.terminals) + val toRepair = "NAME = ( NAME .".tokenizeByWhitespace() + val levBall = makeLevFSA(toRepair, 3, gram.terminals) val intGram = gram.intersectLevFSA(levBall) - .also { println("LEV ∩ CFG grammar:\n${it.pretty}") } +// .also { println("LEV ∩ CFG grammar:\n${it.pretty}") } val clock = TimeSource.Monotonic.markNow() - val lbhSet = intGram.enumSeq(List(6) { "_" }.joinToString(" ")) + val template = List(toRepair.size + 2) { "_" }.joinToString(" ") + val lbhSet = intGram.enumSeq(template) .onEach { println(it) assertTrue(it in gram.language)