/lambda

Lambda calculus parser and beta-reducer in Elixir

Primary LanguageElixir

Lambda calculus parser/unparser and reducer.

Demo:

iex()> import Lambda
iex()> expr = "(λx.Ly.x (y z)) w" # "L" can be used in place of "λ" for ease of typing
iex()> expr |> tokenize
  ["(", "λ", "x", ".", "λ", "y", ".", "x", " ", "(", "y", " ", "z", ")", ")", " ", "w"]
iex()> expr |> tokenize |> to_ast
  {:A, {:L, "x", {:L, "y", {:A, "x", {:A, "y", "z"}}}}, "w"}
iex()> expr |> tokenize |> to_ast == expr |> parse
  true
iex()> expr |> parse |> as_string
  "(λx.λy.x (y z)) w"
iex()> expr |> parse |> reduce_once
  {:L, "y", {:A, "w", {:A, "y", "z"}}}
iex()> expr |> parse |> reduce_once |> as_string
  "λy.w (y z)"

iex()> "((λx.λy.x (y z)) a) b" |> parse |> reduce |> as_string
  "a (b z)"

iex()> y_combinator = "λg.(λx.g (x x)) (Lx.g (x x))"
iex()> y_combinator |> parse |> reduce_once |> as_string
  "λg.g ((λx.g (x x)) (λx.g (x x)))"
iex()> y_combinator |> parse |> reduce(2) |> as_string
  "λg.g (g ((λx.g (x x)) (λx.g (x x))))"
iex()> y_combinator |> parse |> reduce(4) |> as_string
  "λg.g (g (g (g ((λx.g (x x)) (λx.g (x x))))))"

iex()> "(λx.x x) (λx.x x)" |> parse |> reduce(100) |> as_string
  "(λx.x x) (λx.x x)"