source: sizechecking/L.hs @ 7

Last change on this file since 7 was 7, checked in by gobi, 13 years ago

new embedding of Lambda Calculus

File size: 5.0 KB
Line 
1{-# Language GADTs, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, FunctionalDependencies, ScopedTypeVariables, TypeFamilies, NoMonomorphismRestriction #-}
2
3import Data.Char(ord, chr)
4import Control.Monad.State
5import Data.Supply
6
7data OpName = PLUS | MINUS | MUL
8data Bottom = Bottom
9  deriving Show
10
11{- Lambda calculus without free variables -}
12class 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
18class 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
26instance 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 -}
35newtype LPrint a = LPrint { unPrint :: Int -> State Int ShowS }
36
37instance 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
54instance 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
75mprint x = putStrLn $ (fst $ runState (unPrint x 0) 0) ""
76
77showVar 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
81getPrec :: OpName -> (Int,Int,Int,Char)
82getPrec PLUS = (4,4,5,'+')
83getPrec MINUS = (4,4,5,'-')
84getPrec MUL = (5,5,6,'*')
85
86getVar :: State Int Int
87getVar = do { x <- get; put (x+1); return x }
88
89x = aabs (\s _ -> s) `app` list (lit 0) (labs $ \_ -> undef)
90y = list 0 $ labs $ \_ -> undef
91z = (labs $ \s -> s+1) `app` (lit 1+2)
92conss = labs $ \x -> aabs $ \ys yf -> list (ys + 1) $ shift yf ys (labs $ \_ -> x)
93concats = aabs $ \xs xf -> (aabs $ \ys yf -> list (xs+ys) $ shift xf xs yf)
94maps = labs $ \x -> aabs $ \ys yf -> list ys ( x `app` yf )
95l0 = list (lit 0) (labs $ \_ -> unsized)
96l1 = list (lit 1) (labs $ \_ -> unsized)
97l2 = list (lit 2) (labs $ \_ -> unsized)
98l00 = list (lit 0) (labs $ \_ -> list (lit 0) (labs $ \_ -> unsized))
99l10 = list (lit 1) (labs $ \_ -> list (lit 0) (labs $ \_ -> unsized))
100l01 = list (lit 0) (labs $ \_ -> list (lit 1) (labs $ \_ -> unsized))
101l11 = list (lit 1) (labs $ \_ -> list (lit 1) (labs $ \_ -> unsized))
102l12 = list (lit 1) (labs $ \_ -> list (lit 2) (labs $ \_ -> unsized))
103
104{- Evaluating -}
105newtype R a = R { unR :: a }
106instance 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
116newtype RList a = RList { unList :: (Int, Int -> a)  }
117instance (Show a) => Show (RList a) where
118  show (RList (s,f)) = show (map f [0..s-1])
119
120instance 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 -}
131data Nil
132data Cons a
133data SLInt a where
134  SLNil  :: SLInt Nil
135  SLCons :: Int -> SLInt a -> SLInt (Cons a)
136
137class MGS a where
138  mgs :: Supply Int -> a -> a
139  mgs = mgs' []
140  mgs' :: [Int] -> Supply Int -> a -> a
141
142
143instance MGS () where
144  mgs' _ _ _ = ()
145instance 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)
Note: See TracBrowser for help on using the repository browser.