package esl.cuenet.query.pattern.matcher;
import esl.cuenet.query.pattern.exceptions.PatternGraphException;
import esl.cuenet.query.pattern.graph.EventStream;
import esl.cuenet.query.pattern.graph.EventStreamToken;
import esl.cuenet.query.pattern.graph.PatternGraph;
import esl.cuenet.query.pattern.graph.PatternGraphNode;
import java.util.HashSet;
import java.util.Stack;
public class MatchingAlgorithm {
private ModelPatterns patterns = null;
private enum MatchingResults {
VIOLATION,
MATCH,
MISMATCH
}
public MatchingAlgorithm(ModelPatterns patterns) {
this.patterns = patterns;
for (PatternGraph p: patterns) p.buildIndex();
}
public FringeClasses find(EventStream stream) {
FringeClasses results = new FringeClasses();
int pos = 0;
for (PatternGraph pattern: patterns) {
if ( !containment(pattern, stream, pos) ) continue;
if (violates(pattern, stream)) continue;
pos = matches(pattern, stream);
if (pos == pattern.size()) results.add(stream.getLast());
else if (pos == 0)
throw new PatternGraphException("Matching failed at position 0 -- Bad Pattern Graph?");
else {
for (String s: pattern.getEvents(pos)) results.add(s);
results.add(stream.getLast());
}
}
return results;
}
private int matches(PatternGraph pattern, EventStream stream) {
int curIx = 0, tokIx = 0;
PatternGraphNode current;
EventStreamToken token;
while (true) {
current = pattern.get(curIx);
token = stream.get(tokIx);
MatchingResults match = match(current, token);
if (match == MatchingResults.MATCH) {
tokIx++;
if (tokIx == stream.size()) break;
} else if (match == MatchingResults.MISMATCH) {
curIx++;
if (curIx == pattern.size()) break;
} else if (match == MatchingResults.VIOLATION) {
return -1;
}
}
return curIx;
}
private MatchingResults match(PatternGraphNode n, EventStreamToken token) {
Stack<PatternGraphNode> dfsStack = new Stack<PatternGraphNode>();
EventStreamToken sub = token;
dfsStack.push(n);
while ( !dfsStack.empty() ) {
PatternGraphNode node = dfsStack.pop();
// VISIT NODE
if (node.label().equals(sub.getOntClass())) {
/* check violation */
if (sub.getSubEventToken() == null) return MatchingResults.MATCH;
else sub = sub.getSubEventToken();
}
if (node.getSubEventPatternGraph() != null) {
for (int i=node.getSubEventPatternGraph().size()-1; i>=0; i--)
dfsStack.push(node.getSubEventPatternGraph().get(i));
}
}
return MatchingResults.MISMATCH;
}
private boolean containment(PatternGraph pattern, EventStream stream, int start) {
return true;
}
private boolean violates(PatternGraph pattern, EventStream stream) {
return false;
}
}