require 'lib/codon_mod' module Mapper # "Bucket rule" codon representation: # # index_of_choice = (codon / bucket) mod num_of_choices # # where # bucket(symbolX) = num_of_choices[symbol0] * num_of_choices[symbol1] ... * num_of_choices[symbolX-1] # # This grammar-dependent representation modifies the standard GE representation implemented # by Mapper::CodonMod. # With this rule, every codon encodes a unique set of producion rules, each from one nonterminal. # See: # http://books.google.com/books?id=eCbu4GwRLusC&lpg=PA123&ots=hUc3zvqYIh&lr&pg=PA123#v=onepage&q&f=false # class CodonBucket < CodonMod # Initialise a codon representation. # bit_size is the number of bits per one codon. def initialize super @bucket = nil @max_closure = nil end # Closures hash. The element c.bucket['s'] represents a modifier for all codons encoding a symbol 's'. attr_reader :bucket # Maximal value of the codon modifier. attr_reader :max_closure # Set the current grammar for codon representation. def grammar= gram @bucket = {} @max_closure = 1 gram.symbols.each do |sym| alts = gram[sym] @bucket[sym] = @max_closure @max_closure *= alts.size end end # Interpret the codon given a number of choices and a symbol ( (c/s) mod n ) def interpret( numof_choices, codon, symbol=nil ) codon = codon.divmod( @bucket[symbol] ).first unless @bucket.nil? or symbol.nil? super( numof_choices, codon ) end # Create the codon from the index of the choice, number of choices and a symbol. # See CodonMod#generate for details. def generate( numof_choices, index, symbol=nil ) codon = super( numof_choices, index ) ( @bucket.nil? or symbol.nil? ) ? codon : ( codon * @bucket[symbol] ) end # Mutate a single bit in the source codon, return the mutated codon. def mutate_bit codon return super if @bucket.nil? codon ^ (2 ** @random.rand( @bit_size + @max_closure.to_s(2).size-1 )) end # Generate a valid random codon def rand_gen return super if @bucket.nil? @random.rand( @card * @max_closure ) end # Return true if the codon is valid def valid_codon? codon return super if @bucket.nil? codon >= 0 and codon < @card*@max_closure end end end