package org.aksw.jena_sparql_api.sparql_path2;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.aksw.jena_sparql_api.utils.model.Directed;
import org.jgrapht.DirectedGraph;
import com.google.common.collect.AbstractIterator;
public class SimplePathBfsIterator<V, E>
extends AbstractIterator<List<NestedPath<V, E>>>
{
protected DirectedGraph<V, E> graph;
protected List<NestedPath<V, E>> frontier;
protected Predicate<NestedPath<V, E>> isAccepted;
public SimplePathBfsIterator(DirectedGraph<V, E> graph, Collection<V> start, Predicate<NestedPath<V, E>> isAccepted) {
super();
this.graph = graph;
this.frontier = start.stream()
.map(item -> new NestedPath<V, E>(item))
.collect(Collectors.toList());
this.isAccepted = isAccepted;
}
public static <V, E> List<NestedPath<V, E>> collectPaths(List<NestedPath<V, E>> paths, Predicate<NestedPath<V, E>> predicate) {
List<NestedPath<V, E>> result = paths.stream()
.filter(predicate)
.collect(Collectors.toList());
return result;
}
public static <V, E> List<NestedPath<V, E>> advanceFrontier(DirectedGraph<V, E> graph, Collection<NestedPath<V, E>> paths) {
List<NestedPath<V, E>> result = new ArrayList<>();
for(NestedPath<V, E> path : paths) {
V current = path.getCurrent();
Set<E> edges = graph.outgoingEdgesOf(current);
for(E edge : edges) {
boolean isCycle = path.containsEdge(edge, false);
V v = graph.getEdgeTarget(edge);
if(!isCycle) {
NestedPath<V, E> nextPath = new NestedPath<>(new ParentLink<>(path, new Directed<>(edge, false)), v);
result.add(nextPath);
}
}
}
return result;
}
@Override
protected List<NestedPath<V, E>> computeNext() {
List<NestedPath<V, E>> result;
while(true) {
// Collect paths
result = collectPaths(frontier, isAccepted);
// Advance the frontier
frontier = advanceFrontier(graph, frontier);
if(!result.isEmpty()) {
break;
} else if(frontier.isEmpty()) {
result = endOfData();
break;
}
}
return result;
}
}