private Rule renameVariables(Rule rule) {
        int uniqueVariableId = variableIdGenerator.incrementAndGet();

        Set<Variable> variables = new HashSet<Variable>();

        // At first I'll get a list of all variables that appear in the head of the rule.
        for (Term term : rule.getHead().getArgs()) {
            if (term instanceof Variable) {
                variables.add((Variable) term);
            }
        }

        List<Predicate> newConditions = new ArrayList<Predicate>(rule.getConditions().size());

        // The next step is to go through all conditions and see whether they use variables
        // that don't appear in the head of the rule. If that's the case, rename those
        // variables to ensure that they won't be captured later on.
        for (Predicate condition : rule.getConditions()) {
            for (Term term : condition.getArgs()) {
                if (term instanceof Variable && !variables.contains(term)) {
                    // If this is true, then we'll better rename this variable to some unique thing.
                    // In this case, I'll just prepend the prefix "__$$__" and a unique ID in front
                    // of the variable name.
                    Variable variable = (Variable) term;
                    condition = (Predicate) condition.substitute(
                            variable, new Variable("__$$__" +
                                    uniqueVariableId + "_" + variable.getName()));
                }
            }
            
            newConditions.add(condition);
        }

        return new Rule(rule.getHead(), newConditions);
    }