Commit 1c27a61a authored by Hans-Peter Deifel's avatar Hans-Peter Deifel 🐢
Browse files

wta: Allow to restrict number of different monoid values

Otherwise states get one of 2^64 different values in the initial partition,
meaning that they will be distinguished already.
parent 5ce3af69
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ import Control.Monad.Reader
import           Data.Coerce
import           Data.Maybe
import           Data.Foldable
import           Control.Arrow ((&&&))

import           Types hiding (spec)
import           Probability
@@ -18,6 +19,7 @@ import Probability
data GeneratorConfig m = GeneratorConfig
   { spec :: WTASpec m
   , zeroFreq :: Probability
   , differentValues :: Maybe Int
   }

type Generator m = ReaderT (GeneratorConfig m) IO
@@ -26,10 +28,13 @@ runGenerator :: GeneratorConfig m -> Generator m a -> IO a
runGenerator config action = runReaderT action config

genMonoidValue :: Generator m m
genMonoidValue = asks (monoid . spec) >>= \case
  Powerset -> liftIO $ randomIO
  OrWord   -> liftIO $ randomIO
  MaxInt   -> liftIO $ randomIO
genMonoidValue = asks ((monoid . spec) &&& differentValues) >>= \case
  (Powerset, Nothing) -> liftIO $ randomIO
  (Powerset, _) -> error $ "differentValues not supported for powerset" -- FIXME detect this early (and handle the case <=2)
  (OrWord, Nothing)   -> liftIO $ randomIO
  (OrWord, Just x)   -> liftIO $ randomRIO (0, fromIntegral (x-1))
  (MaxInt, Nothing)   -> liftIO $ randomIO
  (MaxInt, Just x)   -> liftIO $ randomRIO (0, x-1)

genStates :: Generator m (Vector m)
genStates = do
+11 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ import qualified Text.Megaparsec.Char.Lexer as Mega
import           Data.Void
import           System.Random
import           System.IO
import           Numeric

import           Types
import           Generator
@@ -32,6 +33,7 @@ data Opts = Opts
  , optSymbols :: SymbolSpec
  , optZeroFrequency :: Probability
  , optRandomState :: Maybe StdGen
  , optDifferentValues :: Maybe Int
  }

readMonoid :: Options.ReadM SomeMonoid
@@ -55,6 +57,12 @@ readSymbols = Options.maybeReader (Mega.parseMaybe parser)
    parser :: Mega.Parsec Void String (Vector Int)
    parser = V.fromList <$> Mega.decimal `Mega.sepBy` (Mega.string ",")

readCount :: String -> Either String Int
readCount input = case readDec input of
  [(0, "")] -> Left "Count must be >0"
  [(x, "")] -> Right x
  _ -> Left "Count not parse Number"

parseOpts :: Options.Parser Opts
parseOpts =
  Opts
@@ -93,6 +101,8 @@ parseOpts =
          )
    <*> Options.optional
          (Options.option Options.auto (Options.long "random-state"))
    <*> Options.optional
          (Options.option (Options.eitherReader readCount) (Options.long "different-values" <> Options.metavar "NUM" <> Options.help "Maximal number of differnt monoid values to generate"))

withSpec :: Opts -> (forall m . WTASpec m -> x) -> x
withSpec opts f = case optMonoid opts of
@@ -113,6 +123,6 @@ main = do

  withSpec opts $ \spec -> do
    randGen <- getStdGen
    wta <- runGenerator (GeneratorConfig spec (optZeroFrequency opts)) genWTA
    wta <- runGenerator (GeneratorConfig spec (optZeroFrequency opts) (optDifferentValues opts)) genWTA
    putStrLn $ "# Random state for this automaton: '" <> show randGen <> "'"
    T.putStr (Build.toLazyText (buildWTA wta))