narust_158/language/features/
term.rs

1//! 📄OpenNARS `nars.language.Term`
2//! * ⚠️不包含与特定层数Narsese有关的逻辑
3//!   * 📄事关NAL-6的`isConstant`、`renameVariables`方法,不予在此实现
4//! * ⚠️不包含与「记忆区」有关的方法
5//!   * 📄`make`
6//!   * 📝OpenNARS中有关`make`的目的:避免在记忆区中**重复构造**词项
7//!     * 🚩已经在概念区中⇒使用已有「概念」的词项
8//!     * 📌本质上是「缓存」的需求与作用
9//! * ✅【2024-06-14 16:33:57】基本完成对「基础词项」的属性检查
10
11use crate::language::*;
12use crate::symbols::*;
13use narsese::api::{GetCategory, TermCategory};
14
15/// 📄OpenNARS `nars.language.Term`
16impl Term {
17    /// 模拟`Term.getName`
18    /// * 🆕使用自身内建的「获取名称」方法
19    ///   * 相较OpenNARS更**短**
20    ///   * 仍能满足OpenNARS的需求
21    /// * 🎯OpenNARS原有需求
22    ///   * 📌保证「词项不同 ⇔ 名称不同」
23    ///   * 📌保证「可用于『概念』『记忆区』的索引」
24    ///
25    /// # 📄OpenNARS
26    ///
27    /// Reporting the name of the current Term.
28    ///
29    /// @return The name of the term as a String
30    #[doc(alias = "get_name")]
31    pub fn name(&self) -> String {
32        self.format_name()
33    }
34
35    // * ✅`is_constant`已在别处定义
36    // * ✅`is_placeholder`已在别处定义
37
38    /// 模拟`Term.getComplexity`
39    /// * 🚩逻辑 from OpenNARS
40    ///   * 原子 ⇒ 1
41    ///   * ~~变量 ⇒ 0~~
42    ///   * 复合 ⇒ 1 + 所有组分复杂度之和
43    ///
44    /// # 📄OpenNARS
45    ///
46    /// - The syntactic complexity, for constant atomic Term, is 1.
47    /// - The complexity of the term is the sum of those of the components plus 1
48    /// - ~~The syntactic complexity of a variable is 0, because it does not refer to * any concept.~~
49    ///
50    /// @return The complexity of the term, an integer
51    #[doc(alias = "get_complexity")]
52    pub fn complexity(&self) -> usize {
53        // 剩余类型
54        use TermComponents::*;
55        match self.components() {
56            // 占位符 ⇒ 0
57            Empty => 0,
58            // 原子/变量 ⇒ 1 | 不包括「变量」
59            // * 🚩目前遵照更新的PyNARS设置,将「变量词项」的复杂度定为1
60            Word(..) | Variable(..) => 1,
61            // 多元 ⇒ 1 + 内部所有词项复杂度之和
62            Compound(terms) => 1 + terms.iter().map(Term::complexity).sum::<usize>(),
63        }
64    }
65
66    /// 🆕判断是否为「零复杂度」
67    /// * 🎯用于部分「除以复杂度」的函数
68    #[doc(alias = "zero_complexity")]
69    pub fn is_zero_complexity(&self) -> bool {
70        self.complexity() == 0
71    }
72
73    /// 🆕用于替代Java的`x.getClass() == y.getClass()`
74    #[inline(always)]
75    pub fn is_same_type(&self, other: &Self) -> bool {
76        self.identifier() == other.identifier()
77    }
78}
79
80impl GetCategory for Term {
81    fn get_category(&self) -> TermCategory {
82        use TermCategory::*;
83        match self.identifier() {
84            // * 🚩原子:词语、占位符、变量
85            WORD | PLACEHOLDER | VAR_INDEPENDENT | VAR_DEPENDENT | VAR_QUERY => Atom,
86            // * 🚩陈述:继承、相似、蕴含、等价 | ❌不包括「实例」「属性」「实例属性」
87            INHERITANCE_RELATION | IMPLICATION_RELATION | SIMILARITY_RELATION
88            | EQUIVALENCE_RELATION => Statement,
89            // * 🚩一元:否定
90            NEGATION_OPERATOR |
91            // * 🚩二元序列:差集
92            DIFFERENCE_EXT_OPERATOR | DIFFERENCE_INT_OPERATOR |
93            // * 🚩多元序列:乘积、像
94            PRODUCT_OPERATOR | IMAGE_EXT_OPERATOR | IMAGE_INT_OPERATOR |
95            // * 🚩多元集合:词项集、交集、合取、析取
96            SET_EXT_OPERATOR
97            | SET_INT_OPERATOR
98            | INTERSECTION_EXT_OPERATOR
99            | INTERSECTION_INT_OPERATOR
100            | CONJUNCTION_OPERATOR
101            | DISJUNCTION_OPERATOR => Compound,
102            // * 🚩其它⇒panic(不应出现)
103            id => panic!("Unexpected compound term identifier: {id}"),
104        }
105    }
106}
107
108/// 单元测试
109#[cfg(test)]
110mod tests {
111    use super::*;
112    use crate::test_term as term;
113    use crate::{ok, util::AResult};
114    use nar_dev_utils::{asserts, macro_once};
115
116    #[test]
117    fn name() -> AResult {
118        macro_once! {
119            // * 🚩模式:词项字符串 ⇒ 预期
120            macro fmt($($term:literal => $expected:expr)*) {
121                asserts! {$(
122                    term!($term).to_string() => $expected
123                )*}
124            }
125            // 占位符
126            "_" => "_"
127            // 原子词项
128            "A" => "A"
129            "$A" => "$1" // ! 🚩【2024-06-13 19:02:58】现在对「变量词项」会自动重命名
130            "#A" => "#1" // ! 🚩【2024-06-13 19:02:58】现在对「变量词项」会自动重命名
131            "?A" => "?1" // ! 🚩【2024-06-13 19:02:58】现在对「变量词项」会自动重命名
132            // 复合词项
133            "{A, B}" => "{}(A B)"
134            "[A, B]" => "[](A B)"
135            "(&, A, B)" => "&(A B)"
136            "(|, A, B)" => "|(A B)"
137            "(-, A, B)" => "(A - B)"
138            "(~, A, B)" => "(A ~ B)"
139            "(*, A, B)" => "*(A B)"
140            r"(/, R, _)" => r"/(R _)"
141            r"(\, R, _)" => r"\(R _)"
142            r"(/, R, _, A)" => r"/(R _ A)"
143            r"(\, R, _, A)" => r"\(R _ A)"
144            r"(&&, A, B)" => r"&&(A B)"
145            r"(||, A, B)" => r"||(A B)"
146            r"(--, A)" => r"(-- A)"
147            // 陈述
148            "<A --> B>" => "(A --> B)"
149            "<A <-> B>" => "(A <-> B)"
150            "<A ==> B>" => "(A ==> B)"
151            "<A <=> B>" => "(A <=> B)"
152            // ! 自动排序
153            "<B <-> A>" => "(A <-> B)"
154            "<B <=> A>" => "(A <=> B)"
155            // ! 变量重命名
156            "(*, $e, #d, ?c, $b, #a)" => "*($1 #2 ?3 $4 #5)"
157            "(/, $e, #d, ?c, $b, #a, _)" => "/($1 #2 ?3 $4 #5 _)"
158        }
159        ok!()
160    }
161
162    #[test]
163    fn complexity() -> AResult {
164        macro_once! {
165            // * 🚩模式:词项字符串 ⇒ 预期
166            macro fmt($($term:literal => $expected:expr)*) {
167                asserts! {$(
168                    term!($term).complexity() => $expected
169                )*}
170            }
171            // 占位符
172            "_" => 0
173            // 词语
174            "A" => 1
175            // 变量
176            "$A" => 1 // ! 🚩【2024-06-14 00:28:01】现在遵照PyNARS等更新版本的做法
177            "#A" => 1
178            "?A" => 1
179            // 复合词项
180            "{A}" => 2
181            "[A]" => 2
182            "(-, A, B)" => 3
183            "(~, A, B)" => 3
184            "(&, A, B, C)" => 4
185            "(|, A, B, C)" => 4
186            "(*, A, B, C, D)" => 5
187            r"(/, R, _)" => 2
188            r"(\, R, _)" => 2
189            r"(/, R, _, A)" => 3
190            r"(\, R, _, A)" => 3
191            r"(&&, A, B)" => 3
192            r"(||, A, B)" => 3
193            r"(--, A)" => 2
194            r"(*, (*, A))" => 3
195            r"(*, (*, (*, A)))" => 4
196            // 陈述
197            "<A --> B>" => 3
198            "<A <-> B>" => 3
199            "<A ==> B>" => 3
200            "<A <=> B>" => 3
201            "<<A --> B> ==> X>" => 5
202            "<<A <-> B> <=> X>" => 5
203            "<<A --> B> ==> X>" => 5
204            "<<A <-> B> <=> X>" => 5
205            "<<A --> B> --> <C ==> D>>" => 7
206            "<<A <-> B> <-> <C <=> D>>" => 7
207            "<<A --> B> ==> <C ==> D>>" => 7
208            "<<A <-> B> <=> <C <=> D>>" => 7
209        }
210        ok!()
211    }
212
213    /// * 【2024-04-25 16:17:17】📌直接参照的`identifier`
214    #[test]
215    fn is_same_type() -> AResult {
216        macro_once! {
217            // * 🚩模式:词项字符串 ⇒ 预期
218            macro is_same_type($( $s:literal ~ $s2:literal => $id:expr )*) {
219                $(
220                    let term = term!($s);
221                    let term2 = term!($s2);
222                    assert!(term.is_same_type(&term2));
223                    assert_eq!(term.identifier(), $id);
224                    assert_eq!(term2.identifier(), $id);
225                )*
226            }
227            // 占位符
228            "_" ~ "_" => PLACEHOLDER
229            // 原子词项
230            "A" ~ "B" => WORD
231            "$A" ~ "$x" => VAR_INDEPENDENT
232            "#A" ~ "#1" => VAR_DEPENDENT
233            "?A" ~ "?question" => VAR_QUERY
234            // 复合词项
235            "{A}" ~ "{x, y, z}" => SET_EXT_OPERATOR
236            "[A]" ~ "[ㄚ, ㄛ, ㄜ]" => SET_INT_OPERATOR
237            "(&, A, B)" ~ "(&, x, y)" => INTERSECTION_EXT_OPERATOR
238            "(|, A, B)" ~ "(|, a, b)" => INTERSECTION_INT_OPERATOR
239            "(-, A, B)" ~ "(-, B, A)" => DIFFERENCE_EXT_OPERATOR
240            "(~, A, B)" ~ "(~, B, C)" => DIFFERENCE_INT_OPERATOR
241            "(*, A)" ~ "(*, α, β, γ)" => PRODUCT_OPERATOR
242            r"(/, R, _)" ~ r"(/, R, A, _, B)" => IMAGE_EXT_OPERATOR
243            r"(\, R, _)" ~ r"(\, R, A, B, _)" => IMAGE_INT_OPERATOR
244            r"(&&, A, B)" ~ r"(&&, X, Y, Z)" => CONJUNCTION_OPERATOR
245            r"(||, A, B)" ~ r"(||, (||, A, B), C)" => DISJUNCTION_OPERATOR
246            r"(--, A)" ~ r"(--, (~, B, A))" => NEGATION_OPERATOR
247            // 陈述
248            "<A --> B>" ~ "<<B ==> C> --> A>" => INHERITANCE_RELATION
249            "<A <-> B>" ~ "<<B <=> C> <-> A>" => SIMILARITY_RELATION
250            "<A ==> B>" ~ "<<B --> C> ==> A>" => IMPLICATION_RELATION
251            "<A <=> B>" ~ "<<B <-> C> <=> A>" => EQUIVALENCE_RELATION
252        }
253        ok!()
254    }
255}