Class: Legion::Extensions::Agentic::Inference::PerceptualInference::Helpers::PerceptualField

Inherits:
Object
  • Object
show all
Includes:
Logging::Helper
Defined in:
lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePerceptualField

Returns a new instance of PerceptualField.



14
15
16
17
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 14

def initialize
  @hypotheses = {}
  @evidence_log = []
end

Instance Attribute Details

#evidence_logObject (readonly)

Returns the value of attribute evidence_log.



12
13
14
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 12

def evidence_log
  @evidence_log
end

#hypothesesObject (readonly)

Returns the value of attribute hypotheses.



12
13
14
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 12

def hypotheses
  @hypotheses
end

Instance Method Details

#adapt_priors(modality:, correct_hypothesis_id:) ⇒ Object



84
85
86
87
88
89
90
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 84

def adapt_priors(modality:, correct_hypothesis_id:)
  validate_modality!(modality)
  hypotheses_for(modality).each do |h|
    outcome = h.id == correct_hypothesis_id ? :correct : :incorrect
    h.adapt_prior(outcome: outcome)
  end
end

#ambiguity_levelObject



92
93
94
95
96
97
98
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 92

def ambiguity_level
  rival_count = MODALITIES.count { |m| rivalry?(modality: m) && hypotheses_for(m).any? }
  total_active = MODALITIES.count { |m| hypotheses_for(m).any? }
  return 0.0 if total_active.zero?

  rival_count.to_f / total_active
end

#current_percept(modality:) ⇒ Object



67
68
69
70
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 67

def current_percept(modality:)
  validate_modality!(modality)
  @hypotheses.values.find { |h| h.modality == modality && h.state == :selected }
end

#decay_allObject



100
101
102
103
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 100

def decay_all
  @hypotheses.each_value(&:decay)
  @hypotheses.reject! { |_, h| h.state == :decayed }
end

#hypotheses_for(modality) ⇒ Object



72
73
74
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 72

def hypotheses_for(modality)
  @hypotheses.values.select { |h| h.modality == modality }
end

#present_evidence(modality:, content:, strength: 0.5) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 33

def present_evidence(modality:, content:, strength: 0.5)
  validate_modality!(modality)
  strength = [strength.to_f, EVIDENCE_STRENGTH_FLOOR].max
  record_evidence(modality, content, strength)

  active_hypotheses_for(modality).each do |h|
    h.likelihood = compute_likelihood(h, content, strength)
    h.compute_posterior(evidence_weight: strength)
  end

  hypotheses_for(modality).size
end

#register_hypothesis(content:, modality:, domain: :general, prior: DEFAULT_PRIOR) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 19

def register_hypothesis(content:, modality:, domain: :general, prior: DEFAULT_PRIOR)
  validate_modality!(modality)
  prune_modality(modality) if hypotheses_for(modality).size >= MAX_HYPOTHESES

  hypothesis = PerceptualHypothesis.new(
    content:  content,
    modality: modality,
    domain:   domain,
    prior:    prior
  )
  @hypotheses[hypothesis.id] = hypothesis
  hypothesis
end

#rivalry?(modality:) ⇒ Boolean

Returns:

  • (Boolean)


58
59
60
61
62
63
64
65
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 58

def rivalry?(modality:)
  validate_modality!(modality)
  candidates = active_hypotheses_for(modality)
  return false if candidates.size < 2

  top_two = candidates.max_by(2, &:posterior)
  top_two.first.rival_with?(top_two.last)
end

#select_percept(modality:) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 46

def select_percept(modality:)
  validate_modality!(modality)
  candidates = active_hypotheses_for(modality)
  return nil if candidates.empty?

  winner = candidates.max_by(&:posterior)
  return nil if winner.posterior < SELECTION_THRESHOLD

  candidates.each { |h| h.id == winner.id ? h.select! : h.suppress! }
  winner
end

#suppress_hypothesis(hypothesis_id:) ⇒ Object



76
77
78
79
80
81
82
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 76

def suppress_hypothesis(hypothesis_id:)
  h = @hypotheses[hypothesis_id]
  return false unless h

  h.suppress!
  true
end

#to_hObject



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/legion/extensions/agentic/inference/perceptual_inference/helpers/perceptual_field.rb', line 105

def to_h
  by_modality = MODALITIES.each_with_object({}) do |m, acc|
    hs = hypotheses_for(m)
    next if hs.empty?

    acc[m] = {
      count:   hs.size,
      rivalry: rivalry?(modality: m),
      percept: current_percept(modality: m)&.to_h
    }
  end

  {
    hypotheses_total: @hypotheses.size,
    ambiguity_level:  ambiguity_level.round(4),
    by_modality:      by_modality
  }
end