code: private boolean isNegationSafe(){
          if (this.isPositive()) return true;
          if (bindingVariables().isEmpty()) return false;
          //check nested blocks
          return getComplementQueries().stream()
                  .map(ResolvableQuery::asComposite)
                  .allMatch(CompositeQuery::isNegationSafe);
      }
docs: We interpret negation blocks as equivalent to defining a rule with the content of the block being the rule body.
  Writing the query in terms of variables it depends on we have:
  
  Q(x1, ..., xn) :- P1(xi, ...), ..., Pn(..., xj), NOT { R1(xk, ...), ..., Rn(..., xm) }
  
  We can then rewrite the negative part in terms of some unknown relation:
  
  ?(xk', ..., xm') :- R1(xk, ...), ..., Rn(..., xm)
  
  Where the sets of variables:
  V = {x1, ..., xn}
  Vp = {xi, ..., xj}
  Vn = {xk, ..., xm}
  Vr = {xk', ..., xm'}
  
  satisfy:
  
  Vp e V
  Vn e V
  Vr e Vn
  
  This procedure can follow recursively for multiple nested negation blocks.
  Then, for the negation to be safe, we require:
  
  - the set of variables Vr to be non-empty
  
  NB: We do not require the negation blocks to be ground with respect to the positive part as we can rewrite the
  negation blocks in terms of a ground relation defined via rule. i.e.:
  
  Q(x) :- T(x), (x, y), NOT{ (y, z) }
  
  can be rewritten as:
  
  Q(x) :- T(x), (x, y), NOT{ ?(y) }
  ?(y) :- (y, z)
  
  @return true if this composite query is safe to resolve