catlog/tt/util/idx.rs
1//! Indices.
2//!
3//! We find it useful to distinguish between backward indices (used in syntax, where
4//! 0 refers to the *end* of the context) and forward indices (used in values, where
5//! 0 refers to the *beginning* of the context).
6//!
7//! In the literature, backward indices are known as DeBruijn indices and forward
8//! indices are known as DeBruijn levels, but we think that "backwards and forwards"
9//! is more clear, and it corresponds with "backwards and forwards linked lists". A forwards linked list uses `cons` to put a new element on the front; a backwards
10//! linked list uses `snoc` to put a new element on the back.
11//!
12//! We take this terminology from [narya](https://github.com/gwaithimirdain/narya).
13
14use derive_more::From;
15use std::ops::Deref;
16
17/// Forward indices (aka DeBruijn levels)
18///
19/// Get the underlying `usize` using the [Deref] implementation.
20#[derive(Copy, Clone, PartialEq, Eq, Debug, From)]
21pub struct FwdIdx(usize);
22
23impl Deref for FwdIdx {
24 type Target = usize;
25
26 fn deref(&self) -> &Self::Target {
27 &self.0
28 }
29}
30
31impl FwdIdx {
32 /// The forward index refering the the next variable in the scope
33 pub fn next(&self) -> Self {
34 Self(self.0 + 1)
35 }
36
37 /// Convert into a backward index, assuming that the scope is of
38 /// length `scope_length`
39 pub fn as_bwd(&self, scope_length: usize) -> BwdIdx {
40 BwdIdx(scope_length - self.0 - 1)
41 }
42}
43
44/// Backward indices (aka DeBruijn indices).
45///
46/// Get the underlying `usize` using the [Deref] implementation.
47#[derive(Copy, Clone, PartialEq, Eq, Debug, From)]
48pub struct BwdIdx(usize);
49
50impl Deref for BwdIdx {
51 type Target = usize;
52
53 fn deref(&self) -> &Self::Target {
54 &self.0
55 }
56}
57
58impl BwdIdx {
59 /// The backwards index refering to the previous variable in the scope
60 pub fn prev(&self) -> Self {
61 Self(self.0 + 1)
62 }
63}