use crate::{
control::{
ContextDerivationConcept, ReasonContext, ReasonContextTransform, ReasonContextWithLinks,
ReasonDirection,
},
entity::{Sentence, TLink, TruthValue},
inference::{BudgetInferenceContext, TruthFunctions},
language::{CompoundTermRef, StatementRef, Term},
symbols::*,
};
use nar_dev_utils::{unwrap_or_return, RefCount};
pub fn transform_task(context: &mut ReasonContextTransform) {
let t_link = context.current_task_link();
let task_rc = t_link.target_rc();
let task = task_rc.get_();
debug_assert!(
task.content().is_compound(),
"// ! 此处必须假定其为复合词项:转换规则的任务均为复合词项"
);
let task_content = unwrap_or_return! {
?task.content().as_compound()
};
let indexes = t_link.indexes();
let inh = unwrap_or_return! {
?unwrap_or_return! {
?get_inheritance_to_be_transform(
task_content,
indexes
)
}.as_statement_type(INHERITANCE_RELATION)
};
let old_content = task_content.inner.clone();
let inheritance_to_be_transform = inh.statement.clone();
drop(task);
drop(task_rc);
match old_content == inheritance_to_be_transform {
true => {
let inh = unwrap_or_return!(?inheritance_to_be_transform.as_statement());
let inh_subject = inh.subject;
let inh_predicate = inh.predicate;
if let Some(inh_subject) = inh_subject.as_compound() {
transform_subject_product_image(inh_subject, inh_predicate, context);
}
if let Some(inh_predicate) = inh_predicate.as_compound() {
transform_predicate_product_image(inh_subject, inh_predicate, context);
}
}
false => {
if let Some(old_content) = old_content.as_compound() {
transform_product_image(
inheritance_to_be_transform
.as_statement()
.expect("此处一定是陈述"),
old_content,
context,
);
}
}
}
}
fn truth_transforming(
context: &mut ReasonContextTransform,
new_content: &Term,
) -> (Option<TruthValue>, crate::entity::BudgetValue) {
let direction = context.reason_direction();
use ReasonDirection::*;
let truth = match direction {
Forward => Some(
context.current_task().get_().unwrap_judgement().identity(), ),
Backward => None,
};
let budget = match direction {
Forward => context.budget_compound_forward(truth.as_ref(), new_content),
Backward => context.budget_compound_backward(new_content),
};
(truth, budget)
}
fn get_inheritance_to_be_transform<'t>(
task_content: CompoundTermRef<'t>,
indexes: &[usize],
) -> Option<&'t Term> {
match indexes.len() {
2 if task_content.instanceof_inheritance() => Some(task_content.inner),
3 => task_content.component_at(indexes[0]),
4 => task_content
.as_conditional()?
.1
.component_at(indexes[1]),
_ => None,
}
}
fn transform_product_image(
inheritance_to_be_transform: StatementRef,
old_content: CompoundTermRef,
context: &mut ReasonContextTransform,
) {
let t_link = context.current_task_link();
let task_rc = t_link.target_rc();
let task = task_rc.get_();
let indexes = t_link.indexes();
let new_inheritance =
unwrap_or_return!(?transform_inheritance(inheritance_to_be_transform, indexes));
let content =
unwrap_or_return!(?replaced_transformed_content(old_content, indexes, new_inheritance));
drop(task);
drop(task_rc);
let (truth, budget) = truth_transforming(context, &content);
context.single_premise_task_structural(content, truth, budget);
}
fn replaced_transformed_content(
old_content: CompoundTermRef,
indexes: &[usize],
new_inheritance: Term,
) -> Option<Term> {
match indexes.len() {
2 => Some(new_inheritance.clone()),
_ if old_content.is_statement() && indexes[0] == 1 => {
debug_assert!(
indexes.len() == 3,
"【2024-07-03 21:55:34】此处原意是「三层、陈述、在谓项中」"
);
debug_assert!(old_content.is_compound(), "原内容必须是复合词项");
Term::make_statement(
&old_content,
old_content
.as_compound()
.unwrap()
.component_at(0)
.expect("复合词项必须有元素")
.clone(),
new_inheritance,
)
}
_ => match old_content.as_conditional() {
Some((statement, conditional)) => {
debug_assert!(
indexes.len() == 4,
"【2024-07-03 21:55:34】此处原意是「四层、条件、在条件项中」"
);
let new_condition = conditional.set_component(indexes[1], Some(new_inheritance))?;
Term::make_statement(&statement, new_condition, statement.predicate.clone())
}
_ => {
let mut components = old_content.clone_components();
components[indexes[0]] = new_inheritance;
if let Some(conjunction) = old_content.as_compound_type(CONJUNCTION_OPERATOR) {
Term::make_compound_term(conjunction, components)
} else if let Some(statement) = old_content.as_statement() {
let subject = components.remove(0);
let predicate = components.remove(0);
Term::make_statement(&statement, subject, predicate)
} else {
None
}
}
},
}
}
fn transform_inheritance(
inheritance_to_be_transform: StatementRef,
indexes: &[usize],
) -> Option<Term> {
let index = indexes[indexes.len() - 1]; let side = indexes[indexes.len() - 2]; let inner_compound = inheritance_to_be_transform
.into_compound_ref()
.component_at(side)?
.as_compound()?; let [subject, predicate] = match inner_compound.identifier() {
PRODUCT_OPERATOR => match side {
0 => [
inner_compound.component_at(index)?.clone(),
Term::make_image_ext_from_product(
inner_compound,
inheritance_to_be_transform.predicate,
index,
)?,
],
_ => [
Term::make_image_int_from_product(
inner_compound,
inheritance_to_be_transform.subject,
index,
)?,
inner_compound.component_at(index)?.clone(),
],
},
IMAGE_EXT_OPERATOR if side == 1 => match index {
0 => {
let [image, outer] = Term::make_image_ext_from_image(
inner_compound,
inheritance_to_be_transform.subject,
index,
)?;
[outer, image]
}
_ => {
let [image, outer] = Term::make_image_ext_from_image(
inner_compound,
inheritance_to_be_transform.subject,
index,
)?;
[outer, image]
}
},
IMAGE_INT_OPERATOR if side == 1 => match index {
0 => {
let [image, outer] = Term::make_image_ext_from_image(
inner_compound,
inheritance_to_be_transform.subject,
index,
)?;
[outer, image]
}
_ => {
let [image, outer] = Term::make_image_ext_from_image(
inner_compound,
inheritance_to_be_transform.subject,
index,
)?;
[outer, image]
}
},
_ => return None,
};
Term::make_inheritance(subject, predicate)
}
fn transform_subject_product_image(
inh_subject: CompoundTermRef,
inh_predicate: &Term,
context: &mut ReasonContextTransform,
) {
if let Some(product) = inh_subject.as_compound_type(PRODUCT_OPERATOR) {
for (i, new_subject) in product.components.iter().cloned().enumerate() {
let new_predicate = unwrap_or_return!(?Term::make_image_ext_from_product(product, inh_predicate, i) => continue);
let inheritance =
unwrap_or_return!(?Term::make_inheritance(new_subject, new_predicate) => continue);
let (truth, budget) = truth_transforming(context, &inheritance);
context.single_premise_task_structural(inheritance, truth, budget);
}
}
else if let Some(image) = inh_subject.as_compound_type(IMAGE_INT_OPERATOR) {
let placeholder_index = image.get_placeholder_index();
for i in 1..image.size() {
let [new_subject, new_predicate] = match i == placeholder_index {
true => {
let [product, relation] =
unwrap_or_return!(?Term::make_product(image, inh_predicate) => continue);
[relation, product] }
false => {
let [image, outer] = unwrap_or_return!(?Term::make_image_int_from_image(image, inh_predicate, i-1) => continue);
[image, outer]
}
};
let inheritance =
unwrap_or_return!(?Term::make_inheritance(new_subject, new_predicate) => continue);
let (truth, budget) = truth_transforming(context, &inheritance);
context.single_premise_task_structural(inheritance, truth, budget);
}
}
}
fn transform_predicate_product_image(
inh_subject: &Term,
inh_predicate: CompoundTermRef,
context: &mut ReasonContextTransform,
) {
if let Some(product) = inh_predicate.as_compound_type(PRODUCT_OPERATOR) {
for (i, new_predicate) in product.components.iter().cloned().enumerate() {
let new_subject = unwrap_or_return!(?Term::make_image_int_from_product(product, inh_subject, i) => continue);
let inheritance =
unwrap_or_return!(?Term::make_inheritance(new_subject, new_predicate) => continue);
let (truth, budget) = truth_transforming(context, &inheritance);
context.single_premise_task_structural(inheritance, truth, budget);
}
}
else if let Some(image) = inh_predicate.as_compound_type(IMAGE_EXT_OPERATOR) {
let placeholder_index = image.get_placeholder_index();
for i in 1..image.size() {
let [new_subject, new_predicate] = match i == placeholder_index {
true => {
let [product, relation] =
unwrap_or_return!(?Term::make_product(image, inh_subject) => continue);
[product, relation] }
false => {
let [image, outer] = unwrap_or_return!(?Term::make_image_ext_from_image(image, inh_subject, i-1) => continue);
[outer, image]
}
};
let inheritance =
unwrap_or_return!(?Term::make_inheritance(new_subject, new_predicate) => continue);
let (truth, budget) = truth_transforming(context, &inheritance);
context.single_premise_task_structural(inheritance, truth, budget);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::inference::{process_direct, tools::*, InferenceEngine};
use narsese::lexical_nse_term;
const ENGINE: InferenceEngine = InferenceEngine::new(
process_direct, transform_task,
InferenceEngine::ECHO.matching_f(),
InferenceEngine::ECHO.reason_f(),
);
fn test_transform_and_expect_terms(
cmds: impl AsRef<str>,
expect_terms: impl IntoIterator<Item = narsese::lexical::Term>,
) {
let mut vm = create_reasoner_from_engine(ENGINE);
let outs = vm.input_cmds_and_fetch_out(cmds.as_ref());
print_outputs(&outs);
for expected in expect_terms {
expect_outputs_contains_term(&outs, expected);
}
}
#[test]
fn transform_basic_ext() {
test_transform_and_expect_terms(
r"
nse <(*, A, B) --> R>.
cyc 10
",
[
lexical_nse_term!(r"<A --> (/, R, _, B)>"),
lexical_nse_term!(r"<B --> (/, R, A, _)>"),
],
)
}
#[test]
fn transform_basic_int() {
test_transform_and_expect_terms(
r"
nse <S --> (*, C, D)>.
cyc 10
",
[
lexical_nse_term!(r"<(\, S, _, D) --> C>"),
lexical_nse_term!(r"<(\, S, C, _) --> D>"),
],
)
}
#[test]
fn transform_backward_ext() {
test_transform_and_expect_terms(
r"
nse <A --> (/, R, _, B)>.
cyc 10
",
[
lexical_nse_term!(r"<(*, A, B) --> R>"),
lexical_nse_term!(r"<B --> (/, R, A, _)>"),
],
)
}
#[test]
fn transform_backward_int() {
test_transform_and_expect_terms(
r"
nse <(\, S, _, D) --> C>.
cyc 10
",
[
lexical_nse_term!(r"<S --> (*, C, D)>"),
lexical_nse_term!(r"<(\, S, C, _) --> D>"),
],
)
}
#[test]
fn stability() {
let mut vm = create_reasoner_from_engine(ENGINE);
let outs = vm.input_cmds_and_fetch_out(
"
nse <(*, A, B) --> R>.
nse <S --> (*, C, D)>.
cyc 1000
",
);
print_outputs(&outs);
}
}