Module: Abstractor::Methods::Models::AbstractorSubject::InstanceMethods

Included in:
AbstractorSubject
Defined in:
lib/abstractor/methods/models/abstractor_subject.rb

Instance Method Summary collapse

Instance Method Details

#abstract(about) ⇒ void

This method returns an undefined value.

Creates or finds an instance of an Abstractor::AbstractorAbstraction. The method will create instances of Abstractor::AbstractorSuggestion and Abstractor::AbstractorSuggestionSource for the abstractable entity passed via the about parameter.

The method cycles through each Abstractor::AbstractorAbstractionSource setup for the instance of the Abstractor::AbstractorSubject. The Abstractor::AbstractorSubject#abstractor_abstraction_source_type attribute determines the abstraction strategy:

  • ‘nlp suggestion’: creates instances of Abstractor::AbstractorSuggestion based on natural language processing (nlp) logic searching the text provided by the Abstractor::AbstractorSubject#from_methd attribute.

  • ‘custom suggestion’: creates instances of Abstractor::AbstractorSuggestion based on custom logic delegated to the method configured in AbstractorAbstractionSource#custom_method.

  • ‘indirect’: creates an instance of Abstractor::AbstractorIndirectSource wih null source_type, source_id, source_method attributes – all waiting to be set upon selection of an indirect source.

  • ‘custom nlp suggestion’: looks up a suggestion endpoint to submit text, object values and object value variants to an external, custom NLP provider for the delegation of suggestion generation.

Parameters:

  • about (ActiveRecord::Base)

    The entity to abstract. An instance of the class specified in the Abstractor::AbstractorSubject#subject_type attribute.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 45

def abstract(about)
  abstractor_abstraction = about.find_or_create_abstractor_abstraction(abstractor_abstraction_schema, self)

  abstractor_abstraction_sources.each do |abstractor_abstraction_source|
    case abstractor_abstraction_source.abstractor_abstraction_source_type.name
    when 'nlp suggestion'
      abstract_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
    when 'custom suggestion'
      abstract_custom_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
    when 'indirect'
      abstract_indirect_source(about, abstractor_abstraction, abstractor_abstraction_source)
    when 'custom nlp suggestion'
      abstract_custom_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
    end
  end
end

#abstract_canonical_name_value(about, abstractor_abstraction, abstractor_abstraction_source, source, parser, sentence) ⇒ Object



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 274

def abstract_canonical_name_value(about, abstractor_abstraction, abstractor_abstraction_source, source, parser, sentence)
  skip_sentinental = false
  abstractor_abstraction_schema.predicate_variants.each do |predicate_variant|
    if abstractor_abstraction_schema.abstractor_object_type && (abstractor_abstraction_schema.abstractor_object_type.number? || abstractor_abstraction_schema.abstractor_object_type.number_list?)
      object_regex = Abstractor::Enum::NUMERIC_REGEX

      match_values = ["#{Regexp.escape(predicate_variant)}:\s*#{object_regex}", "#{Regexp.escape(predicate_variant)}#{object_regex}"]
      match_values.each do |match_value|
        matches = parser.sentence_match_scan(sentence[:sentence], match_value, word_boundary: true).uniq
        if abstractor_abstraction_schema.abstractor_object_type.number_list?
          # filter matched numbers by list of available values
          abstractor_abstraction_schema.abstractor_object_values.each do |abstractor_object_value|
            abstractor_object_value.object_variants.each do |object_variant|
              matches.each do |match|
                if object_variant == match[:object_value]
                  skip_sentinental = suggest(abstractor_abstraction, abstractor_abstraction_source, match.to_s, match.to_s, source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name],  abstractor_object_value, nil, nil, nil, nil)
                end
              end
            end
          end
        else
          matches.each do |match|
            skip_sentinental = suggest(abstractor_abstraction, abstractor_abstraction_source, match.to_s, match.to_s, source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], match[:object_value], nil, nil, nil, nil)
          end
        end
      end
    else
      abstractor_abstraction_schema.abstractor_object_values.each do |abstractor_object_value|
        abstractor_object_value.object_variants.each do |object_variant|
          match_values = ["#{Regexp.escape(predicate_variant)}:\s*#{Regexp.escape(object_variant)}", "#{Regexp.escape(predicate_variant)}#{Regexp.escape(object_variant)}"]
          match_values.each do |match_value|
            matches = parser.sentence_scan(sentence[:sentence], match_value, word_boundary: true).uniq
            matches.each do |match|
              suggest(abstractor_abstraction, abstractor_abstraction_source, match, match, source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name],  abstractor_object_value, nil, nil, nil, nil)
            end
          end
        end
      end
    end
  end
  skip_sentinental
