Skip to content

Commit 92cf3da

Browse files
Merge branch 'release-1.2.0'. Refs #117.
2 parents ceb628b + e9dcc89 commit 92cf3da

File tree

37 files changed

+779
-981
lines changed

37 files changed

+779
-981
lines changed

ogma-cli/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Revision history for ogma-cli
22

3+
## [1.2.0] - 2024-01-21
4+
5+
* Version bump 1.2.0 (#117).
6+
* Re-structure README around on backends (#75).
7+
38
## [1.1.0] - 2023-11-21
49

510
* Version bump 1.1.0 (#112).

ogma-cli/README.md

Lines changed: 17 additions & 275 deletions
Large diffs are not rendered by default.

ogma-cli/ogma-cli.cabal

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ cabal-version: 2.0
3232
build-type: Simple
3333

3434
name: ogma-cli
35-
version: 1.1.0
35+
version: 1.2.0
3636
homepage: http://nasa.gov
3737
license: OtherLicense
3838
license-file: LICENSE.pdf
@@ -141,7 +141,7 @@ executable ogma
141141
build-depends:
142142
base >= 4.11.0.0 && < 5
143143
, optparse-applicative
144-
, ogma-core >= 1.1.0 && < 1.2
144+
, ogma-core >= 1.2.0 && < 1.3
145145

146146
hs-source-dirs:
147147
src

ogma-core/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Revision history for ogma-core
22

3+
## [1.2.0] - 2024-01-21
4+
5+
* Version bump 1.2.0 (#117).
6+
* Generalize JSON parser (#115).
7+
38
## [1.1.0] - 2023-11-21
49

510
* Version bump 1.1.0 (#112).

ogma-core/ogma-core.cabal

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ cabal-version: 2.0
3232
build-type: Simple
3333

3434
name: ogma-core
35-
version: 1.1.0
35+
version: 1.2.0
3636
homepage: http://nasa.gov
3737
license: OtherLicense
3838
license-file: LICENSE.pdf
@@ -92,8 +92,8 @@ library
9292
Language.Trans.CStruct2CopilotStruct
9393
Language.Trans.CStructs2Copilot
9494
Language.Trans.CStructs2MsgHandlers
95-
Language.Trans.FRETComponentSpec2Copilot
9695
Language.Trans.FRETReqsDB2Copilot
96+
Language.Trans.Spec2Copilot
9797
Language.Trans.SMV2Copilot
9898

9999
other-modules:
@@ -105,17 +105,19 @@ library
105105
build-depends:
106106
base >= 4.11.0.0 && < 5
107107
, aeson >= 2.0.0.0 && < 2.2
108+
, bytestring
108109
, filepath
109110
, IfElse
110111
, mtl
111112

112-
, ogma-extra >= 1.1.0 && < 1.2
113-
, ogma-language-c >= 1.1.0 && < 1.2
114-
, ogma-language-cocospec >= 1.1.0 && < 1.2
115-
, ogma-language-copilot >= 1.1.0 && < 1.2
116-
, ogma-language-fret-cs >= 1.1.0 && < 1.2
117-
, ogma-language-fret-reqs >= 1.1.0 && < 1.2
118-
, ogma-language-smv >= 1.1.0 && < 1.2
113+
, ogma-extra >= 1.2.0 && < 1.3
114+
, ogma-language-c >= 1.2.0 && < 1.3
115+
, ogma-language-cocospec >= 1.2.0 && < 1.3
116+
, ogma-language-copilot >= 1.2.0 && < 1.3
117+
, ogma-language-fret-reqs >= 1.2.0 && < 1.3
118+
, ogma-language-jsonspec >= 1.2.0 && < 1.3
119+
, ogma-language-smv >= 1.2.0 && < 1.3
120+
, ogma-spec >= 1.2.0 && < 1.3
119121

120122
hs-source-dirs:
121123
src

ogma-core/src/Command/FPrimeApp.hs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,14 @@ import Data.ByteString.Extra as B ( safeReadFile )
5353
import Data.String.Extra ( sanitizeLCIdentifier, sanitizeUCIdentifier )
5454
import System.Directory.Extra ( copyDirectoryRecursive )
5555

56+
-- External imports: ogma
57+
import Data.OgmaSpec (Spec, externalVariableName, externalVariables,
58+
requirementName, requirements)
59+
import Language.JSONSpec.Parser (JSONFormat (..), parseJSONSpec)
60+
5661
-- Internal imports: auxiliary
5762
import Command.Result ( Result (..) )
5863
import Data.Location ( Location (..) )
59-
import Language.FRETComponentSpec.AST ( FRETComponentSpec,
60-
fretExternalVariableName,
61-
fretExternalVariables,
62-
fretRequirementName, fretRequirements )
6364

6465
-- Internal imports
6566
import Paths_ogma_core ( getDataDir )
@@ -153,14 +154,13 @@ fprimeApp' targetDir varNames varDB monitors =
153154
-- | Process FRET component spec, if available, and return its abstract
154155
-- representation.
155156
parseOptionalFRETCS :: Maybe FilePath
156-
-> ExceptT ErrorTriplet IO (Maybe FRETComponentSpec)
157+
-> ExceptT ErrorTriplet IO (Maybe (Spec String))
157158
parseOptionalFRETCS Nothing = return Nothing
158159
parseOptionalFRETCS (Just fp) = do
159160
-- Throws an exception if the file cannot be read.
160161
content <- liftIO $ B.safeReadFile fp
161-
162-
let fretCS :: Either String FRETComponentSpec
163-
fretCS = eitherDecode =<< content
162+
let fretCS :: Either String (Spec String)
163+
fretCS = parseJSONSpec return fretFormat =<< eitherDecode =<< content
164164

165165
case fretCS of
166166
Left e -> throwError $ cannotOpenFRETFile fp e
@@ -219,7 +219,7 @@ parseOptionalVarDBFile (Just fp) = do
219219
--
220220
-- If a FRET file is not provided, then the user must provide BOTH a variable
221221
-- list, and a list of handlers.
222-
checkArguments :: Maybe FRETComponentSpec
222+
checkArguments :: Maybe (Spec a)
223223
-> Maybe [String]
224224
-> Maybe [String]
225225
-> Either ErrorTriplet ()
@@ -232,19 +232,19 @@ checkArguments _ _ _ = Right ()
232232

233233
-- | Extract the variables from a FRET component specification, and sanitize
234234
-- them to be used in FPrime.
235-
fretCSExtractExternalVariables :: Maybe FRETComponentSpec -> [String]
235+
fretCSExtractExternalVariables :: Maybe (Spec a) -> [String]
236236
fretCSExtractExternalVariables Nothing = []
237237
fretCSExtractExternalVariables (Just cs) = map sanitizeLCIdentifier
238-
$ map fretExternalVariableName
239-
$ fretExternalVariables cs
238+
$ map externalVariableName
239+
$ externalVariables cs
240240

241241
-- | Extract the requirements from a FRET component specification, and sanitize
242242
-- them to match the names of the handlers used by Copilot.
243-
fretCSExtractHandlers :: Maybe FRETComponentSpec -> [String]
243+
fretCSExtractHandlers :: Maybe (Spec a) -> [String]
244244
fretCSExtractHandlers Nothing = []
245245
fretCSExtractHandlers (Just cs) = map handlerNameF
246-
$ map fretRequirementName
247-
$ fretRequirements cs
246+
$ map requirementName
247+
$ requirements cs
248248
where
249249
handlerNameF = ("handlerprop" ++) . sanitizeUCIdentifier
250250

@@ -737,3 +737,19 @@ ecCannotOpenHandlersFile = 1
737737
-- permissions or some I/O error.
738738
ecCannotCopyTemplate :: ErrorCode
739739
ecCannotCopyTemplate = 1
740+
741+
-- | JSONPath selectors for a FRET file
742+
fretFormat :: JSONFormat
743+
fretFormat = JSONFormat
744+
{ specInternalVars = "..Internal_variables[*]"
745+
, specInternalVarId = ".name"
746+
, specInternalVarExpr = ".assignmentCopilot"
747+
, specInternalVarType = ".type"
748+
, specExternalVars = "..Other_variables[*]"
749+
, specExternalVarId = ".name"
750+
, specExternalVarType = ".type"
751+
, specRequirements = "..Requirements[*]"
752+
, specRequirementId = ".name"
753+
, specRequirementDesc = ".fretish"
754+
, specRequirementExpr = ".ptLTL"
755+
}

ogma-core/src/Command/FRETComponentSpec2Copilot.hs

Lines changed: 98 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE ExistentialQuantification #-}
12
-- Copyright 2020 United States Government as represented by the Administrator
23
-- of the National Aeronautics and Space Administration. All Rights Reserved.
34
--
@@ -41,7 +42,8 @@ module Command.FRETComponentSpec2Copilot
4142

4243
-- External imports
4344
import Control.Monad.IfElse ( awhen )
44-
import Data.Aeson ( eitherDecode )
45+
import Data.Aeson ( eitherDecode, decode )
46+
import Data.ByteString.Lazy (fromStrict)
4547

4648
-- External imports: auxiliary
4749
import Data.ByteString.Extra as B ( safeReadFile )
@@ -50,12 +52,22 @@ import Data.ByteString.Extra as B ( safeReadFile )
5052
import Command.Result ( Result (..) )
5153
import Data.Location ( Location (..) )
5254

53-
-- Internal imports
54-
import Language.FRETComponentSpec.AST ( FRETComponentSpec )
55-
import qualified Language.Trans.FRETComponentSpec2Copilot as T
56-
( fretComponentSpec2Copilot
57-
, FRETComponentSpec2CopilotOptions(FRETComponentSpec2CopilotOptions)
58-
)
55+
-- Internal imports: language ASTs, transformers
56+
import Data.OgmaSpec (Spec)
57+
58+
import qualified Language.CoCoSpec.AbsCoCoSpec as CoCoSpec
59+
import qualified Language.CoCoSpec.ParCoCoSpec as CoCoSpec ( myLexer,
60+
pBoolSpec )
61+
62+
import Language.JSONSpec.Parser (JSONFormat (..), parseJSONSpec)
63+
64+
import qualified Language.SMV.AbsSMV as SMV
65+
import qualified Language.SMV.ParSMV as SMV (myLexer, pBoolSpec)
66+
import Language.SMV.Substitution (substituteBoolExpr)
67+
68+
import qualified Language.Trans.CoCoSpec2Copilot as CoCoSpec (boolSpec2Copilot)
69+
import Language.Trans.SMV2Copilot as SMV (boolSpec2Copilot)
70+
import Language.Trans.Spec2Copilot (spec2Copilot, specAnalyze)
5971

6072
-- | Print the contents of a Copilot module that implements the Past-time TL
6173
-- formula in a FRET file.
@@ -72,22 +84,44 @@ fretComponentSpec2Copilot :: FilePath -- ^ Path to a file containing a FRET
7284
-> IO (Result ErrorCode)
7385
fretComponentSpec2Copilot fp options = do
7486

75-
-- All of the following operations use Either to return error messages. The
76-
-- use of the monadic bind to pass arguments from one function to the next
77-
-- will cause the program to stop at the earliest error.
78-
fret <- parseFretComponentSpec fp
87+
let functions = fretExprPair (fretCS2CopilotUseCoCoSpec options)
7988

80-
-- Extract internal command options from external command options
81-
let internalOptions = fretComponentSpec2CopilotOptions options
82-
83-
let copilot = T.fretComponentSpec2Copilot internalOptions =<< fret
89+
copilot <- fretComponentSpec2Copilot' fp options functions
8490

8591
let (mOutput, result) =
8692
fretComponentSpec2CopilotResult options fp copilot
8793

8894
awhen mOutput putStrLn
8995
return result
9096

97+
-- | Print the contents of a Copilot module that implements the Past-time TL
98+
-- formula in a FRET file, using a subexpression handler.
99+
--
100+
-- PRE: The file given is readable, contains a valid FRET file with a PT
101+
-- formula in the @ptExpanded@ key, the formula does not use any identifiers
102+
-- that exist in Copilot, or any of @prop@, @clock@, @ftp@. All identifiers
103+
-- used are valid C99 identifiers.
104+
fretComponentSpec2Copilot' :: FilePath
105+
-> FRETComponentSpec2CopilotOptions
106+
-> FRETExprPair
107+
-> IO (Either String String)
108+
fretComponentSpec2Copilot' fp options (FRETExprPair parse replace print) = do
109+
let name = fretCS2CopilotFilename options
110+
useCoCoSpec = fretCS2CopilotUseCoCoSpec options
111+
typeMaps = fretTypeToCopilotTypeMapping options
112+
113+
-- All of the following operations use Either to return error messages. The
114+
-- use of the monadic bind to pass arguments from one function to the next
115+
-- will cause the program to stop at the earliest error.
116+
content <- B.safeReadFile fp
117+
res <- case content of
118+
Left s -> return $ Left s
119+
Right b -> return $ parseJSONSpec parse (fretFormat useCoCoSpec) =<< eitherDecode b
120+
121+
let copilot = spec2Copilot name typeMaps replace print =<< specAnalyze =<< res
122+
123+
return copilot
124+
91125
-- | Options used to customize the conversion of FRET Component Specifications
92126
-- to Copilot code.
93127
data FRETComponentSpec2CopilotOptions = FRETComponentSpec2CopilotOptions
@@ -97,17 +131,6 @@ data FRETComponentSpec2CopilotOptions = FRETComponentSpec2CopilotOptions
97131
, fretCS2CopilotFilename :: String
98132
}
99133

100-
-- | Parse a JSON file containing a FRET component specification.
101-
--
102-
-- Returns a 'Left' with an error message if the file does not have the correct
103-
-- format.
104-
--
105-
-- Throws an exception if the file cannot be read.
106-
parseFretComponentSpec :: FilePath -> IO (Either String FRETComponentSpec)
107-
parseFretComponentSpec fp = do
108-
content <- B.safeReadFile fp
109-
return $ eitherDecode =<< content
110-
111134
-- * Error codes
112135

113136
-- | Encoding of reasons why the command can fail.
@@ -120,19 +143,6 @@ type ErrorCode = Int
120143
ecFretCSError :: ErrorCode
121144
ecFretCSError = 1
122145

123-
-- * Input arguments
124-
125-
-- | Convert command input argument options to internal transformation function
126-
-- input arguments.
127-
fretComponentSpec2CopilotOptions :: FRETComponentSpec2CopilotOptions
128-
-> T.FRETComponentSpec2CopilotOptions
129-
fretComponentSpec2CopilotOptions options =
130-
T.FRETComponentSpec2CopilotOptions
131-
(fretCS2CopilotUseCoCoSpec options)
132-
(fretCS2CopilotIntType options)
133-
(fretCS2CopilotRealType options)
134-
(fretCS2CopilotFilename options)
135-
136146
-- * Result
137147

138148
-- | Process the result of the transformation function.
@@ -143,3 +153,52 @@ fretComponentSpec2CopilotResult :: FRETComponentSpec2CopilotOptions
143153
fretComponentSpec2CopilotResult options fp result = case result of
144154
Left msg -> (Nothing, Error ecFretCSError msg (LocationFile fp))
145155
Right t -> (Just t, Success)
156+
157+
-- * Parser
158+
159+
-- | JSONPath selectors for a FRET file
160+
fretFormat :: Bool -> JSONFormat
161+
fretFormat useCoCoSpec = JSONFormat
162+
{ specInternalVars = "..Internal_variables[*]"
163+
, specInternalVarId = ".name"
164+
, specInternalVarExpr = ".assignmentCopilot"
165+
, specInternalVarType = ".type"
166+
, specExternalVars = "..Other_variables[*]"
167+
, specExternalVarId = ".name"
168+
, specExternalVarType = ".type"
169+
, specRequirements = "..Requirements[*]"
170+
, specRequirementId = ".name"
171+
, specRequirementDesc = ".fretish"
172+
, specRequirementExpr = if useCoCoSpec then ".CoCoSpecCode" else ".ptLTL"
173+
}
174+
175+
-- * Mapping of types from FRET to Copilot
176+
fretTypeToCopilotTypeMapping :: FRETComponentSpec2CopilotOptions
177+
-> [(String, String)]
178+
fretTypeToCopilotTypeMapping options =
179+
[ ("bool", "Bool")
180+
, ("int", fretCS2CopilotIntType options)
181+
, ("integer", fretCS2CopilotIntType options)
182+
, ("real", fretCS2CopilotRealType options)
183+
, ("string", "String")
184+
]
185+
186+
-- * Handler for boolean expressions
187+
188+
-- | Handler for boolean expressions that knows how to parse them, replace
189+
-- variables in them, and convert them to Copilot.
190+
data FRETExprPair = forall a . FRETExprPair
191+
{ exprParse :: String -> Either String a
192+
, exprReplace :: [(String, String)] -> a -> a
193+
, exprPrint :: a -> String
194+
}
195+
196+
-- | Return a handler depending on whether it should be for CoCoSpec boolean
197+
-- expressions or for SMV boolean expressions.
198+
fretExprPair :: Bool -> FRETExprPair
199+
fretExprPair True = FRETExprPair (CoCoSpec.pBoolSpec . CoCoSpec.myLexer)
200+
(\_ -> id)
201+
(CoCoSpec.boolSpec2Copilot)
202+
fretExprPair False = FRETExprPair (SMV.pBoolSpec . SMV.myLexer)
203+
(substituteBoolExpr)
204+
(SMV.boolSpec2Copilot)

0 commit comments

Comments
 (0)