Loading src/random-wta/Generator.hs +8 −9 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE LambdaCase #-} module Generator (genWTA, runGenerator, GeneratorConfig(..), ZeroFrequency(..)) where module Generator (genWTA, runGenerator, GeneratorConfig(..), EdgeConfig(..)) where import Data.Vector ( Vector ) import qualified Data.Vector as V Loading @@ -21,18 +21,18 @@ import Probability import IndexedTransition import qualified IndexedTransition data ZeroFrequency = Percentage Probability | OutDegree Int data EdgeConfig = ZeroFrequency Probability | NumTransitions Int data GeneratorConfig m = GeneratorConfig { spec :: WTASpec m , zeroPolicy :: ZeroFrequency , zeroPolicy :: EdgeConfig , differentValues :: Maybe Int } type Generator m = ReaderT (GeneratorConfig m) IO zeroFreq :: GeneratorConfig m -> Probability zeroFreq (GeneratorConfig { zeroPolicy = Percentage p }) = p zeroFreq (GeneratorConfig { zeroPolicy = ZeroFrequency p }) = p zeroFreq _ = error "zeroFreq: unexpected out degree" -- TODO Ugly as hell runGenerator :: GeneratorConfig m -> Generator m a -> IO a Loading Loading @@ -107,13 +107,12 @@ uniqueTransitions num (IndexedTransition.Index max) = helper S.empty num genTransitions' :: Int -> Generator m (Vector (Vector (Transition m))) genTransitions' outDegree = do genTransitions' numTransitions = do wtaSpec <- asks spec let n = numStates wtaSpec m = IndexedTransition.maxIndex wtaSpec desiredEdges = n * outDegree transitions <- lift $ map (IndexedTransition.fromIndex wtaSpec) <$> uniqueTransitions desiredEdges m transitions <- lift $ map (IndexedTransition.fromIndex wtaSpec) <$> uniqueTransitions numTransitions m weightedTransitions <- (traverse.traverse.traverse) (const genMonoidValue) transitions let byState = foldl' (\m (State s, t) -> M.insertWith (++) s [t] m) M.empty weightedTransitions Loading @@ -126,5 +125,5 @@ genTransitions' outDegree = do genWTA :: Generator m (WTA m) genWTA = asks zeroPolicy >>= \case OutDegree d -> WTA <$> asks spec <*> genStates <*> (genTransitions' d) Percentage _ -> WTA <$> asks spec <*> genStates <*> genTransitions NumTransitions d -> WTA <$> asks spec <*> genStates <*> (genTransitions' d) ZeroFrequency _ -> WTA <$> asks spec <*> genStates <*> genTransitions src/random-wta/Main.hs +12 −13 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ data Opts = Opts { optMonoid :: SomeMonoid , optStates :: Int , optSymbols :: SymbolSpec , optZeroFrequency :: ZeroFrequency , optEdgeConfig :: EdgeConfig , optRandomState :: Maybe StdGen , optDifferentValues :: Maybe Int } Loading Loading @@ -104,9 +104,9 @@ parseOpts = ) ) parseZeroFreq :: Options.Parser ZeroFrequency parseZeroFreq :: Options.Parser EdgeConfig parseZeroFreq = (Percentage <$> Options.option (ZeroFrequency <$> Options.option (Options.eitherReader readProbability) ( Options.long "zero-frequency" <> Options.showDefault Loading @@ -116,13 +116,12 @@ parseZeroFreq = "Frequency of edges with zero weight as number between 0 and 1." ) ) <|> (OutDegree <$> Options.option <|> (NumTransitions <$> Options.option Options.auto ( Options.long "out-degree" <> Options.metavar "NUM_TRANSITIONS" ( Options.long "transitions" <> Options.metavar "NUM" <> Options.help ("Expected number of outgoing transitions per state." <> " This calculates the zero frequency from the number of states, symbols and this parameter." ("Number of transitions to generate. They will be distributed randomly over states." ) ) ) Loading @@ -134,9 +133,9 @@ withSpec opts f = case optMonoid opts of , numSymbols = optSymbols opts } computeProbability :: WTASpec m -> ZeroFrequency -> Probability computeProbability _ (Percentage p) = p computeProbability spec (OutDegree d) = computeProbability :: WTASpec m -> EdgeConfig -> Probability computeProbability _ (ZeroFrequency p) = p computeProbability spec (NumTransitions d) = let n = numStates spec t = V.sum (V.imap (\i syms -> syms * n ^ i) (numSymbols spec)) in fromRationalApprox (1 - fromIntegral d / fromIntegral t) Loading @@ -157,10 +156,10 @@ main = do withSpec opts $ \spec -> do randGen <- getStdGen -- let zeroFreq = computeProbability spec (optZeroFrequency opts) -- let zeroFreq = computeProbability spec (optEdgeConfig opts) -- hPutStrLn stderr $ "p hacking: " ++ show zeroFreq wta <- runGenerator (GeneratorConfig spec (optZeroFrequency opts) (optDifferentValues opts)) (GeneratorConfig spec (optEdgeConfig opts) (optDifferentValues opts)) genWTA putStrLn $ "# Random state for this automaton: '" <> show randGen <> "'" T.putStr (Build.toLazyText (buildWTA wta)) Loading
src/random-wta/Generator.hs +8 −9 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE LambdaCase #-} module Generator (genWTA, runGenerator, GeneratorConfig(..), ZeroFrequency(..)) where module Generator (genWTA, runGenerator, GeneratorConfig(..), EdgeConfig(..)) where import Data.Vector ( Vector ) import qualified Data.Vector as V Loading @@ -21,18 +21,18 @@ import Probability import IndexedTransition import qualified IndexedTransition data ZeroFrequency = Percentage Probability | OutDegree Int data EdgeConfig = ZeroFrequency Probability | NumTransitions Int data GeneratorConfig m = GeneratorConfig { spec :: WTASpec m , zeroPolicy :: ZeroFrequency , zeroPolicy :: EdgeConfig , differentValues :: Maybe Int } type Generator m = ReaderT (GeneratorConfig m) IO zeroFreq :: GeneratorConfig m -> Probability zeroFreq (GeneratorConfig { zeroPolicy = Percentage p }) = p zeroFreq (GeneratorConfig { zeroPolicy = ZeroFrequency p }) = p zeroFreq _ = error "zeroFreq: unexpected out degree" -- TODO Ugly as hell runGenerator :: GeneratorConfig m -> Generator m a -> IO a Loading Loading @@ -107,13 +107,12 @@ uniqueTransitions num (IndexedTransition.Index max) = helper S.empty num genTransitions' :: Int -> Generator m (Vector (Vector (Transition m))) genTransitions' outDegree = do genTransitions' numTransitions = do wtaSpec <- asks spec let n = numStates wtaSpec m = IndexedTransition.maxIndex wtaSpec desiredEdges = n * outDegree transitions <- lift $ map (IndexedTransition.fromIndex wtaSpec) <$> uniqueTransitions desiredEdges m transitions <- lift $ map (IndexedTransition.fromIndex wtaSpec) <$> uniqueTransitions numTransitions m weightedTransitions <- (traverse.traverse.traverse) (const genMonoidValue) transitions let byState = foldl' (\m (State s, t) -> M.insertWith (++) s [t] m) M.empty weightedTransitions Loading @@ -126,5 +125,5 @@ genTransitions' outDegree = do genWTA :: Generator m (WTA m) genWTA = asks zeroPolicy >>= \case OutDegree d -> WTA <$> asks spec <*> genStates <*> (genTransitions' d) Percentage _ -> WTA <$> asks spec <*> genStates <*> genTransitions NumTransitions d -> WTA <$> asks spec <*> genStates <*> (genTransitions' d) ZeroFrequency _ -> WTA <$> asks spec <*> genStates <*> genTransitions
src/random-wta/Main.hs +12 −13 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ data Opts = Opts { optMonoid :: SomeMonoid , optStates :: Int , optSymbols :: SymbolSpec , optZeroFrequency :: ZeroFrequency , optEdgeConfig :: EdgeConfig , optRandomState :: Maybe StdGen , optDifferentValues :: Maybe Int } Loading Loading @@ -104,9 +104,9 @@ parseOpts = ) ) parseZeroFreq :: Options.Parser ZeroFrequency parseZeroFreq :: Options.Parser EdgeConfig parseZeroFreq = (Percentage <$> Options.option (ZeroFrequency <$> Options.option (Options.eitherReader readProbability) ( Options.long "zero-frequency" <> Options.showDefault Loading @@ -116,13 +116,12 @@ parseZeroFreq = "Frequency of edges with zero weight as number between 0 and 1." ) ) <|> (OutDegree <$> Options.option <|> (NumTransitions <$> Options.option Options.auto ( Options.long "out-degree" <> Options.metavar "NUM_TRANSITIONS" ( Options.long "transitions" <> Options.metavar "NUM" <> Options.help ("Expected number of outgoing transitions per state." <> " This calculates the zero frequency from the number of states, symbols and this parameter." ("Number of transitions to generate. They will be distributed randomly over states." ) ) ) Loading @@ -134,9 +133,9 @@ withSpec opts f = case optMonoid opts of , numSymbols = optSymbols opts } computeProbability :: WTASpec m -> ZeroFrequency -> Probability computeProbability _ (Percentage p) = p computeProbability spec (OutDegree d) = computeProbability :: WTASpec m -> EdgeConfig -> Probability computeProbability _ (ZeroFrequency p) = p computeProbability spec (NumTransitions d) = let n = numStates spec t = V.sum (V.imap (\i syms -> syms * n ^ i) (numSymbols spec)) in fromRationalApprox (1 - fromIntegral d / fromIntegral t) Loading @@ -157,10 +156,10 @@ main = do withSpec opts $ \spec -> do randGen <- getStdGen -- let zeroFreq = computeProbability spec (optZeroFrequency opts) -- let zeroFreq = computeProbability spec (optEdgeConfig opts) -- hPutStrLn stderr $ "p hacking: " ++ show zeroFreq wta <- runGenerator (GeneratorConfig spec (optZeroFrequency opts) (optDifferentValues opts)) (GeneratorConfig spec (optEdgeConfig opts) (optDifferentValues opts)) genWTA putStrLn $ "# Random state for this automaton: '" <> show randGen <> "'" T.putStr (Build.toLazyText (buildWTA wta))