packages feed

pangraph (empty) → 0.1.1.5

raw patch · 16 files changed

+585/−0 lines, 16 filesdep +HUnitdep +algebraic-graphsdep +basesetup-changed

Dependencies added: HUnit, algebraic-graphs, base, bytestring, containers, hexml, pangraph

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author name here (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Author name here nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ pangraph.cabal view
@@ -0,0 +1,48 @@+name:                 pangraph+version:              0.1.1.5+synopsis:             A set of parsers for graph languages.+description:          A package allowing parsing of graph files into graph library datatypes. With aim the cope with large networks and provide translations between graph libraries. Like a pandoc but for graphs. This is my first library so any feedback and help is appreicated. For example use please see the homepage.+homepage:             https://github.com/tuura/pangraph#readme+license:              BSD3+license-file:         LICENSE+author:               Joe Scott+maintainer:           joseph-scott@hotmail.co.uk+copyright:            2017 Joe Scott+category:             graphs, library, data-structures, parser, xml+build-type:           Simple+cabal-version:        >=1.10+tested-with:          GHC==8.0.2++library+  hs-source-dirs:     src+  exposed-modules:    Pangraph+                   ,  Pangraph.Containers+                   ,  Pangraph.GraphML.Parser+                   ,  Pangraph.GraphML.Writer+                   ,  Pangraph.Internal.XMLTemplate+                   ,  Pangraph.Examples.Reading+                   ,  Pangraph.Examples.Writing+                   ,  Pangraph.Examples.ToContainersGraph+                   ,  Pangraph.Examples.SampleGraph+  build-depends:      base >= 4.8 && < 5+                   ,  bytestring+                   ,  hexml+                   ,  containers+                   ,  algebraic-graphs+  default-language:   Haskell2010+  GHC-options:        -Wall -fwarn-tabs++test-suite pangraph-test+  type:               exitcode-stdio-1.0+  hs-source-dirs:     test+  main-is:            Main.hs+  other-modules:      Show+                   ,  GraphML+                   ,  Containers+  build-depends:      base >= 4.8 && < 5+                   ,  pangraph+                   ,  bytestring+                   ,  HUnit+                   ,  containers+  default-language:   Haskell2010+  GHC-options:        -Wall -fwarn-tabs -fbreak-on-exception
+ src/Pangraph.hs view
@@ -0,0 +1,142 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeFamilies #-}++module Pangraph (+    -- * Abstract Types+    Pangraph, Edge, Vertex, Attribute,+    Key, Value, VertexID, EdgeID,++    -- * Constructors+    makePangraph, makeEdge, makeVertex,++    -- * Pangraph Getters+    edgeList, vertexList, lookupVertex, lookupEdge,++    -- * Getters on Vertex and Edge+    edgeAttributes, vertexAttributes,+    edgeEndpoints, edgeID, vertexID++) where++import Data.Maybe            (mapMaybe)+import Data.Map.Strict       (Map)+import qualified Data.Map.Strict  as Map+import qualified Data.ByteString  as BS+import qualified Algebra.Graph.Class as Alga++-- | The 'Pangraph' type is the core intermediate type between abstract representations of graphs.+data Pangraph = Pangraph+  { vertices' :: Map VertexID Vertex+  , edges' :: Map EdgeID Edge+  } deriving (Eq)+-- | A Vertex holds ['Attribute'] and must have a unique 'VertexID' to be constructed with 'makeVertex'.+data Vertex = Vertex+  { vertexID' :: VertexID+  , vertexAttributes' :: [Attribute]+  } deriving (Eq)+-- | Edges also reqiure ['Attribute'] and a tuple of 'Vertex' passed as connections to be constructed with 'makeEdge'+data Edge = Edge+  { edgeID' :: Maybe EdgeID+  , edgeAttributes' :: [Attribute]+  , endpoints' :: (Vertex, Vertex)+  } deriving (Eq)++-- | A type exposed for lookup in the resulting lists.+type EdgeID = Int+-- | A field that is Maybe internally is exposed for lookup.+type VertexID = BS.ByteString+-- | The type alias for storage of fields.+type Attribute = (Key, Value)+-- | The 'Key' in the tuple that makes up 'Attribute'.+type Key = BS.ByteString+-- | The 'Value' in the tuple that makes up 'Attribute'.+type Value = BS.ByteString++type MalformedEdge = (Edge, (Maybe Vertex, Maybe Vertex))++instance Show Pangraph where+  show p = "makePangraph " ++ show (Map.elems (vertices' p)) ++ " " ++ show (Map.elems (edges' p))++instance Show Vertex where+  show (Vertex i as) = unwords ["makeVertex", show i, show as]++instance Show Edge where+  show (Edge _ as e) = unwords ["makeEdge", show as, show e]++instance Alga.ToGraph Pangraph where+    type ToVertex Pangraph = Vertex+    toGraph p = Alga.graph (vertexList p) (map edgeEndpoints $ edgeList p)++-- * List based constructors++-- | Takes lists of 'Vertex' and 'Edge' to produce 'Just Pangraph' if the graph is correctly formed.+makePangraph :: [Vertex] -> [Edge] -> Maybe Pangraph+makePangraph vs es = case verifyGraph vertexMap es of+  [] -> Just $ Pangraph vertexMap edgeMap+  _ -> Nothing+  where+    vertexMap :: Map VertexID Vertex+    vertexMap = Map.fromList $ zip (map vertexID vs) vs+    edgeMap :: Map EdgeID Edge+    edgeMap = Map.fromList indexEdges+    indexEdges :: [(EdgeID, Edge)]+    indexEdges = map (\ (i, Edge _ as a) -> (i, Edge (Just i) as a )) $ zip [0..] es++verifyGraph :: Map VertexID Vertex -> [Edge] -> [MalformedEdge]+verifyGraph vs = mapMaybe (\e -> lookupEndpoints (e, edgeEndpoints e))+  where+    lookupEndpoints :: (Edge, (Vertex, Vertex)) ->  Maybe MalformedEdge+    lookupEndpoints (e, (v1,v2)) =+      case (Map.lookup (vertexID v1) vs, Map.lookup (vertexID v2) vs) of+        (Just _ , Just _)  -> Nothing+        (Nothing, Just _)  -> Just (e, (Just v1, Nothing))+        (Just _ , Nothing) -> Just (e, (Nothing, Just v2))+        (Nothing, Nothing) -> Just (e, (Just v1, Just v2))++-- | Edge constructor+makeEdge :: [Attribute] -> (Vertex, Vertex) -> Edge+makeEdge = Edge Nothing++-- | Vertex constructor+makeVertex :: VertexID -> [Attribute] -> Vertex+makeVertex = Vertex++-- * Pangraph Getters++-- | Returns the ['Edge'] from a 'Pangraph' instance+edgeList :: Pangraph -> [Edge]+edgeList p = Map.elems $ edges' p++-- | Returns the ['Vertex'] from a 'Pangraph' instance+vertexList :: Pangraph -> [Vertex]+vertexList p = Map.elems $ vertices' p++-- | Lookup of the 'EdgeID' in a 'Pangraph'. Complexity: /O(log n)/+lookupEdge :: EdgeID -> Pangraph -> Maybe Edge+lookupEdge key p = Map.lookup key $ edges' p++-- | Lookup of the 'VertexID' in a 'Pangraph'. Complexity: /O(log n)/+lookupVertex :: VertexID -> Pangraph -> Maybe Vertex+lookupVertex key p = Map.lookup key $ vertices' p++-- * Getters on 'Edge' and 'Vertex'++-- | Returns the ['Attribute'] of an 'Edge'+edgeAttributes :: Edge -> [Attribute]+edgeAttributes = edgeAttributes'++-- | Returns the ['Attribute'] list of an 'Edge'+vertexAttributes :: Vertex -> [Attribute]+vertexAttributes = vertexAttributes'++-- | Returns the endpoint of tupled 'Vertex' of an 'Edge'+edgeEndpoints :: Edge -> (Vertex, Vertex)+edgeEndpoints = endpoints'++-- | Returns the EdgeID if it has one. 'Edge's are given a new 'EdgeID' when they are passed and retrived from a 'Pangraph'+edgeID :: Edge -> Maybe EdgeID+edgeID = edgeID'++-- | Returns a 'VertexID'+vertexID :: Vertex -> VertexID+vertexID = vertexID'
+ src/Pangraph/Containers.hs view
@@ -0,0 +1,39 @@+module Pangraph.Containers+    ( convert+    ) where++import Pangraph+import qualified Data.Graph as CGraph++import Data.Maybe       (fromMaybe)+import Data.List        (groupBy, sort)+import Control.Arrow    ((***))++import Data.Map.Strict  (Map)+import qualified Data.Map.Strict as Map++-- | Transforms a 'Pangraph' in a 'CGraph.Graph'.+convert :: Pangraph -> (CGraph.Graph, CGraph.Vertex -> (Vertex, VertexID, [VertexID]), VertexID -> Maybe CGraph.Vertex)+convert p = CGraph.graphFromEdges getVertices+  where+    -- A helper function for getting the IDs of endpoints.+    edgeEndpointIDs :: Edge -> (VertexID, VertexID)+    edgeEndpointIDs e = (vertexID *** vertexID) $ edgeEndpoints e++    -- Create an Edge Map using VertexID grouping edge sources together.+    edgeMap :: Map VertexID [VertexID]+    edgeMap = (Map.fromList . groupIDs) $ map edgeEndpointIDs $ edgeList p++    -- Lookup the edges for this vertex. Returning empty list on Nothing.+    vertexConnections :: Vertex -> [VertexID]+    vertexConnections v = fromMaybe [] (Map.lookup (vertexID v) edgeMap)++    -- Convert Pangraph Vertex into a form ready to collect Edges from the Pangraph+    getVertices :: [(Vertex, VertexID, [VertexID])]+    getVertices = map (\v ->(v, vertexID v, vertexConnections v)) $ vertexList p++groupIDs :: [(VertexID, VertexID)] -> [(VertexID, [VertexID])]+groupIDs vs = map (\ts -> (fst $ head ts, map snd ts)) groupedEdges+  where+    groupedEdges :: [[(VertexID, VertexID)]]+    groupedEdges = groupBy (\a b -> fst a == fst b) $ sort vs
+ src/Pangraph/Examples/Reading.hs view
@@ -0,0 +1,13 @@+module Pangraph.Examples.Reading where++import Prelude hiding (readFile)++import Data.ByteString (readFile)++import qualified Pangraph.GraphML.Parser as GraphML++main :: IO ()+main = do+  fileName <- getLine+  file <- readFile fileName+  print (GraphML.parse file)
+ src/Pangraph/Examples/SampleGraph.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE OverloadedStrings #-}++module Pangraph.Examples.SampleGraph+    ( smallGraph+    ) where++import Pangraph++smallGraph :: Pangraph+smallGraph = case graph of+  Just p  -> p+  Nothing -> error "Small graph literal failed to construct."+  where+    graph =+      makePangraph+        [makeVertex "n0" [("id","n0")]+        ,makeVertex "n1" [("id","n1")]+        ,makeVertex "n2" [("id","n2")]]+        [makeEdge [("source","n0"),("target","n2")]+          (makeVertex "n0" [("id","n0")]+          ,makeVertex "n2" [("id","n2")])]
+ src/Pangraph/Examples/ToContainersGraph.hs view
@@ -0,0 +1,9 @@+module Pangraph.Examples.ToContainersGraph where++import Pangraph.Containers(convert)+import Pangraph.Examples.SampleGraph(smallGraph)++main :: IO ()+main =+  -- Transform to Containers Data.Graph and print.+  print $ ((\(a,_,_) -> a) . convert) smallGraph
+ src/Pangraph/Examples/Writing.hs view
@@ -0,0 +1,8 @@+module Pangraph.Examples.Writing where++import Pangraph.GraphML.Writer(write)+import Pangraph.Examples.SampleGraph(smallGraph)++main :: IO ()+main =+  print $ write smallGraph
+ src/Pangraph/GraphML/Parser.hs view
@@ -0,0 +1,20 @@+module Pangraph.GraphML.Parser (+parse,+unsafeParse+) where++import Data.Maybe+import qualified Data.ByteString            as BS+import qualified Pangraph                   as P+import qualified Text.XML.Hexml as H+import qualified Pangraph.Internal.XMLTemplate       as PT++-- * Parsing++-- | Returns 'Pangraph' if it can be parsed from a raw GraphML file.+parse :: BS.ByteString -> Maybe P.Pangraph+parse file = either (const Nothing) (PT.hexmlToPangraph PT.graphMLTemplate) (H.parse file)++-- | Like 'parse' except it throws an error on Nothing, which is when parsing fails.+unsafeParse :: BS.ByteString -> P.Pangraph+unsafeParse file = fromMaybe (error "Parse failed") (parse file)
+ src/Pangraph/GraphML/Writer.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE OverloadedStrings #-}++module Pangraph.GraphML.Writer+( write+) where++import Pangraph+import Prelude hiding(concat)+import Data.ByteString(ByteString, append, concat)+import Data.ByteString.Char8(pack)+++-- | Serialise a 'Pangraph' into a GraphML file producing a 'ByteString'.+write :: Pangraph -> ByteString+write p = concat $+    writeHeader  0 :+    writeGraphML 0 :+    writeGraphTag 1 :+    [] +++    map (writeNode 2) (vertexList p) +++    map (writeEdge 2) (edgeList p) +++    [closingTags]++writeHeader :: Int -> ByteString+writeHeader _ = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"++writeGraphML :: Int -> ByteString+writeGraphML _ = "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\" \+  \xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"++writeGraphTag :: Int -> ByteString+writeGraphTag i = getIndentBS i `append` "<graph id=\"G\" edgedefault=\"undirected\">\n"++writeNode :: Int -> Vertex -> ByteString+writeNode i v = concat [getIndentBS i, "<node", nodesAtts, "/>\n"]+  where+    nodesAtts :: ByteString+    nodesAtts = concat $ map writeAttribute (vertexAttributes v)++writeEdge :: Int -> Edge -> ByteString+writeEdge i e = concat [getIndentBS i, "<edge", edgeAtts, "/>\n"]+  where+    edgeAtts :: ByteString+    edgeAtts = concat $ map writeAttribute (edgeAttributes e)++writeAttribute :: Attribute -> ByteString+writeAttribute (a,b) = concat [" ",  a, "=\"",  b, "\""]++closingTags :: ByteString+closingTags = append (getIndentBS 1) $ append "</graph>\n" "</graphml>"++-- Where i is the level of indentation.+getIndentBS :: Int -> ByteString+getIndentBS i = pack $ replicate (2*i) ' '
+ src/Pangraph/Internal/XMLTemplate.hs view
@@ -0,0 +1,87 @@+{-# LANGUAGE OverloadedStrings #-}++module Pangraph.Internal.XMLTemplate+( Template,+  graphMLTemplate,+  hexmlToPangraph+) where++import Data.Maybe++import qualified Pangraph as P++import qualified Text.XML.Hexml as H+import qualified Data.ByteString as BS++-- A list of places to find vertices and extractEdges.+data Template = XML [VertexRule] [EdgeRule]+-- A list of the locations of tags and which elements to take from them.+newtype EdgeRule = EdgeRule [(Path, Element)]+newtype VertexRule = VertexRule [(Path, Element)]++type Path = [BS.ByteString]+type Element = [BS.ByteString]+type HexmlVertex = H.Node++-- A template for graphML, it extracts the vertices and edges.+graphMLTemplate :: Template+graphMLTemplate = XML+  [VertexRule [( ["graphml", "graph", "node"], ["id"])]]+  [EdgeRule [( ["graphml", "graph", "edge"], ["source", "target"] )]]++hexmlToPangraph :: Template -> HexmlVertex -> Maybe P.Pangraph+hexmlToPangraph (XML nt et) root = P.makePangraph n e+  where+    -- Map all the given rules over the XML tree for vertices+    n = concatMap (extractVertices root "id") nt+    -- Map all the given rules over the XML tree for edges+    e = concatMap (extractEdges (assocVertices n) root ) et+    assocVertices :: [P.Vertex] -> [(P.VertexID, P.Vertex)]+    assocVertices vs = zip (map P.vertexID vs) vs++-- Applies the Vertex rule to the Hexml root node, returning a list of pangraph vertices found.+extractVertices :: HexmlVertex -> BS.ByteString -> VertexRule -> [P.Vertex]+extractVertices hexml idElement (VertexRule pe) = concatMap (makeVertex hexml idElement) pe++makeVertex :: HexmlVertex -> BS.ByteString -> (Path, Element) -> [P.Vertex]+makeVertex hexml idElement (path, element) = map (\as -> P.makeVertex (idElem as) as) attList+  where+    idElem :: [P.Attribute] -> P.VertexID+    idElem list =  fromMaybe (error $ "Fatal: node missing id value: " ++ show list)+      (lookup idElement list)+++    attList :: [[P.Attribute]]+    attList = map (getAttributePairs element) $ resolvePath path hexml++-- Applies the edge rule to the Hexml root edge, returning a list of pangraph extractEdges found.+extractEdges:: [(P.VertexID, P.Vertex)] -> HexmlVertex -> EdgeRule -> [P.Edge]+extractEdges verticesAssoc hexml (EdgeRule pe) = concatMap (makeEdge verticesAssoc hexml) pe++makeEdge :: [(P.VertexID, P.Vertex)] ->  HexmlVertex -> (Path, Element) -> [P.Edge]+makeEdge verticesAssoc hexml (path, element) = map (\as -> P.makeEdge as (getPrimitives as)) attList+  where+    getPrimitives :: [P.Attribute] -> (P.Vertex, P.Vertex)+    getPrimitives list = case (lookup src list, lookup dst list) of+      (Just srcID, Just dstID) ->+        case (lookup srcID verticesAssoc, lookup dstID verticesAssoc) of+          (Just vertexSrc, Just vertexDst) -> (vertexSrc, vertexDst)+          _ -> error $ "Fatal: Edge endpoints are not vertices: " ++ show list+      _ -> error $ "Fatal: Edge endpoints not found in attribute list: " ++ show list+    attList :: [[P.Attribute]]+    attList = map (getAttributePairs element) $ resolvePath path hexml+    src = "source"+    dst = "target"++resolvePath:: Path -> HexmlVertex -> [HexmlVertex]+resolvePath [] h = [h]+resolvePath bs h = concatMap (resolvePath (tail bs)) children+  where+    children :: [HexmlVertex]+    children = H.childrenBy h $ head bs++getAttributePairs:: Element -> HexmlVertex -> [P.Attribute]+getAttributePairs e h = map toAttribute $  mapMaybe (H.attributeBy h) e+  where+    toAttribute :: H.Attribute -> P.Attribute+    toAttribute a = (H.attributeName a, H.attributeValue a)
+ test/Containers.hs view
@@ -0,0 +1,13 @@+module Containers+    ( containersTests+    ) where++import Test.HUnit+import Pangraph.Examples.SampleGraph(smallGraph)+import Pangraph.Containers(convert)++containersTests :: [Test]+containersTests = [case1]++case1 :: Test+case1 = TestCase $ assertEqual "Containers Convert case 1" ("array (0,2) [(0,[2]),(1,[]),(2,[])]") $ (show . (\(a,_,_) -> a) . convert) smallGraph
+ test/GraphML.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE OverloadedStrings #-}++module GraphML (+graphmlTests+) where++import Test.HUnit++import Data.Maybe++import Pangraph+import Pangraph.GraphML.Parser+import Pangraph.GraphML.Writer++graphmlTests :: [Test]+graphmlTests = [case1, case2]++case1 :: Test+case1 =+  let+    file = parse "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \+            \<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"\+            \    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\+            \    xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns\+            \     http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\+            \  <graph id=\"G\" edgedefault=\"undirected\">\+            \    <node id=\"n0\"/>\+            \    <node id=\"n1\"/>\+            \    <node id=\"n2\"/>\+            \    <edge id=\"e1\" source=\"n0\" target=\"n2\"/>\+            \    </graph>\+            \</graphml>"+    sampleVertices = [+                      makeVertex "n0" [ ("id","n0")],+                      makeVertex "n1" [ ("id","n1")],+                      makeVertex "n2" [ ("id","n2")]]+    graph = makePangraph sampleVertices+      [makeEdge+        [("source","n0"),("target","n2")]+        (head sampleVertices, sampleVertices !! 2)]+  in TestCase $ assertEqual "GraphML Parse case 1" (graph :: Maybe Pangraph) file++case2 :: Test+case2 =+  let+    sampleVertices = [+                      makeVertex "n0" [ ("id","n0")],+                      makeVertex "n1" [ ("id","n1")],+                      makeVertex "n2" [ ("id","n2")]]+    graph = makePangraph sampleVertices+      [makeEdge+        [("source","n0"),("target","n2")]+        (head sampleVertices, sampleVertices !! 2)]+    justGraph = fromMaybe (error "Sample graph failed to compile") graph+  in TestCase $ assertEqual "GraphML Write case 1" (graph :: Maybe Pangraph) (parse $ write justGraph)
+ test/Main.hs view
@@ -0,0 +1,10 @@+module Main where++import GraphML+import Show+import Containers++import Test.HUnit++main :: IO Counts+main = runTestTT $ TestList $ concat [graphmlTests, showTests, containersTests]
+ test/Show.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE OverloadedStrings #-}++module Show (+showTests+) where++import Data.Maybe+import Test.HUnit+import Pangraph+++showTests :: [Test]+showTests = [case1]++case1 :: Test+case1 =+  let+    literal = "makePangraph [makeVertex \"0\" \+    \[(\"id\",\"0\")],makeVertex \"1\" \+    \[(\"id\",\"1\")]] [makeEdge \+    \[(\"source\",\"0\"),(\"target\",\"1\")] \+    \(makeVertex \"0\" \+    \[(\"id\",\"0\")],makeVertex \"1\" [(\"id\",\"1\")])]"+    sampleVertices = [makeVertex "0" [("id","0")]+                     ,makeVertex "1" [ ("id","1")]]+    graph = show $ fromMaybe+             (error "Sample graph failed to build") $+             makePangraph+               sampleVertices [+               makeEdge+                 [("source","0"), ("target","1")]+                 (head sampleVertices, sampleVertices !! 1)+             ]+  in TestCase $ assertEqual "Show instance case 1" literal (graph :: String)