EdgeUtils.hs revision 4ea99e115bbade1632815267d5e0dcb9931aac1e
{-|
Module : $Header$
Copyright : (c) Jorina F. Gerken, Till Mossakowski, Uni Bremen 2002-2004
License : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
Maintainer : jfgerken@tzi.de
Stability : provisional
Portability : non-portable(Logic)
utility functions for edges of a development graphs.
-}
module Proofs.EdgeUtils where
import Data.List(nub)
import Logic.Logic
import Logic.Grothendieck
import Static.DevGraph
import Static.DGToSpec
import Data.Graph.Inductive.Graph
import qualified Common.Lib.Map as Map
import Proofs.Proofs
delLEdge :: LEdge DGLinkLab -> DGraph -> DGraph
delLEdge (v, w, l) g = case match v g of
(Just(p, v', l', s), g') -> (p, v', l', filter (/= (l, w)) s) & g'
_ -> g
-- -------------------------------------
-- methods to check the type of an edge
-- -------------------------------------
isProven :: LEdge DGLinkLab -> Bool
isProven edge = isGlobalDef edge || isLocalDef edge
|| isProvenGlobalThm edge || isProvenLocalThm edge
|| isProvenHidingThm edge
isDefEdge :: LEdge DGLinkLab -> Bool
isDefEdge edge = isGlobalDef edge || isLocalDef edge || isHidingDef edge
isGlobalEdge :: LEdge DGLinkLab -> Bool
isGlobalEdge edge = isGlobalDef edge || isGlobalThm edge
isLocalEdge :: LEdge DGLinkLab -> Bool
isLocalEdge edge = isLocalDef edge || isLocalThm edge
isGlobalThm :: LEdge DGLinkLab -> Bool
isGlobalThm edge = isProvenGlobalThm edge || isUnprovenGlobalThm edge
isLocalThm :: LEdge DGLinkLab -> Bool
isLocalThm edge = isProvenLocalThm edge || isUnprovenLocalThm edge
isProvenGlobalThm :: LEdge DGLinkLab -> Bool
isProvenGlobalThm (_,_,edgeLab) =
case dgl_type edgeLab of
(GlobalThm (Proven _ _) _ _) -> True
_ -> False
isUnprovenGlobalThm :: LEdge DGLinkLab -> Bool
isUnprovenGlobalThm (_,_,edgeLab) =
case dgl_type edgeLab of
(GlobalThm LeftOpen _ _) -> True
_ -> False
isProvenLocalThm :: LEdge DGLinkLab -> Bool
isProvenLocalThm (_,_,edgeLab) =
case dgl_type edgeLab of
(LocalThm (Proven _ _) _ _) -> True
_ -> False
isUnprovenLocalThm :: LEdge DGLinkLab -> Bool
isUnprovenLocalThm (_,_,edgeLab) =
case dgl_type edgeLab of
(LocalThm LeftOpen _ _) -> True
_ -> False
isHidingEdge :: LEdge DGLinkLab -> Bool
isHidingEdge edge = isHidingDef edge || isHidingThm edge
isHidingDef :: LEdge DGLinkLab -> Bool
isHidingDef (_,_,edgeLab) =
case dgl_type edgeLab of
HidingDef -> True
_ -> False
isHidingThm :: LEdge DGLinkLab -> Bool
isHidingThm edge = isProvenHidingThm edge || isUnprovenHidingThm edge
isProvenHidingThm :: LEdge DGLinkLab -> Bool
isProvenHidingThm (_,_,edgeLab) =
case dgl_type edgeLab of
(HidingThm _ (Proven _ _)) -> True
_ -> False
isUnprovenHidingThm :: LEdge DGLinkLab -> Bool
isUnprovenHidingThm (_,_,edgeLab) =
case dgl_type edgeLab of
(HidingThm _ LeftOpen) -> True
_ -> False
-- ----------------------------------------------------------------------------
-- other methods on edges
-- ----------------------------------------------------------------------------
{- returns true, if an identical edge is already in the graph or marked to be inserted,
false otherwise-}
isDuplicate :: LEdge DGLinkLab -> DGraph -> [DGChange] -> Bool
isDuplicate newEdge dgraph changes =
elem (InsertEdge newEdge) changes || elem newEdge (labEdges dgraph)
isIdentityEdge :: LEdge DGLinkLab -> LibEnv -> DGraph -> Bool
isIdentityEdge (src,tgt,edgeLab) libEnv dgraph =
if isDGRef nodeLab then
case Map.lookup (dgn_libname nodeLab) libEnv of
Just (_,_,refDgraph) -> isIdentityEdge (dgn_node nodeLab,tgt,edgeLab) libEnv refDgraph
Nothing -> False
else if src == tgt && (dgl_morphism edgeLab) == (ide Grothendieck (dgn_sign nodeLab)) then True else False
where nodeLab = lab' (context dgraph src)
{- returns the DGLinkLab of the given LEdge -}
getLabelOfEdge :: (LEdge b) -> b
getLabelOfEdge (_,_,label) = label
-- ----------------------------------------------
-- methods that calculate paths of certain types
-- ----------------------------------------------
{- returns a list of all proven global paths of the given morphism between
the given source and target node-}
getAllGlobPathsOfMorphismBetween :: DGraph -> GMorphism -> Node -> Node
-> [[LEdge DGLinkLab]]
getAllGlobPathsOfMorphismBetween dgraph morphism src tgt =
filterPathsByMorphism morphism allPaths
where
allPaths = getAllGlobPathsBetween dgraph src tgt
{- returns all paths from the given list whose morphism is equal to the
given one-}
filterPathsByMorphism :: GMorphism -> [[LEdge DGLinkLab]]
-> [[LEdge DGLinkLab]]
filterPathsByMorphism morphism paths =
[path| path <- paths, (calculateMorphismOfPath path) == (Just morphism)]
{- returns all paths consisting of global edges only
or
of one local edge followed by any number of global edges-}
getAllLocGlobPathsBetween :: DGraph -> Node -> Node -> [[LEdge DGLinkLab]]
getAllLocGlobPathsBetween dgraph src tgt =
locGlobPaths ++ globPaths
where
outEdges = out dgraph src
locEdges = [(edge,target)|edge@(_,target,_) <-
(filter isLocalEdge outEdges)]
locGlobPaths = (concat [map ([edge]++)
(getAllPathsOfTypesBetween dgraph isGlobalEdge node tgt [])|
(edge,node) <- locEdges])
globPaths = getAllPathsOfTypesBetween dgraph isGlobalEdge src tgt []
{- returns all paths of globalDef edges or globalThm edges
between the given source and target node -}
getAllGlobPathsBetween :: DGraph -> Node -> Node -> [[LEdge DGLinkLab]]
getAllGlobPathsBetween dgraph src tgt =
getAllPathsOfTypesBetween dgraph (liftOr isGlobalDef isGlobalThm) src tgt []
{- returns all paths consiting of edges of the given type between the
given node -}
getAllPathsOfTypeBetween :: DGraph -> (LEdge DGLinkLab -> Bool) -> Node
-> Node -> [[LEdge DGLinkLab]]
getAllPathsOfTypeBetween dgraph isType src tgt =
getAllPathsOfTypesBetween dgraph isType src tgt []
{- returns all paths consisting of edges of the given types between
the given nodes -}
getAllPathsOfTypesBetween :: DGraph -> (LEdge DGLinkLab -> Bool) -> Node
-> Node -> [LEdge DGLinkLab]
-> [[LEdge DGLinkLab]]
getAllPathsOfTypesBetween dgraph types src tgt path =
[edge:path| edge <- edgesFromSrc]
++ (concat
[getAllPathsOfTypesBetween dgraph types src nextTgt (edge:path)|
(edge,nextTgt) <- nextStep] )
where
inGoingEdges = inn dgraph tgt
edgesOfTypes =
[edge| edge <- filter types inGoingEdges, notElem edge path]
edgesFromSrc =
[edge| edge@(source,_,_) <- edgesOfTypes, source == src]
nextStep =
[(edge, source)| edge@(source,_,_) <- edgesOfTypes, source /= src]
getAllPathsOfTypeFrom :: DGraph -> Node -> (LEdge DGLinkLab -> Bool) -> [[LEdge DGLinkLab]]
getAllPathsOfTypeFrom = getAllPathsOfTypeFromAux []
getAllPathsOfTypeFromAux :: [LEdge DGLinkLab] -> DGraph -> Node
-> (LEdge DGLinkLab -> Bool) -> [[LEdge DGLinkLab]]
getAllPathsOfTypeFromAux path dgraph src isType =
[path ++ [edge]| edge <- edgesFromSrc, notElem edge path && isType edge]
++(concat
[getAllPathsOfTypeFromAux (path ++ [edge]) dgraph nextSrc isType|
(edge,nextSrc) <- nextStep])
where
edgesFromSrc = out dgraph src
nextStep = [(edge,tgt)| edge@(_,tgt,_) <- edgesFromSrc,
tgt /= src && notElem edge path && isType edge]
-- ----------------------------------------------------------------------------
-- methods to determine the labels of the inserted edges in the given dgchange
-- ----------------------------------------------------------------------------
{- filters the list of changes for insertions of edges and returns the label
of one of these; or Nothing if no insertion was found -}
getLabelsOfInsertedEdges :: [DGChange] -> [DGLinkLab]
getLabelsOfInsertedEdges changes =
[label | (_,_,label) <- getInsertedEdges changes]
{- returns all insertions of edges from the given list of changes -}
getInsertedEdges :: [DGChange] -> [LEdge DGLinkLab]
getInsertedEdges [] = []
getInsertedEdges (change:list) =
case change of
(InsertEdge edge) -> edge:(getInsertedEdges list)
_ -> getInsertedEdges list
-- ----------------------------------------
-- methods to check and select proof basis
-- ----------------------------------------
{- determines all proven paths in the given list and tries to selet a
proof basis from these (s. selectProofBasisAux);
if this fails the same is done for the rest of the given paths, i.e.
for the unproven ones -}
selectProofBasis :: DGLinkLab -> [[LEdge DGLinkLab]] -> [DGLinkLab]
selectProofBasis label paths =
if null provenProofBasis then selectProofBasisAux label unprovenPaths
else provenProofBasis
where
provenPaths = filterProvenPaths paths
provenProofBasis = selectProofBasisAux label provenPaths
unprovenPaths = [path | path <- paths, notElem path provenPaths]
{- selects the first path that does not form a proof cycle with the given
label (if such a path exits) and returns the labels of its edges -}
selectProofBasisAux :: DGLinkLab -> [[LEdge DGLinkLab]] -> [DGLinkLab]
selectProofBasisAux _ [] = []
selectProofBasisAux label (path:list) =
if notProofCycle label path then nub (calculateProofBasis path)
else selectProofBasisAux label list
{- calculates the proofBasis of the given path,
i.e. the list of all DGLinkLabs the proofs of the edges contained in the path
are based on, plus the DGLinkLabs of the edges themselves;
duplicates are not removed here, but in the calling method
selectProofBasisAux -}
calculateProofBasis :: [LEdge DGLinkLab] -> [DGLinkLab]
calculateProofBasis [] = []
calculateProofBasis ((_,_,label):edges) =
label:((getProofBasis label)++(calculateProofBasis edges))
{- returns the proofBasis contained in the given DGLinkLab -}
getProofBasis :: DGLinkLab -> [DGLinkLab]
getProofBasis label =
case dgl_type label of
(GlobalThm (Proven _ proofBasis) _ _) -> proofBasis
(LocalThm (Proven _ proofBasis) _ _) -> proofBasis
_ -> []
{- returns all proven paths from the given list -}
filterProvenPaths :: [[LEdge DGLinkLab]] -> [[LEdge DGLinkLab]]
filterProvenPaths [] = []
filterProvenPaths (path:list) =
if (and [isProven edge| edge <- path]) then path:(filterProvenPaths list)
else filterProvenPaths list
{- opposite of isProofCycle -}
notProofCycle :: DGLinkLab -> [LEdge DGLinkLab] -> Bool
notProofCycle label = not.(isProofCycle label)
{- checks if the given label is contained in the ProofBasis of one of the
edges of the given path -}
isProofCycle :: DGLinkLab -> [LEdge DGLinkLab] -> Bool
isProofCycle _ [] = False
isProofCycle label (edge:path) =
if (elemOfProofBasis label edge) then True else (isProofCycle label path)
{- checks if the given label is contained in the ProofBasis of the given
edge -}
elemOfProofBasis :: DGLinkLab -> (LEdge DGLinkLab) -> Bool
elemOfProofBasis label (_,_,dglink) =
case dgl_type dglink of
(GlobalThm (Proven _ proofBasis) _ _) -> elem label proofBasis
(LocalThm (Proven _ proofBasis) _ _) -> elem label proofBasis
_ -> False