{-# LANGUAGE OverloadedStrings #-}
-- |
-- Module: NetSpider.Spider.Internal.Graph
-- Description: Graph (greskell) operation for Spider
-- Maintainer: Toshio Ito <debug.ito@gmail.com>
--
-- __this module is internal. End-users should not use it.__
module NetSpider.Spider.Internal.Graph
       ( gClearAll,
         -- * VNode
         gAllNodes,
         gHasNodeID,
         gHasNodeEID,
         gNodeEID,
         gNodeID,
         gMakeNode,
         -- * VFoundNode
         gAllFoundNode,
         gHasFoundNodeEID,
         gMakeFoundNode,
         gSelectFoundNode,
         gLatestFoundNode,
         gSubjectNodeID,
         gFilterFoundNodeByTime,
         gTraverseViaFinds,
         -- * Mix of VNode and VFoundNode
         gNodeMix,
         gFoundNodeOnly,
         gEitherNodeMix,
         gNodeFirst,
         gDedupNodes,
         -- * EFinds
         gFinds,
         gFindsTarget
       ) where

import Control.Category ((<<<))
import Control.Monad (void)
import Data.Aeson (ToJSON(..), FromJSON(..), Value(..))
import Data.Foldable (fold)
import Data.Greskell
  ( WalkType, AEdge,
    GTraversal, Filter, Transform, SideEffect, Walk, liftWalk, unsafeCastEnd, unsafeCastStart,
    Binder, newBind,
    source, sV, sV', sAddV, gAddV, gHasLabel, gHasId, gHas2, gHas2P, gId, gProperty, gPropertyV, gV,
    gNot, gIdentity', gIdentity, gUnion, gChoose3, gDedup,
    gAddE, gSideEffect, gTo, gFrom, gDrop, gOut, gOrder, gBy, gBy2, gValues, gOutE, gIn, gLabel,
    ($.), (<*.>), (=:),
    ToGTraversal,
    Key, oDecr, gLimit,
    pGt, pGte, pLt, pLte,
    tId
  )
import Data.Int (Int64)
import Data.Text (Text, pack)
import Data.Time.LocalTime (TimeZone(..))
import Data.Traversable (traverse)

import NetSpider.Graph
  ( EID, VNode, VFoundNode, EFinds,
    LinkAttributes(..), NodeAttributes(..)
  )
import NetSpider.Graph.Internal
  ( keyTimestamp, gSetTimestamp, gSetLinkState,
    gFindsTarget
  )
import NetSpider.Found (FoundLink(..), LinkState(..), FoundNode(..), linkStateToText)
import NetSpider.Interval (lowerBound', upperBound')
import NetSpider.Query (Interval, Extended(..))
import NetSpider.Timestamp (Timestamp(..))
import NetSpider.Spider.Config (Config(..))
import NetSpider.Spider.Internal.Spider (Spider(..))

spiderNodeIdKey :: Spider n na fla -> Key VNode n
spiderNodeIdKey :: Spider n na fla -> Key VNode n
spiderNodeIdKey = Config n na fla -> Key VNode n
forall n na fla. Config n na fla -> Key VNode n
nodeIdKey (Config n na fla -> Key VNode n)
-> (Spider n na fla -> Config n na fla)
-> Spider n na fla
-> Key VNode n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Spider n na fla -> Config n na fla
forall n na fla. Spider n na fla -> Config n na fla
spiderConfig

gNodeEID :: Walk Transform VNode (EID VNode)
gNodeEID :: Walk Transform VNode (EID VNode)
gNodeEID = Walk Transform VNode (EID VNode)
forall s. Element s => Walk Transform s (ElementID s)
gId

gNodeID :: Spider n na fla -> Walk Transform VNode n
gNodeID :: Spider n na fla -> Walk Transform VNode n
gNodeID Spider n na fla
spider = [Key VNode n] -> Walk Transform VNode n
forall s e. Element s => [Key s e] -> Walk Transform s e
gValues [Spider n na fla -> Key VNode n
forall n na fla. Spider n na fla -> Key VNode n
spiderNodeIdKey Spider n na fla
spider]

gAllNodes :: GTraversal Transform () VNode
gAllNodes :: GTraversal Transform () VNode
gAllNodes = Greskell Text -> Walk Transform VNode VNode
forall s c. (Element s, WalkType c) => Greskell Text -> Walk c s s
gHasLabel Greskell Text
"node" Walk Transform VNode VNode
-> GTraversal Transform () VNode -> GTraversal Transform () VNode
forall c b d a. Walk c b d -> GTraversal c a b -> GTraversal c a d
$. [Greskell (EID VNode)]
-> Greskell GraphTraversalSource -> GTraversal Transform () VNode
forall v.
Vertex v =>
[Greskell (ElementID v)]
-> Greskell GraphTraversalSource -> GTraversal Transform () v
sV [] (Greskell GraphTraversalSource -> GTraversal Transform () VNode)
-> Greskell GraphTraversalSource -> GTraversal Transform () VNode
forall a b. (a -> b) -> a -> b
$ Text -> Greskell GraphTraversalSource
source Text
"g"

gHasNodeID :: (ToJSON n, WalkType c) => Spider n na fla -> n -> Binder (Walk c VNode VNode)
gHasNodeID :: Spider n na fla -> n -> Binder (Walk c VNode VNode)
gHasNodeID Spider n na fla
spider n
nid = do
  Greskell n
var_nid <- n -> Binder (Greskell n)
forall v. ToJSON v => v -> Binder (Greskell v)
newBind n
nid
  Walk c VNode VNode -> Binder (Walk c VNode VNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk c VNode VNode -> Binder (Walk c VNode VNode))
-> Walk c VNode VNode -> Binder (Walk c VNode VNode)
forall a b. (a -> b) -> a -> b
$ Key VNode n -> Greskell n -> Walk c VNode VNode
forall c s v.
(WalkType c, Element s) =>
Key s v -> Greskell v -> Walk c s s
gHas2 (Spider n na fla -> Key VNode n
forall n na fla. Spider n na fla -> Key VNode n
spiderNodeIdKey Spider n na fla
spider) Greskell n
var_nid

gHasNodeEID :: (WalkType c) => EID VNode -> Binder (Walk c VNode VNode)
gHasNodeEID :: EID VNode -> Binder (Walk c VNode VNode)
gHasNodeEID EID VNode
eid = do
  Greskell (EID VNode)
var_eid <- EID VNode -> Binder (Greskell (EID VNode))
forall v. ToJSON v => v -> Binder (Greskell v)
newBind EID VNode
eid
  Walk c VNode VNode -> Binder (Walk c VNode VNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk c VNode VNode -> Binder (Walk c VNode VNode))
-> Walk c VNode VNode -> Binder (Walk c VNode VNode)
forall a b. (a -> b) -> a -> b
$ Greskell (EID VNode) -> Walk c VNode VNode
forall s c.
(Element s, WalkType c) =>
Greskell (ElementID s) -> Walk c s s
gHasId Greskell (EID VNode)
var_eid

gMakeNode :: ToJSON n => Spider n na fla -> n -> Binder (Walk SideEffect a VNode)
gMakeNode :: Spider n na fla -> n -> Binder (Walk SideEffect a VNode)
gMakeNode Spider n na fla
spider n
nid = do
  Greskell n
var_nid <- n -> Binder (Greskell n)
forall v. ToJSON v => v -> Binder (Greskell v)
newBind n
nid
  Walk SideEffect a VNode -> Binder (Walk SideEffect a VNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk SideEffect a VNode -> Binder (Walk SideEffect a VNode))
-> Walk SideEffect a VNode -> Binder (Walk SideEffect a VNode)
forall a b. (a -> b) -> a -> b
$ Key VNode n -> Greskell n -> Walk SideEffect VNode VNode
forall e v.
Element e =>
Key e v -> Greskell v -> Walk SideEffect e e
gProperty (Spider n na fla -> Key VNode n
forall n na fla. Spider n na fla -> Key VNode n
spiderNodeIdKey Spider n na fla
spider) Greskell n
var_nid Walk SideEffect VNode VNode
-> Walk SideEffect a VNode -> Walk SideEffect a VNode
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< Greskell Text -> Walk SideEffect a VNode
forall v a. Vertex v => Greskell Text -> Walk SideEffect a v
gAddV Greskell Text
"node"

gGetNodeByEID :: EID VNode -> Binder (Walk Transform s VNode)
gGetNodeByEID :: EID VNode -> Binder (Walk Transform s VNode)
gGetNodeByEID EID VNode
vid = do
  Walk Transform VNode VNode
f <- EID VNode -> Binder (Walk Transform VNode VNode)
forall c. WalkType c => EID VNode -> Binder (Walk c VNode VNode)
gHasNodeEID EID VNode
vid
  Walk Transform s VNode -> Binder (Walk Transform s VNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk Transform VNode VNode
f Walk Transform VNode VNode
-> Walk Transform s VNode -> Walk Transform s VNode
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< [Greskell (EID VNode)] -> Walk Transform s VNode
forall v s.
Vertex v =>
[Greskell (ElementID v)] -> Walk Transform s v
gV [])


gAllFoundNode :: GTraversal Transform () VFoundNode
gAllFoundNode :: GTraversal Transform () VFoundNode
gAllFoundNode = Greskell Text -> Walk Transform VFoundNode VFoundNode
forall s c. (Element s, WalkType c) => Greskell Text -> Walk c s s
gHasLabel Greskell Text
"found_node" Walk Transform VFoundNode VFoundNode
-> GTraversal Transform () VFoundNode
-> GTraversal Transform () VFoundNode
forall c b d a. Walk c b d -> GTraversal c a b -> GTraversal c a d
$. [Greskell (ElementID VFoundNode)]
-> Greskell GraphTraversalSource
-> GTraversal Transform () VFoundNode
forall v.
Vertex v =>
[Greskell (ElementID v)]
-> Greskell GraphTraversalSource -> GTraversal Transform () v
sV [] (Greskell GraphTraversalSource
 -> GTraversal Transform () VFoundNode)
-> Greskell GraphTraversalSource
-> GTraversal Transform () VFoundNode
forall a b. (a -> b) -> a -> b
$ Text -> Greskell GraphTraversalSource
source Text
"g"

gHasFoundNodeEID :: WalkType c => EID VFoundNode -> Binder (Walk c VFoundNode VFoundNode)
gHasFoundNodeEID :: ElementID VFoundNode -> Binder (Walk c VFoundNode VFoundNode)
gHasFoundNodeEID ElementID VFoundNode
eid = do
  Greskell (ElementID VFoundNode)
var_eid <- ElementID VFoundNode -> Binder (Greskell (ElementID VFoundNode))
forall v. ToJSON v => v -> Binder (Greskell v)
newBind ElementID VFoundNode
eid
  Walk c VFoundNode VFoundNode
-> Binder (Walk c VFoundNode VFoundNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk c VFoundNode VFoundNode
 -> Binder (Walk c VFoundNode VFoundNode))
-> Walk c VFoundNode VFoundNode
-> Binder (Walk c VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ Greskell (ElementID VFoundNode) -> Walk c VFoundNode VFoundNode
forall s c.
(Element s, WalkType c) =>
Greskell (ElementID s) -> Walk c s s
gHasId Greskell (ElementID VFoundNode)
var_eid

gMakeFoundNode :: (LinkAttributes la, NodeAttributes na)
               => EID VNode -- ^ subject node EID
               -> [(FoundLink n la, EID VNode)] -- ^ (link, target node EID)
               -> FoundNode n na la
               -> Binder (GTraversal SideEffect () VFoundNode)
gMakeFoundNode :: EID VNode
-> [(FoundLink n la, EID VNode)]
-> FoundNode n na la
-> Binder (GTraversal SideEffect () VFoundNode)
gMakeFoundNode EID VNode
subject_vid [(FoundLink n la, EID VNode)]
link_pairs FoundNode n na la
fnode = 
  Binder (Walk SideEffect VFoundNode VFoundNode)
mAddFindsEdges
  Binder (Walk SideEffect VFoundNode VFoundNode)
-> Binder (GTraversal SideEffect () VFoundNode)
-> Binder (GTraversal SideEffect () VFoundNode)
forall (f :: * -> *) c b d a.
Applicative f =>
f (Walk c b d) -> f (GTraversal c a b) -> f (GTraversal c a d)
<*.> na -> Binder (Walk SideEffect VFoundNode VFoundNode)
forall ps.
NodeAttributes ps =>
ps -> Binder (Walk SideEffect VFoundNode VFoundNode)
writeNodeAttributes (FoundNode n na la -> na
forall n na la. FoundNode n na la -> na
nodeAttributes FoundNode n na la
fnode)
  Binder (Walk SideEffect VFoundNode VFoundNode)
-> Binder (GTraversal SideEffect () VFoundNode)
-> Binder (GTraversal SideEffect () VFoundNode)
forall (f :: * -> *) c b d a.
Applicative f =>
f (Walk c b d) -> f (GTraversal c a b) -> f (GTraversal c a d)
<*.> Timestamp -> Binder (Walk SideEffect VFoundNode VFoundNode)
gSetTimestamp (FoundNode n na la -> Timestamp
forall n na la. FoundNode n na la -> Timestamp
foundAt FoundNode n na la
fnode)
  Binder (Walk SideEffect VFoundNode VFoundNode)
-> Binder (GTraversal SideEffect () VFoundNode)
-> Binder (GTraversal SideEffect () VFoundNode)
forall (f :: * -> *) c b d a.
Applicative f =>
f (Walk c b d) -> f (GTraversal c a b) -> f (GTraversal c a d)
<*.> Binder (Walk SideEffect VFoundNode VFoundNode)
mAddObservedEdge
  Binder (Walk SideEffect VFoundNode VFoundNode)
-> Binder (GTraversal SideEffect () VFoundNode)
-> Binder (GTraversal SideEffect () VFoundNode)
forall (f :: * -> *) c b d a.
Applicative f =>
f (Walk c b d) -> f (GTraversal c a b) -> f (GTraversal c a d)
<*.> GTraversal SideEffect () VFoundNode
-> Binder (GTraversal SideEffect () VFoundNode)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GTraversal SideEffect () VFoundNode
 -> Binder (GTraversal SideEffect () VFoundNode))
-> GTraversal SideEffect () VFoundNode
-> Binder (GTraversal SideEffect () VFoundNode)
forall a b. (a -> b) -> a -> b
$ Greskell Text
-> Greskell GraphTraversalSource
-> GTraversal SideEffect () VFoundNode
forall v.
Vertex v =>
Greskell Text
-> Greskell GraphTraversalSource -> GTraversal SideEffect () v
sAddV Greskell Text
"found_node" (Greskell GraphTraversalSource
 -> GTraversal SideEffect () VFoundNode)
-> Greskell GraphTraversalSource
-> GTraversal SideEffect () VFoundNode
forall a b. (a -> b) -> a -> b
$ Text -> Greskell GraphTraversalSource
source Text
"g"
  where
    mAddObservedEdge :: Binder (Walk SideEffect VFoundNode VFoundNode)
    mAddObservedEdge :: Binder (Walk SideEffect VFoundNode VFoundNode)
mAddObservedEdge = do
      Walk Transform VFoundNode VNode
v <- EID VNode -> Binder (Walk Transform VFoundNode VNode)
forall s. EID VNode -> Binder (Walk Transform s VNode)
gGetNodeByEID EID VNode
subject_vid
      Walk SideEffect VFoundNode VFoundNode
-> Binder (Walk SideEffect VFoundNode VFoundNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk SideEffect VFoundNode VFoundNode
 -> Binder (Walk SideEffect VFoundNode VFoundNode))
-> Walk SideEffect VFoundNode VFoundNode
-> Binder (Walk SideEffect VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ Walk SideEffect VFoundNode AEdge
-> Walk SideEffect VFoundNode VFoundNode
forall (g :: * -> * -> * -> *) c p s e.
(ToGTraversal g, WalkType c, WalkType p, Split c p) =>
g c s e -> Walk p s s
gSideEffect (Walk SideEffect VFoundNode AEdge
 -> Walk SideEffect VFoundNode VFoundNode)
-> Walk SideEffect VFoundNode AEdge
-> Walk SideEffect VFoundNode VFoundNode
forall a b. (a -> b) -> a -> b
$ Walk SideEffect VFoundNode AEdge
-> Walk SideEffect VFoundNode AEdge
forall (g :: * -> * -> * -> *) c s.
ToGTraversal g =>
g c s AEdge -> g c s AEdge
emitsAEdge (Walk SideEffect VFoundNode AEdge
 -> Walk SideEffect VFoundNode AEdge)
-> Walk SideEffect VFoundNode AEdge
-> Walk SideEffect VFoundNode AEdge
forall a b. (a -> b) -> a -> b
$ Greskell Text
-> AddAnchor VFoundNode VNode -> Walk SideEffect VFoundNode AEdge
forall vs ve e.
(Vertex vs, Vertex ve, Edge e) =>
Greskell Text -> AddAnchor vs ve -> Walk SideEffect vs e
gAddE Greskell Text
"is_observed_as" (AddAnchor VFoundNode VNode -> Walk SideEffect VFoundNode AEdge)
-> AddAnchor VFoundNode VNode -> Walk SideEffect VFoundNode AEdge
forall a b. (a -> b) -> a -> b
$ Walk Transform VFoundNode VNode -> AddAnchor VFoundNode VNode
forall (g :: * -> * -> * -> *) s e.
ToGTraversal g =>
g Transform s e -> AddAnchor s e
gFrom Walk Transform VFoundNode VNode
v
    mAddFindsEdges :: Binder (Walk SideEffect VFoundNode VFoundNode)
mAddFindsEdges = ([Walk SideEffect VFoundNode VFoundNode]
 -> Walk SideEffect VFoundNode VFoundNode)
-> Binder [Walk SideEffect VFoundNode VFoundNode]
-> Binder (Walk SideEffect VFoundNode VFoundNode)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Walk SideEffect VFoundNode VFoundNode]
-> Walk SideEffect VFoundNode VFoundNode
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold (Binder [Walk SideEffect VFoundNode VFoundNode]
 -> Binder (Walk SideEffect VFoundNode VFoundNode))
-> Binder [Walk SideEffect VFoundNode VFoundNode]
-> Binder (Walk SideEffect VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ ((FoundLink n la, EID VNode)
 -> Binder (Walk SideEffect VFoundNode VFoundNode))
-> [(FoundLink n la, EID VNode)]
-> Binder [Walk SideEffect VFoundNode VFoundNode]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (FoundLink n la, EID VNode)
-> Binder (Walk SideEffect VFoundNode VFoundNode)
forall la n.
LinkAttributes la =>
(FoundLink n la, EID VNode)
-> Binder (Walk SideEffect VFoundNode VFoundNode)
mAddFindsEdgeFor [(FoundLink n la, EID VNode)]
link_pairs
    mAddFindsEdgeFor :: LinkAttributes la => (FoundLink n la, EID VNode) -> Binder (Walk SideEffect VFoundNode VFoundNode)
    mAddFindsEdgeFor :: (FoundLink n la, EID VNode)
-> Binder (Walk SideEffect VFoundNode VFoundNode)
mAddFindsEdgeFor (FoundLink n la
link, EID VNode
target_vid) = do
      Walk Transform VFoundNode VNode
v <- EID VNode -> Binder (Walk Transform VFoundNode VNode)
forall s. EID VNode -> Binder (Walk Transform s VNode)
gGetNodeByEID EID VNode
target_vid
      Walk SideEffect EFinds EFinds
g_set_link_state <- LinkState -> Binder (Walk SideEffect EFinds EFinds)
gSetLinkState (LinkState -> Binder (Walk SideEffect EFinds EFinds))
-> LinkState -> Binder (Walk SideEffect EFinds EFinds)
forall a b. (a -> b) -> a -> b
$ FoundLink n la -> LinkState
forall n la. FoundLink n la -> LinkState
linkState FoundLink n la
link
      Walk SideEffect EFinds EFinds
addAttrs <- la -> Binder (Walk SideEffect EFinds EFinds)
forall ps.
LinkAttributes ps =>
ps -> Binder (Walk SideEffect EFinds EFinds)
writeLinkAttributes (la -> Binder (Walk SideEffect EFinds EFinds))
-> la -> Binder (Walk SideEffect EFinds EFinds)
forall a b. (a -> b) -> a -> b
$ FoundLink n la -> la
forall n la. FoundLink n la -> la
linkAttributes FoundLink n la
link
      Walk SideEffect VFoundNode VFoundNode
-> Binder (Walk SideEffect VFoundNode VFoundNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk SideEffect VFoundNode VFoundNode
 -> Binder (Walk SideEffect VFoundNode VFoundNode))
-> Walk SideEffect VFoundNode VFoundNode
-> Binder (Walk SideEffect VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ Walk SideEffect VFoundNode EFinds
-> Walk SideEffect VFoundNode VFoundNode
forall (g :: * -> * -> * -> *) c p s e.
(ToGTraversal g, WalkType c, WalkType p, Split c p) =>
g c s e -> Walk p s s
gSideEffect ( Walk SideEffect EFinds EFinds
addAttrs
                             Walk SideEffect EFinds EFinds
-> Walk SideEffect VFoundNode EFinds
-> Walk SideEffect VFoundNode EFinds
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< Walk SideEffect EFinds EFinds
g_set_link_state
                             Walk SideEffect EFinds EFinds
-> Walk SideEffect VFoundNode EFinds
-> Walk SideEffect VFoundNode EFinds
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< Greskell Text
-> AddAnchor VFoundNode VNode -> Walk SideEffect VFoundNode EFinds
forall vs ve e.
(Vertex vs, Vertex ve, Edge e) =>
Greskell Text -> AddAnchor vs ve -> Walk SideEffect vs e
gAddE Greskell Text
"finds" (Walk Transform VFoundNode VNode -> AddAnchor VFoundNode VNode
forall (g :: * -> * -> * -> *) s e.
ToGTraversal g =>
g Transform s e -> AddAnchor s e
gTo Walk Transform VFoundNode VNode
v)
                           )

emitsAEdge :: ToGTraversal g => g c s AEdge -> g c s AEdge
emitsAEdge :: g c s AEdge -> g c s AEdge
emitsAEdge = g c s AEdge -> g c s AEdge
forall a. a -> a
id

gClearAll :: GTraversal SideEffect () ()
gClearAll :: GTraversal SideEffect () ()
gClearAll = GTraversal SideEffect () AVertex -> GTraversal SideEffect () ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (GTraversal SideEffect () AVertex -> GTraversal SideEffect () ())
-> GTraversal SideEffect () AVertex -> GTraversal SideEffect () ()
forall a b. (a -> b) -> a -> b
$ Walk SideEffect AVertex AVertex
forall e. Element e => Walk SideEffect e e
gDrop Walk SideEffect AVertex AVertex
-> GTraversal SideEffect () AVertex
-> GTraversal SideEffect () AVertex
forall c b d a. Walk c b d -> GTraversal c a b -> GTraversal c a d
$. GTraversal Transform () AVertex -> GTraversal SideEffect () AVertex
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk (GTraversal Transform () AVertex
 -> GTraversal SideEffect () AVertex)
-> GTraversal Transform () AVertex
-> GTraversal SideEffect () AVertex
forall a b. (a -> b) -> a -> b
$ [Greskell (ElementID AVertex)]
-> Greskell GraphTraversalSource -> GTraversal Transform () AVertex
sV' [] (Greskell GraphTraversalSource -> GTraversal Transform () AVertex)
-> Greskell GraphTraversalSource -> GTraversal Transform () AVertex
forall a b. (a -> b) -> a -> b
$ Text -> Greskell GraphTraversalSource
source Text
"g"

gSelectFoundNode :: Walk Filter VFoundNode VFoundNode -> Walk Transform VNode VFoundNode
gSelectFoundNode :: Walk Filter VFoundNode VFoundNode
-> Walk Transform VNode VFoundNode
gSelectFoundNode Walk Filter VFoundNode VFoundNode
filterFoundNode = Walk Filter VFoundNode VFoundNode
-> Walk Transform VFoundNode VFoundNode
forall (g :: * -> * -> * -> *) from to s e.
(ToGTraversal g, WalkType from, WalkType to, Lift from to) =>
g from s e -> g to s e
liftWalk Walk Filter VFoundNode VFoundNode
filterFoundNode Walk Transform VFoundNode VFoundNode
-> Walk Transform VNode VFoundNode
-> Walk Transform VNode VFoundNode
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< [Greskell Text] -> Walk Transform VNode VFoundNode
forall v1 v2.
(Vertex v1, Vertex v2) =>
[Greskell Text] -> Walk Transform v1 v2
gOut [Greskell Text
"is_observed_as"]

gLatestFoundNode :: Walk Transform VFoundNode VFoundNode
gLatestFoundNode :: Walk Transform VFoundNode VFoundNode
gLatestFoundNode = Greskell Int -> Walk Transform VFoundNode VFoundNode
forall s. Greskell Int -> Walk Transform s s
gLimit Greskell Int
1 Walk Transform VFoundNode VFoundNode
-> Walk Transform VFoundNode VFoundNode
-> Walk Transform VFoundNode VFoundNode
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< [ByComparator VFoundNode] -> Walk Transform VFoundNode VFoundNode
forall s. [ByComparator s] -> Walk Transform s s
gOrder [Key VFoundNode TsEpoch
-> Greskell (Order TsEpoch)
-> ByComparator (ProjectionLikeStart (Key VFoundNode TsEpoch))
forall p comp.
(ProjectionLike p, ToGreskell p, Comparator comp,
 ProjectionLikeEnd p ~ CompareArg comp) =>
p -> Greskell comp -> ByComparator (ProjectionLikeStart p)
gBy2 Key VFoundNode TsEpoch
keyTimestamp Greskell (Order TsEpoch)
forall a. Greskell (Order a)
oDecr]

gSubjectNodeID :: Spider n na fla -> Walk Transform VFoundNode n
gSubjectNodeID :: Spider n na fla -> Walk Transform VFoundNode n
gSubjectNodeID Spider n na fla
spider = Spider n na fla -> Walk Transform VNode n
forall n na fla. Spider n na fla -> Walk Transform VNode n
gNodeID Spider n na fla
spider Walk Transform VNode n
-> Walk Transform VFoundNode VNode -> Walk Transform VFoundNode n
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< [Greskell Text] -> Walk Transform VFoundNode VNode
forall v1 v2.
(Vertex v1, Vertex v2) =>
[Greskell Text] -> Walk Transform v1 v2
gIn [Greskell Text
"is_observed_as"]

gFilterFoundNodeByTime :: Interval Timestamp -> Binder (Walk Filter VFoundNode VFoundNode)
gFilterFoundNodeByTime :: Interval Timestamp -> Binder (Walk Filter VFoundNode VFoundNode)
gFilterFoundNodeByTime Interval Timestamp
interval = do
  Walk Filter VFoundNode VFoundNode
fl <- Binder (Walk Filter VFoundNode VFoundNode)
filterLower
  Walk Filter VFoundNode VFoundNode
fh <- Binder (Walk Filter VFoundNode VFoundNode)
filterUpper
  Walk Filter VFoundNode VFoundNode
-> Binder (Walk Filter VFoundNode VFoundNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk Filter VFoundNode VFoundNode
fh Walk Filter VFoundNode VFoundNode
-> Walk Filter VFoundNode VFoundNode
-> Walk Filter VFoundNode VFoundNode
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< Walk Filter VFoundNode VFoundNode
fl)
  where
    filterLower :: Binder (Walk Filter VFoundNode VFoundNode)
filterLower = case Interval Timestamp -> IntervalEnd Timestamp
forall r. Interval r -> IntervalEnd r
lowerBound' Interval Timestamp
interval of
      (Extended Timestamp
PosInf, Bool
_) -> Walk Filter VFoundNode VFoundNode
-> Binder (Walk Filter VFoundNode VFoundNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk Filter VFoundNode VFoundNode
 -> Binder (Walk Filter VFoundNode VFoundNode))
-> Walk Filter VFoundNode VFoundNode
-> Binder (Walk Filter VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ Walk Filter VFoundNode VFoundNode
-> Walk Filter VFoundNode VFoundNode
forall (g :: * -> * -> * -> *) c p s e.
(ToGTraversal g, WalkType c, WalkType p, Split c p) =>
g c s e -> Walk p s s
gNot Walk Filter VFoundNode VFoundNode
forall s. Walk Filter s s
gIdentity'
      (Extended Timestamp
NegInf, Bool
_) -> Walk Filter VFoundNode VFoundNode
-> Binder (Walk Filter VFoundNode VFoundNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk Filter VFoundNode VFoundNode
 -> Binder (Walk Filter VFoundNode VFoundNode))
-> Walk Filter VFoundNode VFoundNode
-> Binder (Walk Filter VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ Walk Filter VFoundNode VFoundNode
forall s. Walk Filter s s
gIdentity'
      (Finite Timestamp
ts, Bool
False) -> (Greskell (P TsEpoch) -> Walk Filter VFoundNode VFoundNode)
-> Binder (Greskell (P TsEpoch))
-> Binder (Walk Filter VFoundNode VFoundNode)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Key VFoundNode TsEpoch
-> Greskell (P TsEpoch) -> Walk Filter VFoundNode VFoundNode
forall c s v.
(WalkType c, Element s) =>
Key s v -> Greskell (P v) -> Walk c s s
gHas2P Key VFoundNode TsEpoch
keyTimestamp) (Binder (Greskell (P TsEpoch))
 -> Binder (Walk Filter VFoundNode VFoundNode))
-> Binder (Greskell (P TsEpoch))
-> Binder (Walk Filter VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ (Greskell TsEpoch -> Greskell (P TsEpoch))
-> Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Greskell TsEpoch -> Greskell (P TsEpoch)
forall p. PLike p => PParameter p -> Greskell p
pGt  (Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch)))
-> Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch))
forall a b. (a -> b) -> a -> b
$ TsEpoch -> Binder (Greskell TsEpoch)
forall v. ToJSON v => v -> Binder (Greskell v)
newBind (TsEpoch -> Binder (Greskell TsEpoch))
-> TsEpoch -> Binder (Greskell TsEpoch)
forall a b. (a -> b) -> a -> b
$ Timestamp -> TsEpoch
epochTime Timestamp
ts
      (Finite Timestamp
ts, Bool
True)  -> (Greskell (P TsEpoch) -> Walk Filter VFoundNode VFoundNode)
-> Binder (Greskell (P TsEpoch))
-> Binder (Walk Filter VFoundNode VFoundNode)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Key VFoundNode TsEpoch
-> Greskell (P TsEpoch) -> Walk Filter VFoundNode VFoundNode
forall c s v.
(WalkType c, Element s) =>
Key s v -> Greskell (P v) -> Walk c s s
gHas2P Key VFoundNode TsEpoch
keyTimestamp) (Binder (Greskell (P TsEpoch))
 -> Binder (Walk Filter VFoundNode VFoundNode))
