src/Pure/General/multi_map.scala
author wenzelm
Thu, 20 Feb 2014 14:36:17 +0100
changeset 55618 995162143ef4
parent 55488 60c159d490a2
child 56744 0b74d1df4b8e
permissions -rw-r--r--
tuned imports;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52975
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/General/multi_map.scala
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     2
    Module:     PIDE
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     3
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     4
Maps with multiple entries per key.
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     5
*/
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     6
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     7
package isabelle
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     8
55618
995162143ef4 tuned imports;
wenzelm
parents: 55488
diff changeset
     9
52975
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    10
import scala.collection.generic.{ImmutableMapFactory, CanBuildFrom}
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    11
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    12
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    13
object Multi_Map extends ImmutableMapFactory[Multi_Map]
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    14
{
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    15
  private val empty_val: Multi_Map[Any, Nothing] = new Multi_Map[Any, Nothing](Map.empty)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    16
  override def empty[A, B] = empty_val.asInstanceOf[Multi_Map[A, B]]
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    17
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    18
  implicit def canBuildFrom[A, B]: CanBuildFrom[Coll, (A, B), Multi_Map[A, B]] =
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    19
    new MapCanBuildFrom[A, B]
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    20
}
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    21
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    22
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    23
final class Multi_Map[A, +B] private(rep: Map[A, List[B]])
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    24
  extends scala.collection.immutable.Map[A, B]
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    25
  with scala.collection.immutable.MapLike[A, B, Multi_Map[A, B]]
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    26
{
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    27
  /* Multi_Map operations */
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    28
55488
60c159d490a2 more integrity checks of theory names vs. full node names;
wenzelm
parents: 52975
diff changeset
    29
  def iterator_list: Iterator[(A, List[B])] = rep.iterator
60c159d490a2 more integrity checks of theory names vs. full node names;
wenzelm
parents: 52975
diff changeset
    30
52975
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    31
  def get_list(a: A): List[B] = rep.getOrElse(a, Nil)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    32
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    33
  def insert[B1 >: B](a: A, b: B1): Multi_Map[A, B1] =
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    34
  {
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    35
    val bs = get_list(a)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    36
    if (bs.contains(b)) this
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    37
    else new Multi_Map(rep + (a -> (b :: bs)))
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    38
  }
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    39
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    40
  def remove[B1 >: B](a: A, b: B1): Multi_Map[A, B1] =
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    41
  {
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    42
    val bs = get_list(a)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    43
    if (bs.contains(b)) {
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    44
      bs.filterNot(_ == b) match {
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    45
        case Nil => new Multi_Map(rep - a)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    46
        case bs1 => new Multi_Map(rep + (a -> bs1))
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    47
      }
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    48
    }
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    49
    else this
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    50
  }
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    51
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    52
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    53
  /* Map operations */
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    54
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    55
  override def stringPrefix = "Multi_Map"
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    56
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    57
  override def empty = Multi_Map.empty
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    58
  override def isEmpty: Boolean = rep.isEmpty
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    59
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    60
  override def keySet: Set[A] = rep.keySet
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    61
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    62
  override def iterator: Iterator[(A, B)] =
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    63
    for ((a, bs) <- rep.iterator; b <- bs.iterator) yield (a, b)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    64
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    65
  def get(a: A): Option[B] = get_list(a).headOption
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    66
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    67
  def + [B1 >: B](p: (A, B1)): Multi_Map[A, B1] = insert(p._1, p._2)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    68
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    69
  def - (a: A): Multi_Map[A, B] =
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    70
    if (rep.isDefinedAt(a)) new Multi_Map(rep - a) else this
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    71
}