code: private void collectVariableReferencesWithLeftJoin(Set<Variable> vars, Function atom) {
  		if (atom.isDataFunction()) {
  			TermUtils.addReferencedVariablesTo(vars, atom);
  		}
  		else if (atom.isAlgebraFunction()) {
  			Predicate functionSymbol = atom.getFunctionSymbol();
  			if (functionSymbol.equals(datalogFactory.getSparqlJoinPredicate())) {
  				// if it's a join, we need to collect all the variables of each nested atom
  				convert(atom.getTerms()).stream()
  						.filter(f -> !f.isOperation())
  						.forEach(f -> collectVariableReferencesWithLeftJoin(vars, f));
  			}
  			else if (functionSymbol.equals(datalogFactory.getSparqlLeftJoinPredicate())) {
  				// if it's a left join, only of the first data/algebra atom (the left atom)
  				collectVariableReferencesWithLeftJoin(vars, (Function) atom.getTerm(0));
  			}
  		}
  	}
docs: Collects (recursively) the set of variables that participate in data atoms
  (either in this atom directly or in nested ones, excluding those on the
  right-hand side of left joins.
  
  @param vars
  @param atom
  @return