-> Binder (Greskell (P TsEpoch))
-> Binder (Walk Filter VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ (Greskell TsEpoch -> Greskell (P TsEpoch))
-> Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Greskell TsEpoch -> Greskell (P TsEpoch)
forall p. PLike p => PParameter p -> Greskell p
pGte (Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch)))
-> Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch))
forall a b. (a -> b) -> a -> b
$ TsEpoch -> Binder (Greskell TsEpoch)
forall v. ToJSON v => v -> Binder (Greskell v)
newBind (TsEpoch -> Binder (Greskell TsEpoch))
-> TsEpoch -> Binder (Greskell TsEpoch)
forall a b. (a -> b) -> a -> b
$ Timestamp -> TsEpoch
epochTime Timestamp
ts
    filterUpper :: Binder (Walk Filter VFoundNode VFoundNode)
filterUpper = case Interval Timestamp -> IntervalEnd Timestamp
forall r. Interval r -> IntervalEnd r
upperBound' Interval Timestamp
interval of
      (Extended Timestamp
PosInf, Bool
_) -> Walk Filter VFoundNode VFoundNode
-> Binder (Walk Filter VFoundNode VFoundNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk Filter VFoundNode VFoundNode
 -> Binder (Walk Filter VFoundNode VFoundNode))
-> Walk Filter VFoundNode VFoundNode
-> Binder (Walk Filter VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ Walk Filter VFoundNode VFoundNode
forall s. Walk Filter s s
gIdentity'
      (Extended Timestamp
NegInf, Bool
_) -> Walk Filter VFoundNode VFoundNode
-> Binder (Walk Filter VFoundNode VFoundNode)
forall (m :: * -> *) a. Monad m => a -> m a
return (Walk Filter VFoundNode VFoundNode
 -> Binder (Walk Filter VFoundNode VFoundNode))
-> Walk Filter VFoundNode VFoundNode
-> Binder (Walk Filter VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ Walk Filter VFoundNode VFoundNode
-> Walk Filter VFoundNode VFoundNode
forall (g :: * -> * -> * -> *) c p s e.
(ToGTraversal g, WalkType c, WalkType p, Split c p) =>
g c s e -> Walk p s s
gNot Walk Filter VFoundNode VFoundNode
forall s. Walk Filter s s
gIdentity'
      (Finite Timestamp
ts, Bool
False) -> (Greskell (P TsEpoch) -> Walk Filter VFoundNode VFoundNode)
-> Binder (Greskell (P TsEpoch))
-> Binder (Walk Filter VFoundNode VFoundNode)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Key VFoundNode TsEpoch
-> Greskell (P TsEpoch) -> Walk Filter VFoundNode VFoundNode
forall c s v.
(WalkType c, Element s) =>
Key s v -> Greskell (P v) -> Walk c s s
gHas2P Key VFoundNode TsEpoch
keyTimestamp) (Binder (Greskell (P TsEpoch))
 -> Binder (Walk Filter VFoundNode VFoundNode))
-> Binder (Greskell (P TsEpoch))
-> Binder (Walk Filter VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ (Greskell TsEpoch -> Greskell (P TsEpoch))
-> Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Greskell TsEpoch -> Greskell (P TsEpoch)
forall p. PLike p => PParameter p -> Greskell p
pLt  (Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch)))
-> Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch))
forall a b. (a -> b) -> a -> b
$ TsEpoch -> Binder (Greskell TsEpoch)
forall v. ToJSON v => v -> Binder (Greskell v)
newBind (TsEpoch -> Binder (Greskell TsEpoch))
-> TsEpoch -> Binder (Greskell TsEpoch)
forall a b. (a -> b) -> a -> b
$ Timestamp -> TsEpoch
epochTime Timestamp
ts
      (Finite Timestamp
ts, Bool
True)  -> (Greskell (P TsEpoch) -> Walk Filter VFoundNode VFoundNode)
-> Binder (Greskell (P TsEpoch))
-> Binder (Walk Filter VFoundNode VFoundNode)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Key VFoundNode TsEpoch
-> Greskell (P TsEpoch) -> Walk Filter VFoundNode VFoundNode
forall c s v.
(WalkType c, Element s) =>
Key s v -> Greskell (P v) -> Walk c s s
gHas2P Key VFoundNode TsEpoch
keyTimestamp) (Binder (Greskell (P TsEpoch))
 -> Binder (Walk Filter VFoundNode VFoundNode))
