I have the following definition of a directed graph in Kotlin. (I'm still learning Kotlin so please forgive any shortcomings. Improvements and suggestions are always welcome.) My goal is to have a method, reverse
, which maintains the vertices and loops but swaps the directions of the other edges.
// We use an edge list because it makes it the easiest to swap.
data class ReversibleDirectedGraph<T>(val vertices: Set<T>, val edgeList: List<Pair<T,T>>) {
// This should be a self-inverting function.
fun reverse(): ReversibleDirectedGraph<T> {
// Make sure all vertices in edgeList are in vertices.
val allVertices = edgeList.flatMap { it.toList() }
require(allVertices.all { it in vertices }) { "Illegal graph specification" }
// Swap the edges.
val newEdgeList = edgeList.map { it.second to it.first }
return ReversibleDirectedGraph(allVertices.toSet(), newEdgeList)
}
}
fun main() {
// Example test: works correctly. Double edge reversal results in original graph.
val g = ReversibleDirectedGraph(setOf(0, 1, 2, 3),
listOf(0 to 1, 2 to 1, 3 to 2, 3 to 0, 1 to 3))
println(g)
val gr = g.reverse()
println(gr)
val grr = gr.reverse()
println(grr)
println(grr == g)
}
I'd like to use property-based testing to test this code using KotinTest, but I'm having trouble structuring it to properly produce random samples of undirected graphs. If I can achieve that point, I can reverse the edge direction twice and then ensure that the original graph is achieved.
I'm familiar with Gen.list
, Gen.choose
, etc, but I can't seem to fit the pieces together to get the final product, i.e. the random undirecteed graph.
I've gotten up to this, but this is clearly missing pieces, and I was hoping that someone might be able to assist. I suspect I could do it in Scala since I have more experience there, but I am determined to learn Kotlin. Ultimately, something along the lines of:
class ReversibleDirectedGraphTest: StringSpec() {
init {
"reversibleDirectedGraphTest" {
forAll { g: ReversibleDirectedGraph<Int> ->
assertEqual(g.reverse().reverse() == g) }
}
}
}
}
Any help / suggestions would be greatly appreciated. Thanks!