graph icon indicating copy to clipboard operation
graph copied to clipboard

comparing two boolean values and the unary 'not'

Open Pippin555 opened this issue 4 years ago • 7 comments

This is not an issue, but a request for a smarter solution,

I would like to compare two boolean values with an 'is' operator. But that operator is not available for groovysh_evaluate.

    t = (g.V()
         .limit(1)
         .sack(assign)
         .by(constant(true))
         .sack(is)
         .by(constant(false))
         .sack()
         )

When I try to negate a boolean value, there is no operator for that either.

          .sack(assign)
           .by(constant(true))
           .sack(not)
          .sack()

In the end I wrote a solution with a .choose, comparing with constant(true), see below.

Another solution is to convert boolean to int 0 and 1 and then use .math('x - y'), when that gives 0, the booleans are the same.

I can't believe that there is no shorter way to achieve this.

This determines the exclusive-or for the values in as('x') and as('y'):

        .choose(
                or_(
                    and_(
                        select('x').is(true),
                        select('y').is(true)),
                    and_(
                        select('x').is(false),
                        select('y').is(false))),
                constant(false),
                constant(true))

Pippin555 avatar Mar 21 '21 20:03 Pippin555

Just a couple of chapters further on:

             .choose(where('x', neq('y')),
                     constant(true),
                     constant(false))

this solves the first issue:

x y xor F F F F T T T F T T T F

Pippin555 avatar Mar 22 '21 08:03 Pippin555

You could implement boolean not logic using a Coalesce step

gremlin> g.inject(false).coalesce(is(true).constant(false),is(false).constant(true))
==>true  

krlawrence avatar Mar 22 '21 18:03 krlawrence

Also I updated the section that talks about choose and option over the weekend. The option step now accepts predicates which may also help in your case.

krlawrence avatar Mar 22 '21 19:03 krlawrence

a small change to your example: 'GraphTraversalSource" object has no attribute 'coalesce', you'll need g.V()

My Python implementation:

    print('option')
    for x in [False, True]:
        t = (g.V()
             .choose(constant(x))
             .option(True, constant(False))
             .option(False, constant(True)))
        r = next(t, None)
        print(f'{x}, {r}')

Pippin555 avatar Mar 23 '21 08:03 Pippin555

In my example above the V() is not needed as the inject is there. That turns the source into a Traversal. Keep in mind that g.V() looks at ALL vertices in the graph unless constrained by a filter like has or where.

krlawrence avatar Mar 24 '21 17:03 krlawrence

I used g.coalesce(constant(true).is(true).constant(false),constant(true)) and that does not work...

About V(): yes, I already have inadvertently doubled all vertices in the database when I used g.V().addV(...) , wondering where all those vertices came from...

on the side: Could you add in chapter 4.12 a word about where lambda functions are executed? I sent a question about those functions to the makers of ArangoDB Tinkerpop Provider and they asked me whether it would be executed "in the database" (I would say "on the server side") and they do not allow that.

Pippin555 avatar Mar 25 '21 10:03 Pippin555

Now that work has started on a second edition we will take the remaining discussions in this issue as part of that work.

krlawrence avatar Sep 23 '23 18:09 krlawrence