fst 0.9.0.1 → 0.10.0.0
raw patch · 39 files changed
+2737/−4245 lines, 39 filesdep +QuickCheckdep +fstdep +haskelinedep ~basenew-component:exe:fststudionew-uploaderPVP ok
version bump matches the API change (PVP)
Dependencies added: QuickCheck, fst, haskeline, mtl, transformers
Dependency ranges changed: base
API changes (from Hackage documentation)
- FST.Alex: Acc :: Int -> String -> a -> [StartCode] -> (Maybe (Char -> Bool)) -> (Maybe SNum) -> Accept a
- FST.Alex: Pn :: !Int -> !Int -> !Int -> Posn
- FST.Alex: St :: Bool -> [Accept a] -> SNum -> (Array Char SNum) -> State a
- FST.Alex: check_ctx :: DFA f -> (StartCode, s) -> Char -> Sv f -> Bool
- FST.Alex: data Accept a
- FST.Alex: data Posn
- FST.Alex: data State a
- FST.Alex: dfa_alphabet :: [Char]
- FST.Alex: dump_dfa :: DFA a -> DFADump
- FST.Alex: eof_pos :: Posn
- FST.Alex: gscan :: GScan s r -> s -> String -> r
- FST.Alex: gscan' :: GScan s r -> Posn -> Char -> String -> (StartCode, s) -> r
- FST.Alex: instance Eq Posn
- FST.Alex: instance Show Posn
- FST.Alex: load_dfa :: [(String, f)] -> f -> DFADump -> DFA f
- FST.Alex: load_gscan :: GActions s r -> DFADump -> GScan s r
- FST.Alex: load_scan :: Actions t -> DFADump -> Scan t
- FST.Alex: move_pos :: Posn -> Char -> Posn
- FST.Alex: recover_dfa :: DFADump -> DFA ()
- FST.Alex: scan :: Scan t -> String -> [t]
- FST.Alex: scan' :: Scan t -> Posn -> Char -> String -> [t]
- FST.Alex: scan_tkn :: DFA f -> Posn -> Char -> String -> Int -> SNum -> [Sv f] -> [Sv f]
- FST.Alex: scan_token :: DFA f -> (StartCode, s) -> Posn -> Char -> String -> Maybe (Sv f)
- FST.Alex: start_pos :: Posn
- FST.Alex: type AcceptDump = (Int, String, [StartCode], Maybe (ArrDump Bool), Maybe SNum)
- FST.Alex: type Actions t = ([(String, TokenAction t)], StopAction t)
- FST.Alex: type ArrDump a = ((Char, Char), [(Char, a)])
- FST.Alex: type DFA a = Array SNum (State a)
- FST.Alex: type DFADump = [(Bool, [AcceptDump], SNum, ArrDump Int)]
- FST.Alex: type GActions s r = ([(String, GTokenAction s r)], GStopAction s r)
- FST.Alex: type GScan s r = (DFA (GTokenAction s r), GStopAction s r)
- FST.Alex: type GStopAction s r = Posn -> Char -> String -> (StartCode, s) -> r
- FST.Alex: type GTokenAction s r = Posn -> Char -> String -> Int -> ((StartCode, s) -> r) -> (StartCode, s) -> r
- FST.Alex: type SNum = Int
- FST.Alex: type Scan t = GScan () [t]
- FST.Alex: type StartCode = Int
- FST.Alex: type StopAction t = Posn -> String -> [t]
- FST.Alex: type Sv t = (Posn, Char, String, Int, Accept t)
- FST.Alex: type TokenAction t = Posn -> String -> t
- FST.Arguments: ApplyD :: [String] -> InteractiveCommand
- FST.Arguments: ApplyDown :: InteractiveCommand
- FST.Arguments: ApplyU :: [String] -> InteractiveCommand
- FST.Arguments: ApplyUp :: InteractiveCommand
- FST.Arguments: BuildNTransducer :: InteractiveCommand
- FST.Arguments: BuildTransducer :: InteractiveCommand
- FST.Arguments: ClearMemory :: InteractiveCommand
- FST.Arguments: Determinize :: InteractiveCommand
- FST.Arguments: Help :: InteractiveCommand
- FST.Arguments: LComposition :: FilePath -> FilePath -> InteractiveCommand
- FST.Arguments: LProduct :: FilePath -> FilePath -> InteractiveCommand
- FST.Arguments: LStar :: FilePath -> InteractiveCommand
- FST.Arguments: LUnion :: FilePath -> FilePath -> InteractiveCommand
- FST.Arguments: Load :: FilePath -> InteractiveCommand
- FST.Arguments: Minimize :: InteractiveCommand
- FST.Arguments: NoCommand :: InteractiveCommand
- FST.Arguments: Quit :: InteractiveCommand
- FST.Arguments: Save :: FilePath -> InteractiveCommand
- FST.Arguments: StdInReg :: String -> InteractiveCommand
- FST.Arguments: ViewInput :: InteractiveCommand
- FST.Arguments: ViewOutput :: InteractiveCommand
- FST.Arguments: ViewReg :: InteractiveCommand
- FST.Arguments: ViewTransducer :: InteractiveCommand
- FST.Arguments: data InteractiveCommand
- FST.Arguments: inputB :: [BatchCommand] -> Maybe FilePath
- FST.Arguments: instance Show BatchCommand
- FST.Arguments: isDAT :: String -> Bool
- FST.Arguments: isFST :: String -> Bool
- FST.Arguments: isNET :: String -> Bool
- FST.Arguments: isTHIS :: String -> Bool
- FST.Arguments: isUpB :: [BatchCommand] -> Bool
- FST.Arguments: outputB :: [BatchCommand] -> Maybe FilePath
- FST.Arguments: parseBatch :: [String] -> Either String (FilePath, [BatchCommand])
- FST.Arguments: parseInteractive :: [String] -> InteractiveCommand
- FST.AutomatonTypes: type State = Int
- FST.FileImport: open :: FilePath -> IO (Either String String)
- FST.FileImport: saveToFile :: FilePath -> String -> IO (Either String ())
- FST.GetOpt: NoArg :: a -> ArgDescr a
- FST.GetOpt: OptArg :: (Maybe String -> a) -> String -> ArgDescr a
- FST.GetOpt: Option :: [Char] -> [String] -> (ArgDescr a) -> String -> OptDescr a
- FST.GetOpt: Permute :: ArgOrder a
- FST.GetOpt: ReqArg :: (String -> a) -> String -> ArgDescr a
- FST.GetOpt: RequireOrder :: ArgOrder a
- FST.GetOpt: ReturnInOrder :: (String -> a) -> ArgOrder a
- FST.GetOpt: data ArgDescr a
- FST.GetOpt: data ArgOrder a
- FST.GetOpt: data OptDescr a
- FST.GetOpt: getOpt :: ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String])
- FST.GetOpt: usageInfo :: String -> [OptDescr a] -> String
- FST.Info: Info :: (Transducer String, Bool) -> (RReg String, Bool) -> ([String], Bool) -> ([String], Bool) -> Info
- FST.Info: clearInfo :: Info -> Info
- FST.Info: data Info
- FST.Info: emptyInfo :: Info
- FST.Info: expression :: Info -> (RReg String, Bool)
- FST.Info: expressionRead :: Info -> Bool
- FST.Info: fstStudio :: IO ()
- FST.Info: getExpression :: Info -> RReg String
- FST.Info: getInput :: Info -> [String]
- FST.Info: getOutputs :: Info -> [String]
- FST.Info: getTransducer :: Info -> Transducer String
- FST.Info: help :: IO ()
- FST.Info: input :: Info -> ([String], Bool)
- FST.Info: inputRead :: Info -> Bool
- FST.Info: noExpression :: IO ()
- FST.Info: noInput :: IO ()
- FST.Info: noOutputs :: IO ()
- FST.Info: noTransducer :: IO ()
- FST.Info: outputs :: Info -> ([String], Bool)
- FST.Info: outputsRead :: Info -> Bool
- FST.Info: prompt :: IO ()
- FST.Info: transducer :: Info -> (Transducer String, Bool)
- FST.Info: transducerBuilt :: Info -> Bool
- FST.Info: updateExpression :: RReg String -> Info -> Info
- FST.Info: updateInput :: [String] -> Info -> Info
- FST.Info: updateOutputs :: [String] -> Info -> Info
- FST.Info: updateTransducer :: Transducer String -> Info -> Info
- FST.Lexer: Err :: String -> Token
- FST.Lexer: TokenAll :: Int -> Token
- FST.Lexer: TokenComplement :: Int -> Token
- FST.Lexer: TokenComposition :: Int -> Token
- FST.Lexer: TokenConcatS :: (Int, String) -> Token
- FST.Lexer: TokenContainment :: Int -> Token
- FST.Lexer: TokenCrossproduct :: Int -> Token
- FST.Lexer: TokenDef :: Int -> Token
- FST.Lexer: TokenEps :: Int -> Token
- FST.Lexer: TokenFun :: (Int, (Name, [String])) -> Token
- FST.Lexer: TokenHCB :: Int -> Token
- FST.Lexer: TokenHOB :: Int -> Token
- FST.Lexer: TokenIntersect :: Int -> Token
- FST.Lexer: TokenMain :: Int -> Token
- FST.Lexer: TokenMinus :: Int -> Token
- FST.Lexer: TokenNum :: (Int, Int) -> Token
- FST.Lexer: TokenPlus :: Int -> Token
- FST.Lexer: TokenRelation :: Int -> Token
- FST.Lexer: TokenRepeat :: Int -> Token
- FST.Lexer: TokenS :: (Int, String) -> Token
- FST.Lexer: TokenSCB :: Int -> Token
- FST.Lexer: TokenSOB :: Int -> Token
- FST.Lexer: TokenSemi :: Int -> Token
- FST.Lexer: TokenStar :: Int -> Token
- FST.Lexer: TokenUnion :: Int -> Token
- FST.Lexer: TokenVar :: (Int, String) -> Token
- FST.Lexer: allSymbol :: Posn -> String -> Token
- FST.Lexer: complement :: Posn -> String -> Token
- FST.Lexer: composition :: Posn -> String -> Token
- FST.Lexer: concatsymbols :: Posn -> String -> Token
- FST.Lexer: containment :: Posn -> String -> Token
- FST.Lexer: crossproduct :: Posn -> String -> Token
- FST.Lexer: data Token
- FST.Lexer: definitions :: Posn -> String -> Token
- FST.Lexer: equal :: Posn -> String -> Token
- FST.Lexer: hardClosedBracket :: Posn -> String -> Token
- FST.Lexer: hardOpenBracket :: Posn -> String -> Token
- FST.Lexer: instance Eq Token
- FST.Lexer: instance Show Token
- FST.Lexer: intersect :: Posn -> String -> Token
- FST.Lexer: lexer :: String -> [Token]
- FST.Lexer: listEps :: Posn -> String -> Token
- FST.Lexer: litint :: Posn -> String -> Token
- FST.Lexer: lx__0_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__10_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__11_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__12_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__13_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__14_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__15_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__16_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__17_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__18_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__19_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__1_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__20_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__21_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__22_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__23_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__24_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__25_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__26_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__27_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__28_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__29_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__2_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__30_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__31_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__32_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__33_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__34_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__35_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__36_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__37_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__38_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__39_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__3_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__40_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__41_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__42_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__4_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__5_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__6_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__7_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__8_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: lx__9_0 :: (Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))
- FST.Lexer: mainId :: Posn -> String -> Token
- FST.Lexer: minus :: Posn -> String -> Token
- FST.Lexer: params :: String -> [String]
- FST.Lexer: plus :: Posn -> String -> Token
- FST.Lexer: relation :: Posn -> String -> Token
- FST.Lexer: repeatSymbol :: Posn -> String -> Token
- FST.Lexer: semicolon :: Posn -> String -> Token
- FST.Lexer: softClosedBracket :: Posn -> String -> Token
- FST.Lexer: softOpenBracket :: Posn -> String -> Token
- FST.Lexer: star :: Posn -> String -> Token
- FST.Lexer: symbol :: Posn -> String -> Token
- FST.Lexer: token_lx :: [(Bool, [(Int, String, [Int], Maybe ((Char, Char), [(Char, Bool)]), Maybe Int)], Int, ((Char, Char), [(Char, Int)]))]
- FST.Lexer: type Name = String
- FST.Lexer: union :: Posn -> String -> Token
- FST.Lexer: variable :: Posn -> String -> Token
- FST.Lexer: zeroEps :: Posn -> String -> Token
- FST.MinimalBrzozowski: minimize :: Ord a => Automaton a -> Automaton a
- FST.MinimalTBrzozowski: minimize :: Ord a => Transducer a -> Transducer a
- FST.Parse: FailE :: String -> E a
- FST.Parse: Function :: Name -> [String] -> (NReg String) -> Def
- FST.Parse: HappyAbsSyn5 :: t5 -> HappyAbsSyn t5 t6 t7
- FST.Parse: HappyAbsSyn6 :: t6 -> HappyAbsSyn t5 t6 t7
- FST.Parse: HappyAbsSyn7 :: t7 -> HappyAbsSyn t5 t6 t7
- FST.Parse: HappyErrorToken :: Int -> HappyAbsSyn t5 t6 t7
- FST.Parse: HappyState :: (Int -> Int -> b -> HappyState b c -> [HappyState b c] -> c) -> HappyState b c
- FST.Parse: HappyStk :: a -> (HappyStk a) -> HappyStk a
- FST.Parse: HappyTerminal :: Token -> HappyAbsSyn t5 t6 t7
- FST.Parse: Main :: (NReg String) -> Def
- FST.Parse: Ok :: a -> E a
- FST.Parse: apply :: NReg String -> [Def] -> E (NReg String)
- FST.Parse: data Def
- FST.Parse: data E a
- FST.Parse: data HappyAbsSyn t5 t6 t7
- FST.Parse: data HappyStk a
- FST.Parse: failE :: String -> E a
- FST.Parse: happyError :: [Token] -> E a
- FST.Parse: instance Monad E
- FST.Parse: newtype HappyState b c
- FST.Parse: parseExp :: String -> Either String (RReg String)
- FST.Parse: parseList :: [String] -> [NReg String] -> E ([NReg String])
- FST.Parse: parseProgram :: String -> Either String (RReg String)
- FST.Parse: replace :: NReg String -> [(String, NReg String)] -> E (NReg String)
- FST.Parse: returnE :: a -> E a
- FST.StateMonad: STM :: (State -> (a, State)) -> STM a
- FST.StateMonad: fetchState :: STM State
- FST.StateMonad: instance Monad STM
- FST.StateMonad: newtype STM a
- FST.StateMonad: run :: STM a -> State -> a
- FST.StateMonad: setState :: State -> STM ()
- FST.TransducerTypes: type State = Int
- FST.Utils: cross :: [a] -> [b] -> [(a, b)]
- FST.Utils: insert :: Eq b => (b, [(a, b)]) -> [(b, [(a, b)])] -> [(b, [(a, b)])]
- FST.Utils: merge :: Eq b => [(b, [(a, b)])] -> [(b, [(a, b)])] -> [(b, [(a, b)])]
- FST.Utils: remove :: Eq b => b -> [(b, [(a, b)])] -> [(b, [(a, b)])]
- FST.Utils: tagging :: [a] -> Int -> (Int, [(a, Int)])
+ FST.AutomatonTypes: type StateTy = Int
+ FST.TransducerInterface: open :: FilePath -> ErrorT String IO String
+ FST.TransducerInterface: saveToFile :: FilePath -> String -> ErrorT String IO ()
+ FST.TransducerTypes: type StateTy = Int
- FST.Automaton: rename :: Eq b => [(b, [(a, b)])] -> Sigma a -> [b] -> [b] -> State -> Automaton a
+ FST.Automaton: rename :: Eq b => [(b, [(a, b)])] -> Sigma a -> [b] -> [b] -> StateTy -> Automaton a
- FST.AutomatonInterface: compile :: Ord a => Reg a -> Sigma a -> State -> Automaton a
+ FST.AutomatonInterface: compile :: Ord a => Reg a -> Sigma a -> StateTy -> Automaton a
- FST.AutomatonInterface: compileNFA :: Ord a => Reg a -> Sigma a -> State -> Automaton a
+ FST.AutomatonInterface: compileNFA :: Ord a => Reg a -> Sigma a -> StateTy -> Automaton a
- FST.AutomatonInterface: initial :: Automaton a -> State
+ FST.AutomatonInterface: initial :: Automaton a -> StateTy
- FST.AutomatonTypes: firstState :: (AutomatonFunctions f, Eq a) => f a -> State
+ FST.AutomatonTypes: firstState :: (AutomatonFunctions f, Eq a) => f a -> StateTy
- FST.AutomatonTypes: isFinal :: AutomatonFunctions f => f a -> State -> Bool
+ FST.AutomatonTypes: isFinal :: AutomatonFunctions f => f a -> StateTy -> Bool
- FST.AutomatonTypes: lastState :: (AutomatonFunctions f, Eq a) => f a -> State
+ FST.AutomatonTypes: lastState :: (AutomatonFunctions f, Eq a) => f a -> StateTy
- FST.AutomatonTypes: states :: AutomatonFunctions f => f a -> [State]
+ FST.AutomatonTypes: states :: AutomatonFunctions f => f a -> [StateTy]
- FST.AutomatonTypes: transitionList :: AutomatonFunctions f => f a -> State -> Transitions a
+ FST.AutomatonTypes: transitionList :: AutomatonFunctions f => f a -> StateTy -> Transitions a
- FST.AutomatonTypes: transitions :: (AutomatonFunctions f, Eq a) => f a -> (State, a) -> [State]
+ FST.AutomatonTypes: transitions :: (AutomatonFunctions f, Eq a) => f a -> (StateTy, a) -> [StateTy]
- FST.AutomatonTypes: type FinalStates = [State]
+ FST.AutomatonTypes: type FinalStates = [StateTy]
- FST.AutomatonTypes: type InitialStates = [State]
+ FST.AutomatonTypes: type InitialStates = [StateTy]
- FST.AutomatonTypes: type TransitionTable a = [(State, Transitions a)]
+ FST.AutomatonTypes: type TransitionTable a = [(StateTy, Transitions a)]
- FST.AutomatonTypes: type Transitions a = [(a, State)]
+ FST.AutomatonTypes: type Transitions a = [(a, StateTy)]
- FST.LBFA: compileToAutomaton :: Ord a => Reg a -> Sigma a -> State -> Automaton a
+ FST.LBFA: compileToAutomaton :: Ord a => Reg a -> Sigma a -> StateTy -> Automaton a
- FST.LBFA: compileToLBFA :: Ord a => Reg a -> Sigma a -> State -> LBFA a
+ FST.LBFA: compileToLBFA :: Ord a => Reg a -> Sigma a -> StateTy -> LBFA a
- FST.LBFA: initial :: LBFA a -> State
+ FST.LBFA: initial :: LBFA a -> StateTy
- FST.LBFT: LBFT :: TTransitionTable a -> State -> [State] -> Sigma a -> State -> LBFT a
+ FST.LBFT: LBFT :: TTransitionTable a -> StateTy -> [StateTy] -> Sigma a -> StateTy -> LBFT a
- FST.LBFT: finalS :: LBFT a -> [State]
+ FST.LBFT: finalS :: LBFT a -> [StateTy]
- FST.LBFT: initS :: LBFT a -> State
+ FST.LBFT: initS :: LBFT a -> StateTy
- FST.LBFT: lastS :: LBFT a -> State
+ FST.LBFT: lastS :: LBFT a -> StateTy
- FST.Transducer: construct :: (State, State) -> TTransitionTable a -> Sigma a -> InitialStates -> FinalStates -> Transducer a
+ FST.Transducer: construct :: (StateTy, StateTy) -> TTransitionTable a -> Sigma a -> InitialStates -> FinalStates -> Transducer a
- FST.Transducer: initial :: Transducer a -> State
+ FST.Transducer: initial :: Transducer a -> StateTy
- FST.Transducer: rename :: Eq b => [(b, [(Relation a, b)])] -> Sigma a -> [b] -> [b] -> State -> Transducer a
+ FST.Transducer: rename :: Eq b => [(b, [(Relation a, b)])] -> Sigma a -> [b] -> [b] -> StateTy -> Transducer a
- FST.Transducer: transitions :: Eq a => Transducer a -> (State, Relation a) -> [State]
+ FST.Transducer: transitions :: Eq a => Transducer a -> (StateTy, Relation a) -> [StateTy]
- FST.TransducerInterface: load :: FilePath -> IO (Either String (Transducer String))
+ FST.TransducerInterface: load :: FilePath -> ErrorT String IO (Transducer String)
- FST.TransducerInterface: save :: FilePath -> Transducer String -> IO (Either String ())
+ FST.TransducerInterface: save :: FilePath -> Transducer String -> ErrorT String IO ()
- FST.TransducerInterface: transitions :: Eq a => Transducer a -> (State, Relation a) -> [State]
+ FST.TransducerInterface: transitions :: Eq a => Transducer a -> (StateTy, Relation a) -> [StateTy]
- FST.TransducerTypes: firstState :: TransducerFunctions f => f a -> State
+ FST.TransducerTypes: firstState :: TransducerFunctions f => f a -> StateTy
- FST.TransducerTypes: isFinal :: TransducerFunctions f => f a -> State -> Bool
+ FST.TransducerTypes: isFinal :: TransducerFunctions f => f a -> StateTy -> Bool
- FST.TransducerTypes: lastState :: TransducerFunctions f => f a -> State
+ FST.TransducerTypes: lastState :: TransducerFunctions f => f a -> StateTy
- FST.TransducerTypes: states :: TransducerFunctions f => f a -> [State]
+ FST.TransducerTypes: states :: TransducerFunctions f => f a -> [StateTy]
- FST.TransducerTypes: transitionList :: TransducerFunctions f => f a -> State -> TTransitions a
+ FST.TransducerTypes: transitionList :: TransducerFunctions f => f a -> StateTy -> TTransitions a
- FST.TransducerTypes: transitionsD :: (TransducerFunctions f, Eq a) => f a -> (State, Symbol a) -> [(Symbol a, State)]
+ FST.TransducerTypes: transitionsD :: (TransducerFunctions f, Eq a) => f a -> (StateTy, Symbol a) -> [(Symbol a, StateTy)]
- FST.TransducerTypes: transitionsU :: (TransducerFunctions f, Eq a) => f a -> (State, Symbol a) -> [(Symbol a, State)]
+ FST.TransducerTypes: transitionsU :: (TransducerFunctions f, Eq a) => f a -> (StateTy, Symbol a) -> [(Symbol a, StateTy)]
- FST.TransducerTypes: type FinalStates = [State]
+ FST.TransducerTypes: type FinalStates = [StateTy]
- FST.TransducerTypes: type InitialStates = [State]
+ FST.TransducerTypes: type InitialStates = [StateTy]
- FST.TransducerTypes: type TTransitionTable a = [(State, [(Relation a, State)])]
+ FST.TransducerTypes: type TTransitionTable a = [(StateTy, [(Relation a, StateTy)])]
- FST.TransducerTypes: type TTransitions a = [(Relation a, State)]
+ FST.TransducerTypes: type TTransitions a = [(Relation a, StateTy)]
Files
- FST/Arguments.hs +114/−76
- FST/Automaton.hs +59/−64
- FST/AutomatonInterface.hs +44/−37
- FST/AutomatonTypes.hs +44/−46
- FST/Complete.hs +22/−21
- FST/Deterministic.hs +27/−34
- FST/DeterministicT.hs +20/−29
- FST/EpsilonFreeT.hs +40/−46
- FST/FSTStudio.hs +206/−0
- FST/FileImport.hs +0/−24
- FST/GetOpt.hs +0/−154
- FST/Info.hs +38/−88
- FST/LBFA.hs +202/−229
- FST/LBFT.hs +189/−215
- FST/Lexer.hs +36/−1
- FST/Main.hs +0/−346
- FST/MinimalBrzozowski.hs +0/−23
- FST/MinimalTBrzozowski.hs +0/−23
- FST/NReg.hs +57/−68
- FST/Parse.hs +42/−10
- FST/RRegTypes.hs +60/−84
- FST/RegTypes.hs +119/−161
- FST/Reversal.hs +27/−21
- FST/ReversalT.hs +7/−11
- FST/RunTransducer.hs +29/−34
- FST/StateMonad.hs +0/−46
- FST/Transducer.hs +161/−200
- FST/TransducerInterface.hs +157/−65
- FST/TransducerTypes.hs +45/−62
- FST/Utils.hs +22/−44
- Main.hs +574/−0
- doc/Interface0.9.ps +0/−655
- doc/fstMan0.9.ps +0/−1299
- fst.cabal +91/−29
- tests/drink.fst +7/−0
- tests/drink.hs +47/−0
- tests/email.fst +51/−0
- tests/email.hs +108/−0
- tests/properties.hs +92/−0
FST/Arguments.hs view
@@ -1,51 +1,81 @@-{-- **************************************************************- * Filename : Arguments.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : - *- **************************************************************+{- |+Helper functions for handling shell/command-line options -}+module FST.Arguments ( -module FST.Arguments ( parseInteractive,- InteractiveCommand(..),- isFST,- isDAT,- isNET,- isTHIS,- parseBatch,- inputB,- outputB,- isUpB- ) where+ -- * Commands ADT+ InteractiveCommand (..),+ BatchCommand (..), -import FST.GetOpt+ -- * Helper functions+ parseInteractive,+ isFST,+ isDAT,+ isNET,+ isTHIS,+ parseBatch,+ inputB,+ outputB,+ isUpB+ ) where -data InteractiveCommand = BuildTransducer |- BuildNTransducer |- Minimize |- Determinize |- StdInReg String |- Load FilePath |- LUnion FilePath FilePath |- LProduct FilePath FilePath |- LStar FilePath |- LComposition FilePath FilePath |- Save FilePath |- ApplyDown |- ApplyUp |- ApplyD [String] |- ApplyU [String] |- ViewReg |- ViewInput |- ViewOutput |- ViewTransducer |- Help |- ClearMemory |- Quit |- NoCommand+import System.Console.GetOpt +import Data.List+import Data.Maybe +-- | ADT for a shell command+data InteractiveCommand =+ -- | Build an epsilon-free, deterministic, minimal transducer from a+ -- loaded/typed regular relation.+ BuildTransducer + -- | Build an epsilon-free, possibly non-deterministic, non-minimal+ -- transducer from a load/typed regular relation.+ | BuildNTransducer+ -- | Minimize a built transducer.+ | Minimize+ -- | Determinize a built transducer.+ | Determinize+ -- | Read a regular relation from standard input.+ | StdInReg String+ -- | Load from FILE.+ | Load FilePath+ -- | Load and union two transducers.+ | LUnion FilePath FilePath+ -- | Load and concatenate two transducers.+ | LProduct FilePath FilePath+ -- | Load and apply Kleene's star on a transducer.+ | LStar FilePath+ -- | Load and compose two transducers.+ | LComposition FilePath FilePath+ -- | Save to file.+ | Save FilePath+ -- | Apply transducer down with loaded input.+ | ApplyDown+ -- | Apply transducer up with loaded input.+ | ApplyUp+ -- | Apply tranducer down with given symbols.+ | ApplyD [String]+ -- | Apply tranducer up with given symbols.+ | ApplyU [String]+ -- | View loaded/typed regular relation.+ | ViewReg+ -- | View loaded input.+ | ViewInput+ -- | View prodeced output.+ | ViewOutput+ -- | View loaded/built transducer.+ | ViewTransducer+ -- | List commands.+ | Help+ -- | Clear loaded transducers/input/output.+ | ClearMemory+ -- | Quit the shell+ | Quit+ -- | Unparseable command+ | NoCommand+ deriving (Eq, Show)++-- | Parse input string into a command parseInteractive :: [String] -> InteractiveCommand parseInteractive ["b"] = BuildTransducer parseInteractive ["bn"] = BuildNTransducer@@ -71,61 +101,69 @@ parseInteractive ["c"] = ClearMemory parseInteractive _ = NoCommand +-- | Does the file end with .fst? isFST :: String -> Bool-isFST str = case (reverse str) of- ('t':'s':'f':'.':_) -> True- _ -> False+isFST = isSuffixOf ".fst" +-- | Does the file end with .dat? isDAT :: String -> Bool-isDAT str = case (reverse str) of- ('t':'a':'d':'.':_) -> True- _ -> False+isDAT = isSuffixOf ".dat" +-- | Does the file end with .net? isNET :: String -> Bool-isNET str = case (reverse str) of- ('t':'e':'n':'.':_) -> True- _ -> False+isNET = isSuffixOf ".net" +-- | Is the internal transducer being specified? isTHIS :: String -> Bool isTHIS = (== "*") +-- | Is apply up? isApplyUp :: [String] -> Bool isApplyUp = elem "-u" -data BatchCommand = DownB |- UpB |- InvalidCommand |- Input String |- Output String |- HelpB- deriving Show+-- | Batch command ADT+data BatchCommand =+ -- | Apply down+ DownB+ -- | Apply up+ | UpB+ -- | Invalid command+ | InvalidCommand+ -- | Take input from given file+ | Input String+ -- | Write output to file+ | Output String+ -- | Display help+ | HelpB+ deriving (Eq, Show) +-- | Information for parsing batch options batchOptions :: [OptDescr BatchCommand]-batchOptions = [Option ['u'] ["up"] (NoArg UpB) "apply the transducer up (default is down)",- Option ['d'] ["down"] (NoArg DownB) "apply the transducer down (default)",- Option ['i'] ["input"] (ReqArg Input "FILE") "read input from FILE",- Option ['o'] ["output"] (ReqArg Output "FILE") "write output to FILE"]+batchOptions = [+ Option ['u'] ["up"] (NoArg UpB) "apply the transducer up (default is down)",+ Option ['d'] ["down"] (NoArg DownB) "apply the transducer down (default)",+ Option ['i'] ["input"] (ReqArg Input "FILE") "read input from FILE",+ Option ['o'] ["output"] (ReqArg Output "FILE") "write output to FILE"+ ] +-- | Parse batch commands parseBatch :: [String] -> Either String (FilePath,[BatchCommand]) parseBatch cmdline = case getOpt Permute batchOptions cmdline of- (o,[file],[]) -> Right (file,o)- (_,_,errs) -> Left $ concat errs ++ usageInfo header batchOptions- where header = "Usage: fst [FILE.net or FILE.fst] [OPTIONS...]"+ (o, [file], []) -> Right (file, o)+ (_, _, errs) -> Left (concat errs ++ usageInfo header batchOptions) where+ header = "Usage: fst [FILE.net or FILE.fst] [OPTIONS...]" -inputB :: [BatchCommand] -> Maybe FilePath-inputB [] = Nothing-inputB ((Input file):_) = return file-inputB (_:xs) = inputB xs+-- | Handle batch input command+inputB :: [BatchCommand] -> Maybe FilePath+inputB cs = listToMaybe [ file | Input file <- cs ] +-- | Handle batch output command outputB :: [BatchCommand] -> Maybe FilePath-outputB [] = Nothing-outputB ((Output file):_) = return file-outputB (_:xs) = outputB xs+outputB cs = listToMaybe [ file | Output file <- cs ] +-- | Is batch command apply up? isUpB :: [BatchCommand] -> Bool-isUpB [] = False-isUpB (UpB:_) = True-isUpB (_:xs) = isUpB xs+isUpB = elem UpB {- -----------------------------------------------------------------------------------------
FST/Automaton.hs view
@@ -1,63 +1,57 @@-{-- **************************************************************- * Filename : Automaton.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 120 *- **************************************************************+{- |+Finite state automatons -}--module FST.Automaton ( module FST.AutomatonTypes,- Automaton, -- data type for an automaton- construct, -- construct an automaton.- Convertable, -- type class for conversion to- -- an from an 'Automaton'.- decode, -- from an automaton to an structure.- encode, -- from a structure to an Automaton.- rename,- showAutomaton- ) where+module FST.Automaton (+ module FST.AutomatonTypes,+ + -- * Types+ Automaton,+ Convertable (decode, encode),+ + -- * Automaton construction+ construct,+ + -- * Actions on automatons+ rename,+ showAutomaton,+ + ) where import FST.AutomatonTypes import FST.Utils (tagging)--import Data.Maybe (fromJust)+import Data.Maybe (fromJust, maybeToList) --- data type for an automaton+-- | Data type for an automaton data Automaton a = Automaton {- stateTrans :: TransitionTable a,- initialStates :: InitialStates,- finalStates :: FinalStates,- alpha :: Sigma a,- firstS :: FirstState,- lastS :: LastState- }- deriving (Show,Read)+ stateTrans :: TransitionTable a,+ initialStates :: InitialStates,+ finalStates :: FinalStates,+ alpha :: Sigma a,+ firstS :: FirstState,+ lastS :: LastState+ } deriving (Show,Read) -- | Construct an automaton construct :: (FirstState,LastState) -> TransitionTable a -> Sigma a -> InitialStates -> FinalStates -> Automaton a construct bs table sigma inits fs = Automaton {- stateTrans = table,- initialStates = inits,- finalStates = fs,- alpha = sigma,- firstS = fst bs,- lastS = snd bs- }+ stateTrans = table,+ initialStates = inits,+ finalStates = fs,+ alpha = sigma,+ firstS = fst bs,+ lastS = snd bs+ } --- |Instance of AutomatonFunctions+-- | Instance of AutomatonFunctions instance AutomatonFunctions Automaton where- states = (map fst).stateTrans- isFinal auto s = elem s (finalStates auto)+ states = map fst . stateTrans+ isFinal auto s = s `elem` finalStates auto initials = initialStates finals = finalStates transitionTable = stateTrans- transitionList auto s = case (lookup s (stateTrans auto)) of- Just tl -> tl- _ -> []- transitions auto (s,a) = map snd $ filter (\(b,_) -> b == a) $ transitionList auto s+ transitionList auto s = maybe [] id (lookup s (stateTrans auto))+ transitions auto (s,a) = [ st | (b, st) <- transitionList auto s, b == a ] firstState = firstS lastState = lastS alphabet = alpha@@ -65,32 +59,33 @@ -- | Convert automaton labelled with something other than -- states to an 'Automaton'. rename :: Eq b => [(b,[(a,b)])] -> Sigma a -> [b] -> [b] ->- State -> Automaton a+ StateTy -> Automaton a rename tTable sigma initS fs s- = let (maxS,table) = tagging (map fst tTable) s- nI = map (\b -> lookupState b table) initS- nfs = map (\b -> lookupState b table) fs- nTrans = renameTable tTable table- in construct (s,maxS) nTrans sigma nI nfs- where lookupState st tab = fromJust $ lookup st tab+ = let (maxS, table) = tagging (map fst tTable) s+ nI = map (`lookupState` table) initS+ nfs = map (`lookupState` table) fs+ nTrans = renameTable tTable table+ in construct (s, maxS) nTrans sigma nI nfs+ where lookupState st tab = fromJust (lookup st tab) renameTable [] _ = [] renameTable ((b,tl):tll) table = let s1 = lookupState b table- ntl = map (\(a,b1) -> (a,lookupState b1 table)) tl- in (s1,ntl):renameTable tll table+ ntl = map (\(a, b1) -> (a, lookupState b1 table)) tl+ in (s1, ntl):renameTable tll table --- | Type class Convertable+-- | Type class for conversion to/from an automaton class Convertable f where- encode :: Eq a => f a -> Automaton a- decode :: Eq a => Automaton a -> f a+ encode :: Eq a => f a -> Automaton a -- ^ From an automaton to an structure+ decode :: Eq a => Automaton a -> f a -- ^ From a structure to an Automaton -- | Display the automaton showAutomaton :: Show a => Automaton a -> String-showAutomaton auto- = "\n>>>> Automaton Construction <<<<" ++- "\n\nTransitions:\n" ++ aux (stateTrans auto) ++- "\nNumber of States => " ++ show (length (stateTrans auto)) ++- "\nInitials => " ++ show (initials auto) ++- "\nFinals => " ++ show (finals auto) ++ "\n"- where aux [] = []- aux ((s,tl):xs) = show s ++" => " ++ show tl ++ "\n" ++ aux xs+showAutomaton auto = unlines+ [ "Transitions:"+ , aux (stateTrans auto)+ , "Number of States => " ++ show (length (stateTrans auto))+ , "Initials => " ++ show (initials auto)+ , "Finals => " ++ show (finals auto)+ ]+ where+ aux tr = unlines [ show s ++ " => " ++ show tl | (s, tl) <- tr ]
FST/AutomatonInterface.hs view
@@ -1,58 +1,65 @@-{-- **************************************************************- * Filename : AutomatonInterface.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 58 *- **************************************************************+{- |+API for finite state automatons -}--module FST.AutomatonInterface ( compileNFA,- minimize,- complete,- determinize,- compile,- Automaton,--- states,--- isFinal,- initial,--- finals,--- transitionList,--- transitions,- showAutomaton,- module FST.RegTypes,- module FST.AutomatonTypes,- numberOfStates,- numberOfTransitions- ) where+module FST.AutomatonInterface (+ module FST.RegTypes,+ module FST.AutomatonTypes,+ + -- * Types+ Automaton,+ + -- * Construction of automatons+ compile,+ compileNFA,+ + -- * Transformation of automatons+ determinize,+ minimize,+ complete,+ + -- * Query inforation about automatons+ initial,+ numberOfStates,+ numberOfTransitions,+ showAutomaton,+ ) where import FST.Automaton import FST.AutomatonTypes-import qualified FST.MinimalBrzozowski as M import FST.Complete import qualified FST.Deterministic as D import qualified FST.LBFA as L-import FST.RegTypes+import FST.RegTypes hiding (reversal)+import FST.Reversal (reversal) -compileNFA :: Ord a => Reg a -> Sigma a -> State -> Automaton a-compileNFA reg sigma s = L.compileToAutomaton reg sigma s+-- | Compile a non-deterministic finite-state automaton+compileNFA :: Ord a => Reg a -> Sigma a -> StateTy -> Automaton a+compileNFA = L.compileToAutomaton +-- | Minimize an automaton using the Brzozowski algorithm. Note that+-- the determinize function must construct an automaton with the+-- usefulS property. minimize :: Ord a => Automaton a -> Automaton a-minimize automaton = M.minimize automaton+minimize = determinize . reversal . determinize . reversal+{-# SPECIALIZE minimize :: Automaton String -> Automaton String #-} +-- | Make a non-deterministic finite-state automaton deterministic determinize :: Ord a => Automaton a -> Automaton a-determinize automaton = D.determinize automaton+determinize = D.determinize -compile :: Ord a => Reg a -> Sigma a -> State -> Automaton a+-- | Compile a minimized non-deterministic finite-state automaton+compile :: Ord a => Reg a -> Sigma a -> StateTy -> Automaton a compile reg sigma s = minimize $ L.compileToAutomaton reg sigma s -initial :: Automaton a -> State+-- | Get the initial state of a finite-state automaton+initial :: Automaton a -> StateTy initial automaton = head $ initials automaton +-- | Count the number of states in a finite-state automaton numberOfStates :: Ord a => Automaton a -> Int numberOfStates auto = length $ states auto +-- | Count the number of transitions in a finite-state automaton numberOfTransitions :: Ord a => Automaton a -> Int-numberOfTransitions auto = sum [length (transitionList auto s) |- s <- states auto]+numberOfTransitions auto = sum [length (transitionList auto s)+ | s <- states auto]
FST/AutomatonTypes.hs view
@@ -1,63 +1,61 @@-{-- **************************************************************- * Filename : AutomatonTypes.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 71 *- **************************************************************+{- |+Types for Automaton -}+module FST.AutomatonTypes ( -module FST.AutomatonTypes ( State, -- State.- FirstState, -- the first state.- LastState, -- the last state.- InitialStates, -- the initial states.- FinalStates, -- set of final states.- Transitions, -- set of transitions.- TransitionTable, -- table of transitions.- Sigma, -- the alphabet of an automaton.- AutomatonFunctions, -- Type class of automaton- -- functions.- states, -- get the states of an automaton.- isFinal, -- is the given state a final state?- initials, -- get the initial states of an automaton.- finals, -- get the final states of an automaton.- transitionTable, -- get the transitionTable.- transitionList, -- get the transitions w.r.t. a state.- transitions, -- get the transitions- -- w.r.t. a state and a symbol.- firstState,- lastState, -- get the maximum state of a automaton.- alphabet -- get the alphabet of an automaton.- ) where+ -- * Types+ StateTy, FirstState, LastState, InitialStates, FinalStates, + Transitions, TransitionTable,+ Sigma, --- Types for Automaton+ -- * Type class+ AutomatonFunctions (..)+ ) where -type State = Int+-- | A state+type StateTy = Int +-- | First state type FirstState = Int +-- | Last state type LastState = Int -type InitialStates = [State]+-- | Initial states+type InitialStates = [StateTy] -type FinalStates = [State]+-- | Final states+type FinalStates = [StateTy] -type Transitions a = [(a,State)]+-- | Transitions+type Transitions a = [(a, StateTy)] -type TransitionTable a = [(State,Transitions a)]+-- | Table of transitions+type TransitionTable a = [(StateTy, Transitions a)] +-- | The alphabet of an automaton type Sigma a = [a] -- | Class of AutomatonFunctions class AutomatonFunctions f where- states :: f a -> [State]- isFinal :: f a -> State -> Bool- finals :: f a -> FinalStates- initials :: f a -> InitialStates- transitionList :: f a -> State -> Transitions a- transitionTable :: f a -> TransitionTable a- transitions :: Eq a => f a -> (State, a) -> [State]- firstState :: Eq a => f a -> State- lastState :: Eq a => f a -> State- alphabet :: f a -> Sigma a+ -- | Get the states of an automaton+ states :: f a -> [StateTy]+ -- | Is the given state a final state?+ isFinal :: f a -> StateTy -> Bool+ -- | Get the final states of an automaton+ finals :: f a -> FinalStates+ -- | Get the initial states of an automaton+ initials :: f a -> InitialStates+ -- | Get the transitions w.r.t. a state+ transitionList :: f a -> StateTy -> Transitions a+ -- | Get the transitionTable+ transitionTable :: f a -> TransitionTable a+ -- | Get the transitions w.r.t. a state and a symbol+ transitions :: Eq a => f a -> (StateTy, a) -> [StateTy]+ -- | Get the first state of a automaton+ firstState :: Eq a => f a -> StateTy+ -- | Get the last state of a automaton+ lastState :: Eq a => f a -> StateTy+ -- | Get the alphabet of an automaton+ alphabet :: f a -> Sigma a+
FST/Complete.hs view
@@ -1,28 +1,29 @@-{-- **************************************************************- * Filename : Complete.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 29 *- **************************************************************--}+{-# LANGUAGE TupleSections #-} -module FST.Complete ( complete -- Makes a automaton complete (transition on every symbol at every state)- ) where+{- |+Function for making an automaton complete (transition on every symbol at every state)+-}+module FST.Complete (+ complete+ ) where import FST.Automaton import Data.List ( (\\) ) +-- | Make a automaton complete (transition on every symbol at every state) complete :: Eq a => Automaton a -> Automaton a-complete auto = let sink = lastState auto + 1- sinkTr = (sink,map (\a -> (a,sink)) (alphabet auto))- newTrans = sinkTr:completeStates auto sink (states auto) []- in construct (firstState auto,sink) newTrans (alphabet auto) (initials auto) (finals auto)+complete auto =+ construct (firstState auto, sink) newTrans+ (alphabet auto) (initials auto)+ (finals auto) where+ sink = lastState auto + 1+ sinkTr = (sink, map (,sink) (alphabet auto))+ newTrans = sinkTr:completeStates auto sink (states auto) [] -completeStates :: Eq a => Automaton a -> State -> [State] -> [(State,Transitions a)] -> [(State,Transitions a)]-completeStates _ _ [] trans = trans-completeStates auto sink (s:sts) trans- = let tr = transitionList auto s- nTr = map (\a -> (a,sink)) ((alphabet auto) \\ (map fst tr))- in completeStates auto sink sts ((s,tr++nTr):trans)+completeStates :: Eq a => Automaton a -> StateTy -> [StateTy] -> [(StateTy,Transitions a)] -> [(StateTy,Transitions a)]+completeStates _ _ [] trans = trans+completeStates auto sink (state:states) trans+ = completeStates auto sink states ((state, tr ++ nTr):trans)+ where+ tr = transitionList auto state+ nTr = map (,sink) (alphabet auto \\ map fst tr)
FST/Deterministic.hs view
@@ -1,49 +1,42 @@-{-- **************************************************************- * Filename : Deterministic.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 78 *- **************************************************************+{- |+Function for making automatons deterministic -}--module FST.Deterministic ( determinize -- Makes an automaton deterministic and usefulS.- ) where+module FST.Deterministic (+ determinize+ ) where import FST.Automaton import Data.List (sort, nub) -{- *************************************- * Types for subsets. *- *************************************--}+-- | A subset is an ordered set without duplication+newtype SubSet = SubSet [StateTy] -newtype SubSet = SubSet [State] -- a subset is an ordered set- -- without duplication.-type SubSets = [SubSet]-type Done = SubSets-type UnDone = SubSets-type SubTransitions a = [(SubSet, [(a,SubSet)])]+-- | A list of subets+type SubSets = [SubSet] +-- | List of processed states+type Done = SubSets++-- | List of unprocessed states+type UnDone = SubSets++-- | Subset transitions+type SubTransitions a = [(SubSet, [(a, SubSet)])]+ instance Eq (SubSet) where- (SubSet xs) == (SubSet ys) = xs == ys+ SubSet xs == SubSet ys = xs == ys -sub :: [State] -> SubSet+sub :: [StateTy] -> SubSet sub sts = SubSet $ sort $ nub sts containsFinal :: Automaton a -> SubSet -> Bool-containsFinal automaton (SubSet xs) = or $ map (isFinal automaton) xs--{- ************************************************- * Construct a deterministic, usefulS automaton. *- ************************************************--}+containsFinal automaton (SubSet xs) = any (isFinal automaton) xs +-- | Make an automaton deterministic and usefulS determinize :: Ord a => Automaton a -> Automaton a-determinize automaton = let inS = sub $ initials automaton in- det automaton ([],[inS]) []+determinize automaton = let inS = sub $ initials automaton+ in det automaton ([],[inS]) [] det :: Ord a => Automaton a -> (Done,UnDone) -> SubTransitions a -> Automaton a@@ -61,10 +54,10 @@ getTransitions :: Ord a => Automaton a -> SubSet -> SubTransitions a -> (SubSets, SubTransitions a) getTransitions auto subset@(SubSet xs) trans- = let tr = groupBySymbols (concat $ map (transitionList auto) xs) [] in- (map snd tr, ((subset,tr):trans))+ = let tr = groupBySymbols (concat $ map (transitionList auto) xs) []+ in (map snd tr, (subset,tr):trans) -groupBySymbols :: Eq a => [(a,State)] -> [(a,[State])] -> [(a,SubSet)]+groupBySymbols :: Eq a => [(a,StateTy)] -> [(a,[StateTy])] -> [(a,SubSet)] groupBySymbols [] tr = map (\(a,xs) -> (a,sub xs)) tr groupBySymbols ((a,s):xs) tr = groupBySymbols xs (ins (a,s) tr) where ins (a1,s1) [] = [(a1,[s1])]
FST/DeterministicT.hs view
@@ -1,48 +1,39 @@-{-- **************************************************************- * Filename : DeterministicT.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 78 *- **************************************************************+{- |+Function for making transducers deterministic -}--module FST.DeterministicT ( determinize, -- Makes an transducer deterministic- -- and usefulS.- ) where+module FST.DeterministicT (+ determinize+ ) where import FST.Transducer import Data.List (sort, nub) +-- | A subset is an ordered set without duplication+newtype SubSet = SubSet [StateTy] -{- *************************************- * Types for subsets. *- *************************************--}+-- | A list of subets+type SubSets = [SubSet] -newtype SubSet = SubSet [State] -- a subset is an ordered set- -- without duplication.-type SubSets = [SubSet]-type Done = SubSets-type UnDone = SubSets-type SubTransitions a = [(SubSet, [(Relation a,SubSet)])]+-- | List of processed states+type Done = SubSets +-- | List of unprocessed states+type UnDone = SubSets++-- | Subset transitions+type SubTransitions a = [(SubSet, [(Relation a,SubSet)])]+ instance Eq (SubSet) where (SubSet xs) == (SubSet ys) = xs == ys -sub :: [State] -> SubSet+sub :: [StateTy] -> SubSet sub sts = SubSet $ sort $ nub sts containsFinal :: Transducer a -> SubSet -> Bool containsFinal automaton (SubSet xs) = or $ map (isFinal automaton) xs -{- ************************************************- * Construct a deterministic, usefulS automaton. *- ************************************************--}-+-- | Construct a deterministic, usefulS transducer determinize :: Ord a => Transducer a -> Transducer a determinize automaton = let inS = sub $ initials automaton in det automaton ([],[inS]) []@@ -66,7 +57,7 @@ = let tr = groupBySymbols (concat $ map (transitionList auto) xs) [] in (map snd tr, ((subset,tr):trans)) -groupBySymbols :: Eq a => [(a,State)] -> [(a,[State])] -> [(a,SubSet)]+groupBySymbols :: Eq a => [(a,StateTy)] -> [(a,[StateTy])] -> [(a,SubSet)] groupBySymbols [] tr = map (\(a,xs) -> (a,sub xs)) tr groupBySymbols ((a,s):xs) tr = groupBySymbols xs (ins (a,s) tr) where ins (a1,s1) [] = [(a1,[s1])]
FST/EpsilonFreeT.hs view
@@ -1,46 +1,40 @@-{- - ************************************************************** - * Filename : EpsilonFreeT.hs * - * Author : Markus Forsberg * - * d97forma@dtek.chalmers.se * - * Last Modified : 7 July, 2001 * - * Lines : 46 * - ************************************************************** --} - -module FST.EpsilonFreeT (epsilonfree -- construct an epsilonfree, - -- usefulS transducer. - ) where - -import FST.Transducer -import Data.List (partition) - -epsilonfree :: Eq a => Transducer a -> Transducer a -epsilonfree transducer - = epsFree transducer ([],initials transducer) [] [] - -epsFree :: Eq a => Transducer a -> ([State],[State]) -> FinalStates -> - [(State,[(Relation a,State)])] -> Transducer a -epsFree transducer (_,[]) fs table - = construct (firstState transducer, lastState transducer) - table (alphabet transducer) (initials transducer) fs -epsFree transducer (done,(s:undone)) fs table - = let (newtl,fsB) = stateEpsRemove [] (transitionList transducer s) - ([],False) - newSts = map snd $ filter (\(_,s1) -> not (elem s1 (s:done))) newtl - in epsFree transducer (s:done,newSts ++ undone) - (if (fsB || isFinal transducer s) then (s:fs) else fs) - ((s,newtl):table) - where epsTransitions = ( \ ((a,b),_) -> (a == Eps) && (b == Eps) ) - stateEpsRemove _ [] (tl,fsB) = (tl,fsB) - stateEpsRemove history tlist (tl,fsB) - = case (partition epsTransitions tlist) of - ( [],ntl) -> (tl++ntl,fsB) - (epstl,ntl) -> let newSts = map snd $ - filter (\(_,s1) -> not (elem s1 history)) - epstl - fsBnew = or $ map (isFinal transducer) newSts - in stateEpsRemove (newSts++history) - (concat (map (transitionList transducer) - newSts)) - (ntl++tl,fsB || fsBnew) +{- |+Function for constructing an epsilon-free transducer+-}+module FST.EpsilonFreeT (+ epsilonfree+ ) where++import FST.Transducer+import Data.List (partition)++-- | Construct an epsilon-free, usefulS transducer+epsilonfree :: Eq a => Transducer a -> Transducer a+epsilonfree transducer+ = epsFree transducer ([],initials transducer) [] []++epsFree :: Eq a => Transducer a -> ([StateTy],[StateTy]) -> FinalStates ->+ [(StateTy,[(Relation a,StateTy)])] -> Transducer a+epsFree transducer (_,[]) fs table+ = construct (firstState transducer, lastState transducer)+ table (alphabet transducer) (initials transducer) fs+epsFree transducer (done,(s:undone)) fs table+ = let (newtl, fsB) = stateEpsRemove [] (transitionList transducer s)+ ([], False)+ newSts = filter (`notElem` s:done) (map snd newtl)+ in epsFree transducer (s:done, newSts ++ undone)+ (if fsB || isFinal transducer s then s:fs else fs)+ ((s,newtl):table)+ where+ epsTransitions :: Eq a => ((Symbol a, Symbol a), t) -> Bool+ epsTransitions (eps, _) = eps == (Eps, Eps)+ + stateEpsRemove _ [] (tl, fsB) = (tl,fsB)+ stateEpsRemove history tlist (tl, fsB)+ = case partition epsTransitions tlist of+ ([], ntl) -> (tl ++ ntl, fsB)+ (epstl, ntl) -> let newSts = filter (`notElem` history) (map snd epstl)+ fsBnew = any (isFinal transducer) newSts+ in stateEpsRemove (newSts ++ history)+ (concatMap (transitionList transducer) newSts)+ (ntl ++ tl, fsB || fsBnew)
+ FST/FSTStudio.hs view
@@ -0,0 +1,206 @@+{-# LANGUAGE DoAndIfThenElse, FlexibleContexts, GeneralizedNewtypeDeriving #-}++{- |+fstStudio takes a program consisting of regular relations that denotes+the relation between two regular languages and constructs a+transducer. If a regular expression, not a relation, is given, then it+is interpreted as the identity relation. The syntax is very similar to+Xerox's finite state transducer syntax with two fundamental+differences: a distinction is made between functions (definitions) and+strings, and fststudio allows functional definitions.++[@\"a\"@] A symbol. Example: @[\"b\"]@ denotes the language @{\"b\"}@.++[@a@] A variable. A symbol without quotes is a variable.++[@\"a\":\"b\"@] Describes a relation between the symbol @a@ and @b@.+This relation is ordered and @a@ is said to be a part of the /upper+language/ and @b@ is said to be part of the /lower language/.+Example: @[\"a\":\"b\"]@ denotes the relation @{(\"a\",\"b\")}@.++[@0@] Epsilon symbol. The epsilon symbol denotes the string with no+symbols. Example: @[0]@ denotes the language @{\"\"}@.++[@?@] All symbol. The all symbol denotes the union of all symbols in+the alphabet. Example: @[?]@ and an alphabet @{a,b,c}@ denotes the+language @{\"a\",\"b\",\"c\"}@.++[@\"\"@] quotes cancel every special meaning of the symbols. Example:+@[\"? 0\"]@ denotes the language @{\"? 0\"}@.++[@\[A\]@] brackets are used to change the precedence of a regular+relation.++[@(A)@] parenthesis expresses optionality, and has the same meaning as+@[A|0]@.++[@A B@] Concatenation of the expressions or relations A and+B. Example: @[[a b] [c d]]@ denotes the language @{\"ac\", \"ad\", \"bc\",+\"bd\"}@++[@A^n@] Concatenation of @A@ /n/ times. @A^0@ is defined as the empty+string. Example: @[a]^3@ describes the language @{\"aaa\"}@.++[@A|B@] Union of the languages or relations @A@ and @B@. Example: @[a|b]@+describes the language @{\"a\",\"b\"}@.++[@A & B@] Intersection of the languages @A@ and @B@. Example: @[a b]+& [a]@ describes the language @{\"a\"}@.++[@A - B@] Minus of the languages @A@ and @B@, and has the same meaning as+@[A & B]@. Example: @[a b] - [a]@ describes the language @{\"b\"}@.++[@~A@] Describes the complement of an expression, and has the same+meaning as @[?* - A]@. Note that complement is always defined over+an alphabet. The expression @[A]@ is only unambiguous with respect to+an alphabet. Example: @[a]@ denotes the language that doesn't contain+the string @\"a\"@. If the alphabet is @{\"a\",\"b\"}@ then @[a]@+denotes the language @{\"\",\"b\",\"aa\",\"ba\",...}@.++[@A+@] Repetition (Kleenes plus). A concatenated with itself an+arbitrary number of times, including zero times. Example: @[a]+@ denotes+the infinite language @{\"a\",\"aa\",\"aaa\",...}@++[@A*@] Kleene’s star: @[A+ | 0]@. Example: @[a]*@ denotes the infinite+language @{\"\",\"a\",\"aa\",...}@++[@$A@] Containment. The set of strings where @A@ appear at least once+as a substring. Containment is the same thing as @[?* A ?*]@.++[@A .x. B@] Cross product of the languages @A@ and @B@. Example: @[[a b]+.x. c]@ describes the relations @{(\"a\",\"c\"), (\"b\",\"c\")}@.++[@A .o. B@] Composition of the relations @A@ and @B@. Example: @[a:b c:d]+.o. [d:e]@ describes the relation @{(\"c\",\"e\")}@.++The precedence of the operators is as follows, where 4 is the highest+precedence:++ 1. @.x.@ @.o.@++ 2. @&@ @-@++ 3. /Concatenation/++ 4. @~@ @^@ @*@ @+@ @$@++A file containing a program must end with @.fst@, and an input file+mustend with @.dat@. A program is a collection of functions defining+regular relations. A function with zero arguments is called a+definition or a macro. A definition, or a macro, can for example look+like this:++> <digits> ::= "1" | "2" | "3" | "4" | "5" |+> "6" | "7" | "8" | "9" | "0" ;++and a function can look like this:++> <swap,a,b> ::= b a ;++Note that strings are marked with quotes, and variables have no+quotes. Every program must contain a @\<main\>@ definition (a program+without one will result in a parse error).++> <main> ::= ... ;++The alphabet of a program is the symbols in the regular relation+defined in the program.++/Example program/++> <nickel> ::= ["n" .x. "c"^5];+> <dime> ::= ["d" .x. "c"^10];+> <quarter> ::= ["q" .x. "c"^25];+> <cent> ::= ["c" .x. "c"];+> <money> ::= [ <nickel> | <dime> | <quarter> | <cent>]*;+> <drink> ::= ["c"^65 .x. "PLONK"];+> <main> ::= [ <money> .o. <drink> ];++/Batch mode/++Usage: @fst FILE [Options]@. FILE must end with @.fst@, which defines+an FstStudio program, or @.net@, which defines a saved transducer. If+no options are given, then input is taken from standard input, the+transducer is applied down, and the output, if any, is produced on+standard output.++[@-u@] Apply the transducer up++[@-d@] Apply the transducer down++[@-i FILE@] Take input from FILE++[@-o FILE@] Write output to FILE++/Interactive mode - list of commands/++[@r REG@] Read a regular relation from standard input. If a regular+expression is typed, then it is interpreted as the identity relation.++[@b@] Build an epsilon-free, deterministic, minimal transducer from a+loaded/typed regular relation.++[@bn@] Build an epsilon-free, possibly non-deterministic, non-minimal+transducer from a load/typed regular relation.++[@m@] Minimize a built transducer.++[@det@] Determinize a built transducer.++[@s FILE@] Save to @FILE@. If @FILE@ ends with @.net@, then the built+transducer is saved. Any other suffix saves the produced output in the+system to @FILE@, if any.++[@l FILE@] Load from @FILE@. @FILE@ must end with @.fst@, @.net@ or+@.dat@. If @FILE@ ends with @.fst@, then a FstStudio program is loaded+into FstStudio. If @FILE@ ends with @.net@, then a transducer is loaded+into FstStudio. If @FILE@ ends with @.dat@, then input is loaded into+FstStudio.++[@l a | b@] Load and union two transducers. a and b must either be a+file ending with @.net@ or the symbol @*@, which refers to the interior+transducer. The produced transducer is possibly non-deterministic and+non-minimal.++[@l a b@] Load and concatenate two transducers. a and b must either be+ale ending with @.net@ or the symbol @*@, which refers to the interior+transducer. The produced transducer is possibly non-deterministicand+non-minimal.++[@l a*@] Load and apply Kleene’s star on a transducer. a must either+be a file ending with @.net@ or the symbol @*@, which refers to the+interior transducer. The produced transducer is possibly+non-deterministicand non-minimal.++[@l a .o. b@] Load and compose two transducers. a and b must either be+a file ending with @.net@ or the symbol @*@, which refers to the+interior transducer. The produced transducer is possibly+non-deterministic andnon-minimal.++[@vt@] View loaded/built transducer.++[@vr@] View loaded/typed regular relation.++[@vi@] View loaded input.++[@vo@] View produced output.++[@d@] Apply transducer down with loaded input.++[@u@] Apply transducer up with loaded input.++[@d SYMBOLS@] Apply tranducer down with @SYMBOLS@.++[@u SYMBOLS@] Apply transducer up with @SYMBOLS@.++[@c@] Clear memory.++[@h@] List commands.++[@q@] End session.++-}+module FST.FSTStudio where++-- This is a dummy module for the sake of documenation+
− FST/FileImport.hs
@@ -1,24 +0,0 @@-{-- **************************************************************- * Filename : FileImport.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 25 *- **************************************************************--}--module FST.FileImport (open,saveToFile) where-import System.IO.Error (try)--open :: FilePath -> IO (Either String String)-open file = do res <- try (readFile file)- case res of- Right res -> return $ Right res- Left res -> return $ Left $ "\nError:\tUnable to open \"" ++ file ++"\".\n"--saveToFile :: FilePath -> String -> IO (Either String ())-saveToFile file str = do res <- try (writeFile file str)- case res of- Right res -> return $ Right ()- Left res -> return $ Left $ "\nError:\tUnable to save to \"" ++ file ++"\".\n"
− FST/GetOpt.hs
@@ -1,154 +0,0 @@--------------------------------------------------------------------------------------------- A Haskell port of GNU's getopt library------ Sven Panne <Sven.Panne@informatik.uni-muenchen.de> Oct. 1996; last change: Jul. 1998------ Two rather obscure features are missing: The Bash 2.0 non-option hack (if you don't--- already know it, you probably don't want to hear about it...) and the recognition of--- long options with a single dash (e.g. '-help' is recognised as '--help', as long as--- there is no short option 'h').------ Other differences between GNU's getopt and this implementation:--- * To enforce a coherent description of options and arguments, there are explanation--- fields in the option/argument descriptor.--- * Error messages are now more informative, but no longer POSIX compliant... :-(------ And a final Haskell advertisement: The GNU C implementation uses well over 1100 lines,--- we need only 199 here, including a 46 line example! :-)--------------------------------------------------------------------------------------------module FST.GetOpt (- ArgOrder(..), OptDescr(..), ArgDescr(..), usageInfo, getOpt- ) where--import Data.List (isPrefixOf)--data ArgOrder a -- what to do with options following non-options:- = RequireOrder -- no option processing after first non-option- | Permute -- freely intersperse options and non-options- | ReturnInOrder (String -> a) -- wrap non-options into options--data OptDescr a = -- description of a single options:- Option [Char] -- list of short option characters- [String] -- list of long option strings (without "--")- (ArgDescr a) -- argument descriptor- String -- explanation of option for user--data ArgDescr a -- description of an argument option:- = NoArg a -- no argument expected- | ReqArg (String -> a) String -- option requires argument- | OptArg (Maybe String -> a) String -- optional argument--data OptKind a -- kind of cmd line arg (internal use only):- = Opt a -- an option- | NonOpt String -- a non-option- | EndOfOpts -- end-of-options marker (i.e. "--")- | OptErr String -- something went wrong...--usageInfo :: String -- header- -> [OptDescr a] -- option descriptors- -> String -- nicely formatted decription of options-usageInfo header optDescr = unlines (header:table)- where (ss,ls,ds) = (unzip3 . map fmtOpt) optDescr- table = zipWith3 paste (sameLen ss) (sameLen ls) (sameLen ds)- paste x y z = " " ++ x ++ " " ++ y ++ " " ++ z- sameLen xs = flushLeft ((maximum . map length) xs) xs- flushLeft n xs = [ take n (x ++ repeat ' ') | x <- xs ]--fmtOpt :: OptDescr a -> (String,String,String)-fmtOpt (Option sos los ad descr) = (sepBy ", " (map (fmtShort ad) sos),- sepBy ", " (map (fmtLong ad) los),- descr)- where sepBy _ [] = ""- sepBy _ [x] = x- sepBy sep (x:xs) = x ++ sep ++ sepBy sep xs--fmtShort :: ArgDescr a -> Char -> String-fmtShort (NoArg _ ) so = "-" ++ [so]-fmtShort (ReqArg _ ad) so = "-" ++ [so] ++ " " ++ ad-fmtShort (OptArg _ ad) so = "-" ++ [so] ++ "[" ++ ad ++ "]"--fmtLong :: ArgDescr a -> String -> String-fmtLong (NoArg _ ) lo = "--" ++ lo-fmtLong (ReqArg _ ad) lo = "--" ++ lo ++ "=" ++ ad-fmtLong (OptArg _ ad) lo = "--" ++ lo ++ "[=" ++ ad ++ "]"--getOpt :: ArgOrder a -- non-option handling- -> [OptDescr a] -- option descriptors- -> [String] -- the commandline arguments- -> ([a],[String],[String]) -- (options,non-options,error messages)-getOpt _ _ [] = ([],[],[])-getOpt ordering optDescr args = procNextOpt opt ordering- where procNextOpt (Opt o) _ = (o:os,xs,es)- procNextOpt (NonOpt x) RequireOrder = ([],x:rest,[])- procNextOpt (NonOpt x) Permute = (os,x:xs,es)- procNextOpt (NonOpt x) (ReturnInOrder f) = (f x :os, xs,es)- procNextOpt EndOfOpts RequireOrder = ([],rest,[])- procNextOpt EndOfOpts Permute = ([],rest,[])- procNextOpt EndOfOpts (ReturnInOrder f) = (map f rest,[],[])- procNextOpt (OptErr e) _ = (os,xs,e:es)-- (opt,rest) = getNext args optDescr- (os,xs,es) = getOpt ordering optDescr rest---- take a look at the next cmd line arg and decide what to do with it-getNext :: [String] -> [OptDescr a] -> (OptKind a,[String])-getNext (('-':'-':[]):rest) _ = (EndOfOpts,rest)-getNext (('-':'-':xs):rest) optDescr = longOpt xs rest optDescr-getNext (('-':x:xs) :rest) optDescr = shortOpt x xs rest optDescr-getNext (a :rest) _ = (NonOpt a,rest)-getNext [] _ = error "getNext: impossible"---- handle long option-longOpt :: String -> [String] -> [OptDescr a] -> (OptKind a,[String])-longOpt xs rest optDescr = long ads arg rest- where (opt,arg) = break (=='=') xs- options = [ o | o@(Option _ ls _ _) <- optDescr, l <- ls, opt `isPrefixOf` l ]- ads = [ ad | Option _ _ ad _ <- options ]- optStr = ("--"++opt)-- long (_:_:_) _ rest1 = (errAmbig options optStr,rest1)- long [NoArg a ] [] rest1 = (Opt a,rest1)- long [NoArg _ ] ('=':_) rest1 = (errNoArg optStr,rest1)- long [ReqArg _ d] [] [] = (errReq d optStr,[])- long [ReqArg f _] [] (r:rest1) = (Opt (f r),rest1)- long [ReqArg f _] ('=':ys) rest1 = (Opt (f ys),rest1)- long [OptArg f _] [] rest1 = (Opt (f Nothing),rest1)- long [OptArg f _] ('=':ys) rest1 = (Opt (f (Just ys)),rest1)- long [_] (_ :_) _ = error "long: impossible"- long [] _ rest1 = (errUnrec optStr,rest1)---- handle short option-shortOpt :: Char -> String -> [String] -> [OptDescr a] -> (OptKind a,[String])-shortOpt x xs rest optDescr = short ads xs rest- where options = [ o | o@(Option ss _ _ _) <- optDescr, s <- ss, x == s ]- ads = [ ad | Option _ _ ad _ <- options ]- optStr = '-':[x]-- short (_:_:_) _ rest1 = (errAmbig options optStr,rest1)- short (NoArg a :_) [] rest1 = (Opt a,rest1)- short (NoArg a :_) ys rest1 = (Opt a,('-':ys):rest1)- short (ReqArg _ d:_) [] [] = (errReq d optStr,[])- short (ReqArg f _:_) [] (r:rest1) = (Opt (f r),rest1)- short (ReqArg f _:_) ys rest1 = (Opt (f ys),rest1)- short (OptArg f _:_) [] rest1 = (Opt (f Nothing),rest1)- short (OptArg f _:_) ys rest1 = (Opt (f (Just ys)),rest1)- short [] [] rest1 = (errUnrec optStr,rest1)- short [] ys rest1 = (errUnrec optStr,('-':ys):rest1)---- miscellaneous error formatting--errAmbig :: [OptDescr a] -> String -> OptKind a-errAmbig ods optStr = OptErr (usageInfo header ods)- where header = "option `" ++ optStr ++ "' is ambiguous; could be one of:"--errReq :: String -> String -> OptKind a-errReq d optStr = OptErr ("option `" ++ optStr ++ "' requires an argument " ++ d ++ "\n")--errUnrec :: String -> OptKind a-errUnrec optStr = OptErr ("unrecognized option `" ++ optStr ++ "'\n")--errNoArg :: String -> OptKind a-errNoArg optStr = OptErr ("option `" ++ optStr ++ "' doesn't allow an argument\n")--
FST/Info.hs view
@@ -1,122 +1,72 @@-{-- **************************************************************- * Filename : Info.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 89 *- **************************************************************+{- |+State data structure for the interactive shell -}- module FST.Info where import FST.TransducerInterface +-- | State in interactive shell data Info = Info {- transducer :: (Transducer String,Bool),- expression :: (RReg String,Bool),- input :: ([String],Bool),- outputs :: ([String],Bool)- }--clearInfo :: Info -> Info-clearInfo info = info { transducer = (emptyTransducer,False),- expression = (empty,False),- input = ([],False),- outputs = ([],False) }+ transducer :: (Transducer String, Bool),+ expression :: (RReg String, Bool),+ input :: ([String], Bool),+ outputs :: ([String], Bool)+ } deriving (Show) +-- | Empty information emptyInfo :: Info emptyInfo = Info {- transducer = (emptyTransducer,False),- expression = (empty,False),- input = ([],False),- outputs = ([],False)- }+ transducer = (emptyTransducer, False),+ expression = (empty, False),+ input = ([], False),+ outputs = ([], False)+ } +-- | Is there a built transducer in the state? transducerBuilt :: Info -> Bool-transducerBuilt info = snd $ transducer info+transducerBuilt = snd . transducer +-- | Is there a read expression in the state? expressionRead :: Info -> Bool-expressionRead info = snd $ expression info+expressionRead = snd . expression +-- | Is there an input in the state? inputRead :: Info -> Bool-inputRead info = snd $ input info+inputRead = snd . input +-- | Is there an output in the state? outputsRead :: Info -> Bool-outputsRead info = snd $ outputs info+outputsRead = snd . outputs +-- | Set transducer in state updateTransducer :: Transducer String -> Info -> Info-updateTransducer t info = info {transducer = (t,True)}+updateTransducer t info = info { transducer = (t, True) } +-- | Set expression in state updateExpression :: RReg String -> Info -> Info-updateExpression r info = info {expression = (r,True)}+updateExpression r info = info { expression = (r, True) } +-- | Set input in state updateInput :: [String] -> Info -> Info-updateInput inp info = info {input = (inp,True)}+updateInput inp info = info { input = (inp, True) } +-- | Set outputs in state updateOutputs :: [String] -> Info -> Info-updateOutputs out info = info { outputs = (out,True)}+updateOutputs out info = info { outputs = (out, True) } +-- | Get transducer from state getTransducer :: Info -> Transducer String-getTransducer = fst.transducer+getTransducer = fst . transducer +-- | Get expression from state getExpression :: Info -> RReg String-getExpression = fst.expression+getExpression = fst . expression +-- | Get input from state getInput :: Info -> [String]-getInput = fst.input+getInput = fst . input +-- | Get outputs from state getOutputs :: Info -> [String]-getOutputs = fst.outputs--noTransducer :: IO ()-noTransducer = do putStrLn "No transducer has been loaded/built."--noExpression :: IO ()-noExpression = do putStrLn "No regular expression has been typed/loaded into fstStudio."--noInput :: IO ()-noInput = do putStrLn "No input has been loaded into fstStudio."--noOutputs :: IO ()-noOutputs = do putStrLn "No outputs has been produced."--help :: IO ()-help = do putStrLn "\nList of Commands:"- putStrLn "r <reg exp> : read a regular relation from standard input."- putStrLn "b : build a deterministic, minimal transducer."- putStrLn "bn : build a possibly non-deterministic, non-minimal transducer."- putStrLn "m : minimize loaded/built transducer."- putStrLn "det : determinize loaded/built transducer."- putStrLn "s <filename> : save to file."- putStrLn "l <filename> : load from file."- putStrLn "l a | b : load and union."- putStrLn "l a b : load and concatenate."- putStrLn "l a * : load and apply Kleene's star."- putStrLn "l a .o. b : load and compose."- putStrLn "vt : view loaded/built transducer."- putStrLn "vr : view typed/loaded regular relation."- putStrLn "vi : view loaded input."- putStrLn "vo : view produced output."- putStrLn "d : apply transducer down with loaded input."- putStrLn "u : apply transducer up with loaded input."- putStrLn "d <symbols> : apply transducer down with symbols."- putStrLn "u <symbols> : apply transducer up with symbols."- putStrLn "c : Clear memory."- putStrLn "h : display list of commands."- putStrLn "q : end session.\n"--prompt :: IO ()-prompt = do putStr ">"+getOutputs = fst . outputs -fstStudio :: IO ()-fstStudio = do putStrLn "\n*****************************************************"- putStrLn "* Welcome to Finite State Transducer Studio! *"- putStrLn "* Written purely in Haskell. *"- putStrLn "* Version : 0.9 *"- putStrLn "* Date : 11 August 2001 *"- putStrLn "* Author : Markus Forsberg *"- putStrLn "* Please send bug reports/suggestions to: *"- putStrLn "* d97forma@dtek.chalmers.se *"- putStrLn "*****************************************************\n"- putStrLn "Type 'h' for help.\n"
FST/LBFA.hs view
@@ -1,30 +1,21 @@-{-- **************************************************************- * Filename : LBFA.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 7 July, 2001 *- * Lines : 279 *- **************************************************************+{- |+Left-biased finite automata -}+module FST.LBFA (+ module FST.Automaton, -module FST.LBFA ( module FST.Automaton,- LBFA, -- Data type for LBFA--- states, -- get the states of a LBFA--- finals, -- get the final states of a LBFA--- isFinal, -- check if a state is a final state.--- transitionTable,--- transitionList, -- get the transitions of a state.--- transitions, -- get the transitions of a state and a symbol--- alphabet, -- get the alphabet of a LBFA.- initial, -- get the initial state of a LBFA.--- lastState, -- get the max state of a LBFA.- compileToLBFA,- compileToAutomaton- ) where+ -- * Types+ LBFA, + -- * Functions on LBFA+ initial,+ compileToLBFA,+ compileToAutomaton+ ) where++import Control.Monad.State + import FST.RegTypes-import FST.StateMonad import FST.Automaton import FST.Deterministic import FST.Complete@@ -32,234 +23,216 @@ import Data.List (delete,nub,(\\)) -{- **********************************************************- * data type for a LBFA *- **********************************************************--}-+-- | Data type for LBFA (left-biased finite automata) data LBFA a = LBFA {- trans :: [(State, Transitions a)],- initS :: State,- finalS :: [State],- alpha :: Sigma a,- lastS :: State- }--{- **********************************************************- * LBFA functions *- **********************************************************--}+ trans :: [(StateTy, Transitions a)],+ initS :: StateTy,+ finalS :: [StateTy],+ alpha :: Sigma a,+ lastS :: StateTy+ } instance AutomatonFunctions LBFA where- states lbfa = map fst $ trans lbfa- isFinal lbfa s = elem s (finals lbfa)- initials lbfa = [(initS lbfa)]- finals = finalS- transitionTable = trans- transitionList lbfa s = case(lookup s (trans lbfa)) of- Just tl -> tl- _ -> []- transitions lbfa (s,a) = map snd $ filter (\(b,_) -> a == b) $ transitionList lbfa s- firstState = minimum.states- lastState = lastS- alphabet = alpha+ -- | Get the states of a LBFA+ states lbfa = map fst (trans lbfa)+ -- | Check if a state is a final state.+ isFinal lbfa s = elem s (finals lbfa)+ -- | Get the initial states of a LBFA+ initials lbfa = [(initS lbfa)]+ -- | Get the final states of a LBFA+ finals = finalS+ -- | Get the transition table+ transitionTable = trans+ -- | Get the transitions of a state+ transitionList lbfa s = case lookup s (trans lbfa) of+ Just tl -> tl+ _ -> []+ -- | Get the transitions of a state and a symbol+ transitions lbfa (s, a) = [ st | (b, st) <- transitionList lbfa s, a == b ]+ -- |+ firstState = minimum . states+ -- | Get the max state of a LBFA+ lastState = lastS+ -- | Get the alphabet of a LBFA+ alphabet = alpha -initial :: LBFA a -> State-initial lbfa = (initS lbfa)+-- | Get the initial state of a LBFA+initial :: LBFA a -> StateTy+initial = initS +-- | Does the LBFA accept epsilon? acceptEpsilon :: LBFA a -> Bool acceptEpsilon lbfa = isFinal lbfa (initial lbfa) -{- **********************************************************- * compile a regular expression to a LBFA *- **********************************************************--}--compileToLBFA :: Ord a => Reg a -> Sigma a -> State -> LBFA a-compileToLBFA reg sigma s = run (build reg (nub (sigma++symbols reg))) s--{- ************************************************************************- * compile a regular expression to an minimal, useful and deterministic *- * Automaton, using the LBFA algorithm while building. *- ************************************************************************--}-compileToAutomaton :: Ord a => Reg a -> Sigma a -> State -> Automaton a-compileToAutomaton reg sigma s = encode $ compileToLBFA reg sigma s--{- ************************************************************************- * Building a LBFA from a regular expression *- ************************************************************************--}--build :: Ord a => Reg a -> Sigma a -> STM (LBFA a)-build (Empty) sigma = do s <- fetchState- return $ LBFA {- trans = [(s,[])],- initS = s,- finalS = [],- alpha = sigma,- lastS = s- }+-- | Compile a regular expression to a LBFA+compileToLBFA :: Ord a => Reg a -> Sigma a -> StateTy -> LBFA a+compileToLBFA reg sigma = evalState $ build reg $ nub $ sigma ++ symbols reg -build (Epsilon) sigma = do s <- fetchState- return $ LBFA {- trans = [(s,[])],- initS = s,- finalS = [s],- alpha = sigma,- lastS = s- }+-- | Compile a regular expression to an minimal, useful and+-- deterministic automaton, using the LBFA algorithm while building.+compileToAutomaton :: Ord a => Reg a -> Sigma a -> StateTy -> Automaton a+compileToAutomaton reg sigma s = encode (compileToLBFA reg sigma s) -build (Symbol a) sigma = do s1 <- fetchState- s2 <- fetchState- return $ LBFA {- trans = [(s1,[(a,s2)]),(s2,[])],- initS = s1,- finalS = [s2],- alpha = sigma,- lastS = s2- }+fetchState :: State StateTy StateTy+fetchState = do+ state <- get+ put (state + 1)+ return state -build (All) sigma = build (allToSymbols sigma) sigma+-- | Build a LBFA from a regular expression+build :: Ord a => Reg a -> Sigma a -> State StateTy (LBFA a)+build Empty sigma = do+ s <- fetchState+ return $ LBFA {+ trans = [(s, [])],+ initS = s,+ finalS = [],+ alpha = sigma,+ lastS = s+ }+ +build Epsilon sigma = do+ s <- fetchState+ return LBFA {+ trans = [(s, [])],+ initS = s,+ finalS = [s],+ alpha = sigma,+ lastS = s+ } -build (r1 :.: r2) sigma- = do lbfa1 <- build r1 sigma- lbfa2 <- build r2 sigma- s <- fetchState- let transUnion = (remove (initial lbfa1) (trans lbfa1)) ++- (remove (initial lbfa2) (trans lbfa2))- transConc = let t = (transitionList lbfa2 (initial lbfa2)) in- [(f,t)| f <- (finals lbfa1)]- transInit = [(s, transitionList lbfa1 (initial lbfa1) ++- listEps lbfa1 (transitionList lbfa2 (initial lbfa2)))]- fs = finals lbfa2 ++ listEps lbfa2 (finals lbfa1) ++- if (acceptEpsilon lbfa1 && acceptEpsilon lbfa2)- then [s] else []- return $ LBFA {- trans = transInit ++ merge transConc transUnion,- finalS = fs \\ [(initial lbfa1),(initial lbfa2)],- alpha = sigma,- initS = s,- lastS = s- }+build (Symbol a) sigma = do+ s1 <- fetchState+ s2 <- fetchState+ return LBFA {+ trans = [(s1, [(a, s2)]), (s2, [])],+ initS = s1,+ finalS = [s2],+ alpha = sigma,+ lastS = s2+ } -build (r1 :|: r2) sigma- = do lbfa1 <- build r1 sigma- lbfa2 <- build r2 sigma- s <- fetchState- let transUnion = (remove (initial lbfa1) (trans lbfa1)) ++- (remove (initial lbfa2) (trans lbfa2))- transInit = [(s, transitionList lbfa1 (initial lbfa1) ++- transitionList lbfa2 (initial lbfa2))]- fs = finals lbfa1 ++ finals lbfa2 ++- if (acceptEpsilon lbfa1 || acceptEpsilon lbfa2)- then [s] else []- return $ LBFA {- trans = transInit ++ transUnion,- finalS = fs \\ [(initial lbfa1),(initial lbfa2)],- alpha = sigma,- initS = s,- lastS = s- }+build All sigma = build (allToSymbols sigma) sigma+build (r1 :.: r2) sigma = do+ lbfa1 <- build r1 sigma+ lbfa2 <- build r2 sigma+ s <- fetchState+ let transUnion = (remove (initial lbfa1) (trans lbfa1)) +++ (remove (initial lbfa2) (trans lbfa2))+ transConc = let t = transitionList lbfa2 (initial lbfa2) in+ [ (f,t) | f <- finals lbfa1 ]+ transInit = [(s, transitionList lbfa1 (initial lbfa1) +++ listEps lbfa1 (transitionList lbfa2 (initial lbfa2)))]+ fs = finals lbfa2 ++ listEps lbfa2 (finals lbfa1) +++ [ s | acceptEpsilon lbfa1 && acceptEpsilon lbfa2 ]+ return $ LBFA {+ trans = transInit ++ merge transConc transUnion,+ finalS = fs \\ [(initial lbfa1), (initial lbfa2)],+ alpha = sigma,+ initS = s,+ lastS = s+ } -build (Star r1) sigma- = do lbfa1 <- build r1 sigma- s <- fetchState- let transUnion = remove (initial lbfa1) (trans lbfa1)- transLoop = let t = transitionList lbfa1 (initial lbfa1) in- (s,t): [(f,t) | f <- finals lbfa1]- return $ LBFA {- trans = merge transLoop transUnion,- finalS = (s:(delete (initial lbfa1) (finals lbfa1))),- alpha = sigma,- initS = s,- lastS = s- }+build (r1 :|: r2) sigma = do+ lbfa1 <- build r1 sigma+ lbfa2 <- build r2 sigma+ s <- fetchState+ let transUnion = (remove (initial lbfa1) (trans lbfa1)) +++ (remove (initial lbfa2) (trans lbfa2))+ transInit = [(s, transitionList lbfa1 (initial lbfa1) +++ transitionList lbfa2 (initial lbfa2))]+ fs = finals lbfa1 ++ finals lbfa2 +++ [ s | acceptEpsilon lbfa1 || acceptEpsilon lbfa2 ]+ return $ LBFA {+ trans = transInit ++ transUnion,+ finalS = fs \\ [(initial lbfa1),(initial lbfa2)],+ alpha = sigma,+ initS = s,+ lastS = s+ } -build (Complement r1) sigma- = do lbfa <- build r1 sigma- let lbfa1 = decode $ determinize $ complete $ encode lbfa- setState $ lastState lbfa1 +1- return $ LBFA {- trans = trans lbfa1,- finalS = (states lbfa1) \\ (finals lbfa1),- alpha = sigma,- initS = initial lbfa1,- lastS = lastState lbfa1- }+build (Star r1) sigma = do+ lbfa1 <- build r1 sigma+ s <- fetchState+ let transUnion = remove (initial lbfa1) (trans lbfa1)+ transLoop = let t = transitionList lbfa1 (initial lbfa1)+ in (s,t) : [ (f,t) | f <- finals lbfa1 ]+ return $ LBFA {+ trans = merge transLoop transUnion,+ finalS = s:(delete (initial lbfa1) (finals lbfa1)),+ alpha = sigma,+ initS = s,+ lastS = s+ } -build (r1 :&: r2) sigma- = do lbfa1 <- build r1 sigma- lbfa2 <- build r2 sigma- let minS1 = firstState lbfa1- minS2 = firstState lbfa2- name (s1,s2) = (lastState lbfa2 - minS2 +1) *- (s1 - minS1) + s2 - minS2 + minS1- nS = name (lastState lbfa1,lastState lbfa2) +1- transInit = (nS,[(a,name (s1,s2)) | (a,s1) <- transitionList- lbfa1 (initial lbfa1),- (b,s2) <- transitionList- lbfa2 (initial lbfa2),- a == b])- transTable = [(name (s1,s2),[(a,name (s3,s4)) | (a,s3) <- tl1,- (b,s4) <- tl2,- a == b ]) |- (s1,tl1) <- trans lbfa1,- (s2,tl2) <- trans lbfa2,- s1 /= initial lbfa1 ||- s2 /= initial lbfa2- ]- transUnion = transInit:transTable- fs = (if (acceptEpsilon lbfa1 && acceptEpsilon lbfa2)- then [nS] else []) ++- [name (f1,f2)| f1 <- finals lbfa1,- f2 <- finals lbfa2]- setState $ nS +1- return LBFA {- trans = merge [(s,[]) | s <- fs] transUnion,- finalS = fs,- alpha = sigma,- initS = nS,- lastS = nS- }+build (Complement r1) sigma = do+ lbfa <- build r1 sigma+ let lbfa1 = decode $ determinize $ complete $ encode lbfa+ put (lastState lbfa1 + 1)+ return $ LBFA {+ trans = trans lbfa1,+ finalS = states lbfa1 \\ finals lbfa1,+ alpha = sigma,+ initS = initial lbfa1,+ lastS = lastState lbfa1+ } -{- **********************************************************- * Instance of Convertable (LBFA a) *- **********************************************************--}+build (r1 :&: r2) sigma = do+ lbfa1 <- build r1 sigma+ lbfa2 <- build r2 sigma+ let minS1 = firstState lbfa1+ minS2 = firstState lbfa2+ name (s1,s2) = (lastState lbfa2 - minS2 +1) *+ (s1 - minS1) + s2 - minS2 + minS1+ nS = name (lastState lbfa1,lastState lbfa2) +1+ transInit = (nS, [ (a, name (s1, s2))+ | (a,s1) <- transitionList+ lbfa1 (initial lbfa1)+ , (b,s2) <- transitionList+ lbfa2 (initial lbfa2)+ , a == b])+ transTable = [(name (s1, s2),+ [(a, name (s3, s4))+ | (a,s3) <- tl1+ , (b,s4) <- tl2, a == b ])+ | (s1,tl1) <- trans lbfa1+ , (s2,tl2) <- trans lbfa2+ , s1 /= initial lbfa1 || s2 /= initial lbfa2 ]+ transUnion = transInit:transTable+ fs = [ nS | acceptEpsilon lbfa1 && acceptEpsilon lbfa2 ]+ ++ + [ name (f1,f2) | f1 <- finals lbfa1, f2 <- finals lbfa2 ]+ put (nS + 1)+ return LBFA {+ trans = merge [ (s, []) | s <- fs ] transUnion,+ finalS = fs,+ alpha = sigma,+ initS = nS,+ lastS = nS+ } instance Convertable LBFA where- encode lbfa = construct (firstState lbfa,lastState lbfa) (trans lbfa)- (alphabet lbfa) (initials lbfa) (finals lbfa)- decode auto = LBFA {- trans = transitionTable auto,- initS = head (initials auto),- finalS = finals auto,- alpha = alphabet auto,- lastS = lastState auto- }--{- **********************************************************- * Instance of Show (LBFA a) *- **********************************************************--}+ encode lbfa = construct (firstState lbfa,lastState lbfa) (trans lbfa)+ (alphabet lbfa) (initials lbfa) (finals lbfa)+ decode auto = LBFA {+ trans = transitionTable auto,+ initS = head (initials auto),+ finalS = finals auto,+ alpha = alphabet auto,+ lastS = lastState auto+ } instance (Eq a,Show a) => Show (LBFA a) where- show auto = "\n>>>> LBFA Construction <<<<" ++- "\n\nTransitions:\n" ++ aux (trans auto) ++- "\nNumber of States => " ++ show countStates ++- "\nInitial => " ++ show (initial auto) ++- "\nFinals => " ++ show (finals auto) ++ "\n"- where aux [] = []- aux ((s,tl):xs) = show s ++" => " ++ show tl ++ "\n" ++ aux xs- countStates = length $ nub $ map fst (trans auto) ++- finals auto--{- **********************************************************- * Auxiliary functions *- **********************************************************--}+ show auto = unlines [+ "Transitions:", aux (trans auto),+ "Number of States => " ++ show countStates,+ "Initial => " ++ show (initial auto),+ "Finals => " ++ show (finals auto)+ ] where+ aux xs = unlines [show s ++" => " ++ show tl | (s, tl) <- xs ]+ countStates = length $ nub $ map fst (trans auto) ++ finals auto +-- | If the LBFA accepts epsilon, return second argument listEps :: LBFA a -> [b] -> [b] listEps lbfa xs | acceptEpsilon lbfa = xs
FST/LBFT.hs view
@@ -1,188 +1,175 @@-{-- **************************************************************- * Filename : LBFT.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 7 July, 2001 *- * Lines : 277 *- **************************************************************+{- |+Left-biased finite transducers -}+module FST.LBFT (+ module FST.Transducer, -module FST.LBFT ( LBFT (..),- module FST.Transducer,- compileToLBFT,- compileToTransducer- ) where+ -- * Types+ LBFT (..), + -- * Compile functions+ compileToLBFT,+ compileToTransducer+ ) where+ import Data.List (delete,nub,(\\))+import Control.Monad.State + import FST.EpsilonFreeT import FST.RRegTypes-import FST.StateMonad import FST.Transducer import FST.Utils (merge,remove) import qualified FST.AutomatonInterface as A -{- **********************************************************- * data type for a LBFT *- **********************************************************--}-+-- | Data type for a LBFT (left-biased finite transducer) data LBFT a = LBFT { trans :: TTransitionTable a,- initS :: State,- finalS :: [State],+ initS :: StateTy,+ finalS :: [StateTy], alpha :: Sigma a,- lastS :: State+ lastS :: StateTy } -{- **********************************************************- * LBFT functions *- **********************************************************--}-+-- | LBFT functions instance TransducerFunctions LBFT where- states = (map fst).trans- isFinal t s = elem s (finals t)- initials t = [initS t]- finals = finalS- transitionTable = trans- transitionList t s = case (lookup s (trans t)) of- Just xs -> xs- _ -> []- transitionsU t (s,a) = map (\((_,c),s1) -> (c,s1)) $- filter (\((b,_),_) -> a == b) $ transitionList t s- transitionsD t (s,a) = map (\((c,_),s1) -> (c,s1)) $- filter (\((_,b),_) -> a == b) $ transitionList t s- lastState = lastS- firstState = minimum.states- alphabet = alpha+ states = (map fst).trans+ isFinal t s = elem s (finals t)+ initials t = [initS t]+ finals = finalS+ transitionTable = trans+ transitionList t s = case (lookup s (trans t)) of+ Just xs -> xs+ _ -> []+ transitionsU t (s,a) = map (\((_,c),s1) -> (c,s1)) $+ filter (\((b,_),_) -> a == b) $ transitionList t s+ transitionsD t (s,a) = map (\((c,_),s1) -> (c,s1)) $+ filter (\((_,b),_) -> a == b) $ transitionList t s+ lastState = lastS+ firstState = minimum.states+ alphabet = alpha +-- | Does the LBFT accept epsilon? acceptEpsilon :: LBFT a -> Bool acceptEpsilon lbft = isFinal lbft (initialLBFT lbft) -initialLBFT :: LBFT a -> State+-- | Get the initial state of a LBFT+initialLBFT :: LBFT a -> StateTy initialLBFT = initS -{- **********************************************************- * compile a regular relation to a LBFT *- **********************************************************--}-+-- | Compile a regular relation to a LBFT compileToLBFT :: Ord a => RReg a -> Sigma a -> LBFT a-compileToLBFT reg sigma = run (build reg (nub (sigma++symbols reg))) 0+compileToLBFT reg sigma = evalState (build reg (nub (sigma++symbols reg))) 0 -{- ************************************************************************- * compile a regular relation to an minimal, useful and deterministic *- * transducer, using the LBFT algorithm while building. *- ************************************************************************--}+-- | Compile a regular relation to an minimal, useful and+-- deterministic transducer, using the LBFT algorithm while building. compileToTransducer :: Ord a => RReg a -> Sigma a -> Transducer a compileToTransducer reg sigma = encode $ compileToLBFT reg sigma -{- ************************************************************************- * Building a LBFT from a regular relation *- ************************************************************************--}--build :: Ord a => RReg a -> Sigma a -> STM (LBFT a)-build (EmptyR) sigma = do s <- fetchState- return $ LBFT {- trans = [(s,[])],- initS = s,- finalS = [],- alpha = sigma,- lastS = s- }+fetchState :: State StateTy StateTy+fetchState = do+ state <- get+ put (state + 1)+ return state -build (Relation a b) sigma- = do s1 <- fetchState- s2 <- fetchState- return $ LBFT {- trans = [(s1,[((a,b),s2)]),(s2,[])],- initS = s1,- finalS = [s2],- alpha = sigma,- lastS = s2- }+-- | Build a LBFT from a regular relation+build :: Ord a => RReg a -> Sigma a -> State StateTy (LBFT a)+build (EmptyR) sigma = do+ s <- fetchState+ return $ LBFT {+ trans = [(s, [])],+ initS = s,+ finalS = [],+ alpha = sigma,+ lastS = s+ } -build (Identity r1) sigma- = do s <- fetchState- let auto = A.compileNFA r1 sigma s- nTrans = [(s1,map (\(a,s2) -> ((S a, S a),s2))- (A.transitionList auto s1)) | s1 <- A.states auto]- setState (A.lastState auto+1)- return $ LBFT {- trans = nTrans,- initS = head (A.initials auto),- finalS = A.finals auto,- alpha = sigma,- lastS = A.lastState auto- }+build (Relation a b) sigma = do+ s1 <- fetchState+ s2 <- fetchState+ return $ LBFT {+ trans = [(s1, [((a, b), s2)]), (s2, [])],+ initS = s1,+ finalS = [s2],+ alpha = sigma,+ lastS = s2+ } -build (ProductR r1 r2) sigma- = do lbft1 <- build r1 sigma- lbft2 <- build r2 sigma- s <- fetchState- let transUnion = (remove (initialLBFT lbft1) (trans lbft1)) ++- (remove (initialLBFT lbft2) (trans lbft2))- transConc = let t = (transitionList lbft2 (initialLBFT lbft2)) in- [(f,t)| f <- (finals lbft1)]- transInit = [(s, transitionList lbft1 (initialLBFT lbft1) ++- listEps lbft1 (transitionList lbft2 (initialLBFT lbft2)))]- fs = finals lbft2 ++ listEps lbft2 (finals lbft1) ++- if (acceptEpsilon lbft1 && acceptEpsilon lbft2)- then [s] else []- return $ LBFT {- trans = transInit ++ merge transConc transUnion,- finalS = fs \\ [(initialLBFT lbft1),(initialLBFT lbft2)],- alpha = sigma,- initS = s,- lastS = s- }+build (Identity r1) sigma = do+ s <- fetchState+ let auto = A.compileNFA r1 sigma s+ nTrans = [(s1, map (\(a,s2) -> ((S a, S a), s2)) (A.transitionList auto s1))+ | s1 <- A.states auto ]+ put (A.lastState auto + 1)+ return $ LBFT {+ trans = nTrans,+ initS = head (A.initials auto),+ finalS = A.finals auto,+ alpha = sigma,+ lastS = A.lastState auto+ } -build (UnionR r1 r2) sigma- = do lbft1 <- build r1 sigma- lbft2 <- build r2 sigma- s <- fetchState- let transUnion = (remove (initialLBFT lbft1) (trans lbft1)) ++- (remove (initialLBFT lbft2) (trans lbft2))- transInit = [(s, transitionList lbft1 (initialLBFT lbft1) ++- transitionList lbft2 (initialLBFT lbft2))]- fs = finals lbft1 ++ finals lbft2 ++- if (acceptEpsilon lbft1 || acceptEpsilon lbft2)- then [s] else []- return $ LBFT {- trans = transInit ++ transUnion,- finalS = fs \\ [(initialLBFT lbft1),(initialLBFT lbft2)],- alpha = sigma,- initS = s,- lastS = s- }+build (ProductR r1 r2) sigma = do+ lbft1 <- build r1 sigma+ lbft2 <- build r2 sigma+ s <- fetchState+ let transUnion = (remove (initialLBFT lbft1) (trans lbft1)) +++ (remove (initialLBFT lbft2) (trans lbft2))+ transConc = let t = (transitionList lbft2 (initialLBFT lbft2))+ in [ (f,t) | f <- finals lbft1 ]+ transInit = [(s, transitionList lbft1 (initialLBFT lbft1) +++ listEps lbft1 (transitionList lbft2 (initialLBFT lbft2)))]+ fs = finals lbft2 ++ listEps lbft2 (finals lbft1) +++ [ s | acceptEpsilon lbft1 && acceptEpsilon lbft2 ]+ return $ LBFT {+ trans = transInit ++ merge transConc transUnion,+ finalS = fs \\ [(initialLBFT lbft1),(initialLBFT lbft2)],+ alpha = sigma,+ initS = s,+ lastS = s+ }+ +build (UnionR r1 r2) sigma = do+ lbft1 <- build r1 sigma+ lbft2 <- build r2 sigma+ s <- fetchState+ let transUnion = (remove (initialLBFT lbft1) (trans lbft1)) +++ (remove (initialLBFT lbft2) (trans lbft2))+ transInit = [(s, transitionList lbft1 (initialLBFT lbft1) +++ transitionList lbft2 (initialLBFT lbft2))]+ fs = finals lbft1 ++ finals lbft2 +++ [ s | acceptEpsilon lbft1 || acceptEpsilon lbft2 ]+ return $ LBFT {+ trans = transInit ++ transUnion,+ finalS = fs \\ [(initialLBFT lbft1), (initialLBFT lbft2)],+ alpha = sigma,+ initS = s,+ lastS = s+ } -build (StarR r1) sigma- = do lbft1 <- build r1 sigma- s <- fetchState- let transUnion = remove (initialLBFT lbft1) (trans lbft1)- transLoop = let t = transitionList lbft1 (initialLBFT lbft1) in- (s,t): [(f,t) | f <- finals lbft1]- return $ LBFT {- trans = merge transLoop transUnion,- finalS = (s:(delete (initialLBFT lbft1) (finals lbft1))),- alpha = sigma,- initS = s,- lastS = s- }+build (StarR r1) sigma = do+ lbft1 <- build r1 sigma+ s <- fetchState+ let transUnion = remove (initialLBFT lbft1) (trans lbft1)+ transLoop = let t = transitionList lbft1 (initialLBFT lbft1)+ in (s,t) : [(f,t) | f <- finals lbft1]+ return $ LBFT {+ trans = merge transLoop transUnion,+ finalS = s:(delete (initialLBFT lbft1) (finals lbft1)),+ alpha = sigma,+ initS = s,+ lastS = s+ } -build (Cross r1 r2) sigma =- do s <- fetchState- let auto1 = A.compileNFA r1 sigma s- auto2 = A.compileNFA r2 sigma s- (trTable,fs) = cross auto1 auto2+build (Cross r1 r2) sigma = do+ s <- fetchState+ let auto1 = A.compileNFA r1 sigma s+ auto2 = A.compileNFA r2 sigma s+ (trTable,fs) = cross auto1 auto2 ([],[(A.initial auto1,A.initial auto2)]) ([],[])- lbft = decode $ rename trTable sigma- [(A.initial auto1,A.initial auto2)] fs s- setState $ lastState lbft + 1- return lbft+ lbft = decode $ rename trTable sigma+ [(A.initial auto1,A.initial auto2)] fs s+ put (lastState lbft + 1)+ return lbft where cross _ _ (_,[]) result = result cross auto1 auto2 (done,((s1,s2):undone)) (tr,fs) = let tl = combine auto1 auto2 (A.transitionList auto1 s1)@@ -201,75 +188,62 @@ (if (A.isFinal auto2 s2) then [((S a,Eps),(s3,s2)) | (a,s3) <- xs] else []) -build (Comp r1 r2) sigma- = do lbft1 <- build r1 sigma- lbft2 <- build r2 sigma- let minS1 = firstState lbft1- minS2 = firstState lbft2- name (s1,s2) = (lastState lbft2 - minS2 +1) *- (s1 - minS1) + s2 - minS2 + minS1- nS = name (lastState lbft1,lastState lbft2) +1- transInit = (nS,[((a,d),name (s1,s2)) |- ((a,b),s1) <- ((Eps,Eps),initialLBFT lbft1):transitionList- lbft1 (initialLBFT lbft1),- ((c,d),s2) <- ((Eps,Eps),initialLBFT lbft2):transitionList- lbft2 (initialLBFT lbft2),- ((a,b) /= (Eps,Eps)) || ((c,d) /= (Eps,Eps)),- b == c])- transTable = [(name (s1,s2),[((a,d),name (s3,s4)) | ((a,b),s3) <- ((Eps,Eps),s1):tl1,- ((c,d),s4) <- ((Eps,Eps),s2):tl2,- ((a,b) /= (Eps,Eps)) || ((c,d) /= (Eps,Eps)),- b == c]) |- (s1,tl1) <- trans lbft1,- (s2,tl2) <- trans lbft2,- s1 /= initialLBFT lbft1 ||- s2 /= initialLBFT lbft2]- transUnion = transInit : transTable- fs = (if (acceptEpsilon lbft1 && acceptEpsilon lbft2)- then [nS] else []) ++- [name (f1,f2)| f1 <- finals lbft1, f2 <- finals lbft2]- setState $ nS +1- return $ decode $ epsilonfree $ encode $- LBFT {trans = merge [(s,[]) | s <- fs] transUnion- ,finalS = fs,alpha = sigma,- initS = nS,lastS = nS}--{- **********************************************************- * Instance of Convertable (LBFT a) *- **********************************************************--}+build (Comp r1 r2) sigma = do+ lbft1 <- build r1 sigma+ lbft2 <- build r2 sigma+ let minS1 = firstState lbft1+ minS2 = firstState lbft2+ name (s1,s2) = (lastState lbft2 - minS2 +1) *+ (s1 - minS1) + s2 - minS2 + minS1+ nS = name (lastState lbft1,lastState lbft2) +1+ transInit = (nS,[ ((a, d), name (s1,s2))+ | ((a, b), s1) <- ((Eps, Eps),initialLBFT lbft1):transitionList lbft1 (initialLBFT lbft1)+ , ((c, d), s2) <- ((Eps,Eps),initialLBFT lbft2):transitionList lbft2 (initialLBFT lbft2)+ , ((a,b) /= (Eps,Eps)) || ((c,d) /= (Eps,Eps)), b == c])+ transTable = [(name (s1,s2),[ ((a, d), name (s3,s4))+ | ((a, b), s3) <- ((Eps,Eps),s1):tl1+ , ((c,d),s4) <- ((Eps,Eps),s2):tl2+ , ((a,b) /= (Eps,Eps)) || ((c,d) /= (Eps,Eps))+ , b == c])+ | (s1,tl1) <- trans lbft1+ , (s2,tl2) <- trans lbft2+ , s1 /= initialLBFT lbft1 || s2 /= initialLBFT lbft2]+ transUnion = transInit : transTable+ fs = [ nS | acceptEpsilon lbft1 && acceptEpsilon lbft2 ]+ ++ + [ name (f1,f2) | f1 <- finals lbft1, f2 <- finals lbft2 ]+ put (nS + 1)+ return $ decode $ epsilonfree $ encode $+ LBFT {+ trans = merge [ (s, []) | s <- fs ] transUnion,+ finalS = fs,+ alpha = sigma,+ initS = nS,+ lastS = nS+ } instance TConvertable LBFT where- encode lbft = rename (trans lbft) (alphabet lbft) (initials lbft)- (finals lbft) (firstState lbft)- decode t = LBFT {- trans = transitionTable t,- initS = head (initials t),- finalS = finals t,- alpha = alphabet t,- lastS = lastState t- }--{- **********************************************************- * Instance of Show (LBFT a) *- **********************************************************--}+ encode lbft = rename (trans lbft) (alphabet lbft) (initials lbft)+ (finals lbft) (firstState lbft)+ decode t = LBFT {+ trans = transitionTable t,+ initS = head (initials t),+ finalS = finals t,+ alpha = alphabet t,+ lastS = lastState t+ } instance (Eq a,Show a) => Show (LBFT a) where- show t = "\n>>>> LBFT Construction <<<<" ++- "\n\nTransitions:\n" ++ aux (trans t) ++- "\nNumber of States => " ++ show (length (trans t)) ++- "\nInitial => " ++ show (initialLBFT t) ++- "\nFinals => " ++ show (finals t) ++ "\n"- where aux [] = []- aux ((s,tl):xs) = show s ++" => " ++ show tl ++ "\n" ++ aux xs---{- **********************************************************- * Auxiliary functions *- **********************************************************--}+ show t = unlines [+ "Transitions:"+ , aux (trans t)+ , "Number of States => " ++ show (length (trans t))+ , "Initial => " ++ show (initialLBFT t)+ , "Finals => " ++ show (finals t)+ ] where+ aux xs = unlines [ show s ++ " => " ++ show tl | (s, tl) <- xs ] +-- | If the LBFT accepts epsilon, return second argument listEps :: LBFT a -> [b] -> [b] listEps lbft xs | acceptEpsilon lbft = xs
FST/Lexer.hs view
@@ -1,3 +1,6 @@+{- |+Lexer file generated by Alex+-} module FST.Lexer where @@ -121,7 +124,39 @@ TokenDef Int | -- '::=' TokenVar (Int,String) | -- Variable Err String- deriving (Eq,Show)+ deriving (Eq)+ +instance Show Token where+ show = prettyPrint+ +-- | Pretty print, for more helpful parse error messages+prettyPrint :: Token -> String+prettyPrint (TokenSemi _) = ";"+prettyPrint (TokenHOB _) = "["+prettyPrint (TokenHCB _) = "]"+prettyPrint (TokenSOB _) = "("+prettyPrint (TokenSCB _) = ")"+prettyPrint (TokenConcatS (_,str)) = "{"++str++"}"+prettyPrint (TokenStar _) = "*"+prettyPrint (TokenComplement _) = "~"+prettyPrint (TokenContainment _) = "$"+prettyPrint (TokenMinus _) = "-"+prettyPrint (TokenIntersect _) = "&"+prettyPrint (TokenUnion _) = "|"+prettyPrint (TokenPlus _) = "+"+prettyPrint (TokenEps _) = "0"+prettyPrint (TokenAll _) = "?"+prettyPrint (TokenS (_,str)) = str+prettyPrint (TokenRelation _) = ":"+prettyPrint (TokenCrossproduct _) = ".x."+prettyPrint (TokenComposition _) = ".o."+prettyPrint (TokenRepeat _) = "^"+prettyPrint (TokenNum (_,int)) = show int+prettyPrint (TokenFun (_,(name,args))) = "<"++name++(concatMap ((++) ",") args)++">"+prettyPrint (TokenMain _) = "<main>"+prettyPrint (TokenDef _) = "::="+prettyPrint (TokenVar (_,str)) = str+prettyPrint (Err str) = str lexer :: String -> [Token] lexer inp = scan tokens_scan inp
− FST/Main.hs
@@ -1,346 +0,0 @@-{-- **************************************************************- * Filename : Main.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 346 *- **************************************************************--}--module Main where--import FST.TransducerInterface-import FST.FileImport-import FST.RRegTypes-import System.Environment (getArgs)--import FST.Arguments-import FST.Info--main :: IO()-main = do args <- getArgs- case args of- [] -> do fstStudio- run emptyInfo- as -> batchMode as--batchMode :: [String] -> IO ()-batchMode cmdopt = case parseBatch cmdopt of- Left err -> putStrLn err- Right (file,cmd)- | isFST file -> do res <- open file- case res of- Right str -> case (parseProgram str) of- Left err -> putStrLn err- Right reg- | isUpB cmd -> let tr = compile reg [] in- case inputB cmd of- Just file -> do res <- open file- case res of- Right str -> case outputB cmd of- Just f -> do res <- saveToFile f str- case res of- Left err -> putStrLn err- _ -> return ()- _ -> putStrLn $ upB tr str- Left err -> putStrLn err- Nothing -> do interact (upB tr)- | otherwise -> let tr = compile reg [] in- case inputB cmd of- Just file -> do res <- open file- case res of- Right str -> case outputB cmd of- Just f -> do res <- saveToFile f str- case res of- Left err -> putStrLn err- _ -> return ()- _ -> putStrLn $ downB tr str- Left err -> putStrLn err- Nothing -> do interact (downB tr)- Left err -> do putStrLn err- | isNET file -> do tr <- load file- case tr of- Right tr- | isUpB cmd -> case inputB cmd of- Just file -> do res <- open file- case res of- Right str -> case outputB cmd of- Just f -> do res <- saveToFile f str- case res of- Left err -> putStrLn err- _ -> return ()- _ -> putStrLn $ upB tr str- Left err -> putStrLn err- Nothing -> do interact (upB tr)- | otherwise -> case inputB cmd of- Just file -> do res <- open file- case res of- Right str -> case outputB cmd of- Just f -> do res <- saveToFile f str- case res of- Left err -> putStrLn err- _ -> return ()- _ -> putStrLn $ downB tr str- Left err -> putStrLn err- Nothing -> do interact (downB tr)- Left err -> putStrLn err- | otherwise -> putStrLn "Input file must end with *.fst or *.net"--upB :: Transducer String -> String -> String-upB transducer str = case (applyUp transducer (words str)) of- Just xs -> unlines $ map unwords xs- Nothing -> []--downB :: Transducer String -> String -> String-downB transducer str = case (applyDown transducer (words str)) of- Just xs -> unlines $ map unwords xs- Nothing -> []--run :: Info -> IO ()-run info- = do prompt- com <- getLine- case (parseInteractive (words com)) of- BuildTransducer- | expressionRead info ->- do let tNew = compile (getExpression info) []- putStrLn ("\nBuilt a deterministic, minimal transducer with "- ++ (show (numberOfStates tNew)) ++ " states and "- ++ (show (numberOfTransitions tNew)) ++ " transitions.\n")- run $ updateTransducer tNew info- | otherwise ->- do noExpression- run info- BuildNTransducer- | expressionRead info ->- do let tNew = compileN (getExpression info) []- putStrLn ("\nBuilt a possibly non-deterministic, non-minimal transducer with "- ++ (show (numberOfStates tNew)) ++ " states and "- ++ (show (numberOfTransitions tNew)) ++ " transitions.\n")- run $ updateTransducer tNew info- | otherwise ->- do noExpression- run info- Minimize- | transducerBuilt info ->- do let tNew = minimize (getTransducer info)- putStrLn ("\nMinimized loaded/built transducer resulting in a transducer with "- ++ (show (numberOfStates tNew)) ++ " states and "- ++ (show (numberOfTransitions tNew)) ++ " transitions.\n")- run $ updateTransducer tNew info- | otherwise ->- do noTransducer- run info- Determinize- | transducerBuilt info ->- do let tNew = determinize (getTransducer info)- putStrLn ("\nDeterminized loaded/built transducer resulting in a transducer with "- ++ (show (numberOfStates tNew)) ++ " states and "- ++ (show (numberOfTransitions tNew)) ++ " transitions.\n")- run $ updateTransducer tNew info- | otherwise ->- do noTransducer- run info- ViewTransducer- | transducerBuilt info ->- do putStrLn (showTransducer (getTransducer info))- run info- | otherwise ->- do noTransducer- run info- Load file- | isFST file -> do res <- open file- case (res) of- Right str -> case (parseProgram str) of- Left err -> do putStrLn err- run info- Right reg -> do putStrLn ("\nLoaded a regular relation from " ++file ++".\n")- run $ updateExpression reg info- Left err -> do putStrLn err- run info- | isNET file -> do res <- load file- case res of- Right t -> do putStrLn ("\nLoaded transducer from file " ++ file ++".\n")- run $ updateTransducer t info- Left err -> do putStrLn err- run info- | isDAT file -> do res <- open file- case (res) of- Right str -> do putStrLn ("\nRead input from file "++file++".\n")- run $ updateInput (words str) info- Left err -> do putStrLn err- run info- | otherwise -> do putStrLn ("\nUnable to load from " ++ file ++ ". The filename must end with *.fst, *.net or *.dat.\n")- run info- LUnion file1 file2- | isNET file1 && isNET file2 -> do res1 <- load file1- res2 <- load file2- case (res1,res2) of- (Left err,_) -> do putStrLn err- run info- (_,Left err) -> do putStrLn err- run info- (Right t1, Right t2) -> do putStrLn "\nLoaded and unified two transducers.\n"- run $ updateTransducer (unionT t1 t2) info- | transducerBuilt info && isNET file1 && isTHIS file2- -> do res <- load file1- case res of- (Left err) -> do putStrLn err- run info- (Right t1) -> do putStrLn "\nLoaded a transducer, and unified it with the interior transducer.\n"- run $ updateTransducer (unionT t1 (getTransducer info)) info- | transducerBuilt info && isTHIS file1 && isNET file2- -> do res <- load file2- case res of- (Left err) -> do putStrLn err- run info- (Right t1) -> do putStrLn "\nLoaded a transducer, and unified it with the interior transducer.\n"- run $ updateTransducer (unionT t1 (getTransducer info)) info- | otherwise -> do putStrLn $ "\nUnable to union " ++ file1 ++ " and " ++file2++".\n"- run info- LProduct file1 file2- | isNET file1 && isNET file2 -> do res1 <- load file1- res2 <- load file2- case (res1,res2) of- (Left err,_) -> do putStrLn err- run info- (_,Left err) -> do putStrLn err- run info- (Right t1, Right t2) -> do putStrLn "\nLoaded and concatenated two transducers.\n"- run $ updateTransducer (productT t1 t2) info- | transducerBuilt info && isNET file1 && isTHIS file2- -> do res <- load file1- case res of- (Left err) -> do putStrLn err- run info- (Right t1) -> do putStrLn "\nLoaded a transducer, and concatenated it with the interior transducer.\n"- run $ updateTransducer (productT t1 (getTransducer info)) info- | transducerBuilt info && isTHIS file1 && isNET file2- -> do res <- load file2- case res of- (Left err) -> do putStrLn err- run info- (Right t1) -> do putStrLn "\nLoaded a transducer, and concatenated it with the interior transducer.\n"- run $ updateTransducer (productT t1 (getTransducer info)) info- | otherwise -> do putStrLn $ "\nUnable to concatenate " ++ file1 ++ " and " ++file2++".\n"- run info- LStar file- | isNET file -> do res <- load file- case res of- (Left err) -> do putStrLn err- run info- (Right t1) -> do putStrLn "\nLoaded a transducer, and applied Kleene's star.\n"- run $ updateTransducer (starT t1) info- | transducerBuilt info && isTHIS file -> do putStrLn "\nApplied Kleene's star on interior transducer.\n"- run $ updateTransducer (starT (getTransducer info)) info- | otherwise -> do putStrLn $ "\nUnable to apply Kleene's star on " ++ file ++ ".\n"- run info- LComposition file1 file2- | isNET file1 && isNET file2 -> do res1 <- load file1- res2 <- load file2- case (res1,res2) of- (Left err,_) -> do putStrLn err- run info- (_,Left err) -> do putStrLn err- run info- (Right t1, Right t2) -> do putStrLn "\nLoaded and composed two transducers.\n"- run $ updateTransducer (compositionT t1 t2) info- | transducerBuilt info && isNET file1 && isTHIS file2- -> do res <- load file1- case res of- (Left err) -> do putStrLn err- run info- (Right t1) -> do putStrLn "\nLoaded a transducer, and composed it with the interior transducer.\n"- run $ updateTransducer (compositionT t1 (getTransducer info)) info- | transducerBuilt info && isTHIS file1 && isNET file2- -> do res <- load file2- case res of- (Left err) -> do putStrLn err- run info- (Right t1) -> do putStrLn "\nLoaded a transducer, and composed it with the interior transducer.\n"- run $ updateTransducer (compositionT t1 (getTransducer info)) info- | otherwise -> do putStrLn $ "\nUnable to compose " ++ file1 ++ " and " ++file2++".\n"- run info- Save file- | isNET file -> do res <- save file (getTransducer info)- case res of- Right t -> do putStrLn ("\nSaved transducer to file "++file++".\n")- run info- Left err -> do putStrLn err- run info- | outputsRead info -> do res <- saveToFile file (unlines (getOutputs info))- case res of- Right _ -> do putStrLn ("\nSaved outputs to file " ++ file ++".\n")- run info- Left err -> do putStrLn err- run info- | otherwise -> do noOutputs- run info- StdInReg str -> case (parseExp str) of- Left err -> do putStrLn err- run info- Right reg -> do putStrLn "\nRead a regular relation.\n"- run $ updateExpression reg info- ViewReg- | expressionRead info -> do putStrLn ("\nExpression:\n" ++ (show (getExpression info)) ++ "\n")- run info- | otherwise -> do noExpression- run info- Quit -> do putStr "\nDo you really want to quit? (y): "- s <- getLine- case s of- "y" -> putStrLn "\nSession ended.\n"- "Y" -> putStrLn "\nSession ended.\n"- _ -> run info- ClearMemory -> do run $ clearInfo info- NoCommand -> do putStrLn "\nInvalid Command. Type 'h' for help.\n"- run info- ViewInput- | inputRead info -> do putStrLn ("\nInput: \n" ++ (unwords (getInput info)))- run info- | otherwise -> do noInput- run info- ViewOutput- | outputsRead info -> do putStrLn ("\nOutputs : \n" ++ (unlines (getOutputs info)))- run info- | otherwise -> do noOutputs- run info- Help -> do help- run info- ApplyUp- | transducerBuilt info && inputRead info -> case (applyUp (getTransducer info) (getInput info)) of- Just res -> do putStrLn "\nInput accepted. Type 'vo' to view outputs.\n"- run (updateOutputs (map unwords res) info)- Nothing -> do putStrLn "\nInput rejected.\n"- run info- | transducerBuilt info -> do noTransducer- run info- | otherwise -> do noInput- run info- ApplyDown- | transducerBuilt info && inputRead info -> case (applyDown (getTransducer info) (getInput info)) of- Just res -> do putStrLn "\nInput accepted. Type 'vo' to view outputs.\n"- run (updateOutputs (map unwords res) info)- Nothing -> do putStrLn "\nInput rejected.\n"- run info- | transducerBuilt info -> do noTransducer- run info- | otherwise -> do noInput- run info- ApplyU inp- | transducerBuilt info -> case (applyUp (getTransducer info) inp) of- Just res -> do putStrLn "\nInput accepted. Type 'vo' to view outputs.\n"- run (updateOutputs (map unwords res) info)- Nothing -> do putStrLn "\nInput rejected.\n"- run info- | otherwise -> do noTransducer- run info- ApplyD inp- | transducerBuilt info -> case (applyDown (getTransducer info) inp) of- Just res -> do putStrLn "\nInput accepted. Type 'vo' to view outputs.\n"- run (updateOutputs (map unwords res) info)- Nothing -> do putStrLn "\nInput rejected.\n"- run info- | otherwise -> do noTransducer- run info
− FST/MinimalBrzozowski.hs
@@ -1,23 +0,0 @@-{-- **************************************************************- * Filename : MinimalBrzozowski.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 7 July, 2001 *- * Lines : 20 *- **************************************************************--}--module FST.MinimalBrzozowski ( minimize -- minimize an automaton.- ) where--import FST.Automaton-import FST.Reversal-import FST.Deterministic--{- An algorithm due to Brzozowski.- Note that the determinize function must construct a- automaton with the usefulS property. -}-{-# SPECIALIZE minimize :: Automaton String -> Automaton String #-}-minimize :: Ord a => Automaton a -> Automaton a-minimize = determinize.reversal.determinize.reversal
− FST/MinimalTBrzozowski.hs
@@ -1,23 +0,0 @@-{-- **************************************************************- * Filename : MinimalTBrzozowski.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 7 July, 2001 *- * Lines : 20 *- **************************************************************--}--module FST.MinimalTBrzozowski ( minimize -- minimize an automaton.- ) where--import FST.Transducer-import FST.DeterministicT-import FST.ReversalT--{- An algorithm due to Brzozowski -}--{-# SPECIALIZE minimize :: Transducer String -> Transducer String #-}--minimize :: Ord a => Transducer a -> Transducer a-minimize = determinize.reversal.determinize.reversal
FST/NReg.hs view
@@ -1,83 +1,72 @@-{-- **************************************************************- * Filename : NReg.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 5 July, 2001 *- * Lines : 78 *- **************************************************************+{- |+Neutral regular expressions -}+module FST.NReg (+ -- * Types+ NReg(..), -module FST.NReg ( NReg(..), -- Neutral Regular expression.- toRReg, -- If possible, converts NReg to RReg- toReg, -- If possible, converts NReg to Reg- nVarToSymbol- ) where+ -- * Conversion functions+ toRReg,+ toReg,+ nVarToSymbol+ ) where +import Control.Monad import FST.RegTypes import FST.RRegTypes -{- *******************************************- * Datatype for neutral regular expression *- *******************************************--}--data NReg a = NCross (NReg a) (NReg a) |- NComp (NReg a) (NReg a) |- NUnion (NReg a) (NReg a) |- NProduct (NReg a) (NReg a) |- NStar (NReg a) |- NIntersect (NReg a) (NReg a) |- NComplement (NReg a) |- NSymbol a |- NRelation a a |- NEpsilon |- NEmptySet |- NVar String |- Fun String [NReg a] |- NAll--{- **************************************- * Convert functions toRReg and toReg *- **************************************--}---- If possible, build a regular expression instead of a--- regular relation.+-- | Neutral regular expressions+data NReg a = NCross (NReg a) (NReg a)+ | NComp (NReg a) (NReg a)+ | NUnion (NReg a) (NReg a)+ | NProduct (NReg a) (NReg a)+ | NIntersect (NReg a) (NReg a)+ | NStar (NReg a)+ | NComplement (NReg a)+ | NSymbol a+ | NRelation a a+ | NEpsilon+ | NEmptySet+ | NVar String+ | Fun String [NReg a]+ | NAll +-- | If possible, build a regular expression instead of a regular relation toRReg :: Eq a => NReg a -> Maybe (RReg a)-toRReg reg = maybe (nRReg reg) (return.idR) (toReg reg)- where nRReg (NEmptySet) = return EmptyR- nRReg (NRelation a b) = return $ r a b- nRReg (NComp n1 n2) = do r1 <- toRReg n1; r2 <- toRReg n2; return $ r1 <.> r2- nRReg (NCross n1 n2) = do r1 <- toReg n1; r2 <- toReg n2; return $ r1 <*> r2- nRReg (NUnion n1 n2) = case (toRReg n1,toRReg n2) of- (Just r1,Just r2) -> return $ r1 <|> r2- _ -> do r1 <- toReg n1; r2 <- toReg n2- return $ idR $ r1 <|> r2- nRReg (NProduct n1 n2) = case (toRReg n1,toRReg n2) of- (Just r1,Just r2) -> return $ r1 |> r2- _ -> do r1 <- toReg n1;r2 <- toReg n2; return $ idR $ r1 |> r2- nRReg (NStar n1) = case (toRReg n1) of- (Just r1) -> return $ star r1- _ -> do r1 <- toReg n1; return $ idR $ star r1- nRReg (NIntersect n1 n2) = do r1 <- toReg n1; r2 <- toReg n2- return $ idR $ r1 <&> r2- nRReg (NComplement n1) = do r1 <- toReg n1; return $ idR $ complement r1- nRReg _ = Nothing+toRReg reg = maybe (nRReg reg) (return . idR) (toReg reg)+ where+ nRReg :: Eq a => NReg a -> Maybe (RReg a)+ nRReg NEmptySet = Just EmptyR+ nRReg (NRelation a b) = Just (r a b)+ nRReg (NComp n1 n2) = liftM2 (<.>) (toRReg n1) (toRReg n2)+ nRReg (NCross n1 n2) = liftM2 (<*>) (toReg n1) (toReg n2)+ nRReg (NUnion n1 n2) = case (toRReg n1, toRReg n2) of+ (Just r1, Just r2) -> Just (r1 <|> r2)+ _ -> fmap idR $ liftM2 (<|>) (toReg n1) (toReg n2)+ nRReg (NProduct n1 n2) = case (toRReg n1, toRReg n2) of+ (Just r1,Just r2) -> Just (r1 |> r2)+ _ -> fmap idR $ liftM2 (|>) (toReg n1) (toReg n2)+ nRReg (NStar n1) = case toRReg n1 of+ Just r1 -> Just (star r1)+ _ -> liftM (idR . star) (toReg n1)+ nRReg (NIntersect n1 n2) = fmap idR $ liftM2 (<&>) (toReg n1) (toReg n2)+ nRReg (NComplement n1) = fmap (idR . complement) (toReg n1)+ nRReg _ = Nothing +-- | If possible, converts NReg to Reg toReg :: Eq a => NReg a -> Maybe (Reg a)-toReg (NEmptySet) = return empty-toReg (NEpsilon) = return eps-toReg (NSymbol a) = return $ s a-toReg (NAll) = return allS-toReg (NUnion n1 n2) = do r1 <- toReg n1; r2 <- toReg n2; return $ r1 <|> r2-toReg (NProduct n1 n2) = do r1 <- toReg n1; r2 <- toReg n2; return $ r1 |> r2-toReg (NStar n1) = do r1 <- toReg n1; return $ star r1-toReg (NIntersect n1 n2) = do r1 <- toReg n1; r2 <- toReg n2; return $ r1 <&> r2-toReg (NComplement n1) = do r1 <- toReg n1; return $ complement r1+toReg NEmptySet = return empty+toReg NEpsilon = return eps+toReg NAll = return allS+toReg (NSymbol a) = return (s a)+toReg (NStar n1) = liftM star (toReg n1)+toReg (NComplement n1) = liftM complement (toReg n1)+toReg (NUnion n1 n2) = liftM2 (<|>) (toReg n1) (toReg n2)+toReg (NIntersect n1 n2) = liftM2 (<&>) (toReg n1) (toReg n2)+toReg (NProduct n1 n2) = liftM2 (|>) (toReg n1) (toReg n2) toReg _ = Nothing +-- | Convert variables to symbols nVarToSymbol :: NReg String -> NReg String nVarToSymbol (NCross n1 n2) = NCross (nVarToSymbol n1) (nVarToSymbol n2) nVarToSymbol (NComp n1 n2) = NComp (nVarToSymbol n1) (nVarToSymbol n2)
FST/Parse.hs view
@@ -1,5 +1,6 @@--- parser produced by Happy Version 1.10-+{- |+Parser produced by Happy Version 1.10+-} module FST.Parse where import FST.NReg@@ -467,7 +468,7 @@ happyReduction_6 ((HappyTerminal (TokenFun happy_var_1)) `HappyStk` happyRest) = happyThen ( case (parseList (snd $ snd happy_var_1) []) of- FailE str -> failE $ "\nfstStudio failed to parse.\nParse error at line: "++ show (fst happy_var_1) ++"\n"+ FailE str -> failE $ "Parse failure: parse error at line "++ show (fst happy_var_1) Ok list -> returnE $ Fun (fst $ snd happy_var_1) list ) (\r -> happyReturn (HappyAbsSyn7 r)) @@ -675,7 +676,36 @@ parseNReg tks = happyThen (happyParse action_1 tks) (\x -> case x of {HappyAbsSyn7 z -> happyReturn z; _other -> notHappyAtAll }) happyError :: [Token] -> E a-happyError _ = failE $ "\nfstStudio failed to parse.\n No useful message can be printed.\n"+happyError [] = failE $ "Parse failure"+happyError (t:_) = failE $ "Parse failure at symbol '"++ show t ++"' on line " ++ show (getLineNo t)+ where+ getLineNo :: Token -> Int+ getLineNo (TokenSemi l) = l+ getLineNo (TokenHOB l) = l+ getLineNo (TokenHCB l) = l+ getLineNo (TokenSOB l) = l+ getLineNo (TokenSCB l) = l+ getLineNo (TokenConcatS (l,_)) = l+ getLineNo (TokenStar l) = l+ getLineNo (TokenComplement l) = l+ getLineNo (TokenContainment l) = l+ getLineNo (TokenMinus l) = l+ getLineNo (TokenIntersect l) = l+ getLineNo (TokenUnion l) = l+ getLineNo (TokenPlus l) = l+ getLineNo (TokenEps l) = l+ getLineNo (TokenAll l) = l+ getLineNo (TokenS (l,_)) = l+ getLineNo (TokenRelation l) = l+ getLineNo (TokenCrossproduct l) = l+ getLineNo (TokenComposition l) = l+ getLineNo (TokenRepeat l) = l+ getLineNo (TokenNum (l,_)) = l+ getLineNo (TokenFun (l,_)) = l+ getLineNo (TokenMain l) = l+ getLineNo (TokenDef l) = l+ getLineNo (TokenVar (l,_)) = l+ getLineNo (Err str) = 0 data E a = Ok a | FailE String@@ -702,7 +732,7 @@ FailE str -> FailE str functional (FailE str) = FailE str -getMain [] = failE "\nfstStudio failed to parse.\nNo main function exists.\n"+getMain [] = failE "Parse failure: no main function exists." getMain ((Main n1):xs) = Ok n1 getMain (_:xs) = getMain xs @@ -717,7 +747,7 @@ apply (Fun str ns) env = do applyFun (str,ns) env env apply n1 _ = returnE n1 -applyFun (str,_) [] _ = failE $ "\nfstStudio failed to parse.\nFound a unidentified function: " ++ str ++ "\n"+applyFun (str,_) [] _ = failE $ "Parse failure: unidentified function: " ++ str applyFun (str,ns) ((Function name vars n1):xs) env | str == name = do res <- (replace n1 (zip vars ns)) apply res env@@ -734,7 +764,7 @@ replace (NComplement n1) env = do liftM NComplement (replace n1 env) replace (NVar str) env = case (lookup str env) of Just n1 -> returnE n1- Nothing -> failE $ "\nfstStudio failed to parse.\nFound a unidentified variable: " ++ str ++"\n"+ Nothing -> failE $ "Parse failure: unidentified variable: " ++ str replace n1 env = returnE n1 parseList :: [String] -> [NReg String] -> E ([NReg String])@@ -743,19 +773,21 @@ FailE str -> FailE str Ok n1 -> parseList list (n1:res) +-- | Parse a regular expression from a string parseExp :: String -> Either String (RReg String) parseExp str = case ((parseNReg.lexer) str) of- FailE str -> Left "\nfstStudio failed to parse given expression.\n"+ FailE str -> Left $ "Failed to parse expression: " ++ str Ok n1 -> case (toRReg (nVarToSymbol n1)) of Just rreg -> Right rreg- Nothing -> Left "\nfstStudio failed to parse given expression.\n"+ Nothing -> Left $ "Failed to parse expression: " ++ str +-- | Parse a program from a string parseProgram :: String -> Either String (RReg String) parseProgram str = case ((functional.parse.lexer) str) of FailE str -> Left str Ok n1 -> case (toRReg n1) of Just rreg -> Right rreg- Nothing -> Left "\nfstStudio failed to parse.\nNo main function exists.\n"+ Nothing -> Left "Parse failure." {-# LINE 1 "GenericTemplate.hs" -} {-# LINE 1 "GenericTemplate.hs" -} -- $Id: GenericTemplate.hs,v 1.11 2001/03/30 14:24:07 simonmar Exp $
FST/RRegTypes.hs view
@@ -1,113 +1,89 @@-{-- **************************************************************- * Filename : RRegTypes.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 5 July, 2001 *- * Lines : 113 *- **************************************************************+{- |+Functions for constructing a simplified regular relation. -}--module FST.RRegTypes ( module FST.RegTypes,- RReg(..), -- data type for regular relations.--- (<|>), -- union combinator for regular relations.--- (|>), -- product combinator for regular relations.--- star, -- Kleene's star for regular relations.--- plus, -- Kleene's plus for regular relations.--- empty, -- The empty set of regular relations.- (<*>), -- Cross product opertor.- (<.>), -- Composition operator.- idR, -- Identity relation.- r, -- Relation.--- symbols -- Collect the symbols in a regular relations.- ) where+module FST.RRegTypes ( + module FST.RegTypes,+ -- * Types+ RReg(..),+ -- * Combinators+ (<*>), (<.>),+ -- * Constructors+ idR, r,+ ) where import FST.RegTypes import FST.TransducerTypes (Symbol(..)) -import Data.List(nub)+import Data.List (nub) -{- *************************************- * Datatype for a regular relations *- *************************************--}+-- | Datatype for a regular relations+data RReg a =+ Cross (Reg a) (Reg a) -- ^ Cross product + | Comp (RReg a) (RReg a) -- ^ Composition + | ProductR (RReg a) (RReg a) -- ^ Concatenation + | UnionR (RReg a) (RReg a) -- ^ Union + | StarR (RReg a) -- ^ Kleene star + | Identity (Reg a) -- ^ Identity relation + | Relation (Symbol a) (Symbol a) -- ^ (a:b) + | EmptyR -- ^ Empty language + deriving (Eq) -data RReg a- = Cross (Reg a) (Reg a) -- ^ Cross product - | Comp (RReg a) (RReg a) -- ^ Composition - | ProductR (RReg a) (RReg a) -- ^ Concatenation - | UnionR (RReg a) (RReg a) -- ^ Union - | StarR (RReg a) -- ^ Kleene star - | Identity (Reg a) -- ^ Identity relation - | Relation (Symbol a) (Symbol a) -- ^ (a:b) - | EmptyR -- ^ Empty language - deriving (Eq)+instance Eq a => Combinators (RReg a) where+ -- Union+ EmptyR <|> r2 = r2 -- [ r1 | [] ] = r1+ r1 <|> EmptyR = r1 -- [ [] | r2 ] = r2+ r1 <|> r2 = if r1 == r2 then r1 else UnionR r1 r2 -- [ r1 | r1 ] = r1 -{- *************************************- * Instance of Combinators (RReg a) *- *************************************--}+ -- Concatenation+ EmptyR |> _ = EmptyR -- [ [] r2 ] = []+ _ |> EmptyR = EmptyR -- [ r1 [] ] = []+ r1 |> r2 = ProductR r1 r2 -instance Eq a => Combinators (RReg a) where- EmptyR <|> r2 = r2 -- [ r1 | [] ] = r1- r1 <|> EmptyR = r1 -- [ [] | r2 ] = r2- r1 <|> r2- | r1 == r2 = r1 -- [ r1 | r1 ] = r1- | otherwise = UnionR r1 r2- EmptyR |> _ = EmptyR -- [ [] r2 ] = []- _ |> EmptyR = EmptyR -- [ r1 [] ] = []- r1 |> r2 = ProductR r1 r2- star (StarR r1) = star r1 -- [ r1* ]* = r1*- star r1 = StarR r1- plus r1 = r1 |> star r1- empty = EmptyR+ -- Kleene's star+ star (StarR r1) = star r1 -- [ r1* ]* = r1*+ star r1 = StarR r1 + -- Kleene's plus+ plus r1 = r1 |> star r1+ empty = EmptyR+ infixl 2 <*> infixl 1 <.> --- Cross product operator.+-- | Cross product operator (<*>) :: Eq a => Reg a -> Reg a -> RReg a (<*>) = Cross --- Composition operator+-- | Composition operator (<.>) :: Eq a => RReg a -> RReg a -> RReg a (<.>) = Comp --- Identity relation.+-- | Identity relation idR :: Eq a => Reg a -> RReg a idR = Identity +-- | Relation r :: Eq a => a -> a -> RReg a r a b = Relation (S a) (S b) -{- *************************************- * Instance of Symbols (RReg a) *- *************************************--}- instance Symbols RReg where- symbols (Cross r1 r2) = nub $ symbols r1 ++ symbols r2- symbols (Comp r1 r2) = nub $ symbols r1 ++ symbols r2- symbols (ProductR r1 r2) = nub $ symbols r1 ++ symbols r2- symbols (UnionR r1 r2) = nub $ symbols r1 ++ symbols r2- symbols (StarR r1) = symbols r1- symbols (Identity r1) = symbols r1- symbols (Relation a b) = let sym (S c) = [c]- sym _ = []+ symbols (Cross r1 r2) = nub $ symbols r1 ++ symbols r2+ symbols (Comp r1 r2) = nub $ symbols r1 ++ symbols r2+ symbols (ProductR r1 r2) = nub $ symbols r1 ++ symbols r2+ symbols (UnionR r1 r2) = nub $ symbols r1 ++ symbols r2+ symbols (StarR r1) = symbols r1+ symbols (Identity r1) = symbols r1+ symbols (Relation a b) = let sym (S c) = [c]+ sym _ = [] in nub $ sym a ++ sym b- symbols _ = []--{- *************************************- * Instance of Show (RReg a) *- *************************************--}+ symbols _ = [] instance Show a => Show (RReg a) where- show (Cross r1 r2) = "[ " ++ show r1 ++ " .x. " ++ show r2 ++ " ]"- show (Comp r1 r2) = "[ " ++ show r1 ++ " .o. " ++ show r2 ++ " ]"- show (UnionR r1 r2) = "[ " ++ show r1 ++ " | " ++ show r2 ++ " ]"- show (ProductR r1 r2)= "[ " ++ show r1 ++ " " ++ show r2 ++ " ]"- show (Identity r) = show r- show (StarR r) = "[ " ++ show r ++ " ]*"- show (Relation a b) = "[ " ++ show a ++":"++show b ++" ]"- show (EmptyR) = "[]"+ show (Cross r1 r2) = "[ " ++ show r1 ++ " .x. " ++ show r2 ++ " ]"+ show (Comp r1 r2) = "[ " ++ show r1 ++ " .o. " ++ show r2 ++ " ]"+ show (UnionR r1 r2) = "[ " ++ show r1 ++ " | " ++ show r2 ++ " ]"+ show (ProductR r1 r2) = "[ " ++ show r1 ++ " " ++ show r2 ++ " ]"+ show (Identity r) = show r+ show (StarR r) = "[ " ++ show r ++ " ]*"+ show (Relation a b) = "[ " ++ show a ++":"++show b ++" ]"+ show EmptyR = "[]"
FST/RegTypes.hs view
@@ -1,115 +1,95 @@-{-- **************************************************************- * Filename : RegTypes.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 5 July, 2001 *- * Lines : 219 *- **************************************************************+{- |+Functions for constructing a simplified regular expression. -}--module FST.RegTypes ( Reg(..), -- data type for the regular expression- Combinators, -- Type class for Combinators.- (<|>), -- Union combinator- (|>), -- Concatenation combinator- (<&>), -- Intersection combinator- (<->), -- Minus combinator- s, -- Symbol- eps, -- Epsilon- empty, -- Empty- complement, -- Complement- star, -- Star- plus, -- Plus- allS, -- All Symbol- allToSymbols, -- transform the 'all' symbol to union over- -- alphabet.- allFree, -- free a regular expression from 'all'- -- symbols.- reversal, -- reverse a regular expression.- acceptEps, -- Does the regular expression accept epsilon?- Symbols, -- Type class for Symbols.- symbols -- Collect the symbols in a- -- regular expression.- ) where+module FST.RegTypes (+ -- * Type classes+ Combinators (+ (<|>), (|>), star, plus, empty+ ),+ Symbols (symbols),+ + -- * Types+ Reg(..),+ + -- * Combinators+ (<&>), (<->),+ complement, reversal, allFree,+ + -- * Constructors+ s, eps, allS,+ allToSymbols,+ + -- * Query functions+ acceptEps,+ ) where import Data.List (nub) -{- **********************************************************- * Data type for a regular expression. *- **********************************************************--}--data Reg a = Empty | -- []- Epsilon | -- 0- All | -- ?- Symbol a | -- a- Reg a :|: Reg a | -- [ r1 | r2 ]- Reg a :.: Reg a | -- [ r1 r2 ]- Reg a :&: Reg a | -- [ r1 & r2 ]- Complement (Reg a) | -- ~[ r1 ]- Star (Reg a) -- [ r2 ]*- deriving (Eq)--{- **********************************************************- * Combinators. *- * The regular expressions are simplified while combined. *- **********************************************************--}+-- | Data type for a regular expression.+data Reg a =+ Empty -- ^ [ ]+ | Epsilon -- ^ 0+ | All -- ^ ?+ | Symbol a -- ^ a+ | Reg a :|: Reg a -- ^ [ r1 | r2 ]+ | Reg a :.: Reg a -- ^ [ r1 r2 ]+ | Reg a :&: Reg a -- ^ [ r1 & r2 ]+ | Complement (Reg a) -- ^ ~[ r1 ]+ | Star (Reg a) -- ^ [ r2 ]*+ deriving (Eq) -infixl 5 |> -- Concatenation infixl 4 <|> -- Union+infixl 5 |> -- Concatenation infixl 3 <&> -- Intersection infixl 3 <-> -- Set minus +-- | Combinators. The regular expressions are simplified while combined. class Combinators a where- (<|>) :: a -> a -> a -- Union- (|>) :: a -> a -> a -- Concatenation- star :: a -> a -- Kleene's star- plus :: a -> a -- Kleene's plus- empty :: a+ (<|>) :: a -> a -> a -- ^ Union+ (|>) :: a -> a -> a -- ^ Concatenation+ star :: a -> a -- ^ Kleene's star+ plus :: a -> a -- ^ Kleene's plus+ empty :: a -- ^ Empty language instance Eq a => Combinators (Reg a) where- Empty <|> b = b -- [ [] | r1 ] = r1- a <|> Empty = a -- [ r1 | [] ] = r1- _ <|> (Star All) = Star All- (Star All) <|> _ = Star All- a1@(a :.: b) <|> a2@(c :.: d)- | a1 == a2 = a1- | a == c = a |> (b <|> d)- | b == d = (a <|> c) |> b- | otherwise = a1 :|: a2- a <|> b- | a == b = a -- [ r1 | r1 ] = r1- | otherwise = a :|: b+ Empty <|> b = b -- [ [] | r1 ] = r1+ a <|> Empty = a -- [ r1 | [] ] = r1+ _ <|> Star All = Star All+ Star All <|> _ = Star All - Empty |> _ = empty -- [ [] r1 ] = []- _ |> Empty = empty -- [ r1 [] ] = []- Epsilon |> b = b -- [ 0 r1 ] = r1- a |> Epsilon = a -- [ r1 0 ] = r1- a |> b = a :.: b+ a@(a1 :.: a2) <|> b@(b1 :.: b2)+ | a == b = a+ | a1 == b1 = a1 |> (a2 <|> b2)+ | a2 == b2 = (a1 <|> b1) |> a2+ | otherwise = a :|: b + a <|> b = if a == b then a else a :|: b -- [ r1 | r1 ] = r1 - star (Star a) = star a -- [r1]** = [r1]*- star (Epsilon) = eps -- [0]* = 0- star (Empty) = eps -- [ [] ]* = 0- star a = Star a+ Empty |> _ = empty -- [ [] r1 ] = []+ _ |> Empty = empty -- [ r1 [] ] = []+ Epsilon |> b = b -- [ 0 r1 ] = r1+ a |> Epsilon = a -- [ r1 0 ] = r1+ a |> b = a :.: b - plus a = a |> star a+ star (Star a) = star a -- [r1]** = [r1]*+ star (Epsilon) = eps -- [0]* = 0+ star (Empty) = eps -- [ [] ]* = 0+ star a = Star a - empty = Empty+ plus a = a |> star a -{- Intersection -}+ empty = Empty +-- | Intersection (<&>) :: Eq a => Reg a -> Reg a -> Reg a-_ <&> Empty = Empty -- [ r1 & [] ] = []-Empty <&> _ = Empty -- [ [] & r1 ] = []-(Star All) <&> a = a-a <&> (Star All) = a-a <&> b+_ <&> Empty = Empty -- [ r1 & [] ] = []+Empty <&> _ = Empty -- [ [] & r1 ] = []+Star All <&> a = a+a <&> Star All = a+a <&> b | a == b = a -- [ r1 & r1 ] = r1 | otherwise = a :&: b -{- Minus. Definition A - B = A & ~B -}-+-- | Minus. Definition A - B = A & ~B (<->) :: Eq a => Reg a -> Reg a -> Reg a Empty <-> _ = empty -- [ [] - r1 ] = [] a <-> Empty = a -- [ r1 - [] ] = r1@@ -117,102 +97,80 @@ | a == b = empty -- [ r1 - r1 ] = [] | otherwise = a <&> (complement b) +-- | Symbol s :: a -> Reg a s a = Symbol a-+ +-- | Epsilon eps :: Reg a eps = Epsilon +-- | All symbol allS :: Reg a allS = All +-- | Complement complement :: Eq a => Reg a -> Reg a-complement Empty = star allS -- ~[ [] ] = ?*-complement Epsilon = plus allS -- ~[ 0 ] = [? ?*]-complement (Star All) = empty+complement Empty = star allS -- ~[ [] ] = ?*+complement Epsilon = plus allS -- ~[ 0 ] = [? ?*]+complement (Star All) = empty complement (Complement a) = a-complement a = Complement a--{- *******************************************************************- * allToSymbols: ? -> [a|..] with respect to an alphabet [a] *- * allFreeReg: Construct a ?-free regular expression with respect *- * to an alphabet [a] *- *******************************************************************--}+complement a = Complement a +-- | Transform the 'all' symbol to union over alphabet. ? -> [a|..] with respect to an alphabet [a] allToSymbols :: Eq a => [a] -> Reg a-allToSymbols sigma = case sigma of- [] -> empty- ys -> foldr1 (:|:) [s a| a <- ys]+allToSymbols [] = empty+allToSymbols ys = foldr1 (:|:) (map s ys) +-- | Construct a ?-free regular expression with respect to an alphabet [a] allFree :: Eq a => Reg a -> [a] -> Reg a-allFree (a :|: b) sigma = (allFree a sigma) :|: (allFree b sigma)-allFree (a :.: b) sigma = (allFree a sigma) :.: (allFree b sigma)-allFree (a :&: b) sigma = (allFree a sigma) :&: (allFree b sigma)+allFree (a :|: b) sigma = allFree a sigma :|: allFree b sigma+allFree (a :.: b) sigma = allFree a sigma :.: allFree b sigma+allFree (a :&: b) sigma = allFree a sigma :&: allFree b sigma allFree (Complement a) sigma = Complement (allFree a sigma) allFree (Star a) sigma = Star (allFree a sigma)-allFree (All) sigma = allToSymbols sigma-allFree r _ = r--{- **********************************************************- * reversal: reverse the language denoted by the regular *- * expression. *- **********************************************************--}+allFree All sigma = allToSymbols sigma+allFree r _ = r +-- | Reverse the language denoted by the regular expression. reversal :: Eq a => Reg a -> Reg a-reversal (a :|: b) = (reversal a) :|: (reversal b)-reversal (a :.: b) = (reversal b) :.: (reversal a)-reversal (a :&: b) = (reversal a) :&: (reversal b)+reversal (a :|: b) = reversal a :|: reversal b+reversal (a :.: b) = reversal b :.: reversal a+reversal (a :&: b) = reversal a :&: reversal b reversal (Complement a) = Complement (reversal a) reversal (Star a) = Star (reversal a) reversal r = r -{- ***********************************************************- * acceptEps: Examines if a regular expression accepts *- * the empty string. *- ***********************************************************--}-+-- | Examines if a regular expression accepts the empty string. acceptEps :: Eq a => Reg a -> Bool-acceptEps (Epsilon) = True-acceptEps (Star _) = True-acceptEps (a :|: b) = acceptEps a || acceptEps b-acceptEps (a :.: b) = acceptEps a && acceptEps b-acceptEps (a :&: b) = acceptEps a && acceptEps b-acceptEps (Complement a) = not (acceptEps a)-acceptEps _ = False--{- **********************************************************- * Symbols: type class for the collection of symbols in a *- * expression. *- **********************************************************--}+acceptEps Epsilon = True+acceptEps (Star _) = True+acceptEps (a :|: b) = acceptEps a || acceptEps b+acceptEps (a :.: b) = acceptEps a && acceptEps b+acceptEps (a :&: b) = acceptEps a && acceptEps b+acceptEps (Complement a) = not (acceptEps a)+acceptEps _ = False +-- | Type class for the collection of symbols in an expression. class Symbols f where- symbols :: Eq a => f a -> [a]--instance Symbols Reg where- symbols (Symbol a) = [a]- symbols (a :.: b) = nub $ (symbols a) ++ (symbols b)- symbols (a :|: b) = nub $ (symbols a) ++ (symbols b)- symbols (a :&: b) = nub $ (symbols a) ++ (symbols b)- symbols (Complement a) = symbols a- symbols (Star a) = symbols a- symbols _ = []+ symbols :: Eq a => f a -> [a] -- ^ Collect the symbols in a regular expression. -{- **********************************************************- * Instance of Show (Reg a) *- **********************************************************--}+instance Symbols Reg where+ symbols (Symbol a) = [a]+ symbols (a :.: b) = nub (symbols a ++ symbols b)+ symbols (a :|: b) = nub (symbols a ++ symbols b)+ symbols (a :&: b) = nub (symbols a ++ symbols b)+ symbols (Complement a) = symbols a+ symbols (Star a) = symbols a+ symbols _ = [] instance Show a => Show (Reg a) where- show (Empty) = "[0 - 0]"- show (Epsilon) = "0"- show (Symbol a) = show a- show (All) = "?"- show (Complement a) = "~" ++ "[" ++ show a ++ "]"- show (Star a) = "[" ++ show a ++ "]* "- show (a :|: b) = "[" ++ show a ++ " | " ++ show b ++ "]"- show (a :.: b) = "[" ++ show a ++ " " ++ show b ++ "]"- show (a :&: b) = "[" ++ show a ++ " & " ++ show b ++ "]"+ show Empty = "[0 - 0]"+ show Epsilon = "0"+ show (Symbol a) = show a+ show All = "?"+ show (Complement a) = "~[" ++ show a ++ "]"+ show (Star a) = "[" ++ show a ++ "]* "+ show (a :|: b) = "[" ++ show a ++ " | " ++ show b ++ "]"+ show (a :.: b) = "[" ++ show a ++ " " ++ show b ++ "]"+ show (a :&: b) = "[" ++ show a ++ " & " ++ show b ++ "]"
FST/Reversal.hs view
@@ -1,30 +1,36 @@-{-- **************************************************************- * Filename : Reversal.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 7 July, 2001 *- * Lines : 28 *- **************************************************************+{- |+Reverse an automaton -}--module FST.Reversal ( reversal -- Reverse an automaton.- ) where+module FST.Reversal (+ reversal+ ) where import FST.Automaton import Data.Array +-- | Reverse an automaton reversal :: Eq a => Automaton a -> Automaton a-reversal automaton = reverseTrans (rename (transitionTable automaton)- (alphabet automaton)- (finals automaton)- (initials automaton)- (firstState automaton))+reversal automaton =+ reverseTrans $+ rename (transitionTable automaton)+ (alphabet automaton)+ (finals automaton)+ (initials automaton)+ (firstState automaton) +-- | Helper function for automaton reversal reverseTrans :: Eq a => Automaton a -> Automaton a-reverseTrans automaton = let bs = (firstState automaton, lastState automaton)- table = assocs $ accumArray (\tl1 tl2 -> tl1 ++ tl2) []- bs [(s1,[(a,s)]) | (s,tl) <- transitionTable automaton,- (a,s1) <- tl]- in construct bs table (alphabet automaton) (initials automaton) (finals automaton)+reverseTrans automaton =+ construct bs table+ (alphabet automaton)+ (initials automaton)+ (finals automaton) where+ bs :: (StateTy, StateTy)+ bs = (firstState automaton, lastState automaton)++ table = assocs $ accumArray (++) [] bs+ [(s1,[(a,s)])+ | (s,tl) <- transitionTable automaton+ , (a,s1) <- tl]+
FST/ReversalT.hs view
@@ -1,20 +1,15 @@-{-- **************************************************************- * Filename : ReversalT.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 7 July, 2001 *- * Lines : 30 *- **************************************************************+{- |+Reverse an transducer -}--module FST.ReversalT ( reversal -- Reverse a transducer.- ) where+module FST.ReversalT (+ reversal+ ) where import FST.Transducer import Data.Array +-- | Reverse a transducer reversal :: Eq a => Transducer a -> Transducer a reversal transducer = reverseTrans (rename (transitionTable transducer) (alphabet transducer)@@ -22,6 +17,7 @@ (initials transducer) (firstState transducer)) +-- | Helper function for transducer reversal reverseTrans :: Eq a => Transducer a -> Transducer a reverseTrans transducer = let bs = (firstState transducer, lastState transducer) table = assocs $ accumArray (\tl1 tl2 -> tl1 ++ tl2) []
FST/RunTransducer.hs view
@@ -1,66 +1,61 @@-{-- **************************************************************- * Filename : RunTransducer.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 88 *- **************************************************************+{- |+Running a transducer with some input -}--module FST.RunTransducer ( applyUp,- applyDown- ) where+module FST.RunTransducer (+ -- * Run functions+ applyUp, applyDown+ ) where import FST.Transducer import Data.Maybe (catMaybes) -type TransitionFunction a = (Transducer a -> (State,Symbol a) ->- [(Symbol a,State)])+-- | A transition betwee states in a transducer+type TransitionFunction a = (Transducer a -> (StateTy,Symbol a) ->+ [(Symbol a,StateTy)]) +-- | Apply a transducer upwards applyUp :: Eq a => Transducer a -> [a] -> Maybe [[a]] applyUp transducer input = apply transducer transitionsD input (initial transducer) [] +-- | Apply a transducer downwards applyDown :: Eq a => Transducer a -> [a] -> Maybe [[a]] applyDown transducer input = apply transducer transitionsU input (initial transducer) [] -apply :: Eq a => Transducer a -> TransitionFunction a -> [a] -> State ->+-- | Generic function for applying a transducer+apply :: Eq a => Transducer a -> TransitionFunction a -> [a] -> StateTy -> [Symbol a] -> Maybe [[a]]-apply transducer transFun input s result =+apply transducer transFun input s result = case (runEpsilon transducer transFun input s result,- runSymbol transducer transFun input s result) of- (Just xs, Just ys) -> Just $ xs ++ ys- (a, Nothing) -> a- (Nothing, b) -> b+ runSymbol transducer transFun input s result) of+ (Just xs, Just ys) -> Just (xs ++ ys)+ (a, Nothing) -> a+ (Nothing, b ) -> b -runEpsilon :: Eq a => Transducer a -> TransitionFunction a -> [a] -> State ->+runEpsilon :: Eq a => Transducer a -> TransitionFunction a -> [a] -> StateTy -> [Symbol a] -> Maybe [[a]] runEpsilon transducer transFun input s result =- case (transFun transducer (s,Eps)) of+ case transFun transducer (s, Eps) of [] -> Nothing- tl -> case (concat $ catMaybes $- map (\(a,s1) -> apply transducer transFun input s1 (a:result)) tl) of+ tl -> case concat $ catMaybes $+ map (\(a,s1) -> apply transducer transFun input s1 (a:result)) tl of [] -> Nothing- xs -> return xs+ xs -> Just xs -runSymbol :: Eq a => Transducer a -> TransitionFunction a -> [a] -> State ->+runSymbol :: Eq a => Transducer a -> TransitionFunction a -> [a] -> StateTy -> [Symbol a] -> Maybe [[a]] runSymbol transducer _ [] s result- | isFinal transducer s = return [transform result]+ | isFinal transducer s = Just [transform result] | otherwise = Nothing runSymbol transducer transFun (i:input) s result = case (transFun transducer (s,S i)) of [] -> Nothing- tl -> case (concat $ catMaybes $- map (\(a,s1) -> apply transducer transFun input s1 (a:result)) tl) of+ tl -> case concat $ catMaybes $+ map (\(a,s1) -> apply transducer transFun input s1 (a:result)) tl of [] -> Nothing- xs -> return xs+ xs -> Just xs transform :: [Symbol a] -> [a]-transform ys = transform' ys []- where transform' [] res = res- transform' ((S a):xs) res = transform' xs (a:res)- transform' ((_:xs)) res = transform' xs res+transform ys = reverse [ a | S a <- ys ]
− FST/StateMonad.hs
@@ -1,46 +0,0 @@-{-- **************************************************************- * Filename : StateMonad.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 5 July, 2001 *- * Lines : 47 *- **************************************************************--}--module FST.StateMonad ( STM(..), -- type for the state monad.- setState, -- set the internal state.- fetchState, -- fetch and increment the internal state.- run -- run the state monad.- ) where--import FST.AutomatonTypes (State)--{- **********************************************************- * Type and instance of the State Monad *- **********************************************************--}--newtype STM a = STM(State -> (a,State))--instance Monad STM where- return x = STM(\s -> (x,s))- (STM m) >>= f = STM(\s -> let (a,s1) = m s in- unSTM (f a) s1)--unSTM :: STM a -> State -> (a,State)-unSTM (STM f) = f--{- **********************************************************- * Functions on the state monad. *- **********************************************************--}--setState :: State -> STM ()-setState s = STM (\_ -> ((),s))--fetchState :: STM State-fetchState = STM (\s -> (s,(s+1)))--run :: STM a -> State -> a-run stM s = let (a,_) = (unSTM stM) s in a
FST/Transducer.hs view
@@ -1,187 +1,156 @@-{-- **************************************************************- * Filename : Transducer.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 144 *- **************************************************************+{- |+Transducers and their functions -}+module FST.Transducer (+ module FST.TransducerTypes, -module FST.Transducer ( module FST.TransducerTypes,- Transducer, -- data type for a transducer- construct, -- construct a transducer.- TConvertable, -- type class for conversion to- -- an from a 'Transducer'.- decode, -- from a transducer to an structure.- encode, -- from a structure to a transducer.- rename,- initial,- transitions,- nullFirstState,- productT,- unionT,- starT,- compositionT,- showTransducer- ) where+ -- * Types+ Transducer,+ TConvertable (decode, encode), + -- * Transducer construction+ construct,++ -- * Actions on transducers+ rename,+ initial,+ transitions,+ nullFirstState,+ productT,+ unionT,+ starT,+ compositionT,+ showTransducer+ ) where+ import FST.TransducerTypes-import FST.Utils (tagging,remove,merge)+import FST.Utils (tagging, remove, merge) import Data.Maybe (fromJust)-import Data.List ((\\),nub,delete)--{- **********************************************************- * data types for a transducer *- **********************************************************--}+import Data.List ((\\), nub, delete) +-- | Data type for a transducer data Transducer a = Transducer {- stateTrans :: TTransitionTable a,- initS :: InitialStates,- finalStates :: FinalStates,- alpha :: Sigma a,- firstS :: FirstState,- lastS :: LastState- }- deriving (Show,Read)--{- **********************************************************- * Instance of TransducerFunctions *- **********************************************************--}+ stateTrans :: TTransitionTable a,+ initS :: InitialStates,+ finalStates :: FinalStates,+ alpha :: Sigma a,+ firstS :: FirstState,+ lastS :: LastState+ } deriving (Show,Read) instance TransducerFunctions Transducer where- states = (map fst).stateTrans- isFinal a s = elem s (finalStates a)- initials = initS- finals = finalStates- transitionTable = stateTrans- transitionList a s = case (lookup s (stateTrans a)) of- Just xs -> xs- _ -> []- transitionsU auto (s,a) = map (\((_,c),s1) -> (c,s1)) $- filter (\((b,_),_) -> a == b) (transitionList auto s)- transitionsD auto (s,a) = map (\((c,_),s1) -> (c,s1)) $- filter (\((_,b),_) -> a == b) (transitionList auto s)- lastState = lastS- firstState = firstS- alphabet = alpha+ states = map fst . stateTrans+ isFinal a s = s `elem` finalStates a+ initials = initS+ finals = finalStates+ transitionTable = stateTrans+ transitionList a s = case lookup s (stateTrans a) of+ Just xs -> xs+ _ -> []+ transitionsU auto (s,a) = [ (c, s1)+ | ((b, c), s1) <- transitionList auto s, a == b ]+ transitionsD auto (s,a) = [ (b, s1)+ | ((b, c), s1) <- transitionList auto s, a == c ]+ lastState = lastS+ firstState = firstS+ alphabet = alpha -initial :: Transducer a -> State-initial = head.initials+-- | Initial state+initial :: Transducer a -> StateTy+initial = head . initials +-- | Set first state to null nullFirstState :: Transducer a -> Transducer a-nullFirstState transducer = transducer {firstS = 0}--transitions :: Eq a => Transducer a -> (State,Relation a) -> [State]-transitions transducer (s,r) = map snd $ filter (\(r1,_) -> r == r1)- (transitionList transducer s)+nullFirstState transducer = transducer { firstS = 0 } -{- **********************************************************- * Construct a transducer *- **********************************************************--}+-- | Get transition as a list of states+transitions :: Eq a => Transducer a -> (StateTy,Relation a) -> [StateTy]+transitions transducer (s,r) = + [ r2 | (r1, r2) <- transitionList transducer s, r == r1 ] -construct :: (State,State) -> TTransitionTable a -> Sigma a ->+-- | Construct a transducer+construct :: (StateTy, StateTy) -> TTransitionTable a -> Sigma a -> InitialStates -> FinalStates -> Transducer a-construct bs table sigma is fs = Transducer {- stateTrans = table,- initS = is,- finalStates = fs,- firstS = fst bs,- lastS = snd bs,- alpha = sigma- }--{- **********************************************************- * Type class TConvertable *- **********************************************************--}+construct (first, last) table sigma is fs =+ Transducer {+ stateTrans = table,+ initS = is,+ finalStates = fs,+ firstS = first,+ lastS = last,+ alpha = sigma+ } +-- | Type class TConvertable class TConvertable f where encode :: Eq a => f a -> Transducer a decode :: Eq a => Transducer a -> f a -{- **********************************************************- * Convert automaton labelled with something other than *- * states to an 'Automaton'. *- **********************************************************--}-+-- | Convert transducer labelled with something other than states to a Transducer rename :: Eq b => [(b,[(Relation a,b)])] -> Sigma a -> [b] -> [b] ->- State -> Transducer a+ StateTy -> Transducer a rename tTable sigma initS fs s- = let (maxS,table) = tagging (map fst tTable) s- nI = map (\b -> lookupState b table) initS- nfs = map (\b -> lookupState b table) fs- nTrans = renameTable tTable table- in construct (s,maxS) nTrans sigma nI nfs- where lookupState st tab = fromJust $ lookup st tab+ = let (maxS, table) = tagging (map fst tTable) s+ nI = map (`lookupState` table) initS+ nfs = map (`lookupState` table) fs+ nTrans = renameTable tTable table+ in construct (s, maxS) nTrans sigma nI nfs+ where lookupState st tab = fromJust (lookup st tab)+ renameTable [] _ = [] renameTable ((b,tl):tll) table = let s1 = lookupState b table- ntl = map (\(a,b1) -> (a,lookupState b1 table)) tl+ ntl = [ (a, lookupState b table) | (a, b) <- tl ] in (s1,ntl):renameTable tll table -{- ***********************************************************- * Combine transducers *- ***********************************************************--}--renameT :: Transducer a -> Transducer a -> (Transducer a,Transducer a,State)-renameT transducer1 transducer2 = let tr2 = rename- (transitionTable transducer2)- (alphabet transducer2)- (initials transducer2)- (finals transducer2)- (lastState transducer1 +1)- in (transducer1,tr2,lastState tr2 +1)+-- |+renameT :: Transducer a -> Transducer a -> (Transducer a,Transducer a,StateTy)+renameT transd1 transd2 = (transd1, tr2, lastState tr2 + 1) where+ tr2 = rename (transitionTable transd2)+ (alphabet transd2) (initials transd2)+ (finals transd2) (lastState transd1 + 1) +-- | Product of two transducers productT :: Eq a => Transducer a -> Transducer a -> Transducer a-productT transducer1 transducer2 = productT' $ renameT transducer1- transducer2- where productT' (t1,t2,s) =- let transUnion = (remove (initial t1) (transitionTable t1)) ++- (remove (initial t2) (transitionTable t2))- transConc = let t = (transitionList t2 (initial t2)) in- [(f,t)| f <- (finals t1)]- transInit = [(s, transitionList t1 (initial t1) ++- listEps t1 (transitionList t2 (initial t2)))]- fs = finals t2 ++ listEps t2 (finals t1) ++- if (acceptEpsilon t1 && acceptEpsilon t2)- then [s] else []- in Transducer- {- stateTrans = transInit ++ merge transConc transUnion,- finalStates = fs \\ [(initial t1),(initial t2)],- alpha = nub $ alphabet t1 ++ alphabet t2,- initS = [s],- firstS = firstState t1,- lastS = s- }+productT transd1 transd2 = productT' (renameT transd1 transd2) where+ productT' (t1,t2,s) = let+ transUnion = remove (initial t1) (transitionTable t1) +++ remove (initial t2) (transitionTable t2)+ transConc = let t = (transitionList t2 (initial t2))+ in [(f, t)| f <- finals t1]+ transInit = [(s, transitionList t1 (initial t1) +++ listEps t1 (transitionList t2 (initial t2)))]+ fs = finals t2 ++ listEps t2 (finals t1) +++ [ s | acceptEpsilon t1 && acceptEpsilon t2]+ in Transducer {+ stateTrans = transInit ++ merge transConc transUnion,+ finalStates = fs \\ [initial t1, initial t2],+ alpha = nub $ alphabet t1 ++ alphabet t2,+ initS = [s],+ firstS = firstState t1,+ lastS = s+ } +-- | Union of two transducers unionT :: Eq a => Transducer a -> Transducer a -> Transducer a-unionT transducer1 transducer2 = unionT' $ renameT transducer1 transducer2+unionT transducer1 transducer2 = unionT' (renameT transducer1 transducer2) where unionT' (t1,t2,s) =- let transUnion = (remove (initial t1) (transitionTable t1)) ++- (remove (initial t2) (transitionTable t2))+ let transUnion = remove (initial t1) (transitionTable t1) +++ remove (initial t2) (transitionTable t2) transInit = [(s, transitionList t1 (initial t1) ++ transitionList t2 (initial t2))]- fs = finals t1 ++ finals t2 ++- if (acceptEpsilon t1 || acceptEpsilon t2)- then [s] else []- in Transducer- {- stateTrans = transInit ++ transUnion,- finalStates = fs \\ [(initial t1),(initial t2)],- alpha = nub $ alphabet t1 ++ alphabet t2,- initS = [s],- firstS = firstState t1,- lastS = s- }+ fs = finals t1 ++ finals t2 ++ [ s | acceptEpsilon t1 || acceptEpsilon t2 ]+ in Transducer {+ stateTrans = transInit ++ transUnion,+ finalStates = fs \\ [initial t1, initial t2],+ alpha = nub (alphabet t1 ++ alphabet t2),+ initS = [s],+ firstS = firstState t1,+ lastS = s+ } +-- | Kleene star of two transducers starT :: Eq a => Transducer a -> Transducer a starT t1 = let s = lastState t1 +1@@ -189,14 +158,15 @@ transLoop = let t = transitionList t1 (initial t1) in (s,t): [(f,t) | f <- finals t1] in Transducer {- stateTrans = merge transLoop transUnion,- finalStates = (s:(delete (initial t1) (finals t1))),- alpha = alphabet t1,- initS = [s],- firstS = firstState t1,- lastS = s- }+ stateTrans = merge transLoop transUnion,+ finalStates = s:(delete (initial t1) (finals t1)),+ alpha = alphabet t1,+ initS = [s],+ firstS = firstState t1,+ lastS = s+ } +-- | Compose two transducers compositionT :: Eq a => Transducer a -> Transducer a -> Transducer a compositionT t1 t2 = let minS1 = firstState t1@@ -204,59 +174,50 @@ name (s1,s2) = (lastState t2 - minS2 +1) * (s1 - minS1) + s2 - minS2 + minS1 nS = name (lastState t1,lastState t2) +1- transInit = (nS,[((a,d),name (s1,s2)) |- ((a,b),s1) <- ((Eps,Eps),initial t1):transitionList- t1 (initial t1),- ((c,d),s2) <- ((Eps,Eps),initial t2):transitionList- t2 (initial t2),- ((a,b) /= (Eps,Eps)) || ((c,d) /= (Eps,Eps)),- b == c])- transTable = [(name (s1,s2),[((a,d),name (s3,s4)) | ((a,b),s3) <- ((Eps,Eps),s1):tl1,- ((c,d),s4) <- ((Eps,Eps),s2):tl2,- ((a,b) /= (Eps,Eps)) || ((c,d) /= (Eps,Eps)),- b == c]) |- (s1,tl1) <- transitionTable t1,- (s2,tl2) <- transitionTable t2,- s1 /= initial t1 ||- s2 /= initial t2- ]+ transInit = (nS, [ ((a, d), name (s1, s2))+ | ((a, b), s1) <- ((Eps,Eps), initial t1):transitionList t1 (initial t1)+ , ((c, d), s2) <- ((Eps,Eps), initial t2):transitionList t2 (initial t2)+ , (a, b) /= (Eps, Eps) || (c,d) /= (Eps,Eps)+ , b == c ])+ transTable = [(name (s1,s2),[ ((a, d), name (s3, s4))+ | ((a, b), s3) <- ((Eps, Eps), s1):tl1+ , ((c, d), s4) <- ((Eps, Eps), s2):tl2+ , (a, b) /= (Eps, Eps) || (c,d) /= (Eps, Eps)+ , b == c])+ | (s1, tl1) <- transitionTable t1+ , (s2, tl2) <- transitionTable t2+ , s1 /= initial t1 || s2 /= initial t2 ] transUnion = transInit:transTable- fs = (if (acceptEpsilon t1 && acceptEpsilon t2)- then [nS] else []) ++- [name (f1,f2)| f1 <- finals t1,- f2 <- finals t2]- in Transducer- {- stateTrans = merge [(s,[]) | s <- fs] transUnion,- finalStates = fs,- alpha = nub $ alphabet t1 ++ alphabet t2 ,- initS = [nS],- firstS = min (firstState t1) (firstState t2),- lastS = nS- }+ fs = [ nS | acceptEpsilon t1 && acceptEpsilon t2 ] +++ [name (f1, f2) | f1 <- finals t1, f2 <- finals t2]+ in Transducer {+ stateTrans = merge [(s, []) | s <- fs] transUnion,+ finalStates = fs,+ alpha = nub $ alphabet t1 ++ alphabet t2 ,+ initS = [nS],+ firstS = min (firstState t1) (firstState t2),+ lastS = nS+ } +-- | Does a transducer accept epsilon acceptEpsilon :: Transducer a -> Bool acceptEpsilon transducer = isFinal transducer (initial transducer) +-- | If the transducer accepts epsilon, return second argument listEps :: Transducer a -> [b] -> [b]-listEps transducer xs- | acceptEpsilon transducer = xs- | otherwise = []--{- ***********************************************************- * Display a transducer *- ***********************************************************--}+listEps transducer xs = if acceptEpsilon transducer then xs else [] +-- | Show a transducer showTransducer :: Show a => Transducer a -> String-showTransducer transducer- = "\n>>>> Transducer Construction <<<<" ++- "\n\nTransitions:\n" ++ aux (stateTrans transducer) ++- "\nNumber of States => " ++ show (length (transitionTable transducer)) ++- "\nNumber of Transitions => " ++ show (sum [length tl | (s,tl) <- transitionTable transducer]) ++- "\nAlphabet => " ++ show (alphabet transducer) ++- "\nInitials => " ++ show (initials transducer) ++- "\nFinals => " ++ show (finals transducer) ++ "\n"+showTransducer transducer = unlines+ [ "Transitions:"+ , aux (stateTrans transducer)+ , "Number of States => " ++ show (length (transitionTable transducer))+ , "Number of Transitions => " ++ show (sum [length tl | (s,tl) <- transitionTable transducer])+ , "Alphabet => " ++ show (alphabet transducer)+ , "Initials => " ++ show (initials transducer)+ , "Finals => " ++ show (finals transducer)+ ] where aux [] = [] aux ((s,tl):xs) = show s ++" => " ++ aux2 tl ++ "\n" ++ aux xs aux2 [] = []
FST/TransducerInterface.hs view
@@ -1,88 +1,180 @@-{-- **************************************************************- * Filename : TransducerInterface.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 85 *- **************************************************************+{-# LANGUAGE ScopedTypeVariables #-}+{- |+Main API for finite-state transducer library.+Importing this module gives you access to the folllowing functions.++/Regular expressions/++Functions for constructing a simplified regular expression.++> s :: a -> Reg a -- symbol+> eps :: Reg a -- epsilon+> empty :: Reg a -- empty set+> allS :: Reg a -- all symbol+> star :: Reg a -> Reg a -- kleene’s star+> plus :: Reg a -> Reg a -- kleene’s plus+> complement :: Reg a -> Reg a -- complement+> (<|>) :: Reg a -> Reg a -> Reg a -- union+> (|>) :: Reg a -> Reg a -> Reg a -- product+> (<&>) :: Reg a -> Reg a -> Reg a -- intersection+> (<->) :: Reg a -> Reg a -> Reg a -- set minus+> symbols :: Reg a -> a -- collect all symbols.++/Regular relations/++Functions for constructing a simplified regular relation.++> r :: a -> a -> Reg a -- relation+> empty :: RReg a -- empty set+> idR :: Reg a -> RReg a -- identity+> star :: RReg a -> RReg a -- kleene’s star+> plus :: RReg a -> RReg a -- kleene’s plus+> (<|>) :: RReg a -> RReg a -> RReg a -- union+> (|>) :: RReg a -> RReg a -> RReg a -- product+> (<*>) :: Reg a -> Reg a -> RReg a -- cross product+> (<.>) :: RReg a -> RReg a -> RReg a -- composition+> symbols :: RReg a -> a -- collect all symbols++/Parsing regular relations/++Functions for parsing regular relations.++'parseProgram' takes a string containing a fstStudio program, and try+to parse it - if unsuccessful, it returns a error message. 'parseExp' parses a+string containing a regular relation.++> parseProgram :: String -> Either String (RReg String)+> parseExp :: String -> Either String (RReg String)++/Construction and running/++Functions for constructing and running a nite state transducer.+The function 'compile' construct a deterministic, epsilonfree, minimal+transducer, and 'compileN' construct a epsilonfree, possibly non-deterministic,+non-minimal transducer. The 'Sigma' type provides a way to add symbols+that is not present in the regular relation. 'applyDown' and 'applyUp' are+used to run the transducer.++> type Sigma a = [a]+>+> compile :: Ord a => RReg a -> Sigma a -> Transducer a+> compileN :: Ord a => RReg a -> Sigma a -> Transducer a+> determinize :: Ord a => Transducer a -> Transducer a+> minimize :: Ord a => Transducer a -> Transducer a+> unionT :: Ord a => Transducer a -> Transducer a -> Transducer a+> productT :: Ord a => Transducer a -> Transducer a -> Transducer a+> starT :: Ord a => Transducer a -> Transducer a+> compositionT :: Ord a => Transducer a -> Transducer a -> Transducer a+> emptyTransducer :: Transducer a+> applyDown :: Ord a => Transducer a -> [a] -> Maybe [[a]]+> applyUp :: Ord a => Transducer a -> [a] -> Maybe [[a]]+> load :: FilePath -> IO (Either String (Transducer String))+> save :: FilePath -> Transducer String -> IO (Either String ())++/Transducer Information/++Functions for getting information about a built transducer.++type StateTy = Int++> states :: Transducer a -> [StateTy]+> isFinal :: Transducer a -> StateTy -> Bool+> initial :: Transducer a -> StateTy+> finals :: Transducer a -> [StateTy]+> transitonsU :: Transducer a -> (StateTy,a) -> [(a,StateTy)]+> transitionsD :: Transducer a -> (StateTy,a) -> [(a,StateTy)]+> showTransducer :: Transducer a -> String+> numberOfStates :: Transducer a -> Int+> numberOfTransitions :: Transducer a -> Int+ -}+module FST.TransducerInterface (+ -- * Functions on regular expressions and relations+ module FST.RRegTypes, -module FST.TransducerInterface ( compile,- compileN,- minimize,- determinize,- Transducer,--- states,--- isFinal,--- initial,--- finals,- transitions,--- transitionList,--- transitionsU,--- transitionsD,- showTransducer,- module FST.RRegTypes,- module FST.TransducerTypes,- numberOfStates,- numberOfTransitions,- applyUp,- applyDown,- load,- save,- emptyTransducer,- parseProgram,- parseExp,- unionT,- productT,- starT,- compositionT- ) where+ -- * Types+ Transducer, -import FST.Parse-import FST.RRegTypes+ -- * Transducer-building functions+ compile, compileN, minimize, determinize,+ emptyTransducer,+ + -- * Query functions on transducer+ numberOfStates, numberOfTransitions,+ transitions, showTransducer,++ -- * Transducer combinators+ unionT, productT, starT, compositionT,++ -- * File IO functions+ load, save, open, saveToFile,+ + -- * Parse functions+ parseProgram, parseExp,++ -- * Run functions+ applyUp, applyDown,+ ) where++import Prelude hiding (catch)+import FST.Parse (parseProgram, parseExp) +import FST.RRegTypes hiding (reversal) import FST.RunTransducer import FST.Transducer import FST.TransducerTypes-import System.IO.Error (try) import qualified FST.DeterministicT as D import qualified FST.LBFT as L-import qualified FST.MinimalTBrzozowski as M+import FST.ReversalT +import Control.Exception (IOException, catch, try)+import Control.Monad.Error++-- | Construct a deterministic, epsilon-free, minimal transducer+compile :: Ord a => RReg a -> Sigma a -> Transducer a+compile rreg sigma = minimize $ nullFirstState $ L.compileToTransducer rreg sigma++-- | Construct an epsilon-free, possibly non-deterministic, non-minimal transducer compileN :: Ord a => RReg a -> Sigma a -> Transducer a-compileN reg sigma = L.compileToTransducer reg sigma+compileN = L.compileToTransducer +-- | Make a transducer deterministic determinize :: Ord a => Transducer a -> Transducer a-determinize transducer = D.determinize transducer+determinize = D.determinize +-- | Make a transducer minimal minimize :: Ord a => Transducer a -> Transducer a-minimize transducer = M.minimize transducer--compile :: Ord a => RReg a -> Sigma a -> Transducer a-compile rreg sigma = M.minimize $ nullFirstState $ L.compileToTransducer rreg sigma+minimize = D.determinize . reversal . D.determinize . reversal+{-# SPECIALIZE minimize :: Transducer String -> Transducer String #-} +-- | Return the number of states in a transducer numberOfStates :: Ord a => Transducer a -> Int-numberOfStates transducer = length $ states transducer+numberOfStates = length . states +-- | Return the number of transitions in a transducer numberOfTransitions :: Ord a => Transducer a -> Int-numberOfTransitions transducer = sum [length (transitionList transducer s) |- s <- states transducer]+numberOfTransitions transducer = sum [ length (transitionList transducer s)+ | s <- states transducer] -load :: FilePath -> IO (Either String (Transducer String))-load file- = do res <- try (readFile file)- case res of- Right str -> return $ Right (read str)- Left _ -> return $ Left $- "\nError:\tUnable to open \"" ++ file ++"\".\n"+-- | Load a transducer from file+load :: FilePath -> ErrorT String IO (Transducer String)+load = fmap read . open -save :: FilePath -> Transducer String -> IO (Either String ())-save file auto- = do res <- try (writeFile file $ show auto)- case res of- Right _ -> return $ Right ()- Left _ -> return $ Left $- "\nError:\tUnable to save to \"" ++ file ++"\".\n"+-- | Save a transducer from file+save :: FilePath -> Transducer String -> ErrorT String IO ()+save file auto = saveToFile file (show auto) +-- | Open a file and return contents as string+open :: FilePath -> ErrorT String IO String+open file = ErrorT $ catch + (Right `liftM` readFile file) + (\(e :: IOException) -> return $ throwError $ "Error: Unable to open \"" ++ file ++ "\"")++-- | Save contents (as string) to a file+saveToFile :: FilePath -> String -> ErrorT String IO ()+saveToFile file str = ErrorT $ catch + (Right `liftM` writeFile file str) + (\(e :: IOException) -> return $ throwError $ "Error: Unable to save to \"" ++ file ++ "\"")++-- | The empty transucer emptyTransducer :: Ord a => Transducer a emptyTransducer = compile EmptyR []
FST/TransducerTypes.hs view
@@ -1,74 +1,57 @@-{-- **************************************************************- * Filename : TransducerTypes.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 6 July, 2001 *- * Lines : 75 *- **************************************************************+{- |+Type system for transducers -}--module FST.TransducerTypes ( State,- FinalStates,- FirstState,- LastState,- Sigma,- Relation,- Upper,- Lower,- Symbol (..),- TTransitions,- TTransitionTable,- InitialStates,- TransducerFunctions,- states,- isFinal,- initials,- finals,- transitionTable,- transitionList,- transitionsU,- transitionsD,- firstState,- lastState,- alphabet- ) where+module FST.TransducerTypes ( -import FST.AutomatonTypes (State,FinalStates,Sigma,FirstState,LastState,- InitialStates)+ -- * Types+ StateTy,+ FinalStates,+ FirstState,+ LastState,+ Sigma,+ Relation,+ Upper,+ Lower,+ Symbol (..),+ TTransitions,+ TTransitionTable,+ InitialStates,+ TransducerFunctions (..),+ ) where -{- **********************************************************- * Transducer types *- **********************************************************--}+import FST.AutomatonTypes (+ StateTy, FinalStates, Sigma, FirstState, LastState, InitialStates+ ) +-- | A relation between upper/lower languages type Relation a = (Upper a, Lower a)++-- | Upper language type Upper a = Symbol a-type Lower a = Symbol a -data Symbol a- = S a |- Eps- deriving (Show,Read,Eq)+-- | Lower language+type Lower a = Symbol a -type TTransitions a = [(Relation a,State)]+-- | A symbol+data Symbol a = S a | Eps+ deriving (Show, Read, Eq) -type TTransitionTable a = [(State,[(Relation a,State)])]+-- | Transducer transitions+type TTransitions a = [(Relation a, StateTy)] -{- **********************************************************- * Class of TransducerFunctions *- **********************************************************--}+-- | Transducer transition table+type TTransitionTable a = [(StateTy, [(Relation a, StateTy)])] +-- | Class of TransducerFunctions class TransducerFunctions f where- states :: f a -> [State]- isFinal :: f a -> State -> Bool- initials :: f a -> InitialStates- finals :: f a -> FinalStates- transitionTable :: f a -> TTransitionTable a- transitionList :: f a -> State -> TTransitions a- transitionsU :: Eq a => f a -> (State, Symbol a) -> [(Symbol a, State)]- transitionsD :: Eq a => f a -> (State, Symbol a) -> [(Symbol a, State)]- firstState :: f a -> State- lastState :: f a -> State- alphabet :: f a -> Sigma a+ states :: f a -> [StateTy]+ isFinal :: f a -> StateTy -> Bool+ initials :: f a -> InitialStates+ finals :: f a -> FinalStates+ transitionTable :: f a -> TTransitionTable a+ transitionList :: f a -> StateTy -> TTransitions a+ transitionsU :: Eq a => f a -> (StateTy, Symbol a) -> [(Symbol a, StateTy)]+ transitionsD :: Eq a => f a -> (StateTy, Symbol a) -> [(Symbol a, StateTy)]+ firstState :: f a -> StateTy+ lastState :: f a -> StateTy+ alphabet :: f a -> Sigma a
FST/Utils.hs view
@@ -1,65 +1,43 @@-{-- **************************************************************- * Filename : Utils.hs *- * Author : Markus Forsberg *- * d97forma@dtek.chalmers.se *- * Last Modified : 22 July, 2001 *- * Lines : 66 *- **************************************************************+{- |+General utility functions -}- module FST.Utils (- cross, -- cross product of two lists.- insert,- merge,- remove,- tagging- ) where--{- **********************************************************- * cross: cartesian product of two lists. *- **********************************************************--}--{-# SPECIALIZE cross :: [Int] -> [Int] -> [(Int,Int)] #-}+ cross,+ insert,+ merge,+ remove,+ tagging+ ) where +-- | Cartesian product of two lists cross :: [a] -> [b] -> [(a,b)] cross as bs = [(a,b) | a <- as, b <- bs]--{- **********************************************************- * insert, merge, remove: aux. functions for transition *- * tables. *- **********************************************************--}--{-# SPECIALIZE insert :: (Int,[(String,Int)]) -> [(Int,[(String,Int)])] -> [(Int,[(String,Int)])] #-}+-- {-# SPECIALIZE cross :: [Int] -> [Int] -> [(Int,Int)] #-} +-- | Insert an entry into a transition table insert :: Eq b => (b,[(a,b)]) -> [(b,[(a,b)])] -> [(b,[(a,b)])]-insert (s,t1) [] = [(s,t1)]-insert (s,t1) ((s1,t2):xs)+insert (s, t1) [] = [(s,t1)]+insert (s, t1) ((s1,t2):xs) | s == s1 = (s1, t1++t2):xs | otherwise = (s1,t2):insert (s,t1) xs--{-# SPECIALIZE merge :: [(Int,[(String,Int)])] -> [(Int,[(String,Int)])] -> [(Int,[(String,Int)])] #-}+{-# SPECIALIZE insert :: (Int,[(String,Int)]) -> [(Int,[(String,Int)])] -> [(Int,[(String,Int)])] #-} +-- | Merge two transition tables merge :: Eq b => [(b,[(a,b)])] -> [(b,[(a,b)])] -> [(b,[(a,b)])] merge [] table2 = table2 merge (a:table1) table2 = merge table1 (insert a table2)--{-# SPECIALIZE remove :: Int -> [(Int,[(String,Int)])] -> [(Int,[(String,Int)])] #-}+{-# SPECIALIZE merge :: [(Int,[(String,Int)])] -> [(Int,[(String,Int)])] -> [(Int,[(String,Int)])] #-} +-- | Remove transitions from state b from a transition table remove :: Eq b => b -> [(b,[(a,b)])] -> [(b,[(a,b)])] remove _ [] = [] remove s ((s1,tl):xs) | s == s1 = xs | otherwise = (s1,tl):remove s xs--{- **********************************************************- * tagging: Tag a list of polymorphic type with integers. *- **********************************************************--}+{-# SPECIALIZE remove :: Int -> [(Int,[(String,Int)])] -> [(Int,[(String,Int)])] #-} +-- | Tag a list of polymorphic type with integers tagging :: [a] -> Int -> (Int,[(a,Int)])-tagging xs s = tag xs s []- where tag [] s1 ys = ((s1-1),ys)- tag (a:zs) s1 ys = tag zs (s1+1) ((a,s1):ys)+tagging xs s = tag xs s [] where+ tag [] s1 ys = ((s1-1),ys)+ tag (a:zs) s1 ys = tag zs (s1+1) ((a,s1):ys)
+ Main.hs view
@@ -0,0 +1,574 @@+{-# LANGUAGE DoAndIfThenElse, FlexibleContexts, GeneralizedNewtypeDeriving #-}++{- |+fstStudio takes a program consisting of regular relations that denotes+the relation between two regular languages and constructs a+transducer. If a regular expression, not a relation, is given, then it+is interpreted as the identity relation. The syntax is very similar to+Xerox's finite state transducer syntax with two fundamental+differences: a distinction is made between functions (definitions) and+strings, and fststudio allows functional definitions.++[@\"a\"@] A symbol. Example: @[\"b\"]@ denotes the language @{\"b\"}@.++[@a@] A variable. A symbol without quotes is a variable.++[@\"a\":\"b\"@] Describes a relation between the symbol @a@ and @b@.+This relation is ordered and @a@ is said to be a part of the /upper+language/ and @b@ is said to be part of the /lower language/.+Example: @[\"a\":\"b\"]@ denotes the relation @{(\"a\",\"b\")}@.++[@0@] Epsilon symbol. The epsilon symbol denotes the string with no+symbols. Example: @[0]@ denotes the language @{\"\"}@.++[@?@] All symbol. The all symbol denotes the union of all symbols in+the alphabet. Example: @[?]@ and an alphabet @{a,b,c}@ denotes the+language @{\"a\",\"b\",\"c\"}@.++[@\"\"@] quotes cancel every special meaning of the symbols. Example:+@[\"? 0\"]@ denotes the language @{\"? 0\"}@.++[@\[A\]@] brackets are used to change the precedence of a regular+relation.++[@(A)@] parenthesis expresses optionality, and has the same meaning as+@[A|0]@.++[@A B@] Concatenation of the expressions or relations A and+B. Example: @[[a b] [c d]]@ denotes the language @{\"ac\", \"ad\", \"bc\",+\"bd\"}@++[@A^n@] Concatenation of @A@ /n/ times. @A^0@ is defined as the empty+string. Example: @[a]^3@ describes the language @{\"aaa\"}@.++[@A|B@] Union of the languages or relations @A@ and @B@. Example: @[a|b]@+describes the language @{\"a\",\"b\"}@.++[@A & B@] Intersection of the languages @A@ and @B@. Example: @[a b]+& [a]@ describes the language @{\"a\"}@.++[@A - B@] Minus of the languages @A@ and @B@, and has the same meaning as+@[A & B]@. Example: @[a b] - [a]@ describes the language @{\"b\"}@.++[@~A@] Describes the complement of an expression, and has the same+meaning as @[?* - A]@. Note that complement is always defined over+an alphabet. The expression @[A]@ is only unambiguous with respect to+an alphabet. Example: @[a]@ denotes the language that doesn't contain+the string @\"a\"@. If the alphabet is @{\"a\",\"b\"}@ then @[a]@+denotes the language @{\"\",\"b\",\"aa\",\"ba\",...}@.++[@A+@] Repetition (Kleenes plus). A concatenated with itself an+arbitrary number of times, including zero times. Example: @[a]+@ denotes+the infinite language @{\"a\",\"aa\",\"aaa\",...}@++[@A*@] Kleene’s star: @[A+ | 0]@. Example: @[a]*@ denotes the infinite+language @{\"\",\"a\",\"aa\",...}@++[@$A@] Containment. The set of strings where @A@ appear at least once+as a substring. Containment is the same thing as @[?* A ?*]@.++[@A .x. B@] Cross product of the languages @A@ and @B@. Example: @[[a b]+.x. c]@ describes the relations @{(\"a\",\"c\"), (\"b\",\"c\")}@.++[@A .o. B@] Composition of the relations @A@ and @B@. Example: @[a:b c:d]+.o. [d:e]@ describes the relation @{(\"c\",\"e\")}@.++The precedence of the operators is as follows, where 4 is the highest+precedence:++ 1. @.x.@ @.o.@++ 2. @&@ @-@++ 3. /Concatenation/++ 4. @~@ @^@ @*@ @+@ @$@++A file containing a program must end with @.fst@, and an input file+mustend with @.dat@. A program is a collection of functions defining+regular relations. A function with zero arguments is called a+definition or a macro. A definition, or a macro, can for example look+like this:++> <digits> ::= "1" | "2" | "3" | "4" | "5" |+> "6" | "7" | "8" | "9" | "0" ;++and a function can look like this:++> <swap,a,b> ::= b a ;++Note that strings are marked with quotes, and variables have no+quotes. Every program must contain a @\<main\>@ definition (a program+without one will result in a parse error).++> <main> ::= ... ;++The alphabet of a program is the symbols in the regular relation+defined in the program.++/Example program/++> <nickel> ::= ["n" .x. "c"^5];+> <dime> ::= ["d" .x. "c"^10];+> <quarter> ::= ["q" .x. "c"^25];+> <cent> ::= ["c" .x. "c"];+> <money> ::= [ <nickel> | <dime> | <quarter> | <cent>]*;+> <drink> ::= ["c"^65 .x. "PLONK"];+> <main> ::= [ <money> .o. <drink> ];++/Batch mode/++Usage: @fst FILE [Options]@. FILE must end with @.fst@, which defines+an FstStudio program, or @.net@, which defines a saved transducer. If+no options are given, then input is taken from standard input, the+transducer is applied down, and the output, if any, is produced on+standard output.++[@-u@] Apply the transducer up++[@-d@] Apply the transducer down++[@-i FILE@] Take input from FILE++[@-o FILE@] Write output to FILE++/Interactive mode - list of commands/++[@r REG@] Read a regular relation from standard input. If a regular+expression is typed, then it is interpreted as the identity relation.++[@b@] Build an epsilon-free, deterministic, minimal transducer from a+loaded/typed regular relation.++[@bn@] Build an epsilon-free, possibly non-deterministic, non-minimal+transducer from a load/typed regular relation.++[@m@] Minimize a built transducer.++[@det@] Determinize a built transducer.++[@s FILE@] Save to @FILE@. If @FILE@ ends with @.net@, then the built+transducer is saved. Any other suffix saves the produced output in the+system to @FILE@, if any.++[@l FILE@] Load from @FILE@. @FILE@ must end with @.fst@, @.net@ or+@.dat@. If @FILE@ ends with @.fst@, then a FstStudio program is loaded+into FstStudio. If @FILE@ ends with @.net@, then a transducer is loaded+into FstStudio. If @FILE@ ends with @.dat@, then input is loaded into+FstStudio.++[@l a | b@] Load and union two transducers. a and b must either be a+file ending with @.net@ or the symbol @*@, which refers to the interior+transducer. The produced transducer is possibly non-deterministic and+non-minimal.++[@l a b@] Load and concatenate two transducers. a and b must either be+ale ending with @.net@ or the symbol @*@, which refers to the interior+transducer. The produced transducer is possibly non-deterministicand+non-minimal.++[@l a*@] Load and apply Kleene’s star on a transducer. a must either+be a file ending with @.net@ or the symbol @*@, which refers to the+interior transducer. The produced transducer is possibly+non-deterministicand non-minimal.++[@l a .o. b@] Load and compose two transducers. a and b must either be+a file ending with @.net@ or the symbol @*@, which refers to the+interior transducer. The produced transducer is possibly+non-deterministic andnon-minimal.++[@vt@] View loaded/built transducer.++[@vr@] View loaded/typed regular relation.++[@vi@] View loaded input.++[@vo@] View produced output.++[@d@] Apply transducer down with loaded input.++[@u@] Apply transducer up with loaded input.++[@d SYMBOLS@] Apply tranducer down with @SYMBOLS@.++[@u SYMBOLS@] Apply transducer up with @SYMBOLS@.++[@c@] Clear memory.++[@h@] List commands.++[@q@] End session.++-}+module Main where++import FST.TransducerInterface+import FST.RRegTypes+import FST.Arguments+import FST.Info++import Text.Printf++import Control.Monad (liftM)+import Control.Monad.State+import Control.Monad.Error+import Control.Monad.IO.Class (liftIO)+import System.Environment (getArgs)+import System.Console.Haskeline++-- | Main entry point+main :: IO ()+main = do+ args <- getArgs+ case args of+ [] -> do+ welcome+ runInputT defaultSettings (evalStateT loop emptyInfo)+ as -> do+ ret <- runErrorT (batchMode as)+ case ret of+ Left err -> putStrLn err+ Right _ -> return ()++-- | Display welcome message+welcome :: IO ()+welcome = putStr $ unlines [+ "***********************************************************",+ "* Finite State Transducer Studio",+ "* Written purely in Haskell.",+ "* Version : 0.10",+ "* Updated : 17 March 2013",+ "* Author : Markus Forsberg",+ "* With contributions by Baldur Blöndal & John J. Camilleri",+ "***********************************************************",+ "",+ "Type 'h' for help."+ ]++-- | Run in batch mode with given arguments+batchMode :: [String] -> ErrorT String IO ()+batchMode cmdopt = do+ (file, cmd) <- (ErrorT . return . parseBatch) cmdopt++ -- Only accept .NET or .FST files+ when (not (isNET file) && not (isFST file)) $ + throwError "Input file must end with *.fst or *.net"++ transducer <- if isFST file+ then do str <- open file+ fmap (flip compile []) $ ErrorT $ return $ parseProgram str+ + -- Load transducer directly from .NET files+ else load file+ + let action = if isUpB cmd then upB else downB+ inputFile = inputB cmd+ outputFile = outputB cmd+ + case inputFile of+ Just file -> do+ str <- open file+ case outputFile of+ Just f -> saveToFile f str+ Nothing -> throwError $ action transducer str+ Nothing -> liftIO $ interact (action transducer)++-- | Apply up in batch mode+upB :: Transducer String -> String -> String+upB transducer str =+ case applyUp transducer (words str) of+ Just xs -> unlines (map unwords xs)+ Nothing -> []++-- | Apply down in batch mode+downB :: Transducer String -> String -> String+downB transducer str =+ case applyDown transducer (words str) of+ Just xs -> unlines (map unwords xs)+ Nothing -> []++-- | Error when there is no built transducer+noTransducer :: String+noTransducer = "No transducer has been loaded/built."++-- | Error when there is no regular expression+noExpression :: String+noExpression = "No regular expression has been typed/loaded into fstStudio."++-- | Error when there is no loaded input+noInput :: String+noInput = "No input has been loaded."++-- | Error when no output has been produced+noOutputs :: String+noOutputs = "No outputs has been produced."++-- | Adds a new transducer to the environment and returns it+mkTransducer :: MonadState Info m => Transducer String -> m (Transducer String)+mkTransducer newTransducer = do+ modify (updateTransducer newTransducer)+ return newTransducer++-- | Main interactive-shell loop+loop :: StateT Info (InputT IO) ()+loop = do+ input <- lift $ getInputLine "> "+ let command = fmap (parseInteractive . words) input+ case command of+ Nothing -> return ()+ Just Quit -> lift $ outputStrLn "Session ended."+ Just cmd -> do+ -- Run a single command entered at the prompt+ result <- runErrorT $ runCmd cmd++ -- Print the resulting output or error message+ lift (either outputStrLn outputStrLn result)+ loop ++-- | Called for each user command+runCmd :: InteractiveCommand -> ErrorT String (StateT Info (InputT IO)) String+runCmd BuildTransducer = do+ info <- get+ unless (expressionRead info) $ throwError noExpression+ + let newTransducer = compile (getExpression info) []+ modify (updateTransducer newTransducer)+ return $ printf "Built a deterministic, minimal transducer with %d states and %d transitions." + (numberOfStates newTransducer) (numberOfTransitions newTransducer)+ +runCmd BuildNTransducer = do+ info <- get+ unless (expressionRead info) $ throwError noExpression++ newTransducer <- mkTransducer $ compileN (getExpression info) []++ return $ printf "Built a possibly non-deterministic, non-minimal transducer with %d states and %d transitions."+ (numberOfStates newTransducer) (numberOfTransitions newTransducer) ++runCmd Minimize = do+ info <- get+ unless (transducerBuilt info) $ throwError noTransducer + newTransducer <- mkTransducer $ minimize $ getTransducer info++ return $ + printf "Minimized loaded/built transducer resulting in a transducer with %d states and %d transitions."+ (numberOfStates newTransducer) (numberOfTransitions newTransducer) ++runCmd Determinize = do+ info <- get+ unless (transducerBuilt info) $ throwError noTransducer + newTransducer <- mkTransducer $ determinize $ getTransducer info+ return $+ printf "Determinized loaded/built transducer resulting in a transducer with %d states and %d transitions."+ (numberOfStates newTransducer) (numberOfTransitions newTransducer) +++runCmd ViewTransducer = do+ info <- get+ + if transducerBuilt info+ then return $ showTransducer $ getTransducer info+ else throwError $ noTransducer++runCmd (Load file)+ | isFST file = do+ res <- liftIO $ runErrorT $ open file+ str <- ErrorT $ return res+ reg <- ErrorT $ return $ parseProgram str+ modify (updateExpression reg)+ return (printf "Loaded a regular relation from %s." file)+ | isNET file = do+ res <- liftIO $ runErrorT $ load file+ transd <- ErrorT $ return res+ modify (updateTransducer transd)+ return (printf "Loaded transducer from file %s." file)+ | isDAT file = do+ res <- liftIO $ runErrorT $ open file+ str <- ErrorT $ return res+ modify $ updateInput $ words str+ return $ printf "Read input from file %s." file+ | otherwise =+ throwError $ "Unable to load from "++file++". The filename must end with *.fst, *.net or *.dat."+ +runCmd (LUnion file1 file2)+ | isNET file1 && isNET file2 = do+ res1 <- liftIO $ runErrorT $ load file1+ res2 <- liftIO $ runErrorT $ load file2+ t1 <- ErrorT $ return res1+ t2 <- ErrorT $ return res2+ modify $ updateTransducer (unionT t1 t2)+ return "Loaded and unified two transducers."+ + | isNET file1 && isTHIS file2 = unionWith file1+ | isTHIS file1 && isNET file2 = unionWith file2+ | otherwise = return $ printf "Unable to union %s and %s." file1 file2 where+ unionWith file = do+ info <- get+ res <- liftIO $ runErrorT $ load file+ unless (transducerBuilt info) $ throwError "No interior transducer built."+ r1 <- ErrorT $ return res+ modify $ \info -> updateTransducer (unionT r1 (getTransducer info)) info+ return "Loaded a transducer, and unified it with the interior transducer." ++runCmd (LProduct file1 file2)+ | isNET file1 && isNET file2 = do+ res1 <- liftIO $ runErrorT $ load file1+ res2 <- liftIO $ runErrorT $ load file2+ t1 <- ErrorT (return res1)+ t2 <- ErrorT (return res2)+ modify (updateTransducer (productT t1 t2))+ return "Loaded and concatenated two transducers."+ | isNET file1 && isTHIS file2 = productWith file1+ | isTHIS file1 && isNET file2 = productWith file2+ | otherwise = return $ printf "Unable to concatenate %s and %s." file1 file2 where+ productWith file = do+ info <- get+ res <- liftIO $ runErrorT $ load file+ unless (transducerBuilt info) $ throwError "No interior transducer built."+ t1 <- ErrorT $ return res+ modify $ \info -> updateTransducer (productT t1 (getTransducer info)) info+ return "Loaded a transducer, and concatenated it with the interior transducer."++runCmd (LStar file)+ | isNET file = do+ res <- liftIO $ runErrorT $ load file+ t1 <- ErrorT (return res)+ modify $ updateTransducer (starT t1)+ return "Loaded a transducer, and applied Kleene's star."+ | isTHIS file = do+ info <- get+ unless (transducerBuilt info) $ throwError "No interior transducer built."+ modify $ updateTransducer (starT (getTransducer info))+ return "Applied Kleene's star on interior transducer."+ | otherwise = return $ printf "Unable to apply Kleene's star on %s." file++runCmd (LComposition file1 file2)+ | isNET file1 && isNET file2 = do+ res1 <- liftIO $ runErrorT $ load file1+ res2 <- liftIO $ runErrorT $ load file2+ t1 <- ErrorT (return res1)+ t2 <- ErrorT (return res2)+ modify $ updateTransducer (compositionT t1 t2)+ return "Loaded and composed two transducers."+ | isNET file1 && isTHIS file2 = composeWith file1+ | isTHIS file1 && isNET file2 = composeWith file2+ | otherwise = return $ printf "Unable to compose %s and %s." file1 file2 where+ composeWith file = do+ info <- get+ res <- liftIO $ runErrorT $ load file+ unless (transducerBuilt info) $ throwError "No interior transducer built."+ t1 <- ErrorT (return res)+ modify $ \info -> updateTransducer (compositionT t1 (getTransducer info)) info+ return "Loaded a transducer, and composed it with the interior transducer."++runCmd (Save file) = do+ info <- get+ case () of+ _ | isNET file -> do+ res <- liftIO $ runErrorT $ save file $ getTransducer info+ _ <- ErrorT (return res)+ return $ printf "Saved transducer to file %s." file+ | outputsRead info -> do+ res <- liftIO $ runErrorT $ saveToFile file $ unlines $ getOutputs info+ _ <- ErrorT (return res)+ return $ printf "Saved outputs to file %s." file+ | otherwise -> return noOutputs++runCmd (StdInReg f) = + case parseExp f of+ Left err -> throwError err+ Right reg -> modify (updateExpression reg) >> return "Read a regular relation."++runCmd ViewReg = do+ info <- get+ if expressionRead info+ then return $ show (getExpression info)+ else throwError noExpression++runCmd Quit = return "Session ended."+runCmd ClearMemory = modify (const emptyInfo) >> return ""+runCmd NoCommand = throwError "Invalid Command. Type 'h' for help."+runCmd Help = return help +runCmd ViewInput = do+ info <- get+ if inputRead info+ then return $ unwords $ getInput info+ else throwError noInput++runCmd ViewOutput = do+ info <- get+ if outputsRead info+ then return $ unlines $ getOutputs info+ else throwError noOutputs++runCmd ApplyUp = do+ info <- get+ case (transducerBuilt info, inputRead info) of+ (True, True) ->+ case applyUp (getTransducer info) (getInput info) of+ Just res -> do+ modify $ updateOutputs $ map unwords res+ return "Input accepted. Type 'vo' to view outputs."+ Nothing -> throwError "Input rejected."+ (True, False) -> throwError noTransducer+ _ -> throwError noInput++runCmd ApplyDown = do+ info <- get+ case (transducerBuilt info, inputRead info) of+ (True, True) ->+ case applyDown (getTransducer info) (getInput info) of+ Just res -> do+ modify (updateOutputs (map unwords res))+ return "Input accepted. Type 'vo' to view outputs."+ Nothing -> throwError "Input rejected."+ (True, False) -> throwError noTransducer+ _ -> throwError noInput++runCmd (ApplyU inp) = do+ info <- get+ unless (transducerBuilt info) $ throwError noTransducer++ case applyUp (getTransducer info) inp of+ Just res -> do+ modify $ updateOutputs $ map unwords res+ return "Input accepted. Type 'vo' to view outputs."+ Nothing -> return "Input rejected."+ +runCmd (ApplyD inp) = do+ info <- get+ unless (transducerBuilt info) $ throwError noTransducer++ case applyDown (getTransducer info) inp of+ Just res -> do+ modify $ updateOutputs $ map unwords res+ return "Input accepted. Type 'vo' to view outputs."+ Nothing -> return "Input rejected."++-- | Dislay list of shell commands for user+help :: String+help = unlines [+ "List of Commands:",+ "r <reg exp> : read a regular relation from standard input.",+ "b : build a deterministic, minimal transducer.",+ "bn : build a possibly non-deterministic, non-minimal transducer.",+ "m : minimize loaded/built transducer.",+ "det : determinize loaded/built transducer.",+ "s <filename> : save to file.",+ "l <filename> : load from file.",+ "l a | b : load and union.",+ "l a b : load and concatenate.",+ "l a * : load and apply Kleene's star.",+ "l a .o. b : load and compose.",+ "vt : view loaded/built transducer.",+ "vr : view typed/loaded regular relation.",+ "vi : view loaded input.",+ "vo : view produced output.",+ "d : apply transducer down with loaded input.",+ "u : apply transducer up with loaded input.",+ "d <symbols> : apply transducer down with symbols.",+ "u <symbols> : apply transducer up with symbols.",+ "c : Clear memory.",+ "h : display list of commands.",+ "q : end session."+ ]
− doc/Interface0.9.ps
@@ -1,655 +0,0 @@-%!PS-Adobe-2.0-%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software-%%Title: Interface0.9.dvi-%%Pages: 3-%%PageOrder: Ascend-%%BoundingBox: 0 0 596 842-%%EndComments-%DVIPSWebPage: (www.radicaleye.com)-%DVIPSCommandLine: dvips -f Interface0.9.dvi-%DVIPSParameters: dpi=600, compressed-%DVIPSSource: TeX output 2001.10.01:1124-%%BeginProcSet: texc.pro-%!-/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S-N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72-mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0-0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{-landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize-mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[-matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round-exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{-statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]-N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin-/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array-/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2-array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N-df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A-definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get-}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}-B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr-1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3-1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx-0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx-sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{-rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp-gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B-/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{-/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{-A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy-get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse}-ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp-fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17-{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add-chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{-1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop}-forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn-/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put-}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{-bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A-mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{-SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{-userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X-1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4-index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N-/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{-/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)-(LaserWriter 16/600)]{A length product length le{A length product exch 0-exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse-end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask-grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot}-imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round-exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto-fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p-delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M}-B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{-p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S-rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end--%%EndProcSet-TeXDict begin 39158280 55380996 1000 600 600 (Interface0.9.dvi)-@start-%DVIPSBitmapFont: Fa cmtt10 10.95 52-/Fa 52 125 df<EB07C0EB1FF0497E497E13FF803801FC7EEBF83EEBF03F00037F13E0A5-5CA2143E91387E1FFF9026F0FE3F1380000113FC13F1EBF3F89026F7F01F130001FFEB07-C06C13E0ECC00F02805BEC001F4892C7FC5B00035C486C133E5A48EB807ED83FCF137C90-388FC0FCD87F075B007E13E101035B00FE13F338FC01FB6DB45AA26E5A023F1307923880-0F80A26CEB7FC0007E9038FFE01FD87F0113F001879038FC3F00263FFFF9B5FC6C01F15B-14E06C9038C03FFC6C9038001FF8D800F8EB03E0293A7DB830>38-D<EA03C0EA0FF0A2EA1FF813FCA2EA0FFEA21203EA007EA513FE13FCA2120113F81203EA-07F0120FEA1FE0EA7FC012FF13801300127C12380F1D70B730>I<141E147F14FF5BEB03-FEEB07F8EB0FF0EB1FE0EB3FC0EB7F80EBFF005B485A485A5B12075B120F5B121F5B123F-90C7FCA25A127EA412FE5AAB7E127EA4127F7EA27F121F7F120F7F12077F12037F6C7E6C-7E7FEB7F80EB3FC0EB1FE0EB0FF0EB07F8EB03FEEB01FF7F147F141E184771BE30>I<12-7812FE7E7F6C7EEA1FE06C7E6C7E6C7E6C7E6C7E7FEB3F80EB1FC0130F14E0130714F013-0314F8130114FC1300A214FE147EA4147F143FAB147F147EA414FE14FCA2130114F81303-14F0130714E0130F14C0131FEB3F80EB7F005B485A485A485A485A485AEA7FC0485A90C7-FC5A1278184778BE30>I<14E0497EA70030EC0180007CEC07C000FFEC1FE00181133F01-E113FF267FF9F313C0261FFDF713000007B512FC000114F06C5C013F1380D90FFEC7FC90-383FFF8090B512E04880000714FC391FFDF7FF267FF9F313C026FFE1F013E00181133F01-01131F007CEC07C00030EC0180000091C7FCA76D5A23277AAE30>I<EA07C0EA0FF0EA1F-F8123F13FCA213FEA2121F120F1207EA007E13FE13FC1201A2EA07F8EA0FF0123FEAFFE0-13C01380EA7E0012380F18708A30>44 D<003FB612E04815F0B712F8A36C15F06C15E025-077B9E30>I<120EEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA0E000B0B6E8A30>I<120EEA-3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA0E00C7FCB1120EEA3F80EA7FC0EAFFE0A5EA7FC0-EA3F80EA0E000B276EA630>58 D<16E0ED01F0ED07F8150F153FEDFFF04A13E0020713C0-4A1300EC3FFEEC7FF8903801FFE0495B010F90C7FC495AEB7FF8495A000313C0485BD81F-FEC8FC485AEA7FF0485A138013E06C7EEA3FFC6C7E3807FF806C7FC613F06D7EEB1FFE6D-7E010313C06D7F9038007FF8EC3FFEEC0FFF6E13C0020113E06E13F0ED3FF8150F1507ED-01F0ED00E0252F7BB230>60 D<003FB612FE4881B81280A36C16006C5DCBFCA7003FB612-FE4881B81280A36C16006C5D29157DA530>I<1238127CB4FC7F13E0EA7FF86C7E6CB4FC-00077F6C13E0C67FEB3FFC6D7E903807FF806D7F010013F06E7EEC1FFE6E7E020313C06E-13E09138007FF0ED3FF8150F153FED7FF0913801FFE04A13C0020F13004A5AEC7FF84A5A-010313C0495BD91FFEC7FC495AEBFFF000035B481380001F90C8FCEA3FFC485AEAFFE013-8090C9FC127C1238252F7BB230>I<007FB512F0B612FE6F7E82826C813A03F0001FF815-076F7E1501150082167EA516FE5E15015E15074B5AED7FE090B65A5E4BC7FC6F7E16E082-9039F0000FF8ED03FCED00FE167E167F82A2EE1F80A6163F17005EA2ED01FE1503ED0FFC-007FB65AB7FC16E05E93C7FC6C14FC29387EB730>66 D<007FB512E015FCB67E6F7E6C81-823A03F0007FF0ED1FF815076F7E6F7E1500167FA2EE3F80A2161F17C0A2160FA317E016-07AB160F17C0A3161F1780163FA2EE7F00A216FE15014B5A1507ED1FF8ED7FF0007FB65A-5EB75A93C7FC6C14FC15E02B387FB730>68 D<007FB612FEB8FCA47ED803F0C7123FA816-1E93C7FCA4157815FCA490B5FCA6EBF000A4157892C8FCA5EE0780EE0FC0A9007FB7FCB8-FCA46C16802A387DB730>I<007FB7128017C0B8FCA27EA2D801F8C7120FA8EE078093C7-FCA5151E153FA490B6FCA69038F8003FA4151E92C8FCAE387FFFF080B5FCA27E5C2A387E-B730>I<007FB512FEB7FCA46C14FE390007E000B3B3A8007FB512FEB7FCA46C14FE2038-78B730>73 D<D87FF0EC7FF06D14FF00FF16F86D5B007F16F0A2D807DE903803DF00A301-DF130701CF149FA2EC800FA201C7141FECC01FA201C3131EECE03EA201C1133CECF07CA3-9038C0F8F8A3EC78F0147DA2EC3DE0143FA2EC1FC0A2EC0F80EC070091C7FCADD87FFC90-3801FFF0A2486C4913F8A26C486D13F0A22D387FB730>77 D<D87FF890381FFFC0486C49-13E0A27FA26C6C6D13C0D803EF903800F800A28013E7A28013E380A213E180A213E080A2-147CA380A2141E141FA2801580A2EC07C0A3EC03E0A2140115F0A2140015F8A21578157C-153CA2153E151EA2D87FFF131FB5EA800FA21507A26C496C5A2B387EB730>I<90383FFF-E048B512FC000714FF4815804815C04815E09038F0007F01C0131F4848EB0FF090C71207-A2007E1403A300FE15F8481401B3A96C1403A2007E15F0A3007F1407A26D130F6C6CEB1F-E001F813FF90B6FC6C15C06C15806C1500000114FCD8003F13E0253A7BB830>I<007FB5-12E0B612FC15FF16C016E06C15F03903F0003FED0FF8ED03FC1501ED00FEA2167E167F16-3FA6167F167E16FEA2ED01FC1503ED0FF8ED3FF090B6FC16E016C0160015FC15E001F0C8-FCB0387FFF80B57EA46C5B28387DB730>I<007FB5FCB612E015F815FE816C812603F001-7F6E6C7E151F6F7E15071503821501A515035E1507150F4B5A157F4A485A90B65A93C7FC-5D5D8181D9F0017FEC007FED1FC0150F821507A917F0EEE1F8A316F13A7FFF8003F3B500-C0EBFFF0A26F13E0816C49EB7FC0C9EA1F002D397EB730>82 D<90390FF801C090397FFF-03E048B512C34814F74814FF5A381FF007383FE001903880007F48C7123F007E141F12FE-48140FA21507A46CEC03C0007E91C7FC127F6C7E13E0EA1FF86CB47E6C13F86CEBFF806C-14F0D8003F13FC01077F9038007FFF020713809138007FC0153FED0FE0ED07F01503A216-F80078140112FCA56C140316F06C14077F6DEB0FE001F0EB3FC001FE13FF90B612801600-00FD5CD8F87F13F8011F13E0D870011380253A7BB830>I<007FB712C0B812E0A53AFC00-1F8007A80078ED03C0C791C7FCB3B1010FB5FC4980A46D91C7FC2B387EB730>I<3B7FFF-800FFFF0B56C4813F8A46C496C13F0D803F0C7EA7E00B3B16D14FE00015DA26D1301A26C-6C495AA2017F495A90393FC01FE0ECF07F6DB55A6D5C6D91C7FC6D5B010013F8EC1FC02D-397FB730>I<007FB5FCB61280A4150000FCC8FCB3B3B3A5B6FC1580A46C140019476DBE-30>91 D<007FB5FCB61280A47EC7121FB3B3B3A5007FB5FCB6FCA46C140019477DBE30>-93 D<EB3FF03801FFFE0007EBFFC04880488048809038C00FFCEC03FE1400157F6C487F-0006C77FC8121FA4EC1FFF0103B5FC133F90B6FC1203000FEBFC1F381FFE00EA3FF013C0-48C7FC12FE5AA4153F7E007F14FF6D5A263FE00FEBFF806CB712C0A26C14EF6C14870001-D9FC00138026003FE090C7FC2A2A7BA830>97 D<EA7FF87F12FFA2127FA21200AAEC03F8-EC1FFF027F13C091B57E90B612F8A29138F80FFC9138E003FE4AC67E4A7F91C7EA3F8049-141F17C049140FA217E0A21607A7160FA26D15C0161FA26DEC3F80167F6EEBFF006E485A-ECE0039138F80FFC91B55A01FD5C01FC5C6E13809026781FFEC7FC90380007F02B397FB7-30>I<49B47E010F13F0013F13FC497F48B6FC4815803907FE007F13F8485A485A49EB3F-004848130C90C9FC5A127EA212FE5AA87E127EA2127FED07806C6CEB0FC07F6C6C131F6C-6C148001FC133F6CB4EBFF006C90B5FC6C5C6C5C013F13F0010F13C0D901FEC7FC222A79-A830>I<913803FFC0825CA280A2EC0007AAEB01FC90380FFF87013F13E790B512F74814-FF5A3807FE03380FF80049137F4848133F4848131F49130F48C7FC1507127E12FEA25AA7-7E150F127EA2007F141F7E6D133F6C6C137F6D13FF380FF8012607FE07EBFFC06CB7FC6C-02F713E06C14E76D01C713C0011F1303D903F8C8FC2B397DB730>I<EB01FE90380FFFC0-013F13F090B57E488048803907FE01FFD9F80013804848133F4848EB1FC049130F484814-E090C712075A127E16F000FE14035AB7FCA516E000FCC9FC7E127E127FA26C6CEB01E06D-EB03F0121F01F013076C6CEB0FE0D807FE131F3A03FF807FC06C90B512806C15006D5B01-1F5B010713F0010090C7FC242A7BA830>I<157F913803FFE0020F13F0143F4A13F8A2EC-FF07EB01FE9138FC03F0903903F800C04A1300A8007FB612C0B712E0A46C15C0260003F0-C7FCB3A9003FB6FCA2481580A26C1500A225397DB830>I<D903FC137F903A0FFF03FFC0-013F13CF90B712E05A5AD9FE07EB07C03B07F801FE0380D9F00090C7FC4848137F497F00-1F8149131FA66D133F000F92C7FC6D5B6C6C13FEEBF8013903FE07FC90B55A5A5D4814C0-018F90C8FCEB83FC0180C9FCA27F12077F6CB512F015FF4815E0488148813A3FC0000FFC-49EB00FE007EC8127F007C8100FC81178048150FA46C151F007EED3F00007F5D6C6C14FE-01E01303D81FFEEB3FFC6CB65A6C5D000115C06C6C91C7FC011F13FC010113C02B3E7DA7-30>I<EA7FF87F12FFA2127FA21200AAEC03F8EC1FFF027F7F91B57E01FD8090B6FC9138-F80FF0ECE0074A6C7E1480EC0001A25BA25BB3A23B7FFFF83FFFF05DB500FC14F8A26C01-F814F0812D387FB730>I<EB01C0EB07F0A2497EA36D5AA2EB01C090C9FCA9383FFFF048-7FA47EEA0001B3A9007FB6128016C0B7FCA27E1680223979B830>I<EA7FF0487EA4127F-1200AB0203B512805C17C0A21780809139001FC0004B5A03FFC7FC4A5A4A5A4A5AEC0FE0-4A5A4A5A4AC8FC5C01F97F01FB7F90B57E14E7ECC3F0EC81F8EC00FC5B49137E497F6F7E-A26F7E6F7E6F7EA23B7FFFF01FFFE0B56C5A17F0A217E06C497E2C387EB730>107-D<387FFFF0B57EA47EEA0001B3B3A8007FB612E0B712F0A46C15E024387AB730>I<9039-01F001F03A7F8FFC0FFC3AFFDFFE1FFE90B5487E92B51280A23A7FFE1FFE1F3B07FC0FFC-0FC001F813F89039F007F00701E013E0A401C013C0B3A23B7FFC1FFC1FFC3BFFFE3FFE3F-FEA43B7FFC1FFC1FFC2F2880A730>I<EC03F8397FF81FFFD9FC7F7F00FF90B57E01FD80-6CB6FC9138F80FF0C6EBE0074A6C7E1480EC0001A25BA25BB3A23B7FFFF83FFFF05DB500-FC14F8A26C01F814F0812D287FA730>I<EB01FC90380FFF80013F13E090B512F8488048-803907FE03FF260FF800138049137FD81FC0EB1FC0A24848EB0FE090C712074815F0007E-1403A200FE15F8481401A86C1403007E15F0A2007F1407A26C6CEB0FE06D131F6C6CEB3F-C06D137F6C6CEBFF802607FE0313006CB55A6C5C6C5C013F13E0010F1380D903FEC7FC25-2A7BA830>I<EC03F8397FF81FFFD9FC7F13C000FF90B57E90B612F87E9138F80FFCC690-38E003FE4AC67E4A7F91C7EA3F8049141F17C049140FA217E0A21607A7160FA26D15C016-1FA26DEC3F80167F6EEBFF006E485AECE0039138F80FFC91B55A01FD5C01FC5C6E1380DA-1FFEC7FCEC07F091C9FCAD387FFFF8A2B57EA26C5BA22B3C7FA730>I<ED0FF0D87FFFEB-7FFEB50081B5FC1487028F1480149F6C9038BFF07F39001FFFC09238003F004A130C4A90-C7FC5C5C5CA25CA45CAF007FB512FCB6FC81A25D7E29287DA730>114-D<90381FFC0E90B5129F000714FF5A5A5A387FE007EB800100FEC77E5A81A37E007F141E-01C090C7FCEA3FF8381FFFE06C13FF000314C0C614F0010F13FC9038007FFEEC03FFEC00-7F0078EC3F8000FC141FED0FC0A27EA27E151F01C0EB3F806D137F9039F803FF0090B6FC-5D5D00F814F0013F13C0267007FEC7FC222A79A830>I<EB0780497EAA007FB612E0B712-F0A46C15E026000FC0C7FCB2167816FCA5ECE001ED03F8903807F0079138FC0FF06DB512-E07F16C06D1400EC3FFCEC07F026337EB130>I<D87FF8EBFFF06D8000FF5BA2007F7FA2-00001401B3A41503A21507150F6D131F903A7F807FFFF091B6FC6D15F8A26D01F913F001-0713E0010090C8FC2D287FA630>I<3B7FFF803FFFC0B56C4813E0A46C496C13C03B01F0-0001F000A26D130300005DA2017C495AA36D495AA36D49C7FCA390380F803EA36D6C5AA2-ECE0FC01035BA214F101015BA214FB01005BA214FF6E5AA3021FC8FC2B277EA630>I<3B-7FFF800FFFF06E5AB515F8A26C16F04A7ED807C0C7EA1F00A26D5C0003153EA56D147E00-01157CEC0FC0EC1FE0EC3FF0A32600F87F5BEC7DF8147CA214FC01786D5AA290387CF87C-137D157D14F0013DEB3DE0013F133FA2ECE01FA2011F5C6D486C5A2D277FA630>I<263F-FFC0B5FC48168014E1A214C06C16003A007E001F806D49C7FCEB1F80157E6D6C5A6D6C5A-EB03F1903801F3F0ECFFE06D5B147F6E5A92C8FCA2814A7E4A7EEB01F3ECF1F0903803E0-F849487E010F137C49487EEC003F496D7E017E6D7E4913073B7FFF803FFF806E4813C0B5-FCA27E4A6C13802A277EA630>I<3B7FFF803FFFC06E4813E0B5FCA27E4A6C13C03B01F8-0001F000120015036D5C137C4B5A7FA2013F495A7FA26E48C7FC130F14C00107133EA214-E001035BA2EB01F05DA2EB00F85D1479147D5D143FA26E5AA36E5AA2141F92C8FCA25C14-3EA2147E147C120F486C5AEA3FC113C3EB07F0495A13FF6C5B5C6C90C9FCEA07FCEA01F0-2B3C7EA630>I<003FB612FC4815FEA416FC007EC7EA07F8ED0FF0ED1FE0ED3FC0ED7F80-003CECFF00C7485AEC07FC4A5A4A5A4A5A4A5A4A5A4990C7FC495A495A495A495A495A49-5A49C7121E4848143F485A485A485A485A485A48B7FCB8FCA46C15FE28277DA630>I<12-38127C12FEB3B3B3AD127C123807476CBE30>124 D E-%EndDVIPSBitmapFont-%DVIPSBitmapFont: Fb cmbx12 12 29-/Fb 29 121 df<EA0780EA1FE0EA3FF0EA7FF8A2EAFFFCA4EA7FF8A2EA3FF0EA1FE0EA07-800E0E788D1F>46 D<EC3FF849B5FC010F14E090393FF01FF890397FC007FC49486C7E48-496C7E48486D13804848EC7FC0A24848EC3FE0A2001F16F0A2003F16F849141FA2007F16-FCA600FF16FEB3A3007F16FCA5003F16F86D143FA2001F16F0A2000F16E06D147F000716-C0A26C6CECFF806C6C4913006C6D485A6D6C485A90393FF01FF8010FB512E00103148090-26003FF8C7FC2F427CC038>48 D<EC03C01407141F147FEB03FF133FB6FCA313C3EA0003-B3B3AFB712FCA4264177C038>I<ECFFE0010F13FE013FEBFFC090B612F02603FE017F3A-07F0007FFCD80FC0EB1FFF48486D138048C77E6F13C0D87FC015E06D7F486C15F06D7F17-F8A46C5AA26C5A6C5AC913F0A25D17E0A24B13C017805D17004B5A4B5A5EED3FE04B5A4B-5A93C7FCEC01FC4A5A4A5AEC0FC04A5A4AC71278147C5C494814F8494814F0495A49C8FC-131E49140149140390B7FC4816E05A5A5A5A5A5AB812C0A42D417BC038>I<ECFFF00107-13FF011F14C0D97F8013F09039FC001FF8D801F06D7ED803C080486C6D7ED80FF815807F-6D15C0487EA56C5A17806C5A6C485BC814005E151F5E4B5A5EED7FC04A485ADA0FFEC7FC-903807FFF85D15FF90C713C0ED1FF0ED0FFC6F7E826F138017C017E08117F0A217F8A2EA-0FC0EA3FF0487EA2487EA217F0A3494913E0127F4915C06C4849138090C71400D81FC05B-D80FF0EB1FFCD803FFEBFFF86C90B55A6C6C14C0011F49C7FC010113E02D427BC038>I<-161F5EA25E5E5DA25D5D5D5DA25D5D92B5FCEC01F715E7EC03C7EC0787140FEC1F07141E-143C147814F8EB01F014E0EB03C0EB0780130FEB1F00131E5B5B13F85B485A485A485A12-0F90C7FC121E5A127C5AB91280A4C8000F90C7FCAC027FB61280A431417DC038>I<0003-1503D807E0143F01FFEB07FF91B55A5E5E5E5E5E93C7FC5D15F815E04AC8FC01C0C9FCAA-EC3FF001C1B5FC01C714C09039DFC03FF09039FE000FF801F86D7E496D7E496D7E491580-6C4815C0C8FC6F13E0A217F0A317F8A21206EA1FC0487E487E12FF7FA217F05BA24915E0-6C485B5B003CC714C0003E4A1380001E16006C6C495A6C6C495AD803F0EB3FF8D801FEEB-FFF06CB65A013F1480010F01FCC7FC010113C02D427BC038>I<DCFFF81430031F01FF14-704AB638E001F00207EDF803023F9039E003FE074A48C7EA7F0F902601FFF0EC1F9F4901-C0EC07FF010F90C87E494815004948167F495A4948163F4849161F4A160F5A48491607A2-4890CAFC481803A25B003F1801A3127F4994C7FCA312FFAC127FA37F003F19F0A3121F7F-19016C19E06C7F19036C6D17C06C18076E17806C6DEE0F006D6C5E6D6C161E6D6C167C6D-6C5E010301C0EC03F06D01F04A5A9026007FFEEC3F8091283FFFE001FFC7FC020790B512-FC020115F0DA001F1480030001F8C8FC44467AC451>67 D<B712E0A4D8001F90C7FCB3B3-B3A6B712E0A423447DC32A>73 D<B9FC18F018FE727ED8001F90C7001F13E005017F716C-7E727E727E85721380A27213C0A31AE0A81AC0A34E1380A24E1300614E5AF0FFF84D5B05-1F13C092B7C7FC18FC18C092CBFCB3A9B712E0A443447DC34D>80-D<B812F8EFFFC018F818FED8001F90C7383FFF80050713E005017F716C7E727E85727EA2-727FA286A762A26097C7FC61183F614E5A943801FFE005075B057F90C8FC92B612F818C0-8492C713F8EF3FFCEF0FFF717F717F8583858385A785A61B0FA2727EA2063F141E857214-3CB700E06D138072EBE0F80601EBFFF0DE003F13E0CC0003130050457DC354>82-D<003FBA12E0A49026FE000FEB800301F0EE007FD87FC0EF1FF049170F90C71607007E18-03007C1801A300781800A400F819F8481978A5C81700B3B3A40107B8FCA445437CC24E>-84 D<903801FFE0011F13FE017F6D7E9039FF007FE0D801F0EB1FF0D803FC6D7E486C6D-7E000F816D6D7EA283816C4881A26C5AEA00F090C7FCA4150F021FB5FC0103B6FC011F13-8190387FF8013801FFC0481300485A485A485A485A127FA2485AA35DA36C6C1306150E6C-6C4913F06C6C9039387FFFC0390FFF81F000039038FFE01FC6EC8007D90FFEC9FC322F7D-AD36>97 D<EC3FFC49B512C0010F14F090391FF007F890397FC0007C9039FF8001FE4849-487E4848158048485B120FA2485A003F6E1300A26F5A4848EB007893C7FCA312FFAA127F-A37F123FEE03C0121F6DEC0780120F6C6CEC0F0012036C6C141E6C6D5BD97FE013F89039-3FF807F0010FB512C0010391C7FC9038003FF82A2F7CAD32>99 D<EE03FEED07FFA4ED00-1F160FB2EC3FF0903801FFFE010FEBFF8F90393FF80FEF90397FC001FF9039FF80007F48-90C7123F4848141F4848140F120F485AA2123FA2485AA412FFAA127FA4123F7F121FA26C-7E0007151F6D143F0003157F6C6C91B5FC28007FC003EF13FC90393FF01FCF010FB5120F-010313FC9026007FE0EBF80036467CC43E>I<EC3FF849B5FC010F14C090393FF01FF090-397FC007F849486C7E48496C7E48486D7E48481580000F157F484815C0163F003F16E0A2-5B127FEE1FF0A212FFA390B7FCA301F0C9FCA5127FA36C7EA2001F16F0A26C7EEE01E06C-6C14030003ED07C06C6CEC0F806C6DEB1F00D97FE0137E90391FF803FC0107B512F00100-14C0DA1FFCC7FC2C2F7DAD33>I<4AB4FC021F13C0027F13F0903901FF83F8903903FE07-FC90380FFC0F90391FF81FFEA2EB3FF0137F14E0ED0FFC01FFEB07F8ED03F0ED00C01600-ABB612F8A4C601E0C7FCB3B2007FEBFFE0A427467DC522>I<DAFFE0137E010F9038FE03-FF013FD9FF8F1380903BFFC07FFF3FC0489038001FF84848130F4848EB07FC000F9238FE-1F80490103EB0F00001F6FC7FCA2003F82A7001F93C7FCA2000F5D6D130700075D6C6C49-5A6C6C495A6C9038C07FE0D801BFB51280D8038F49C8FC48C613E091CAFC5AA37FA27F13-F090B612C06C15FCEEFF806C16E0836C826C82831207D80FF0C76C7ED81FC01407484814-01007F6F138090C9127F5AA56C6CEDFF00A26C6C4A5A6C6C4A5AD80FF8EC0FF8D807FEEC-3FF03B01FFC001FFC06C6CB6C7FC010F14F8D9007F90C8FC32427DAC38>I<1378EA01FE-487E481380A24813C0A46C1380A26C13006C5AEA007890C7FCABEB7FC0EA7FFFA412037E-B3B1B6FCA418467CC520>105 D<EB7FC0B5FCA412037EB3B3B3A5B61280A419457CC420>-108 D<90277F8003FEEC07FCB590261FFFC090383FFF80037F01F090B512E0923CF81FF8-01F03FF0913D81C00FFC03801FF80003903D830007FE06000FFC6C01865D028C6E488002-986D49130702B803F08002B05D14F04A5DA34A5DB3A8B60081B60003B512FEA4572D7CAC-5E>I<90397F8007FEB590381FFF80037F13E0913981F03FF0913983C01FF80003903987-000FFC6C138E028C800298130702B88014B014F05CA35CB3A8B60083B512FEA4372D7CAC-3E>I<EC1FFC49B512C0010714F090391FF80FFC90397FC001FF49486C7F4890C76C7E48-486E7E48486E7E000F8249140F001F82A2003F82491407007F82A400FF1780AA007F1700-A46C6C4A5AA2001F5EA26C6C4A5A00075E6D143F6C6C4A5A6C6D495A6C6C6C4890C7FC90-393FF80FFE010FB512F8010114C09026001FFCC8FC312F7DAD38>I<90397FC01FF8B590-B5FC02C314C09139CFE03FF09139DF000FF8000301FCEB07FE6C01F06D7E4A1580824A6D-13C018E0A2EF7FF0A218F8A2173FA218FCAA18F8A2177FA218F0A2EFFFE0A24C13C06E15-804C13006E495A02FC495A02DE495A9139CFC07FF002C7B512C002C149C7FC9138C03FF0-92C9FCAEB67EA436407DAC3E>I<90387F807FB53881FFC0028313F091388787F891388E-0FFC0003138C6C90389C1FFE149814B814B09138F00FFC14E0ED07F8ED01E092C7FCA25C-B3A7B612E0A4272D7DAC2E>114 D<90391FFC038090B51287000314FF3807F003380FC0-0048C7123F48141F007E140FA2150712FEA27EA26D90C7FC13E013FE387FFFF014FF6C14-C06C14F06C806C806C806C80D8003F1480010714C0EB003F1403020013E00070143F00F0-141FA26C140FA36C15C0A27EED1F807E6DEB3F0001E0137E39FDFC03FC00F8B512F0D8F0-3F5B26E007FEC7FC232F7CAD2C>I<EB01E0A51303A41307A2130FA2131FA2133F137F13-FF1203000F90B51280B7FCA3C601E0C7FCB3A4ED01E0AA017FEB03C014F0133FED0780D9-1FF8130090380FFC1E903803FFFC6D5B9038001FE023407EBE2C>I<D97FC049B4FCB501-03B5FCA40003EC000F6C81B3AA5EA25E7E5E16376D6C01671380013FD901C713FE90391F-F807876DB51207010313FE9026003FF0EBFC00372E7CAC3E>I<B500FE90383FFFF0A400-0101E0903807F8006C6DEB03E06D6C495A013F4A5A6D6C49C7FC6E5B6D6C137E6DEB807C-6D6D5A6DEBC1F0EDE3E06DEBF7C06EB45A806E90C8FC5D6E7E6E7F6E7FA24A7F4A7F8291-381F3FFCEC3E1F027C7F4A6C7E49486C7F01036D7F49487E02C08049486C7F49C76C7E01-3E6E7E49141FD801FE6E7EB500E090B512FCA4362C7EAB3B>120-D E-%EndDVIPSBitmapFont-%DVIPSBitmapFont: Fc cmr10 10.95 40-/Fc 40 122 df<EC03FC91383FFF809138FE03C0903901F00060D907E07FD90F8013F849-48487E491303133E137EA2496D5A6F5A93C7FCABED01FCB7FCA33900FC000315011500B3-AC486C497E3B7FFFF87FFFF8A32D407EBF33>12 D<121E123FEA7F80EAFFC0A213E0A212-7FEA3F60121E1200A513C0A3EA0180A2EA0300A21206A25A5A5A12200B1C79BE19>39-D<121E123FEA7F80EAFFC0A213E0A2127FEA3F60121E1200A513C0A3EA0180A2EA0300A2-1206A25A5A5A12200B1C798919>44 D<B512FEA517057F951E>I<121E123FEA7F80EAFF-C0A4EA7F80EA3F00121E0A0A798919>I<14C013031307131F137FEA07FFB5FC139FEAF8-1F1200B3B3ACEB7FF0B612F8A31D3D78BC2D>49 D<EB07FC90383FFF8090B512E03901F0-1FF039038003FC48486C7E000C6D7E48EC7F8012380030EC3FC012700060EC1FE0A212FE-6C15F07F150FA36CC7FC003E141F121CC813E0A3ED3FC0A2ED7F8016005D5D4A5A5D4A5A-4A5A4A5A5D4AC7FC143E5C14F0495A5C495A49C8FC010E14305B5B5B4914605B485A48C8-FC000615E0000FB6FC5A5A4815C0B7FCA3243D7CBC2D>I<EB07FC90383FFF809038F80F-E03901C003F848C66C7E00066D7E48147F481580EA1F80486C14C06D133FA46C5A6C4813-7F6CC71380C8FCA216005D5D5D4A5A5D4A5AEC0FC0023FC7FCEB1FFCECFF809038000FE0-EC03F0EC01FC6E7E157F1680153F16C0A2ED1FE0A216F0A2120C123F487E487EA316E05B-153F6CC713C012606CEC7F80003815006C14FE6C495A3907C003F83903F80FF0C6B55A01-3F1380D907FCC7FC243F7CBC2D>I<B712FCEEFF8017E000019039C0001FF86C6C48EB03-FEEE00FFEF3F80717E717E717E717E717EA2717E84841980183F19C0A3F01FE0A519F0AB-19E0A4183F19C0A21980187FA2190018FEA24D5A4D5A17074D5A4D5A4D5A05FFC7FCEE03-FE48486CEB1FF8B85A178004FCC8FC3C3E7DBD45>68 D<B912E0A3000101C0C7FC6C6C48-141FEF07F01703170117001870A31830A418181618A41800A21638A2167816F8150391B5-FCA3EC8003150016781638A21618A21806A3180C93C7FCA4181C1818A21838A21878A218-F0170117031707171F48486CEB01FFB912E0A3373E7DBD3E>I<B91280A300019038C000-036C6C48EB003FEF1FC017071703A21701A31700A41860A21630A31800A31670A216F015-01150791B5FCA3EC8007150115001670A21630A693C8FCAF3801FFE0B612F0A3333E7DBD-3B>I<B612F0A3C6EBF000EB3FC0B3B3B2EBFFF0B612F0A31C3E7EBD21>73-D<B56C91387FFFF880A2C66C6C020313006EEC00FC016F1678D967F81530801363EB61FE-8001607F147F6E7E81141F6E7E8114076E7E8114016E7E82157F6F7E82151F6F7E826F7E-15036F7E8281EE7F8017C0163FEE1FE017F0160FEE07F817FC1603EE01FE17FF82EF7FB0-18F0173F171F170FA217071703A201F01501486C1500EA07FEB500F015701830A23D3E7D-BD44>78 D<B712F8EEFF8017E000019039C0001FF86C6C48EB03FC707EEE007FEF3F8018-C0EF1FE0A218F0170F18F8A818F0171F18E0A2EF3FC01880EF7F00EE01FEEE07FCEE3FF0-91B612C04CC7FC0280C9FCB3A73801FFE0B612C0A3353E7DBD3E>80-D<D907FC131890381FFF80017FEBE0383A01FC03F0783903F0007CD807C0EB1EF8484813-0748C712031501123E15005A1678A200FC1538A46C1518A37E6C6C14007F6C7E13F86CB4-7E14F86CEBFF806C14F06C14FC6C14FF6C6C14806D14C0010714E0D9007F13F0020713F8-EC007FED0FFC1507ED01FEA21500167F124012C0163FA47EA2163E7E167E6C157C7E16F8-B4EC01F0D8FB8014E0D8F9E0EB03C0D8F0F8EB0F8090397F803F0039E01FFFFED8C00713-F89038007FC028427BBF33>83 D<003FB91280A3903AE0007FE00090C76C48131F007EEF-0FC0007C17070078170300701701A300601700A5481860A5C81600B3B14B7E4B7E0107B6-12FEA33B3D7DBC42>I<B600C090387FFFF8A3000101E0C70003130026007F80EC00FC18-781830B3B3A4013F5EA280011F16E060130F6E4A5A010715036D6C92C7FC6E1406010115-0E6D6C5C027F147891391F8001F091390FF00FC00203B55A020049C8FCED1FF03D407DBD-44>I<EB0FF8EB7FFE3901F01F8039038003E039060001F0390F8000F86D7F486C137C15-7EA2816C5A6C5AC8FCA4EC0FFF0103B5FC90381FFC3FEB7F803801FC00EA03F0485A485A-485A123F48C7FCEE018012FEA3157FA3007F14DFEC019F3B3F80038F83003A1FC0070FC7-3A07F01C07FE3A01FFF803FC3A003FE001F0292A7DA82D>97 D<EA01F812FFA312071203-1201B1EC07F8EC3FFF9138780FC09138C003E09039F98001F001FBC77E01FE147C498049-143F1780161F17C0A2EE0FE0A317F0A917E0A2161F17C0A21780163F6D1500167E01F614-7C5E01E3495A9039C1C007E09039C0F01F809026803FFEC7FCC7EA0FF02C407DBE33>I<-49B4FC010F13E090383F00F8017C131C4913064848131F48485B0007EC7F80485A121F5B-003FEC3F00151E007F91C7FC90C9FCA35AA97EA27F123F16C0121F6DEB0180120F6C6CEB-0300A26C6C13066C6C5BD8007C133890383F01F090380FFFC0D901FEC7FC222A7DA828>-I<ED03F815FFA3150715031501B114FF010713C190381F80F190387E003901F8130D4848-1307485A0007140348481301121F5B123FA2127F90C7FCA25AA97EA36C7EA2121F7F000F-140312076C6C13076C6CEB0DFC6C6CEB19FE017C903871FFF090383F01E190380FFF8190-3A01FE01F8002C407DBE33>I<EB01FE90380FFFC090383F03F090387C00F801F0137C00-038049133F48487F000F1580485AED0FC0123FA248C713E0A35AA290B6FCA290C9FCA67E-A27F123F1660121F6D14C0120F6C6CEB018012036C6CEB03006C6C130E017E5B90381F80-F0903807FFE0010090C7FC232A7EA828>I<EC1FC0ECFFF0903803F038903807C07C9038-0F80FEEB1F01133F133E90387E00FC1578491300AFB6FCA3D800FCC7FCB3AE487E387FFF-FEA31F407EBF1C>I<167C903903F801FF90391FFF0787903A7E0FCE0F809038F803F839-01F001F03B03E000F8070000076EC7FCA24848137EA2001F147FA6000F147EA26C6C5BA2-00035C6C6C485A6D485A39037E0FC0D91FFFC8FC380703F80006CAFCA2120EA2120F7E7F-7F6CB512F015FE6C6E7E6C15E00003813A07C0001FF848C7EA03FC001E140048157E007C-153E0078153F00F881A50078151E007C153E6C5D001E15786C5DD807C0EB03E0D803F0EB-0FC0D800FE017FC7FC90383FFFFC010313C0293D7EA82D>I<EA01F812FFA31207120312-01B1EC03F8EC1FFF91383C0F8091386007C04A6C7ED9F9807FEBFB0001FE1301825BA35B-B3A6486C497EB500F0B512F0A32C3F7CBE33>I<EA01E0487E487E487EA46C5A6C5A6C5A-C8FCACEA01F8127FA3120712031201B3AC487EB512E0A3133E7DBD19>I<EA01F812FFA3-120712031201B292387FFF80A392381FF800ED0FE01680030EC7FC5D5D15605D4A5A4AC8-FC140E5C143E147FECDF80EBF98F9038FB0FC09038FE07E0EBFC0301F07F6E7E14008115-7E8181826F7E1507826F7E82486CEB07FEB539E03FFFE0A32B3F7EBE30>107-D<EA01F812FFA3120712031201B3B3B1487EB512F0A3143F7DBE19>I<2703F003FCEB01-FE00FF903B0FFF8007FFC0913B3C0FC01E07E0913B7003E03801F00007903BC001F06000-F82603F1806D487F2601F300EBF98001F6D900FBC7127C04FF147E01FC5CA3495CB3A648-6C496C14FFB528F07FFFF83F13FCA346287CA74D>I<3903F003F800FFEB1FFF91383C0F-8091386007C00007496C7E2603F1807F3801F30001F613018213FCA35BB3A6486C497EB5-00F0B512F0A32C287CA733>I<14FF010713E090381F81F890387E007E01F8131F4848EB-0F804848EB07C04848EB03E0000F15F04848EB01F8A2003F15FCA248C812FEA44815FFA9-6C15FEA36C6CEB01FCA3001F15F86C6CEB03F0A26C6CEB07E06C6CEB0FC06C6CEB1F80D8-007EEB7E0090383F81FC90380FFFF0010090C7FC282A7EA82D>I<3901F807F800FFEB3F-FF9138781FC09138C007E03A07F98001F02603FB007FD801FE6D7E49147E49147FEE3F80-A2EE1FC0A217E0A2160F17F0A917E0161FA217C0A2EE3F80A26DEC7F00167E6D5C4B5A01-FB495A9039F9C007E09039F8F01F80DA3FFEC7FCEC0FF091C9FCAD487EB512F0A32C3A7D-A733>I<3903F007E000FFEB1FF0EC7878ECE0FC3907F181FE12033801F3019038F600FC-A2153001FC1300A35BB3A5487EB512FCA31F287EA724>114 D<90387FC0603901FFF8E0-3807C03D380E0007481303481301481300A212F01560A27EA27E007F140013C0EA3FFE38-1FFFE06C13FC6C7F6C7FC61480010F13C09038007FE0EC0FF00040130300C0EB01F81400-7E1578A37E15707E15E07E6CEB01C000F3EB038039E1E01F0038C0FFFCEB1FE01D2A7DA8-24>I<1318A61338A41378A213F8A2120112031207001FB512C0B6FCA2D801F8C7FCB3A2-1560A9000014C07F137CEC0180133E90381F8700EB07FEEB01F81B397EB723>I<D801F8-EB03F800FF14FFA3000714070003140300011401B3A61503A300001407A2017CEB0DFCED-19FE6D903831FFF090381F80E1903807FFC10100903801F8002C297CA733>I<B539C007-FFE0A32707FC000113006C48EB007C0001157816707F00001560A2017E5CA2017F13016D-5CA26D6C48C7FCA26E5A010F1306A26D6C5AA2ECF01C01031318A26D6C5AA2ECFC700100-1360A2EC7EC0A2147F6E5AA26EC8FCA3140EA22B287EA630>I<B53BC3FFFE01FFF8A33D-0FFC001FE0007FC0D803F06D48EB1F800307EC0E007F00016F130CA26D161C00004A6C13-18150D017E5EED1DF815186D5EED307CA2D91F80017E5BED603EA2D90FC090383F0180ED-C01FA2D907E00283C7FC9138E1800F02F11487010315C69138F3000702FB14CE6DB414EC-4A1303010015F8A24A1301027C5C02781300A202385C023014603D287EA642>I<3B7FFF-C00FFFE0A3000390390007FE00C648EB03F0017E6D5A6DEB03801480011F49C7FC90380F-C00E903807E00C6E5A903803F83801015B6D6C5AEC7EC0EC7F80143F141F6E7E81141FEC-3BF0EC71F8ECE1FC14C0903801807E01037FD907007F01066D7E49130F496D7E01386D7E-017880EA01F8D80FFCEB07FEB590381FFFF8A32D277FA630>I<B539C007FFE0A32707FC-000113006C48EB007C0001157816706C6C1460A27F017E5CA26D495AA2EC8003011F91C7-FCA290380FC006A2ECE00E0107130CA26D6C5AA2ECF8380101133014FC01005BA2EC7EC0-A2147F6E5AA26EC8FCA3140EA2140CA2141C1418A25CA2147000381360007C13E000FE5B-13015C49C9FCEA7C07EA700EEA383CEA1FF8EA07E02B3A7EA630>I-E-%EndDVIPSBitmapFont-%DVIPSBitmapFont: Fd cmbx12 24.88 14-/Fd 14 117 df[<EB1FE0EBFFF8000313FE486D7E48804880A248804880A281B6FC81A2-81A416807EA37E7EA27E6C14BF6C143FC613FCEB1FE090C7FC157F1600A55D5DA214015D-A214035D1407A24A5AA24A5AA24A5AA24A5A4AC7FC5B495A5C1307495A495A495AEBFFC0-485B4890C8FC485A5B6C5A6C5A6C5A>33 70 111 270 65 39 D[<BC1280A9C7000103C0-C8FCB3B3B3B3B3B3B0BC1280A9>73 142 121 269 87 73 D[<BE12F8F5FFF01EFF1FE0-1FFCF7FF8020E020F820FEC7000392C9000781E2003F15C00B03810B00810C3F8078800C-07807880788178818E8B8E8B8E8B8EA28EA28B8EA42380AC2300A46A67A26AA26A676A67-6A9CB65A6A665492C7FC545C0C1F5C545C9BB612E00B075D0B3F5D0A07B648C8FC95BB12-F820E0208055C9FC1FF09CCAFC1EF00BF8CBFC0680D0FCB3B3B2BB12FEA9>137-142 120 269 159 80 D<93387FFFF8033FB612E00203B712FE021FEEFFC0027F17F049-B912FC4918FF49912680007F14C04901E0C7000F80496D020314F8496D0200806F6F7F49-6D6F7F738090B68173807380A27380A288856D4984A26D5B747F6D5B6D5B6D5B010090CA-FC91CBFCAA0603B6FC050FB7FC0403B8FC167F0307B9FC153F4AB7C67E020F15C0023F02-FCC7FC91B612C0010392C8FC010F14FC4914F04914C04991C9FC90B55A485C485C485C48-5C5D5A485CA24891CAFCA3B6FC5CA397B5FCA461806C60F107EF6C6E150F6F16CF6CF03F-8F6F037F806C6EDBFF0F14C06C02FCDA03FE15FC6C6E91260FFC0791B5FC6C6E6CD93FF8-17806C923AF003FFF003013F91B6487E010FEF8000010394C77E010004FC141F021F03E0-1407020192C96C1400DA000701F093C9FC695F79DD71>97 D<94387FFFF8040FB612E093-B712FE0307EEFFC0031F17F092B912FC4A84020784021F9126F0000714804A0280D9007F-13C04A49C8B512E049B500F85C494A4A14F0495C494A4A14F8495C93C8FC495B495B90B5-FC5D5A484A6F14F0A2487214E05D487214C0741380487313004BEE07F897C8FC5AA4485C-A5B6FCB07EA281A37EA36C80A37E6F18FE6CF201FFA26C6E5F1CFE6C801B076C6E18FC6D-6D170FF31FF86D6EEE3FF06D6E167F6D6EEEFFE06D02F84B13C06D6E4B13806D02FF150F-6D03C0023F1300023F02F0ECFFFC6E02FF010F5B020792B65A6E18C0020060033F4CC7FC-030716F0030016C0040F02FCC8FCDC007F1380585F78DD67>99 D<94387FFFC0040FB6FC-93B712E0030716FC031F16FF037F17C04AB912F00207DAF80380021F912680003F13FE4A-49C7000F7F4A01F802038049B5486E804902C06E6C7F494A6F7F4991C9FC49727F494970-7F4B84498490B548707F5A4B198048855D481CC086481CE05D5A871DF05AA25D5AA21DF8-87A2B6FCA392BBFCA51DF00380CDFCA77EA4817EA37EA2817EA26CF307F06FF00FF87E81-6C1B1F6F19F06C1B3F6D6DF07FE06D7FF4FFC06D6E4C13806D6E5E6D02F04C13006D6EEE-1FFE6D6E4C5A6D6C01FFEEFFF86E02E002035B6E02FC021F5B02079126FFC003B55A6E92-B7C7FC020060033F17F8030F17E003011780DB003F03FCC8FC040315C0DC000F01F8C9FC-5D5F7ADD6A>101 D[<F03FFF050FB512E094B612FC040715FF043F168093B812E0030317-F04BECF007031FDA000F13F84B01FC4913FC4B495B92B500E04913FE4A5C4A4A90B6FC4A-91C7FCA24A5B5C5E5C5E4A7013FEA27313FCA291B5486E13F87313F0070313C007001300-97C7FCB3A5BA12F8A9C702F8CAFCB3B3B3B3A2003FB812FEA9>80-144 121 271 71 I<F57F80932607FFF892380FFFF04BB600E0023F13FC030F03FC49B5-7E037F9238FF80070203B8D8F01F80020FDDFC3F15804A7148133F027FDA003F90B500E0-14C091B500F001031580494A6DECFC00010702806D6C495B93C86C8149496F7F49496F6D-158049496F6D7F1F0049746C5A90B5486F6E6C5AF500E0487590C7FCA2484A6F80A44887-AB6C63A46C6E4B5CA26C63A26D6D4B5C6D97C9FCA26D6D4B5B6D6D4B5B6D6D4B5B705C01-0102E049B512E06D6E495C4902FF013F5C4992B648CAFC62D907F317F090260FE07F1680-030F03FCCBFC90261FC00115E0DB000701F8CCFC013F91CFFCA3137FA280A380A2808080-6E7E15E092B812E06DF0FFE01BFEF3FFC06D1AF81CFE767E6D1BE06D87896D1BFE7F6D87-6E876E8749BDFC010F88013F8890BEFC4802C0C9001F814891CB7E4801FC180748490601-804849727E484985884849737F88A2B55A88A66E616C65A26E616C656C6D4F5B6E616C6D-4F5B6C6D96B55A6C6D6C05035C6F5FC602F0051F49C7FC6D01FC057F5B6D01FF4CB55A01-0F02F0031F14E06DDAFFC00107B65A010092B848C8FC023F19F8020719C002004EC9FC03-1F17F003004CCAFC040192CBFC6A887ADD74>I<DB7FC0912601FFFCF0FFFE90B6033FD9-FFE0041FEBFFF0B74AB600FC93B612FE060703FF03036F7E061F04C0020F16E0067F7002-3F8295B800F84A16FC0503D9F8016E902701FFFC00804D902680007F6D4901C0013F7F4D-48C76C4B90C77EDD1FF86E6DD90FFC6E80D8003FDB3FE06E9126801FF06E800107DB7F80-F03FC04DC86C6E48486E806DDAC1FE4FC8FC4D6F6E486F80DCC3F8F0E1FCDCC7F0DEF3F8-844D61DCCFC0F0F7E04D6F4B8104DF19FF04FFC94C84A24C97CAFCA24C61A34C61A44C61-B3B3AFB900C0017FB800E0013FB812F0A9B45D77DCC3>109 D<DB7FC0913803FFF890B6-033FEBFFC0B74AB612F8060715FE061F6F7E067F16E04DB87E4DD9F003804DD9800080DD-0FFCC76C7FDD1FF080D8003F4B486E7F0107DB7F80804DC8816DDAC1FE844D81EEC3F8DC-C7F0845FEECFC0DCDF8081A204FFC981A25EA25EA35EA45EB3B3AFB900C090B912C0A972-5D77DC81>I<94381FFFF00407B612C0047F15FC0303B87E030F17E0037F17FC4ABAFC4A-9126FC007F80020F02C0010714E04A49C880027F01F8033F13FC91B5486F7F4902C00307-7F494A6F804991C96C80494970804949717F49874949717FA290B548717F48884B83481D-80A2481DC04B83481DE0A2481DF0A3484A7114F8A4481DFCA5B61BFEAF6C1DFCA56C6E4D-14F8A36C1DF0A36C1DE06F5F6C1DC0A26C6E4D1480A26C1D006F5F6C646D6D4D5B6F94B5-FC6D636D6D4C5C6D6E4B5C6D6E4B5C6D02F0031F5C6D6E4B91C7FC6D6C01FE92B512FC6E-D9FFC001075C6E02FC017F5C020791B812C0020196C8FC6E6C17FC031F17F003031780DB-007F03FCC9FC040715C0DC001F01F0CAFC675F7ADD74>I<DB7F8049B47E90B6020F13F8-B7027F13FE4DB67E4D15E0050F814D8194263FFE077F94387FF00FDEC01F7F4D48487FD8-003F913881FE0001074B491480EE83F86DEC87F0A2EE8FE05F169F5F04BFC76C1400A273-5B16FE735B4C6E5B735B9638007F804C92C8FCA45EA75EB3B3A9B912F8A9515D79DC5F>-114 D<92260FFFF814F80203B638C001FC021FEDF80791B7EAFE0F0107EEFFBF4917FF01-3F9038F0000F4990C8FCD9FFF8153F4849150F4801C015034849814890CAFC197F484817-3FA24848171FA2007F180FA312FF19077FA27F80806E705A02F893C8FC14FEECFFC06C14-FCEDFFE0EEFF806C16FCEFFFC06C17F86C17FF19C06C18F06C846C18FE6C846D846D846D-840107840101846D6C83141F020383DA003F821503DB000F1680EE003F050115C0717E18-1F1807007F050114E0486C8285856D83A2857F85A27F1BC07FA27F1B806D5FA26D19006E-5E6E5F6E4C5A6E167F02FC4C5A6E03035B6E6C4A5B03E0023F5B03FE0103B55A01F990B8-C7FCD9F07F16FCD9E01F5ED9800716C0D900014BC8FC48D9003F14F0007C020149C9FC4B-5F78DD5C>I[<ED03FEA81507A5150FA4151FA3153FA2157FA215FFA25CA25C5CA25C5C5C-5C91B5FC13035B131F017F91B712F00007BAFCBBFCA7C76C49C9FCB3B3AAF101FFB1616E-17FE82A219076E17FC836EEE0FF871131F6EEE3FF06E02F0EB7FE07113FF6EDAFE0313C0-6E91B612806F16006F5D030F5D03035D030015E0040F91C7FC040013F8>72-132 124 258 90 I E-%EndDVIPSBitmapFont-%DVIPSBitmapFont: Fe cmbx12 20.74 8-/Fe 8 117 df<EE01F04C7E160F161F167FED01FF1507153F4AB5FC141F010FB6FCB8FC-A44A7E14E0EBF000C8FCB3B3B3B3B0007FBA12F0A7447171F061>49-D<96267FFFE01670063FB616F80503B700E01401053F04FC14034CB91407040706C0130F-043F06F0131F93B626FE000F01FC133F030303809026007FFE137F030F02FCC8390FFF80-FF4B02E0030313C1037F91CA13E392B500FCEF3FF7020302F071B5FC4A4A17074A028083-4A91CB7E4A01FC844A498591B54885494A854988494A85495C93CD7E4988495B49885D90-B51C7F5D481E3F485CA21F1F485CA2481E0F5D5AA21F075D5AA2F703F09CC7FC5AA392D1-FCA2B6FCB27EA281A37EA3F701F06CF603F881A37E816C1E0720F06C80A36C6E1B0F6C1F-E06F1B1F7F6F1CC06D1D3F6D6DF37F807F70F2FF006D6E626D6E19016D525A6D6E4F5A6E-6D190F6E01FE4F5A6E6D4F5A6E6E4E5A6E02E04D485A6E6E4D90C7FC020002FCEF0FFE6F-01FFEF3FFC031F02E0EEFFF06F02FC03075B0303DAFFC0023F1380030003FE0107B5C8FC-043F91B712FC040718F0040118C0DC003F94C9FC050316F8DD003F1580DE007F01F0CAFC-757A75F78C>67 D<92383FFFF8020FB612E0027F15FC0103B87E010F17E04983499026E0-007F13FCD97FFCC7000F7F496C02037F486D6E806F6D6C7F86486E6E7F727F8684868486-6C5CA26C91C86C806D5A6D5A6D5AEB03C090CAFCA80507B6FC041FB7FC0303B8FC157F02-03B9FC021FECFE0391B612800103ECF800010F14C04991C7FC017F13FC90B512F04814C0-485C4891C8FC485B485BA2485BA2485BA2B5FC5CA360A360806C5FA26C6D153E6E5D6C05-FC806C01FFDA03F8806C6ED90FF014FC6C02E090263FE07FEBFFFC6C9128FC03FFC03F14-FE6C91B61280013F4B487E010F4B1307010303F01301D9003F0280D9001F13FC020101F8-CBFC57507ACE5E>97 D<EE3FFF0307B512F8033F14FF4AB712E0020716F8021F16FE027F-D9F8037F49B526C0007F7F4991C76C13E04901FC020F7F49498049496E7F49496E7F4949-6E7F90B55A48727E92C9FC48721380485B1BC048841BE0485BA27313F05AA25C5AA21BF8-85A2B5FCA391BAFCA41BF002F8CCFCA67EA3807EA47E806CF101F0F203F86C7F1A076C6E-17F06C190F6F17E06C6E161F6D6DEE3FC06D6D167F6D6DEEFF806D6D030313006D6D6C4A-5A6D02E0EC1FFC6D02F8EC7FF86D913AFF8007FFF0023F91B65A020F178002034CC7FC02-0016F8031F15C003014AC8FCDB000F13C04D507BCE58>101 D<903801FFFCB6FCA7C67E-131F7FB3AE95380FFFE095B512FE05036E7E050F15E0053F15F84D819426FFF01F7F4CD9-00077FDC07FC010180EE0FF0DC1FC06D804D82043EC87E5E04FC835EDBFDF0815E03FF84-5EA25EA393C9FCA45DB3B3A7B8D8E003B81280A7617879F76C>104-D<902601FFFCEC7FFEB60207B512F0053F14FE4CB712C0040716F0041F824C16FE4CD900-7F7FC66C9026FDFFF0010F14C0011F90B500800103806D4AC76C804C6E6C7F04F06F7F4C-6F7F5E4C6F7F93C96C14805D7414C01DE0861DF0A2861DF8A2871DFCA57513FEAF5113FC-A41DF8A298B5FC1DF0A2621DE0A25014C01D80626F1900505B705D705F704B5B704B5B70-92B55A04FE02035C706C010F91C7FC4B01E0013F5B93267FFC01B55A041FB712F07016C0-040393C8FC040015F8051F14C0050301F0C9FC94CCFCB3A7B812E0A75F6F7ACD6C>112-D<902601FFF8EB07FEB691383FFFC094B512F04C800407804C8093391FFC3FFF93263FE0-7F1380C66C0380B512C0011F4A5A6DDAFC0114E0A2EDF9F816F015FB16E015FF4C6C14C0-A24C6D1380721300725A93C76C5AF001E095C8FCA25DA55DB3B3A4B812F8A7434E7ACD4F->114 D<157FA75DA45CA45CA25CA25CA25CA25C5C91B5FC5B5B5B5B133F90B6FC000792-B6FCBAFCA6D8000791C9FCB3B3A4F00FE0AE181F6D6E14C0A2183F6D178070137F6D1700-705B6E6D485A6E9038FE07FC6E90B55A6E5D6E5D02015D6E6C5C031F49C7FC030013F03B-6E7CEC4B>116 D E-%EndDVIPSBitmapFont-end-%%EndProlog-%%BeginSetup-%%Feature: *Resolution 600dpi-TeXDict begin-%%PaperSize: A4--%%EndSetup-%%Page: 1 1-1 0 bop 382 1171 a Fe(Chapter)65 b(1)382 1586 y Fd(Programmer's)74-b(In)-6 b(terface)382 2031 y Fc(Imp)s(orting)33 b(the)i(mo)s(dule)e('T)--8 b(ransducerIn)m(terface.hs')35 b(giv)m(es)i(y)m(ou)e(access)h(to)g-(the)f(fol-)382 2144 y(lo)m(wing)c(functions.)382 2385-y Fb(1.0.1)112 b(Regular)37 b(expressions)382 2557 y-Fc(F)-8 b(unctions)31 b(for)f(constructing)h(a)g(simpli\014ed)d-(regular)j(expression.)382 2757 y Fa(s)477 b(::)47 b(a)h(->)f(Reg)g(a)-668 b(--)47 b(symbol)382 2870 y(eps)381 b(::)47 b(Reg)g(a)907-b(--)47 b(epsilon)382 2983 y(empty)285 b(::)47 b(Reg)g(a)907-b(--)47 b(empty)f(set)382 3096 y(allS)333 b(::)47 b(Reg)g(a)907-b(--)47 b(all)g(symbol)382 3209 y(star)333 b(::)47 b(Reg)g(a)g(->)h-(Reg)f(a)477 b(--)47 b(kleene's)e(star)382 3322 y(plus)333-b(::)47 b(Reg)g(a)g(->)h(Reg)f(a)477 b(--)47 b(kleene's)e(plus)382-3435 y(complement)g(::)i(Reg)g(a)g(->)h(Reg)f(a)477 b(--)47-b(complement)382 3548 y(\(<|>\))285 b(::)47 b(Reg)g(a)g(->)h(Reg)f(a)g-(->)g(Reg)g(a)h(--)f(union)382 3660 y(\(|>\))333 b(::)47-b(Reg)g(a)g(->)h(Reg)f(a)g(->)g(Reg)g(a)h(--)f(product)382-3773 y(\(<&>\))285 b(::)47 b(Reg)g(a)g(->)h(Reg)f(a)g(->)g(Reg)g(a)h-(--)f(intersection)382 3886 y(\(<->\))285 b(::)47 b(Reg)g(a)g(->)h(Reg)-f(a)g(->)g(Reg)g(a)h(--)f(set)g(minus)382 3999 y(symbols)189-b(::)47 b(Reg)g(a)g(->)h(a)668 b(--)47 b(collect)f(all)g(symbols.)382-4241 y Fb(1.0.2)112 b(Regular)37 b(relations)382 4412-y Fc(F)-8 b(unctions)31 b(for)f(constructing)h(a)g(simpli\014ed)d-(regular)j(relation.)382 4613 y Fa(r)477 b(::)47 b(a)h(->)f(a)g(->)g-(Reg)g(a)573 b(--)47 b(relation)382 4726 y(empty)285-b(::)47 b(RReg)g(a)1002 b(--)47 b(empty)f(set)382 4839-y(idR)381 b(::)47 b(Reg)g(a)95 b(->)47 b(RReg)g(a)525-b(--)47 b(identity)382 4951 y(star)333 b(::)47 b(RReg)g(a)g(->)g(RReg)g-(a)525 b(--)47 b(kleene's)e(star)382 5064 y(plus)333-b(::)47 b(RReg)g(a)g(->)g(RReg)g(a)525 b(--)47 b(kleene's)e(plus)382-5177 y(\(<|>\))285 b(::)47 b(RReg)g(a)g(->)g(RReg)g(a)g(->)h(RReg)e(a)i-(--)f(union)382 5290 y(\(|>\))333 b(::)47 b(RReg)g(a)g(->)g(RReg)g(a)g-(->)h(RReg)e(a)i(--)f(product)382 5403 y(\(<*>\))285-b(::)47 b(Reg)g(a)95 b(->)47 b(Reg)g(a)95 b(->)48 b(RReg)e(a)i(--)f-(cross)f(product)1854 5652 y Fc(1)p eop-%%Page: 2 2-2 1 bop 382 548 a Fa(\(<.>\))285 b(::)47 b(RReg)g(a)g(->)g(RReg)g(a)g-(->)h(RReg)e(a)i(--)f(composition)382 661 y(symbols)189-b(::)47 b(RReg)g(a)g(->)g(a)764 b(--)47 b(collect)f(all)h(symbols.)382-904 y Fb(1.0.3)112 b(P)m(arsing)37 b(regular)g(relations)382-1076 y Fc(F)-8 b(unctions)31 b(for)f(parsing)g(regular)g(relations.)523-1189 y('parseProgram')36 b(tak)m(es)i(a)f(string)g(con)m(taining)h(a)f-(fstStudio)f(program,)h(and)f(try)382 1302 y(to)c(parse)e(it)i(-)f(if)g-(unsuccessful,)f(it)h(returns)f(a)h(error)g(message.)42-b('parseExp')31 b(parses)f(a)382 1415 y(string)g(con)m(taining)i(a)f-(regular)f(relation.)382 1740 y Fa(parseProgram)44 b(::)k(String)e(->)h-(Either)f(String)g(\(RReg)g(String\))382 1853 y(parseExp)236-b(::)48 b(String)e(->)h(Either)f(String)g(\(RReg)g(String\))382-2096 y Fb(1.0.4)112 b(Construction)37 b(and)h(running)382-2268 y Fc(F)-8 b(unctions)31 b(for)f(constructing)h(and)f(running)e(a)j-(\014nite)f(state)i(transducer.)523 2381 y(The)40 b(function)h-('compile')g(construct)g(a)g(deterministic,)j(epsilonfree,)f(minimal)-382 2494 y(transducer,)22 b(and)d('compileN')i(construct)g(a)f-(epsilonfree,)j(p)s(ossibly)d(non-deterministic,)382-2607 y(non-minimal)31 b(transducer.)48 b(The)33 b('Sigma')g(t)m(yp)s(e)-h(pro)m(vides)f(a)g(w)m(a)m(y)h(to)g(add)f(sym)m(b)s(ols)382-2720 y(that)h(is)f(not)g(presen)m(t)g(in)g(the)g(regular)h(relation.)50-b('applyDo)m(wn')34 b(and)e('applyUp')h(are)382 2833-y(used)c(to)j(run)d(the)h(transducer.)382 3045 y Fa(type)47-b(Sigma)f(a)h(=)h([a])382 3271 y(compile)428 b(::)47-b(Ord)g(a)g(=>)g(RReg)g(a)g(->)h(Sigma)e(a)h(->)h(Transducer)d(a)382-3384 y(compileN)380 b(::)47 b(Ord)g(a)g(=>)g(RReg)g(a)g(->)h(Sigma)e(a)-h(->)h(Transducer)d(a)382 3497 y(determinize)236 b(::)47-b(Ord)g(a)g(=>)g(Transducer)e(a)j(->)f(Transducer)e(a)382-3610 y(minimize)380 b(::)47 b(Ord)g(a)g(=>)g(Transducer)e(a)j(->)f-(Transducer)e(a)382 3723 y(unionT)476 b(::)47 b(Ord)g(a)g(=>)g-(Transducer)e(a)j(->)f(Transducer)e(a)i(->)h(Transducer)d(a)382-3836 y(productT)380 b(::)47 b(Ord)g(a)g(=>)g(Transducer)e(a)j(->)f-(Transducer)e(a)i(->)h(Transducer)d(a)382 3948 y(starT)524-b(::)47 b(Ord)g(a)g(=>)g(Transducer)e(a)j(->)f(Transducer)e(a)382-4061 y(compositionT)188 b(::)47 b(Ord)g(a)g(=>)g(Transducer)e(a)j(->)f-(Transducer)e(a)i(->)h(Transducer)d(a)382 4174 y(emptyTransducer)f(::)j-(Transducer)e(a)382 4287 y(applyDown)332 b(::)47 b(Ord)g(a)g(=>)g-(Transducer)e(a)j(->)f([a])g(->)g(Maybe)f([[a]])382 4400-y(applyUp)428 b(::)47 b(Ord)g(a)g(=>)g(Transducer)e(a)j(->)f([a])g(->)g-(Maybe)f([[a]])382 4513 y(load)572 b(::)47 b(FilePath)e(->)i(IO)h-(\(Either)d(String)i(\(Transducer)d(String\)\))382 4626-y(save)572 b(::)47 b(FilePath)e(->)i(Transducer)e(String)i(->)g(IO)g-(\(Either)f(String)g(\(\)\))382 4869 y Fb(1.0.5)112 b(T)-9-b(ransducer)38 b(Information)382 5041 y Fc(F)-8 b(unctions)31-b(for)f(getting)i(information)e(ab)s(out)g(a)h(built)f(transducer.)382-5253 y Fa(type)47 b(State)f(=)h(Int)1854 5652 y Fc(2)p-eop-%%Page: 3 3-3 2 bop 382 548 a Fa(states)666 b(::)48 b(Transducer)d(a)i(->)g-([State])382 661 y(isFinal)618 b(::)48 b(Transducer)d(a)i(->)g(State)g-(->)g(Bool)382 774 y(initial)618 b(::)48 b(Transducer)d(a)i(->)g(State)-382 887 y(finals)666 b(::)48 b(Transducer)d(a)i(->)g([State])382-1000 y(transitionsU)378 b(::)48 b(Transducer)d(a)i(->)g(\(State,a\))f-(->)h([\(a,State\)])382 1112 y(transitionsD)378 b(::)48-b(Transducer)d(a)i(->)g(\(State,a\))f(->)h([\(a,State\)])382-1225 y(showTransducer)282 b(::)48 b(Transducer)d(a)i(->)g(String)382-1338 y(numberOfStates)282 b(::)48 b(Transducer)d(a)i(->)g(Int)382-1451 y(numberOfTransitions)42 b(::)48 b(Transducer)d(a)i(->)g(Int)1854-5652 y Fc(3)p eop-%%Trailer-end-userdict /end-hook known{end-hook}if-%%EOF
− doc/fstMan0.9.ps
@@ -1,1299 +0,0 @@-%!PS-Adobe-2.0-%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software-%%Pages: 8-%%PageOrder: Ascend-%%BoundingBox: 0 0 596 842-%%EndComments-%DVIPSWebPage: (www.radicaleye.com)-%DVIPSCommandLine: dvips -f-%DVIPSParameters: dpi=600, compressed-%DVIPSSource: TeX output 2001.08.28:0920-%%BeginProcSet: texc.pro-%!-/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S-N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72-mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0-0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{-landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize-mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[-matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round-exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{-statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]-N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin-/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array-/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2-array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N-df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A-definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get-}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}-B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr-1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3-1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx-0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx-sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{-rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp-gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B-/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{-/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{-A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy-get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse}-ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp-fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17-{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add-chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{-1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop}-forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn-/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put-}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{-bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A-mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{-SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{-userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X-1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4-index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N-/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{-/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)-(LaserWriter 16/600)]{A length product length le{A length product exch 0-exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse-end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask-grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot}-imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round-exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto-fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p-delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M}-B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{-p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S-rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end--%%EndProcSet-TeXDict begin 39158280 55380996 1000 600 600 () @start-%DVIPSBitmapFont: Fa cmtt10 10.95 71-/Fa 71 125 df<121C127FA2EAFF80B2EA7F00B1123EC7FCA9121C127FA2EAFF80A3EA7F-00A2121C09396DB830>33 D<003C131E00FEEB3F80A26C137FA248133FB3007E1400007C-7F003C131E191B75B830>I<147814FCA5EB03FF011F13E090B512FC4880000780481580-261FFCFC13C001F0EB3FE0D83FC0130FD87F80EB07F001001303007E15F812FE5A1507A3-ED03F07E007E91C7FC127FEA3F8013E0EA1FF8EA0FFF7E6CEBFF80C614F0013F7F010F13-FE01007F168002FC13C0153FED0FE0ED07F0A21503007E15F81501B4FCA35A1503A2007E-15F0007F1407ED0FE0D83FC0131FD81FE0EB7FC09039FCFDFF806CB612006C5C6C5CC614-F0013F13C0D903FEC7FCEB00FCA6147825477BBE30>36 D<EA03C0EA0FF0A2EA1FF813FC-A2EA0FFEA21203EA007EA513FE13FCA2120113F81203EA07F0120FEA1FE0EA7FC012FF13-801300127C12380F1D70B730>39 D<141E147F14FF5BEB03FEEB07F8EB0FF0EB1FE0EB3F-C0EB7F80EBFF005B485A485A5B12075B120F5B121F5B123F90C7FCA25A127EA412FE5AAB-7E127EA4127F7EA27F121F7F120F7F12077F12037F6C7E6C7E7FEB7F80EB3FC0EB1FE0EB-0FF0EB07F8EB03FEEB01FF7F147F141E184771BE30>I<127812FE7E7F6C7EEA1FE06C7E-6C7E6C7E6C7E6C7E7FEB3F80EB1FC0130F14E0130714F0130314F8130114FC1300A214FE-147EA4147F143FAB147F147EA414FE14FCA2130114F8130314F0130714E0130F14C0131F-EB3F80EB7F005B485A485A485A485A485AEA7FC0485A90C7FC5A1278184778BE30>I<14-E0497EA70030EC0180007CEC07C000FFEC1FE00181133F01E113FF267FF9F313C0261FFD-F713000007B512FC000114F06C5C013F1380D90FFEC7FC90383FFF8090B512E048800007-14FC391FFDF7FF267FF9F313C026FFE1F013E00181133F0101131F007CEC07C00030EC01-80000091C7FCA76D5A23277AAE30>I<EA07C0EA0FF0EA1FF8123F13FCA213FEA2121F12-0F1207EA007E13FE13FC1201A2EA07F8EA0FF0123FEAFFE013C01380EA7E0012380F1870-8A30>44 D<120EEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA0E000B0B6E8A30>46-D<16E0ED01F0ED03F8A2150716F0150F16E0151F16C0153F1680A2157F16005D5D14015D-14035D14075D140F5D141F5DA2143F5D147F92C7FC5C5C13015C13035C13075C130F5C13-1F5CA2133F5C137F91C8FC5B5B12015B12035B12075B120F5BA2121F5B123F5B127F90C9-FC5A5AA2127C123825477BBE30>I<EB01FCEB07FF011F13C0497F497F90B57E48EB07FC-3903FC01FE48486C7E497F4848EB3F8049131F001F15C049130F003F15E090C71207A200-7EEC03F0A548EC01F8AD6C1403007E15F0A3007F1407A26C15E06D130FA2001F15C06D13-1F6C6CEB3F80A26C6CEB7F006D5B6C6C485A3901FF07FC6CEBFFF86D5B6D5B6D5B010790-C7FCEB01FC253A7BB830>I<EB0380497EA2130FA2131F133FA2137FEA01FF5A127FB5FC-A213CF138FEA7C0F1200B3B0007FB512F8A2B612FCA26C14F8A21E3976B830>I<EB07FC-90383FFF8090B512F00003804814FE4880261FF8071380EBE000D83F80EB3FC048C7EA1F-E0007E140FED07F000FE1403A26C15F81501A2127EA21218C8FCA2150316F0150716E015-0F16C0151FED3F80ED7F005D4A5A4A5A4A5A4A5A4A5AEC7FC04A5A4990C7FC495AEB07F8-495AEB3FE0495A495A4890C8FCD803FC14F04848EB01F8EA1FF0485A48B6FCB7FCA46C15-F025397BB830>I<EB03FF011F13E090B512F84814FE4880481580260FFC0013C001F013-3FD81FC0EB0FE06D130716F01503A26C5A6C5AC8FC150716E0A2150FED1FC0153FEDFF80-02071300903807FFFE495B5D8115FF6D148090C713C0ED1FE0ED0FF0ED07F8150116FC15-0016FE167EA21218127EB4FCA216FE16FC481401A2007FEC07F86DEB0FF0D83FE0131FD8-1FFCEBFFE06CB612C06C15806C1500C614FC011F13E0010390C7FC273A7CB830>I<EC03-FC4A7E140FA2141FEC3FBE153E147F147E14FEEB01FC14F81303EB07F014E0130F14C013-1FEB3F8014005B13FE5B12015B1203485A5B120F485A5B123F90C7FC5A12FEB8FC1780A4-6C1600C8003EC7FCAA91383FFFFE4A7FA46E5B29397DB830>I<000FB612804815C0A416-800180C8FCAEEB81FF018F13E001BF13F890B57E8181D9FE0113809039F0007FC049131F-49EB0FE04913076CC713F0C81203A216F81501A4123C127EB4FC150316F015074815E000-7E140F007FEC1FC06D137FD83FE0EBFF80261FF80713006CB55A6C5C6C5C6C14E0D8003F-1380D907F8C7FC25397BB730>I<EC0FF0ECFFFE01037F010F14804914C04914E090387F-F00F9039FF8007F048EB000FEA03FC5B485A4848EB07E0ED03C0484890C7FC5B123F90C9-FCA25A127E903803FF80011F13F0D8FE7F7F48B512FE00FD80B7FCD9FC00138001F0EB3F-C001C0131F49EB0FE090C7EA07F0A248140316F81501A3127EA4127F6C14036D14F0A200-1F14076DEB0FE06C6C131F6DEB3FC06C6CEB7F803A03FE01FF006CB6FC6C5C6D13F86D5B-010F13C0D901FEC7FC253A7BB830>I<1278B712FC16FEA416FC00FCC7EA03F8ED07F0ED-0FE00078EC1FC0C8EA3F80ED7F00157E15FE4A5A5D4A5A14075D140F5D4A5AA24AC7FCA2-147EA214FE5C13015CA213035CA213075CA3130F5CA5131F5CA96DC8FCA2273A7CB830>-I<49B4FC011F13F0017F13FC90B57E0003ECFF804815C04848C613E0D81FF8EB3FF001E0-130F4848EB07F849130348C7EA01FC007E1400A5007F14016C15F86D13036C6CEB07F06C-6CEB0FE0D807F8EB3FC03A03FF01FF806C90B512006C6C13FC011F13F0497F90B512FE48-802607FE0013C0D80FF0EB1FE04848EB0FF0D83F80EB03F890C712014815FC007E140000-FE15FE48157EA66C15FE007E15FC007F14016C6CEB03F86D13076C6CEB0FF001F8133FD8-0FFEEBFFE06CB612C06C1580C6ECFE006D5B011F13F0010190C7FC273A7CB830>I<EB01-FC90381FFF80017F13E090B512F8488048803807FE03390FF800FFD81FE0EB7F80484813-3F49EB1FC048C7120F007E15E0150712FE4815F01503A416F8A37E127E007F1407A26C6C-130F6C6C131F6D137F390FF801FF6CB6FC15FD6C14F9C614F36D13C390390FFE03F090C7-FCA2150716E0150F16C0151F121E003FEC3F80486CEB7F005D4A5A4A5AEB000F393FC03F-F890B55A6C5C6C14806C91C7FC000113F838003FC0253A7BB830>I<120EEA3F80EA7FC0-EAFFE0A5EA7FC0EA3F80EA0E00C7FCB1120EEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA0E-000B276EA630>I<EA0380EA0FE0EA1FF0EA3FF8A5EA1FF0EA0FE0EA0380C7FCB1EA0780-EA0FE0EA1FF0123F13F8A4121F120F12071201120313F0A21207EA0FE0121FEA7FC0EAFF-8013005A127C12380D3470A630>I<16E0ED01F0ED07F8150F153FEDFFF04A13E0020713-C04A1300EC3FFEEC7FF8903801FFE0495B010F90C7FC495AEB7FF8495A000313C0485BD8-1FFEC8FC485AEA7FF0485A138013E06C7EEA3FFC6C7E3807FF806C7FC613F06D7EEB1FFE-6D7E010313C06D7F9038007FF8EC3FFEEC0FFF6E13C0020113E06E13F0ED3FF8150F1507-ED01F0ED00E0252F7BB230>I<003FB612FE4881B81280A36C16006C5DCBFCA7003FB612-FE4881B81280A36C16006C5D29157DA530>I<1238127CB4FC7F13E0EA7FF86C7E6CB4FC-00077F6C13E0C67FEB3FFC6D7E903807FF806D7F010013F06E7EEC1FFE6E7E020313C06E-13E09138007FF0ED3FF8150F153FED7FF0913801FFE04A13C0020F13004A5AEC7FF84A5A-010313C0495BD91FFEC7FC495AEBFFF000035B481380001F90C8FCEA3FFC485AEAFFE013-8090C9FC127C1238252F7BB230>I<EB0FFE90B512E0000314F8000F14FE4880481580EB-F0013A7F80003FC000FEC7EA1FE0150F6C1407A3007E140F151FC8EA3FC0EDFF805C0207-13004A5AEC1FF84A5AEC7FC05D4AC7FC495A5C13035C13075CA86D5A90C9FCA9EB01C0EB-07F0A2497EA36D5AA2EB01C023397AB830>I<EC1FE0ECFFF8010313FE010F7F49148049-14C090397FE01FE09038FF800F3A01FE0007F0484813039039F801F9F83907E007FF000F-131F494813FCEA1F80495A48EBFF0F003EEBFC03903901F801FE007EEBF000EA7C034A13-7EA2EAFC0712F84A133EA86E137E12FCD87C03147CA26E13FCD87E0114F8003EEBF80190-3900FC03F0003FEBFF0F6C90387FFFE06D6C13C0EA0FC06D6C13800007903807FE003903-F801F86DC7127C6C6C14FE3900FF800390387FE00F6DB512FC6D14F86D14E0010314C001-00EBFE00EC1FF0273A7CB830>I<EC3F804A7EA44A7EA214FBA201017FA214F1A201037F-A414E001077FA490380FC07EA4011F137F4A7EA449486C7EA4498091B5FCA490B67EA290-38FC0007A2000181491303A3000381491301A2D87FFF90381FFFC06E5AB515E0A26C16C0-4A7E2B397EB830>I<007FB512F0B612FE6F7E82826C813A03F0001FF815076F7E150115-0082167EA516FE5E15015E15074B5AED7FE090B65A5E4BC7FC6F7E16E0829039F0000FF8-ED03FCED00FE167E167F82A2EE1F80A6163F17005EA2ED01FE1503ED0FFC007FB65AB7FC-16E05E93C7FC6C14FC29387EB730>I<007FB512E015FCB67E6F7E6C81823A03F0007FF0-ED1FF815076F7E6F7E1500167FA2EE3F80A2161F17C0A2160FA317E01607AB160F17C0A3-161F1780163FA2EE7F00A216FE15014B5A1507ED1FF8ED7FF0007FB65A5EB75A93C7FC6C-14FC15E02B387FB730>68 D<007FB7128017C0B8FCA27EA2D801F8C7120FA8EE078093C7-FCA5151E153FA490B6FCA69038F8003FA4151E92C8FCAE387FFFF080B5FCA27E5C2A387E-B730>70 D<3B7FFF803FFFC0B56C4813E0A46C496C13C03B03F00001F800B290B6FCA690-38F00001B3A23B7FFF803FFFC0B56C4813E0A46C496C13C02B387EB730>72-D<007FB512FEB7FCA46C14FE390007E000B3B3A8007FB512FEB7FCA46C14FE203878B730->I<D87FFFEB1FFF1780B56C5AA26C497E1700D803E0EB07E0A24B5A4B5A4BC7FC5D157E-5D4A5A4A5AA24A5A4A5A4A5A143F92C8FC147E14FE13E18013E301E77F9038EFCFC014C7-9038FF87E0140301FE7F140101FC7FEBF800497F49137C157E818182150F821507821503-826F7E1500D87FFF903807FF8017C0B56C5AA26C497E17802A387EB730>75-D<387FFFF8B5FC80A25C7ED801F8C9FCB3B0160FEE1F80A9007FB7FCB8FCA46C16002938-7DB730>I<D87FF0EC7FF06D14FF00FF16F86D5B007F16F0A2D807DE903803DF00A301DF-130701CF149FA2EC800FA201C7141FECC01FA201C3131EECE03EA201C1133CECF07CA390-38C0F8F8A3EC78F0147DA2EC3DE0143FA2EC1FC0A2EC0F80EC070091C7FCADD87FFC9038-01FFF0A2486C4913F8A26C486D13F0A22D387FB730>I<D87FF890381FFFC0486C4913E0-A27FA26C6C6D13C0D803EF903800F800A28013E7A28013E380A213E180A213E080A2147C-A380A2141E141FA2801580A2EC07C0A3EC03E0A2140115F0A2140015F8A21578157C153C-A2153E151EA2D87FFF131FB5EA800FA21507A26C496C5A2B387EB730>I<90383FFFE048-B512FC000714FF4815804815C04815E09038F0007F01C0131F4848EB0FF090C71207A200-7E1403A300FE15F8481401B3A96C1403A2007E15F0A3007F1407A26D130F6C6CEB1FE001-F813FF90B6FC6C15C06C15806C1500000114FCD8003F13E0253A7BB830>I<007FB512E0-B612FC15FF16C016E06C15F03903F0003FED0FF8ED03FC1501ED00FEA2167E167F163FA6-167F167E16FEA2ED01FC1503ED0FF8ED3FF090B6FC16E016C0160015FC15E001F0C8FCB0-387FFF80B57EA46C5B28387DB730>I<90390FF801C090397FFF03E048B512C34814F748-14FF5A381FF007383FE001903880007F48C7123F007E141F12FE48140FA21507A46CEC03-C0007E91C7FC127F6C7E13E0EA1FF86CB47E6C13F86CEBFF806C14F0D8003F13FC01077F-9038007FFF020713809138007FC0153FED0FE0ED07F01503A216F80078140112FCA56C14-0316F06C14077F6DEB0FE001F0EB3FC001FE13FF90B61280160000FD5CD8F87F13F8011F-13E0D870011380253A7BB830>83 D<007FB712C0B812E0A53AFC001F8007A80078ED03C0-C791C7FCB3B1010FB5FC4980A46D91C7FC2B387EB730>I<D87FFE90380FFFC0B54913E0-A46C486D13C0D807E0903800FC00A26D130100035DA36D130300015DA36D130700005DA3-6D130F017E5CA3017F131F6D5CA3EC803F011F91C7FCA490380FC07EA46D6C5AA4903803-F1F8A401015B14FBA301005B14FFA36E5AA36E5A2B397EB730>86-D<D87FF8ECFFF0486C4913F8A46C486D13F0001FC8EA07C06C6CEC0F80A76D141F000716-00A73A03E01FC03EEC3FE0A4EC7DF0A30001153C01F0147CECF8F8A59038F1F07C000015-78A201F914F8A2ECE03CA201FB133E017B5CECC01EA4017F131FEC800FA2013F5CA2EC00-07011E6D5A2D397FB730>I<007FB5FCB61280A4150000FCC8FCB3B3B3A5B6FC1580A46C-140019476DBE30>91 D<007FB5FCB61280A47EC7121FB3B3B3A5007FB5FCB6FCA46C1400-19477DBE30>93 D<1307EB1FC0497EEBFFF8000313FE000FEBFF80D81FFD13C0D87FF813-F039FFE03FF8EB800FEB0007007CEB01F00070EB00701D0D77B730>I<EB3FF03801FFFE-0007EBFFC04880488048809038C00FFCEC03FE1400157F6C487F0006C77FC8121FA4EC1F-FF0103B5FC133F90B6FC1203000FEBFC1F381FFE00EA3FF013C048C7FC12FE5AA4153F7E-007F14FF6D5A263FE00FEBFF806CB712C0A26C14EF6C14870001D9FC00138026003FE090-C7FC2A2A7BA830>97 D<EA7FF87F12FFA2127FA21200AAEC03F8EC1FFF027F13C091B57E-90B612F8A29138F80FFC9138E003FE4AC67E4A7F91C7EA3F8049141F17C049140FA217E0-A21607A7160FA26D15C0161FA26DEC3F80167F6EEBFF006E485AECE0039138F80FFC91B5-5A01FD5C01FC5C6E13809026781FFEC7FC90380007F02B397FB730>I<49B47E010F13F0-013F13FC497F48B6FC4815803907FE007F13F8485A485A49EB3F004848130C90C9FC5A12-7EA212FE5AA87E127EA2127FED07806C6CEB0FC07F6C6C131F6C6C148001FC133F6CB4EB-FF006C90B5FC6C5C6C5C013F13F0010F13C0D901FEC7FC222A79A830>I<913803FFC082-5CA280A2EC0007AAEB01FC90380FFF87013F13E790B512F74814FF5A3807FE03380FF800-49137F4848133F4848131F49130F48C7FC1507127E12FEA25AA77E150F127EA2007F141F-7E6D133F6C6C137F6D13FF380FF8012607FE07EBFFC06CB7FC6C02F713E06C14E76D01C7-13C0011F1303D903F8C8FC2B397DB730>I<EB01FE90380FFFC0013F13F090B57E488048-803907FE01FFD9F80013804848133F4848EB1FC049130F484814E090C712075A127E16F0-00FE14035AB7FCA516E000FCC9FC7E127E127FA26C6CEB01E06DEB03F0121F01F013076C-6CEB0FE0D807FE131F3A03FF807FC06C90B512806C15006D5B011F5B010713F0010090C7-FC242A7BA830>I<157F913803FFE0020F13F0143F4A13F8A2ECFF07EB01FE9138FC03F0-903903F800C04A1300A8007FB612C0B712E0A46C15C0260003F0C7FCB3A9003FB6FCA248-1580A26C1500A225397DB830>I<D903FC137F903A0FFF03FFC0013F13CF90B712E05A5A-D9FE07EB07C03B07F801FE0380D9F00090C7FC4848137F497F001F8149131FA66D133F00-0F92C7FC6D5B6C6C13FEEBF8013903FE07FC90B55A5A5D4814C0018F90C8FCEB83FC0180-C9FCA27F12077F6CB512F015FF4815E0488148813A3FC0000FFC49EB00FE007EC8127F00-7C8100FC81178048150FA46C151F007EED3F00007F5D6C6C14FE01E01303D81FFEEB3FFC-6CB65A6C5D000115C06C6C91C7FC011F13FC010113C02B3E7DA730>I<EA7FF87F12FFA2-127FA21200AAEC03F8EC1FFF027F7F91B57E01FD8090B6FC9138F80FF0ECE0074A6C7E14-80EC0001A25BA25BB3A23B7FFFF83FFFF05DB500FC14F8A26C01F814F0812D387FB730>-I<EB01C0EB07F0A2497EA36D5AA2EB01C090C9FCA9383FFFF0487FA47EEA0001B3A9007F-B6128016C0B7FCA27E1680223979B830>I<EA7FF0487EA4127F1200AB0203B512805C17-C0A21780809139001FC0004B5A03FFC7FC4A5A4A5A4A5AEC0FE04A5A4A5A4AC8FC5C01F9-7F01FB7F90B57E14E7ECC3F0EC81F8EC00FC5B49137E497F6F7EA26F7E6F7E6F7EA23B7F-FFF01FFFE0B56C5A17F0A217E06C497E2C387EB730>107 D<387FFFF0B57EA47EEA0001-B3B3A8007FB612E0B712F0A46C15E024387AB730>I<903901F001F03A7F8FFC0FFC3AFF-DFFE1FFE90B5487E92B51280A23A7FFE1FFE1F3B07FC0FFC0FC001F813F89039F007F007-01E013E0A401C013C0B3A23B7FFC1FFC1FFC3BFFFE3FFE3FFEA43B7FFC1FFC1FFC2F2880-A730>I<EC03F8397FF81FFFD9FC7F7F00FF90B57E01FD806CB6FC9138F80FF0C6EBE007-4A6C7E1480EC0001A25BA25BB3A23B7FFFF83FFFF05DB500FC14F8A26C01F814F0812D28-7FA730>I<EB01FC90380FFF80013F13E090B512F8488048803907FE03FF260FF8001380-49137FD81FC0EB1FC0A24848EB0FE090C712074815F0007E1403A200FE15F8481401A86C-1403007E15F0A2007F1407A26C6CEB0FE06D131F6C6CEB3FC06D137F6C6CEBFF802607FE-0313006CB55A6C5C6C5C013F13E0010F1380D903FEC7FC252A7BA830>I<EC03F8397FF8-1FFFD9FC7F13C000FF90B57E90B612F87E9138F80FFCC69038E003FE4AC67E4A7F91C7EA-3F8049141F17C049140FA217E0A21607A7160FA26D15C0161FA26DEC3F80167F6EEBFF00-6E485AECE0039138F80FFC91B55A01FD5C01FC5C6E1380DA1FFEC7FCEC07F091C9FCAD38-7FFFF8A2B57EA26C5BA22B3C7FA730>I<903901FC01E090390FFF83F0013F13E390B512-F34814FB4814FF481301380FF80049133F4848131F4848130F5B48C71207A2127E150312-FE5AA77E1507127E127F150F6C7E151F6C6C133F6D137FD80FF813FF3807FE036CB6FC6C-14FB6C14F36D13C3011F1303EB03F890C7FCAD4AB512E04A14F0A46E14E02C3C7CA730>-I<ED0FF0D87FFFEB7FFEB50081B5FC1487028F1480149F6C9038BFF07F39001FFFC09238-003F004A130C4A90C7FC5C5C5CA25CA45CAF007FB512FCB6FC81A25D7E29287DA730>I<-90381FFC0E90B5129F000714FF5A5A5A387FE007EB800100FEC77E5A81A37E007F141E01-C090C7FCEA3FF8381FFFE06C13FF000314C0C614F0010F13FC9038007FFEEC03FFEC007F-0078EC3F8000FC141FED0FC0A27EA27E151F01C0EB3F806D137F9039F803FF0090B6FC5D-5D00F814F0013F13C0267007FEC7FC222A79A830>I<EB0780497EAA007FB612E0B712F0-A46C15E026000FC0C7FCB2167816FCA5ECE001ED03F8903807F0079138FC0FF06DB512E0-7F16C06D1400EC3FFCEC07F026337EB130>I<D87FF8EBFFF06D8000FF5BA2007F7FA200-001401B3A41503A21507150F6D131F903A7F807FFFF091B6FC6D15F8A26D01F913F00107-13E0010090C8FC2D287FA630>I<3B7FFF803FFFC0B56C4813E0A46C496C13C03B01F000-01F000A26D130300005DA2017C495AA36D495AA36D49C7FCA390380F803EA36D6C5AA2EC-E0FC01035BA214F101015BA214FB01005BA214FF6E5AA3021FC8FC2B277EA630>I<3B7F-FF800FFFF06E5AB515F8A26C16F04A7ED807C0C7EA1F00A26D5C0003153EA56D147E0001-157CEC0FC0EC1FE0EC3FF0A32600F87F5BEC7DF8147CA214FC01786D5AA290387CF87C13-7D157D14F0013DEB3DE0013F133FA2ECE01FA2011F5C6D486C5A2D277FA630>I<263FFF-C0B5FC48168014E1A214C06C16003A007E001F806D49C7FCEB1F80157E6D6C5A6D6C5AEB-03F1903801F3F0ECFFE06D5B147F6E5A92C8FCA2814A7E4A7EEB01F3ECF1F0903803E0F8-49487E010F137C49487EEC003F496D7E017E6D7E4913073B7FFF803FFF806E4813C0B5FC-A27E4A6C13802A277EA630>I<3B7FFF803FFFC06E4813E0B5FCA27E4A6C13C03B01F800-01F000120015036D5C137C4B5A7FA2013F495A7FA26E48C7FC130F14C00107133EA214E0-01035BA2EB01F05DA2EB00F85D1479147D5D143FA26E5AA36E5AA2141F92C8FCA25C143E-A2147E147C120F486C5AEA3FC113C3EB07F0495A13FF6C5B5C6C90C9FCEA07FCEA01F02B-3C7EA630>I<1238127C12FEB3B3B3AD127C123807476CBE30>124-D E-%EndDVIPSBitmapFont-%DVIPSBitmapFont: Fb cmmi10 10.95 3-/Fb 3 98 df<17035F5FA25F5FA24D7EA217FF5EA2EE037FA21606160E160C04187FA216-30EE703F166016C0A2ED0180150316001506845D031C131F15185DA25DA25D4A5A844AC7-FC170F4AB6FC5CA20218C7120FA25C5C845CA24948140749C8FCA21306A25B131C131801-788213FCD807FEED1FFE267FFFE00107B512F8B5FC6C5B3D417DC044>65-D<91B712F84916FF19E090260001FEC7EA3FF04BEC07F8727E727E854A4880A21A80A24A-48157F19FFA34A481600606118034A485D4E5A180FF01FE04A484A5A4E5ADD01FEC7FCEF-07F84AC7EA7FE092B6C8FC18E092C7EA07F802FEEC01FE717E727E727E495A85181FA249-5A85A349485E183FA2614948157F6118FF4D90C7FC49485D17034D5AEF1FF049484A5AEF-FFC0017F020790C8FC007FB712FCB812F06C93C9FC413E7DBD45>I<143F903801FFC090-3903E0E0E090390F8031F090381F001B133E49EB0FE05B485A000314074848EB0FC0A248-5AA2001FEC1F805B123FA248C7EA3F00A400FE147EA4EDFC01481503A3913801F806127C-1403007E150C003E1307140C6C013813186CEB70783A0781C038703A03FF801FE03A007E-000F8028297CA730>97 D E-%EndDVIPSBitmapFont-%DVIPSBitmapFont: Fc cmsy10 10.95 4-/Fc 4 107 df<D91FE01620D97FF816703801FFFE486D7E48804814F09026E01FF815F0-391F8007FC273E0001FE15E0003CD9007F140148EC3FC0DB0FE0EB03C00070DA07F81307-00F0DA03FEEB1F80923A01FF807F00486E90B5FC043F5B705B04075B040113E000409238-007F803C157BA047>24 D<153FEC03FFEC0FE0EC3F00147E5C495A495AA2495AB3AA5C13-0F5C131F49C7FC13FEEA03F8EA7FE048C8FCEA7FE0EA03F8EA00FE133F6D7E130F801307-80B3AA6D7EA26D7E6D7E147E80EC0FE0EC03FFEC003F205B7AC32D>102-D<127CEAFFC0EA07F0EA00FC137E7F6D7E6D7EA26D7EB3AA1303801301806D7E147FEC1F-C0EC07FEEC00FFEC07FEEC1FC0EC7F0014FC495A5C13035C1307B3AA495AA2495A49C7FC-137E5BEA07F0EAFFC0007CC8FC205B7AC32D>I<126012F0B3B3B3B3B11260045B76C319>-106 D E-%EndDVIPSBitmapFont-%DVIPSBitmapFont: Fd cmbx10 10.95 52-/Fd 52 121 df<EDFFE0020F13FC027F13FF903A01FFC01F80903A07FC0007C04948497E-D91FE0497E4948133F834948137FA249C7FCA2705AA2705AEE078093C8FCA6EE07F8B8FC-A4C6903880001F160FB3AD003FD9FE03B512E0A433407EBF3A>12-D<D80780130FD81FE0EB3FC0486CEB7FE0486CEBFFF0A2486C4813F8A201FE14FCA2007F-7FA2003F147FD81FEEEB3FDCD8078EEB0F1CD8000E1300A2491438A4491470A24914E0A2-49EB01C0000114034848EB07804848EB0F0048C7121E001E5C001C14380018143026207D-BE37>34 D<143CA449B47E011F13F0017F13FC90B6FC3A03FE3C7FC0D807F0EB0FE0D80F-E0EB03F0D81F801301ED00F8D83F001478163C007E15FCED03FE150712FE150FA27EA201-80EB07FC01C0EB03F801E0EB01F001F090C7FCEA7FFEEBFFFC806CEBFFE015F86C806C14-FF16806C15C06C15E0C6FC6D14F0131F010314F8EB003F16FCEC3C3F151FED0FFE001F14-07D87FC013031501EAFFE01500A313C016FC1380EA7E000078EC01F8127C003C15F0003E-14036CEC07E0D80FC0EB0FC0D807E0131FD803FEEBFF006CB55A6C6C13F8011F13E00103-90C7FCEB003CA427497AC334>36 D<EC01FCEC07FF021F7F91387F83C09138FE01E09038-01FC0049487F13071678495AA3131FA2167016F05E15016E485AA24B5A4BCAFC010F131E-6E5A4B91381FFFFE5D6DB45A5D4B9138007F006D90C9123C6F157C616D6D5D4E5A496D14-03495F496C6C4A5A011E6D140FD93C3F93C7FC01FC6D141E48486C6C143E00036D6C5C00-076F137848486C5D001F6DEBC001003F6F485A6E6D485A007F6D01F85B6F6C48C8FC00FF-6E6C5A031F133E6F6C5A6F5B6D6D49143C6F5B007F6E13F8706C14786C6C6F14F86C6C49-B513016DD90FF39038C003F000079026807FE19038F80FE06C90B5D8807FB512C0C69126-FE000F1480013F01F00103EBFE00010390C8EA3FF047417CBF51>38-D<1407140F141E143C147CEB01F8EB03F014E0EB07C0130FEB1F80EB3F00A2137E13FE5B-12015B12035B1207A2485AA3121F5BA2123FA3485AA612FFB0127FA66C7EA3121FA27F12-0FA36C7EA212037F12017F12007F137E7FA2EB1F80EB0FC01307EB03E014F0EB01F8EB00-7C143C141F140F1407185A76C329>40 D<126012F012787E123E6C7E6C7E12076C7E7F6C-7E6C7EA2137E137F7F1480131F14C0130F14E0A2EB07F0A314F81303A214FCA3EB01FEA6-14FFB014FEA6EB03FCA314F8A2130714F0A3EB0FE0A214C0131F1480133F14005B137E5B-A2485A485A5B485A120F485A003EC7FC123C5A5A1260185A7AC329>I<14F8497EA2497E-6D5AA4007CEC01F000FEEC03F839FF00F80701C0131F01E0133F01F0137F9038FCF9FF26-3FFEFB13E00007B61200000114FCD8003F13E0010790C7FCA2013F13E048B512FC000714-FF263FFEFB13E026FFFCF913F89038F0F87F01E0133F01C0131F0100130739FE01FC0300-7CEC01F0000091C7FCA4497E6D5AA26D5A252879C334>I<16F04B7EB3AD007FBA12E0BB-12F0A46C19E0C8D801F8C9FCB3AD6F5A44467AB951>I<B612E0A81B087F9723>45-D<EA0780EA1FE0EA3FF0EA7FF8A2EAFFFCA4EA7FF8A2EA3FF0EA1FE0EA07800E0E798D1D->I<ECFFE0010713FC011F13FFD97FE013C09039FF803FE03A01FE000FF000038148486D-7E491303000F81001F81A348486D1380A3007F16C0A500FF16E0B3A2007F16C0A5003F16-80A26D5B001F1600A2000F5D6D130700075D6C6C495A6C6C495A6C6D485A90397FE0FFC0-011FB5C7FC010713FC010013E02B3D7CBB34>48 D<141E143E14FE1303131FEA03FFB5FC-A213E7EAFC071200B3B3AA007FB612F0A4243C78BB34>I<903803FF80011F13F090B512-FE00036E7E2607FC077F260FE00113F0261F80007F48C76C7E6D133FD87FE06D7E7F00FF-816D7F1780A46C5A6C5A6C5A0007C7FCC81400A25D5EA24B5A5E4B5A4B5A5E4A5B4A90C7-FC5D4A5AEC0FF04A5A4A5A4AC8FC14FE4948EB0780495A5CD907C0EB0F00495A49C7FC13-3E495C13F048B7FC485D5A5A5A5A5AA2B75AA3293C7BBB34>I<ECFFE0010F13FC013FEB-FF80D9FF0113E03A01F8007FF0D803E06D7E48486D7E13F0486C807F486C80A5120F495C-1207EA03F0C8485A5EA24B5A5E4B5A4A90C7FCEC0FFC903807FFF015FE6F7ED9000113E0-9138007FF86F7E6F7E6F7EA217806F13C0A3D8078015E0EA1FE0487E487EA2487EA217C0-A36C484913805B6C48150049495A001F143FD80FF0EB7FF83A07FE01FFF00001B65A6C15-80011F01FCC7FC010113C02B3D7CBB34>I<ED01F0A215031507150F151FA2153F157F15-FFA25C5C5CEC0FBF153F141E143C147C147814F0EB01E0130314C0EB0780EB0F005B133E-133C5B5B12015B485A485A120F48C7FC121E5A5A12F8B812F8A4C8387FF000AB49B612F8-A42D3C7DBB34>I<EA0780EA1FE0EA3FF0EA7FF8A2EAFFFCA4EA7FF8A2EA3FF0EA1FE0EA-0780C7FCACEA0780EA1FE0EA3FF0EA7FF8A2EAFFFCA4EA7FF8A2EA3FF0EA1FE0EA07800E-2879A71D>58 D<EB0FFF90B512F0000314FC390FF007FF261F80011380D83E0014C0003F-6D13E0487E7F486C14F0A46C5A16E06C5A260E000113C0C7FC4A13804A1300EC0FFC15F0-4A5A5D4A5A92C7FC147E147C5CA25CA213015CA990C9FCA8EB01E0EB07F8497E497EA249-7EA46D5AA26D5A6D5AEB01E024407ABF31>63 D<16FCA24B7EA24B7EA34B7FA24B7FA34B-7FA24B7FA34B7F157C03FC7FEDF87FA2020180EDF03F0203804B7E02078115C082020F81-4B7E021F811500824A81023E7F027E81027C7FA202FC814A147F01018291B7FCA24982A2-D907E0C7001F7F4A80010F835C83011F8391C87E4983133E83017E83017C8148B483B500-FC91B612FCA4463F7CBE4F>65 D<B812F8EFFF8018F018FC26003FFCC7EA3FFEEF0FFF71-13807113C019E08319F08319F8A719F05FA24D13E019C04D13804D13004D5AEFFFF891B7-12E095C7FC18F002FCC7EA3FFE943807FF807113C07113E07113F0F07FF819FC183F19FE-A219FFA819FEA2187F19FCF0FFF85F4D13F04D13E0053F13C0BA120018FC18F095C7FC40-3E7DBD4A>I<BAFCA426003FFEC7001F138017031700187F183F181F180F19C01807A218-03A2EE03C0A219E01801A3040790C7FCA2160F161F167F91B6FCA49138FE007F161F160F-1607A20403143CA31978A393C8FCA219F819F0A21801A21803A21807F00FE0181F187FEF-01FF171FBAFC19C0A33E3D7DBC45>69 D<B912FEA426003FFEC7EA3FFF17071701838484-841980180FA21807A3EE078019C01803A395C7FC160FA2161F163F16FF91B6FCA44AC6FC-163F161F160FA21607A693C9FCAEB712E0A43A3D7DBC42>I<922607FFC0130E92B500F8-131E020702FF133E021FEDC0FE027F9038003FF1902601FFF0EB07FB010701C0EB00FF49-90C8127FD93FFC153F4948150F49481507485B4A1503481701485B18004890CAFC48187E-A25B003F183EA2127F5B96C7FCA212FFAB0407B612FC127FA27F93C7383FFE00123FA212-1F7FA27E6C7FA26C7F6C7FA26C7F6D7ED93FFE157FD90FFF15FF6D01C05B010101F05B6D-6CB4EB1FF1021F90B512C00207ED003E020002FC130E030701C090C7FC46407ABE52>I<-B71280A426003FFEC7FCB3B3B2B71280A4213E7DBD28>73 D<B712E0A426003FFEC9FCB3-AF181EA4183CA4187CA318FCA2EF01F8A217031707170F173F17FF1607B912F0A4373E7D-BD3F>76 D<B500FE050FB512C06E5F6F5EA2D8003F97C7FC6F1677A2013E6D16E7A26E6C-ED01C7A26E6CED0387A36E6CED0707A26E6C150EA26E6C151CA26E6D1438A36E6D1470A2-6E6D14E0A26F6CEB01C0A26F6CEB0380A36F6CEB0700A26F6C130EA26F6C5BA26F6D5AA3-6F6D5AA26F6D5AA293387FF1C0A293383FFB80A370B4C7FCA2705AA2705AA2705A137FB6-0080031FB612C0705AA2705A5A3E7CBD63>I<ED3FFF0203B512F0021F14FE913A7FF807-FF80902701FFC00013E0010790C7EA3FF8D90FFCEC0FFCD93FF86EB4FC49486E7F49486E-7F48844A8048496F7E488491C9123F4884488449161FA2003F84A34848701380A400FF19-C0AD007F19806D5EA3003F1900A26D5E6C60A26C6D4B5AA26C6D4B5A6C606E5C6C606C6D-4A5B6D6C4A5BD93FFE021F90C7FC6D6C4A5A010701C0EBFFF80101D9F80713E06D90B65A-021F4AC8FC020314F0DA003F90C9FC42407ABE4F>79 D<B812C017FCEFFF8018F028003F-FC000113FC9338003FFE717E05077F717F85A2717FA285A761A24D5BA24D5B61DD1FFEC8-FC4D5A933803FFF091B712C04DC9FCA2913AFC0007FF8004017F7013F0717E84173F8417-1F84A685A5F20180F203C019C083A271EC078019E0B76D9038F00F000500EBF81E95387F-FFFC060F5BCC13E04A3F7DBD4E>82 D<903A01FF8001C0011FEBF803017FEBFE0748B612-8F489038007FDFD807F8EB0FFF484813034848130049147F003F153F49141F127F160F16-0712FFA36D1403A27F7F01FC91C7FC6CB4FC14F8ECFF806C14FCEDFF806C15E0826C15FC-6C816C816C16806C7E011F15C0010715E0EB007F020314F0EC003F1503030013F8167F16-3F127000F0151FA2160FA36C16F0A36C16E06C151F6C16C07F6DEC3F8001F0147F01FCEC-FF003AFEFFE007FED8FC3FB512F8D8F80F14E0D8F003148027E0001FFCC7FC2D407ABE3A->I<B600FE020FB512C0A4C66C90C9383FC000735A6D6D4BC7FC6D6D157EA26D6D5D6D6D-4A5A816D4C5A6D6D4A5A816D4C5A6E6C4A5A6E7F4EC8FC6E6D137E6E7F606E6D485A6E13-F84D5A6E6D485A6E13FE70485A6F495A6F139F05FFC9FC6F5B815F6F5B816F5B5FB3A302-07B612F8A44A3E7EBD4F>89 D<B5FCA6EAFC00B3B3B3B3A7B5FCA6105B76C31D>91-D<1304130E131FEB7FC0497E487F487F487F380FF1FE393FC07F80397F803FC039FE000F-E04813070070EB01C00020EB00801B0F74BE34>94 D<903807FF80013F13F848B512FE3A-03FC01FF803A07E0007FC0486C6D7E6D6D7E486C6D7EA28215076C4880A26C5AEA01C0C8-FCA3EC3FFF0103B5FC131F9038FFFC074813E000071380380FFE00485A485A485AA25B12-FFA3150FA2007F141F6D131D6C6C903839FF806C6C01F813FE390FFE03F00003B5EAC03F-C6EC000FD90FFC90C7FC2F2B7DA933>97 D<EA01FE12FFA412071203B04AB47E020F13F0-023F13FE91397F01FF809139F8007FC0D9FFE06D7E4A6D7E4A6D7E91C77F707EA2838218-80A318C0AA1880A34C1300A25FA26E495A4C5A6E5C6E495AD9FCF8EBFFC09026F87E0390-C7FC9039F03FFFFCD9E00F13F0C7000190C8FC32407CBE3A>I<EC7FF00103B5FC011F14-C090393FE01FE09039FF8003F04890380007F84848130F0007EC1FFC485A121F5B003FEC-0FF8A249EB07F0007FEC01C092C7FCA212FFAA127FA36C7E161E121F7F000F153C6C6C14-7C16F8D801FFEB01F06C90388003E090397FE01FC0011FB512800107EBFC009038007FE0-272B7DA92E>I<EE0FF0ED07FFA4ED003F161FB0EC3FF0903803FFFC010F13FF90393FF0-1FDF9039FFC003FF48EB000148487F0007157F4848143F485AA2123FA2485AA312FFAA12-7FA3123F7F121FA26C6C147F000715FF6C6C5B6C6C497F6C6D48EBFFC090397FE03FBF90-391FFFFE3F010313F89026007FE0EBC00032407DBE3A>I<EC7FE0903807FFFC011F13FF-90397FE07FC09039FF801FE048496C7E48486D7E48486D7E120F48486D7EA2003F815B00-7F80A21780A212FFA290B7FCA301F0C9FCA4127FA46C7EEE0780121F120F6DEC0F000007-5D6C6C143E6C6C5C6C9038C001F890393FF00FF0010FB512C0010391C7FC9038003FF029-2B7DA930>I<EC0FF8EC7FFF49B51280903907FC1FC090390FF03FE0EB1FE090393FC07F-F01480137FA29138003FE05BED0F8092C7FCABB612E0A4C60180C7FCB3AE003FEBFF80A4-24407DBF20>I<903A03FF8007F0011F9038F03FF8017F9038FCFFFC3B01FF01FFF8FE48-486C13C04848137F484890383FE0FC177C484890381FF000A2003F81A7001F5DA26C6C49-5AA26C6C495A6C6C495A6D4890C7FCECFFFCD8079F13F00103138048CAFCA47F7F7F90B5-12FE6CECFFE016FC6C15FF17806C16C04816E0120F271FE0000113F0D83F80EB001F48C8-120FEE07F800FE1503A5007E16F0007F15076C6CEC0FE06D141F6C6CEC3FC0D80FF8ECFF-803B03FF800FFE00C690B512F8011F14C0010101FCC7FC2F3D7DA834>I<EA01FE12FFA4-12071203B0ED3FF0EDFFFE02036D7E91390FC07FC04AC66C7E143C4A804A131F5C6D4880-A25CA291C7FCB3A6B5D8FC07B512E0A4333F7CBE3A>I<EA01E0EA07F8487E487EA2487E-A46C5AA26C5A6C5AEA01E0C8FCA913FE12FFA412071203B3ADB512F0A414407BBF1E>I<-EA01FE12FFA412071203B3B3B1B512F8A4153F7BBE1E>108 D<D801FED93FF049B47E00-FFDAFFFE010713F002039026FF801F13FC913C0FC07FC07E03FE913C1F003FE0F801FF00-07013CECE1E0000349DAF3C014804A90391FF780004A92C7FC6D4802FE15C0A24A5CA291-C75BB3A6B5D8FC07B5D8E03F13FFA450297CA857>I<D801FEEB3FF000FFECFFFE02036D-7E91390FC07FC04AC66C7E0007133C000349804A131F5C6D4880A25CA291C7FCB3A6B5D8-FC07B512E0A433297CA83A>I<EC7FF0903803FFFE011FEBFFC090397FE03FF09039FF80-0FF848496C7E48486D7E48486D7E48486D1380001F16C0A2003F16E049147F007F16F0A4-00FF16F8AA007F16F0A46C6CECFFE0A2001F16C0000F16806D5B6C6C4913006C6C495A6C-6D485A3A007FE03FF0011FB512C0010791C7FC9038007FF02D2B7DA934>I<3A01FE01FF-8000FF010F13F0023F13FE91397F03FF80DAF8007F2607FFE06D7E6C496D7E4A6D7E91C7-6C7E83A2707EA21880A28218C0AA18805EA21800A24C5AA26E495A5F6E495A6E495A02F8-495ADA7E0790C7FC91383FFFFC020F13F0020190C8FC91CAFCADB512FCA4323B7CA83A>-I<DA3FE01370902603FFFC13F0010FEBFE0190393FF81F839039FFC007C34890388003E7-4890380001EF4848EB00FF000F157F485A163F485AA2127F161F5B12FFAA127F7FA2123F-163F6C7E167F120F6C6C14FF6C6C5B6C6D5A6C6D5A90397FF03F3F90381FFFFE010313F8-9038007FC091C7FCAD030FB512C0A4323B7DA837>I<3901FC03F800FFEB0FFF4A13C091-383C1FE0EC783F00079038F07FF03803FDE014C0EBFF80ED3FE0A29138001FC0ED070092-C7FCA25BB3A4B512FEA424297CA82B>I<90381FFC0E90B5123E000314FE380FE007381F-8000003EC7127E153E5A151E12FCA27E7E6D90C7FC13E06CB47E14FC6CEBFF8015E06C80-6C14FC000380C680133F01031480EB000F020113C00070EB007F00F0143F151F6C140FA3-6C1580A27E6CEC1F006D133E6D137E9038F803FC00FCB512F0D8F83F13C026E007FEC7FC-222B7DA929>I<EB0780A5130FA4131FA3133F137FA213FF5A1207001FEBFFFEB6FCA300-01EB8000B3A2150FA96C141E14C0017F131C90383FE03CECF07890380FFFF0010313E090-38007F80203B7EB929>I<01FFEC07F8B5EB07FFA40007EC003F6C151FB3A7163FA2167F-7E16EF6CD980017F923903CFFFE090397FE01F8F011FB5120F010713FC010001E0EBF000-332A7CA83A>I<B500F890381FFFC0A400030180903803F0006C6F5A6E13036C5E80017F-4A5AA26E130F013F92C7FC6E5B011F141E6E133E010F143C6E137C010714786E13F86D5C-15816D5C15C16DEBC3C0A215E7027F5B15FF6E90C8FCA26E5AA26E5AA26E5AA26E5AA26E-5A32287EA737>I<B5D8F801B5FCA40001903980003FC06C6D91C7FC6D6C133E6D6C5B6E-5B6D6C485A010F495A6D6C485A903803FF0F6DEB9F8003FFC8FC6D5B6E5A6E5A141F6E7E-81814A7F5C027E7F91387C7FE04A6C7ED901F07F49486C7E49486C7E90380F8007011F6D-7E49486C7F017E81017C6D7FD801FC6E7EB5D88003B512C0A432287EA737>120-D E-%EndDVIPSBitmapFont-%DVIPSBitmapFont: Fe cmr10 10.95 76-/Fe 76 123 df<DA03FFEB0FE0021F9038C07FF8913AFE00F1F81CD901F890383BE03ED9-07E090387FC07F49489038FF80FF49485AD93F005C013E167E017E163C6F48130049147E-AEB91280A3D800FCC7007EC7FCB3AE486C14FF277FFFF83F13FFA338407FBF35>11-D<EC03FC91383FFF809138FE03C0903901F00060D907E07FD90F8013F84948487E491303-133E137EA2496D5A6F5A93C7FCABED01FCB7FCA33900FC000315011500B3AC486C497E3B-7FFFF87FFFF8A32D407EBF33>I<DA03FEEB01FE913B1FFF801FFFC0913BFE01E07F01E0-903C01F00070F80030D907E0D91BF07FD90F80D97FC0137C011F4A4813FE494848140101-3E1500137EA2496D486D5A047E147896C7FCAB19FEBAFCA3D800FCC7387E00011800197E-B3AC486C02FF14FF277FFFF83FD9FC3F13FCA346407EBF4C>14 D<001E130F003FEB1F80-397F803FC039FFC07FE0A201E013F0A2007F133F393F601FB0001EEB0F3000001300A549-1360A3484813C0A23903000180A20006EB0300A2481306485B485B002013101C1C7DBE2D->34 D<14E0A4EB07FC90383FFF804913E03901F8E3F03903E0E078D80780131CD80F007F-001E8081481580007C14011278ED06C000F8140F151F153FA36CEC1F80ED0F0092C7FC12-7E127FA2EA3FC013E0EA1FFE13FF6C13FC6C13FF6C14C06C806C6C7F011F7F01037F0100-7F14E7ECE1FFECE07FED3F80151FA2ED0FC01218123C007E1407B4FCA35A5A00C0158012-60150F16006C5C151E6C5C121C6C14F8390780E1F03903F0EFE0C6B51280D93FFEC7FCEB-0FF8EB00E0A422497BC32D>36 D<EC0F80EC3FC0ECF06049487E49487EA2EB0780010F7F-A3131F1400A314805DA35D5DA2010F5BECC180A202C3CAFC14C6D907EC91383FFFFC14F8-A24A020313C00103923800FE0018786D6C157001031660496C15E0010C5E496C4A5AEB30-7ED9607F4AC7FCD9E03F1406D801C07F0003011F5C01807F00076D6C5B000F01075CD81F-007F486D6C5B48010114E06F5B6E6C485A48DA7F03C8FCA2ED3F86ED1FCCDB0FF814186D-1307007F6E5A7014386F6C14306C6C496C1470001FDA0F7F14E06C6C90391E1FC0016C6C-903AF80FE003C03D03FC07F007F80F806CB5D8C001B512006C6C90C7EA7FFCD90FF8EC0F-F03E437CC047>38 D<121E123FEA7F80EAFFC0A213E0A2127FEA3F60121E1200A513C0A3-EA0180A2EA0300A21206A25A5A5A12200B1C79BE19>I<1430147014E0EB01C0EB0380EB-0700130EA25B5B1378137013F05B1201485AA2485AA348C7FCA35A121EA2123EA2123CA2-127CA5127812F8B21278127CA5123CA2123EA2121EA2121F7EA36C7EA36C7EA26C7E1200-7F1370137813387F7FA27FEB0380EB01C0EB00E014701430145A77C323>I<7E7E7E1270-7E7E7EA27E6C7E7F12017F12007F1378A27FA37FA3131F7FA21480A21307A214C0A51303-14E0B214C01307A51480A2130FA21400A25B131EA35BA35BA25B5B12015B12035B48C7FC-120EA25A5A5A5A5A5A135A7AC323>I<EB03C0A2805CA600F0140F00FC143F00FE147F00-FF14FF393FC3C3FC390FE187F03903F18FC03900FDBF00EB3FFCEB0FF0EB03C0EB0FF0EB-3FFCEBFDBF3903F18FC0390FE187F0393FC3C3FC39FF03C0FF00FE147F00FC143F00F014-0F00001400A6805CA220277AC32D>I<1506150FB3A9007FB912E0BA12F0A26C18E0C800-0FC9FCB3A915063C3C7BB447>I<121E123FEA7F80EAFFC0A213E0A2127FEA3F60121E12-00A513C0A3EA0180A2EA0300A21206A25A5A5A12200B1C798919>I<B512FEA517057F95-1E>I<121E123FEA7F80EAFFC0A4EA7F80EA3F00121E0A0A798919>I<ED0180ED03C0A215-071680A2150F1600A25D151EA2153E153CA2157C157815F85DA214015DA214035DA21407-5DA2140F92C7FCA25C141EA2143E143CA2147C1478A214F85CA213015C13035CA213075C-A2130F91C8FCA25B131EA2133E133CA2137C1378A213F85BA212015BA212035BA212075B-120F90C9FCA25A121EA2123E123CA2127C1278A212F85AA21260225B7BC32D>I<EB01FE-90380FFFC090383F03F090387C00F849137C48487F48487F4848EB0F80A2000F15C04848-EB07E0A3003F15F0A290C712034815F8A64815FCB3A26C15F8A56C6CEB07F0A3001F15E0-A36C6CEB0FC0A26C6CEB1F80000315006C6C133E6C6C5B017C5B90383F03F090380FFFC0-D901FEC7FC263F7DBC2D>I<14C013031307131F137FEA07FFB5FC139FEAF81F1200B3B3-ACEB7FF0B612F8A31D3D78BC2D>I<EB07FC90383FFF8090B512E03901F01FF039038003-FC48486C7E000C6D7E48EC7F8012380030EC3FC012700060EC1FE0A212FE6C15F07F150F-A36CC7FC003E141F121CC813E0A3ED3FC0A2ED7F8016005D5D4A5A5D4A5A4A5A4A5A5D4A-C7FC143E5C14F0495A5C495A49C8FC010E14305B5B5B4914605B485A48C8FC000615E000-0FB6FC5A5A4815C0B7FCA3243D7CBC2D>I<EB07FC90383FFF809038F80FE03901C003F8-48C66C7E00066D7E48147F481580EA1F80486C14C06D133FA46C5A6C48137F6CC71380C8-FCA216005D5D5D4A5A5D4A5AEC0FC0023FC7FCEB1FFCECFF809038000FE0EC03F0EC01FC-6E7E157F1680153F16C0A2ED1FE0A216F0A2120C123F487E487EA316E05B153F6CC713C0-12606CEC7F80003815006C14FE6C495A3907C003F83903F80FF0C6B55A013F1380D907FC-C7FC243F7CBC2D>I<150EA2151E153EA2157E15FEA214011403157E1406140E140C1418-14381430146014E014C0EB0180130314001306130E130C5B133813305B13E05B485A1203-90C7FC1206120E120C5A123812305A12E0B8FCA3C8EAFE00AC4A7E49B6FCA3283E7EBD2D->I<00021403D807C0130F01F813FE90B55A5D5D5D158092C7FC38063FF890C9FCADEB01-FE90380FFF8090383E03E090387001F09038C00078D80780137C90C77E153F0002EC1F80-C8FC16C0A2ED0FE0A316F0A4123E127F5A7FA290C713E0A248141F006015C0A200701580-0030143F003815000018147E000E5C6C495A3903C003F03901F00FE06CB55A013F90C7FC-EB07F8243F7CBC2D>I<EC1FE0ECFFF8903803F01C903807800690381F0003013EEB0180-49130F49EB1FC04848133FA2485A120749EB1F80000FEC0F0092C7FC485AA2123FA348C9-FCA2EB01FE903807FF8090380E03E039FF1800F049137849137C8149133FED1F80A24914-C0150F16E0A290C7FC16F0A47EA57E7F16E0A2121FED1FC0120F6D14800007EC3F007F00-03147E6C6C137C6C6C485A90387E07F090383FFFC0010F5BD903FCC7FC243F7CBC2D>I<-12301238123E003FB612FCA316F84815F0A216E00070C812C00060EC0180A2ED03001506-5A5D5DA2C85A5D15E05D4A5A140392C7FC1406A2140E5CA2143C14381478A214F85CA213-01A21303A3495AA4130FA6131FA96D5A6D5A26407BBD2D>I<EB03FC90381FFF8090383C-03E09038E000F04848133C48C77E4880120EED07805AED03C0A2123CA3123EA2003FEC07-807FD81FE014006D5B6C6C131E01FE131C6C6C5B6CEBC0F06CEBE1E06CEBFF806D48C7FC-6D7E010F7F15E0497F017813FC9038E03FFE48486C7E3803800748486C1380000E010013-C0001E147F48EC1FE00038140F00781407ED03F0481401A31500A416E01278ED01C07EED-03807E6CEC07006C6C131ED803E0137C3901FC03F039007FFFE0011F1380D903FCC7FC24-3F7CBC2D>I<121E123FEA7F80EAFFC0A4EA7F80EA3F00121EC7FCB3121E123FEA7F80EA-FFC0A4EA7F80EA3F00121E0A2779A619>58 D<EB1FF890B5FC3903E01FC039070007F000-0CEB01F84814FC4813004814FE127C00FE14FF7EA4127E003C14FEC7120115FC140315F8-EC07E0EC0FC0EC1F801500143E143C5C147014F05C495AA35C1303A291C7FCA990C8FCA9-EB0780497E497E497EA46D5A6D5A6D5A20407BBF2B>63 D<1507A34B7EA34B7EA24B7EA3-4B7E156FA2EDEFF815C7A291380187FC1583A291380303FE1501A291380600FFA34A6D7E-A34A6D7EA34A6D7EA20270800260130FA202E0804A1307A201018191B6FCA2498191C712-01A201068182A2496F7EA3496F7EA3496F7EA21370717E13F0486C82D80FFEED3FFCB500-E0010FB512F8A33D417DC044>65 D<B712FCEEFF8017F00001903980000FF86C6CC7EA03-FEEE00FFEF7F80EF3FC018E0171F18F0170F18F8A31707170FA318F0171F18E0173F18C0-EF7F80EFFF00EE03FCEE0FF8EE7FE091B6C7FC17E091C7EA03FCEE00FEEF7F80EF3FC0EF-1FE0EF0FF018F8170718FC1703A218FEA718FC1707A2EF0FF8EF1FF0A2EF3FE0EFFFC04C-138048486C90380FFE00B85A17E094C7FC373E7DBD40>I<DB3FF01306913803FFFE020F-9038FF800E913A3FF007E01E9139FF8000F0D901FCC7EA383ED907F0EC0C7E4948140649-48EC03FE4948140149C9FC13FE4848167E0003173E5B4848161E120FA24848160EA2123F-5B1806127FA349160012FFAC127F7F1806A2123FA27F121F180C6C7EA2000717186C7E6D-1638000117306C6C1660137F6D6C15C06D6CEC01806D6CEC03006D6C140ED901FC5C6DB4-6C13F891393FF007F0020FB512C0020391C7FC9138003FF037427BBF42>I<B712FCEEFF-8017E000019039C0001FF86C6C48EB03FEEE00FFEF3F80717E717E717E717E717EA2717E-84841980183F19C0A3F01FE0A519F0AB19E0A4183F19C0A21980187FA2190018FEA24D5A-4D5A17074D5A4D5A4D5A05FFC7FCEE03FE48486CEB1FF8B85A178004FCC8FC3C3E7DBD45->I<B912E0A3000101C0C7FC6C6C48141FEF07F01703170117001870A31830A418181618-A41800A21638A2167816F8150391B5FCA3EC8003150016781638A21618A21806A3180C93-C7FCA4181C1818A21838A21878A218F0170117031707171F48486CEB01FFB912E0A3373E-7DBD3E>I<B91280A300019038C000036C6C48EB003FEF1FC017071703A21701A31700A4-1860A21630A31800A31670A216F01501150791B5FCA3EC8007150115001670A21630A693-C8FCAF3801FFE0B612F0A3333E7DBD3B>I<B6D8C01FB512F8A3000101E0C7383FFC0026-007F80EC0FF0B3A691B7FCA30280C7120FB3A92601FFE0EC3FFCB6D8C01FB512F8A33D3E-7DBD44>72 D<B612F0A3C6EBF000EB3FC0B3B3B2EBFFF0B612F0A31C3E7EBD21>I<B600-C090381FFFFCA3000101E0C70007138026007F80913801FC0018F06018804DC7FC17065F-5F5F5F5F4C5A4CC8FC16065E5E5E5E5E4B5A15074B7E4B7E153FED6FF0EDCFF8EC818791-388303FC02867FEC8C0191389800FF02B08002E0137F4A6D7E4A80161F707E831607707E-831601707E84177F717E717E84170F717E841703844D7E2601FFE04A13C0B600C090B6FC-A3403E7DBD47>75 D<B612F8A3000101E0C9FC38007F80B3B0EF0180A517031800A45FA3-5FA25F5F5F17FE160348486C133FB8FCA3313E7DBD39>I<B56C93387FFFC06E93B5FCA2-0001F1E00026006FE0923801BF80A3D967F0ED033FA2D963F81506A3D961FC150CA3D960-FE1518A2027F1530A36E6C1460A26E6C14C0A36E6CEB0180A36E6CEB0300A26E6C1306A3-6E6C5BA36E6C5BA2037F5BA36F6C5AA36F6C5AA292380FE180A3DB07F3C7FCA2ED03FEA3-6F5AA213F0486C6D5AD807FEEFFFE0B500F00170017FEBFFC0A34A3E7CBD53>I<B56C91-387FFFF880A2C66C6C020313006EEC00FC016F1678D967F81530801363EB61FE8001607F-147F6E7E81141F6E7E8114076E7E8114016E7E82157F6F7E82151F6F7E826F7E15036F7E-8281EE7F8017C0163FEE1FE017F0160FEE07F817FC1603EE01FE17FF82EF7FB018F0173F-171F170FA217071703A201F01501486C1500EA07FEB500F015701830A23D3E7DBD44>I<-ED7FE0913807FFFE91391FC03F8091397E0007E0D901F8EB01F8D907F0EB00FED90FC014-3F49486E7E49C86C7E017E6F7E01FE8248486F7E49150100038348486F7EA24848167FA2-001F1880A24848EE3FC0A3007F18E049161FA300FF18F0AC007F18E06D163FA4003F18C0-6D167F001F1880A26D16FF000F1800A26C6C4B5A00035F6D150300015F6C6C4B5A017F4B-5A6D6C4A5A6D6C4A5A6D6C4AC7FC6D6C14FED901F8EB01F8D9007EEB07E091391FC03F80-912607FFFEC8FC9138007FE03C427BBF47>I<B712F8EEFF8017E000019039C0001FF86C-6C48EB03FC707EEE007FEF3F8018C0EF1FE0A218F0170F18F8A818F0171F18E0A2EF3FC0-1880EF7F00EE01FEEE07FCEE3FF091B612C04CC7FC0280C9FCB3A73801FFE0B612C0A335-3E7DBD3E>I<B712C016FCEEFF8000019039C0007FE06C6C48EB0FF0EE03FC707E707E71-7E717EA284171F84A760173F6060177F4DC7FCEE01FC4C5AEE0FE0EEFF8091B500FCC8FC-5E91388000FFEE3F80EE0FE0707E707E707EA283160083A684A61906A2EF7FC0A2053F13-0C3801FFE0B600C0EB1FE0050F1318943803F870CA3801FFE09438003F803F407DBD43>-82 D<D907FC131890381FFF80017FEBE0383A01FC03F0783903F0007CD807C0EB1EF848-48130748C712031501123E15005A1678A200FC1538A46C1518A37E6C6C14007F6C7E13F8-6CB47E14F86CEBFF806C14F06C14FC6C14FF6C6C14806D14C0010714E0D9007F13F00207-13F8EC007FED0FFC1507ED01FEA21500167F124012C0163FA47EA2163E7E167E6C157C7E-16F8B4EC01F0D8FB8014E0D8F9E0EB03C0D8F0F8EB0F8090397F803F0039E01FFFFED8C0-0713F89038007FC028427BBF33>I<003FB91280A3903AE0007FE00090C76C48131F007E-EF0FC0007C17070078170300701701A300601700A5481860A5C81600B3B14B7E4B7E0107-B612FEA33B3D7DBC42>I<B600C090387FFFF8A3000101E0C70003130026007F80EC00FC-18781830B3B3A4013F5EA280011F16E060130F6E4A5A010715036D6C92C7FC6E14060101-150E6D6C5C027F147891391F8001F091390FF00FC00203B55A020049C8FCED1FF03D407D-BD44>I<B6913807FFFEA3000301E0020013E0C60180ED3F80F01F00017F160E180C6E15-1C013F1618A26D6C5DA280010F5EA26E15E001075EA26D6C4A5AA28001014BC7FCA26E5C-6D150681027F5CA26F131C023F1418A26F1338021F143081020F5CA26F13E002075CA26E-6C485AA215FE020149C8FCA26F5A6E1306A2ED7F8CA216CCED3FD8A216F86F5AA26F5AA3-6F5AA36F5AA23F407EBD44>I<007FB5D8C003B512E0A3C66C48C7387FFC00D93FF8EC1F-E06D48EC0F806D6C92C7FC170E6D6C140C6D6C5C17386D6C14306D6D5B17E06E6C5B023F-495AEDE003DA1FF090C8FC020F1306EDF80E6E6C5A1618913803FE386E6C5A16606E13E0-6F5AA26F7E6F7EA26F7E4B7EA2ED33FEED71FF156103C07F0201137F03807F4A486C7E5C-02066D7E4A6D7E141C02186D7E4A6D7E147002606D7E4A6D7F13014A6E7E49C86C7E5B01-066F7E010E6F7E133F496C812607FFC0EC3FFFB500F80103B512FEA33F3E7EBD44>88-D<B66C49B51280A3000101F0C8383FF8006C6C48ED1FC0013F70C7FC180E6D6C150C181C-6D6C15186D6C153818306D6C5D6E15E06D5E6D6D1301606E6C49C8FC6E6C5B17066E6C13-0E170C6E6C5B6E7E5F6E6C13706F13606E14E06E6D5AEE8180ED7FC3DB3FE3C9FC16E7ED-1FF616FC150F6F5AB3A4ED1FFC020FB512FCA3413E7FBD44>I<EAFFFCA4EAF000B3B3B3-B3ABEAFFFCA40E5B77C319>91 D<6D1340000114C039030001800006EB0300481306A248-5BA2485BA2485BA3485BA500CFEB678039DF806FC039FFC07FE001E013F0A2007F133FA2-393FC01FE0391F800FC0390F0007801C1C73BE2D>I<EAFFFCA4EA003CB3B3B3B3ABEAFF-FCA40E5B7FC319>I<1318133C137E13FF3801E7803803C3C0380781E0380F00F0001E13-7848133C48131E00E0130700401302180D76BD2D>I<EB0FF8EB7FFE3901F01F80390380-03E039060001F0390F8000F86D7F486C137C157EA2816C5A6C5AC8FCA4EC0FFF0103B5FC-90381FFC3FEB7F803801FC00EA03F0485A485A485A123F48C7FCEE018012FEA3157FA300-7F14DFEC019F3B3F80038F83003A1FC0070FC73A07F01C07FE3A01FFF803FC3A003FE001-F0292A7DA82D>97 D<EA01F812FFA3120712031201B1EC07F8EC3FFF9138780FC09138C0-03E09039F98001F001FBC77E01FE147C498049143F1780161F17C0A2EE0FE0A317F0A917-E0A2161F17C0A21780163F6D1500167E01F6147C5E01E3495A9039C1C007E09039C0F01F-809026803FFEC7FCC7EA0FF02C407DBE33>I<49B4FC010F13E090383F00F8017C131C49-13064848131F48485B0007EC7F80485A121F5B003FEC3F00151E007F91C7FC90C9FCA35A-A97EA27F123F16C0121F6DEB0180120F6C6CEB0300A26C6C13066C6C5BD8007C13389038-3F01F090380FFFC0D901FEC7FC222A7DA828>I<ED03F815FFA3150715031501B114FF01-0713C190381F80F190387E003901F8130D48481307485A0007140348481301121F5B123F-A2127F90C7FCA25AA97EA36C7EA2121F7F000F140312076C6C13076C6CEB0DFC6C6CEB19-FE017C903871FFF090383F01E190380FFF81903A01FE01F8002C407DBE33>I<EB01FE90-380FFFC090383F03F090387C00F801F0137C00038049133F48487F000F1580485AED0FC0-123FA248C713E0A35AA290B6FCA290C9FCA67EA27F123F1660121F6D14C0120F6C6CEB01-8012036C6CEB03006C6C130E017E5B90381F80F0903807FFE0010090C7FC232A7EA828>-I<EC1FC0ECFFF0903803F038903807C07C90380F80FEEB1F01133F133E90387E00FC1578-491300AFB6FCA3D800FCC7FCB3AE487E387FFFFEA31F407EBF1C>I<167C903903F801FF-90391FFF0787903A7E0FCE0F809038F803F83901F001F03B03E000F8070000076EC7FCA2-4848137EA2001F147FA6000F147EA26C6C5BA200035C6C6C485A6D485A39037E0FC0D91F-FFC8FC380703F80006CAFCA2120EA2120F7E7F7F6CB512F015FE6C6E7E6C15E00003813A-07C0001FF848C7EA03FC001E140048157E007C153E0078153F00F881A50078151E007C15-3E6C5D001E15786C5DD807C0EB03E0D803F0EB0FC0D800FE017FC7FC90383FFFFC010313-C0293D7EA82D>I<EA01F812FFA3120712031201B1EC03F8EC1FFF91383C0F8091386007-C04A6C7ED9F9807FEBFB0001FE1301825BA35BB3A6486C497EB500F0B512F0A32C3F7CBE-33>I<EA01E0487E487E487EA46C5A6C5A6C5AC8FCACEA01F8127FA3120712031201B3AC-487EB512E0A3133E7DBD19>I<EA01F812FFA3120712031201B292387FFF80A392381FF8-00ED0FE01680030EC7FC5D5D15605D4A5A4AC8FC140E5C143E147FECDF80EBF98F9038FB-0FC09038FE07E0EBFC0301F07F6E7E140081157E8181826F7E1507826F7E82486CEB07FE-B539E03FFFE0A32B3F7EBE30>107 D<EA01F812FFA3120712031201B3B3B1487EB512F0-A3143F7DBE19>I<2703F003FCEB01FE00FF903B0FFF8007FFC0913B3C0FC01E07E0913B-7003E03801F00007903BC001F06000F82603F1806D487F2601F300EBF98001F6D900FBC7-127C04FF147E01FC5CA3495CB3A6486C496C14FFB528F07FFFF83F13FCA346287CA74D>-I<3903F003F800FFEB1FFF91383C0F8091386007C00007496C7E2603F1807F3801F30001-F613018213FCA35BB3A6486C497EB500F0B512F0A32C287CA733>I<14FF010713E09038-1F81F890387E007E01F8131F4848EB0F804848EB07C04848EB03E0000F15F04848EB01F8-A2003F15FCA248C812FEA44815FFA96C15FEA36C6CEB01FCA3001F15F86C6CEB03F0A26C-6CEB07E06C6CEB0FC06C6CEB1F80D8007EEB7E0090383F81FC90380FFFF0010090C7FC28-2A7EA82D>I<3901F807F800FFEB3FFF9138781FC09138C007E03A07F98001F02603FB00-7FD801FE6D7E49147E49147FEE3F80A2EE1FC0A217E0A2160F17F0A917E0161FA217C0A2-EE3F80A26DEC7F00167E6D5C4B5A01FB495A9039F9C007E09039F8F01F80DA3FFEC7FCEC-0FF091C9FCAD487EB512F0A32C3A7DA733>I<02FF13180107EBC03890381F80E090397E-0030784913184848130C4848EB06F8485A000F1403485AA248481301A2127FA290C7FC5A-A97E7FA2123FA26C7E15036C7E000714076C7E6C6C130D00001419017E137190383F81E1-90380FFF81903801FE0190C7FCAD4B7E92B512F0A32C3A7DA730>I<3903F007E000FFEB-1FF0EC7878ECE0FC3907F181FE12033801F3019038F600FCA2153001FC1300A35BB3A548-7EB512FCA31F287EA724>I<90387FC0603901FFF8E03807C03D380E0007481303481301-481300A212F01560A27EA27E007F140013C0EA3FFE381FFFE06C13FC6C7F6C7FC6148001-0F13C09038007FE0EC0FF00040130300C0EB01F814007E1578A37E15707E15E07E6CEB01-C000F3EB038039E1E01F0038C0FFFCEB1FE01D2A7DA824>I<1318A61338A41378A213F8-A2120112031207001FB512C0B6FCA2D801F8C7FCB3A21560A9000014C07F137CEC018013-3E90381F8700EB07FEEB01F81B397EB723>I<D801F8EB03F800FF14FFA3000714070003-140300011401B3A61503A300001407A2017CEB0DFCED19FE6D903831FFF090381F80E190-3807FFC10100903801F8002C297CA733>I<B539C007FFE0A32707FC000113006C48EB00-7C0001157816707F00001560A2017E5CA2017F13016D5CA26D6C48C7FCA26E5A010F1306-A26D6C5AA2ECF01C01031318A26D6C5AA2ECFC7001001360A2EC7EC0A2147F6E5AA26EC8-FCA3140EA22B287EA630>I<B53BC3FFFE01FFF8A33D0FFC001FE0007FC0D803F06D48EB-1F800307EC0E007F00016F130CA26D161C00004A6C1318150D017E5EED1DF815186D5EED-307CA2D91F80017E5BED603EA2D90FC090383F0180EDC01FA2D907E00283C7FC9138E180-0F02F11487010315C69138F3000702FB14CE6DB414EC4A1303010015F8A24A1301027C5C-02781300A202385C023014603D287EA642>I<3B7FFFC00FFFE0A3000390390007FE00C6-48EB03F0017E6D5A6DEB03801480011F49C7FC90380FC00E903807E00C6E5A903803F838-01015B6D6C5AEC7EC0EC7F80143F141F6E7E81141FEC3BF0EC71F8ECE1FC14C090380180-7E01037FD907007F01066D7E49130F496D7E01386D7E017880EA01F8D80FFCEB07FEB590-381FFFF8A32D277FA630>I<B539C007FFE0A32707FC000113006C48EB007C0001157816-706C6C1460A27F017E5CA26D495AA2EC8003011F91C7FCA290380FC006A2ECE00E010713-0CA26D6C5AA2ECF8380101133014FC01005BA2EC7EC0A2147F6E5AA26EC8FCA3140EA214-0CA2141C1418A25CA2147000381360007C13E000FE5B13015C49C9FCEA7C07EA700EEA38-3CEA1FF8EA07E02B3A7EA630>I<001FB61280A29039E0003F0090C7127E001E14FE001C-495A5D0018495A003813075D0030495A141F4A5A92C7FC147EC712FE495A5C495A13075C-495A011FEB0180EB3F801400137E13FE485A491303485A000715005B48485B001F5C485A-90C7123F007E49B4FCB7FCA221277EA628>I E-%EndDVIPSBitmapFont-%DVIPSBitmapFont: Ff cmbx12 14.4 37-/Ff 37 122 df<EA03E0EA0FF8487E487E487EA2B51280A56C1300A26C5A6C5A6C5AEA03-E01111769025>46 D<157815FC14031407141F14FF130F0007B5FCB6FCA2147F13F0EAF8-00C7FCB3B3B3A6007FB712FEA52F4E76CD43>49 D<EC1FFC49B512E0010F14FC013F14FF-90B712C048D9803F7F2703FC00077FD807F06D13FC484801007F4848147F48488101E06E-1380D87FF8806D16C06D8000FF17E07FA27013F0A36C5AA26C5AA2EA0FF0D803C05CC914-E0A34C13C0A218805E18004C5A5F16FF5F4B5B4B5B4B5B94C7FC4B5A4B5A4B5AED7FE05E-4B5A4A90C8FCEC03FC4A5A4A48EB01F04A5A4A5A4A5A02FEC7EA03E0495A495A495A5C49-48140749C8FC013E150F017FB7FC90B812C05A5A5A5A5A5A5AA2B91280A4344E79CD43>-I<91380FFF8091B512FC010314FF010F15C090263FF00313F09026FF800013FC4848C76C-7ED803F86E7E4980D807FC168001FF16C0487F82486D15E0A3805CA27E4A4913C07E6C90-C7FCD800FC168090C85A18005F167F4C5A5F4B13E04B5B030F5BDB7FFEC7FC91B512F816-C016FCEEFF80DA000713E0030013F8707E70B4FC7013807013C018E07013F0A218F88218-FCA318FEEA01C0EA0FF8487E487E487EA2B57E18FCA44C13F86C90C7FC18F0495C6C4816-E001F04A13C06C484A1380D80FF84A1300D807FE4A5A2703FFF0035BC690B612F0013F15-C0010F92C7FC010114F8D9001F1380374F7ACD43>I<177C17FEA2160116031607160FA2-161F163F167FA216FF5D5DA25D5DED1FBFED3F3F153E157C15FCEC01F815F0EC03E01407-EC0FC01580EC1F005C147E147C5C1301495A495A5C495A131F49C7FC133E5B13FC485A5B-485A1207485A485A90C8FC123E127E5ABA12C0A5C96C48C7FCAF020FB712C0A53A4F7CCE-43>I<0003160ED807E0153E01FCEC03FED9FFE0137F91B65A5F5F5F5F5F94C7FC5E16F8-5E16C04BC8FC15F801E090C9FC91CAFCABEC0FFF027F13F001E3B512FC01E714FF9026FF-F80713C0DAC0017F49C713F8496E7E01F0143F496E7E49816C5AC9148018C082A218E0A3-18F0A3EA07C0EA1FF0487E487EA2487EA318E0A25B18C06C485C49168013C0003EC81400-003F5D6C6C5D6C6C4A5A6D4A5AD807F8495B6C6C01075B2701FFC03F5B6C90B6C7FC013F-14FC010F14F0010314809026007FF8C8FC344F79CD43>I<ED0FFE92B512C0020714F002-1F14FC91397FFC01FE9139FFE0007F01030180131F4990C7EA0F80D90FFCEC3FC0494814-FF013F5C49484913E0495A48495BA25A485B7013C05A91C76C138070130048163C94C7FC-5AA25BA2127F1508EDFFF8020313FF020F14C000FF498091393E007FF84AEB1FFC02706D-7E02F06D7E6D4815804A6D13C0A24A15E0A27013F091C7FC18F8A34916FCA3127FA6123F-A37F6C17F8A27E18F0A26C4B13E0806C17C06C7F4C13806C6D4913006D6C495AD93FFC49-5A6DB4EBFFF8010790B512E06D5D010092C7FC023F13FC020313C0364F7ACD43>I<121F-7F7FEBFF8091B81280A448180060A26060606060A2485F0180C86CC7FC007EC912FE5F00-7C15014C5A4C5A4C5A4C5A485E163F4CC8FC16FEC8485A5E15034B5A150F5E4B5A153FA2-4B5AA24BC9FCA25C5C5D1407A34A5AA2141FA3143FA34A5AA414FFA65BAB6D5B6E5A6E5A-6E5A395279D043>I<913807FFC0027F13FC49B67E010715E090261FFC007FD93FC0EB3F-FC4948EB0FFE49C76C7E48488048486E138082484816C0A2000FEE7FE0A3121F7FA27F7F-6E15C002E014FF8002FC15806C01FF5BDBC00313006F485A6C02F85B9238FE0FF86C9138-FF3FF06CEDFFE017806C4BC7FC7F6D6E7E010F15E06D81010115FC4981010F81013F1680-EB7FC32601FF8015C048496C14E04848131F4848010714F0497F001F020014F84848143F-160F48486E13FC1601824848157F173F171FA2170FA318F8A26C7E18F0171F6C6C16E0A2-6C6CED3FC06DED7F806C6C15FF6C6C6C4913006C01E0EB0FFE6C01FCEB7FF86C6CB65A01-1F15C0010792C7FC010014F8020F1380364F7ACD43>I<913807FF80027F13F00103B512-FC010F14FF90261FFE0113C0903A7FF8007FE0D9FFE06D7E48496D7E48496D7E486F7E48-90C77FA2486F1380A2484816C0A2007F17E0A28200FF17F0A418F8A618FCA2127F5EA312-3F5E6C7EA26C5DA26C6D5B6C153D6C6D13396C6D13F990397FF801F1011FB512E16D02C1-13F8010314019038007FFCEC00401500A218F05EA218E013F0EA03FC486C16C0486C5C18-80487F18005E5F91C7485A4C5A6C48147F495DD807F049485A4B5B6C6C010F5B6CB4D93F-FEC7FC6C90B55A6D14F0011F14C0010749C8FC010013E0364F7ACD43>I<BA12C019FEF1-FFC01AF01AFCD8000701F0C7000313FFDE007F7F737F070F7F737F878587858785A287A8-4F5BA263616361634F5B4F5B077F90C7FC4E485A060713F892B812E097C8FC861AF003F0-C7000313FE9539003FFF80070F13E0737F07017F87737F747E1C807413C0A27413E0A31C-F0A386A362A31CE0A2621CC0A250138097B5FC1C004F5B19074F5B073F13F04EB55ABC12-8098C7FC1AF81AC007F8C8FC54527CD160>66 D<BC1280A5D8000701F8C7000114C0F000-1F19071901851A7F1A3F1A1FA2F20FE0A21A07A31A03A318F81BF01A01A497C7FC1701A3-17031707170F177F92B6FCA59238F8007F170F170717031701A317001B3EA31B7CA395C8-FCA21BFCA21BF8A21A01A31A031BF01A071A0FA21A1F1A3FF27FE0F101FF1907191F0603-B5FCBCFCA21BC0A34F517CD058>69 D<BB12FEA5D8000701F8C700077FF0007F191F1907-85858586861B80A21A1FA31A0FA41BC006F81307A497C7FCA31701A317031707170F177F-92B6FCA59238F8007F170F170717031701A31700A795C9FCB3B812F8A54A517CD055>I<-B812C0A5D8000701F8C7FCB3B3B3B2B812C0A52A527CD132>73 D<B812F8A5D8000701F8-CAFCB3B3A91A7CA41AFC1AF8A51901A31903A219071AF0190FA2191F193F197F19FF1803-60183F4DB5FCBB12E0A546527CD151>76 D<B912F0F0FF8019F819FF1AC0D8000701F0C7-14F0060F7F060113FE727F737F737F85737F87A2737FA387A863A2616363A24F5B4F5B4F-90C8FC4F5A06035B060F13F095B512C092B8C9FC19F819E019F89226F0000313FE943900-7FFF80061F7F727F727F86727F8486A2727FA887A71D1C1D3E8785A275137E73157C7315-FC736D13F8B86C6DEBF801739038FE07F07390B512E0736C14C0080F1400CEEA7FFC5F53-7CD164>82 D<91260FFF80130791B500F85B010302FF5B010FEDC03F013FEDF07F90267F-F8006D5A2601FFC0EB07FD4890C70001B5FC48486E7E49814848150F48488183003F825B-007F82A284A200FF83A27F84A27F7F7F6D93C7FC6C13C014F014FF6C14F0EDFF806C15F8-EEFF806C16F017FC6C16FF6C836C17E06C836D82011F826D821303010082020F16801400-030715C0ED007F1603DC007F13E083170F7113F08383127800F882A3187FA27E19E0A37E-19C06C17FF6D17807F6D4B13006D5D6D5E01FE4B5AD9FFC0EC1FF802F84A5A903B1FFFC0-03FFE0D8FE0790B65AD8FC0193C7FC486C6C14FC48010714E0489026003FFEC8FC3C5479-D24B>I<EC3FFF0107B512F0011F14FE017F6E7E2701FFC0077F2703FC000113F001FF6D-6C7E486D6D7E83486D131F707EA284A26C497F846C90C7FCEA00FC90C8FCA6033FB5FC02-0FB6FC91B7FC01071407011F13E090387FFE003801FFF84813E0485B485B4890C7FC485A-5B127FA2485AA45EA25E6C6C141D163D6C6C02797F6C6C02F113F86C9026C003E0EBFFE0-6C9027F01FC07F13F06C90B5487EC64A487E011F01F8010713E0010001E090C8FC3C387C-B641>97 D<913801FFF8021FEBFF8091B612E0010315F8010F9038800FFE4948C77ED93F-F81303D9FFF0491380485B4A4913C0485B5A4890C7FCA2486F13805B003F6F1300EE00FC-94C7FC485AA412FFAB127FA27FA2123FA2001FEE03E07F7E6EEC07C07E6EEC0F806C6D14-1F6CEE3F006C6D147ED97FFC5CD91FFEEB03F8903A0FFFC01FF0010390B55A0100158002-1F01FCC7FC020113E033387CB63C>99 D<4DB47E0407B5FCA5EE001F1707B3A4EDFFC002-1F13FC91B6FC010315C7010F9038C01FE7903A1FFE0003F7D93FF86DB5FCD9FFF06D7E48-49804849805C48824890C8FCA2485AA2123FA2485AA412FFAB127FA46C7EA3121FA26C7E-6C5E6E5C6C7F6C5E6C6D49B5FCD97FF84914E06D6CD90FEFEBFF80903A0FFF807FCF0103-90B5120F010014FE023F13F00203018049C7FC41547CD24B>I<913803FFC0023F13FC49-B6FC010715C04901817F903A3FFC003FF0D97FF06D7E4948EB07FC48498048496D7E5A91-C76C13805A486F13C05B003F17E0A2177F485A18F0A312FFA390B8FCA318E001FCCAFCA5-127FA37F123FA2001F17E06DED01F07E17036C6D15E06C16076C6DEC0FC06C6DEC1F806D-6CEC3F006D6C14FED91FFEEB03FC903A0FFFC03FF8010390B55A010015C0021F49C7FC02-0113F034387CB63D>I<ED1FF84AB5FC020F14C0023F14E09139FFF81FF0499038C03FF8-49EB807F49010013FC494813FF5C495AA2133F4AEB7FF8017FEC3FF0EE1FE0EE0FC093C7-FCAEB712E0A526007FF8C8FCB3B3A7007FB512FEA52E547CD329>I<DA1FFF147F91B539-E003FFC00107DAFC0F13E0011FECFF3F90263FFC079038FF1FF09026FFE00013F84849EB-7FF04A133F4890C7D81FF813E0489338FC0FC0F0038048486E6CC7FCA3001F82A7000F5E-A36C6C4A5AA26C5E6C6D495A6E137F6C6D495A90267FFC07138090B7C8FCD801E714FC01-E014E02603C01F90C9FC91CBFC1207A37FA27F7F13FE90B7FC6C16F017FE717E6C17E084-6C836D826D8248B9FC12074848C71201D81FF8DA001F1380484815074848817113C04848-81A66C6C4B1380A26C6C4B1300A26C6C4B5AD80FFEED1FFC6C6C4B5A6C01C0ECFFF0C601-FC010F13C0013FB7C7FC010F15FC010115E0D9000F01FCC8FC3C4F7CB543>I<EB3FF0B5-FCA51203C6FCB3A4EE1FFC93B57E030314E0030F14F892391FC07FFC92393E001FFE5D03-F06D7EECF1E0DAF3C0814B7F02F7C7FC02FF825CA25CA35CB3ADB6D8F807B612C0A54253-7BD24B>I<137F497E487F487F487F487FA76C5B6C5B6C5B6C5B6DC7FC90C8FCADEB3FF0-B5FCA512017EB3B3A6B612E0A51B547BD325>I<EB3FF0B5FCA512017EB3B3B3B1B612F0-A51C537BD225>108 D<D93FF0D91FFCEDFFE0B591B56C010713FC030302E0011F13FF03-0F02F8017F14C092271FC07FFCD9FE037F922A3E001FFE01F0007F00034A4B5AC602F090-270FFF07806D7EDAF1E04BC7FCDAF3C0039E814B6D019C143F02F7C714B802FF04F8814A-5EA24A5EA34A5EB3ADB6D8F807B6D8C03FB512FEA567367BB570>I<D93FF0EB1FFCB591-B57E030314E0030F14F892391FC07FFC92393E001FFE00035CC602F06D7EECF1E0DAF3C0-814B7F02F7C7FC02FF825CA25CA35CB3ADB6D8F807B612C0A542367BB54B>I<913801FF-E0021F13FE91B612C0010315F0010F9038807FFC903A1FFC000FFED97FF0903803FF8049-486D7F48496D7F48496E7EA24890C86C7E488349151F001F83A2003F834981A2007F1880-A400FF18C0AC007F1880A36C6C4B1300A3001F5FA26C6C4B5AA26C6D4A5A6C5F6C6D4A5A-6C6D495B6D6C495BD93FFC010F90C7FC903A0FFF807FFC6D90B55A010015C0023F91C8FC-020113E03A387CB643>I<D93FF0EBFFE0B5010F13FE033F6D7E92B612E09126F1FE0113-F8913AF7F0003FFE0003D9FFC06D7EC64A01077F92C76C7F4A824A6E7F4A8085727EA285-183FA285A284A21A80AB1A0060A361A24E5AA24E5AA24D5B6E5E6E5C6E4A5B6F495B6F49-48C7FC03F0EB7FFC913AFBFC03FFF002F8B65A033F91C8FC030F13FC0301138092CBFCB1-B612F8A5414D7BB54B>I<90397FE001FCB590380FFF80033F13E04B13F09238FE1FF891-39E1F03FFC0003EBE3E0C69138C07FFEECE780150014EF14EE02FEEB3FFC5CEE1FF8EE07-E04A90C7FCA55CB3AAB612FCA52F367CB537>114 D<903901FFE007011FEBFC1F017FEB-FF7F48B7FC3907FE001FD80FF01307D81FC01301497F003F8148C87EA34881A27FA27F01-F091C7FC13FC387FFFC014FEECFFF06C14FEEDFFC06C816C15F86C810001816C81013F15-80010715C01300020714E0EC001F1503030013F00078157F00F8153F161F7E160FA27E17-E07EA26DEC1FC07F6DEC3F806DEC7F0001FCEB01FE9039FF800FFC013FB55AD8FC1F14E0-D8F803148027E0007FF8C7FC2C387CB635>I<143EA6147EA414FEA21301A313031307A2-130F131F133F13FF5A000F90B6FCB8FCA426003FFEC8FCB3A9EE07C0AB011FEC0F80807F-EE1F006D1380EDC03E6D6D5A0100EBFFF86E5B021F5B020190C7FC2A4D7ECB34>I<D93F-F8913801FFC0B50207B5FCA50003ED001FC61607B3AF5FA35F017F5D173B177B6D6C14F3-011FDA01E313F06ED907C3EBFFC0903A0FFF801F83010390B512036D14FED9003F13F802-0301C091C7FC42377BB54B>I<B600F00107B5FCA5000101F8C8EA7FC06C6DED3F00A201-7F163E6E157E013F167C6E15FC6D5E6F13016D5E8117036D5E6F13076D5E6F130F6D5E6F-131F6D93C7FC815F6E6C133E177E023F147C6F13FC6E5C16816E5C16C3A26EEBE3E016E7-6E5C16FF6E5CA26E91C8FCA26F5AA36F5AA26F5AA26F5AA26F5A6F5A40367DB447>I<00-7FB500F090387FFFFEA5C66C48C7000F90C7FC6D6CEC03F86D6D495A6D6D495A6D4B5A6F-495A6D6D91C8FC6D6D137E6D6D5B91387FFE014C5A6E6C485A6EEB8FE06EEBCFC06EEBFF-806E91C9FCA26E5B6E5B6F7E6F7EA26F7F834B7F4B7F92B5FCDA01FD7F03F87F4A486C7E-4A486C7E020F7FDA1FC0804A486C7F4A486C7F02FE6D7F4A6D7F495A49486D7F01076F7E-49486E7E49486E7FEBFFF0B500FE49B612C0A542357EB447>120-D<B600F00107B5FCA5C601F8C8EA7FC06EED3F00A26D6C153E187E013F167C6E15FC6D5E-6F13016D5E6F13036D5E8117076D6D5C170F6D6D5C171F6D93C7FC6F5B027F143E6F137E-023F147C6F13FCA26E6D5A16816EEBC1F016C36E5C16E76E5C16FF6E5CA26E91C8FCA36F-5AA26F5AA26F5AA26F5AA26F5AA35E150F5E151F93C9FC5DD81FC0133E486C137E486C13-7C486C13FC5D14015D14034A5A6C48485A49485A263FC07FCAFCEB81FE6CB45A6C13F000-035BC690CBFC404D7DB447>I E-%EndDVIPSBitmapFont-%DVIPSBitmapFont: Fg cmbx12 24.88 15-/Fg 15 118 df[<C21280A421C0A5C700030380C81201F40007F5007F0C1F14E01E071E-018A1F3F8B8B8B7913F0A28B8BA2207FA3203F21F8201FA4200FA321FC2007A4F47FC0A3-F803FEA49DC7FCA31CFFA463A263A26363631B7F50B5FC1A1F95B8FCA9953880001F1A01-747E1B1F878787A287A287A41C7FAA99CBFCB3AFBC12F0A9>127-141 120 268 146 70 D[<B96C0C3FB812E07266729BB9FC7265A37265A27265C70003A1-01F8C8FC72F50FF7A2706DF51FE7A3706EF43FC7A2706EF47F87A2706EF4FF07A2706EF3-01FEA3706EF303FCA2706EF307F8A2706EF30FF0A2716DF31FE0A3716EF23FC0A2716EF2-7F80A2716EF2FF00A2716E4F5AA3716E4F5AA2716E4F5AA2716E4F5AA2726D4F5AA3726E-4E5AA2726E4E5AA2726E4EC7FCA2726E4D5AA3726E4D5AA2726E4D5AA2726E4D5AA2736D-4D5AA3736E4C5AA2736E4C5AA2736E4CC8FCA3736E4B5AA2736E4B5AA2736E4B5AA2736E-4B5AA3746D4B5AA2746E4A5AA2746E4A5AA2746E4AC9FCA3746E495AA2746E495AA2746E-495AA2746E495AA3756D495AA2756E485AA2756E485AA2756E48CAFCA375ECF1FEA275EC-FBFCA275ECFFF8A2755DA3765CA2765CA2765CA27691CBFCA3765B4A7F49B500FE715BB9-00FC51BB12E0765BA2765BA3775A775A775A>203 142 120 269-220 77 D[<932607FFF8163E4BB600E0153F030F03FC5D037FDBFF805C4AB800F05B020F-05FC5B4A05FF5B027FF0C00F91B526FC000FECF01F010302C0D9003F6D5A4949C800076D-5A4901F8030090B6FC4901E0163F4949160F49498290B5CA12014A834849844849181F87-484984A2484984874886A248498588A24887A388A2B58680A36E85A3806E85A28080816C-6E725A03F096C7FC8115FE6F7E6C15F016FF17F86CEEFF8018FC6CEFFFC019FE6CF0FFE0-6C19FEF2FFC06C1AF06C1AFC1BFF6D1AC06D866D1AF86D866D866D866D876D87023F866E-8602078614016E6C85031F851503DB007F8404031980EE003F050118C0EF001F060017E0-190FF1007F080F15F01A031A007514F81B1F87877514FC87A2007F86486C86A288A288A4-6D86A31EF87FA37F1EF0A26D621EE07F7F6D5013C0A26E1B806E616E1B0002F896B5FC6E-4E5B6E4E5B6E7E03E0050F5B6F4D5B03FE4D5B6F6C93B55A04F803035C496CD9FF80020F-91C7FCD9FC1F02FF91B55AD9F80792B75A496C19F049C66C6049011F18804901074DC8FC-90C817F048030F168048030003FCC9FC007C04011480>102 146-115 271 129 83 D[<BB00FE040FB912C0A9C700030380CD001F02E0C7FC9E26007FF8C8-FC7C5AB3B3B3B3B36E555AA38480585AA36F65726481696F9CC9FC72626F66721A0F6F53-5AA26F6E505A6F6E505A6F1DFF724F5B706E4E5B706E60706E4E5B706E063F90CAFC706E-4E5A7002FE4D485A706E6C04075B706C02E0043F5B7102F84BB512C0050FDAFF80021F5C-7103FC0107B6CBFC050192B812FC716C19F0061F6106071980060006FCCCFC071F17F007-011780DF001F03F8CDFCE0003F01FCCEFC>162 144 120 269 179-85 D<93387FFFF8033FB612E00203B712FE021FEEFFC0027F17F049B912FC4918FF4991-2680007F14C04901E0C7000F80496D020314F8496D0200806F6F7F496D6F7F738090B681-73807380A27380A288856D4984A26D5B747F6D5B6D5B6D5B010090CAFC91CBFCAA0603B6-FC050FB7FC0403B8FC167F0307B9FC153F4AB7C67E020F15C0023F02FCC7FC91B612C001-0392C8FC010F14FC4914F04914C04991C9FC90B55A485C485C485C485C5D5A485CA24891-CAFCA3B6FC5CA397B5FCA461806C60F107EF6C6E150F6F16CF6CF03F8F6F037F806C6EDB-FF0F14C06C02FCDA03FE15FC6C6E91260FFC0791B5FC6C6E6CD93FF817806C923AF003FF-F003013F91B6487E010FEF8000010394C77E010004FC141F021F03E01407020192C96C14-00DA000701F093C9FC695F79DD71>97 D[<F57FC098B6FC4FB7FCA996C77E1B0FA287B3-B294383FFF80040FB512F8047F14FF0303B712E0031F16F8037F16FE4AB9128702079126-FC003F13C7021F02E0010313F74A91C890B6FC4A01FC153F49B548814902E01507494A81-494A814991CAFC4949834B83498590B54883A2485C5AA2485CA25A5D5AA35AA25D5AA5B6-FCB07EA57E81A37EA27EA2817EA26C806C62A26C6E5F636D6D94B6FC6D606D6D5E6D6D5E-6D6E5D704B81010102F0157F6D6E92B712FC6E01FE020301EF91B5FC6E6D6C011F138F02-0FDAF001B5120F020391B612FC6E17F8DA003F16E0030F16800301EDFC00DB001F14E004-0001FCC702FCC7FC>112 144 120 270 129 100 D<94387FFFC0040FB6FC93B712E003-0716FC031F16FF037F17C04AB912F00207DAF80380021F912680003F13FE4A49C7000F7F-4A01F802038049B5486E804902C06E6C7F494A6F7F4991C9FC49727F4949707F4B844984-90B548707F5A4B198048855D481CC086481CE05D5A871DF05AA25D5AA21DF887A2B6FCA3-92BBFCA51DF00380CDFCA77EA4817EA37EA2817EA26CF307F06FF00FF87E816C1B1F6F19-F06C1B3F6D6DF07FE06D7FF4FFC06D6E4C13806D6E5E6D02F04C13006D6EEE1FFE6D6E4C-5A6D6C01FFEEFFF86E02E002035B6E02FC021F5B02079126FFC003B55A6E92B7C7FC0200-60033F17F8030F17E003011780DB003F03FCC8FC040315C0DC000F01F8C9FC5D5F7ADD6A->I[<EC3FC0ECFFF0010313FC497F497F498049804980A290B67EA24881A86C5DA26D5CA2-6D5C6D5C6D91C7FC6D5B6D5B010013F0EC3FC091C9FCB3A3ED3FE0017FB5FCB7FCA9EA00-3F1307A27FB3B3B3B0B9FCA9>48 144 119 271 64 105 D[<ED3FE0017FB5FCB7FCA9EA-003F1307A27FB3B3B3B3B3B3ACB91280A9>49 143 119 270 64-108 D<DB7FC0913803FFF890B6033FEBFFC0B74AB612F8060715FE061F6F7E067F16E04D-B87E4DD9F003804DD9800080DD0FFCC76C7FDD1FF080D8003F4B486E7F0107DB7F80804D-C8816DDAC1FE844D81EEC3F8DCC7F0845FEECFC0DCDF8081A204FFC981A25EA25EA35EA4-5EB3B3AFB900C090B912C0A9725D77DC81>110 D<94381FFFF00407B612C0047F15FC03-03B87E030F17E0037F17FC4ABAFC4A9126FC007F80020F02C0010714E04A49C880027F01-F8033F13FC91B5486F7F4902C003077F494A6F804991C96C80494970804949717F498749-49717FA290B548717F48884B83481D80A2481DC04B83481DE0A2481DF0A3484A7114F8A4-481DFCA5B61BFEAF6C1DFCA56C6E4D14F8A36C1DF0A36C1DE06F5F6C1DC0A26C6E4D1480-A26C1D006F5F6C646D6D4D5B6F94B5FC6D636D6D4C5C6D6E4B5C6D6E4B5C6D02F0031F5C-6D6E4B91C7FC6D6C01FE92B512FC6ED9FFC001075C6E02FC017F5C020791B812C0020196-C8FC6E6C17FC031F17F003031780DB007F03FCC9FC040715C0DC001F01F0CAFC675F7ADD-74>I<DB7F8049B47E90B6020F13F8B7027F13FE4DB67E4D15E0050F814D8194263FFE07-7F94387FF00FDEC01F7F4D48487FD8003F913881FE0001074B491480EE83F86DEC87F0A2-EE8FE05F169F5F04BFC76C1400A2735B16FE735B4C6E5B735B9638007F804C92C8FCA45E-A75EB3B3A9B912F8A9515D79DC5F>114 D<92260FFFF814F80203B638C001FC021FEDF8-0791B7EAFE0F0107EEFFBF4917FF013F9038F0000F4990C8FCD9FFF8153F4849150F4801-C015034849814890CAFC197F4848173FA24848171FA2007F180FA312FF19077FA27F8080-6E705A02F893C8FC14FEECFFC06C14FCEDFFE0EEFF806C16FCEFFFC06C17F86C17FF19C0-6C18F06C846C18FE6C846D846D846D840107840101846D6C83141F020383DA003F821503-DB000F1680EE003F050115C0717E181F1807007F050114E0486C8285856D83A2857F85A2-7F1BC07FA27F1B806D5FA26D19006E5E6E5F6E4C5A6E167F02FC4C5A6E03035B6E6C4A5B-03E0023F5B03FE0103B55A01F990B8C7FCD9F07F16FCD9E01F5ED9800716C0D900014BC8-FC48D9003F14F0007C020149C9FC4B5F78DD5C>I[<ED03FEA81507A5150FA4151FA3153F-A2157FA215FFA25CA25C5CA25C5C5C5C91B5FC13035B131F017F91B712F00007BAFCBBFC-A7C76C49C9FCB3B3AAF101FFB1616E17FE82A219076E17FC836EEE0FF871131F6EEE3FF0-6E02F0EB7FE07113FF6EDAFE0313C06E91B612806F16006F5D030F5D03035D030015E004-0F91C7FC040013F8>72 132 124 258 90 I<DB1FF0F01FF0017FB5057FB5FCB793B7FC-A9D8003FF0003F01071907A26D85B3B3B063A463A263A26D61A26398B6FC6D6E16FDF201-F96E1703E007F1806E6DED1FE170DB3FC114FF6E6D03FFEEFFC06E02C0010313816E02F8-011F13016E91B612FC020017F86F16F0030F16C003031600DB003F14F8040102800480C7-FC725E77DC81>I E-%EndDVIPSBitmapFont-%DVIPSBitmapFont: Fh cmbx12 20.74 8-/Fh 8 117 df<EE01F04C7E160F161F167FED01FF1507153F4AB5FC141F010FB6FCB8FC-A44A7E14E0EBF000C8FCB3B3B3B3B0007FBA12F0A7447171F061>49-D<96267FFFE01670063FB616F80503B700E01401053F04FC14034CB91407040706C0130F-043F06F0131F93B626FE000F01FC133F030303809026007FFE137F030F02FCC8390FFF80-FF4B02E0030313C1037F91CA13E392B500FCEF3FF7020302F071B5FC4A4A17074A028083-4A91CB7E4A01FC844A498591B54885494A854988494A85495C93CD7E4988495B49885D90-B51C7F5D481E3F485CA21F1F485CA2481E0F5D5AA21F075D5AA2F703F09CC7FC5AA392D1-FCA2B6FCB27EA281A37EA3F701F06CF603F881A37E816C1E0720F06C80A36C6E1B0F6C1F-E06F1B1F7F6F1CC06D1D3F6D6DF37F807F70F2FF006D6E626D6E19016D525A6D6E4F5A6E-6D190F6E01FE4F5A6E6D4F5A6E6E4E5A6E02E04D485A6E6E4D90C7FC020002FCEF0FFE6F-01FFEF3FFC031F02E0EEFFF06F02FC03075B0303DAFFC0023F1380030003FE0107B5C8FC-043F91B712FC040718F0040118C0DC003F94C9FC050316F8DD003F1580DE007F01F0CAFC-757A75F78C>67 D<92383FFFF8020FB612E0027F15FC0103B87E010F17E04983499026E0-007F13FCD97FFCC7000F7F496C02037F486D6E806F6D6C7F86486E6E7F727F8684868486-6C5CA26C91C86C806D5A6D5A6D5AEB03C090CAFCA80507B6FC041FB7FC0303B8FC157F02-03B9FC021FECFE0391B612800103ECF800010F14C04991C7FC017F13FC90B512F04814C0-485C4891C8FC485B485BA2485BA2485BA2B5FC5CA360A360806C5FA26C6D153E6E5D6C05-FC806C01FFDA03F8806C6ED90FF014FC6C02E090263FE07FEBFFFC6C9128FC03FFC03F14-FE6C91B61280013F4B487E010F4B1307010303F01301D9003F0280D9001F13FC020101F8-CBFC57507ACE5E>97 D<EE3FFF0307B512F8033F14FF4AB712E0020716F8021F16FE027F-D9F8037F49B526C0007F7F4991C76C13E04901FC020F7F49498049496E7F49496E7F4949-6E7F90B55A48727E92C9FC48721380485B1BC048841BE0485BA27313F05AA25C5AA21BF8-85A2B5FCA391BAFCA41BF002F8CCFCA67EA3807EA47E806CF101F0F203F86C7F1A076C6E-17F06C190F6F17E06C6E161F6D6DEE3FC06D6D167F6D6DEEFF806D6D030313006D6D6C4A-5A6D02E0EC1FFC6D02F8EC7FF86D913AFF8007FFF0023F91B65A020F178002034CC7FC02-0016F8031F15C003014AC8FCDB000F13C04D507BCE58>101 D<903801FFFCB6FCA7C67E-131F7FB3AE95380FFFE095B512FE05036E7E050F15E0053F15F84D819426FFF01F7F4CD9-00077FDC07FC010180EE0FF0DC1FC06D804D82043EC87E5E04FC835EDBFDF0815E03FF84-5EA25EA393C9FCA45DB3B3A7B8D8E003B81280A7617879F76C>104-D<902601FFFCEC7FFEB60207B512F0053F14FE4CB712C0040716F0041F824C16FE4CD900-7F7FC66C9026FDFFF0010F14C0011F90B500800103806D4AC76C804C6E6C7F04F06F7F4C-6F7F5E4C6F7F93C96C14805D7414C01DE0861DF0A2861DF8A2871DFCA57513FEAF5113FC-A41DF8A298B5FC1DF0A2621DE0A25014C01D80626F1900505B705D705F704B5B704B5B70-92B55A04FE02035C706C010F91C7FC4B01E0013F5B93267FFC01B55A041FB712F07016C0-040393C8FC040015F8051F14C0050301F0C9FC94CCFCB3A7B812E0A75F6F7ACD6C>112-D<902601FFF8EB07FEB691383FFFC094B512F04C800407804C8093391FFC3FFF93263FE0-7F1380C66C0380B512C0011F4A5A6DDAFC0114E0A2EDF9F816F015FB16E015FF4C6C14C0-A24C6D1380721300725A93C76C5AF001E095C8FCA25DA55DB3B3A4B812F8A7434E7ACD4F->114 D<157FA75DA45CA45CA25CA25CA25CA25C5C91B5FC5B5B5B5B133F90B6FC000792-B6FCBAFCA6D8000791C9FCB3B3A4F00FE0AE181F6D6E14C0A2183F6D178070137F6D1700-705B6E6D485A6E9038FE07FC6E90B55A6E5D6E5D02015D6E6C5C031F49C7FC030013F03B-6E7CEC4B>116 D E-%EndDVIPSBitmapFont-end-%%EndProlog-%%BeginSetup-%%Feature: *Resolution 600dpi-TeXDict begin-%%PaperSize: A4--%%EndSetup-%%Page: 1 1-1 0 bop 382 1171 a Fh(Chapter)65 b(1)382 1586 y Fg(FstStudio)79-b(User)e(Man)-6 b(ual)382 2067 y Ff(1.1)135 b(In)l(tro)t(duction)382-2270 y Fe(FstStudio)39 b(\(Finite)g(State)h(T)-8 b(ransducer)37-b(Studio\))i(is)f(a)h(program)f(for)g(construction)382-2383 y(and)30 b(running)e(of)j(\014nite)f(state)i(transducers.)40-b(If)30 b(y)m(ou're)h(not)g(familiar)f(with)g(the)h(con-)382-2496 y(cept)g(of)f(transducers)g(and)g(regular)g(relations,)i(then)e-(Xero)m(x's)h(fst)g(homepage)382 2609 y(h)m(ttp://www.xrce.xero)m-(x.com/researc)m(h/mltt/fst/)382 2722 y(is)25 b(recommended)e(as)i(an)g-(in)m(tro)s(duction)g(\(primarily)f(b)s(ecause)h(the)h(syn)m(tax)f(of)g-(Xero)m(x's)382 2835 y(fst)30 b(program)f(has)h(functioned)g(as)h(an)f-(inspiration)h(for)f(the)g(syn)m(tax)h(of)g(fstStudio\).)382-3121 y Ff(1.2)135 b(Installation)382 3324 y Fe(If)23-b(y)m(ou)h(ha)m(v)m(e)h(access)h(to)e(the)g(binary)f(\014le,)j(then)d-(all)i(y)m(ou)f(ha)m(v)m(e)h(to)g(do)f(is)f(to)i(cop)m(y)g(the)f-(\014le)382 3437 y(to)j(an)g(appropriate)f(library)g(and)g(run)f(the)i-(program)e(according)j(to)f(the)g(instructions)382 3550-y(b)s(elo)m(w.)42 b(If)30 b(y)m(ou)h(ha)m(v)m(e)h(access)f(to)h(the)f-(source)f(co)s(de,)i(compile)e(the)h(system)f(b)m(y)g(t)m(yping)382-3663 y(\\mak)m(e".)45 b(This)30 b(will)i(construct)g(a)g(\014le)g-(named)e(\\fst")i(in)f(the)h(source)f(library)-8 b(.)44-b(T)-8 b(o)32 b(b)s(e)382 3776 y(able)g(to)g(compile)f(the)h(system,)f-(y)m(ou)h(m)m(ust)e(ha)m(v)m(e)j(ghc)e(installed)i(at)f(y)m(our)f-(system.)43 b(If)382 3889 y(y)m(ou)35 b(don't)f(ha)m(v)m(e)i(it)f-(already)-8 b(,)37 b(a)e(free)g(distribution)f(of)h(ghc)f(can)h(b)s(e)f-(do)m(wnloaded)h(at)382 4002 y(h)m(ttp://www.hask)m(ell.org/ghc/.)59-b(It)35 b(can)h(also)g(b)s(e)f(run)e(in)i(Hugs.)56 b(Load)35-b('Main.hs')382 4114 y(and)30 b(t)m(yp)s(e)g('main'.)382-4401 y Ff(1.3)135 b(Syn)l(tax)382 4604 y Fe(fstStudio)37-b(tak)m(es)j(a)e(program)f(consisting)h(of)g(regular)h(relations)g-(that)f(denotes)g(the)382 4717 y(relation)23 b(b)s(et)m(w)m(een)g(t)m-(w)m(o)h(regular)f(languages)g(and)f(constructs)g(a)h(transducer.)37-b(If)22 b(a)h(reg-)382 4830 y(ular)k(expression,)g(not)g(a)h(relation,)-h(is)e(giv)m(en,)i(then)d(it)i(is)f(in)m(terpreted)g(as)g(the)g(iden)m-(tit)m(y)382 4943 y(relation.)40 b(The)25 b(syn)m(tax)h(is)f(v)m(ery)h-(similar)f(to)h(Xero)m(x's)h(\014nite)e(state)i(transducer)d(syn)m(tax)-382 5055 y(with)33 b(t)m(w)m(o)j(fundamen)m(tal)c(di\013erences:)48-b(a)34 b(distinction)h(is)f(made)f(b)s(et)m(w)m(een)h(functions)382-5168 y(\(de\014nitions\))d(and)e(strings,)i(and)e(fststudio)i(allo)m-(ws)g(functional)g(de\014nitions.)382 5381 y Fd("a")1854-5652 y Fe(1)p eop-%%Page: 2 2-2 1 bop 609 548 a Fe(sym)m(b)s(ol.)609 661 y(Example:)40-b(["b"])31 b(denotes)g(the)g(language)g Fc(f)p Fe("b")p-Fc(g)p Fe(.)382 846 y Fd(a)609 959 y Fe(v)-5 b(ariable.)42-b(A)30 b(sym)m(b)s(ol)f(without)i(quotes)g(is)f(a)h(v)-5-b(ariable.)382 1256 y Fd("a":"b")609 1369 y Fe(Describ)s(es)43-b(a)f(relation)i(b)s(et)m(w)m(een)f(the)g(sym)m(b)s(ol)e(a)i(and)e(b.)-76 b(This)42 b(relation)i(is)609 1482 y(ordered)29 b(and)g(a)h(is)g-(said)g(to)g(b)s(e)f(a)h(part)g(of)f(the)h(upp)s(er)e(language)j(and)e-(b)g(is)h(said)609 1595 y(to)h(b)s(e)f(part)g(of)h(the)f(lo)m(w)m(er)i-(language.)609 1708 y(Example:)40 b([)31 b("a":"b")h(])e(denotes)h(the)-g(relation)g Fc(f)p Fe(\("a","b"\))p Fc(g)p Fe(.)382-1893 y Fd(0)609 2006 y Fe(epsilon)j(sym)m(b)s(ol.)51-b(The)33 b(epsilon)h(sym)m(b)s(ol)f(denotes)h(the)g(string)g(with)g(no)-g(sym-)609 2118 y(b)s(ols.)609 2231 y(Example:)40 b([0])31-b(denotes)g(the)g(language)g Fc(f)p Fe("")p Fc(g)p Fe(.)382-2416 y Fd(?)609 2529 y Fe(all)40 b(sym)m(b)s(ol.)64 b(The)39-b(all)g(sym)m(b)s(ol)f(denotes)h(the)g(union)f(of)h(all)h(sym)m(b)s-(ols)d(in)h(the)609 2642 y(alphab)s(et.)609 2755 y(Example:)d([?])i-(and)20 b(an)g(alphab)s(et)g Fc(f)p Fe(a,)k(b,)e(c)p-Fc(g)f Fe(denotes)g(the)f(language)i Fc(f)p Fe(\\a","b","c")p-Fc(g)p Fe(.)382 2940 y Fd("")609 3052 y Fe(quotes)31-b(cancels)h(ev)m(ery)f(sp)s(ecial)g(meaning)e(of)i(the)f(sym)m(b)s-(ols.)609 3165 y(Example:)40 b(["?)71 b(0"])32 b(denotes)f(the)f-(language)i Fc(f)p Fe("?)72 b(0")p Fc(g)p Fe(.)382 3350-y Fd([A)45 b Fe(])609 3463 y(brac)m(k)m(ets)32 b(are)f(used)e(to)i(c)m-(hange)h(the)f(precedence)f(of)h(a)g(regular)f(relation.)382-3648 y Fd(\(A\))609 3761 y Fe(paren)m(thesis)h(expresses)f(optionalit)m-(y)-8 b(,)33 b(and)d(has)g(the)h(same)e(meaning)h(as)h([)p-Fb(A)p Fc(j)p Fe(0].)382 3946 y Fd(A)70 b(B)609 4058-y Fe(Concatenation)32 b(of)f(the)f(expressions)g(or)h(relations)g(A)g-(and)e(B.)609 4171 y(Example:)39 b([[a)55 b(b])27 b([c)55-b(d]])28 b(denotes)g(the)f(language)i Fc(f)p Fe("ac",)h("ad",)f("b)s-(c",)g("b)s(d")p Fc(g)382 4356 y Fd(A)35 b(^)g(n)609-4469 y Fe(Concatenation)d(of)f(A)f(n)g(times.)40 b(A^0)32-b(is)e(de\014ned)f(as)i(the)f(empt)m(y)g(string.)609-4582 y(Example:)40 b([a]^3)32 b(describ)s(es)e(the)g(language)i-Fc(f)p Fe("aaa")p Fc(g)p Fe(.)382 4767 y Fd(A)70 b(B)609-4880 y Fe(Union)30 b(of)h(the)f(languages)i(or)e(relations)i(A)e(and)g-(B.)609 4992 y(Example:)40 b([a)61 b(b])30 b(describ)s(es)g(the)h-(language)g Fc(f)p Fe(\\a",)i(\\b")p Fc(g)p Fe(.)382-5177 y Fd(A)i(&)g(B)609 5290 y Fe(In)m(tersection)d(of)e(the)h-(languages)h(A)e(and)g(B.)609 5403 y(Example:)40 b([a)61-b(b])30 b(&)g([a])i(describ)s(es)d(the)i(language)h Fc(f)p-Fe(\\a")p Fc(g)p Fe(.)1854 5652 y(2)p eop-%%Page: 3 3-3 2 bop 382 548 a Fd(A)35 b(-)f(B)609 661 y Fe(Min)m(us)e(of)h(the)f-(languages)h(A)g(and)e(B,)i(and)f(has)g(the)g(same)g(meaning)f(as)h([A)-h(&)609 774 y Fc(\030)10 b Fb(B)5 b Fe(])609 887 y(Example:)40-b([a)61 b(b])30 b(-)h([a])g(describ)s(es)f(the)g(language)i-Fc(f)p Fe(\\b")p Fc(g)p Fe(.)382 1073 y Fc(\030)p Fd(A)609-1186 y Fe(Describ)s(es)25 b(the)f(complemen)m(t)g(of)g(an)h-(expression,)g(and)f(has)g(the)h(same)e(meaning)609 1299-y(as)k([?*)g(-)g(A].)g(Note)g(that)h(complemen)m(t)d(is)i(alw)m(a)m(ys)-h(de\014ned)d(o)m(v)m(er)j(an)e(alphab)s(et)g(-)609 1412-y(the)h(expression)g Fc(\030)10 b Fe([)p Fb(A)p Fe(])27-b(is)g(only)g(unam)m(biguous)e(with)i(resp)s(ect)g(to)h(an)e(alphab)s-(et.)609 1525 y(Example:)50 b Fc(\030)18 b Fe([)p Fb(a)p-Fe(])35 b(denotes)h(the)f(language)i(that)f(do)s(esn't)f(con)m(tain)h-(the)g(string)609 1638 y(\\a".)k(If)24 b(the)h(alphab)s(et)g(is)f-Fc(f)p Fe(a,b)p Fc(g)p Fe(,)k(then)c Fc(\030)10 b Fe([)p-Fb(a)p Fe(])25 b(denotes)g(the)g(language)h Fc(f)p Fe("",)h("b",)609-1751 y("aa",)33 b("ba",)e(...)p Fc(g)382 1937 y Fd(A+)609-2050 y Fe(Rep)s(etition)44 b(\(Kleenes)f(plus\).)77 b(A)42-b(concatenated)j(with)d(itself)h(an)g(arbitrary)609 2163-y(n)m(um)m(b)s(er)28 b(of)j(times,)f(including)g(zero)h(times.)609-2276 y(Example:)40 b([a]+)31 b(denotes)g(the)f(in\014nite)g(language)i-Fc(f)p Fe(\\a","aa","aaa")q(,...)q Fc(g)382 2463 y Fd(A*)609-2575 y Fe(Kleene's)f(star:)41 b([A+)61 b(0].)609 2688-y(Example:)40 b([a]*)32 b(denotes)f(the)f(in\014nite)g(language)i-Fc(f)p Fe("","a","aa",...)p Fc(g)382 2875 y Fd($A)609-2988 y Fe(Con)m(tainmen)m(t.)63 b(The)38 b(set)g(of)g(strings)g(where)f-(A)h(app)s(ear)f(at)i(least)g(once)f(as)g(a)609 3101-y(substring.)i(Con)m(tainmen)m(t)30 b(is)h(the)f(same)g(thing)g(as)h-([?*)g(A)f(?*])382 3287 y Fd(A)35 b(.x.)47 b(B)609 3400-y Fe(Cross)30 b(pro)s(duct)f(of)i(the)f(languages)i(A)e(and)g(B.)609-3513 y(Example:)39 b([[a)56 b(b])27 b(.x.)40 b(c])29-b(describ)s(es)e(the)h(relations)g Fc(f)p Fe(\("a",)j("c"\),)f(\(\\b",)-f("c"\))p Fc(g)p Fe(.)382 3700 y Fd(A)35 b(.o.)47 b(B)609-3813 y Fe(Comp)s(osition)30 b(of)g(the)h(relations)g(A)g(and)e(B.)609-3925 y(Example:)40 b([a:b)61 b(c:)41 b(d])30 b(.o.)42-b([d:e])31 b(describ)s(es)e(the)i(relation)g Fc(f)p Fe(\("c","e"\))p-Fc(g)p Fe(.)523 4135 y(The)41 b(precedence)i(of)f(the)g(op)s(erators)g-(is)g(as)g(follo)m(ws,)47 b(where)41 b(4)h(is)g(the)g(highest)382-4248 y(precedence:)382 4433 y Fd(4)k Fc(\030)30 b Fe(^)g(*)h(+)f($)382-4619 y Fd(3)46 b Fe(Concatenation)382 4806 y Fd(2)76-b Fe(&)30 b(-)382 4992 y Fd(1)46 b Fe(.x.)41 b(.o.)523-5177 y(A)31 b(\014le)g(con)m(taining)h(a)f(program)f(m)m(ust)f(end)h-(with)h(*.fst,)g(and)g(an)f(input)g(\014le)h(m)m(ust)382-5290 y(end)44 b(with)h(*.dat.)86 b(A)45 b(program)f(is)h(a)h-(collection)h(of)f(functions)e(de\014ning)g(regular)382-5403 y(relations.)39 b(A)22 b(function)h(with)f(zero)h(argumen)m(ts)e-(is)i(called)g(a)g Fd(de\014nition)e Fe(or)h(a)h Fd(macro)p-Fe(.)1854 5652 y(3)p eop-%%Page: 4 4-4 3 bop 523 548 a Fe(A)31 b(de\014nition,)f(or)g(a)h(macro,)f(can)h-(for)f(example)g(lo)s(ok)h(lik)m(e)h(this:)382 848 y-Fa(<digits>)45 b(::=)i("1")g(|)h("2")f(|)g("3")g(|)g("4")g(|)h("5")f(|)-1002 961 y("6")g(|)h("7")f(|)g("8")g(|)g("9")g(|)h("0";)382-1149 y Fe(and)30 b(a)g(function)g(can)h(lo)s(ok)g(lik)m(e)h(this:)382-1450 y Fa(<swap,a,b>)45 b(::=)i(b)g(a)h(;)523 1637 y-Fe(Note)29 b(that)g(strings)e(are)i(mark)m(ed)e(with)g(quotes,)i(and)f-(v)-5 b(ariables)28 b(ha)m(v)m(e)h(no)f(quotes.)523 1750-y(Ev)m(ery)42 b(program)e(m)m(ust)g(con)m(tain)j(a)e(main)g-(de\014nition)g(\(a)h(program)e(without)h(a)382 1863-y(main)29 b(de\014nition)h(will)h(result)f(in)g(a)h(parse)f(error\).)-382 2164 y Fa(<main>)46 b(::=)h(...)g(;)523 2351 y Fe(The)26-b(alphab)s(et)h(of)g(a)h(program)d(is)i(the)g(sym)m(b)s(ols)f(in)g(the)-i(regular)f(relation)h(de\014ned)382 2464 y(in)i(the)h(program.)382-2751 y Ff(1.4)135 b(Example)46 b(program)382 2953 y Fe(The)20-b(example)g(w)m(as)g(found)f(at)i(h)m(ttp://www.xrce.xero)m-(x.com/researc)m(h/mltt/fst/fsexamples.h)m(tml.)382 3066-y(The)38 b(program)f(sim)m(ulates)i(a)f(so)s(da)h(mac)m(hine)f(and)g-(tak)m(es)h(a)g(collection)i(of)e(sym)m(b)s(ols)382 3179-y(that)32 b(sym)m(b)s(olises)e(di\013eren)m(t)i(coins.)43-b(If)31 b(the)h(amoun)m(t)e(of)i(money)e(applied)h(to)h(the)f(ma-)382-3292 y(c)m(hine)26 b(corresp)s(onds)e(to)j(65)f(cen)m(t,)i(then)d(the)h-(mac)m(hine)f(pro)s(duces)g(a)h(PLONK)f(\(enough)382-3405 y(money)k(has)h(b)s(een)g(put)g(in)m(to)h(the)g(mac)m(hine)f(to)h-(get)g(a)g(so)s(da\).)382 3618 y Fa(<nickel>)93 b(::=)47-b(["n")g(.x.)g("c"^5];)382 3731 y(<dime>)189 b(::=)47-b(["d")g(.x.)g("c"^10];)382 3843 y(<quarter>)e(::=)i(["q")g(.x.)g-("c"^25];)382 3956 y(<cent>)189 b(::=)47 b(["c")g(.x.)g("c"];)382-4069 y(<money>)141 b(::=)47 b([)h(<nickel>)d(|)j(<dime>)e(|)h-(<quarter>)e(|)j(<cent>]*;)382 4182 y(<drink>)141 b(::=)47-b(["c"^65)f(.x.)h("PLONK"];)382 4295 y(<main>)189 b(::=)47-b([)h(<money>)d(.o.)i(<drink>)f(];)382 4582 y Ff(1.5)135-b(Running)45 b(FstStudio)382 4784 y Fe(fstStudio)30 b(can)g(b)s(e)g-(run)f(in)h(t)m(w)m(o)i(mo)s(des,)d(batc)m(h)i(mo)s(de)e(and)h(in)m-(teractiv)m(e)j(mo)s(de.)382 5071 y Ff(1.6)135 b(Batc)l(h)45-b(mo)t(de)382 5274 y Fd(fst)609 5387 y Fe(Starts)31 b(fstStudio)e(in)i-(in)m(teractiv)m(e)i(mo)s(de.)39 b(See)31 b(b)s(elo)m(w.)1854-5652 y(4)p eop-%%Page: 5 5-5 4 bop 417 548 a Fd(fst)34 b(FILE)g([Options)45 b Fe(])609-661 y(Run)24 b(fstStudio)g(in)g(batc)m(h)h(mo)s(de.)38-b(FILE)24 b(m)m(ust)f(end)h(with)h(*.fst,)h(whic)m(h)f(de\014nes)609-774 y(a)38 b(FstStudio)f(program,)i(or)e(*.net,)j(whic)m(h)d(de\014nes)-g(a)h(sa)m(v)m(ed)g(transducer.)61 b(If)609 887 y(no)27-b(options)g(is)g(giv)m(en,)h(then)f(input)f(is)h(tak)m(en)g(from)f-(standard)g(input,)h(the)f(tran-)609 1000 y(ducer)f(is)h(applied)f(do)m-(wn,)i(and)e(the)h(output,)g(if)g(an)m(y)-8 b(,)27 b(is)f(pro)s(duced)e-(on)h(standard)609 1112 y(output.)p 523 1233 1549 4 v-523 1250 V 521 1363 4 113 v 538 1363 V 589 1329 a Fd(Options)p-996 1363 V 99 w(Meaning)p 2053 1363 V 2070 1363 V 523-1366 1549 4 v 521 1479 4 113 v 538 1479 V 589 1445 a-Fe(-u)p 996 1479 V 377 w(apply)30 b(the)h(transducer)e(up)p-2053 1479 V 2070 1479 V 521 1592 V 538 1592 V 589 1558-a(-d)p 996 1592 V 377 w(apply)h(the)h(transducer)e(up)p-2053 1592 V 2070 1592 V 521 1705 V 538 1705 V 589 1671-a(-i)i(FILE)p 996 1705 V 161 w(tak)m(e)h(input)d(from)g(FILE)p-2053 1705 V 2070 1705 V 521 1818 V 538 1818 V 589 1784-a(-o)j(FILE)p 996 1818 V 140 w(write)f(output)f(to)h(FILE)p-2053 1818 V 2070 1818 V 523 1821 1549 4 v 523 1838 V-382 2065 a Ff(1.7)135 b(In)l(teractiv)l(e)47 b(mo)t(de)382-2268 y Fe(In)m(teractiv)m(e)33 b(mo)s(de)c(is)h(en)m(tered)h(b)m(y)f(t)-m(yping)h(the)g(follo)m(wing)h(command:)382 2585 y Fa($)47-b(fstStudio)f(<return>)382 2811 y(************************)o(****)o-(***)o(****)o(****)o(***)o(****)o(****)o(***)382 2924-y(*)h(Welcome)f(to)h(Finite)f(State)h(Transducer)e(Studio!)380-b(*)382 3036 y(*)47 b(Written)f(purely)g(in)h(Haskell.)1144-b(*)382 3149 y(*)47 b(Version)f(:)i(0.9)1765 b(*)382-3262 y(*)47 b(Date)190 b(:)48 b(11)f(August)f(2001)1240-b(*)382 3375 y(*)47 b(Author)94 b(:)48 b(Markus)e(Forsberg)1191-b(*)382 3488 y(*)47 b(Please)f(send)h(bug)g(reports/suggestions)c(to:)-524 b(*)382 3601 y(*)47 b(d97forma@dtek.chalmers.se)1187-b(*)382 3714 y(************************)o(****)o(***)o(****)o(****)o-(***)o(****)o(****)o(***)382 3940 y(Type)47 b('h')f(for)h(help.)382-4166 y(>)382 4564 y Ff(1.8)135 b(List)46 b(of)f(commands)382-4767 y Fd(r)35 b(REG)609 4879 y Fe(Read)g(a)h(regular)f(relation)h-(from)d(standard)h(input.)54 b(If)34 b(a)i(regular)f(expression)609-4992 y(is)c(t)m(yp)s(ed,)f(then)g(it)h(is)f(in)m(terpreted)h(as)g(the)f-(iden)m(tit)m(y)i(relation.)382 5177 y Fd(b)609 5290-y Fe(Build)20 b(a)h(epsilonfree,)i(deterministic,)f(minimal)d-(transducer)g(from)g(a)i(loaded/t)m(yp)s(ed)609 5403-y(regular)31 b(relation.)1854 5652 y(5)p eop-%%Page: 6 6-6 5 bop 382 548 a Fd(bn)609 661 y Fe(Build)47 b(a)g(epsilonfree,)k(p)s-(ossibly)46 b(non-deterministic,)k(non-minimal)45 b(trans-)609-774 y(ducer)30 b(from)f(a)i(load/t)m(yp)s(ed)g(regular)f(relation.)382-961 y Fd(m)609 1074 y Fe(Minimize)h(a)f(built)h(transducer.)382-1262 y Fd(det)609 1375 y Fe(Determinize)g(a)g(built)f(transducer)382-1562 y Fd(s)35 b(FILE)609 1675 y Fe(Sa)m(v)m(e)k(to)e(FILE.)h(If)e-(FILE)h(ends)f(with)h(*.net,)j(then)d(the)g(built)g(transducer)g(is)609-1788 y(sa)m(v)m(ed.)55 b(An)m(y)34 b(other)h(su\016x,)g(sa)m(v)m(es)h-(the)f(pro)s(duced)e(output)h(in)g(the)h(system)f(to)609-1901 y(FILE,)d(if)f(an)m(y)-8 b(.)382 2089 y Fd(l)34-b(FILE)609 2202 y Fe(Load)i(from)e(FILE.)h(FILE)h(m)m(ust)e(end)h(with)-g(*.fst,)j(*.net)e(or)g(*.dat.)57 b(If)35 b(FILE)609-2315 y(ends)28 b(with)g(*.fst,)h(then)f(a)h(FstStudio)f(program)f(is)h-(loaded)h(in)m(to)g(FstStudio.)40 b(If)609 2428 y(FILE)33-b(ends)g(with)g(*.net,)j(then)d(a)h(transducer)f(is)g(loaded)h(in)m(to)-h(FstStudio.)50 b(If)609 2540 y(FILE)30 b(ends)g(with)g(*.dat,)i(then)e-(input)f(is)h(loaded)h(in)m(to)h(FstStudio.)382 2728-y Fd(l)i(ab)609 2841 y Fe(Load)c(and)e(union)g(t)m(w)m(o)j-(transducers.)39 b(a)30 b(and)e(b)h(m)m(ust)f(either)i(b)s(e)e(a)i-(\014le)f(ending)609 2954 y(with)22 b(*.net)h(or)g(the)f(sym)m(b)s(ol)f-(*,)k(whic)m(h)d(refers)f(to)i(the)g(in)m(terior)g(transducer.)37-b(The)609 3067 y(pro)s(duced)29 b(transducer)g(is)i(p)s(ossibly)e-(non-deterministic)h(and)g(non-minimal.)382 3254 y Fd(l)k(a)g(b)609-3367 y Fe(Load)44 b(and)g(concatenate)i(t)m(w)m(o)g(transducers.)80-b(a)45 b(and)e(b)h(m)m(ust)e(either)j(b)s(e)e(a)609 3480-y(\014le)f(ending)g(with)g(*.net)h(or)f(the)g(sym)m(b)s(ol)f(*,)k(whic)-m(h)d(refers)g(to)h(the)f(in)m(terior)609 3593 y(transducer.)81-b(The)43 b(pro)s(duced)f(transducer)h(is)h(p)s(ossibly)f-(non-deterministic)609 3706 y(and)30 b(non-minimal.)382-3894 y Fd(l)k(a)g(*)609 4007 y Fe(Load)41 b(and)g(apply)f(Kleene's)i-(star)f(on)g(a)g(transducer.)72 b(a)42 b(m)m(ust)d(either)j(b)s(e)e(a)-609 4120 y(\014le)i(ending)g(with)g(*.net)h(or)f(the)g(sym)m(b)s(ol)f-(*,)k(whic)m(h)d(refers)g(to)h(the)f(in)m(terior)609-4232 y(transducer.)81 b(The)43 b(pro)s(duced)f(transducer)h(is)h(p)s-(ossibly)f(non-deterministic)609 4345 y(and)30 b(non-minimal.)382-4533 y Fd(l)k(a)g(.o.)47 b(b)609 4646 y Fe(Load)42 b(and)g(comp)s(ose)f-(t)m(w)m(o)j(transducers.)75 b(a)42 b(and)g(b)f(m)m(ust)g(either)i(b)s-(e)e(a)i(\014le)609 4759 y(ending)32 b(with)g(*.net)i(or)e(the)h(sym)m-(b)s(ol)e(*,)j(whic)m(h)e(refers)g(to)i(the)e(in)m(terior)i(trans-)609-4872 y(ducer.)85 b(The)45 b(pro)s(duced)e(transducer)i(is)g(p)s-(ossibly)f(non-deterministic)h(and)609 4985 y(non-minimal.)382-5172 y Fd(vt)609 5285 y Fe(View)31 b(loaded/built)g(transducer.)1854-5652 y(6)p eop-%%Page: 7 7-7 6 bop 382 548 a Fd(vr)609 661 y Fe(View)31 b(loaded/t)m(yp)s(ed)g-(regular)g(relation.)382 847 y Fd(vi)609 960 y Fe(View)g(loaded)g-(input.)382 1146 y Fd(v)m(o)609 1259 y Fe(View)g(pro)s(duced)e(output.)-382 1445 y Fd(d)609 1558 y Fe(Apply)h(transducer)f(do)m(wn)h(with)g-(loaded)h(input.)382 1744 y Fd(u)609 1857 y Fe(Apply)f(transducer)f(up)-h(with)g(loaded)h(input.)382 2043 y Fd(d)k(SYMBOLS)609-2156 y Fe(Apply)30 b(tranducer)g(do)m(wn)f(with)i(SYMBOLS.)382-2342 y Fd(u)k(SYMBOLS)609 2455 y Fe(Apply)30 b(transducer)f(up)h(with)g-(SYMBOLS.)382 2641 y Fd(c)609 2754 y Fe(Clear)h(memory)-8-b(.)382 2940 y Fd(h)609 3053 y Fe(List)31 b(commands.)382-3239 y Fd(q)609 3352 y Fe(End)e(session.)382 3637 y Ff(1.9)135-b(Example)46 b(on)f(FstStudio)g(in)g(in)l(teractiv)l(e)i(mo)t(de)382-3840 y Fe(First,)39 b(sa)m(v)m(e)g(example)e(program)e(ab)s(o)m(v)m(e)k-(to)e(the)h(\014le)f('drink.fst'.)60 b(Then)36 b(start)i(Fst-)382-3953 y(Studio)30 b(in)g(in)m(teractiv)m(e)j(mo)s(de.)382-4161 y Fa(>l)47 b(drink.fst)382 4387 y(Loaded)f(a)h(regular)f(relation)-g(from)g(drink.fst.)382 4613 y(>b)382 4839 y(Built)g(a)i-(deterministic,)c(minimal)h(transducer)g(with)i(26)g(states)f(and)h(46)-g(transitions.)382 5064 y(>u)g(PLONK)382 5290 y(Input)f(accepted.)g-(Type)g('vo')h(to)g(view)g(outputs.)1854 5652 y Fe(7)p-eop-%%Page: 8 8-8 7 bop 382 548 a Fa(>vo)382 774 y(...)382 887 y(q)47-b(n)h(n)f(d)h(d)f(d)382 1000 y(q)g(n)h(n)f(d)h(d)f(n)h(n)382-1112 y(q)f(n)h(n)f(d)h(n)f(n)h(d)382 1225 y(q)f(n)h(n)f(d)h(n)f(n)h(n)f-(n)382 1338 y(q)g(n)h(n)f(d)h(n)f(d)h(n)382 1451 y(q)f(d)h(n)f(q)382-1564 y(q)g(d)h(n)f(n)h(d)f(d)382 1677 y(q)g(d)h(n)f(n)h(d)f(n)h(n)382-1790 y(q)f(d)h(n)f(n)h(n)f(n)h(d)382 1903 y(q)f(d)h(n)f(n)h(n)f(n)h(n)f-(n)382 2016 y(q)g(d)h(n)f(n)h(n)f(d)h(n)382 2129 y(q)f(d)h(n)f(d)h(n)f-(d)382 2242 y(q)g(d)h(n)f(d)h(n)f(n)h(n)382 2355 y(q)f(d)h(n)f(d)h(d)f-(n)382 2467 y(q)g(d)h(q)f(n)382 2580 y(q)g(d)h(d)f(d)h(d)382-2693 y(q)f(d)h(d)f(d)h(n)f(n)382 2806 y(q)g(d)h(d)f(n)h(n)f(d)382-2919 y(q)g(d)h(d)f(n)h(n)f(n)h(n)382 3032 y(...)382 3258-y(>s)f(drink.out)382 3484 y(Saved)f(outputs)g(to)h(file)g(drink.out.)-382 3709 y(>q)382 3935 y(Do)g(you)g(really)f(want)h(to)g(quit?)f-(\(y\):y)382 4161 y(Session)g(ended.)523 4374 y Fe(In)36-b('drink.out')g(w)m(e)h(no)m(w)f(ha)m(v)m(e)i(all)f(p)s(ossible)f(w)m-(a)m(ys)i(to)f(feed)f(the)h(so)s(da)f(mac)m(hine)382-4487 y(with)d(coins,)i(with)f(regard)f(to)i(order,)f(in)f(suc)m(h)g(a)h-(w)m(a)m(y)h(that)f(w)m(e)g(get)h(a)f(so)s(da.)50 b(There)382-4599 y(are)31 b(634)g(di\013eren)m(t)g(w)m(a)m(ys.)1854-5652 y(8)p eop-%%Trailer-end-userdict /end-hook known{end-hook}if-%%EOF
fst.cabal view
@@ -1,33 +1,95 @@-name: fst-version: 0.9.0.1-synopsis: Finite state transducers-description: Fst is an application for construction and running of- finite state transducers. The application was written- purely in Haskell, and is intended to be a tool for the- Haskell programmer, especially for ones that develop language applications.-category: Compilers/Interpreters-license: BSD3-license-file: LICENSE-author: Markus Forsberg-homepage: http://www.cse.chalmers.se/alumni/markus/fstStudio/-build-type: Simple-Cabal-Version: >= 1.2-tested-with: GHC==6.8.2+name: fst+version: 0.10.0.0+synopsis: Finite state transducers+description:+ Fst is an application for construction and running of finite state+ transducers, as based on the concepts of transducers and regular+ relations developed by Xerox. The syntax of Xerox's fst program has+ functioned as an inspiration for the syntax of fstStudio.+ .+ The application was written purely in Haskell, and is intended to be+ a tool for the Haskell programmer, especially for ones that develop+ language applications.+ .+ This package provides an interactive shell for parsing transducers+ specified in a specialized FST language. See "FST.FSTStudio".+ .+ This package also provides a programmer's interface for building and+ applying transducers. See "FST.TransducerInterface".+category: Compilers/Interpreters+license: BSD3+license-file: LICENSE+author: Markus Forsberg+maintainer: Baldur Blöndal, John J. Camilleri+homepage: http://www.cse.chalmers.se/alumni/markus/fstStudio/+bug-reports: https://github.com/johnjcamilleri/fst/issues+build-type: Simple+cabal-version: >= 1.8 -data-files: doc/fstMan0.9.ps, doc/Interface0.9.ps+extra-source-files:+ tests/drink.fst+ tests/drink.hs+ tests/email.fst+ tests/email.hs -Library- Build-Depends: base>=3 && <5, array- exposed-modules: FST.Alex, FST.Arguments, FST.Automaton, FST.AutomatonInterface, FST.AutomatonTypes,- FST.Complete, FST.Deterministic, FST.DeterministicT, FST.EpsilonFreeT, FST.FileImport,- FST.GetOpt, FST.Info, FST.LBFA, FST.LBFT, FST.Lexer, FST.MinimalBrzozowski, FST.MinimalTBrzozowski,- FST.NReg, FST.Parse, FST.RegTypes, FST.Reversal, FST.ReversalT, FST.RRegTypes, FST.RunTransducer,- FST.StateMonad, FST.Transducer, FST.TransducerInterface, FST.TransducerTypes, FST.Utils- ghc-options: -O2- ghc-prof-options: -prof -auto-all+source-repository head+ type: git+ location: git://github.com/johnjcamilleri/fst.git -Executable fst- main-is: FST/Main.hs- ghc-options: -O2- ghc-prof-options: -prof -auto-all+source-repository this+ type: git+ location: git://github.com/johnjcamilleri/fst.git+ tag: v0.10.0.0 +library+ build-depends:+ base>=4 && <5,+ array,+ mtl+ exposed-modules:+ FST.Automaton+ FST.AutomatonInterface+ FST.AutomatonTypes+ FST.Complete+ FST.Deterministic+ FST.DeterministicT+ FST.EpsilonFreeT+ FST.LBFA+ FST.LBFT+ FST.NReg+ FST.RegTypes+ FST.Reversal+ FST.ReversalT+ FST.RRegTypes+ FST.RunTransducer+ FST.Transducer+ FST.TransducerInterface+ FST.TransducerTypes+ FST.FSTStudio+ other-modules:+ FST.Alex+ FST.Arguments+ FST.Info+ FST.Lexer+ FST.Parse+ FST.Utils+ ghc-prof-options: -prof -auto-all++executable fststudio+ main-is: Main.hs+ ghc-prof-options: -prof -auto-all+ build-depends:+ base,+ array,+ mtl,+ transformers,+ haskeline++test-suite test-fst+ type: exitcode-stdio-1.0+ hs-source-dirs: tests+ main-is: properties.hs+ build-depends:+ base,+ fst,+ QuickCheck
+ tests/drink.fst view
@@ -0,0 +1,7 @@+<nickel> ::= ["n" .x. "c"^5];+<dime> ::= ["d" .x. "c"^10];+<quarter> ::= ["q" .x. "c"^25];+<cent> ::= ["c" .x. "c"];+<money> ::= [ <nickel> | <dime> | <quarter> | <cent> ]*;+<drink> ::= ["c"^65 .x. "PLONK"];+<main> ::= [ <money> .o. <drink> ];
+ tests/drink.hs view
@@ -0,0 +1,47 @@+-- | Haskell version of drinks example++import FST.TransducerInterface+import Data.Maybe (fromJust)++{-+<nickel> ::= ["n" .x. "c"^5];+<dime> ::= ["d" .x. "c"^10];+<quarter> ::= ["q" .x. "c"^25];+<cent> ::= ["c" .x. "c"];+<money> ::= [ <nickel> | <dime> | <quarter> | <cent> ]*;+<drink> ::= ["c"^65 .x. "PLONK"];+<main> ::= [ <money> .o. <drink> ];+-}++-- | Emulation of ^ operator+times :: Int -> String -> Reg String+times n str = foldl (\a b -> a |> s b) (s (head ss)) (tail ss)+ where ss = replicate n str++nickel = s "n" <*> (times 5 "c")+dime = s "d" <*> (times 10 "c")+quarter = s "q" <*> (times 25 "c")+cent = s "c" <*> s "c"+money = star (nickel <|> dime <|> quarter <|> cent)+drink = (times 65 "c") <*> s "PLONK"+main' = money <.> drink++main :: IO ()+main = do+ let trans = compile main' []+ putStrLn $ unwords $ concat $ fromJust $ applyUp trans ["PLONK"]++-- | Parsed version of drinks transducer+parsed :: RReg String+parsed = case either of+ Right r -> r+ where+ either = parseProgram $ unlines [+ "<nickel> ::= [\"n\" .x. \"c\"^5];",+ "<dime> ::= [\"d\" .x. \"c\"^10];",+ "<quarter> ::= [\"q\" .x. \"c\"^25];",+ "<cent> ::= [\"c\" .x. \"c\"];",+ "<money> ::= [ <nickel> | <dime> | <quarter> | <cent> ]*;",+ "<drink> ::= [\"c\"^65 .x. \"PLONK\"];",+ "<main> ::= [ <money> .o. <drink> ];"+ ]
+ tests/email.fst view
@@ -0,0 +1,51 @@+# Recogniser for email addresses with some support for known domains++<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;+<digit1> ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;+<letter> ::= "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" ;+<punct> ::= "!" | "#" | "$" | "%" | "&" | "'" | "*" | "+" | "-" | "/" | "=" | "?" | "^" | "_" | "{" | "|" | "}" | "~" ;+<hyphen> ::= "-" ;++# Local part+<local_sym> ::= <digit> | <letter> | <punct> ;+# Should be limited to 64 chars, but this is impossible to compile:+# <local> ::= [<local_sym>+] - [<local_sym>^65 <local_sym>*] ;+<local> ::= <local_sym>+ ;++# IP address+<ip_segment> ::=+ <digit>+ | [<digit1> <digit>]+ | ["1" <digit>^2]+ | ["2" ["0" | "1" | "2" | "3" | "4"] <digit>]+ | ["2" "5" [<digit> - ["6" | "7" | "8" | "9"]]]+ ; +<ip> ::= [<ip_segment> "."]^3 <ip_segment> ;++# DNS names+<hostname> ::= [<digit> | <letter> | <hyphen>]+ ;+<subdomain> ::= <hostname> ;+<domain> ::=+ [<subdomain> "."]* <hostname>+ | [(["Student":"student" | "Academic Staff":"staff"] "at":".") "Chalmers University":"chalmers"]+ | ["Apple Inc.":"apple"]+ | [("Google Mail":"mail" "at":".") "Google":"google"]+ ;++# Some known TLDs+<tld_se> ::= "Sweden":"se" ;+<tld_mt> ::= "Malta":"com.mt" ;+<tld_uk> ::= "UK":"co.uk" ;+<tld_com> ::= "com" ;+<tld_net> ::= "net" ;+<tld_org> ::= "org" ;+<tld> ::= <tld_se> | <tld_mt> | <tld_uk> | <tld_com> | <tld_net> | <tld_org> ;++# Either DNS or IP+<email> ::=+ [<local> "@" <domain> ["|":"."] <tld>]+ | [<local> "@" <ip>]+ ;++<main> ::= <email> ;+
+ tests/email.hs view
@@ -0,0 +1,108 @@+-- | Email address recogniser using transducer interface API++import FST.TransducerInterface+import Data.Maybe (fromJust)++charsToUnion :: [Char] -> Reg String+charsToUnion cs = foldl (\a b -> a <|> s [b]) (s [head cs]) (tail cs)++digit :: Reg String+digit = charsToUnion ['0'..'9']++digit1 :: Reg String+digit1 = charsToUnion ['1'..'9']++letter :: Reg String+letter = charsToUnion ['a'..'z']++punct :: Reg String+punct = charsToUnion "!#$%&'*+-/=?^_{|}~"++hyphen :: Reg String+hyphen = s "-" ;++-- Local part+local :: RReg String+local = idR $ plus local_sym+ where local_sym = digit <|> letter <|> punct++-- Should be limited to 64 chars, but this is impossible to compile:+-- local = idR $ (plus local_sym) <-> over65+-- where local_sym = digit <|> letter <|> punct+-- over65 = foldl (\a b -> a <|> b) local_sym (replicate 65 local_sym)++-- IP address+ip_segment :: Reg String+ip_segment =+ digit+ <|> (digit1 |> digit)+ <|> (s "1" |> digit |> digit)+ <|> (s "2" |> d0to5 |> digit)+ <|> (s "2" |> s "5" |> (digit <-> d6to9))+ where+ d0to5 = s "0" <|> s "1" <|> s "2" <|> s "3" <|> s "4"+ d6to9 = s "6" <|> s "7" <|> s "8" <|> s "9"++ip :: RReg String+ip = idR $ ip_segment |> dot |> ip_segment |> dot |> ip_segment |> dot |> ip_segment+ where dot = s "."++-- DNS names+hostname :: Reg String+hostname = plus (digit <|> letter <|> hyphen)++subdomain :: RReg String+subdomain = idR hostname++-- | Emulation of optionality (?)+option :: RReg String -> RReg String+option rr = rr <|> idR eps++domain :: RReg String+domain =+ ((star (subdomain |> dot)) |> idR hostname)+ <|> option ((student <|> staff) |> dot) |> "Chalmers University" `r` "chalmers"+ <|> "Apple Inc." `r` "apple"+ <|> option gmail |> ("Google" `r` "google")+ where+ student = "Student" `r` "student"+ staff = "Academic Staff" `r` "staff"+ gmail = "Google Mail" `r` "mail" |> dot+ dot = "at" `r` "."++-- Some known TLDs+tld_se = "Sweden" `r` "se"+tld_mt = "Malta" `r` "com.mt"+tld_uk = "UK" `r` "co.uk"+tld_com = idR (s "com")+tld_net = idR (s "net")+tld_org = idR (s "org")+tld = tld_se <|> tld_mt <|> tld_uk <|> tld_com <|> tld_net <|> tld_org++-- | An email address using either DNS names or IP address+email :: RReg String+email =+ local |> at |> domain |> dot |> tld+ <|> local |> at |> ip+ where+ at = idR (s "@")+ dot = "|" `r` "."++-- | Main test function+main :: IO ()+main = do+ let trans = compile email [] :: Transducer String+ tests = map words [test1, test2, test3, test4, test5, test6]+ sequence_ $ map (handle . applyUp trans) tests+ where+ handle :: Maybe [[String]] -> IO ()+ handle (Just outs) = putStrLn $ unwords $ concat outs+ handle Nothing = putStrLn "Input rejected."++-- Test cases+test1 = "j o h n @ 1 9 2 . 1 6 8 . 0 . 1"+test2 = "j o h n { 8 6 } @ chalmers . se"+test3 = "j - ! @ student . chalmers . se"+test4 = "a b c d @ staff . chalmers . se"+test5 = "# $ % ^ @ mail . google . com.mt"+test6 = "b a l d u r @ apple . co.uk"
+ tests/properties.hs view
@@ -0,0 +1,92 @@+{-# LANGUAGE ViewPatterns #-}++import Data.List+import Control.Applicative+import Control.Monad+import Data.Maybe++import Test.QuickCheck++import FST.LBFA+import FST.Automaton++import FST.RegTypes+import FST.RRegTypes (idR)+import FST.TransducerTypes+import FST.TransducerInterface (compile)+import FST.RunTransducer++instance Arbitrary a => Arbitrary (Reg a) where+ arbitrary = oneof [return Empty,+ return Epsilon,+ return All,+ liftM2 (:|:) arbitrary arbitrary,+ liftM2 (:.:) arbitrary arbitrary,+ liftM2 (:&:) arbitrary arbitrary,+ liftM Symbol arbitrary,+ liftM Complement arbitrary,+ liftM Star arbitrary]++-- | A datatype that only accepts the empty string.+newtype EmptyString a = EmptyString { unEmpty :: Reg a } deriving Show++instance Arbitrary a => Arbitrary (EmptyString a) where+ arbitrary =+ fmap EmptyString $+ oneof [return Epsilon,+ liftM Star arbitrary,+ liftM2 (:|:) arbitrary (fmap unEmpty arbitrary),+ liftM2 (:|:) (fmap unEmpty arbitrary) arbitrary,+ liftM2 (:&:) (fmap unEmpty arbitrary) (fmap unEmpty arbitrary),+ liftM2 (:.:) (fmap unEmpty arbitrary) (fmap unEmpty arbitrary),+ fmap (Complement . Complement) (fmap unEmpty arbitrary)] + +prop_empty :: Eq a => EmptyString a -> Bool+prop_empty (EmptyString xs) = acceptEps xs++instance Arbitrary a => Arbitrary (Symbol a) where+ arbitrary = frequency [(4, S `fmap` arbitrary)+ ,(1, return Eps )] +++newtype Language = Language { unLanguage :: (Reg Char, [String]) } deriving Show++instance Arbitrary Language where+ arbitrary = sized gLanguage + +gLanguage :: Int -> Gen Language+gLanguage 0 = Language `fmap` oneof+ -- Return empty language ε+ [return (Epsilon, [""]),+ + -- Return one of two symbols: a or b+ elements "ab" >>= \ch -> return (Symbol ch, [[ch]])]+gLanguage n = Language `fmap` oneof+ -- Generate A* ≅ {ε, A, A} out of arbitrary A+ [do (reg, lang) <- fmap unLanguage subGen+ let matches = concat [[""], lang, (++) <$> lang <*> lang]+ return (Star reg, nub matches),+ + -- Sequence A B out of arbitrary A and B+ do (reg1, lang1) <- fmap unLanguage subGen+ (reg2, lang2) <- fmap unLanguage subGen+ let matches = (++) <$> lang1 <*> lang2+ return (reg1 :.: reg2, nub matches)]+ where subGen :: Gen Language+ subGen = gLanguage (n `div` 4)++-- If a regular expression generates a (sub)language, then compiling it and +-- running it on all strings of that languages should always match.+prop_language (Language (reg, inputs)) =+ and [ maybe False (elem input) appliedUp && maybe False (elem input) appliedDown+ | input <- inputs+ , let appliedUp = applyUp (compile (idR reg) "ab") input+ , let appliedDown = applyDown (compile (idR reg) "ab") input ] ++-- | Run the test suite+main :: IO ()+main = do+ putStrLn "Running tests"+ quickCheck (prop_empty :: EmptyString String -> Bool)+ quickCheck prop_language+