An interpreter for lambda calculus.
- C++ 17 compatible compiler
- Bazel
To build all targets execute
$ bazel build ...
To test all targets execute
$ bazel test ...
To run the lambda calculus interpreter execute
$ bazel run //lhat/repl:main
To add names to a nameless combinator term use 'add-names'.
> add-names (^ 0)
(^ a a)
To remove names from a term use 'remove-names'.
> remove-names (^ x x)
(^ 0)
To check if two terms are α-equivalent use alpha-equiv?
.
> alpha-equiv? ((^ x x) z) ((^ y y) z)
true
To check if a term is a β-redex use beta-redex?
.
> beta-redex? ((^ x x) z)
true
To check if a term is in β-normal form use beta-normal?
.
> beta-normal? (x ((^ y y) z))
false
To check if a term is in head normal form use head-normal?
.
> head-normal? (^ x (^ y ((^ z (y z)) x)))
false
β-reduction of lambda terms is performed using beta-reduce
.
> beta-reduce ((^ x x) ((^ y y) z))
((^ a a) z)
Applicative β-normalization of lambda terms is performed using beta-eval-appl
.
> beta-eval-appl ((^ x (x y)) z)
(z y)
Normal β-normalization of lambda terms is performed using beta-eval-normal
.
> beta-eval-normal ((^ x y) ((^ x (x x)) (^ x (x x))))
y
η-reduction of lambda terms is performed using eta-reduce
.
> eta-reduce (^ x ((^ y z) x))
(^ a z)
η-normalization of lambda terms is performed using eta-eval
.
> eta-eval (^ v ((w (^ x ((^ y z) x))) v))
(w (^ a z))
Applicative βη-normalization of lambda terms is performed using beta-eta-eval-appl
.
> beta-eta-eval-appl (^ u (((^ x (x y)) z) u))
(z y)
Normal βη-normalization of lambda terms is performed using beta-eta-eval-normal
.
> beta-eta-eval-normal (^ u (((^ x y) ((^ x (x x)) (^ x (x x)))) u))
y
To infer the type of a term use infer-type
.
> infer-type (^ x (^ y (x y)))
(T4 -> T5) -> T4 -> T5
The interpreter supports definition of constants via the def
command. While
reducing a lambda term it automatically substitutes the constants present in the
term for their predefined values. To reference a constant in a term prefix its name
by '
.
> def K (^ x (^ y x))
> def I (^ x x)
> def K* ('K 'I)
> eval-appl ('K z)
(^ a z)
> eval-appl ('K* z)
(^ a a)
The behavior of the interpreter can be controlled using the following command-line flags.
The interpreter could execute a list of commands specified in a file before
becoming interactive. Pass the path to the file as an argument to the --exec
flag. Multiple --exec
flags could be provided in a single run of the interpreter.
$ bazel run //lhat/repl:main -- --exec /git/lhat/examples/combinators
> eval-appl ('K z)
(^ a z)