Class: Bparity::Formal::ValueEnumerator

Inherits:
Object
  • Object
show all
Defined in:
lib/bparity/formal/bounded.rb

Instance Method Summary collapse

Constructor Details

#initialize(size:, depth:, alphabet: %w[a b],, observed: [], limit: nil) ⇒ ValueEnumerator

Returns a new instance of ValueEnumerator.



18
19
20
21
22
23
24
# File 'lib/bparity/formal/bounded.rb', line 18

def initialize(size:, depth:, alphabet: %w[a b], observed: [], limit: nil)
  @size = size
  @depth = depth
  @alphabet = alphabet
  @observed = observed
  @limit = limit
end

Instance Method Details

#arrays(element_type) ⇒ Object



44
45
46
47
48
49
50
51
# File 'lib/bparity/formal/bounded.rb', line 44

def arrays(element_type)
  return [[]] if @depth.zero?

  elements = values(element_type)
  Enumerator.new do |items|
    (0..@size).each { |length| elements.repeated_permutation(length) { |value| items << value } }
  end
end

#hashes(key_type, value_type) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/bparity/formal/bounded.rb', line 53

def hashes(key_type, value_type)
  return [{}] if @depth.zero?

  pairs = []
  values(key_type).product(values(value_type)) do |pair|
    pairs << pair
    break if @limit && pairs.length >= @limit
  end
  Enumerator.new do |results|
    results << {}
    (1..@size).each do |length|
      pairs.combination(length) do |items|
        hash = items.to_h
        results << hash if hash.length == length
      end
    end
  end
end

#values(type) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/bparity/formal/bounded.rb', line 26

def values(type)
  generated = case type.to_s
              when "Integer" then integers
              when "String" then strings
              when "Symbol" then (@observed.grep(Symbol) + @alphabet.map(&:to_sym)).uniq
              when "Array" then arrays(inferred_array_type)
              when "Hash" then hashes(*inferred_hash_types)
              when "NilClass", "nil" then [nil]
              when "TrueClass", "FalseClass", "Boolean" then [false, true]
              else return user_structures(type)
              end
  klass = constant_class(type)
  bounded(Enumerator.new do |items|
    generated.each { |value| items << value }
    @observed.grep(klass).each { |value| items << value } if klass
  end)
end