1 | {-# Language GADTs, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, FunctionalDependencies, ScopedTypeVariables, TypeFamilies, NoMonomorphismRestriction #-} |
---|
2 | |
---|
3 | import Data.Char(ord, chr) |
---|
4 | import Control.Monad.State |
---|
5 | import Data.Supply |
---|
6 | |
---|
7 | data OpName = PLUS | MINUS | MUL |
---|
8 | data Bottom = Bottom |
---|
9 | deriving Show |
---|
10 | |
---|
11 | {- Lambda calculus without free variables -} |
---|
12 | class Lambda l where |
---|
13 | labs :: (l a -> l b) -> l (a -> b) |
---|
14 | app :: l (a -> b) -> l a -> l b |
---|
15 | lit :: Int -> l Int |
---|
16 | op :: l Int -> OpName -> l Int -> l Int |
---|
17 | |
---|
18 | class SizeExp l where |
---|
19 | type List l :: * -> * |
---|
20 | list :: l Int -> l (Int -> b) -> l (List l b) |
---|
21 | aabs :: (l Int -> l (Int -> a) -> l b) -> l (List l a -> b) |
---|
22 | shift :: l (Int -> a) -> l Int -> l (Int -> a) -> l (Int -> a) |
---|
23 | undef :: l Bottom |
---|
24 | unsized :: l () |
---|
25 | |
---|
26 | instance Lambda l => Num (l Int) where |
---|
27 | fromInteger = lit . fromIntegral |
---|
28 | lhs + rhs = op lhs PLUS rhs |
---|
29 | lhs - rhs = op lhs MINUS rhs |
---|
30 | lhs * rhs = op lhs MUL rhs |
---|
31 | abs = error "abs is not implemented" |
---|
32 | signum = error "signum is not implemented" |
---|
33 | |
---|
34 | {- Printing -} |
---|
35 | newtype LPrint a = LPrint { unPrint :: Int -> State Int ShowS } |
---|
36 | |
---|
37 | instance Lambda LPrint where |
---|
38 | lit x = LPrint $ \p -> return $ shows x |
---|
39 | op m opc n = LPrint $ \p -> do |
---|
40 | let (prec, lprec, rprec, c) = getPrec opc |
---|
41 | l1 <- (unPrint m lprec) |
---|
42 | l2 <- (unPrint n rprec) |
---|
43 | return $ showParen (p>prec) $ l1 . showChar c . l2 |
---|
44 | app f v = LPrint $ \p -> do |
---|
45 | l1 <- unPrint f 6 |
---|
46 | l2 <- unPrint v 7 |
---|
47 | return $ showParen (p>6) $ l1 . showChar ' ' . l2 |
---|
48 | labs e = LPrint $ \p -> do |
---|
49 | v <- getVar |
---|
50 | let var = LPrint $ \_ -> return $ showVar v |
---|
51 | l <- unPrint (e var) 0 |
---|
52 | return $ showParen (p>0) $ showChar 'λ' . showVar v . showChar '.' . l |
---|
53 | |
---|
54 | instance SizeExp LPrint where |
---|
55 | type List LPrint = [] |
---|
56 | aabs f = LPrint $ \p -> do |
---|
57 | v1 <- getVar |
---|
58 | v2 <- getVar |
---|
59 | let var1 = LPrint $ \_ -> return $ showVar v1 |
---|
60 | var2 = LPrint $ \_ -> return $ showVar v2 |
---|
61 | l <- unPrint (f var1 var2) 0 |
---|
62 | return $ showParen (p>0) $ showChar 'Î' . showVar v1 . showChar ',' . showVar v2 . showChar '.' . l |
---|
63 | list s f = LPrint $ \p -> do |
---|
64 | l1 <- unPrint s 9 |
---|
65 | l2 <- unPrint f 9 |
---|
66 | return $ showParen (p>0) $ showString "List " . l1 . showChar ' ' . l2 |
---|
67 | shift e1 s e2 = LPrint $ \p -> do |
---|
68 | l1 <- unPrint e1 2 |
---|
69 | l2 <- unPrint s 2 |
---|
70 | l3 <- unPrint e2 2 |
---|
71 | return $ showParen (p>0) $ showString "Shift " . l1 . showChar ' ' . l2 . showChar ' ' . l3 |
---|
72 | undef = LPrint $ \_ -> return $ showChar 'âŽ' |
---|
73 | unsized = LPrint $ \_ -> return $ showChar 'U' |
---|
74 | |
---|
75 | mprint x = putStrLn $ (fst $ runState (unPrint x 0) 0) "" |
---|
76 | |
---|
77 | showVar x = if x>28 |
---|
78 | then showVar (x `div` 29) . showChar (chr $ ord 'a' + (x `mod` 29)) |
---|
79 | else showChar $ chr $ ord 'a' + x |
---|
80 | |
---|
81 | getPrec :: OpName -> (Int,Int,Int,Char) |
---|
82 | getPrec PLUS = (4,4,5,'+') |
---|
83 | getPrec MINUS = (4,4,5,'-') |
---|
84 | getPrec MUL = (5,5,6,'*') |
---|
85 | |
---|
86 | getVar :: State Int Int |
---|
87 | getVar = do { x <- get; put (x+1); return x } |
---|
88 | |
---|
89 | x = aabs (\s _ -> s) `app` list (lit 0) (labs $ \_ -> undef) |
---|
90 | y = list 0 $ labs $ \_ -> undef |
---|
91 | z = (labs $ \s -> s+1) `app` (lit 1+2) |
---|
92 | conss = labs $ \x -> aabs $ \ys yf -> list (ys + 1) $ shift yf ys (labs $ \_ -> x) |
---|
93 | concats = aabs $ \xs xf -> (aabs $ \ys yf -> list (xs+ys) $ shift xf xs yf) |
---|
94 | maps = labs $ \x -> aabs $ \ys yf -> list ys ( x `app` yf ) |
---|
95 | l0 = list (lit 0) (labs $ \_ -> unsized) |
---|
96 | l1 = list (lit 1) (labs $ \_ -> unsized) |
---|
97 | l2 = list (lit 2) (labs $ \_ -> unsized) |
---|
98 | l00 = list (lit 0) (labs $ \_ -> list (lit 0) (labs $ \_ -> unsized)) |
---|
99 | l10 = list (lit 1) (labs $ \_ -> list (lit 0) (labs $ \_ -> unsized)) |
---|
100 | l01 = list (lit 0) (labs $ \_ -> list (lit 1) (labs $ \_ -> unsized)) |
---|
101 | l11 = list (lit 1) (labs $ \_ -> list (lit 1) (labs $ \_ -> unsized)) |
---|
102 | l12 = list (lit 1) (labs $ \_ -> list (lit 2) (labs $ \_ -> unsized)) |
---|
103 | |
---|
104 | {- Evaluating -} |
---|
105 | newtype R a = R { unR :: a } |
---|
106 | instance Lambda R where |
---|
107 | labs f = R $ unR . f . R |
---|
108 | app e1 e2 = R $ (unR e1) (unR e2) |
---|
109 | lit i = R i |
---|
110 | op e1 op e2 = let opm = case op of |
---|
111 | PLUS -> (+) |
---|
112 | MINUS -> (-) |
---|
113 | MUL -> (*) |
---|
114 | in R $ opm (unR e1) (unR e2) |
---|
115 | |
---|
116 | newtype RList a = RList { unList :: (Int, Int -> a) } |
---|
117 | instance (Show a) => Show (RList a) where |
---|
118 | show (RList (s,f)) = show (map f [0..s-1]) |
---|
119 | |
---|
120 | instance SizeExp R where |
---|
121 | type List R = RList |
---|
122 | undef = R $ Bottom |
---|
123 | unsized = R $ () |
---|
124 | list s f = R $ RList (unR s, unR f) |
---|
125 | aabs e = R $ \(RList (s,f)) -> unR (e (R s) (R f)) |
---|
126 | shift a s c = R $ \i -> if i<(unR s) then unR a i else unR c i |
---|
127 | |
---|
128 | {- Create a restricted deep embedding to work with the expression -} |
---|
129 | |
---|
130 | {- sized [a] to prove -} |
---|
131 | data Nil |
---|
132 | data Cons a |
---|
133 | data SLInt a where |
---|
134 | SLNil :: SLInt Nil |
---|
135 | SLCons :: Int -> SLInt a -> SLInt (Cons a) |
---|
136 | |
---|
137 | class MGS a where |
---|
138 | mgs :: Supply Int -> a -> a |
---|
139 | mgs = mgs' [] |
---|
140 | mgs' :: [Int] -> Supply Int -> a -> a |
---|
141 | |
---|
142 | |
---|
143 | instance MGS () where |
---|
144 | mgs' _ _ _ = () |
---|
145 | instance MGS a => MGS (RList a) where |
---|
146 | mgs' bound supp _ = RList undefined |
---|
147 | where |
---|
148 | (s1, s2, s3) = split3 supp |
---|
149 | listsize = mgs' bound supp (undefined :: a) |
---|