| DGRestriction (MaybeRestricted) (
Set.Set G_symbol)
| DGFreeOrCofree FreeOrCofree
-- | node content or reference to another library's node
{ node_origin :: DGOrigin -- origin in input language
, node_cons_status :: ConsStatus } -- like a link from the empty signature
| DGRef -- reference to node in a different DG
{ ref_libname :: LibName -- pointer to DG where ref'd node resides
, ref_node :: Node -- pointer to ref'd node
{- | node inscriptions in development graphs.
Nothing entries indicate "not computed yet" -}
{ dgn_name :: NodeName -- name in the input language
, dgn_theory :: G_theory -- local theory
, globalTheory :: Maybe G_theory -- global theory
, labelHasHiding :: Bool -- has this node an ingoing hiding link
, labelHasFree :: Bool -- has incoming free definition link
, dgn_nf :: Maybe Node -- normal form, for Theorem-Hide-Shift
, dgn_sigma :: Maybe GMorphism -- inclusion of signature into nf signature
, dgn_freenf :: Maybe Node -- normal form for freeness
, dgn_phi :: Maybe GMorphism -- morphism from signature to nffree signature
, dgn_lock :: Maybe (MVar ())
, dgn_symbolpathlist :: G_symbolmap [SLinkPath]
instance Show (MVar a) where
isDGRef :: DGNodeLab -> Bool
isDGRef l = case nodeInfo l of
sensWithKind :: (forall a . SenStatus a (AnyComorphism, BasicProof) -> Bool)
hasSenKind :: (forall a . SenStatus a (AnyComorphism, BasicProof) -> Bool)
hasSenKind f = not . null . sensWithKind f . dgn_theory
-- | test if a given node label has local open goals
hasOpenGoals :: DGNodeLab -> Bool
hasOpenGoals = hasSenKind (\ s -> not (isAxiom s) && not (isProvenSenStatus s))
-- | check if the node has an internal name
isInternalNode :: DGNodeLab -> Bool
isInternalNode DGNodeLab {dgn_name = n} = isInternal n
getNodeConsStatus :: DGNodeLab -> ConsStatus
getNodeConsStatus lbl = case nodeInfo lbl of
DGRef {} -> mkConsStatus None
DGNode { node_cons_status = c } -> c
getNodeCons :: DGNodeLab -> Conservativity
getNodeCons = getConsOfStatus . getNodeConsStatus
-- | returns the Conservativity if the given node has one, otherwise none
getNodeConservativity :: LNode DGNodeLab -> Conservativity
getNodeConservativity = getNodeCons . snd
{- | test if a node conservativity is open,
return input for refs or nodes with normal forms -}
hasOpenNodeConsStatus :: Bool -> DGNodeLab -> Bool
hasOpenNodeConsStatus b lbl = if isJust $ dgn_nf lbl then b else
hasOpenConsStatus b $ getNodeConsStatus lbl
markNodeConsistency :: Conservativity -> String -> DGNodeLab -> DGNodeLab
markNodeConsistency newc str dgnode = dgnode
{ nodeInfo = case nodeInfo dgnode of
ninfo@DGNode { node_cons_status = ConsStatus c pc thm } ->
if pc == newc && isProvenThmLinkStatus thm then ninfo else
ninfo { node_cons_status = ConsStatus c newc
$ Proven (DGRule $ showConsistency newc ++ str)
markNodeConsistent :: String -> DGNodeLab -> DGNodeLab
markNodeConsistent = markNodeConsistency Cons
markNodeInconsistent :: String -> DGNodeLab -> DGNodeLab
markNodeInconsistent = markNodeConsistency Inconsistent
-- | test if a conservativity is open, return input for None
hasOpenConsStatus :: Bool -> ConsStatus -> Bool
hasOpenConsStatus b (ConsStatus cons _ thm) = case cons of
_ -> not $ isProvenThmLinkStatus thm
data DGNodeType = DGNodeType
, isInternalSpec :: Bool }
-- | creates a DGNodeType from a DGNodeLab
getRealDGNodeType :: DGNodeLab -> DGNodeType
getRealDGNodeType dgnlab = DGNodeType
{ isRefType = isDGRef dgnlab
, isProvenNode = not $ hasOpenGoals dgnlab
, isProvenCons = not $ hasOpenNodeConsStatus False dgnlab
, isInternalSpec = isInternalNode dgnlab }
-- | Creates a list with all DGNodeType types
listDGNodeTypes :: [DGNodeType]
listDGNodeTypes = let bs = [False, True] in
, isProvenNode = isEmpty'
, isInternalSpec = spec }
{- an edge id used to be represented as a list of ints.
the reason of an edge can have multiple ids is, for example, there exists
an proven edge e1 with id 1 and an unproven edge e2 with id 2 between
two nodes. Now after applying some rules e2 is proven, but it's actually
the same as the proven edge e1, then the proven e2 should not be inserted
into the graph again, but e1 will take e2's id 2 because 2 is probably
saved in some other places. As a result, e1 would have 1 and 2 as its id.
This type can be extended to a more complicated struture, like a tree
-- | unique number for edges
newtype EdgeId = EdgeId Int deriving (Show, Eq, Ord, Enum)
-- | the first edge in a graph
showEdgeId :: EdgeId -> String
showEdgeId (EdgeId i) = show i
newtype ProofBasis = ProofBasis { proofBasis ::
Set.Set EdgeId }
-- | a wrapper for fitting morphisms with a trivial Eq instance
newtype Fitted = Fitted [G_mapping] deriving Show
| DGLinkInst SIMPLE_ID Fitted
| DGLinkInstArg SIMPLE_ID
| DGLinkView SIMPLE_ID Fitted
| DGLinkFitView SIMPLE_ID
| DGLinkFitViewImp SIMPLE_ID
| DGLinkRefinement SIMPLE_ID
{- | Rules in the development graph calculus,
Sect. IV:4.4 of the CASL Reference Manual explains them in depth
mutual recursive with 'DGLinkLab', 'DGLinkType', and 'ThmLinkStatus'
| DGRuleWithEdge String (LEdge DGLinkLab)
| DGRuleLocalInference [(String, String)] -- renamed theorems
| Composition [LEdge DGLinkLab]
-- | proof status of a link
data ThmLinkStatus = LeftOpen | Proven DGRule ProofBasis deriving (Show, Eq)
isProvenThmLinkStatus :: ThmLinkStatus -> Bool
isProvenThmLinkStatus tls = case tls of
data Scope = Local | Global deriving (Show, Eq, Ord)
data LinkKind = DefLink | ThmLink ThmLinkStatus deriving (Show, Eq)
data FreeOrCofree = Free | Cofree | NPFree
deriving (Show, Eq, Ord, Enum, Bounded, Read)
fcList = [minBound .. maxBound]
-- | required and proven conservativity (with a proof)
data ConsStatus = ConsStatus Conservativity Conservativity ThmLinkStatus
isProvenConsStatusLink :: ConsStatus -> Bool
isProvenConsStatusLink = not . hasOpenConsStatus False
mkConsStatus :: Conservativity -> ConsStatus
mkConsStatus c = ConsStatus c None LeftOpen
getConsOfStatus :: ConsStatus -> Conservativity
getConsOfStatus (ConsStatus c _ _) = c
-- | to be displayed as edge label
showConsStatus :: ConsStatus -> String
showConsStatus cs = case cs of
ConsStatus None None _ -> ""
ConsStatus None _ LeftOpen -> ""
ConsStatus c _ LeftOpen -> show c ++ "?"
ConsStatus _ cp _ -> show cp
{- | Link types of development graphs,
Sect. IV:4.2 of the CASL Reference Manual explains them in depth. -}
ScopedLink Scope LinkKind ConsStatus
| FreeOrCofreeDefLink FreeOrCofree MaybeNode -- the "parameter" node
| HidingFreeOrCofreeThm (Maybe FreeOrCofree) Node GMorphism ThmLinkStatus
{- DGLink S1 S2 m2 (DGLinkType m1 p) n
corresponds to a span of morphisms
S1 <--m1-- S --m2--> S2 -}
-- | extract theorem link status from link type
thmLinkStatus :: DGLinkType -> Maybe ThmLinkStatus
thmLinkStatus t = case t of
ScopedLink _ (ThmLink s) _ -> Just s
HidingFreeOrCofreeThm _ _ _ s -> Just s
-- | link inscriptions in development graphs
{ dgl_morphism :: GMorphism -- signature morphism of link
, dgl_type :: DGLinkType -- type: local, global, def, thm?
, dgl_origin :: DGLinkOrigin -- origin in input language
, dglPending :: Bool -- open proofs of edges in proof basis
, dgl_id :: EdgeId -- id of the edge
, dglName :: NodeName -- name of the edge
mkDGLink :: GMorphism -> DGLinkType -> DGLinkOrigin -> NodeName -> EdgeId
mkDGLink mor ty orig nn ei = DGLink
nameDGLink :: NodeName -> DGLinkLab -> DGLinkLab
nameDGLink nn l = l { dglName = nn }
defDGLink :: GMorphism -> DGLinkType -> DGLinkOrigin -> DGLinkLab
{- See svn-version 13804 for a naming concept which unfortunately introduced
same names for different links. -}
defDGLink m ty orig = mkDGLink m ty orig (makeName $ mkSimpleId "")
defDGLinkId :: GMorphism -> DGLinkType -> DGLinkOrigin -> EdgeId -> DGLinkLab
defDGLinkId m ty orig ei = (defDGLink m ty orig) { dgl_id = ei }
globDefLink :: GMorphism -> DGLinkOrigin -> DGLinkLab
globDefLink m = defDGLink m globalDef
-- | describe the link type of the label
getDGLinkType :: DGLinkLab -> String
getDGLinkType = getDGEdgeTypeName . getRealDGLinkType
-- | converts a DGEdgeType to a String
getDGEdgeTypeName :: DGEdgeType -> String
(if isInc e then (++ "Inc") else id)
$ getDGEdgeTypeModIncName $ edgeTypeModInc e
revertDGEdgeTypeName :: String -> DGEdgeType
$ find ((== tp) . getDGEdgeTypeName) listDGEdgeTypes
getDGEdgeTypeModIncName :: DGEdgeTypeModInc -> String
getDGEdgeTypeModIncName et = case et of
ThmType thm isPrvn _ _ ->
let prvn = (if isPrvn then "P" else "Unp") ++ "roven" in
HidingThm -> prvn ++ "HidingThm"
FreeOrCofreeThm fc -> prvn ++ shows fc "Thm"
GlobalOrLocalThm scope isHom ->
let het = if isHom then id else ("Het" ++) in
Global -> if isHom then "Global" else "") ++ prvn ++ "Thm"
FreeOrCofreeDef fc -> shows fc "Def"
data DGEdgeType = DGEdgeType
{ edgeTypeModInc :: DGEdgeTypeModInc
| FreeOrCofreeDef FreeOrCofree
| ThmType { thmEdgeType :: ThmTypes
| FreeOrCofreeThm FreeOrCofree
| GlobalOrLocalThm { isLocalThmType :: Scope
getHomEdgeType :: Bool -> Bool -> DGLinkType -> DGEdgeTypeModInc
getHomEdgeType isPend isHom lt = case lt of
ScopedLink scope lk cons -> case lk of
Global -> if isHom then GlobalDef else HetDef
{ thmEdgeType = GlobalOrLocalThm scope isHom
, isProvenEdge = isProvenThmLinkStatus st
, isConservativ = isProvenConsStatusLink cons
, isPending = isPend } -- needs to be checked
HidingDefLink -> HidingDef
FreeOrCofreeDefLink fc _ -> FreeOrCofreeDef fc
HidingFreeOrCofreeThm mh _ _ st -> ThmType
{ thmEdgeType = case mh of
Just fc -> FreeOrCofreeThm fc
, isProvenEdge = isProvenThmLinkStatus st
-- | creates a DGEdgeType from a DGLinkLab
getRealDGLinkType :: DGLinkLab -> DGEdgeType
getRealDGLinkType lnk = let
{ edgeTypeModInc = getHomEdgeType (dglPending lnk) (isHomogeneous gmor)
GMorphism cid _ _ mor _ -> isInclusionComorphism cid && isInclusion mor
-- | Creates a list with all DGEdgeType types
listDGEdgeTypes :: [DGEdgeType]
[ DGEdgeType { edgeTypeModInc = modinc
] ++ [ FreeOrCofreeDef fc | fc <- fcList ] ++
[ ThmType { thmEdgeType = thmType
: [ FreeOrCofreeThm fc | fc <- fcList ] ++
[ GlobalOrLocalThm { isLocalThmType = local
| local <- [Local, Global]
, proven <- [True, False]
, pending <- [True, False]
, isInclusion' <- [True, False]
-- ** types for global environments
-- | import, formal parameters and united signature of formal params
data GenSig = GenSig MaybeNode [NodeSig] MaybeNode deriving Show
data ExtGenSig = ExtGenSig GenSig NodeSig deriving Show
-- | source, morphism, parameterized target
data ExtViewSig = ExtViewSig NodeSig GMorphism ExtGenSig deriving Show
{- ** types for architectural and unit specification analysis
(as defined for basic static semantics in Chap. III:5.1) -}
data UnitSig = UnitSig [NodeSig] NodeSig (Maybe NodeSig) deriving (Show, Eq)
{- Maybe NodeSig stores the union of the parameters
the node is needed for consistency checks -}
data ImpUnitSigOrSig = ImpUnitSig MaybeNode UnitSig | Sig NodeSig
type StUnitCtx =
Map.Map SIMPLE_ID ImpUnitSigOrSig
emptyStUnitCtx :: StUnitCtx
{- data ArchSig = ArchSig StUnitCtx UnitSig deriving Show
this type is superseeded by RefSig -}
type RefSigMap =
Map.Map SIMPLE_ID RefSig
type BStContext =
Map.Map SIMPLE_ID RefSig
-- there should be only BranchRefSigs
data RefSig = BranchRefSig RTPointer (UnitSig, Maybe BranchSig)
| ComponentRefSig RTPointer RefSigMap
instance Show RefSig where
-- made this instance for debugging purposes
show (BranchRefSig _ (usig, mbsig)) =
Just bsig -> case bsig of
else "UnitSigAsBranch:" ++ shows u "\n "
BranchStaticContext bst ->
$ map (\ (n, s) -> shows n " mapped to\n" ++ shows s "\n")
"Branch: \n before refinement:\n " ++ show usig ++
"\n after refinement: \n" ++ bStr ++ "\n"
show (ComponentRefSig _ rsm) =
foldl (++) "CompRefSig:" $ map (\ n -> show n ++ "\n ") $
getPointerFromRef :: RefSig -> RTPointer
getPointerFromRef (BranchRefSig p _) = p
getPointerFromRef (ComponentRefSig p _) = p
setPointerInRef :: RefSig -> RTPointer -> RefSig
setPointerInRef (BranchRefSig _ x) y = BranchRefSig y x
setPointerInRef (ComponentRefSig _ x) y = ComponentRefSig y x
setUnitSigInRef :: RefSig -> UnitSig -> RefSig
setUnitSigInRef (BranchRefSig x (_, y)) usig = BranchRefSig x (usig, y)
setUnitSigInRef _ _ = error "setUnitSigInRef"
getUnitSigFromRef :: RefSig -> Result UnitSig
getUnitSigFromRef (BranchRefSig _ (usig, _)) = return usig
getUnitSigFromRef (ComponentRefSig _ rsm) =
error $ "getUnitSigFromRef:" ++ show (
Map.keys rsm)
mkRefSigFromUnit :: UnitSig -> RefSig
mkRefSigFromUnit usig = BranchRefSig RTNone
(usig, Just $ UnitSigAsBranchSig usig)
mkBotSigFromUnit :: UnitSig -> RefSig
mkBotSigFromUnit usig = BranchRefSig RTNone (usig, Nothing)
data BranchSig = UnitSigAsBranchSig UnitSig
| BranchStaticContext BStContext
type RefStUnitCtx =
Map.Map SIMPLE_ID RefSig
-- only BranchRefSigs allowed
emptyRefStUnitCtx :: RefStUnitCtx
-- Auxiliaries for refinament signatures composition
matchesContext :: RefSigMap -> BStContext -> Bool
matchesContext rsmap bstc =
&& namesMatchCtx (
Map.keys rsmap) bstc rsmap
equalSigs :: UnitSig -> UnitSig -> Bool
equalSigs (UnitSig ls1 ns1 _) (UnitSig ls2 ns2 _) =
length ls1 == length ls2 && getSig ns1 == getSig ns2
&& all (\ (x1, x2) -> getSig x1 == getSig x2) (zip ls1 ls2)
namesMatchCtx :: [SIMPLE_ID] -> BStContext -> RefSigMap -> Bool
namesMatchCtx [] _ _ = True
namesMatchCtx (un : unitNames) bstc rsmap =
BranchRefSig _ (_usig, mbsig) -> case mbsig of
Nothing -> False -- should not be the case
Just bsig -> case bsig of
UnitSigAsBranchSig usig' ->
BranchRefSig _ (usig'', _mbsig') -> equalSigs usig' usig'' &&
namesMatchCtx unitNames bstc rsmap
BranchStaticContext bstc' ->
ComponentRefSig _ rsmap' ->
matchesContext rsmap' bstc' &&
namesMatchCtx unitNames bstc rsmap
{- This is where I introduce something new wrt to the original paper:
if bstc' has only one element
it suffices to have the signature of that element
matching the signature from rsmap' -}
rsmap' =
Map.mapKeys (\ x -> if x == un then un1 else x)
in namesMatchCtx [un1] bstc' rsmap' &&
namesMatchCtx unitNames bstc rsmap
_ -> False -- this should never be the case
modifyCtx :: [SIMPLE_ID] -> RefSigMap -> BStContext -> BStContext
modifyCtx [] _ bstc = bstc
modifyCtx (un : unitNames) rsmap bstc =
BranchRefSig n1 (usig, mbsig) -> case mbsig of
Nothing -> modifyCtx unitNames rsmap bstc -- should not be the case
Just bsig -> case bsig of
UnitSigAsBranchSig usig' ->
BranchRefSig n2 (usig'', bsig'') -> if equalSigs usig' usig'' then
modifyCtx unitNames rsmap $
(usig, bsig'')) bstc -- was usig'
else error "illegal composition"
_ -> modifyCtx unitNames rsmap bstc
BranchStaticContext bstc' ->
ComponentRefSig n2 rsmap' -> modifyCtx unitNames rsmap $
(BranchRefSig (compPointer n1 n2) (usig, Just $
BranchStaticContext $ modifyCtx (
Map.keys rsmap') rsmap' bstc'))
_ -> let f = if
Map.size bstc' == 1 then
(\ x -> if x == un then un1 else x)
bstc'' = modifyCtx [un1] rsmap' bstc'
BranchRefSig RTNone (usig, Just
$ BranchStaticContext bstc'')
in
Map.union f $ modifyCtx unitNames rsmap bstc
_ -> modifyCtx unitNames rsmap bstc -- same as above
refSigComposition :: RefSig -> RefSig -> Result RefSig
refSigComposition (BranchRefSig n1 (usig1, Just (UnitSigAsBranchSig usig2)))
(BranchRefSig n2 (usig3, bsig)) =
if equalSigs usig2 usig3 then
return $ BranchRefSig (compPointer n1 n2) (usig1, bsig)
else fail $ "Signatures: \n" ++ show usig2 ++ "\n and \n " ++ show usig3 ++
refSigComposition _rsig1@(BranchRefSig n1
(usig1, Just (BranchStaticContext bstc)))
_rsig2@(ComponentRefSig n2 rsmap) =
if matchesContext rsmap bstc then
return $ BranchRefSig (compPointer n1 n2)
(usig1, Just $ BranchStaticContext $
else fail ("Signatures do not match:" ++ show (
Map.keys bstc) ++ " "
refSigComposition (ComponentRefSig n1 rsmap1) (ComponentRefSig n2 rsmap2) = do
s <- refSigComposition (rsmap1 Map.! x) (rsmap2 Map.! x)
return $ ComponentRefSig (compPointer n1 n2) unionMap
refSigComposition _rsig1 _rsig2 =
fail "composition of refinement signatures"
-- | an entry of the global environment
type GlobalEnv =
Map.Map SIMPLE_ID GlobalEntry
-- ** change and history types
-- | the edit operations of the DGraph
InsertNode (LNode DGNodeLab)
| DeleteNode (LNode DGNodeLab)
| InsertEdge (LEdge DGLinkLab)
| DeleteEdge (LEdge DGLinkLab)
-- it contains the old label and new label with node
| SetNodeLab DGNodeLab (LNode DGNodeLab)
| HistGroup DGRule ProofHistory
-- datatypes for the refinement tree
data RTNodeType = RTPlain UnitSig | RTRef Node deriving (Eq)
instance Show RTNodeType where
show (RTPlain u) = "RTPlain\n" ++ show u
data RTNodeLab = RTNodeLab
instance Show RTNodeLab where
RTPlain u -> "plain: " ++ show u
-- utility functions for handling refinement tree
addNodeRT :: DGraph -> UnitSig -> String -> (Node, DGraph)
in (n, dg {refTree = insNode (n, l) g})
addSpecNodeRT :: DGraph -> UnitSig -> String -> (Node, DGraph)
addSpecNodeRT dg usig s =
(n, dg') = addNodeRT dg usig s
in (n, dg' {specRoots = f})
updateNodeNameRT :: DGraph -> Node -> String -> DGraph
updateNodeNameRT dg n s =
newL = oldL {rtn_name = s}
updateSigRT :: DGraph -> Node -> UnitSig -> DGraph
newL = oldL {rtn_type = RTPlain usig}
updateNodeNameSpecRT :: DGraph -> Node -> String -> DGraph
updateNodeNameSpecRT dg n s =
let dg' = updateNodeNameRT dg n s
in dg' {specRoots =
Map.insert s n $ specRoots dg}
addSubTree :: DGraph -> Maybe RTLeaves -> RTPointer -> (DGraph, RTPointer)
addSubTree dg Nothing (NPComp h) =
(\ ~(d, NPComp cp) (k, p) -> let
(d', p') = addSubTree d Nothing p
addSubTree dg Nothing p = let
(dg', f) = copySubTree dg s Nothing
addSubTree dg (Just (RTLeaf x)) p = let
(dg', f) = copySubTree dg s $ Just x
addSubTree dg (Just (RTLeaves g)) (NPComp h) =
(\ ~(d, NPComp cp) (k, p) -> let
(d', p') = addSubTree d (Just l) p
addSubTree _ _ _ = error "addSubTree"
copySubTree :: DGraph -> Node -> Maybe Node -> (DGraph,
Map.Map Node Node)
nLab = fromMaybe (error "copyNode") $ lab rTree n
rTree' = insNode (n', nLab) rTree
in copySubTreeN dg {refTree = rTree'} [n] $
Map.fromList [(n, n')]
copySubTreeN :: DGraph -> [Node] ->
Map.Map Node Node
copySubTreeN dg nList pairs =
(dg', pairs') = foldl (copyNode pairsN) (dg, pairs) descs
in copySubTreeN dg' (nub $ nList' ++ map fst descs) pairs'
copyNode :: Node -> (DGraph,
Map.Map Node Node) -> LNode RTLinkLab
copyNode s (dg, nMap) (n, eLab) = let
nLab = fromMaybe (error "copyNode") $ lab rTree n
rTree' = insNode (n', nLab) rTree
addRefEdgeRT :: DGraph -> Node -> Node -> DGraph
(n1, n2, RTLink {rtl_type = RTRefine}) g
in if b then dg {refTree = g'}
else error "addRefEdgeRT"
addEdgesToNodeRT :: DGraph -> [Node] -> Node -> DGraph
addEdgesToNodeRT dg' rnodes n' =
(g', b) = foldl (\ (g0, b0) n0 -> let
(n', n0, RTLink {rtl_type = RTComp}) g0
in if not b then error "addEdgesToNodeRT"
-- datatypes for storing the nodes of the ref tree in the global env
| NPBranch Node (
Map.Map SIMPLE_ID RTPointer)
-- here the leaves can be either NPUnit or NPComp
| NPComp (
Map.Map SIMPLE_ID RTPointer)
{- here the leaves can be NPUnit or NPComp
and roots are needed for inserting edges -}
mapRTNodes ::
Map.Map Node Node -> RTPointer -> RTPointer
NPUnit x -> NPUnit (app f x)
NPRef x y -> NPRef (app f x) (app f y)
NPBranch x g -> NPBranch (app f x) (
Map.map (mapRTNodes f) g)
NPComp g -> NPComp (
Map.map (mapRTNodes f) g)
compPointer :: RTPointer -> RTPointer -> RTPointer
compPointer (NPUnit n1) (NPUnit n2) = NPRef n1 n2
compPointer (NPUnit n1) (NPBranch _ f) = NPBranch n1 f
compPointer (NPUnit n1) (NPRef _ n2) = NPRef n1 n2
compPointer (NPRef n1 _) (NPRef _ n2) = NPRef n1 n2
compPointer (NPRef n1 _) (NPBranch _ f) = NPBranch n1 f
compPointer (NPBranch n1 f1) (NPComp f2) =
compPointer (NPComp f1) (NPComp f2) =
compPointer x y = error $ "compPointer:" ++ show x ++ " " ++ show y
refSource :: RTPointer -> Node
refSource (NPBranch n _) = n
refSource (NPRef n _) = n
refSource x = error ("refSource:" ++ show x)
data RTLeaves = RTLeaf Node | RTLeaves (
Map.Map SIMPLE_ID RTLeaves)
refTarget :: RTPointer -> RTLeaves
refTarget (NPUnit n) = RTLeaf n
refTarget (NPRef _ n) = RTLeaf n
refTarget (NPComp f) = RTLeaves $
Map.map refTarget f
refTarget (NPBranch _ f) = RTLeaves $
Map.map refTarget f
refTarget x = error ("refTarget:" ++ show x)
{- I copied these types from ArchDiagram
to store the diagrams of the arch specs in the dgraph -}
data DiagNodeLab = DiagNode { dn_sig :: NodeSig, dn_desc :: String }
data DiagLinkLab = DiagLink { dl_morphism :: GMorphism, dl_number :: Int }
instance Show DiagLinkLab where
diagGraph ::
Tree.Gr DiagNodeLab DiagLinkLab,
{- | the actual development graph with auxiliary information. A
'G_sign' should be stored in 'sigMap' under its 'gSignSelfIdx'. The
same applies to 'G_morphism' with 'morMap' and 'gMorphismSelfIdx'
resp. 'G_theory' with 'thMap' and 'gTheorySelfIdx'. -}
{ globalAnnos :: GlobalAnnos -- ^ global annos of library
, optLibDefn :: Maybe LIB_DEFN
, globalEnv :: GlobalEnv -- ^ name entities (specs, views) of a library
, dgBody ::
Tree.Gr DGNodeLab DGLinkLab -- ^ actual 'DGraph` tree
, refTree ::
Tree.Gr RTNodeLab RTLinkLab -- ^ the refinement tree
, specRoots ::
Map.Map String Node -- ^ root nodes for named specs
, archSpecDiags ::
Map.Map String Diag
-- ^ dependency diagrams between units
, getNewEdgeId :: EdgeId -- ^ edge counter
, refNodes ::
Map.Map Node (LibName, Node) -- ^ unexpanded 'DGRef's
, allRefNodes ::
Map.Map (LibName, Node) Node -- ^ all DGRef's
, sigMap ::
Map.Map SigId G_sign -- ^ signature map
, thMap ::
Map.Map ThId G_theory -- ^ morphism map
, morMap ::
Map.Map MorId G_morphism -- ^ theory map
, proofHistory :: ProofHistory -- ^ applied proof steps
, redoHistory :: ProofHistory -- ^ undone proofs steps
{ globalAnnos = emptyGlobalAnnos
, getNewEdgeId = startEdgeId
type LibEnv =
Map.Map LibName DGraph
-- | an empty environment
-- ** for node signatures
emptyG_sign :: AnyLogic -> G_sign
emptyG_sign (Logic lid) = G_sign lid (ext_empty_signature lid) startSigId
getMaybeSig :: MaybeNode -> G_sign
getMaybeSig (JustNode ns) = getSig ns
getMaybeSig (EmptyNode l) = emptyG_sign l
getLogic :: MaybeNode -> AnyLogic
getLogic (JustNode ns) = getNodeLogic ns
getLogic (EmptyNode l) = l
getNodeLogic :: NodeSig -> AnyLogic
getNodeLogic (NodeSig _ (G_sign lid _ _)) = Logic lid
emptyNodeName :: NodeName
emptyNodeName = NodeName (mkSimpleId "") "" 0 []
showExt :: NodeName -> String
showExt n = let i = extIndex n in extString n ++ if i == 0 then "" else show i
showName :: NodeName -> String
showName n = let ext = showExt n in
tokStr (getName n) ++ if null ext then ext else "__" ++ ext
makeName :: SIMPLE_ID -> NodeName
makeName n = NodeName n "" 0 [ElemName $ tokStr n]
parseNodeName :: String -> NodeName
parseNodeName s = case splitByList "__" s of
let n = makeName $ mkSimpleId i
(es, sf) = fromMaybe (e, 0) mSf
$ "parseNodeName: malformed NodeName, too many __: "
incBy :: Int -> NodeName -> NodeName
{ extIndex = extIndex n + i
, xpath = case xpath n of
ChildIndex j : r -> ChildIndex (j + i) : r
inc :: NodeName -> NodeName
extName :: String -> NodeName -> NodeName
{ extString = showExt n ++ take 1 s
, xpath = ElemName s : xpath n }
-- ** accessing node label
-- | get the origin of a non-reference node (partial)
dgn_origin :: DGNodeLab -> DGOrigin
dgn_origin = node_origin . nodeInfo
-- | get the referenced library (partial)
dgn_libname :: DGNodeLab -> LibName
dgn_libname = ref_libname . nodeInfo
-- | get the referenced node (partial)
dgn_node :: DGNodeLab -> Node
dgn_node = ref_node . nodeInfo
-- | get the signature of a node's theory (total)
dgn_sign :: DGNodeLab -> G_sign
dgn_sign dn = case dgn_theory dn of
G_theory lid sig ind _ _ -> G_sign lid sig ind
-- | gets the name of a development graph node as a string (total)
getDGNodeName :: DGNodeLab -> String
getDGNodeName = showName . dgn_name
-- | gets the name of a development graph link as a string (total)
getDGLinkName :: DGLinkLab -> String
getDGLinkName = showName . dglName
-- ** creating node content and label
-- | create default content
newNodeInfo :: DGOrigin -> DGNodeInfo
newNodeInfo orig = DGNode
, node_cons_status = mkConsStatus None }
-- | create a reference node part
newRefInfo :: LibName -> Node -> DGNodeInfo
-- | create a new node label
newInfoNodeLab :: NodeName -> DGNodeInfo -> G_theory -> DGNodeLab
newInfoNodeLab name info gTh@(G_theory lid _ _ _ _) = DGNodeLab
, dgn_symbolpathlist = G_symbolmap lid
Map.empty }
-- | create a new node label using 'newNodeInfo' and 'newInfoNodeLab'
newNodeLab :: NodeName -> DGOrigin -> G_theory -> DGNodeLab
newNodeLab name = newInfoNodeLab name . newNodeInfo
-- ** handle the lock of a node
-- | wrapper to access the maybe lock
treatNodeLock :: (MVar () -> a) -> DGNodeLab -> a
treatNodeLock f = maybe (error "MVar not initialised") f . dgn_lock
-- | Tries to acquire the local lock. Return False if already acquired.
tryLockLocal :: DGNodeLab -> IO Bool
tryLockLocal = treatNodeLock $ flip tryPutMVar ()
-- | Releases the local lock.
unlockLocal :: DGNodeLab -> IO ()
unlockLocal = treatNodeLock $ \ lock ->
tryTakeMVar lock >>= maybe (error "Local lock wasn't locked.") return
-- | checks if locking MVar is initialized
hasLock :: DGNodeLab -> Bool
hasLock = isJust . dgn_lock
-- ** handle edge numbers and proof bases
-- | create a default ID which has to be changed when inserting a certain edge.
defaultEdgeId = EdgeId (-1)
emptyProofBasis :: ProofBasis
nullProofBasis :: ProofBasis -> Bool
addEdgeId :: ProofBasis -> EdgeId -> ProofBasis
addEdgeId (ProofBasis s) e = ProofBasis $
Set.insert e s
-- | checks if the given edge is contained in the given proof basis..
roughElem :: LEdge DGLinkLab -> ProofBasis -> Bool
roughElem (_, _, label) =
Set.member (dgl_id label) . proofBasis
-- ** edge label equalities
-- | equality without comparing the edge ids
eqDGLinkLabContent :: DGLinkLab -> DGLinkLab -> Bool
eqDGLinkLabContent l1 l2 = let
in if i1 <= defaultEdgeId || i2 <= defaultEdgeId then
dgl_morphism l1 == dgl_morphism l2
&& dgl_type l1 == dgl_type l2
&& dgl_origin l1 == dgl_origin l2
&& dglName l1 == dglName l2
else let r = eqDGLinkLabContent l1 l2 { dgl_id = defaultEdgeId}
-- | equality comparing ids only
eqDGLinkLabById :: DGLinkLab -> DGLinkLab -> Bool
eqDGLinkLabById l1 l2 = let
in if i1 > defaultEdgeId && i2 > defaultEdgeId then i1 == i2 else
{- these index maps should be global for all libraries,
therefore their contents need to be copied -}
cpIndexMaps :: DGraph -> DGraph -> DGraph
to { sigMap = sigMap from
setSigMapDG ::
Map.Map SigId G_sign -> DGraph -> DGraph
setSigMapDG m dg = dg { sigMap = m }
setThMapDG ::
Map.Map ThId G_theory -> DGraph -> DGraph
setThMapDG m dg = dg { thMap = m }
setMorMapDG ::
Map.Map MorId G_morphism -> DGraph -> DGraph
setMorMapDG m dg = dg { morMap = m }
-- ** looking up in index maps
lookupSigMapDG :: SigId -> DGraph -> Maybe G_sign
lookupThMapDG :: ThId -> DGraph -> Maybe G_theory
lookupMorMapDG :: MorId -> DGraph -> Maybe G_morphism
-- ** getting index maps and their maximal index
getMapAndMaxIndex :: Ord k => k -> (b ->
Map.Map k a) -> b -> (
Map.Map k a, k)
getMapAndMaxIndex c f gctx =
sigMapI :: DGraph -> (
Map.Map SigId G_sign, SigId)
sigMapI = getMapAndMaxIndex startSigId sigMap
thMapI :: DGraph -> (
Map.Map ThId G_theory, ThId)
thMapI = getMapAndMaxIndex startThId thMap
morMapI :: DGraph -> (
Map.Map MorId G_morphism, MorId)
morMapI = getMapAndMaxIndex startMorId morMap
-- ** lookup other graph parts
lookupGlobalEnvDG :: SIMPLE_ID -> DGraph -> Maybe GlobalEntry
lookupGlobalEnvDG sid =
Map.lookup sid . globalEnv
-- | lookup a referenced library and node of a given reference node
lookupInRefNodesDG :: Node -> DGraph -> Maybe (LibName, Node)
-- | lookup a reference node for a given libname and node
lookupInAllRefNodesDG :: DGNodeInfo -> DGraph -> Maybe Node
lookupInAllRefNodesDG ref dg = case ref of
DGRef { ref_libname = libn, ref_node = refn } ->
-- ** lookup nodes by their names or other properties
-- | lookup a node in the graph with a predicate.
lookupNodeWith :: (LNode DGNodeLab -> Bool) -> DGraph -> [LNode DGNodeLab]
lookupNodeWith f dg = filter f $ labNodesDG dg
{- | lookup a node in the graph by its name, using showName
lookupNodeByName :: String -> DGraph -> [LNode DGNodeLab]
lookupNodeByName s dg = lookupNodeWith f dg where
f (_, lbl) = getDGNodeName lbl == s
{- | filters all local nodes in the graph by their names, using showName
to convert nodenames. See also 'lookupNodeByName'. -}
filterLocalNodesByName :: String -> DGraph -> [LNode DGNodeLab]
filterLocalNodesByName s dg = lookupNodeWith f dg where
f (_, lbl) = not (isDGRef lbl) && getDGNodeName lbl == s
{- | filter all ref nodes in the graph by their names, using showName
to convert nodenames. See also 'lookupNodeByName'. -}
filterRefNodesByName :: String -> LibName -> DGraph -> [LNode DGNodeLab]
filterRefNodesByName s ln dg = lookupNodeWith f dg where
f (_, lbl) = case nodeInfo lbl of
DGRef { ref_libname = libn } ->
libn == ln && getDGNodeName lbl == s
{- | Given a 'LibEnv' we search each DGraph in it for a (maybe referenced) node
with the given name. We return the labeled node and the Graph where this node
resides as local node. See also 'lookupLocalNode'. -}
lookupLocalNodeByNameInEnv :: LibEnv -> String
-> Maybe (DGraph, LNode DGNodeLab)
lookupLocalNodeByNameInEnv le s = f $
Map.elems le where
f (dg : l) = case lookupNodeByName s dg of
(nd, _) : _ -> Just $ lookupLocalNode le dg nd
{- | We search only the given 'DGraph' for a (maybe referenced) node with the
given name. We return the labeled node and the Graph where this node resides
as local node. See also 'lookupLocalNode'. -}
lookupLocalNodeByName :: LibEnv -> DGraph -> String
-> Maybe (DGraph, LNode DGNodeLab)
lookupLocalNodeByName le dg s =
case lookupNodeByName s dg of
(nd, _) : _ -> Just $ lookupLocalNode le dg nd
{- | Given a Node and a 'DGraph' we follow the node to the graph where it is
defined as a local node. -}
lookupLocalNode :: LibEnv -> DGraph -> Node -> (DGraph, LNode DGNodeLab)
f dg n = case labDG dg n of
DGNodeLab { nodeInfo = DGRef { ref_libname = ln
f (lookupDGraph ln le) n'
-- ** treat reference nodes
-- | add a new referenced node into the refNodes map of the given DG
addToRefNodesDG :: Node -> DGNodeInfo -> DGraph -> DGraph
addToRefNodesDG n ref dg = case ref of
DGRef { ref_libname = libn, ref_node = refn } ->
dg { refNodes =
Map.insert n (libn, refn) $ refNodes dg
, allRefNodes =
Map.insert (libn, refn) n $ allRefNodes dg }
-- | delete the given referenced node out of the refnodes map
deleteFromRefNodesDG :: Node -> DGraph -> DGraph
deleteFromRefNodesDG n dg = dg { refNodes =
Map.delete n $ refNodes dg }
-- ** accessing the actual graph
-- | get the next available node id
getNewNodeDG :: DGraph -> Node
labNodesDG :: DGraph -> [LNode DGNodeLab]
labNodesDG = labNodes . dgBody
labEdgesDG :: DGraph -> [LEdge DGLinkLab]
labEdgesDG = labEdges . dgBody
-- | checks if a DG is empty or not.
isEmptyDG :: DGraph -> Bool
isEmptyDG = isEmpty . dgBody
-- | checks if a given node belongs to a given DG
gelemDG :: Node -> DGraph -> Bool
gelemDG n = gelem n . dgBody
-- | get all the incoming ledges of the given node in a given DG
innDG :: DGraph -> Node -> [LEdge DGLinkLab]
-- | get all the outgoing ledges of the given node in a given DG
outDG :: DGraph -> Node -> [LEdge DGLinkLab]
-- | get all the nodes of the given DG
nodesDG :: DGraph -> [Node]
-- | tries to get the label of the given node in a given DG
labDG :: DGraph -> Node -> DGNodeLab
labDG dg = fromMaybe (error "labDG") . lab (dgBody dg)
-- | tries to get the label of the given node in a given RT
labRT :: DGraph -> Node -> RTNodeLab
labRT dg = fromMaybe (error "labRT") . lab (refTree dg)
-- | get the name of a node from the number of node
getNameOfNode :: Node -> DGraph -> String
getNameOfNode index gc = getDGNodeName $ labDG gc index
-- | gets the given number of new node-ids in a given DG.
newNodesDG :: Int -> DGraph -> [Node]
newNodesDG n = newNodes n . dgBody
-- | get the context and throw input string as error message
safeContextDG :: String -> DGraph -> Node -> Context DGNodeLab DGLinkLab
safeContextDG s = safeContext s . dgBody where
safeContext err g v = -- same as context with extra message
fromMaybe (error $ err ++ ": Match Exception, Node: " ++ show v)
-- | sets the node with new label and returns the new graph and the old label
labelNodeDG :: LNode DGNodeLab -> DGraph -> (DGraph, DGNodeLab)
-- | delete the node out of the given DG
delNodeDG :: Node -> DGraph -> DGraph
delNodeDG n dg = dg { dgBody = delNode n $ dgBody dg }
-- | delete the LNode out of the given DG
delLNodeDG :: LNode DGNodeLab -> DGraph -> DGraph
delLNodeDG n dg = dg { dgBody =
Tree.delLNode (==) n $ dgBody dg }
-- | delete a list of nodes out of the given DG
delNodesDG :: [Node] -> DGraph -> DGraph
delNodesDG ns dg = dg { dgBody = delNodes ns $ dgBody dg }
-- | insert a new node into given DGraph
insNodeDG :: LNode DGNodeLab -> DGraph -> DGraph
insNodeDG n dg = dg { dgBody = insNode n $ dgBody dg }
-- | inserts a lnode into a given DG
insLNodeDG :: LNode DGNodeLab -> DGraph -> DGraph
if gelemDG v g then error $ "insLNodeDG " ++ show v else insNodeDG n g
-- | insert a new node with the given node content into a given DGraph
insNodesDG :: [LNode DGNodeLab] -> DGraph -> DGraph
insNodesDG ns dg = dg { dgBody = insNodes ns $ dgBody dg }
-- | delete a labeled edge out of the given DG
delLEdgeDG :: LEdge DGLinkLab -> DGraph -> DGraph
-- | inserts an edge between two nodes, labelled with inclusion
insInclEdgeDG :: LogicGraph -> DGraph -> NodeSig -> NodeSig ->
insInclEdgeDG lgraph dg s t = do
incl <- ginclusion lgraph (getSig s) (getSig t)
let l = globDefLink incl DGLinkImports
(_, dg') = insLEdgeDG (getNode s, getNode t, l) dg
-- | insert a labeled edge into a given DG, return possibly new id of edge
insLEdgeDG :: LEdge DGLinkLab -> DGraph -> (LEdge DGLinkLab, DGraph)
newId = eId == defaultEdgeId
e = (s, t, if newId then l { dgl_id = nId } else l)
{ getNewEdgeId = if newId then succ nId else max nId $ succ eId
compareLinks :: DGLinkLab -> DGLinkLab -> Ordering
compareLinks l1 l2 = if eqDGLinkLabContent l1 { dgl_id = defaultEdgeId } l2
then EQ else comparing dgl_id l1 l2
{- | tries to insert a labeled edge into a given DG, but if this edge
already exists, then does nothing. -}
insLEdgeNubDG :: LEdge DGLinkLab -> DGraph -> DGraph
insLEdgeNubDG (v, w, l) g =
let oldEdgeId = getNewEdgeId g
(v, w, l { dgl_id = oldEdgeId }) $ dgBody g
g { getNewEdgeId = if change then succ oldEdgeId else oldEdgeId
{- | inserts a new edge into the DGraph using it's own edgeId.
ATTENTION: the caller must ensure that an edgeId is not used twice -}
insEdgeAsIs :: LEdge DGLinkLab -> DGraph -> DGraph
insEdgeAsIs (v, w, l) g = let
in if ei == defaultEdgeId then error "illegal link id" else
-- | insert a list of labeled edge into a given DG
insEdgesDG :: [LEdge DGLinkLab] -> DGraph -> DGraph
insEdgesDG = flip $ foldr insLEdgeNubDG
-- | merge a list of lnodes and ledges into a given DG
mkGraphDG :: [LNode DGNodeLab] -> [LEdge DGLinkLab] -> DGraph -> DGraph
mkGraphDG ns ls = insEdgesDG ls . insNodesDG ns
-- | get links by id (inefficiently)
getDGLinksById :: EdgeId -> DGraph -> [LEdge DGLinkLab]
getDGLinksById e = filter (\ (_, _, l) -> e == dgl_id l) . labEdgesDG
-- ** top-level functions
-- | initializes the MVar for locking if nessesary
initLocking :: DGraph -> LNode DGNodeLab -> IO (DGraph, DGNodeLab)
initLocking dg (node, dgn) = do
let dgn' = dgn { dgn_lock = Just lock }
return (fst $ labelNodeDG (node, dgn') dg, dgn')
-- | returns the DGraph that belongs to the given library name
lookupDGraph :: LibName -> LibEnv -> DGraph
{- | compute the theory of a given node.
If this node is a DGRef, the referenced node is looked up first. -}
computeLocalTheory :: Monad m => LibEnv -> LibName -> Node -> m G_theory
computeLocalTheory libEnv ln =
computeLocalNodeTheory libEnv $ lookupDGraph ln libEnv
computeLocalNodeTheory :: Monad m => LibEnv -> DGraph -> Node -> m G_theory
computeLocalNodeTheory libEnv dg = computeLocalLabelTheory libEnv . labDG dg
computeLocalLabelTheory :: Monad m => LibEnv -> DGNodeLab -> m G_theory
computeLocalLabelTheory libEnv nodeLab =
computeLocalTheory libEnv (dgn_libname nodeLab) $ dgn_node nodeLab
else return $ dgn_theory nodeLab
liftE :: (DGLinkType -> a) -> LEdge DGLinkLab -> a
liftE f (_, _, edgeLab) = f $ dgl_type edgeLab
liftOr :: (a -> Bool) -> (a -> Bool) -> a -> Bool
liftOr f g x = f x || g x
isGlobalDef :: DGLinkType -> Bool
isGlobalDef lt = case lt of
ScopedLink Global DefLink _ -> True
isLocalDef :: DGLinkType -> Bool
isLocalDef lt = case lt of
ScopedLink Local DefLink _ -> True
isHidingDef :: DGLinkType -> Bool
isHidingDef lt = case lt of
isDefEdge :: DGLinkType -> Bool
isDefEdge edge = case edge of
ScopedLink _ DefLink _ -> True
FreeOrCofreeDefLink _ _ -> True
isLocalEdge :: DGLinkType -> Bool
isLocalEdge edge = case edge of
ScopedLink Local _ _ -> True
isHidingEdge :: DGLinkType -> Bool
isHidingEdge edge = case edge of
HidingFreeOrCofreeThm Nothing _ _ _ -> True
hidingThm :: Node -> GMorphism -> DGLinkType
hidingThm n m = HidingFreeOrCofreeThm Nothing n m LeftOpen
globalThm = localOrGlobalThm Global None
localThm = localOrGlobalThm Local None
globalConsThm :: Conservativity -> DGLinkType
globalConsThm = localOrGlobalThm Global
localConsThm :: Conservativity -> DGLinkType
localConsThm = localOrGlobalThm Local
localOrGlobalThm :: Scope -> Conservativity -> DGLinkType
localOrGlobalThm sc = ScopedLink sc (ThmLink LeftOpen) . mkConsStatus
localOrGlobalDef :: Scope -> Conservativity -> DGLinkType
localOrGlobalDef sc = ScopedLink sc DefLink . mkConsStatus
globalConsDef :: Conservativity -> DGLinkType
globalConsDef = localOrGlobalDef Global
globalDef = localOrGlobalDef Global None
localDef = localOrGlobalDef Local None
-- ** link conservativity
getLinkConsStatus :: DGLinkType -> ConsStatus
getLinkConsStatus lt = case lt of
getEdgeConsStatus :: DGLinkLab -> ConsStatus
getEdgeConsStatus = getLinkConsStatus . dgl_type
getCons :: DGLinkType -> Conservativity
getCons = getConsOfStatus . getLinkConsStatus
-- | returns the Conservativity if the given edge has one, otherwise none
getConservativity :: LEdge DGLinkLab -> Conservativity
getConservativity (_, _, edgeLab) = getConsOfStatus $ getEdgeConsStatus edgeLab
-- | returns the conservativity of the given path
getConservativityOfPath :: [LEdge DGLinkLab] -> Conservativity
getConservativityOfPath path = minimum [getConservativity e | e <- path]
-- | Creates a LibName relation wrt dependencies via reference nodes
getLibDepRel :: LibEnv ->
Rel.Rel LibName
foldr ((\ x -> if isDGRef x then
Set.insert (ln, dgn_libname x) else id)
topsortedLibsWithImports ::
Rel.Rel LibName -> [LibName]
getTopsortedLibs :: LibEnv -> [LibName]
getTopsortedLibs le = let
ls = reverse $ topsortedLibsWithImports rel
{- | Get imported libs in topological order,
i.e. lib(s) without imports first.
The input lib-name will be last -}
dependentLibs :: LibName -> LibEnv -> [LibName]
let rel = getLibDepRel le
ts = topsortedLibsWithImports rel
in reverse $ ln : intersect ts is
topsortedNodes :: DGraph -> [LNode DGNodeLab]
topsortedNodes dgraph = let dg = dgBody dgraph in
reverse $ postorderF $ dffWith (\ (_, n, nl, _) -> (n, nl)) (nodes dg)
$ efilter (\ (s, t, el) -> s /= t && isDefEdge (dgl_type el)) dg
changedPendingEdges :: DGraph -> [LEdge DGLinkLab]
changedPendingEdges dg = let
ls = filter (liftE $ not . isDefEdge) $ labEdgesDG dg
(ms, ps) = foldr (\ (s, t, l) (m, es) ->
Proven _ pb -> proofBasis pb) . thmLinkStatus $ dgl_type l) m
, if b && isLocalEdge (dgl_type l) then
Set.insert e es else es))
in if new == known then new else close new
in filter (\ (_, _, l) -> dglPending l /=
Set.member (dgl_id l) aPs) ls
changedLocalTheorems :: DGraph -> LNode DGNodeLab -> [LEdge DGLinkLab]
changedLocalTheorems dg (v, lbl) =
foldr (\ e@(_, _, el) l ->
in case thmLinkStatus $ dgl_type el of
Just (Proven (DGRuleLocalInference nms) _) | pend
$ filter (liftE $ \ e -> isLocalEdge e && not (isLocalDef e))
duplicateDefEdges :: DGraph -> [Edge]
duplicateDefEdges = concat .
filter (not . isSingle) . group . map (\ (s, t, _) -> (s, t))
. filter (liftE isDefEdge) . labEdgesDG