{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Swish.GraphMatch
( graphMatch,
LabelMap, GenLabelMap(..), LabelEntry, GenLabelEntry(..),
ScopedLabel(..), makeScopedLabel, makeScopedArc,
LabelIndex, EquivalenceClass, nullLabelVal, emptyMap,
labelIsVar, labelHash,
mapLabelIndex, setLabelHash, newLabelMap,
graphLabels, assignLabelMap, newGenerationMap,
graphMatch1, graphMatch2, equivalenceClasses, reclassify
) where
import Swish.GraphClass (Arc(..), ArcSet, Label(..))
import Swish.GraphClass (getComponents, arcLabels, hasLabel, arcToTriple)
import Control.Exception.Base (assert)
import Control.Arrow (second)
import Data.Function (on)
import Data.Hashable (hashWithSalt)
import Data.List (foldl', sortBy, groupBy, partition)
import Data.Ord (comparing)
import Data.Word
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
type LabelIndex = (Word32, Word32)
nullLabelVal :: LabelIndex
nullLabelVal :: LabelIndex
nullLabelVal = (Word32
0, Word32
0)
data (Label lb) => GenLabelEntry lb lv = LabelEntry lb lv
type LabelEntry lb = GenLabelEntry lb LabelIndex
instance (Label lb, Show lv) => Show (GenLabelEntry lb lv) where
show :: GenLabelEntry lb lv -> String
show (LabelEntry lb
k lv
v) = forall a. Show a => a -> String
show lb
k forall a. [a] -> [a] -> [a]
++ String
":" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show lv
v
instance (Label lb, Eq lv) => Eq (GenLabelEntry lb lv) where
(LabelEntry lb
k1 lv
v1) == :: GenLabelEntry lb lv -> GenLabelEntry lb lv -> Bool
== (LabelEntry lb
k2 lv
v2) = (lb
k1,lv
v1) forall a. Eq a => a -> a -> Bool
== (lb
k2,lv
v2)
instance (Label lb, Ord lv) => Ord (GenLabelEntry lb lv) where
(LabelEntry lb
lb1 lv
lv1) compare :: GenLabelEntry lb lv -> GenLabelEntry lb lv -> Ordering
`compare` (LabelEntry lb
lb2 lv
lv2) =
(lb
lb1, lv
lv1) forall a. Ord a => a -> a -> Ordering
`compare` (lb
lb2, lv
lv2)
data (Label lb, Eq lv, Show lv) => GenLabelMap lb lv =
LabelMap Word32 (M.Map lb lv)
type LabelMap lb = GenLabelMap lb LabelIndex
instance (Label lb) => Show (LabelMap lb) where
show :: LabelMap lb -> String
show = forall lb. Label lb => LabelMap lb -> String
showLabelMap
instance (Label lb) => Eq (LabelMap lb) where
LabelMap Word32
gen1 Map lb LabelIndex
lmap1 == :: LabelMap lb -> LabelMap lb -> Bool
== LabelMap Word32
gen2 Map lb LabelIndex
lmap2 =
(Word32
gen1, Map lb LabelIndex
lmap1) forall a. Eq a => a -> a -> Bool
== (Word32
gen2, Map lb LabelIndex
lmap2)
emptyMap :: (Label lb) => LabelMap lb
emptyMap :: forall lb. Label lb => LabelMap lb
emptyMap = forall lb lv. Word32 -> Map lb lv -> GenLabelMap lb lv
LabelMap Word32
1 forall k a. Map k a
M.empty
type EquivalenceClass lb = (LabelIndex, [lb])
ecLabels :: EquivalenceClass lb -> [lb]
ecLabels :: forall lb. EquivalenceClass lb -> [lb]
ecLabels = forall a b. (a, b) -> b
snd
ecRemoveLabel :: (Label lb) => EquivalenceClass lb -> lb -> EquivalenceClass lb
ecRemoveLabel :: forall lb.
Label lb =>
EquivalenceClass lb -> lb -> EquivalenceClass lb
ecRemoveLabel EquivalenceClass lb
xs lb
l = forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second (forall a. Eq a => a -> [a] -> [a]
L.delete lb
l) EquivalenceClass lb
xs
pairUngroup ::
(a,[b])
-> [(a,b)]
pairUngroup :: forall a b. (a, [b]) -> [(a, b)]
pairUngroup (a
a,[b]
bs) = [ (a
a,b
b) | b
b <- [b]
bs ]
pairSort :: (Ord a) => [(a,b)] -> [(a,b)]
pairSort :: forall a b. Ord a => [(a, b)] -> [(a, b)]
pairSort = forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall a b. (a, b) -> a
fst)
pairGroup :: (Ord a) => [(a,b)] -> [(a,[b])]
pairGroup :: forall a b. Ord a => [(a, b)] -> [(a, [b])]
pairGroup = forall a b. (a -> b) -> [a] -> [b]
map (forall {a} {b}. ([a], b) -> (a, b)
factor forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. [(a, b)] -> ([a], [b])
unzip) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy forall {b}. (a, b) -> (a, b) -> Bool
eqFirst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Ord a => [(a, b)] -> [(a, b)]
pairSort
where
factor :: ([a], b) -> (a, b)
factor ([a]
as, b
bs) = (forall a. [a] -> a
head [a]
as, b
bs)
eqFirst :: (a, b) -> (a, b) -> Bool
eqFirst = forall a. Eq a => a -> a -> Bool
(==) forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` forall a b. (a, b) -> a
fst
data (Label lb) => ScopedLabel lb = ScopedLabel Int lb
makeScopedLabel :: (Label lb) => Int -> lb -> ScopedLabel lb
makeScopedLabel :: forall lb. Label lb => Int -> lb -> ScopedLabel lb
makeScopedLabel = forall lb. Int -> lb -> ScopedLabel lb
ScopedLabel
makeScopedArc :: (Label lb) => Int -> Arc lb -> Arc (ScopedLabel lb)
makeScopedArc :: forall lb. Label lb => Int -> Arc lb -> Arc (ScopedLabel lb)
makeScopedArc Int
scope = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall lb. Int -> lb -> ScopedLabel lb
ScopedLabel Int
scope)
instance (Label lb) => Label (ScopedLabel lb) where
getLocal :: ScopedLabel lb -> String
getLocal ScopedLabel lb
lab = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"getLocal for ScopedLabel: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ScopedLabel lb
lab
makeLabel :: String -> ScopedLabel lb
makeLabel String
locnam = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"makeLabel for ScopedLabel: " forall a. [a] -> [a] -> [a]
++ String
locnam
labelIsVar :: ScopedLabel lb -> Bool
labelIsVar (ScopedLabel Int
_ lb
lab) = forall lb. Label lb => lb -> Bool
labelIsVar lb
lab
labelHash :: Int -> ScopedLabel lb -> Int
labelHash Int
seed (ScopedLabel Int
scope lb
lab)
| forall lb. Label lb => lb -> Bool
labelIsVar lb
lab = Int
seed forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
scope
| Bool
otherwise = forall lb. Label lb => Int -> lb -> Int
labelHash Int
seed lb
lab
instance (Label lb) => Eq (ScopedLabel lb) where
(ScopedLabel Int
s1 lb
l1) == :: ScopedLabel lb -> ScopedLabel lb -> Bool
== (ScopedLabel Int
s2 lb
l2)
= lb
l1 forall a. Eq a => a -> a -> Bool
== lb
l2 Bool -> Bool -> Bool
&& Int
s1 forall a. Eq a => a -> a -> Bool
== Int
s2
instance (Label lb) => Show (ScopedLabel lb) where
show :: ScopedLabel lb -> String
show (ScopedLabel Int
s1 lb
l1) = forall a. Show a => a -> String
show Int
s1 forall a. [a] -> [a] -> [a]
++ String
":" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show lb
l1
instance (Label lb) => Ord (ScopedLabel lb) where
compare :: ScopedLabel lb -> ScopedLabel lb -> Ordering
compare (ScopedLabel Int
s1 lb
l1) (ScopedLabel Int
s2 lb
l2) =
case forall a. Ord a => a -> a -> Ordering
compare Int
s1 Int
s2 of
Ordering
LT -> Ordering
LT
Ordering
EQ -> forall a. Ord a => a -> a -> Ordering
compare lb
l1 lb
l2
Ordering
GT -> Ordering
GT
graphMatch :: (Label lb) =>
(lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> (Bool, LabelMap (ScopedLabel lb))
graphMatch :: forall lb.
Label lb =>
(lb -> lb -> Bool)
-> ArcSet lb -> ArcSet lb -> (Bool, LabelMap (ScopedLabel lb))
graphMatch lb -> lb -> Bool
matchable ArcSet lb
gs1 ArcSet lb
gs2 =
let
sgs1 :: Set (Arc (ScopedLabel lb))
sgs1 = forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map (forall lb. Label lb => Int -> Arc lb -> Arc (ScopedLabel lb)
makeScopedArc Int
1) ArcSet lb
gs1
sgs2 :: Set (Arc (ScopedLabel lb))
sgs2 = forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map (forall lb. Label lb => Int -> Arc lb -> Arc (ScopedLabel lb)
makeScopedArc Int
2) ArcSet lb
gs2
ls1 :: Set (ScopedLabel lb)
ls1 = forall lb. Label lb => ArcSet lb -> Set lb
graphLabels Set (Arc (ScopedLabel lb))
sgs1
ls2 :: Set (ScopedLabel lb)
ls2 = forall lb. Label lb => ArcSet lb -> Set lb
graphLabels Set (Arc (ScopedLabel lb))
sgs2
lmap :: LabelMap (ScopedLabel lb)
lmap =
forall lb. Label lb => LabelMap lb -> LabelMap lb
newGenerationMap forall a b. (a -> b) -> a -> b
$
forall lb. Label lb => Set lb -> LabelMap lb -> LabelMap lb
assignLabelMap Set (ScopedLabel lb)
ls1 forall a b. (a -> b) -> a -> b
$
forall lb. Label lb => Set lb -> LabelMap lb -> LabelMap lb
assignLabelMap Set (ScopedLabel lb)
ls2 forall lb. Label lb => LabelMap lb
emptyMap
ec1 :: [EquivalenceClass (ScopedLabel lb)]
ec1 = forall lb.
Label lb =>
LabelMap lb -> Set lb -> [EquivalenceClass lb]
equivalenceClasses LabelMap (ScopedLabel lb)
lmap Set (ScopedLabel lb)
ls1
ec2 :: [EquivalenceClass (ScopedLabel lb)]
ec2 = forall lb.
Label lb =>
LabelMap lb -> Set lb -> [EquivalenceClass lb]
equivalenceClasses LabelMap (ScopedLabel lb)
lmap Set (ScopedLabel lb)
ls2
ecpairs :: [(EquivalenceClass (ScopedLabel lb),
EquivalenceClass (ScopedLabel lb))]
ecpairs = forall a b. [a] -> [b] -> [(a, b)]
zip (forall a b. Ord a => [(a, b)] -> [(a, b)]
pairSort [EquivalenceClass (ScopedLabel lb)]
ec1) (forall a b. Ord a => [(a, b)] -> [(a, b)]
pairSort [EquivalenceClass (ScopedLabel lb)]
ec2)
matchableScoped :: ScopedLabel lb -> ScopedLabel lb -> Bool
matchableScoped (ScopedLabel Int
_ lb
l1) (ScopedLabel Int
_ lb
l2) = lb -> lb -> Bool
matchable lb
l1 lb
l2
match :: (Bool, LabelMap (ScopedLabel lb))
match = forall lb.
Label lb =>
Bool
-> (lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (Bool, LabelMap lb)
graphMatch1 Bool
False ScopedLabel lb -> ScopedLabel lb -> Bool
matchableScoped Set (Arc (ScopedLabel lb))
sgs1 Set (Arc (ScopedLabel lb))
sgs2 LabelMap (ScopedLabel lb)
lmap [(EquivalenceClass (ScopedLabel lb),
EquivalenceClass (ScopedLabel lb))]
ecpairs
in
if forall (t :: * -> *) a. Foldable t => t a -> Int
length [EquivalenceClass (ScopedLabel lb)]
ec1 forall a. Eq a => a -> a -> Bool
/= forall (t :: * -> *) a. Foldable t => t a -> Int
length [EquivalenceClass (ScopedLabel lb)]
ec2 then (Bool
False,forall lb. Label lb => LabelMap lb
emptyMap) else (Bool, LabelMap (ScopedLabel lb))
match
graphMatch1 ::
(Label lb)
=> Bool
-> (lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb,EquivalenceClass lb)]
-> (Bool,LabelMap lb)
graphMatch1 :: forall lb.
Label lb =>
Bool
-> (lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (Bool, LabelMap lb)
graphMatch1 Bool
guessed lb -> lb -> Bool
matchable ArcSet lb
gs1 ArcSet lb
gs2 LabelMap lb
lmap [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs =
let
([(EquivalenceClass lb, EquivalenceClass lb)]
secs,[(EquivalenceClass lb, EquivalenceClass lb)]
mecs) = forall a. (a -> Bool) -> [a] -> ([a], [a])
partition forall {a} {a} {a} {a}. ((a, [a]), (a, [a])) -> Bool
uniqueEc [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs
uniqueEc :: ((a, [a]), (a, [a])) -> Bool
uniqueEc ( (a
_,[a
_]) , (a
_,[a
_]) ) = Bool
True
uniqueEc ( (a, [a])
_ , (a, [a])
_ ) = Bool
False
doMatch :: ((a, [lb]), (a, [lb])) -> Bool
doMatch ( (a
_,[lb
l1]) , (a
_,[lb
l2]) ) = forall lb.
Label lb =>
(lb -> lb -> Bool) -> LabelMap lb -> lb -> lb -> Bool
labelMatch lb -> lb -> Bool
matchable LabelMap lb
lmap lb
l1 lb
l2
doMatch ((a, [lb]), (a, [lb]))
x = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"doMatch failue: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ((a, [lb]), (a, [lb]))
x
ecEqSize :: ((a, t a), (a, t a)) -> Bool
ecEqSize ( (a
_,t a
ls1) , (a
_,t a
ls2) ) = forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
ls1 forall a. Eq a => a -> a -> Bool
== forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
ls2
eSize :: ((a, t a), b) -> Int
eSize ( (a
_,t a
ls1) , b
_ ) = forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
ls1
ecCompareSize :: ((a, [a]), b) -> ((a, [a]), b) -> Ordering
ecCompareSize = forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing forall {t :: * -> *} {a} {a} {b}.
Foldable t =>
((a, t a), b) -> Int
eSize
(LabelMap lb
lmap',[(EquivalenceClass lb, EquivalenceClass lb)]
mecs',Bool
newEc,Bool
matchEc) = forall lb.
Label lb =>
ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (LabelMap lb, [(EquivalenceClass lb, EquivalenceClass lb)],
Bool, Bool)
reclassify ArcSet lb
gs1 ArcSet lb
gs2 LabelMap lb
lmap [(EquivalenceClass lb, EquivalenceClass lb)]
mecs
match2 :: (Bool, LabelMap lb)
match2 = forall lb.
Label lb =>
(lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (Bool, LabelMap lb)
graphMatch2 lb -> lb -> Bool
matchable ArcSet lb
gs1 ArcSet lb
gs2 LabelMap lb
lmap forall a b. (a -> b) -> a -> b
$ forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy forall {a} {a} {b}. ((a, [a]), b) -> ((a, [a]), b) -> Ordering
ecCompareSize [(EquivalenceClass lb, EquivalenceClass lb)]
mecs
in
if Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all forall {a} {a}. (Show a, Show a) => ((a, [lb]), (a, [lb])) -> Bool
doMatch [(EquivalenceClass lb, EquivalenceClass lb)]
secs then (Bool
False,LabelMap lb
lmap)
else
if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(EquivalenceClass lb, EquivalenceClass lb)]
mecs then (forall lb.
Label lb =>
LabelMap lb -> ArcSet lb -> ArcSet lb -> Bool
graphMapEq LabelMap lb
lmap ArcSet lb
gs1 ArcSet lb
gs2,LabelMap lb
lmap)
else
if Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all forall {t :: * -> *} {t :: * -> *} {a} {a} {a} {a}.
(Foldable t, Foldable t) =>
((a, t a), (a, t a)) -> Bool
ecEqSize [(EquivalenceClass lb, EquivalenceClass lb)]
mecs) Bool -> Bool -> Bool
|| Bool -> Bool
not Bool
matchEc
then (Bool
False, LabelMap lb
lmap)
else if Bool
newEc
then forall lb.
Label lb =>
Bool
-> (lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (Bool, LabelMap lb)
graphMatch1 Bool
guessed lb -> lb -> Bool
matchable ArcSet lb
gs1 ArcSet lb
gs2 LabelMap lb
lmap' [(EquivalenceClass lb, EquivalenceClass lb)]
mecs'
else if forall a b. (a, b) -> a
fst (Bool, LabelMap lb)
match2 then (Bool, LabelMap lb)
match2 else (Bool
False, LabelMap lb
lmap)
graphMatch2 :: (Label lb) => (lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb,EquivalenceClass lb)]
-> (Bool,LabelMap lb)
graphMatch2 :: forall lb.
Label lb =>
(lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (Bool, LabelMap lb)
graphMatch2 lb -> lb -> Bool
_ ArcSet lb
_ ArcSet lb
_ LabelMap lb
_ [] = forall a. HasCallStack => String -> a
error String
"graphMatch2 sent an empty list"
graphMatch2 lb -> lb -> Bool
matchable ArcSet lb
gs1 ArcSet lb
gs2 LabelMap lb
lmap ((ec1 :: EquivalenceClass lb
ec1@(LabelIndex
ev1,[lb]
ls1),ec2 :: EquivalenceClass lb
ec2@(LabelIndex
ev2,[lb]
ls2)):[(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs) =
let
v1 :: Word32
v1 = forall a b. (a, b) -> b
snd LabelIndex
ev1
try :: [(lb, lb)] -> (Bool, LabelMap lb)
try [] = (Bool
False,LabelMap lb
lmap)
try ((lb
l1,lb
l2):[(lb, lb)]
lps) = if (Bool, LabelMap lb) -> lb -> lb -> Bool
isEquiv (Bool, LabelMap lb)
try1 lb
l1 lb
l2 then (Bool, LabelMap lb)
try1 else [(lb, lb)] -> (Bool, LabelMap lb)
try [(lb, lb)]
lps
where
try1 :: (Bool, LabelMap lb)
try1 = forall lb.
Label lb =>
Bool
-> (lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (Bool, LabelMap lb)
graphMatch1 Bool
True lb -> lb -> Bool
matchable ArcSet lb
gs1 ArcSet lb
gs2 LabelMap lb
lmap' [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs'
lmap' :: LabelMap lb
lmap' = forall lb. Label lb => LabelMap lb -> [(lb, Word32)] -> LabelMap lb
newLabelMap LabelMap lb
lmap [(lb
l1,Word32
v1),(lb
l2,Word32
v1)]
ecpairs' :: [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs' = ((LabelIndex
ev',[lb
l1]),(LabelIndex
ev',[lb
l2]))forall a. a -> [a] -> [a]
:(EquivalenceClass lb, EquivalenceClass lb)
ec'forall a. a -> [a] -> [a]
:[(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs
ev' :: LabelIndex
ev' = forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
lmap' lb
l1
ec' :: (EquivalenceClass lb, EquivalenceClass lb)
ec' = (forall lb.
Label lb =>
EquivalenceClass lb -> lb -> EquivalenceClass lb
ecRemoveLabel EquivalenceClass lb
ec1 lb
l1, forall lb.
Label lb =>
EquivalenceClass lb -> lb -> EquivalenceClass lb
ecRemoveLabel EquivalenceClass lb
ec2 lb
l2)
isEquiv :: (Bool, LabelMap lb) -> lb -> lb -> Bool
isEquiv (Bool
False,LabelMap lb
_) lb
_ lb
_ = Bool
False
isEquiv (Bool
True,LabelMap lb
lm) lb
x1 lb
x2 =
forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
m1 lb
x1 forall a. Eq a => a -> a -> Bool
== forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
m2 lb
x2
where
m1 :: LabelMap lb
m1 = forall lb.
Label lb =>
ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
remapLabels ArcSet lb
gs1 LabelMap lb
lm [lb
x1]
m2 :: LabelMap lb
m2 = forall lb.
Label lb =>
ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
remapLabels ArcSet lb
gs2 LabelMap lb
lm [lb
x2]
glp :: [(lb, lb)]
glp = [ (lb
l1,lb
l2) | lb
l1 <- [lb]
ls1 , lb
l2 <- [lb]
ls2 , lb -> lb -> Bool
matchable lb
l1 lb
l2 ]
in
forall a. HasCallStack => Bool -> a -> a
assert (LabelIndex
ev1 forall a. Eq a => a -> a -> Bool
== LabelIndex
ev2)
forall a b. (a -> b) -> a -> b
$ [(lb, lb)] -> (Bool, LabelMap lb)
try [(lb, lb)]
glp
hashModulus :: Int
hashModulus :: Int
hashModulus = Int
16000001
showLabelMap :: (Label lb) => LabelMap lb -> String
showLabelMap :: forall lb. Label lb => LabelMap lb -> String
showLabelMap (LabelMap Word32
gn Map lb LabelIndex
lmap) =
String
"LabelMap gen=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
Prelude.show Word32
gn forall a. [a] -> [a] -> [a]
++ String
", map=" forall a. [a] -> [a] -> [a]
++
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' forall a. [a] -> [a] -> [a]
(++) String
"" (forall a b. (a -> b) -> [a] -> [b]
map ((String
"\n " forall a. [a] -> [a] -> [a]
++) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
Prelude.show) [(lb, LabelIndex)]
es)
where
es :: [(lb, LabelIndex)]
es = forall k a. Map k a -> [(k, a)]
M.toList Map lb LabelIndex
lmap
mapLabelIndex :: (Label lb) => LabelMap lb -> lb -> LabelIndex
mapLabelIndex :: forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex (LabelMap Word32
_ Map lb LabelIndex
lxms) lb
lb = forall k a. Ord k => a -> k -> Map k a -> a
M.findWithDefault LabelIndex
nullLabelVal lb
lb Map lb LabelIndex
lxms
labelMatch :: (Label lb)
=> (lb -> lb -> Bool) -> LabelMap lb -> lb -> lb -> Bool
labelMatch :: forall lb.
Label lb =>
(lb -> lb -> Bool) -> LabelMap lb -> lb -> lb -> Bool
labelMatch lb -> lb -> Bool
matchable LabelMap lb
lmap lb
l1 lb
l2 =
lb -> lb -> Bool
matchable lb
l1 lb
l2 Bool -> Bool -> Bool
&& (forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
lmap lb
l1 forall a. Eq a => a -> a -> Bool
== forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
lmap lb
l2)
newLabelMap :: (Label lb) => LabelMap lb -> [(lb, Word32)] -> LabelMap lb
newLabelMap :: forall lb. Label lb => LabelMap lb -> [(lb, Word32)] -> LabelMap lb
newLabelMap LabelMap lb
lmap [] = forall lb. Label lb => LabelMap lb -> LabelMap lb
newGenerationMap LabelMap lb
lmap
newLabelMap LabelMap lb
lmap ((lb, Word32)
lv:[(lb, Word32)]
lvs) = forall lb. Label lb => LabelMap lb -> (lb, Word32) -> LabelMap lb
setLabelHash (forall lb. Label lb => LabelMap lb -> [(lb, Word32)] -> LabelMap lb
newLabelMap LabelMap lb
lmap [(lb, Word32)]
lvs) (lb, Word32)
lv
setLabelHash :: (Label lb)
=> LabelMap lb -> (lb, Word32) -> LabelMap lb
setLabelHash :: forall lb. Label lb => LabelMap lb -> (lb, Word32) -> LabelMap lb
setLabelHash (LabelMap Word32
g Map lb LabelIndex
lmap) (lb
lb,Word32
lh) =
forall lb lv. Word32 -> Map lb lv -> GenLabelMap lb lv
LabelMap Word32
g forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert lb
lb (Word32
g,Word32
lh) Map lb LabelIndex
lmap
newGenerationMap :: (Label lb) => LabelMap lb -> LabelMap lb
newGenerationMap :: forall lb. Label lb => LabelMap lb -> LabelMap lb
newGenerationMap (LabelMap Word32
g Map lb LabelIndex
lvs) = forall lb lv. Word32 -> Map lb lv -> GenLabelMap lb lv
LabelMap (Word32
g forall a. Num a => a -> a -> a
+ Word32
1) Map lb LabelIndex
lvs
assignLabelMap :: (Label lb) => S.Set lb -> LabelMap lb -> LabelMap lb
assignLabelMap :: forall lb. Label lb => Set lb -> LabelMap lb -> LabelMap lb
assignLabelMap Set lb
ns LabelMap lb
lmap = forall a b. (a -> b -> a) -> a -> Set b -> a
S.foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall lb. Label lb => lb -> LabelMap lb -> LabelMap lb
assignLabelMap1) LabelMap lb
lmap Set lb
ns
assignLabelMap1 :: (Label lb) => lb -> LabelMap lb -> LabelMap lb
assignLabelMap1 :: forall lb. Label lb => lb -> LabelMap lb -> LabelMap lb
assignLabelMap1 lb
lab (LabelMap Word32
g Map lb LabelIndex
lvs) =
forall lb lv. Word32 -> Map lb lv -> GenLabelMap lb lv
LabelMap Word32
g forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
M.insertWith (forall a b. a -> b -> a
const forall a. a -> a
id) lb
lab (Word32
g, forall lb. Label lb => lb -> Word32
initVal lb
lab) Map lb LabelIndex
lvs
initVal :: (Label lb) => lb -> Word32
initVal :: forall lb. Label lb => lb -> Word32
initVal = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall lb. Label lb => Word32 -> lb -> Int
hashVal Word32
0
hashVal :: (Label lb) => Word32 -> lb -> Int
hashVal :: forall lb. Label lb => Word32 -> lb -> Int
hashVal Word32
seed lb
lab =
if forall lb. Label lb => lb -> Bool
labelIsVar lb
lab then Int
23 forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Word32
seed else forall lb. Label lb => Int -> lb -> Int
labelHash (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
seed) lb
lab
equivalenceClasses ::
(Label lb)
=> LabelMap lb
-> S.Set lb
-> [EquivalenceClass lb]
equivalenceClasses :: forall lb.
Label lb =>
LabelMap lb -> Set lb -> [EquivalenceClass lb]
equivalenceClasses LabelMap lb
lmap Set lb
ls =
forall a b. Ord a => [(a, b)] -> [(a, [b])]
pairGroup forall a b. (a -> b) -> a -> b
$ forall a. Set a -> [a]
S.toList forall a b. (a -> b) -> a -> b
$ forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map lb -> (LabelIndex, lb)
labelPair Set lb
ls
where
labelPair :: lb -> (LabelIndex, lb)
labelPair lb
l = (forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
lmap lb
l,lb
l)
reclassify ::
(Label lb)
=> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb,EquivalenceClass lb)]
-> (LabelMap lb,[(EquivalenceClass lb,EquivalenceClass lb)],Bool,Bool)
reclassify :: forall lb.
Label lb =>
ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (LabelMap lb, [(EquivalenceClass lb, EquivalenceClass lb)],
Bool, Bool)
reclassify ArcSet lb
gs1 ArcSet lb
gs2 lmap :: LabelMap lb
lmap@(LabelMap Word32
_ Map lb LabelIndex
lm) [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs =
forall a. HasCallStack => Bool -> a -> a
assert (Word32
gen1 forall a. Eq a => a -> a -> Bool
== Word32
gen2)
(forall lb lv. Word32 -> Map lb lv -> GenLabelMap lb lv
LabelMap Word32
gen1 Map lb LabelIndex
lm',[(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs',Bool
newPart,Bool
matchPart)
where
LabelMap Word32
gen1 Map lb LabelIndex
lm1 =
forall lb.
Label lb =>
ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
remapLabels ArcSet lb
gs1 LabelMap lb
lmap forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 forall a. [a] -> [a] -> [a]
(++) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall lb. EquivalenceClass lb -> [lb]
ecLabels forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs
LabelMap Word32
gen2 Map lb LabelIndex
lm2 =
forall lb.
Label lb =>
ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
remapLabels ArcSet lb
gs2 LabelMap lb
lmap forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 forall a. [a] -> [a] -> [a]
(++) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall lb. EquivalenceClass lb -> [lb]
ecLabels forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs
lm' :: Map lb LabelIndex
lm' = forall a b. Ord a => Map a b -> Map a b -> Map a b
classifyCombine Map lb LabelIndex
lm forall a b. (a -> b) -> a -> b
$ forall a b. Ord a => Map a b -> Map a b -> Map a b
M.union Map lb LabelIndex
lm1 Map lb LabelIndex
lm2
tmap :: (t -> b) -> (t, t) -> (b, b)
tmap t -> b
f (t
a,t
b) = (t -> b
f t
a, t -> b
f t
b)
ecGroups :: [([EquivalenceClass lb], [EquivalenceClass lb])]
ecGroups = forall a b. (a -> b) -> [a] -> [b]
map (forall {t} {b}. (t -> b) -> (t, t) -> (b, b)
tmap forall {a}. (a, [lb]) -> [EquivalenceClass lb]
remapEc) [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs
ecpairs' :: [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs' = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a b. [a] -> [b] -> [(a, b)]
zip) [([EquivalenceClass lb], [EquivalenceClass lb])]
ecGroups
newPart :: Bool
newPart = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any forall {a} {a}. (Ord a, Ord a, Num a, Num a) => (a, a) -> Bool
pairG1 [(Int, Int)]
lenGroups
matchPart :: Bool
matchPart = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int, Int) -> Bool
pairEq [(Int, Int)]
lenGroups
lenGroups :: [(Int, Int)]
lenGroups = forall a b. (a -> b) -> [a] -> [b]
map (forall {t} {b}. (t -> b) -> (t, t) -> (b, b)
tmap forall (t :: * -> *) a. Foldable t => t a -> Int
length) [([EquivalenceClass lb], [EquivalenceClass lb])]
ecGroups
pairEq :: (Int, Int) -> Bool
pairEq = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a. Eq a => a -> a -> Bool
(==)
pairG1 :: (a, a) -> Bool
pairG1 (a
p1,a
p2) = a
p1 forall a. Ord a => a -> a -> Bool
> a
1 Bool -> Bool -> Bool
|| a
p2 forall a. Ord a => a -> a -> Bool
> a
1
remapEc :: (a, [lb]) -> [EquivalenceClass lb]
remapEc = forall a b. Ord a => [(a, b)] -> [(a, [b])]
pairGroup forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall {b} {a}.
Ord b =>
Map b LabelIndex -> (a, b) -> (LabelIndex, b)
newIndex Map lb LabelIndex
lm') forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, [b]) -> [(a, b)]
pairUngroup
newIndex :: Map b LabelIndex -> (a, b) -> (LabelIndex, b)
newIndex Map b LabelIndex
x (a
_,b
lab) = (forall k a. Ord k => a -> k -> Map k a -> a
M.findWithDefault LabelIndex
nullLabelVal b
lab Map b LabelIndex
x,b
lab)
classifyCombine :: (Ord a) => M.Map a b -> M.Map a b -> M.Map a b
classifyCombine :: forall a b. Ord a => Map a b -> Map a b -> Map a b
classifyCombine = forall k a b c.
Ord k =>
(k -> a -> b -> Maybe c)
-> (Map k a -> Map k c)
-> (Map k b -> Map k c)
-> Map k a
-> Map k b
-> Map k c
M.mergeWithKey (\a
_ b
_ b
v -> forall a. a -> Maybe a
Just b
v) forall a. a -> a
id (forall a b. a -> b -> a
const forall k a. Map k a
M.empty)
remapLabels ::
(Label lb)
=> ArcSet lb
-> LabelMap lb
-> [lb]
-> LabelMap lb
remapLabels :: forall lb.
Label lb =>
ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
remapLabels ArcSet lb
gs lmap :: LabelMap lb
lmap@(LabelMap Word32
gen Map lb LabelIndex
_) [lb]
ls =
forall lb lv. Word32 -> Map lb lv -> GenLabelMap lb lv
LabelMap Word32
gen' forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(lb, LabelIndex)]
newEntries
where
gen' :: Word32
gen' = Word32
gen forall a. Num a => a -> a -> a
+ Word32
1
newEntries :: [(lb, LabelIndex)]
newEntries = [ (lb
l, (Word32
gen', forall a b. (Integral a, Num b) => a -> b
fromIntegral (lb -> Int
newIndex lb
l))) | lb
l <- [lb]
ls ]
newIndex :: lb -> Int
newIndex lb
l
| forall lb. Label lb => lb -> Bool
labelIsVar lb
l = lb -> Int
mapAdjacent lb
l
| Bool
otherwise = forall lb. Label lb => Word32 -> lb -> Int
hashVal Word32
gen lb
l
mapAdjacent :: lb -> Int
mapAdjacent lb
l = Int
hashModulus forall a. Hashable a => Int -> a -> Int
`hashWithSalt` forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (lb -> [Int]
sigsOver lb
l)
gls :: [Arc lb]
gls = forall a. Set a -> [a]
S.toList ArcSet lb
gs
sigsOver :: lb -> [Int]
sigsOver lb
l = forall a b. (a -> Bool) -> [a] -> [b] -> [b]
select (forall lb. Eq lb => lb -> Arc lb -> Bool
hasLabel lb
l) [Arc lb]
gls (forall lb. Label lb => LabelMap lb -> [Arc lb] -> [Int]
arcSignatures LabelMap lb
lmap [Arc lb]
gls)
select :: ( a -> Bool ) -> [a] -> [b] -> [b]
select :: forall a b. (a -> Bool) -> [a] -> [b] -> [b]
select a -> Bool
_ [] [] = []
select a -> Bool
f (a
e1:[a]
l1) (b
e2:[b]
l2)
| a -> Bool
f a
e1 = b
e2 forall a. a -> [a] -> [a]
: forall a b. (a -> Bool) -> [a] -> [b] -> [b]
select a -> Bool
f [a]
l1 [b]
l2
| Bool
otherwise = forall a b. (a -> Bool) -> [a] -> [b] -> [b]
select a -> Bool
f [a]
l1 [b]
l2
select a -> Bool
_ [a]
_ [b]
_ = forall a. HasCallStack => String -> a
error String
"select supplied with different length lists"
graphLabels :: (Label lb) => ArcSet lb -> S.Set lb
graphLabels :: forall lb. Label lb => ArcSet lb -> Set lb
graphLabels = forall b a. Ord b => (a -> [b]) -> Set a -> Set b
getComponents forall lb. Arc lb -> [lb]
arcLabels
arcSignatures ::
(Label lb)
=> LabelMap lb
-> [Arc lb]
-> [Int]
arcSignatures :: forall lb. Label lb => LabelMap lb -> [Arc lb] -> [Int]
arcSignatures LabelMap lb
lmap =
forall a b. (a -> b) -> [a] -> [b]
map ((lb, lb, lb) -> Int
sigCalc forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall lb. Arc lb -> (lb, lb, lb)
arcToTriple)
where
sigCalc :: (lb, lb, lb) -> Int
sigCalc (lb
s,lb
p,lb
o) =
Int
hashModulus forall a. Hashable a => Int -> a -> Int
`hashWithSalt`
( lb -> Word32
labelVal2 lb
s forall a. Num a => a -> a -> a
+
lb -> Word32
labelVal2 lb
p forall a. Num a => a -> a -> a
* Word32
3 forall a. Num a => a -> a -> a
+
lb -> Word32
labelVal2 lb
o forall a. Num a => a -> a -> a
* Word32
5 )
labelVal :: lb -> LabelIndex
labelVal = forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
lmap
labelVal2 :: lb -> Word32
labelVal2 = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a. Num a => a -> a -> a
(*) forall b c a. (b -> c) -> (a -> b) -> a -> c
. lb -> LabelIndex
labelVal
graphMap ::
(Label lb)
=> LabelMap lb
-> ArcSet lb
-> ArcSet LabelIndex
graphMap :: forall lb.
Label lb =>
LabelMap lb -> ArcSet lb -> ArcSet LabelIndex
graphMap = forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex
graphMapEq ::
(Label lb)
=> LabelMap lb
-> ArcSet lb
-> ArcSet lb
-> Bool
graphMapEq :: forall lb.
Label lb =>
LabelMap lb -> ArcSet lb -> ArcSet lb -> Bool
graphMapEq LabelMap lb
lmap = forall a. Eq a => a -> a -> Bool
(==) forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` forall lb.
Label lb =>
LabelMap lb -> ArcSet lb -> ArcSet LabelIndex
graphMap LabelMap lb
lmap