-> Binder (Greskell (P TsEpoch))
-> Binder (Walk Filter VFoundNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ (Greskell TsEpoch -> Greskell (P TsEpoch))
-> Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Greskell TsEpoch -> Greskell (P TsEpoch)
forall p. PLike p => PParameter p -> Greskell p
pLte (Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch)))
-> Binder (Greskell TsEpoch) -> Binder (Greskell (P TsEpoch))
forall a b. (a -> b) -> a -> b
$ TsEpoch -> Binder (Greskell TsEpoch)
forall v. ToJSON v => v -> Binder (Greskell v)
newBind (TsEpoch -> Binder (Greskell TsEpoch))
-> TsEpoch -> Binder (Greskell TsEpoch)
forall a b. (a -> b) -> a -> b
$ Timestamp -> TsEpoch
epochTime Timestamp
ts

gFinds :: Walk Transform VFoundNode EFinds
gFinds :: Walk Transform VFoundNode EFinds
gFinds = [Greskell Text] -> Walk Transform VFoundNode EFinds
forall v e.
(Vertex v, Edge e) =>
[Greskell Text] -> Walk Transform v e
gOutE [Greskell Text
"finds"]

gTraverseViaFinds :: Walk Transform VFoundNode VNode
gTraverseViaFinds :: Walk Transform VFoundNode VNode
gTraverseViaFinds = [Greskell Text] -> Walk Transform VFoundNode VNode
forall v1 v2.
(Vertex v1, Vertex v2) =>
[Greskell Text] -> Walk Transform v1 v2
gOut [Greskell Text
"finds"]

