-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathEncode.hs
113 lines (94 loc) · 2.95 KB
/
Encode.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
module Encode where
-- Will encode Lambda Calculus functions into a form
-- readable by the purely syntactic system of the Lambda Calculus
-- This must be Haskell based, the Lambda Calculus is a syntactic system
-- and symbols like 'x' or 'y' hold no special meaning and are unable to
-- compared for equality
import Lambda
import LambdaCore
import qualified Data.Map as Map
import Control.Monad.State
import Data.Maybe
type Env = Map.Map String Exp
--type RC = StateT (Env, Exp) IO
type RC = State (Env, Exp)
recode expr = fst$runState (rc expr) (Map.empty, zero)
rc :: Exp -> RC Exp
rc expr = do
x <- enc expr
let xx = cbv (App cbV x)
(env, _) <- get
dex <- deco xx
return dex
encode expr = fst $ runState (enc expr) (Map.empty, zero)
enc :: Exp -> RC Exp
enc (Lam v e) = do
(env, vn) <- get
case Map.lookup v env of
Nothing -> do
let advn = nor (App sucs vn)
put $ (Map.insert v vn env, advn)
e' <- enc e
return $ App (App pr one)
(App (App pr vn) e')
Just x -> do
e' <- enc e
return $ App (App pr one)
(App (App pr x) e')
enc (App e1 e2) = do
e1' <- enc e1
e2' <- enc e2
return $ App (App pr two)
(App (App pr e1') e2')
enc (Var v) = do
(env, vn) <- get
case Map.lookup v env of
Nothing -> do
let advn = nor (App sucs vn)
put $ (Map.insert v vn env, advn)
return $ App (App pr three) vn
Just x -> return $ App (App pr three) x
deco :: Exp -> RC Exp
deco term = do
let rest = nor (App scnd term)
(env, _) <- get
let env' = swap env
case (nor (App frst term)) of
Lam "f" (Lam "x" (App (Var "f") (Var "x"))) -> do
e <- deco (nor (App scnd rest))
let nm = nor (App frst rest)
let nm' = fromJust $ Map.lookup nm env'
return $ Lam nm' e
Lam "f" (Lam "x" (App (Var "f") (App (Var "f") (Var "x")))) -> do
e1 <- deco (nor (App frst rest))
e2 <- deco (nor (App scnd rest))
return $ App e1 e2
Lam "f" (Lam "x" (App (Var "f") (App (Var "f") (App (Var "f") (Var "x"))))) -> do
let name = fromJust $ Map.lookup rest env'
return $ Var name
swap env = Map.fromList $ map (\(a,b) -> (b,a)) $ Map.toList env
decode term = let rest = nor (App scnd term) in
case (nor (App frst term)) of
Lam "f" (Lam "x" (App (Var "f") (Var "x"))) ->
Lam (n2v (nor (App frst rest))) (decode (nor (App scnd rest)))
Lam "f" (Lam "x" (App (Var "f") (App (Var "f") (Var "x")))) ->
App (decode (nor (App frst rest))) (decode (nor (App scnd rest)))
Lam "f" (Lam "x" (App (Var "f") (App (Var "f") (App (Var "f") (Var "x"))))) ->
Var (n2v rest)
{-
decode term = do
let exp = nor (App frst term)
let rst = nor (App scnd term)
case exp of
one -> do
let v = n2v (nor (App frst rst))
e <- decode (nor (App scnd rest))
return $ Lam v e
two -> do
e1 <- (decode (nor (App frst rest)))
e2 <- (decode (nor (App scnd rest)))
return $ App e1 e2
three -> return Var (n2v rst)
-}
n2v (Lam "f" (Lam "x" (Var "x"))) = "a"
n2v (Lam "f" (Lam "x" (App (Var "f") rest))) = n2v (Lam "f" (Lam "x" rest)) ++ "'"