narust_158/language/conversion/
into.rs

1//! 词项→其它类型
2
3use super::super::base::*;
4use crate::symbols::*;
5use nar_dev_utils::*;
6use narsese::{
7    api::{FormatTo, GetCapacity},
8    lexical::Term as TermLexical,
9};
10
11/// 词项⇒字符串
12/// * 🎯用于更好地打印「词项」名称
13/// * 🎯用于从「词法Narsese」中解析
14///   * 考虑「变量语义」
15impl Term {
16    /// 格式化名称
17    /// * 🚩以方便打印的「内部方言语法」呈现Narsese
18    ///   * 📌括号全用 圆括号
19    ///   * 📌无逗号分隔符
20    pub fn format_name(&self) -> String {
21        // 格式化所用常量
22        const OPENER: &str = "(";
23        const CLOSER: &str = ")";
24        const SEPARATOR: &str = " ";
25
26        use narsese::api::TermCapacity::*;
27        use TermComponents::*;
28        let id = self.identifier();
29        match self.components() {
30            // 空组分
31            Empty => id.to_string(),
32            // 名称 | 原子词项
33            Word(name) => format!("{id}{name}"),
34            // 名称 | 变量词项
35            Variable(n) => format!("{id}{n}"),
36            Compound(terms) => {
37                match self.get_capacity() {
38                    // 一元
39                    Unary => {
40                        // 📄 "(-- A)"
41                        manipulate!(
42                            String::new()
43                            => {+= OPENER}#
44                            => {+= id}#
45                            => {+= SEPARATOR}#
46                            => {+= &terms[0].format_name()}#
47                            => {+= CLOSER}#
48                        )
49                    }
50                    // 二元
51                    BinaryVec | BinarySet => {
52                        // 📄 "(A --> B)"
53                        manipulate!(
54                            String::new()
55                            => {+= OPENER}#
56                            => {+= &terms[0].format_name()}#
57                            => {+= SEPARATOR}#
58                            => {+= id}#
59                            => {+= SEPARATOR}#
60                            => {+= &terms[1].format_name()}#
61                            => {+= CLOSER}#
62                        )
63                    }
64                    // 多元
65                    Vec | Set => {
66                        let mut s = id.to_string() + OPENER;
67                        let mut terms = terms.iter();
68                        if let Some(t) = terms.next() {
69                            s += &t.format_name();
70                        }
71                        for t in terms {
72                            s += SEPARATOR;
73                            s += &t.format_name();
74                        }
75                        s + CLOSER
76                    }
77                    Atom => unreachable!("复合词项只可能是「一元」「二元」或「多元」"),
78                }
79            }
80        }
81    }
82
83    /// 从「内部Narsese」转换为「词法Narsese」
84    /// * 🚩基本无损转换(无需考虑失败情况)
85    pub fn to_lexical(&self) -> TermLexical {
86        use TermComponents::*;
87        type LTerm = TermLexical;
88        let (id, comp) = self.id_comp();
89        match (id, comp) {
90            // 专用 / 集合词项 | 默认已排序
91            (SET_EXT_OPERATOR, Compound(v)) => {
92                let v = v.iter().map(Self::to_lexical).collect::<Vec<_>>();
93                LTerm::new_set(SET_EXT_OPENER, v, SET_EXT_CLOSER)
94            }
95            (SET_INT_OPERATOR, Compound(v)) => {
96                let v = v.iter().map(Self::to_lexical).collect::<Vec<_>>();
97                LTerm::new_set(SET_INT_OPENER, v, SET_INT_CLOSER)
98            }
99            //  陈述
100            (
101                INHERITANCE_RELATION | SIMILARITY_RELATION | IMPLICATION_RELATION
102                | EQUIVALENCE_RELATION,
103                Compound(terms),
104            ) if terms.len() == 2 => {
105                LTerm::new_statement(id, (&terms[0]).into(), (&terms[1]).into())
106            }
107            // 通用 / 空:仅前缀
108            (_, Empty) => LTerm::new_atom(id, ""),
109            // 通用 / 具名:前缀+词项名
110            (_, Word(name)) => LTerm::new_atom(id, name),
111            // 通用 / 变量:前缀+变量编号
112            (_, Variable(num)) => LTerm::new_atom(id, num.to_string()),
113            // 通用 / 多元
114            (_, Compound(terms)) => {
115                LTerm::new_compound(id, terms.iter().map(Self::to_lexical).collect())
116            }
117        }
118    }
119
120    /// 转换为显示呈现上的ASCII格式
121    /// * 📌对标OpenNARS的默认呈现
122    /// * ⚠️【2024-07-02 00:52:54】目前需要「词法Narsese」作为中间格式,可能会有性能损失
123    #[doc(alias = "to_display_ascii")]
124    pub fn format_ascii(&self) -> String {
125        use narsese::conversion::string::impl_lexical::format_instances::FORMAT_ASCII;
126        self.to_lexical().format_to(&FORMAT_ASCII)
127    }
128}
129
130// * 🚩此处的「变量词项」一开始就应该是个数值,从「具名变量」变为「数字变量」
131/// 词项⇒词法Narsese
132impl From<&Term> for TermLexical {
133    fn from(term: &Term) -> Self {
134        term.to_lexical()
135    }
136}
137
138impl From<TermComponents> for Vec<Term> {
139    /// 将「词项组分」转换为「可变数组<词项>」
140    /// * 🚩原子词项⇒空数组
141    /// * 🚩复合词项⇒其内所有词项构成的数组
142    fn from(value: TermComponents) -> Self {
143        use TermComponents::*;
144        match value {
145            Empty | Word(..) | Variable(..) => vec![],
146            Compound(terms) => terms.into(),
147        }
148    }
149}
150
151impl From<TermComponents> for Box<[Term]> {
152    /// 将「词项组分」转换为「定长数组<词项>」
153    /// * 🚩原子词项⇒空数组
154    /// * 🚩复合词项⇒其内所有词项构成的数组
155    /// * ℹ️与上述对[`Vec`]的转换不同:此处直接使用`Box::new([])`构造空数组
156    fn from(value: TermComponents) -> Self {
157        use TermComponents::*;
158        match value {
159            Empty | Word(..) | Variable(..) => Box::new([]),
160            Compound(terms) => terms,
161        }
162    }
163}