end

#abstract_custom_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void

This method returns an undefined value.

Looks up a suggestion endpoint to submit text to an external custom NLP provider for the delegation of suggestion generation.

The method will determine an endpoint by looking in config/abstractor/custom_nlp_providers.yml based on the current environment and the value of the AbstractorAbstractionSource#custom_nlp_provider attribute.

A template configratuon file can be generated in the the host application by calling the rake task abstractor:custom_nlp_provider. The configuration is expected to provide different endpoints per environment, per provider. Abstractor will format a JSON body to post to the discovered endpoint. The custom NLP provider will be expected to generate suggestions and post them back to /abstractor_abstractions/:abstractor_abstraction_id/abstractor_suggestions/

Examples:

Example of body prepared by Abstractor to submit to an custom NLP provider

{
  "abstractor_abstraction_schema_id":1,
  "abstractor_abstraction_schema_uri":"https://moomin.com/abstractor_abstraction_schemas/1",
  "abstractor_abstraction_id":1,
  "abstractor_abstraction_source_id":1,
  "source_type":  "PathologyCase",
  "source_method": "note_text",
  "text": "The patient has a diagnosis of glioblastoma.  GBM does not have a good prognosis.  But I can't rule out meningioma."
}

Parameters:

  • about (ActiveRecord::Base)

    The entity to abstract. An instance of the class specified in the Abstractor::AbstractorSubject#subject_type attribute.

  • abstractor_abstraction (Abstractor::AbstractorAbstraction)

    The instance of Abstractor::AbstractorAbstraction to make suggestions against.

  • abstractor_abstraction_source (Abstractor::AbstractorAbstractionSource)

    The instance of the Abstractor::AbstractorAbstractionSource that provides the name of the custom NLP provider.



169
170
171
172
173
174
175
176
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 169

def abstract_custom_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
  suggestion_endpoint = CustomNlpProvider.determine_suggestion_endpoint(abstractor_abstraction_source.custom_nlp_provider)
  abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source|
    abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source)
    body = Abstractor::CustomNlpProvider.format_body_for_suggestion_endpoint(abstractor_abstraction, abstractor_abstraction_source, abstractor_text, source)
    HTTParty.post(suggestion_endpoint, body: body.to_json, headers: { 'Content-Type' => 'application/json' })
  end
end

#abstract_custom_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void

This method returns an undefined value.

Creates instances of Abstractor::AbstractorSuggestion and Abstractor::AbstractorSuggestionSource based on calling the method configured by the AbstractorAbstractionSource#custom_method attribute. The method is called on the abstractable entity passed via the about parameter.

Setting up an Abstractor::AbstractorSubject with an AbstractorAbstractionSource with an AbstractorAbstractionSource#abstractor_abstraction_source_type attribute set to ‘custom suggestion’ obligates the developer to implement an instance method on the abstractable entitty to make suggestions as appropriate. The ‘custom suggestion’ source type is intended to faciliate the generation of suggestions in a customizable way. The method implemented by the developer should return an array of hashes, each has with 2 keys, like so

{ suggestion: ‘a suggestion’, explanation: ‘why i made the suggestion}

The suggestion will be presented to the user as possible answer for the abstraction. The explanation will be displayed to the user to explain how the sytem arrived at the suggestion.

Parameters:

  • about (ActiveRecord::Base)

    The entity to abstract. An instance of the class specified in the Abstractor::AbstractorSubject#subject_type attribute.

  • abstractor_abstraction (Abstractor::AbstractorAbstraction)

    The instance of Abstractor::AbstractorAbstraction to make suggestions against.

  • abstractor_abstraction_source (Abstractor::AbstractorAbstractionSource)

    The instance of the Abstractor::AbstractorAbstractionSource that provides the custom method to invoke on the abstractable entity to make custom suggestions.



