@@ -0,0 +1,112 @@
1+{-# LANGUAGE FlexibleContexts #-}
3+module Core.Constraints(ucheck) where
7+import Control.Applicative
9+import Control.Monad.Error
10+import Control.Monad.RWS
11+import Control.Monad.State
14+import qualified Data.Map as M
17+ucheck :: Int -> [(UConstraint, FC)] -> TC ()
18+ucheck num cs = case solve (mkNode num cs) of
19+ Left _ -> tfail UniverseError
22+mkNode :: Int -> [(UConstraint, FC)] -> Node
23+mkNode num cs = relNode num (M.toList (mkRels cs M.empty))
25+type Relations = M.Map UExp [(UConstraint, FC)]
27+mkRels :: [(UConstraint, FC)] -> Relations -> Relations
29+mkRels ((c, f) : cs) acc
30+ = case M.lookup (lhs c) acc of
31+ Nothing -> mkRels cs (M.insert (lhs c) [(c,f)] acc)
32+ Just rs -> mkRels cs (M.insert (lhs c) ((c,f):rs) acc)
33+ where lhs (ULT l _) = l
36+relNode :: Int -> [(UExp, [(UConstraint, FC)])] -> Node
37+relNode num [] = CI 0 $ map Le (map (expNode . UVar) [0..num])
38+relNode num ((c, cons) : cs) = relNode num cs
40+data Child = Lt Node | Le Node
43+data Node = CI Int [Child]
47+expNode :: UExp -> Node
48+expNode (UVar i) = CV (show (UVar i)) []
49+expNode (UVal i) = CI i []
52+test = CI 0 $ [Lt x, Lt y, Le z] ++ map Le ints
57+ ints = [ -- CI 3 [Lt y]
60+add :: Node -> Node -> Node
61+add i node = undefined
64+test2 = CI 0 $ [ Le v84, Le q25 ] ++ map Le [g,e85,v29,f90,j45,g86,n45,v84,q25,y48,q45,h45,g90]
67+ e85 = CV "e85" [Le n45, Le q45, Le h45]
68+ v29 = CV "v29" [Lt g90]
69+ f90 = CV "f90" [Lt g90]
70+ j45 = CV "j45" [Lt f90]
71+ g86 = CV "g86" [Lt f90]
81+cyclic = CI 0 $ map Le [a,b,c]
87+-- onChild :: Int -> Child -> m ()
88+onChild i (Lt n) = solveFrom (i+1) n
89+onChild i (Le n) = solveFrom i n
93+ , MonadState (M.Map String Int, [String]) m
94+ , MonadError String m
95+ ) => Int -> Node -> m ()
96+solveFrom num (CI i chs ) = do
98+ mapM_ (onChild numi) chs
99+solveFrom num (CV nm chs) = do
102+ then throwError $ "cycle: " ++ intercalate ", " nms
104+ modify $ second (nm:) -- add this node for cycle detection
105+ i <- M.lookup nm . fst <$> get
106+ let numi = max num (fromMaybe 0 i)
107+ modify $ first (M.insert nm numi)
108+ mapM_ (onChild numi) chs
109+ modify $ second (drop 1) -- remove the node
111+solve :: Node -> Either String (M.Map String Int)
112+solve n = fst <$> execStateT (solveFrom 0 n) (M.empty, [])