use super::{JudgementV1, QuestionV1};
use crate::{
__impl_to_display_and_display,
entity::{
sentence::{PunctuatedSentenceRef, Punctuation, Sentence, SentenceInner},
Stamp, TruthValue,
},
global::ClockTime,
inference::Evidential,
language::Term,
};
use anyhow::Result;
use nar_dev_utils::enum_union;
use narsese::lexical::Sentence as LexicalSentence;
use serde::{Deserialize, Serialize};
enum_union! {
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub SentenceV1 = JudgementV1 | QuestionV1;
}
impl SentenceV1 {
pub fn with_punctuation(
new_content: Term,
punctuation: Punctuation,
new_stamp: Stamp,
truth_revisable: Option<(TruthValue, bool)>,
) -> Result<Self> {
use Punctuation::*;
let sentence = match (punctuation, truth_revisable) {
(Judgement, Some((new_truth, revisable))) => {
JudgementV1::new(new_content, new_truth, new_stamp, revisable).into()
}
(Question, ..) => QuestionV1::new(new_content, new_stamp).into(),
_ => Err(anyhow::anyhow!(
"无效的语句:{punctuation:?}, {truth_revisable:?}"
))?,
};
Ok(sentence)
}
fn inner(&self) -> &SentenceInner {
match self {
SentenceV1::JudgementV1(JudgementV1 { inner, .. })
| SentenceV1::QuestionV1(QuestionV1 { inner, .. }) => inner,
}
}
fn inner_mut(&mut self) -> &mut SentenceInner {
match self {
SentenceV1::JudgementV1(JudgementV1 { inner, .. })
| SentenceV1::QuestionV1(QuestionV1 { inner, .. }) => inner,
}
}
}
impl Evidential for SentenceV1 {
fn evidential_base(&self) -> &[ClockTime] {
self.inner().stamp().evidential_base()
}
fn creation_time(&self) -> ClockTime {
self.inner().stamp().creation_time()
}
fn stamp_to_lexical(&self) -> narsese::lexical::Stamp {
self.inner().stamp().stamp_to_lexical()
}
}
macro_rules! as_variant {
{$this:expr, $name:ident => $($code:tt)*} => {
match $this {
SentenceV1::JudgementV1($name) => $($code)*,
SentenceV1::QuestionV1($name) => $($code)*,
}
};
}
impl Sentence for SentenceV1 {
fn sentence_clone<'s, 'sentence: 's>(&'s self) -> impl Sentence + 'sentence {
self.clone()
}
fn content(&self) -> &Term {
self.inner().content()
}
fn content_mut(&mut self) -> &mut Term {
self.inner_mut().content_mut()
}
type Judgement = JudgementV1;
type Question = QuestionV1;
fn as_punctuated_ref(&self) -> PunctuatedSentenceRef<Self::Judgement, Self::Question> {
use PunctuatedSentenceRef::*;
use SentenceV1::*;
match self {
JudgementV1(j) => Judgement(j),
QuestionV1(q) => Question(q),
}
}
fn to_key(&self) -> String {
as_variant! {
self, s => s.to_key()
}
}
fn sentence_to_display(&self) -> String {
as_variant! {
self, s => s.sentence_to_display()
}
}
fn sentence_to_lexical(&self) -> LexicalSentence {
as_variant! {
self, s => s.sentence_to_lexical()
}
}
}
__impl_to_display_and_display! {
@(sentence_to_display;;)
SentenceV1 as Sentence
}