Class: I8::Surjection

Inherits:
Object show all
Includes:
Hamster::Immutable
Defined in:
lib/nrser/labs/i8/surjection.rb

Overview

Definitions

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pairs = {}) ⇒ Surjection

Construction



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/nrser/labs/i8/surjection.rb', line 54

def initialize pairs = {}
  @hash = I8::Hash[
    pairs.each_with_object( {} ) { |(keys, value), hash|
      set = I8::Set.new keys
      if hash.key? value
        hash[value] |= set
      else
        hash[value] = set
      end
    }
  ]

  @hash.values.combination( 2 ).each do |a, b|
    ( a & b ).unless( :empty? ) { |intersection|
      raise NRSER::ConflictError.new \
        "Sets", a, "and", b, "are not disjoint, sharing", intersection
    }
  end
end

Class Method Details

.[](pairs = {}) ⇒ Object

Class Methods



41
42
43
# File 'lib/nrser/labs/i8/surjection.rb', line 41

def self.[] pairs = {}
  new pairs
end

.alloc(hash) ⇒ Object



46
47
48
# File 'lib/nrser/labs/i8/surjection.rb', line 46

def self.alloc hash
  allocate.tap { |instance| instance.instance_variable_set :@hash, hash }
end

Instance Method Details

#[](key) ⇒ Object

See Also:



88
# File 'lib/nrser/labs/i8/surjection.rb', line 88

def []  key;  call key; end

#call(arg) ⇒ Object

Instance Methods



78
79
80
81
# File 'lib/nrser/labs/i8/surjection.rb', line 78

def call arg
  @hash.each { |value, set| return value if set.include?( arg ) }
  nil
end

#codomainI8::Set

The codomain of the surjection (or “values” in Ruby-Hash-y lingo).

Returns:



157
158
159
# File 'lib/nrser/labs/i8/surjection.rb', line 157

def codomain
  I8::Set.new @hash.keys
end

#domainI8::Set

The domain of the surjection (or “keys” in Ruby-Hash-y lingo).

Returns:



126
127
128
# File 'lib/nrser/labs/i8/surjection.rb', line 126

def domain
  @hash.each_value.reduce I8::Set.empty, :|
end

#get(key) ⇒ Object

See Also:



86
# File 'lib/nrser/labs/i8/surjection.rb', line 86

def get key;  call key; end

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)

See Also:



146
# File 'lib/nrser/labs/i8/surjection.rb', line 146

def has_key?  key; key? key; end

#has_value?(value) ⇒ Boolean

Returns:

  • (Boolean)

See Also:



179
# File 'lib/nrser/labs/i8/surjection.rb', line 179

def has_value? value; value? value; end

#include?(key) ⇒ Boolean

Returns:

  • (Boolean)

See Also:



148
# File 'lib/nrser/labs/i8/surjection.rb', line 148

def include?  key; key? key; end

#inspectObject



182
183
184
# File 'lib/nrser/labs/i8/surjection.rb', line 182

def inspect
  to_s_with :inspect
end

#key?(key) ⇒ Boolean

The Ruby-Hash-y way of finding out if an object is in the #domain.

Functionally the same as ‘surjection.domain.include? obj`.

Parameters:

Returns:

  • (Boolean)


138
139
140
141
# File 'lib/nrser/labs/i8/surjection.rb', line 138

def key? key
  # domain.include? key
  @hash.each_value.any? { |key_set| key_set.include? key }
end

#member?(key) ⇒ Boolean

Returns:

  • (Boolean)

See Also:



150
# File 'lib/nrser/labs/i8/surjection.rb', line 150

def member?   key; key? key; end

#put(arg, value) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/nrser/labs/i8/surjection.rb', line 91

def put arg, value
  if domain.include?( arg ) && call( arg ) != value
    raise NRSER::ConflictError.new "Already mapping", arg, "to", call( arg )
  end

  if value? value
    # We already have a set of keys mapping to the value
    if @hash[value].include? arg
      # And it already has the key, so we can just return this instance
      self
    else
      # The key set we have for the value does not have the key in it.
      # 
      # We need to 
      # 
      # 1.  Create a new hash with the key in the value's key set.
      # 2.  Allocate a new surjection.
      # 3.  set that as it's hash.
      # 
      self.class.alloc @hash.put( value ) { |set| set.add arg }
    end
  else
    # We don't have a set of keys for that value
    self.class.alloc @hash.put( value, I8::Set[ arg ] )
  end
end

#store(*args, &block) ⇒ Object

The standard aliases (as methods for easy subclass overrides)



119
# File 'lib/nrser/labs/i8/surjection.rb', line 119

def store *args, █ put *args, █ end

#to_sObject



187
188
189
# File 'lib/nrser/labs/i8/surjection.rb', line 187

def to_s
  to_s_with :to_s
end

#value?(value) ⇒ Boolean

Is ‘value` in the surjection’s #codomain?

Parameters:

Returns:

  • (Boolean)


172
173
174
# File 'lib/nrser/labs/i8/surjection.rb', line 172

def value? value
  @hash.key? value
end

#valuesObject

See Also:



164
# File 'lib/nrser/labs/i8/surjection.rb', line 164

def values; codomain; end