From d5cb01965eb14e60bc7ab0fbaabd283813873d41 Mon Sep 17 00:00:00 2001 From: breandan Date: Tue, 30 Apr 2024 13:51:04 -0400 Subject: [PATCH] use conventional FSA rendering --- .../ai/hypergraph/kaliningraph/types/Graph.kt | 4 ++-- .../kaliningraph/automata/WFSATest.kt | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/commonMain/kotlin/ai/hypergraph/kaliningraph/types/Graph.kt b/src/commonMain/kotlin/ai/hypergraph/kaliningraph/types/Graph.kt index 1ca2232f..112fa96c 100644 --- a/src/commonMain/kotlin/ai/hypergraph/kaliningraph/types/Graph.kt +++ b/src/commonMain/kotlin/ai/hypergraph/kaliningraph/types/Graph.kt @@ -156,11 +156,11 @@ interface IGraph: IGF, Set, Encodable graph ["concentrate"="false","rankdir"="LR","bgcolor"="transparent","margin"="0.0","compound"="true","nslimit"="20"] ${ vertices.joinToString("\n") { - """"${it.id.htmlify()}" ["color"="black","fontcolor"="black","fontname"="JetBrains Mono","fontsize"="15","penwidth"="2.0","shape"="Mrecord"${if(it in highlight)""","fillcolor"=lightgray,"style"=filled""" else ""}]""" } + """"${it.id.htmlify()}" ["shape"="Mrecord","color"="black","fontcolor"="black","fontname"="JetBrains Mono","fontsize"="15","penwidth"="2.0"${if(it in highlight)""","fillcolor"=lightgray,"style"=filled""" else ""}]""" } } ${edgList.joinToString("\n") { (v, e) -> val (src, tgt) = v.id.htmlify() to e.target.id.htmlify() - """"$src" -> "$tgt" ["color"="${ if (v is LGVertex && v.occupied) "red" else "black" }","arrowhead"="normal","penwidth"="2.0","label"="${(e as? LabeledEdge)?.label ?: ""}"]""" } + """"$src" -> "$tgt" ["color"="${ if (v is LGVertex && v.occupied) "red" else "black" }","fontname"="JetBrains Mono","arrowhead"="normal","penwidth"="2.0","label"="${(e as? LabeledEdge)?.label ?: ""}"]""" } } } """.trimIndent() diff --git a/src/jvmTest/kotlin/ai/hypergraph/kaliningraph/automata/WFSATest.kt b/src/jvmTest/kotlin/ai/hypergraph/kaliningraph/automata/WFSATest.kt index 98d54f2d..5204f264 100644 --- a/src/jvmTest/kotlin/ai/hypergraph/kaliningraph/automata/WFSATest.kt +++ b/src/jvmTest/kotlin/ai/hypergraph/kaliningraph/automata/WFSATest.kt @@ -4,7 +4,7 @@ import Grammars import Grammars.shortS2PParikhMap import ai.hypergraph.kaliningraph.graphs.LabeledGraph import ai.hypergraph.kaliningraph.parsing.* -import ai.hypergraph.kaliningraph.visualization.alsoCopy +import ai.hypergraph.kaliningraph.visualization.* import net.jhoogland.jautomata.* import net.jhoogland.jautomata.Automaton import net.jhoogland.jautomata.operations.* @@ -44,14 +44,24 @@ class WFSATest { transitionsOut(state).forEach { val label = label(it) + "/" + transitionWeight(it).toString().take(4) val next = this@toDot.to(it) - state.hashCode().toString()[label] = next.hashCode().toString() + val initws = initialWeight(state) + val finalws = finalWeight(state) + val initwn = initialWeight(next) + val finalwn = finalWeight(next) + (state.hashCode().toString() + "#$initws/$finalws")[label] = next.hashCode().toString() + "#$initwn/$finalwn" if (next !in processed) { processed.add(next) stateQueue.add(next) } } } - }.toDot().replace("Mrecord\"", "Mrecord\", label=\"\"") + }.toDot() + // States are typically unlabeled in FSA diagrams + .replace("Mrecord\"", "Mrecord\", label=\"\"") + // Final states are suffixed with /1.0 and drawn as double circles + .replace("/1.0\" [\"shape\"=\"Mrecord\"", "/1.0\" [\"shape\"=\"doublecircle\"") + .replace("Mrecord", "circle") // FSA states should be circular + .replace("null", "ε") // null label = ε-transition /* ./gradlew jvmTest --tests "ai.hypergraph.kaliningraph.automata.WFSATest.testLBHRepair" @@ -75,7 +85,7 @@ class WFSATest { addTransition(s1, s2, a.root, 1.0) } } - )?.also { println("\n" + Operations.determinizeER(it).toDot().alsoCopy() + "\n") } + )?.also { println("\n" + it.toDot().alsoCopy() + "\n") } .also { println("Total: ${Automata.transitions(it).size} arcs, ${Automata.states(it).size}") } .let { Automata.bestStrings(it, 1000).map { it.label.joinToString(" ") }.toSet() } }.also {