Skip to content

Commit 5a139fd

Browse files
committed
profiling and cleanup
1 parent 0220d53 commit 5a139fd

File tree

5 files changed

+57
-67
lines changed

5 files changed

+57
-67
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,12 @@ val CFG.ntMap by cache { ntLst.mapIndexed { i, s -> s to i }.toMap() }
6464
// which is then flattened to a list of adjacent pairs of nonterminal indices
6565
val CFG.vindex: Array<IntArray> by cache {
6666
Array(bindex.indexedNTs.size) { i ->
67-
bimap[bindex[i]].filter { it.size > 1 }
68-
.flatMap { listOf(bindex[it[0]], bindex[it[1]]) }.toIntArray()
67+
// val lhs = bindex[i]
68+
bimap[bindex[i]].filter { it.size == 2 }
69+
// .map { it to -(PCFG3_BIFI[lhs to it[0] to it[1]] ?: 0).also { s -> println("$lhs -> ${it[0]} ${it[1]} ($s)" )} }
70+
// .sortedBy { it.second }.map { it.first }
71+
.map { it.map { bindex[it] } }.flatten()
72+
.toIntArray()
6973
}
7074
}
7175

src/commonMain/kotlin/ai/hypergraph/kaliningraph/repair/Grammars.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import ai.hypergraph.kaliningraph.parsing.noEpsilonOrNonterminalStubs
55
import ai.hypergraph.kaliningraph.parsing.noNonterminalStubs
66
import ai.hypergraph.kaliningraph.parsing.parseCFG
77

8-
val s2pCFGStr = """
8+
val s2pCFGStr = """
99
START -> Stmts_Or_Newlines
1010
Stmts_Or_Newlines -> Stmt_Or_Newline | Stmt_Or_Newline Stmts_Or_Newlines
1111
Stmt_Or_Newline -> Stmt | Newline

src/commonMain/kotlin/ai/hypergraph/kaliningraph/tensor/Tensor.kt

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,9 @@ operator fun DoubleMatrix.times(value: Double): DoubleMatrix =
339339
DoubleMatrix(numRows, numCols, data.map { it * value })
340340

