All Projects → ucsd-progsys → Elsa

ucsd-progsys / Elsa

Licence: mit
Elsa is a lambda calculus evaluator

Programming Languages

haskell
3896 projects

Projects that are alternatives of or similar to Elsa

Lambda Talk
A Flock of Functions: Combinators, Lambda Calculus, & Church Encodings in JS
Stars: ✭ 315 (+133.33%)
Mutual labels:  lambda-calculus
Ltext
λtext - higher-order file applicator
Stars: ✭ 37 (-72.59%)
Mutual labels:  lambda-calculus
Church
⛪️ Church Encoding in JS
Stars: ✭ 107 (-20.74%)
Mutual labels:  lambda-calculus
Plam
An interpreter for learning and exploring pure λ-calculus
Stars: ✭ 385 (+185.19%)
Mutual labels:  lambda-calculus
Dblib Linear
Formalisation of the linear lambda calculus in Coq
Stars: ✭ 10 (-92.59%)
Mutual labels:  lambda-calculus
Lambda calculus
A simple, zero-dependency implementation of the untyped lambda calculus in Safe Rust
Stars: ✭ 46 (-65.93%)
Mutual labels:  lambda-calculus
Cedille
Cedille, a dependently typed programming languages based on the Calculus of Dependent Lambda Eliminations
Stars: ✭ 289 (+114.07%)
Mutual labels:  lambda-calculus
Iron
Coq formalizations of functional languages.
Stars: ✭ 114 (-15.56%)
Mutual labels:  lambda-calculus
Zion
A statically-typed strictly-evaluated garbage-collected readable programming language.
Stars: ✭ 33 (-75.56%)
Mutual labels:  lambda-calculus
Formality Javascript
An implementation of the Formality language in JavaScript
Stars: ✭ 71 (-47.41%)
Mutual labels:  lambda-calculus
Hol
Canonical sources for HOL4 theorem-proving system. Branch `develop` is where “mainline development” occurs; when `develop` passes our regression tests, `master` is merged forward to catch up.
Stars: ✭ 414 (+206.67%)
Mutual labels:  lambda-calculus
Aws Lambda Workshop
Some incremental examples suitable to host an AWS Lambda Functions workshop
Stars: ✭ 18 (-86.67%)
Mutual labels:  lambda-calculus
Mikrokosmos
(λ) Educational lambda calculus interpreter
Stars: ✭ 50 (-62.96%)
Mutual labels:  lambda-calculus
Magic In Ten Mins
十分钟魔法练习
Stars: ✭ 327 (+142.22%)
Mutual labels:  lambda-calculus
Y Combinator For Non Programmers
🍱 Y Combinator for Non-programmers: A Wild Introduction to Computer Science
Stars: ✭ 109 (-19.26%)
Mutual labels:  lambda-calculus
Lambda
🔮 Estudos obscuros de programação funcional
Stars: ✭ 297 (+120%)
Mutual labels:  lambda-calculus
Pts
implementation of Pure Type Systems (PTS) in Rust.
Stars: ✭ 41 (-69.63%)
Mutual labels:  lambda-calculus
Kind
A modern proof language
Stars: ✭ 2,075 (+1437.04%)
Mutual labels:  lambda-calculus
Combinators Js
🐦 Some combinators
Stars: ✭ 114 (-15.56%)
Mutual labels:  lambda-calculus
Lambda
Fun with λ calculus!
Stars: ✭ 65 (-51.85%)
Mutual labels:  lambda-calculus

ELSA

elsa is a tiny language designed to build intuition about how the Lambda Calculus, or more generally, computation-by-substitution works. Rather than the usual interpreter that grinds lambda terms down to values, elsa aims to be a light-weight proof checker that determines whether, under a given sequence of definitions, a particular term reduces to to another.

Online Demo

You can try elsa online at this link

Install

You can locally build and run elsa by

  1. Installing stack
  2. Cloning this repo
  3. Building elsa with stack.

That is, to say

$ curl -sSL https://get.haskellstack.org/ | sh
$ git clone https://github.com/ucsd-progsys/elsa.git
$ cd elsa
$ stack install

Editor Plugins

Overview

elsa programs look like:

-- id_0.lc
let id   = \x -> x
let zero = \f x -> x

