@@ -1,5 +1,5 @@
2−module Constrain (constrain, Context (..)) where
2+module Types.Constrain (constrain) where
5import Types
5import Types
@@ -7,28 +7,29 @@ import Data.List (foldl')
7import qualified Data.Set as Set
7import qualified Data.Set as Set
8import qualified Data.Map as Map
8import qualified Data.Map as Map
9import Control.Arrow (second)
9import Control.Arrow (second)
10−import Control.Monad (liftM,mapM,zipWithM)
10+import Control.Monad (liftM,mapM,zipWithM,foldM)
11import Control.Monad.State (evalState)
11import Control.Monad.State (evalState)
12import Guid
12import Guid
13+import Types.Substitutions
15+--import System.IO.Unsafe
17+prints xs v = v --unsafePerformIO (putStrLn "~~~~~~~~~~" >> mapM print xs) `seq` v
14beta = VarT `liftM` guid
19beta = VarT `liftM` guid
15unionA = Map.unionWith (++)
20unionA = Map.unionWith (++)
16unionsA = Map.unionsWith (++)
21unionsA = Map.unionsWith (++)
18−data Context a b = Context a b deriving (Eq, Show)
21−instance (Ord a, Eq c) => Ord (Context c a) where
22− compare (Context _ x) (Context _ y) = compare x y
24constrain hints (Module _ _ _ stmts) = do
23constrain hints (Module _ _ _ stmts) = do
25 (ass,css,schemess) <- unzip3 `liftM` mapM stmtGen stmts
24 (ass,css,schemess) <- unzip3 `liftM` mapM stmtGen stmts
26− let allHints = Map.fromList $ hints ++ concat schemess
25+ allHints <- liftM (Map.fromList . (++ concat schemess)) hints
26+ let insert as n = do v <- guid; return $ Map.insertWith' (\_ x -> x) n [v] as
27+ assumptions <- foldM insert (unionsA ass) $ map fst (concat schemess)
27− let combine k s vs = map (\v -> ctx (Var k) $ VarT v :<<: s) vs
28+ let cs = let f k s vs = map (\v -> Context k $ v :<<: s) vs in
28− let cMap = Map.intersectionWithKey combine allHints (unionsA ass)
29+ concat . Map.elems $ Map.intersectionWithKey f allHints assumptions
29− return (Set.toList (Set.unions css) ++ (concatMap snd $ Map.toList cMap))
30+ return $ cs ++ Set.toList (Set.unions css)
31−gen :: Expr -> GuidCounter (Map.Map String [X], Set.Set (Context Expr Constraint), Type)
32+gen :: Expr -> GuidCounter (Map.Map String [X], Set.Set (Context String Constraint), Type)
33gen (Var x) =
34gen (Var x) =
34 do b <- guid
35 do b <- guid
@@ -56,7 +57,8 @@ gen (Let defs e) =
56 let names = map (\(Definition x _ _) -> x) defs
57 let names = map (\(Definition x _ _) -> x) defs
57 let genCs name s = do
58 let genCs name s = do
60+ let vs = Map.findWithDefault [v] name assumptions
59− return . map (\x -> ctx (Var name) $ VarT x :<<: s) $ Map.findWithDefault [v] name assumptions
61+ return $ map (\x -> ctx (Var name) $ x :<<: s) vs
60 cs' <- zipWithM genCs names schemes
62 cs' <- zipWithM genCs names schemes
61 return ( foldr Map.delete assumptions names
63 return ( foldr Map.delete assumptions names
62 , Set.union (Set.fromList . concat $ cs') cs
64 , Set.union (Set.fromList . concat $ cs') cs
@@ -96,50 +98,62 @@ gen other =
96primitive t = return (Map.empty, Set.empty, t)
98primitive t = return (Map.empty, Set.empty, t)
98caseGen tipe (p,e) = do
100caseGen tipe (p,e) = do
99− (as,cs,t) <- gen e
101+ (as ,cs , t ) <- gen e
100− return ( foldr Map.delete as (namesIn p)
102+ (as',cs',[t']) <- patternGen (as,cs,[]) p
101− , cs
103+ let cs'' = Set.union cs' . Set.singleton . ctx p $ t' :=: tipe
102− , t)
104+ return ( as', cs'', t )
104−namesIn PAnything = []
106+patternGen (as,cs,ts) PAnything = ((,,) as cs . (\t -> ts++[t])) `liftM` beta
105−namesIn (PVar v) = [v]
107+patternGen (as,cs,ts) (PVar v) = do
106−namesIn (PData name ps) = concatMap namesIn ps
108+ b <- beta
107−
109+ let cs' = map (\x -> ctx (Var v) $ VarT x :=: b) $ Map.findWithDefault [] v as
108−defScheme (Definition name args e) =
110+ return ( Map.delete v as, Set.union cs $ Set.fromList cs', ts ++ [b] )
109− do argDict <- mapM (\a -> liftM ((,) a) guid) args
111+patternGen (as,cs,ts) p@(PData name ps) = do
110− (as,cs,t) <- gen e
112+ constr <- guid
111− let genCs (arg,x) = do
113+ output <- beta
112− v <- guid
114+ (as',cs',ts') <- foldM patternGen (as,cs,[]) ps
113− return . map (\y -> VarT x :=: VarT y) $ Map.findWithDefault [v] arg as
115+ let t = foldr (==>) output ts'
114− cs' <- concat `liftM` mapM genCs argDict
116+ let getC | isTupleString name = do
115− let cs'' = map (\(Context _ c) -> c) (Set.toList cs)
117+ vs <- mapM (\_ -> beta) ps
116− let tipe = foldr (==>) t $ map (VarT . snd) argDict
118+ return . Set.singleton . ctx p $ output :=: ADT name vs
117− return ( foldr Map.delete as args
119+ | otherwise = return Set.empty
118− , Forall (map snd argDict) (cs' ++ cs'') tipe)
120+ cs'' <- getC
119−
121+ return ( unionA as' (Map.singleton name [constr])
122+ , Set.unions [cs',cs'', Set.singleton . ctx p $ VarT constr :=: t]
126+defScheme :: Definition -> GuidCounter (Map.Map String [X], Scheme)
127+defScheme (Definition name args e) = do
128+ (as,cs,hint) <- defGen name args e
129+ return ( as, snd hint )
120−stmtGen (Def name args e) = do
131+defGen name args e = do
121 argDict <- mapM (\a -> liftM ((,) a) guid) args
132 argDict <- mapM (\a -> liftM ((,) a) guid) args
122 (as,cs,t) <- gen e
133 (as,cs,t) <- gen e
123 let genCs (arg,x) = do
134 let genCs (arg,x) = do
124 v <- guid
135 v <- guid
125− return . map (\y -> VarT x :=: VarT y) $ Map.findWithDefault [v] arg as
136+ return . map (\y -> Context arg $ VarT x :=: VarT y) $ Map.findWithDefault [v] arg as
126 cs' <- concat `liftM` mapM genCs argDict
137 cs' <- concat `liftM` mapM genCs argDict
127− let cs'' = map (\(Context _ c) -> c) (Set.toList cs)
138+ let as' = foldr Map.delete as args
128 let tipe = foldr (==>) t $ map (VarT . snd) argDict
139 let tipe = foldr (==>) t $ map (VarT . snd) argDict
129− return ( foldr Map.delete as args
140+ scheme <- generalize (concat $ Map.elems as') $
131− , [ (name, Forall (map snd argDict) (cs' ++ cs'') tipe) ] )
141+ Forall (map snd argDict) (cs' ++ Set.toList cs) tipe
142+ return ( as', Set.empty, (name, scheme) )
144+stmtGen (Def name args e) = do (as,cs,hint) <- defGen name args e
145+ return ( as, cs, [hint] )
133stmtGen (Datatype name xs tcs) = do schemes <- mapM gen' tcs'
147stmtGen (Datatype name xs tcs) = do schemes <- mapM gen' tcs'
134 return (Map.empty, Set.empty, schemes)
148 return (Map.empty, Set.empty, schemes)
135 where names = map (+ (length xs)) [1..5]
149 where names = map (+ (length xs)) [1..5]
136 tcs' = map (second . map $ rnm names) tcs
150 tcs' = map (second . map $ rnm names) tcs
137− supers t = zipWith (:<:) (map VarT names)
151+ supers t = map (Context name) $ zipWith (:<:) (map VarT names)
138 [ number, time, appendable t, comparable, transformable ]
152 [ number, time, appendable t, comparable, transformable ]
139− gen' (n,ts) = do
153+ gen' (n,ts) = do t <- beta
141− return . (,) n . Forall (xs ++ names) (supers t) $
154+ let s = Forall (xs ++ names) (supers t) $
142− foldr (==>) (ADT name $ map VarT xs) ts
155+ foldr (==>) (ADT name $ map VarT xs) ts
156+ (,) n `liftM` generalize [] s
143 rnm [a,b,c,d,e] (ADT n []) | n == "Number" = VarT a
157 rnm [a,b,c,d,e] (ADT n []) | n == "Number" = VarT a
144 | n == "Time" = VarT b
158 | n == "Time" = VarT b
145 | n == "Appendable" = VarT c
159 | n == "Appendable" = VarT c
@@ -156,12 +170,10 @@ stmtGen (ExportEvent js elm tipe) = do
156stmtGen (ImportEvent js base elm tipe) = do
170stmtGen (ImportEvent js base elm tipe) = do
157 (as,cs,t) <- gen base
171 (as,cs,t) <- gen base
158 return ( as
172 return ( as
159− , Set.insert (ctx (Var elm) (t :=: tipe)) cs
173+ , Set.insert (ctx base (signalOf t :=: tipe)) cs
160 , [ (elm, Forall [] [] tipe) ] )
174 , [ (elm, Forall [] [] tipe) ] )
162−ffiHints (ims,exs) =
176+getDatatypeInfo (Datatype name args tcs) =
163− map (\(_,_,n,t) -> n -: t) ims ++ map (\(_,n,t) -> n -: t) exs
177+ Just (name, args, tcs)
178+getDatatypeInfo _ = Nothing
165−checkFFI dict ims exs = list $ ims' ++ exs'
166− where ims' = map (\(_,b,n,_)-> Binop "==" (Var n) (App (Var "constant") b)) ims
167− exs' = map (\(_,n,_) -> Binop "==" (Var n) (Var $ dict n)) exs