@@ -150,6 +150,9 @@ groupEquivStates DFA { dfa_states = statemap }
150
150
-- a map from token T to
151
151
-- a map from state S to the set of states that transition to
152
152
-- S on token T
153
+ -- bigmap is an inversed transition function classified by each input token.
154
+ -- the codomain of each inversed function is a set of states rather than single state
155
+ -- since a transition function might not be an injective.
153
156
-- This is a cache of the information needed to compute xs below
154
157
bigmap :: IntMap (IntMap EquivalenceClass )
155
158
bigmap = IM. fromListWith (IM. unionWith IS. union)
@@ -162,22 +165,27 @@ groupEquivStates DFA { dfa_states = statemap }
162
165
go r [] = r
163
166
go r (a: q) = uncurry go $ List. foldl' go0 (a: r,q) xs
164
167
where
165
- xs :: [EquivalenceClass ]
166
- xs =
167
- [ x
168
- | preimageMap <- IM. elems bigmap
168
+ preimage :: IntMap EquivalenceClass -- inversed transition function
169
+ -> EquivalenceClass -- subset of codomain of original transition function
170
+ -> EquivalenceClass -- preimage of given subset
169
171
#if MIN_VERSION_containers(0, 6, 0)
170
- , let x = IS. unions (IM. restrictKeys preimageMap a)
172
+ preimage invMap a = IS. unions (IM. restrictKeys invMap a)
171
173
#else
172
- , let x = IS. unions [IM. findWithDefault IS. empty s preimageMap | s <- IS. toList a]
174
+ preimage invMap a = IS. unions [IM. findWithDefault IS. empty s invMap | s <- IS. toList a]
173
175
#endif
176
+
177
+ xs :: [EquivalenceClass ]
178
+ xs =
179
+ [ x
180
+ | invMap <- IM. elems bigmap
181
+ , let x = preimage invMap a
174
182
, not (IS. null x)
175
183
]
176
184
177
185
refineWith
178
- :: IntSet -- preimage set that bisects the input equivalence class
179
- -> IntSet -- initial equivalence class
180
- -> Maybe (IntSet , IntSet )
186
+ :: EquivalenceClass -- preimage set that bisects the input equivalence class
187
+ -> EquivalenceClass -- input equivalence class
188
+ -> Maybe (EquivalenceClass , EquivalenceClass ) -- refined equivalence class
181
189
refineWith x y =
182
190
if IS. null y1 || IS. null y2
183
191
then Nothing
@@ -188,13 +196,15 @@ groupEquivStates DFA { dfa_states = statemap }
188
196
189
197
go0 (r,q) x = go1 r [] []
190
198
where
199
+ -- iterates over R
191
200
go1 [] r' q' = (r', go2 q q')
192
201
go1 (y: r) r' q' = case refineWith x y of
193
202
Nothing -> go1 r (y: r') q'
194
203
Just (y1, y2)
195
204
| IS. size y1 <= IS. size y2 -> go1 r (y2: r') (y1: q')
196
205
| otherwise -> go1 r (y1: r') (y2: q')
197
206
207
+ -- iterates over Q
198
208
go2 [] q' = q'
199
209
go2 (y: q) q' = case refineWith x y of
200
210
Nothing -> go2 q (y: q')
0 commit comments