package org.aksw.jena_sparql_api.sparql_path2;
import java.util.Collections;
import org.jgrapht.DirectedGraph;
import org.jgrapht.VertexFactory;
import com.google.common.collect.FluentIterable;
//https://swtch.com/~rsc/regexp/regexp1.html
public class NfaOps {
/**
* e1 e2
*
* @param graph
* @param a
* @param b
* @return
*/
public static <V, E, T> PartialNfa<V, T> concatenate(DirectedGraph<V, E> graph, PartialNfa<V, T> a, PartialNfa<V, T> b, EdgeLabelAccessor<E, T> edgeLabelAccessor) {
V target = b.getStartVertex();
for(HalfEdge<V, T> looseEnd : a.getLooseEnds()) {
V start = looseEnd.getStartVertex();
T edgeLabel = looseEnd.getEdgeLabel();
E edge = graph.addEdge(start, target);
edgeLabelAccessor.setLabel(edge, edgeLabel);
//E edge = edgeFactory.createEdge(start, target, edgeLabel);
//graph.addEdge(start, target, edge);
}
PartialNfa<V, T> result = PartialNfa.create(a.getStartVertex(), b.getLooseEnds());
return result;
}
/**
* e1 | e2
*
* @param graph
* @param a
* @param b
* @return
*/
public static <V, E, T> PartialNfa<V, T> alternate(DirectedGraph<V, E> graph, VertexFactory<V> vertexFactory, PartialNfa<V, T> a, PartialNfa<V, T> b) {
V newStartVertex = vertexFactory.createVertex();
graph.addVertex(newStartVertex);
graph.addEdge(newStartVertex, a.getStartVertex());
graph.addEdge(newStartVertex, b.getStartVertex());
Iterable<HalfEdge<V, T>> newLooseEnds = FluentIterable
.from(a.getLooseEnds())
.append(b.getLooseEnds())
.toList();
PartialNfa<V, T> result = PartialNfa.create(newStartVertex, newLooseEnds);
return result;
}
/**
* e?
*
* @param graph
* @param vertexFactory
* @param a
* @return
*/
public static <V, E, T> PartialNfa<V, T> zeroOrOne(DirectedGraph<V, E> graph, VertexFactory<V> vertexFactory, PartialNfa<V, T> a) {
V newStartVertex = vertexFactory.createVertex();
graph.addVertex(newStartVertex);
V oldStartVertex = a.getStartVertex();
graph.addEdge(newStartVertex, oldStartVertex);
Iterable<HalfEdge<V, T>> newLooseEnds = FluentIterable
.from(a.getLooseEnds())
.append(Collections.singletonList(new HalfEdge<V, T>(newStartVertex, null)))
.toList();
PartialNfa<V, T> result = PartialNfa.create(newStartVertex, newLooseEnds);
return result;
}
/**
* e*
*
* @param graph
* @param a
* @return
*/
public static <V, E, T> PartialNfa<V, T> zeroOrMore(DirectedGraph<V, E> graph, VertexFactory<V> vertexFactory, PartialNfa<V, T> a, EdgeLabelAccessor<E, T> edgeLabelAccessor) {
V newStartVertex = vertexFactory.createVertex();
graph.addVertex(newStartVertex);
V oldStartVertex = a.getStartVertex();
graph.addEdge(newStartVertex, oldStartVertex);
for(HalfEdge<V, T> looseEnd : a.getLooseEnds()) {
E edge = graph.addEdge(looseEnd.getStartVertex(), newStartVertex);
edgeLabelAccessor.setLabel(edge, looseEnd.getEdgeLabel());
}
Iterable<HalfEdge<V, T>> newLooseEnds = Collections.singletonList(new HalfEdge<V, T>(newStartVertex, null));
PartialNfa<V, T> result = PartialNfa.create(newStartVertex, newLooseEnds);
return result;
}
/**
* e+
*
* @param graph
* @param vertexFactory
* @param a
* @return
*/
public static <V, E, T> PartialNfa<V, T> oneOrMore(DirectedGraph<V, E> graph, VertexFactory<V> vertexFactory, PartialNfa<V, T> a, EdgeLabelAccessor<E, T> edgeLabelAccessor) {
V tmpVertex = vertexFactory.createVertex();
graph.addVertex(tmpVertex);
for(HalfEdge<V, T> looseEnd : a.getLooseEnds()) {
E edge = graph.addEdge(looseEnd.getStartVertex(), tmpVertex);
edgeLabelAccessor.setLabel(edge, looseEnd.getEdgeLabel());
}
V oldStartVertex = a.getStartVertex();
graph.addEdge(tmpVertex, oldStartVertex);
Iterable<HalfEdge<V, T>> newLooseEnds = Collections.singletonList(new HalfEdge<V, T>(tmpVertex, null));
PartialNfa<V, T> result = PartialNfa.create(oldStartVertex, newLooseEnds);
return result;
}
}