{"action":"created","issue":{"url":"https://api.github.com/repos/google/cayley/issues/209","labels_url":"https://api.github.com/repos/google/cayley/issues/209/labels{/name}","comments_url":"https://api.github.com/repos/google/cayley/issues/209/comments","events_url":"https://api.github.com/repos/google/cayley/issues/209/events","html_url":"https://github.com/google/cayley/issues/209","id":56983081,"number":209,"title":"ForAll / Universal Quantifiers","user":{"login":"barakmich","id":98356,"avatar_url":"https://avatars.githubusercontent.com/u/98356?v=3","gravatar_id":"","url":"https://api.github.com/users/barakmich","html_url":"https://github.com/barakmich","followers_url":"https://api.github.com/users/barakmich/followers","following_url":"https://api.github.com/users/barakmich/following{/other_user}","gists_url":"https://api.github.com/users/barakmich/gists{/gist_id}","starred_url":"https://api.github.com/users/barakmich/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/barakmich/subscriptions","organizations_url":"https://api.github.com/users/barakmich/orgs","repos_url":"https://api.github.com/users/barakmich/repos","events_url":"https://api.github.com/users/barakmich/events{/privacy}","received_events_url":"https://api.github.com/users/barakmich/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/google/cayley/labels/Query%20Languages%20and%20Features","name":"Query Languages and Features","color":"009800"},{"url":"https://api.github.com/repos/google/cayley/labels/Starter","name":"Starter","color":"bfe5bf"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-02-09T02:55:12Z","updated_at":"2015-05-01T22:30:59Z","closed_at":null,"body":"We have a Not iterator now. It'd be possible to add a shorthand macro in Gremlin to emulate the [Universal Quantifier](http://en.wikipedia.org/wiki/Universal_quantification), ForAll.\r\n\r\nAll queries currently work on existence. That is, each stage depends on \"there exists some path X to node Y\". Using negation you can achieve \"for all paths from X,  (rest of query holds)\". \r\n\r\nThe key insight being that \r\n`(X holds for (ForAll A)) == (X holds for A) AND (X holds for (Not (Not A))) == (X holds for (A AND (Not (Not A))))`\r\n\r\nIn today's parlance, this is:\r\nvar a = g.M()....\r\n`g.V().And(a).And(g.V().Except(g.V().Except(a)))...`\r\n\r\nIt's a hack, but one that holds mathematically. Currently can be implemented as a macro on the query level, and is actually really hard to optimize further. (Suggestions, of course, are welcome)"},"comment":{"url":"https://api.github.com/repos/google/cayley/issues/comments/98255646","html_url":"https://github.com/google/cayley/issues/209#issuecomment-98255646","issue_url":"https://api.github.com/repos/google/cayley/issues/209","id":98255646,"user":{"login":"barakmich","id":98356,"avatar_url":"https://avatars.githubusercontent.com/u/98356?v=3","gravatar_id":"","url":"https://api.github.com/users/barakmich","html_url":"https://github.com/barakmich","followers_url":"https://api.github.com/users/barakmich/followers","following_url":"https://api.github.com/users/barakmich/following{/other_user}","gists_url":"https://api.github.com/users/barakmich/gists{/gist_id}","starred_url":"https://api.github.com/users/barakmich/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/barakmich/subscriptions","organizations_url":"https://api.github.com/users/barakmich/orgs","repos_url":"https://api.github.com/users/barakmich/repos","events_url":"https://api.github.com/users/barakmich/events{/privacy}","received_events_url":"https://api.github.com/users/barakmich/received_events","type":"User","site_admin":false},"created_at":"2015-05-01T22:30:59Z","updated_at":"2015-05-01T22:30:59Z","body":"@allonhadaya Precisely. Vacuous truth is a weird thing; it often means returning a whole bunch of unrelated nodes. That said, if implemented by the book, it would also be correct -- so I could see a case for either."}}