From 54a5ea07948ff242063cf9bd5eae07e04068202e Mon Sep 17 00:00:00 2001 From: breandan Date: Tue, 14 Jan 2025 00:57:00 -0500 Subject: [PATCH] add larger radius example to unit test --- .../hypergraph/kaliningraph/automata/FSA.kt | 38 +++++++++++-------- .../kaliningraph/parsing/BarHillelTest.kt | 9 +++++ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/commonMain/kotlin/ai/hypergraph/kaliningraph/automata/FSA.kt b/src/commonMain/kotlin/ai/hypergraph/kaliningraph/automata/FSA.kt index d2bdc412..051b2be5 100644 --- a/src/commonMain/kotlin/ai/hypergraph/kaliningraph/automata/FSA.kt +++ b/src/commonMain/kotlin/ai/hypergraph/kaliningraph/automata/FSA.kt @@ -129,21 +129,29 @@ open class FSA constructor(open val Q: TSA, open val init: Set<Σᐩ>, open val // println(dp.joinToString("\n") { it.joinToString(" ") { it.joinToString("", "[", "]") { if (it) "1" else "0"} } }) val startIdx = cfg.bindex[START_SYMBOL] - var fresh = true - while (fresh) { - fresh = false - for (p in 0 until levFSA.numStates) - for (q in (p + 1) until levFSA.numStates) - for ((w, /*->*/ x, z) in cfg.tripleIntProds) - if (!dp[p][q][w]) - for (r in levFSA.allPairs[p to q] ?: emptySet()) - if (dp[p][r][x] && dp[r][q][z]) { -// println("Found: ${levFSA.stateLst[p]} ${levFSA.stateLst[q]} / ${cfg.bindex[w]} -> ${cfg.bindex[x]} ${cfg.bindex[z]}") - if (p == 0 && w == startIdx && q in levFSA.finalIdxs) return true - dp[p][q][w] = true - fresh = true - break - } + + // For pairs (p,q) in topological order by (rank(q) - rank(p)): + for (dist in 1..levFSA.numStates-1) { + for (iP in 0 until levFSA.numStates - dist) { + val p = iP + val q = iP + dist + // For each A -> B C + for ((A, B, C) in cfg.tripleIntProds) { + if (!dp[p][q][A]) { + // Check possible midpoints r in [p+1, q-1] + // or in general, r in levFSA.allPairs[p->q] + for (r in (levFSA.allPairs[p to q] ?: emptySet())) { + if (dp[p][r][B] && dp[r][q][C]) { + if (p == 0 && A == startIdx && q in levFSA.finalIdxs) return true + dp[p][q][A] = true + // We don't need fresh = true, because once we pass this step, + // we won't come back to (p,q) in a later sweep + break + } + } + } + } + } } // println("AFTER (sum=${dp.sumOf { it.sumOf { it.sumOf { if(it) 1.0 else 0.0 } } }})") diff --git a/src/commonTest/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillelTest.kt b/src/commonTest/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillelTest.kt index 8a41387a..bbd685dc 100644 --- a/src/commonTest/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillelTest.kt +++ b/src/commonTest/kotlin/ai/hypergraph/kaliningraph/parsing/BarHillelTest.kt @@ -484,5 +484,14 @@ class BarHillelTest { measureTimedValue { FSA.nonemptyLevInt(str, Grammars.dyck, led - 1) } .also { println("${it.value} / ${it.duration}") } .also { assertFalse(it.value) } + + val pythonCode = "NAME = [ ( STRING , STRING ) , ( STRING , STRING ) , ( STRING , STRING ) , ( STRING , NAME ) , , ( NAME , NAME ) , , ( NAME , STRING ) , , ( NAME , NAME ) ]" + measureTimedValue { FSA.nonemptyLevInt(pythonCode, vanillaS2PCFG, 4) } + .also { println("${it.value} / ${it.duration}") } + .also { assertTrue(it.value) } + + measureTimedValue { FSA.nonemptyLevInt(pythonCode, vanillaS2PCFG, 3) } + .also { println("${it.value} / ${it.duration}") } + .also { assertFalse(it.value) } } } \ No newline at end of file