1 | {-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances, |
---|
2 | IncoherentInstances, RankNTypes, ScopedTypeVariables, |
---|
3 | FlexibleContexts,UndecidableInstances #-} |
---|
4 | |
---|
5 | module SizedExp where |
---|
6 | -- ( |
---|
7 | -- SizedExp(..), ($), unQ, prove |
---|
8 | -- ) where |
---|
9 | |
---|
10 | import Lambda as L |
---|
11 | import Constraints |
---|
12 | import Data.Supply |
---|
13 | import Control.Arrow |
---|
14 | import Control.Monad |
---|
15 | |
---|
16 | class 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 | |
---|
21 | instance (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 | |
---|
24 | instance (SizedExp se, se~se1, c1~c2, TS c2) => Unify se (Size se1 c1) c2 where |
---|
25 | unify f g = g undefined |
---|
26 | |
---|
27 | class 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 | |
---|
37 | instance Show (Size se a) where |
---|
38 | show (==) = error "no show on Size!" |
---|
39 | instance Eq (Size se a) where |
---|
40 | (==) = undefined |
---|
41 | instance (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 |
---|
47 | instance (SizedExp se) => Ord(Size se Int) where |
---|
48 | |
---|
49 | {- |
---|
50 | - Implementation of constraints |
---|
51 | -} |
---|
52 | sizeof :: Size Q a -> IO [SExp] |
---|
53 | sizeof (QSynt s) = s |
---|
54 | sizeof (QProvable l _) = return [([], l)] |
---|
55 | |
---|
56 | fresh :: TypeKind -> Supply Int -> L |
---|
57 | fresh 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 | |
---|
72 | freshvars2 :: (TS b, Unify Q (Size Q a) a) => Supply Int -> b -> Size Q a -> (Size Q a, L -> L) |
---|
73 | freshvars2 supply q exp = (exp , id) |
---|
74 | |
---|
75 | freshvars :: (TS c, Unify Q a b) => Supply Int -> c -> (Size Q c -> a) -> (Size Q (c -> b), L -> L) |
---|
76 | freshvars 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 | -- putStrLn $ "[Bind] var="++ show fv ++" of type "++ show (tk q) |
---|
84 | return [([], fv)] |
---|
85 | fv = fresh (tk q) s3 |
---|
86 | |
---|
87 | addConstraint :: Constraint -> [SExp] -> [SExp] |
---|
88 | addConstraint nc = map (first ((:) nc)) |
---|
89 | |
---|
90 | concatMapM :: (a -> IO [b]) -> [a] -> IO [b] |
---|
91 | concatMapM f l = liftM concat $ mapM f l |
---|
92 | |
---|
93 | type SExp = ([Constraint], L) |
---|
94 | newtype Q a = Q { unQ :: () } |
---|
95 | instance SizedExp Q where |
---|
96 | data Size Q a = QSynt (IO [SExp]) | QProvable L (Supply Int -> IO [Condition]) |
---|
97 | known l = QSynt $return [([], l)] |
---|
98 | true = QSynt $ return [] |
---|
99 | match l nil cons = let |
---|
100 | match1 (cond, ltype) = do |
---|
101 | x <- sizeof l |
---|
102 | -- putStrLn $ "ORIGINAL is " ++ show x |
---|
103 | -- putStrLn $ "[MATCH] ==> " ++ show ltype |
---|
104 | let lt = rall$ App (AAbs 18 5 $ Var 18) ltype |
---|
105 | -- putStrLn $ " --- NIL ---" ++ show lt |
---|
106 | nils <- sizeof nil |
---|
107 | -- print nils |
---|
108 | let nilc = foldr addConstraint nils $ Zero lt:cond |
---|
109 | let tx = rall $ App (AAbs 18 5 $ App (Var 5) (Op (Var 18) '-' (Num 1))) ltype |
---|
110 | let txs = rall $App (AAbs 18 5 $ List (Op (Var 18) '-' (Num 1)) (Var 5)) ltype |
---|
111 | -- putStrLn $ " --- CONS --- "++ show tx ++" <-> "++ show txs |
---|
112 | conss <- sizeof $ cons (QSynt$return [([], tx)]) (QSynt$return [([], txs)]) |
---|
113 | -- print conss |
---|
114 | let consc = foldr addConstraint conss $ lt `GEC` Num 1:cond |
---|
115 | -- print "END MATCH" |
---|
116 | -- print $ nilc ++ consc |
---|
117 | return $ nilc ++ consc |
---|
118 | in QSynt $ sizeof l >>= concatMapM match1 |
---|
119 | |
---|
120 | iff _ l1 l2 = QSynt $ do |
---|
121 | ll1 <- sizeof l1 |
---|
122 | ll2 <- sizeof l2 |
---|
123 | return $ ll1 ++ ll2 |
---|
124 | |
---|
125 | app l1 l2 = QSynt $ do |
---|
126 | ll1 <- sizeof l1 |
---|
127 | ll2 <- sizeof l2 |
---|
128 | return [ (c1 ++ c2, App e1 e2) | (c1,e1) <- ll1, (c2,e2) <- ll2] |
---|
129 | |
---|
130 | bind l exp = z $ \supply -> let (s1,s2) = split2 supply in unify (freshvars s1) (freshvars2 s2) exp |
---|
131 | where |
---|
132 | z :: (Supply Int -> (Size Q c, L -> L)) -> Size Q c |
---|
133 | z x = QProvable l $ \supply -> let |
---|
134 | (sexp, f) = x supply |
---|
135 | ll = rall $ f l |
---|
136 | rr (Zero a) = Zero $ rall a |
---|
137 | rr (GEC a b) = rall a `GEC` rall b |
---|
138 | rr (LTC a b) = rall a `LTC` rall b |
---|
139 | in do |
---|
140 | l3 <- sizeof sexp |
---|
141 | -- print l |
---|
142 | -- print ll |
---|
143 | return $ map (\(c,l2) -> Condition (map rr c) ll (rall l2)) l3 |
---|
144 | |
---|
145 | num n = QSynt $return [([], Unsized)] |
---|
146 | |
---|
147 | instance Num (Size Q Int) where |
---|
148 | (+) = undefined |
---|
149 | (*) = undefined |
---|
150 | abs = undefined |
---|
151 | signum = undefined |
---|
152 | fromInteger = num |
---|
153 | |
---|
154 | conditions :: Size Q b -> IO () |
---|
155 | conditions (QProvable l x) = do |
---|
156 | (s1,s2,s3) <- liftM split3 $ newSupply 30 (+1) |
---|
157 | c <- x s1 |
---|
158 | print c |
---|
159 | |
---|
160 | prove :: Size Q b -> IO Bool |
---|
161 | prove (QProvable l x) = do |
---|
162 | (s1,s2,s3) <- liftM split3 $ newSupply 30 (+1) |
---|
163 | c <- x s1 |
---|
164 | putStrLn "" |
---|
165 | putStrLn "------------" |
---|
166 | putStrLn "Conditions: " |
---|
167 | print c |
---|
168 | putStrLn "" |
---|
169 | putStrLn "------------" |
---|
170 | putStrLn "Equations: " |
---|
171 | x <- checkCond s2 c |
---|
172 | print x |
---|
173 | putStrLn "" |
---|
174 | putStrLn "------------" |
---|
175 | putStrLn "Solving: " |
---|
176 | y <- solve x s3 |
---|
177 | putStrLn "" |
---|
178 | if null y then do |
---|
179 | putStrLn "QED" |
---|
180 | return True |
---|
181 | else do |
---|
182 | putStrLn "------------" |
---|
183 | putStrLn "Cannot prove: " |
---|
184 | print y |
---|
185 | return False |
---|