src/Pure/General/multi_map.scala
author blanchet
Wed, 24 Sep 2014 15:45:55 +0200
changeset 58425 246985c6b20b
parent 56744 0b74d1df4b8e
child 59073 dcecfcc56dce
permissions -rw-r--r--
simpler proof
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
56744
0b74d1df4b8e tuned headers;
wenzelm
parents: 55618
diff changeset
     3
    Author:     Makarius
52975
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     4
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     5
Maps with multiple entries per key.
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
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     8
package isabelle
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
     9
55618
995162143ef4 tuned imports;
wenzelm
parents: 55488
diff changeset
    10
52975
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    11
import scala.collection.generic.{ImmutableMapFactory, CanBuildFrom}
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
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    14
object Multi_Map extends ImmutableMapFactory[Multi_Map]
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    15
{
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    16
  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
    17
  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
    18
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    19
  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
    20
    new MapCanBuildFrom[A, B]
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
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    24
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
    25
  extends scala.collection.immutable.Map[A, B]
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    26
  with scala.collection.immutable.MapLike[A, B, Multi_Map[A, B]]
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    27
{
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    28
  /* Multi_Map operations */
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    29
55488
60c159d490a2 more integrity checks of theory names vs. full node names;
wenzelm
parents: 52975
diff changeset
    30
  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
    31
52975
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    32
  def get_list(a: A): List[B] = rep.getOrElse(a, Nil)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    33
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    34
  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
    35
  {
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    36
    val bs = get_list(a)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    37
    if (bs.contains(b)) this
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    38
    else new Multi_Map(rep + (a -> (b :: bs)))
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
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    41
  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
    42
  {
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    43
    val bs = get_list(a)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    44
    if (bs.contains(b)) {
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    45
      bs.filterNot(_ == b) match {
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    46
        case Nil => new Multi_Map(rep - a)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    47
        case bs1 => new Multi_Map(rep + (a -> bs1))
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
    }
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    50
    else this
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
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    54
  /* Map operations */
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    55
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    56
  override def stringPrefix = "Multi_Map"
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    57
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    58
  override def empty = Multi_Map.empty
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    59
  override def isEmpty: Boolean = rep.isEmpty
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    60
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    61
  override def keySet: Set[A] = rep.keySet
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    62
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    63
  override def iterator: Iterator[(A, B)] =
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    64
    for ((a, bs) <- rep.iterator; b <- bs.iterator) yield (a, b)
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    65
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    66
  def get(a: A): Option[B] = get_list(a).headOption
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    67
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    68
  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
    69
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    70
  def - (a: A): Multi_Map[A, B] =
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    71
    if (rep.isDefinedAt(a)) new Multi_Map(rep - a) else this
457c006f91bb support for maps with multiple entries per key;
wenzelm
parents:
diff changeset
    72
}