{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Swish.GraphMem
( GraphMem(..)
, LabelMem(..)
, setArcs, getArcs, addGraphs, delete, extract, labels
, labelIsVar, labelHash
, matchGraphMem
) where
import qualified Data.Set as S
import Swish.GraphClass
import Swish.GraphMatch
import Data.Hashable (Hashable(..))
#if (!defined(__GLASGOW_HASKELL__)) || (__GLASGOW_HASKELL__ < 710)
import Data.Monoid (Monoid(..))
#endif
import Data.Ord (comparing)
#if !(MIN_VERSION_base(4, 11, 0))
import Data.Semigroup
#endif
data GraphMem lb = GraphMem { forall lb. GraphMem lb -> ArcSet lb
arcs :: ArcSet lb }
instance LDGraph GraphMem lb where
emptyGraph :: GraphMem lb
emptyGraph = ArcSet lb -> GraphMem lb
forall lb. ArcSet lb -> GraphMem lb
GraphMem ArcSet lb
forall a. Set a
S.empty
getArcs :: GraphMem lb -> ArcSet lb
getArcs = GraphMem lb -> ArcSet lb
forall lb. GraphMem lb -> ArcSet lb
arcs
setArcs :: GraphMem lb -> ArcSet lb -> GraphMem lb
setArcs GraphMem lb
g ArcSet lb
as = GraphMem lb
g { arcs=as }
instance (Label lb) => Eq (GraphMem lb) where
== :: GraphMem lb -> GraphMem lb -> Bool
(==) = GraphMem lb -> GraphMem lb -> Bool
forall lb. Label lb => GraphMem lb -> GraphMem lb -> Bool
graphEq
instance (Label lb) => Ord (GraphMem lb) where
compare :: GraphMem lb -> GraphMem lb -> Ordering
compare = (GraphMem lb -> ArcSet lb)
-> GraphMem lb -> GraphMem lb -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing GraphMem lb -> ArcSet lb
forall (lg :: * -> *) lb. LDGraph lg lb => lg lb -> ArcSet lb
getArcs
instance (Label lb) => Show (GraphMem lb) where
show :: GraphMem lb -> String
show = GraphMem lb -> String
forall lb. Label lb => GraphMem lb -> String
graphShow
instance (Label lb) => Semigroup (GraphMem lb) where
<> :: GraphMem lb -> GraphMem lb -> GraphMem lb
(<>) = GraphMem lb -> GraphMem lb -> GraphMem lb
forall (lg :: * -> *) lb.
(LDGraph lg lb, Ord lb) =>
lg lb -> lg lb -> lg lb
addGraphs
instance (Label lb) => Monoid (GraphMem lb) where
mempty :: GraphMem lb
mempty = GraphMem lb
forall (lg :: * -> *) lb. LDGraph lg lb => lg lb
emptyGraph
#if !(MIN_VERSION_base(4, 11, 0))
mappend = (<>)
#endif
graphShow :: (Label lb) => GraphMem lb -> String
graphShow :: forall lb. Label lb => GraphMem lb -> String
graphShow GraphMem lb
g = String
"Graph:" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Arc lb -> ShowS) -> String -> Set (Arc lb) -> String
forall a b. (a -> b -> b) -> b -> Set a -> b
S.foldr (String -> ShowS
forall a. [a] -> [a] -> [a]
(++) (String -> ShowS) -> (Arc lb -> String) -> Arc lb -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
"\n " String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> (Arc lb -> String) -> Arc lb -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Arc lb -> String
forall a. Show a => a -> String
show) String
"" (GraphMem lb -> Set (Arc lb)
forall lb. GraphMem lb -> ArcSet lb
arcs GraphMem lb
g)
graphEq :: (Label lb) => GraphMem lb -> GraphMem lb -> Bool
graphEq :: forall lb. Label lb => GraphMem lb -> GraphMem lb -> Bool
graphEq GraphMem lb
g1 GraphMem lb
g2 = (Bool, LabelMap (ScopedLabel lb)) -> Bool
forall a b. (a, b) -> a
fst ( GraphMem lb -> GraphMem lb -> (Bool, LabelMap (ScopedLabel lb))
forall lb.
Label lb =>
GraphMem lb -> GraphMem lb -> (Bool, LabelMap (ScopedLabel lb))
matchGraphMem GraphMem lb
g1 GraphMem lb
g2 )
matchGraphMem ::
(Label lb)
=> GraphMem lb
-> GraphMem lb
-> (Bool,LabelMap (ScopedLabel lb))
matchGraphMem :: forall lb.
Label lb =>
GraphMem lb -> GraphMem lb -> (Bool, LabelMap (ScopedLabel lb))
matchGraphMem GraphMem lb
g1 GraphMem lb
g2 =
let
gs1 :: ArcSet lb
gs1 = GraphMem lb -> ArcSet lb
forall lb. GraphMem lb -> ArcSet lb
arcs GraphMem lb
g1
gs2 :: ArcSet lb
gs2 = GraphMem lb -> ArcSet lb
forall lb. GraphMem lb -> ArcSet lb
arcs GraphMem lb
g2
matchable :: a -> a -> Bool
matchable a
l1 a
l2
| a -> Bool
forall lb. Label lb => lb -> Bool
labelIsVar a
l1 Bool -> Bool -> Bool
&& a -> Bool
forall lb. Label lb => lb -> Bool
labelIsVar a
l2 = Bool
True
| a -> Bool
forall lb. Label lb => lb -> Bool
labelIsVar a
l1 Bool -> Bool -> Bool
|| a -> Bool
forall lb. Label lb => lb -> Bool
labelIsVar a
l2 = Bool
False
| Bool
otherwise = a
l1 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
l2
in
(lb -> lb -> Bool)
-> ArcSet lb -> ArcSet lb -> (Bool, LabelMap (ScopedLabel lb))
forall lb.
Label lb =>
(lb -> lb -> Bool)
-> ArcSet lb -> ArcSet lb -> (Bool, LabelMap (ScopedLabel lb))
graphMatch lb -> lb -> Bool
forall {a}. Label a => a -> a -> Bool
matchable ArcSet lb
gs1 ArcSet lb
gs2
data LabelMem
= LF String
| LV String
instance Hashable LabelMem where
hashWithSalt :: Int -> LabelMem -> Int
hashWithSalt Int
salt (LF String
l) = Int
salt Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
1::Int) Int -> String -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` String
l
hashWithSalt Int
salt (LV String
l) = Int
salt Int -> Int -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` (Int
2::Int) Int -> String -> Int
forall a. Hashable a => Int -> a -> Int
`hashWithSalt` String
l
#if !MIN_VERSION_hashable(1,2,0)
hash (LF l) = 1 `hashWithSalt` l
hash (LV l) = 2 `hashWithSalt` l
#endif
instance Label LabelMem where
labelIsVar :: LabelMem -> Bool
labelIsVar (LV String
_) = Bool
True
labelIsVar LabelMem
_ = Bool
False
getLocal :: LabelMem -> String
getLocal (LV String
loc) = String
loc
getLocal LabelMem
lab = ShowS
forall a. HasCallStack => String -> a
error String
"getLocal of non-variable label: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ LabelMem -> String
forall a. Show a => a -> String
show LabelMem
lab
makeLabel :: String -> LabelMem
makeLabel = String -> LabelMem
LV
labelHash :: Int -> LabelMem -> Int
labelHash = Int -> LabelMem -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt
instance Eq LabelMem where
(LF String
l1) == :: LabelMem -> LabelMem -> Bool
== (LF String
l2) = String
l1 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
l2
(LV String
l1) == (LV String
l2) = String
l1 String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
l2
LabelMem
_ == LabelMem
_ = Bool
False
instance Ord LabelMem where
(LF String
l1) compare :: LabelMem -> LabelMem -> Ordering
`compare` (LF String
l2) = String
l1 String -> String -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` String
l2
(LV String
l1) `compare` (LV String
l2) = String
l1 String -> String -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` String
l2
(LF String
_) `compare` LabelMem
_ = Ordering
LT
LabelMem
_ `compare` (LF String
_) = Ordering
GT
instance Show LabelMem where
show :: LabelMem -> String
show (LF String
l1) = Char
'!' Char -> ShowS
forall a. a -> [a] -> [a]
: String
l1
show (LV String
l2) = Char
'?' Char -> ShowS
forall a. a -> [a] -> [a]
: String
l2