1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
module ccti (main) where
import FilePath (takeDirectory)
import FlatCurry.Annotated.Pretty (ppFuncDecls)
import FlatCurry.Annotated.Types
import List (nub)
import System (getProgName)
import Text.Pretty
import CCTOptions (CCTOpts (..), badUsage, getOpts)
import FCYFunctorInstances
import FCY2SMTLib (fcy2SMT)
import FlatCurryGoodies (extendAnn, getMainBody)
import IdentifyCases (idCases)
import Output (debug, status)
import ReadTFCY
import Search (csearch, ppTestCase)
import Utils (inDirectory)
import System.CurryPath ( sysLibPath )
import System.FrontendExec ( FrontendParams, FrontendTarget (TFCY)
, callFrontendWithParams, rcParams, setFullPath )
main :: IO ()
main = do
(opts, files) <- getOpts
exec <- getProgName
params <- rcParams
let params' = setFullPath (nub (sysLibPath ++ optImportPaths opts)) params
status opts "Generating FlatCurry code"
let modpath = head files
callFrontendWithParams TFCY params' modpath
status opts "Reading FlatCurry file(s)"
prog@(AProg m _ _ _ _) <- readTFCYFile $ tfcyFile modpath
case getMainBody prog of
Nothing -> badUsage exec ["The module must include a main function with a function call in its body."]
Just e -> do
(ts, fs) <- inDirectory (takeDirectory modpath) (getTysFuns m)
status opts "Annotating case expressions with fresh identifiers"
let (fs', v) = idCases fs
e' = fmap extendAnn e
debug opts (pPrint $ text "Annotated Functions:" <+> ppFuncDecls fs')
status opts "Generating SMT-LIB declarations for FlatCurry types"
let smtInfo = fcy2SMT ts
debug opts (pPrint $ text "Generated SMTLIB declarations:" <+> pretty smtInfo)
status opts "Beginning with concolic search"
testCases <- csearch opts fs' v smtInfo e'
status opts "Printing generated test cases:"
putStrLn $ pPrint $ vsep $ map ppTestCase testCases
getTysFuns :: String -> IO ([TypeDecl], [AFuncDecl TypeExpr])
getTysFuns mod = do
(ts, fs, _) <- getTysFuns' [] [] [] mod
return (ts, fs)
where
getTysFuns' ts fs ms m
| m `elem` ms = return (ts, fs, ms)
| otherwise = do
(AProg _ is mts mfs _) <- readTFCY m
foldIO (\(ts', fs', ms') i -> getTysFuns' ts' fs' ms' i)
(ts ++ mts, fs ++ mfs, m:ms)
is
|