133
134
135
136
137
138
139
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 133

def abstract_custom_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
  suggestions = about.send(abstractor_abstraction_source.custom_method, abstractor_abstraction)
  suggestions.each do |suggestion|
    suggest(abstractor_abstraction, abstractor_abstraction_source, nil, nil, about.id, about.class.to_s, abstractor_abstraction_source.from_method, abstractor_abstraction_source.section_name, suggestion[:suggestion], nil, nil, abstractor_abstraction_source.custom_method, suggestion[:explanation])
  end
  create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
end

#abstract_indirect_source(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void

This method returns an undefined value.

Creates an instance of Abstractor::AbstractorIndirectSource – if one does not already exist – for the abstractor_abstraction and abstraction_source parameters. An ‘indirect’ Abstractor::AbstractorAbstractionSources give developers the ability to define a pool of documents that are indrectly related to an abstraction. The developer is responsible for implementing a method on the abstractable enttiy specified in Abstractor::AbstractorAbstractionSource#from_method. The method should return a hash with the following keys populated:

  • Array <ActiveRecord::Base>

    :sources An array of active record objects that constitute the list of indirect sources.

  • Symbol

    :source_id A method specifying the primary key of each member in sources.

  • Symbol

    :source_method A method specifying the source text of each member in sources.

Parameters:

  • about (ActiveRecord::Base)

    The entity to abstract. An instance of the class specified in the Abstractor::AbstractorSubject#subject_type attribute.

  • abstractor_abstraction (Abstractor::AbstractorAbstraction)

    The instance of Abstractor::AbstractorAbstraction to insert an indirect source.

  • abstractor_abstraction_source (Abstractor::AbstractorAbstractionSource)

    The instance of the Abstractor::AbstractorAbstractionSource that provides the indirec source.



79
80
81
82
83
84
85
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 79

def abstract_indirect_source(about, abstractor_abstraction, abstractor_abstraction_source)
  if !abstractor_abstraction.detect_abstractor_indirect_source(abstractor_abstraction_source)
    source = about.send(abstractor_abstraction_source.from_method)
    abstractor_abstraction.abstractor_indirect_sources.build(abstractor_abstraction_source: abstractor_abstraction_source, source_type: source[:source_type], source_method: source[:source_method])
    abstractor_abstraction.save!
  end
end

#abstract_name_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void

This method returns an undefined value.

Generates suggestions for name/value pairs.

Tht method will detect sentenses in the source text that match any of the predicate variants. For each detected sentence, method would first try to abstract canonical name/value pair. If canonical match was not found, method would try to abstract sentinental match.

Parameters:

  • about (ActiveRecord::Base)

    The entity to abstract. An instance of the class specified in the Abstractor::AbstractorSubject#subject_type attribute.

  • abstractor_abstraction (Abstractor::AbstractorAbstraction)

    The instance of Abstractor::AbstractorAbstraction to make suggestions against.

  • abstractor_abstraction_source (Abstractor::AbstractorAbstractionSource)

    The instance of the Abstractor::AbstractorAbstractionSource that provides the custom method to invoke on the abstractable entity to make custom suggestions.



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 251

def abstract_name_value(about, abstractor_abstraction, abstractor_abstraction_source)
  abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source|
    abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source)
    parser = Abstractor::Parser.new(abstractor_text)

    sentences = []
    # get all matching sentences
    abstractor_abstraction_schema.predicate_variants.each do |predicate_variant|
      ranges = parser.range_all(Regexp.escape(predicate_variant), word_boundary: false)
      ranges.each do |range|
        sentence = parser.find_sentence(range)
        sentences << sentence if sentence
      end
    end
    sentences.uniq.each do |sentence|
      skip_sentinental = abstract_canonical_name_value(about, abstractor_abstraction, abstractor_abstraction_source, source, parser, sentence)
      abstract_sentential_name_value(about, abstractor_abstraction, abstractor_abstraction_source, source, parser, sentence) unless skip_sentinental
    end
  end
  create_unknown_abstractor_suggestion_name_only(about, abstractor_abstraction, abstractor_abstraction_source)
  create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
