@@ -23,7 +23,7 @@ import Data.List (elemIndex)
23
23
import qualified Data.Map.Strict as Map
24
24
import Data.Maybe (fromMaybe , mapMaybe )
25
25
import Data.Sequence as Seq
26
- import Data.Text.Lazy (Text , isInfixOf , isPrefixOf , last , pack , take )
26
+ import Data.Text.Lazy (Text , concat , isInfixOf , isPrefixOf , last , pack , take , unpack )
27
27
import Database.Requirement (Modifier (.. ), Req (.. ))
28
28
import DynamicGraphs.CourseFinder (lookupCourses )
29
29
import DynamicGraphs.GraphNodeUtils (formatModOr , maybeHead , paddingSpaces , stringifyModAnd )
@@ -67,7 +67,7 @@ reqsToGraph options reqs = do
67
67
allStmts <- concatUnique <$> mapM (reqToStmts options) reqs
68
68
return $ buildGraph allStmts
69
69
where
70
- concatUnique = nubOrd . concat
70
+ concatUnique = nubOrd . Prelude. concat
71
71
72
72
data GeneratorState = GeneratorState Integer (Map. Map Text (DotNode Text ))
73
73
@@ -111,7 +111,7 @@ reqToStmts options (name, req) = do
111
111
then do
112
112
node <- makeNode name $ Just (nodeColor options name)
113
113
stmts <- reqToStmtsTree options (nodeID node) req
114
- return $ DN node: concat (toList stmts)
114
+ return $ DN node: Prelude. concat (toList stmts)
115
115
else return []
116
116
117
117
reqToStmtsTree :: GraphOptions -- ^ Options to toggle dynamic graph
@@ -129,7 +129,7 @@ reqToStmtsTree options parentID (J name2 _) = do
129
129
return (Node [] [] )
130
130
-- Two or more required prerequisites.
131
131
reqToStmtsTree options parentID (ReqAnd reqs) = do
132
- andNode <- makeBool " and"
132
+ ( andNode, _) <- makeBool " and" reqs
133
133
edge <- makeEdge (nodeID andNode) parentID Nothing
134
134
prereqStmts <- mapM (reqToStmtsTree options (nodeID andNode)) reqs
135
135
let filteredStmts = Prelude. filter (Node [] [] /= ) prereqStmts
@@ -142,7 +142,7 @@ reqToStmtsTree options parentID (ReqAnd reqs) = do
142
142
_ -> return $ Node [DN andNode, DE edge] filteredStmts
143
143
-- A choice from two or more prerequisites.
144
144
reqToStmtsTree options parentID (ReqOr reqs) = do
145
- orNode <- makeBool " or"
145
+ ( orNode, _) <- makeBool " or" reqs
146
146
edge <- makeEdge (nodeID orNode) parentID Nothing
147
147
prereqStmts <- mapM (reqToStmtsTree options (nodeID orNode)) reqs
148
148
let filteredStmts = Prelude. filter (Node [] [] /= ) prereqStmts
@@ -275,13 +275,23 @@ makeNode name nodeCol = do
275
275
return node
276
276
Just node -> return node
277
277
278
- makeBool :: Text -> State GeneratorState (DotNode Text )
279
- makeBool text1 = do
280
- GeneratorState i nodesMap <- State. get
281
- State. put (GeneratorState (i + 1 ) nodesMap)
282
- let nodeId = mappendTextWithCounter text1 i
283
- return $ DotNode nodeId
284
- ([AC. Label (toLabelValue text1), ID nodeId] ++ ellipseAttrs)
278
+ makeBool :: Text -> [Req ] -> State GeneratorState (DotNode Text , Text )
279
+ makeBool text1 reqs = do
280
+ GeneratorState i boolsMap <- State. get
281
+ reqsList <- mapM generateBoolKey reqs
282
+ let sortedList = toList (sort $ fromList reqsList)
283
+ let boolKey = Data.Text.Lazy. concat $ text1 : sortedList
284
+ case Map. lookup boolKey boolsMap of
285
+ Nothing -> do
286
+ let nodeId = mappendTextWithCounter text1 i
287
+ let boolNode = DotNode nodeId
288
+ ([AC. Label (toLabelValue text1), ID nodeId] ++ ellipseAttrs)
289
+ boolsMap' = Map. insert boolKey boolNode boolsMap
290
+ State. put (GeneratorState (i + 1 ) boolsMap')
291
+
292
+ return (boolNode, boolKey)
293
+ Just node -> do
294
+ return (node, boolKey)
285
295
286
296
-- | Create edge from two node ids. Also allow for potential edge label
287
297
makeEdge :: Text -> Text -> Maybe Text -> State GeneratorState (DotEdge Text )
@@ -296,6 +306,20 @@ makeEdge id1 id2 description =
296
306
mappendTextWithCounter :: Text -> Integer -> Text
297
307
mappendTextWithCounter text1 counter = text1 `mappend` " _counter_" `mappend` pack (show counter)
298
308
309
+ -- | Generates a unique key for each boolean node
310
+ -- May generate lower level nodes that make up the boolean node
311
+ generateBoolKey :: Req -> State GeneratorState Text
312
+ generateBoolKey (J s1 _) = return $ pack (" _" ++ s1)
313
+ generateBoolKey (Grade _ req) = do
314
+ generateBoolKey req
315
+ generateBoolKey (ReqAnd reqs) = do
316
+ (_, boolKey)<- makeBool " and" reqs
317
+ return $ pack (" _[" ++ unpack boolKey ++ " ]" )
318
+ generateBoolKey (ReqOr reqs) = do
319
+ (_, boolKey) <- makeBool " or" reqs
320
+ return $ pack (" _[" ++ unpack boolKey ++ " ]" )
321
+ generateBoolKey _ = return " "
322
+
299
323
-- ** Graphviz configuration
300
324
301
325
-- | With the dot statements converted from original requirement data as input, create the corresponding DotGraph
0 commit comments