spectacle-1.0.0: src/Language/Spectacle/Specification.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Language.Spectacle.Specification
( -- * Specification Constraint
Specification (Specification),
specInit,
specNext,
specProp,
-- ** Lowering
runInitialSpec,
getActionFormulae,
getTemporalFormulae,
getFairnessSpec,
getModalitySpec,
-- * Re-export
module Language.Spectacle.Specification.Action,
module Language.Spectacle.Specification.Prop,
module Language.Spectacle.Specification.Variable,
)
where
import Data.Function ((&))
import Data.Hashable (Hashable)
import Data.Kind (Type)
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Set (Set)
import qualified Data.Set as Set
import GHC.TypeLits (Symbol)
import Data.Type.Rec as Rec
( Ascribe,
HasDict,
RecF,
foldMapF,
mapF,
sequenceF,
)
import Data.World (World, makeWorld)
import Language.Spectacle.AST.Action (Action)
import Language.Spectacle.AST.Temporal (Temporal)
import Language.Spectacle.Fairness (Fairness)
import Language.Spectacle.Lang (Lang, runLang)
import Language.Spectacle.Specification.Action
( ActionType (ActionSF, ActionUF, ActionWF),
toAction,
toFairness,
)
import Language.Spectacle.Specification.Prop
( Modality (Always, Eventually, Infinitely, Stays),
TemporalType (PropF, PropFG, PropG, PropGF),
toFormula,
toModality,
)
import Language.Spectacle.Specification.Variable
( HasVars (runInitActions),
runInitStates,
)
import Language.Spectacle.Syntax.NonDet (NonDet, runNonDetA)
-- ---------------------------------------------------------------------------------------------------------------------
type Specification ::
[Ascribe Symbol Type] ->
[Ascribe Symbol Fairness] ->
[Ascribe Symbol Modality] ->
Type
data Specification ctx acts form where
Specification ::
{ specInit :: RecF (Lang '[] '[NonDet]) ctx
, specNext :: RecF (ActionType ctx) acts
, specProp :: RecF (TemporalType ctx) form
} ->
Specification ctx acts form
runInitialSpec :: HasDict Hashable ctx => Specification ctx acts form -> Set (World ctx)
runInitialSpec spec =
specInit spec
& Rec.mapF (\_ -> runLang . runNonDetA @[])
& Rec.sequenceF
& foldMap (Set.singleton . makeWorld)
getActionFormulae :: Specification ctx acts form -> Map String (Action ctx Bool)
getActionFormulae = Rec.foldMapF (\nm act -> Map.singleton (show nm) (toAction act)) . specNext
getTemporalFormulae :: Specification ctx acts form -> Map String (Temporal ctx Bool)
getTemporalFormulae = Rec.foldMapF (\nm form -> Map.singleton (show nm) (toFormula form)) . specProp
getFairnessSpec :: Specification ctx acts form -> Map String Fairness
getFairnessSpec = Rec.foldMapF (\nm act -> Map.singleton (show nm) (toFairness act)) . specNext
getModalitySpec :: Specification ctx acts form -> Map String Modality
getModalitySpec = Rec.foldMapF (\nm form -> Map.singleton (show nm) (toModality form)) . specProp