1use super::structs::*;
6use crate::symbols::*;
7use crate::util::ToDisplayAndBrief;
8
9impl Term {
11 #[inline]
13 pub fn identifier(&self) -> &str {
14 &self.identifier
15 }
16
17 #[inline]
19 pub fn components(&self) -> &TermComponents {
20 &self.components
21 }
22
23 #[inline]
25 pub(in crate::language) fn components_mut(&mut self) -> &mut TermComponents {
26 &mut self.components
27 }
28
29 pub fn is_placeholder(&self) -> bool {
32 self.identifier == PLACEHOLDER
33 }
34
35 pub fn id_comp(&self) -> (&str, &TermComponents) {
38 (&self.identifier, &self.components)
39 }
40
41 #[cfg(test)]
48 pub(in crate::language) fn id_comp_mut(&mut self) -> (&mut String, &mut TermComponents) {
49 (&mut self.identifier, &mut self.components)
50 }
51
52 pub fn unwrap_id_comp(self) -> (String, TermComponents) {
55 (self.identifier, self.components)
56 }
57
58 pub fn contain_type(&self, identifier: &str) -> bool {
61 self.identifier == identifier || self.components.contain_type(identifier)
62 }
63
64 pub fn for_each_atom(&self, f: &mut impl FnMut(&Term)) {
72 use TermComponents::*;
73 match self.components() {
74 Empty | Word(..) | Variable(..) => f(self),
76 Compound(terms) => {
78 for term in terms.iter() {
79 term.for_each_atom(f);
80 }
81 }
82 }
83 }
84
85 pub(crate) fn for_each_atom_mut(&mut self, f: &mut impl FnMut(&Term)) {
89 use TermComponents::*;
90 match self.components_mut() {
91 Empty | Word(..) | Variable(..) => f(self),
93 Compound(terms) => {
95 for term in terms.iter_mut() {
96 term.for_each_atom_mut(f);
97 }
98 }
99 }
100 }
101}
102
103impl std::fmt::Display for Term {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 f.write_str(&self.format_name())
110 }
111}
112
113impl ToDisplayAndBrief for Term {
117 #[inline]
118 fn to_display(&self) -> String {
119 self.format_ascii()
120 }
121}
122
123impl TermComponents {
125 pub fn len(&self) -> usize {
129 use TermComponents::*;
130 match self {
131 Empty | Word(..) | Variable(..) => 0,
133 Compound(terms) => terms.len(),
135 }
136 }
137
138 pub fn is_empty(&self) -> bool {
141 use TermComponents::*;
142 match self {
143 Empty | Word(..) | Variable(..) => true,
145 Compound(terms) => terms.is_empty(),
147 }
148 }
149
150 pub fn get(&self, index: usize) -> Option<&Term> {
154 use TermComponents::*;
155 match self {
156 Empty | Word(..) | Variable(..) => None,
158 Compound(terms) => terms.get(index),
160 }
161 }
162
163 pub unsafe fn get_unchecked(&self, index: usize) -> &Term {
171 use TermComponents::*;
172 match self {
173 Compound(terms) => terms.get_unchecked(index),
175 _ => panic!("尝试在非法位置 {index} 获取词项:{self:?}"),
177 }
178 }
179
180 pub fn iter(&self) -> impl Iterator<Item = &Term> {
184 use TermComponents::*;
185 let b: Box<dyn Iterator<Item = &Term>> = match self {
187 Empty | Word(..) | Variable(..) => Box::new(None.into_iter()),
189 Compound(terms) => Box::new(terms.iter()),
191 };
192 b
193 }
194
195 pub(crate) fn sort_dedup(self) -> Self {
204 use TermComponents::*;
205 match self {
206 Empty | Word(..) | Variable(..) => self,
208 Compound(terms) => Self::Compound(Self::sort_dedup_terms(terms)),
210 }
211 }
212
213 pub fn sort_dedup_terms(terms: Box<[Term]>) -> Box<[Term]> {
215 let mut new_terms = Vec::from(terms);
217 Self::sort_dedup_term_vec(&mut new_terms);
219 new_terms.into_boxed_slice()
221 }
222
223 pub fn sort_dedup_term_vec(terms: &mut Vec<Term>) {
225 terms.sort();
227 terms.dedup();
229 }
230
231 pub fn clone_to_vec(&self) -> Vec<Term> {
234 use TermComponents::*;
235 match self {
236 Empty | Word(..) | Variable(..) => vec![],
238 Compound(terms) => terms.to_vec(),
240 }
241 }
242
243 pub fn contain_type(&self, identifier: &str) -> bool {
248 self.iter().any(|term| term.contain_type(identifier))
249 }
250
251 pub fn structural_match(&self, other: &Self) -> bool {
257 use TermComponents::*;
258 match (self, other) {
259 (Empty, Empty) | (Word(..), Word(..)) | (Variable(..), Variable(..)) => true,
261 (Compound(terms1), Compound(terms2)) => terms1.len() == terms2.len(),
263 _ => false,
265 }
266 }
267}
268
269#[cfg(test)]
271mod tests {
272 use super::*;
273 use crate::test_term as term;
274 use crate::{ok, util::AResult};
275 use nar_dev_utils::asserts;
276
277 mod term {
279 use super::*;
280 use nar_dev_utils::macro_once;
281
282 #[test]
283 fn eq() -> AResult {
284 macro_once! {
285 macro eq($( $left:literal $op:tt $right:expr )*) {
287 asserts! {$(
288 term!($left) $op term!($right),
289 )*}
290 }
291 "A" == "A"
293 "<A --> B>" == "<A-->B>"
294 "[A]" == "[A]"
295 "<A <-> B>" == "<B <-> A>"
297 "(&, C, A, B)" == "(&, B, C, A)"
298 "{C, A, B}" == "{B, C, A}"
299 r"(/, _, A, B)" == "(*, A, B)"
301 r"(\, _, A, B)" == "(*, A, B)"
302 "$A" != "A"
304 "$A" != "#A"
305 r"(\, A, _, B)" != r"(/, A, _, B)"
306 "<A <-> B>" != "<A <=> B>"
307 "A" != "a"
309 "(*, A, B, C)" != "(*, A, B)"
310 "(*, A, B, C)" != "(*, A, B, c)"
311 "(/, A, B, _)" != "(/, A, _, B)"
312 "{C, A, B}" != "{B, C}"
313 }
314 ok!()
315 }
316
317 #[test]
320 fn hash() -> AResult {
321 use std::collections::{HashMap, HashSet};
322 use std::hash::RandomState;
323 let mut map = HashMap::from([(term!("A"), term!("B")), (term!("C"), term!("D"))]);
325 let mut set: HashSet<Term, RandomState> = HashSet::from_iter(map.keys().cloned());
326 asserts! {
327 map.get(&term!("A")) => Some(&term!("B")),
328 map.get(&term!("C")) => Some(&term!("D")),
329 map.get(&term!("E")) => None,
330 set.contains(&term!("A"))
331 set.contains(&term!("C"))
332 }
333 map.insert(term!("D"), term!("C"));
335 for v in map.values() {
336 set.insert(v.clone());
337 }
338 asserts! {
339 map.get(&term!("D")) => Some(&term!("C")),
340 set.contains(&term!("B"))
341 set.contains(&term!("D"))
342 }
343 dbg!(&map, &set);
345 ok!()
346 }
347
348 #[test]
349 fn identifier() -> AResult {
350 macro_once! {
351 macro identifier($( $s:literal => $expected:expr )*) {
353 asserts! {$(
354 term!($s).identifier() => $expected,
355 )*}
356 }
357 "_" => PLACEHOLDER
359 "A" => WORD
361 "$A" => VAR_INDEPENDENT
362 "#A" => VAR_DEPENDENT
363 "?A" => VAR_QUERY
364 "{A}" => SET_EXT_OPERATOR
366 "[A]" => SET_INT_OPERATOR
367 "(&, A, B)" => INTERSECTION_EXT_OPERATOR "(|, A, B)" => INTERSECTION_INT_OPERATOR "(-, A, B)" => DIFFERENCE_EXT_OPERATOR
370 "(~, A, B)" => DIFFERENCE_INT_OPERATOR
371 "(*, A)" => PRODUCT_OPERATOR
372 r"(/, R, _)" => IMAGE_EXT_OPERATOR
373 r"(\, R, _)" => IMAGE_INT_OPERATOR
374 r"(&&, A, B)" => CONJUNCTION_OPERATOR r"(||, A, B)" => DISJUNCTION_OPERATOR r"(--, A)" => NEGATION_OPERATOR
377 "<A --> B>" => INHERITANCE_RELATION
379 "<A <-> B>" => SIMILARITY_RELATION
380 "<A ==> B>" => IMPLICATION_RELATION
381 "<A <=> B>" => EQUIVALENCE_RELATION
382 }
383 ok!()
384 }
385
386 #[test]
387 fn components() -> AResult {
388 use TermComponents::*;
389 macro_once! {
390 macro components($( $s:literal => $expected:pat )*) {
392 asserts! {$(
393 term!($s).components() => @$expected,
394 )*}
395 }
396 "_" => Empty
398 "A" => Word(..)
400 "$A" => Variable(..)
402 "#A" => Variable(..)
403 "?A" => Variable(..)
404 "(--, A)" => Compound(..)
406 "(-, A, B)" => Compound(..)
408 "(~, A, B)" => Compound(..)
409 "<A --> B>" => Compound(..)
410 "<A <-> B>" => Compound(..)
411 "<A ==> B>" => Compound(..)
412 "<A <=> B>" => Compound(..)
413 "{A}" => Compound(..)
415 "[A]" => Compound(..)
416 "(&, A, B)" => Compound(..)
417 "(|, A, B)" => Compound(..)
418 "(*, A)" => Compound(..)
419 r"(&&, A, B)" => Compound(..)
420 r"(||, A, B)" => Compound(..)
421 r"(/, R, _)" => Compound(..)
423 r"(\, R, _)" => Compound(..)
424 }
425 ok!()
426 }
427
428 #[test]
429 fn is_placeholder() -> AResult {
430 macro_once! {
431 macro is_placeholder($( $s:literal => $expected:expr )*) {
433 asserts! {$(
434 term!($s).is_placeholder() => $expected,
435 )*}
436 }
437 "_" => true
439 "A" => false
441 "$A" => false
442 "#A" => false
443 "?A" => false
444 "{A}" => false
446 "[A]" => false
447 "(&, A, B)" => false "(|, A, B)" => false "(-, A, B)" => false
450 "(~, A, B)" => false
451 "(*, A)" => false
452 r"(/, R, _)" => false
453 r"(\, R, _)" => false
454 r"(&&, A)" => false
455 r"(||, A)" => false
456 r"(--, A)" => false
457 "<A --> B>" => false
459 "<A <-> B>" => false
460 "<A ==> B>" => false
461 "<A <=> B>" => false
462 }
463 ok!()
464 }
465
466 #[test]
468 fn id_comp() -> AResult {
469 macro_once! {
470 macro id_comp($($s:literal)*) {
472 asserts! {$(
473 term!($s).id_comp() => @(&_, &_),
474 )*}
475 }
476 "_"
478 "A"
480 "$A"
481 "#A"
482 "?A"
483 "{A}"
485 "[A]"
486 "(&, A)"
487 "(|, A)"
488 "(-, A, B)"
489 "(~, A, B)"
490 "(*, A)"
491 r"(/, R, _)"
492 r"(\, R, _)"
493 r"(&&, A)"
494 r"(||, A)"
495 r"(--, A)"
496 "<A --> B>"
498 "<A <-> B>"
499 "<A ==> B>"
500 "<A <=> B>"
501 }
502 ok!()
503 }
504
505 #[test]
507 fn id_comp_mut() -> AResult {
508 macro_once! {
509 macro id_comp_mut($($s:literal)*) {
511 asserts! {$(
512 term!($s).id_comp_mut() => @(&mut _, &mut _),
513 )*}
514 }
515 "_"
517 "A"
519 "$A"
520 "#A"
521 "?A"
522 "{A}"
524 "[A]"
525 "(&, A)"
526 "(|, A)"
527 "(-, A, B)"
528 "(~, A, B)"
529 "(*, A)"
530 r"(/, R, _)"
531 r"(\, R, _)"
532 r"(&&, A)"
533 r"(||, A)"
534 r"(--, A)"
535 "<A --> B>"
537 "<A <-> B>"
538 "<A ==> B>"
539 "<A <=> B>"
540 }
541 ok!()
542 }
543
544 #[test]
545 fn contain_type() -> AResult {
546 macro_once! {
547 macro contain_type($($expected:ident in $s:literal)*) {
549 asserts! {$(
550 term!($s).contain_type($expected)
551 )*}
552 }
553 WORD in "{A}"
555 WORD in "[A]"
556 WORD in "(&, A, B)" WORD in "(|, A, B)" WORD in "(-, A, B)"
559 WORD in "(~, A, B)"
560 WORD in "(*, A)"
561 WORD in r"(/, R, _)"
562 WORD in r"(\, R, _)"
563 WORD in r"(&&, A, B)" WORD in r"(||, A, B)" WORD in r"(--, A)"
566
567 VAR_INDEPENDENT in "{$A}"
568 VAR_INDEPENDENT in "[$A]"
569 VAR_INDEPENDENT in "(&, $A)"
570 VAR_INDEPENDENT in "(|, $A)"
571 VAR_INDEPENDENT in "(-, $A, B)"
572 VAR_INDEPENDENT in "(~, $A, B)"
573 VAR_INDEPENDENT in "(*, $A)"
574 VAR_INDEPENDENT in r"(/, $R, _)"
575 VAR_INDEPENDENT in r"(\, $R, _)"
576 VAR_INDEPENDENT in r"(&&, $A, #B)" VAR_INDEPENDENT in r"(||, $A, #B)" VAR_DEPENDENT in r"(&&, $A, #B)" VAR_DEPENDENT in r"(||, $A, #B)" VAR_INDEPENDENT in r"(--, $A)"
581
582 PRODUCT_OPERATOR in "{(*, A)}"
583 PRODUCT_OPERATOR in "[(*, A)]"
584 PRODUCT_OPERATOR in "(&, (*, A), B)" PRODUCT_OPERATOR in "(|, (*, A), B)" PRODUCT_OPERATOR in "(-, (*, A), B)"
587 PRODUCT_OPERATOR in "(~, (*, A), B)"
588 PRODUCT_OPERATOR in "(*, (*, A))"
589 PRODUCT_OPERATOR in r"(/, (*, R), _)"
590 PRODUCT_OPERATOR in r"(\, (*, R), _)"
591 PRODUCT_OPERATOR in r"(&&, (*, A), B)" PRODUCT_OPERATOR in r"(||, (*, A), B)" PRODUCT_OPERATOR in r"(--, (*, A))"
594
595 WORD in "<A --> B>"
597 WORD in "<A <-> B>"
598 WORD in "<A ==> B>"
599 WORD in "<A <=> B>"
600
601 INHERITANCE_RELATION in "<<A --> B> --> <C ==> D>>" SIMILARITY_RELATION in "<<A <-> B> <-> <C <=> D>>" IMPLICATION_RELATION in "<<A --> B> ==> <C ==> D>>" EQUIVALENCE_RELATION in "<<A <-> B> <=> <C <=> D>>" }
606 ok!()
607 }
608
609 #[test]
611 fn structural_match() -> AResult {
612 macro_once! {
613 macro assert_structural_match($($term1:literal => $term2:literal)*) {
615 asserts! {$(
616 term!($term1).structural_match(&term!($term2))
617 )*}
618 }
619 "_" => "__"
622 "A" => "a"
624 "$A" => "$a"
625 "#A" => "#a"
626 "?A" => "?a"
627 "{A}" => "{a}"
629 "[A]" => "[a]"
630 "(&, A, B)" => "(&, a, b)"
631 "(|, A, B)" => "(|, a, b)"
632 "(-, A, B)" => "(-, a, b)"
633 "(~, A, B)" => "(~, a, b)"
634 "(*, A)" => "(*, a)"
635 r"(/, R, _)" => r"(/, r, _)"
636 r"(\, R, _)" => r"(\, r, _)"
637 r"(&&, A, B)" => r"(&&, a, b)"
638 r"(||, A, B)" => r"(||, a, b)"
639 r"(--, A)" => r"(--, a)"
640 "<A --> B>" => "<a --> b>"
642 "<A <-> B>" => "<a <-> b>"
643 "<A ==> B>" => "<a ==> b>"
644 "<A <=> B>" => "<a <=> b>"
645 "{A, B, C}" => "{0, 1, 2}"
647 "{A, B, [C]}" => "{0, 1, [2]}"
648 "{A, {B, C, D}, [E]}" => "{{0, 1, 2}, 1, [2]}"
649 }
650 ok!()
651 }
652
653 #[test]
654 fn fmt() -> AResult {
655 macro_once! {
656 macro fmt($($term:literal => $expected:expr)*) {
658 asserts! {$(
659 format!("{}", term!($term)) => $expected
660 )*}
661 }
662 "_" => "_"
664 "A" => "A"
666 "$A" => "$1" "#A" => "#1" "?A" => "?1" "{A, B}" => "{}(A B)"
671 "[A, B]" => "[](A B)"
672 "(&, A, B)" => "&(A B)"
673 "(|, A, B)" => "|(A B)"
674 "(-, A, B)" => "(A - B)"
675 "(~, A, B)" => "(A ~ B)"
676 "(*, A, B)" => "*(A B)"
677 r"(/, R, _)" => r"/(R _)"
678 r"(\, R, _)" => r"\(R _)"
679 r"(/, R, _, A)" => r"/(R _ A)"
680 r"(\, R, _, A)" => r"\(R _ A)"
681 r"(&&, A, B)" => r"&&(A B)"
682 r"(||, A, B)" => r"||(A B)"
683 r"(--, A)" => r"(-- A)"
684 "<A --> B>" => "(A --> B)"
686 "<A <-> B>" => "(A <-> B)"
687 "<A ==> B>" => "(A ==> B)"
688 "<A <=> B>" => "(A <=> B)"
689 }
690 ok!()
691 }
692
693 #[test]
694 fn for_each_atom() -> AResult {
695 fn test(term: Term, expected: &[Term]) {
696 let mut v = vec![];
698 term.for_each_atom(&mut |t| v.push(t.clone()));
700 assert_eq!(v, expected);
702 }
703 macro_once! {
704 macro for_each_atom($($term:literal => [ $($expected:expr),* ] )*) {
706 $( test(term!($term), &term!([ $($expected),* ])); )*
707 }
708 "_" => ["_"]
711 "A" => ["A"]
713 "$A" => ["$A"]
714 "#A" => ["#A"]
715 "?A" => ["?A"]
716 "{A, B}" => ["A", "B"]
718 "[A, B]" => ["A", "B"]
719 "(&, A, B)" => ["A", "B"]
720 "(|, A, B)" => ["A", "B"]
721 "(-, A, B)" => ["A", "B"]
722 "(~, A, B)" => ["A", "B"]
723 "(*, A, B)" => ["A", "B"]
724 r"(/, R, _)" => ["R", "_"] r"(\, R, _)" => ["R", "_"]
726 r"(/, R, _, A)" => ["R", "_", "A"]
727 r"(\, R, _, A)" => ["R", "_", "A"]
728 r"(&&, A, B)" => ["A", "B"]
729 r"(||, A, B)" => ["A", "B"]
730 r"(--, A)" => ["A"]
731 "<A --> B>" => ["A", "B"]
733 "<A <-> B>" => ["A", "B"]
734 "<A ==> B>" => ["A", "B"]
735 "<A <=> B>" => ["A", "B"]
736 "(&&, A, B, [C, D])" => ["A", "B", "C", "D"]
739 "<(--, (--, (--, (--, (--, (--, (--, (--, A)))))))) ==> <(-, B, C) --> (*, (*, (*, (*, (*, D)))))>>" => ["A", "B", "C", "D"]
740 "<<A --> B> ==> <C --> D>>" => ["A", "B", "C", "D"]
741 }
742 ok!()
743 }
744
745 }
747
748 mod term_components {
750 use super::*;
751 use nar_dev_utils::macro_once;
752
753 #[test]
755 fn len() -> AResult {
756 macro_once! {
757 macro asserts_len($( $term:literal => $s:expr )*) {
759 asserts! { $( term!($term).components.len() => $s )* }
760 }
761 "B" => 0
763 "?quine" => 0
764 "<A --> B>" => 2
765 "(*, {SELF}, x, y)" => 3
766 "(--, [good])" => 1
767 "(/, A, _, B)" => 3
769 "[2, 1, 0, 0, 1, 2]" => 3
771 }
772 ok!()
773 }
774
775 #[test]
777 fn is_empty() -> AResult {
778 macro_once! {
779 macro is_empty($($term:literal => $expected:expr)*) {
781 asserts! { $( term!($term).components.is_empty() => $expected )* }
782 }
783 "B" => true
784 "?quine" => true
785 "<A --> B>" => false
786 "(*, {SELF}, x, y)" => false
787 "(--, [good])" => false
788 "(/, A, _, B)" => false
789 "[2, 1, 0, 0, 1, 2]" => false
790 }
791 ok!()
792 }
793
794 #[test]
796 fn get() -> AResult {
797 macro_once! {
798 macro get($($s:literal . $i:expr => $expected:expr)*) {
800 asserts! { $(
801 term!($s).components.get($i) => $expected
802 )* }
803 }
804 "B".0 => None
806 "?quine".0 => None
807 "<A --> B>".0 => Some(&term!("A"))
808 "<A --> B>".1 => Some(&term!("B"))
809 "<A --> B>".2 => None
810 "{SELF}".0 => Some(&term!("SELF"))
811 "{SELF}".1 => None
812 "(*, {SELF}, x, y)".0 => Some(&term!("{SELF}"))
813 "(*, {SELF}, x, y)".1 => Some(&term!("x"))
814 "(*, {SELF}, x, y)".2 => Some(&term!("y"))
815 "(*, {SELF}, x, y)".3 => None
816 "(--, [good])".0 => Some(&term!("[good]"))
817 "(--, [good])".1 => None
818 "(/, A, _, B)".0 => Some(&term!("A"))
820 "(/, A, _, B)".1 => Some(&term!("_")) "(/, A, _, B)".2 => Some(&term!("B"))
822 "(/, A, _, B)".3 => None
823 "[2, 1, 0, 0, 1, 2]".0 => Some(&term!("0"))
825 "[2, 1, 0, 0, 1, 2]".1 => Some(&term!("1"))
826 "[2, 1, 0, 0, 1, 2]".2 => Some(&term!("2"))
827 "[2, 1, 0, 0, 1, 2]".3 => None
828 }
829 ok!()
830 }
831
832 #[test]
834 fn get_unchecked() -> AResult {
835 macro_once! {
836 macro get_unchecked($($s:literal . $i:expr => $expected:expr)*) {
838 unsafe { asserts! { $(
839 term!($s).components.get_unchecked($i) => $expected
840 )* } }
841 }
842 "<A --> B>".0 => &term!("A")
844 "<A --> B>".1 => &term!("B")
845 "{SELF}".0 => &term!("SELF")
846 "(*, {SELF}, x, y)".0 => &term!("{SELF}")
847 "(*, {SELF}, x, y)".1 => &term!("x")
848 "(*, {SELF}, x, y)".2 => &term!("y")
849 "(--, [good])".0 => &term!("[good]")
850 "(/, A, _, B)".0 => &term!("A")
852 "(/, A, _, B)".1 => &term!("_")
853 "(/, A, _, B)".2 => &term!("B")
854 "[2, 1, 0, 0, 1, 2]".0 => &term!("0")
856 "[2, 1, 0, 0, 1, 2]".1 => &term!("1")
857 "[2, 1, 0, 0, 1, 2]".2 => &term!("2")
858 }
859 ok!()
860 }
861
862 #[test]
865 fn iter() -> AResult {
866 macro_once! {
867 macro iter($($s:literal => $expected:expr)*) {
869 asserts! { $(
870 term!($s).components.iter().collect::<Vec<_>>() => $expected
871 )* }
872 }
873 "<A --> B>" => term!(["A", "B"]&)
875 "{SELF}" => term!(["SELF"]&)
876 "(*, {SELF}, x, y)" => term!(["{SELF}", "x", "y"]&)
877 "(--, [good])" => term!(["[good]"]&)
878 "(/, A, _, B)" => term!(["A", "_", "B"]&)
880 "[2, 1, 0, 0, 1, 2]" => term!(["0", "1", "2"]&)
882 }
883 ok!()
884 }
885
886 #[test]
887 fn sort_dedup() -> AResult {
888 macro_once! {
889 macro sort_dedup($($s:literal => $expected:literal)*) {
891 $(
892 let mut term = term!($s);
894 print!("{term}");
895 term.components = term.components.sort_dedup();
897 let expected = term!($expected);
899 println!(" => {term}");
900 assert_eq!(term, expected);
901 )*
902 }
903 "(*, B, C, A)" => "(*, A, B, C)"
905 "(*, 2, 1, 3)" => "(*, 1, 2, 3)"
906 "(/, R, T, _, S)" => "(/, R, S, T, _)" "{[C], $B, A}" => "{A, $B, [C]}"
908 "(*, あ, え, い, お, う)" => "(*, あ, い, う, え, お)"
909 "(*, ア, エ, イ, オ, ウ)" => "(*, ア, イ, ウ, エ, オ)"
910 "(*, 一, 丄, 七, 丁, 丂)" => "(*, 一, 丁, 丂, 七, 丄)"
911 "(*, F, A, D, E, D)" => "(*, A, D, E, F)"
913 "(*, 1, 1, 4, 5, 1, 4)" => "(*, 1, 4, 5)"
914 }
915 ok!()
916 }
917
918 }
922}