eval id_zero :
  id zero
  =d> (\x -> x) (\f x -> x)   -- expand definitions
  =a> (\z -> z) (\f x -> x)   -- alpha rename
  =b> (\f x -> x)             -- beta reduce
  =d> zero                    -- expand definitions

eval id_zero_tr :
  id zero  
  =*> zero                    -- transitive reductions

When you run elsa on the above, you should get the following output:

$ elsa ex1.lc

OK id_zero, id_zero_tr.

Partial Evaluation

If instead you write a partial sequence of reductions, i.e. where the last term can still be further reduced:

-- succ_1_bad.lc
let one  = \f x -> f x
let two  = \f x -> f (f x)
let incr = \n f x -> f (n f x)

eval succ_one :
  incr one
  =d> (\n f x -> f (n f x)) (\f x -> f x)
  =b> \f x -> f ((\f x -> f x) f x)
  =b> \f x -> f ((\x -> f x) x)

Then elsa will complain that

$ elsa ex2.lc

ex2.lc:11:7-30: succ_one can be further reduced

  11  |   =b> \f x -> f ((\x -> f x) x)
              ^^^^^^^^^^^^^^^^^^^^^^^^^

You can fix the error by completing the reduction

-- succ_1.lc
let one  = \f x -> f x
let two  = \f x -> f (f x)
let incr = \n f x -> f (n f x)

eval succ_one :
  incr one
  =d> (\n f x -> f (n f x)) (\f x -> f x)
  =b> \f x -> f ((\f x -> f x) f x)
  =b> \f x -> f ((\x -> f x) x)
  =b> \f x -> f (f x)                 -- beta-reduce the above
  =d> two                             -- optional

Similarly, elsa rejects the following program,

-- id_0_bad.lc
let id   = \x -> x
let zero = \f x -> x

eval id_zero :
  id zero
  =b> (\f x -> x)
  =d> zero

with the error

$ elsa ex4.lc

ex4.lc:7:5-20: id_zero has an invalid beta-reduction

   7  |   =b> (\f x -> x)
          ^^^^^^^^^^^^^^^

You can fix the error by inserting the appropriate intermediate term as shown in id_0.lc above.

Syntax of elsa Programs

An elsa program has the form

-- definitions
[let <id> = <term>]+

-- reductions
[<reduction>]*

where the basic elements are lambda-calulus terms

<term> ::=  <id>
          \ <id>+ -> <term>
            (<term> <term>)

and id are lower-case identifiers

<id>   ::= x, y, z, ...

A <reduction> is a sequence of terms chained together with a <step>

<reduction> ::= eval <id> : <term> (<step> <term>)*

<step>      ::= =a>   -- alpha equivalence
                =b>   -- beta  equivalence
                =d>   -- def   equivalence
                =*>   -- trans equivalence
                =~>   -- normalizes to

Semantics of elsa programs

A reduction of the form t_1 s_1 t_2 s_2 ... t_n is valid if

  • Each t_i s_i t_i+1 is valid, and
  • t_n is in normal form (i.e. cannot be further beta-reduced.)

Furthermore, a step of the form

  • t =a> t' is valid if t and t' are equivalent up to alpha-renaming,
  • t =b> t' is valid if t beta-reduces to t' in a single step,
  • t =d> t' is valid if t and t' are identical after let-expansion.
  • t =*> t' is valid if t and t' are in the reflexive, transitive closure of the union of the above three relations.
  • t =~> t' is valid if t normalizes to t'.

(Due to Michael Borkowski)

The difference between =*> and =~> is as follows.

  • t =*> t' is any sequence of zero or more steps from t to t'. So if you are working forwards from the start, backwards from the end, or a combination of both, you could use =*> as a quick check to see if you're on the right track.

  • t =~> t' says that t reduces to t' in zero or more steps and that t' is in normal form (i.e. t' cannot be reduced further). This means you can only place it as the final step.

So elsa would accept these three

eval ex1:
  (\x y -> x y) (\x -> x) b 
  =*> b

eval ex2:
  (\x y -> x y) (\x -> x) b 
  =~> b

eval ex3:
  (\x y -> x y) (\x -> x) (\z -> z) 
  =*> (\x -> x) (\z -> z) 
  =b> (\z -> z)

but elsa would not accept

eval ex3:
  (\x y -> x y) (\x -> x) (\z -> z) 
  =~> (\x -> x) (\z -> z) 
  =b> (\z -> z)

because the right hand side of =~> can still be reduced further.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].