[17] | 1 | -- |
---|
| 2 | -- Copyright (C) 2012 Attila Gobi - http://kp.elte.hu/sizechecking |
---|
| 3 | -- |
---|
| 4 | |
---|
[5] | 5 | {-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances, |
---|
| 6 | IncoherentInstances, RankNTypes, ScopedTypeVariables, |
---|
[15] | 7 | FlexibleContexts,UndecidableInstances, DeriveDataTypeable, |
---|
| 8 | ImpredicativeTypes #-} |
---|
[5] | 9 | module Constraints where |
---|
| 10 | |
---|
| 11 | import Lambda |
---|
| 12 | import qualified Data.List as List |
---|
| 13 | import qualified Data.Set as Set |
---|
| 14 | import qualified Data.Map as Map |
---|
| 15 | import qualified Data.Ord as Ord |
---|
| 16 | import qualified Data.SBV as SBV |
---|
| 17 | import Data.SBV ( (.==), (.<), (.>=)) |
---|
| 18 | import Control.Monad |
---|
[15] | 19 | import Control.Monad.IO.Class |
---|
[6] | 20 | import Data.IORef() |
---|
[5] | 21 | import Data.Supply as S |
---|
[15] | 22 | import Data.Data |
---|
| 23 | import Data.IORef |
---|
| 24 | import Data.Dynamic |
---|
[5] | 25 | |
---|
| 26 | asType :: a -> a -> a |
---|
[6] | 27 | asType a _ = a |
---|
[5] | 28 | |
---|
| 29 | data D = D { var::Int, cond::[Condition] } |
---|
| 30 | |
---|
| 31 | data TypeKind = V | L TypeKind | F TypeKind TypeKind | U |
---|
| 32 | deriving Show |
---|
| 33 | |
---|
| 34 | |
---|
| 35 | class TS a where |
---|
| 36 | tk :: a -> TypeKind |
---|
| 37 | instance (TS a, TS b) => TS (a -> b) where |
---|
| 38 | tk _ = F (tk (undefined :: a)) (tk (undefined :: b)) |
---|
| 39 | instance TS a => TS [a] where |
---|
| 40 | tk _ = L (tk (undefined :: a)) |
---|
| 41 | instance TS a where |
---|
| 42 | tk _ = V |
---|
| 43 | instance TS Int where |
---|
| 44 | tk _ = U |
---|
| 45 | |
---|
| 46 | appall :: Int -> [L] -> L |
---|
[6] | 47 | appall var = foldl App (Var var) |
---|
[5] | 48 | |
---|
| 49 | data Condition = Condition [Constraint] L L |
---|
| 50 | |
---|
| 51 | instance Show Condition where |
---|
| 52 | showsPrec _ (Condition d a b) = shows d . showString "|- " . shows a . showString " = " . shows b |
---|
| 53 | showList [] = showString "" |
---|
| 54 | showList [x] = shows x |
---|
| 55 | showList (x:xs) = shows x . showString "\n" . shows xs |
---|
| 56 | |
---|
| 57 | data Constraint = Zero L | LTC L L | GEC L L |
---|
| 58 | deriving Eq |
---|
| 59 | |
---|
| 60 | instance Show Constraint where |
---|
| 61 | showList [] = id |
---|
| 62 | showList [s] = shows s . showChar ' ' |
---|
| 63 | showList (x:xs) = shows x . showString ", " . shows xs |
---|
| 64 | showsPrec _ (Zero s) = shows s . showString " = 0" |
---|
| 65 | showsPrec _ (LTC s1 s2) = shows s1 . showString " < " . shows s2 |
---|
| 66 | showsPrec _ (GEC s1 s2) = shows s1 . showString " >= " . shows s2 |
---|
| 67 | |
---|
| 68 | normalize :: L -> L |
---|
| 69 | normalize l = delzero $ foldl (\a b -> Op a '-' b) (foldl (\a b -> Op a '+' b) (f1 $ List.sortBy (Ord.comparing snd) a) c) d |
---|
| 70 | where |
---|
| 71 | (a,b,c,d) = norm l |
---|
| 72 | f1 ((0,l):xs) = f1 xs |
---|
| 73 | f1 ((1,l):xs) = Op (f1 xs) '+' (Var l) |
---|
| 74 | f1 ((-1,l):xs) = Op (f1 xs) '-' (Var l) |
---|
| 75 | f1 [] = Num b |
---|
| 76 | |
---|
| 77 | delzero (Op (Num 0) '+' b) = b |
---|
| 78 | delzero (Op a c b) = Op (delzero a) c b |
---|
| 79 | delzero l = l |
---|
| 80 | |
---|
| 81 | gnormalize :: L -> (L, Int) |
---|
| 82 | gnormalize l = case (c,d) of |
---|
| 83 | ([], []) -> case nonzero of |
---|
| 84 | [] -> (Num 0, b) |
---|
| 85 | _ -> (expr, b) |
---|
[6] | 86 | (_, _) -> error $ "Expression in condition" ++ show c |
---|
[5] | 87 | where |
---|
| 88 | nonzero = List.sortBy (Ord.comparing snd) $ filter ((/=0).fst) a |
---|
| 89 | proc (1, l) = Var l |
---|
| 90 | proc (-1, l) = Op (Num (-1)) '*' (Var l) |
---|
| 91 | t :: L -> (Int, Int) -> L |
---|
| 92 | t l (1, var) = Op l '+' (Var var) |
---|
| 93 | t l (-1, var) = Op l '-' (Var var) |
---|
| 94 | expr = foldl t (proc $ head nonzero) (tail nonzero) |
---|
| 95 | |
---|
| 96 | (a,b,c,d) = norm l |
---|
| 97 | |
---|
| 98 | normalizec :: Constraint -> Constraint |
---|
| 99 | normalizec (Zero l) = Zero $ normalize l |
---|
| 100 | normalizec (LTC a b) = LTC (normalize a) (normalize b) |
---|
| 101 | normalizec (GEC a b) = GEC (normalize a) (normalize b) |
---|
| 102 | --normalizec (LTC a b) = LTC x (Num (-y)) |
---|
| 103 | -- where (x,y) = gnormalize $ Op a '-' b |
---|
| 104 | --normalizec (GEC a b) = GEC x (Num (-y)) |
---|
| 105 | -- where (x,y) = gnormalize $ Op a '-' b |
---|
| 106 | |
---|
| 107 | normalizecs :: [Constraint] -> [Constraint] |
---|
| 108 | normalizecs = normalizecs' . Prelude.map normalizec |
---|
| 109 | where |
---|
| 110 | normalizecs' [] = [] |
---|
| 111 | normalizecs' (x:xs) = x:normalizecs' (filter (/=x) xs) |
---|
| 112 | |
---|
| 113 | {- |
---|
| 114 | - Takes an extended lambda expression and |
---|
| 115 | -} |
---|
| 116 | norm :: L -> ([(Int, Int)], Int, [L], [L]) |
---|
| 117 | norm (App a b) = ([], 0, [App (normalize a) (normalize b)], []) |
---|
| 118 | norm (List a b) = ([], 0, [List (normalize a) (normalize b)], []) |
---|
| 119 | norm (AAbs a b e) = ([], 0, [AAbs a b (normalize e)], []) |
---|
| 120 | norm (Shift a b c) = ([], 0, [Shift (normalize a) (normalize b) (normalize c)], []) |
---|
| 121 | norm (Unsized) = ([], 0, [Unsized], []) |
---|
| 122 | norm (Bottom) = ([], 0, [Bottom], []) |
---|
| 123 | norm (Abs i l) = ([], 0, [Abs i $ normalize l], []) |
---|
| 124 | norm (Var i) = ([(1, i)], 0, [], []) |
---|
| 125 | norm (Num i) = ([], i, [], []) |
---|
| 126 | norm q@(Op a c b) = case c of |
---|
| 127 | '+' -> (a1++b1, a2+b2, a3++b3, a4++b4) |
---|
| 128 | '-' -> (sub a1 b1, a2-b2, a3++b4, a4++b3) |
---|
| 129 | '*' -> case a of |
---|
| 130 | (Num cnt) -> (map (mul cnt) b1, cnt*b2, map (Op (Num cnt) '*') b3, map (Op (Num cnt) '*') b4) |
---|
| 131 | _ -> ([], 0, [q], []) |
---|
| 132 | _ -> ([], 0, [q], []) |
---|
| 133 | where |
---|
| 134 | mul c (x,var) = (c*x, var) |
---|
| 135 | (a1, a2, a3, a4) = norm a |
---|
| 136 | (b1, b2, b3, b4) = norm b |
---|
| 137 | sub l1 ((c,i):xs) = sub (sub' l1 c i) xs |
---|
| 138 | where |
---|
| 139 | sub' [] c i = [(-c, i)] |
---|
| 140 | sub' ((cc,ii):xs) c i = if i==ii then (cc-c,i):xs else (cc,ii):sub' xs c i |
---|
| 141 | sub l1 [] = l1 |
---|
| 142 | |
---|
| 143 | tnorm = Op (Num 1) '+' (Op (Var 0) '-' (Num 1)) |
---|
| 144 | |
---|
| 145 | checkCond :: Supply Int -> [Condition] -> IO [Condition] |
---|
| 146 | checkCond v l = do |
---|
| 147 | ll <- mapM (checkCond1 v) l |
---|
| 148 | return $ concat ll |
---|
| 149 | |
---|
| 150 | where |
---|
| 151 | -- checkCond1 v p@(Condition d a b) | a==b = do |
---|
| 152 | -- return [] |
---|
| 153 | checkCond1 v z@(Condition d (List a b) (List p q)) = do |
---|
| 154 | -- i <- freshtypevar v |
---|
| 155 | let (v1,v2,v3) = split3 v |
---|
| 156 | let i = supplyValue v1 |
---|
| 157 | let b' = rall $ App b (Var i) |
---|
| 158 | let q' = rall $ App q (Var i) |
---|
| 159 | l1 <- checkCond1 v2 (Condition ((Var i `GEC` Num 0):d) a p) |
---|
| 160 | l2 <- checkCond1 v3 (Condition ((Var i `GEC` Num 0):(Var i `LTC` a):(Var i `LTC` p):d) b' q') |
---|
| 161 | return $ l1++l2 |
---|
| 162 | checkCond1 v z@(Condition d (App (Shift e f g) h) x) = do |
---|
| 163 | let (v1,v2,v3) = split3 v |
---|
| 164 | let e' = rall $ App e h |
---|
| 165 | let g' = rall $ App g $ Op h '-' f |
---|
| 166 | l1 <- checkCond1 v1 (Condition ((h `LTC` f):d) e' x) |
---|
| 167 | l2 <- checkCond1 v2 (Condition ((h `GEC` f):d) g' x) |
---|
[14] | 168 | -- putStrLn $ " -> " ++ show l1 |
---|
| 169 | -- putStrLn $ " -> " ++ show l2 |
---|
[5] | 170 | return $ l1 ++ l2 |
---|
[6] | 171 | checkCond1 v z@(Condition d (App (Var a) x) (App (Var b) y)) | a==b = |
---|
[5] | 172 | checkCond1 v (Condition d x y) |
---|
[6] | 173 | checkCond1 v p@(Condition d x z@(App (Shift e f g) h)) = |
---|
[5] | 174 | checkCond1 v (Condition d z x) |
---|
[6] | 175 | checkCond1 v z@(Condition d a b) = return [Condition dd (normalize a) (normalize b)] |
---|
[5] | 176 | where |
---|
| 177 | dd = normalizecs d |
---|
| 178 | |
---|
| 179 | subst ndl hst (App a b) = App (subst ndl hst a) (subst ndl hst b) |
---|
| 180 | subst ndl hst (List a b) = List (subst ndl hst a) (subst ndl hst b) |
---|
| 181 | subst ndl hst (AAbs a b e) = AAbs a b (subst ndl hst e) |
---|
| 182 | subst ndl hst (Shift a b c) = Shift (subst ndl hst a) (subst ndl hst b) (subst ndl hst c) |
---|
| 183 | subst ndl hst (Unsized) = Unsized |
---|
| 184 | subst ndl hst (Bottom) = Bottom |
---|
| 185 | subst ndl hst q@(Abs i l) = if ndl==i then q else Abs i $ subst ndl hst l |
---|
| 186 | subst ndl hst q@(Var i) = if ndl==i then hst else q |
---|
| 187 | subst ndl hst (Num i) = Num i |
---|
| 188 | subst ndl hst (Op a c b) = Op (subst ndl hst a) c (subst ndl hst b) |
---|
| 189 | |
---|
| 190 | substc ndl hst (Zero l) = Zero $ subst ndl hst l |
---|
| 191 | substc ndl hst (LTC a b) = LTC (subst ndl hst a) (subst ndl hst b) |
---|
| 192 | substc ndl hst (GEC a b) = GEC (subst ndl hst a) (subst ndl hst b) |
---|
| 193 | |
---|
| 194 | reorder cs = if any check cs |
---|
| 195 | then Just (map r cs) |
---|
| 196 | else Nothing |
---|
| 197 | where |
---|
| 198 | check (Zero _) = False |
---|
| 199 | check (LTC a (Num 0)) = False |
---|
| 200 | check (GEC a (Num 0)) = False |
---|
| 201 | check _ = True |
---|
| 202 | r (LTC a b) = LTC (normalize (Op a '-' b)) (Num 0) |
---|
| 203 | r (GEC a b) = GEC (normalize (Op a '-' b)) (Num 0) |
---|
| 204 | r l = l |
---|
| 205 | |
---|
| 206 | solve :: [Condition] -> Supply Int -> IO [Condition] |
---|
| 207 | solve l supply = do |
---|
| 208 | ll <- forM (zip l $ split supply) (\(c,s) -> do |
---|
[6] | 209 | putStrLn $ "\nSOLVING " ++ show c |
---|
[5] | 210 | solve1 s c |
---|
| 211 | ) |
---|
| 212 | return $ concat ll |
---|
| 213 | where |
---|
| 214 | |
---|
| 215 | searchzero (Zero (Var a):xs) = Just (a,xs) |
---|
| 216 | searchzero (x:xs) = do |
---|
| 217 | (a,l) <- searchzero xs |
---|
| 218 | return (a,x:l) |
---|
| 219 | searchzero [] = Nothing |
---|
| 220 | |
---|
| 221 | |
---|
| 222 | searcheq (q@(GEC (Var var) exp):xs) prev = case findeq (List.reverse prev ++ xs) [] of |
---|
| 223 | Nothing -> searcheq xs (q:prev) |
---|
| 224 | l -> l |
---|
| 225 | where |
---|
| 226 | expinc = normalize $ Op exp '+' $ Num 1 |
---|
| 227 | findeq [] _ = Nothing |
---|
| 228 | findeq (LTC (Var var2) exp2:xs) prev2 | var==var2 && exp2==expinc = Just (var, exp, List.reverse prev2 ++ xs) |
---|
| 229 | findeq (x:xs) prev2 = findeq xs (x:prev2) |
---|
| 230 | |
---|
| 231 | searcheq (x:xs) prev = searcheq xs (x:prev) |
---|
| 232 | searcheq [] _ = Nothing |
---|
| 233 | |
---|
| 234 | checkConds [] = False |
---|
[6] | 235 | checkConds (LTC a b : xs) | GEC a b `elem` xs = True |
---|
| 236 | checkConds (GEC a b : xs) | LTC a b `elem` xs = True |
---|
| 237 | checkConds (LTC a (Num b) : xs) | b<=0 && elem (Zero a) xs = True |
---|
| 238 | checkConds (GEC a (Num b) : xs) | b>0 && elem (Zero a) xs = True |
---|
[5] | 239 | checkConds (_:xs) = checkConds xs |
---|
| 240 | |
---|
| 241 | checkConds2 (LTC (Num a) (Num b):xs) | a>=b = Nothing |
---|
| 242 | checkConds2 (LTC (Num a) (Num b):xs) | a<b = checkConds2 xs |
---|
| 243 | checkConds2 (GEC (Num a) (Num b):xs) | a<b = Nothing |
---|
| 244 | checkConds2 (GEC (Num a) (Num b):xs) | a>=b = checkConds2 xs |
---|
| 245 | checkConds2 (x:xs) = do { y <- checkConds2 xs; return (x:y) } |
---|
| 246 | checkConds2 [] = Just [] |
---|
| 247 | |
---|
| 248 | -- applyList a b d supp = do |
---|
| 249 | -- let (s1,s2,s3) = split3 supp |
---|
| 250 | -- let t = fresh (L V) s1 |
---|
| 251 | -- let dd = (Condition d (rall $ App a t) (rall $ App b t)) |
---|
| 252 | -- putStrLn $ "Applying a fresh variable: "++(show t) ++"\n"++(show dd) |
---|
| 253 | -- x <- checkCond s2 [dd] >>= mapM (solve1 s3) |
---|
| 254 | -- return $ concat x |
---|
| 255 | |
---|
| 256 | solve1 supp c@(Condition d a b) = case checkConds2 d of |
---|
| 257 | Nothing -> do |
---|
| 258 | putStrLn "Contradiction in preconditions" |
---|
| 259 | return [] |
---|
| 260 | Just d' -> solve1' supp $ Condition d a b |
---|
| 261 | |
---|
| 262 | solve1' supp c@(Condition d a b) |
---|
[15] | 263 | -- | checkConds d = do |
---|
| 264 | -- putStrLn "Contradiction in preconditions" |
---|
| 265 | -- return [] |
---|
[5] | 266 | | a==b = do |
---|
[6] | 267 | putStrLn "Equals" |
---|
[5] | 268 | return [] |
---|
[15] | 269 | -- | Just (var, nl) <- searchzero d = do |
---|
| 270 | -- let x = Condition (Prelude.map (normalizec.substc var (Num 0)) nl) |
---|
| 271 | -- (normalize$subst var (Num 0) a) |
---|
| 272 | -- (normalize$subst var (Num 0) b) |
---|
| 273 | -- |
---|
| 274 | -- putStrLn $ show (Var var) ++ " is zero:\n" ++ show x |
---|
| 275 | -- solve1 supp x |
---|
| 276 | -- | Just (var, exp, nl) <- searcheq d [] = do |
---|
| 277 | -- putStrLn $ "Found equation " ++ show (Var var) ++ " = " ++ show exp |
---|
| 278 | -- let x = Condition (Prelude.map (normalizec.substc var exp) nl ) |
---|
| 279 | -- (normalize$subst var exp a) |
---|
| 280 | -- (normalize$subst var exp b) |
---|
| 281 | -- putStrLn $ "New equations:\n" ++ show x |
---|
| 282 | -- solve1 supp x |
---|
[5] | 283 | | App p q <- a, App r s <- b = do |
---|
[6] | 284 | putStrLn "Branching!" |
---|
[5] | 285 | nc <- checkCond supp [Condition d p r, Condition d q s] |
---|
| 286 | solve nc supp |
---|
| 287 | |
---|
| 288 | -- | Abs _ _ <- a, Abs _ _ <- b = do |
---|
| 289 | -- let (s1, s2) = split2 supp |
---|
| 290 | -- let t = fresh (tk a) s1 |
---|
| 291 | -- let dd= (Condition d (rall $ App a t) (rall $ App b t)) |
---|
| 292 | -- putStrLn $ "Applying a fresh variable: "++(show t) ++"\n"++(show dd) |
---|
| 293 | -- solve1 s2 dd |
---|
| 294 | -- | AAbs _ _ _ <- a, Abs _ _ <- b = applyList a b d supp |
---|
| 295 | -- | Abs _ _ <- a, AAbs _ _ _ <- b = applyList a b d supp |
---|
| 296 | -- | AAbs _ _ _ <- a, AAbs _ _ _ <- b = applyList a b d supp |
---|
[15] | 297 | |
---|
| 298 | -- | Just dd <- reorder d = do |
---|
| 299 | -- putStrLn $ "Reorder " ++ show dd |
---|
| 300 | -- solve1 supp $ Condition dd a b |
---|
[5] | 301 | | otherwise = do |
---|
| 302 | putStrLn "Tying to call solver" |
---|
| 303 | let x = compiletosolver a b d |
---|
| 304 | y <- SBV.prove x |
---|
| 305 | print y |
---|
| 306 | case y of |
---|
| 307 | (SBV.ThmResult (SBV.Unsatisfiable _)) -> return [] |
---|
| 308 | otherwise -> return [c] |
---|
| 309 | |
---|
[15] | 310 | data LU = LU deriving (Eq, Ord, Data, Typeable) |
---|
| 311 | instance SBV.SymWord LU |
---|
| 312 | instance SBV.HasKind LU |
---|
| 313 | |
---|
[5] | 314 | fvc (Zero a) = fv a |
---|
| 315 | fvc (LTC a b) = fv a `Set.union` fv b |
---|
| 316 | fvc (GEC a b) = fv a `Set.union` fv b |
---|
| 317 | |
---|
| 318 | compiletosolver :: L -> L -> [Constraint] -> SBV.Symbolic SBV.SBool |
---|
| 319 | compiletosolver a b d = do |
---|
[15] | 320 | varmap <- liftIO createVarPool |
---|
| 321 | expmap <- liftIO createExpPool |
---|
| 322 | supply <- liftIO $ newNumSupply |
---|
| 323 | let (s1,s2,s3,s4) = split4 supply |
---|
| 324 | cs <- mapM (\(s,x) -> compilec varmap expmap s x) $ zip (split s1) d |
---|
| 325 | mapM_ (SBV.constrain) cs |
---|
| 326 | lhs <- compilel varmap expmap s3 a |
---|
| 327 | rhs <- compilel varmap expmap s4 b |
---|
| 328 | return $ lhs .== rhs |
---|
[5] | 329 | |
---|
[15] | 330 | data VarT = VarI | VarF VarT VarT |
---|
| 331 | type VarPool = IORef (Map.Map Int Dynamic) |
---|
| 332 | type ExpPool = IORef (Map.Map L SBV.SInteger) |
---|
[5] | 333 | |
---|
[15] | 334 | createVarPool :: IO (VarPool) |
---|
| 335 | createVarPool = newIORef $ Map.empty |
---|
| 336 | createExpPool :: IO (ExpPool) |
---|
| 337 | createExpPool = newIORef $ Map.empty |
---|
| 338 | |
---|
| 339 | |
---|
| 340 | sbvTc :: TyCon |
---|
| 341 | sbvTc = mkTyCon3 "Data" "SBV" "SBV" |
---|
| 342 | |
---|
| 343 | instance (Typeable t) => Typeable (SBV.SBV t) where |
---|
| 344 | typeOf x = mkTyConApp sbvTc [typeOf (get x)] |
---|
| 345 | where |
---|
| 346 | get :: SBV.SBV a -> a |
---|
| 347 | get = undefined |
---|
| 348 | |
---|
| 349 | |
---|
| 350 | getVarSymbol :: VarPool -> (SBV.Symbolic Dynamic) -> Int -> SBV.Symbolic Dynamic |
---|
| 351 | getVarSymbol pool factory a = do |
---|
| 352 | v <- liftIO $ readIORef pool |
---|
| 353 | case Map.lookup a v of |
---|
| 354 | Just q -> return $ q |
---|
| 355 | Nothing -> do |
---|
| 356 | dx <- factory |
---|
| 357 | let newmap = Map.insert a dx v |
---|
| 358 | liftIO $ writeIORef pool newmap |
---|
| 359 | return dx |
---|
| 360 | |
---|
| 361 | getExpSymbol :: ExpPool -> (SBV.Symbolic SBV.SInteger) -> L -> SBV.Symbolic SBV.SInteger |
---|
| 362 | getExpSymbol pool factory a = do |
---|
| 363 | v <- liftIO $ readIORef pool |
---|
| 364 | case Map.lookup a v of |
---|
| 365 | Just q -> return $ q |
---|
| 366 | Nothing -> do |
---|
| 367 | dx <- factory |
---|
| 368 | let newmap = Map.insert a dx v |
---|
| 369 | liftIO $ writeIORef pool newmap |
---|
| 370 | return dx |
---|
| 371 | |
---|
| 372 | |
---|
| 373 | compilec :: VarPool -> ExpPool -> Supply Int -> Constraint -> SBV.Symbolic (SBV.SBool) |
---|
| 374 | compilec v e s (Zero a) = do |
---|
| 375 | lhs <- compilel v e s a |
---|
| 376 | return $ lhs .== (0::SBV.SInteger) |
---|
| 377 | |
---|
| 378 | compilec v e s (LTC a b) = do |
---|
| 379 | let (s1,s2) = split2 s |
---|
| 380 | lhs <- compilel v e s1 a |
---|
| 381 | rhs <- compilel v e s2 b |
---|
| 382 | return $ lhs .< rhs |
---|
| 383 | |
---|
| 384 | compilec v e s (GEC a b) = do |
---|
| 385 | let (s1,s2) = split2 s |
---|
| 386 | lhs <- compilel v e s1 a |
---|
| 387 | rhs <- compilel v e s2 b |
---|
| 388 | return $ lhs .>= rhs |
---|
| 389 | |
---|
| 390 | class Typeable a => VarFactory a where |
---|
| 391 | createDyn :: String -> a -> SBV.Symbolic Dynamic |
---|
| 392 | createDyn a n = do |
---|
| 393 | x <- createVar a n |
---|
| 394 | return $ toDyn x |
---|
| 395 | createVar :: String -> a -> SBV.Symbolic a |
---|
| 396 | |
---|
| 397 | instance VarFactory SBV.SInteger where |
---|
| 398 | createVar n _ = SBV.free n |
---|
| 399 | |
---|
| 400 | compilel :: VarPool -> ExpPool -> Supply Int -> L -> SBV.Symbolic (SBV.SInteger) |
---|
| 401 | compilel v e s (Op a c b) = do |
---|
| 402 | let (s1, s2) = split2 s |
---|
| 403 | al <- compilel v e s1 a |
---|
| 404 | bl <- compilel v e s1 b |
---|
| 405 | return $ case c of |
---|
[5] | 406 | '+' -> al + bl |
---|
| 407 | '-' -> al - bl |
---|
| 408 | '*' -> al * bl |
---|
[14] | 409 | '/' -> al `SBV.sDiv` bl |
---|
[15] | 410 | compilel v e s (Var a) = do |
---|
| 411 | let itype = (undefined ::SBV.SInteger) |
---|
| 412 | sym <- getVarSymbol v (createDyn (showVar a "") itype) a |
---|
| 413 | let var = (fromDynamic sym) :: Maybe SBV.SInteger |
---|
| 414 | case var of |
---|
| 415 | Just x -> return x |
---|
| 416 | Nothing -> do |
---|
| 417 | error "Type Error" |
---|
| 418 | compilel v e s (Num a) = return $ SBV.literal $ fromIntegral a |
---|
| 419 | compilel v e s (Bottom) = SBV.free_ |
---|
| 420 | compilel v e s l = do |
---|
| 421 | sym <- getExpSymbol e (return $ SBV.uninterpret ("unint" ++ showVar (supplyValue s) "") ) l |
---|
| 422 | return sym |
---|
| 423 | --compilel v e x = error $ "Cannot compile "++ show x |
---|
| 424 | |
---|
| 425 | gettype :: ((b -> t) -> t) -> a -> b -> a |
---|
| 426 | gettype = error "???" |
---|
| 427 | |
---|
| 428 | {- |
---|
| 429 | compileapp :: (VarFactory b, SBV.Uninterpreted (b -> SBV.SInteger)) => VarPool -> L -> ((b -> t) -> t) -> SBV.Symbolic (SBV.SInteger) |
---|
| 430 | compileapp v (Var a) f = do |
---|
| 431 | let itype = (error :: SBV.SInteger) |
---|
| 432 | sym <- getVarSymbol v (createDyn (showVar a "") (gettype f itype)) a |
---|
| 433 | let var = (fromDynamic sym) :: Maybe SBV.SInteger |
---|
| 434 | case var of |
---|
| 435 | Just x -> return x |
---|
| 436 | Nothing -> do |
---|
| 437 | error "Type Error" |
---|
| 438 | -} |
---|
| 439 | compileapp v (App x y) t = error $ "Not yet implemented." |
---|
| 440 | |
---|