class ProducerStatement extends Statement {
object Context {
def sort(contexts: Seq[Context]) : Seq[Context] = {
- val ordering = scala.collection.mutable.Set[(Context, Context)]()
- for(c1 <- contexts; c2 <- contexts)
- (c1.tryCompare(c2)) match {
- case Some(x) => {
- if (x<0)
- ordering += (c1 -> c2)
- else if (x>0)
- ordering += (c2 -> c1)
- }
- case None => ()
- }
+ def pathFunction(c1: Context, c2: Context) = c1.tryCompare(c2) match {
+ case Some(x) if x<0 => true
+ case _ => false
+ }
- val totalOrdering = Ordering.transitiveClosure(ordering.toSet)
+ val totalOrdering = Ordering.transitiveClosure(contexts, pathFunction(_: Context, _: Context))
contexts.sortWith((a,b) => totalOrdering.contains(a,b))
}
}
package ofc.util
-import scala.annotation.tailrec
object Ordering {
-
- @tailrec
- def transitiveClosure[T](ordering: Set[(T, T)]) : Set[(T, T)] = {
- def step[T](ordering: Set[(T, T)]) = {
- val newOrdering = scala.collection.mutable.Set[(T, T)]()
- newOrdering ++= ordering
+ def transitiveClosure[T](nodes: Seq[T], hasPath: (T,T) => Boolean) : Set[(T,T)] = {
+ val ordering = scala.collection.mutable.Set[(T, T)]()
+ ordering ++= { for(n1 <- nodes; n2 <- nodes; if hasPath(n1, n2)) yield (n1 -> n2) }
- for ((a1,a2) <- ordering; (b1, b2) <- ordering; if a2 == b1)
- newOrdering += (a1 -> b2)
+ for(via <- nodes; start <- nodes; end <- nodes)
+ if (!ordering.contains(start -> end) && ordering.contains(start -> via) && ordering.contains(via -> end))
+ ordering += (start -> end)
- assert(newOrdering.size >= ordering.size)
- newOrdering.toSet
- }
-
- val stepped = step(ordering)
-
- if (stepped.size == ordering.size)
- ordering
- else
- transitiveClosure(stepped)
+ ordering.toSet
}
}