Module: AIA::ToolFilter::WordNetExpander

Defined in:
lib/aia/tool_filter/wordnet_expander.rb

Constant Summary collapse

MIN_WORD_LENGTH =
4

Class Method Summary collapse

Class Method Details

.available?Boolean

Returns true if the wn executable is on PATH. Result is cached for the process lifetime.

Returns:

  • (Boolean)


31
32
33
34
35
36
# File 'lib/aia/tool_filter/wordnet_expander.rb', line 31

def available?
  @available_mutex.synchronize do
    return @available unless @available.nil?
    @available = system("which wn", out: File::NULL, err: File::NULL) ? true : false
  end
end

.clear_cache!Object

Wipe the in-process synonym cache. Used between tests.



79
80
81
# File 'lib/aia/tool_filter/wordnet_expander.rb', line 79

def clear_cache!
  @cache_mutex.synchronize { @cache.clear }
end

.expand(text) ⇒ String

Expand text by appending synonyms for each content word. Returns the original text unchanged if wn is unavailable.

Parameters:

  • text (String)

    raw tool description text

Returns:

  • (String)

    original text plus appended synonym terms



43
44
45
46
47
48
49
50
51
52
# File 'lib/aia/tool_filter/wordnet_expander.rb', line 43

def expand(text)
  return text unless available?

  words     = text.downcase.scan(/[a-z]{#{MIN_WORD_LENGTH},}/).uniq
  new_terms = words.flat_map { |w| synonyms_for(w) }
                   .uniq
                   .reject { |w| words.include?(w) }

  new_terms.empty? ? text : "#{text} #{new_terms.join(' ')}"
end

.reset_for_testing!Object

Reset all cached state. Used in test teardowns.



84
85
86
87
# File 'lib/aia/tool_filter/wordnet_expander.rb', line 84

def reset_for_testing!
  @available_mutex.synchronize { @available = nil }
  @cache_mutex.synchronize { @cache.clear }
end

.synonyms_for(word) ⇒ Array<String>

Return synonyms for a single word from WordNet (nouns + verbs). Does not include the word itself. Returns [] if not found. Results are cached per-word for the process lifetime.

Parameters:

  • word (String)

    lowercase word to look up

Returns:

  • (Array<String>)

    synonym strings, single-word only



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/aia/tool_filter/wordnet_expander.rb', line 60

def synonyms_for(word)
  # fast path: already cached
  @cache_mutex.synchronize { return @cache[word] if @cache.key?(word) }

  syns = (query_wn(word, 'n') + query_wn(word, 'v'))
         .uniq
         .reject { |w| w == word }

  # write path: first writer wins; read-back in same lock so clear_cache!
  # between write and read cannot cause nil to escape
  @cache_mutex.synchronize do
    @cache[word] = syns unless @cache.key?(word)
    @cache[word]
  end
rescue StandardError
  []
end