Skip to content

Commit 4a8a753

Browse files
committed
tree and (unknown) lambda
1 parent bdb6a64 commit 4a8a753

File tree

2 files changed

+189
-0
lines changed

2 files changed

+189
-0
lines changed

ITMOPrelude/MyLambda.hs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
module Lambda where
2+
3+
import Prelude hiding (iterate, elem)
4+
5+
type Variable = String
6+
7+
-- Лямбда-терм
8+
data Term = Var Variable
9+
| Abs Variable Term
10+
| App Term Term
11+
deriving (Show)
12+
13+
-- Тип [ a ] == Типу List a
14+
-- значение [] == значению Nil
15+
-- значение [ a ] == значению Cons a Nil
16+
-- конструктор (:) == конструктору Cons
17+
18+
-- Свободные переменные терма
19+
free (Var v) = [v]
20+
free (Abs v t) = filter (/= v) . free $ t -- /= это <<не равно>>
21+
free (App t t') = (free t) ++ (free t')
22+
23+
binded (Var v) = []
24+
binded (Abs v t) = v : binded t
25+
binded (App t t') = binded t ++ binded t'
26+
27+
-- Заменить все свободные вхождения переменной var на what в терме term
28+
subst var what term = case term of
29+
Var v -> if v == var then what else term
30+
Abs v t -> if v == var then term else Abs v (subst var what t)
31+
App t t' -> App (subst var what t) (subst var what t')
32+
33+
-- Содержит ли список элемент?
34+
elem a [] = False
35+
elem a (l:ls) = if a == l then True else elem a ls
36+
37+
-- Любопытная функция
38+
iterate f x = (:) x $ iterate f (f x)
39+
40+
-- Генерирует список имён, производных от v, не входящих в fv
41+
newname fv v = head . filter (\x -> not . elem x $ fv) . iterate ('_':) $ v
42+
43+
-- Обычная бета-редукция, хендлящая переименования переменных
44+
betaReduct :: Variable -> Term -> Term -> Term
45+
betaReduct var what term = subst var what $ renameBindings (free what) term
46+
where renameBindings vars subterm = case subterm of
47+
Var _ -> subterm
48+
App t t' -> App (renameBindings vars t) (renameBindings vars t')
49+
Abs n t -> Abs nn newt
50+
where nameUsed = elem n vars
51+
nn = if nameUsed then newname (vars ++ free t) n else n
52+
newt = if nameUsed then subst n (Var nn) t else t
53+
54+
hasRedexes (Var _) = False
55+
hasRedexes (Abs v t) = hasRedexes t
56+
hasRedexes (App (Abs _ t) t') = True
57+
hasRedexes (App t t') = hasRedexes t || hasRedexes t'
58+
59+
-- Нормализация нормальным порядком терма term
60+
normal' :: Term -> Term
61+
normal' term = if (hasRedexes term) then normal' $ normalReduce term else term
62+
63+
normalReduce term = case term of
64+
Var _ -> term
65+
Abs var subterm -> Abs var $ normalReduce subterm
66+
App (Abs var subterm) term' -> betaReduct var term' subterm
67+
App term term' -> if hasRedexes term
68+
then App (normalReduce term) term'
69+
else App term $ normalReduce term'
70+
71+
-- Нормализация аппликативным порядком терма term
72+
applicative' :: Term -> Term
73+
applicative' term = if (hasRedexes term) then applicative' $ applicativeReduce term else term
74+
75+
applicativeReduce term = case term of
76+
Var _ -> term
77+
Abs var subterm -> Abs var $ applicativeReduce subterm
78+
App term term' -> if hasRedexes term' then App term $ applicativeReduce term' else case term of
79+
Abs v subt -> betaReduct v term' subt
80+
_ -> App (applicativeReduce term) term'
81+
82+
83+
-- Маркер конца ресурсов
84+
data TooLoong = TooLoong deriving Show
85+
86+
-- (*) Нормализация нормальным порядком терма term за неболее чем n шагов.
87+
-- Результат: Или числа итераций недостаточно, чтобы достичь нормальной
88+
-- формы. Или (число нерастраченных итераций, терм в нормальной форме).
89+
--
90+
normal :: Int -> Term -> Either TooLoong (Int, Term)
91+
normal n term
92+
| n < 0 = Left TooLoong
93+
| otherwise = if (hasRedexes term)
94+
then normal (n - 1) $ normalReduce term
95+
else Right (n, term)
96+
97+
-- (*) Аналогичная нормализация аппликативным порядком.
98+
applicative :: Int -> Term -> Either TooLoong (Int, Term)
99+
applicative n term
100+
| n < 0 = Left TooLoong
101+
| otherwise = if (hasRedexes term)
102+
then applicative (n - 1) $ applicativeReduce term
103+
else Right (n, term)
104+
105+
-- (***) Придумайте и реализуйте обобщённую функцию, выражающую некоторое
106+
-- семейство стратегий редуцирования. В том смысле, что номальная, нормальная
107+
-- головная, нормальная слабо-головная и аппликативная стратегии
108+
-- при помощи этой функции будут выражаться некоторым элементарным образом.
109+
-- Аргумент n можно отбросить, а можно оставить.
110+
--
111+
-- strategy = ?
112+
--
113+
-- normal = strategy ?
114+
-- hnf = strategy ?
115+
-- whnf = strategy ?
116+
-- applicative = strategy ?
117+
--
118+
-- Какие ещё стратегии редуцирования вы знаете? Можно ли их выразить
119+
-- при помощи этой стратегии? Если да, то как?
120+
-- Если нет, то можно ли реализовать аналогичную функцию для _всех_
121+
-- возможных стратегий редуцирования, а не только для такого семейства?
122+
-- Если да, то как? Если нет, то почему?
123+
124+
--------------------------------------------------------
125+
126+
-- Область тестирования
127+
128+
loop' = Abs "x" $ App (Var "x") (Var "x")
129+
loop = App loop' loop'
130+
131+
u = Abs "a" $ Abs "b" $ App (Var "a") $ App (Var "b") (Var "_b")
132+
v = Abs "a" $ Abs "b" $ App (App (Var "a") (Var "b")) (Var "_b")
133+
w = Abs "a" $ Abs "b" $ Abs "c" $ Abs "d" $ App (App (Var "a") (Var "b")) (App (Var "c") (Var "d"))
134+
135+
main = test 100
136+
[ ("no", normal)
137+
, ("ap", applicative) ]
138+
[ Var "a"
139+
, u
140+
, v
141+
, loop'
142+
, u `App` Var "a"
143+
, v `App` Var "a"
144+
, u `App` Var "b"
145+
, v `App` Var "b"
146+
, u `App` Var "_b"
147+
, v `App` Var "_b"
148+
, (u `App` Var "_b") `App` Var "_b"
149+
, (v `App` Var "_b") `App` Var "_b"
150+
, w
151+
, w `App` (Abs "a" (Var "a") `App` (Abs "b" $ Var "b"))
152+
, (w `App` Abs "a" (Var "b")) `App` loop
153+
, loop
154+
]
155+
156+
-- Если вы не понимаете как это работает, то пока и не надо
157+
pall n term = mapM_ (\(desc, reduce) -> putStr (desc ++ ": ") >> print (reduce n term))
158+
159+
test :: Show a => Int -> [(String, Int -> Term -> a)] -> [Term] -> IO ()
160+
test n funcs = mapM_ (\term -> print term >> pall n term funcs)

ITMOPrelude/Tree.hs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{-# LANGUAGE NoImplicitPrelude #-}
2+
module ITMOPrelude.Tree where
3+
4+
import Prelude (Show,Read,error, show)
5+
import ITMOPrelude.Primitive
6+
7+
data Tree a =
8+
Node a (Tree a) (Tree a) |
9+
Leaf
10+
deriving (Show, Read)
11+
12+
emptyTree = Leaf
13+
addToRoot x t = Node x t Leaf
14+
15+
addToLeftLeaf x (Node a l r) = Node a (addToLeftLeaf x l) r
16+
addToLeftLeaf x Leaf = Node x Leaf Leaf
17+
18+
addToRightLeaf x (Node a l r) = Node a l (addToRightLeaf x r)
19+
addToRightLeaf x Leaf = Node x Leaf Leaf
20+
21+
-- rotations? which rotations
22+
23+
tmap :: (a -> b) -> Tree a -> Tree b
24+
tmap f Leaf = Leaf
25+
tmap f (Node x l r) = Node (f x) (tmap f l) (tmap f r)
26+
27+
tfold :: (a -> b -> b) -> b -> Tree a -> b
28+
tfold f z Leaf = z
29+
tfold f z (Node x l r) = f x (tfold f (tfold f z r) l)

0 commit comments

Comments
 (0)