ttt/
debruijn_indexed.rs

1/// Syntax nodes which have free variables represented by DeBruijn indices
2pub trait DeBruijnIndexed: Sized {
3    fn map_indices_from<F>(&self, start: usize, map_fn: F) -> Self
4    where
5        F: Fn(usize) -> usize + Clone;
6
7    fn get_var(&self) -> Option<usize>;
8
9    fn map_indices<F>(&self, map_fn: F) -> Self
10    where
11        F: Fn(usize) -> usize + Clone,
12    {
13        self.map_indices_from(0, map_fn)
14    }
15
16    // type VarType: std::cmp::Ord;
17    /// Increment de Bruijn indices in the term which are at least equal to `start`
18    /// by `amount`.
19    /// This is required for example, when adjusting de Bruijn indices in an
20    /// expression where new variables are bound.
21    fn increment_indices_from_by(&self, start: usize, amount: usize) -> Self {
22        self.map_indices_from(start, |i| i + amount)
23    }
24
25    /// Increment de Bruijn indices in the term by `amount`.
26    fn increment_indices_by(&self, amount: usize) -> Self {
27        self.increment_indices_from_by(0, amount)
28    }
29
30    /// Increment de Bruijn indices in the term by one.
31    fn increment_indices(&self) -> Self {
32        self.increment_indices_by(1)
33    }
34}
35
36impl<T: DeBruijnIndexed> DeBruijnIndexed for Box<T> {
37    fn map_indices_from<F>(&self, start: usize, map_fn: F) -> Self
38    where
39        F: Fn(usize) -> usize + Clone,
40    {
41        (**self).map_indices_from(start, map_fn).into()
42    }
43
44    fn get_var(&self) -> Option<usize> {
45        DeBruijnIndexed::get_var(&**self)
46    }
47}
48
49impl<T: DeBruijnIndexed> DeBruijnIndexed for Option<T> {
50    fn map_indices_from<F>(&self, start: usize, map_fn: F) -> Self
51    where
52        F: Fn(usize) -> usize + Clone,
53    {
54        self.as_ref()
55            .map(|expr| expr.map_indices_from(start, map_fn))
56    }
57
58    fn get_var(&self) -> Option<usize> {
59        self.as_ref().and_then(|expr| expr.get_var())
60    }
61}