1use std::iter::once;
2
3use lambda_calculus::Term;
4
5pub fn encode(a: &Term) -> Box<dyn Iterator<Item = bool> + '_> {
6 match a {
7 Term::Var(a) => Box::new((0..=*a).map(|_| true).chain(once(false))),
8 Term::Abs(term) => Box::new([false, false].into_iter().chain(encode(&term))),
9 Term::App(a) => {
10 let (a, b) = &**a;
11 return Box::new([false, true].into_iter().chain(encode(a)).chain(encode(b)));
12 }
13 }
14}
15pub fn decode(a: &mut impl Iterator<Item = bool>) -> Option<Term> {
16 Some(match a.next()? {
17 true => {
18 let mut i = 0;
19 while a.next()? {
20 i += 1
21 }
22 Term::Var(i)
23 }
24 false => match a.next()? {
25 false => Term::Abs(Box::new(decode(a)?)),
26 true => Term::App(Box::new((decode(a)?, decode(a)?))),
27 },
28 })
29}