use super::Term;
use narsese::conversion::string::impl_lexical::format_instances::FORMAT_ASCII;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
impl Serialize for Term {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let lexical = self.to_lexical();
let s = FORMAT_ASCII.format(&lexical);
s.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Term {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s: String = Deserialize::deserialize(deserializer)?;
let lexical = FORMAT_ASCII
.parse_term(&s)
.map_err(serde::de::Error::custom)?;
Term::from_lexical(lexical).map_err(serde::de::Error::custom)
}
}
#[cfg(test)]
mod tests {
use crate::{language::Term, ok, test_term as term, util::AResult};
use nar_dev_utils::macro_once;
#[test]
fn test_soundness() -> AResult {
fn test(term: Term) {
let mut strong_soundness = true;
let ser = serde_json::to_string(&term).expect("词项序列化失败");
let de = serde_json::from_str::<Term>(&ser).expect("词项反序列化失败");
strong_soundness &= term == de;
let ser2 = serde_json::to_string(&de).expect("词项重序列化失败");
strong_soundness &= ser == ser2;
if !strong_soundness {
eprintln!("【警告】当前序列反序列化机制 不满足强一致性!\n1 {term} vs\n3 {de}\nfrom\n2 {ser} vs\n4 {ser2}");
}
let de2 = serde_json::from_str::<Term>(&ser2).expect("词项反序列化失败");
assert_eq!(
de, de2,
"序列化-反序列化 不可靠! {de} vs\n{de2}\nfrom {ser2:?}"
);
let ser3 = serde_json::to_string(&de2).expect("词项重序列化失败");
assert_eq!(
ser2, ser3,
"反序列化-序列化 不可靠! {ser} vs\n{ser3}\nfrom {de}"
);
}
macro_once! {
macro test( $($term:literal)* ) {
$( test( term!($term) ); )*
}
"(&&,<#1 --> object>,<#1 --> [unscrewing]>)"
"<(&&,<$1 --> [pliable]>,<(*,{SELF},$1) --> #reshape>) ==> <$1 --> [hardened]>>"
"<(&&,<(*,$1,plastic) --> made_of>,<(*,{SELF},$1) --> #lighter>) ==> <$1 --> [heated]>>"
"<(&&,<(*,{SELF},wolf) --> close_to>,#1000) ==> <{SELF} --> [hurt]>>"
"<(&&,<(*,{SELF},$1,FALSE) --> #want>,<(*,{SELF},$1) --> #anticipate>) ==> <(*,{SELF},$1) --> afraid_of>>"
"<(*,cup,plastic) --> made_of>"
"<(*,toothbrush,plastic) --> made_of>"
"<(*,{SELF},?what) --> afraid_of>"
"<(*,{SELF},wolf) --> close_to>"
"<(*,{tom},(&,[black],glasses)) --> own>"
"<(*,{tom},sunglasses) --> own>"
"<<$1 --> (/,livingIn,_,{graz})> ==> <$1 --> murder>>"
"<<$1 --> [aggressive]> ==> <$1 --> murder>>"
"<<$1 --> [hardened]> ==> <$1 --> [unscrewing]>>"
"<<$1 --> [heated]> ==> <$1 --> [melted]>>"
"<<$1 --> [melted]> <=> <$1 --> [pliable]>>"
"<<(*,$1,sunglasses) --> own> ==> <$1 --> [aggressive]>>"
"<?1 ==> <c --> C>>"
"<a --> A>"
"<b --> B>"
"<c --> C>"
"<cup --> [bendable]>"
"<cup --> object>"
"<sunglasses --> (&,[black],glasses)>"
"<toothbrush --> [bendable]>"
"<toothbrush --> object>"
"<{?who} --> murder>"
"<{SELF} --> [hurt]>"
"<{tim} --> (/,livingIn,_,{graz})>"
"(&&,<#1 --> lock>,<<$2 --> key> ==> <#1 --> (/,open,$2,_)>>)"
"(&&,<#x --> (/,open,#y,_)>,<#x --> lock>,<#y --> key>)"
"(&&,<#x --> bird>,<#x --> swimmer>)"
"(&&,<#x --> key>,<{lock1} --> (/,open,#x,_)>)"
"(&&,<robin --> [flying]>,<robin --> swimmer>)"
"(&&,<robin --> swimmer>,<robin --> [flying]>)"
"(--,<robin --> [flying]>)"
"(||,<robin --> [flying]>,<robin --> swimmer>)"
"<(&&,<#1 --> lock>,<#1 --> (/,open,$2,_)>) ==> <$2 --> key>>"
"<(&&,<$x --> [chirping]>,<$x --> [with_wings]>) ==> <$x --> bird>>"
"<(&&,<$x --> flyer>,<$x --> [chirping]>) ==> <$x --> bird>>"
"<(&&,<$x --> flyer>,<$x --> [chirping]>, <(*, $x, worms) --> food>) ==> <$x --> bird>>"
"<(&&,<$x --> flyer>,<(*,$x,worms) --> food>) ==> <$x --> bird>>"
"<(&&,<$x --> key>,<$y --> lock>) ==> <$y --> (/,open,$x,_)>>"
"<(&&,<robin --> [chirping]>,<robin --> [flying]>) ==> <robin --> bird>>"
"<(&&,<robin --> [chirping]>,<robin --> [flying]>,<robin --> [with_wings]>) ==> <robin --> bird>>"
"<(&&,<robin --> [flying]>,<robin --> [with_wings]>) ==> <robin --> [living]>>"
"<(&&,<robin --> [flying]>,<robin --> bird>) ==> <robin --> [living]>>"
"<(&&,<robin --> bird>,<robin --> [living]>) ==> <robin --> animal>>"
"<(&,<{Tweety} --> bird>,<bird --> fly>) --> claimedByBob>"
"<(&,bird,swimmer) --> (&,animal,swimmer)>"
"<(&,swan,swimmer) --> bird>"
"<(*,(*,(*,0))) --> num>"
"<(*,a,b) --> like>"
"<(*,bird,plant) --> ?x>"
"<(-,swimmer,animal) --> (-,swimmer,bird)>"
"<(--,<robin --> [flying]>) ==> <robin --> bird>>"
"<(--,<robin --> bird>) ==> <robin --> [flying]>>"
"<(/,neutralization,_,base) --> ?x>"
r"<(\,(\,REPRESENT,_,<(*,CAT,FISH) --> FOOD>),_,eat,fish) --> cat>"
r"<(\,REPRESENT,_,CAT) --> cat>"
r"<(\,neutralization,acid,_) --> ?x>"
"<(|,boy,girl) --> youth>"
"<(~,boy,girl) --> [strong]>"
"<(~,swimmer,swan) --> bird>"
"<0 --> (/,num,_)>"
"<0 --> num>"
"<<$1 --> lock> ==> (&&,<#2 --> key>,<$1 --> (/,open,#2,_)>)>"
"<<$1 --> num> ==> <(*,$1) --> num>>"
"<<$x --> animal> <=> <$x --> bird>>"
"<<$x --> bird> ==> <$x --> animal>>"
"<<$x --> key> ==> <{lock1} --> (/,open,$x,_)>>"
"<<$y --> [with_wings]> ==> <$y --> flyer>>"
"<<$y --> flyer> ==> <$y --> [with_wings]>>"
"<<(&,<#1 --> $2>,<$3 --> #1>) --> claimedByBob> ==> <<$3 --> $2> --> claimedByBob>>"
"<<(*,$1,$2) --> like> <=> <(*,$2,$1) --> like>>"
"<<bird --> $x> ==> <robin --> $x>>"
"<<lock1 --> (/,open,$1,_)> ==> <$1 --> key>>"
"<<robin --> [flying]> ==> <robin --> [with_beak]>>"
"<<robin --> [flying]> ==> <robin --> animal>>"
"<<robin --> animal> <=> <robin --> bird>>"
"<<robin --> bird> <=> <robin --> [flying]>>"
"<<robin --> bird> ==> (&&,<robin --> animal>,<robin --> [flying]>)>"
"<<robin --> bird> ==> <robin --> [flying]>>"
"<<robin --> bird> ==> <robin --> animal>>"
"<?1 --> swimmer>"
"<Birdie <-> Tweety>"
"<Tweety {-- bird>"
"<Tweety {-] yellow>"
"<[bright] <-> [smart]>"
"<[smart] --> [bright]>"
"<acid --> (/,reaction,_,base)>"
"<cat --> (/,(/,REPRESENT,_,<(*,CAT,FISH) --> FOOD>),_,eat,fish)>"
"<neutralization --> (*,acid,base)>"
"<planetX --> {Mars,Pluto,Venus}>"
"<planetX --> {Pluto,Saturn}>"
"<raven --] black>"
"<robin --> (&,bird,swimmer)>"
"<robin --> (-,bird,swimmer)>"
"<robin --> (|,bird,swimmer)>"
"<robin --> [flying]>"
"<{?1} --> swimmer>"
"<{Birdie} <-> {Tweety}>"
"<{Tweety} --> [with_wings]>"
"<{Tweety} --> flyer>"
"<{Tweety} --> {Birdie}>"
"<{key1} --> (/,open,_,{lock1})>"
"(&&,<(*,1,FALSE) --> #3>,<(*,1) --> #2>)" }
ok!()
}
}