-- | Make a mixed stream of 'VNode' and 'VFoundNode'. In the result
-- walk, the input 'VNode' is output first, and then, the 'VFoundNode'
-- derived from the 'VNode' follows.
gNodeMix :: Walk Transform VNode VFoundNode -- ^ walk to derive 'VFoundNode's from 'VNode'.
         -> Walk Transform VNode (Either VNode VFoundNode)
gNodeMix :: Walk Transform VNode VFoundNode
-> Walk Transform VNode (Either VNode VFoundNode)
gNodeMix Walk Transform VNode VFoundNode
walk_vfn = [Walk Transform VNode (Either VNode VFoundNode)]
-> Walk Transform VNode (Either VNode VFoundNode)
forall (g :: * -> * -> * -> *) c s e.
(ToGTraversal g, WalkType c) =>
[g c s e] -> Walk c s e
gUnion [Walk Transform VNode VNode
-> Walk Transform VNode (Either VNode VFoundNode)
forall (g :: * -> * -> * -> *) c s e1 e2.
(ToGTraversal g, WalkType c) =>
g c s e1 -> g c s e2
unsafeCastEnd Walk Transform VNode VNode
forall c s. WalkType c => Walk c s s
gIdentity, Walk Transform VNode VFoundNode
-> Walk Transform VNode (Either VNode VFoundNode)
forall (g :: * -> * -> * -> *) c s e1 e2.
(ToGTraversal g, WalkType c) =>
g c s e1 -> g c s e2
unsafeCastEnd Walk Transform VNode VFoundNode
walk_vfn]

