class Markovian::Chain

Attributes

one_key_dictionary[R]

for equality checking

two_key_dictionary[R]

for equality checking

Public Class Methods

new() click to toggle source
# File lib/markovian/chain.rb, line 8
def initialize
  @one_key_dictionary = Dictionary.new
  @two_key_dictionary = Dictionary.new
end

Public Instance Methods

==(other) click to toggle source
# File lib/markovian/chain.rb, line 33
def ==(other)
  self.one_key_dictionary == other.one_key_dictionary &&
    self.two_key_dictionary == other.two_key_dictionary
end
lengthen(word, next_word:, previous_word: nil) click to toggle source
# File lib/markovian/chain.rb, line 19
def lengthen(word, next_word:, previous_word: nil)
  push(tokeneyes(word), tokeneyes(next_word), tokeneyes(previous_word))
end
next_word(word, previous_word: nil) click to toggle source
# File lib/markovian/chain.rb, line 23
def next_word(word, previous_word: nil)
  if dictionary_entry = entry(word, previous_word)
    dictionary_entry.next_word
  end
end
random_word() click to toggle source
# File lib/markovian/chain.rb, line 29
def random_word
  one_key_dictionary.random_word
end
word_entry(word) click to toggle source

Allow access to a word’s metadata by providing its dictionary entry. For now, we only do individual words, not two-word phrases.

# File lib/markovian/chain.rb, line 15
def word_entry(word)
  @one_key_dictionary[word]
end

Protected Instance Methods

entry(word, previous_word = nil) click to toggle source
# File lib/markovian/chain.rb, line 49
def entry(word, previous_word = nil)
  if previous_word
    entry_for_two_words(previous_word, word) || entry_for_one_word(word)
  else
    entry_for_one_word(word)
  end
end
entry_for_one_word(word) click to toggle source
# File lib/markovian/chain.rb, line 61
def entry_for_one_word(word)
  # Not strictly necessary, since if there's an empty entry here we'll just get nils, but better to
  # do it right.
  entry_if_present(@one_key_dictionary[word])
end
entry_for_two_words(previous_word, word) click to toggle source
# File lib/markovian/chain.rb, line 57
def entry_for_two_words(previous_word, word)
  entry_if_present(@two_key_dictionary[two_word_key(previous_word, word)])
end
entry_if_present(entry) click to toggle source
# File lib/markovian/chain.rb, line 67
def entry_if_present(entry)
  # Ignore empty entries that haven't actually been seen in the corpus
  # TODO refactor to not even create them
  entry if entry.occurrences > 0
end
push(word, next_word, previous_word) click to toggle source
# File lib/markovian/chain.rb, line 40
def push(word, next_word, previous_word)
  write_to_dictionary(@one_key_dictionary, word, word, next_word)
  write_to_dictionary(@two_key_dictionary, two_word_key(previous_word, word), word, next_word)
  word
end
tokeneyes(word) click to toggle source

Allow strings to be passed in natively. There won’t be metadata, but for small things this makes the gem much easier to use.

# File lib/markovian/chain.rb, line 86
def tokeneyes(word)
  return nil unless word

  if word.is_a?(Tokeneyes::Word)
    word
  else
    Tokeneyes::Word.new(word)
  end
end
two_word_key(word1, word2) click to toggle source

We represent the two words as a space-delimited phrase for simplicity and speed of access via hash keys.

# File lib/markovian/chain.rb, line 75
def two_word_key(word1, word2)
  "#{word1} #{word2}"
end
write_to_dictionary(dictionary, key, word_instance, next_word) click to toggle source
# File lib/markovian/chain.rb, line 79
def write_to_dictionary(dictionary, key, word_instance, next_word)
  dictionary[key].record_observance(word_instance)
  dictionary[key].push(next_word)
end