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}