lambda

Random lambda calculus stuff

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
use std::collections::HashSet;

#[derive(PartialEq, Clone, Debug)]
enum E {
    L(i64, Box<E>),
    A(Box<E>, Box<E>),
    I(i64),
}

fn sub(term: E, var: i64, rep: &E, offset: i64, bound: &mut HashSet<i64>) -> E {
    match term {
        E::L(var, body) => {
            bound.insert(var);
            let x = E::L(var + offset, Box::new(sub(*body, var, rep, offset, bound)));
            bound.remove(&var);
            x
        }
        E::A(func, arg) => E::A(
            Box::new(sub(*func, var, rep, offset, bound)),
            Box::new(sub(*arg, var, rep, offset, bound)),
        ),
        x => {
            if x == E::I(var) {
                rep.clone()
            } else {
                x
            }
        }
    }
}

fn red(term: E) -> E {
    match term {
        E::L(var, body) => E::L(var, Box::new(red(*body))),
        E::A(func, arg) => {
            let rfunc = red(*func);
            match rfunc {
                E::L(var, body) => red(sub(
                    *body,
                    var,
                    &arg,
                    rand::random_range(0..1 << 32),
                    &mut HashSet::<i64>::new(),
                )),
                x => x,
            }
        }
        x => x,
    }
}

fn main() {
    // Prints nothing?
    println!(
        "{:?}",
        red(E::A(
            Box::new(E::L(1, Box::new(E::L(2, Box::new(E::I(1)))))),
            Box::new(E::I(2))
        ))
    );
}