use super::{ReasonContext, ReasonContextCore, ReasonContextCoreOut, ReasonContextWithLinks};
use crate::{
__delegate_from_core,
control::Reasoner,
entity::{Concept, JudgementV1, RCTask, TLink, Task, TaskLink, TermLink},
global::{ClockTime, Float},
parameters::Parameters,
storage::Memory,
};
use nar_dev_utils::{unwrap_or_return, RefCount};
use navm::output::Output;
use std::ops::{Deref, DerefMut};
#[derive(Debug)]
pub struct ReasonContextConcept<'this> {
pub(crate) core: ReasonContextCore<'this>,
pub(crate) outs: ReasonContextCoreOut,
current_task_link: TaskLink,
current_belief: Option<JudgementV1>,
current_belief_link: TermLink,
belief_links_to_reason: Vec<TermLink>,
}
impl<'this> ReasonContextConcept<'this> {
pub fn new<'r: 'this>(
reasoner: &'r mut Reasoner,
current_concept: Concept,
current_task_link: TaskLink,
mut belief_links_to_reason: Vec<TermLink>,
) -> Self {
let core = ReasonContextCore::new(reasoner, current_concept);
let outs = ReasonContextCoreOut::new();
debug_assert!(!belief_links_to_reason.is_empty());
belief_links_to_reason.reverse(); let current_belief_link = belief_links_to_reason.pop().expect("待推理链接不应为空");
let mut this = Self {
core,
outs,
current_task_link,
current_belief: None,
current_belief_link,
belief_links_to_reason,
};
this.update_current_belief();
this
}
}
impl ReasonContextConcept<'_> {
pub fn current_belief_link(&self) -> &TermLink {
&self.current_belief_link
}
pub fn current_belief_link_mut(&mut self) -> &mut TermLink {
&mut self.current_belief_link
}
pub fn next_belief(&mut self) -> (bool, Option<TermLink>) {
let mut current_belief_link = unwrap_or_return! {
?self.belief_links_to_reason.pop()
=> (false, None)
};
std::mem::swap(&mut self.current_belief_link, &mut current_belief_link);
let old_term_link = current_belief_link;
self.update_current_belief();
let overflowed_old_link = self.current_concept_mut().put_term_link_back(old_term_link);
(true, overflowed_old_link)
}
fn update_current_belief(&mut self) {
self.current_belief = self.updated_current_belief();
}
fn updated_current_belief(&self) -> Option<JudgementV1> {
let new_belief_link = &self.current_belief_link;
let belief_term = &*new_belief_link.target();
let belief_concept = self.term_to_concept(belief_term)?;
belief_concept
.get_belief(&*self.current_task().get_())
.cloned()
}
}
impl ReasonContext for ReasonContextConcept<'_> {
__delegate_from_core! {}
fn current_task<'r, 's: 'r>(&'s self) -> impl Deref<Target = RCTask> + 'r {
self.current_task_link.target_rc()
}
fn current_task_mut<'r, 's: 'r>(&'s mut self) -> impl DerefMut<Target = RCTask> + 'r {
self.current_task_link.target_rc_mut()
}
fn absorbed_by_reasoner(mut self) {
let _ = self
.core
.current_concept_mut()
.put_term_link_back(self.current_belief_link);
let _ = self
.core
.current_concept_mut()
.put_task_link_back(self.current_task_link);
drop(self.current_belief);
self.core.absorbed_by_reasoner(self.outs);
}
}
impl ReasonContextWithLinks for ReasonContextConcept<'_> {
fn current_belief(&self) -> Option<&JudgementV1> {
self.current_belief.as_ref()
}
fn belief_link_for_budget_inference(&self) -> Option<&TermLink> {
Some(&self.current_belief_link)
}
fn belief_link_for_budget_inference_mut(&mut self) -> Option<&mut TermLink> {
Some(&mut self.current_belief_link)
}
fn current_task_link(&self) -> &TaskLink {
&self.current_task_link
}
fn current_task_link_mut(&mut self) -> &mut TaskLink {
&mut self.current_task_link
}
}