1use super::*;
4
5pub fn to_net(term : &Term) -> INet {
8 fn encode_term
9 ( net : &mut INet
10 , term : &Term
11 , up : Port
12 , scope : &mut HashMap<Vec<u8>,u32>
13 , vars : &mut Vec<(Vec<u8>,u32)>
14 ) -> Port {
15 match term {
16 &Lam { ref nam, ref typ, ref bod } => {
35 let fun = new_node(net, CON);
36 if let Some(ref typ) = typ {
37 let ann = new_node(net, ANN);
38 let typ = encode_term(net, typ, port(ann, 0), scope, vars);
39 link(net, port(ann, 0), typ);
40 link(net, port(fun, 1), port(ann, 1));
41 scope.insert(nam.to_vec(), port(ann, 2));
42 } else {
43 scope.insert(nam.to_vec(), port(fun, 1));
44 }
45 if nam == b"*" {
46 let era = new_node(net, ERA);
47 link(net, port(era, 1), port(era, 2));
48 link(net, port(fun, 1), port(era, 0));
49 }
50 let bod = encode_term(net, bod, port(fun, 2), scope, vars);
51 link(net, port(fun, 2), bod);
52 port(fun, 0)
53 },
54 &App{ref fun, ref arg} => {
59 let app = new_node(net, CON);
60 let fun = encode_term(net, fun, port(app, 0), scope, vars);
61 link(net, port(app, 0), fun);
62 let arg = encode_term(net, arg, port(app, 1), scope, vars);
63 link(net, port(app, 1), arg);
64 port(app, 2)
65 },
66 &Ann{ref val, ref typ} => {
71 let ann = new_node(net, ANN);
72 let val = encode_term(net, val, port(ann, 2), scope, vars);
73 link(net, port(ann, 2), val);
74 let typ = encode_term(net, typ, port(ann, 0), scope, vars);
75 link(net, port(ann, 0), typ);
76 port(ann, 1)
77 },
78 &Sup{tag, ref fst, ref snd} => {
83 let dup = new_node(net, DUP + tag);
84 let fst = encode_term(net, fst, port(dup, 1), scope, vars);
85 link(net, port(dup, 1), fst);
86 let snd = encode_term(net, snd, port(dup, 2), scope, vars);
87 link(net, port(dup, 2), snd);
88 port(dup, 0)
89 },
90 &Dup{tag, ref fst, ref snd, ref val, ref nxt} => {
95 let dup = new_node(net, DUP + tag);
96 scope.insert(fst.to_vec(), port(dup, 1));
97 scope.insert(snd.to_vec(), port(dup, 2));
98 if fst == b"*" {
100 let era = new_node(net, ERA);
101 link(net, port(era, 1), port(era, 2));
102 link(net, port(dup, 1), port(era, 0));
103 }
104 if snd == b"*" {
106 let era = new_node(net, ERA);
107 link(net, port(era, 1), port(era, 2));
108 link(net, port(dup, 2), port(era, 0));
109 }
110 let val = encode_term(net, &val, port(dup, 0), scope, vars);
111 link(net, val, port(dup, 0));
112 encode_term(net, &nxt, up, scope, vars)
113 },
114 &Set => {
116 let set = new_node(net, ERA);
117 link(net, port(set, 1), port(set, 2));
118 port(set, 0)
119 },
120 Var{ref nam} => {
121 vars.push((nam.to_vec(), up));
122 up
123 }
124 }
125 }
126
127 let mut net = new_inet();
128 let mut vars = Vec::new();
129 let mut scope = HashMap::new();
130
131 let main = encode_term(&mut net, &term, ROOT, &mut scope, &mut vars);
133
134 for i in 0..vars.len() {
136 let (ref nam, var) = vars[i];
137 match scope.get(nam) {
138 Some(next) => {
139 let next = *next;
140 if enter(&net, next) == next {
141 link(&mut net, var, next);
142 } else {
143 panic!("Variable used more than once: {}.", std::str::from_utf8(nam).unwrap());
144 }
145 },
146 None => panic!("Unbound variable: {}.", std::str::from_utf8(nam).unwrap())
147 }
148 }
149
150 for (_, addr) in scope {
152 if enter(&net, addr) == addr {
153 let era = new_node(&mut net, ERA);
154 link(&mut net, port(era, 1), port(era, 2));
155 link(&mut net, addr, port(era, 0));
156 }
157 }
158
159 link(&mut net, 1, main);
161
162 net
163}
164
165pub fn from_net(net : &INet) -> Term {
167 fn name_of(net : &INet, var_port : Port, var_name : &mut HashMap<u32, Vec<u8>>) -> Vec<u8> {
169 if kind(net, addr(enter(net, var_port))) == ERA {
171 return b"*".to_vec();
172 }
173 if !var_name.contains_key(&var_port) {
174 let nam = index_to_name(var_name.len() as u32 + 1);
175 var_name.insert(var_port, nam.clone());
176 }
177 var_name.get(&var_port).unwrap().to_vec()
178 }
179
180 fn read_term
182 ( net : &INet
183 , next : Port
184 , var_name : &mut HashMap<u32, Vec<u8>>
185 , dups_vec : &mut Vec<u32>
186 , dups_set : &mut HashSet<(u32)>
187 ) -> Term {
188 match kind(net, addr(next)) {
189 ERA => Set,
191 CON => match slot(next) {
193 0 => {
195 let nam = name_of(net, port(addr(next), 1), var_name);
196 let prt = enter(net, port(addr(next), 2));
197 let bod = read_term(net, prt, var_name, dups_vec, dups_set);
198 let ann = enter(net, port(addr(next), 1));
199 let typ = if kind(net, addr(ann)) == ANN && slot(ann) == 1 {
200 let ann_addr = addr(ann);
201 let typ_port = enter(net, port(ann_addr, 0));
202 Some(Box::new(read_term(net, typ_port, var_name, dups_vec, dups_set)))
203 } else {
204 None
205 };
206 let mut lam = Lam {
207 nam: nam,
208 typ: typ,
209 bod: Box::new(bod),
210 };
211 lam
212 },
213 1 => {
215 Var{nam: name_of(net, next, var_name)}
216 },
217 _ => {
219 let prt = enter(net, port(addr(next), 0));
220 let fun = read_term(net, prt, var_name, dups_vec, dups_set);
221 let prt = enter(net, port(addr(next), 1));
222 let arg = read_term(net, prt, var_name, dups_vec, dups_set);
223 App{fun: Box::new(fun), arg: Box::new(arg)}
224 }
225 },
226 ANN => match slot(next) {
228 0 => {
230 todo!();
231 },
232 1 => {
234 let prt = enter(net, port(addr(next), 2));
235 let val = read_term(net, prt, var_name, dups_vec, dups_set);
236 let prt = enter(net, port(addr(next), 0));
237 let typ = read_term(net, prt, var_name, dups_vec, dups_set);
238 Ann{val: Box::new(val), typ: Box::new(typ)}
239 },
240 _ => {
242 let prt = enter(net, port(addr(next), 1));
243 let val = read_term(net, prt, var_name, dups_vec, dups_set);
244 val
245 }
249 },
250
251 tag => match slot(next) {
253 0 => {
255 let tag = tag - DUP;
256 let prt = enter(net, port(addr(next), 1));
257 let fst = read_term(net, prt, var_name, dups_vec, dups_set);
258 let prt = enter(net, port(addr(next), 2));
259 let snd = read_term(net, prt, var_name, dups_vec, dups_set);
260 Sup{tag, fst: Box::new(fst), snd: Box::new(snd)}
261 },
262 _ => {
265 if !dups_set.contains(&addr(next)) {
266 dups_set.insert(addr(next));
267 dups_vec.push(addr(next));
268 }
269 let nam = name_of(net, next, var_name);
270 Var{nam}
271 }
272 }
273 }
274 }
275
276 let mut binder_name = HashMap::new();
279
280 let mut dups_vec = Vec::new();
284 let mut dups_set = HashSet::new();
285
286 let mut main = read_term(net, enter(net, ROOT), &mut binder_name, &mut dups_vec, &mut dups_set);
288
289 while dups_vec.len() > 0 {
291 let dup = dups_vec.pop().unwrap();
292 let val = read_term(net, enter(net,port(dup,0)), &mut binder_name, &mut dups_vec, &mut dups_set);
293 let tag = kind(net, dup) - DUP;
294 let fst = name_of(net, port(dup,1), &mut binder_name);
295 let snd = name_of(net, port(dup,2), &mut binder_name);
296 let val = Box::new(val);
297 let nxt = Box::new(main);
298 main = Dup{tag, fst, snd, val, nxt};
299 }
300 main
301}