end

#abstract_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void

This method returns an undefined value.

Creates instances of Abstractor::AbstractorSuggestion and Abstractor::AbstractorSuggestionSource based on natural languange processing (nlp).

The Abstractor::AbstractorSubject#abstractor_rule_type attribute determines the nlp strategy to employ:

  • ‘name/value’: attempts to search for non-negated sentences mentioning of an Abstractor::AbstractorAbstractionSchema#predicate and an Abstractor::AbstractorObjectValue

  • ‘value’: attempts to search for non-negated sentences mentioning an Abstractor::AbstractorObjectValue

  • ‘unknown’: will automatically create an ‘unknown’ Abstractor::AbstractorSuggestion

Parameters:

  • about (ActiveRecord::Base)

    The entity to abstract. An instance of the class specified in the Abstractor::AbstractorSubject#subject_type attribute.

  • abstractor_abstraction (Abstractor::AbstractorAbstraction)

    The instance of Abstractor::AbstractorAbstraction to make suggestions against.

  • abstractor_abstraction_source (Abstractor::AbstractorAbstractionSource)

    The instance of the Abstractor::AbstractorAbstractionSource that provides the rule type and from method to make nlp suggestions.



101
102
103
104
105
106
107
108
109
110
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 101

def abstract_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
  case abstractor_abstraction_source.abstractor_rule_type.name
  when 'name/value'
    abstract_name_value(about, abstractor_abstraction, abstractor_abstraction_source)
  when 'value'
    abstract_value(about, abstractor_abstraction, abstractor_abstraction_source)
  when 'unknown'
    abstract_unknown(about, abstractor_abstraction, abstractor_abstraction_source)
  end
end

#abstract_sentential_name_value(about, abstractor_abstraction, abstractor_abstraction_source, source, parser, sentence) ⇒ Object



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 317

def abstract_sentential_name_value(about, abstractor_abstraction, abstractor_abstraction_source, source, parser, sentence)
  abstractor_abstraction_schema.predicate_variants.each do |predicate_variant|
    if match = parser.match_sentence(sentence[:sentence], predicate_variant)
      if abstractor_abstraction_schema.abstractor_object_type && (abstractor_abstraction_schema.abstractor_object_type.number? || abstractor_abstraction_schema.abstractor_object_type.number_list?)
        object_regex = object_regex = Abstractor::Enum::NUMERIC_REGEX
        filtered_matches = parser.sentence_match_scan(sentence[:sentence], object_regex).reject{|m| m.begin(0) > match.begin(0) && m.end(0) < match.end(0)}
        if filtered_matches.any?
          closest_post_match  = filtered_matches.select{|m| m.begin(0) > match.end(0)}.first
          closest_pre_match   = filtered_matches.select{|m| m.end(0)   < match.begin(0)}.last

          closest_match = nil
          if closest_post_match && closest_pre_match
            if closest_post_match.begin(0) - match.end(0) > match.begin(0) - closest_pre_match.end(0) and sentence[:sentence][closest_pre_match.end(0)..match.begin(0)] !~ /[,;]/
              closest_match = closest_pre_match
            else
              closest_match = closest_post_match
            end
          else
            closest_match =   closest_post_match
            closest_match ||= closest_pre_match
          end

          scoped_sentence = Abstractor::NegationDetection.parse_negation_scope(sentence[:sentence])
          reject = (
                     Abstractor::NegationDetection.negated_match_value?(scoped_sentence[:scoped_sentence], predicate_variant) ||
                     Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], predicate_variant) ||
                     Abstractor::NegationDetection.negated_match_value?(scoped_sentence[:scoped_sentence], closest_match[:object_value]) ||
                     Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], closest_match[:object_value])
                   )
          if !reject
            if abstractor_abstraction_schema.abstractor_object_type.number_list?
              # filter matched numbers by list of available values
              abstractor_abstraction_schema.abstractor_object_values.each do |abstractor_object_value|
                abstractor_object_value.object_variants.each do |object_variant|
                  if object_variant == closest_match[:object_value]
                    suggest(abstractor_abstraction, abstractor_abstraction_source, sentence[:sentence], sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name],  abstractor_object_value, nil, nil, nil, nil)
                  end
                end
              end
            else
              suggest(abstractor_abstraction, abstractor_abstraction_source, sentence[:sentence], sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], closest_match[:object_value], nil, nil, nil, nil)
            end
          end
        end
      else
        abstractor_abstraction_schema.abstractor_object_values.each do |abstractor_object_value|
          abstractor_object_value.object_variants.each do |object_variant|
            match = parser.match_sentence(sentence[:sentence], Regexp.escape(object_variant))
            if match
              scoped_sentence = Abstractor::NegationDetection.parse_negation_scope(sentence[:sentence])
              reject = (
                         Abstractor::NegationDetection.negated_match_value?(scoped_sentence[:scoped_sentence], predicate_variant) ||
                         Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], predicate_variant) ||
                         Abstractor::NegationDetection.negated_match_value?(scoped_sentence[:scoped_sentence], object_variant) ||
                         Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], object_variant)
                       )
              if !reject
                suggest(abstractor_abstraction, abstractor_abstraction_source, sentence[:sentence], sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], abstractor_object_value, nil, nil, nil, nil)
              end
            end
          end
        end
      end
    end
  end
