module Analysis.CriticalPairs
( CriticalPairType (..),
CriticalPair (..),
getCriticalPairMatches,
getCriticalPairComatches,
getNacIndexOfCriticalPair,
getNacMatchOfCriticalPair,
getCriticalPairType,
findCriticalPairs,
findPotentialCriticalPairs,
namedCriticalPairs,
findAllDeleteUse,
findAllProduceForbid,
findAllProduceDangling,
findAllDeleteUseAndProduceDangling
) where
import Abstract.AdhesiveHLR as RW
import Abstract.DPO as RW hiding (calculateComatch)
import Analysis.DiagramAlgorithms
import Analysis.EpimorphicPairs
import Data.Maybe (mapMaybe)
data CriticalPairType =
FreeOverlap
| DeleteUse
| ProduceForbid
| ProduceDangling
deriving(Eq,Show)
type NamedRule m = (String, Production m)
type NamedCriticalPairs m = (String,String,[CriticalPair m])
data CriticalPair m = CriticalPair {
matches :: (m, m),
comatches :: Maybe (m, m),
nacMatch :: Maybe (m, Int),
cpType :: CriticalPairType
} deriving (Eq,Show)
getCriticalPairMatches :: CriticalPair m -> (m, m)
getCriticalPairMatches = matches
getCriticalPairComatches :: CriticalPair m -> Maybe (m, m)
getCriticalPairComatches = comatches
getCriticalPairType :: CriticalPair m -> CriticalPairType
getCriticalPairType = cpType
getNacMatchOfCriticalPair :: CriticalPair m -> Maybe m
getNacMatchOfCriticalPair criticalPair =
case nacMatch criticalPair of
Just (nac,_) -> Just nac
Nothing -> Nothing
getNacIndexOfCriticalPair :: CriticalPair m -> Maybe Int
getNacIndexOfCriticalPair criticalPair =
case nacMatch criticalPair of
Just (_,idx) -> Just idx
Nothing -> Nothing
namedCriticalPairs :: (EpiPairs m, DPO m) => MorphismsConfig -> [NamedRule m] -> [NamedCriticalPairs m]
namedCriticalPairs conf namedRules =
map (uncurry getCPs) [(a,b) | a <- namedRules, b <- namedRules]
where
getCPs (n1,r1) (n2,r2) =
(n1, n2, findCriticalPairs conf r1 r2)
findPotentialCriticalPairs :: (DPO m, EpiPairs m) => MorphismsConfig -> Production m -> Production m -> [(m, m)]
findPotentialCriticalPairs conf p1 p2 = satisfyingPairs
where
pairs = createJointlyEpimorphicPairsFromCodomains (matchRestriction conf) (getLHS p1) (getLHS p2)
satisfyingPairs = filter (\(m1,m2) -> satisfyRewritingConditions conf (p1,m1) (p2,m2)) pairs
findCriticalPairs :: (EpiPairs m, DPO m) => MorphismsConfig -> Production m -> Production m -> [CriticalPair m]
findCriticalPairs conf p1 p2 =
findAllDeleteUseAndProduceDangling conf p1 p2 ++ findAllProduceForbid conf p1 p2
findAllDeleteUse :: (EpiPairs m, DPO m) => MorphismsConfig -> Production m -> Production m -> [CriticalPair m]
findAllDeleteUse conf p1 p2 =
map (\m -> CriticalPair m Nothing Nothing DeleteUse) deleteUsePairs
where
satisfyingPairs = findPotentialCriticalPairs conf p1 p2
deleteUsePairs = filter (isDeleteUse conf p1) satisfyingPairs
findAllProduceDangling :: (EpiPairs m, DPO m) => MorphismsConfig -> Production m -> Production m -> [CriticalPair m]
findAllProduceDangling conf p1 p2 =
map (\m -> CriticalPair m Nothing Nothing ProduceDangling) produceDanglingPairs
where
satisfyingPairs = findPotentialCriticalPairs conf p1 p2
produceDanglingPairs = filter (isProduceDangling conf p1 p2) satisfyingPairs
findAllDeleteUseAndProduceDangling :: (EpiPairs m, DPO m) => MorphismsConfig -> Production m -> Production m -> [CriticalPair m]
findAllDeleteUseAndProduceDangling conf p1 p2 =
map categorizeConflict conflicts
where
gluing = findPotentialCriticalPairs conf p1 p2
conflicts = mapMaybe (deleteUseDangling conf p1 p2) gluing
categorizeConflict x = case x of
(Left m) -> CriticalPair m Nothing Nothing DeleteUse
(Right m) -> CriticalPair m Nothing Nothing ProduceDangling
findAllProduceForbid :: (EpiPairs m, DPO m) => MorphismsConfig -> Production m -> Production m -> [CriticalPair m]
findAllProduceForbid conf p1 p2 =
concatMap (findProduceForbidForNAC conf p1 p2) (zip (getNACs p2) [0..])
findProduceForbidForNAC :: (EpiPairs m, DPO m) => MorphismsConfig -> Production m -> Production m -> (m, Int) -> [CriticalPair m]
findProduceForbidForNAC conf p1 p2 nac =
map
(\(m,m',nac) -> CriticalPair m (Just m') (Just nac) ProduceForbid)
(produceForbidOneNac conf p1 p2 nac)