Skip to content

Commit ca60ad8

Browse files
committed
try to understand how this is possible
1 parent d1c0a69 commit ca60ad8

File tree

4 files changed

+79
-4
lines changed

4 files changed

+79
-4
lines changed

src/commonMain/kotlin/ai/hypergraph/kaliningraph/CommonUtils.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,19 @@ class KBitSet(val n: Int) {
133133
constructor(n: Int, v: Collection<Int>) : this(n) { v.forEach { set(it) } }
134134
// Each element of 'data' holds 64 bits, covering up to n bits total.
135135
private val data = LongArray((n + 63) ushr 6)
136+
var set = mutableSetOf<Int>()
137+
var modified = false
136138

137139
fun set(index: Int) {
140+
modified = true
138141
val word = index ushr 6
139142
val bit = index and 63
143+
set += index
140144
data[word] = data[word] or (1L shl bit)
141145
}
142146

147+
fun setAll() { (0..<n).forEach { set(it) } }
148+
143149
operator fun get(index: Int): Boolean {
144150
val word = index ushr 6
145151
val bit = index and 63

src/commonMain/kotlin/ai/hypergraph/kaliningraph/parsing/CFG.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,16 @@ class Bindex<T>(
258258
class BiMap(val cfg: CFG) {
259259
val L2RHS by lazy { cfg.groupBy({ it.LHS }, { it.RHS }).mapValues { it.value.toSet() } }
260260
val R2LHS by lazy { cfg.groupBy({ it.RHS }, { it.LHS }).mapValues { it.value.toSet() } }
261+
val R2LHSV by lazy { cfg.filter { it.RHS.all { it in cfg.nonterminals } }.groupBy({ it.RHS }, { it.LHS }).mapValues { it.value.toSet() } }
262+
val R2LHSI by lazy {
263+
val mmap = List(cfg.nonterminals.size) { List(cfg.nonterminals.size) { mutableListOf<Int>() } }
264+
R2LHSV.forEach {
265+
val rhs = it.key.map { cfg.bindex[it] }
266+
mmap[rhs[0]][rhs[1]] += it.value.map { cfg.bindex[it] }
267+
}
268+
// R2LHSV.map { it.key.map { cfg.bindex[it] } to it.value.map { cfg.bindex[it] } }.toMap()
269+
mmap
270+
}
261271

262272
val TDEPS: Map<Σᐩ, MutableSet<Σᐩ>> by lazy { // Maps all symbols to NTs that can generate them
263273
mutableMapOf<Σᐩ, MutableSet<Σᐩ>>().apply {

src/commonMain/kotlin/ai/hypergraph/kaliningraph/parsing/SetValiant.kt

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ fun CFG.isValid(str: List<Σᐩ>): Bln =
5050
if (str.size == 1) checkUnitWord(str.first()).isNotEmpty()
5151
// else initialUTBMatrix(str.pad3()).seekFixpoint().diagonals.last()[0][0]
5252
else {
53-
val dp = Array(str.size + 1) { Array(str.size + 1) { BooleanArray(nonterminals.size) { false } } }
53+
val dp = Array(str.size + 1) { Array(str.size + 1) { BooleanArray(nonterminals.size) { false } } }
5454
str.map {
5555
// if (it != "_" && tmMap[it] == null) println("What was this? \"$it\" / ${str.joinToString(" ")}")
5656
if (it == "_" || tmMap[it] == null) (0..<nonterminals.size).toList()
@@ -76,8 +76,26 @@ fun CFG.isValid(str: List<Σᐩ>): Bln =
7676
}
7777
dp[0][str.size][bindex[START_SYMBOL]]
7878
}
79-
//.also { it.forEachIndexed { r, d -> d.forEachIndexed { i, it -> println("$r, $i: ${toNTSet(it)}") } } }
80-
//.also { println("Last: ${it.joinToString(",") {if (it) "1" else "0"}}") }
79+
80+
fun CFG.isValidAlt(str: List<Σᐩ>): Bln =
81+
if (str.size == 1) checkUnitWord(str.first()).isNotEmpty()
82+
else {
83+
val dp = Array(str.size + 1) { Array(str.size + 1) { KBitSet(nonterminals.size) } }
84+
str.map {
85+
if (it == "_" || tmMap[it] == null) (0..<nonterminals.size).toList()
86+
else tmToVidx[tmMap[it]!!] }.forEachIndexed { i, it -> it.forEach { vidx -> dp[i][i+1].set(vidx) } }
87+
88+
for (dist: Int in 0 until dp.size) {
89+
for (iP: Int in 0 until dp.size - dist) {
90+
val p = iP
91+
val q = iP + dist
92+
val appq = p..q
93+
for (r in appq) for (lt in dp[p][r].set) for (rt in dp[r][q].set)
94+
bimap.R2LHSI[lt][rt].forEach { dp[p][q].set(it) }
95+
}
96+
}
97+
dp[0][str.size][bindex[START_SYMBOL]]
98+
}
8199

82100
fun CFG.corner(str: Σᐩ) =
83101
solveFixedpoint(str.tokenizeByWhitespace())[0].last().map { it.root }.toSet()
@@ -288,6 +306,47 @@ fun CFG.initialMatrix(str: List<Σᐩ>): TreeMatrix =
288306
}.toSet()
289307
}
290308

309+
typealias GRES = List<GRE?>
310+
311+
fun CFG.makeGRESAlgebra(): Ring<GRES> =
312+
Ring.of(// Not a proper ring, but close enough.
313+
// 0 = ∅
314+
nil = listOf(),
315+
// x + y = x ∪ y
316+
plus = { x, y ->
317+
if (x.isEmpty()) y else if (y.isEmpty()) x
318+
else x.zip(y) { a, b ->
319+
if (a == null) b
320+
else if (b == null) a
321+
else a + b
322+
}
323+
},
324+
// x · y = { A0 | A1 ∈ x, A2 ∈ y, (A0 -> A1 A2) ∈ P }
325+
times = { x, y -> if (x.isEmpty() || y.isEmpty()) emptyList() else greJoin(x, y) }
326+
)
327+
328+
fun CFG.greJoin(left: GRES, right: GRES): GRES =
329+
vindex.map { lrs ->
330+
val pairs = mutableListOf<GRE>()
331+
for (i in 0..<lrs.size step 2) {
332+
val left = (left[lrs[i]])
333+
val right = (right[lrs[i + 1]])
334+
if (left != null && right != null)
335+
pairs += left * right
336+
}
337+
if (pairs.isEmpty()) null else GRE.CUP(*pairs.toTypedArray())
338+
}
339+
340+
fun CFG.initialGREMatrix(str: List<Σᐩ>): FreeMatrix<GRES> =
341+
FreeMatrix(makeGRESAlgebra(), str.size + 1) { i, j ->
342+
if (i + 1 != j) listOf<GRE>()
343+
else if (str[j - 1] == HOLE_MARKER || str[j - 1] !in tmMap)
344+
List(nonterminals.size) { GRE.SET(KBitSet(terminals.size).apply { setAll() }) }
345+
else bimap[listOf(str[j - 1])].map { nt ->
346+
GRE.SET(KBitSet(terminals.size).apply { set(tmMap[str[j - 1]]!!) })
347+
}
348+
}
349+
291350
fun CFG.initialUTBMatrix(
292351
tokens: List<Σᐩ>,
293352
allNTs: Set<Σᐩ> = nonterminals,

src/commonTest/kotlin/ai/hypergraph/kaliningraph/parsing/SetValiantTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ class SetValiantTest {
440440
}.also { println("Fast transition: ${it.duration.inWholeMilliseconds}ms") }.value
441441

442442
measureTimedValue {
443-
println(str in language)
443+
println(isValidAlt(str))
444444
}.also { println("DP transition: ${it.duration.inWholeMilliseconds}ms") }.value
445445

446446
println("Length: ${str.size}")

0 commit comments

Comments
 (0)