From 4a0461c34f1bbde528294fda32ffbe1f58c99107 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 30 Oct 2010 11:54:43 -0400 Subject: [PATCH] minor updates to utilities --- util/collection/Relation.scala | 50 +++++++++++++++++------------ util/collection/TypeFunctions.scala | 6 ++-- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/util/collection/Relation.scala b/util/collection/Relation.scala index a282bf7e2..b305bb47c 100644 --- a/util/collection/Relation.scala +++ b/util/collection/Relation.scala @@ -3,12 +3,40 @@ */ package sbt + import Relation._ + object Relation { /** Constructs a new immutable, finite relation that is initially empty. */ def empty[A,B]: Relation[A,B] = make(Map.empty, Map.empty) def make[A,B](forward: Map[A,Set[B]], reverse: Map[B, Set[A]]): Relation[A,B] = new MRelation(forward, reverse) + def reconstruct[A,B](forward: Map[A, Set[B]]): Relation[A,B] = + { + val reversePairs = for( (a,bs) <- forward.view; b <- bs.view) yield (b, a) + val reverse = (Map.empty[B,Set[A]] /: reversePairs) { case (m, (b, a)) => add(m, b, a :: Nil) } + make(forward, reverse) + } + + + private[sbt] def remove[X,Y](map: M[X,Y], from: X, to: Y): M[X,Y] = + map.get(from) match { + case Some(tos) => + val newSet = tos - to + if(newSet.isEmpty) map - from else map.updated(from, newSet) + case None => map + } + + private[sbt] def combine[X,Y](a: M[X,Y], b: M[X,Y]): M[X,Y] = + (a /: b) { (map, mapping) => add(map, mapping._1, mapping._2) } + + private[sbt] def add[X,Y](map: M[X,Y], from: X, to: Iterable[Y]): M[X,Y] = + map.updated(from, get(map, from) ++ to) + + private[sbt] def get[X,Y](map: M[X,Y], t: X): Set[Y] = map.getOrElse(t, Set.empty[Y]) + + private[sbt] type M[X,Y] = Map[X, Set[Y]] } + /** Binary relation between A and B. It is a set of pairs (_1, _2) for _1 in A, _2 in B. */ trait Relation[A,B] { @@ -49,8 +77,6 @@ trait Relation[A,B] } private final class MRelation[A,B](fwd: Map[A, Set[B]], rev: Map[B, Set[A]]) extends Relation[A,B] { - type M[X,Y] = Map[X, Set[Y]] - def forwardMap = fwd def reverseMap = rev @@ -65,9 +91,9 @@ private final class MRelation[A,B](fwd: Map[A, Set[B]], rev: Map[B, Set[A]]) ext def all: Traversable[(A,B)] = fwd.iterator.flatMap { case (a, bs) => bs.iterator.map( b => (a,b) ) }.toTraversable def +(pair: (A,B)) = this + (pair._1, Set(pair._2)) - def +(from: A, to: B) = this + (from, Set(to)) + def +(from: A, to: B) = this + (from, to :: Nil) def +(from: A, to: Iterable[B]) = - new MRelation( add(fwd, from, to), (rev /: to) { (map, t) => add(map, t, Seq(from)) }) + new MRelation( add(fwd, from, to), (rev /: to) { (map, t) => add(map, t, from :: Nil) }) def ++(rs: Iterable[(A,B)]) = ((this: Relation[A,B]) /: rs) { _ + _ } def ++(other: Relation[A,B]) = new MRelation[A,B]( combine(fwd, other.forwardMap), combine(rev, other.reverseMap) ) @@ -84,21 +110,5 @@ private final class MRelation[A,B](fwd: Map[A, Set[B]], rev: Map[B, Set[A]]) ext case None => this } - private def remove[X,Y](map: M[X,Y], from: X, to: Y): M[X,Y] = - map.get(from) match { - case Some(tos) => - val newSet = tos - to - if(newSet.isEmpty) map - from else map.updated(from, newSet) - case None => map - } - - private def combine[X,Y](a: M[X,Y], b: M[X,Y]): M[X,Y] = - (a /: b) { (map, mapping) => add(map, mapping._1, mapping._2) } - - private[this] def add[X,Y](map: M[X,Y], from: X, to: Iterable[Y]): M[X,Y] = - map.updated(from, get(map, from) ++ to) - - private[this] def get[X,Y](map: M[X,Y], t: X): Set[Y] = map.getOrElse(t, Set.empty[Y]) - override def toString = all.map { case (a,b) => a + " -> " + b }.mkString("Relation [", ", ", "]") } \ No newline at end of file diff --git a/util/collection/TypeFunctions.scala b/util/collection/TypeFunctions.scala index 92a5fb4b7..ca173f9bc 100644 --- a/util/collection/TypeFunctions.scala +++ b/util/collection/TypeFunctions.scala @@ -6,9 +6,9 @@ package sbt trait TypeFunctions { type Id[X] = X - trait Const[A] { type Apply[B] = A } - trait Compose[A[_], B[_]] { type Apply[T] = A[B[T]] } - trait P1of2[M[_,_], A] { type Apply[B] = M[A,B]; type Flip[B] = M[B, A] } + sealed trait Const[A] { type Apply[B] = A } + sealed trait Compose[A[_], B[_]] { type Apply[T] = A[B[T]] } + sealed trait P1of2[M[_,_], A] { type Apply[B] = M[A,B]; type Flip[B] = M[B, A] } final val left = new (Id ~> P1of2[Left, Nothing]#Flip) { def apply[T](t: T) = Left(t) } final val right = new (Id ~> P1of2[Right, Nothing]#Apply) { def apply[T](t: T) = Right(t) }