1#![no_std]
5
6extern crate alloc;
7extern crate core;
8
9use core::{fmt, mem};
10use alloc::{boxed::Box, format, string::String};
11use hashbrown::HashMap;
12
13#[deny(clippy::unwrap_used)]
14#[deny(clippy::expect_used)]
15#[deny(clippy::panic)]
16#[allow(clippy::empty_line_after_outer_attr)]
17
18pub type ID = usize;
22pub type ZtaFn = for<'a> fn(inp: &'a mut Kind) -> Result<Kind, &'a mut Kind>;
23
24#[derive(Clone)]
25pub enum Kind {
26 Alp {id: ID},
27 Zta {sid: Option<ID>, hid: ID, fnc: ZtaFn},
28 Pir {l: Box<Kind>, r: Box<Kind>}
29}
30impl From<ID> for Kind {
31 fn from(val: ID) -> Self {
32 Self::Alp {id: val}
33 }
34}
35impl TryFrom<(ZtaFn, ID)> for Kind {
36 type Error = ();
37 fn try_from(val: (ZtaFn, ID)) -> Result<Self, Self::Error> {
38 match val.1.checked_add(2) {
39 Some(hid) => Ok(Self::Zta {sid: None, hid, fnc: val.0}),
40 None => Err(()),
41 }
42 }
43}
44impl From<(Kind, Kind)> for Kind {
45 fn from(val: (Kind, Kind)) -> Self {
46 Self::Pir {l: Box::new(val.0), r: Box::new(val.1)}
47 }
48}
49impl fmt::Debug for Kind {
50 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51 match self {
52 Kind::Alp { id } => write!(f, "I:{id}"),
53 Kind::Zta { sid, hid, ..} => match sid {
54 Some(id) => write!(f, "Z:{hid}:{id}"),
55 None => write!(f, "Z:{hid}"),
56 },
57 Kind::Pir { l, r } => write!(f, "({l:?} {r:?})"),
58 }
59 }
60}
61
62struct MapIDK {
66 map: HashMap<ID, Option<Kind>>
67}
68impl MapIDK {
69 fn new() -> Self { Self {map: HashMap::new()} }
70 fn get(&mut self, id: ID) -> Option<Kind> {
71 self.map.get_mut(&id).and_then(|k| k.take())
72 }
73 fn set(&mut self, id: ID, v: Kind) {
74 self.map.insert(id, Some(v));
75 }
76}
77
78struct Mtc {
82 map: MapIDK
83}
84impl Mtc {
85 fn new() -> Self { Self { map: MapIDK::new() } }
86 fn alp(&mut self, x: &mut Kind, n: &mut Kind) -> bool {
87 match n {
88 Kind::Alp { id } => match self.map.get(*id) {
89 Some(mut ol) => {
90 if self.mtc(x, &mut ol) {
91 self.map.set(*id, ol); return true
93 }
94 false
96 },
97 None => {
98 let mut k = x.clone();
99 if let Kind::Zta { sid, ..} = &mut k {
100 *sid = Some(*id);
101 }
102
103 self.map.set(*id, k);
104 true
105 },
106 },
107 _ => false
108 }
109 }
110 fn zta(&mut self, x: &mut Kind, n: &mut Kind) -> bool {
111 match x {
112 Kind::Pir { l: mz, r: inp } => match mz.as_mut() {
113 Kind::Zta {fnc, ..}
114 => match fnc(inp) {
115 Ok(xr) => {
116 *x = xr;
117 self.mtc(x, n)
118 },
119 Err(_) => false,
120 },
121 _ => false
122 },
123 _ => false
124 }
125 }
126 fn rec(&mut self, x: &mut Kind, n: &mut Kind) -> bool {
127 match (x, n) {
128 (
129 Kind::Zta {hid: xid, ..},
130 Kind::Zta {hid: nid, ..}
131 ) => {xid == nid},
132 (
133 Kind::Pir {l: xl, r: xr},
134 Kind::Pir {l: nl, r: nr}
135 ) => {
136 if !self.mtc(xl, nl) {return false}
137 self.mtc(xr, nr)
138 },
139 _ => false
140 }
141 }
142 fn mtc(&mut self, x: &mut Kind, n: &mut Kind) -> bool {
143 if self.alp(x, n) {return true}
144 if self.rec(x, n) {return true}
145 self.zta(x, n)
146 }
147 fn ins(&mut self, b: &mut Kind) {
148 match b {
149 Kind::Alp {id} => match self.map.get(*id) {
150 Some(k) => {
151 self.map.set(*id, k.clone()); *b = k
153 },
154 None => (),
155 },
156 Kind::Pir {l, r} => {
157 self.ins(l);
158 self.ins(r)
159 },
160 _ => ()
161 }
162 }
163}
164
165pub fn eta<'a>(inp: &'a mut Kind) -> Result<Kind, &'a mut Kind> {
169 let (n, b, x) = match inp {
170 Kind::Pir {l: nb, r: x} => {
171 match nb.as_mut() {
172 Kind::Pir {l: n, r: b} => (n, b, x),
173 _ => return Err(inp)
174 }
175 },
176 _ => return Err(inp)
177 };
178
179 let mut mt = Mtc::new();
180 if !mt.mtc(x, n) {return Err(inp)}
181 mt.ins(b);
182
183 let bb = mem::replace(b, Box::new(new_omi_kind()));
185
186 Ok(*bb)
187}
188
189pub fn omi<'a>(inp: &'a mut Kind) -> Result<Kind, &'a mut Kind> { Err(inp) }
191
192pub fn new_eta_kind() -> Kind { Kind::Zta {sid:None, hid:1, fnc:eta} }
193pub fn new_omi_kind() -> Kind { Kind::Zta {sid:None, hid:0, fnc:omi} }
194
195pub fn lore(end: Kind) -> Kind {
199 Kind::from((
200 Kind::from((new_omi_kind(), new_omi_kind())),
201 Kind::from((new_eta_kind(), end))
202 ))
203}
204
205pub fn lore_end() -> Kind {
206 Kind::from((
207 new_eta_kind(),
208 Kind::from((
209 Kind::from((new_omi_kind(), new_omi_kind())),
210 new_omi_kind()
211 ))
212 ))
213}
214
215pub struct Dict {
219 map: HashMap<String, ID>,
220 rev: HashMap<ID, String>,
221 i: ID
222}
223impl Dict {
224 pub fn new() -> Self { Self {map: HashMap::new(), rev: HashMap::new(), i: 0} }
225 pub fn get(&mut self, name: String) -> ID {
226 match self.map.get(&name) {
227 Some(id) => *id,
228 None => {
229 self.map.insert(name.clone(), self.i);
230 self.rev.insert(self.i, name);
231 let ret = self.i;
232 self.i += 1;
233 ret
234 },
235 }
236 }
237 pub fn get_name(&self, id: ID) -> Option<String> {
239 self.rev.get(&id).cloned()
240 }
241}
242
243pub fn pretty_string(root: &Kind, dict: &Dict) -> String {
244 match root {
245 Kind::Alp { id } => match dict.get_name(*id) {
246 Some(name) => name,
247 None => format!("#{root:?}"),
248 },
249 Kind::Zta { sid, .. } => match *sid {
250 None => format!("#{root:?}"),
251 Some(id) => match dict.get_name(id) {
252 Some(name) => name,
253 None => format!("#{root:?}"),
254 },
255 }
256 Kind::Pir { l, r } => format!(
257 "({} {})",
258 pretty_string(l, dict), pretty_string(r, dict)
259 )
260 }
261}