narust_158/inference/
budget_inference.rs1use super::{BudgetInferenceFunction, BudgetInferenceResult, Truth};
6use crate::{
7 control::ReasonContextWithLinks,
8 entity::{BudgetValue, ShortFloat, TLink, TruthValue},
9 inference::{Budget, BudgetFunctions, ReviseResult},
10 language::Term,
11};
12use nar_dev_utils::{OrSomeRef, RefCount};
13
14pub trait BudgetInference: Budget {
16 fn merge_from(&mut self, other: &impl Budget)
20 where
21 Self: Sized,
22 {
23 let this = &*self;
24 let new_budget = this.merge(other);
25 self.copy_budget_from(&new_budget);
26 }
27
28 fn revise_direct(
35 new_belief_truth: &impl Truth,
36 old_belief_truth: &impl Truth,
37 revised_truth: &impl Truth,
38 current_task_budget: &mut impl Budget,
39 ) -> BudgetValue {
40 let ReviseResult {
42 new_budget,
43 new_task_budget,
44 ..
45 } = BudgetValue::revise(
46 new_belief_truth,
47 old_belief_truth,
48 revised_truth,
49 current_task_budget,
50 None::<(&BudgetValue, &BudgetValue)>,
51 );
52 current_task_budget.copy_budget_from(&new_task_budget);
54 new_budget
56 }
57}
58
59impl<B: Budget> BudgetInference for B {}
62
63use BudgetInferenceFunction::*;
64pub trait BudgetInferenceContext: ReasonContextWithLinks {
66 fn revise_matching(
69 &mut self,
70 new_belief_truth: &impl Truth,
71 old_belief_truth: &impl Truth,
72 revised_truth: &impl Truth,
73 ) -> BudgetValue {
74 let current_task = self.current_task();
76 let current_task_link = self.current_task_link();
77 let current_belief_link = self.belief_link_for_budget_inference();
78 let current_links_budget = current_belief_link.map(|b_link| (current_task_link, b_link));
79 let result = BudgetValue::revise(
80 new_belief_truth,
81 old_belief_truth,
82 revised_truth,
83 &*current_task.get_(),
84 current_links_budget,
85 );
86 drop(current_task);
89 self.current_task_mut()
90 .mut_()
91 .copy_budget_from(&result.new_task_budget);
92 if let Some([new_t_budget, new_b_budget]) = result.new_links_budget {
94 let current_task_link = self.current_task_link_mut();
95 current_task_link.copy_budget_from(&new_t_budget);
96 if let Some(current_belief_link) = self.belief_link_for_budget_inference_mut() {
97 current_belief_link.copy_budget_from(&new_b_budget);
98 }
99 }
100 result.new_budget
102 }
103
104 fn budget_forward<T: Truth>(&mut self, truth: impl OrSomeRef<T>) -> BudgetValue {
108 self.budget_inference(Forward, truth.or_some_ref(), None)
109 }
110
111 fn budget_backward<T: Truth>(&mut self, truth: impl OrSomeRef<T>) -> BudgetValue {
115 self.budget_inference(Backward, truth.or_some_ref(), None)
116 }
117
118 fn budget_backward_weak<T: Truth>(&mut self, truth: impl OrSomeRef<T>) -> BudgetValue {
122 self.budget_inference(BackwardWeak, truth.or_some_ref(), None)
123 }
124
125 fn budget_compound_forward<T: Truth>(
129 &mut self,
130 truth: impl OrSomeRef<T>,
131 content: impl OrSomeRef<Term>,
132 ) -> BudgetValue {
133 self.budget_inference(CompoundForward, truth.or_some_ref(), content.or_some_ref())
134 }
135
136 fn budget_compound_backward(&mut self, content: impl OrSomeRef<Term>) -> BudgetValue {
140 self.budget_inference(CompoundBackward, None::<&TruthValue>, content.or_some_ref())
141 }
142
143 fn budget_compound_backward_weak(&mut self, content: impl OrSomeRef<Term>) -> BudgetValue {
147 self.budget_inference(
148 CompoundBackwardWeak,
149 None::<&TruthValue>,
150 content.or_some_ref(),
151 )
152 }
153
154 fn budget_inference(
158 &mut self,
159 function: BudgetInferenceFunction,
160 truth: Option<&impl Truth>,
161 content: Option<&Term>,
162 ) -> BudgetValue {
163 let t_link = self.current_task_link();
165 let b_link = self.belief_link_for_budget_inference();
166 let target_activation = b_link.map_or(ShortFloat::ZERO, |b_link| {
168 self.concept_activation(&b_link.target())
169 });
170 let result = BudgetValue::budget_inference(
172 function,
173 truth,
174 content,
175 t_link,
176 b_link,
177 target_activation,
178 );
179 let b_link = self.belief_link_for_budget_inference_mut();
181 Self::budget_inference_apply(result, b_link)
182 }
183
184 fn concept_activation(&self, term: &Term) -> ShortFloat {
188 self.term_to_concept(term)
189 .map_or(ShortFloat::ZERO, |c| c.priority())
190 }
191
192 fn budget_inference_apply(
196 result: BudgetInferenceResult,
197 belief_link_budget: Option<&mut impl Budget>,
198 ) -> BudgetValue {
199 if let (Some(b_budget), Some(ref new_budget)) =
201 (belief_link_budget, result.new_belief_link_budget)
202 {
203 b_budget.copy_budget_from(new_budget);
204 }
205 result.new_budget
207 }
208}
209impl<C: ReasonContextWithLinks> BudgetInferenceContext for C {}
210
211#[cfg(test)]
213mod tests {
214 }