1extern crate sic;
7
8use term::*;
9use term::Vars;
10use term::Defs;
11use term::Term::*;
12use term::Context;
13
14pub fn term_to_lambda(term : &Term, defs : &Defs, scope : &mut Vec<Vec<u8>>, name_count : &mut u32, copy_count : &mut u32) -> sic::term::Term {
15 pub fn gen_name(name_count : &mut u32) -> Vec<u8> {
16 *name_count += 1;
17 sic::term::new_name(*name_count)
18 }
19 pub fn build(term : &Term, rec : &mut (Vec<u8>, Vec<u8>), defs : &Defs, scope : &mut Vec<Vec<u8>>, name_count : &mut u32, copy_count : &mut u32) -> sic::term::Term {
20 match term {
21 All{nam: _, typ: _, bod: _} => {
22 sic::term::Term::Set
24 },
25 Lam{nam: _, typ: _, bod} => {
26 let nam = gen_name(name_count);
27 scope.push(nam.clone());
28 let bod = Box::new(build(bod, rec, defs, scope, name_count, copy_count));
29 scope.pop();
30 sic::term::Term::Lam{nam, bod}
31 },
32 Var{idx} => {
33 sic::term::Term::Var{nam: scope[scope.len() - (*idx as usize) - 1].clone()}
34 },
35 App{fun, arg} => {
36 let fun = Box::new(build(fun, rec, defs, scope, name_count, copy_count));
37 let arg = Box::new(build(arg, rec, defs, scope, name_count, copy_count));
38 sic::term::Term::App{fun, arg}
39 },
40 Idt{nam: _, arg: _, par: _, typ: _, ctr: _} => {
41 sic::term::Term::Set
43 },
44 New{idt: _, ctr, bod} => {
45 let mut nams = Vec::new();
46
47 for _ in 0..ctr.len() {
48 let nam = gen_name(name_count);
49 scope.push(nam.clone());
50 nams.push(nam);
51 }
52
53 let mut res = build(bod, rec, defs, scope, name_count, copy_count);
54
55 for _ in 0..ctr.len() {
56 scope.pop();
57 }
58
59 for i in (0..ctr.len()).rev() {
60 res = sic::term::Term::Lam{nam: nams[i].clone(), bod: Box::new(res)};
61 }
62
63 res
64 },
65 Cas{val, cas, ret: _} => {
66 let mut folds = false;
68 for (_, cas_typ, cas_bod) in cas {
69 folds = folds || uses(cas_bod, cas_typ.len() as i32) > 0;
70 }
71
72 let fold_a = if folds { gen_name(name_count) } else { Vec::new() };
74 let fold_b = if folds { gen_name(name_count) } else { Vec::new() };
75
76 let var = gen_name(name_count);
83 let mut fun_bod = sic::term::Term::Var{nam: var.clone()};
84
85 for (_cas_nam, cas_args, cas_bod) in cas {
87 let mut nams = Vec::new();
89 let fold_nam = gen_name(name_count);
90 scope.push(fold_nam.clone());
91 for _ in 0..cas_args.len() {
92 let field_nam = gen_name(name_count);
93 scope.push(field_nam.clone());
94 nams.push(field_nam);
95 }
96 if folds { nams.push(fold_nam.clone()); }
97
98 let cas_bod = build(cas_bod, rec, defs, scope, name_count, copy_count);
100
101 scope.pop();
103 for _ in 0..cas_args.len() {
104 scope.pop();
105 }
106
107 let mut cas_fun = cas_bod;
109 for i in 0..nams.len() {
110 cas_fun = sic::term::Term::Lam{nam: nams[nams.len() - i - 1].clone(), bod: Box::new(cas_fun)}
111 }
112
113 fun_bod = sic::term::Term::App{fun: Box::new(fun_bod), arg: Box::new(cas_fun)};
115 }
116
117 let fun = if folds {
121 sic::term::Term::Let{
122 tag: *copy_count + 10,
123 fst: fold_a.clone(),
124 snd: fold_b.clone(),
125 val: Box::new(sic::term::Term::Lam{
126 nam: var,
127 bod: Box::new(sic::term::Term::App{
128 fun: Box::new(fun_bod),
129 arg: Box::new(sic::term::Term::Var{nam: fold_a})
130 })
131 }),
132 nxt: Box::new(sic::term::Term::Var{nam: fold_b.clone()})
133 }
134 } else {
135 sic::term::Term::Lam{
136 nam: var,
137 bod: Box::new(fun_bod)
138 }
139 };
140
141 let val = build(val, rec, defs, scope, name_count, copy_count);
143
144 let res = sic::term::Term::App{
146 fun: Box::new(fun),
147 arg: Box::new(val)
148 };
149
150 res
151 },
152
153 Cpy{nam: _, val, bod} => {
154 let val = Box::new(build(val, rec, defs, scope, name_count, copy_count));
155
156 let nam_a = gen_name(name_count);
157 scope.push(nam_a.clone());
158
159 let nam_b = gen_name(name_count);
160 scope.push(nam_b.clone());
161
162 let bod = Box::new(build(bod, rec, defs, scope, name_count, copy_count));
163
164 scope.pop();
165
166 scope.pop();
167
168 *copy_count += 1;
169
170 let tag = *copy_count + 10;
171 let fst = nam_a;
172 let snd = nam_b;
173 let val = val;
174 let nxt = bod;
175 sic::term::Term::Let{tag, fst, snd, val, nxt}
176 },
177 Ref{nam} => {
178 if *nam == rec.0 {
179 let nam = rec.1.clone();
180 rec.1 = b"".to_vec();
181 sic::term::Term::Var{nam}
182 } else {
183 match defs.get(nam) {
184 Some(term) => {
185 *copy_count += 1;
186
187 let mut nam_a = nam.clone();
188 nam_a.extend_from_slice(b"$a$");
189 nam_a.append(&mut copy_count.to_string().into_bytes());
190
191 let mut nam_b = nam.clone();
192 nam_b.extend_from_slice(b"$b$");
193 nam_b.append(&mut copy_count.to_string().into_bytes());
194
195 let mut rec = (nam.to_vec(), nam_b.clone());
196 let tag = *copy_count + 10;
197 let fst = nam_a.clone();
198 let snd = nam_b.clone();
199 let ter = build(&term, &mut rec, defs, scope, name_count, copy_count);
200 if rec.1 == b"" {
201 let val = Box::new(ter);
202 let nxt = Box::new(sic::term::Term::Var{nam: nam_a});
203 sic::term::Term::Let{tag, fst, snd, val, nxt}
204 } else {
205 ter
206 }
207 },
208 None => panic!("Undefined variable.")
209 }
210 }
211 },
212 Set => {
213 panic!("Not implemented.")
214 }
215 }
216 }
217 build(term, &mut (b"".to_vec(), b"".to_vec()), defs, scope, name_count, copy_count)
218}
219
220pub fn term_from_lambda(term : &sic::term::Term, typ : &Term, defs : &Defs, vars : &mut Vars, ctx : &mut Context) -> Term {
221 pub fn infer(term : &sic::term::Term, defs : &Defs, vars : &mut Vars, ctx : &mut Context) -> (Term, Term) {
222 match term {
223 sic::term::Term::Lam{nam: _, bod: _} => {
224 panic!("Not implemented.")
225 },
226 sic::term::Term::App{fun, arg} => {
227 let (fun_v, fun_t) = infer(fun, defs, vars, ctx);
228 match fun_t {
229 All{nam: _, typ, bod} => {
230 let fun = Box::new(fun_v);
231 let arg = Box::new(term_from_lambda(arg, &typ, defs, vars, ctx));
232 let mut bod = bod.clone();
233 subs(&mut bod, &arg, 0);
234 (App{fun, arg}, *bod)
235 },
236 t => panic!("Not implemented. {}", t)
237 }
238 },
239 sic::term::Term::Var{nam} => {
240 for i in (0..vars.len()).rev() {
241 if *nam == vars[i] {
242 let val = Var{idx: (vars.len() - i - 1) as i32};
243 let typ = ctx[i].clone();
244 return (val, typ);
245 }
246 }
247 panic!("Not implemented.");
248 },
249 sic::term::Term::Set => {
250 (Set, Set)
251 },
252 _ => panic!("Not implemented. {}", term)
253 }
254 }
255 match term {
256 sic::term::Term::Lam{nam: term_nam, bod: term_bod} => {
257 let typ = weak_reduced(&typ, defs, true);
258 match &typ {
259 All{nam, typ, bod} => {
260 let nam = nam.to_vec();
261 let typ = typ.clone();
262 extend_context(&shifted(&typ,1,0), ctx);
263 vars.push(term_nam.clone());
264 let bod = Box::new(term_from_lambda(term_bod, &bod, defs, vars, ctx));
265 narrow_context(ctx);
266 vars.pop();
267 Lam{nam, typ, bod}
268 },
269 Idt{nam: _, arg: _, par: _, typ: _, ctr} => {
270 for i in 0..ctr.len() {
272 let ctr_typ = &apply_idt_args(&typ).1[i].1;
273 extend_context(&shifted(&ctr_typ, ctr.len() as i32, 0), ctx);
274 }
275
276 let mut bod = term;
278 for _ in 0..ctr.len() {
279 bod = match bod {
280 sic::term::Term::Lam{ref nam, ref bod} => {
281 vars.push(nam.clone());
282 bod
283 },
284 _ => panic!("Attempted to read wrongly shaped SIC term. This is probably a Formality bug.")
285 }
286 }
287
288 let (res, _) = infer(bod, defs, vars, ctx);
290
291 for _ in 0..ctr.len() {
293 vars.pop();
294 narrow_context(ctx);
295 }
296
297 New {
299 idt: Box::new(typ.clone()),
300 ctr: ctr.iter().map(|c| c.0.clone()).collect(),
301 bod: Box::new(res)
302 }
303 },
304 t => panic!("Not implemented. {} : {}", term, t)
305 }
306 },
307 term => {
308 infer(term, defs, vars, ctx).0
309 }
310 }
311}
312
313pub fn eval(term : &Term, defs : &Defs) -> (sic::net::Stats, Term) {
314 let term_type = infer(&term, &defs, true).unwrap();
315 let lambda = term_to_lambda(&term, &defs, &mut Vec::new(), &mut 0, &mut 0);
316 let mut net = sic::term::to_net(&lambda);
317 let stats = sic::net::reduce(&mut net);
318 let lambda_nf = sic::term::from_net(&net); let term_nf = term_from_lambda(&lambda_nf, &term_type, defs, &mut Vec::new(), &mut Vec::new());
320 (stats, term_nf)
321}
322
323pub fn partial_eval(term : &Term, defs : &Defs) -> (sic::net::Stats, sic::term::Term) {
324 let lambda = term_to_lambda(&term, &defs, &mut Vec::new(), &mut 0, &mut 0);
325 let mut net = sic::term::to_net(&lambda);
326 let stats = sic::net::reduce(&mut net);
327 let lambda_nf = sic::term::from_net(&net);
328 (stats, lambda_nf)
329}