1use super::Term;
5use narsese::conversion::string::impl_lexical::format_instances::FORMAT_ASCII;
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8impl Serialize for Term {
9 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
10 where
11 S: Serializer,
12 {
13 let lexical = self.to_lexical();
16 let s = FORMAT_ASCII.format(&lexical);
18 s.serialize(serializer)
19 }
20}
21
22impl<'de> Deserialize<'de> for Term {
23 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
24 where
25 D: Deserializer<'de>,
26 {
27 let s: String = Deserialize::deserialize(deserializer)?;
29 let lexical = FORMAT_ASCII
31 .parse_term(&s)
32 .map_err(serde::de::Error::custom)?;
33 Term::from_lexical(lexical).map_err(serde::de::Error::custom)
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use crate::{language::Term, ok, test_term as term, util::AResult};
41 use nar_dev_utils::macro_once;
42
43 #[test]
56 fn test_soundness() -> AResult {
57 fn test(term: Term) {
58 let mut strong_soundness = true;
60 let ser = serde_json::to_string(&term).expect("词项序列化失败");
62 let de = serde_json::from_str::<Term>(&ser).expect("词项反序列化失败");
63 strong_soundness &= term == de;
64 let ser2 = serde_json::to_string(&de).expect("词项重序列化失败");
70 strong_soundness &= ser == ser2;
71 if !strong_soundness {
78 eprintln!("【警告】当前序列反序列化机制 不满足强一致性!\n1 {term} vs\n3 {de}\nfrom\n2 {ser} vs\n4 {ser2}");
79 }
80
81 let de2 = serde_json::from_str::<Term>(&ser2).expect("词项反序列化失败");
84 assert_eq!(
85 de, de2,
86 "序列化-反序列化 不可靠! {de} vs\n{de2}\nfrom {ser2:?}"
87 );
88 let ser3 = serde_json::to_string(&de2).expect("词项重序列化失败");
90 assert_eq!(
91 ser2, ser3,
92 "反序列化-序列化 不可靠! {ser} vs\n{ser3}\nfrom {de}"
93 );
94 }
95 macro_once! {
96 macro test( $($term:literal)* ) {
98 $( test( term!($term) ); )*
99 }
100 "(&&,<#1 --> object>,<#1 --> [unscrewing]>)"
101 "<(&&,<$1 --> [pliable]>,<(*,{SELF},$1) --> #reshape>) ==> <$1 --> [hardened]>>"
102 "<(&&,<(*,$1,plastic) --> made_of>,<(*,{SELF},$1) --> #lighter>) ==> <$1 --> [heated]>>"
103 "<(&&,<(*,{SELF},wolf) --> close_to>,#1000) ==> <{SELF} --> [hurt]>>"
104 "<(&&,<(*,{SELF},$1,FALSE) --> #want>,<(*,{SELF},$1) --> #anticipate>) ==> <(*,{SELF},$1) --> afraid_of>>"
105 "<(*,cup,plastic) --> made_of>"
106 "<(*,toothbrush,plastic) --> made_of>"
107 "<(*,{SELF},?what) --> afraid_of>"
108 "<(*,{SELF},wolf) --> close_to>"
109 "<(*,{tom},(&,[black],glasses)) --> own>"
110 "<(*,{tom},sunglasses) --> own>"
111 "<<$1 --> (/,livingIn,_,{graz})> ==> <$1 --> murder>>"
112 "<<$1 --> [aggressive]> ==> <$1 --> murder>>"
113 "<<$1 --> [hardened]> ==> <$1 --> [unscrewing]>>"
114 "<<$1 --> [heated]> ==> <$1 --> [melted]>>"
115 "<<$1 --> [melted]> <=> <$1 --> [pliable]>>"
116 "<<(*,$1,sunglasses) --> own> ==> <$1 --> [aggressive]>>"
117 "<?1 ==> <c --> C>>"
118 "<a --> A>"
119 "<b --> B>"
120 "<c --> C>"
121 "<cup --> [bendable]>"
122 "<cup --> object>"
123 "<sunglasses --> (&,[black],glasses)>"
124 "<toothbrush --> [bendable]>"
125 "<toothbrush --> object>"
126 "<{?who} --> murder>"
127 "<{SELF} --> [hurt]>"
128 "<{tim} --> (/,livingIn,_,{graz})>"
129
130 "(&&,<#1 --> lock>,<<$2 --> key> ==> <#1 --> (/,open,$2,_)>>)"
131 "(&&,<#x --> (/,open,#y,_)>,<#x --> lock>,<#y --> key>)"
132 "(&&,<#x --> bird>,<#x --> swimmer>)"
133 "(&&,<#x --> key>,<{lock1} --> (/,open,#x,_)>)"
134 "(&&,<robin --> [flying]>,<robin --> swimmer>)"
135 "(&&,<robin --> swimmer>,<robin --> [flying]>)"
136 "(--,<robin --> [flying]>)"
137 "(||,<robin --> [flying]>,<robin --> swimmer>)"
138 "<(&&,<#1 --> lock>,<#1 --> (/,open,$2,_)>) ==> <$2 --> key>>"
139 "<(&&,<$x --> [chirping]>,<$x --> [with_wings]>) ==> <$x --> bird>>"
140 "<(&&,<$x --> flyer>,<$x --> [chirping]>) ==> <$x --> bird>>"
141 "<(&&,<$x --> flyer>,<$x --> [chirping]>, <(*, $x, worms) --> food>) ==> <$x --> bird>>"
142 "<(&&,<$x --> flyer>,<(*,$x,worms) --> food>) ==> <$x --> bird>>"
143 "<(&&,<$x --> key>,<$y --> lock>) ==> <$y --> (/,open,$x,_)>>"
144 "<(&&,<robin --> [chirping]>,<robin --> [flying]>) ==> <robin --> bird>>"
145 "<(&&,<robin --> [chirping]>,<robin --> [flying]>,<robin --> [with_wings]>) ==> <robin --> bird>>"
146 "<(&&,<robin --> [flying]>,<robin --> [with_wings]>) ==> <robin --> [living]>>"
147 "<(&&,<robin --> [flying]>,<robin --> bird>) ==> <robin --> [living]>>"
148 "<(&&,<robin --> bird>,<robin --> [living]>) ==> <robin --> animal>>"
149 "<(&,<{Tweety} --> bird>,<bird --> fly>) --> claimedByBob>"
150 "<(&,bird,swimmer) --> (&,animal,swimmer)>"
151 "<(&,swan,swimmer) --> bird>"
152 "<(*,(*,(*,0))) --> num>"
153 "<(*,a,b) --> like>"
154 "<(*,bird,plant) --> ?x>"
155 "<(-,swimmer,animal) --> (-,swimmer,bird)>"
156 "<(--,<robin --> [flying]>) ==> <robin --> bird>>"
157 "<(--,<robin --> bird>) ==> <robin --> [flying]>>"
158 "<(/,neutralization,_,base) --> ?x>"
159 r"<(\,(\,REPRESENT,_,<(*,CAT,FISH) --> FOOD>),_,eat,fish) --> cat>"
160 r"<(\,REPRESENT,_,CAT) --> cat>"
161 r"<(\,neutralization,acid,_) --> ?x>"
162 "<(|,boy,girl) --> youth>"
163 "<(~,boy,girl) --> [strong]>"
164 "<(~,swimmer,swan) --> bird>"
165 "<0 --> (/,num,_)>"
166 "<0 --> num>"
167 "<<$1 --> lock> ==> (&&,<#2 --> key>,<$1 --> (/,open,#2,_)>)>"
168 "<<$1 --> num> ==> <(*,$1) --> num>>"
169 "<<$x --> animal> <=> <$x --> bird>>"
170 "<<$x --> bird> ==> <$x --> animal>>"
171 "<<$x --> key> ==> <{lock1} --> (/,open,$x,_)>>"
172 "<<$y --> [with_wings]> ==> <$y --> flyer>>"
173 "<<$y --> flyer> ==> <$y --> [with_wings]>>"
174 "<<(&,<#1 --> $2>,<$3 --> #1>) --> claimedByBob> ==> <<$3 --> $2> --> claimedByBob>>"
175 "<<(*,$1,$2) --> like> <=> <(*,$2,$1) --> like>>"
176 "<<bird --> $x> ==> <robin --> $x>>"
177 "<<lock1 --> (/,open,$1,_)> ==> <$1 --> key>>"
178 "<<robin --> [flying]> ==> <robin --> [with_beak]>>"
179 "<<robin --> [flying]> ==> <robin --> animal>>"
180 "<<robin --> animal> <=> <robin --> bird>>"
181 "<<robin --> bird> <=> <robin --> [flying]>>"
182 "<<robin --> bird> ==> (&&,<robin --> animal>,<robin --> [flying]>)>"
183 "<<robin --> bird> ==> <robin --> [flying]>>"
184 "<<robin --> bird> ==> <robin --> animal>>"
185 "<?1 --> swimmer>"
186 "<Birdie <-> Tweety>"
187 "<Tweety {-- bird>"
188 "<Tweety {-] yellow>"
189 "<[bright] <-> [smart]>"
190 "<[smart] --> [bright]>"
191 "<acid --> (/,reaction,_,base)>"
192 "<cat --> (/,(/,REPRESENT,_,<(*,CAT,FISH) --> FOOD>),_,eat,fish)>"
193 "<neutralization --> (*,acid,base)>"
194 "<planetX --> {Mars,Pluto,Venus}>"
195 "<planetX --> {Pluto,Saturn}>"
196 "<raven --] black>"
197 "<robin --> (&,bird,swimmer)>"
198 "<robin --> (-,bird,swimmer)>"
199 "<robin --> (|,bird,swimmer)>"
200 "<robin --> [flying]>"
201 "<{?1} --> swimmer>"
202 "<{Birdie} <-> {Tweety}>"
203 "<{Tweety} --> [with_wings]>"
204 "<{Tweety} --> flyer>"
205 "<{Tweety} --> {Birdie}>"
206 "<{key1} --> (/,open,_,{lock1})>"
207
208 "(&&,<(*,1,FALSE) --> #3>,<(*,1) --> #2>)" }
211 ok!()
212 }
213}