-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adding readme and basic combinators for examples
- Loading branch information
Showing
3 changed files
with
162 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
module Combinators where | ||
|
||
import LambdaCalculus | ||
|
||
|
||
-- компактно записанные переменные | ||
[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z] = | ||
map (Var . (:[])) "abcdefghijklmnopqrstuvwxyz" | ||
-- аппликация двух аргументов | ||
app2 f x y = f :@ x :@ y | ||
-- аппликация трёх аргументов | ||
app3 f x y z = f :@ x :@ y :@ z | ||
|
||
-- комбинаторы | ||
cI = Lam "x" x | ||
cK = Lam "x" $ Lam "y" x | ||
cK_ast = Lam "x" $ Lam "y" y | ||
cB = Lam "f" $ Lam "g" $ Lam "x" $ f :@ (g :@ x) | ||
cS = Lam "f" $ Lam "g" $ Lam "x" $ f :@ x :@ (g :@ x) | ||
|
||
-- Булевы значения | ||
fls = Lam "t" $ Lam "f" f | ||
tru = Lam "t" $ Lam "f" t | ||
|
||
iif = Lam "b" $ Lam "x" $ Lam "y" $ b :@ x :@ y | ||
|
||
not' = Lam "b" $ Lam "t" $ Lam "f" $ app2 b f t | ||
and' = Lam "x" $ Lam "y" $ app2 x y fls | ||
or' = Lam "x" $ Lam "y" $ app2 x tru y | ||
|
||
-- пары | ||
pair = Lam "x" $ Lam "y" $ Lam "f" $ app2 f x y | ||
|
||
fst' = Lam "p" $ p :@ tru | ||
snd' = Lam "p" $ p :@ fls | ||
|
||
-- числа Чёрча | ||
zero = Lam "s" $ Lam "z" z | ||
one = Lam "s" $ Lam "z" $ s :@ z | ||
two = Lam "s" $ Lam "z" $ s :@ (s :@ z) | ||
three = Lam "s" $ Lam "z" $ s :@ (s :@ (s :@ z)) | ||
four = Lam "s" $ Lam "z" $ s :@ (s :@ (s :@ (s :@ z))) | ||
five = Lam "s" $ Lam "z" $ s :@ (s :@ (s :@ (s :@ (s :@ z)))) | ||
six = Lam "s" $ Lam "z" $ s :@ (s :@ (s :@ (s :@ (s :@ (s :@ z))))) | ||
seven = Lam "s" $ Lam "z" $ s :@ (s :@ (s :@ (s :@ (s :@ (s :@ (s :@ z)))))) | ||
eight = Lam "s" $ Lam "z" $ s :@ (s :@ (s :@ (s :@ (s :@ (s :@ (s :@ (s :@ z))))))) | ||
nine = Lam "s" $ Lam "z" $ s :@ (s :@ (s :@ (s :@ (s :@ (s :@ (s :@ (s :@ (s :@ z)))))))) | ||
ten = Lam "s" $ Lam "z" $ s :@ (s :@ (s :@ (s :@ (s :@ (s :@ (s :@ (s :@ (s :@ (s :@ z))))))))) | ||
|
||
iszro = Lam "n" $ n :@ (Lam "x" fls) :@ tru | ||
|
||
suc = Lam "n" $ Lam "s" $ Lam "z" $ s :@ (n :@ s :@ z) | ||
|
||
plus = Lam "m" $ Lam "n" $ Lam "s" $ Lam "z" $ app2 m s (app2 n s z) | ||
|
||
mult = Lam "m" $ Lam "n" $ Lam "s" $ m :@ (n :@ s) | ||
|
||
pow = Lam "m" $ Lam "n" $ n :@ m | ||
|
||
omega = Lam "x" $ x :@ x | ||
|
||
zp = pair :@ zero :@ zero | ||
sp = Lam "p" $ pair :@ (snd' :@ p) :@ (suc :@ (snd' :@ p)) | ||
pred' = Lam "m" $ fst' :@ (m :@ sp :@ zp) | ||
|
||
-- факториал | ||
zf = pair :@ one :@ zero | ||
sf = Lam "p" $ pair :@ (mult :@ (fst' :@ p) :@ (suc :@ (snd' :@ p))) :@ (suc :@ (snd' :@ p)) | ||
fac = Lam "m" $ fst' :@ (m :@ sf :@ zf) | ||
|
||
-- общая схема примитивной рекурсии | ||
xz = Lam "x" $ pair :@ x :@ zero | ||
fs = Lam "f" $ Lam "p" $ pair :@ (f :@ (fst' :@ p) :@ (snd' :@ p)) :@ (suc :@ (snd' :@ p)) | ||
rec = Lam "m" $ Lam "f" $ Lam "x" $ fst' :@ (m :@ (fs :@ f) :@ (xz :@ x)) | ||
|
||
pred'' = Lam "n" $ rec :@ n :@ cK_ast :@ zero | ||
|
||
minus = Lam "k" $ Lam "l" $ l :@ pred' :@ k | ||
|
||
lt = Lam "n" $ Lam "m" $ not' :@ (iszro :@ (minus :@ m :@ n)) | ||
ge = Lam "n" $ Lam "m" $ iszro :@ (app2 minus m n) | ||
gt = Lam "n" $ Lam "m" $ not' :@ (iszro :@ (app2 minus n m)) | ||
le = Lam "n" $ Lam "m" $ iszro :@ (app2 minus n m) | ||
eq = Lam "n" $ Lam "m" $ and' :@ (le :@ m :@ n) :@ (ge :@ m :@ n) | ||
|
||
fac'step = Lam "u" $ Lam "v" $ app2 mult u (suc :@ v) | ||
fac' = Lam "n" $ app3 rec n fac'step one | ||
|
||
-- Y-комбинатор | ||
cY = Lam "f" $ (Lam "z" $ f :@ (z :@ z)) :@ (Lam "z" $ f :@ (z :@ z)) | ||
cTheta = aa :@ aa | ||
where aa = Lam "a" $ Lam "b" $ b :@ (a :@ a :@ b) | ||
|
||
fac''step = Lam "f" $ Lam "n" $ iif :@ (iszro :@ n) :@ one :@ (mult :@ n :@ (f :@ (pred' :@ n))) | ||
fac'' = cY :@ fac''step | ||
fac''' = cTheta :@ fac''step | ||
|
||
-- списки | ||
nil = Lam "c" $ Lam "n" n | ||
cons = Lam "e" $ Lam "l" $ Lam "c" $ Lam "n" $ app2 c e (app2 l c n) | ||
|
||
l532 = app2 cons five (app2 cons three (app2 cons two nil)) | ||
l2 = Lam "c" $ Lam "n" $ c :@ two :@ n | ||
|
||
empty = Lam "l" $ app2 l (Lam "h" $ Lam "t" fls) tru | ||
|
||
length' = Lam "l" $ app2 l (Lam "x" $ Lam "y" $ suc :@ y) zero | ||
length'' = Lam "l" $ app2 l (Lam "y" $ suc) zero | ||
|
||
head' = Lam "l" $ app2 l cK cI | ||
|
||
zpl = app2 pair nil nil | ||
spl = Lam "e" $ Lam "p" $ app2 pair (snd' :@ p) (app2 cons e (snd' :@ p)) | ||
tail' = Lam "l" $ fst' :@ (app2 l spl zpl) | ||
|
||
sum' = Lam "l" $ app2 l plus zero | ||
sum'' = Lam "l" $ app2 l (Lam "h" $ Lam "t" $ app2 plus h t) zero |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,11 @@ | ||
module Main where | ||
|
||
|
||
import Combinators | ||
import LambdaCalculus | ||
import Methods | ||
import Parser | ||
|
||
|
||
|
||
main :: IO () | ||
main = do | ||
putStrLn "Lambda calculator" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,44 @@ | ||
# LambdaCalculator | ||
# LambdaCalculator | ||
Для взаимодействия с библиотекой понадобится [ghci](https://downloads.haskell.org/~ghc/9.0.1/docs/html/users_guide/ghci.html). Чтобы запустить парсер откройте терминал и введите | ||
```bash | ||
$ ghci Main.hs | ||
``` | ||
Теперь вам доступны все реализованные [методы](https://github.com/alexbuyan/LambdaCalculator/blob/main/Methods.hs) | ||
|
||
## Пример работы с библиотекой | ||
```haskell | ||
# substituion | ||
GHCi> subst "y" (Var "x") (Lam "x" $ (Var "x") :@ (Var "y")) | ||
\x' -> x' x | ||
|
||
# alpha equivalence | ||
GHCi> (Lam "x" $ Lam "y" $ Var "x") `alphaEq` (Lam "y" $ Lam "x" $ Var "y") | ||
True | ||
|
||
# beta reduction | ||
GHCi> reduceOnce $ Lam "x" $ Lam "y" $ Var "x" | ||
Nothing | ||
GHCi> reduceOnce $ Lam "x" $ Lam "y" $ (Lam "z" $ Var "z") :@ Var "x" | ||
Just \x -> \y -> x | ||
GHCi> let omega = Lam "x" $ Var "x" :@ Var "x" in reduceOnce $ omega :@ omega | ||
Just (\x -> x x) (\x -> x x) | ||
|
||
# reduction to NF | ||
GHCi> nf (fac :@ three) `alphaEq` six | ||
True | ||
|
||
# beta equivalence | ||
GHCi> fac :@ three `betaEq` six | ||
True | ||
``` | ||
|
||
Тип данных `Expr` является представителем `Show` и `Read` и строковое представление всегда является валидным лямбда-термом | ||
```haskell | ||
GHCi> show $ Lam "x" (Var "x" :@ Var "y") | ||
"\\x -> x y" | ||
GHCi> cY = let {x = Var "x"; f = Var "f"; fxx = Lam "x" $ f :@ (x :@ x)} in Lam "f" $ fxx :@ fxx | ||
GHCi> show cY | ||
"\\f -> (\\x -> f (x x)) (\\x -> f (x x))" | ||
GHCi> cY | ||
\f -> (\x -> f (x x)) (\x -> f (x x)) | ||
``` |