1#![warn(missing_docs)]
2#![doc = include_str!("../README.md")]
3#![doc = include_str!("../examples/church_encoding.rs")]
8#![doc = include_str!("../examples/parser.rs")]
14#![doc = include_str!("../examples/y_combinator.rs")]
20mod error;
23mod eval;
24mod exp;
25
26#[doc(hidden)]
27pub mod builder;
28pub mod parser;
29#[cfg(feature = "wasm")]
30pub mod wasm;
31
32pub use error::Error;
33pub use eval::SIMPLIFY_LIMIT;
34pub use exp::Exp;
35pub use exp::Ident;
36
37#[cfg(test)]
38mod tests {
39 use super::{Exp, Ident};
40 use crate::{lambda, Error};
41
42 #[test]
43 fn test_display() {
44 println!(
45 "{}",
46 Exp::Abs(
47 Ident(String::from("x"), 0),
48 Box::new(Exp::App(
49 Box::new(Exp::Var(Ident(String::from("y"), 0))),
50 Box::new(Exp::Var(Ident(String::from("x"), 2)))
51 ))
52 )
53 )
54 }
55 #[test]
56 fn test_clone() {
57 let mut tt = lambda!(x.y.x).purify();
58 let mut ff = tt.clone();
59 ff.into_abs()
60 .unwrap()
61 .1
62 .into_abs()
63 .unwrap()
64 .1
65 .into_ident()
66 .unwrap()
67 .1 = 1;
68 assert_eq!(
69 tt.into_abs()
70 .unwrap()
71 .1
72 .into_abs()
73 .unwrap()
74 .1
75 .into_ident()
76 .unwrap()
77 .1,
78 2
79 );
80 println!("tt = {}, ff = {}", tt, ff);
81 }
82 #[test]
83 fn test_macros() {
84 let l_true = lambda!(x.y.x);
85 let l_false = lambda!(x.y.y);
86 let y_comb = lambda!(f.(x. f (x x)) (x. f (x x)));
87 assert_eq!(format!("{}", y_comb), "λf. (λx. f (x x)) λx. f (x x)");
88 assert_eq!(
89 format!("{:#}", y_comb),
90 "λf. (λx. f<2> (x<1> x<1>)) λx. f<2> (x<1> x<1>)"
91 );
92
93 println!("{}\n{}\n{}\n", l_true, l_false, y_comb);
94 println!("{:#}\n{:#}\n{:#}", l_true, l_false, y_comb);
95
96 let test_app = lambda!(x. y. z. x y z);
97 let test_app2 = lambda!(x. y. z. (x (y z)) (x z));
98
99 println!("{}\n{}", test_app, test_app2);
100 }
101 #[test]
102 fn test_eval() {
103 let tt = lambda!(x. (y. x));
104 let and = lambda!(x. y. x y x);
105 let mut res = lambda!({and} {tt} {tt});
109
110 println!("res = {}", res);
111 while res.eval_normal_order(false) {
112 println!("res = {}", res);
113 }
114 assert_eq!(res.to_string(), "λx. λy. x");
115 }
116 #[test]
117 fn test_nat() -> Result<(), Error> {
118 let zero = lambda!(s. (z. z));
119 let suc = lambda!(n. s. z. s (n s z));
120 let mut plus = lambda!(n. m. n {suc} m);
121 plus.simplify()?;
122
123 let mut nats = vec![zero];
124 for i in 1..10 {
125 let x = nats.last().unwrap();
126 let mut sx = lambda!({suc} {x});
127 sx.simplify()?;
128 eprintln!("{} = {}", i, sx.purify());
129 nats.push(sx);
130 }
131 let mut test = lambda!({plus} {nats[4]} {nats[3]});
132 test.simplify()?;
133 println!("test = {:#}", test);
134
135 assert_eq!(test.to_string(), nats[7].to_string());
136 Ok(())
137 }
138}