module Pattern.Graph
(
GraphLens(..)
, nodes
, isNode
, isRelationship
, relationships
, source
, target
, reverseRel
, isWalk
, walks
, walkNodes
, neighbors
, incidentRels
, degree
, connectedComponents
, bfs
, findPath
) where
import Pattern.Core (Pattern(..))
import Data.Maybe (mapMaybe)
import qualified Data.Set as Set
import Data.Map ()
data GraphLens v = GraphLens
{ forall v. GraphLens v -> Pattern v
scopePattern :: Pattern v
, forall v. GraphLens v -> Pattern v -> Bool
testNode :: Pattern v -> Bool
}
nodes :: GraphLens v -> [Pattern v]
nodes :: forall v. GraphLens v -> [Pattern v]
nodes lens :: GraphLens v
lens@(GraphLens (Pattern v
_ [Pattern v]
elems) Pattern v -> Bool
_) =
(Pattern v -> Bool) -> [Pattern v] -> [Pattern v]
forall a. (a -> Bool) -> [a] -> [a]
filter (GraphLens v -> Pattern v -> Bool
forall v. GraphLens v -> Pattern v -> Bool
isNode GraphLens v
lens) [Pattern v]
elems
isNode :: GraphLens v -> Pattern v -> Bool
isNode :: forall v. GraphLens v -> Pattern v -> Bool
isNode (GraphLens Pattern v
_ Pattern v -> Bool
testNodePred) Pattern v
p = Pattern v -> Bool
testNodePred Pattern v
p
isRelationship :: GraphLens v -> Pattern v -> Bool
isRelationship :: forall v. GraphLens v -> Pattern v -> Bool
isRelationship lens :: GraphLens v
lens@(GraphLens Pattern v
_ Pattern v -> Bool
_) p :: Pattern v
p@(Pattern v
_ [Pattern v]
els) =
Bool -> Bool
not (GraphLens v -> Pattern v -> Bool
forall v. GraphLens v -> Pattern v -> Bool
isNode GraphLens v
lens Pattern v
p) Bool -> Bool -> Bool
&&
[Pattern v] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Pattern v]
els Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 Bool -> Bool -> Bool
&&
(Pattern v -> Bool) -> [Pattern v] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (GraphLens v -> Pattern v -> Bool
forall v. GraphLens v -> Pattern v -> Bool
isNode GraphLens v
lens) [Pattern v]
els
relationships :: GraphLens v -> [Pattern v]
relationships :: forall v. GraphLens v -> [Pattern v]
relationships lens :: GraphLens v
lens@(GraphLens (Pattern v
_ [Pattern v]
elems) Pattern v -> Bool
_) =
(Pattern v -> Bool) -> [Pattern v] -> [Pattern v]
forall a. (a -> Bool) -> [a] -> [a]
filter (GraphLens v -> Pattern v -> Bool
forall v. GraphLens v -> Pattern v -> Bool
isRelationship GraphLens v
lens) [Pattern v]
elems
source :: GraphLens v -> Pattern v -> Maybe (Pattern v)
source :: forall v. GraphLens v -> Pattern v -> Maybe (Pattern v)
source GraphLens v
lens p :: Pattern v
p@(Pattern v
_ (Pattern v
s:[Pattern v]
_))
| GraphLens v -> Pattern v -> Bool
forall v. GraphLens v -> Pattern v -> Bool
isRelationship GraphLens v
lens Pattern v
p = Pattern v -> Maybe (Pattern v)
forall a. a -> Maybe a
Just Pattern v
s
| Bool
otherwise = Maybe (Pattern v)
forall a. Maybe a
Nothing
source GraphLens v
_ Pattern v
_ = Maybe (Pattern v)
forall a. Maybe a
Nothing
target :: GraphLens v -> Pattern v -> Maybe (Pattern v)
target :: forall v. GraphLens v -> Pattern v -> Maybe (Pattern v)
target GraphLens v
lens p :: Pattern v
p@(Pattern v
_ [Pattern v
_, Pattern v
t])
| GraphLens v -> Pattern v -> Bool
forall v. GraphLens v -> Pattern v -> Bool
isRelationship GraphLens v
lens Pattern v
p = Pattern v -> Maybe (Pattern v)
forall a. a -> Maybe a
Just Pattern v
t
| Bool
otherwise = Maybe (Pattern v)
forall a. Maybe a
Nothing
target GraphLens v
_ Pattern v
_ = Maybe (Pattern v)
forall a. Maybe a
Nothing
reverseRel :: Pattern v -> Pattern v
reverseRel :: forall v. Pattern v -> Pattern v
reverseRel (Pattern v
v [Pattern v
a, Pattern v
b]) = v -> [Pattern v] -> Pattern v
forall v. v -> [Pattern v] -> Pattern v
Pattern v
v [Pattern v
b, Pattern v
a]
reverseRel Pattern v
p = Pattern v
p
consecutivelyConnected :: Eq v => GraphLens v -> [Pattern v] -> Bool
consecutivelyConnected :: forall v. Eq v => GraphLens v -> [Pattern v] -> Bool
consecutivelyConnected GraphLens v
lens [Pattern v]
rels =
case [Pattern v]
rels of
[] -> Bool
True
[Pattern v
_] -> Bool
True
(Pattern v
r1:Pattern v
r2:[Pattern v]
rest) ->
case (GraphLens v -> Pattern v -> Maybe (Pattern v)
forall v. GraphLens v -> Pattern v -> Maybe (Pattern v)
target GraphLens v
lens Pattern v
r1, GraphLens v -> Pattern v -> Maybe (Pattern v)
forall v. GraphLens v -> Pattern v -> Maybe (Pattern v)
source GraphLens v
lens Pattern v
r2) of
(Just Pattern v
t, Just Pattern v
s) -> Pattern v
t Pattern v -> Pattern v -> Bool
forall a. Eq a => a -> a -> Bool
== Pattern v
s Bool -> Bool -> Bool
&& GraphLens v -> [Pattern v] -> Bool
forall v. Eq v => GraphLens v -> [Pattern v] -> Bool
consecutivelyConnected GraphLens v
lens (Pattern v
r2Pattern v -> [Pattern v] -> [Pattern v]
forall a. a -> [a] -> [a]
:[Pattern v]
rest)
(Maybe (Pattern v), Maybe (Pattern v))
_ -> Bool
False
isWalk :: Eq v => GraphLens v -> Pattern v -> Bool
isWalk :: forall v. Eq v => GraphLens v -> Pattern v -> Bool
isWalk lens :: GraphLens v
lens@(GraphLens Pattern v
_ Pattern v -> Bool
_) p :: Pattern v
p@(Pattern v
_ [Pattern v]
elems) =
Bool -> Bool
not (GraphLens v -> Pattern v -> Bool
forall v. GraphLens v -> Pattern v -> Bool
isNode GraphLens v
lens Pattern v
p) Bool -> Bool -> Bool
&&
(Pattern v -> Bool) -> [Pattern v] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (GraphLens v -> Pattern v -> Bool
forall v. GraphLens v -> Pattern v -> Bool
isRelationship GraphLens v
lens) [Pattern v]
elems Bool -> Bool -> Bool
&&
GraphLens v -> [Pattern v] -> Bool
forall v. Eq v => GraphLens v -> [Pattern v] -> Bool
consecutivelyConnected GraphLens v
lens [Pattern v]
elems
walks :: Eq v => GraphLens v -> [Pattern v]
walks :: forall v. Eq v => GraphLens v -> [Pattern v]
walks lens :: GraphLens v
lens@(GraphLens (Pattern v
_ [Pattern v]
elems) Pattern v -> Bool
_) =
(Pattern v -> Bool) -> [Pattern v] -> [Pattern v]
forall a. (a -> Bool) -> [a] -> [a]
filter (GraphLens v -> Pattern v -> Bool
forall v. Eq v => GraphLens v -> Pattern v -> Bool
isWalk GraphLens v
lens) [Pattern v]
elems
walkNodes :: Eq v => GraphLens v -> Pattern v -> [Pattern v]
walkNodes :: forall v. Eq v => GraphLens v -> Pattern v -> [Pattern v]
walkNodes GraphLens v
lens p :: Pattern v
p@(Pattern v
_ [Pattern v]
rels)
| GraphLens v -> Pattern v -> Bool
forall v. Eq v => GraphLens v -> Pattern v -> Bool
isWalk GraphLens v
lens Pattern v
p = case [Pattern v]
rels of
[] -> []
(Pattern v
r:[Pattern v]
rest) -> case GraphLens v -> Pattern v -> Maybe (Pattern v)
forall v. GraphLens v -> Pattern v -> Maybe (Pattern v)
source GraphLens v
lens Pattern v
r of
Just Pattern v
s -> Pattern v
s Pattern v -> [Pattern v] -> [Pattern v]
forall a. a -> [a] -> [a]
: (Pattern v -> Maybe (Pattern v)) -> [Pattern v] -> [Pattern v]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (GraphLens v -> Pattern v -> Maybe (Pattern v)
forall v. GraphLens v -> Pattern v -> Maybe (Pattern v)
target GraphLens v
lens) (Pattern v
rPattern v -> [Pattern v] -> [Pattern v]
forall a. a -> [a] -> [a]
:[Pattern v]
rest)
Maybe (Pattern v)
Nothing -> []
| Bool
otherwise = []
neighbors :: Eq v => GraphLens v -> Pattern v -> [Pattern v]
neighbors :: forall v. Eq v => GraphLens v -> Pattern v -> [Pattern v]
neighbors GraphLens v
lens Pattern v
node =
let rels :: [Pattern v]
rels = GraphLens v -> [Pattern v]
forall v. GraphLens v -> [Pattern v]
relationships GraphLens v
lens
connectedNodes :: [Pattern v]
connectedNodes = (Pattern v -> [Pattern v]) -> [Pattern v] -> [Pattern v]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\Pattern v
r ->
case (GraphLens v -> Pattern v -> Maybe (Pattern v)
forall v. GraphLens v -> Pattern v -> Maybe (Pattern v)
source GraphLens v
lens Pattern v
r, GraphLens v -> Pattern v -> Maybe (Pattern v)
forall v. GraphLens v -> Pattern v -> Maybe (Pattern v)
target GraphLens v
lens Pattern v
r) of
(Just Pattern v
s, Just Pattern v
t) | Pattern v
s Pattern v -> Pattern v -> Bool
forall a. Eq a => a -> a -> Bool
== Pattern v
node -> [Pattern v
t]
| Pattern v
t Pattern v -> Pattern v -> Bool
forall a. Eq a => a -> a -> Bool
== Pattern v
node -> [Pattern v
s]
(Maybe (Pattern v), Maybe (Pattern v))
_ -> []
) [Pattern v]
rels
in [Pattern v]
connectedNodes
incidentRels :: Eq v => GraphLens v -> Pattern v -> [Pattern v]
incidentRels :: forall v. Eq v => GraphLens v -> Pattern v -> [Pattern v]
incidentRels GraphLens v
lens Pattern v
node =
(Pattern v -> Bool) -> [Pattern v] -> [Pattern v]
forall a. (a -> Bool) -> [a] -> [a]
filter (\Pattern v
r ->
case (GraphLens v -> Pattern v -> Maybe (Pattern v)
forall v. GraphLens v -> Pattern v -> Maybe (Pattern v)
source GraphLens v
lens Pattern v
r, GraphLens v -> Pattern v -> Maybe (Pattern v)
forall v. GraphLens v -> Pattern v -> Maybe (Pattern v)
target GraphLens v
lens Pattern v
r) of
(Just Pattern v
s, Maybe (Pattern v)
_) | Pattern v
s Pattern v -> Pattern v -> Bool
forall a. Eq a => a -> a -> Bool
== Pattern v
node -> Bool
True
(Maybe (Pattern v)
_, Just Pattern v
t) | Pattern v
t Pattern v -> Pattern v -> Bool
forall a. Eq a => a -> a -> Bool
== Pattern v
node -> Bool
True
(Maybe (Pattern v), Maybe (Pattern v))
_ -> Bool
False
) (GraphLens v -> [Pattern v]
forall v. GraphLens v -> [Pattern v]
relationships GraphLens v
lens)
degree :: Eq v => GraphLens v -> Pattern v -> Int
degree :: forall v. Eq v => GraphLens v -> Pattern v -> Int
degree GraphLens v
lens Pattern v
node = [Pattern v] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (GraphLens v -> Pattern v -> [Pattern v]
forall v. Eq v => GraphLens v -> Pattern v -> [Pattern v]
incidentRels GraphLens v
lens Pattern v
node)
connectedComponents :: Ord v => GraphLens v -> [[Pattern v]]
connectedComponents :: forall v. Ord v => GraphLens v -> [[Pattern v]]
connectedComponents GraphLens v
lens = GraphLens v
-> [Pattern v] -> Set (Pattern v) -> [[Pattern v]] -> [[Pattern v]]
forall v.
Ord v =>
GraphLens v
-> [Pattern v] -> Set (Pattern v) -> [[Pattern v]] -> [[Pattern v]]
findComponents GraphLens v
lens (GraphLens v -> [Pattern v]
forall v. GraphLens v -> [Pattern v]
nodes GraphLens v
lens) Set (Pattern v)
forall a. Set a
Set.empty []
findComponents :: Ord v => GraphLens v -> [Pattern v] -> Set.Set (Pattern v) -> [[Pattern v]] -> [[Pattern v]]
findComponents :: forall v.
Ord v =>
GraphLens v
-> [Pattern v] -> Set (Pattern v) -> [[Pattern v]] -> [[Pattern v]]
findComponents GraphLens v
_ [] Set (Pattern v)
_ [[Pattern v]]
acc = [[Pattern v]] -> [[Pattern v]]
forall a. [a] -> [a]
reverse [[Pattern v]]
acc
findComponents GraphLens v
lens (Pattern v
n:[Pattern v]
ns) Set (Pattern v)
visited [[Pattern v]]
acc =
if Pattern v -> Set (Pattern v) -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member Pattern v
n Set (Pattern v)
visited
then GraphLens v
-> [Pattern v] -> Set (Pattern v) -> [[Pattern v]] -> [[Pattern v]]
forall v.
Ord v =>
GraphLens v
-> [Pattern v] -> Set (Pattern v) -> [[Pattern v]] -> [[Pattern v]]
findComponents GraphLens v
lens [Pattern v]
ns Set (Pattern v)
visited [[Pattern v]]
acc
else
let component :: [Pattern v]
component = GraphLens v -> Pattern v -> [Pattern v]
forall v. Ord v => GraphLens v -> Pattern v -> [Pattern v]
bfs GraphLens v
lens Pattern v
n
newVisited :: Set (Pattern v)
newVisited = Set (Pattern v) -> Set (Pattern v) -> Set (Pattern v)
forall a. Ord a => Set a -> Set a -> Set a
Set.union Set (Pattern v)
visited ([Pattern v] -> Set (Pattern v)
forall a. Ord a => [a] -> Set a
Set.fromList [Pattern v]
component)
newAcc :: [[Pattern v]]
newAcc = [Pattern v]
component [Pattern v] -> [[Pattern v]] -> [[Pattern v]]
forall a. a -> [a] -> [a]
: [[Pattern v]]
acc
in GraphLens v
-> [Pattern v] -> Set (Pattern v) -> [[Pattern v]] -> [[Pattern v]]
forall v.
Ord v =>
GraphLens v
-> [Pattern v] -> Set (Pattern v) -> [[Pattern v]] -> [[Pattern v]]
findComponents GraphLens v
lens [Pattern v]
ns Set (Pattern v)
newVisited [[Pattern v]]
newAcc
bfs :: Ord v => GraphLens v -> Pattern v -> [Pattern v]
bfs :: forall v. Ord v => GraphLens v -> Pattern v -> [Pattern v]
bfs GraphLens v
lens Pattern v
start = GraphLens v
-> Set (Pattern v) -> [Pattern v] -> [Pattern v] -> [Pattern v]
forall v.
Ord v =>
GraphLens v
-> Set (Pattern v) -> [Pattern v] -> [Pattern v] -> [Pattern v]
bfsHelper GraphLens v
lens Set (Pattern v)
forall a. Set a
Set.empty [Pattern v
start] []
bfsHelper :: Ord v => GraphLens v -> Set.Set (Pattern v) -> [Pattern v] -> [Pattern v] -> [Pattern v]
bfsHelper :: forall v.
Ord v =>
GraphLens v
-> Set (Pattern v) -> [Pattern v] -> [Pattern v] -> [Pattern v]
bfsHelper GraphLens v
_ Set (Pattern v)
_ [] [Pattern v]
acc = [Pattern v] -> [Pattern v]
forall a. [a] -> [a]
reverse [Pattern v]
acc
bfsHelper GraphLens v
lens Set (Pattern v)
visited (Pattern v
n:[Pattern v]
queue) [Pattern v]
acc
| Pattern v -> Set (Pattern v) -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member Pattern v
n Set (Pattern v)
visited = GraphLens v
-> Set (Pattern v) -> [Pattern v] -> [Pattern v] -> [Pattern v]
forall v.
Ord v =>
GraphLens v
-> Set (Pattern v) -> [Pattern v] -> [Pattern v] -> [Pattern v]
bfsHelper GraphLens v
lens Set (Pattern v)
visited [Pattern v]
queue [Pattern v]
acc
| Bool
otherwise =
let newVisited :: Set (Pattern v)
newVisited = Pattern v -> Set (Pattern v) -> Set (Pattern v)
forall a. Ord a => a -> Set a -> Set a
Set.insert Pattern v
n Set (Pattern v)
visited
newAcc :: [Pattern v]
newAcc = Pattern v
n Pattern v -> [Pattern v] -> [Pattern v]
forall a. a -> [a] -> [a]
: [Pattern v]
acc
nodeNeighbors :: [Pattern v]
nodeNeighbors = GraphLens v -> Pattern v -> [Pattern v]
forall v. Eq v => GraphLens v -> Pattern v -> [Pattern v]
Pattern.Graph.neighbors GraphLens v
lens Pattern v
n
newQueue :: [Pattern v]
newQueue = [Pattern v]
queue [Pattern v] -> [Pattern v] -> [Pattern v]
forall a. [a] -> [a] -> [a]
++ (Pattern v -> Bool) -> [Pattern v] -> [Pattern v]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Pattern v -> Bool) -> Pattern v -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Pattern v -> Set (Pattern v) -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set (Pattern v)
newVisited)) [Pattern v]
nodeNeighbors
in GraphLens v
-> Set (Pattern v) -> [Pattern v] -> [Pattern v] -> [Pattern v]
forall v.
Ord v =>
GraphLens v
-> Set (Pattern v) -> [Pattern v] -> [Pattern v] -> [Pattern v]
bfsHelper GraphLens v
lens Set (Pattern v)
newVisited [Pattern v]
newQueue [Pattern v]
newAcc
findPath :: Ord v => GraphLens v -> Pattern v -> Pattern v -> Maybe [Pattern v]
findPath :: forall v.
Ord v =>
GraphLens v -> Pattern v -> Pattern v -> Maybe [Pattern v]
findPath GraphLens v
lens Pattern v
start Pattern v
end
| Pattern v
start Pattern v -> Pattern v -> Bool
forall a. Eq a => a -> a -> Bool
== Pattern v
end = [Pattern v] -> Maybe [Pattern v]
forall a. a -> Maybe a
Just [Pattern v
start]
| Bool
otherwise = GraphLens v
-> Set (Pattern v)
-> [(Pattern v, [Pattern v])]
-> Pattern v
-> Maybe [Pattern v]
forall v.
Ord v =>
GraphLens v
-> Set (Pattern v)
-> [(Pattern v, [Pattern v])]
-> Pattern v
-> Maybe [Pattern v]
findPathHelper GraphLens v
lens Set (Pattern v)
forall a. Set a
Set.empty [(Pattern v
start, [Pattern v
start])] Pattern v
end
findPathHelper :: Ord v => GraphLens v -> Set.Set (Pattern v) -> [(Pattern v, [Pattern v])] -> Pattern v -> Maybe [Pattern v]
findPathHelper :: forall v.
Ord v =>
GraphLens v
-> Set (Pattern v)
-> [(Pattern v, [Pattern v])]
-> Pattern v
-> Maybe [Pattern v]
findPathHelper GraphLens v
_ Set (Pattern v)
_ [] Pattern v
_ = Maybe [Pattern v]
forall a. Maybe a
Nothing
findPathHelper GraphLens v
lens Set (Pattern v)
visited ((Pattern v
n, [Pattern v]
path):[(Pattern v, [Pattern v])]
queue) Pattern v
targetNode
| Pattern v
n Pattern v -> Pattern v -> Bool
forall a. Eq a => a -> a -> Bool
== Pattern v
targetNode = [Pattern v] -> Maybe [Pattern v]
forall a. a -> Maybe a
Just ([Pattern v] -> [Pattern v]
forall a. [a] -> [a]
reverse [Pattern v]
path)
| Pattern v -> Set (Pattern v) -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member Pattern v
n Set (Pattern v)
visited = GraphLens v
-> Set (Pattern v)
-> [(Pattern v, [Pattern v])]
-> Pattern v
-> Maybe [Pattern v]
forall v.
Ord v =>
GraphLens v
-> Set (Pattern v)
-> [(Pattern v, [Pattern v])]
-> Pattern v
-> Maybe [Pattern v]
findPathHelper GraphLens v
lens Set (Pattern v)
visited [(Pattern v, [Pattern v])]
queue Pattern v
targetNode
| Bool
otherwise =
let newVisited :: Set (Pattern v)
newVisited = Pattern v -> Set (Pattern v) -> Set (Pattern v)
forall a. Ord a => a -> Set a -> Set a
Set.insert Pattern v
n Set (Pattern v)
visited
nodeNeighbors :: [Pattern v]
nodeNeighbors = GraphLens v -> Pattern v -> [Pattern v]
forall v. Eq v => GraphLens v -> Pattern v -> [Pattern v]
Pattern.Graph.neighbors GraphLens v
lens Pattern v
n
newPaths :: [(Pattern v, [Pattern v])]
newPaths = (Pattern v -> (Pattern v, [Pattern v]))
-> [Pattern v] -> [(Pattern v, [Pattern v])]
forall a b. (a -> b) -> [a] -> [b]
map (\Pattern v
neighbor -> (Pattern v
neighbor, Pattern v
neighborPattern v -> [Pattern v] -> [Pattern v]
forall a. a -> [a] -> [a]
:[Pattern v]
path)) [Pattern v]
nodeNeighbors
unvisitedPaths :: [(Pattern v, [Pattern v])]
unvisitedPaths = ((Pattern v, [Pattern v]) -> Bool)
-> [(Pattern v, [Pattern v])] -> [(Pattern v, [Pattern v])]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(Pattern v
neighbor, [Pattern v]
_) -> Bool -> Bool
not (Pattern v -> Set (Pattern v) -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member Pattern v
neighbor Set (Pattern v)
newVisited)) [(Pattern v, [Pattern v])]
newPaths
newQueue :: [(Pattern v, [Pattern v])]
newQueue = [(Pattern v, [Pattern v])]
queue [(Pattern v, [Pattern v])]
-> [(Pattern v, [Pattern v])] -> [(Pattern v, [Pattern v])]
forall a. [a] -> [a] -> [a]
++ [(Pattern v, [Pattern v])]
unvisitedPaths
in GraphLens v
-> Set (Pattern v)
-> [(Pattern v, [Pattern v])]
-> Pattern v
-> Maybe [Pattern v]
forall v.
Ord v =>
GraphLens v
-> Set (Pattern v)
-> [(Pattern v, [Pattern v])]
-> Pattern v
-> Maybe [Pattern v]
findPathHelper GraphLens v
lens Set (Pattern v)
newVisited [(Pattern v, [Pattern v])]
newQueue Pattern v
targetNode