use crate::language::*;
use crate::symbols::*;
use narsese::api::{GetCategory, TermCategory};
impl Term {
#[doc(alias = "get_name")]
pub fn name(&self) -> String {
self.format_name()
}
#[doc(alias = "get_complexity")]
pub fn complexity(&self) -> usize {
use TermComponents::*;
match self.components() {
Empty => 0,
Word(..) | Variable(..) => 1,
Compound(terms) => 1 + terms.iter().map(Term::complexity).sum::<usize>(),
}
}
#[doc(alias = "zero_complexity")]
pub fn is_zero_complexity(&self) -> bool {
self.complexity() == 0
}
#[inline(always)]
pub fn is_same_type(&self, other: &Self) -> bool {
self.identifier() == other.identifier()
}
}
impl GetCategory for Term {
fn get_category(&self) -> TermCategory {
use TermCategory::*;
match self.identifier() {
WORD | PLACEHOLDER | VAR_INDEPENDENT | VAR_DEPENDENT | VAR_QUERY => Atom,
INHERITANCE_RELATION | IMPLICATION_RELATION | SIMILARITY_RELATION
| EQUIVALENCE_RELATION => Statement,
NEGATION_OPERATOR |
DIFFERENCE_EXT_OPERATOR | DIFFERENCE_INT_OPERATOR |
PRODUCT_OPERATOR | IMAGE_EXT_OPERATOR | IMAGE_INT_OPERATOR |
SET_EXT_OPERATOR
| SET_INT_OPERATOR
| INTERSECTION_EXT_OPERATOR
| INTERSECTION_INT_OPERATOR
| CONJUNCTION_OPERATOR
| DISJUNCTION_OPERATOR => Compound,
id => panic!("Unexpected compound term identifier: {id}"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_term as term;
use crate::{ok, util::AResult};
use nar_dev_utils::{asserts, macro_once};
#[test]
fn name() -> AResult {
macro_once! {
macro fmt($($term:literal => $expected:expr)*) {
asserts! {$(
term!($term).to_string() => $expected
)*}
}
"_" => "_"
"A" => "A"
"$A" => "$1" "#A" => "#1" "?A" => "?1" "{A, B}" => "{}(A B)"
"[A, B]" => "[](A B)"
"(&, A, B)" => "&(A B)"
"(|, A, B)" => "|(A B)"
"(-, A, B)" => "(A - B)"
"(~, A, B)" => "(A ~ B)"
"(*, A, B)" => "*(A B)"
r"(/, R, _)" => r"/(R _)"
r"(\, R, _)" => r"\(R _)"
r"(/, R, _, A)" => r"/(R _ A)"
r"(\, R, _, A)" => r"\(R _ A)"
r"(&&, A, B)" => r"&&(A B)"
r"(||, A, B)" => r"||(A B)"
r"(--, A)" => r"(-- A)"
"<A --> B>" => "(A --> B)"
"<A <-> B>" => "(A <-> B)"
"<A ==> B>" => "(A ==> B)"
"<A <=> B>" => "(A <=> B)"
"<B <-> A>" => "(A <-> B)"
"<B <=> A>" => "(A <=> B)"
"(*, $e, #d, ?c, $b, #a)" => "*($1 #2 ?3 $4 #5)"
"(/, $e, #d, ?c, $b, #a, _)" => "/($1 #2 ?3 $4 #5 _)"
}
ok!()
}
#[test]
fn complexity() -> AResult {
macro_once! {
macro fmt($($term:literal => $expected:expr)*) {
asserts! {$(
term!($term).complexity() => $expected
)*}
}
"_" => 0
"A" => 1
"$A" => 1 "#A" => 1
"?A" => 1
"{A}" => 2
"[A]" => 2
"(-, A, B)" => 3
"(~, A, B)" => 3
"(&, A, B, C)" => 4
"(|, A, B, C)" => 4
"(*, A, B, C, D)" => 5
r"(/, R, _)" => 2
r"(\, R, _)" => 2
r"(/, R, _, A)" => 3
r"(\, R, _, A)" => 3
r"(&&, A, B)" => 3
r"(||, A, B)" => 3
r"(--, A)" => 2
r"(*, (*, A))" => 3
r"(*, (*, (*, A)))" => 4
"<A --> B>" => 3
"<A <-> B>" => 3
"<A ==> B>" => 3
"<A <=> B>" => 3
"<<A --> B> ==> X>" => 5
"<<A <-> B> <=> X>" => 5
"<<A --> B> ==> X>" => 5
"<<A <-> B> <=> X>" => 5
"<<A --> B> --> <C ==> D>>" => 7
"<<A <-> B> <-> <C <=> D>>" => 7
"<<A --> B> ==> <C ==> D>>" => 7
"<<A <-> B> <=> <C <=> D>>" => 7
}
ok!()
}
#[test]
fn is_same_type() -> AResult {
macro_once! {
macro is_same_type($( $s:literal ~ $s2:literal => $id:expr )*) {
$(
let term = term!($s);
let term2 = term!($s2);
assert!(term.is_same_type(&term2));
assert_eq!(term.identifier(), $id);
assert_eq!(term2.identifier(), $id);
)*
}
"_" ~ "_" => PLACEHOLDER
"A" ~ "B" => WORD
"$A" ~ "$x" => VAR_INDEPENDENT
"#A" ~ "#1" => VAR_DEPENDENT
"?A" ~ "?question" => VAR_QUERY
"{A}" ~ "{x, y, z}" => SET_EXT_OPERATOR
"[A]" ~ "[ㄚ, ㄛ, ㄜ]" => SET_INT_OPERATOR
"(&, A, B)" ~ "(&, x, y)" => INTERSECTION_EXT_OPERATOR
"(|, A, B)" ~ "(|, a, b)" => INTERSECTION_INT_OPERATOR
"(-, A, B)" ~ "(-, B, A)" => DIFFERENCE_EXT_OPERATOR
"(~, A, B)" ~ "(~, B, C)" => DIFFERENCE_INT_OPERATOR
"(*, A)" ~ "(*, α, β, γ)" => PRODUCT_OPERATOR
r"(/, R, _)" ~ r"(/, R, A, _, B)" => IMAGE_EXT_OPERATOR
r"(\, R, _)" ~ r"(\, R, A, B, _)" => IMAGE_INT_OPERATOR
r"(&&, A, B)" ~ r"(&&, X, Y, Z)" => CONJUNCTION_OPERATOR
r"(||, A, B)" ~ r"(||, (||, A, B), C)" => DISJUNCTION_OPERATOR
r"(--, A)" ~ r"(--, (~, B, A))" => NEGATION_OPERATOR
"<A --> B>" ~ "<<B ==> C> --> A>" => INHERITANCE_RELATION
"<A <-> B>" ~ "<<B <=> C> <-> A>" => SIMILARITY_RELATION
"<A ==> B>" ~ "<<B --> C> ==> A>" => IMPLICATION_RELATION
"<A <=> B>" ~ "<<B <-> C> <=> A>" => EQUIVALENCE_RELATION
}
ok!()
}
}