end

#abstract_sentential_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 187

def abstract_sentential_value(about, abstractor_abstraction, abstractor_abstraction_source)
  abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source|
    abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source)
    abstractor_object_value_ids = abstractor_abstraction_schema.abstractor_object_values.map(&:id)

    abstractor_object_values = []
    abstractor_object_value_variants = []
    target_abstractor_object_values =[]
    target_abstractor_object_value_variants = Abstractor::AbstractorObjectValueVariant.where("abstractor_object_value_id in (?)", abstractor_object_value_ids).to_a

    at = nil
    at = abstractor_text.downcase unless abstractor_text.blank?
    target_abstractor_object_value_variants.each do |abstractor_object_value_variant|
      re = Regexp.new('\b' + Regexp.escape(abstractor_object_value_variant.value.downcase) + '\b')
      if re =~ at
        abstractor_object_value_variants << abstractor_object_value_variant
        abstractor_object_values << abstractor_object_value_variant.abstractor_object_value
      end
    end

    target_abstractor_object_values = abstractor_abstraction_schema.abstractor_object_values
    target_abstractor_object_values = target_abstractor_object_values - abstractor_object_values

    target_abstractor_object_values.each do |abstractor_object_value|
      re = Regexp.new('\b' + Regexp.escape(abstractor_object_value.value.downcase) + '\b')
      if re =~ at
        abstractor_object_values << abstractor_object_value
      end
    end

    parser = Abstractor::Parser.new(abstractor_text)
    abstractor_object_values.each do |abstractor_object_value|
      object_variants(abstractor_object_value, abstractor_object_value_variants).each do |object_variant|
        ranges = parser.range_all(Regexp.escape(object_variant.downcase))
        if ranges.any?
          ranges.each do |range|
            sentence = parser.find_sentence(range)
            if sentence
              scoped_sentence = Abstractor::NegationDetection.parse_negation_scope(sentence[:sentence])
              reject = (
                        Abstractor::NegationDetection.negated_match_value?(scoped_sentence[:scoped_sentence], object_variant) ||
                        Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], object_variant)
                      )
              if !reject
                suggest(abstractor_abstraction, abstractor_abstraction_source, object_variant.downcase, sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], abstractor_object_value, nil, nil, nil, nil)
              end
            end
          end
        end
      end
    end
  end
end

#abstract_unknown(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object



178
179
180
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 178

def abstract_unknown(about, abstractor_abstraction, abstractor_abstraction_source)
  create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
end

#abstract_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object



182
183
184
185
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 182

def abstract_value(about, abstractor_abstraction, abstractor_abstraction_source)
  abstract_sentential_value(about, abstractor_abstraction, abstractor_abstraction_source)
  create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
end

#abstractor_object_value?(suggested_value) ⇒ Boolean

Returns:

  • (Boolean)


423
424
425
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 423

def abstractor_object_value?(suggested_value)
  suggested_value.instance_of?(Abstractor::AbstractorObjectValue)
end

#create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object



455
456
457
458
459
460
461
462
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 455

