Analysis.hs revision abd5fc85dc7e19b1614890182436940e922963a4
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina SojakovaModule : $Header$
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina SojakovaDescription : Static analysis for the Edinburgh Logical Framework
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina SojakovaCopyright : (c) Kristina Sojakova, DFKI Bremen 2010
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu ProdescuLicense : GPLv2 or higher, see LICENSE.txt
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina SojakovaMaintainer : k.sojakova@jacobs-university.de
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina SojakovaStability : experimental
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina SojakovaPortability : portable
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakovaimport qualified Data.Map as Map
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakovaimport qualified Data.Set as Set
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakovasen_type_exp :: EXP
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakovasen_type_exp = Type
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakovagen_file :: String
118add2c5ac398465f6f66adb165852dffe1264dKristina Sojakovagen_file = gen_base
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakovagen_sig1 :: String
118add2c5ac398465f6f66adb165852dffe1264dKristina Sojakovagen_sig1 = gen_module
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakovagen_sig2 :: String
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakovagen_sig2 = gen_module ++ "'"
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovagenPref :: String -> String
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovagenPref s = gen ++ s
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakovagen_ax :: String
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakovagen_ax = genPref "ax"
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina SojakovanumSuf :: String -> Int -> String
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina SojakovanumSuf s i = s ++ "_" ++ show i
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina SojakovamkSig :: String -> String -> String
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina SojakovamkSig n cont = "%sig " ++ n ++ " = {\n" ++ cont ++ "}.\n"
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina SojakovamkIncl :: String -> String
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina SojakovamkIncl n = "%include " ++ n ++ " %open.\n"
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina SojakovamkRead :: String -> String
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina SojakovamkRead n = "%read \"" ++ n ++ "\".\n"
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina SojakovagetSigItems :: [Annoted BASIC_ITEM] -> [Annoted BASIC_ITEM]
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina SojakovagetSigItems = filter ( \ (Annoted i _ _ _) ->
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova Decl _ -> True
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova Form _ -> False )
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina SojakovagetSenItems :: [Annoted BASIC_ITEM] -> [Annoted BASIC_ITEM]
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina SojakovagetSenItems = filter ( \ (Annoted i _ _ _) ->
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova Decl _ -> False
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova Form _ -> True )
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovaprintSigItems :: [Annoted BASIC_ITEM] -> String
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovaprintSigItems is =
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova concat $ map (\ (Annoted i _ _ _) ->
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova Decl d -> d ++ ".\n"
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovaprintSenItems :: String -> [Annoted BASIC_ITEM] -> String
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovaprintSenItems sen_type items = printSenItemsH sen_type 0 items
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovaprintSenItemsH :: String -> Int -> [Annoted BASIC_ITEM] -> String
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovaprintSenItemsH _ _ [] = ""
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovaprintSenItemsH sen_type num (i:is) =
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova Annoted (Form f) _ _ _ ->
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let lab = getRLabel i
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova lab' = if null lab then numSuf gen_ax num else lab
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova num' = if null lab then num + 1 else num
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova in lab' ++ " : " ++ sen_type ++ " = " ++ f ++ ".\n" ++
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova printSenItemsH sen_type num' is
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova _ -> printSenItemsH sen_type num is
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina SojakovamakeNamedForms :: [(NAME,Sentence)] -> [[Annotation]] -> [Named Sentence]
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina SojakovamakeNamedForms ss as = map makeNamedForm $ zip ss as
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina SojakovamakeNamedForm :: ((NAME,Sentence),[Annotation]) -> Named Sentence
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina SojakovamakeNamedForm ((n,s),annos) =
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova let implies = or $ map isImplies annos
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova implied = or $ map isImplied annos
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova isTheorem = implies || implied
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova in (makeNamed n s) {isAxiom = not isTheorem}
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovagetSigFromLibs :: MODULE -> LIBS -> Sign
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovagetSigFromLibs n libs =
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova let (sigs,_) = Map.findWithDefault (error badLibError) gen_file libs
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova in Map.findWithDefault (error $ badSigError n) n sigs
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovaunknownSyms :: [RAW_SYM] -> Sign -> [RAW_SYM]
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovaunknownSyms syms sig =
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova filter (\ s -> Set.notMember s $ Set.map symName $ getLocalSyms sig) syms
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovatoSym :: RAW_SYM -> Symbol
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovatoSym s = Symbol gen_base gen_module s
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova-----------------------------------------------------------------
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova-----------------------------------------------------------------
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina Sojakova-- basic analysis for LF
ccaa75089b23c0f043cdbd4001cba4e076ca4fd3Kristina SojakovabasicAnalysis :: (BASIC_SPEC, Sign, GlobalAnnos) ->
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova Result (BASIC_SPEC, ExtSign Sign Symbol, [Named EXP])
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina SojakovabasicAnalysis (bs@(Basic_spec items), initsig, _) = do
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakova let (sig,sens) = unsafePerformIO $ makeSigSen initsig items
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakova let syms = getSymbols sig
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakova let fs = makeNamedForms sens $ map r_annos $ getSenItems items
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakova return (bs, ExtSign sig syms, fs)
e8dd447a2aa5fbac10668749dfe4142c05ec3d7dKristina Sojakova-- constructs the signatures and sentences
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina SojakovamakeSigSen :: Sign -> [Annoted BASIC_ITEM] -> IO (Sign,[(NAME,Sentence)])
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina SojakovamakeSigSen sig items = do
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova -- make a Twelf file
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let sen_type = show $ pretty sen_type_exp
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova let cont1 = if (null $ getDefs sig) then "" else show (pretty sig) ++ "\n"
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let cont2 = printSigItems $ getSigItems items
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let cont3 = printSenItems sen_type $ getSenItems items
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let s1 = mkSig gen_sig1 $ cont1 ++ cont2
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let s2 = mkSig gen_sig2 $ mkIncl gen_sig1 ++ cont3
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let contents = s1 ++ "\n" ++ s2
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakova writeFile gen_file contents
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova -- run Twelf on the created file
5e35940c3516ccea02caa0450d2b075de0106fa5Kristina Sojakova libs <- twelf2SigMor gen_file
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova -- construct the signature and sentences
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let sig1 = getSigFromLibs gen_sig1 libs
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let sig2 = getSigFromLibs gen_sig2 libs
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova let sens = getSens sig2
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova return (sig1,sens)
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovagetSens :: Sign -> [(NAME,Sentence)]
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova map (\ (Def s _ v) ->
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova Nothing -> error $ badValError $ symName s
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova Just v' -> (symName s, v')
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova ) $ getLocalDefs sig
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova-----------------------------------------------------------------
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova-----------------------------------------------------------------
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova-- symbol analysis for LF
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovasymbAnalysis :: [SYMB_ITEMS] -> Result [RAW_SYM]
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovasymbAnalysis ss = Result [] $ Just $ concat $ map (\ (Symb_items s) -> s) ss
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova-- symbol map analysis for LF
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovasymbMapAnalysis :: [SYMB_MAP_ITEMS] -> Result (Map.Map RAW_SYM RAW_SYM)
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovasymbMapAnalysis ss = Result [] $ Just $
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova foldl (\ m s -> Map.union m (makeSymbMap s)) Map.empty ss
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovamakeSymbMap :: SYMB_MAP_ITEMS -> Map.Map RAW_SYM RAW_SYM
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina SojakovamakeSymbMap (Symb_map_items ss) =
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova foldl (\ m s -> case s of
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova Symb s1 -> Map.insert s1 s1 m
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova Symb_map s1 s2 -> Map.insert s1 s2 m
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova----------------------------------------------------------------
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova-----------------------------------------------------------------
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova{- converts a mapping of raw symbols to a mapping of symbols to expressions
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova annotated with their type -}
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovatranslMapAnalysis :: Map.Map RAW_SYM RAW_SYM -> Sign -> Sign ->
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova Map.Map Symbol (EXP,EXP)
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovatranslMapAnalysis m sig1 sig2 =
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova let syms = unknownSyms (Map.keys m) sig1
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova in if not (null syms) then error $ badDomError syms else
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova unsafePerformIO $ codAnalysis m sig2
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovacodAnalysis :: Map.Map RAW_SYM RAW_SYM -> Sign -> IO (Map.Map Symbol (EXP,EXP))
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovacodAnalysis m sig2 = do
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova -- make a Twelf file
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova let cont1 = (show $ pretty sig2) ++ "\n"
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova let cont2 = concat $ map (\ (k,v) -> (genPref k) ++ " = " ++ v ++ ".\n") $
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let s1 = mkSig gen_sig1 cont1
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let s2 = mkSig gen_sig2 $ mkIncl gen_sig1 ++ cont2
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let contents = s1 ++ "\n" ++ s2
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova writeFile gen_file contents
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova -- run Twelf on the created file
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova libs <- twelf2SigMor gen_file
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova -- construct the mapping
d71bb9deea089887b4fd829c5b766e7e4de9f204Kristina Sojakova let sig' = getSigFromLibs gen_sig2 libs
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova return $ getMap sig'
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovagetMap :: Sign -> Map.Map Symbol (EXP,EXP)
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovagetMap sig = Map.fromList $ map
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova (\ (Def s t v) ->
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova Nothing -> error $ badValError $ symName s
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova Just v' -> let Just n = stripPrefix gen $ symName s
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova in (toSym n, (v',t))
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova ) $ getLocalDefs sig
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova---------------------------------------------------------------------------
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova---------------------------------------------------------------------------
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova-- ERROR MESSAGES
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovabadLibError :: String
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovabadLibError = "Library not found."
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovabadSigError :: MODULE -> String
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovabadSigError n = "Signature " ++ n ++ " not found."
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovabadDomError :: [String] -> String
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovabadDomError ss = "Symbols " ++ (show ss) ++
abd5fc85dc7e19b1614890182436940e922963a4Kristina Sojakova " are unknown or cannot be used in a morphism."
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovabadValError :: String -> String
abd5fc85dc7e19b1614890182436940e922963a4Kristina SojakovabadValError s = "Symbol " ++ s ++ "does not have a value."