module XML.ParseSndOrderRule (
parseSndOrderRules
, getLeftObjNameMapping
, getRightObjNameMapping
, getObjectNacNameMorphism
, getObjectNacNameMorphismNodes
, getObjectNacNameMorphismEdges
, getObjectNameMorphism
) where
import Abstract.Morphism
import Data.Char (toLower)
import Data.List (find, groupBy, sortBy, sortOn, (\\))
import Data.Maybe (fromMaybe, mapMaybe)
import Data.String.Utils (join, split)
import Graph.Graph
import Graph.GraphMorphism as GM
import TypedGraph.Morphism as TGM
import XML.ParsedTypes
getLeftObjNameMapping :: SndOrderRuleSide -> SndOrderRuleSide -> [Mapping]
getLeftObjNameMapping (_,_,((_,left,_,_),_)) (_,_,((_,right,_,_),_)) = getObjNameMapping left right
getRightObjNameMapping :: SndOrderRuleSide -> SndOrderRuleSide -> [Mapping]
getRightObjNameMapping (_,_,((_,_,left,_),_)) (_,_,((_,_,right,_),_)) = getObjNameMapping left right
getObjNameMapping :: ParsedTypedGraph -> ParsedTypedGraph -> [Mapping]
getObjNameMapping (_,nodesL,edgesL) (_,nodesR,edgesR) = mapNodes ++ mapEdges
where
f id (Just n) = Just (id,n)
f _ _ = Nothing
fNodes (id,m,_) = f id m
fEdges (id,m,_,_,_) = f id m
nodesLMap = mapMaybe fNodes nodesL
nodesRMap = mapMaybe fNodes nodesR
edgesLMap = mapMaybe fEdges edgesL
edgesRMap = mapMaybe fEdges edgesR
getMap f = mapMaybe
(\(id,n) ->
case find (\(_,b) -> n == b) f of
Just (x,_) -> Just (x, Nothing, id)
_ -> Nothing)
nonMono = concatMap
(\(id,objName) ->
map
(\name -> (id,name))
(split "|" objName)
)
mapNodes = getMap (nonMono nodesRMap) nodesLMap
mapEdges = getMap (nonMono edgesRMap) edgesLMap
parseSndOrderRules :: [RuleWithNacs] -> [(SndOrderRuleSide,SndOrderRuleSide,[SndOrderRuleSide])]
parseSndOrderRules = groupRules . map getSndOrderRuleSide
getSndOrderRuleSide :: RuleWithNacs -> SndOrderRuleSide
getSndOrderRuleSide rule@((name,_,_,_),_) = (side, ruleName, rule)
where
splitted = split "_" name
side = if length splitted < 3
then error "Error parsing 2rule name"
else map toLower $ splitted !! 1
ruleName = join "_" (tail (tail splitted))
groupRules :: [SndOrderRuleSide] -> [(SndOrderRuleSide,SndOrderRuleSide,[SndOrderRuleSide])]
groupRules rules =
map
(\list ->
let left = getLeft list
right = getRight list
remainList = list \\ [left,right]
in (left,right,remainList)
) grouped
where
side (x,_,_) = x
name (_,x,_) = x
sorted = sortOn name rules
grouped = groupBy (\x y -> name x == name y) sorted
getLeft list = fromMaybe (error "Second order rule without left") (findSide "left" list)
getRight list = fromMaybe (error "Second order rule without right") (findSide "right" list)
findSide str = find (\x -> side x == str)
getObjectNacNameMorph :: GraphMorphism a b -> ([Mapping], [Mapping])
getObjectNacNameMorph m = (nodesMap m, edgesMap m)
where
adjustNonMono = parseNonMonoObjNames . group . sort
nodesMap = adjustNonMono . getMap GM.applyNodeUnsafe . nodeIds . domain
edgesMap = adjustNonMono . getMap GM.applyEdgeUnsafe . edgeIds . domain
getMap f = map (\e -> (show (f m e), Nothing, show e))
group = groupBy (\(x,_,_) (y,_,_) -> x == y)
sort = sortBy (\(x,_,_) (y,_,_) -> compare x y)
getObjectNacNameMorphism :: GraphMorphism a b -> [Mapping]
getObjectNacNameMorphism m = nods ++ edgs
where
(nods,edgs) = getObjectNacNameMorph m
getObjectNacNameMorphismNodes :: GraphMorphism a b -> [Mapping]
getObjectNacNameMorphismNodes m = fst (getObjectNacNameMorph m)
getObjectNacNameMorphismEdges :: GraphMorphism a b -> [Mapping]
getObjectNacNameMorphismEdges m = snd (getObjectNacNameMorph m)
parseNonMonoObjNames :: [[Mapping]] -> [Mapping]
parseNonMonoObjNames [] = []
parseNonMonoObjNames (x:xs) = (a,b,newObjName) : parseNonMonoObjNames xs
where
(a,b,_) = head x
allObjNames = map (\(_,_,y) -> y) x
newObjName = join "|" allObjNames
getObjectNameMorphism :: TypedGraphMorphism a b -> TypedGraphMorphism a b -> [Mapping]
getObjectNameMorphism left right = nodesMap ++ edgesMap
where
nodesMap = getMap TGM.applyNodeUnsafe (nodeIdsFromDomain left)
edgesMap = getMap TGM.applyEdgeUnsafe (edgeIdsFromDomain left)
getMap f = map (\e -> (show (f right e), Nothing, show (f left e)))