[ 
https://issues.apache.org/jira/browse/TINKERPOP-2940?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Cole Greer updated TINKERPOP-2940:
----------------------------------
    Description: 
The current implementation of [ternary boolean 
logic|https://tinkerpop.apache.org/docs/3.6.2/dev/provider/#_ternary_boolean_logics]
 in TinkerPop leads to inconsistent and unexpected behavior depending on 
strategy application. This stems from the binary reduction logic implemented 
[here|https://github.com/Bit-Quill/tinkerpop/blob/d653b2401271ff9eb8e2249f878344c27ac81418/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/FilterStep.java#L44].
 `TraversalFilterStep` and `WhereStep` are currently special cases which will 
trigger early reduction of boolean error states to false. The issue is that 
some strategies such as `InlineFilterStrategy` will sometimes remove such steps 
to produce optimized traversals which are almost equivalent, but don't have 
this early reduction behavior.

Here is a simple example of this in TinkerGraph 3.6.2:
{code:bash}
gremlin> 
g.withoutStrategies(InlineFilterStrategy).inject(1).not(where(is(lt(NaN))))
==>1
gremlin> 
g.withoutStrategies(InlineFilterStrategy).inject(1).not(where(is(lt(NaN)))).explain()
==>Traversal Explanation
==========================================================================================================
Original Traversal                    [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]

ConnectiveStrategy              [D]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
CountStrategy                   [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
IdentityRemovalStrategy         [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
EarlyLimitStrategy              [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
MatchPredicateStrategy          [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
IncidentToAdjacentStrategy      [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
AdjacentToIncidentStrategy      [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
FilterRankingStrategy           [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
ByModulatorOptimizationStrategy [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
RepeatUnrollStrategy            [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
PathRetractionStrategy          [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
LazyBarrierStrategy             [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
TinkerGraphCountStrategy        [P]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
TinkerGraphStepStrategy         [P]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
ProfileStrategy                 [F]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
StandardVerificationStrategy    [V]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]

Final Traversal                       [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
gremlin> g.inject(1).not(where(is(lt(NaN))))
gremlin> g.inject(1).not(where(is(lt(NaN)))).explain()
==>Traversal Explanation
==========================================================================================================
Original Traversal                    [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]

ConnectiveStrategy              [D]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
CountStrategy                   [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
IdentityRemovalStrategy         [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
EarlyLimitStrategy              [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
MatchPredicateStrategy          [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
FilterRankingStrategy           [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
InlineFilterStrategy            [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
IncidentToAdjacentStrategy      [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
AdjacentToIncidentStrategy      [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
ByModulatorOptimizationStrategy [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
RepeatUnrollStrategy            [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
PathRetractionStrategy          [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
LazyBarrierStrategy             [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
TinkerGraphCountStrategy        [P]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
TinkerGraphStepStrategy         [P]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
ProfileStrategy                 [F]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
StandardVerificationStrategy    [V]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]

Final Traversal                       [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
{code}
 
In the first case, the final traversal contains `[InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]`. In this example, the 
`error` from the `IsStep` get's reduced early to `false` by the 
`TraversalFilterStep`. Therefore it is evaluated to `not(false)` which is 
`true`.

In the second case, the `TraversalFilterStep` is removed by the 
`InlineFilterStrategy` which leads to a final traversal of `[InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]`. In this case there is no early reduction step, so 
it evaluates to `not(error)`, which produces the result `error`, which is then 
reduced to `false`.

The interaction between the strategies and the early reduction behavior of the 
where step can lead to very unpredictable results. For example, here is a query 
which I would expect to behave in the same manner as the second traversal from 
above.
{code:bash}
gremlin> g.addV().property("test", 1)
==>v[2]
gremlin> g.V().not(where(values('test').is(lt(NaN))))
==>v[2]
gremlin> g.V().not(where(values('test').is(lt(NaN)))).explain()
==>Traversal Explanation
===================================================================================================================================================
Original Traversal                    [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]

ConnectiveStrategy              [D]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
CountStrategy                   [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
IdentityRemovalStrategy         [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
EarlyLimitStrategy              [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
MatchPredicateStrategy          [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
FilterRankingStrategy           [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
InlineFilterStrategy            [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
IncidentToAdjacentStrategy      [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
AdjacentToIncidentStrategy      [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
ByModulatorOptimizationStrategy [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
RepeatUnrollStrategy            [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
PathRetractionStrategy          [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
LazyBarrierStrategy             [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
TinkerGraphCountStrategy        [P]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
TinkerGraphStepStrategy         [P]   [TinkerGraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
ProfileStrategy                 [F]   [TinkerGraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
StandardVerificationStrategy    [V]   [TinkerGraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]

Final Traversal                       [TinkerGraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
{code}
This is essentially the same traversal as above, but in this case the 
TraversalFilterStep is preserved, leading to the early reduction of the `error`.

  was:
The current implementation of [ternary boolean 
logic|https://tinkerpop.apache.org/docs/3.6.2/dev/provider/#_ternary_boolean_logics]
 in TinkerPop leads to inconsistent and unexpected behavior depending on 
strategy application. This stems from the binary reduction logic implemented 
[here|https://github.com/Bit-Quill/tinkerpop/blob/d653b2401271ff9eb8e2249f878344c27ac81418/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/FilterStep.java#L44].
 `TraversalFilterStep` and `WhereStep` are currently special cases which will 
trigger early reduction of boolean error states to false. The issue is that 
some strategies such as `InlineFilterStrategy` will sometimes remove such steps 
to produce optimized traversals which are almost equivalent, but don't have 
this early reduction behavior.

Here is a simple example of this in TinkerGraph 3.6.2:
{code:bash}
gremlin> 
g.withoutStrategies(InlineFilterStrategy).inject(1).not(where(is(lt(NaN))))
==>1
gremlin> 
g.withoutStrategies(InlineFilterStrategy).inject(1).not(where(is(lt(NaN)))).explain()
==>Traversal Explanation
==========================================================================================================
Original Traversal                    [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]

ConnectiveStrategy              [D]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
CountStrategy                   [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
IdentityRemovalStrategy         [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
EarlyLimitStrategy              [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
MatchPredicateStrategy          [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
IncidentToAdjacentStrategy      [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
AdjacentToIncidentStrategy      [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
FilterRankingStrategy           [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
ByModulatorOptimizationStrategy [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
RepeatUnrollStrategy            [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
PathRetractionStrategy          [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
LazyBarrierStrategy             [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
TinkerGraphCountStrategy        [P]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
TinkerGraphStepStrategy         [P]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
ProfileStrategy                 [F]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
StandardVerificationStrategy    [V]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]

Final Traversal                       [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
gremlin> g.inject(1).not(where(is(lt(NaN))))
gremlin> g.inject(1).not(where(is(lt(NaN)))).explain()
==>Traversal Explanation
==========================================================================================================
Original Traversal                    [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]

ConnectiveStrategy              [D]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
CountStrategy                   [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
IdentityRemovalStrategy         [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
EarlyLimitStrategy              [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
MatchPredicateStrategy          [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
FilterRankingStrategy           [O]   [InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
InlineFilterStrategy            [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
IncidentToAdjacentStrategy      [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
AdjacentToIncidentStrategy      [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
ByModulatorOptimizationStrategy [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
RepeatUnrollStrategy            [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
PathRetractionStrategy          [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
LazyBarrierStrategy             [O]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
TinkerGraphCountStrategy        [P]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
TinkerGraphStepStrategy         [P]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
ProfileStrategy                 [F]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
StandardVerificationStrategy    [V]   [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]

Final Traversal                       [InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]
{code}
 
In the first case, the final traversal contains `[InjectStep([1]), 
NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]`. In this example, the 
`error` from the `IsStep` get's reduced early to `false` by the 
`TraversalFilterStep`. Therefore it is evaluated to `not(false)` which is 
`true`.

In the second case, the `TraversalFilterStep` is removed by the 
`InlineFilterStrategy` which leads to a final traversal of `[InjectStep([1]), 
NotStep([IsStep(lt(NaN))])]`. In this case there is no early reduction step, so 
it evaluates to `not(error)`, which produces the result `error`, which is then 
reduced to `false`.

The interaction between the strategies and the early reduction behavior of the 
where step lead to very unpredictable results. For example, here is a query 
which I would expect to behave in the same manner as the second traversal from 
above.


{code:bash}
gremlin> g.addV().property("test", 1)
==>v[2]
gremlin> g.V().not(where(values('test').is(lt(NaN))))
==>v[2]
gremlin> g.V().not(where(values('test').is(lt(NaN)))).explain()
==>Traversal Explanation
===================================================================================================================================================
Original Traversal                    [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]

ConnectiveStrategy              [D]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
CountStrategy                   [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
IdentityRemovalStrategy         [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
EarlyLimitStrategy              [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
MatchPredicateStrategy          [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
FilterRankingStrategy           [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
InlineFilterStrategy            [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
IncidentToAdjacentStrategy      [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
AdjacentToIncidentStrategy      [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
ByModulatorOptimizationStrategy [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
RepeatUnrollStrategy            [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
PathRetractionStrategy          [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
LazyBarrierStrategy             [O]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
TinkerGraphCountStrategy        [P]   [GraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
TinkerGraphStepStrategy         [P]   [TinkerGraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
ProfileStrategy                 [F]   [TinkerGraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
StandardVerificationStrategy    [V]   [TinkerGraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]

Final Traversal                       [TinkerGraphStep(vertex,[]), 
NotStep([TraversalFilterStep([PropertiesStep([test],value), IsStep(lt(NaN))])])]
{code}

This is essentially the same traversal as above, but in this case the 
TraversalFilterStep is preserved, leading to the early reduction of the `error`.


> Strategy Dependent Behavior of Ternary Boolean Logic
> ----------------------------------------------------
>
>                 Key: TINKERPOP-2940
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-2940
>             Project: TinkerPop
>          Issue Type: Improvement
>          Components: process
>    Affects Versions: 3.6.2
>            Reporter: Cole Greer
>            Priority: Major
>
> The current implementation of [ternary boolean 
> logic|https://tinkerpop.apache.org/docs/3.6.2/dev/provider/#_ternary_boolean_logics]
>  in TinkerPop leads to inconsistent and unexpected behavior depending on 
> strategy application. This stems from the binary reduction logic implemented 
> [here|https://github.com/Bit-Quill/tinkerpop/blob/d653b2401271ff9eb8e2249f878344c27ac81418/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/FilterStep.java#L44].
>  `TraversalFilterStep` and `WhereStep` are currently special cases which will 
> trigger early reduction of boolean error states to false. The issue is that 
> some strategies such as `InlineFilterStrategy` will sometimes remove such 
> steps to produce optimized traversals which are almost equivalent, but don't 
> have this early reduction behavior.
> Here is a simple example of this in TinkerGraph 3.6.2:
> {code:bash}
> gremlin> 
> g.withoutStrategies(InlineFilterStrategy).inject(1).not(where(is(lt(NaN))))
> ==>1
> gremlin> 
> g.withoutStrategies(InlineFilterStrategy).inject(1).not(where(is(lt(NaN)))).explain()
> ==>Traversal Explanation
> ==========================================================================================================
> Original Traversal                    [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> ConnectiveStrategy              [D]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> CountStrategy                   [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> IdentityRemovalStrategy         [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> EarlyLimitStrategy              [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> MatchPredicateStrategy          [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> IncidentToAdjacentStrategy      [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> AdjacentToIncidentStrategy      [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> FilterRankingStrategy           [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> ByModulatorOptimizationStrategy [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> RepeatUnrollStrategy            [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> PathRetractionStrategy          [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> LazyBarrierStrategy             [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> TinkerGraphCountStrategy        [P]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> TinkerGraphStepStrategy         [P]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> ProfileStrategy                 [F]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> StandardVerificationStrategy    [V]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> Final Traversal                       [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> gremlin> g.inject(1).not(where(is(lt(NaN))))
> gremlin> g.inject(1).not(where(is(lt(NaN)))).explain()
> ==>Traversal Explanation
> ==========================================================================================================
> Original Traversal                    [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> ConnectiveStrategy              [D]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> CountStrategy                   [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> IdentityRemovalStrategy         [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> EarlyLimitStrategy              [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> MatchPredicateStrategy          [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> FilterRankingStrategy           [O]   [InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]
> InlineFilterStrategy            [O]   [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> IncidentToAdjacentStrategy      [O]   [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> AdjacentToIncidentStrategy      [O]   [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> ByModulatorOptimizationStrategy [O]   [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> RepeatUnrollStrategy            [O]   [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> PathRetractionStrategy          [O]   [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> LazyBarrierStrategy             [O]   [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> TinkerGraphCountStrategy        [P]   [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> TinkerGraphStepStrategy         [P]   [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> ProfileStrategy                 [F]   [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> StandardVerificationStrategy    [V]   [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> Final Traversal                       [InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]
> {code}
>  
> In the first case, the final traversal contains `[InjectStep([1]), 
> NotStep([TraversalFilterStep([IsStep(lt(NaN))])])]`. In this example, the 
> `error` from the `IsStep` get's reduced early to `false` by the 
> `TraversalFilterStep`. Therefore it is evaluated to `not(false)` which is 
> `true`.
> In the second case, the `TraversalFilterStep` is removed by the 
> `InlineFilterStrategy` which leads to a final traversal of `[InjectStep([1]), 
> NotStep([IsStep(lt(NaN))])]`. In this case there is no early reduction step, 
> so it evaluates to `not(error)`, which produces the result `error`, which is 
> then reduced to `false`.
> The interaction between the strategies and the early reduction behavior of 
> the where step can lead to very unpredictable results. For example, here is a 
> query which I would expect to behave in the same manner as the second 
> traversal from above.
> {code:bash}
> gremlin> g.addV().property("test", 1)
> ==>v[2]
> gremlin> g.V().not(where(values('test').is(lt(NaN))))
> ==>v[2]
> gremlin> g.V().not(where(values('test').is(lt(NaN)))).explain()
> ==>Traversal Explanation
> ===================================================================================================================================================
> Original Traversal                    [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> ConnectiveStrategy              [D]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> CountStrategy                   [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> IdentityRemovalStrategy         [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> EarlyLimitStrategy              [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> MatchPredicateStrategy          [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> FilterRankingStrategy           [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> InlineFilterStrategy            [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> IncidentToAdjacentStrategy      [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> AdjacentToIncidentStrategy      [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> ByModulatorOptimizationStrategy [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> RepeatUnrollStrategy            [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> PathRetractionStrategy          [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> LazyBarrierStrategy             [O]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> TinkerGraphCountStrategy        [P]   [GraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> TinkerGraphStepStrategy         [P]   [TinkerGraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> ProfileStrategy                 [F]   [TinkerGraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> StandardVerificationStrategy    [V]   [TinkerGraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> Final Traversal                       [TinkerGraphStep(vertex,[]), 
> NotStep([TraversalFilterStep([PropertiesStep([test],value), 
> IsStep(lt(NaN))])])]
> {code}
> This is essentially the same traversal as above, but in this case the 
> TraversalFilterStep is preserved, leading to the early reduction of the 
> `error`.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to