       else
         [c, a, b]
 
-  vertices: -> [@a, @b, @c]
-
-  toSeq: -> seq [@a, @b, @c]
+  memo @, 'vertices', -> [@a, @b, @c]
+  memo @, 'toSeq',    -> seq @vertices()
+  memo @, 'toString', -> "T(#{@a}, #{@b}, #{@c})"
+  memo @, 'hashCode', -> hashCode @toString()
 
   equals: (other) ->
     equal(@a, other.a) and equal(@b, other.b) and equal(@c, other.c)
 
-  toString: -> "T(#{@a}, #{@b}, #{@c})"
 
 # Here's a quick shortcut for the constructor.
 tri = (a, b, c) -> new Triangle a, b, c

  plus:  (p)  -> new Point2d @x + p.x, @y + p.y
  minus: (p)  -> new Point2d @x - p.x, @y - p.y
  times: (f)  -> new Point2d @x * f, @y * f
  toString:   -> "(#{@x}, #{@y})"
  equals: (p) -> @constructor == p.constructor and @x == p.x and @y == p.y


# ----

      @sites__         = args[1] || new HashSet()
      @children__      = args[2] || new HashMap()

    # The method `toSeq` returns the proper (non-virtual) triangles contained
    # in this triangulation as a lazy sequence. It does so by removing any
    # triangles from the underlying triangulation object which contain a
    # virtual vertex.
    memo @, 'toSeq', -> seq.select @triangulation__, (t) ->
      seq.forall t, (p) -> not p.isInfinite()

    # The method `third` finds the unique third vertex forming a triangle with
    # the two given ones in the given orientation, if any.
