lamcalc/
lib.rs

1#![warn(missing_docs)]
2#![doc = include_str!("../README.md")]
3//!
4//! ## Example: Church Encoding
5//!
6//! ```rust
7#![doc = include_str!("../examples/church_encoding.rs")]
8//! ```
9//!
10//! ## Example: Parser
11//!
12//! ```rust
13#![doc = include_str!("../examples/parser.rs")]
14//! ```
15//!
16//! ## Example: Y Combinator
17//!
18//! ```rust
19#![doc = include_str!("../examples/y_combinator.rs")]
20//! ```
21
22mod 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 or = lambda!(x. y. x y [tt]);
106        // let neg = lambda!(x. x [ff] [tt]);
107
108        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}