def create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
  #Create an 'unknown' suggestion based on matching nothing only if we have not made a suggstion
  abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source|
    if abstractor_abstraction.abstractor_suggestions(true).select { |abstractor_suggestion| abstractor_suggestion.unknown != true || abstractor_suggestion.unknown == true}.empty?
      suggest(abstractor_abstraction, abstractor_abstraction_source, nil, nil, source[:source_id], source[:source_type].to_s, source[:source_method],source[:section_name],  nil, true, nil, nil, nil)
    end
  end
end

#create_unknown_abstractor_suggestion_name_only(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object



427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 427

def create_unknown_abstractor_suggestion_name_only(about, abstractor_abstraction, abstractor_abstraction_source)
  abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source|
    abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source)
    parser = Abstractor::Parser.new(abstractor_text)
    #Create an 'unknown' suggestion based on match name only if we have not made a suggstion
    if abstractor_abstraction.abstractor_suggestions(true).empty?
      abstractor_abstraction_schema.predicate_variants.each do |predicate_variant|
        ranges = parser.range_all(Regexp.escape(predicate_variant))
        if ranges
          ranges.each do |range|
            sentence = parser.find_sentence(range)
            if sentence
              scoped_sentence = Abstractor::NegationDetection.parse_negation_scope(sentence[:sentence])
              reject = (
                        Abstractor::NegationDetection.negated_match_value?(scoped_sentence[:scoped_sentence], predicate_variant) ||
                        Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], predicate_variant)
                      )
              if !reject
                suggest(abstractor_abstraction, abstractor_abstraction_source, predicate_variant.downcase, sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name],  nil, true, nil, nil, nil)
              end
            end
          end
        end
      end
    end
  end
end

#groupable?Boolean

Returns:

  • (Boolean)


464
465
466
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 464

def groupable?
  !abstractor_subject_group_member.nil?
end

#suggest(abstractor_abstraction, abstractor_abstraction_source, match_value, sentence_match_value, source_id, source_type, source_method, section_name, suggested_value, unknown, not_applicable, custom_method, custom_explanation) ⇒ Object



384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 384

def suggest(abstractor_abstraction, abstractor_abstraction_source, match_value, sentence_match_value, source_id, source_type, source_method, section_name, suggested_value, unknown, not_applicable, custom_method, custom_explanation)
  match_value.strip! unless match_value.nil?
  sentence_match_value.strip! unless sentence_match_value.nil?
  if abstractor_object_value?(suggested_value)
    abstractor_object_value = suggested_value
    suggested_value = suggested_value.value
  end
  abstractor_suggestion = abstractor_abstraction.detect_abstractor_suggestion(suggested_value, unknown, not_applicable)
  if !abstractor_suggestion
    abstractor_suggestion_status_needs_review = Abstractor::AbstractorSuggestionStatus.where(name: 'Needs review').first
    abstractor_suggestion = Abstractor::AbstractorSuggestion.create(
                                                        abstractor_abstraction: abstractor_abstraction,
                                                        abstractor_suggestion_status: abstractor_suggestion_status_needs_review,
                                                        suggested_value: suggested_value,
                                                        unknown: unknown,
                                                        not_applicable: not_applicable
                                                        )

    abstractor_suggestion.abstractor_suggestion_object_value = Abstractor::AbstractorSuggestionObjectValue.new(abstractor_object_value: abstractor_object_value) if abstractor_object_value
  end

  abstractor_suggestion_source = abstractor_suggestion.detect_abstractor_suggestion_source(abstractor_abstraction_source, sentence_match_value, source_id, source_type, source_method, section_name)
  if !abstractor_suggestion_source
    Abstractor::AbstractorSuggestionSource.create(
                                      abstractor_abstraction_source: abstractor_abstraction_source,
                                      abstractor_suggestion: abstractor_suggestion,
                                      match_value: match_value,
                                      sentence_match_value: sentence_match_value,
                                      source_id: source_id,
                                      source_type: source_type,
                                      source_method: source_method,
                                      section_name: section_name,
                                      custom_method: custom_method,
                                      custom_explanation: custom_explanation
                                     )
  end
  abstractor_suggestion
end