[ 
https://issues.apache.org/jira/browse/TINKERPOP3-949?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15006971#comment-15006971
 ] 

Marko A. Rodriguez commented on TINKERPOP3-949:
-----------------------------------------------

The reason there is:

{code}
gremlin> g.V(a1).times(3).repeat(__.out()).emit().path()
==>[v[0], v[2]]
==>[v[0], v[2], v[4]]
==>[v[0], v[2], v[4], v[6]]
==>[v[0], v[2], v[4], v[6]]
gremlin> g.V(a1).repeat(__.out()).times(3).emit().path()
==>[v[0], v[2]]
==>[v[0], v[2], v[4]]
==>[v[0], v[2], v[4], v[6]]
gremlin>
{code}

Is because when {{emit()}}/{{until()}} are both at the start (end), they will 
either "break" or  it will "emit", but not both. This is not the same for when 
these are split amongst start and end.  This was a design choice. Why? Well, 
look at the when {{v[6]}} gets returned twice.

{code}
gremlin> g.V(a1).times(3).repeat(__.out()).emit().path()
==>[v[0], v[2]]
==>[v[0], v[2], v[4]]
==>[v[0], v[2], v[4], v[6]]
==>[v[0], v[2], v[4], v[6]]
{code}

How does this work? {{out()}} happens, then the object is emitted, then the 
object is sent back to {{times(3)}}. Has it been repeated 3 times? Lets say, 
yes.  Then it breaks. Thus, "double emit."

Next, why does this do what id does?

{code}
gremlin> g.V(a1).emit().repeat(__.out()).times(3).path()
==>[v[0]]
==>[v[0], v[2]]
==>[v[0], v[2], v[4]]
==>[v[0], v[2], v[4], v[6]]
{code}

Well, you emit, then you out, and then you ask "have you been repeated 3 
times?," if yes, then break (single emit).

Lets look at when {{times(3).emit()}} are in the start.

{code}
gremlin> g.V(a1).times(3).emit().repeat(__.out()).path()
==>[v[0]]
==>[v[0], v[2]]
==>[v[0], v[2], v[4]]
==>[v[0], v[2], v[4], v[6]]
{code}

No repeat. Like when {{times().emit()}} were at the end, it will say: "Ah, I 
should break out of the loop, thus, I will already be emitted."

Given that when they are "split" they are two different steps (RepeatStart and 
RepeatEnd) and they don't communicate with one another.

Again, this was a design decision. One thing we can do, though this would be 
pretty insane backwards compatible wise is give an order to emit() and times() 
even when on the same side of repeat().

Thus, {{emit().times(3)}} would "double repeat" but {{times(3).emit()}} would 
not. Right now, we don't make that distinction, but we could and it would give 
the user more control. However, again, it would be breaking.

> times(x) after RepeatStep violates do while semantics.
> ------------------------------------------------------
>
>                 Key: TINKERPOP3-949
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP3-949
>             Project: TinkerPop 3
>          Issue Type: Bug
>          Components: process
>    Affects Versions: 3.0.2-incubating
>            Reporter: pieter martin
>            Assignee: Daniel Kuppitz
>
> {noformat}
>     @Test
>     public void testTimesAfterRepeat() {
>         final TinkerGraph g = TinkerGraph.open();
>         Vertex a1 = g.addVertex(T.label, "A", "name", "a1");
>         Vertex b1 = g.addVertex(T.label, "B", "name", "b1");
>         Vertex c1 = g.addVertex(T.label, "C", "name", "c1");
>         Vertex d1 = g.addVertex(T.label, "D", "name", "d1");
>         a1.addEdge("ab", b1);
>         b1.addEdge("bc", c1);
>         c1.addEdge("cd", d1);
>         List<Vertex> vertices = 
> g.traversal().V().hasLabel("A").emit().repeat(__.out()).times(2).toList();
>         assertEquals(4, vertices.size());
>     }
> {noformat}
> This test will fail for as it will return only 3 vertices.
> The current implementation of RepeatStep implements {{while do}} semantics 
> for a {{LoopTraversal}} regardless of the position of the {{times}} clause in 
> the gremlin query.
> a1->b1->c1->d1
> start at a1, emit a1
> travers to b1 loop==0
> emit b1 travers c1 loop==1
> emit c1 traverse d1 loop==2
> d1 is the last element so it is returned.
> a1, b1, c1 emitted and d1 is the last.
> Ultimately if I understand the intended semantics correctly, 
> {{repeat().times(a)}} is equivalent to {{times(a + 1).repeat()}}
> Having a look at {{RepeatStep.standardAlgorithm}} I see that the loop counter 
> is always incremented before {{doUntil}}. This translates to {{while do}} 
> semantics. For {{do while}} semantics the increment should occur after the 
> {{doUntil}}
> Or the {{LoopTraversal}} should be smarter about its predicate for {{do 
> while}}
> I am testing on the 3.0.2-incubating branch. I have only been working on 
> repeatSteps that start from a GraphStep. The same applies to starting from a 
> VertexStep but I am not yet there.
> With my current understanding of {{LoopTraversal}} and {{do while}} semantics 
> the following tests are failling,
> {{RepeatTest.g_V_repeatXoutX_timesX2X}}
> {{RepeatTest.g_V_repeatXoutX_timesX2X_repeatXinX_timesX2X_name}}
> {{PathTest.g_V_repeatXoutX_timesX2X_path_byXitX_byXnameX_byXlangX}}
> {{GroupTest.g_V_repeatXbothXfollowedByXX_timesX2X_group_byXsongTypeX_byXcountX}}
> {{GroupTest.g_V_repeatXbothXfollowedByXX_timesX2X_groupXaX_byXsongTypeX_byXcountX_capXaX}}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to