AnalysisLibrary.hs revision b4fbc96e05117839ca409f5f20f97b3ac872d1ed
5fbced719b71e659322b4ce3e4a39c9b039674c7Bob HalleyModule : $Header$
5fbced719b71e659322b4ce3e4a39c9b039674c7Bob HalleyCopyright : (c) Till Mossakowski, Uni Bremen 2002-2004
5fbced719b71e659322b4ce3e4a39c9b039674c7Bob HalleyLicence : similar to LGPL, see HetCATS/LICENCE.txt or LIZENZ.txt
5fbced719b71e659322b4ce3e4a39c9b039674c7Bob HalleyMaintainer : till@tzi.de
5fbced719b71e659322b4ce3e4a39c9b039674c7Bob HalleyStability : provisional
5fbced719b71e659322b4ce3e4a39c9b039674c7Bob HalleyPortability : non-portable(Logic)
5fbced719b71e659322b4ce3e4a39c9b039674c7Bob Halley Analysis of libraries
5fbced719b71e659322b4ce3e4a39c9b039674c7Bob Halley Follows the verification semantics sketched in Chap. IV:6
5fbced719b71e659322b4ce3e4a39c9b039674c7Bob Halley of the CASL Reference Manual.
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley Generalization to heterogeneous views
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley check that libname coincides with filename (otherwise internal error occurs)
b897c52f865b2fc4e220e2110b874e59c716456bBob Halleymodule Static.AnalysisLibrary (anaFile, ana_LIB_DEFN, anaString) where
efd6c944a4ebd3fb65dc39f9172d322198b2b1d3Bob Halleyimport Syntax.AS_Structured hiding (View_defn, Spec_defn)
e6d6ce00e2bf0f6a755f8229212e35706e4035aeMichael Graffimport qualified Common.Lib.Map as Map
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halleyimport Driver.WriteFn (writeFileInfo)
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley-- | parsing and static analysis for files
efd6c944a4ebd3fb65dc39f9172d322198b2b1d3Bob Halley-- Parameters: logic graph, default logic, file name
b897c52f865b2fc4e220e2110b874e59c716456bBob HalleyanaFile :: LogicGraph -> AnyLogic -> HetcatsOpts -> LibEnv -> String
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley -> IO (Maybe (LIB_NAME,LIB_DEFN,DGraph,LibEnv))
178f6ad061e54bc5babfca3577f72058fa0797c1Bob HalleyanaFile logicGraph defaultLogic opts libenv fname = do
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley putIfVerbose opts 1 ("Reading " ++ fname)
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley fname' <- existsAnSource fname
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley case fname' of
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley Nothing -> do
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley if outputToStdout opts then
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley putStrLn (fname++" not found.")
efd6c944a4ebd3fb65dc39f9172d322198b2b1d3Bob Halley else return ()
efd6c944a4ebd3fb65dc39f9172d322198b2b1d3Bob Halley return Nothing
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley Just fname'' -> do
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley input <- readFile fname''
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley anaString logicGraph defaultLogic opts libenv input (Just fname'')
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley-- | parsing and static analysis for string (=contents of file)
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley-- Parameters: logic graph, default logic, contents of file, filename (if any)
b897c52f865b2fc4e220e2110b874e59c716456bBob HalleyanaString :: LogicGraph -> AnyLogic -> HetcatsOpts -> LibEnv -> String
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley -> Maybe String -> IO (Maybe (LIB_NAME,LIB_DEFN,DGraph,LibEnv))
b897c52f865b2fc4e220e2110b874e59c716456bBob HalleyanaString logicGraph defaultLogic opts libenv input fname = do
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley let fname' = case fname of
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley Nothing -> "<stdin>"
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley ast <- read_LIB_DEFN_M defaultLogic fname' input
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley Result ds res <-
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley ioresToIO (ana_LIB_DEFN logicGraph defaultLogic opts
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley -- no diags expected here, since these are handled in ana_LIB_DEFN
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley -- sequence (map (putStrLn . show) diags)
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley case (res,fname) of
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley (Just (ln,_,_,lenv), Just n) ->
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley writeFileInfo opts ds n ln lenv
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley _ -> return ()
178f6ad061e54bc5babfca3577f72058fa0797c1Bob HalleyanaLibFile :: LogicGraph -> AnyLogic -> HetcatsOpts -> LibEnv -> LIB_NAME
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley -> IO ([Diagnosis], LibEnv)
178f6ad061e54bc5babfca3577f72058fa0797c1Bob HalleyanaLibFile logicGraph defaultLogic opts libenv libname = do
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley -- is the library already in memory?
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley case Map.lookup libname libenv of
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley Just _ -> return ([],libenv)
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley Nothing -> do
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley -- if not compute the filename,
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley fname <- case getLIB_ID libname of
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley Indirect_link file _ -> do
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley path <- case libdir opts of
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley "" -> catch (getEnv "HETS_LIB")
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley (\ _ -> return "")
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley p -> return p
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley -- add trailing "/" if necessary
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley let path1 = case path of
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley p -> case last p of
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley return (path1++file)
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley Direct_link _ _ ->
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley if outputToStdout opts then
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley error "No direct links implemented yet"
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley else return (error "No direct links implemented yet")
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley -- check if and env file is there and read it if it is recent
19ba7857f6bf38619eda1f1dae0eb05a6cdd2b77Bob Halley let env_fname = fname++".env"
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley -- fname is sufficient here, because anaFile
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley -- trys all possible suffices with this basename
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley recent_env_file <- checkRecentEnv env_fname fname
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley if recent_env_file
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley putIfVerbose opts 1 ("Reading "++env_fname)
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley (Result dias mgc) <- globalContextfromShATerm env_fname
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley -- the conversion/reading might yield an error that
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley -- should be caught here
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley (dias2, mLibEnv) <-
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley maybe (do ioresToIO $ showDiags1 opts
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley (resToIORes (Result dias mgc))
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley anaLibFile' fname dias)
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley (\ gc@(_,_,dgraph) -> do
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley putIfVerbose opts 1 ""
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley -- get all DGRefs from DGraph
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley let libEnv' = (Map.insert libname gc libenv)
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley nodesDGRef =
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley filter (\ labDG -> case labDG of
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley DGRef _ _ _ _ _ -> True
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley (map snd (labNodes dgraph))
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley -- and call anaLibFile with each of the dgn_libname
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley -- of the DGRefs
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley refLibs = nub $ map dgn_libname nodesDGRef
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley newRefLibs =
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley filter (\ ln ->
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley not (ln `elem` Map.keys libEnv'))
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley foldl (\ioLibEnv tlibname ->
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley do (dias3 ,p_libEnv) <- ioLibEnv
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley putIfVerbose opts 1
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley ("Analyzing from " ++
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley showPretty tlibname "\n")
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley (dias4, libEnvF) <-
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley anaLibFile logicGraph defaultLogic
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley opts p_libEnv tlibname
178f6ad061e54bc5babfca3577f72058fa0797c1Bob Halley return ((dias3 ++ dias4),libEnvF)
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley ) (return ([], libEnv')) newRefLibs
59a6d9cbcdbec6960d47e5871fb7e7c0253e1fb2Mark Andrews if outputToStdout opts then
59a6d9cbcdbec6960d47e5871fb7e7c0253e1fb2Mark Andrews return ([], mLibEnv)
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley else return( dias ++ dias2 , mLibEnv)
b897c52f865b2fc4e220e2110b874e59c716456bBob Halley else anaLibFile' fname []
foldl ana (return ([],(gannos,Map.empty,empty),defl,libenv))
Map.insert ln gctx libenv')
if Map.member spn genv
Map.insert spn (SpecEntry (imp,params,parsig,body)) genv,
if Map.member asn genv
Map.insert asn (ArchEntry archSig) genv,
if Map.member usn genv
Map.insert usn (UnitEntry unitSig) genv,
let analyseMessage = "Analyzing refinement " ++ showPretty rn "\n (refinement analysis not implemented yet)"
if Map.member rn genv
Map.insert rn (RefEntry) genv,
case Map.lookup ln libenv' of
show ln++" available: "++show (Map.keys libenv')))
++show ln++" available: "++show (Map.keys libenv')) nullPos)
if Map.member vn genv
Map.insert vn (ViewEntry vsig) genv,
(showPretty old " not found") (Map.lookup old genv')
case Map.lookup new genv of
genv1 = Map.insert new (SpecEntry extsig1) genv
genv1 = Map.insert new (ViewEntry vsig1) genv