lib/megahal/megahal.rb
# Here we take a generated sequence of norms and convert them back to a string
# that may be displayed to the user as output. This involves using the @case
# model to rewrite each norm as a word, and then using the @punc model to
# insert appropriate word separators.
Here we take a generated sequence of norms and convert them back to a string
that may be displayed to the user as output. This involves using the @case
model to rewrite each norm as a word, and then using the @punc model to
insert appropriate word separators.
Here we take a generated sequence of norms and convert them back to a string that may be displayed to the user as output . This involves using the @case model to rewrite each norm as a word and then using the @punc model to insert appropriate word separators .
def _rewrite(norm_symbols)
    decode = Hash[@dictionary.to_a.map(&:reverse)]
    word_symbols = []
    context = [1, 1]
    i = 0
    retries = 0
    while word_symbols.length != norm_symbols.length
      return nil if retries > 9
      context[0] = (i == 0) ? 1 : word_symbols[i-1]
      context[1] = norm_symbols[i]
      id = @brain[context.dup] ||= @brain.length
      count = @case.count(id)
      unless failed = (count == 0)
        limit = rand(count) + 1
        word_symbols << @case.select(id, limit)
      end
      if (word_symbols.length == norm_symbols.length)
        context[0] = word_symbols.last
        context[1] = 1
        id = @brain[context.dup] ||= @brain.length
        failed = (@punc.count(id) == 0)
      end
      if failed
        retries += 1
        word_symbols.clear
        i = 0
        next
      end
      i += 1
    end
    punc_symbols = []
    context = [1, 1]
    (word_symbols + [1]).each do |word|
      context << word
      context.shift
      id = @brain[context.dup] ||= @brain.length
      limit = rand(@punc.count(id)) + 1
      punc_symbols << @punc.select(id, limit)
    end
    punc_symbols.zip(word_symbols).flatten.map { |word| decode[word] }.join
  end
def _rewrite ( norm_symbols ) decode = Hash [ @dictionary . to_a . map ( & :reverse ) ] word_symbols = [ ] context = [ 1 , 1 ] i = 0 retries = 0 while word_symbols . length != norm_symbols . length return nil if retries > 9 context [ 0 ] = ( i == 0 ) ? 1 : word_symbols [ i - 1 ] context [ 1 ] = norm_symbols [ i ] id = @brain [ context . dup ] ||= @brain . length count = @case . count ( id ) unless failed = ( count == 0 ) limit = rand ( count ) + 1 word_symbols << @case . select ( id , limit ) end if ( word_symbols . length == norm_symbols . length ) context [ 0 ] = word_symbols . last context [ 1 ] = 1 id = @brain [ context . dup ] ||= @brain . length failed = ( @punc . count ( id ) == 0 ) end if failed retries += 1 word_symbols . clear i = 0 next end i += 1 end punc_symbols = [ ] context = [ 1 , 1 ] ( word_symbols + [ 1 ] ) . each do | word | context << word context . shift id = @brain [ context . dup ] ||= @brain . length limit = rand ( @punc . count ( id ) ) + 1 punc_symbols << @punc . select ( id , limit ) end punc_symbols . zip ( word_symbols ) . flatten . map { | word | decode [ word ] } . join end
Here we take a generated sequence of norms and convert them back to a string
that may be displayed to the user as output.
Here we take a generated sequence of norms and convert them back to a string that may be displayed to the user as output .
# Here we generate the sequence of words. This is slightly tricky, because # it is possible to generate a word (based on the context of the previous # word and the current norm) such that it is impossible to generate the next # word in the sequence (because we may generate a word of a different case # than what we have observed in the past). So we keep trying until we # stumble upon a combination that works, or until we've tried too many # times. Note that backtracking would need to go back an arbitrary number of # steps, and is therefore too messy to implement. # We're trying to rewrite norms to words, so build a context for the @case # model, of the previous word and the current norm.  This may fail if the # previous word hasn't been observed adjacent to the current norm, which # will happen if the rewrote the previous norm to a different case that # what was observed previously. # We need to check that the final word has been previously observed. # We've used the case model to rewrite the norms to a words in a way that # guarantees that each adjacent pair of words has been previously observed. # Now we use the @punc model to generate the word-separators to be inserted # between the words in the reply. # Finally we zip the word-separators and the words together, decode the # symbols to their string representations (as stored in the @dictionary), # and join everything together to give the final reply.
norm_symbols