class Glaemscribe::API::SheafChainIterator

Attributes

cross_map[RW]
errors[RW]
prototype[R]
sheaf_chain[RW]

Public Class Methods

new(sheaf_chain, cross_schema = nil) click to toggle source

If a cross schema is passed, the prototype of the chain will be permutated

# File lib/api/sheaf_chain_iterator.rb, line 34
def initialize(sheaf_chain, cross_schema = nil)
  @sheaf_chain            = sheaf_chain
  # Sizes contains the number of fragments/sheaf
  @sizes                  = sheaf_chain.sheaves.map { |sheaf| sheaf.fragments.count }
  # An array of counters, one for each sheaf, to increment on fragments
  @iterators              = Array.new(@sizes.count,0)
    
  @errors                 = []
    
  # Construct the identity array
  identity_cross_array    = []
  sheaf_count             = sheaf_chain.sheaves.count
  sheaf_count.times { |i| identity_cross_array << i }  

  # Make a list of iterable sheaves
  iterable_idxs     = []
  prototype_array   = []
  sheaf_chain.sheaves.each_with_index { |sheaf,i| 
    if sheaf.linkable 
      iterable_idxs.push(i) 
      prototype_array.push(sheaf.fragments.count)
    end
  }

  @cross_array = identity_cross_array
  @prototype   = prototype_array.join('x')
  @prototype   = 'CONST'  if @prototype.empty?
 
  # Construct the cross array
  if cross_schema
  
    cross_schema          = cross_schema.split(",").map{ |i| i.to_i - 1 }
        
    # Verify that the number of iterables is equal to the cross schema length
    it_count              = iterable_idxs.count
    ca_count              = cross_schema.count
    @errors << "#{it_count} linkable sheaves found in right predicate, but #{ca_count} elements in cross rule." and return  if ca_count != it_count
    
    # Verify that the cross schema is correct (should be a permutation of the identity)
    it_identity_array = []
    it_count.times { |i| it_identity_array << i }     
    @errors << "Cross rule schema should be a permutation of the identity (it should contain 1,2,..,n numbers once and only once)." and return  if it_identity_array != cross_schema.sort
  
    proto_array_permutted = prototype_array.clone
    
    # Now calculate the cross array
    cross_schema.each_with_index{ |to,from|
      to_permut = iterable_idxs[from]
      permut    = iterable_idxs[to]
      @cross_array[to_permut] = permut
 
      proto_array_permutted[from] = prototype_array[to] 
    }  
    prototype_array = proto_array_permutted
  end  
  
  # Recalculate prototype
  @prototype = prototype_array.join('x')
  @prototype   = 'CONST'  if @prototype.empty?
end

Public Instance Methods

combinations() click to toggle source

Calculate all cominations for the chain, for the current iterator value

# File lib/api/sheaf_chain_iterator.rb, line 112
def combinations
  resolved = []
  @iterators.each_with_index{ |counter, index|
    sheaf     = sheaf_chain.sheaves[index]
    fragment  = sheaf.fragments[counter]
    
    resolved << fragment.combinations
  }
  res = resolved[0]
  (resolved.count-1).times { |i|
    res = res.product(resolved[i+1]).map{|e1,e2| e1+e2} 
  }
  res
end
iterate() click to toggle source
# File lib/api/sheaf_chain_iterator.rb, line 95
def iterate
  pos = 0
  while pos < @sizes.count do
    realpos = @cross_array[pos]
    @iterators[realpos] += 1
    if @iterators[realpos] >= @sizes[realpos]
      @iterators[realpos] = 0
      pos += 1
    else
      return true
    end
  end
  # Wrapped!
  return false
end