package org.simantics.modeling.scl;
import gnu.trove.list.array.TIntArrayList;
import gnu.trove.set.hash.THashSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.exception.DatabaseException;
import org.simantics.diagram.stubs.DiagramResource;
public class RouteGraphMatching {
public static boolean TRACE = false;
private static class Link {
public final int a;
public final int b;
public Link(int a, int b) {
this.a = a;
this.b = b;
}
}
private static class MatchingProcess {
ReadGraph graph;
DiagramResource DIA;
Resource[] result;
ArrayList[] ls;
ArrayList[] alternatives;
TIntArrayList stack = new TIntArrayList();
THashSet knownResources = new THashSet();
@SuppressWarnings("unchecked")
public MatchingProcess(ReadGraph graph, int size) {
this.graph = graph;
this.DIA = DiagramResource.getInstance(graph);
this.result = new Resource[size];
this.ls = new ArrayList[size];
this.alternatives = new ArrayList[size];
for(int i=0;i(2);
}
public void addLink(int a, int b) {
Link link = new Link(a, b);
ls[link.a].add(link);
ls[link.b].add(link);
}
public boolean match(List known) throws DatabaseException {
for(int i=0;i alt = alternatives[i];
if(alt != null) {
alt.removeAll(knownResources);
if(alt.isEmpty())
return false;
if(alt.size() == 1) {
result[i] = alt.get(0);
alternatives[i] = null;
stack.add(i);
}
}
}
return true;
}
private void printState() {
for(int i=0;i neighbors =
new ArrayList(graph.getObjects(r, DIA.AreConnected));
neighbors.removeAll(knownResources);
for(Link link : ls[pos]) {
int other = link.a == pos ? link.b : link.a;
ls[other].remove(link);
if(!setAlternatives(other, neighbors))
return false;
}
ls[pos].clear();
return true;
}
private boolean setKnown(int i, Resource value) throws DatabaseException {
if(TRACE)
System.out.println("setKnown(" + i + ", " + value + ")");
if(result[i] != null)
return result[i].equals(value);
if(alternatives[i] != null) {
if(!alternatives[i].contains(value))
return false;
alternatives[i] = null;
}
result[i] = value;
stack.add(i);
return true;
}
private boolean setAlternatives(int i, Collection values) throws DatabaseException {
if(TRACE)
System.out.println("setAlternatives(" + i + ", " + values + ")");
if(result[i] != null)
return values.contains(result[i]);
if(values.isEmpty())
return false;
if(values.size() == 1)
return setKnown(i, values.iterator().next());
ArrayList oldAlternatives = alternatives[i];
if(oldAlternatives == null) {
alternatives[i] = new ArrayList(values);
return true;
}
oldAlternatives.retainAll(values);
if(oldAlternatives.isEmpty())
return false;
if(oldAlternatives.size() == 1)
return setKnown(i, oldAlternatives.get(0));
return true;
}
}
public static List matchRouteGraph(ReadGraph graph,
List connectors, int routeLineCount, List links) throws DatabaseException {
MatchingProcess process = new MatchingProcess(graph, connectors.size() + routeLineCount);
for(int i=0;i