Skip to content

Commit c301169

Browse files
committed
[ Re #71 ] DFAMin: add type signatures
To increase documentation and readability, I added type signatures also to some local definitions. Needs language extension ScopedTypeVariables.
1 parent 5bbb6fb commit c301169

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

src/DFAMin.hs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
2-
{-# LANGUAGE PatternGuards #-}
2+
3+
{-# LANGUAGE PatternGuards #-}
4+
{-# LANGUAGE ScopedTypeVariables #-}
5+
36
module DFAMin (minimizeDFA) where
47

58
import AbsSyn
@@ -31,19 +34,22 @@ import Data.List as List
3134
-- end;
3235
-- end;
3336

34-
minimizeDFA :: Ord a => DFA Int a -> DFA Int a
37+
minimizeDFA :: forall a. Ord a => DFA Int a -> DFA Int a
3538
minimizeDFA dfa@DFA { dfa_start_states = starts,
3639
dfa_states = statemap
3740
}
3841
= DFA { dfa_start_states = starts,
3942
dfa_states = Map.fromList states }
4043
where
44+
equiv_classes :: [EquivalenceClass]
4145
equiv_classes = groupEquivStates dfa
4246

47+
numbered_states :: [(Int, EquivalenceClass)]
4348
numbered_states = number (length starts) equiv_classes
4449

4550
-- assign each state in the minimized DFA a number, making
4651
-- sure that we assign the numbers [0..] to the start states.
52+
number :: Int -> [EquivalenceClass] -> [(Int, EquivalenceClass)]
4753
number _ [] = []
4854
number n (ss:sss) =
4955
case filter (`IS.member` ss) starts of
@@ -53,6 +59,7 @@ minimizeDFA dfa@DFA { dfa_start_states = starts,
5359
-- to multiple starts states, we just have to duplicate
5460
-- that state.
5561

62+
states :: [(Int, State Int a)]
5663
states = [
5764
let old_states = map (lookup statemap) (IS.toList equiv)
5865
accs = map fix_acc (state_acc (head old_states))
@@ -64,35 +71,44 @@ minimizeDFA dfa@DFA { dfa_start_states = starts,
6471
| (n, equiv) <- numbered_states
6572
]
6673

74+
fix_acc :: Accept a -> Accept a
6775
fix_acc acc = acc { accRightCtx = fix_rctxt (accRightCtx acc) }
6876

77+
fix_rctxt :: RightContext SNum -> RightContext SNum
6978
fix_rctxt (RightContextRExp s) = RightContextRExp (get_new s)
7079
fix_rctxt other = other
7180

81+
lookup :: Ord k => Map k v -> k -> v
7282
lookup m k = Map.findWithDefault (error "minimizeDFA") k m
83+
84+
get_new :: Int -> Int
7385
get_new = lookup old_to_new
7486

7587
old_to_new :: Map Int Int
7688
old_to_new = Map.fromList [ (s,n) | (n,ss) <- numbered_states,
7789
s <- IS.toList ss ]
7890

91+
type EquivalenceClass = IntSet
7992

80-
groupEquivStates :: (Ord a) => DFA Int a -> [IntSet]
93+
groupEquivStates :: forall a. Ord a => DFA Int a -> [EquivalenceClass]
8194
groupEquivStates DFA { dfa_states = statemap }
8295
= go init_p init_q
8396
where
97+
accepting, nonaccepting :: Map Int (State Int a)
8498
(accepting, nonaccepting) = Map.partition acc statemap
8599
where acc (State as _) = not (List.null as)
86100

101+
nonaccepting_states :: EquivalenceClass
87102
nonaccepting_states = IS.fromList (Map.keys nonaccepting)
88103

89104
-- group the accepting states into equivalence classes
105+
accept_map :: Map [Accept a] [Int]
90106
accept_map = {-# SCC "accept_map" #-}
91107
foldl' (\m (n,s) -> Map.insertWith (++) (state_acc s) [n] m)
92108
Map.empty
93109
(Map.toList accepting)
94110

95-
-- accept_groups :: Ord s => [Set s]
111+
accept_groups :: [EquivalenceClass]
96112
accept_groups = map IS.fromList (Map.elems accept_map)
97113

98114
init_p = nonaccepting_states : accept_groups
@@ -118,6 +134,7 @@ groupEquivStates DFA { dfa_states = statemap }
118134
| s <- IS.toList a ]
119135

120136
-- The outer loop: recurse on each set in Q
137+
go :: [EquivalenceClass] -> [EquivalenceClass] -> [EquivalenceClass]
121138
go p [] = p
122139
go p (a:q) = go1 0 p q
123140
where
@@ -145,6 +162,3 @@ groupEquivStates DFA { dfa_states = statemap }
145162
replaceyin (z:zs)
146163
| z == y = i : d : zs
147164
| otherwise = z : replaceyin zs
148-
149-
150-

0 commit comments

Comments
 (0)