-- | Filter the 'VFoundNode' only from the mix of 'VNode' and
-- 'VFoundNode'.
gFoundNodeOnly :: Walk Transform (Either VNode VFoundNode) VFoundNode
gFoundNodeOnly :: Walk Transform (Either VNode VFoundNode) VFoundNode
gFoundNodeOnly = Walk Transform VFoundNode VFoundNode
-> Walk Transform (Either VNode VFoundNode) VFoundNode
forall (g :: * -> * -> * -> *) c s1 e s2.
(ToGTraversal g, WalkType c) =>
g c s1 e -> g c s2 e
unsafeCastStart (Walk Transform VFoundNode VFoundNode
 -> Walk Transform (Either VNode VFoundNode) VFoundNode)
-> Walk Transform VFoundNode VFoundNode
-> Walk Transform (Either VNode VFoundNode) VFoundNode
forall a b. (a -> b) -> a -> b
$ Greskell Text -> Walk Transform VFoundNode VFoundNode
forall s c. (Element s, WalkType c) => Greskell Text -> Walk c s s
gHasLabel Greskell Text
"found_node"

-- | Transform the mixed stream of 'VNode' and 'VFoundNode' into a
-- common type @a@.
gEitherNodeMix :: Walk Transform VNode a
               -> Walk Transform VFoundNode a
               -> Walk Transform (Either VNode VFoundNode) a
