syfco-1.1.0.0: src/Writer/Formats/Slugs.hs
-----------------------------------------------------------------------------
-- |
-- Module : Writer.Formats.Slugs
-- License : MIT (see the LICENSE file)
-- Maintainer : Felix Klein (klein@react.uni-saarland.de)
--
-- Transforms a specification in GR(1) into the Slugs format.
--
-----------------------------------------------------------------------------
module Writer.Formats.Slugs where
-----------------------------------------------------------------------------
import Config
import Data.Error
import Data.LTL
import Data.List
import Writer.Eval
import Writer.Error
import Data.Specification
import Detection
import Control.Exception
-----------------------------------------------------------------------------
-- | Slugs format writer.
writeFormat
:: Configuration -> Specification -> Either Error String
writeFormat c s =
case detectGR c s of
Left v -> case v of
Left err -> Left err
Right _ -> errNoGR1 "not in GR(1)" "slugs"
Right gr
| level gr > 1 ->
errNoGR1 ("in GR(" ++ show (level gr) ++ ")") "slugs"
| primeSymbol c == "'" -> do
(iv,ov) <- signals c s
case find (== '\'') $ concat (iv ++ ov) of
Nothing -> printSlugs gr
Just _ ->
cfgError $
"The specification contains primes, which cannot be used " ++
"inside Slugs signal names.\nThey can be replaced " ++
"by changing the default value of the \"-ps\" option."
| otherwise -> printSlugs gr
where
printSlugs gr = do
let
es = initEnv gr
ss = initSys gr
rs = assertEnv gr
is = assertSys gr
(le,ls) = case liveness gr of
[] -> ([],[])
x:_ -> x
(iv,ov) <- signals c s
return $ "[INPUT]"
++ "\n" ++ unlines iv
++ "\n" ++ "[OUTPUT]"
++ "\n" ++ unlines ov
++ (if null es then "" else
"\n" ++ "[ENV_INIT]" ++
"\n" ++ unlines (map prFormula es))
++ (if null ss then "" else
"\n" ++ "[SYS_INIT]" ++
"\n" ++ unlines (map prFormula ss))
++ (if null rs then "" else
"\n" ++ "[ENV_TRANS]" ++
"\n" ++ unlines (map prFormula rs))
++ (if null is then "" else
"\n" ++ "[SYS_TRANS]" ++
"\n" ++ unlines (map prFormula is))
++ (if null le then "" else
"\n" ++ "[ENV_LIVENESS]" ++
"\n" ++ unlines (map prFormula le))
++ (if null ls then "" else
"\n" ++ "[SYS_LIVENESS]" ++
"\n" ++ unlines (map prFormula ls))
prFormula fml = case fml of
TTrue -> "TRUE"
FFalse -> "FALSE"
Atomic x -> show x
Not x -> "!" ++ prFormula' x
Next (Atomic x) -> show x ++ "'"
Next (Not (Atomic x)) -> "!(" ++ show x ++ "')"
Next (And xs) -> prFormula $ And $ map Next xs
Next (Or xs) -> prFormula $ Or $ map Next xs
Next x -> "X " ++ prFormula' x
And [] -> prFormula TTrue
And [x] -> prFormula x
And (x:xr) -> prFormula' x ++
concatMap (\y -> " && " ++ prFormula' y) xr
Or [] -> prFormula FFalse
Or [x] -> prFormula x
Or (x:xr) -> prFormula' x ++
concatMap (\y -> " || " ++ prFormula' y) xr
Implies x y -> prFormula' x ++ " -> " ++ prFormula' y
Equiv x y -> prFormula' x ++ " <-> " ++ prFormula' y
_ -> assert False undefined
where
prFormula' f = case f of
TTrue -> prFormula f
FFalse -> prFormula f
Atomic _ -> prFormula f
Not _ -> prFormula f
Next (Atomic _) -> prFormula f
Next (Not (Atomic _)) -> prFormula f
_ -> "(" ++ prFormula f ++ ")"
-----------------------------------------------------------------------------