|
1 | | -{-# LANGUAGE CPP #-} |
2 | | - |
3 | 1 | module DFAMin (minimizeDFA) where |
4 | 2 |
|
5 | 3 | import AbsSyn |
6 | 4 |
|
7 | | -import Control.Monad (guard) |
| 5 | +import Control.Monad (guard) |
8 | 6 | import Data.Bifunctor (second) |
9 | | --- import Data.Foldable (fold) |
10 | | -import Data.IntMap (IntMap) |
11 | | -import Data.IntSet (IntSet) |
12 | | --- import Data.Map (Map) |
| 7 | +import Data.IntMap (IntMap) |
| 8 | +import Data.IntSet (IntSet) |
13 | 9 |
|
14 | | -import qualified Data.IntMap as IntMap |
15 | | -import qualified Data.IntSet as IntSet |
16 | | -import qualified Data.List as List |
17 | | -import qualified Data.Map as Map |
| 10 | +import qualified Data.IntMap as IntMap |
| 11 | +import qualified Data.IntSet as IntSet |
| 12 | +import qualified Data.List as List |
| 13 | +import qualified Data.Map as Map |
18 | 14 |
|
19 | 15 | {- Note [Hopcroft's Algorithm] |
20 | 16 |
|
@@ -203,20 +199,6 @@ generateReverseTransitionCache dfa = IntMap.elems $ |
203 | 199 | pure (token, IntMap.singleton targetState (IntSet.singleton sourceState)) |
204 | 200 |
|
205 | 201 |
|
206 | | --- -- | Given an IntMap and an IntSet, restrict the IntMap to the keys that are |
207 | | --- -- within the IntSet. |
208 | | --- -- |
209 | | --- -- This function is a simple wrapper around 'IntMap.restrictKeys', provided for |
210 | | --- -- compatibility with older versions of @containers@. |
211 | | --- restrictKeys :: forall a. IntMap a -> IntSet -> IntMap a |
212 | | --- restrictKeys m s = |
213 | | --- #if MIN_VERSION_containers(0,6,0) |
214 | | --- IntMap.restrictKeys m s |
215 | | --- #else |
216 | | --- IntMap.filterWithKey (\k _ -> k `IntSet.member` s) m |
217 | | --- #endif |
218 | | - |
219 | | - |
220 | 202 | -- | Given two sets X and Y, compute their intersection and difference. |
221 | 203 | -- Only returns both if both are non-empty, otherwise return neither. |
222 | 204 | refine |
@@ -246,12 +228,11 @@ groupEquivalentStates dfa = outerLoop ([], initialSubsets dfa) |
246 | 228 | outerLoop :: ([EquivalenceClass], [EquivalenceClass]) -> [EquivalenceClass] |
247 | 229 | outerLoop (r, []) = r |
248 | 230 | outerLoop (r, a:w) = outerLoop $ List.foldl' refineWithX (a:r,w) $ do |
249 | | - allPreviousStates :: IntMap EquivalenceClass <- reverseTransitionCache |
250 | | - -- let x = fold $ restrictKeys allPreviousStates a |
251 | | - -- Is 'restrictKeys' here really better than the following simpler filter? |
252 | | - -- The given asymptotics does look better, but aren't there overheads to create a balanced 'IntMap' |
253 | | - -- just to destroy it immediately with a 'fold'? |
254 | | - let x = IntSet.unions $ map (\ (tgt, srcs) -> if tgt `IntSet.member` a then srcs else IntSet.empty) $ IntMap.toList allPreviousStates |
| 231 | + allPreviousStates <- reverseTransitionCache |
| 232 | + let x = IntSet.unions $ do |
| 233 | + (target, sources) <- IntMap.toList allPreviousStates |
| 234 | + guard $ target `IntSet.member` a |
| 235 | + pure sources |
255 | 236 | guard $ not $ IntSet.null x |
256 | 237 | pure x |
257 | 238 |
|
|
0 commit comments