next up previous
Next: Dictionnaires Up: Spécifications des principaux types Previous: Relations

Séquences

TYPE sequence{t: type}
  INHERIT equality{sequence{t}}
  INHERIT total_order{sequence{t}}
  IMPORT Subtype FROM type
  EXPORT prefix suffix sorted distinct permutation frequency
    -- Generated by {empty, add}.

  MESSAGE empty
    -- Literal [ ] = empty.
    REPLY(s: sequence{t})

  MESSAGE add(x: t, s1: sequence{t})
    -- Literal [x] = add(x, empty).
    -- Literal [x, $s] = add(x, s).
    REPLY(s2: sequence{t})

  MESSAGE remove(x: t, s1: sequence{t})
    -- Remove all instances of x from s.
    REPLY(s2: sequence{t})
    WHERE ALL(x: t :: remove(x, empty) = empty),
      ALL(x: t, s: sequence{t} ::
          remove(x, add(x, s)) = remove(x, s) ),
      ALL(x y: t, s: sequence{t} SUCH THAT x ~= y
          :: remove(x, add(y, s)) = add(y, remove(x, s)) )

  MESSAGE "||"(s1 s2: sequence{t})  -- Concatenation.
    -- Literal [$s1, $s2] = s1 || s2.
    REPLY(s2: sequence{t})
    WHERE ALL(s: sequence{t} :: empty || s = s),
      ALL(x: t, s1 s2: sequence{t} ::
          add(x, s1) || s2 = add(x, s1 || s2) )

  MESSAGE "["(s: sequence{t}, n: nat)
    -- Indexing, "["(a, b) is written a[b].
    WHEN 1 <= n <= length(s)
      REPLY(x: t)
      WHERE ALL(x: t, s: sequence{t} :: add(x, s)[1] = x),
        ALL(n: nat, x: t, s: sequence{t} SUCH THAT n > 1
          :: add(x, s)[n] = s[n - 1] )
    OTHERWISE REPLY EXCEPTION bounds_error

  MESSAGE "["(s1: sequence{t}, s2: sequence{nat})
    -- Indirect indexing.
    -- Subrange is a special case:
    -- s[1 .. 3] is the same as s[[1, 2, 3]].
    WHEN ALL(n: nat SUCH THAT n IN s2 :: n IN domain(s1))
      REPLY(s3: sequence{t})
      WHERE length(s3) = length(s2),
        ALL(n: nat SUCH THAT n IN domain(s2) ::
            s3[n] = s1[s2[n]] )
    OTHERWISE REPLY EXCEPTION bounds_error

  MESSAGE length(s: sequence{t})
    REPLY(n: nat)
    WHERE length(empty) = 0,
      ALL(x: t, s: sequence{t} ::
          length(add(x, s)) = length(s) + 1 )

  MESSAGE domain(s: sequence{t})
    REPLY(d: set{nat})
    WHERE d = {1 .. length(s)}

  MESSAGE "IN"(x: t, s: sequence{t})
    -- "IN"(x, s) is written x IN s.
    REPLY(b: boolean)
    WHERE b <=> SOME(n: nat SUCH THAT n IN domain(s) :: s[n] = x)

  MESSAGE "IN"(s1 s2: sequence{t})
    REPLY(b: boolean)
    WHERE b <=> SOME(x y: sequence{t} :: x || s1 || y = s2)

  MESSAGE equal(s1 s2: sequence{t})
    REPLY(b: boolean)
    WHERE b <=> ALL(n: nat :: s1[n] = s2[n])

  MESSAGE "<"(s1 s2: sequence{t})
    -- Lexicographic ordering (dictionary ordering on strings).
    WHEN Has_operation{t, t, boolean}(t, "<") &
         Partial_ordering("<"@t)
      REPLY(b: boolean)
      WHERE ALL(s: sequence{t}, x: t :: [ ] < [x, $s]),
        ALL(s1 s2: sequence{t}, x1 x2: t
           :: [x1, $s1] < [x2, $s2] <=>
              x1 < x2 | x1 = x2 & s1 < s2 )
    OTHERWISE REPLY EXCEPTION operation_not_applicable

  MESSAGE subsequence(s1 s2: sequence{t})
    REPLY(b: boolean)
    -- True if the elements of s1 are embedded in s2,
    -- in the same order.
    WHERE ALL(s: sequence{t} :: subsequence([ ], s)),
      ALL(s1 s2: sequence{t}, x: t :: subsequence([x, $s1], s2)
              <=> SOME(s3 s4: sequence{t}
                       :: s2 = [$s3, x, $s4] &
                          subsequence(s1, s4) )),
      Partial_ordering(subsequence)

  MESSAGE ".."(x1 x2: t)  -- ".."(x1, x2)" is written [x1 .. x2].
    WHEN Subtype(t, total_order)
      REPLY(s: sequence{t})
      WHERE sorted{"<"@t}(s),
            ALL(x: t :: x IN s <=> x1 <= x <= x2)
    OTHERWISE REPLY EXCEPTION operation_not_applicable

  MESSAGE apply{rt: type}(f: function{t, rt}, s1: sequence{t})
    REPLY(s2: sequence{rt})
    WHERE length(s2) = length(s1),
      ALL(n: nat SUCH THAT n IN domain(s1) :: s2[n] = f(s1[n]))

  MESSAGE reduce{f: function{t, t, t}, identity: t SUCH THAT
                 ALL(y: t :: f(y, identity) = y) }
            (s: sequence{t})
      REPLY(x: t)
      WHERE IF s = [ ] THEN x = identity
            ELSE x = f(s[1], reduce{f}(s[2 .. length(s)])) FI

  MESSAGE reduce1{f: function{t, t, t}} (s: sequence{t})
      WHEN length(s) > 1 REPLY(x: t)
        WHERE x = f(s[1], reduce1{f}(s[2 .. length(s)]))
      WHEN length(s) = 1 REPLY(x: t) WHERE x = s[1]
      OTHERWISE REPLY EXCEPTION empty_reduction_undefined

  MESSAGE scan(s: sequence{t})
    GENERATE(s1: sequence{t}) WHERE s1 = s

  CONCEPT prefix(s1 s2: sequence{t})
    VALUE(b: boolean)
    -- True if s1 is a prefix of s2.
    WHERE b <=> SOME(s: sequence{t} :: s1 || s = s2)

  CONCEPT suffix(s1 s2: sequence{t})
    VALUE(b: boolean)
    -- True if s1 is a suffix of s2.
    WHERE b <=> SOME(s: sequence{t} :: s || s1 = s2)

  CONCEPT sorted{le: function{t, t, boolean} SUCH THAT
                 Total_ordering(le) }
            (s: sequence{t})
    VALUE(b: boolean)
    -- True if s is sorted in nondecreasing order
    -- with respect to le.
    WHERE b <=> ALL(n1 n2: nat SUCH THAT
                    1 <= n1 < n2 <= length(s) ::
                    le(s[n1], s[n2]) )

  CONCEPT distinct(s: sequence{t})
    VALUE(b: boolean)
    -- True if there are no repeated elements in s.
    WHERE b <=> ALL(n1 n2: nat SUCH THAT
                    1 <= n1 < n2 <= length(s) ::
                    s[n1] ~= s[n2] )

  CONCEPT permutation(s1 s2: sequence{t})
    VALUE(b: boolean)
    -- True is s1 is a permutation of s2.
    WHERE b <=> ALL(x: t :: frequency(x, s1) = frequency(x, s2))

  CONCEPT frequency(x: t, s: sequence{t})
    VALUE(n: nat)
    -- The number of times x appears as an element of s.
    WHERE n = NUMBER(k: nat SUCH THAT s[k] = x :: k)
END



Tremblay Guy
2/4/1999