// Path: src/main/java/de/unikiel/inf/comsys/neo4j/inference/rules/Rule.java
// public interface Rule {
// 
// 	/**
// 	 * Called to set the value factory that is used by the caller.
// 	 *
// 	 * Useful for consistent generation of URIs and blank nodes. Must be called
// 	 * before using any other methods.
// 	 *
// 	 * @param vf the value factory to use
// 	 */
// 	public void setValueFactory(ValueFactory vf);
// 
// 	/**
// 	 * Returns if this rule is applicable to a statement pattern.
// 	 *
// 	 * @param node the statement pattern to check
// 	 * @return true, if this rule would transform the pattern, false otherwise
// 	 */
// 	public boolean canApply(StatementPattern node);
// 
// 	/**
// 	 * Transforms a statement pattern to include inference.
// 	 *
// 	 * @param node the statement pattern to transform
// 	 * @return a list of expressions that still need to be transformed
// 	 */
// 	public List<QueryModelNode> apply(StatementPattern node);
// }


import de.unikiel.inf.comsys.neo4j.inference.rules.Rule;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import org.openrdf.query.algebra.QueryModelNode;
import org.openrdf.query.algebra.StatementPattern;
import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;

package de.unikiel.inf.comsys.neo4j.inference;

/*
 * #%L
 * neo4j-sparql-extension
 * %%
 * Copyright (C) 2014 Niclas Hoyer
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */


/**
 * A {@link QueryModelVisitorBase} implementation that transforms an expression
 * according to a list of rules.
 * 
 * This visitor visits each node and tries to apply all rules. If a rules
 * has been applied to a parent node it won't be applied in any child nodes.
 */
class RuleTransformationVisitor
		extends QueryModelVisitorBase<RuntimeException> {

	private final ArrayList<Rule> rules;
	/**
	 * A map to store reduced rule sets for rules.
	 * 
	 * An identity hash map is used because the Sesame implementation of
	 * the hash method of {@link QueryModelNode} is misleading.
	 * The hash method returns equal hashes for different statement patterns
	 * with the same entries. But the visitor needs to distinguish them, so
	 * the identity of the Java object is used instead of the hash value.
	 */
	private final IdentityHashMap<QueryModelNode, ArrayList<Rule>> applied;
	
	/**
	 * Creates a new rule transformation visitor that uses the given rules
	 * for query rewriting.
	 * 
	 * @param rules the rules used for rewriting
	 */
// Path: src/main/java/de/unikiel/inf/comsys/neo4j/inference/rules/Rule.java
// public interface Rule {
// 
// 	/**
// 	 * Called to set the value factory that is used by the caller.
// 	 *
// 	 * Useful for consistent generation of URIs and blank nodes. Must be called
// 	 * before using any other methods.
// 	 *
// 	 * @param vf the value factory to use
// 	 */
// 	public void setValueFactory(ValueFactory vf);
// 
// 	/**
// 	 * Returns if this rule is applicable to a statement pattern.
// 	 *
// 	 * @param node the statement pattern to check
// 	 * @return true, if this rule would transform the pattern, false otherwise
// 	 */
// 	public boolean canApply(StatementPattern node);
// 
// 	/**
// 	 * Transforms a statement pattern to include inference.
// 	 *
// 	 * @param node the statement pattern to transform
// 	 * @return a list of expressions that still need to be transformed
// 	 */
// 	public List<QueryModelNode> apply(StatementPattern node);
// }


// Path: src/main/java/de/unikiel/inf/comsys/neo4j/inference/RuleTransformationVisitor.java
import de.unikiel.inf.comsys.neo4j.inference.rules.Rule;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import org.openrdf.query.algebra.QueryModelNode;
import org.openrdf.query.algebra.StatementPattern;
import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;


package de.unikiel.inf.comsys.neo4j.inference;

/*
 * #%L
 * neo4j-sparql-extension
 * %%
 * Copyright (C) 2014 Niclas Hoyer
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */


/**
 * A {@link QueryModelVisitorBase} implementation that transforms an expression
 * according to a list of rules.
 * 
 * This visitor visits each node and tries to apply all rules. If a rules
 * has been applied to a parent node it won't be applied in any child nodes.
 */
class RuleTransformationVisitor
		extends QueryModelVisitorBase<RuntimeException> {

	private final ArrayList<Rule> rules;
	/**
	 * A map to store reduced rule sets for rules.
	 * 
	 * An identity hash map is used because the Sesame implementation of
	 * the hash method of {@link QueryModelNode} is misleading.
	 * The hash method returns equal hashes for different statement patterns
	 * with the same entries. But the visitor needs to distinguish them, so
	 * the identity of the Java object is used instead of the hash value.
	 */
	private final IdentityHashMap<QueryModelNode, ArrayList<Rule>> applied;
	
	/**
	 * Creates a new rule transformation visitor that uses the given rules
	 * for query rewriting.
	 * 
	 * @param rules the rules used for rewriting
	 */
	public RuleTransformationVisitor(ArrayList<Rule> rules) {