gEitherNodeMix :: Walk Transform VNode a
-> Walk Transform VFoundNode a
-> Walk Transform (Either VNode VFoundNode) a
gEitherNodeMix Walk Transform VNode a
walk_vn Walk Transform VFoundNode a
walk_vfn =
  Walk Filter (Either VNode VFoundNode) VNode
-> Walk Transform (Either VNode VFoundNode) a
-> Walk Transform (Either VNode VFoundNode) a
-> Walk Transform (Either VNode VFoundNode) a
forall (g :: * -> * -> * -> *) cc c s ep e.
(ToGTraversal g, Split cc c, WalkType cc, WalkType c) =>
g cc s ep -> g c s e -> g c s e -> Walk c s e
gChoose3 (Walk Filter VNode VNode
-> Walk Filter (Either VNode VFoundNode) VNode
forall (g :: * -> * -> * -> *) c s1 e s2.
(ToGTraversal g, WalkType c) =>
g c s1 e -> g c s2 e
unsafeCastStart Walk Filter VNode VNode
walk_pred) (Walk Transform VNode a
-> Walk Transform (Either VNode VFoundNode) a
forall (g :: * -> * -> * -> *) c s1 e s2.
(ToGTraversal g, WalkType c) =>
g c s1 e -> g c s2 e
unsafeCastStart Walk Transform VNode a
walk_vn) (Walk Transform VFoundNode a
-> Walk Transform (Either VNode VFoundNode) a
forall (g :: * -> * -> * -> *) c s1 e s2.
(ToGTraversal g, WalkType c) =>
g c s1 e -> g c s2 e
unsafeCastStart Walk Transform VFoundNode a
walk_vfn)
  where
    walk_pred :: Walk Filter VNode VNode
    walk_pred :: Walk Filter VNode VNode
