{-# 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 qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
import Control.Exception.Base (assert)
import Control.Arrow (second)
import Data.Foldable (Foldable(..))
import Data.Function (on)
import Data.Hashable (hashWithSalt)
import Data.List (sortBy, groupBy, partition)
import Data.Ord (comparing)
import Data.Word
import Prelude hiding (Foldable(..))
import Swish.GraphClass (Arc(..), ArcSet, Label(..))
import Swish.GraphClass (getComponents, arcLabels, hasLabel, arcToTriple)
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) = lb -> String
forall a. Show a => a -> String
show lb
k String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
":" String -> ShowS
forall a. [a] -> [a] -> [a]
++ lv -> String
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) (lb, lv) -> (lb, lv) -> Bool
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) (lb, lv) -> (lb, lv) -> Ordering
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 = LabelMap lb -> String
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) (Word32, Map lb LabelIndex) -> (Word32, Map lb LabelIndex) -> Bool
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 = Word32 -> Map lb LabelIndex -> GenLabelMap lb LabelIndex
forall lb lv.
(Label lb, Eq lv, Show lv) =>
Word32 -> Map lb lv -> GenLabelMap lb lv
LabelMap Word32
1 Map lb LabelIndex
forall k a. Map k a
M.empty
type EquivalenceClass lb = (LabelIndex, [lb])
ecLabels :: EquivalenceClass lb -> [lb]
ecLabels :: forall lb. EquivalenceClass lb -> [lb]
ecLabels = (LabelIndex, [lb]) -> [lb]
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 = ([lb] -> [lb]) -> EquivalenceClass lb -> EquivalenceClass lb
forall b c d. (b -> c) -> (d, b) -> (d, c)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second (lb -> [lb] -> [lb]
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 = ((a, b) -> (a, b) -> Ordering) -> [(a, b)] -> [(a, b)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((a, b) -> a) -> (a, b) -> (a, b) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (a, b) -> a
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 = ([(a, b)] -> (a, [b])) -> [[(a, b)]] -> [(a, [b])]
forall a b. (a -> b) -> [a] -> [b]
map (([a], [b]) -> (a, [b])
forall {a} {b}. ([a], b) -> (a, b)
factor (([a], [b]) -> (a, [b]))
-> ([(a, b)] -> ([a], [b])) -> [(a, b)] -> (a, [b])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(a, b)] -> ([a], [b])
forall a b. [(a, b)] -> ([a], [b])
unzip) ([[(a, b)]] -> [(a, [b])])
-> ([(a, b)] -> [[(a, b)]]) -> [(a, b)] -> [(a, [b])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, b) -> (a, b) -> Bool) -> [(a, b)] -> [[(a, b)]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (a, b) -> (a, b) -> Bool
forall {b}. (a, b) -> (a, b) -> Bool
eqFirst ([(a, b)] -> [[(a, b)]])
-> ([(a, b)] -> [(a, b)]) -> [(a, b)] -> [[(a, b)]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(a, b)] -> [(a, b)]
forall a b. Ord a => [(a, b)] -> [(a, b)]
pairSort
where
factor :: ([a], b) -> (a, b)
factor ([], b
_) = String -> (a, b)
forall a. HasCallStack => String -> a
error String
"internal error"
factor (a
a:[a]
_, b
bs) = (a
a, b
bs)
eqFirst :: (a, b) -> (a, b) -> Bool
eqFirst = a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==) (a -> a -> Bool) -> ((a, b) -> a) -> (a, b) -> (a, b) -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (a, b) -> a
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 = Int -> lb -> ScopedLabel lb
forall lb. Label 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 = (lb -> ScopedLabel lb) -> Arc lb -> Arc (ScopedLabel lb)
forall a b. (a -> b) -> Arc a -> Arc b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> lb -> ScopedLabel lb
forall lb. Label lb => Int -> lb -> ScopedLabel lb
ScopedLabel Int
scope)
instance (Label lb) => Label (ScopedLabel lb) where
getLocal :: ScopedLabel lb -> String
getLocal ScopedLabel lb
lab = ShowS
forall a. HasCallStack => String -> a
error ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String
"getLocal for ScopedLabel: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ScopedLabel lb -> String
forall a. Show a => a -> String
show ScopedLabel lb
lab
makeLabel :: String -> ScopedLabel lb
makeLabel String
locnam = String -> ScopedLabel lb
forall a. HasCallStack => String -> a
error (String -> ScopedLabel lb) -> String -> ScopedLabel lb
forall a b. (a -> b) -> a -> b
$ String
"makeLabel for ScopedLabel: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
locnam
labelIsVar :: ScopedLabel lb -> Bool
labelIsVar (ScopedLabel Int
_ lb
lab) = lb -> Bool
forall lb. Label lb => lb -> Bool
labelIsVar lb
lab
labelHash :: Int -> ScopedLabel lb -> Int
labelHash Int
seed (ScopedLabel Int
scope lb
lab)
| lb -> Bool
forall lb. Label lb => lb -> Bool
labelIsVar lb
lab = Int
seed Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Int
scope
| Bool
otherwise = Int -> lb -> Int
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 lb -> lb -> Bool
forall a. Eq a => a -> a -> Bool
== lb
l2 Bool -> Bool -> Bool
&& Int
s1 Int -> Int -> Bool
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) = Int -> String
forall a. Show a => a -> String
show Int
s1 String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
":" String -> ShowS
forall a. [a] -> [a] -> [a]
++ lb -> String
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 Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
s1 Int
s2 of
Ordering
LT -> Ordering
LT
Ordering
EQ -> lb -> lb -> Ordering
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 = (Arc lb -> Arc (ScopedLabel lb))
-> ArcSet lb -> Set (Arc (ScopedLabel lb))
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map (Int -> Arc lb -> Arc (ScopedLabel lb)
forall lb. Label lb => Int -> Arc lb -> Arc (ScopedLabel lb)
makeScopedArc Int
1) ArcSet lb
gs1
sgs2 :: Set (Arc (ScopedLabel lb))
sgs2 = (Arc lb -> Arc (ScopedLabel lb))
-> ArcSet lb -> Set (Arc (ScopedLabel lb))
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map (Int -> Arc lb -> Arc (ScopedLabel lb)
forall lb. Label lb => Int -> Arc lb -> Arc (ScopedLabel lb)
makeScopedArc Int
2) ArcSet lb
gs2
ls1 :: Set (ScopedLabel lb)
ls1 = Set (Arc (ScopedLabel lb)) -> Set (ScopedLabel lb)
forall lb. Label lb => ArcSet lb -> Set lb
graphLabels Set (Arc (ScopedLabel lb))
sgs1
ls2 :: Set (ScopedLabel lb)
ls2 = Set (Arc (ScopedLabel lb)) -> Set (ScopedLabel lb)
forall lb. Label lb => ArcSet lb -> Set lb
graphLabels Set (Arc (ScopedLabel lb))
sgs2
lmap :: LabelMap (ScopedLabel lb)
lmap =
LabelMap (ScopedLabel lb) -> LabelMap (ScopedLabel lb)
forall lb. Label lb => LabelMap lb -> LabelMap lb
newGenerationMap (LabelMap (ScopedLabel lb) -> LabelMap (ScopedLabel lb))
-> LabelMap (ScopedLabel lb) -> LabelMap (ScopedLabel lb)
forall a b. (a -> b) -> a -> b
$
Set (ScopedLabel lb)
-> LabelMap (ScopedLabel lb) -> LabelMap (ScopedLabel lb)
forall lb. Label lb => Set lb -> LabelMap lb -> LabelMap lb
assignLabelMap Set (ScopedLabel lb)
ls1 (LabelMap (ScopedLabel lb) -> LabelMap (ScopedLabel lb))
-> LabelMap (ScopedLabel lb) -> LabelMap (ScopedLabel lb)
forall a b. (a -> b) -> a -> b
$
Set (ScopedLabel lb)
-> LabelMap (ScopedLabel lb) -> LabelMap (ScopedLabel lb)
forall lb. Label lb => Set lb -> LabelMap lb -> LabelMap lb
assignLabelMap Set (ScopedLabel lb)
ls2 LabelMap (ScopedLabel lb)
forall lb. Label lb => LabelMap lb
emptyMap
ec1 :: [EquivalenceClass (ScopedLabel lb)]
ec1 = LabelMap (ScopedLabel lb)
-> Set (ScopedLabel lb) -> [EquivalenceClass (ScopedLabel lb)]
forall lb.
Label lb =>
LabelMap lb -> Set lb -> [EquivalenceClass lb]
equivalenceClasses LabelMap (ScopedLabel lb)
lmap Set (ScopedLabel lb)
ls1
ec2 :: [EquivalenceClass (ScopedLabel lb)]
ec2 = LabelMap (ScopedLabel lb)
-> Set (ScopedLabel lb) -> [EquivalenceClass (ScopedLabel lb)]
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 = [EquivalenceClass (ScopedLabel lb)]
-> [EquivalenceClass (ScopedLabel lb)]
-> [(EquivalenceClass (ScopedLabel lb),
EquivalenceClass (ScopedLabel lb))]
forall a b. [a] -> [b] -> [(a, b)]
zip ([EquivalenceClass (ScopedLabel lb)]
-> [EquivalenceClass (ScopedLabel lb)]
forall a b. Ord a => [(a, b)] -> [(a, b)]
pairSort [EquivalenceClass (ScopedLabel lb)]
ec1) ([EquivalenceClass (ScopedLabel lb)]
-> [EquivalenceClass (ScopedLabel lb)]
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 = Bool
-> (ScopedLabel lb -> ScopedLabel lb -> Bool)
-> Set (Arc (ScopedLabel lb))
-> Set (Arc (ScopedLabel lb))
-> LabelMap (ScopedLabel lb)
-> [(EquivalenceClass (ScopedLabel lb),
EquivalenceClass (ScopedLabel lb))]
-> (Bool, LabelMap (ScopedLabel lb))
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 [EquivalenceClass (ScopedLabel lb)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EquivalenceClass (ScopedLabel lb)]
ec1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [EquivalenceClass (ScopedLabel lb)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [EquivalenceClass (ScopedLabel lb)]
ec2 then (Bool
False,LabelMap (ScopedLabel lb)
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) = ((EquivalenceClass lb, EquivalenceClass lb) -> Bool)
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> ([(EquivalenceClass lb, EquivalenceClass lb)],
[(EquivalenceClass lb, EquivalenceClass lb)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (EquivalenceClass lb, EquivalenceClass lb) -> Bool
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]) ) = (lb -> lb -> Bool) -> LabelMap lb -> lb -> lb -> Bool
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 = String -> Bool
forall a. HasCallStack => String -> a
error (String -> Bool) -> String -> Bool
forall a b. (a -> b) -> a -> b
$ String
"doMatch failue: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ((a, [lb]), (a, [lb])) -> String
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) ) = t a -> Int
forall a. t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
ls1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== t a -> Int
forall a. t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
ls2
eSize :: ((a, t a), b) -> Int
eSize ( (a
_,t a
ls1) , b
_ ) = t a -> Int
forall a. t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
ls1
ecCompareSize :: ((a, [a]), b) -> ((a, [a]), b) -> Ordering
ecCompareSize = (((a, [a]), b) -> Int)
-> ((a, [a]), b) -> ((a, [a]), b) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing ((a, [a]), b) -> Int
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) = ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (LabelMap lb, [(EquivalenceClass lb, EquivalenceClass lb)],
Bool, Bool)
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 = (lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (Bool, LabelMap lb)
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 ([(EquivalenceClass lb, EquivalenceClass lb)]
-> (Bool, LabelMap lb))
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (Bool, LabelMap lb)
forall a b. (a -> b) -> a -> b
$ ((EquivalenceClass lb, EquivalenceClass lb)
-> (EquivalenceClass lb, EquivalenceClass lb) -> Ordering)
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> [(EquivalenceClass lb, EquivalenceClass lb)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (EquivalenceClass lb, EquivalenceClass lb)
-> (EquivalenceClass lb, EquivalenceClass lb) -> Ordering
forall {a} {a} {b}. ((a, [a]), b) -> ((a, [a]), b) -> Ordering
ecCompareSize [(EquivalenceClass lb, EquivalenceClass lb)]
mecs
in
if Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ ((EquivalenceClass lb, EquivalenceClass lb) -> Bool)
-> [(EquivalenceClass lb, EquivalenceClass lb)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (EquivalenceClass lb, EquivalenceClass lb) -> Bool
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 [(EquivalenceClass lb, EquivalenceClass lb)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(EquivalenceClass lb, EquivalenceClass lb)]
mecs then (LabelMap lb -> ArcSet lb -> ArcSet lb -> Bool
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 (((EquivalenceClass lb, EquivalenceClass lb) -> Bool)
-> [(EquivalenceClass lb, EquivalenceClass lb)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (EquivalenceClass lb, EquivalenceClass lb) -> Bool
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 Bool
-> (lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (Bool, LabelMap lb)
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 (Bool, LabelMap lb) -> Bool
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
_ [] = String -> (Bool, 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 = LabelIndex -> Word32
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 = Bool
-> (lb -> lb -> Bool)
-> ArcSet lb
-> ArcSet lb
-> LabelMap lb
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> (Bool, LabelMap lb)
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' = LabelMap lb -> [(lb, Word32)] -> LabelMap lb
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]))(EquivalenceClass lb, EquivalenceClass lb)
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> [(EquivalenceClass lb, EquivalenceClass lb)]
forall a. a -> [a] -> [a]
:(EquivalenceClass lb, EquivalenceClass lb)
ec'(EquivalenceClass lb, EquivalenceClass lb)
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> [(EquivalenceClass lb, EquivalenceClass lb)]
forall a. a -> [a] -> [a]
:[(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs
ev' :: LabelIndex
ev' = LabelMap lb -> lb -> LabelIndex
forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
lmap' lb
l1
ec' :: (EquivalenceClass lb, EquivalenceClass lb)
ec' = (EquivalenceClass lb -> lb -> EquivalenceClass lb
forall lb.
Label lb =>
EquivalenceClass lb -> lb -> EquivalenceClass lb
ecRemoveLabel EquivalenceClass lb
ec1 lb
l1, EquivalenceClass lb -> lb -> EquivalenceClass lb
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 =
LabelMap lb -> lb -> LabelIndex
forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
m1 lb
x1 LabelIndex -> LabelIndex -> Bool
forall a. Eq a => a -> a -> Bool
== LabelMap lb -> lb -> LabelIndex
forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
m2 lb
x2
where
m1 :: LabelMap lb
m1 = ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
forall lb.
Label lb =>
ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
remapLabels ArcSet lb
gs1 LabelMap lb
lm [lb
x1]
m2 :: LabelMap lb
m2 = ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
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
Bool -> (Bool, LabelMap lb) -> (Bool, LabelMap lb)
forall a. HasCallStack => Bool -> a -> a
assert (LabelIndex
ev1 LabelIndex -> LabelIndex -> Bool
forall a. Eq a => a -> a -> Bool
== LabelIndex
ev2)
((Bool, LabelMap lb) -> (Bool, LabelMap lb))
-> (Bool, LabelMap lb) -> (Bool, LabelMap lb)
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=" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word32 -> String
forall a. Show a => a -> String
Prelude.show Word32
gn String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", map=" String -> ShowS
forall a. [a] -> [a] -> [a]
++
(String -> ShowS) -> String -> [String] -> String
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' String -> ShowS
forall a. [a] -> [a] -> [a]
(++) String
"" (((lb, LabelIndex) -> String) -> [(lb, LabelIndex)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ((String
"\n " String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> ((lb, LabelIndex) -> String) -> (lb, LabelIndex) -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (lb, LabelIndex) -> String
forall a. Show a => a -> String
Prelude.show) [(lb, LabelIndex)]
es)
where
es :: [(lb, LabelIndex)]
es = Map lb LabelIndex -> [(lb, LabelIndex)]
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 = LabelIndex -> lb -> Map lb LabelIndex -> LabelIndex
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
&& (LabelMap lb -> lb -> LabelIndex
forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
lmap lb
l1 LabelIndex -> LabelIndex -> Bool
forall a. Eq a => a -> a -> Bool
== LabelMap lb -> lb -> LabelIndex
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 [] = LabelMap lb -> LabelMap lb
forall lb. Label lb => LabelMap lb -> LabelMap lb
newGenerationMap LabelMap lb
lmap
newLabelMap LabelMap lb
lmap ((lb, Word32)
lv:[(lb, Word32)]
lvs) = LabelMap lb -> (lb, Word32) -> LabelMap lb
forall lb. Label lb => LabelMap lb -> (lb, Word32) -> LabelMap lb
setLabelHash (LabelMap lb -> [(lb, Word32)] -> LabelMap lb
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) =
Word32 -> Map lb LabelIndex -> GenLabelMap lb LabelIndex
forall lb lv.
(Label lb, Eq lv, Show lv) =>
Word32 -> Map lb lv -> GenLabelMap lb lv
LabelMap Word32
g (Map lb LabelIndex -> GenLabelMap lb LabelIndex)
-> Map lb LabelIndex -> GenLabelMap lb LabelIndex
forall a b. (a -> b) -> a -> b
$ lb -> LabelIndex -> Map lb LabelIndex -> Map lb LabelIndex
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) = Word32 -> Map lb LabelIndex -> GenLabelMap lb LabelIndex
forall lb lv.
(Label lb, Eq lv, Show lv) =>
Word32 -> Map lb lv -> GenLabelMap lb lv
LabelMap (Word32
g Word32 -> Word32 -> Word32
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 = (LabelMap lb -> lb -> LabelMap lb)
-> LabelMap lb -> Set lb -> LabelMap lb
forall a b. (a -> b -> a) -> a -> Set b -> a
S.foldl' ((lb -> LabelMap lb -> LabelMap lb)
-> LabelMap lb -> lb -> LabelMap lb
forall a b c. (a -> b -> c) -> b -> a -> c
flip lb -> LabelMap lb -> LabelMap lb
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) =
Word32 -> Map lb LabelIndex -> GenLabelMap lb LabelIndex
forall lb lv.
(Label lb, Eq lv, Show lv) =>
Word32 -> Map lb lv -> GenLabelMap lb lv
LabelMap Word32
g (Map lb LabelIndex -> GenLabelMap lb LabelIndex)
-> Map lb LabelIndex -> GenLabelMap lb LabelIndex
forall a b. (a -> b) -> a -> b
$ (LabelIndex -> LabelIndex -> LabelIndex)
-> lb -> LabelIndex -> Map lb LabelIndex -> Map lb LabelIndex
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
M.insertWith ((LabelIndex -> LabelIndex)
-> LabelIndex -> LabelIndex -> LabelIndex
forall a b. a -> b -> a
const LabelIndex -> LabelIndex
forall a. a -> a
id) lb
lab (Word32
g, lb -> Word32
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 = Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word32) -> (lb -> Int) -> lb -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> lb -> Int
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 lb -> Bool
forall lb. Label lb => lb -> Bool
labelIsVar lb
lab then Int
23 Int -> Word32 -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Word32
seed else Int -> lb -> Int
forall lb. Label lb => Int -> lb -> Int
labelHash (Word32 -> Int
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 =
[(LabelIndex, lb)] -> [(LabelIndex, [lb])]
forall a b. Ord a => [(a, b)] -> [(a, [b])]
pairGroup ([(LabelIndex, lb)] -> [(LabelIndex, [lb])])
-> [(LabelIndex, lb)] -> [(LabelIndex, [lb])]
forall a b. (a -> b) -> a -> b
$ Set (LabelIndex, lb) -> [(LabelIndex, lb)]
forall a. Set a -> [a]
S.toList (Set (LabelIndex, lb) -> [(LabelIndex, lb)])
-> Set (LabelIndex, lb) -> [(LabelIndex, lb)]
forall a b. (a -> b) -> a -> b
$ (lb -> (LabelIndex, lb)) -> Set lb -> Set (LabelIndex, lb)
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 = (LabelMap lb -> lb -> LabelIndex
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 =
Bool
-> (LabelMap lb, [(EquivalenceClass lb, EquivalenceClass lb)],
Bool, Bool)
-> (LabelMap lb, [(EquivalenceClass lb, EquivalenceClass lb)],
Bool, Bool)
forall a. HasCallStack => Bool -> a -> a
assert (Word32
gen1 Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
gen2)
(Word32 -> Map lb LabelIndex -> LabelMap lb
forall lb lv.
(Label lb, Eq lv, Show 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 =
ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
forall lb.
Label lb =>
ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
remapLabels ArcSet lb
gs1 LabelMap lb
lmap ([lb] -> LabelMap lb) -> [lb] -> LabelMap lb
forall a b. (a -> b) -> a -> b
$ ([lb] -> [lb] -> [lb]) -> [[lb]] -> [lb]
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 [lb] -> [lb] -> [lb]
forall a. [a] -> [a] -> [a]
(++) ([[lb]] -> [lb]) -> [[lb]] -> [lb]
forall a b. (a -> b) -> a -> b
$ ((EquivalenceClass lb, EquivalenceClass lb) -> [lb])
-> [(EquivalenceClass lb, EquivalenceClass lb)] -> [[lb]]
forall a b. (a -> b) -> [a] -> [b]
map (EquivalenceClass lb -> [lb]
forall lb. EquivalenceClass lb -> [lb]
ecLabels (EquivalenceClass lb -> [lb])
-> ((EquivalenceClass lb, EquivalenceClass lb)
-> EquivalenceClass lb)
-> (EquivalenceClass lb, EquivalenceClass lb)
-> [lb]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (EquivalenceClass lb, EquivalenceClass lb) -> EquivalenceClass lb
forall a b. (a, b) -> a
fst) [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs
LabelMap Word32
gen2 Map lb LabelIndex
lm2 =
ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
forall lb.
Label lb =>
ArcSet lb -> LabelMap lb -> [lb] -> LabelMap lb
remapLabels ArcSet lb
gs2 LabelMap lb
lmap ([lb] -> LabelMap lb) -> [lb] -> LabelMap lb
forall a b. (a -> b) -> a -> b
$ ([lb] -> [lb] -> [lb]) -> [[lb]] -> [lb]
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 [lb] -> [lb] -> [lb]
forall a. [a] -> [a] -> [a]
(++) ([[lb]] -> [lb]) -> [[lb]] -> [lb]
forall a b. (a -> b) -> a -> b
$ ((EquivalenceClass lb, EquivalenceClass lb) -> [lb])
-> [(EquivalenceClass lb, EquivalenceClass lb)] -> [[lb]]
forall a b. (a -> b) -> [a] -> [b]
map (EquivalenceClass lb -> [lb]
forall lb. EquivalenceClass lb -> [lb]
ecLabels (EquivalenceClass lb -> [lb])
-> ((EquivalenceClass lb, EquivalenceClass lb)
-> EquivalenceClass lb)
-> (EquivalenceClass lb, EquivalenceClass lb)
-> [lb]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (EquivalenceClass lb, EquivalenceClass lb) -> EquivalenceClass lb
forall a b. (a, b) -> b
snd) [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs
lm' :: Map lb LabelIndex
lm' = Map lb LabelIndex -> Map lb LabelIndex -> Map lb LabelIndex
forall a b. Ord a => Map a b -> Map a b -> Map a b
classifyCombine Map lb LabelIndex
lm (Map lb LabelIndex -> Map lb LabelIndex)
-> Map lb LabelIndex -> Map lb LabelIndex
forall a b. (a -> b) -> a -> b
$ Map lb LabelIndex -> Map lb LabelIndex -> Map lb LabelIndex
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 = ((EquivalenceClass lb, EquivalenceClass lb)
-> ([EquivalenceClass lb], [EquivalenceClass lb]))
-> [(EquivalenceClass lb, EquivalenceClass lb)]
-> [([EquivalenceClass lb], [EquivalenceClass lb])]
forall a b. (a -> b) -> [a] -> [b]
map ((EquivalenceClass lb -> [EquivalenceClass lb])
-> (EquivalenceClass lb, EquivalenceClass lb)
-> ([EquivalenceClass lb], [EquivalenceClass lb])
forall {t} {b}. (t -> b) -> (t, t) -> (b, b)
tmap EquivalenceClass lb -> [EquivalenceClass lb]
forall {a}. (a, [lb]) -> [EquivalenceClass lb]
remapEc) [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs
ecpairs' :: [(EquivalenceClass lb, EquivalenceClass lb)]
ecpairs' = (([EquivalenceClass lb], [EquivalenceClass lb])
-> [(EquivalenceClass lb, EquivalenceClass lb)])
-> [([EquivalenceClass lb], [EquivalenceClass lb])]
-> [(EquivalenceClass lb, EquivalenceClass lb)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (([EquivalenceClass lb]
-> [EquivalenceClass lb]
-> [(EquivalenceClass lb, EquivalenceClass lb)])
-> ([EquivalenceClass lb], [EquivalenceClass lb])
-> [(EquivalenceClass lb, EquivalenceClass lb)]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [EquivalenceClass lb]
-> [EquivalenceClass lb]
-> [(EquivalenceClass lb, EquivalenceClass lb)]
forall a b. [a] -> [b] -> [(a, b)]
zip) [([EquivalenceClass lb], [EquivalenceClass lb])]
ecGroups
newPart :: Bool
newPart = ((Int, Int) -> Bool) -> [(Int, Int)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Int, Int) -> Bool
forall {a} {a}. (Ord a, Ord a, Num a, Num a) => (a, a) -> Bool
pairG1 [(Int, Int)]
lenGroups
matchPart :: Bool
matchPart = ((Int, Int) -> Bool) -> [(Int, Int)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int, Int) -> Bool
pairEq [(Int, Int)]
lenGroups
lenGroups :: [(Int, Int)]
lenGroups = (([EquivalenceClass lb], [EquivalenceClass lb]) -> (Int, Int))
-> [([EquivalenceClass lb], [EquivalenceClass lb])] -> [(Int, Int)]
forall a b. (a -> b) -> [a] -> [b]
map (([EquivalenceClass lb] -> Int)
-> ([EquivalenceClass lb], [EquivalenceClass lb]) -> (Int, Int)
forall {t} {b}. (t -> b) -> (t, t) -> (b, b)
tmap [EquivalenceClass lb] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length) [([EquivalenceClass lb], [EquivalenceClass lb])]
ecGroups
pairEq :: (Int, Int) -> Bool
pairEq = (Int -> Int -> Bool) -> (Int, Int) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(==)
pairG1 :: (a, a) -> Bool
pairG1 (a
p1,a
p2) = a
p1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
1 Bool -> Bool -> Bool
|| a
p2 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
1
remapEc :: (a, [lb]) -> [EquivalenceClass lb]
remapEc = [(LabelIndex, lb)] -> [EquivalenceClass lb]
forall a b. Ord a => [(a, b)] -> [(a, [b])]
pairGroup ([(LabelIndex, lb)] -> [EquivalenceClass lb])
-> ((a, [lb]) -> [(LabelIndex, lb)])
-> (a, [lb])
-> [EquivalenceClass lb]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, lb) -> (LabelIndex, lb)) -> [(a, lb)] -> [(LabelIndex, lb)]
forall a b. (a -> b) -> [a] -> [b]
map (Map lb LabelIndex -> (a, lb) -> (LabelIndex, lb)
forall {b} {a}.
Ord b =>
Map b LabelIndex -> (a, b) -> (LabelIndex, b)
newIndex Map lb LabelIndex
lm') ([(a, lb)] -> [(LabelIndex, lb)])
-> ((a, [lb]) -> [(a, lb)]) -> (a, [lb]) -> [(LabelIndex, lb)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, [lb]) -> [(a, lb)]
forall a b. (a, [b]) -> [(a, b)]
pairUngroup
newIndex :: Map b LabelIndex -> (a, b) -> (LabelIndex, b)
newIndex Map b LabelIndex
x (a
_,b
lab) = (LabelIndex -> b -> Map b LabelIndex -> LabelIndex
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 = (a -> b -> b -> Maybe b)
-> (Map a b -> Map a b)
-> (Map a b -> Map a b)
-> Map a b
-> Map a b
-> Map a b
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 -> b -> Maybe b
forall a. a -> Maybe a
Just b
v) Map a b -> Map a b
forall a. a -> a
id (Map a b -> Map a b -> Map a b
forall a b. a -> b -> a
const Map a b
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 =
Word32 -> Map lb LabelIndex -> LabelMap lb
forall lb lv.
(Label lb, Eq lv, Show lv) =>
Word32 -> Map lb lv -> GenLabelMap lb lv
LabelMap Word32
gen' (Map lb LabelIndex -> LabelMap lb)
-> Map lb LabelIndex -> LabelMap lb
forall a b. (a -> b) -> a -> b
$ [(lb, LabelIndex)] -> Map lb LabelIndex
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(lb, LabelIndex)]
newEntries
where
gen' :: Word32
gen' = Word32
gen Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
1
newEntries :: [(lb, LabelIndex)]
newEntries = [ (lb
l, (Word32
gen', Int -> Word32
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
| lb -> Bool
forall lb. Label lb => lb -> Bool
labelIsVar lb
l = lb -> Int
mapAdjacent lb
l
| Bool
otherwise = Word32 -> lb -> Int
forall lb. Label lb => Word32 -> lb -> Int
hashVal Word32
gen lb
l
mapAdjacent :: lb -> Int
mapAdjacent lb
l = Int
hashModulus Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (lb -> [Int]
sigsOver lb
l)
gls :: [Arc lb]
gls = ArcSet lb -> [Arc lb]
forall a. Set a -> [a]
S.toList ArcSet lb
gs
sigsOver :: lb -> [Int]
sigsOver lb
l = (Arc lb -> Bool) -> [Arc lb] -> [Int] -> [Int]
forall a b. (a -> Bool) -> [a] -> [b] -> [b]
select (lb -> Arc lb -> Bool
forall lb. Eq lb => lb -> Arc lb -> Bool
hasLabel lb
l) [Arc lb]
gls (LabelMap lb -> [Arc lb] -> [Int]
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 b -> [b] -> [b]
forall a. a -> [a] -> [a]
: (a -> Bool) -> [a] -> [b] -> [b]
forall a b. (a -> Bool) -> [a] -> [b] -> [b]
select a -> Bool
f [a]
l1 [b]
l2
| Bool
otherwise = (a -> Bool) -> [a] -> [b] -> [b]
forall a b. (a -> Bool) -> [a] -> [b] -> [b]
select a -> Bool
f [a]
l1 [b]
l2
select a -> Bool
_ [a]
_ [b]
_ = String -> [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 = (Arc lb -> [lb]) -> Set (Arc lb) -> Set lb
forall b a. Ord b => (a -> [b]) -> Set a -> Set b
getComponents Arc lb -> [lb]
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 =
(Arc lb -> Int) -> [Arc lb] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map ((lb, lb, lb) -> Int
sigCalc ((lb, lb, lb) -> Int) -> (Arc lb -> (lb, lb, lb)) -> Arc lb -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Arc lb -> (lb, lb, lb)
forall lb. Arc lb -> (lb, lb, lb)
arcToTriple)
where
sigCalc :: (lb, lb, lb) -> Int
sigCalc (lb
s,lb
p,lb
o) =
Int
hashModulus Int -> Word32 -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt`
( lb -> Word32
labelVal2 lb
s Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+
lb -> Word32
labelVal2 lb
p Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
3 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+
lb -> Word32
labelVal2 lb
o Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
5 )
labelVal :: lb -> LabelIndex
labelVal = LabelMap lb -> lb -> LabelIndex
forall lb. Label lb => LabelMap lb -> lb -> LabelIndex
mapLabelIndex LabelMap lb
lmap
labelVal2 :: lb -> Word32
labelVal2 = (Word32 -> Word32 -> Word32) -> LabelIndex -> Word32
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
(*) (LabelIndex -> Word32) -> (lb -> LabelIndex) -> lb -> Word32
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 = (Arc lb -> Arc LabelIndex) -> Set (Arc lb) -> ArcSet LabelIndex
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map ((Arc lb -> Arc LabelIndex) -> Set (Arc lb) -> ArcSet LabelIndex)
-> (LabelMap lb -> Arc lb -> Arc LabelIndex)
-> LabelMap lb
-> Set (Arc lb)
-> ArcSet LabelIndex
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (lb -> LabelIndex) -> Arc lb -> Arc LabelIndex
forall a b. (a -> b) -> Arc a -> Arc b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((lb -> LabelIndex) -> Arc lb -> Arc LabelIndex)
-> (LabelMap lb -> lb -> LabelIndex)
-> LabelMap lb
-> Arc lb
-> Arc LabelIndex
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabelMap lb -> lb -> LabelIndex
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 = ArcSet LabelIndex -> ArcSet LabelIndex -> Bool
forall a. Eq a => a -> a -> Bool
(==) (ArcSet LabelIndex -> ArcSet LabelIndex -> Bool)
-> (ArcSet lb -> ArcSet LabelIndex)
-> ArcSet lb
-> ArcSet lb
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` LabelMap lb -> ArcSet lb -> ArcSet LabelIndex
forall lb.
Label lb =>
LabelMap lb -> ArcSet lb -> ArcSet LabelIndex
graphMap LabelMap lb
lmap