narust_158/language/base/
construct.rs1use super::structs::*;
4use crate::symbols::*;
5use anyhow::Result;
6use nar_dev_utils::*;
7
8impl Term {
9 fn new(identifier: impl Into<String>, components: TermComponents) -> Self {
13 Self {
14 identifier: identifier.into(),
15 components,
16 }
17 }
18
19 pub(super) fn new_word(name: impl Into<String>) -> Self {
25 Self::new(WORD, TermComponents::Word(name.into()))
26 }
27
28 pub(super) fn new_placeholder() -> Self {
34 Self::new(PLACEHOLDER, TermComponents::Empty)
35 }
36
37 fn new_var(identifier: impl Into<String>, id: impl Into<usize>) -> Self {
40 Self::new(identifier.into(), TermComponents::Variable(id.into()))
41 }
42
43 pub(super) fn new_var_i(id: impl Into<usize>) -> Self {
45 Self::new_var(VAR_INDEPENDENT, id.into())
46 }
47
48 pub(super) fn new_var_d(id: impl Into<usize>) -> Self {
50 Self::new_var(VAR_DEPENDENT, id.into())
51 }
52
53 pub(super) fn new_var_q(id: impl Into<usize>) -> Self {
55 Self::new_var(VAR_QUERY, id.into())
56 }
57
58 pub(in super::super) fn from_var_similar(
63 var_type: impl Into<String>,
64 new_id: impl Into<usize>,
65 ) -> Self {
66 Self::new_var(var_type, new_id)
67 }
68
69 pub(super) fn new_set_ext(terms: impl Into<Vec<Term>>) -> Self {
74 Self::new(SET_EXT_OPERATOR, TermComponents::new_multi(terms.into()))
75 }
76
77 pub(super) fn new_set_int(terms: impl Into<Vec<Term>>) -> Self {
80 Self::new(SET_INT_OPERATOR, TermComponents::new_multi(terms.into()))
81 }
82
83 pub(super) fn new_intersection_ext(terms: impl Into<Vec<Term>>) -> Self {
86 Self::new(
87 INTERSECTION_EXT_OPERATOR,
88 TermComponents::new_multi(terms.into()),
89 )
90 }
91
92 pub(super) fn new_intersection_int(terms: impl Into<Vec<Term>>) -> Self {
95 Self::new(
96 INTERSECTION_INT_OPERATOR,
97 TermComponents::new_multi(terms.into()),
98 )
99 }
100
101 pub(super) fn new_diff_ext(term1: Term, term2: Term) -> Self {
103 Self::new(
104 DIFFERENCE_EXT_OPERATOR,
105 TermComponents::new_binary(term1, term2),
106 )
107 }
108
109 pub(super) fn new_diff_int(term1: Term, term2: Term) -> Self {
111 Self::new(
112 DIFFERENCE_INT_OPERATOR,
113 TermComponents::new_binary(term1, term2),
114 )
115 }
116
117 pub(super) fn new_product(terms: impl Into<Vec<Term>>) -> Self {
119 Self::new(PRODUCT_OPERATOR, TermComponents::new_multi(terms.into()))
120 }
121
122 pub(super) fn new_image_ext(terms: impl Into<Vec<Term>>) -> Result<Self> {
128 Ok(Self::new(
129 IMAGE_EXT_OPERATOR,
130 Self::_process_image_terms(terms)?,
131 ))
132 }
133
134 pub(super) fn new_image_int(terms: impl Into<Vec<Term>>) -> Result<Self> {
140 Ok(Self::new(
141 IMAGE_INT_OPERATOR,
142 Self::_process_image_terms(terms)?,
143 ))
144 }
145
146 #[inline(always)]
154 fn _process_image_terms(terms: impl Into<Vec<Term>>) -> Result<TermComponents> {
155 let terms = terms.into();
157 let i_placeholder = terms.iter().position(Term::is_placeholder);
159 match i_placeholder {
161 Some(i_placeholder) => {
162 if i_placeholder == 0 {
164 return Err(anyhow::anyhow!("占位符不能压在「关系词项」的位置上"));
165 }
166 }
167 None => return Err(anyhow::anyhow!("未在像的元素中找到占位符")),
168 }
169 Ok(TermComponents::new_multi(terms))
172 }
173
174 pub(super) fn new_conjunction(terms: impl Into<Vec<Term>>) -> Self {
177 Self::new(
178 CONJUNCTION_OPERATOR,
179 TermComponents::new_multi(terms.into()),
180 )
181 }
182
183 pub(super) fn new_disjunction(terms: impl Into<Vec<Term>>) -> Self {
186 Self::new(
187 DISJUNCTION_OPERATOR,
188 TermComponents::new_multi(terms.into()),
189 )
190 }
191
192 pub(super) fn new_negation(term: Term) -> Self {
194 Self::new(NEGATION_OPERATOR, TermComponents::new_unary(term))
195 }
196
197 pub(super) fn new_inheritance(subject: Term, predicate: Term) -> Self {
201 Self::new(
202 INHERITANCE_RELATION,
203 TermComponents::new_binary(subject, predicate),
204 )
205 }
206
207 pub(super) fn new_similarity(subject: Term, predicate: Term) -> Self {
209 Self::new(
210 SIMILARITY_RELATION,
211 TermComponents::new_binary_unordered(subject, predicate),
212 )
213 }
214
215 pub(super) fn new_implication(subject: Term, predicate: Term) -> Self {
217 Self::new(
218 IMPLICATION_RELATION,
219 TermComponents::new_binary(subject, predicate),
220 )
221 }
222
223 pub(super) fn new_equivalence(subject: Term, predicate: Term) -> Self {
225 Self::new(
226 EQUIVALENCE_RELATION,
227 TermComponents::new_binary_unordered(subject, predicate),
228 )
229 }
230}
231
232impl TermComponents {
233 pub(super) fn new_unary(term: Term) -> Self {
236 Self::Compound(Box::new([term]))
237 }
238
239 pub(super) fn new_binary(term1: Term, term2: Term) -> Self {
242 Self::Compound(Box::new([term1, term2]))
243 }
244
245 pub(super) fn new_binary_unordered(term1: Term, term2: Term) -> Self {
251 pipe! {
252 manipulate!(
254 [term1, term2]
255 => .sort()
256 )
257 => Box::new
259 => Self::Compound
260 }
261 }
262
263 pub(super) fn new_multi(terms: Vec<Term>) -> Self {
268 pipe! {
269 terms
270 => .into_boxed_slice()
272 => Self::Compound
274 }
275 }
276}
277
278#[macro_export]
280macro_rules! term {
281 ($s:literal) => {
283 $s.parse::<$crate::language::Term>()
284 };
285 (unwrap $s:expr) => {
287 $s.parse::<$crate::language::Term>().unwrap()
288 };
289 ($($t:tt)*) => {
291 stringify!($($t)*).parse::<$crate::language::Term>()
292 };
293}
294
295#[cfg(test)]
297mod tests {
298 use super::*;
299 use crate::{ok, test_term as t, util::AResult};
300 use nar_dev_utils::fail_tests;
301 #[test]
305 fn test_term() -> AResult {
306 fn detect(term: &Term) {
308 use TermComponents::*;
309 match term.id_comp() {
310 (WORD, Word(name)) => {
311 println!("word with {name:?}");
312 }
313 (IMAGE_EXT_OPERATOR, Compound(v)) => {
314 let i = v.iter().position(Term::is_placeholder).unwrap();
315 println!("ext_image '/' with {i}");
316 println!("<components>");
317 for term in v.iter() {
318 detect(term);
319 }
320 println!("</components>");
321 }
322 _ => println!("term {:?}: {}", term.identifier, term.format_name()),
323 }
324 }
325 let im_ext = Term::new(
327 IMAGE_EXT_OPERATOR,
328 TermComponents::new_multi(vec![Term::new_word("word"), Term::new_placeholder()]),
329 );
330 detect(&im_ext);
331 detect(&t!("<A --> B>"));
333 detect(&t!("(--, [C, B, A, 0, 1, 2])"));
334 detect(&t!(
335 "{<B <-> A>, <D <=> C>, (&&, <A --> B>, <B --> C>), $i, #d, ?q}"
336 ));
337 detect(&t!("(/, _, A, B)"));
338 detect(&t!("(/, A, _, B)"));
339 detect(&t!("(/, A, B, _)"));
340 detect(&t!(r"(\, _, A, B)"));
341 detect(&t!(r"(\, A, _, B)"));
342 detect(&t!(r"(\, A, B, _)"));
343 ok!()
345 }
346
347 fail_tests! {
349 组分数不对_二元_外延差1 t!(unwrap "(-, A)");
350 组分数不对_二元_外延差3 t!(unwrap "(-, A, B, C)");
351 组分数不对_一元_否定 t!(unwrap "(--, A, B)");
352 空集_外延集 t!(unwrap "{}");
353 空集_内涵集 t!(unwrap "[]");
354 空集_外延像 t!(unwrap r"(/, _)");
355 空集_内涵像 t!(unwrap r"(\, _)");
356 }
357}