narust_158/language/features/statement.rs
1//! 📄OpenNARS `nars.language.Statement`
2//! * 📌NAL底层的「陈述」逻辑,对应`Statement`及其所有子类
3//! * ⚠️不包括与记忆区有关的`make`系列方法
4//! * ⚠️不包括只和语法解析有关的`isRelation`、`makeName`、`makeStatementName`等方法
5//! * ✅【2024-06-14 14:53:10】基本完成方法复刻
6//!
7//! # 方法列表
8//! 🕒最后更新:【2024-06-14 14:53:18】
9//!
10//! * `Statement`
11//! * `invalidStatement` => `is_invalid_statement`
12//! * `invalidReflexive`
13//! * `invalidPair`
14//! * `invalid`
15//! * `getSubject`
16//! * `getPredicate`
17//!
18//! # 📄OpenNARS
19//!
20//! A statement is a compound term, consisting of a subject, a predicate, and a relation symbol in between.
21//! It can be of either first-order or higher-order.
22
23use super::compound_term::CompoundTermRef;
24use crate::language::*;
25use crate::symbols::*;
26use nar_dev_utils::{if_return, matches_or};
27use std::{
28 fmt::{Display, Formatter},
29 ops::{Deref, DerefMut},
30};
31
32impl Term {
33 /// 🆕用于判断是否为「陈述词项」
34 /// * 📄OpenNARS `instanceof Statement` 逻辑
35 #[inline(always)]
36 pub fn instanceof_statement(&self) -> bool {
37 Self::is_statement_identifier(self.identifier())
38 }
39
40 /// 🆕抽象出来的「标识符(对应的词项类型)是否『可交换』」
41 /// * 🎯同时用于「词项属性」与「词项转换」
42 /// * 📄参见[`super::_dialect`]中的`reform_term`函数
43 pub fn is_statement_identifier(identifier: &str) -> bool {
44 matches!(
45 identifier,
46 // 四大主要系词
47 INHERITANCE_RELATION
48 | SIMILARITY_RELATION
49 | IMPLICATION_RELATION
50 | EQUIVALENCE_RELATION
51 // ↓下边都是派生系词(实际上不会出现,OpenNARS也一样)
52 | INSTANCE_RELATION
53 | PROPERTY_RELATION
54 | INSTANCE_PROPERTY_RELATION
55 )
56 }
57
58 /// 🆕用于判断是否为「继承」
59 /// * 📄OpenNARS`instanceof Inheritance`逻辑
60 /// * 📝OpenNARS中「继承」与「实例」「属性」「实例属性」没有继承关系
61 /// * 🎯[`crate::inference::RuleTables`]推理规则分派
62 #[inline(always)]
63 pub fn instanceof_inheritance(&self) -> bool {
64 self.identifier() == INHERITANCE_RELATION
65 }
66
67 /// 🆕用于判断是否为「相似」
68 /// * 📄OpenNARS`instanceof Similarity`逻辑
69 /// * 🎯[`crate::inference::RuleTables`]推理规则分派
70 #[inline(always)]
71 pub fn instanceof_similarity(&self) -> bool {
72 self.identifier() == SIMILARITY_RELATION
73 }
74
75 /// 🆕用于判断是否为「蕴含」
76 /// * 📄OpenNARS`instanceof Implication`逻辑
77 /// * 🎯[`crate::inference::RuleTables`]推理规则分派
78 #[inline(always)]
79 pub fn instanceof_implication(&self) -> bool {
80 self.identifier() == IMPLICATION_RELATION
81 }
82
83 /// 🆕用于判断是否为「等价」
84 /// * 📄OpenNARS`instanceof Equivalence`逻辑
85 /// * 🎯[`crate::inference::RuleTables`]推理规则分派
86 #[inline(always)]
87 pub fn instanceof_equivalence(&self) -> bool {
88 self.identifier() == EQUIVALENCE_RELATION
89 }
90
91 /// 🆕判断一个词项是否为「陈述词项」
92 /// * 🚩判断其「内部元素」的个数是否为2,并且要判断其标识符
93 /// * 🚩【2024-09-07 14:59:00】现在采用更严格的条件——需要判断是否为「陈述系词」
94 pub fn is_statement(&self) -> bool {
95 self.instanceof_statement()
96 && matches!(self.components(), TermComponents::Compound(terms) if terms.len() == 2)
97 }
98
99 /// 🆕将一个复合词项转换为「陈述词项」(不可变引用)
100 /// * 🚩转换为Option
101 /// * 🚩【2024-09-07 14:59:00】现在采用更严格的条件——需要判断是否为「陈述系词」
102 #[must_use]
103 pub fn as_statement(&self) -> Option<StatementRef> {
104 matches_or!(
105 ?self.components(),
106 TermComponents::Compound(ref terms)
107 if self.instanceof_statement() && terms.len() == 2
108 => StatementRef {
109 statement: self,
110 subject: &terms[0],
111 predicate: &terms[1],
112 }
113 )
114 }
115
116 /// 🆕用于判断词项是否为「指定类型的复合词项」,并尝试返回「复合词项」的引用信息
117 /// * 📌包括陈述
118 /// * 🚩模式匹配后返回一个[`Option`],只在其为「符合指定类型的词项」时为[`Some`]
119 /// * 🚩返回不可变引用
120 #[must_use]
121 pub fn as_statement_type(&self, statement_class: impl AsRef<str>) -> Option<StatementRef> {
122 matches_or! {
123 ?self.as_statement(),
124 Some(statement)
125 // * 🚩标识符相等
126 if statement_class.as_ref() == self.identifier()
127 // * 🚩内部(类型相等)的复合词项
128 => statement
129 }
130 }
131
132 /// 🆕将一个复合词项转换为「陈述词项」(可变引用)
133 /// * 🚩转换为Option
134 #[must_use]
135 pub fn as_statement_mut(&mut self) -> Option<StatementRefMut> {
136 matches_or!(
137 ?self.components_mut(),
138 TermComponents::Compound(ref mut terms) if terms.len() == 2
139 => StatementRefMut {
140 // * 🚩均转换为裸指针
141 subject: &mut terms[0] as *mut Term,
142 predicate: &mut terms[1] as *mut Term,
143 statement: self,
144 }
145 )
146 }
147
148 /// 🆕用于判断词项是否为「陈述」并解包其中的主项和谓项
149 /// * 🚩模式匹配后返回一个[`Option`],只在其为「符合指定类型的词项」时为[`Some`]
150 /// * 🚩返回内部所有元素的所有权
151 #[must_use]
152 pub fn unwrap_statement_components(self) -> Option<[Term; 2]> {
153 matches_or! {
154 ?self.unwrap_compound_components(),
155 // * 🚩匹配到(语句所作为的)复合词项,同时长度合规
156 Some(terms) if terms.len() == 2
157 // * 🚩返回内容
158 => {
159 // ? 💭后续或许能提取出一个统一的逻辑
160 let mut terms = terms.into_vec();
161 let predicate = terms.pop().expect("已经假定了长度为2");
162 let subject = terms.pop().expect("已经假定了长度为2");
163 [subject, predicate]
164 }
165 }
166 }
167
168 /// 🆕用于判断词项是否为「陈述」并解包其中的主项、系词和谓项
169 /// * 🚩模式匹配后返回一个[`Option`],只在其为「符合指定类型的词项」时为[`Some`]
170 /// * 🚩返回标识符与内部所有元素的所有权
171 #[must_use]
172 pub fn unwrap_statement_id_components(self) -> Option<(Term, String, Term)> {
173 matches_or! {
174 ?self.unwrap_compound_id_components(),
175 // * 🚩匹配到(语句所作为的)复合词项,同时长度合规
176 Some((copula, terms)) if terms.len() == 2
177 // * 🚩返回内容
178 => {
179 // ? 💭后续或许能提取出一个统一的逻辑
180 let mut terms = terms.into_vec();
181 let predicate = terms.pop().expect("已经假定了长度为2");
182 let subject = terms.pop().expect("已经假定了长度为2");
183 (subject, copula, predicate)
184 }
185 }
186 }
187
188 /// 🆕用于判断词项是否为「指定类型的陈述」,并解包其中的主项和谓项
189 /// * 🚩模式匹配后返回一个[`Option`],只在其为「符合指定类型的词项」时为[`Some`]
190 /// * 🚩返回内部所有元素的所有权
191 #[must_use]
192 pub fn unwrap_statement_type_components(
193 self,
194 statement_class: impl AsRef<str>,
195 ) -> Option<[Term; 2]> {
196 matches_or! {
197 ?self.unwrap_compound_type_components(statement_class),
198 // * 🚩匹配到(语句所作为的)复合词项,同时长度合规
199 Some(terms) if terms.len() == 2
200 // * 🚩返回内容
201 => {
202 // ? 💭后续或许能提取出一个统一的逻辑
203 let mut terms = terms.into_vec();
204 let predicate = terms.pop().expect("已经假定了长度为2");
205 let subject = terms.pop().expect("已经假定了长度为2");
206 [subject, predicate]
207 }
208 }
209 }
210}
211
212/// 为「复合词项」添加「转换到陈述」的方法
213/// * 📌依据:陈述 ⊂ 复合词项
214impl<'s> CompoundTermRef<'s> {
215 /// 🆕判断一个复合词项是否为「陈述词项」
216 /// * 🚩判断其「内部元素」的个数是否为2
217 /// * 📌与[`Term::is_statement`]一致
218 pub fn is_statement(&self) -> bool {
219 self.components.len() == 2
220 }
221
222 /// 🆕将一个复合词项转换为「陈述词项」(不可变引用)
223 /// * 🚩转换为Option
224 /// * 📌与[`Term::as_statement`]一致
225 pub fn as_statement(self) -> Option<StatementRef<'s>> {
226 matches_or!(
227 ?self.components,
228 [ref subject, ref predicate]
229 => StatementRef {
230 statement: self.inner,
231 subject,
232 predicate,
233 }
234 )
235 }
236
237 // ! ❌【2024-06-14 14:47:26】没必要添加一个额外的`unchecked`方法:可以使用`unwrap`现场解包
238}
239
240/// 为「复合词项」添加「转换到陈述」的方法(可变引用)
241/// * 📌依据:陈述 ⊂ 复合词项
242impl CompoundTermRefMut<'_> {
243 /// 🆕将一个复合词项转换为「陈述词项」(可变引用)
244 /// * 🚩转换为Option
245 /// * 📌与[`Term::as_statement`]一致
246 pub fn as_statement(&mut self) -> Option<StatementRef> {
247 matches_or!(
248 // * 📝此处必须内联`self.components()`,以告诉借用检查器「并非使用整个结构」
249 // ! SAFETY: 此处保证对整体(整个复合词项)拥有引用
250 ? unsafe { &mut *self.components },
251 [ref mut subject, ref mut predicate]
252 => StatementRef {
253 statement: self.inner,
254 subject,
255 predicate,
256 }
257 )
258 }
259
260 // ! ❌【2024-06-14 14:47:26】没必要添加一个额外的`unchecked`方法:可以使用`unwrap`现场解包
261}
262
263/// 🆕作为「陈述引用」的词项类型
264/// * 🎯在程序类型层面表示一个「陈述」(不可变引用)
265#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
266pub struct StatementRef<'a> {
267 /// 陈述词项本身
268 pub statement: &'a Term,
269 /// 陈述词项的主项
270 pub subject: &'a Term,
271 /// 陈述词项的谓项
272 pub predicate: &'a Term,
273}
274
275impl<'s> StatementRef<'s> {
276 /// 📄OpenNARS `getSubject`
277 ///
278 /// # 📄OpenNARS
279 ///
280 /// 🈚
281 pub fn subject(&self) -> &'s Term {
282 self.subject
283 }
284
285 /// 📄OpenNARS `getPredicate`
286 ///
287 /// # 📄OpenNARS
288 ///
289 /// 🈚
290 pub fn predicate(&self) -> &'s Term {
291 self.predicate
292 }
293
294 /// 🆕主项-谓项 二元数组
295 pub fn sub_pre(&self) -> [&'s Term; 2] {
296 [self.subject, self.predicate]
297 }
298
299 /// 📄OpenNARS `invalidStatement`
300 /// * ⚠️必须是「陈述」才能调用
301 /// * 🎯检查「无效陈述」
302 /// * 🎯基于AIKR,避免定义无用、冗余的陈述
303 /// * 📄如「永远成立」的「重言式」tautology
304 /// * 📌无效案例:
305 /// * `<A --> A>`
306 /// * `<A --> [A]>`
307 /// * `<[A] --> A>`
308 /// * `<<A --> B> ==> <B --> A>>`
309 ///
310 /// # 📄OpenNARS
311 ///
312 /// Check the validity of a potential Statement. [To be refined]
313 pub fn invalid_statement(subject: &Term, predicate: &Term) -> bool {
314 if_return! {
315 // 重言式⇒无效
316 subject == predicate => true
317 //自反性检查(双向)
318 Self::invalid_reflexive(subject, predicate) => true
319 Self::invalid_reflexive(predicate, subject) => true
320 }
321 // 都是陈述⇒进一步检查
322 matches_or! {
323 (subject.as_statement(), predicate.as_statement()),
324 // 获取各自的主词、谓词,并检查是否相等
325 // ! 禁止如下格式: <<A --> B> ==> <B --> A>>
326 // * 📄ERR: !!! INVALID INPUT: parseTerm: <<A --> B> ==> <B --> A>> --- invalid statement
327 // ? 💭【2024-04-24 15:04:44】目前尚未明确含义,可能是防止「重复推导」
328 /* 📄OpenNARS源码:
329 if ((subject instanceof Statement) && (predicate instanceof Statement)) {
330 Statement s1 = (Statement) subject;
331 Statement s2 = (Statement) predicate;
332 Term t11 = s1.getSubject();
333 Term t12 = s1.getPredicate();
334 Term t21 = s2.getSubject();
335 Term t22 = s2.getPredicate();
336 if (t11.equals(t22) && t12.equals(t21)) {
337 return true;
338 }
339 } */
340 (
341 Some(StatementRef { subject:ss, predicate:sp,.. }),
342 Some(StatementRef { subject:ps, predicate:pp,.. })
343 ) if ss == pp && sp == ps => return true,
344 () // 无效案例⇒继续检查
345 }
346 // 检查完毕⇒否
347 false
348 }
349
350 /// 📄OpenNARS `invalidReflexive`
351 /// * 🚩主词项是「非像复合词项」并且包括另一词项
352 /// * 📄`<A <-> {A}>`
353 /// * 📄`<A ==> (*, B, C, A)>`
354 ///
355 /// # 📄OpenNARS
356 ///
357 /// Check if one term is identical to or included in another one, except in a reflexive relation
358 pub fn invalid_reflexive(may_container: &Term, may_component: &Term) -> bool {
359 /* 📄OpenNARS源码:
360 if (!(t1 instanceof CompoundTerm)) {
361 return false;
362 }
363 CompoundTerm com = (CompoundTerm) t1;
364 if ((com instanceof ImageExt) || (com instanceof ImageInt)) {
365 return false;
366 }
367 return com.containComponent(t2);
368 */
369 /* 📝原样转译的Rust代码:
370 if_return! {
371 !container.instanceof_compound() => false
372 container.instanceof_image() => false
373 }
374 container.contain_component(maybe_component)
375 */
376 // 筛查词项类型:复合词项
377 // ! 仅在复合词项时继续检查
378 if let Some(compound) = may_container.as_compound() {
379 // 筛查词项类型
380 if_return! {
381 compound.inner.instanceof_image() => false
382 }
383 // 若包含词项,则为「无效」
384 return compound.contain_component(may_component);
385 }
386 // 非复合词项⇒通过
387 false
388 }
389
390 /// 📄OpenNARS `invalidPair`
391 /// * 📝总体逻辑:是否「一边包含独立变量,而另一边不包含」
392 /// * 💭可能是要「避免自由变量」
393 /// * 🚩两边「包含独立变量」的情况不一致
394 ///
395 /// # 📄OpenNARS
396 ///
397 /// 🈚
398 pub fn invalid_pair(subject: &Term, predicate: &Term) -> bool {
399 /* 📄OpenNARS源码:
400 if (Variable.containVarI(s1) && !Variable.containVarI(s2)) {
401 return true;
402 } else if (!Variable.containVarI(s1) && Variable.containVarI(s2)) {
403 return true;
404 }
405 return false; */
406 subject.contain_var_i() != predicate.contain_var_i()
407 }
408
409 /// 📄OpenNARS `invalid`
410 ///
411 /// # 📄OpenNARS
412 ///
413 /// 🈚
414 pub fn invalid(&self) -> bool {
415 Self::invalid_statement(self.subject(), self.predicate())
416 }
417
418 /// 🆕作为「条件句」使用
419 /// * 🎯用于形如`<(&&, A, B) ==> C>`~~或`<(&&, A, B) <=> C>`~~的Narsese词项
420 /// * ~~📌同时兼容`<S <=> (&&, A, B)>`,即「合取不一定在第一个」~~
421 /// * ✨不仅可以判别,还可解包出其中的元素
422 /// * 🚩返回`(陈述自身, 第一个找到的合取词项引用, 这个合取词项所在位置索引)`
423 ///
424 /// ! ❌【2024-07-05 17:04:02】不再考虑支持「等价」陈述的词项链转换,同时也不再将「等价陈述」视作「条件句」
425 /// * 📌【2024-07-05 17:05:48】目前认知:「等价」陈述完全可以「先转换为蕴含,再参与条件推理」
426 ///
427 /// ## 📄OpenNARS 参考代码
428 ///
429 /// ```java
430 /// if (taskContent instanceof Equivalence)
431 /// throw new Error("【2024-07-05 17:03:18】简化代码:早已去掉「等价」系词的「复合条件」词项链!");
432 /// // ! ❌【2024-07-05 17:04:02】不再考虑支持「等价」陈述的词项链转换
433 /// final int conditionIndex = indices[0];
434 /// final Term contentCondition = taskContent.componentAt(conditionIndex);
435 /// // * 🚩判断「条件句」
436 /// // * 选取的「条件项」是「合取」
437 /// final boolean conditionCondition = contentCondition instanceof Conjunction;
438 /// // * 整体是「等价」或「合取在前头的『蕴含』」
439 /// final boolean conditionWhole = (taskContent instanceof Implication && conditionIndex == 0)
440 /// || taskContent instanceof Equivalence;
441 /// if (conditionSubject && conditionWhole) {
442 /// /* ... */
443 /// }
444 /// ```
445 pub fn as_conditional(self) -> Option<(StatementRef<'s>, CompoundTermRef<'s>)> {
446 // // * 🚩提取其中的继承项
447 // let subject = self.subject;
448 // let predicate = self.subject;
449
450 // // * 🚩判断「条件句」
451 // match self.identifier() {
452 // // * 主项是「合取」的「蕴含」
453 // IMPLICATION_RELATION => {
454 // let subject = subject.as_compound_type(CONJUNCTION_OPERATOR)?;
455 // Some((self, subject, 0))
456 // }
457 // // * 【任一处含有合取】的「等价」
458 // EQUIVALENCE_RELATION => {
459 // // * 🚩优先判断并提取主项
460 // if let Some(subject) = subject.as_compound_type(CONJUNCTION_OPERATOR) {
461 // return Some((self, subject, 0));
462 // }
463 // if let Some(predicate) = predicate.as_compound_type(CONJUNCTION_OPERATOR) {
464 // return Some((self, predicate, 1));
465 // }
466 // None
467 // }
468 // // * 其它⇒空
469 // _ => None,
470 // }
471
472 // * 🚩蕴含 | 【2024-07-05 17:08:34】现在只判断「蕴含」陈述
473 if !self.instanceof_implication() {
474 return None;
475 }
476 // * 🚩主项是合取
477 let subject_conjunction = self.subject.as_compound_type(CONJUNCTION_OPERATOR)?;
478 // * 🚩返回
479 Some((self, subject_conjunction))
480 }
481
482 /// 转换为「复合词项引用」
483 /// * 🎯不通过额外的「类型判断」(从[`DerefMut`]中来)转换为「复合词项引用」
484 /// * ❌【2024-06-15 16:37:07】危险:不能在此【只传引用】,否则将能在「拿出引用」的同时「使用自身」
485 /// * 📝因此不能实现`Deref<Target = CompoundTermRef>`
486 pub fn into_compound_ref(self) -> CompoundTermRef<'s> {
487 debug_assert!(self.is_statement());
488 // SAFETY: 保证「陈述词项」一定从「复合词项」中来
489 unsafe { self.statement.as_compound_unchecked() }
490 }
491}
492
493/// 转发「呈现」方法到「内部词项」
494impl Display for StatementRef<'_> {
495 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
496 self.statement.fmt(f)
497 }
498}
499
500/// 向词项本身的自动解引用
501/// * 🎯让「陈述引用」可以被看作是一个普通的词项
502impl Deref for StatementRef<'_> {
503 type Target = Term;
504
505 fn deref(&self) -> &Self::Target {
506 self.statement
507 }
508}
509
510/// 🆕作为「陈述引用」的词项类型
511/// * 🎯在程序类型层面表示一个「陈述」(可变引用)
512/// * 📝【2024-06-15 17:08:26】目前「陈述可变引用」用处不大
513/// * 📄OpenNARS中没有与之相关的独有方法(`Statement`类中没有可变的方法)
514#[derive(Debug, PartialEq, Eq, Hash)]
515pub struct StatementRefMut<'a> {
516 /// 陈述词项本身
517 statement: &'a mut Term,
518 /// 陈述词项的主项
519 subject: *mut Term,
520 /// 陈述词项的谓项
521 predicate: *mut Term,
522}
523
524impl<'a> StatementRefMut<'a> {
525 /// 获取陈述整体
526 #[doc(alias = "inner")]
527 pub fn statement(self) -> &'a mut Term {
528 self.statement
529 }
530
531 /// 🆕同时获取「主项」与「谓项」的可变引用
532 /// * ⚠️此处对裸指针解引用
533 /// * 📄安全性保证同[`CompoundTermRefMut::components`]
534 /// * 🎯获取陈述的主谓项,在这之后对齐进行变量替换
535 pub fn sub_pre(&mut self) -> [&'a mut Term; 2] {
536 // SAFETY: 同[`Compound::components`]
537 unsafe { [&mut *self.subject, &mut *self.predicate] }
538 }
539
540 /// 📄OpenNARS `getSubject`
541 /// # 📄OpenNARS
542 ///
543 /// 🈚
544 pub fn subject(&mut self) -> &'a mut Term {
545 let [sub, _] = self.sub_pre();
546 sub
547 }
548
549 /// 📄OpenNARS `getPredicate`
550 /// # 📄OpenNARS
551 ///
552 /// 🈚
553 pub fn predicate(&mut self) -> &'a mut Term {
554 let [_, pre] = self.sub_pre();
555 pre
556 }
557
558 /// 生成一个不可变引用
559 /// * 🚩将自身的所有字段转换为不可变引用,然后构造一个「不可变引用」结构
560 /// * 📌可变引用一定能转换成不可变引用
561 /// * ⚠️与[`AsRef`]与[`Deref`]不同:此处需要返回所有权,而非对目标类型([`Term`])的引用
562 /// * ❌返回`&CompoundTermRef`会导致「返回临时变量引用」故无法使用
563 /// * ❌【2024-06-15 16:37:07】危险:不能在此【只传引用】,否则将能在「拿出引用」的同时「使用自身」
564 pub fn into_ref<'s>(self) -> StatementRef<'s>
565 where
566 Self: 's,
567 {
568 // * 🚩解引用前(在debug模式下)检查
569 debug_assert!(self.statement.is_statement());
570 // * 🚩传递引用 & 裸指针解引用
571 StatementRef {
572 statement: self.statement,
573 // SAFETY: 自身相当于对词项的可变引用,同时所有字段均保证有效——那就一定能同时转换
574 subject: unsafe { &*self.subject },
575 // SAFETY: 自身相当于对词项的可变引用,同时所有字段均保证有效——那就一定能同时转换
576 predicate: unsafe { &*self.predicate },
577 }
578 }
579
580 /// 转换为「复合词项可变引用」
581 /// * 🎯不通过额外的「类型判断」(从[`DerefMut`]中来)转换为「复合词项可变引用」
582 /// * ❌【2024-06-15 16:37:07】危险:不能在此【只传引用】,否则将能在「拿出引用」的同时「使用自身」
583 pub fn into_compound_ref<'s>(self) -> CompoundTermRefMut<'s>
584 where
585 Self: 's,
586 {
587 debug_assert!(self.is_statement());
588 // SAFETY: 保证「陈述词项」一定从「复合词项」中来
589 unsafe { self.statement.as_compound_mut_unchecked() }
590 }
591}
592
593/// 转发「呈现」方法到「内部词项」
594impl Display for StatementRefMut<'_> {
595 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
596 self.statement.fmt(f)
597 }
598}
599
600/// 可变引用 ⇒ 不可变引用
601impl<'s> From<StatementRefMut<'s>> for StatementRef<'s> {
602 #[inline]
603 fn from(r: StatementRefMut<'s>) -> Self {
604 r.into_ref()
605 }
606}
607
608/// 陈述可变引用 ⇒ 复合词项可变引用
609impl<'s> From<StatementRefMut<'s>> for CompoundTermRefMut<'s> {
610 #[inline]
611 fn from(r: StatementRefMut<'s>) -> Self {
612 r.into_compound_ref()
613 }
614}
615
616/// 向词项本身的自动解引用
617/// * 🎯让「陈述可变引用」可以被看作是一个普通的词项
618/// * 📌【2024-06-15 15:08:55】安全性保证:在该引用结构使用「元素列表」时,独占引用不允许其再度解引用
619/// * ❌【2024-06-15 15:38:58】不能实现「自动解引用到不可变引用」
620impl Deref for StatementRefMut<'_> {
621 type Target = Term;
622
623 fn deref(&self) -> &Self::Target {
624 self.statement
625 }
626}
627
628/// 向词项本身的自动解引用
629/// * 🎯让「陈述可变引用」可以被看作是一个普通的词项(可变引用)
630/// * 📌【2024-06-15 15:08:55】安全性保证:在该引用结构使用「元素列表」时,独占引用不允许其再度解引用
631impl DerefMut for StatementRefMut<'_> {
632 fn deref_mut(&mut self) -> &mut Self::Target {
633 self.statement
634 }
635}
636
637/// 具备所有权的复合词项
638/// * 🎯初步决定用于「推理规则」向下分派
639#[derive(Debug, Clone, PartialEq, Eq, Hash)]
640pub struct Statement {
641 /// 内部词项
642 term: Term,
643}
644
645impl Statement {
646 /// 获取不可变引用
647 /// * 🚩【2024-07-10 23:51:54】此处使用[`Option::unwrap`]代替`unsafe`操作
648 pub fn get_ref(&self) -> StatementRef {
649 self.term.as_statement().unwrap()
650 }
651
652 /// 获取可变引用
653 /// * 🚩【2024-07-10 23:51:54】此处使用[`Option::unwrap`]代替`unsafe`操作
654 pub fn mut_ref(&mut self) -> StatementRefMut {
655 self.term.as_statement_mut().unwrap()
656 }
657
658 /// 🆕同时快捷获取`[主项, 谓项]`
659 /// * 🚩【2024-07-31 22:24:07】现场解包[`StatementRef`]中的引用,避免「临时对象dropped」
660 pub fn sub_pre(&self) -> [&Term; 2] {
661 let StatementRef {
662 subject, predicate, ..
663 } = self.get_ref();
664 [subject, predicate]
665 }
666
667 /// 🆕同时快捷获取`[主项, 谓项]`的可变引用
668 /// * 🎯用于场景「获取 主项/谓项,然后对齐进行变量替换」
669 pub fn sub_pre_mut(&mut self) -> [&mut Term; 2] {
670 self.mut_ref().sub_pre()
671 }
672
673 /// 解包为内部元素(主项、谓项)
674 /// * 🎯用于「推理规则」中的新词项生成
675 pub fn unwrap_components(self) -> [Term; 2] {
676 self.term.unwrap_statement_components().unwrap()
677 }
678
679 /// 解包为内部成分(主项、系词、谓项)
680 /// * 🎯用于「推理规则」中的新词项生成
681 pub fn unwrap(self) -> (Term, String, Term) {
682 self.term.unwrap_statement_id_components().unwrap()
683 }
684}
685
686/// 仅有的一处入口:从[词项](Term)构造
687impl TryFrom<Term> for Statement {
688 /// 转换失败时,返回原始词项
689 type Error = Term;
690
691 fn try_from(term: Term) -> Result<Self, Self::Error> {
692 // * 🚩仅在是复合词项时转换成功
693 match term.is_statement() {
694 true => Ok(Self { term }),
695 false => Err(term),
696 }
697 }
698}
699
700/// 出口(转换成词项)
701impl From<Statement> for Term {
702 fn from(value: Statement) -> Self {
703 value.term
704 }
705}
706
707/// 方便直接作为词项使用
708/// * ❓是否要滥用此种「类似继承的模式」
709impl Deref for Statement {
710 type Target = Term;
711
712 fn deref(&self) -> &Self::Target {
713 &self.term
714 }
715}
716
717/// 方便直接作为词项使用(可变)
718impl DerefMut for Statement {
719 fn deref_mut(&mut self) -> &mut Self::Target {
720 &mut self.term
721 }
722}
723
724/// 内联「显示呈现」
725impl Display for Statement {
726 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
727 self.term.fmt(f)
728 }
729}
730
731/// 陈述引用⇒陈述
732impl StatementRef<'_> {
733 /// 从「陈述引用」转换为陈述(获得所有权)
734 /// * ✅对于「陈述可变引用」可以先转换为「不可变引用」使用
735 pub fn to_owned(&self) -> Statement {
736 debug_assert!(self.statement.is_statement()); // 转换前检验是否为陈述类词项
737 Statement {
738 term: self.statement.clone(),
739 }
740 }
741}
742
743/// 单元测试
744#[cfg(test)]
745mod tests {
746 use super::*;
747 use crate::test_term as term;
748 use crate::{ok, util::AResult};
749 use nar_dev_utils::{asserts, macro_once};
750
751 macro_rules! statement {
752 // 具所有权/新常量
753 (box $term:literal) => {
754 statement!(box term!($term))
755 };
756 // 具所有权/原有变量
757 (box $term:expr) => {
758 Statement::try_from($term).unwrap()
759 };
760 // 可变引用/新常量
761 (mut $term:literal) => {
762 statement!(mut term!($term))
763 };
764 // 可变引用/原有变量
765 (mut $term:expr) => {
766 $term.as_statement_mut().unwrap()
767 };
768 // 不可变引用 解包
769 (unwrap $term:literal) => {
770 statement!(term!(unwrap $term))
771 };
772 // 不可变引用
773 ($term:literal) => {
774 statement!(term!($term))
775 };
776 // 不可变引用
777 ($term:expr) => {
778 $term.as_statement().unwrap()
779 };
780 }
781
782 /// 不可变引用
783 mod statement_ref {
784 use super::*;
785 use nar_dev_utils::fail_tests;
786
787 /// 陈述有效性
788 /// * 🎯一并测试
789 /// * `invalid`
790 /// * `invalid_statement`
791 /// * `invalid_reflexive`
792 /// * `invalid_pair`
793 #[test]
794 fn invalid() -> AResult {
795 asserts! {
796 // 合法
797 !statement!("<A --> B>").invalid()
798 !statement!("<A --> [B]>").invalid()
799 !statement!("<[A] --> B>").invalid()
800 !statement!("<<A --> B> ==> <B --> C>>").invalid()
801 !statement!("<<A --> B> ==> <C --> A>>").invalid()
802 !statement!("<<A --> B> ==> <C --> D>>").invalid()
803 }
804 ok!()
805 }
806
807 // ! 📌【2024-09-07 13:40:39】现在无效的词项本身就不能被构建
808 fail_tests! {
809 invalid_非陈述词项 statement!(unwrap "(*, A, B)"); // ! 📌【2024-09-07 15:00:45】二元复合词项本该不是陈述词项
810 invalid_重言式 term!(unwrap "<A --> A>");
811 invalid_被包含的重言式_主项包含谓项 term!(unwrap "<[A] --> A>");
812 invalid_被包含的重言式_谓项包含主项 term!(unwrap "<A --> [A]>");
813 invalid_蕴含重言式 term!(unwrap "<<A --> B> ==> <B --> A>>");
814 }
815
816 #[test]
817 fn subject_predicate() -> AResult {
818 macro_once! {
819 // * 🚩模式:陈述 ⇒ [主词, 谓词]
820 macro test($($statement:expr => [$subject:literal, $predicate:literal])*) {
821 asserts! {$(
822 statement!($statement).subject() => &term!($subject)
823 statement!($statement).predicate() => &term!($predicate)
824 )*}
825 }
826 "<A --> B>" => ["A", "B"]
827 "<あ ==> α>" => ["あ", "α"]
828 "<{SELF} --> [good]>" => ["{SELF}", "[good]"]
829 "<<a --> b> ==> {C}>" => ["<a --> b>", "{C}"]
830 "<$1 --> [2]>" => ["$1", "[2]"] // ! 变量词项可能会被重排编号
831 "<#2 --> {1}>" => ["#2", "{1}"] // ! 变量词项可能会被重排编号
832 "<(*, 1, 2, 3) ==> 4>" => ["(*, 1, 2, 3)", "4"]
833 // ! 实例、属性、实例属性 ⇒ 继承
834 "<A {-- B>" => ["{A}", "B"]
835 "<A --] B>" => [ "A", "[B]"]
836 "<A {-] B>" => ["{A}", "[B]"]
837 }
838 ok!()
839 }
840 }
841
842 /// 可变引用
843 mod statement_ref_mut {
844 use super::*;
845
846 #[test]
847 fn subject_predicate() -> AResult {
848 macro_once! {
849 // * 🚩模式:陈述 ⇒ [主词, 谓词]
850 macro test($($statement:expr => [$subject:literal, $predicate:literal])*) {
851 asserts! {$(
852 statement!(mut $statement).subject() => &term!($subject)
853 statement!(mut $statement).predicate() => &term!($predicate)
854 )*}
855 }
856 "<A --> B>" => ["A", "B"]
857 "<あ ==> α>" => ["あ", "α"]
858 "<{SELF} --> [good]>" => ["{SELF}", "[good]"]
859 "<<a --> b> ==> {C}>" => ["<a --> b>", "{C}"]
860 "<$1 --> [2]>" => ["$1", "[2]"] // ! 变量词项可能会被重排编号
861 "<#2 --> {1}>" => ["#2", "{1}"] // ! 变量词项可能会被重排编号
862 "<(*, 1, 2, 3) ==> 4>" => ["(*, 1, 2, 3)", "4"]
863 // ! 实例、属性、实例属性 ⇒ 继承
864 "<A {-- B>" => ["{A}", "B"]
865 "<A --] B>" => [ "A", "[B]"]
866 "<A {-] B>" => ["{A}", "[B]"]
867 }
868 ok!()
869 }
870
871 #[test]
872 fn to_ref() -> AResult {
873 fn test(mut term: Term) {
874 // * 🚩非陈述⇒返回 | 🎯检验「检验函数」
875 if !term.is_statement() {
876 return;
877 }
878 // * 🚩构建陈述的可变引用
879 let mut statement = term.as_statement_mut().expect("是陈述了还转换失败");
880 // * 🚩测试/Deref
881 assert!(!statement.as_statement().unwrap().invalid());
882 // * 🚩假定陈述有效
883 let (id, _) = statement.subject().id_comp_mut();
884 *id = "".into();
885 // * 🚩转换为不可变引用
886 let statement = statement.into_ref();
887 assert!(!statement.invalid());
888 }
889 macro_once! {
890 macro test($($term:expr)*) {
891 $(test(term!($term));)*
892 }
893 // !
894 "A"
895 "A"
896 }
897 ok!()
898 }
899 }
900 /// 具所有权
901 mod statement {
902 use super::*;
903 use std::str::FromStr;
904
905 /// 词项之间的类型转换
906 /// * 📄[`Term::try_into`] / [`Statement::try_from`]
907 /// * 📄[`Term::from`] / [`Statement::into`]
908 #[test]
909 fn from_into() -> AResult {
910 /// 通用测试函数
911 fn test(compound: Statement) {
912 // * 🚩首先是一个陈述
913 assert!(compound.is_compound());
914
915 // * 🚩从内部拷贝一个词项后,仍可无损转换为陈述
916 let term: Term = (*compound).clone();
917 let _: Statement = term.try_into().expect("应该是陈述!");
918
919 // * 🚩解包成普通词项后,仍可无损转换为陈述
920 let term: Term = compound.into();
921 let _: Statement = term.try_into().expect("应该是陈述!");
922 }
923 macro_once! {
924 // * 🚩模式:词项字符串 ⇒ 预期
925 macro test($( $term:literal )*) {$(
926 test(statement!(box $term));
927 )*}
928 // 单层
929 "<A --> B>"
930 "<A <-> B>"
931 "<A ==> B>"
932 "<A <=> B>"
933 // 组合
934 "<(*, A, B) --> P>"
935 "<(*, A, B) <-> P>"
936 "<(*, A, B) ==> P>"
937 "<(*, A, B) <=> P>"
938 "<S --> (*, A, B)>"
939 "<S <-> (*, A, B)>"
940 "<S ==> (*, A, B)>"
941 "<S <=> (*, A, B)>"
942 // 多层
943 "<X --> <A ==> B>>"
944 "<X <-> <A <=> B>>"
945 "<<A --> B> ==> X>"
946 "<<A <-> B> <=> X>"
947 "<<A ==> B> --> <C ==> D>>"
948 "<<A <=> B> <-> <C <=> D>>"
949 "<<A --> B> ==> <C --> D>>"
950 "<<A <-> B> <=> <C <-> D>>"
951 r"<(/, R, A, _) --> (\, R, _, B)>"
952 r"<(/, R, A, _) <-> (\, R, _, B)>"
953 r"<(/, R, A, _) ==> (\, R, _, B)>"
954 r"<(/, R, A, _) <=> (\, R, _, B)>"
955 }
956 ok!()
957 }
958
959 #[test]
960 fn get_ref() -> AResult {
961 /// 通用测试函数
962 fn test(statement: Statement) {
963 // * 🚩首先是一个陈述
964 assert!(statement.is_compound());
965
966 // * 🚩获取主谓项
967 let ref_statement = statement.get_ref();
968 let subject = ref_statement.subject();
969 let predicate = ref_statement.predicate();
970 println!("{statement} => [{subject}, {predicate}]");
971
972 // * 🚩遍历所有元素 as 复合词项
973 statement
974 .get_ref()
975 .components()
976 .iter()
977 .enumerate()
978 .for_each(|(i, component)| println!(" [{i}] => {component}"))
979 }
980 macro_once! {
981 // * 🚩模式:词项字符串 ⇒ 预期
982 macro test($( $term:literal )*) {$(
983 test(statement!(box $term));
984 )*}
985 // 单层
986 "<A --> B>"
987 "<A <-> B>"
988 "<A ==> B>"
989 "<A <=> B>"
990 // 组合
991 "<(*, A, B) --> P>"
992 "<(*, A, B) <-> P>"
993 "<(*, A, B) ==> P>"
994 "<(*, A, B) <=> P>"
995 "<S --> (*, A, B)>"
996 "<S <-> (*, A, B)>"
997 "<S ==> (*, A, B)>"
998 "<S <=> (*, A, B)>"
999 // 多层
1000 "<X --> <A ==> B>>"
1001 "<X <-> <A <=> B>>"
1002 "<<A --> B> ==> X>"
1003 "<<A <-> B> <=> X>"
1004 "<<A ==> B> --> <C ==> D>>"
1005 "<<A <=> B> <-> <C <=> D>>"
1006 "<<A --> B> ==> <C --> D>>"
1007 "<<A <-> B> <=> <C <-> D>>"
1008 r"<(/, R, A, _) --> (\, R, _, B)>"
1009 r"<(/, R, A, _) <-> (\, R, _, B)>"
1010 r"<(/, R, A, _) ==> (\, R, _, B)>"
1011 r"<(/, R, A, _) <=> (\, R, _, B)>"
1012 }
1013 ok!()
1014 }
1015
1016 #[test]
1017 fn mut_ref() -> AResult {
1018 /// 通用测试函数
1019 fn test(mut statement: Statement) -> AResult {
1020 // * 🚩首先是一个陈述
1021 assert!(statement.is_compound());
1022
1023 // * 🚩修改:更改主项
1024 let old_s = statement.to_string();
1025 let mut mut_ref = statement.mut_ref();
1026 let subject = mut_ref.subject();
1027 let x = term!("X");
1028 *subject = x.clone();
1029 println!("modification: {old_s:?} => \"{statement}\"");
1030 assert_eq!(*statement.get_ref().subject(), x); // 假定修改后的结果
1031
1032 // * 🚩修改:更改谓项
1033 let old_s = statement.to_string();
1034 let mut mut_ref = statement.mut_ref();
1035 let predicate = mut_ref.predicate();
1036 let y = term!("Y");
1037 *predicate = y.clone();
1038 println!("modification: {old_s:?} => \"{statement}\"");
1039 assert_eq!(*statement.get_ref().predicate(), y); // 假定修改后的结果
1040
1041 // * 🚩遍历修改所有元素
1042 statement
1043 .mut_ref()
1044 .into_compound_ref()
1045 .components()
1046 .iter_mut()
1047 .enumerate()
1048 .for_each(|(i, component)| {
1049 *component = Term::from_str(&format!("T{i}")).unwrap()
1050 });
1051 print!(" => \"{statement}\"");
1052
1053 ok!()
1054 }
1055 macro_once! {
1056 // * 🚩模式:词项字符串 ⇒ 预期
1057 macro test($( $term:literal )*) {$(
1058 test(statement!(box $term))?;
1059 )*}
1060 // 单层
1061 "<A --> B>"
1062 "<A <-> B>"
1063 "<A ==> B>"
1064 "<A <=> B>"
1065 // 组合
1066 "<(*, A, B) --> P>"
1067 "<(*, A, B) <-> P>"
1068 "<(*, A, B) ==> P>"
1069 "<(*, A, B) <=> P>"
1070 "<S --> (*, A, B)>"
1071 "<S <-> (*, A, B)>"
1072 "<S ==> (*, A, B)>"
1073 "<S <=> (*, A, B)>"
1074 // 多层
1075 "<X --> <A ==> B>>"
1076 "<X <-> <A <=> B>>"
1077 "<<A --> B> ==> X>"
1078 "<<A <-> B> <=> X>"
1079 "<<A ==> B> --> <C ==> D>>"
1080 "<<A <=> B> <-> <C <=> D>>"
1081 "<<A --> B> ==> <C --> D>>"
1082 "<<A <-> B> <=> <C <-> D>>"
1083 r"<(/, R, A, _) --> (\, R, _, B)>"
1084 r"<(/, R, A, _) <-> (\, R, _, B)>"
1085 r"<(/, R, A, _) ==> (\, R, _, B)>"
1086 r"<(/, R, A, _) <=> (\, R, _, B)>"
1087 }
1088 ok!()
1089 }
1090 }
1091}