Skip to main content

amaru_uplc/
lib.rs

1pub mod arena;
2pub mod binder;
3pub mod bls;
4pub mod builtin;
5pub mod constant;
6pub mod data;
7pub mod flat;
8pub mod ledger_value;
9pub mod machine;
10pub mod program;
11pub mod syn;
12pub mod term;
13pub mod typ;
14
15pub use bumpalo;
16
17#[cfg(test)]
18mod tests {
19    use pretty_assertions::assert_eq;
20
21    use crate::binder::DeBruijn;
22    use crate::program::Version;
23
24    use super::arena::Arena;
25    use super::program::Program;
26    use super::term::Term;
27
28    #[test]
29    fn add_integer() {
30        let arena = Arena::new();
31
32        let term = Term::add_integer(&arena)
33            .apply(&arena, Term::integer_from(&arena, 1))
34            .apply(&arena, Term::integer_from(&arena, 3));
35
36        let version = Version::plutus_v3(&arena);
37
38        let program = Program::<DeBruijn>::new(&arena, version, term);
39
40        let result = program.eval(&arena);
41
42        assert_eq!(result.term.unwrap(), Term::integer_from(&arena, 4));
43    }
44
45    #[test]
46    fn fibonacci() {
47        let arena = &Arena::new();
48
49        let double_force = Term::var(arena, DeBruijn::new(arena, 1))
50            .apply(arena, Term::var(arena, DeBruijn::new(arena, 1)))
51            .lambda(arena, DeBruijn::zero(arena))
52            .delay(arena)
53            .force(arena)
54            .apply(
55                arena,
56                Term::var(arena, DeBruijn::new(arena, 3))
57                    .apply(
58                        arena,
59                        Term::var(arena, DeBruijn::new(arena, 1))
60                            .apply(arena, Term::var(arena, DeBruijn::new(arena, 1)))
61                            .lambda(arena, DeBruijn::zero(arena))
62                            .delay(arena)
63                            .force(arena)
64                            .apply(arena, Term::var(arena, DeBruijn::new(arena, 2))),
65                    )
66                    .apply(arena, Term::var(arena, DeBruijn::new(arena, 1)))
67                    .lambda(arena, DeBruijn::zero(arena))
68                    .lambda(arena, DeBruijn::zero(arena)),
69            )
70            .lambda(arena, DeBruijn::zero(arena))
71            .delay(arena)
72            .delay(arena)
73            .force(arena)
74            .force(arena);
75
76        let if_condition = Term::if_then_else(arena)
77            .force(arena)
78            .apply(arena, Term::var(arena, DeBruijn::new(arena, 3)))
79            .apply(arena, Term::var(arena, DeBruijn::new(arena, 2)))
80            .apply(arena, Term::var(arena, DeBruijn::new(arena, 1)))
81            .apply(arena, Term::unit(arena))
82            .lambda(arena, DeBruijn::zero(arena))
83            .lambda(arena, DeBruijn::zero(arena))
84            .lambda(arena, DeBruijn::zero(arena))
85            .delay(arena)
86            .force(arena);
87
88        let add = Term::add_integer(arena)
89            .apply(
90                arena,
91                Term::var(arena, DeBruijn::new(arena, 3)).apply(
92                    arena,
93                    Term::subtract_integer(arena)
94                        .apply(arena, Term::var(arena, DeBruijn::new(arena, 2)))
95                        .apply(arena, Term::integer_from(arena, 1)),
96                ),
97            )
98            .apply(
99                arena,
100                Term::var(arena, DeBruijn::new(arena, 3)).apply(
101                    arena,
102                    Term::subtract_integer(arena)
103                        .apply(arena, Term::var(arena, DeBruijn::new(arena, 2)))
104                        .apply(arena, Term::integer_from(arena, 2)),
105                ),
106            )
107            .lambda(arena, DeBruijn::zero(arena));
108
109        let term = double_force
110            .apply(
111                arena,
112                if_condition
113                    .apply(
114                        arena,
115                        Term::less_than_equals_integer(arena)
116                            .apply(arena, Term::var(arena, DeBruijn::new(arena, 1)))
117                            .apply(arena, Term::integer_from(arena, 1)),
118                    )
119                    .apply(
120                        arena,
121                        Term::var(arena, DeBruijn::new(arena, 2))
122                            .lambda(arena, DeBruijn::zero(arena)),
123                    )
124                    .apply(arena, add)
125                    .lambda(arena, DeBruijn::zero(arena))
126                    .lambda(arena, DeBruijn::zero(arena)),
127            )
128            .apply(arena, Term::var(arena, DeBruijn::new(arena, 1)))
129            .lambda(arena, DeBruijn::zero(arena))
130            .apply(arena, Term::integer_from(arena, 15));
131
132        let version = Version::plutus_v3(arena);
133
134        let program = Program::new(arena, version, term);
135
136        let result = program.eval(arena);
137
138        assert_eq!(result.term.unwrap(), Term::integer_from(arena, 610));
139    }
140}