=begin
[((<English|URL:../doc/index.html>))]
= 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|)) を定義しておく必要があります。
次は２次元ベクトルのクラスの例です。

  例:
    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. マニュアル
   * ((<Algebra::Set|URL:finite-set-ja.html>)) (集合)
   * ((<Algebra::Map|URL:finite-map-ja.html>)) (写像)
=end
