Skip to content

rootmos/lambdasylum

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lambdasylum

Build Status

The lambda asylum is a place to try out different kinds of lambda calculi. Currently the following calculi are implemented:

calculi

Usage

Simplest way to try it out is by using Docker:

docker run -it rootmos/lambdasylum

Examples

These example reductions are automagically generated by running the tests.

Examples for clambda

λx.xλy.y (α-equiv)

(λx.x) (λy.y y)λz.z z (α-equiv)

(λx.λ_.x)λa.λb.a (α-equiv)

(λ_.λy.y)λa.λb.b (α-equiv)

(λx.λy.x) (λa.a) (λb.b b)λa.a (α-equiv)

(λx.λy.y) (λa.a) (λb.b b)λb.b b (α-equiv)

((λx.{x}) (λa.a))!λa.a (α-equiv)

((λx.(λx.{x}) (λa.a)) (λb.b b))!λa.a (α-equiv)

((λx.(λy.{x}) (λa.a)) (λb.b b))!λb.b b (α-equiv)

λx.(λy.y) xλa.(λb.b) a (α-equiv) ※ reduction stops at λ, no full β-reduction (which would have yielded λx.x)

(λx.λ_.x) ((λy.y) (λz.z z))λ_.λz.z z (α-equiv) ※ reduction eagerly evaluates arguments (when starting with the β-reduction: λ_.(λy.y) (λz.z z))

reached bottom

{⊥}{..}

{{⊥}}{..}

{{⊥}}!{..}

{{⊥}}!!reached bottom

{λx.x}!λx.x (α-equiv)

(λx.x)!λx.x (α-equiv) ※ forcing a non-thunk is accepted (in the untyped setting)

{λx.x} (λy.y y)λy.y y (α-equiv) ※ thunks showing up function position are forced (in the untyped setting)

{(λx.x) (λx.λy.x)}!λx.λ_.x (α-equiv)

((λx.x) (λx.λy.x))!λx.λ_.x (α-equiv)

Examples for ulambda

00

11

(λx.x) 11

(\lambda x.x) 11

#ttrue

#ffalse

#tλx.λy.x (α-equiv)

#tλx.λy.y (α-equiv)

1+23

2+13

0+11

1+01

7-25

0-00

1-01

0-10 ※ subtraction is floored at 0

2-20

0*40

3*412

0λf.λx.x (α-equiv)

1λf.λx.f x (α-equiv)

2λf.λx.f (f x) (α-equiv)

succ 01

succ 12

succ 78

pred 00

pred 10

pred 21

pred 76

if #t 1 21

if #f 1 22

and #t #ttrue

and #f #tfalse

and #t #ffalse

and #f #ffalse

