// Path: src/main/java/cl/uchile/dcc/blabel/lean/util/Bindings.java
// public class Bindings {
// 	private final ArrayList<BNode> output;
// 	private final ArrayList<Node[]> bindings;
// 	
// 	public Bindings(ArrayList<BNode> output, ArrayList<Node[]> bindings){
// 		this.output = output;
// 		this.bindings = bindings;
// 	}
// 
// 	public ArrayList<BNode> getOutput() {
// 		return output;
// 	}
// 
// 	public ArrayList<Node[]> getBindings() {
// 		return bindings;
// 	}
// }


import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.logging.Logger;
import org.semanticweb.yars.nx.BNode;
import org.semanticweb.yars.nx.Node;
import org.semanticweb.yars.nx.Nodes;
import org.semanticweb.yars.nx.parser.NxParser;
import cl.uchile.dcc.blabel.lean.util.Bindings;

	}
	
	private ArrayList<HashMap<BNode,Node>> getSolutions(ArrayList<Node[]> todo, HashMap<BNode, Node> initialMap) throws InterruptedException{
		ArrayList<HashMap<BNode,Node>> solutions = new ArrayList<HashMap<BNode,Node>>();
		if(initialMap!=null)
			solutions.add(initialMap);
		else solutions.add(new HashMap<BNode,Node>());
		ArrayList<Node[]> todoCopy = new ArrayList<Node[]>(todo);
		return join(todoCopy,solutions);
	}

	/**
	 * 
	 * @param current Pattern with blank node subject and object
	 * @param todo Patterns left to do
	 * @param partialSol A partial solution 
	 * @param timesBound Number of times each term bound in current partial solution
	 * @return null if no valid homomorphism found in depth first search, otherwise a single homomorphism
	 * @throws InterruptedException 
	 */
	private ArrayList<HashMap<BNode,Node>> join(ArrayList<Node[]> todo, ArrayList<HashMap<BNode,Node>> partialSols) throws InterruptedException{
		ArrayList<HashMap<BNode,Node>> nextPartialSols = new ArrayList<HashMap<BNode,Node>>();
		Node[] current = todo.remove(0);
		

		for(HashMap<BNode,Node> partialSol:partialSols){
			if (Thread.interrupted()) {
				throw new InterruptedException();
			}
			joins++;

// Path: src/main/java/cl/uchile/dcc/blabel/lean/util/Bindings.java
// public class Bindings {
// 	private final ArrayList<BNode> output;
// 	private final ArrayList<Node[]> bindings;
// 	
// 	public Bindings(ArrayList<BNode> output, ArrayList<Node[]> bindings){
// 		this.output = output;
// 		this.bindings = bindings;
// 	}
// 
// 	public ArrayList<BNode> getOutput() {
// 		return output;
// 	}
// 
// 	public ArrayList<Node[]> getBindings() {
// 		return bindings;
// 	}
// }


// Path: src/main/java/cl/uchile/dcc/blabel/lean/BFSGraphLeaning.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.logging.Logger;
import org.semanticweb.yars.nx.BNode;
import org.semanticweb.yars.nx.Node;
import org.semanticweb.yars.nx.Nodes;
import org.semanticweb.yars.nx.parser.NxParser;
import cl.uchile.dcc.blabel.lean.util.Bindings;

	}
	
	private ArrayList<HashMap<BNode,Node>> getSolutions(ArrayList<Node[]> todo, HashMap<BNode, Node> initialMap) throws InterruptedException{
		ArrayList<HashMap<BNode,Node>> solutions = new ArrayList<HashMap<BNode,Node>>();
		if(initialMap!=null)
			solutions.add(initialMap);
		else solutions.add(new HashMap<BNode,Node>());
		ArrayList<Node[]> todoCopy = new ArrayList<Node[]>(todo);
		return join(todoCopy,solutions);
	}

	/**
	 * 
	 * @param current Pattern with blank node subject and object
	 * @param todo Patterns left to do
	 * @param partialSol A partial solution 
	 * @param timesBound Number of times each term bound in current partial solution
	 * @return null if no valid homomorphism found in depth first search, otherwise a single homomorphism
	 * @throws InterruptedException 
	 */
	private ArrayList<HashMap<BNode,Node>> join(ArrayList<Node[]> todo, ArrayList<HashMap<BNode,Node>> partialSols) throws InterruptedException{
		ArrayList<HashMap<BNode,Node>> nextPartialSols = new ArrayList<HashMap<BNode,Node>>();
		Node[] current = todo.remove(0);
		

		for(HashMap<BNode,Node> partialSol:partialSols){
			if (Thread.interrupted()) {
				throw new InterruptedException();
			}
			joins++;

			Bindings bindings = getBindings(current,partialSol);
