All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jtransc.graph.acyclic.kt Maven / Gradle / Ivy

Go to download

JVM AOT compiler currently generating JavaScript, C++, Haxe, with initial focus on Kotlin and games.

There is a newer version: 0.6.8
Show newest version
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)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy