com.jtransc.graph.acyclic.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jtransc-core Show documentation
Show all versions of jtransc-core Show documentation
JVM AOT compiler currently generating JavaScript, C++, Haxe, with initial focus on Kotlin and games.
package com.jtransc.graph
import com.jtransc.error.invalidOp
import java.util.*
interface AcyclicDigraph : Digraph
fun Digraph.assertAcyclic(): AcyclicDigraph = if (this is AcyclicDigraph) this else AcyclicDigraphImpl(this)
fun Digraph.hasCycles(): Boolean = !isAcyclic()
fun Digraph.isAcyclic(): Boolean = this.tarjanStronglyConnectedComponentsAlgorithm().components.all {
if (it.indices.size == 1) {
val item = it.indices.first()
item !in it.scgraph.graph.getOut(item)
} else {
false
}
}
class AcyclicDigraphImpl(val graph: Digraph) : AcyclicDigraph {
override val nodes: List = graph.nodes
override val nodeIndices: Map = graph.nodeIndices
//override fun getIn(node: Int): List = graph.getIn(node)
override fun getOut(node: Int): List = graph.getOut(node)
init {
for (c in graph.tarjanStronglyConnectedComponentsAlgorithm().components) {
if (c.indices.size != 1) invalidOp("Cyclic graph")
}
}
}
class AcyclicDigraphLookup(val graph: AcyclicDigraph, val lookup: List>) {
fun common(items: Iterable): T = items.reduce { a, b -> common(a, b) }
fun common(a: T, b: T): T = graph.getNode(this.common(graph.getIndex(a), graph.getIndex(b)))
fun common(items: Iterable): Int = items.reduce { a, b -> common(a, b) }
fun common(a: Int, b: Int): Int {
val aset = lookup[a]
val bset = lookup[b]
for (i in aset) if (i in bset) return i
return UNDEFINED
}
}
fun AcyclicDigraph.createCommonDescendantLookup(): AcyclicDigraphLookup {
val explored = BooleanArray(size)
val descendants = (0 until size).map { LinkedHashSet() }
fun explore(node: Int) {
if (explored[node]) return
explored[node] = true
descendants[node] += node
for (child in getOut(node)) {
explore(child)
descendants[node] += descendants[child]
}
}
for (node in 0 until size) explore(node)
return AcyclicDigraphLookup(this, descendants)
}