341341
// TODO: Rewrite this from scratch using T: List<UTMatrix<T>> recursive type with overlapping trees
342-
// Diagonals of a strictly-UT matrix for DAG-based dynamic programming
343-
class UTMatrix<T> constructor(
342+
// Diagonals of a strictly upper triangular matrix for DAG-based dynamic programming
343+
// All lower diagonal and diagonal entries are zero
344+
open class UTMatrix<T> constructor(
344345
val diagonals: List<List<T>>, // List of strictly-UT diagonals from longest to shortest
345346
override val algebra: Ring<T>
346347
): AbstractMatrix<T, Ring<T>, UTMatrix<T>>(algebra, diagonals.first().size + 1) {
@@ -382,7 +383,9 @@ class UTMatrix<T> constructor(
382383

383384
fun squared() = toFullMatrix().squareUpperTriangular().toUTMatrix()
384385

385-
fun seekFixpoint(
386+
// Performs matrix-matrix multiplication until the fixpoint is reached
387+
// This basically fills up each diagonal until the last upper diagonal
388+
open fun seekFixpoint(
386389
// Carries a triple of:
387390
// (1) the element itself,
388391
// (2) row to an element's left (inclusive)
@@ -411,39 +414,6 @@ class UTMatrix<T> constructor(
411414
).seekFixpoint(next, iteration + 1, maxIterations)
412415
}
413416

414-
fun seekFixpointFast(maxIterations: Int = diagonals.first().size): UTMatrix<T> {
415-
var iteration = 0
416-
417-
val diagonalsMutable = diagonals.toMutableList()
418-
val carry = diagonals.last().map { it to mutableListOf(it) to mutableListOf(it) }.toMutableList()
419-
420-
while (iteration < maxIterations && diagonalsMutable.last().size != 1) {
421-
val next = mutableListOf<Triple<T, MutableList<T>, MutableList<T>>>()
422-
423-
for (i in 1 until carry.size) {
424-
var acc = algebra.nil
425-
for (j in carry[i - 1].second.indices) {
426-
acc = with(algebra) { acc + (carry[i - 1].second[j] * carry[i].third[j]) }
427-
}
428-
429-
val left = carry[i - 1].second.apply { add(acc) }
430-
val right = carry[i].third.apply { add(0, acc) }
431-
432-
next.add(Triple(acc, left, right))
433-
}
434-
435-
diagonalsMutable += next.map { it.first }
436-
carry.clear()
437-
carry.addAll(next)
438-
iteration++
439-
}
440-
441-
return UTMatrix(
442-
diagonals = diagonalsMutable,
443-
algebra = algebra
444-
)
445-
}
446-
447417
// Offsets diagonals by one when converting back to matrix (superdiagonal)
448418
fun toFullMatrix() =
449419
if (diagonals.last().size != 1)

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

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import ai.hypergraph.kaliningraph.parsing.*
22

33
object Grammars {
4-
val sss = """START -> b | START | START START | START START START"""
5-
.parseCFG().noNonterminalStubs
4+
val sss by lazy {
5+
"""START -> b | START | START START | START START START"""
6+
.parseCFG().noNonterminalStubs
7+
}
68

7-
val ifThen = """
9+
val ifThen by lazy {
10+
"""
811
START -> X
912
X -> I | F | P | Q
1013
P -> I O I | P O I
@@ -18,33 +21,34 @@ object Grammars {
1821
BO -> and | or | xor | nand
1922
N -> !
2023
""".parseCFG().noNonterminalStubs
24+
}
2125

22-
val toyArith = """
26+
val toyArith by lazy { """
2327
S -> S + S | S * S | S - S | S / S | ( S ) | - S
2428
S -> 0 | 1 | 2 | 3 | 4
2529
S -> X | Y | Z
26-
""".parseCFG().noNonterminalStubs
30+
""".parseCFG().noNonterminalStubs }
2731

28-
val dyckUnambig = """S -> ( S ) S | ( S ) | ( ) S | ( )""".parseCFG().noEpsilonOrNonterminalStubs
29-
val dyck = """S -> ( S ) | ( ) | S S""".parseCFG().noEpsilonOrNonterminalStubs
32+
val dyckUnambig by lazy { """S -> ( S ) S | ( S ) | ( ) S | ( )""".parseCFG().noEpsilonOrNonterminalStubs }
33+
val dyck by lazy { """S -> ( S ) | ( ) | S S""".parseCFG().noEpsilonOrNonterminalStubs }
3034

31-
val dyckEmbedded = """
35+
val dyckEmbedded by lazy { """
3236
START -> ( ) | ( START ) | START START
3337
START -> START + START | START * START
3438
START -> 1
35-
""".parseCFG().noNonterminalStubs
39+
""".parseCFG().noNonterminalStubs}
3640

37-
val deadSimple = """S -> ( ) | ( S )""".parseCFG().noEpsilonOrNonterminalStubs
38-
val dsNorm = """
41+
val deadSimple by lazy { """S -> ( ) | ( S )""".parseCFG().noEpsilonOrNonterminalStubs }
42+
val dsNorm by lazy { """
3943
START -> START START
4044
START -> A B
4145
START -> A C
4246
A -> (
4347
B -> )
4448
C -> START B
45-
""".parseCFG().noEpsilonOrNonterminalStubs
49+
""".parseCFG().noEpsilonOrNonterminalStubs }
4650

47-
val ocamlCFG = """
51+
val ocamlCFG by lazy { """
4852
S -> X
4953
X -> A | V | ( X , X ) | X X | ( X )
5054
A -> FUN | F | LI | M | L
@@ -69,9 +73,9 @@ object Grammars {
6973
VO -> = | < | `||` | `&&`
7074
I -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
7175
B -> true | false
72-
""".parseCFG().noNonterminalStubs
76+
""".parseCFG().noNonterminalStubs }
7377

74-
val coarsenedPythonCFG = """
78+
val coarsenedPythonCFG by lazy { """
7579
S -> w | S ( S ) | ( ) | S = S | S . S | S S | ( S ) | [ S ] | { S } | : | * S | [ ]
7680
S -> S , S | S ; S | S : S
7781
S -> S IOP S | S BOP S
@@ -86,9 +90,9 @@ object Grammars {
8690
S -> if S | if S else S | return S
8791
S -> not S | S or S
8892
S -> lambda w : S | lambda w , w : S | lambda w , w , w : S | lambda w , w , w , w : S
89-
""".parseCFG().noNonterminalStubs
93+
""".parseCFG().noNonterminalStubs }
9094

91-
val tinyC: CFG = """
95+
val tinyC: CFG by lazy { """
9296
START -> program
9397
program -> statement
9498
statement -> if paren_expr statement
@@ -103,10 +107,10 @@ object Grammars {
103107
test -> sum | sum < sum
104108
sum -> term | sum + term | sum - term
105109
term -> id | int | paren_expr
106-
""".parseCFG().freeze()
110+
""".parseCFG().freeze() }
107111

108112
// https://aclanthology.org/2020.conll-1.41.pdf#page=12
109-
val hardestCFL: CFG = """
113+
val hardestCFL: CFG by lazy { """
110114
S' -> R ${'$'} Q S L ;
111115
L -> L' , U
112116
L' -> , V L'
@@ -131,10 +135,10 @@ object Grammars {
131135
T -> [ Q S Q ]
132136
T -> ( Q )
133137
T -> [ Q ]
134-
""".trimIndent().parseCFG().noNonterminalStubs
138+
""".trimIndent().parseCFG().noNonterminalStubs }
135139

136140
val shortS2PParikhMap by lazy { ParikhMap(seq2parsePythonCFG, 20) }
137-
val seq2parsePythonCFGStr = """
141+
val seq2parsePythonCFGStr by lazy { """
138142
START -> Stmts_Or_Newlines
139143
Stmts_Or_Newlines -> Stmt_Or_Newline | Stmt_Or_Newline Stmts_Or_Newlines
140144
Stmt_Or_Newline -> Stmt | Newline
@@ -325,12 +329,12 @@ object Grammars {
325329
326330
Yield_Expr -> Yield_Keyword | Yield_Keyword Yield_Arg
327331
Yield_Arg -> From_Keyword Test | Testlist_Endcomma
328-
"""
332+
""" }
329333

330-
val seq2parsePythonCFG: CFG = seq2parsePythonCFGStr.parseCFG().noNonterminalStubs
331-
val seq2parsePythonVanillaCFG: CFG = seq2parsePythonCFGStr.parseCFG().noEpsilonOrNonterminalStubs
334+
val seq2parsePythonCFG: CFG by lazy { seq2parsePythonCFGStr.parseCFG().noNonterminalStubs }
335+
val seq2parsePythonVanillaCFG: CFG by lazy { seq2parsePythonCFGStr.parseCFG().noEpsilonOrNonterminalStubs }
332336

333-
val checkedArithCFG = """
337+
val checkedArithCFG by lazy { """
334338
START -> S
335339
S -> S1 = S1
336340
S -> S2 = S2
@@ -381,13 +385,13 @@ P6 -> P6 / P1
381385
P7 -> P7 / P1
382386
P8 -> P8 / P1
383387
P9 -> P9 / P1
384-
""".parseCFG().noNonterminalStubs.freeze()
388+
""".parseCFG().noNonterminalStubs.freeze() }
385389

386-
val arith = """
390+
val arith by lazy { """
387391
O -> + | * | - | /
388392
S -> S O S | ( S )
389393
S -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
390-
""".parseCFG()
394+
""".parseCFG() }
391395

392396
private fun Tree.middle(): Σᐩ? = children.drop(1).firstOrNull()?.terminal
393397
fun Tree.evalArith(): Int = when {

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ import kotlin.time.*
1515
./gradlew jvmTest --tests "ai.hypergraph.kaliningraph.parsing.SetValiantTest"
1616
*/
1717
class SetValiantTest {
18+
/*
19+
./gradlew jvmTest --tests "ai.hypergraph.kaliningraph.parsing.SetValiantTest.testStressRecognizer"
20+
*/
21+
@Test
22+
fun testStressRecognizer() {
23+
val g = Grammars.seq2parsePythonVanillaCFG
24+
g.sliceSample(20).take(10000).forEach {
25+
assertTrue(it.matches(g))
26+
assertFalse(it.tokenizeByWhitespace().dropLastWhile { it == "DEDENT" || it == "NEWLINE" }.matches(g))
27+
}
28+
}
29+
1830
/*
1931
./gradlew jvmTest --tests "ai.hypergraph.kaliningraph.parsing.SetValiantTest.testSimpleGrammar"
2032
*/

0 commit comments

Comments
 (0)