walk_pred = Greskell Text -> Walk Filter VNode VNode
forall s c. (Element s, WalkType c) => Greskell Text -> Walk c s s
gHasLabel Greskell Text
"node"

-- | Sort the mix of 'VNode' and 'VFoundNode' so that 'VNode' is
-- output first.
gNodeFirst :: Walk Transform (Either VNode VFoundNode) (Either VNode VFoundNode)
gNodeFirst :: Walk Transform (Either VNode VFoundNode) (Either VNode VFoundNode)
gNodeFirst = Walk Transform (Either VNode VFoundNode) VNode
-> Walk
     Transform (Either VNode VFoundNode) (Either VNode VFoundNode)
forall (g :: * -> * -> * -> *) c s e1 e2.
(ToGTraversal g, WalkType c) =>
g c s e1 -> g c s e2
unsafeCastEnd (Walk Transform (Either VNode VFoundNode) VNode
 -> Walk
      Transform (Either VNode VFoundNode) (Either VNode VFoundNode))
-> Walk Transform (Either VNode VFoundNode) VNode
-> Walk
     Transform (Either VNode VFoundNode) (Either VNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ Walk Transform VNode VNode
-> Walk Transform (Either VNode VFoundNode) VNode
forall (g :: * -> * -> * -> *) c s1 e s2.
(ToGTraversal g, WalkType c) =>
g c s1 e -> g c s2 e
unsafeCastStart (Walk Transform VNode VNode
 -> Walk Transform (Either VNode VFoundNode) VNode)
-> Walk Transform VNode VNode
-> Walk Transform (Either VNode VFoundNode) VNode
forall a b. (a -> b) -> a -> b
$ Walk Transform VNode VNode
walk_for_elem
  where
    walk_for_elem :: Walk Transform VNode VNode
    walk_for_elem :: Walk Transform VNode VNode
walk_for_elem = [ByComparator VNode] -> Walk Transform VNode VNode
forall s. [ByComparator s] -> Walk Transform s s
gOrder [Walk Transform VNode Text
-> Greskell (Order Text)
-> ByComparator (ProjectionLikeStart (Walk Transform VNode Text))
forall p comp.
(ProjectionLike p, ToGreskell p, Comparator comp,
 ProjectionLikeEnd p ~ CompareArg comp) =>
p -> Greskell comp -> ByComparator (ProjectionLikeStart p)
gBy2 Walk Transform VNode Text
forall s. Element s => Walk Transform s Text
gLabel Greskell (Order Text)
forall a. Greskell (Order a)
oDecr]

-- | Dedup mix of 'VNode' and 'VFoundNode' based on their 'EID'.
gDedupNodes :: Walk Transform (Either VNode VFoundNode) (Either VNode VFoundNode)
gDedupNodes :: Walk Transform (Either VNode VFoundNode) (Either VNode VFoundNode)
gDedupNodes = Walk Transform (Either VNode VFoundNode) VNode
-> Walk
     Transform (Either VNode VFoundNode) (Either VNode VFoundNode)
forall (g :: * -> * -> * -> *) c s e1 e2.
(ToGTraversal g, WalkType c) =>
g c s e1 -> g c s e2
unsafeCastEnd (Walk Transform (Either VNode VFoundNode) VNode
 -> Walk
      Transform (Either VNode VFoundNode) (Either VNode VFoundNode))
-> Walk Transform (Either VNode VFoundNode) VNode
-> Walk
     Transform (Either VNode VFoundNode) (Either VNode VFoundNode)
forall a b. (a -> b) -> a -> b
$ Walk Transform VNode VNode
-> Walk Transform (Either VNode VFoundNode) VNode
forall (g :: * -> * -> * -> *) c s1 e s2.
(ToGTraversal g, WalkType c) =>
g c s1 e -> g c s2 e
unsafeCastStart (Walk Transform VNode VNode
 -> Walk Transform (Either VNode VFoundNode) VNode)
-> Walk Transform VNode VNode
-> Walk Transform (Either VNode VFoundNode) VNode
forall a b. (a -> b) -> a -> b
$ Walk Transform VNode VNode
walk_for_elem
  where
    walk_for_elem :: Walk Transform VNode VNode
    walk_for_elem :: Walk Transform VNode VNode
walk_for_elem = Maybe (ByProjection VNode (EID VNode))
-> Walk Transform VNode VNode
forall s e. Maybe (ByProjection s e) -> Walk Transform s s
gDedup (Maybe (ByProjection VNode (EID VNode))
 -> Walk Transform VNode VNode)
-> Maybe (ByProjection VNode (EID VNode))
-> Walk Transform VNode VNode
forall a b. (a -> b) -> a -> b
$ ByProjection VNode (EID VNode)
-> Maybe (ByProjection VNode (EID VNode))
forall a. a -> Maybe a
Just (ByProjection VNode (EID VNode)
 -> Maybe (ByProjection VNode (EID VNode)))
-> ByProjection VNode (EID VNode)
-> Maybe (ByProjection VNode (EID VNode))
forall a b. (a -> b) -> a -> b
$ Greskell (T VNode (EID VNode))
-> ByProjection
     (ProjectionLikeStart (Greskell (T VNode (EID VNode))))
     (ProjectionLikeEnd (Greskell (T VNode (EID VNode))))
forall p.
(ProjectionLike p, ToGreskell p) =>
p -> ByProjection (ProjectionLikeStart p) (ProjectionLikeEnd p)
gBy Greskell (T VNode (EID VNode))
forall a. Element a => Greskell (T a (ElementID a))
tId