module Language.Lojban.Mlismu (newMlismu ,isValidFatci ,addFatci ,readFatci ,randomBridi ,randomBridiRel ,Mlismu) where import Data.Maybe import Data.Char import Language.Lojban.Util import System.Directory import System.IO import System.Process import Utils -- | Create a new mlismu handle. newMlismu :: FilePath -> IO (Either String Mlismu) newMlismu path = do is <- doesFileExist path if is then do db <- openFile path AppendMode return $ Right $ Mlismu path db else return $ Left $ "\"" ++ path ++ "\" does not exist" -- | Is a fatci valid? isValidFatci :: String -> IO Bool isValidFatci text = do -- validLojban <- isValidLojban text if True -- validLojban then isJust `fmap` mlismuBridi (Right text) Nothing 1 else return False mlismuBridi :: (Either FilePath String) -> Maybe String -> Int -> IO (Maybe [String]) mlismuBridi path selbri lines' = do out <- run ("mlismu -n " ++ show lines' ++ " -f " ++ path' ++ selbri') input case out of Right ("",good@(_:_)) | Just good' /= selbri -> return $ Just $ lines $ good where good' = list "" (head . lines) good _ -> return Nothing where selbri' = maybe "" (" "++) selbri path' = either id (const "/dev/stdin") path input = either (const "") (++"\n") path -- | Return a random bridi for a (maybe) given selbri. randomBridi :: Mlismu -> Maybe String -> IO (Maybe String) randomBridi mli bridi = start `fmap` mlismuBridi (Left $ mliFile mli) bridi 1 where start = (>>= list Nothing (Just . head)) -- | Try to return a random bridi for one of the given selbri. randomBridiRel :: Mlismu -> [String] -> IO (Maybe String) randomBridiRel mli bridis = findM bridis where findM [] = randomBridi mli Nothing findM (x:xs) = do randomBridi mli (Just x) >>= maybe (findM xs) (return . Just) -- | Add a new fatci. addFatci :: Mlismu -> String -> IO Bool addFatci mli fatci = do is <- isValidFatci fatci if is then do hPutStrLn (mliDB mli) fatci hFlush (mliDB mli) return True else return False -- | Add any valid fatci from a set of utterances. readFatci :: Mlismu -> String -> IO () readFatci mli = mapM_ (addFatci mli) . splitBridis splitBridis :: String -> [String] splitBridis = map unwords . splitBy ((=="i") . filter isLetter) . words data Mlismu = Mlismu { mliFile :: FilePath , mliDB :: Handle }