[English]

Finite Set

Version: 0.56.27 (2002.03.11)

Author: 原信一郎 (sinara@blade.nagaokaut.ac.jp)

これは集合と写像を表現する Ruby のライブラリです。

これは "Algebra" ライブラリの一部分として作成されました。

1. インストール

lib/*.rb を Ruby がロード可能なディレクトリにコピーしてください。

2. 使い方

集合を作るには Set[] を使います。返り値は Set オブジェクトであり、 集合の結び、交わり等基本的な演算が使えるようになります。eql? で等しい 要素は 1 つに数えられます。要素を表示させたときの要素の順番は不定です。 また、写像を作るには Map[] を使います。

例:
  require "finite-set"
  include Algebra
  s = Set[3, 0, 1, 2, 3]
  p s #=> {0, 1, 2, 3}

  t = Set[2, 3, 4, 5]
  p s & t #=> {2, 3}
  p s | t #=> {5, 0, 1, 2, 3, 4}

  require "finite-map"
  m = Map[0 => 10, 1 => 11, 2 => 21, 3 => 31]
  p m.image(s) #=> {10, 31, 21, 11}

3. 使用上の注意

Set, Map 共に処理の高速化のためにデータを Hash オブジェクトとして 保持しています。したがって、要素の同一性は(== でなく)eql? で行わ れます。そして、ユーザーが定義したクラスのインスタンスを要素に するには、eql?hash メソッドを、目的に合うように 定義しなおさなければなりません。特に

a.eql?(b) が真の時、必ず a.hash == b.hash が成り立つ

ように、eql?hash を定義しておく必要があります。 次は2次元ベクトルのクラスの例です。

例:
  class Vector
    attr_accessor :x, :y
    def initialize(x, y)
      @x, @y = x, y
    end
    def eql?(other)
      @x == other.x and @y == other.y
    end
    alias == eql?
    def hash
      @x.hash ^ @y.hash
    end
    def inspect
      "[#{@x.inspect}, #{@y.inspect}]"
    end
  end
  v0, v1 = Vector.new(0, 1), Vector.new(1, 2)
  s = Set[v0, v1]
  p s.has? Vector.new(0, 1) #=> true

ただし、組み込みのクラスに対してはすでに eql?hash は適切に定義済みです。

たとえ組み込みクラスのインスタンスが要素であっても、インスタンスの 状態が変化すると、集合から取り出すことができなくなります。 この障害は Set#rehash により回復できます。

例
  a = [0, 1]
  b = [1, 2]
  s = Set[a, b]
  a[0] = 10
  p s #=> {[1, 2], [10, 1]}
  p s.has? [10, 1] #=> false
  s.rehash
  p s.has? [10, 1] #=> true

4. マニュアル