{-# LANGUAGE FlexibleInstances #-}
module TypedGraph.DPO.GraphRule (
GraphRule
, getLHS
, getRHS
, getNACs
, invertProductionWithoutNacs
, deletedNodes
, deletedEdges
, createdNodes
, createdEdges
, preservedNodes
, preservedEdges
, emptyGraphRule
, nullGraphRule
, buildGraphRule
, checkDeletion
) where
import Abstract.DPO as DPO
import Abstract.Morphism as M
import Graph.Graph as G
import qualified Graph.GraphMorphism as GM
import TypedGraph.Graph as GM
import TypedGraph.Morphism as TGM
type GraphRule a b = Production (TypedGraphMorphism a b)
deletedNodes :: GraphRule a b -> [G.NodeId]
deletedNodes r = TGM.orphanTypedNodeIds (getLHS r)
createdNodes :: GraphRule a b -> [G.NodeId]
createdNodes r = TGM.orphanTypedNodeIds (getRHS r)
deletedEdges :: GraphRule a b -> [G.EdgeId]
deletedEdges r = TGM.orphanTypedEdgeIds (getLHS r)
createdEdges :: GraphRule a b -> [G.EdgeId]
createdEdges = TGM.orphanTypedEdgeIds . getRHS
preservedNodes :: GraphRule a b -> [G.NodeId]
preservedNodes = nodeIdsFromDomain . getLHS
preservedEdges :: GraphRule a b -> [G.EdgeId]
preservedEdges = edgeIdsFromDomain . getLHS
emptyGraphRule :: Graph (Maybe a) (Maybe b) -> Production (TypedGraphMorphism a b)
emptyGraphRule typegraph = emptyRule
where
emptyGraph = empty
emptyGM = GM.empty emptyGraph typegraph
emptyTGM = idMap emptyGM emptyGM
emptyRule = buildProduction emptyTGM emptyTGM []
type ListOfNodesAndEdges = ([(Int,Int)],[(Int,Int,Int,Int)])
buildGraphRule :: Graph (Maybe a) (Maybe b) -> ListOfNodesAndEdges -> ListOfNodesAndEdges -> ListOfNodesAndEdges -> [ListOfNodesAndEdges] -> Production (TypedGraphMorphism a b)
buildGraphRule typegraph deleted created (preservedNodes, preservedEdges) nacs = resultingRule
where
preservedGraph = build (map fst preservedNodes) (map (\(e,s,t,_) -> (e,s,t)) preservedEdges)
preservedTypeGraph = GM.buildGraphMorphism preservedGraph typegraph preservedNodes (map (\(e,_,_,t) -> (e,t)) preservedEdges)
leftAndRightPreserved = M.id preservedTypeGraph
addCreated = addElementsOnCodomain leftAndRightPreserved created
addDeleted = addElementsOnCodomain leftAndRightPreserved deleted
idLeft = M.id (codomain addDeleted)
resultingNacs = map (addElementsOnCodomain idLeft) nacs
resultingRule = buildProduction addDeleted addCreated resultingNacs
addElementsOnCodomain init (nodes,edges) = addEdges
where
addNodes = foldr (\(n,t) -> TGM.createNodeOnCodomain (NodeId n) (NodeId t)) init nodes
addEdges = foldr (\(e,s,t,tp) -> TGM.createEdgeOnCodomain (EdgeId e) (NodeId s) (NodeId t) (EdgeId tp)) addNodes edges
nullGraphRule :: GraphRule a b -> Bool
nullGraphRule rule = null l && null k && null r
where
null = G.null . untypedGraph
l = codomain $ getLHS rule
k = domain $ getLHS rule
r = codomain $ getRHS rule
instance DPO (TypedGraphMorphism a b) where
invertProduction conf rule =
buildProduction (getRHS rule) (getLHS rule) (concatMap (shiftNacOverProduction conf rule) (getNACs rule))
shiftNacOverProduction conf rule nac = [calculateComatch nac rule | satisfiesGluingConditions conf rule nac]
isPartiallyMonomorphic = isPartialInjective