next up previous
Next: Tuples Up: Spécifications des principaux types Previous: Séquences

Dictionnaires

TYPE map {key result: type SUCH THAT Subtype(key, equality{t})}
    -- The domain of the map must have an equality operation
    -- with the standard interpretation.

INHERIT partial_order{map{key, result}}
IMPORT Subtype FROM type
IMPORT distinct FROM sequence{pair}

MODEL(default: result, pairs: set{pair})
INVARIANT ALL(m: map{key, result} :: single_valued(m.pairs)),
  ALL(m: map{key, result}, p: pair SUCH THAT
      p IN m.pairs :: p.y ~= default )

  MESSAGE create(v: result)
    REPLY(m: map{key, result})
      WHERE m.default = v, m.pairs = { }
      -- m[x] = v for all x.

  MESSAGE bind(x: key, y: result, m: map{key, result})
    REPLY(mm: map{key, result})
      WHERE mm[x] = y, mm.default = m.default,
        ALL(z: key SUCH THAT z ~= x :: mm[z] = m[z])

  MESSAGE remove(x: key, m: map{key, result})
    REPLY(mm: map{key, result})
      WHERE mm[x] = m.default, mm.default = m.default,
        ALL(z: key SUCH THAT z ~= x :: mm[z] = m[z])

  MESSAGE remove(s: set{key}, m: map{key, result})
    REPLY(mm: map{key, result})
      WHERE ALL(x: key :: IF x IN s THEN mm[x] = m.default
                          ELSE mm[x] = m[x] FI ),
        mm.default = m.default

  MESSAGE extend(m1 m2: map{key, result})
    REPLY(m3: map{key, result})
      WHERE ALL(x: key :: IF x IN m1 THEN m3[x] = m1.default
                          ELSE IF x IN m2 THEN m3[x] = m2[x]
                          ELSE m3[x] = m1.default FI ),
        m3.default = m1.default

  MESSAGE "["(m: map{key, result}, x: key)
    -- "["(m, x) is written m[x].
    REPLY(y: result)
      WHERE IF x IN m
            THEN SOME(p: pair :: p IN m.pairs &
                                 p.x = x & p.y = y )
            ELSE y = m.default FI

  MESSAGE "IN"(x: key, m: map{key, result}) REPLY(b: boolean)
    WHERE b <=> x IN domain(m)
    -- b <=> m[x] ~= m.default.

  MESSAGE equal(m1 m2: map{key, result})
    REPLY(b: boolean)
      WHERE b <=> ALL(x: key :: m1[x] = m2[x])

  MESSAGE "<="(m1 m2: map{key, result})
    REPLY(b: boolean)
      WHERE b <=> subset(m1.pairs, m2.pairs) &
                  m1.default = m2.default
      -- b <=> ALL(x: key :: m1[x] = m2[x] |
      --                     m1[x] = default(m2) ).

  MESSAGE domain(m: map{key, result})
    REPLY(s: set{key})
      WHERE s = SET(p: pair SUCH THAT p IN m.pairs :: p.x)
      -- s = {x | x in m}.

  MESSAGE range(m: map{key, result})
    REPLY(s: set{result})
      WHERE ALL(y: result :: y IN s <=>
                SOME(x: key :: m[x] = y) )
      -- s = {y | y = m[x] for some x},
      -- includes the default value.

  MESSAGE default(m: map{key, result})
    REPLY(y: result)
      WHERE y = m.default
      -- The default value of the map.

  MESSAGE scan(m: map{key, result})
    GENERATE(s1: sequence{pair})
    WHERE ALL(x: t :: x IN s1 <=> x IN m.pairs), distinct(s1)

  CONCEPT pair: type
    WHERE pair = tuple{x :: key, y :: result}

  CONCEPT single_valued(s: set{pair})
    VALUE(b: boolean)
    WHERE b <=> ALL(p1 p2: pair SUCH THAT p1 IN s & p2 IN s
                    :: p1.x = p2.x => p1.y = p2.y )
    -- The map associates at most one y value with each x value.
END



Tremblay Guy
2/4/1999