Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
haskell-igraph
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
haskell-igraph
Commits
6ce9fdfd
Commit
6ce9fdfd
authored
Apr 30, 2018
by
Kai Zhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
use dependent types
parent
9877beeb
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
340 additions
and
285 deletions
+340
-285
haskell-igraph.cabal
haskell-igraph.cabal
+1
-0
IGraph.hs
src/IGraph.hs
+133
-127
Clique.chs
src/IGraph/Clique.chs
+4
-4
Community.chs
src/IGraph/Community.chs
+3
-3
GEXF.hs
src/IGraph/Exporter/GEXF.hs
+7
-6
Generators.chs
src/IGraph/Generators.chs
+32
-23
Isomorphism.chs
src/IGraph/Isomorphism.chs
+25
-20
Layout.chs
src/IGraph/Layout.chs
+1
-1
Motif.chs
src/IGraph/Motif.chs
+4
-3
Mutable.hs
src/IGraph/Mutable.hs
+76
-66
Read.hs
src/IGraph/Read.hs
+8
-7
Structure.chs
src/IGraph/Structure.chs
+10
-9
Types.hs
src/IGraph/Types.hs
+23
-6
Attributes.hs
tests/Test/Attributes.hs
+5
-4
Basic.hs
tests/Test/Basic.hs
+6
-5
Structure.hs
tests/Test/Structure.hs
+2
-1
No files found.
haskell-igraph.cabal
View file @
6ce9fdfd
...
@@ -65,6 +65,7 @@ library
...
@@ -65,6 +65,7 @@ library
, hashable
, hashable
, hxt
, hxt
, split
, split
, singletons
extra-libraries: igraph
extra-libraries: igraph
hs-source-dirs: src
hs-source-dirs: src
...
...
src/IGraph.hs
View file @
6ce9fdfd
This diff is collapsed.
Click to expand it.
src/IGraph/Clique.chs
View file @
6ce9fdfd
...
@@ -18,7 +18,7 @@ import IGraph.Internal.C2HS
...
@@ -18,7 +18,7 @@ import IGraph.Internal.C2HS
#include "haskell_igraph.h"
#include "haskell_igraph.h"
cliques ::
L
Graph d v e
cliques :: Graph d v e
-> (Int, Int) -- ^ Minimum and maximum size of the cliques to be returned.
-> (Int, Int) -- ^ Minimum and maximum size of the cliques to be returned.
-- No bound will be used if negative or zero
-- No bound will be used if negative or zero
-> [[Int]] -- ^ cliques represented by node ids
-> [[Int]] -- ^ cliques represented by node ids
...
@@ -27,13 +27,13 @@ cliques gr (lo, hi) = unsafePerformIO $ allocaVectorPtr $ \vptr -> do
...
@@ -27,13 +27,13 @@ cliques gr (lo, hi) = unsafePerformIO $ allocaVectorPtr $ \vptr -> do
(map.map) truncate <$> toLists vptr
(map.map) truncate <$> toLists vptr
{#fun igraph_cliques as ^ { `IGraph', castPtr `Ptr VectorPtr', `Int', `Int' } -> `CInt' void- #}
{#fun igraph_cliques as ^ { `IGraph', castPtr `Ptr VectorPtr', `Int', `Int' } -> `CInt' void- #}
largestCliques ::
L
Graph d v e -> [[Int]]
largestCliques :: Graph d v e -> [[Int]]
largestCliques gr = unsafePerformIO $ allocaVectorPtr $ \vptr -> do
largestCliques gr = unsafePerformIO $ allocaVectorPtr $ \vptr -> do
igraphLargestCliques (_graph gr) vptr
igraphLargestCliques (_graph gr) vptr
(map.map) truncate <$> toLists vptr
(map.map) truncate <$> toLists vptr
{#fun igraph_largest_cliques as ^ { `IGraph', castPtr `Ptr VectorPtr' } -> `CInt' void- #}
{#fun igraph_largest_cliques as ^ { `IGraph', castPtr `Ptr VectorPtr' } -> `CInt' void- #}
maximalCliques ::
L
Graph d v e
maximalCliques :: Graph d v e
-> (Int, Int) -- ^ Minimum and maximum size of the cliques to be returned.
-> (Int, Int) -- ^ Minimum and maximum size of the cliques to be returned.
-- No bound will be used if negative or zero
-- No bound will be used if negative or zero
-> [[Int]] -- ^ cliques represented by node ids
-> [[Int]] -- ^ cliques represented by node ids
...
@@ -42,7 +42,7 @@ maximalCliques gr (lo, hi) = unsafePerformIO $ allocaVectorPtr $ \vpptr -> do
...
@@ -42,7 +42,7 @@ maximalCliques gr (lo, hi) = unsafePerformIO $ allocaVectorPtr $ \vpptr -> do
(map.map) truncate <$> toLists vpptr
(map.map) truncate <$> toLists vpptr
{#fun igraph_maximal_cliques as ^ { `IGraph', castPtr `Ptr VectorPtr', `Int', `Int' } -> `CInt' void- #}
{#fun igraph_maximal_cliques as ^ { `IGraph', castPtr `Ptr VectorPtr', `Int', `Int' } -> `CInt' void- #}
cliqueNumber ::
L
Graph d v e -> Int
cliqueNumber :: Graph d v e -> Int
cliqueNumber gr = unsafePerformIO $ igraphCliqueNumber $ _graph gr
cliqueNumber gr = unsafePerformIO $ igraphCliqueNumber $ _graph gr
{#fun igraph_clique_number as ^
{#fun igraph_clique_number as ^
{ `IGraph'
{ `IGraph'
...
...
src/IGraph/Community.chs
View file @
6ce9fdfd
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE DataKinds #-}
module IGraph.Community
module IGraph.Community
( modularity
( modularity
, findCommunity
, findCommunity
...
@@ -25,8 +26,7 @@ import IGraph.Internal.C2HS
...
@@ -25,8 +26,7 @@ import IGraph.Internal.C2HS
#include "haskell_igraph.h"
#include "haskell_igraph.h"
modularity :: Graph d
modularity :: Graph d v e
=> LGraph d v e
-> [[Int]] -- ^ Communities.
-> [[Int]] -- ^ Communities.
-> Maybe [Double] -- ^ Weights
-> Maybe [Double] -- ^ Weights
-> Double
-> Double
...
@@ -70,7 +70,7 @@ defaultSpinglass = Spinglass
...
@@ -70,7 +70,7 @@ defaultSpinglass = Spinglass
, _coolFact = 0.99
, _coolFact = 0.99
, _gamma = 1.0 }
, _gamma = 1.0 }
findCommunity ::
LGraph
U v e
findCommunity ::
Graph '
U v e
-> Maybe [Double] -- ^ node weights
-> Maybe [Double] -- ^ node weights
-> CommunityMethod -- ^ Community finding algorithms
-> CommunityMethod -- ^ Community finding algorithms
-> [[Int]]
-> [[Int]]
...
...
src/IGraph/Exporter/GEXF.hs
View file @
6ce9fdfd
...
@@ -9,12 +9,13 @@ module IGraph.Exporter.GEXF
...
@@ -9,12 +9,13 @@ module IGraph.Exporter.GEXF
,
writeGEXF
,
writeGEXF
)
where
)
where
import
Data.Colour
(
AlphaColour
,
alphaChannel
,
black
,
import
Data.Colour
(
AlphaColour
,
alphaChannel
,
black
,
opaque
,
opaque
,
over
)
over
)
import
Data.Colour.SRGB
(
channelBlue
,
channelGreen
,
import
Data.Colour.SRGB
(
channelBlue
,
channelGreen
,
channelRed
,
channelRed
,
toSRGB24
)
toSRGB24
)
import
Data.Hashable
import
Data.Hashable
import
Data.Serialize
import
Data.Serialize
import
Data.Singletons
(
SingI
)
import
GHC.Generics
import
GHC.Generics
import
IGraph
import
IGraph
import
Text.XML.HXT.Core
import
Text.XML.HXT.Core
...
@@ -71,7 +72,7 @@ defaultEdgeAttributes = EdgeAttr
...
@@ -71,7 +72,7 @@ defaultEdgeAttributes = EdgeAttr
,
_edgeZindex
=
2
,
_edgeZindex
=
2
}
}
genXMLTree
::
(
ArrowXml
a
,
Graph
d
)
=>
L
Graph
d
NodeAttr
EdgeAttr
->
a
XmlTree
XmlTree
genXMLTree
::
(
SingI
d
,
ArrowXml
a
)
=>
Graph
d
NodeAttr
EdgeAttr
->
a
XmlTree
XmlTree
genXMLTree
gr
=
root
[]
[
gexf
]
genXMLTree
gr
=
root
[]
[
gexf
]
where
where
gexf
=
mkelem
"gexf"
[
attr
"version"
$
txt
"1.2"
gexf
=
mkelem
"gexf"
[
attr
"version"
$
txt
"1.2"
...
@@ -124,7 +125,7 @@ genXMLTree gr = root [] [gexf]
...
@@ -124,7 +125,7 @@ genXMLTree gr = root [] [gexf]
a
=
show
$
alphaChannel
$
_edgeColour
at
a
=
show
$
alphaChannel
$
_edgeColour
at
{-# INLINE genXMLTree #-}
{-# INLINE genXMLTree #-}
writeGEXF
::
Graph
d
=>
FilePath
->
L
Graph
d
NodeAttr
EdgeAttr
->
IO
()
writeGEXF
::
SingI
d
=>
FilePath
->
Graph
d
NodeAttr
EdgeAttr
->
IO
()
writeGEXF
fl
gr
=
runX
(
genXMLTree
gr
>>>
writeDocument
config
fl
)
>>
return
()
writeGEXF
fl
gr
=
runX
(
genXMLTree
gr
>>>
writeDocument
config
fl
)
>>
return
()
where
where
config
=
[
withIndent
yes
]
config
=
[
withIndent
yes
]
src/IGraph/Generators.chs
View file @
6ce9fdfd
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
module IGraph.Generators
module IGraph.Generators
( full
( full
, ErdosRenyiModel(..)
, ErdosRenyiModel(..)
...
@@ -10,6 +12,7 @@ module IGraph.Generators
...
@@ -10,6 +12,7 @@ module IGraph.Generators
import Control.Monad (when)
import Control.Monad (when)
import Data.Hashable (Hashable)
import Data.Hashable (Hashable)
import Data.Serialize (Serialize)
import Data.Serialize (Serialize)
import Data.Singletons (SingI, Sing, sing, fromSing)
import System.IO.Unsafe (unsafePerformIO)
import System.IO.Unsafe (unsafePerformIO)
import qualified Foreign.Ptr as C2HSImp
import qualified Foreign.Ptr as C2HSImp
...
@@ -23,14 +26,17 @@ import IGraph.Mutable
...
@@ -23,14 +26,17 @@ import IGraph.Mutable
#include "haskell_igraph.h"
#include "haskell_igraph.h"
full ::
Graph
d
full ::
forall d. SingI
d
=> Int -- ^ The number of vertices in the graph.
=> Int -- ^ The number of vertices in the graph.
-> Bool -- ^ Whether to include self-edges (loops)
-> Bool -- ^ Whether to include self-edges (loops)
-> d -- ^ U or D
-> Graph d () ()
-> LGraph d () ()
full n hasLoop = unsafePerformIO $ do
full n hasLoop d = unsafePerformIO $ do
gr <- igraphFull n directed hasLoop
gr <- igraphFull n (isD d) hasLoop
unsafeFreeze $ MGraph gr
unsafeFreeze $ MLGraph gr
where
directed = case fromSing (sing :: Sing d) of
D -> True
U -> False
{#fun igraph_full as ^
{#fun igraph_full as ^
{ allocaIGraph- `IGraph' addIGraphFinalizer*
{ allocaIGraph- `IGraph' addIGraphFinalizer*
, `Int', `Bool', `Bool'
, `Int', `Bool', `Bool'
...
@@ -39,18 +45,21 @@ full n hasLoop d = unsafePerformIO $ do
...
@@ -39,18 +45,21 @@ full n hasLoop d = unsafePerformIO $ do
data ErdosRenyiModel = GNP Int Double
data ErdosRenyiModel = GNP Int Double
| GNM Int Int
| GNM Int Int
erdosRenyiGame ::
Graph
d
erdosRenyiGame ::
forall d. SingI
d
=> ErdosRenyiModel
=> ErdosRenyiModel
-> d -- ^ directed
-> Bool -- ^ self-loop
-> Bool -- ^ self-loop
-> IO (LGraph d () ())
-> IO (Graph d () ())
erdosRenyiGame (GNP n p) d self = do
erdosRenyiGame model self = do
gp <- igraphInit >> igraphErdosRenyiGame IgraphErdosRenyiGnp n p (isD d) self
igraphInit
unsafeFreeze $ MLGraph gp
gr <- case model of
erdosRenyiGame (GNM n m) d self = do
GNP n p -> igraphErdosRenyiGame IgraphErdosRenyiGnp n p directed self
gp <- igraphInit >> igraphErdosRenyiGame IgraphErdosRenyiGnm n
GNM n m -> igraphErdosRenyiGame IgraphErdosRenyiGnm n (fromIntegral m)
(fromIntegral m) (isD d) self
directed self
unsafeFreeze $ MLGraph gp
unsafeFreeze $ MGraph gr
where
directed = case fromSing (sing :: Sing d) of
D -> True
U -> False
{#fun igraph_erdos_renyi_game as ^
{#fun igraph_erdos_renyi_game as ^
{ allocaIGraph- `IGraph' addIGraphFinalizer*
{ allocaIGraph- `IGraph' addIGraphFinalizer*
, `ErdosRenyi', `Int', `Double', `Bool', `Bool'
, `ErdosRenyi', `Int', `Double', `Bool', `Bool'
...
@@ -59,24 +68,24 @@ erdosRenyiGame (GNM n m) d self = do
...
@@ -59,24 +68,24 @@ erdosRenyiGame (GNM n m) d self = do
-- | Generates a random graph with a given degree sequence.
-- | Generates a random graph with a given degree sequence.
degreeSequenceGame :: [Int] -- ^ Out degree
degreeSequenceGame :: [Int] -- ^ Out degree
-> [Int] -- ^ In degree
-> [Int] -- ^ In degree
-> IO (
LGraph
D () ())
-> IO (
Graph '
D () ())
degreeSequenceGame out_deg in_deg = withList out_deg $ \out_deg' ->
degreeSequenceGame out_deg in_deg = withList out_deg $ \out_deg' ->
withList in_deg $ \in_deg' -> do
withList in_deg $ \in_deg' -> do
gp <- igraphDegreeSequenceGame out_deg' in_deg' IgraphDegseqSimple
gp <- igraphDegreeSequenceGame out_deg' in_deg' IgraphDegseqSimple
unsafeFreeze $ M
L
Graph gp
unsafeFreeze $ MGraph gp
{#fun igraph_degree_sequence_game as ^
{#fun igraph_degree_sequence_game as ^
{ allocaIGraph- `IGraph' addIGraphFinalizer*
{ allocaIGraph- `IGraph' addIGraphFinalizer*
, castPtr `Ptr Vector', castPtr `Ptr Vector', `Degseq'
, castPtr `Ptr Vector', castPtr `Ptr Vector', `Degseq'
} -> `CInt' void- #}
} -> `CInt' void- #}
-- | Randomly rewires a graph while preserving the degree distribution.
-- | Randomly rewires a graph while preserving the degree distribution.
rewire :: (
Graph d,
Hashable v, Serialize v, Eq v, Serialize e)
rewire :: (Hashable v, Serialize v, Eq v, Serialize e)
=> Int -- ^ Number of rewiring trials to perform.
=> Int -- ^ Number of rewiring trials to perform.
->
L
Graph d v e
-> Graph d v e
-> IO (
L
Graph d v e)
-> IO (Graph d v e)
rewire n gr = do
rewire n gr = do
(M
L
Graph gptr) <- thaw gr
(MGraph gptr) <- thaw gr
err <- igraphRewire gptr n IgraphRewiringSimple
err <- igraphRewire gptr n IgraphRewiringSimple
when (err /= 0) $ error "failed to rewire graph!"
when (err /= 0) $ error "failed to rewire graph!"
unsafeFreeze $ M
L
Graph gptr
unsafeFreeze $ MGraph gptr
{#fun igraph_rewire as ^ { `IGraph', `Int', `Rewiring' } -> `Int' #}
{#fun igraph_rewire as ^ { `IGraph', `Int', `Rewiring' } -> `Int' #}
src/IGraph/Isomorphism.chs
View file @
6ce9fdfd
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE ScopedTypeVariables #-}
module IGraph.Isomorphism
module IGraph.Isomorphism
( getSubisomorphisms
( getSubisomorphisms
, isomorphic
, isomorphic
...
@@ -8,6 +9,7 @@ module IGraph.Isomorphism
...
@@ -8,6 +9,7 @@ module IGraph.Isomorphism
) where
) where
import System.IO.Unsafe (unsafePerformIO)
import System.IO.Unsafe (unsafePerformIO)
import Data.Singletons (SingI, Sing, sing, fromSing)
import Foreign
import Foreign
import Foreign.C.Types
import Foreign.C.Types
...
@@ -19,9 +21,8 @@ import IGraph.Mutable
...
@@ -19,9 +21,8 @@ import IGraph.Mutable
#include "haskell_igraph.h"
#include "haskell_igraph.h"
getSubisomorphisms :: Graph d
getSubisomorphisms :: Graph d v1 e1 -- ^ graph to be searched in
=> LGraph d v1 e1 -- ^ graph to be searched in
-> Graph d v2 e2 -- ^ smaller graph
-> LGraph d v2 e2 -- ^ smaller graph
-> [[Int]]
-> [[Int]]
getSubisomorphisms g1 g2 = unsafePerformIO $ allocaVectorPtr $ \vpptr -> do
getSubisomorphisms g1 g2 = unsafePerformIO $ allocaVectorPtr $ \vpptr -> do
igraphGetSubisomorphismsVf2 gptr1 gptr2 nullPtr nullPtr nullPtr nullPtr vpptr
igraphGetSubisomorphismsVf2 gptr1 gptr2 nullPtr nullPtr nullPtr nullPtr vpptr
...
@@ -45,9 +46,8 @@ getSubisomorphisms g1 g2 = unsafePerformIO $ allocaVectorPtr $ \vpptr -> do
...
@@ -45,9 +46,8 @@ getSubisomorphisms g1 g2 = unsafePerformIO $ allocaVectorPtr $ \vpptr -> do
} -> `CInt' void- #}
} -> `CInt' void- #}
-- | Determine whether two graphs are isomorphic.
-- | Determine whether two graphs are isomorphic.
isomorphic :: Graph d
isomorphic :: Graph d v1 e1
=> LGraph d v1 e1
-> Graph d v2 e2
-> LGraph d v2 e2
-> Bool
-> Bool
isomorphic g1 g2 = unsafePerformIO $ alloca $ \ptr -> do
isomorphic g1 g2 = unsafePerformIO $ alloca $ \ptr -> do
_ <- igraphIsomorphic (_graph g1) (_graph g2) ptr
_ <- igraphIsomorphic (_graph g1) (_graph g2) ptr
...
@@ -57,27 +57,32 @@ isomorphic g1 g2 = unsafePerformIO $ alloca $ \ptr -> do
...
@@ -57,27 +57,32 @@ isomorphic g1 g2 = unsafePerformIO $ alloca $ \ptr -> do
-- | Creates a graph from the given isomorphism class.
-- | Creates a graph from the given isomorphism class.
-- This function is implemented only for graphs with three or four vertices.
-- This function is implemented only for graphs with three or four vertices.
isoclassCreate ::
Graph
d
isoclassCreate ::
forall d. SingI
d
=> Int -- ^ The number of vertices to add to the graph.
=> Int -- ^ The number of vertices to add to the graph.
-> Int -- ^ The isomorphism class
-> Int -- ^ The isomorphism class
-> d
-> Graph d () ()
-> LGraph d () ()
isoclassCreate size idx = unsafePerformIO $ do
isoclassCreate size idx d = unsafePerformIO $ do
gp <- igraphInit >> igraphIsoclassCreate size idx directed
gp <- igraphInit >> igraphIsoclassCreate size idx (isD d)
unsafeFreeze $ MGraph gp
unsafeFreeze $ MLGraph gp
where
directed = case fromSing (sing :: Sing d) of
D -> True
U -> False
{#fun igraph_isoclass_create as ^
{#fun igraph_isoclass_create as ^
{ allocaIGraph- `IGraph' addIGraphFinalizer*
{ allocaIGraph- `IGraph' addIGraphFinalizer*
, `Int', `Int', `Bool'
, `Int', `Int', `Bool'
} -> `CInt' void- #}
} -> `CInt' void- #}
isoclass3 ::
Graph d => d -> [L
Graph d () ()]
isoclass3 ::
forall d. SingI d => [
Graph d () ()]
isoclass3
d = map (flip (isoclassCreate 3) d) n
isoclass3
= map (isoclassCreate 3) (if directed then [0..15] else [0..3])
where
where
n | isD d = [0..15]
directed = case fromSing (sing :: Sing d) of
| otherwise = [0..3]
D -> True
U -> False
isoclass4 ::
Graph d => d -> [L
Graph d () ()]
isoclass4 ::
forall d. SingI d => [
Graph d () ()]
isoclass4
d = map (flip (isoclassCreate 4) d) n
isoclass4
= map (isoclassCreate 4) (if directed then [0..217] else [0..10])
where
where
n | isD d = [0..217]
directed = case fromSing (sing :: Sing d) of
| otherwise = [0..10]
D -> True
U -> False
src/IGraph/Layout.chs
View file @
6ce9fdfd
...
@@ -61,7 +61,7 @@ defaultLGL = LGL
...
@@ -61,7 +61,7 @@ defaultLGL = LGL
where
where
area x = fromIntegral $ x^2
area x = fromIntegral $ x^2
getLayout :: Graph d
=> LGraph d
v e -> LayoutMethod -> IO [(Double, Double)]
getLayout :: Graph d v e -> LayoutMethod -> IO [(Double, Double)]
getLayout gr method = case method of
getLayout gr method = case method of
KamadaKawai seed niter sigma initemp coolexp kkconst -> case seed of
KamadaKawai seed niter sigma initemp coolexp kkconst -> case seed of
Nothing -> allocaMatrix $ \mat -> do
Nothing -> allocaMatrix $ \mat -> do
...
...
src/IGraph/Motif.chs
View file @
6ce9fdfd
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE DataKinds #-}
module IGraph.Motif
module IGraph.Motif
( triad
( triad
, triadCensus
, triadCensus
...
@@ -32,7 +33,7 @@ import IGraph
...
@@ -32,7 +33,7 @@ import IGraph
-- 120C: A->B->C, A<->C.
-- 120C: A->B->C, A<->C.
-- 210: A->B<->C, A<->C.
-- 210: A->B<->C, A<->C.
-- 300: A<->B<->C, A<->C, the complete graph.
-- 300: A<->B<->C, A<->C, the complete graph.
triad :: [
LGraph
D () ()]
triad :: [
Graph '
D () ()]
triad = map make edgeList
triad = map make edgeList
where
where
edgeList =
edgeList =
...
@@ -53,10 +54,10 @@ triad = map make edgeList
...
@@ -53,10 +54,10 @@ triad = map make edgeList
, [(0,1), (1,2), (2,1), (0,2), (2,0)]
, [(0,1), (1,2), (2,1), (0,2), (2,0)]
, [(0,1), (1,0), (1,2), (2,1), (0,2), (2,0)]
, [(0,1), (1,0), (1,2), (2,1), (0,2), (2,0)]
]
]
make :: [(Int, Int)] ->
LGraph
D () ()
make :: [(Int, Int)] ->
Graph '
D () ()
make xs = mkGraph (replicate 3 ()) $ zip xs $ repeat ()
make xs = mkGraph (replicate 3 ()) $ zip xs $ repeat ()
triadCensus :: (Hashable v, Eq v, Read v) =>
L
Graph d v e -> [Int]
triadCensus :: (Hashable v, Eq v, Read v) => Graph d v e -> [Int]
triadCensus gr = unsafePerformIO $ allocaVector $ \result -> do
triadCensus gr = unsafePerformIO $ allocaVector $ \result -> do
igraphTriadCensus (_graph gr) result
igraphTriadCensus (_graph gr) result
map truncate <$> toList result
map truncate <$> toList result
...
...
src/IGraph/Mutable.hs
View file @
6ce9fdfd
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
module
IGraph.Mutable
module
IGraph.Mutable
(
MGraph
(
..
)
(
MGraph
(
..
)
,
MLGraph
(
..
)
,
new
,
addNodes
,
addLNodes
,
delNodes
,
addEdges
,
addLEdges
,
delEdges
,
setEdgeAttr
,
setEdgeAttr
,
setNodeAttr
,
setNodeAttr
)
where
)
where
import
Control.Monad
(
when
,
forM
)
import
Control.Monad
(
forM
,
when
)
import
Control.Monad.Primitive
import
Control.Monad.Primitive
import
Data.Serialize
(
Serialize
,
encode
)
import
Data.Serialize
(
Serialize
,
encode
)
import
Foreign
import
Data.Singletons.Prelude
(
Sing
,
SingI
,
fromSing
,
sing
)
import
Foreign
hiding
(
new
)
import
IGraph.Internal
import
IGraph.Internal
import
IGraph.Internal.Initialization
import
IGraph.Internal.Initialization
import
IGraph.Types
import
IGraph.Types
-- | Mutable labeled graph.
-- | Mutable labeled graph.
newtype
M
LGraph
m
d
v
e
=
ML
Graph
IGraph
newtype
M
Graph
m
(
d
::
EdgeType
)
v
e
=
M
Graph
IGraph
class
MGraph
d
where
-- | Create a new graph.
-- | Create a new graph.
new
::
forall
m
d
v
e
.
(
SingI
d
,
PrimMonad
m
)
new
::
PrimMonad
m
=>
Int
->
m
(
ML
Graph
(
PrimState
m
)
d
v
e
)
=>
Int
->
m
(
M
Graph
(
PrimState
m
)
d
v
e
)
new
n
=
unsafePrimToPrim
$
igraphInit
>>=
igraphNew
n
directed
>>=
return
.
MGraph
-- | Add nodes to the graph.
where
addNodes
::
PrimMonad
m
directed
=
case
fromSing
(
sing
::
Sing
d
)
of
=>
Int
-- ^ The number of new nodes.
D
->
True
->
MLGraph
(
PrimState
m
)
d
v
e
->
m
()
U
->
False
addNodes
n
(
MLGraph
g
)
=
unsafePrimToPrim
$
igraphAddVertices
g
n
nullPtr
-- | Add nodes to the graph.
-- | Add nodes with labels to the graph.
addNodes
::
PrimMonad
m
addLNodes
::
(
Serialize
v
,
PrimMonad
m
)
=>
Int
-- ^ The number of new nodes.
=>
[
v
]
-- ^ vertices' labels
->
MGraph
(
PrimState
m
)
d
v
e
->
m
()
->
MLGraph
(
PrimState
m
)
d
v
e
->
m
()
addNodes
n
(
MGraph
g
)
=
unsafePrimToPrim
$
igraphAddVertices
g
n
nullPtr
addLNodes
labels
(
MLGraph
g
)
=
unsafePrimToPrim
$
withAttr
vertexAttr
labels
$
\
attr
->
-- | Add nodes with labels to the graph.
withPtrs
[
attr
]
(
igraphAddVertices
g
n
.
castPtr
)
addLNodes
::
(
Serialize
v
,
PrimMonad
m
)
where
=>
[
v
]
-- ^ vertices' labels
n
=
length
labels
->
MGraph
(
PrimState
m
)
d
v
e
->
m
()
addLNodes
labels
(
MGraph
g
)
=
unsafePrimToPrim
$
-- | Delete nodes from the graph.
withAttr
vertexAttr
labels
$
\
attr
->
delNodes
::
PrimMonad
m
=>
[
Int
]
->
MLGraph
(
PrimState
m
)
d
v
e
->
m
(
)
withPtrs
[
attr
]
(
igraphAddVertices
g
n
.
castPtr
)
delNodes
ns
(
MLGraph
g
)
=
unsafePrimToPrim
$
withVerticesList
ns
$
\
vs
->
where
igraphDeleteVertices
g
v
s
n
=
length
label
s
-- | Add edges to
the graph.
-- | Delete nodes from
the graph.
addEdges
::
PrimMonad
m
=>
[(
Int
,
Int
)]
->
ML
Graph
(
PrimState
m
)
d
v
e
->
m
()
delNodes
::
PrimMonad
m
=>
[
Int
]
->
M
Graph
(
PrimState
m
)
d
v
e
->
m
()
addEdges
es
(
MLGraph
g
)
=
unsafePrimToPrim
$
withList
xs
$
\
vec
->
delNodes
ns
(
MGraph
g
)
=
unsafePrimToPrim
$
withVerticesList
ns
$
\
vs
->
igraphAddEdges
g
vec
nullPtr
igraphDeleteVertices
g
vs
where
xs
=
concatMap
(
\
(
a
,
b
)
->
[
a
,
b
]
)
es
-- | Add edges to the graph.
addEdges
::
PrimMonad
m
=>
[(
Int
,
Int
)]
->
MGraph
(
PrimState
m
)
d
v
e
->
m
()
-- | Add edges with labels to the graph.
addEdges
es
(
MGraph
g
)
=
unsafePrimToPrim
$
withList
xs
$
\
vec
->
addLEdges
::
(
PrimMonad
m
,
Serialize
e
)
=>
[
LEdge
e
]
->
MLGraph
(
PrimState
m
)
d
v
e
->
m
()
igraphAddEdges
g
vec
nullPtr
addLEdges
es
(
MLGraph
g
)
=
unsafePrimToPrim
$
where
withAttr
edgeAttr
vs
$
\
attr
->
withList
(
concat
xs
)
$
\
vec
->
xs
=
concatMap
(
\
(
a
,
b
)
->
[
a
,
b
]
)
es
withPtrs
[
attr
]
(
igraphAddEdges
g
vec
.
castPtr
)
where
-- | Add edges with labels to the graph.
(
xs
,
vs
)
=
unzip
$
map
(
\
((
a
,
b
),
v
)
->
([
a
,
b
],
v
)
)
es
addLEdges
::
(
PrimMonad
m
,
Serialize
e
)
=>
[
LEdge
e
]
->
MGraph
(
PrimState
m
)
d
v
e
->
m
()
-- | Delete edges from the graph.
addLEdges
es
(
MGraph
g
)
=
unsafePrimToPrim
$
delEdges
::
PrimMonad
m
=>
[(
Int
,
Int
)]
->
MLGraph
(
PrimState
m
)
d
v
e
->
m
()
withAttr
edgeAttr
vs
$
\
attr
->
withList
(
concat
xs
)
$
\
vec
->
withPtrs
[
attr
]
(
igraphAddEdges
g
vec
.
castPtr
)
instance
MGraph
U
where
where
new
n
=
unsafePrimToPrim
$
igraphInit
>>=
igraphNew
n
False
>>=
return
.
MLGraph
(
xs
,
vs
)
=
unzip
$
map
(
\
((
a
,
b
),
v
)
->
([
a
,
b
],
v
)
)
es
delEdges
es
(
MLGraph
g
)
=
unsafePrimToPrim
$
do
-- | Delete edges from the graph.
eids
<-
forM
es
$
\
(
fr
,
to
)
->
igraphGetEid
g
fr
to
False
True
delEdges
::
forall
m
d
v
e
.
(
SingI
d
,
PrimMonad
m
)
withEdgeIdsList
eids
(
igraphDeleteEdges
g
)
=>
[(
Int
,
Int
)]
->
MGraph
(
PrimState
m
)
d
v
e
->
m
(
)
delEdges
es
(
MGraph
g
)
=
unsafePrimToPrim
$
do
instance
MGraph
D
wher
e
eids
<-
forM
es
$
\
(
fr
,
to
)
->
igraphGetEid
g
fr
to
directed
Tru
e
new
n
=
unsafePrimToPrim
$
igraphInit
>>=
igraphNew
n
True
>>=
return
.
MLGraph
withEdgeIdsList
eids
(
igraphDeleteEdges
g
)
where
d
elEdges
es
(
MLGraph
g
)
=
unsafePrimToPrim
$
do
d
irected
=
case
fromSing
(
sing
::
Sing
d
)
of
eids
<-
forM
es
$
\
(
fr
,
to
)
->
igraphGetEid
g
fr
to
True
True
D
->
True
withEdgeIdsList
eids
(
igraphDeleteEdges
g
)
U
->
False
-- | Set node attribute.
-- | Set node attribute.
setNodeAttr
::
(
PrimMonad
m
,
Serialize
v
)
setNodeAttr
::
(
PrimMonad
m
,
Serialize
v
)
=>
Int
-- ^ Node id
=>
Int
-- ^ Node id
->
v
->
v
->
M
L
Graph
(
PrimState
m
)
d
v
e
->
MGraph
(
PrimState
m
)
d
v
e
->
m
()
->
m
()
setNodeAttr
nodeId
x
(
M
L
Graph
gr
)
=
unsafePrimToPrim
$
setNodeAttr
nodeId
x
(
MGraph
gr
)
=
unsafePrimToPrim
$
withByteString
(
encode
x
)
$
\
bs
->
do
withByteString
(
encode
x
)
$
\
bs
->
do
err
<-
igraphHaskellAttributeVASSet
gr
vertexAttr
nodeId
bs
err
<-
igraphHaskellAttributeVASSet
gr
vertexAttr
nodeId
bs
when
(
err
/=
0
)
$
error
"Fail to set node attribute!"
when
(
err
/=
0
)
$
error
"Fail to set node attribute!"
...
@@ -90,9 +100,9 @@ setNodeAttr nodeId x (MLGraph gr) = unsafePrimToPrim $
...
@@ -90,9 +100,9 @@ setNodeAttr nodeId x (MLGraph gr) = unsafePrimToPrim $
setEdgeAttr
::
(
PrimMonad
m
,
Serialize
e
)
setEdgeAttr
::
(
PrimMonad
m
,
Serialize
e
)
=>
Int
-- ^ Edge id
=>
Int
-- ^ Edge id
->
e
->
e
->
M
L
Graph
(
PrimState
m
)
d
v
e
->
MGraph
(
PrimState
m
)
d
v
e
->
m
()
->
m
()
setEdgeAttr
edgeId
x
(
M
L
Graph
gr
)
=
unsafePrimToPrim
$
setEdgeAttr
edgeId
x
(
MGraph
gr
)
=
unsafePrimToPrim
$
withByteString
(
encode
x
)
$
\
bs
->
do
withByteString
(
encode
x
)
$
\
bs
->
do
err
<-
igraphHaskellAttributeEASSet
gr
edgeAttr
edgeId
bs
err
<-
igraphHaskellAttributeEASSet
gr
edgeAttr
edgeId
bs
when
(
err
/=
0
)
$
error
"Fail to set edge attribute!"
when
(
err
/=
0
)
$
error
"Fail to set edge attribute!"
src/IGraph/Read.hs
View file @
6ce9fdfd
...
@@ -4,20 +4,21 @@ module IGraph.Read
...
@@ -4,20 +4,21 @@ module IGraph.Read
,
readAdjMatrixWeighted
,
readAdjMatrixWeighted
)
where
)
where
import
qualified
Data.ByteString.Char8
as
B
import
qualified
Data.ByteString.Char8
as
B
import
Data.ByteString.Lex.Fractional
(
readSigned
,
readExponential
)
import
Data.ByteString.Lex.Fractional
(
readExponential
,
readSigned
)
import
Data.Maybe
(
fromJust
)
import
Data.Maybe
(
fromJust
)
import
Data.Singletons
(
SingI
)
import
IGraph
import
IGraph
readDouble
::
B
.
ByteString
->
Double
readDouble
::
B
.
ByteString
->
Double
readDouble
=
fst
.
fromJust
.
readSigned
readExponential
readDouble
=
fst
.
fromJust
.
readSigned
readExponential
{-# INLINE readDouble #-}
{-# INLINE readDouble #-}
readAdjMatrix
::
Graph
d
=>
FilePath
->
IO
(
L
Graph
d
B
.
ByteString
()
)
readAdjMatrix
::
SingI
d
=>
FilePath
->
IO
(
Graph
d
B
.
ByteString
()
)
readAdjMatrix
=
fmap
fromAdjMatrix
.
B
.
readFile
readAdjMatrix
=
fmap
fromAdjMatrix
.
B
.
readFile
fromAdjMatrix
::
Graph
d
=>
B
.
ByteString
->
L
Graph
d
B
.
ByteString
()
fromAdjMatrix
::
SingI
d
=>
B
.
ByteString
->
Graph
d
B
.
ByteString
()
fromAdjMatrix
bs
=
fromAdjMatrix
bs
=
let
(
header
:
xs
)
=
B
.
lines
bs
let
(
header
:
xs
)
=
B
.
lines
bs
mat
=
map
(
map
readDouble
.
B
.
words
)
xs
mat
=
map
(
map
readDouble
.
B
.
words
)
xs
...
@@ -31,7 +32,7 @@ fromAdjMatrix bs =
...
@@ -31,7 +32,7 @@ fromAdjMatrix bs =
f
((
i
,
j
),
v
)
=
i
<
j
&&
v
/=
0
f
((
i
,
j
),
v
)
=
i
<
j
&&
v
/=
0
{-# INLINE fromAdjMatrix #-}
{-# INLINE fromAdjMatrix #-}
readAdjMatrixWeighted
::
Graph
d
=>
FilePath
->
IO
(
L
Graph
d
B
.
ByteString
Double
)
readAdjMatrixWeighted
::
SingI
d
=>
FilePath
->
IO
(
Graph
d
B
.
ByteString
Double
)
readAdjMatrixWeighted
fl
=
do
readAdjMatrixWeighted
fl
=
do
c
<-
B
.
readFile
fl
c
<-
B
.
readFile
fl
let
(
header
:
xs
)
=
B
.
lines
c
let
(
header
:
xs
)
=
B
.
lines
c
...
...
src/IGraph/Structure.chs
View file @
6ce9fdfd
...
@@ -15,6 +15,7 @@ import qualified Data.HashMap.Strict as M
...
@@ -15,6 +15,7 @@ import qualified Data.HashMap.Strict as M
import Data.Serialize (Serialize, decode)
import Data.Serialize (Serialize, decode)
import System.IO.Unsafe (unsafePerformIO)
import System.IO.Unsafe (unsafePerformIO)
import Data.Maybe
import Data.Maybe
import Data.Singletons (SingI)
import Foreign
import Foreign
import Foreign.C.Types
import Foreign.C.Types
...
@@ -26,14 +27,14 @@ import IGraph.Mutable
...
@@ -26,14 +27,14 @@ import IGraph.Mutable
#include "igraph/igraph.h"
#include "igraph/igraph.h"
inducedSubgraph :: (Hashable v, Eq v, Serialize v) =>
LGraph d v e -> [Int] -> L
Graph d v e
inducedSubgraph :: (Hashable v, Eq v, Serialize v) =>
Graph d v e -> [Int] ->
Graph d v e
inducedSubgraph gr nds = unsafePerformIO $ withVerticesList nds $ \vs ->
inducedSubgraph gr nds = unsafePerformIO $ withVerticesList nds $ \vs ->
igraphInducedSubgraph (_graph gr) vs IgraphSubgraphCreateFromScratch >>=
igraphInducedSubgraph (_graph gr) vs IgraphSubgraphCreateFromScratch >>=
unsafeFreeze . M
L
Graph
unsafeFreeze . MGraph
-- | Closeness centrality
-- | Closeness centrality
closeness :: [Int] -- ^ vertices
closeness :: [Int] -- ^ vertices
->
L
Graph d v e
-> Graph d v e
-> Maybe [Double] -- ^ optional edge weights
-> Maybe [Double] -- ^ optional edge weights
-> Neimode
-> Neimode
-> Bool -- ^ whether to normalize
-> Bool -- ^ whether to normalize
...
@@ -45,7 +46,7 @@ closeness nds gr ws mode normal = unsafePerformIO $ allocaVector $ \result ->
...
@@ -45,7 +46,7 @@ closeness nds gr ws mode normal = unsafePerformIO $ allocaVector $ \result ->
-- | Betweenness centrality
-- | Betweenness centrality
betweenness :: [Int]
betweenness :: [Int]
->
L
Graph d v e
-> Graph d v e
-> Maybe [Double]
-> Maybe [Double]
-> [Double]
-> [Double]
betweenness nds gr ws = unsafePerformIO $ allocaVector $ \result ->
betweenness nds gr ws = unsafePerformIO $ allocaVector $ \result ->
...
@@ -54,7 +55,7 @@ betweenness nds gr ws = unsafePerformIO $ allocaVector $ \result ->
...
@@ -54,7 +55,7 @@ betweenness nds gr ws = unsafePerformIO $ allocaVector $ \result ->
toList result
toList result
-- | Eigenvector centrality
-- | Eigenvector centrality
eigenvectorCentrality ::
L
Graph d v e
eigenvectorCentrality :: Graph d v e
-> Maybe [Double]
-> Maybe [Double]
-> [Double]
-> [Double]
eigenvectorCentrality gr ws = unsafePerformIO $ allocaArpackOpt $ \arparck ->
eigenvectorCentrality gr ws = unsafePerformIO $ allocaArpackOpt $ \arparck ->
...
@@ -63,8 +64,8 @@ eigenvectorCentrality gr ws = unsafePerformIO $ allocaArpackOpt $ \arparck ->
...
@@ -63,8 +64,8 @@ eigenvectorCentrality gr ws = unsafePerformIO $ allocaArpackOpt $ \arparck ->
toList result
toList result
-- | Google's PageRank
-- | Google's PageRank
pagerank ::
Graph
d
pagerank ::
SingI
d
=>
L
Graph d v e
=> Graph d v e
-> Maybe [Double] -- ^ edge weights
-> Maybe [Double] -- ^ edge weights
-> Double -- ^ damping factor, usually around 0.85
-> Double -- ^ damping factor, usually around 0.85
-> [Double]
-> [Double]
...
@@ -81,8 +82,8 @@ pagerank gr ws d
...
@@ -81,8 +82,8 @@ pagerank gr ws d
m = nEdges gr
m = nEdges gr
-- | Personalized PageRank.
-- | Personalized PageRank.
personalizedPagerank ::
Graph
d
personalizedPagerank ::
SingI
d
=>
L
Graph d v e
=> Graph d v e
-> [Double] -- ^ reset probability
-> [Double] -- ^ reset probability
-> Maybe [Double]
-> Maybe [Double]
-> Double
-> Double
...
...
src/IGraph/Types.hs
View file @
6ce9fdfd
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module
IGraph.Types
where
module
IGraph.Types
where
import
Data.Singletons.Prelude
import
Data.Singletons.TH
$
(
singletons
[
d
|
data EdgeType = D
| U
deriving (Show, Read, Eq)
|]
)
type
Node
=
Int
type
Node
=
Int
type
LNode
a
=
(
Node
,
a
)
type
LNode
a
=
(
Node
,
a
)
type
Edge
=
(
Node
,
Node
)
type
Edge
=
(
Node
,
Node
)
type
LEdge
a
=
(
Edge
,
a
)
type
LEdge
a
=
(
Edge
,
a
)
-- | Undirected graph.
data
U
-- | Directed graph.
data
D
vertexAttr
::
String
vertexAttr
::
String
vertexAttr
=
"vertex_attribute"
vertexAttr
=
"vertex_attribute"
...
...
tests/Test/Attributes.hs
View file @
6ce9fdfd
{-# LANGUAGE DataKinds #-}
module
Test.Attributes
module
Test.Attributes
(
tests
(
tests
)
where
)
where
...
@@ -31,14 +32,14 @@ tests = testGroup "Attribute tests"
...
@@ -31,14 +32,14 @@ tests = testGroup "Attribute tests"
nodeLabelTest
::
TestTree
nodeLabelTest
::
TestTree
nodeLabelTest
=
testCase
"node label test"
$
do
nodeLabelTest
=
testCase
"node label test"
$
do
let
ns
=
sort
$
map
show
[
38
..
7000
]
let
ns
=
sort
$
map
show
[
38
..
7000
]
gr
=
mkGraph
ns
[]
::
LGraph
D
String
()
gr
=
mkGraph
ns
[]
::
Graph
'
D
String
()
assertBool
""
$
sort
(
map
(
nodeLab
gr
)
$
nodes
gr
)
==
ns
assertBool
""
$
sort
(
map
(
nodeLab
gr
)
$
nodes
gr
)
==
ns
labelTest
::
TestTree
labelTest
::
TestTree
labelTest
=
testCase
"edge label test"
$
do
labelTest
=
testCase
"edge label test"
$
do
dat
<-
randEdges
1000
10000
dat
<-
randEdges
1000
10000
let
es
=
sort
$
zipWith
(
\
a
b
->
(
a
,
b
))
dat
$
map
show
[
1
..
]
let
es
=
sort
$
zipWith
(
\
a
b
->
(
a
,
b
))
dat
$
map
show
[
1
..
]
gr
=
fromLabeledEdges
es
::
LGraph
D
Int
String
gr
=
fromLabeledEdges
es
::
Graph
'
D
Int
String
es'
=
sort
$
map
(
\
(
a
,
b
)
->
((
nodeLab
gr
a
,
nodeLab
gr
b
),
edgeLab
gr
(
a
,
b
)))
$
edges
gr
es'
=
sort
$
map
(
\
(
a
,
b
)
->
((
nodeLab
gr
a
,
nodeLab
gr
b
),
edgeLab
gr
(
a
,
b
)))
$
edges
gr
assertBool
""
$
es
==
es'
assertBool
""
$
es
==
es'
...
@@ -48,8 +49,8 @@ serializeTest = testCase "serialize test" $ do
...
@@ -48,8 +49,8 @@ serializeTest = testCase "serialize test" $ do
let
es
=
map
(
\
(
a
,
b
)
->
(
let
es
=
map
(
\
(
a
,
b
)
->
(
(
defaultNodeAttributes
{
_nodeZindex
=
a
}
(
defaultNodeAttributes
{
_nodeZindex
=
a
}
,
defaultNodeAttributes
{
_nodeZindex
=
b
}),
defaultEdgeAttributes
)
)
dat
,
defaultNodeAttributes
{
_nodeZindex
=
b
}),
defaultEdgeAttributes
)
)
dat
gr
=
fromLabeledEdges
es
::
LGraph
D
NodeAttr
EdgeAttr
gr
=
fromLabeledEdges
es
::
Graph
'
D
NodeAttr
EdgeAttr
gr'
::
LGraph
D
NodeAttr
EdgeAttr
gr'
::
Graph
'
D
NodeAttr
EdgeAttr
gr'
=
case
decode
$
encode
gr
of
gr'
=
case
decode
$
encode
gr
of
Left
msg
->
error
msg
Left
msg
->
error
msg
Right
r
->
r
Right
r
->
r
...
...
tests/Test/Basic.hs
View file @
6ce9fdfd
{-# LANGUAGE DataKinds #-}
module
Test.Basic
module
Test.Basic
(
tests
(
tests
)
where
)
where
...
@@ -33,8 +34,8 @@ graphCreation = testGroup "Graph creation"
...
@@ -33,8 +34,8 @@ graphCreation = testGroup "Graph creation"
where
where
edgeList
=
sort
$
unsafePerformIO
$
randEdges
1000
100
edgeList
=
sort
$
unsafePerformIO
$
randEdges
1000
100
m
=
length
edgeList
m
=
length
edgeList
gr
=
mkGraph
(
replicate
100
()
)
$
zip
edgeList
$
repeat
()
::
LGraph
D
()
()
gr
=
mkGraph
(
replicate
100
()
)
$
zip
edgeList
$
repeat
()
::
Graph
'
D
()
()
simple
=
mkGraph
(
replicate
3
()
)
$
zip
[(
0
,
1
),(
1
,
2
),(
2
,
0
)]
$
repeat
()
::
LGraph
D
()
()
simple
=
mkGraph
(
replicate
3
()
)
$
zip
[(
0
,
1
),(
1
,
2
),(
2
,
0
)]
$
repeat
()
::
Graph
'
D
()
()
graphCreationLabeled
::
TestTree
graphCreationLabeled
::
TestTree
graphCreationLabeled
=
testGroup
"Graph creation -- with labels"
graphCreationLabeled
=
testGroup
"Graph creation -- with labels"
...
@@ -49,14 +50,14 @@ graphCreationLabeled = testGroup "Graph creation -- with labels"
...
@@ -49,14 +50,14 @@ graphCreationLabeled = testGroup "Graph creation -- with labels"
randEdges
10000
1000
)
$
repeat
1
randEdges
10000
1000
)
$
repeat
1
n
=
length
$
nubSort
$
concatMap
(
\
((
a
,
b
),
_
)
->
[
a
,
b
])
edgeList
n
=
length
$
nubSort
$
concatMap
(
\
((
a
,
b
),
_
)
->
[
a
,
b
])
edgeList
m
=
length
edgeList
m
=
length
edgeList
gr
=
fromLabeledEdges
edgeList
::
LGraph
D
String
Int
gr
=
fromLabeledEdges
edgeList
::
Graph
'
D
String
Int
gr'
=
unsafePerformIO
$
fromLabeledEdges'
edgeList
yieldMany
::
LGraph
D
String
Int
gr'
=
unsafePerformIO
$
fromLabeledEdges'
edgeList
yieldMany
::
Graph
'
D
String
Int
graphEdit
::
TestTree
graphEdit
::
TestTree
graphEdit
=
testGroup
"Graph editing"
graphEdit
=
testGroup
"Graph editing"
[
testCase
""
$
[(
1
,
2
)]
@=?
(
sort
$
edges
simple'
)
]
[
testCase
""
$
[(
1
,
2
)]
@=?
(
sort
$
edges
simple'
)
]
where
where
simple
=
mkGraph
(
replicate
3
()
)
$
zip
[(
0
,
1
),(
1
,
2
),(
2
,
0
)]
$
repeat
()
::
LGraph
U
()
()
simple
=
mkGraph
(
replicate
3
()
)
$
zip
[(
0
,
1
),(
1
,
2
),(
2
,
0
)]
$
repeat
()
::
Graph
'
U
()
()
simple'
=
runST
$
do
simple'
=
runST
$
do
g
<-
thaw
simple
g
<-
thaw
simple
delEdges
[(
0
,
1
),(
0
,
2
)]
g
delEdges
[(
0
,
1
),(
0
,
2
)]
g
...
...
tests/Test/Structure.hs
View file @
6ce9fdfd
{-# LANGUAGE DataKinds #-}
module
Test.Structure
module
Test.Structure
(
tests
(
tests
)
where
)
where
...
@@ -27,7 +28,7 @@ subGraphs = testGroup "generate induced subgraphs"
...
@@ -27,7 +28,7 @@ subGraphs = testGroup "generate induced subgraphs"
,
[
"a"
,
"c"
],
[(
"a"
,
"c"
),
(
"c"
,
"a"
)]
)
,
[
"a"
,
"c"
],
[(
"a"
,
"c"
),
(
"c"
,
"a"
)]
)
test
(
ori
,
ns
,
expect
)
=
sort
expect
@=?
sort
result
test
(
ori
,
ns
,
expect
)
=
sort
expect
@=?
sort
result
where
where
gr
=
fromLabeledEdges
$
zip
ori
$
repeat
()
::
LGraph
D
String
()
gr
=
fromLabeledEdges
$
zip
ori
$
repeat
()
::
Graph
'
D
String
()
ns'
=
map
(
head
.
getNodes
gr
)
ns
ns'
=
map
(
head
.
getNodes
gr
)
ns
gr'
=
inducedSubgraph
gr
ns'
gr'
=
inducedSubgraph
gr
ns'
result
=
map
(
nodeLab
gr'
***
nodeLab
gr'
)
$
edges
gr'
result
=
map
(
nodeLab
gr'
***
nodeLab
gr'
)
$
edges
gr'
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment