DevGraph.hs revision 90d7cac36f60438bd35124e3389b5bce6d114b46
4b0a4c7dea0f67a233dcc42ce9bb18d36de109aeChristian MaederModule : $Header$
5ba323da9f037264b4a356085e844889aedeac23Christian MaederDescription : Central datastructures for development graphs
10397bcc134edbcfbe3ae2c7ea4c6080036aae22Christian MaederCopyright : (c) Till Mossakowski, Uni Bremen 2002-2006
97018cf5fa25b494adffd7e9b4e87320dae6bf47Christian MaederLicense : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
23f2c59644866aa82e90de353e77f9f1d1b51b9aChristian MaederMaintainer : till@informatik.uni-bremen.de
3f69b6948966979163bdfe8331c38833d5d90ecdChristian MaederStability : provisional
4b0a4c7dea0f67a233dcc42ce9bb18d36de109aeChristian MaederPortability : non-portable(Logic)
4b0a4c7dea0f67a233dcc42ce9bb18d36de109aeChristian MaederCentral datastructures for development graphs
f3a94a197960e548ecd6520bb768cb0d547457bbChristian Maeder Follows Sect. IV:4.2 of the CASL Reference Manual.
4b0a4c7dea0f67a233dcc42ce9bb18d36de109aeChristian Maeder T. Mossakowski, S. Autexier and D. Hutter:
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maeder Extending Development Graphs With Hiding.
fc8c6570c7b4ee13f375eb607bed2290438573bfChristian Maeder H. Hussmann (ed.): Fundamental Approaches to Software Engineering 2001,
792df0347edab377785d98c63e2be8e2ce0a8bdeChristian Maeder Lecture Notes in Computer Science 2029, p. 269-283,
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder Springer-Verlag 2001.
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder T. Mossakowski, S. Autexier, D. Hutter, P. Hoffman:
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder CASL Proof calculus. In: CASL reference manual, part IV.
af621d0066770895fd79562728e93099c8c52060Christian Maederimport Logic.Comorphism(mkIdComorphism)
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maederimport qualified Data.Graph.Inductive.Query.DFS as DFS
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maederimport qualified Data.Graph.Inductive.Query.BFS as BFS
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maederimport qualified Common.Lib.Graph as Tree
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maederimport qualified Data.Map as Map
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maederimport qualified Common.OrderedMap as OMap
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maederimport Data.Char (toLower)
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maederimport Data.List(find, intersect, partition)
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder{- | returns one new node id for the given graph
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaedergetNewNode :: Tree.Gr a b -> Node
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaedergetNewNode g = case newNodes 1 g of
9e0472be46104307b974fe5079bf5cc9e94a1a96Christian Maeder{- | returns a list of edge ids with the given number of edge ids
9e0472be46104307b974fe5079bf5cc9e94a1a96Christian Maeder and a specified graph.
9e0472be46104307b974fe5079bf5cc9e94a1a96Christian MaedergetNewEdgeIDs :: Int -> DGraph -> EdgeID
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaedergetNewEdgeIDs count g = take count [(getNewEdgeID g)..]
9e0472be46104307b974fe5079bf5cc9e94a1a96Christian Maeder{- | tries to find the label of a link whose id is given in
9e0472be46104307b974fe5079bf5cc9e94a1a96Christian Maeder a specified graph
afa6848d579d235c9677e1ab477916df8e5ae11aChristian MaedergetDGLinkLabWithIDs :: EdgeID -> DGraph -> Maybe DGLinkLab
afa6848d579d235c9677e1ab477916df8e5ae11aChristian MaedergetDGLinkLabWithIDs ids dgraph =
afa6848d579d235c9677e1ab477916df8e5ae11aChristian Maeder case getDGLEdgeWithIDs ids dgraph of
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder Just (_, _, label) -> Just label
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder Nothing -> Nothing
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder{- | tries to find a link, which includes the src, tgt node
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder and its label according to a given id in a specified graph.
d976ba42e9d48c289f9c73147669c7e57b7aa98eChristian MaedergetDGLEdgeWithIDs :: EdgeID -> DGraph -> Maybe (LEdge DGLinkLab)
d976ba42e9d48c289f9c73147669c7e57b7aa98eChristian MaedergetDGLEdgeWithIDs ids dgraph =
986e0e9cf8c2358f455460b3fc75ce7c5dcf0973Christian Maeder find (\ (_, _, label) -> isIdenticalEdgeID ids $ dgl_id label)
6a7e00a968cb0f3f9ccae19ab47ef3636c7e79bfChristian Maeder $ labEdges $ dgBody dgraph
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maeder{- | returns whether two edge ids are identical to each other or not.
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maeder two edge ids are identical, only if their intersect
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maeder is not empty.
6a7e00a968cb0f3f9ccae19ab47ef3636c7e79bfChristian MaederisIdenticalEdgeID :: EdgeID -> EdgeID -> Bool
6a7e00a968cb0f3f9ccae19ab47ef3636c7e79bfChristian MaederisIdenticalEdgeID id1 id2 = not $ null $ intersect id1 id2
6a7e00a968cb0f3f9ccae19ab47ef3636c7e79bfChristian Maeder{- | similar to getDGLEdgeWithIDs, but an error will be thrown if
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder the specified edge is not found.
59c301c268f79cfde0a4c30a2c572a368db98da5Christian MaedergetDGLEdgeWithIDsForSure :: EdgeID -> DGraph -> (LEdge DGLinkLab)
59c301c268f79cfde0a4c30a2c572a368db98da5Christian MaedergetDGLEdgeWithIDsForSure ids dgraph =
59c301c268f79cfde0a4c30a2c572a368db98da5Christian Maeder case getDGLEdgeWithIDs ids dgraph of
59c301c268f79cfde0a4c30a2c572a368db98da5Christian Maeder Nothing -> error ("ID: "++show ids ++
59c301c268f79cfde0a4c30a2c572a368db98da5Christian Maeder "not found. Static.DevGraph.getDGLEdgeWithIDsForSure")
5334aa8fe0b0d1eb8a1cad40b741aa07172773c9Christian Maeder-- * Types for structured specification analysis
31a189d4cff554f78407cdc422480e84e99a6ec6Christian Maeder-- ??? Some info about the theorems already proved for a node
31a189d4cff554f78407cdc422480e84e99a6ec6Christian Maeder-- should be added
31a189d4cff554f78407cdc422480e84e99a6ec6Christian Maeder-- or should it be kept separately?
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder-- what about open theorems of a node???
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder-- | name of a node in a DG; auxiliary nodes may have extension string
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder-- and non-zero number (for these, names are usually hidden)
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maedertype NODE_NAME = (SIMPLE_ID, String, Int)
5334aa8fe0b0d1eb8a1cad40b741aa07172773c9Christian Maederdata DGNodeInfo = DGNode
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder { node_origin :: DGOrigin -- origin in input language
5334aa8fe0b0d1eb8a1cad40b741aa07172773c9Christian Maeder , node_cons :: Conservativity
5334aa8fe0b0d1eb8a1cad40b741aa07172773c9Christian Maeder , node_cons_status :: ThmLinkStatus }
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder | DGRef -- reference to node in a different DG
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder { ref_libname :: LIB_NAME -- pointer to DG where ref'd node resides
5334aa8fe0b0d1eb8a1cad40b741aa07172773c9Christian Maeder , ref_node :: Node -- pointer to ref'd node
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder } deriving (Show, Eq)
ad187062b0009820118c1b773a232e29b879a2faChristian Maederdgn_origin :: DGNodeLab -> DGOrigin
5334aa8fe0b0d1eb8a1cad40b741aa07172773c9Christian Maederdgn_origin = node_origin . nodeInfo
ad187062b0009820118c1b773a232e29b879a2faChristian Maederdgn_cons :: DGNodeLab -> Conservativity
ad187062b0009820118c1b773a232e29b879a2faChristian Maederdgn_cons = node_cons . nodeInfo
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maederdgn_cons_status :: DGNodeLab -> ThmLinkStatus
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maederdgn_cons_status = node_cons_status . nodeInfo
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maederdgn_libname :: DGNodeLab -> LIB_NAME
e76e6a43f51438215737d6fc176c89da05bb86daChristian Maederdgn_libname = ref_libname . nodeInfo
31a189d4cff554f78407cdc422480e84e99a6ec6Christian Maederdgn_node :: DGNodeLab -> Node
31a189d4cff554f78407cdc422480e84e99a6ec6Christian Maederdgn_node = ref_node . nodeInfo
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder-- | node inscriptions in development graphs
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maederdata DGNodeLab =
8485da94b57d8b5135ee685b55c982b037ed4140Christian Maeder { dgn_name :: NODE_NAME -- name in the input language
8485da94b57d8b5135ee685b55c982b037ed4140Christian Maeder , dgn_theory :: G_theory -- local theory
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder , dgn_nf :: Maybe Node -- normal form, for Theorem-Hide-Shift
e76e6a43f51438215737d6fc176c89da05bb86daChristian Maeder , dgn_sigma :: Maybe GMorphism -- inclusion of signature into nf signature
e76e6a43f51438215737d6fc176c89da05bb86daChristian Maeder , nodeInfo :: DGNodeInfo
e76e6a43f51438215737d6fc176c89da05bb86daChristian Maeder , dgn_lock :: Maybe (MVar ())
ad187062b0009820118c1b773a232e29b879a2faChristian Maeder } deriving (Show, Eq)
e76e6a43f51438215737d6fc176c89da05bb86daChristian Maederinstance Show (MVar ()) where
59c301c268f79cfde0a4c30a2c572a368db98da5Christian Maederdgn_sign :: DGNodeLab -> G_sign
59c301c268f79cfde0a4c30a2c572a368db98da5Christian Maederdgn_sign dn = case dgn_theory dn of
dc6b48bb46df8e56da3491c98476e6da0d1d5d1dChristian Maeder G_theory lid sig ind _ _-> G_sign lid sig ind
4b0a4c7dea0f67a233dcc42ce9bb18d36de109aeChristian MaederisInternalNode :: DGNodeLab -> Bool
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian MaederisInternalNode l@DGNodeLab {dgn_name = n} =
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder if isDGRef l then null $ show $ getName n else isInternal n
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder-- | test for 'LeftOpen', return input for refs or no conservativity
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaederhasOpenConsStatus :: Bool -> DGNodeLab -> Bool
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaederhasOpenConsStatus b dgn = if isDGRef dgn then b else
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder case dgn_cons dgn of
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder _ -> case dgn_cons_status dgn of
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder LeftOpen -> True
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder-- | gets the type of a development graph edge as a string
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaedergetDGNodeType :: DGNodeLab -> String
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaedergetDGNodeType dgnodelab =
62ecb1e7f8fd9573eea8369657de12c7bf9f4f25Christian Maeder (if hasOpenGoals dgnodelab then id else ("locallyEmpty__" ++))
f6f2955769bfe80dbb4cca3b3ee33c5a8a0f5355Christian Maeder $ if isDGRef dgnodelab then "dg_ref" else
c1031ac42b3f3d7d0fe7d9d6b54423a092d473a0Christian Maeder (if hasOpenConsStatus False dgnodelab
fce77b2785912d1abbcc3680088b235f534bdeffChristian Maeder then "open_cons__"
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder else "proven_cons__")
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder ++ if isInternalNode dgnodelab
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder then "internal"
039b7a8265baaeab2ded2a3e3826c04f13364d87Christian Maeder-- gets the name of a development graph node as a string
fe5dbb45b6a8abf34375b4bc5f2a81cda664c0e4Christian MaedergetDGNodeName :: DGNodeLab -> String
3cafc73a998493f9ed3d5e934c0ab80bcfb465c2Christian MaedergetDGNodeName dgn = showName $ dgn_name dgn
039b7a8265baaeab2ded2a3e3826c04f13364d87Christian MaederemptyNodeName :: NODE_NAME
ac19566dc64536c38b5d1d3ae510fb8a07784c2fChristian MaederemptyNodeName = (mkSimpleId "", "", 0)
7bf6d421b0ea31ae63f1fe04919942b931abda47Christian MaedershowInt :: Int -> String
021d7137df04ec1834911d99d90243a092841cedChristian MaedershowInt i = if i == 0 then "" else show i
7c554e9d4a39b8eb3b0881f20807c95dd8e793aeChristian MaedershowName :: NODE_NAME -> String
5581c4644d91dcb9b7e2e7f6052f7cbf5f97b6deChristian MaedershowName (n, s, i) = show n ++ if ext == "" then "" else "_" ++ ext
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder where ext = s ++ showInt i
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian MaedermakeName :: SIMPLE_ID -> NODE_NAME
7c554e9d4a39b8eb3b0881f20807c95dd8e793aeChristian MaedermakeName n = (n, "", 0)
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaedergetName :: NODE_NAME -> SIMPLE_ID
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaedergetName (n, _, _) = n
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaedermakeMaybeName :: Maybe SIMPLE_ID -> NODE_NAME
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaedermakeMaybeName Nothing = emptyNodeName
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaedermakeMaybeName (Just n) = makeName n
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maederinc :: NODE_NAME -> NODE_NAME
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maederinc (n, s, i) = (n, s, i+1)
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaederisInternal :: NODE_NAME -> Bool
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaederisInternal (_, s, i) = i /= 0 || s /= ""
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaederextName :: String -> NODE_NAME -> NODE_NAME
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaederextName s (n, s1, i) = (n, s1 ++ showInt i ++ s, 0)
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaederisDGRef :: DGNodeLab -> Bool
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaederisDGRef l = case nodeInfo l of
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maeder DGNode {} -> False
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maeder DGRef {} -> True
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maeder-- | test if a given node label has local open goals
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian MaederhasOpenGoals :: DGNodeLab -> Bool
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian MaederhasOpenGoals dgn =
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maeder case dgn_theory dgn of
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maeder G_theory _lid _sigma _ sens _->
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maeder (\s -> not (isAxiom s) && not (isProvenSenStatus s) ) sens
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maeder{- | an edge id is represented as a list of ints.
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maeder the reason of an edge can have multiple ids is, for example, there exists
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maeder an proven edge e1 with id 1 and an unproven edge e2 with id 2 between
e13ee09381f136f5eadaabdb9699773c0052cf3dChristian Maeder two nodes. Now after applying some rules e2 is proven, but it's actually
7bf6d421b0ea31ae63f1fe04919942b931abda47Christian Maeder the same as the proven edge e1, then the proven e2 should not be inserted
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder into the graph again, but e1 will take e2's id 2 because 2 is probably
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian Maeder saved in some other places. As a result, e1 would have 1 and 2 as its id.
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder This type can be extended to a more complicated struture, like a tree
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder suggested by Till.
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maedertype EdgeID = [Int]
908a6351595b57641353608c4449d5faa0d1adf8Christian Maeder-- | link inscriptions in development graphs
908a6351595b57641353608c4449d5faa0d1adf8Christian Maederdata DGLinkLab = DGLink
908a6351595b57641353608c4449d5faa0d1adf8Christian Maeder { dgl_morphism :: GMorphism -- signature morphism of link
908a6351595b57641353608c4449d5faa0d1adf8Christian Maeder , dgl_type :: DGLinkType -- type: local, global, def, thm?
bb3bdd4a260606a6184b5f5a5774ca6632ca597aChristian Maeder , dgl_origin :: DGOrigin -- origin in input language
e8a2ca3a7b3e9a19ef03b6b1c0b5d03dbad6463cChristian Maeder , dgl_id :: EdgeID -- id of the edge
4561227a776bdf0ab679b19fb92f1eaaed8786f7Christian Maeder } deriving Show
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian Maeder-- | create a default ID which has to be changed when inserting a certain edge.
7de39d39bc1700cc8a9bb9df90b920aad9e18d4aChristian MaederdefaultEdgeID :: EdgeID
ff9a53595208f532c25ac5168f772f48fd80fdb5Christian MaederdefaultEdgeID = []
type StUnitCtx = Map.Map SIMPLE_ID ImpUnitSigOrSig
emptyStUnitCtx = Map.empty
type GlobalEnv = Map.Map SIMPLE_ID GlobalEntry
, dgBody :: Tree.Gr DGNodeLab DGLinkLab -- ^ actual 'DGraph` tree
, refNodes :: Map.Map Node (LIB_NAME, Node) -- ^ unexpanded 'DGRef's
, allRefNodes :: Map.Map (LIB_NAME, Node) Node -- ^ all DGRef's
, sigMap :: Map.Map Int G_sign -- ^ signature map
, thMap :: Map.Map Int G_theory -- ^ morphism map
, morMap :: Map.Map Int G_morphism -- ^ theory map
, globalEnv = Map.empty
, dgBody = Graph.empty
, refNodes = Map.empty
, allRefNodes = Map.empty
, sigMap = Map.empty
, thMap = Map.empty
, morMap = Map.empty
setSigMapDG :: Map.Map Int G_sign -> DGraph -> DGraph
setThMapDG :: Map.Map Int G_theory -> DGraph -> DGraph
setMorMapDG :: Map.Map Int G_morphism -> DGraph -> DGraph
lookupSigMapDG i = Map.lookup i . sigMap
lookupThMapDG i = Map.lookup i . thMap
lookupMorMapDG i = Map.lookup i . morMap
lookupGlobalEnvDG sid = Map.lookup sid . globalEnv
sigMapI :: DGraph -> (Map.Map Int G_sign, Int)
morMapI :: DGraph -> (Map.Map Int G_morphism, Int)
thMapI :: DGraph -> (Map.Map Int G_theory, Int)
type LibEnv = Map.Map LIB_NAME DGraph
emptyLibEnv = Map.empty
Map.findWithDefault (error "lookupDGraph") ln
gWeaklyAmalgamableCocone :: GDiagram -> Result (G_theory, Map.Map Int GMorphism)
morFun = Map.fromList $
dg{refNodes = Map.insert n (libn, refn) $ refNodes dg,
allRefNodes = Map.insert (libn, refn) n $ allRefNodes dg}
deleteFromRefNodesDG n dg = dg{refNodes = Map.delete n $ refNodes dg}
Map.lookup n $ refNodes dg
Map.lookup refK $ allRefNodes dg
sccDG = DFS.scc . dgBody
topsortDG = DFS.topsort . dgBody
bfsDG n = BFS.bfs n . dgBody