Hello,
In TinkerPop 3.0.0, at the last minute, I got rid of the sack() merge operator
as I was lost in how we would do merge traverser sacks. Why did I get gun shy?
Watch:
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.withSack(1.0).V(1).outE().inV().sack()
==>1.0
==>1.0
==>1.0
So v[1] has 3 outgoing edges and so it generates three traversers and the sack
of the parent traverser is simply copied to the children. What if you want to
preserve a total sack value in the traversal. That is, there can never be more
than 1.0 "energy" in the graph. Well, if your edges have weights (lets say) and
they always are fraction of 1.0, well that would work. *** NOTE that the
TinkerGraph modern graph is not 1.0 normalized. ***
gremlin> g.withSack(1.0d).V(1).outE().sack(mult).by('weight').inV().sack()
==>0.4
==>0.5
==>1.0
Hmm.. but if they are not 1.0 normalized well, that sucks. And its hard to keep
such data consistent with large graphs constantly adding and removing edges…And
what if you don't have weights!!?
For the last week I was going down this rabbit hole of "split operators" for
the withSack() source method. It was all nasty and convoluted. However, last
night and into this morning, I think we can solve this simply with a "barrier
consumer." Watch.
gremlin> g.withSack(1.0).V(1).local(outE().barrier(normalizeSack)).inV().sack()
==>0.3333333333333333
==>0.3333333333333333
==>0.3333333333333333
Cool. What about if you want to have it normalized by edge weights?
gremlin>
g.withSack(1.0).V(1).local(outE().sack(mult).by('weight').barrier(normalizeSack)).inV().sack()
==>0.2105263157894737
==>0.2631578947368421
==>0.5263157894736842
Notice how local(barrier()) gathers all the traversers generated by outE() for
the current object and then allows you to do some mutation on them.
NormalizeSack simply recompute sacks based on the aggregate.
With this, the merge operator can easily just be: g.withSack(1.0,sum). And
then, we can support furcating and converging "energy" in the graph.
This will lead into some very very trippy (theoretical) work I've been doing
with constructive and destructive wave interference models with Gremlin. We
will be able to support "optical algorithms" -- refraction, diffusion,
interference, etc.
Any thoughts/concerns/recommendations?
Marko.
http://markorodriguez.com