use crate::{
control::{ReasonContext, ReasonContextDirect, Reasoner},
entity::{Item, RCTask, Sentence, Task},
inference::Budget,
util::ToDisplayAndBrief,
};
use nar_dev_utils::{unwrap_or_return, RefCount};
impl Reasoner {
pub(in crate::control) fn process_direct(&mut self) -> bool {
let mut messages = vec![];
let tasks_to_process = self.task_buffer.load_from_tasks(
|task| self.memory.has_concept(task.content()),
|message| messages.push(message),
);
for message in messages {
self.report_comment(message)
}
self.immediate_process_tasks(tasks_to_process)
}
fn immediate_process_tasks(
&mut self,
tasks_to_process: impl IntoIterator<Item = Task>,
) -> bool {
let mut has_result = false;
for task in tasks_to_process {
let has_result_single = self.immediate_process(task);
if has_result_single {
has_result = true;
}
}
has_result
}
fn immediate_process(&mut self, task_to_process: Task) -> bool {
self.report_comment(format!("!!! Insert: {}", task_to_process.to_display_long()));
let mut context =
unwrap_or_return!(?self.prepare_direct_process_context(task_to_process) => false);
let new_concept_budget = context
.memory()
.activate_concept_calculate(context.current_concept(), &*context.current_task().get_());
context
.current_concept_mut()
.copy_budget_from(&new_concept_budget);
context.direct_process();
let has_result = context.has_result();
context.absorbed_by_reasoner();
has_result
}
fn prepare_direct_process_context<'this: 'context, 'context>(
&'this mut self,
task_to_process: Task,
) -> Option<ReasonContextDirect<'context>> {
let task_term = task_to_process.content();
let concept_key = self.memory.get_concept_or_create(task_term)?.key().clone();
let current_concept = self.memory.pick_out_concept(&concept_key)?;
let current_task = RCTask::new_(task_to_process);
let context = ReasonContextDirect::new(self, current_concept, current_task);
Some(context)
}
}
impl ReasonContextDirect<'_> {
fn direct_process(&mut self) {
(self.core.reasoner.inference_engine.direct_f())(self);
self.link_concept_to_task()
}
}