if (and #t #t) 1 21

if (and #f #t) 1 22

if (and #t #f) 1 22

if (and #f #f) 1 22

if (or #t #t) 1 21

if (or #f #t) 1 21

if (or #t #f) 1 21

if (or #f #f) 1 22

if (zero? 0) 1 21

if (zero? 1) 1 22

if (zero? 7) 1 22

if (leq? 3 4) 1 21

if (leq? 3 3) 1 21

if (leq? 4 3) 1 22

if (eq? 3 4) 1 22

if (eq? 3 3) 1 21

if (eq? 4 3) 1 22

reached bottom

\botreached bottom

{⊥}{..}

{{⊥}}{..}

{0}!0

{{0}}!{..}

{{0}}!!0

0!0

{λx.x} 22

if #t 0 {⊥}0

if #f {⊥} 11

if #f {0} ⊥reached bottom

(if #t {0} {⊥})!0

(if #f {0} {⊥})!reached bottom

(if #t 1 {⊥})!1

((if #t 1 {2})!)+12

((if #f 1 {2})!)+13

(fix (λk.λn.(if (eq? n 1) 1 {(k (n-1))*n})!)) 5120 ※ factorial function

(fix (λk.λn.(if (leq? n 1) 1 {(k (n-1))+(k (n-2))})!)) 721 ※ naive Fibonacci sequence

nil? niltrue

nil? (cons 0 nil)false

head nilreached bottom

head (cons 0 nil)0

nil? (tail (cons 0 nil))true

head (tail (cons 0 (cons 1 nil)))1

nilλx.λy.y (α-equiv)

nil? (tail nil)truetail nil reduces to nil

Examples for tlambda

(λx:int.x) 00

(λf:(int->int).f 1) (λx:int.x)1

(λx:int.λy:bool.x) 0 #t0

(λx:bool.λy:int.y) #t 00

(λx:int.λy:int.x) 0 10

(λx:int.λy:int.y) 0 11

(λx:bool.x) 0type error

0!type error ※ can not force a non-thunk in the typed setting

{λx:int.x} 0type error ※ contrary to the untyped calculs, thunks in function position are not forced

{0}!0

and #t #ffalse

or #t #ftrue

1+23

2-11

2*36

zero? 0true

zero? 1false

eq? 1 7false

eq? 7 7true

leq? 1 7true

leq? 7 7true

leq? 8 7false

succ 23

pred 21

Examples for flambda

(λx:int.x) 00

(ΛT.λx:T.x) [int] 00

(ΛT.λx:T.x) [bool] 0type error

(λf:∀T.T->T.f [int] 0) (ΛA.λa:A.a)0

(λf:∀T.∀T.T->T.f [bool] [int] 0) (ΛA.ΛA.λa:A.a)0

(λx:int.x) ⊥reached bottom ※ ⊥ is a subtype of any type

⊥ 7reached bottom ※ ⊥ can be typed as any function type as well

if [int] #t 0 10if: ∀T.bool->T->T->T

if [int] #f 0 11

(if [{int}] #t {0} {⊥})!0

(if [{int}] #f {⊥} {1})!1

nil? [int] (nil [int])truenil: ∀T.∀Z.(T->Z->Z)->Z->Z

nil? [bool] (nil [bool])truenil?: ∀T.(∀Z.(T->Z->Z)->Z->Z)->bool

nil? [bool] (nil [int])type error

nil? [int] (cons [int] 0 (nil [int]))falsecons: ∀T.T->(∀Z.(T->Z->Z)->Z->Z)->(∀Z.(T->Z->Z)->Z->Z)

nil? [bool] (cons [bool] #t (nil [bool]))false

(cons [bool] #t (nil [int]))type error

(cons [int] 0 (nil [bool]))type error

head [int] (nil [int])reached bottomhead: ∀T.(∀Z.(T->Z->Z)->Z->Z)->T

head [int] (cons [int] 0 (nil [int]))0

head [bool] (cons [bool] #f (nil [bool]))false

nil? [int] (tail [int] (cons [int] 0 (nil [int])))truetail: ∀T.(∀Z.(T->Z->Z)->Z->Z)->(∀Z.(T->Z->Z)->Z->Z)

head [int] (tail [int] (cons [int] 0 (cons [int] 1 (nil [int]))))1

Examples for tilambda

(λx:int.x+1) 01

(λx.x+1) 01

(λx.x+1) #ttype error

0:int0

⊥:intreached bottom ※ ⊥ can be unified to any type

0:booltype error

(⊥:int->bool) 7reached bottom

0!type error ※ can not force a non-thunk in the typed setting

{λx:int.x} 0type error ※ contrary to the untyped calculs, thunks in function position are not forced

{0}!0

if #t 0 10if: ∀T.bool->T->T->T (poly-type or rank-1 (prenex) polymorphism)

(if #t {0} {⊥})!0

nil? niltrue

nil? (cons 0 nil)false

head nilreached bottom

head (cons 0 nil)0

nil? (tail (cons 0 nil))true

head (tail (cons 0 (cons 1 nil)))1

nilλx.λy.y (α-equiv)

nil? (tail nil)true

cons #t (cons 0 nil)type error

cons 0 (cons #f nil)type error

λf.(λ_.f 0) (f #t)type error

let x = 1 in x+12

let f = λy.y+1 in f 12

let f = λx.x in (λ_.f 0) (f #t)0 ※ let-polymorphism

let f = λx.x in let g = f in (λ_.g 0) (g #t)0

let f = λx.x in (λg.(λ_.g 0) (g #t)) ftype error ※ rank-2 polymorphism not supported

let f = λx.λtl.cons x tl in head (f 0 nil)0

let f = λx.λtl.cons x tl in head (f 0 1)type error

λx.let f = λy.y+x in and x xtype error

About

A place to study some lambda calculi

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published