source: sizechecking/trunk/SizedExp.hs

Last change on this file was 18, checked in by gobi, 11 years ago

creating a branch

File size: 5.6 KB
Line 
1{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances,
2             IncoherentInstances, RankNTypes, ScopedTypeVariables,
3             FlexibleContexts,UndecidableInstances #-}
4--
5-- Copyright (C) 2012 Attila Gobi - http://kp.elte.hu/sizechecking
6--
7
8module SizedExp  where
9
10import Lambda as L
11import Constraints
12import Data.Supply
13import Control.Arrow
14import Control.Monad
15
16class TS b => (Unify se a b)  where
17    unify :: (forall a b c. (TS c, Unify se a b) => c -> (Size se c -> a) -> (Size se (c -> b), d)) ->
18        (b -> Size se b -> (Size se b, d)) ->
19        a -> (Size se b, d)
20
21instance (SizedExp se, Unify se a b, se~se1, c1~c2, TS c2) => Unify se (Size se1 c1->a) (c2->b) where
22    unify f g = f undefined
23
24instance (SizedExp se, se~se1, c1~c2, TS c2) => Unify se (Size se1 c1) c2 where
25    unify f g = g undefined
26
27class SizedExp (se :: * -> *) where
28    data Size se :: * -> *
29    true  :: Size se x
30    known  :: L -> Size se x
31    match :: Size se [l] -> Size se r -> (Size se l -> Size se [l] -> Size se r) ->  Size se r
32    bind  :: (Unify se a b) => L.L -> a -> Size se b
33    app   :: Size se (a->b) -> Size se a -> Size se b
34    iff   :: Bool -> Size se a -> Size se a -> Size se a
35    num   :: Integer -> Size se Int
36
37instance Show (Size se a) where
38    show (==) = error "no show on Size!"
39instance Eq (Size se a) where
40    (==) = undefined
41instance (SizedExp se) => Num (Size se Int) where
42    fromInteger = num
43    x + y = num 0
44    x * y = num 0
45    abs = undefined
46    signum = undefined
47instance (SizedExp se) => Ord(Size se Int) where
48
49{-
50 - Implementation of constraints
51 -}
52sizeof :: Size Q a -> IO [SExp]
53sizeof (QSynt s)       = s
54sizeof (QProvable l _) = return [([], l)]
55
56fresh :: TypeKind -> Supply Int -> L
57fresh sig var = fresh' sig [] var
58    where
59    fresh' U _ _ = Unsized
60    fresh' V l var = appall (supplyValue var) l
61    fresh' (F _ b) l var = Abs i $ fresh' b (Var i:l) v2
62        where
63        (v1,v2) = split2 var
64        i = supplyValue v1
65    fresh' (L a) l var = List (appall i l) (Abs j $ fresh' a (Var j:l) v3)
66        where
67        (v1,v2,v3) = split3 var
68        i = supplyValue v1
69        j = supplyValue v2
70
71
72freshvars2 :: (TS b, Unify Q (Size Q a) a) => Supply Int -> b -> Size Q a -> (Size Q a, L -> L)
73freshvars2 supply q exp = (exp , id)
74
75freshvars :: (TS c, Unify Q a b) => Supply Int -> c -> (Size Q c -> a) -> (Size Q (c -> b), L -> L)
76freshvars supply q = freshvars' (unify (freshvars s1) (freshvars2 s2))
77    where
78    (s1, s2, s3) = split3 supply
79    freshvars' :: (Unify Q a b) => (a -> (Size Q b, L -> L)) -> (Size Q c -> a) -> (Size Q (c -> b), L -> L)
80    freshvars' u exp = (QSynt $ sizeof x, \l -> f $ App l fv)
81        where
82        (x, f) = u $ exp $ QSynt $ do
83            return [([], fv)]
84        fv = fresh (tk q) s3
85
86addConstraint :: Constraint -> [SExp] -> [SExp]
87addConstraint nc = map (first ((:) nc))
88
89concatMapM :: (a -> IO [b]) -> [a] -> IO [b]
90concatMapM f l = liftM concat $ mapM f l
91
92type SExp = ([Constraint], L)
93newtype Q a = Q { unQ :: () }
94instance SizedExp Q where
95    data Size Q a = QSynt (IO [SExp]) | QProvable L (Supply Int -> IO [Condition])
96    known l = QSynt $return [([], l)]
97    true = QSynt $ return []
98    match l nil cons = let
99            match1 (cond, ltype) = do
100                    x <- sizeof l
101                    let lt = rall$  App (AAbs 18 5 $ Var 18) ltype
102                    nils <- sizeof nil
103                    let nilc = foldr addConstraint nils $ Zero lt:cond
104                    let tx = rall $ App (AAbs 18 5 $ App (Var 5) (Op (Var 18) '-' (Num 1))) ltype
105                    let txs = rall $App (AAbs 18 5 $ List (Op (Var 18) '-' (Num 1)) (Var 5)) ltype
106                    conss <- sizeof $ cons (QSynt$return [([], tx)]) (QSynt$return [([], txs)])
107                    let consc = foldr addConstraint conss $ lt `GEC` Num 1:cond
108                    return $ nilc ++ consc
109        in QSynt $ sizeof l >>= concatMapM match1
110
111    iff _ l1 l2 = QSynt $ do
112        ll1 <- sizeof l1
113        ll2 <- sizeof l2
114        return $ ll1 ++ ll2
115
116    app l1 l2 = QSynt $ do
117            ll1 <- sizeof l1
118            ll2 <- sizeof l2
119            return  [ (c1 ++ c2,  App e1 e2) | (c1,e1) <- ll1, (c2,e2) <- ll2]
120
121    bind l exp = z $ \supply -> let (s1,s2) = split2 supply in unify (freshvars s1) (freshvars2 s2) exp
122        where
123        z :: (Supply Int -> (Size Q c, L -> L)) -> Size Q c
124        z x = QProvable l $ \supply -> let
125                (sexp, f) = x supply
126                ll = rall $ f l
127                rr (Zero a) = Zero $ rall a
128                rr (GEC a b) = rall a `GEC` rall b
129                rr (LTC a b) = rall a `LTC` rall b
130            in do
131                l3 <- sizeof sexp
132                return $ map (\(c,l2) -> Condition (map rr c) ll (rall l2)) l3
133
134    num n = QSynt $return [([], Unsized)]
135
136instance Num (Size Q Int) where
137    (+) = undefined
138    (*) = undefined
139    abs = undefined
140    signum = undefined
141    fromInteger = num
142
143conditions :: Size Q b -> IO ()
144conditions (QProvable l x) = do
145    (s1,s2,s3) <- liftM split3 $ newSupply 30 (+1)
146    c <- x s1
147    print c
148
149prove :: Size Q b -> IO Bool
150prove (QProvable l x) = do
151    (s1,s2,s3) <- liftM split3 $ newSupply 30 (+1)
152    c <- x s1
153    putStrLn ""
154    putStrLn "------------"
155    putStrLn "Conditions: "
156    print c
157    putStrLn ""
158    putStrLn "------------"
159    putStrLn "Equations: "
160    x <- checkCond s2 c
161    print x
162    putStrLn ""
163    putStrLn "------------"
164    putStrLn "Solving: "
165    y <- solve x s3
166    putStrLn ""
167    if null y then do
168        putStrLn "QED"
169        return True
170      else do
171        putStrLn "------------"
172        putStrLn "Cannot prove: "
173        print y
174        return False
Note: See TracBrowser for help on using the repository browser.